|
@@ -17,8 +17,6 @@ typedef Array(irValue *) irValueArray;
|
|
|
|
|
|
typedef struct irModule {
|
|
typedef struct irModule {
|
|
CheckerInfo * info;
|
|
CheckerInfo * info;
|
|
- BuildContext *build_context;
|
|
|
|
- BaseTypeSizes sizes;
|
|
|
|
gbArena arena;
|
|
gbArena arena;
|
|
gbArena tmp_arena;
|
|
gbArena tmp_arena;
|
|
gbAllocator allocator;
|
|
gbAllocator allocator;
|
|
@@ -128,9 +126,11 @@ struct irProcedure {
|
|
i32 block_count;
|
|
i32 block_count;
|
|
};
|
|
};
|
|
|
|
|
|
-#define IR_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
|
|
|
|
-#define IR_TYPE_INFO_DATA_NAME "__$type_info_data"
|
|
|
|
-#define IR_TYPE_INFO_DATA_MEMBER_NAME "__$type_info_data_member"
|
|
|
|
|
|
+#define IR_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
|
|
|
|
+#define IR_TYPE_INFO_DATA_NAME "__$type_info_data"
|
|
|
|
+#define IR_TYPE_INFO_TYPES_NAME "__$type_info_types_data"
|
|
|
|
+#define IR_TYPE_INFO_NAMES_NAME "__$type_info_names_data"
|
|
|
|
+#define IR_TYPE_INFO_OFFSETS_NAME "__$type_info_offsets_data"
|
|
|
|
|
|
|
|
|
|
#define IR_INSTR_KINDS \
|
|
#define IR_INSTR_KINDS \
|
|
@@ -324,6 +324,7 @@ typedef struct irValueGlobal {
|
|
bool is_constant;
|
|
bool is_constant;
|
|
bool is_private;
|
|
bool is_private;
|
|
bool is_thread_local;
|
|
bool is_thread_local;
|
|
|
|
+ bool is_foreign;
|
|
bool is_unnamed_addr;
|
|
bool is_unnamed_addr;
|
|
} irValueGlobal;
|
|
} irValueGlobal;
|
|
|
|
|
|
@@ -1293,6 +1294,14 @@ irValue *ir_emit(irProcedure *proc, irValue *instr) {
|
|
return instr;
|
|
return instr;
|
|
}
|
|
}
|
|
irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) {
|
|
irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) {
|
|
|
|
+#if 1
|
|
|
|
+ // NOTE(bill): Sanity check
|
|
|
|
+ Type *a = base_type(base_enum_type(type_deref(ir_type(address))));
|
|
|
|
+ Type *b = base_type(base_enum_type(ir_type(value)));
|
|
|
|
+ if (!is_type_untyped(b)) {
|
|
|
|
+ GB_ASSERT_MSG(are_types_identical(a, b), "%s %s", type_to_string(a), type_to_string(b));
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
return ir_emit(p, ir_make_instr_store(p, address, value));
|
|
return ir_emit(p, ir_make_instr_store(p, address, value));
|
|
}
|
|
}
|
|
irValue *ir_emit_load(irProcedure *p, irValue *address) {
|
|
irValue *ir_emit_load(irProcedure *p, irValue *address) {
|
|
@@ -1428,9 +1437,9 @@ irValue *ir_gen_map_header(irProcedure *proc, irValue *map_val, Type *map_type)
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 1), v_true);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 1), v_true);
|
|
}
|
|
}
|
|
|
|
|
|
- i64 entry_size = type_size_of(proc->module->sizes, a, map_type->Map.entry_type);
|
|
|
|
- i64 entry_align = type_align_of(proc->module->sizes, a, map_type->Map.entry_type);
|
|
|
|
- i64 value_offset = type_offset_of(proc->module->sizes, a, map_type->Map.entry_type, 2);
|
|
|
|
|
|
+ i64 entry_size = type_size_of(a, map_type->Map.entry_type);
|
|
|
|
+ i64 entry_align = type_align_of(a, map_type->Map.entry_type);
|
|
|
|
+ i64 value_offset = type_offset_of(a, map_type->Map.entry_type, 2);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 2), ir_make_const_int(a, entry_size));
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 2), ir_make_const_int(a, entry_size));
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 3), ir_make_const_int(a, entry_align));
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 3), ir_make_const_int(a, entry_align));
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 4), ir_make_const_int(a, value_offset));
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 4), ir_make_const_int(a, value_offset));
|
|
@@ -1450,7 +1459,7 @@ irValue *ir_gen_map_key(irProcedure *proc, irValue *key, Type *key_type) {
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, p, t_u64));
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, v, 0), ir_emit_conv(proc, p, t_u64));
|
|
} else if (is_type_float(t)) {
|
|
} else if (is_type_float(t)) {
|
|
irValue *bits = NULL;
|
|
irValue *bits = NULL;
|
|
- i64 size = type_size_of(proc->module->sizes, proc->module->allocator, t);
|
|
|
|
|
|
+ i64 size = type_size_of(proc->module->allocator, t);
|
|
switch (8*size) {
|
|
switch (8*size) {
|
|
case 32: bits = ir_emit_bitcast(proc, key, t_u32); break;
|
|
case 32: bits = ir_emit_bitcast(proc, key, t_u32); break;
|
|
case 64: bits = ir_emit_bitcast(proc, key, t_u64); break;
|
|
case 64: bits = ir_emit_bitcast(proc, key, t_u64); break;
|
|
@@ -1650,7 +1659,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
|
irModule *m = proc->module;
|
|
irModule *m = proc->module;
|
|
Type *ptr_type = base_type(t_left);
|
|
Type *ptr_type = base_type(t_left);
|
|
GB_ASSERT(!is_type_rawptr(ptr_type));
|
|
GB_ASSERT(!is_type_rawptr(ptr_type));
|
|
- irValue *elem_size = ir_make_const_int(m->allocator, type_size_of(m->sizes, m->allocator, ptr_type->Pointer.elem));
|
|
|
|
|
|
+ irValue *elem_size = ir_make_const_int(m->allocator, type_size_of(m->allocator, ptr_type->Pointer.elem));
|
|
irValue *x = ir_emit_conv(proc, left, type);
|
|
irValue *x = ir_emit_conv(proc, left, type);
|
|
irValue *y = ir_emit_conv(proc, right, type);
|
|
irValue *y = ir_emit_conv(proc, right, type);
|
|
irValue *diff = ir_emit_arith(proc, op, x, y, type);
|
|
irValue *diff = ir_emit_arith(proc, op, x, y, type);
|
|
@@ -1665,7 +1674,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
|
|
left = ir_emit_conv(proc, left, type);
|
|
left = ir_emit_conv(proc, left, type);
|
|
if (!is_type_unsigned(ir_type(right))) {
|
|
if (!is_type_unsigned(ir_type(right))) {
|
|
Type *t = t_u64;
|
|
Type *t = t_u64;
|
|
- if (proc->module->sizes.word_size == 32) {
|
|
|
|
|
|
+ if (build_context.word_size == 32) {
|
|
t = t_u32;
|
|
t = t_u32;
|
|
}
|
|
}
|
|
right = ir_emit_conv(proc, right, t);
|
|
right = ir_emit_conv(proc, right, t);
|
|
@@ -1747,7 +1756,7 @@ irValue *ir_emit_array_ep(irProcedure *proc, irValue *s, irValue *index) {
|
|
Type *t = ir_type(s);
|
|
Type *t = ir_type(s);
|
|
GB_ASSERT(is_type_pointer(t));
|
|
GB_ASSERT(is_type_pointer(t));
|
|
Type *st = base_type(type_deref(t));
|
|
Type *st = base_type(type_deref(t));
|
|
- GB_ASSERT(is_type_array(st) || is_type_vector(st));
|
|
|
|
|
|
+ GB_ASSERT_MSG(is_type_array(st) || is_type_vector(st), "%s", type_to_string(st));
|
|
|
|
|
|
// NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
|
|
// NOTE(bill): For some weird legacy reason in LLVM, structure elements must be accessed as an i32
|
|
index = ir_emit_conv(proc, index, t_i32);
|
|
index = ir_emit_conv(proc, index, t_i32);
|
|
@@ -1762,8 +1771,12 @@ irValue *ir_emit_union_tag_ptr(irProcedure *proc, irValue *u) {
|
|
Type *t = ir_type(u);
|
|
Type *t = ir_type(u);
|
|
GB_ASSERT(is_type_pointer(t) &&
|
|
GB_ASSERT(is_type_pointer(t) &&
|
|
is_type_union(type_deref(t)));
|
|
is_type_union(type_deref(t)));
|
|
- GB_ASSERT(are_types_identical(t, ir_type(u)));
|
|
|
|
- return ir_emit(proc, ir_make_instr_union_tag_ptr(proc, u));
|
|
|
|
|
|
+ irValue *tag_ptr = ir_emit(proc, ir_make_instr_union_tag_ptr(proc, u));
|
|
|
|
+ Type *tpt = ir_type(tag_ptr);
|
|
|
|
+ GB_ASSERT(is_type_pointer(tpt));
|
|
|
|
+ tpt = base_type(type_deref(tpt));
|
|
|
|
+ GB_ASSERT(tpt == t_int);
|
|
|
|
+ return tag_ptr;
|
|
}
|
|
}
|
|
|
|
|
|
irValue *ir_emit_union_tag_value(irProcedure *proc, irValue *u) {
|
|
irValue *ir_emit_union_tag_value(irProcedure *proc, irValue *u) {
|
|
@@ -2175,8 +2188,8 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
|
|
if (is_type_integer(src) && is_type_integer(dst)) {
|
|
if (is_type_integer(src) && is_type_integer(dst)) {
|
|
GB_ASSERT(src->kind == Type_Basic &&
|
|
GB_ASSERT(src->kind == Type_Basic &&
|
|
dst->kind == Type_Basic);
|
|
dst->kind == Type_Basic);
|
|
- i64 sz = type_size_of(proc->module->sizes, proc->module->allocator, src);
|
|
|
|
- i64 dz = type_size_of(proc->module->sizes, proc->module->allocator, dst);
|
|
|
|
|
|
+ i64 sz = type_size_of(proc->module->allocator, src);
|
|
|
|
+ i64 dz = type_size_of(proc->module->allocator, dst);
|
|
irConvKind kind = irConv_trunc;
|
|
irConvKind kind = irConv_trunc;
|
|
if (sz == dz) {
|
|
if (sz == dz) {
|
|
// NOTE(bill): In LLVM, all integers are signed and rely upon 2's compliment
|
|
// NOTE(bill): In LLVM, all integers are signed and rely upon 2's compliment
|
|
@@ -2202,8 +2215,8 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
|
|
|
|
|
|
// float -> float
|
|
// float -> float
|
|
if (is_type_float(src) && is_type_float(dst)) {
|
|
if (is_type_float(src) && is_type_float(dst)) {
|
|
- i64 sz = type_size_of(proc->module->sizes, proc->module->allocator, src);
|
|
|
|
- i64 dz = type_size_of(proc->module->sizes, proc->module->allocator, dst);
|
|
|
|
|
|
+ i64 sz = type_size_of(proc->module->allocator, src);
|
|
|
|
+ i64 dz = type_size_of(proc->module->allocator, dst);
|
|
irConvKind kind = irConv_fptrunc;
|
|
irConvKind kind = irConv_fptrunc;
|
|
if (dz >= sz) {
|
|
if (dz >= sz) {
|
|
kind = irConv_fpext;
|
|
kind = irConv_fpext;
|
|
@@ -2418,8 +2431,8 @@ irValue *ir_emit_transmute(irProcedure *proc, irValue *value, Type *t) {
|
|
|
|
|
|
irModule *m = proc->module;
|
|
irModule *m = proc->module;
|
|
|
|
|
|
- i64 sz = type_size_of(m->sizes, m->allocator, src);
|
|
|
|
- i64 dz = type_size_of(m->sizes, m->allocator, dst);
|
|
|
|
|
|
+ i64 sz = type_size_of(m->allocator, src);
|
|
|
|
+ i64 dz = type_size_of(m->allocator, dst);
|
|
|
|
|
|
GB_ASSERT_MSG(sz == dz, "Invalid transmute conversion: `%s` to `%s`", type_to_string(src_type), type_to_string(t));
|
|
GB_ASSERT_MSG(sz == dz, "Invalid transmute conversion: `%s` to `%s`", type_to_string(src_type), type_to_string(t));
|
|
|
|
|
|
@@ -2443,7 +2456,7 @@ irValue *ir_emit_down_cast(irProcedure *proc, irValue *value, Type *t) {
|
|
Selection sel = lookup_field(proc->module->allocator, t, field_name, false);
|
|
Selection sel = lookup_field(proc->module->allocator, t, field_name, false);
|
|
irValue *bytes = ir_emit_conv(proc, value, t_u8_ptr);
|
|
irValue *bytes = ir_emit_conv(proc, value, t_u8_ptr);
|
|
|
|
|
|
- i64 offset_ = type_offset_of_from_selection(proc->module->sizes, allocator, type_deref(t), sel);
|
|
|
|
|
|
+ i64 offset_ = type_offset_of_from_selection(allocator, type_deref(t), sel);
|
|
irValue *offset = ir_make_const_int(allocator, -offset_);
|
|
irValue *offset = ir_make_const_int(allocator, -offset_);
|
|
irValue *head = ir_emit_ptr_offset(proc, bytes, offset);
|
|
irValue *head = ir_emit_ptr_offset(proc, bytes, offset);
|
|
return ir_emit_conv(proc, head, t);
|
|
return ir_emit_conv(proc, head, t);
|
|
@@ -3058,8 +3071,8 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|
Type *type = type_of_expr(proc->module->info, ce->args.e[0]);
|
|
Type *type = type_of_expr(proc->module->info, ce->args.e[0]);
|
|
Type *ptr_type = make_type_pointer(allocator, type);
|
|
Type *ptr_type = make_type_pointer(allocator, type);
|
|
|
|
|
|
- i64 s = type_size_of(proc->module->sizes, allocator, type);
|
|
|
|
- i64 a = type_align_of(proc->module->sizes, allocator, type);
|
|
|
|
|
|
+ i64 s = type_size_of(allocator, type);
|
|
|
|
+ i64 a = type_align_of(allocator, type);
|
|
|
|
|
|
irValue **args = gb_alloc_array(allocator, irValue *, 2);
|
|
irValue **args = gb_alloc_array(allocator, irValue *, 2);
|
|
args[0] = ir_make_const_int(allocator, s);
|
|
args[0] = ir_make_const_int(allocator, s);
|
|
@@ -3078,8 +3091,8 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|
Type *ptr_type = make_type_pointer(allocator, type);
|
|
Type *ptr_type = make_type_pointer(allocator, type);
|
|
Type *slice_type = make_type_slice(allocator, type);
|
|
Type *slice_type = make_type_slice(allocator, type);
|
|
|
|
|
|
- i64 s = type_size_of(proc->module->sizes, allocator, type);
|
|
|
|
- i64 a = type_align_of(proc->module->sizes, allocator, type);
|
|
|
|
|
|
+ i64 s = type_size_of(allocator, type);
|
|
|
|
+ i64 a = type_align_of(allocator, type);
|
|
|
|
|
|
irValue *elem_size = ir_make_const_int(allocator, s);
|
|
irValue *elem_size = ir_make_const_int(allocator, s);
|
|
irValue *elem_align = ir_make_const_int(allocator, a);
|
|
irValue *elem_align = ir_make_const_int(allocator, a);
|
|
@@ -3193,8 +3206,8 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|
if (is_type_dynamic_array(type)) {
|
|
if (is_type_dynamic_array(type)) {
|
|
Type *elem = type->DynamicArray.elem;
|
|
Type *elem = type->DynamicArray.elem;
|
|
|
|
|
|
- irValue *elem_size = ir_make_const_int(a, type_size_of(proc->module->sizes, a, elem));
|
|
|
|
- irValue *elem_align = ir_make_const_int(a, type_align_of(proc->module->sizes, a, elem));
|
|
|
|
|
|
+ irValue *elem_size = ir_make_const_int(a, type_size_of(a, elem));
|
|
|
|
+ irValue *elem_align = ir_make_const_int(a, type_align_of(a, elem));
|
|
|
|
|
|
ptr = ir_emit_conv(proc, ptr, t_rawptr);
|
|
ptr = ir_emit_conv(proc, ptr, t_rawptr);
|
|
|
|
|
|
@@ -3243,8 +3256,8 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|
GB_ASSERT(is_type_dynamic_array(type));
|
|
GB_ASSERT(is_type_dynamic_array(type));
|
|
Type *elem_type = type->DynamicArray.elem;
|
|
Type *elem_type = type->DynamicArray.elem;
|
|
|
|
|
|
- irValue *elem_size = ir_make_const_int(a, type_size_of(proc->module->sizes, a, elem_type));
|
|
|
|
- irValue *elem_align = ir_make_const_int(a, type_align_of(proc->module->sizes, a, elem_type));
|
|
|
|
|
|
+ irValue *elem_size = ir_make_const_int(a, type_size_of(a, elem_type));
|
|
|
|
+ irValue *elem_align = ir_make_const_int(a, type_align_of(a, elem_type));
|
|
|
|
|
|
array_ptr = ir_emit_conv(proc, array_ptr, t_rawptr);
|
|
array_ptr = ir_emit_conv(proc, array_ptr, t_rawptr);
|
|
|
|
|
|
@@ -3387,7 +3400,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|
Type *slice_type = base_type(ir_type(dst_slice));
|
|
Type *slice_type = base_type(ir_type(dst_slice));
|
|
GB_ASSERT(slice_type->kind == Type_Slice);
|
|
GB_ASSERT(slice_type->kind == Type_Slice);
|
|
Type *elem_type = slice_type->Slice.elem;
|
|
Type *elem_type = slice_type->Slice.elem;
|
|
- i64 size_of_elem = type_size_of(proc->module->sizes, proc->module->allocator, elem_type);
|
|
|
|
|
|
+ i64 size_of_elem = type_size_of(proc->module->allocator, elem_type);
|
|
|
|
|
|
irValue *dst = ir_emit_conv(proc, ir_slice_elem(proc, dst_slice), t_rawptr);
|
|
irValue *dst = ir_emit_conv(proc, ir_slice_elem(proc, dst_slice), t_rawptr);
|
|
irValue *src = ir_emit_conv(proc, ir_slice_elem(proc, src_slice), t_rawptr);
|
|
irValue *src = ir_emit_conv(proc, ir_slice_elem(proc, src_slice), t_rawptr);
|
|
@@ -3459,7 +3472,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
|
|
return ir_emit_conv(proc, s, tv->type);
|
|
return ir_emit_conv(proc, s, tv->type);
|
|
}
|
|
}
|
|
irValue *slice = ir_add_local_generated(proc, tv->type);
|
|
irValue *slice = ir_add_local_generated(proc, tv->type);
|
|
- i64 elem_size = type_size_of(proc->module->sizes, proc->module->allocator, t->Slice.elem);
|
|
|
|
|
|
+ i64 elem_size = type_size_of(proc->module->allocator, t->Slice.elem);
|
|
|
|
|
|
irValue *ptr = ir_emit_conv(proc, ir_slice_elem(proc, s), t_u8_ptr);
|
|
irValue *ptr = ir_emit_conv(proc, ir_slice_elem(proc, s), t_u8_ptr);
|
|
irValue *count = ir_slice_count(proc, s);
|
|
irValue *count = ir_slice_count(proc, s);
|
|
@@ -3746,20 +3759,15 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|
String name = e->token.string;
|
|
String name = e->token.string;
|
|
if (str_eq(name, str_lit("names"))) {
|
|
if (str_eq(name, str_lit("names"))) {
|
|
irValue *ti_ptr = ir_type_info(proc, type);
|
|
irValue *ti_ptr = ir_type_info(proc, type);
|
|
- // {
|
|
|
|
- // irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 1);
|
|
|
|
- // args[0] = ti_ptr;
|
|
|
|
- // ti_ptr = ir_emit_global_call(proc, "type_info_base", args, 1);
|
|
|
|
- // }
|
|
|
|
|
|
+
|
|
irValue *names_ptr = NULL;
|
|
irValue *names_ptr = NULL;
|
|
|
|
|
|
if (is_type_enum(type)) {
|
|
if (is_type_enum(type)) {
|
|
irValue *enum_info = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr);
|
|
irValue *enum_info = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr);
|
|
names_ptr = ir_emit_struct_ep(proc, enum_info, 1);
|
|
names_ptr = ir_emit_struct_ep(proc, enum_info, 1);
|
|
- } else {
|
|
|
|
- GB_PANIC("TODO(bill): `names` for records");
|
|
|
|
- // irValue *record_info = ir_emit_conv(proc, ti_ptr, t_type_info_record_ptr);
|
|
|
|
- // names_ptr = ir_emit_struct_ep(proc, record_info, 1);
|
|
|
|
|
|
+ } else if (type->kind == Type_Record) {
|
|
|
|
+ irValue *record_info = ir_emit_conv(proc, ti_ptr, t_type_info_record_ptr);
|
|
|
|
+ names_ptr = ir_emit_struct_ep(proc, record_info, 1);
|
|
}
|
|
}
|
|
return ir_make_addr(names_ptr);
|
|
return ir_make_addr(names_ptr);
|
|
} else {
|
|
} else {
|
|
@@ -4116,15 +4124,14 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|
default: GB_PANIC("Unknown CompoundLit type: %s", type_to_string(type)); break;
|
|
default: GB_PANIC("Unknown CompoundLit type: %s", type_to_string(type)); break;
|
|
|
|
|
|
case Type_Vector: {
|
|
case Type_Vector: {
|
|
- irValue *vector_elem = ir_vector_elem(proc, v);
|
|
|
|
if (cl->elems.count == 1 && bt->Vector.count > 1) {
|
|
if (cl->elems.count == 1 && bt->Vector.count > 1) {
|
|
isize index_count = bt->Vector.count;
|
|
isize index_count = bt->Vector.count;
|
|
irValue *elem_val = ir_build_expr(proc, cl->elems.e[0]);
|
|
irValue *elem_val = ir_build_expr(proc, cl->elems.e[0]);
|
|
for (isize i = 0; i < index_count; i++) {
|
|
for (isize i = 0; i < index_count; i++) {
|
|
- ir_emit_store(proc, ir_emit_array_epi(proc, vector_elem, i), elem_val);
|
|
|
|
|
|
+ ir_emit_store(proc, ir_emit_array_epi(proc, v, i), elem_val);
|
|
}
|
|
}
|
|
} else if (cl->elems.count > 0) {
|
|
} else if (cl->elems.count > 0) {
|
|
- ir_emit_store(proc, vector_elem, ir_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
|
|
|
|
|
|
+ ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
|
|
for_array(i, cl->elems) {
|
|
for_array(i, cl->elems) {
|
|
AstNode *elem = cl->elems.e[i];
|
|
AstNode *elem = cl->elems.e[i];
|
|
if (ir_is_elem_const(proc->module, elem, et)) {
|
|
if (ir_is_elem_const(proc->module, elem, et)) {
|
|
@@ -4134,7 +4141,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|
Type *t = ir_type(field_expr);
|
|
Type *t = ir_type(field_expr);
|
|
GB_ASSERT(t->kind != Type_Tuple);
|
|
GB_ASSERT(t->kind != Type_Tuple);
|
|
irValue *ev = ir_emit_conv(proc, field_expr, et);
|
|
irValue *ev = ir_emit_conv(proc, field_expr, et);
|
|
- irValue *gep = ir_emit_array_epi(proc, vector_elem, i);
|
|
|
|
|
|
+ irValue *gep = ir_emit_array_epi(proc, v, i);
|
|
ir_emit_store(proc, gep, ev);
|
|
ir_emit_store(proc, gep, ev);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -4186,8 +4193,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|
}
|
|
}
|
|
Type *elem = bt->DynamicArray.elem;
|
|
Type *elem = bt->DynamicArray.elem;
|
|
gbAllocator a = proc->module->allocator;
|
|
gbAllocator a = proc->module->allocator;
|
|
- irValue *size = ir_make_const_int(a, type_size_of(proc->module->sizes, a, elem));
|
|
|
|
- irValue *align = ir_make_const_int(a, type_align_of(proc->module->sizes, a, elem));
|
|
|
|
|
|
+ irValue *size = ir_make_const_int(a, type_size_of(a, elem));
|
|
|
|
+ irValue *align = ir_make_const_int(a, type_align_of(a, elem));
|
|
{
|
|
{
|
|
irValue **args = gb_alloc_array(a, irValue *, 4);
|
|
irValue **args = gb_alloc_array(a, irValue *, 4);
|
|
args[0] = ir_emit_conv(proc, v, t_rawptr);
|
|
args[0] = ir_emit_conv(proc, v, t_rawptr);
|
|
@@ -5662,7 +5669,7 @@ void ir_module_add_value(irModule *m, Entity *e, irValue *v) {
|
|
map_ir_value_set(&m->values, hash_pointer(e), v);
|
|
map_ir_value_set(&m->values, hash_pointer(e), v);
|
|
}
|
|
}
|
|
|
|
|
|
-void ir_init_module(irModule *m, Checker *c, BuildContext *build_context) {
|
|
|
|
|
|
+void ir_init_module(irModule *m, Checker *c) {
|
|
// TODO(bill): Determine a decent size for the arena
|
|
// TODO(bill): Determine a decent size for the arena
|
|
isize token_count = c->parser->total_token_count;
|
|
isize token_count = c->parser->total_token_count;
|
|
isize arena_size = 4 * token_count * gb_size_of(irValue);
|
|
isize arena_size = 4 * token_count * gb_size_of(irValue);
|
|
@@ -5671,8 +5678,6 @@ void ir_init_module(irModule *m, Checker *c, BuildContext *build_context) {
|
|
m->allocator = gb_arena_allocator(&m->arena);
|
|
m->allocator = gb_arena_allocator(&m->arena);
|
|
m->tmp_allocator = gb_arena_allocator(&m->tmp_arena);
|
|
m->tmp_allocator = gb_arena_allocator(&m->tmp_arena);
|
|
m->info = &c->info;
|
|
m->info = &c->info;
|
|
- m->sizes = c->sizes;
|
|
|
|
- m->build_context = build_context;
|
|
|
|
|
|
|
|
map_ir_value_init(&m->values, heap_allocator());
|
|
map_ir_value_init(&m->values, heap_allocator());
|
|
map_ir_value_init(&m->members, heap_allocator());
|
|
map_ir_value_init(&m->members, heap_allocator());
|
|
@@ -5721,12 +5726,30 @@ void ir_init_module(irModule *m, Checker *c, BuildContext *build_context) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- String name = str_lit(IR_TYPE_INFO_DATA_MEMBER_NAME);
|
|
|
|
- Entity *e = make_entity_variable(m->allocator, NULL, make_token_ident(name),
|
|
|
|
- make_type_array(m->allocator, t_type_info_member, count), false);
|
|
|
|
- irValue *g = ir_make_value_global(m->allocator, e, NULL);
|
|
|
|
- ir_module_add_value(m, e, g);
|
|
|
|
- map_ir_value_set(&m->members, hash_string(name), g);
|
|
|
|
|
|
+ {
|
|
|
|
+ String name = str_lit(IR_TYPE_INFO_TYPES_NAME);
|
|
|
|
+ Entity *e = make_entity_variable(m->allocator, NULL, make_token_ident(name),
|
|
|
|
+ make_type_array(m->allocator, t_type_info_ptr, count), false);
|
|
|
|
+ irValue *g = ir_make_value_global(m->allocator, e, NULL);
|
|
|
|
+ ir_module_add_value(m, e, g);
|
|
|
|
+ map_ir_value_set(&m->members, hash_string(name), g);
|
|
|
|
+ }
|
|
|
|
+ {
|
|
|
|
+ String name = str_lit(IR_TYPE_INFO_NAMES_NAME);
|
|
|
|
+ Entity *e = make_entity_variable(m->allocator, NULL, make_token_ident(name),
|
|
|
|
+ make_type_array(m->allocator, t_string, count), false);
|
|
|
|
+ irValue *g = ir_make_value_global(m->allocator, e, NULL);
|
|
|
|
+ ir_module_add_value(m, e, g);
|
|
|
|
+ map_ir_value_set(&m->members, hash_string(name), g);
|
|
|
|
+ }
|
|
|
|
+ {
|
|
|
|
+ String name = str_lit(IR_TYPE_INFO_OFFSETS_NAME);
|
|
|
|
+ Entity *e = make_entity_variable(m->allocator, NULL, make_token_ident(name),
|
|
|
|
+ make_type_array(m->allocator, t_int, count), false);
|
|
|
|
+ irValue *g = ir_make_value_global(m->allocator, e, NULL);
|
|
|
|
+ ir_module_add_value(m, e, g);
|
|
|
|
+ map_ir_value_set(&m->members, hash_string(name), g);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -5759,7 +5782,7 @@ void ir_destroy_module(irModule *m) {
|
|
////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
-bool ir_gen_init(irGen *s, Checker *c, BuildContext *build_context) {
|
|
|
|
|
|
+bool ir_gen_init(irGen *s, Checker *c) {
|
|
if (global_error_collector.count != 0) {
|
|
if (global_error_collector.count != 0) {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -5769,7 +5792,7 @@ bool ir_gen_init(irGen *s, Checker *c, BuildContext *build_context) {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- ir_init_module(&s->module, c, build_context);
|
|
|
|
|
|
+ ir_init_module(&s->module, c);
|
|
s->module.generate_debug_info = false;
|
|
s->module.generate_debug_info = false;
|
|
|
|
|
|
// TODO(bill): generate appropriate output name
|
|
// TODO(bill): generate appropriate output name
|
|
@@ -5865,6 +5888,17 @@ void ir_add_foreign_library_path(irModule *m, Entity *e) {
|
|
array_add(&m->foreign_library_paths, library_path);
|
|
array_add(&m->foreign_library_paths, library_path);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void ir_fill_slice(irProcedure *proc, irValue *slice_ptr, irValue *data, irValue *count) {
|
|
|
|
+ Type *t = ir_type(slice_ptr);
|
|
|
|
+ GB_ASSERT(is_type_pointer(t));
|
|
|
|
+ t = type_deref(t);
|
|
|
|
+ GB_ASSERT(is_type_slice(t));
|
|
|
|
+ irValue *elem = ir_emit_struct_ep(proc, slice_ptr, 0);
|
|
|
|
+ irValue *len = ir_emit_struct_ep(proc, slice_ptr, 1);
|
|
|
|
+ ir_emit_store(proc, elem, data);
|
|
|
|
+ ir_emit_store(proc, len, count);
|
|
|
|
+}
|
|
|
|
+
|
|
void ir_gen_tree(irGen *s) {
|
|
void ir_gen_tree(irGen *s) {
|
|
irModule *m = &s->module;
|
|
irModule *m = &s->module;
|
|
CheckerInfo *info = m->info;
|
|
CheckerInfo *info = m->info;
|
|
@@ -5937,6 +5971,7 @@ void ir_gen_tree(irGen *s) {
|
|
if (!scope->is_global) {
|
|
if (!scope->is_global) {
|
|
if (e->kind == Entity_Procedure && (e->Procedure.tags & ProcTag_export) != 0) {
|
|
if (e->kind == Entity_Procedure && (e->Procedure.tags & ProcTag_export) != 0) {
|
|
} else if (e->kind == Entity_Procedure && e->Procedure.link_name.len > 0) {
|
|
} else if (e->kind == Entity_Procedure && e->Procedure.link_name.len > 0) {
|
|
|
|
+ // Handle later
|
|
} else if (scope->is_init && e->kind == Entity_Procedure && str_eq(name, str_lit("main"))) {
|
|
} else if (scope->is_init && e->kind == Entity_Procedure && str_eq(name, str_lit("main"))) {
|
|
} else {
|
|
} else {
|
|
name = ir_mangle_name(s, e->token.pos.file, e);
|
|
name = ir_mangle_name(s, e->token.pos.file, e);
|
|
@@ -6042,7 +6077,7 @@ void ir_gen_tree(irGen *s) {
|
|
}
|
|
}
|
|
|
|
|
|
#if defined(GB_SYSTEM_WINDOWS)
|
|
#if defined(GB_SYSTEM_WINDOWS)
|
|
- if (m->build_context->is_dll && !has_dll_main) {
|
|
|
|
|
|
+ if (build_context.is_dll && !has_dll_main) {
|
|
// DllMain :: proc(inst: rawptr, reason: u32, reserved: rawptr) -> i32
|
|
// DllMain :: proc(inst: rawptr, reason: u32, reserved: rawptr) -> i32
|
|
String name = str_lit("DllMain");
|
|
String name = str_lit("DllMain");
|
|
Type *proc_params = make_type_tuple(a);
|
|
Type *proc_params = make_type_tuple(a);
|
|
@@ -6193,17 +6228,16 @@ void ir_gen_tree(irGen *s) {
|
|
|
|
|
|
{ // NOTE(bill): Setup type_info data
|
|
{ // NOTE(bill): Setup type_info data
|
|
// TODO(bill): Try and make a lot of this constant aggregate literals in LLVM IR
|
|
// TODO(bill): Try and make a lot of this constant aggregate literals in LLVM IR
|
|
- irValue *type_info_data = NULL;
|
|
|
|
- irValue *type_info_member_data = NULL;
|
|
|
|
|
|
+ irValue *type_info_data = NULL;
|
|
|
|
+ irValue *type_info_member_types = NULL;
|
|
|
|
+ irValue *type_info_member_names = NULL;
|
|
|
|
+ irValue *type_info_member_offsets = NULL;
|
|
|
|
|
|
irValue **found = NULL;
|
|
irValue **found = NULL;
|
|
- found = map_ir_value_get(&proc->module->members, hash_string(str_lit(IR_TYPE_INFO_DATA_NAME)));
|
|
|
|
- GB_ASSERT(found != NULL);
|
|
|
|
- type_info_data = *found;
|
|
|
|
-
|
|
|
|
- found = map_ir_value_get(&proc->module->members, hash_string(str_lit(IR_TYPE_INFO_DATA_MEMBER_NAME)));
|
|
|
|
- GB_ASSERT(found != NULL);
|
|
|
|
- type_info_member_data = *found;
|
|
|
|
|
|
+ type_info_data = *map_ir_value_get(&proc->module->members, hash_string(str_lit(IR_TYPE_INFO_DATA_NAME)));
|
|
|
|
+ type_info_member_types = *map_ir_value_get(&proc->module->members, hash_string(str_lit(IR_TYPE_INFO_TYPES_NAME)));
|
|
|
|
+ type_info_member_names = *map_ir_value_get(&proc->module->members, hash_string(str_lit(IR_TYPE_INFO_NAMES_NAME)));
|
|
|
|
+ type_info_member_offsets = *map_ir_value_get(&proc->module->members, hash_string(str_lit(IR_TYPE_INFO_OFFSETS_NAME)));
|
|
|
|
|
|
CheckerInfo *info = proc->module->info;
|
|
CheckerInfo *info = proc->module->info;
|
|
|
|
|
|
@@ -6223,7 +6257,9 @@ void ir_gen_tree(irGen *s) {
|
|
Type *t_i64_slice_ptr = make_type_pointer(a, make_type_slice(a, t_i64));
|
|
Type *t_i64_slice_ptr = make_type_pointer(a, make_type_slice(a, t_i64));
|
|
Type *t_string_slice_ptr = make_type_pointer(a, make_type_slice(a, t_string));
|
|
Type *t_string_slice_ptr = make_type_pointer(a, make_type_slice(a, t_string));
|
|
|
|
|
|
- i32 type_info_member_index = 0;
|
|
|
|
|
|
+ i32 type_info_member_types_index = 0;
|
|
|
|
+ i32 type_info_member_names_index = 0;
|
|
|
|
+ i32 type_info_member_offsets_index = 0;
|
|
|
|
|
|
for_array(type_info_map_index, info->type_info_map.entries) {
|
|
for_array(type_info_map_index, info->type_info_map.entries) {
|
|
MapIsizeEntry *entry = &info->type_info_map.entries.e[type_info_map_index];
|
|
MapIsizeEntry *entry = &info->type_info_map.entries.e[type_info_map_index];
|
|
@@ -6234,8 +6270,10 @@ void ir_gen_tree(irGen *s) {
|
|
irValue *tag = NULL;
|
|
irValue *tag = NULL;
|
|
irValue *ti_ptr = ir_emit_array_epi(proc, type_info_data, entry_index);
|
|
irValue *ti_ptr = ir_emit_array_epi(proc, type_info_data, entry_index);
|
|
|
|
|
|
|
|
+
|
|
switch (t->kind) {
|
|
switch (t->kind) {
|
|
case Type_Named: {
|
|
case Type_Named: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Named"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_named_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_named_ptr);
|
|
|
|
|
|
// TODO(bill): Which is better? The mangled name or actual name?
|
|
// TODO(bill): Which is better? The mangled name or actual name?
|
|
@@ -6247,6 +6285,7 @@ void ir_gen_tree(irGen *s) {
|
|
} break;
|
|
} break;
|
|
|
|
|
|
case Type_Basic:
|
|
case Type_Basic:
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Basic"));
|
|
switch (t->Basic.kind) {
|
|
switch (t->Basic.kind) {
|
|
case Basic_bool:
|
|
case Basic_bool:
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_boolean_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_boolean_ptr);
|
|
@@ -6265,7 +6304,7 @@ void ir_gen_tree(irGen *s) {
|
|
case Basic_uint: {
|
|
case Basic_uint: {
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_integer_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_integer_ptr);
|
|
bool is_unsigned = (t->Basic.flags & BasicFlag_Unsigned) != 0;
|
|
bool is_unsigned = (t->Basic.flags & BasicFlag_Unsigned) != 0;
|
|
- irValue *bits = ir_make_const_int(a, type_size_of(m->sizes, a, t));
|
|
|
|
|
|
+ irValue *bits = ir_make_const_int(a, type_size_of(a, t));
|
|
irValue *is_signed = ir_make_const_bool(a, !is_unsigned);
|
|
irValue *is_signed = ir_make_const_bool(a, !is_unsigned);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), bits);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), bits);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), is_signed);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), is_signed);
|
|
@@ -6277,7 +6316,7 @@ void ir_gen_tree(irGen *s) {
|
|
// case Basic_f128:
|
|
// case Basic_f128:
|
|
{
|
|
{
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_float_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_float_ptr);
|
|
- irValue *bits = ir_make_const_int(a, type_size_of(m->sizes, a, t));
|
|
|
|
|
|
+ irValue *bits = ir_make_const_int(a, type_size_of(a, t));
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), bits);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), bits);
|
|
} break;
|
|
} break;
|
|
|
|
|
|
@@ -6296,16 +6335,18 @@ void ir_gen_tree(irGen *s) {
|
|
break;
|
|
break;
|
|
|
|
|
|
case Type_Pointer: {
|
|
case Type_Pointer: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Pointer"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_pointer_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_pointer_ptr);
|
|
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Pointer.elem);
|
|
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Pointer.elem);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
|
} break;
|
|
} break;
|
|
case Type_Array: {
|
|
case Type_Array: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Array"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_array_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_array_ptr);
|
|
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Array.elem);
|
|
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Array.elem);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
|
|
|
|
|
- isize ez = type_size_of(m->sizes, a, t->Array.elem);
|
|
|
|
|
|
+ isize ez = type_size_of(a, t->Array.elem);
|
|
irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
|
|
irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
|
|
ir_emit_store(proc, elem_size, ir_make_const_int(a, ez));
|
|
ir_emit_store(proc, elem_size, ir_make_const_int(a, ez));
|
|
|
|
|
|
@@ -6314,55 +6355,110 @@ void ir_gen_tree(irGen *s) {
|
|
|
|
|
|
} break;
|
|
} break;
|
|
case Type_DynamicArray: {
|
|
case Type_DynamicArray: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_DynamicArray"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_dynamic_array_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_dynamic_array_ptr);
|
|
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->DynamicArray.elem);
|
|
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->DynamicArray.elem);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
|
|
|
|
|
- isize ez = type_size_of(m->sizes, a, t->DynamicArray.elem);
|
|
|
|
|
|
+ isize ez = type_size_of(a, t->DynamicArray.elem);
|
|
irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
|
|
irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
|
|
ir_emit_store(proc, elem_size, ir_make_const_int(a, ez));
|
|
ir_emit_store(proc, elem_size, ir_make_const_int(a, ez));
|
|
} break;
|
|
} break;
|
|
case Type_Slice: {
|
|
case Type_Slice: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Slice"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_slice_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_slice_ptr);
|
|
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Slice.elem);
|
|
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Slice.elem);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
|
|
|
|
|
- isize ez = type_size_of(m->sizes, a, t->Slice.elem);
|
|
|
|
|
|
+ isize ez = type_size_of(a, t->Slice.elem);
|
|
irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
|
|
irValue *elem_size = ir_emit_struct_ep(proc, tag, 1);
|
|
ir_emit_store(proc, elem_size, ir_make_const_int(a, ez));
|
|
ir_emit_store(proc, elem_size, ir_make_const_int(a, ez));
|
|
} break;
|
|
} break;
|
|
case Type_Vector: {
|
|
case Type_Vector: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Vector"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_vector_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_vector_ptr);
|
|
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Vector.elem);
|
|
irValue *gep = ir_get_type_info_ptr(proc, type_info_data, t->Vector.elem);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), gep);
|
|
|
|
|
|
- isize ez = type_size_of(m->sizes, a, t->Vector.elem);
|
|
|
|
|
|
+ isize ez = type_size_of(a, t->Vector.elem);
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), ir_make_const_int(a, ez));
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), ir_make_const_int(a, ez));
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), ir_make_const_int(a, t->Vector.count));
|
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), ir_make_const_int(a, t->Vector.count));
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), ir_make_const_int(a, type_align_of(m->sizes, a, t)));
|
|
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), ir_make_const_int(a, type_align_of(a, t)));
|
|
|
|
+
|
|
|
|
+ } break;
|
|
|
|
+ case Type_Proc: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Proc"));
|
|
|
|
+ tag = ir_emit_conv(proc, ti_ptr, t_type_info_procedure_ptr);
|
|
|
|
+
|
|
|
|
+ irValue *params = ir_emit_struct_ep(proc, tag, 0);
|
|
|
|
+ irValue *results = ir_emit_struct_ep(proc, tag, 1);
|
|
|
|
+ irValue *variadic = ir_emit_struct_ep(proc, tag, 2);
|
|
|
|
+ irValue *convention = ir_emit_struct_ep(proc, tag, 3);
|
|
|
|
+
|
|
|
|
+ if (t->Proc.params) {
|
|
|
|
+ ir_emit_store(proc, params, ir_get_type_info_ptr(proc, type_info_data, t->Proc.params));
|
|
|
|
+ }
|
|
|
|
+ if (t->Proc.results) {
|
|
|
|
+ ir_emit_store(proc, results, ir_get_type_info_ptr(proc, type_info_data, t->Proc.results));
|
|
|
|
+ }
|
|
|
|
+ ir_emit_store(proc, variadic, ir_make_const_bool(a, t->Proc.variadic));
|
|
|
|
+ ir_emit_store(proc, convention, ir_make_const_int(a, t->Proc.calling_convention));
|
|
|
|
+
|
|
|
|
+ // TODO(bill): Type_Info for procedures
|
|
|
|
+ } break;
|
|
|
|
+ case Type_Tuple: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Tuple"));
|
|
|
|
+ tag = ir_emit_conv(proc, ti_ptr, t_type_info_tuple_ptr);
|
|
|
|
+
|
|
|
|
+ {
|
|
|
|
+ irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), align);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ irValue *memory_types = ir_type_info_member_offset(proc, type_info_member_types, t->Record.field_count, &type_info_member_types_index);
|
|
|
|
+ irValue *memory_names = ir_type_info_member_offset(proc, type_info_member_names, t->Record.field_count, &type_info_member_names_index);
|
|
|
|
+
|
|
|
|
+ for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
|
|
|
+ // NOTE(bill): offset is not used for tuples
|
|
|
|
+ Entity *f = t->Tuple.variables[i];
|
|
|
|
+
|
|
|
|
+ irValue *index = ir_make_const_int(a, i);
|
|
|
|
+ irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
|
|
|
|
|
|
|
|
+ ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
|
|
|
|
+ if (f->token.string.len > 0) {
|
|
|
|
+ irValue *name = ir_emit_ptr_offset(proc, memory_names, index);
|
|
|
|
+ ir_emit_store(proc, name, ir_make_const_string(a, f->token.string));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, ir_make_const_int(a, t->Record.field_count));
|
|
} break;
|
|
} break;
|
|
case Type_Record: {
|
|
case Type_Record: {
|
|
switch (t->Record.kind) {
|
|
switch (t->Record.kind) {
|
|
case TypeRecord_Struct: {
|
|
case TypeRecord_Struct: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Struct"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_struct_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_struct_ptr);
|
|
|
|
|
|
{
|
|
{
|
|
- irValue *size = ir_make_const_int(a, type_size_of(m->sizes, a, t));
|
|
|
|
- irValue *align = ir_make_const_int(a, type_align_of(m->sizes, a, t));
|
|
|
|
|
|
+ irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
|
|
|
+ irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
|
irValue *packed = ir_make_const_bool(a, t->Record.struct_is_packed);
|
|
irValue *packed = ir_make_const_bool(a, t->Record.struct_is_packed);
|
|
irValue *ordered = ir_make_const_bool(a, t->Record.struct_is_ordered);
|
|
irValue *ordered = ir_make_const_bool(a, t->Record.struct_is_ordered);
|
|
irValue *custom_align = ir_make_const_bool(a, t->Record.custom_align);
|
|
irValue *custom_align = ir_make_const_bool(a, t->Record.custom_align);
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), size);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), align);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), packed);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), ordered);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 5), custom_align);
|
|
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), size);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), align);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 5), packed);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 6), ordered);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 7), custom_align);
|
|
}
|
|
}
|
|
|
|
|
|
- irValue *memory = ir_type_info_member_offset(proc, type_info_member_data, t->Record.field_count, &type_info_member_index);
|
|
|
|
|
|
+ irValue *memory_types = ir_type_info_member_offset(proc, type_info_member_types, t->Record.field_count, &type_info_member_types_index);
|
|
|
|
+ irValue *memory_names = ir_type_info_member_offset(proc, type_info_member_names, t->Record.field_count, &type_info_member_names_index);
|
|
|
|
+ irValue *memory_offsets = ir_type_info_member_offset(proc, type_info_member_offsets, t->Record.field_count, &type_info_member_offsets_index);
|
|
|
|
|
|
- type_set_offsets(m->sizes, a, t); // NOTE(bill): Just incase the offsets have not been set yet
|
|
|
|
|
|
+ type_set_offsets(a, t); // NOTE(bill): Just incase the offsets have not been set yet
|
|
for (isize source_index = 0; source_index < t->Record.field_count; source_index++) {
|
|
for (isize source_index = 0; source_index < t->Record.field_count; source_index++) {
|
|
// TODO(bill): Order fields in source order not layout order
|
|
// TODO(bill): Order fields in source order not layout order
|
|
Entity *f = t->Record.fields_in_src_order[source_index];
|
|
Entity *f = t->Record.fields_in_src_order[source_index];
|
|
@@ -6370,77 +6466,65 @@ void ir_gen_tree(irGen *s) {
|
|
i64 foffset = t->Record.struct_offsets[f->Variable.field_index];
|
|
i64 foffset = t->Record.struct_offsets[f->Variable.field_index];
|
|
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
|
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
|
|
|
|
|
- irValue *field = ir_emit_ptr_offset(proc, memory, ir_make_const_int(a, source_index));
|
|
|
|
- irValue *name = ir_emit_struct_ep(proc, field, 0);
|
|
|
|
- irValue *type_info = ir_emit_struct_ep(proc, field, 1);
|
|
|
|
- irValue *offset = ir_emit_struct_ep(proc, field, 2);
|
|
|
|
|
|
+ irValue *index = ir_make_const_int(a, source_index);
|
|
|
|
+ irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
|
|
|
|
+ irValue *offset = ir_emit_ptr_offset(proc, memory_offsets, index);
|
|
|
|
|
|
|
|
+ ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
|
|
if (f->token.string.len > 0) {
|
|
if (f->token.string.len > 0) {
|
|
|
|
+ irValue *name = ir_emit_ptr_offset(proc, memory_names, index);
|
|
ir_emit_store(proc, name, ir_make_const_string(a, f->token.string));
|
|
ir_emit_store(proc, name, ir_make_const_string(a, f->token.string));
|
|
}
|
|
}
|
|
- ir_emit_store(proc, type_info, tip);
|
|
|
|
ir_emit_store(proc, offset, ir_make_const_int(a, foffset));
|
|
ir_emit_store(proc, offset, ir_make_const_int(a, foffset));
|
|
}
|
|
}
|
|
|
|
|
|
- Type *slice_type = make_type_slice(a, t_type_info_member);
|
|
|
|
- Type *slice_type_ptr = make_type_pointer(a, slice_type);
|
|
|
|
- irValue *slice = ir_emit_struct_ep(proc, tag, 0);
|
|
|
|
- irValue *field_count = ir_make_const_int(a, t->Record.field_count);
|
|
|
|
-
|
|
|
|
- irValue *elem = ir_emit_struct_ep(proc, slice, 0);
|
|
|
|
- irValue *len = ir_emit_struct_ep(proc, slice, 1);
|
|
|
|
-
|
|
|
|
- ir_emit_store(proc, elem, memory);
|
|
|
|
- ir_emit_store(proc, len, field_count);
|
|
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, ir_make_const_int(a, t->Record.field_count));
|
|
} break;
|
|
} break;
|
|
case TypeRecord_Union:
|
|
case TypeRecord_Union:
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Union"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_union_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_union_ptr);
|
|
{
|
|
{
|
|
- irValue *size = ir_make_const_int(a, type_size_of(m->sizes, a, t));
|
|
|
|
- irValue *align = ir_make_const_int(a, type_align_of(m->sizes, a, t));
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), size);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), align);
|
|
|
|
|
|
+ irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
|
|
|
+ irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), size);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), align);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case TypeRecord_RawUnion: {
|
|
case TypeRecord_RawUnion: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_RawUnion"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_raw_union_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_raw_union_ptr);
|
|
{
|
|
{
|
|
- irValue *size = ir_make_const_int(a, type_size_of(m->sizes, a, t));
|
|
|
|
- irValue *align = ir_make_const_int(a, type_align_of(m->sizes, a, t));
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 1), size);
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), align);
|
|
|
|
|
|
+ irValue *size = ir_make_const_int(a, type_size_of(a, t));
|
|
|
|
+ irValue *align = ir_make_const_int(a, type_align_of(a, t));
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), size);
|
|
|
|
+ ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 4), align);
|
|
}
|
|
}
|
|
|
|
|
|
- irValue *memory = ir_type_info_member_offset(proc, type_info_member_data, t->Record.field_count, &type_info_member_index);
|
|
|
|
|
|
+ irValue *memory_types = ir_type_info_member_offset(proc, type_info_member_types, t->Record.field_count, &type_info_member_types_index);
|
|
|
|
+ irValue *memory_names = ir_type_info_member_offset(proc, type_info_member_names, t->Record.field_count, &type_info_member_names_index);
|
|
|
|
+ irValue *memory_offsets = ir_type_info_member_offset(proc, type_info_member_offsets, t->Record.field_count, &type_info_member_offsets_index);
|
|
|
|
|
|
for (isize i = 0; i < t->Record.field_count; i++) {
|
|
for (isize i = 0; i < t->Record.field_count; i++) {
|
|
- irValue *field = ir_emit_ptr_offset(proc, memory, ir_make_const_int(a, i));
|
|
|
|
- irValue *name = ir_emit_struct_ep(proc, field, 0);
|
|
|
|
- irValue *type_info = ir_emit_struct_ep(proc, field, 1);
|
|
|
|
- irValue *offset = ir_emit_struct_ep(proc, field, 2);
|
|
|
|
-
|
|
|
|
Entity *f = t->Record.fields[i];
|
|
Entity *f = t->Record.fields[i];
|
|
- irValue *tip = ir_get_type_info_ptr(proc, type_info_data, f->type);
|
|
|
|
|
|
+ irValue *index = ir_make_const_int(a, i);
|
|
|
|
+ irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
|
|
|
|
+ // NOTE(bill): Offsets are always 0
|
|
|
|
|
|
|
|
+ ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
|
|
if (f->token.string.len > 0) {
|
|
if (f->token.string.len > 0) {
|
|
|
|
+ irValue *name = ir_emit_ptr_offset(proc, memory_names, index);
|
|
ir_emit_store(proc, name, ir_make_const_string(a, f->token.string));
|
|
ir_emit_store(proc, name, ir_make_const_string(a, f->token.string));
|
|
}
|
|
}
|
|
- ir_emit_store(proc, type_info, tip);
|
|
|
|
- ir_emit_store(proc, offset, ir_make_const_int(a, 0));
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- Type *slice_type = make_type_slice(a, t_type_info_member);
|
|
|
|
- Type *slice_type_ptr = make_type_pointer(a, slice_type);
|
|
|
|
- irValue *slice = ir_emit_struct_ep(proc, tag, 0);
|
|
|
|
- irValue *field_count = ir_make_const_int(a, t->Record.field_count);
|
|
|
|
-
|
|
|
|
- irValue *elem = ir_emit_struct_ep(proc, slice, 0);
|
|
|
|
- irValue *len = ir_emit_struct_ep(proc, slice, 1);
|
|
|
|
-
|
|
|
|
- ir_emit_store(proc, elem, memory);
|
|
|
|
- ir_emit_store(proc, len, field_count);
|
|
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 0), memory_types, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 1), memory_names, ir_make_const_int(a, t->Record.field_count));
|
|
|
|
+ ir_fill_slice(proc, ir_emit_struct_ep(proc, tag, 2), memory_offsets, ir_make_const_int(a, t->Record.field_count));
|
|
} break;
|
|
} break;
|
|
case TypeRecord_Enum:
|
|
case TypeRecord_Enum:
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Enum"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_enum_ptr);
|
|
{
|
|
{
|
|
GB_ASSERT(t->Record.enum_base_type != NULL);
|
|
GB_ASSERT(t->Record.enum_base_type != NULL);
|
|
@@ -6495,65 +6579,8 @@ void ir_gen_tree(irGen *s) {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
} break;
|
|
} break;
|
|
-
|
|
|
|
- case Type_Tuple: {
|
|
|
|
- tag = ir_emit_conv(proc, ti_ptr, t_type_info_tuple_ptr);
|
|
|
|
-
|
|
|
|
- {
|
|
|
|
- irValue *align = ir_make_const_int(a, type_align_of(m->sizes, a, t));
|
|
|
|
- ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 2), align);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- irValue *memory = ir_type_info_member_offset(proc, type_info_member_data, t->Tuple.variable_count, &type_info_member_index);
|
|
|
|
-
|
|
|
|
- for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
|
|
|
- irValue *field = ir_emit_ptr_offset(proc, memory, ir_make_const_int(a, i));
|
|
|
|
- irValue *name = ir_emit_struct_ep(proc, field, 0);
|
|
|
|
- irValue *type_info = ir_emit_struct_ep(proc, field, 1);
|
|
|
|
- // NOTE(bill): offset is not used for tuples
|
|
|
|
-
|
|
|
|
- Entity *f = t->Tuple.variables[i];
|
|
|
|
- irValue *tip = ir_get_type_info_ptr(proc, type_info_data, f->type);
|
|
|
|
-
|
|
|
|
- if (f->token.string.len > 0) {
|
|
|
|
- ir_emit_store(proc, name, ir_make_const_string(a, f->token.string));
|
|
|
|
- }
|
|
|
|
- ir_emit_store(proc, type_info, tip);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- Type *slice_type = make_type_slice(a, t_type_info_member);
|
|
|
|
- Type *slice_type_ptr = make_type_pointer(a, slice_type);
|
|
|
|
- irValue *slice = ir_emit_struct_ep(proc, tag, 0);
|
|
|
|
- irValue *variable_count = ir_make_const_int(a, t->Tuple.variable_count);
|
|
|
|
-
|
|
|
|
- irValue *elem = ir_emit_struct_ep(proc, slice, 0);
|
|
|
|
- irValue *len = ir_emit_struct_ep(proc, slice, 1);
|
|
|
|
-
|
|
|
|
- ir_emit_store(proc, elem, memory);
|
|
|
|
- ir_emit_store(proc, len, variable_count);
|
|
|
|
- } break;
|
|
|
|
-
|
|
|
|
- case Type_Proc: {
|
|
|
|
- tag = ir_emit_conv(proc, ti_ptr, t_type_info_procedure_ptr);
|
|
|
|
-
|
|
|
|
- irValue *params = ir_emit_struct_ep(proc, tag, 0);
|
|
|
|
- irValue *results = ir_emit_struct_ep(proc, tag, 1);
|
|
|
|
- irValue *variadic = ir_emit_struct_ep(proc, tag, 2);
|
|
|
|
- irValue *convention = ir_emit_struct_ep(proc, tag, 3);
|
|
|
|
-
|
|
|
|
- if (t->Proc.params) {
|
|
|
|
- ir_emit_store(proc, params, ir_get_type_info_ptr(proc, type_info_data, t->Proc.params));
|
|
|
|
- }
|
|
|
|
- if (t->Proc.results) {
|
|
|
|
- ir_emit_store(proc, results, ir_get_type_info_ptr(proc, type_info_data, t->Proc.results));
|
|
|
|
- }
|
|
|
|
- ir_emit_store(proc, variadic, ir_make_const_bool(a, t->Proc.variadic));
|
|
|
|
- ir_emit_store(proc, convention, ir_make_const_int(a, t->Proc.calling_convention));
|
|
|
|
-
|
|
|
|
- // TODO(bill): Type_Info for procedures
|
|
|
|
- } break;
|
|
|
|
-
|
|
|
|
case Type_Map: {
|
|
case Type_Map: {
|
|
|
|
+ ir_emit_comment(proc, str_lit("Type_Info_Map"));
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_map_ptr);
|
|
tag = ir_emit_conv(proc, ti_ptr, t_type_info_map_ptr);
|
|
|
|
|
|
irValue *key = ir_emit_struct_ep(proc, tag, 0);
|
|
irValue *key = ir_emit_struct_ep(proc, tag, 0);
|
|
@@ -6568,6 +6595,7 @@ void ir_gen_tree(irGen *s) {
|
|
} break;
|
|
} break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
if (tag != NULL) {
|
|
if (tag != NULL) {
|
|
Type *tag_type = type_deref(ir_type(tag));
|
|
Type *tag_type = type_deref(ir_type(tag));
|
|
Type *ti = base_type(t_type_info);
|
|
Type *ti = base_type(t_type_info);
|
|
@@ -6576,8 +6604,9 @@ void ir_gen_tree(irGen *s) {
|
|
Entity *f = ti->Record.fields[i];
|
|
Entity *f = ti->Record.fields[i];
|
|
if (are_types_identical(f->type, tag_type)) {
|
|
if (are_types_identical(f->type, tag_type)) {
|
|
found = true;
|
|
found = true;
|
|
- irValue *tag = ir_make_const_int(proc->module->allocator, i);
|
|
|
|
- ir_emit_store(proc, ir_emit_union_tag_ptr(proc, ti_ptr), tag);
|
|
|
|
|
|
+ irValue *tag = ir_make_const_int(a, i);
|
|
|
|
+ irValue *ptr = ir_emit_union_tag_ptr(proc, ti_ptr);
|
|
|
|
+ ir_emit_store(proc, ptr, tag);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|