diff --git a/src/check_type.cpp b/src/check_type.cpp index 3736a7bca..0148f1f60 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1455,6 +1455,10 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) { Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) { Type *new_type = original_type; + if (is_type_boolean(original_type)) { + return t_llvm_bool; + } + if (build_context.ODIN_ARCH == "x86") { return new_type; } diff --git a/src/checker.cpp b/src/checker.cpp index 62a16cd08..f0ea6ff65 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -3412,7 +3412,7 @@ void check_parsed_files(Checker *c) { // Add "Basic" type information for (isize i = 0; i < gb_count_of(basic_types)-1; i++) { Type *t = &basic_types[i]; - if (t->Basic.size > 0) { + if (t->Basic.size > 0 && t->Basic.kind != Basic_llvm_bool) { add_type_info_type(c, t); } } diff --git a/src/ir.cpp b/src/ir.cpp index d30fb958b..e49f76084 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -854,6 +854,8 @@ irValue *ir_value_param(gbAllocator a, irProcedure *parent, Entity *e, Type *abi } } else if (is_type_integer(abi_type)) { v->Param.kind = irParamPass_Integer; + } else if (abi_type == t_llvm_bool) { + v->Param.kind = irParamPass_Value; } else { GB_PANIC("Invalid abi type pass kind"); } @@ -911,6 +913,12 @@ irValue *ir_instr_local(irProcedure *p, Entity *e, bool zero_initialized) { return v; } +irValue *ir_instr_zero_init(irProcedure *p, irValue *address) { + irValue *v = ir_alloc_instr(p, irInstr_ZeroInit); + irInstr *i = &v->Instr; + i->ZeroInit.address = address; + return v; +} irValue *ir_instr_store(irProcedure *p, irValue *address, irValue *value, bool atomic) { irValue *v = ir_alloc_instr(p, irInstr_Store); @@ -921,13 +929,6 @@ irValue *ir_instr_store(irProcedure *p, irValue *address, irValue *value, bool a return v; } -irValue *ir_instr_zero_init(irProcedure *p, irValue *address) { - irValue *v = ir_alloc_instr(p, irInstr_ZeroInit); - irInstr *i = &v->Instr; - i->ZeroInit.address = address; - return v; -} - irValue *ir_instr_load(irProcedure *p, irValue *address) { irValue *v = ir_alloc_instr(p, irInstr_Load); irInstr *i = &v->Instr; @@ -1040,7 +1041,7 @@ irValue *ir_instr_jump(irProcedure *p, irBlock *block) { irValue *ir_instr_if(irProcedure *p, irValue *cond, irBlock *true_block, irBlock *false_block) { irValue *v = ir_alloc_instr(p, irInstr_If); irInstr *i = &v->Instr; - i->If.cond = cond; + i->If.cond = ir_emit_conv(p, cond, t_llvm_bool); i->If.true_block = true_block; i->If.false_block = false_block; return v; @@ -1447,8 +1448,12 @@ irValue *ir_add_param(irProcedure *proc, Entity *e, AstNode *expr, Type *abi_typ switch (p->kind) { case irParamPass_Value: { irValue *l = ir_add_local(proc, e, expr, false); - ir_emit_store(proc, l, v); - return v; + irValue *x = v; + if (abi_type == t_llvm_bool) { + x = ir_emit_conv(proc, x, t_bool); + } + ir_emit_store(proc, l, x); + return x; } case irParamPass_Pointer: ir_module_add_value(proc->module, e, v); @@ -1534,29 +1539,41 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na // //////////////////////////////////////////////////////////////// - +irValue *ir_emit_global_call(irProcedure *proc, char const *name_, irValue **args, isize arg_count); irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) { -#if 1 // NOTE(bill): Sanity check Type *a = type_deref(ir_type(address)); Type *b = ir_type(value); if (!is_type_untyped(b)) { GB_ASSERT_MSG(are_types_identical(core_type(a), core_type(b)), "%s %s", type_to_string(a), type_to_string(b)); } -#endif + + // if (is_type_boolean(a)) { + // return ir_emit(p, ir_instr_store_bool(p, address, value, false)); + // } return ir_emit(p, ir_instr_store(p, address, value, false)); } irValue *ir_emit_load(irProcedure *p, irValue *address) { GB_ASSERT(address != nullptr); + Type *t = type_deref(ir_type(address)); + // if (is_type_boolean(t)) { + // return ir_emit(p, ir_instr_load_bool(p, address)); + // } return ir_emit(p, ir_instr_load(p, address)); } irValue *ir_emit_select(irProcedure *p, irValue *cond, irValue *t, irValue *f) { return ir_emit(p, ir_instr_select(p, cond, t, f)); } -irValue *ir_emit_zero_init(irProcedure *p, irValue *address) { - return ir_emit(p, ir_instr_zero_init(p, address)); +irValue *ir_emit_zero_init(irProcedure *p, irValue *address) { + gbAllocator a = p->module->allocator; + Type *t = type_deref(ir_type(address)); + irValue **args = gb_alloc_array(a, irValue *, 2); + args[0] = ir_emit_conv(p, address, t_rawptr); + args[1] = ir_const_int(a, type_size_of(a, t)); + return ir_emit_global_call(p, "__mem_zero", args, 2); + // return ir_emit(p, ir_instr_zero_init(p, address)); } irValue *ir_emit_comment(irProcedure *p, String text) { @@ -1626,6 +1643,8 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, irValue **args, isize arg_ } } else if (is_type_integer(new_type)) { args[i] = ir_emit_transmute(p, args[i], new_type); + } else if (new_type == t_llvm_bool) { + args[i] = ir_emit_conv(p, args[i], new_type); } } } @@ -2446,7 +2465,6 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal } } - Type *result = t_bool; if (is_type_array(a)) { ir_emit_comment(proc, str_lit("array.comp.begin")); defer (ir_emit_comment(proc, str_lit("array.comp.end"))); @@ -2468,10 +2486,10 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal irValue *x = ir_emit_load(proc, ir_emit_array_epi(proc, lhs, i)); irValue *y = ir_emit_load(proc, ir_emit_array_epi(proc, rhs, i)); irValue *cmp = ir_emit_comp(proc, op_kind, x, y); - res = ir_emit_arith(proc, cmp_op, res, cmp, result); + res = ir_emit_arith(proc, cmp_op, res, cmp, t_bool); } - return ir_emit_conv(proc, res, result); + return ir_emit_conv(proc, res, t_bool); } if (is_type_string(a)) { @@ -2518,7 +2536,7 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal } - return ir_emit(proc, ir_instr_binary_op(proc, op_kind, left, right, result)); + return ir_emit(proc, ir_instr_binary_op(proc, op_kind, left, right, t_llvm_bool)); } irValue *ir_emit_array_ep(irProcedure *proc, irValue *s, irValue *index) { @@ -3036,6 +3054,14 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { return ir_emit(proc, ir_instr_conv(proc, kind, value, src_type, t)); } + // bool <-> llvm bool + if (is_type_boolean(src) && dst == t_llvm_bool) { + return ir_emit(proc, ir_instr_conv(proc, irConv_trunc, value, src_type, t)); + } + if (src == t_llvm_bool && is_type_boolean(dst)) { + return ir_emit(proc, ir_instr_conv(proc, irConv_zext, value, src_type, t)); + } + // boolean -> integer if (is_type_boolean(src) && is_type_integer(dst)) { return ir_emit(proc, ir_instr_conv(proc, irConv_zext, value, src_type, t)); @@ -8195,7 +8221,9 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info irValue *ptr = ir_emit_union_tag_ptr(proc, variant_ptr); ir_emit_store(proc, ptr, tag); } else { - GB_PANIC("Unhandled Type_Info variant: %s", type_to_string(t)); + if (t != t_llvm_bool) { + GB_PANIC("Unhandled Type_Info variant: %s", type_to_string(t)); + } } } } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 2c341ad57..c3176bde3 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -193,7 +193,7 @@ void ir_print_encoded_global(irFileBuffer *f, String name, bool remove_prefix) { ir_print_escape_string(f, name, true, !remove_prefix); } -void ir_print_type(irFileBuffer *f, irModule *m, Type *t); +void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct = false); void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hint); @@ -260,7 +260,7 @@ void ir_print_proc_type_without_pointer(irFileBuffer *f, irModule *m, Type *t) { ir_write_byte(f, ')'); } -void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { +void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) { i64 word_bits = 8*build_context.word_size; GB_ASSERT_NOT_NULL(t); t = default_type(t); @@ -269,7 +269,9 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { switch (t->kind) { case Type_Basic: switch (t->Basic.kind) { - case Basic_bool: ir_write_string(f, "i1"); return; + case Basic_bool: ir_write_string(f, "i8"); return; + case Basic_llvm_bool: ir_write_string(f, "i1"); return; + case Basic_i8: ir_write_string(f, "i8"); return; case Basic_u8: ir_write_string(f, "i8"); return; case Basic_i16: ir_write_string(f, "i16"); return; @@ -370,7 +372,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { if (i > 0) { ir_write_string(f, str_lit(", ")); } - ir_print_type(f, m, t->Struct.fields[i]->type); + ir_print_type(f, m, t->Struct.fields[i]->type, true); } ir_write_byte(f, '}'); if (t->Struct.is_packed) { @@ -487,9 +489,9 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * switch (value.kind) { case ExactValue_Bool: if (value.value_bool) { - ir_write_string(f, "true"); + ir_write_string(f, type == t_llvm_bool ? "true" : "1"); } else { - ir_write_string(f, "false"); + ir_write_string(f, type == t_llvm_bool ? "false" : "0"); } break; case ExactValue_String: { @@ -975,7 +977,6 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { ir_fprintf(f, ", align %lld\n", type_align_of(m->allocator, type)); break; } - case irInstr_ArrayElementPtr: { Type *et = ir_type(instr->ArrayElementPtr.address); ir_fprintf(f, "%%%d = getelementptr inbounds ", value->index); @@ -1108,13 +1109,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { ir_print_type(f, m, t_int); ir_write_string(f, " 0, "); ir_print_type(f, m, t_i32); - #if 1 - ir_fprintf(f, " 2"); - #else - ir_fprintf(f, " %d", 2); - #endif - ir_write_string(f, " ; UnionTagPtr"); - ir_write_byte(f, '\n'); + ir_fprintf(f, " 2 ; UnionTagPtr\n"); break; } @@ -1127,14 +1122,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { ir_print_type(f, m, et); ir_write_byte(f, ' '); ir_print_value(f, m, instr->UnionTagValue.address, et); - ir_write_byte(f, ','); - #if 1 - ir_fprintf(f, " 2"); - #else - ir_fprintf(f, " %d", 2); - #endif - ir_write_string(f, " ; UnionTagValue"); - ir_write_byte(f, '\n'); + ir_fprintf(f, ", 2 ; UnionTagValue\n"); break; } @@ -1146,8 +1134,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { } case irInstr_If: {; - ir_write_string(f, "br "); - ir_print_type(f, m, t_bool); + ir_write_string(f, "br i1"); ir_write_byte(f, ' '); ir_print_value(f, m, instr->If.cond, t_bool); ir_write_string(f, ", "); @@ -1381,6 +1368,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { } ir_write_byte(f, ' '); irValue *arg = call->args[i]; + if (is_type_boolean(t)) { + + } ir_print_value(f, m, arg, t); param_index++; } diff --git a/src/types.cpp b/src/types.cpp index 34ba4cddc..83918bc37 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -4,6 +4,7 @@ struct AstNode; enum BasicKind { Basic_Invalid, + Basic_llvm_bool, Basic_bool, Basic_i8, Basic_u8, @@ -236,6 +237,8 @@ void selection_add_index(Selection *s, isize index) { gb_global Type basic_types[] = { {Type_Basic, {Basic_Invalid, 0, 0, STR_LIT("invalid type")}}, + {Type_Basic, {Basic_llvm_bool, BasicFlag_Boolean, 1, STR_LIT("llvm bool")}}, + {Type_Basic, {Basic_bool, BasicFlag_Boolean, 1, STR_LIT("bool")}}, {Type_Basic, {Basic_i8, BasicFlag_Integer, 1, STR_LIT("i8")}}, @@ -283,6 +286,7 @@ gb_global Type basic_types[] = { // }; gb_global Type *t_invalid = &basic_types[Basic_Invalid]; +gb_global Type *t_llvm_bool = &basic_types[Basic_llvm_bool]; gb_global Type *t_bool = &basic_types[Basic_bool]; gb_global Type *t_i8 = &basic_types[Basic_i8]; gb_global Type *t_u8 = &basic_types[Basic_u8];