mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-20 12:44:59 -07:00
Prepare SOA Struct code for slices and dynamic arrays *to be implemented*
This commit is contained in:
+2
-2
@@ -1086,7 +1086,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
return;
|
||||
};
|
||||
|
||||
is_soa := b.soa_base_type != nil;
|
||||
is_soa := b.soa_kind != .None;
|
||||
|
||||
strings.write_string(fi.buf, info.name);
|
||||
strings.write_byte(fi.buf, is_soa ? '[' : '{');
|
||||
@@ -1329,7 +1329,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
return;
|
||||
}
|
||||
|
||||
is_soa := info.soa_base_type != nil;
|
||||
is_soa := info.soa_kind != .None;
|
||||
|
||||
strings.write_byte(fi.buf, is_soa ? '[' : '{');
|
||||
defer strings.write_byte(fi.buf, is_soa ? ']' : '}');
|
||||
|
||||
+19
-3
@@ -162,6 +162,11 @@ are_types_identical :: proc(a, b: ^rt.Type_Info) -> bool {
|
||||
y, ok := b.variant.(rt.Type_Info_Opaque);
|
||||
if !ok do return false;
|
||||
return x.elem == y.elem;
|
||||
|
||||
case rt.Type_Info_Simd_Vector:
|
||||
y, ok := b.variant.(rt.Type_Info_Simd_Vector);
|
||||
if !ok do return false;
|
||||
return x.count == y.count && x.elem == y.elem;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -394,13 +399,24 @@ write_type :: proc(buf: ^strings.Builder, ti: ^rt.Type_Info) {
|
||||
write_type(buf, info.value);
|
||||
|
||||
case rt.Type_Info_Struct:
|
||||
if info.soa_base_type != nil {
|
||||
#complete switch info.soa_kind {
|
||||
case .None: // Ignore
|
||||
case .Fixed:
|
||||
write_string(buf, "#soa[");
|
||||
write_i64(buf, i64(info.soa_len));
|
||||
write_byte(buf, ']');
|
||||
write_type(buf, info.soa_base_type);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case .Slice:
|
||||
write_string(buf, "#soa[]");
|
||||
write_type(buf, info.soa_base_type);
|
||||
return;
|
||||
case .Dynamic:
|
||||
write_string(buf, "#soa[dynamic]");
|
||||
write_type(buf, info.soa_base_type);
|
||||
return;
|
||||
}
|
||||
|
||||
write_string(buf, "struct ");
|
||||
if info.is_packed do write_string(buf, "#packed ");
|
||||
if info.is_raw_union do write_string(buf, "#raw_union ");
|
||||
|
||||
@@ -47,6 +47,13 @@ Platform_Endianness :: enum u8 {
|
||||
Big = 2,
|
||||
}
|
||||
|
||||
Type_Info_Struct_Soa_Kind :: enum u8 {
|
||||
None = 0,
|
||||
Fixed = 1,
|
||||
Slice = 2,
|
||||
Dynamic = 3,
|
||||
}
|
||||
|
||||
// Variant Types
|
||||
Type_Info_Named :: struct {name: string, base: ^Type_Info};
|
||||
Type_Info_Integer :: struct {signed: bool, endianness: Platform_Endianness};
|
||||
@@ -88,6 +95,7 @@ Type_Info_Struct :: struct {
|
||||
is_raw_union: bool,
|
||||
custom_align: bool,
|
||||
// These are only set iff this structure is an SOA structure
|
||||
soa_kind: Type_Info_Struct_Soa_Kind,
|
||||
soa_base_type: ^Type_Info,
|
||||
soa_len: int,
|
||||
};
|
||||
|
||||
@@ -137,7 +137,7 @@ print_type :: proc(fd: os.Handle, ti: ^Type_Info) {
|
||||
os.write_string(fd, "()");
|
||||
} else {
|
||||
t := info.params.variant.(Type_Info_Tuple);
|
||||
os.write_string(fd, "(");
|
||||
os.write_byte(fd, '(');
|
||||
for t, i in t.types {
|
||||
if i > 0 do os.write_string(fd, ", ");
|
||||
print_type(fd, t);
|
||||
@@ -150,7 +150,7 @@ print_type :: proc(fd: os.Handle, ti: ^Type_Info) {
|
||||
}
|
||||
case Type_Info_Tuple:
|
||||
count := len(info.names);
|
||||
if count != 1 do os.write_string(fd, "(");
|
||||
if count != 1 do os.write_byte(fd, '(');
|
||||
for name, i in info.names {
|
||||
if i > 0 do os.write_string(fd, ", ");
|
||||
|
||||
@@ -165,9 +165,9 @@ print_type :: proc(fd: os.Handle, ti: ^Type_Info) {
|
||||
if count != 1 do os.write_string(fd, ")");
|
||||
|
||||
case Type_Info_Array:
|
||||
os.write_string(fd, "[");
|
||||
os.write_byte(fd, '[');
|
||||
print_u64(fd, u64(info.count));
|
||||
os.write_string(fd, "]");
|
||||
os.write_byte(fd, ']');
|
||||
print_type(fd, info.elem);
|
||||
case Type_Info_Dynamic_Array:
|
||||
os.write_string(fd, "[dynamic]");
|
||||
@@ -183,13 +183,24 @@ print_type :: proc(fd: os.Handle, ti: ^Type_Info) {
|
||||
print_type(fd, info.value);
|
||||
|
||||
case Type_Info_Struct:
|
||||
if info.soa_base_type != nil {
|
||||
#complete switch info.soa_kind {
|
||||
case .None: // Ignore
|
||||
case .Fixed:
|
||||
os.write_string(fd, "#soa[");
|
||||
print_u64(fd, u64(info.soa_len));
|
||||
os.write_byte(fd, ']');
|
||||
print_type(fd, info.soa_base_type);
|
||||
break;
|
||||
return;
|
||||
case .Slice:
|
||||
os.write_string(fd, "#soa[]");
|
||||
print_type(fd, info.soa_base_type);
|
||||
return;
|
||||
case .Dynamic:
|
||||
os.write_string(fd, "#soa[dynamic]");
|
||||
print_type(fd, info.soa_base_type);
|
||||
return;
|
||||
}
|
||||
|
||||
os.write_string(fd, "struct ");
|
||||
if info.is_packed do os.write_string(fd, "#packed ");
|
||||
if info.is_raw_union do os.write_string(fd, "#raw_union ");
|
||||
@@ -208,7 +219,15 @@ print_type :: proc(fd: os.Handle, ti: ^Type_Info) {
|
||||
os.write_byte(fd, '}');
|
||||
|
||||
case Type_Info_Union:
|
||||
os.write_string(fd, "union {");
|
||||
os.write_string(fd, "union ");
|
||||
if info.custom_align {
|
||||
os.write_string(fd, "#align ");
|
||||
print_u64(fd, u64(ti.align));
|
||||
}
|
||||
if info.no_nil {
|
||||
os.write_string(fd, "#no_nil ");
|
||||
}
|
||||
os.write_byte(fd, '{');
|
||||
for variant, i in info.variants {
|
||||
if i > 0 do os.write_string(fd, ", ");
|
||||
print_type(fd, variant);
|
||||
|
||||
+10
-5
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user