Prepare SOA Struct code for slices and dynamic arrays *to be implemented*

This commit is contained in:
gingerBill
2019-11-19 23:54:36 +00:00
parent 0839dccfdc
commit 44e0e96612
9 changed files with 112 additions and 37 deletions
+10 -5
View File
@@ -3631,10 +3631,13 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
type = t_untyped_integer;
} else if (is_type_struct(op_type)) {
Type *bt = base_type(op_type);
if (bt->Struct.is_soa) {
if (bt->Struct.soa_kind == StructSoa_Fixed) {
mode = Addressing_Constant;
value = exact_value_i64(bt->Struct.soa_count);
type = t_untyped_integer;
} else if ((bt->Struct.soa_kind == StructSoa_Slice && id == BuiltinProc_len) ||
bt->Struct.soa_kind == StructSoa_Dynamic) {
mode = Addressing_Value;
}
}
@@ -4801,7 +4804,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), old_array->Array.count);
soa_struct->Struct.tags = array_make<String>(heap_allocator(), old_array->Array.count);
soa_struct->Struct.node = operand->expr;
soa_struct->Struct.is_soa = true;
soa_struct->Struct.soa_kind = StructSoa_Fixed;
soa_struct->Struct.soa_elem = elem;
soa_struct->Struct.soa_count = count;
@@ -4834,7 +4837,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), old_struct->Struct.fields.count);
soa_struct->Struct.tags = array_make<String>(heap_allocator(), old_struct->Struct.tags.count);
soa_struct->Struct.node = operand->expr;
soa_struct->Struct.is_soa = true;
soa_struct->Struct.soa_kind = StructSoa_Fixed;
soa_struct->Struct.soa_elem = elem;
soa_struct->Struct.soa_count = count;
@@ -6778,8 +6781,10 @@ bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 *max_count)
}
return true;
case Type_Struct:
if (t->Struct.is_soa) {
*max_count = t->Struct.soa_count;
if (t->Struct.soa_kind != StructSoa_None) {
if (t->Struct.soa_kind == StructSoa_Fixed) {
*max_count = t->Struct.soa_count;
}
o->type = t->Struct.soa_elem;
if (o->mode == Addressing_SoaVariable || o->mode == Addressing_Variable) {
o->mode = Addressing_SoaVariable;
+2 -2
View File
@@ -2907,7 +2907,7 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), old_array->Array.count);
soa_struct->Struct.tags = array_make<String>(heap_allocator(), old_array->Array.count);
soa_struct->Struct.node = e;
soa_struct->Struct.is_soa = true;
soa_struct->Struct.soa_kind = StructSoa_Fixed;
soa_struct->Struct.soa_elem = elem;
soa_struct->Struct.soa_count = count;
@@ -2940,7 +2940,7 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
soa_struct->Struct.fields = array_make<Entity *>(heap_allocator(), old_struct->Struct.fields.count);
soa_struct->Struct.tags = array_make<String>(heap_allocator(), old_struct->Struct.tags.count);
soa_struct->Struct.node = e;
soa_struct->Struct.is_soa = true;
soa_struct->Struct.soa_kind = StructSoa_Fixed;
soa_struct->Struct.soa_elem = elem;
soa_struct->Struct.soa_count = count;
+9 -2
View File
@@ -1342,10 +1342,17 @@ void add_type_info_type(CheckerContext *c, Type *t) {
if (bt->Struct.scope != nullptr) {
for_array(i, bt->Struct.scope->elements.entries) {
Entity *e = bt->Struct.scope->elements.entries[i].value;
if (bt->Struct.is_soa) {
switch (bt->Struct.soa_kind) {
case StructSoa_Dynamic:
add_type_info_type(c, t_allocator);
/*fallthrough*/
case StructSoa_Slice:
case StructSoa_Fixed:
add_type_info_type(c, alloc_type_pointer(e->type));
} else {
break;
default:
add_type_info_type(c, e->type);
break;
}
}
}
+16 -9
View File
@@ -3564,13 +3564,13 @@ void ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) {
} else if (addr.kind == irAddr_SoaVariable) {
Type *t = type_deref(ir_type(addr.addr));
t = base_type(t);
GB_ASSERT(t->kind == Type_Struct && t->Struct.is_soa);
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
value = ir_emit_conv(proc, value, t->Struct.soa_elem);
irValue *index = addr.soa.index;
if (index->kind != irValue_Constant) {
Type *t = base_type(type_deref(ir_type(addr.addr)));
GB_ASSERT(t->kind == Type_Struct && t->Struct.is_soa);
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
i64 count = t->Struct.soa_count;
irValue *len = ir_const_int(count);
ir_emit_bounds_check(proc, ast_token(addr.soa.index_expr), index, len);
@@ -3695,8 +3695,8 @@ irValue *ir_addr_load(irProcedure *proc, irAddr const &addr) {
} else if (addr.kind == irAddr_SoaVariable) {
Type *t = type_deref(ir_type(addr.addr));
t = base_type(t);
GB_ASSERT(t->kind == Type_Struct && t->Struct.is_soa);
Type *elem = t->Struct.soa_elem;;
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
Type *elem = t->Struct.soa_elem;
i32 count = cast(i32)t->Struct.soa_count;
irValue *res = ir_add_local_generated(proc, elem, true);
@@ -7559,7 +7559,7 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) {
if (addr.soa.index->kind != irValue_Constant) {
Type *t = base_type(type_deref(ir_type(addr.addr)));
GB_ASSERT(t->kind == Type_Struct && t->Struct.is_soa);
GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
i64 count = t->Struct.soa_count;
irValue *len = ir_const_int(count);
ir_emit_bounds_check(proc, ast_token(addr.soa.index_expr), addr.soa.index, len);
@@ -7626,7 +7626,7 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) {
bool deref = is_type_pointer(t);
t = base_type(type_deref(t));
if (t->kind == Type_Struct && t->Struct.is_soa) {
if (t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None) {
// SOA STRUCTURES!!!!
Type *elem = t->Struct.soa_elem;
@@ -10873,11 +10873,18 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 6), is_raw_union);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 7), is_custom_align);
if (t->Struct.is_soa) {
if (t->Struct.soa_kind != StructSoa_None) {
irValue *kind = ir_emit_struct_ep(proc, tag, 8);
Type *kind_type = type_deref(ir_type(kind));
irValue *soa_kind = ir_value_constant(kind_type, exact_value_i64(t->Struct.soa_kind));
irValue *soa_type = ir_type_info(proc, t->Struct.soa_elem);
irValue *soa_len = ir_const_int(t->Struct.soa_count);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 8), soa_type);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 9), soa_len);
ir_emit_store(proc, kind, soa_kind);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 9), soa_type);
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 10), soa_len);
}
}
+20 -7
View File
@@ -110,6 +110,13 @@ struct BasicType {
String name;
};
enum StructSoaKind {
StructSoa_None = 0,
StructSoa_Fixed = 1,
StructSoa_Slice = 2,
StructSoa_Dynamic = 3,
};
struct TypeStruct {
Array<Entity *> fields;
Array<String> tags;
@@ -129,9 +136,10 @@ struct TypeStruct {
bool is_raw_union;
bool is_polymorphic;
bool is_poly_specialized;
bool is_soa;
Type *soa_elem;
i64 soa_count;
StructSoaKind soa_kind;
Type * soa_elem;
i64 soa_count;
};
struct TypeUnion {
@@ -1135,7 +1143,7 @@ bool is_type_union(Type *t) {
}
bool is_type_soa_struct(Type *t) {
t = base_type(t);
return t->kind == Type_Struct && t->Struct.is_soa;
return t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None;
}
bool is_type_raw_union(Type *t) {
@@ -2199,7 +2207,7 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
}
}
bool is_soa = type->Struct.is_soa;
bool is_soa = type->Struct.soa_kind != StructSoa_None;
bool is_soa_of_array = is_soa && is_type_array(type->Struct.soa_elem);
if (is_soa_of_array) {
@@ -3008,8 +3016,13 @@ gbString write_type_to_string(gbString str, Type *type) {
break;
case Type_Struct: {
if (type->Struct.soa_elem != nullptr) {
str = gb_string_append_fmt(str, "#soa[%d]", cast(int)type->Struct.soa_count);
if (type->Struct.soa_kind != StructSoa_None) {
switch (type->Struct.soa_kind) {
case StructSoa_Fixed: str = gb_string_append_fmt(str, "#soa[%d]", cast(int)type->Struct.soa_count); break;
case StructSoa_Slice: str = gb_string_appendc(str, "#soa[]"); break;
case StructSoa_Dynamic: str = gb_string_appendc(str, "#soa[dynamic]"); break;
default: GB_PANIC("Unknown StructSoaKind"); break;
}
str = write_type_to_string(str, type->Struct.soa_elem);
break;
}