Fix empty union IR bug

This commit is contained in:
gingerBill
2018-01-19 17:11:28 +00:00
parent b03ce0e9b4
commit 2fe660a1d7
3 changed files with 212 additions and 200 deletions
+5 -2
View File
@@ -8076,8 +8076,11 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
i64 tag_size = union_tag_size(a, t); i64 tag_size = union_tag_size(a, t);
i64 tag_offset = align_formula(t->Union.variant_block_size, tag_size); i64 tag_offset = align_formula(t->Union.variant_block_size, tag_size);
ir_emit_store(proc, tag_offset_ptr, ir_const_uintptr(a, tag_offset));
ir_emit_store(proc, tag_type_ptr, ir_type_info(proc, union_tag_type(a, t))); if (tag_size > 0) {
ir_emit_store(proc, tag_offset_ptr, ir_const_uintptr(a, tag_offset));
ir_emit_store(proc, tag_type_ptr, ir_type_info(proc, union_tag_type(a, t)));
}
} }
break; break;
+189 -184
View File
@@ -2,6 +2,7 @@ struct irFileBuffer {
gbVirtualMemory vm; gbVirtualMemory vm;
isize offset; isize offset;
gbFile * output; gbFile * output;
char buf[4096];
}; };
void ir_file_buffer_init(irFileBuffer *f, gbFile *output) { void ir_file_buffer_init(irFileBuffer *f, gbFile *output) {
@@ -39,24 +40,27 @@ void ir_file_buffer_write(irFileBuffer *f, void const *data, isize len) {
void ir_fprintf(irFileBuffer *f, char *fmt, ...) { void ir_fprintf(irFileBuffer *f, char *fmt, ...) {
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
char buf[4096] = {}; isize len = gb_snprintf_va(f->buf, gb_size_of(f->buf)-1, fmt, va);
isize len = gb_snprintf_va(buf, gb_size_of(buf), fmt, va); ir_file_buffer_write(f, f->buf, len-1);
ir_file_buffer_write(f, buf, len-1);
va_end(va); va_end(va);
} }
void ir_write_string(irFileBuffer *f, String s) { void ir_write_string(irFileBuffer *f, String s) {
ir_file_buffer_write(f, s.text, s.len); ir_file_buffer_write(f, s.text, s.len);
} }
void ir_write_string(irFileBuffer *f, char const *s) {
#if 0
#define ir_write_str_lit(f, s) ir_write_string((f), str_lit(s))
#else
void ir_write_str_lit(irFileBuffer *f, char const *s) {
isize len = gb_strlen(s); isize len = gb_strlen(s);
ir_file_buffer_write(f, s, len); ir_file_buffer_write(f, s, len);
} }
#endif
void ir_write_byte(irFileBuffer *f, u8 c) { void ir_write_byte(irFileBuffer *f, u8 c) {
ir_file_buffer_write(f, &c, 1); ir_file_buffer_write(f, &c, 1);
} }
void ir_write_i64(irFileBuffer *f, i64 i) { void ir_write_i64(irFileBuffer *f, i64 i) {
char buf[200] = {}; String str = i64_to_string(i, f->buf, gb_size_of(f->buf)-1);
String str = i64_to_string(i, buf, gb_size_of(buf)-1);
ir_write_string(f, str); ir_write_string(f, str);
} }
@@ -296,38 +300,39 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) {
switch (t->kind) { switch (t->kind) {
case Type_Basic: case Type_Basic:
switch (t->Basic.kind) { switch (t->Basic.kind) {
case Basic_llvm_bool: ir_write_string(f, "i1"); return; case Basic_llvm_bool: ir_write_str_lit(f, "i1"); return;
case Basic_bool: ir_write_string(f, "i8"); return; case Basic_bool: ir_write_str_lit(f, "i8"); return;
case Basic_b8: ir_write_string(f, "i8"); return; case Basic_b8: ir_write_str_lit(f, "i8"); return;
case Basic_b16: ir_write_string(f, "i16"); return; case Basic_b16: ir_write_str_lit(f, "i16"); return;
case Basic_b32: ir_write_string(f, "i32"); return; case Basic_b32: ir_write_str_lit(f, "i32"); return;
case Basic_b64: ir_write_string(f, "i64"); return; case Basic_b64: ir_write_str_lit(f, "i64"); return;
case Basic_i8: ir_write_string(f, "i8"); return; case Basic_i8: ir_write_str_lit(f, "i8"); return;
case Basic_u8: ir_write_string(f, "i8"); return; case Basic_u8: ir_write_str_lit(f, "i8"); return;
case Basic_i16: ir_write_string(f, "i16"); return; case Basic_i16: ir_write_str_lit(f, "i16"); return;
case Basic_u16: ir_write_string(f, "i16"); return; case Basic_u16: ir_write_str_lit(f, "i16"); return;
case Basic_i32: ir_write_string(f, "i32"); return; case Basic_i32: ir_write_str_lit(f, "i32"); return;
case Basic_u32: ir_write_string(f, "i32"); return; case Basic_u32: ir_write_str_lit(f, "i32"); return;
case Basic_i64: ir_write_string(f, "i64"); return; case Basic_i64: ir_write_str_lit(f, "i64"); return;
case Basic_u64: ir_write_string(f, "i64"); return; case Basic_u64: ir_write_str_lit(f, "i64"); return;
case Basic_rune: ir_write_string(f, "i32"); return; case Basic_rune: ir_write_str_lit(f, "i32"); return;
// case Basic_f16: ir_write_string(f, "half"); return; // case Basic_f16: ir_write_str_lit(f, "half"); return;
case Basic_f32: ir_write_string(f, "float"); return; case Basic_f32: ir_write_str_lit(f, "float"); return;
case Basic_f64: ir_write_string(f, "double"); return; case Basic_f64: ir_write_str_lit(f, "double"); return;
// case Basic_complex32: ir_write_string(f, "%%..complex32"); return; // case Basic_complex32: ir_write_str_lit(f, "%%..complex32"); return;
case Basic_complex64: ir_write_string(f, "%..complex64"); return; case Basic_complex64: ir_write_str_lit(f, "%..complex64"); return;
case Basic_complex128: ir_write_string(f, "%..complex128"); return; case Basic_complex128: ir_write_str_lit(f, "%..complex128"); return;
case Basic_rawptr: ir_write_str_lit(f, "%..rawptr"); return;
case Basic_string: ir_write_str_lit(f, "%..string"); return;
case Basic_rawptr: ir_write_string(f, "%..rawptr"); return;
case Basic_string: ir_write_string(f, "%..string"); return;
case Basic_uint: ir_fprintf(f, "i%lld", word_bits); return; case Basic_uint: ir_fprintf(f, "i%lld", word_bits); return;
case Basic_int: ir_fprintf(f, "i%lld", word_bits); return; case Basic_int: ir_fprintf(f, "i%lld", word_bits); return;
case Basic_uintptr: ir_fprintf(f, "i%lld", word_bits); return; case Basic_uintptr: ir_fprintf(f, "i%lld", word_bits); return;
case Basic_any: ir_write_string(f, "%..any"); return; case Basic_any: ir_write_str_lit(f, "%..any"); return;
} }
break; break;
case Type_Pointer: { case Type_Pointer: {
@@ -504,7 +509,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
ir_write_byte(f, '['); ir_write_byte(f, '[');
for (i64 i = 0; i < count; i++) { for (i64 i = 0; i < count; i++) {
if (i > 0) ir_write_string(f, ", "); if (i > 0) ir_write_str_lit(f, ", ");
ir_print_type(f, m, elem); ir_print_type(f, m, elem);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_exact_value(f, m, value, elem); ir_print_exact_value(f, m, value, elem);
@@ -518,35 +523,35 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
switch (value.kind) { switch (value.kind) {
case ExactValue_Bool: case ExactValue_Bool:
if (value.value_bool) { if (value.value_bool) {
ir_write_string(f, type == t_llvm_bool ? "true" : "1"); ir_write_string(f, type == t_llvm_bool ? str_lit("true") : str_lit("1"));
} else { } else {
ir_write_string(f, type == t_llvm_bool ? "false" : "0"); ir_write_string(f, type == t_llvm_bool ? str_lit("false") : str_lit("0"));
} }
break; break;
case ExactValue_String: { case ExactValue_String: {
String str = value.value_string; String str = value.value_string;
if (str.len == 0) { if (str.len == 0) {
ir_write_string(f, "zeroinitializer"); ir_write_str_lit(f, "zeroinitializer");
break; break;
} }
if (!is_type_string(type)) { if (!is_type_string(type)) {
GB_ASSERT(is_type_array(type)); GB_ASSERT(is_type_array(type));
ir_write_string(f, "c\""); ir_write_str_lit(f, "c\"");
ir_print_escape_string(f, str, false, false); ir_print_escape_string(f, str, false, false);
ir_write_string(f, "\\00\""); ir_write_str_lit(f, "\\00\"");
} else { } else {
// HACK NOTE(bill): This is a hack but it works because strings are created at the very end // HACK NOTE(bill): This is a hack but it works because strings are created at the very end
// of the .ll file // of the .ll file
irValue *str_array = ir_add_global_string_array(m, str); irValue *str_array = ir_add_global_string_array(m, str);
ir_write_string(f, "{i8* getelementptr inbounds ("); ir_write_str_lit(f, "{i8* getelementptr inbounds (");
ir_print_type(f, m, str_array->Global.entity->type); ir_print_type(f, m, str_array->Global.entity->type);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, str_array->Global.entity->type); ir_print_type(f, m, str_array->Global.entity->type);
ir_write_string(f, "* "); ir_write_str_lit(f, "* ");
ir_print_encoded_global(f, str_array->Global.entity->token.string, false); ir_print_encoded_global(f, str_array->Global.entity->token.string, false);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, t_int); ir_print_type(f, m, t_int);
ir_write_string(f, " 0, i32 0), "); ir_write_str_lit(f, " 0, i32 0), ");
ir_print_type(f, m, t_int); ir_print_type(f, m, t_int);
ir_fprintf(f, " %lld}", cast(i64)str.len); ir_fprintf(f, " %lld}", cast(i64)str.len);
} }
@@ -555,15 +560,15 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
case ExactValue_Integer: { case ExactValue_Integer: {
if (is_type_pointer(type)) { if (is_type_pointer(type)) {
if (value.value_integer == 0) { if (value.value_integer == 0) {
ir_write_string(f, "null"); ir_write_str_lit(f, "null");
} else { } else {
ir_write_string(f, "inttoptr ("); ir_write_str_lit(f, "inttoptr (");
ir_print_type(f, m, t_int); ir_print_type(f, m, t_int);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_write_i64(f, value.value_integer); ir_write_i64(f, value.value_integer);
ir_write_string(f, " to "); ir_write_str_lit(f, " to ");
ir_print_type(f, m, t_rawptr); ir_print_type(f, m, t_rawptr);
ir_write_string(f, ")"); ir_write_str_lit(f, ")");
} }
} else { } else {
ir_write_i64(f, value.value_integer); ir_write_i64(f, value.value_integer);
@@ -608,16 +613,16 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
ir_write_byte(f, '{'); ir_write_byte(f, '{');
ir_print_type(f, m, ft); ir_write_byte(f, ' '); ir_print_type(f, m, ft); ir_write_byte(f, ' ');
ir_print_exact_value(f, m, exact_value_float(value.value_complex.real), ft); ir_print_exact_value(f, m, exact_value_float(value.value_complex.real), ft);
ir_write_string(f, str_lit(", ")); ir_print_type(f, m, ft); ir_write_byte(f, ' '); ir_write_str_lit(f, ", "); ir_print_type(f, m, ft); ir_write_byte(f, ' ');
ir_print_exact_value(f, m, exact_value_float(value.value_complex.imag), ft); ir_print_exact_value(f, m, exact_value_float(value.value_complex.imag), ft);
ir_write_byte(f, '}'); ir_write_byte(f, '}');
break; break;
} }
case ExactValue_Pointer: case ExactValue_Pointer:
if (value.value_pointer == 0) { if (value.value_pointer == 0) {
ir_write_string(f, "null"); ir_write_str_lit(f, "null");
} else { } else {
ir_write_string(f, "inttoptr ("); ir_write_str_lit(f, "inttoptr (");
ir_print_type(f, m, t_int); ir_print_type(f, m, t_int);
ir_fprintf(f, " %llu to ", cast(u64)cast(uintptr)value.value_pointer); ir_fprintf(f, " %llu to ", cast(u64)cast(uintptr)value.value_pointer);
ir_print_type(f, m, t_rawptr); ir_print_type(f, m, t_rawptr);
@@ -637,7 +642,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
bool has_defaults = ir_type_has_default_values(type); bool has_defaults = ir_type_has_default_values(type);
if (elem_count == 0) { if (elem_count == 0) {
if (!has_defaults) { if (!has_defaults) {
ir_write_string(f, "zeroinitializer"); ir_write_str_lit(f, "zeroinitializer");
} else { } else {
ir_print_exact_value(f, m, empty_exact_value, type); ir_print_exact_value(f, m, empty_exact_value, type);
} }
@@ -647,13 +652,13 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
ir_write_byte(f, '['); ir_write_byte(f, '[');
for (isize i = 0; i < elem_count; i++) { for (isize i = 0; i < elem_count; i++) {
if (i > 0) ir_write_string(f, str_lit(", ")); if (i > 0) ir_write_str_lit(f, ", ");
TypeAndValue tav = type_and_value_of_expr(m->info, cl->elems[i]); TypeAndValue tav = type_and_value_of_expr(m->info, cl->elems[i]);
GB_ASSERT(tav.mode != Addressing_Invalid); GB_ASSERT(tav.mode != Addressing_Invalid);
ir_print_compound_element(f, m, tav.value, elem_type); ir_print_compound_element(f, m, tav.value, elem_type);
} }
for (isize i = elem_count; i < type->Array.count; i++) { for (isize i = elem_count; i < type->Array.count; i++) {
if (i >= elem_count) ir_write_string(f, str_lit(", ")); if (i >= elem_count) ir_write_str_lit(f, ", ");
ir_print_compound_element(f, m, empty_exact_value, elem_type); ir_print_compound_element(f, m, empty_exact_value, elem_type);
} }
@@ -666,7 +671,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
bool has_defaults = ir_type_has_default_values(type); bool has_defaults = ir_type_has_default_values(type);
if (cl->elems.count == 0 && !has_defaults) { if (cl->elems.count == 0 && !has_defaults) {
ir_write_string(f, "zeroinitializer"); ir_write_str_lit(f, "zeroinitializer");
break; break;
} }
@@ -734,7 +739,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
if (!visited[i] && e->Variable.default_is_undef) { if (!visited[i] && e->Variable.default_is_undef) {
ir_print_type(f, m, e->type); ir_print_type(f, m, e->type);
ir_write_string(f, " undef"); ir_write_str_lit(f, " undef");
} else { } else {
ir_print_compound_element(f, m, values[i], e->type); ir_print_compound_element(f, m, values[i], e->type);
} }
@@ -744,7 +749,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
ir_write_byte(f, '}'); ir_write_byte(f, '}');
if (type->Struct.is_packed) ir_write_byte(f, '>'); if (type->Struct.is_packed) ir_write_byte(f, '>');
} else { } else {
ir_write_string(f, "zeroinitializer"); ir_write_str_lit(f, "zeroinitializer");
} }
break; break;
@@ -770,7 +775,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
default: { default: {
bool has_defaults = ir_type_has_default_values(type); bool has_defaults = ir_type_has_default_values(type);
if (!has_defaults) { if (!has_defaults) {
ir_write_string(f, "zeroinitializer"); ir_write_str_lit(f, "zeroinitializer");
} else { } else {
if (is_type_struct(type)) { if (is_type_struct(type)) {
i32 value_count = cast(i32)type->Struct.fields.count; i32 value_count = cast(i32)type->Struct.fields.count;
@@ -788,7 +793,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
Entity *e = type->Struct.fields[i]; Entity *e = type->Struct.fields[i];
if (e->Variable.default_is_undef) { if (e->Variable.default_is_undef) {
ir_print_type(f, m, e->type); ir_print_type(f, m, e->type);
ir_write_string(f, " undef"); ir_write_str_lit(f, " undef");
} else { } else {
ExactValue value = {}; ExactValue value = {};
if (!e->Variable.default_is_nil) { if (!e->Variable.default_is_nil) {
@@ -804,7 +809,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
} else if (is_type_array(type)) { } else if (is_type_array(type)) {
i64 count = type->Array.count; i64 count = type->Array.count;
if (count == 0) { if (count == 0) {
ir_write_string(f, "zeroinitializer"); ir_write_str_lit(f, "zeroinitializer");
} else { } else {
Type *elem = type->Array.elem; Type *elem = type->Array.elem;
ir_write_byte(f, '['); ir_write_byte(f, '[');
@@ -831,7 +836,7 @@ void ir_print_block_name(irFileBuffer *f, irBlock *b) {
ir_print_escape_string(f, b->label, false, false); ir_print_escape_string(f, b->label, false, false);
ir_fprintf(f, "-%td", b->index); ir_fprintf(f, "-%td", b->index);
} else { } else {
ir_write_string(f, "<INVALID-BLOCK>"); ir_write_str_lit(f, "<INVALID-BLOCK>");
} }
} }
@@ -852,7 +857,7 @@ bool ir_print_is_proc_global(irModule *m, irProcedure *proc) {
void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hint) { void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hint) {
if (value == nullptr) { if (value == nullptr) {
ir_write_string(f, "!!!nullptr_VALUE"); ir_write_str_lit(f, "!!!nullptr_VALUE");
return; return;
} }
switch (value->kind) { switch (value->kind) {
@@ -865,21 +870,21 @@ void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hin
case irValue_ConstantSlice: { case irValue_ConstantSlice: {
irValueConstantSlice *cs = &value->ConstantSlice; irValueConstantSlice *cs = &value->ConstantSlice;
if (cs->backing_array == nullptr || cs->count == 0) { if (cs->backing_array == nullptr || cs->count == 0) {
ir_write_string(f, "zeroinitializer"); ir_write_str_lit(f, "zeroinitializer");
} else { } else {
Type *at = base_type(type_deref(ir_type(cs->backing_array))); Type *at = base_type(type_deref(ir_type(cs->backing_array)));
Type *et = at->Array.elem; Type *et = at->Array.elem;
ir_write_byte(f, '{'); ir_write_byte(f, '{');
ir_print_type(f, m, et); ir_print_type(f, m, et);
ir_write_string(f, "* getelementptr inbounds ("); ir_write_str_lit(f, "* getelementptr inbounds (");
ir_print_type(f, m, at); ir_print_type(f, m, at);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, at); ir_print_type(f, m, at);
ir_write_string(f, "* "); ir_write_str_lit(f, "* ");
ir_print_value(f, m, cs->backing_array, at); ir_print_value(f, m, cs->backing_array, at);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, t_int); ir_print_type(f, m, t_int);
ir_write_string(f, " 0, i32 0), "); ir_write_str_lit(f, " 0, i32 0), ");
ir_print_type(f, m, t_int); ir_print_type(f, m, t_int);
ir_fprintf(f, " %lld}", cs->count); ir_fprintf(f, " %lld}", cs->count);
} }
@@ -887,11 +892,11 @@ void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hin
} }
case irValue_Nil: case irValue_Nil:
ir_write_string(f, "zeroinitializer"); ir_write_str_lit(f, "zeroinitializer");
break; break;
case irValue_Undef: case irValue_Undef:
ir_write_string(f, "undef"); ir_write_str_lit(f, "undef");
break; break;
case irValue_TypeName: case irValue_TypeName:
@@ -922,11 +927,11 @@ void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hin
void ir_print_calling_convention(irFileBuffer *f, irModule *m, ProcCallingConvention cc) { void ir_print_calling_convention(irFileBuffer *f, irModule *m, ProcCallingConvention cc) {
switch (cc) { switch (cc) {
case ProcCC_Odin: ir_write_string(f, ""); break; case ProcCC_Odin: ir_write_str_lit(f, ""); break;
case ProcCC_Contextless: ir_write_string(f, ""); break; case ProcCC_Contextless: ir_write_str_lit(f, ""); break;
case ProcCC_CDecl: ir_write_string(f, "ccc "); break; case ProcCC_CDecl: ir_write_str_lit(f, "ccc "); break;
case ProcCC_StdCall: ir_write_string(f, "cc 64 "); break; case ProcCC_StdCall: ir_write_str_lit(f, "cc 64 "); break;
case ProcCC_FastCall: ir_write_string(f, "cc 65 "); break; case ProcCC_FastCall: ir_write_str_lit(f, "cc 65 "); break;
default: GB_PANIC("unknown calling convention: %d", cc); default: GB_PANIC("unknown calling convention: %d", cc);
} }
} }
@@ -945,14 +950,14 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
} }
case irInstr_StartupRuntime: { case irInstr_StartupRuntime: {
ir_write_string(f, "call void "); ir_write_str_lit(f, "call void ");
ir_print_encoded_global(f, str_lit(IR_STARTUP_RUNTIME_PROC_NAME), false); ir_print_encoded_global(f, str_lit(IR_STARTUP_RUNTIME_PROC_NAME), false);
ir_write_string(f, "()\n"); ir_write_str_lit(f, "()\n");
break; break;
} }
case irInstr_Comment: case irInstr_Comment:
ir_write_string(f, "; "); ir_write_str_lit(f, "; ");
ir_write_string(f, instr->Comment.text); ir_write_string(f, instr->Comment.text);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
break; break;
@@ -971,11 +976,11 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
case irInstr_ZeroInit: { case irInstr_ZeroInit: {
Type *type = type_deref(ir_type(instr->ZeroInit.address)); Type *type = type_deref(ir_type(instr->ZeroInit.address));
ir_write_string(f, "store "); ir_write_str_lit(f, "store ");
ir_print_type(f, m, type); ir_print_type(f, m, type);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_exact_value(f, m, empty_exact_value, type); ir_print_exact_value(f, m, empty_exact_value, type);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, type); ir_print_type(f, m, type);
ir_fprintf(f, "* %%%d\n", instr->ZeroInit.address->index); ir_fprintf(f, "* %%%d\n", instr->ZeroInit.address->index);
break; break;
@@ -983,13 +988,13 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
case irInstr_Store: { case irInstr_Store: {
Type *type = type_deref(ir_type(instr->Store.address)); Type *type = type_deref(ir_type(instr->Store.address));
ir_write_string(f, "store "); ir_write_str_lit(f, "store ");
ir_print_type(f, m, type); ir_print_type(f, m, type);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, instr->Store.value, type); ir_print_value(f, m, instr->Store.value, type);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, type); ir_print_type(f, m, type);
ir_write_string(f, "* "); ir_write_str_lit(f, "* ");
ir_print_value(f, m, instr->Store.address, type); ir_print_value(f, m, instr->Store.address, type);
ir_print_debug_location(f, m, value); ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
@@ -1000,9 +1005,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
Type *type = instr->Load.type; Type *type = instr->Load.type;
ir_fprintf(f, "%%%d = load ", value->index); ir_fprintf(f, "%%%d = load ", value->index);
ir_print_type(f, m, type); ir_print_type(f, m, type);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, type); ir_print_type(f, m, type);
ir_write_string(f, "* "); ir_write_str_lit(f, "* ");
ir_print_value(f, m, instr->Load.address, type); ir_print_value(f, m, instr->Load.address, type);
ir_fprintf(f, ", align %lld", type_align_of(m->allocator, type)); ir_fprintf(f, ", align %lld", type_align_of(m->allocator, type));
ir_print_debug_location(f, m, value); ir_print_debug_location(f, m, value);
@@ -1014,13 +1019,13 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_fprintf(f, "%%%d = getelementptr inbounds ", value->index); ir_fprintf(f, "%%%d = getelementptr inbounds ", value->index);
ir_print_type(f, m, type_deref(et)); ir_print_type(f, m, type_deref(et));
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, et); ir_print_type(f, m, et);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, instr->ArrayElementPtr.address, et); ir_print_value(f, m, instr->ArrayElementPtr.address, et);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, t_int); ir_print_type(f, m, t_int);
ir_write_string(f, " 0, "); ir_write_str_lit(f, " 0, ");
irValue *index =instr->ArrayElementPtr.elem_index; irValue *index =instr->ArrayElementPtr.elem_index;
Type *t = ir_type(index); Type *t = ir_type(index);
@@ -1045,13 +1050,13 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
} }
ir_print_type(f, m, type_deref(et)); ir_print_type(f, m, type_deref(et));
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, et); ir_print_type(f, m, et);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, instr->StructElementPtr.address, et); ir_print_value(f, m, instr->StructElementPtr.address, et);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, t_int); ir_print_type(f, m, t_int);
ir_write_string(f, " 0, "); ir_write_str_lit(f, " 0, ");
ir_print_type(f, m, t_i32); ir_print_type(f, m, t_i32);
ir_fprintf(f, " %d", index); ir_fprintf(f, " %d", index);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
@@ -1062,14 +1067,14 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
Type *pt = ir_type(instr->PtrOffset.address); Type *pt = ir_type(instr->PtrOffset.address);
ir_fprintf(f, "%%%d = getelementptr inbounds ", value->index); ir_fprintf(f, "%%%d = getelementptr inbounds ", value->index);
ir_print_type(f, m, type_deref(pt)); ir_print_type(f, m, type_deref(pt));
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, pt); ir_print_type(f, m, pt);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, instr->PtrOffset.address, pt); ir_print_value(f, m, instr->PtrOffset.address, pt);
irValue *offset = instr->PtrOffset.offset; irValue *offset = instr->PtrOffset.offset;
Type *t = ir_type(offset); Type *t = ir_type(offset);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, t); ir_print_type(f, m, t);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, offset, t); ir_print_value(f, m, offset, t);
@@ -1095,11 +1100,11 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
block = instr->block->preds[i]; block = instr->block->preds[i];
} }
ir_write_string(f, "[ "); ir_write_str_lit(f, "[ ");
ir_print_value(f, m, edge, instr->Phi.type); ir_print_value(f, m, edge, instr->Phi.type);
ir_write_string(f, ", %"); ir_write_str_lit(f, ", %");
ir_print_block_name(f, block); ir_print_block_name(f, block);
ir_write_string(f, " ]"); ir_write_str_lit(f, " ]");
} }
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
break; break;
@@ -1133,13 +1138,13 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
GB_ASSERT(is_type_union(t)); GB_ASSERT(is_type_union(t));
ir_print_type(f, m, type_deref(et)); ir_print_type(f, m, type_deref(et));
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, et); ir_print_type(f, m, et);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, instr->UnionTagPtr.address, et); ir_print_value(f, m, instr->UnionTagPtr.address, et);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_type(f, m, t_int); ir_print_type(f, m, t_int);
ir_write_string(f, " 0, "); ir_write_str_lit(f, " 0, ");
ir_print_type(f, m, t_i32); ir_print_type(f, m, t_i32);
ir_fprintf(f, " 2 ; UnionTagPtr\n"); ir_fprintf(f, " 2 ; UnionTagPtr\n");
break; break;
@@ -1159,7 +1164,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
} }
case irInstr_Jump: {; case irInstr_Jump: {;
ir_write_string(f, "br label %"); ir_write_str_lit(f, "br label %");
ir_print_block_name(f, instr->Jump.block); ir_print_block_name(f, instr->Jump.block);
ir_print_debug_location(f, m, value); ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
@@ -1167,12 +1172,12 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
} }
case irInstr_If: {; case irInstr_If: {;
ir_write_string(f, "br i1"); ir_write_str_lit(f, "br i1");
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, instr->If.cond, t_bool); ir_print_value(f, m, instr->If.cond, t_bool);
ir_write_string(f, ", "); ir_write_str_lit(f, ", ");
ir_write_string(f, "label %"); ir_print_block_name(f, instr->If.true_block); ir_write_str_lit(f, "label %"); ir_print_block_name(f, instr->If.true_block);
ir_write_string(f, ", label %"); ir_print_block_name(f, instr->If.false_block); ir_write_str_lit(f, ", label %"); ir_print_block_name(f, instr->If.false_block);
ir_print_debug_location(f, m, value); ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
break; break;
@@ -1180,9 +1185,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
case irInstr_Return: { case irInstr_Return: {
irInstrReturn *ret = &instr->Return; irInstrReturn *ret = &instr->Return;
ir_write_string(f, "ret "); ir_write_str_lit(f, "ret ");
if (ret->value == nullptr) { if (ret->value == nullptr) {
ir_write_string(f, "void"); ir_write_str_lit(f, "void");
} else { } else {
Type *t = ir_type(ret->value); Type *t = ir_type(ret->value);
ir_print_type(f, m, t); ir_print_type(f, m, t);
@@ -1201,7 +1206,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_print_type(f, m, c->from); ir_print_type(f, m, c->from);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, c->value, c->from); ir_print_value(f, m, c->value, c->from);
ir_write_string(f, " to "); ir_write_str_lit(f, " to ");
ir_print_type(f, m, c->to); ir_print_type(f, m, c->to);
ir_print_debug_location(f, m, value); ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
@@ -1223,15 +1228,15 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
switch (uo->op) { switch (uo->op) {
case Token_Sub: case Token_Sub:
if (is_type_float(elem_type)) { if (is_type_float(elem_type)) {
ir_write_string(f, "fsub"); ir_write_str_lit(f, "fsub");
} else { } else {
ir_write_string(f, "sub"); ir_write_str_lit(f, "sub");
} }
break; break;
case Token_Xor: case Token_Xor:
case Token_Not: case Token_Not:
GB_ASSERT(is_type_integer(type) || is_type_boolean(type)); GB_ASSERT(is_type_integer(type) || is_type_boolean(type));
ir_write_string(f, "xor"); ir_write_str_lit(f, "xor");
break; break;
default: default:
GB_PANIC("Unknown unary operator"); GB_PANIC("Unknown unary operator");
@@ -1252,10 +1257,10 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
case Token_Xor: case Token_Xor:
case Token_Not: case Token_Not:
GB_ASSERT(is_type_integer(type) || is_type_boolean(type)); GB_ASSERT(is_type_integer(type) || is_type_boolean(type));
ir_write_string(f, "-1"); ir_write_str_lit(f, "-1");
break; break;
} }
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_value(f, m, uo->expr, type); ir_print_value(f, m, uo->expr, type);
ir_print_debug_location(f, m, value); ir_print_debug_location(f, m, value);
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
@@ -1273,68 +1278,68 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
if (is_type_string(elem_type)) { if (is_type_string(elem_type)) {
GB_PANIC("Unhandled string type"); GB_PANIC("Unhandled string type");
} else if (is_type_float(elem_type)) { } else if (is_type_float(elem_type)) {
ir_write_string(f, "fcmp "); ir_write_str_lit(f, "fcmp ");
switch (bo->op) { switch (bo->op) {
case Token_CmpEq: ir_write_string(f, "oeq"); break; case Token_CmpEq: ir_write_str_lit(f, "oeq"); break;
case Token_NotEq: ir_write_string(f, "one"); break; case Token_NotEq: ir_write_str_lit(f, "one"); break;
case Token_Lt: ir_write_string(f, "olt"); break; case Token_Lt: ir_write_str_lit(f, "olt"); break;
case Token_Gt: ir_write_string(f, "ogt"); break; case Token_Gt: ir_write_str_lit(f, "ogt"); break;
case Token_LtEq: ir_write_string(f, "ole"); break; case Token_LtEq: ir_write_str_lit(f, "ole"); break;
case Token_GtEq: ir_write_string(f, "oge"); break; case Token_GtEq: ir_write_str_lit(f, "oge"); break;
} }
} else if (is_type_complex(elem_type)) { } else if (is_type_complex(elem_type)) {
GB_PANIC("Unhandled complex type"); GB_PANIC("Unhandled complex type");
return; return;
} else { } else {
ir_write_string(f, "icmp "); ir_write_str_lit(f, "icmp ");
if (bo->op != Token_CmpEq && if (bo->op != Token_CmpEq &&
bo->op != Token_NotEq) { bo->op != Token_NotEq) {
if (is_type_unsigned(elem_type)) { if (is_type_unsigned(elem_type)) {
ir_write_string(f, "u"); ir_write_str_lit(f, "u");
} else { } else {
ir_write_string(f, "s"); ir_write_str_lit(f, "s");
} }
} }
switch (bo->op) { switch (bo->op) {
case Token_CmpEq: ir_write_string(f, "eq"); break; case Token_CmpEq: ir_write_str_lit(f, "eq"); break;
case Token_NotEq: ir_write_string(f, "ne"); break; case Token_NotEq: ir_write_str_lit(f, "ne"); break;
case Token_Lt: ir_write_string(f, "lt"); break; case Token_Lt: ir_write_str_lit(f, "lt"); break;
case Token_Gt: ir_write_string(f, "gt"); break; case Token_Gt: ir_write_str_lit(f, "gt"); break;
case Token_LtEq: ir_write_string(f, "le"); break; case Token_LtEq: ir_write_str_lit(f, "le"); break;
case Token_GtEq: ir_write_string(f, "ge"); break; case Token_GtEq: ir_write_str_lit(f, "ge"); break;
default: GB_PANIC("invalid comparison");break; default: GB_PANIC("invalid comparison");break;
} }
} }
} else { } else {
if (is_type_float(elem_type)) { if (is_type_float(elem_type)) {
ir_write_string(f, "f"); ir_write_str_lit(f, "f");
} }
switch (bo->op) { switch (bo->op) {
case Token_Add: ir_write_string(f, "add"); break; case Token_Add: ir_write_str_lit(f, "add"); break;
case Token_Sub: ir_write_string(f, "sub"); break; case Token_Sub: ir_write_str_lit(f, "sub"); break;
case Token_And: ir_write_string(f, "and"); break; case Token_And: ir_write_str_lit(f, "and"); break;
case Token_Or: ir_write_string(f, "or"); break; case Token_Or: ir_write_str_lit(f, "or"); break;
case Token_Xor: ir_write_string(f, "xor"); break; case Token_Xor: ir_write_str_lit(f, "xor"); break;
case Token_Shl: ir_write_string(f, "shl"); break; case Token_Shl: ir_write_str_lit(f, "shl"); break;
case Token_Shr: ir_write_string(f, "lshr"); break; case Token_Shr: ir_write_str_lit(f, "lshr"); break;
case Token_Mul: ir_write_string(f, "mul"); break; case Token_Mul: ir_write_str_lit(f, "mul"); break;
case Token_Not: ir_write_string(f, "xor"); break; case Token_Not: ir_write_str_lit(f, "xor"); break;
case Token_AndNot: GB_PANIC("Token_AndNot Should never be called"); case Token_AndNot: GB_PANIC("Token_AndNot Should never be called");
default: { default: {
if (!is_type_float(elem_type)) { if (!is_type_float(elem_type)) {
if (is_type_unsigned(elem_type)) { if (is_type_unsigned(elem_type)) {
ir_write_string(f, "u"); ir_write_str_lit(f, "u");
} else { } else {
ir_write_string(f, "s"); ir_write_str_lit(f, "s");
} }
} }
switch (bo->op) { switch (bo->op) {
case Token_Quo: ir_write_string(f, "div"); break; case Token_Quo: ir_write_str_lit(f, "div"); break;
case Token_Mod: ir_write_string(f, "rem"); break; case Token_Mod: ir_write_str_lit(f, "rem"); break;
} }
break; break;
} }
@@ -1345,7 +1350,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_print_type(f, m, type); ir_print_type(f, m, type);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, bo->left, type); ir_print_value(f, m, bo->left, type);
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
ir_print_value(f, m, bo->right, type); ir_print_value(f, m, bo->right, type);
ir_print_debug_location(f, m, value); ir_print_debug_location(f, m, value);
@@ -1362,14 +1367,14 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
if (result_type) { if (result_type) {
ir_fprintf(f, "%%%d = ", value->index); ir_fprintf(f, "%%%d = ", value->index);
} }
ir_write_string(f, "call "); ir_write_str_lit(f, "call ");
ir_print_calling_convention(f, m, proc_type->Proc.calling_convention); ir_print_calling_convention(f, m, proc_type->Proc.calling_convention);
if (is_c_vararg) { if (is_c_vararg) {
ir_print_proc_type_without_pointer(f, m, proc_type); ir_print_proc_type_without_pointer(f, m, proc_type);
} else if (result_type && !proc_type->Proc.return_by_pointer) { } else if (result_type && !proc_type->Proc.return_by_pointer) {
ir_print_proc_results(f, m, proc_type); ir_print_proc_results(f, m, proc_type);
} else { } else {
ir_write_string(f, "void"); ir_write_str_lit(f, "void");
} }
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, call->value, call->type); ir_print_value(f, m, call->value, call->type);
@@ -1379,10 +1384,10 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
if (proc_type->Proc.return_by_pointer) { if (proc_type->Proc.return_by_pointer) {
GB_ASSERT(call->return_ptr != nullptr); GB_ASSERT(call->return_ptr != nullptr);
ir_print_type(f, m, proc_type->Proc.results); ir_print_type(f, m, proc_type->Proc.results);
ir_write_string(f, "* "); ir_write_str_lit(f, "* ");
ir_print_value(f, m, call->return_ptr, ir_type(call->return_ptr)); ir_print_value(f, m, call->return_ptr, ir_type(call->return_ptr));
if (call->arg_count > 0) { if (call->arg_count > 0) {
ir_write_string(f, str_lit(", ")); ir_write_str_lit(f, ", ");
} }
} }
@@ -1397,12 +1402,12 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
GB_ASSERT(e != nullptr); GB_ASSERT(e != nullptr);
if (e->kind != Entity_Variable) continue; if (e->kind != Entity_Variable) continue;
if (param_index > 0) ir_write_string(f, str_lit(", ")); if (param_index > 0) ir_write_str_lit(f, ", ");
Type *t = proc_type->Proc.abi_compat_params[i]; Type *t = proc_type->Proc.abi_compat_params[i];
ir_print_type(f, m, t); ir_print_type(f, m, t);
if (e->flags&EntityFlag_NoAlias) { if (e->flags&EntityFlag_NoAlias) {
ir_write_string(f, " noalias"); ir_write_str_lit(f, " noalias");
} }
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
irValue *arg = call->args[i]; irValue *arg = call->args[i];
@@ -1413,7 +1418,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
param_index++; param_index++;
} }
for (; i < call->arg_count; i++) { for (; i < call->arg_count; i++) {
if (param_index > 0) ir_write_string(f, str_lit(", ")); if (param_index > 0) ir_write_str_lit(f, ", ");
irValue *arg = call->args[i]; irValue *arg = call->args[i];
Type *t = ir_type(arg); Type *t = ir_type(arg);
@@ -1429,14 +1434,14 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
GB_ASSERT(e != nullptr); GB_ASSERT(e != nullptr);
if (e->kind != Entity_Variable) continue; if (e->kind != Entity_Variable) continue;
if (param_index > 0) ir_write_string(f, str_lit(", ")); if (param_index > 0) ir_write_str_lit(f, ", ");
irValue *arg = call->args[i]; irValue *arg = call->args[i];
Type *t = proc_type->Proc.abi_compat_params[i]; Type *t = proc_type->Proc.abi_compat_params[i];
ir_print_type(f, m, t); ir_print_type(f, m, t);
if (e->flags&EntityFlag_NoAlias) { if (e->flags&EntityFlag_NoAlias) {
ir_write_string(f, " noalias"); ir_write_str_lit(f, " noalias");
} }
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, arg, t); ir_print_value(f, m, arg, t);
@@ -1445,16 +1450,16 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
} }
} }
if (proc_type->Proc.calling_convention == ProcCC_Odin) { if (proc_type->Proc.calling_convention == ProcCC_Odin) {
if (param_index > 0) ir_write_string(f, str_lit(", ")); if (param_index > 0) ir_write_str_lit(f, ", ");
ir_print_type(f, m, t_context_ptr); ir_print_type(f, m, t_context_ptr);
ir_write_string(f, " noalias nonnull "); ir_write_str_lit(f, " noalias nonnull ");
ir_print_value(f, m, call->context_ptr, t_context_ptr); ir_print_value(f, m, call->context_ptr, t_context_ptr);
} }
ir_write_string(f, ")"); ir_write_str_lit(f, ")");
ir_print_debug_location(f, m, value, instr->block->proc); ir_print_debug_location(f, m, value, instr->block->proc);
ir_write_string(f, "\n"); ir_write_byte(f, '\n');
break; break;
} }
@@ -1629,15 +1634,15 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
String name = e->token.string; String name = e->token.string;
TokenPos pos = e->token.pos; TokenPos pos = e->token.pos;
ir_write_string(f, "call void @llvm.dbg.declare("); ir_write_str_lit(f, "call void @llvm.dbg.declare(");
ir_write_string(f, "metadata "); ir_write_str_lit(f, "metadata ");
ir_print_type(f, m, vt); ir_print_type(f, m, vt);
ir_write_byte(f, ' '); ir_write_byte(f, ' ');
ir_print_value(f, m, dd->value, vt); ir_print_value(f, m, dd->value, vt);
ir_write_string(f, ", metadata !DILocalVariable(name: \""); ir_write_str_lit(f, ", metadata !DILocalVariable(name: \"");
ir_print_escape_string(f, name, false, false); ir_print_escape_string(f, name, false, false);
ir_fprintf(f, "\", scope: !%d, line: %td)", di->id, pos.line); ir_fprintf(f, "\", scope: !%d, line: %td)", di->id, pos.line);
ir_write_string(f, ", metadata !DIExpression()"); ir_write_str_lit(f, ", metadata !DIExpression()");
ir_write_byte(f, ')'); ir_write_byte(f, ')');
ir_fprintf(f, ", !dbg !DILocation(line: %td, column: %td, scope: !%d)", pos.line, pos.column, di->id); ir_fprintf(f, ", !dbg !DILocation(line: %td, column: %td, scope: !%d)", pos.line, pos.column, di->id);
@@ -1650,16 +1655,16 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) { void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
if (proc->body == nullptr) { if (proc->body == nullptr) {
ir_write_string(f, "declare "); ir_write_str_lit(f, "declare ");
// if (proc->tags & ProcTag_dll_import) { // if (proc->tags & ProcTag_dll_import) {
// ir_write_string(f, "dllimport "); // ir_write_string(f, "dllimport ");
// } // }
} else { } else {
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
ir_write_string(f, "define "); ir_write_str_lit(f, "define ");
if (build_context.is_dll) { if (build_context.is_dll) {
if (proc->is_export) { if (proc->is_export) {
ir_write_string(f, "dllexport "); ir_write_str_lit(f, "dllexport ");
} }
} }
// if (!proc->is_export && !proc->is_foreign && !proc->is_entry_point) { // if (!proc->is_export && !proc->is_foreign && !proc->is_entry_point) {
@@ -1688,8 +1693,8 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
if (proc_type->return_by_pointer) { if (proc_type->return_by_pointer) {
ir_print_type(f, m, reduce_tuple_to_single_type(proc_type->results)); ir_print_type(f, m, reduce_tuple_to_single_type(proc_type->results));
ir_write_string(f, "* sret noalias "); ir_write_str_lit(f, "* sret noalias ");
ir_write_string(f, "%agg.result"); ir_write_str_lit(f, "%agg.result");
if (param_count > 0) { if (param_count > 0) {
ir_write_string(f, str_lit(", ")); ir_write_string(f, str_lit(", "));
} }
@@ -1706,11 +1711,11 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
if (param_index > 0) ir_write_string(f, str_lit(", ")); if (param_index > 0) ir_write_string(f, str_lit(", "));
if (i+1 == params->variables.count && proc_type->c_vararg) { if (i+1 == params->variables.count && proc_type->c_vararg) {
ir_write_string(f, " ..."); ir_write_str_lit(f, " ...");
} else { } else {
ir_print_type(f, m, abi_type); ir_print_type(f, m, abi_type);
if (e->flags&EntityFlag_NoAlias) { if (e->flags&EntityFlag_NoAlias) {
ir_write_string(f, " noalias"); ir_write_str_lit(f, " noalias");
} }
if (proc->body != nullptr) { if (proc->body != nullptr) {
if (e->token.string != "" && !is_blank_ident(e->token)) { if (e->token.string != "" && !is_blank_ident(e->token)) {
@@ -1726,24 +1731,24 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
} }
} }
if (proc_type->calling_convention == ProcCC_Odin) { if (proc_type->calling_convention == ProcCC_Odin) {
if (param_index > 0) ir_write_string(f, str_lit(", ")); if (param_index > 0) ir_write_str_lit(f, ", ");
ir_print_type(f, m, t_context_ptr); ir_print_type(f, m, t_context_ptr);
ir_write_string(f, " noalias nonnull %__.context_ptr"); ir_write_str_lit(f, " noalias nonnull %__.context_ptr");
} }
ir_write_string(f, ") "); ir_write_str_lit(f, ") ");
switch (proc->inlining) { switch (proc->inlining) {
default: default:
ir_fprintf(f, "#0 "); ir_fprintf(f, "#0 ");
break; break;
case ProcInlining_inline: case ProcInlining_inline:
ir_write_string(f, "alwaysinline "); ir_write_str_lit(f, "alwaysinline ");
ir_fprintf(f, "#1 "); ir_fprintf(f, "#1 ");
break; break;
case ProcInlining_no_inline: case ProcInlining_no_inline:
ir_write_string(f, "noinline "); ir_write_str_lit(f, "noinline ");
ir_fprintf(f, "#2 "); ir_fprintf(f, "#2 ");
break; break;
} }
@@ -1762,20 +1767,20 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
if (proc->body != nullptr) { if (proc->body != nullptr) {
// ir_fprintf(f, "nounwind uwtable {\n"); // ir_fprintf(f, "nounwind uwtable {\n");
ir_write_string(f, "{\n"); ir_write_str_lit(f, "{\n");
for_array(i, proc->blocks) { for_array(i, proc->blocks) {
irBlock *block = proc->blocks[i]; irBlock *block = proc->blocks[i];
if (i > 0) ir_write_byte(f, '\n'); if (i > 0) ir_write_byte(f, '\n');
ir_print_block_name(f, block); ir_print_block_name(f, block);
ir_write_string(f, ":\n"); ir_write_str_lit(f, ":\n");
for_array(j, block->instrs) { for_array(j, block->instrs) {
irValue *value = block->instrs[j]; irValue *value = block->instrs[j];
ir_print_instr(f, m, value); ir_print_instr(f, m, value);
} }
} }
ir_write_string(f, "}\n"); ir_write_str_lit(f, "}\n");
} else { } else {
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
} }
@@ -1836,35 +1841,35 @@ void print_llvm_ir(irGen *ir) {
i32 word_bits = cast(i32)(8*build_context.word_size); i32 word_bits = cast(i32)(8*build_context.word_size);
if (build_context.ODIN_OS == "osx" || build_context.ODIN_OS == "macos") { if (build_context.ODIN_OS == "osx" || build_context.ODIN_OS == "macos") {
GB_ASSERT(word_bits == 64); GB_ASSERT(word_bits == 64);
ir_write_string(f, "target triple = \"x86_64-apple-macosx10.8\"\n\n"); ir_write_str_lit(f, "target triple = \"x86_64-apple-macosx10.8\"\n\n");
} else if (build_context.ODIN_OS == "windows") { } else if (build_context.ODIN_OS == "windows") {
ir_fprintf(f, "target triple = \"x86%s-pc-windows-msvc\"\n\n", word_bits == 64 ? "_64" : ""); ir_fprintf(f, "target triple = \"x86%s-pc-windows-msvc\"\n\n", word_bits == 64 ? "_64" : "");
} }
ir_print_encoded_local(f, str_lit("..opaque")); ir_print_encoded_local(f, str_lit("..opaque"));
ir_write_string(f, " = type {};\n"); ir_write_str_lit(f, " = type {};\n");
ir_print_encoded_local(f, str_lit("..string")); ir_print_encoded_local(f, str_lit("..string"));
ir_write_string(f, " = type {i8*, "); ir_write_str_lit(f, " = type {i8*, ");
ir_print_type(f, m, t_int); ir_print_type(f, m, t_int);
ir_write_string(f, "} ; Basic_string\n"); ir_write_str_lit(f, "} ; Basic_string\n");
ir_print_encoded_local(f, str_lit("..rawptr")); ir_print_encoded_local(f, str_lit("..rawptr"));
ir_write_string(f, " = type i8* ; Basic_rawptr\n"); ir_write_str_lit(f, " = type i8* ; Basic_rawptr\n");
ir_print_encoded_local(f, str_lit("..complex32")); ir_print_encoded_local(f, str_lit("..complex32"));
ir_write_string(f, " = type {half, half} ; Basic_complex32\n"); ir_write_str_lit(f, " = type {half, half} ; Basic_complex32\n");
ir_print_encoded_local(f, str_lit("..complex64")); ir_print_encoded_local(f, str_lit("..complex64"));
ir_write_string(f, " = type {float, float} ; Basic_complex64\n"); ir_write_str_lit(f, " = type {float, float} ; Basic_complex64\n");
ir_print_encoded_local(f, str_lit("..complex128")); ir_print_encoded_local(f, str_lit("..complex128"));
ir_write_string(f, " = type {double, double} ; Basic_complex128\n"); ir_write_str_lit(f, " = type {double, double} ; Basic_complex128\n");
ir_print_encoded_local(f, str_lit("..any")); ir_print_encoded_local(f, str_lit("..any"));
ir_write_string(f, " = type {"); ir_write_str_lit(f, " = type {");
ir_print_type(f, m, t_rawptr); ir_print_type(f, m, t_rawptr);
ir_write_string(f, ", "); ir_write_str_lit(f, ", ");
ir_print_type(f, m, t_type_info_ptr); ir_print_type(f, m, t_type_info_ptr);
ir_write_string(f, "} ; Basic_any\n"); ir_write_str_lit(f, "} ; Basic_any\n");
ir_write_string(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n"); ir_write_str_lit(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n");
ir_write_byte(f, '\n'); ir_write_byte(f, '\n');
+18 -14
View File
@@ -97,6 +97,11 @@ struct TypeStruct {
#define TYPE_KINDS \ #define TYPE_KINDS \
TYPE_KIND(Basic, BasicType) \ TYPE_KIND(Basic, BasicType) \
TYPE_KIND(Named, struct { \
String name; \
Type * base; \
Entity *type_name; /* Entity_TypeName */ \
}) \
TYPE_KIND(Generic, struct { \ TYPE_KIND(Generic, struct { \
i64 id; \ i64 id; \
String name; \ String name; \
@@ -109,8 +114,16 @@ struct TypeStruct {
i64 count; \ i64 count; \
Type *generic_type; \ Type *generic_type; \
}) \ }) \
TYPE_KIND(DynamicArray, struct { Type *elem; }) \
TYPE_KIND(Slice, struct { Type *elem; }) \ TYPE_KIND(Slice, struct { Type *elem; }) \
TYPE_KIND(DynamicArray, struct { Type *elem; }) \
TYPE_KIND(Map, struct { \
Type * key; \
Type * value; \
Type * entry_type; \
Type * generated_struct_type; \
Type * internal_type; \
Type * lookup_result_type; \
}) \
TYPE_KIND(Struct, TypeStruct) \ TYPE_KIND(Struct, TypeStruct) \
TYPE_KIND(Enum, struct { \ TYPE_KIND(Enum, struct { \
Entity **fields; \ Entity **fields; \
@@ -131,11 +144,6 @@ struct TypeStruct {
i64 custom_align; \ i64 custom_align; \
i64 tag_size; \ i64 tag_size; \
}) \ }) \
TYPE_KIND(Named, struct { \
String name; \
Type * base; \
Entity *type_name; /* Entity_TypeName */ \
}) \
TYPE_KIND(Tuple, struct { \ TYPE_KIND(Tuple, struct { \
Array<Entity *> variables; /* Entity_Variable */ \ Array<Entity *> variables; /* Entity_Variable */ \
Array<i64> offsets; \ Array<i64> offsets; \
@@ -162,14 +170,6 @@ struct TypeStruct {
isize specialization_count; \ isize specialization_count; \
ProcCallingConvention calling_convention; \ ProcCallingConvention calling_convention; \
}) \ }) \
TYPE_KIND(Map, struct { \
Type * key; \
Type * value; \
Type * entry_type; \
Type * generated_struct_type; \
Type * internal_type; \
Type * lookup_result_type; \
}) \
TYPE_KIND(BitFieldValue, struct { u32 bits; }) \ TYPE_KIND(BitFieldValue, struct { u32 bits; }) \
TYPE_KIND(BitField, struct { \ TYPE_KIND(BitField, struct { \
Scope * scope; \ Scope * scope; \
@@ -1367,6 +1367,10 @@ i64 union_tag_size(gbAllocator a, Type *u) {
} }
u64 n = cast(u64)u->Union.variants.count; u64 n = cast(u64)u->Union.variants.count;
if (n == 0) {
return 0;
}
i64 bytes = next_pow2(cast(i64)(floor_log2(n)/8 + 1)); i64 bytes = next_pow2(cast(i64)(floor_log2(n)/8 + 1));
i64 tag_size = gb_max(bytes, 1); i64 tag_size = gb_max(bytes, 1);