mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Tilde: Begin work on #soa
This commit is contained in:
@@ -201,6 +201,14 @@ gb_internal cgAddr cg_addr_map(cgValue addr, cgValue map_key, Type *map_type, Ty
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal cgAddr cg_addr_soa_variable(cgValue addr, cgValue index, Ast *index_expr) {
|
||||||
|
cgAddr v = {cgAddr_SoaVariable, addr};
|
||||||
|
v.soa.index = index;
|
||||||
|
v.soa.index_expr = index_expr;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gb_internal void cg_set_debug_pos_from_node(cgProcedure *p, Ast *node) {
|
gb_internal void cg_set_debug_pos_from_node(cgProcedure *p, Ast *node) {
|
||||||
if (node) {
|
if (node) {
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ struct cgProcedure {
|
|||||||
bool return_by_ptr;
|
bool return_by_ptr;
|
||||||
|
|
||||||
PtrMap<Entity *, cgAddr> variable_map;
|
PtrMap<Entity *, cgAddr> variable_map;
|
||||||
|
PtrMap<Entity *, cgAddr> soa_values_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,26 @@ gb_internal cgValue cg_builtin_len(cgProcedure *p, cgValue value) {
|
|||||||
}
|
}
|
||||||
case Type_Struct:
|
case Type_Struct:
|
||||||
GB_ASSERT(is_type_soa_struct(t));
|
GB_ASSERT(is_type_soa_struct(t));
|
||||||
|
{
|
||||||
|
if (t->Struct.soa_kind == StructSoa_Fixed) {
|
||||||
|
return cg_const_int(p, t_int, t->Struct.soa_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_ASSERT(t->Struct.soa_kind == StructSoa_Slice ||
|
||||||
|
t->Struct.soa_kind == StructSoa_Dynamic);
|
||||||
|
|
||||||
|
isize n = 0;
|
||||||
|
Type *elem = base_type(t->Struct.soa_elem);
|
||||||
|
if (elem->kind == Type_Struct) {
|
||||||
|
n = cast(isize)elem->Struct.fields.count;
|
||||||
|
} else if (elem->kind == Type_Array) {
|
||||||
|
n = cast(isize)elem->Array.count;
|
||||||
|
} else {
|
||||||
|
GB_PANIC("Unreachable");
|
||||||
|
}
|
||||||
|
|
||||||
|
return cg_emit_struct_ev(p, value, n);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-12
@@ -147,8 +147,7 @@ gb_internal cgAddr cg_build_addr_from_entity(cgProcedure *p, Entity *e, Ast *exp
|
|||||||
// NOTE(bill): Calculate the using variable every time
|
// NOTE(bill): Calculate the using variable every time
|
||||||
v = cg_get_using_variable(p, e);
|
v = cg_get_using_variable(p, e);
|
||||||
} else if (e->flags & EntityFlag_SoaPtrField) {
|
} else if (e->flags & EntityFlag_SoaPtrField) {
|
||||||
GB_PANIC("TODO(bill): cg_get_soa_variable_addr");
|
return map_must_get(&p->soa_values_map, e);
|
||||||
// return cg_get_soa_variable_addr(p, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3541,15 +3540,13 @@ gb_internal cgAddr cg_build_addr_index_expr(cgProcedure *p, Ast *expr) {
|
|||||||
bool deref = is_type_pointer(t);
|
bool deref = is_type_pointer(t);
|
||||||
t = base_type(type_deref(t));
|
t = base_type(type_deref(t));
|
||||||
if (is_type_soa_struct(t)) {
|
if (is_type_soa_struct(t)) {
|
||||||
GB_PANIC("TODO(bill): #soa");
|
cgValue val = cg_build_addr_ptr(p, ie->expr);
|
||||||
// // SOA STRUCTURES!!!!
|
if (deref) {
|
||||||
// lbValue val = cg_build_addr_ptr(p, ie->expr);
|
val = cg_emit_load(p, val);
|
||||||
// if (deref) {
|
}
|
||||||
// val = cg_emit_load(p, val);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// cgValue index = cg_build_expr(p, ie->index);
|
cgValue index = cg_build_expr(p, ie->index);
|
||||||
// return cg_addr_soa_variable(val, index, ie->index);
|
return cg_addr_soa_variable(val, index, ie->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ie->expr->tav.mode == Addressing_SoaVariable) {
|
if (ie->expr->tav.mode == Addressing_SoaVariable) {
|
||||||
@@ -3788,8 +3785,7 @@ gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr) {
|
|||||||
cgValue value = cg_build_expr(p, de->expr);
|
cgValue value = cg_build_expr(p, de->expr);
|
||||||
cgValue ptr = cg_emit_struct_ev(p, value, 0);
|
cgValue ptr = cg_emit_struct_ev(p, value, 0);
|
||||||
cgValue idx = cg_emit_struct_ev(p, value, 1);
|
cgValue idx = cg_emit_struct_ev(p, value, 1);
|
||||||
GB_PANIC("TODO(bill): cg_addr_soa_variable");
|
return cg_addr_soa_variable(ptr, idx, nullptr);
|
||||||
// return cg_addr_soa_variable(ptr, idx, nullptr);
|
|
||||||
}
|
}
|
||||||
cgValue addr = cg_build_expr(p, de->expr);
|
cgValue addr = cg_build_expr(p, de->expr);
|
||||||
return cg_addr(addr);
|
return cg_addr(addr);
|
||||||
|
|||||||
+2
-1
@@ -78,6 +78,7 @@ gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool i
|
|||||||
p->branch_regions.allocator = a;
|
p->branch_regions.allocator = a;
|
||||||
|
|
||||||
map_init(&p->variable_map);
|
map_init(&p->variable_map);
|
||||||
|
map_init(&p->soa_values_map);
|
||||||
|
|
||||||
TB_Linkage linkage = TB_LINKAGE_PRIVATE;
|
TB_Linkage linkage = TB_LINKAGE_PRIVATE;
|
||||||
if (p->is_export) {
|
if (p->is_export) {
|
||||||
@@ -143,7 +144,7 @@ gb_internal cgProcedure *cg_procedure_create_dummy(cgModule *m, String const &li
|
|||||||
p->branch_regions.allocator = a;
|
p->branch_regions.allocator = a;
|
||||||
|
|
||||||
map_init(&p->variable_map);
|
map_init(&p->variable_map);
|
||||||
|
map_init(&p->soa_values_map);
|
||||||
|
|
||||||
TB_Linkage linkage = TB_LINKAGE_PRIVATE;
|
TB_Linkage linkage = TB_LINKAGE_PRIVATE;
|
||||||
|
|
||||||
|
|||||||
+121
-2
@@ -1649,6 +1649,126 @@ gb_internal void cg_build_range_stmt_enum(cgProcedure *p, Type *enum_type, Type
|
|||||||
if (done_) *done_ = done;
|
if (done_) *done_ = done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_internal void cg_build_range_stmt_struct_soa(cgProcedure *p, AstRangeStmt *rs, Scope *scope) {
|
||||||
|
Ast *expr = unparen_expr(rs->expr);
|
||||||
|
TypeAndValue tav = type_and_value_of_expr(expr);
|
||||||
|
|
||||||
|
TB_Node *loop = nullptr;
|
||||||
|
TB_Node *body = nullptr;
|
||||||
|
TB_Node *done = nullptr;
|
||||||
|
|
||||||
|
bool is_reverse = rs->reverse;
|
||||||
|
|
||||||
|
cg_scope_open(p, scope);
|
||||||
|
|
||||||
|
Ast *val0 = rs->vals.count > 0 ? cg_strip_and_prefix(rs->vals[0]) : nullptr;
|
||||||
|
Ast *val1 = rs->vals.count > 1 ? cg_strip_and_prefix(rs->vals[1]) : nullptr;
|
||||||
|
Type *val_types[2] = {};
|
||||||
|
if (val0 != nullptr && !is_blank_ident(val0)) {
|
||||||
|
val_types[0] = type_of_expr(val0);
|
||||||
|
}
|
||||||
|
if (val1 != nullptr && !is_blank_ident(val1)) {
|
||||||
|
val_types[1] = type_of_expr(val1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cgAddr array = cg_build_addr(p, expr);
|
||||||
|
if (is_type_pointer(cg_addr_type(array))) {
|
||||||
|
array = cg_addr(cg_addr_load(p, array));
|
||||||
|
}
|
||||||
|
cgValue count = cg_builtin_len(p, cg_addr_load(p, array));
|
||||||
|
|
||||||
|
|
||||||
|
cgAddr index = cg_add_local(p, t_int, nullptr, false);
|
||||||
|
|
||||||
|
if (!is_reverse) {
|
||||||
|
/*
|
||||||
|
for x, i in array {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
i := -1
|
||||||
|
for {
|
||||||
|
i += 1
|
||||||
|
if !(i < len(array)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
x := array[i] // but #soa-ified
|
||||||
|
...
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
cg_addr_store(p, index, cg_const_int(p, t_int, cast(u64)-1));
|
||||||
|
|
||||||
|
loop = cg_control_region(p, "for_soa_loop");
|
||||||
|
cg_emit_goto(p, loop);
|
||||||
|
tb_inst_set_control(p->func, loop);
|
||||||
|
|
||||||
|
cgValue incr = cg_emit_arith(p, Token_Add, cg_addr_load(p, index), cg_const_int(p, t_int, 1), t_int);
|
||||||
|
cg_addr_store(p, index, incr);
|
||||||
|
|
||||||
|
body = cg_control_region(p, "for_soa_body");
|
||||||
|
done = cg_control_region(p, "for_soa_done");
|
||||||
|
|
||||||
|
cgValue cond = cg_emit_comp(p, Token_Lt, incr, count);
|
||||||
|
cg_emit_if(p, cond, body, done);
|
||||||
|
} else {
|
||||||
|
// NOTE(bill): REVERSED LOGIC
|
||||||
|
/*
|
||||||
|
#reverse for x, i in array {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
i := len(array)
|
||||||
|
for {
|
||||||
|
i -= 1
|
||||||
|
if i < 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
#no_bounds_check x := array[i] // but #soa-ified
|
||||||
|
...
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
cg_addr_store(p, index, count);
|
||||||
|
|
||||||
|
loop = cg_control_region(p, "for_soa_loop");
|
||||||
|
cg_emit_goto(p, loop);
|
||||||
|
tb_inst_set_control(p->func, loop);
|
||||||
|
|
||||||
|
cgValue incr = cg_emit_arith(p, Token_Sub, cg_addr_load(p, index), cg_const_int(p, t_int, 1), t_int);
|
||||||
|
cg_addr_store(p, index, incr);
|
||||||
|
|
||||||
|
body = cg_control_region(p, "for_soa_body");
|
||||||
|
done = cg_control_region(p, "for_soa_done");
|
||||||
|
|
||||||
|
cgValue cond = cg_emit_comp(p, Token_Lt, incr, cg_const_int(p, t_int, 0));
|
||||||
|
cg_emit_if(p, cond, done, body);
|
||||||
|
}
|
||||||
|
tb_inst_set_control(p->func, body);
|
||||||
|
|
||||||
|
|
||||||
|
if (val_types[0]) {
|
||||||
|
Entity *e = entity_of_node(val0);
|
||||||
|
if (e != nullptr) {
|
||||||
|
cgAddr soa_val = cg_addr_soa_variable(array.addr, cg_addr_load(p, index), nullptr);
|
||||||
|
map_set(&p->soa_values_map, e, soa_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (val_types[1]) {
|
||||||
|
cg_range_stmt_store_val(p, val1, cg_addr_load(p, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cg_push_target_list(p, rs->label, done, loop, nullptr);
|
||||||
|
|
||||||
|
cg_build_stmt(p, rs->body);
|
||||||
|
|
||||||
|
cg_scope_close(p, cgDeferExit_Default, nullptr);
|
||||||
|
cg_pop_target_list(p);
|
||||||
|
cg_emit_goto(p, loop);
|
||||||
|
tb_inst_set_control(p->func, done);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal void cg_build_range_stmt(cgProcedure *p, Ast *node) {
|
gb_internal void cg_build_range_stmt(cgProcedure *p, Ast *node) {
|
||||||
ast_node(rs, RangeStmt, node);
|
ast_node(rs, RangeStmt, node);
|
||||||
@@ -1664,8 +1784,7 @@ gb_internal void cg_build_range_stmt(cgProcedure *p, Ast *node) {
|
|||||||
if (expr_type != nullptr) {
|
if (expr_type != nullptr) {
|
||||||
Type *et = base_type(type_deref(expr_type));
|
Type *et = base_type(type_deref(expr_type));
|
||||||
if (is_type_soa_struct(et)) {
|
if (is_type_soa_struct(et)) {
|
||||||
GB_PANIC("TODO(bill): #soa array range statements");
|
cg_build_range_stmt_struct_soa(p, rs, rs->scope);
|
||||||
// cg_build_range_stmt_struct_soa(p, rs, scope);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user