diff options
| author | gingerBill <bill@gingerbill.org> | 2019-02-10 20:51:19 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2019-02-10 20:51:19 +0000 |
| commit | e2d46676395ae813312652269b5f5ef0aaa3fe06 (patch) | |
| tree | d320650bc5965bee85c41f5a8a4a89cc91b2c128 /src | |
| parent | b74d828af713f3284a46c0bd643836f17034455d (diff) | |
Fix data layout issue on Windows; Remove unused loads in SSA
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_type.cpp | 10 | ||||
| -rw-r--r-- | src/ir.cpp | 316 | ||||
| -rw-r--r-- | src/ir_opt.cpp | 1 | ||||
| -rw-r--r-- | src/ir_print.cpp | 36 |
4 files changed, 276 insertions, 87 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp index 3eeb40777..953eebdda 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1945,11 +1945,11 @@ bool abi_compat_return_by_value(gbAllocator a, ProcCallingConvention cc, Type *a if (abi_return_type == nullptr) { return false; } - switch (cc) { - case ProcCC_Odin: - case ProcCC_Contextless: - return false; - } + // switch (cc) { + // case ProcCC_Odin: + // case ProcCC_Contextless: + // return false; + // } if (build_context.ODIN_OS == "windows") { diff --git a/src/ir.cpp b/src/ir.cpp index 32c2c7d64..c0bb6d462 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -147,6 +147,11 @@ struct irProcedure { Array<irContextData> context_stack; + irValue *return_ptr_hint_value; + Ast * return_ptr_hint_ast; + bool return_ptr_hint_used; + + Array<irBranchBlocks> branch_blocks; i32 local_count; @@ -180,7 +185,7 @@ gbAllocator ir_allocator(void) { i64 alignment; \ }) \ IR_INSTR_KIND(ZeroInit, struct { irValue *address; }) \ - IR_INSTR_KIND(Store, struct { irValue *address, *value; }) \ + IR_INSTR_KIND(Store, struct { irValue *address, *value; bool is_volatile; }) \ IR_INSTR_KIND(Load, struct { Type *type; irValue *address; }) \ IR_INSTR_KIND(AtomicFence, struct { BuiltinProcId id; }) \ IR_INSTR_KIND(AtomicStore, struct { \ @@ -442,6 +447,7 @@ struct irValue { i32 index; bool index_set; irDebugInfo * loc; + isize uses; union { irValueConstant Constant; irValueConstantSlice ConstantSlice; @@ -841,7 +847,7 @@ Array<irValue *> *ir_value_referrers(irValue *v) { void ir_module_add_value (irModule *m, Entity *e, irValue *v); void ir_emit_zero_init (irProcedure *p, irValue *address, Ast *expr); irValue *ir_emit_comment (irProcedure *p, String text); -irValue *ir_emit_store (irProcedure *p, irValue *address, irValue *value); +irValue *ir_emit_store (irProcedure *p, irValue *address, irValue *value, bool is_volatile=false); irValue *ir_emit_load (irProcedure *p, irValue *address); void ir_emit_jump (irProcedure *proc, irBlock *block); irValue *ir_emit_conv (irProcedure *proc, irValue *value, Type *t); @@ -901,6 +907,8 @@ irValue *ir_value_global(Entity *e, irValue *value) { v->Global.type = alloc_type_pointer(e->type); v->Global.value = value; array_init(&v->Global.referrers, ir_allocator()); // TODO(bill): Replace heap allocator here + + if (value) value->uses += 1; return v; } irValue *ir_value_param(irProcedure *parent, Entity *e, Type *abi_type) { @@ -988,14 +996,20 @@ 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; + + if (address) address->uses += 1; return v; } -irValue *ir_instr_store(irProcedure *p, irValue *address, irValue *value) { +irValue *ir_instr_store(irProcedure *p, irValue *address, irValue *value, bool is_volatile) { irValue *v = ir_alloc_instr(p, irInstr_Store); irInstr *i = &v->Instr; i->Store.address = address; i->Store.value = value; + i->Store.is_volatile = is_volatile; + + if (address) address->uses += 1; + if (value) value->uses += 1; return v; } @@ -1004,6 +1018,9 @@ irValue *ir_instr_load(irProcedure *p, irValue *address) { irInstr *i = &v->Instr; i->Load.address = address; i->Load.type = type_deref(ir_type(address)); + + if (address) address->uses += 1; + return v; } @@ -1020,6 +1037,10 @@ irValue *ir_instr_atomic_store(irProcedure *p, irValue *address, irValue *value, i->AtomicStore.address = address; i->AtomicStore.value = value; i->AtomicStore.id = id; + + if (address) address->uses += 1; + if (value) value->uses += 1; + return v; } @@ -1029,6 +1050,9 @@ irValue *ir_instr_atomic_load(irProcedure *p, irValue *address, BuiltinProcId id i->AtomicLoad.address = address; i->AtomicLoad.type = type_deref(ir_type(address)); i->AtomicLoad.id = id; + + if (address) address->uses += 1; + return v; } @@ -1039,6 +1063,10 @@ irValue *ir_instr_atomic_rmw(irProcedure *p, irValue *address, irValue *value, B i->AtomicRmw.address = address; i->AtomicRmw.value = value; i->AtomicRmw.id = id; + + if (address) address->uses += 1; + if (value) value->uses += 1; + return v; } @@ -1066,6 +1094,12 @@ irValue *ir_instr_atomic_cxchg(irProcedure *p, Type *type, irValue *address, irV i->AtomicCxchg.old_value = old_value; i->AtomicCxchg.new_value = new_value; i->AtomicCxchg.id = id; + + + if (address) address->uses += 1; + if (old_value) old_value->uses += 1; + if (new_value) new_value->uses += 1; + return v; } @@ -1083,6 +1117,9 @@ irValue *ir_instr_array_element_ptr(irProcedure *p, irValue *address, irValue *e i->ArrayElementPtr.elem_index = elem_index; i->ArrayElementPtr.result_type = result_type; + if (address) address->uses += 1; + if (elem_index) elem_index->uses += 1; + GB_ASSERT_MSG(is_type_pointer(ir_type(address)), "%s", type_to_string(ir_type(address))); return v; @@ -1094,6 +1131,8 @@ irValue *ir_instr_struct_element_ptr(irProcedure *p, irValue *address, i32 elem_ i->StructElementPtr.elem_index = elem_index; i->StructElementPtr.result_type = result_type; + if (address) address->uses += 1; + GB_ASSERT_MSG(is_type_pointer(ir_type(address)), "%s", type_to_string(ir_type(address))); return v; @@ -1104,6 +1143,10 @@ irValue *ir_instr_ptr_offset(irProcedure *p, irValue *address, irValue *offset) i->PtrOffset.address = address; i->PtrOffset.offset = offset; + if (address) address->uses += 1; + if (offset) offset->uses += 1; + + GB_ASSERT_MSG(is_type_pointer(ir_type(address)), "%s", type_to_string(ir_type(address))); GB_ASSERT_MSG(is_type_integer(ir_type(offset)), @@ -1120,6 +1163,9 @@ irValue *ir_instr_struct_extract_value(irProcedure *p, irValue *address, i32 ind i->StructExtractValue.address = address; i->StructExtractValue.index = index; i->StructExtractValue.result_type = result_type; + + if (address) address->uses += 1; + return v; } @@ -1127,6 +1173,9 @@ irValue *ir_instr_union_tag_ptr(irProcedure *p, irValue *address) { irValue *v = ir_alloc_instr(p, irInstr_UnionTagPtr); irInstr *i = &v->Instr; i->UnionTagPtr.address = address; + + if (address) address->uses += 1; + // i->UnionTagPtr.type = alloc_type_pointer(t_type_info_ptr); Type *u = type_deref(ir_type(address)); i->UnionTagPtr.type = alloc_type_pointer(union_tag_type(u)); @@ -1137,8 +1186,9 @@ irValue *ir_instr_union_tag_value(irProcedure *p, irValue *address) { irValue *v = ir_alloc_instr(p, irInstr_UnionTagValue); irInstr *i = &v->Instr; i->UnionTagValue.address = address; - // i->UnionTagValue.type = t_type_info_ptr; - // i->UnionTagValue.type = t_int; + + if (address) address->uses += 1; + Type *u = type_deref(ir_type(address)); i->UnionTagPtr.type = union_tag_type(u); return v; @@ -1150,6 +1200,8 @@ irValue *ir_instr_unary_op(irProcedure *p, TokenKind op, irValue *expr, Type *ty i->UnaryOp.op = op; i->UnaryOp.expr = expr; i->UnaryOp.type = type; + + if (expr) expr->uses += 1; return v; } @@ -1161,6 +1213,10 @@ irValue *ir_instr_binary_op(irProcedure *p, TokenKind op, irValue *left, irValue i->BinaryOp.left = left; i->BinaryOp.right = right; i->BinaryOp.type = type; + + if (left) left->uses += 1; + if (right) right->uses += 1; + return v; } @@ -1185,6 +1241,10 @@ irValue *ir_instr_phi(irProcedure *p, Array<irValue *> edges, Type *type) { irInstr *i = &v->Instr; i->Phi.edges = edges; i->Phi.type = type; + + for_array(j, edges) { + edges[j]->uses += 1; + } return v; } @@ -1196,6 +1256,9 @@ irValue *ir_instr_unreachable(irProcedure *p) { irValue *ir_instr_return(irProcedure *p, irValue *value) { irValue *v = ir_alloc_instr(p, irInstr_Return); v->Instr.Return.value = value; + + if (value) value->uses += 1; + return v; } @@ -1204,6 +1267,11 @@ irValue *ir_instr_select(irProcedure *p, irValue *cond, irValue *t, irValue *f) v->Instr.Select.cond = cond; v->Instr.Select.true_value = t; v->Instr.Select.false_value = f; + + if (cond) cond->uses += 1; + if (t) t->uses += 1; + if (f) f->uses += 1; + return v; } @@ -1215,6 +1283,14 @@ irValue *ir_instr_call(irProcedure *p, irValue *value, irValue *return_ptr, Arra v->Instr.Call.type = result_type; v->Instr.Call.context_ptr = context_ptr; v->Instr.Call.inlining = inlining; + + if (value) value->uses += 1; + if (return_ptr) return_ptr->uses += 1; + for_array(i, args) { + args[i]->uses += 1; + } + if (context_ptr) context_ptr->uses += 1; + return v; } @@ -1224,6 +1300,9 @@ irValue *ir_instr_conv(irProcedure *p, irConvKind kind, irValue *value, Type *fr v->Instr.Conv.value = value; v->Instr.Conv.from = from; v->Instr.Conv.to = to; + + if (value) value->uses += 1; + return v; } @@ -1239,6 +1318,9 @@ irValue *ir_instr_debug_declare(irProcedure *p, Ast *expr, Entity *entity, bool v->Instr.DebugDeclare.entity = entity; v->Instr.DebugDeclare.is_addr = is_addr; v->Instr.DebugDeclare.value = value; + + if (value) value->uses += 1; + return v; } @@ -1257,6 +1339,9 @@ irValue *ir_value_constant_slice(Type *type, irValue *backing_array, i64 count) v->ConstantSlice.type = type; v->ConstantSlice.backing_array = backing_array; v->ConstantSlice.count = count; + + if (backing_array) backing_array->uses += 1; + return v; } @@ -2683,7 +2768,7 @@ irValue *ir_emit_runtime_call(irProcedure *proc, char irValue *ir_emit_package_call(irProcedure *proc, char const *package_name_, char const *name_, Array<irValue *> args, Ast *expr = nullptr, ProcInlining inlining = ProcInlining_none); -irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) { +irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value, bool is_volatile) { Type *a = type_deref(ir_type(address)); if (is_type_boolean(a)) { @@ -2691,11 +2776,15 @@ irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) { value = ir_emit_conv(p, value, a); } + address->uses += 1; + value->uses += 1; + + 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)); } - return ir_emit(p, ir_instr_store(p, address, value)); + return ir_emit(p, ir_instr_store(p, address, value, is_volatile)); } irValue *ir_emit_load(irProcedure *p, irValue *address) { GB_ASSERT(address != nullptr); @@ -2703,9 +2792,14 @@ irValue *ir_emit_load(irProcedure *p, irValue *address) { // if (is_type_boolean(t)) { // return ir_emit(p, ir_instr_load_bool(p, address)); // } + address->uses += 1; return ir_emit(p, ir_instr_load(p, address)); } irValue *ir_emit_select(irProcedure *p, irValue *cond, irValue *t, irValue *f) { + cond->uses += 1; + t->uses += 1; + f->uses += 1; + return ir_emit(p, ir_instr_select(p, cond, t, f)); } @@ -2741,6 +2835,9 @@ void ir_emit_zero_init(irProcedure *p, irValue *address, Ast *expr) { gbAllocator a = ir_allocator(); Type *t = type_deref(ir_type(address)); isize sz = type_size_of(t); + + address->uses += 1; + if (!(gb_is_power_of_two(sz) && sz <= build_context.max_align)) { // TODO(bill): Is this a good idea? auto args = array_make<irValue *>(a, 2); @@ -2748,7 +2845,9 @@ void ir_emit_zero_init(irProcedure *p, irValue *address, Ast *expr) { args[1] = ir_const_int(type_size_of(t)); AstPackage *pkg = get_core_package(p->module->info, str_lit("mem")); if (p->entity != nullptr && p->entity->token.string != "zero" && p->entity->pkg != pkg) { - irValue *v = ir_emit_package_call(p, "mem", "zero", args, expr, ProcInlining_no_inline); + ir_emit_comment(p, str_lit("ZeroInit")); + irValue *v = ir_emit_package_call(p, "mem", "zero", args, expr); + return; } } ir_emit(p, ir_instr_zero_init(p, address)); @@ -2779,10 +2878,14 @@ irValue *ir_copy_value_to_ptr(irProcedure *proc, irValue *val, Type *new_type, i irValue *ptr = ir_add_local_generated(proc, new_type, false); ptr->Instr.Local.alignment = alignment; ir_emit_store(proc, ptr, val); + + val->uses += 1; + return ptr; } irValue *ir_emit_bitcast(irProcedure *proc, irValue *data, Type *type) { + data->uses += 1; return ir_emit(proc, ir_instr_conv(proc, irConv_bitcast, data, ir_type(data), type)); } @@ -2843,7 +2946,7 @@ Array<irValue *> ir_value_to_array(irProcedure *p, irValue *value) { } -irValue *ir_emit_call(irProcedure *p, irValue *value, Array<irValue *> args, ProcInlining inlining = ProcInlining_none) { +irValue *ir_emit_call(irProcedure *p, irValue *value, Array<irValue *> args, ProcInlining inlining = ProcInlining_none, bool use_return_ptr_hint = false) { Type *pt = base_type(ir_type(value)); GB_ASSERT(pt->kind == Type_Proc); Type *results = pt->Proc.results; @@ -2894,7 +2997,17 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, Array<irValue *> args, Pro Type *abi_rt = pt->Proc.abi_compat_result_type; Type *rt = reduce_tuple_to_single_type(results); if (pt->Proc.return_by_pointer) { - irValue *return_ptr = ir_add_local_generated(p, rt, true); + irValue *return_ptr = nullptr; + if (use_return_ptr_hint) { + if (are_types_identical(type_deref(ir_type(p->return_ptr_hint_value)), rt)) { + return_ptr = p->return_ptr_hint_value; + p->return_ptr_hint_used = true; + return_ptr->uses += 1; + } + } + if (return_ptr == nullptr) { + return_ptr = ir_add_local_generated(p, rt, true); + } GB_ASSERT(is_type_pointer(ir_type(return_ptr))); ir_emit(p, ir_instr_call(p, value, return_ptr, args, nullptr, context_ptr, inlining)); result = ir_emit_load(p, return_ptr); @@ -3245,7 +3358,7 @@ void ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) { } irValue *ptr = ir_emit_conv(proc, bytes, alloc_type_pointer(int_type)); v = ir_emit_arith(proc, Token_Or, ir_emit_load(proc, ptr), v, int_type); - ir_emit_store(proc, ptr, v); + ir_emit_store(proc, ptr, v, true); return; } @@ -3257,7 +3370,7 @@ void ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) { irValue *v = ir_emit_conv(proc, value, t_u8); v = ir_emit_arith(proc, Token_Shl, v, shift_amount, int_type); v = ir_emit_arith(proc, Token_Or, ir_emit_load(proc, bytes), v, int_type); - ir_emit_store(proc, bytes, v); + ir_emit_store(proc, bytes, v, true); } @@ -3267,7 +3380,7 @@ void ir_addr_store(irProcedure *proc, irAddr const &addr, irValue *value) { irValue *ptr = ir_emit_conv(proc, ir_emit_ptr_offset(proc, bytes, v_one), alloc_type_pointer(int_type)); irValue *v = ir_emit_arith(proc, Token_Shr, value, shift_amount, int_type); v = ir_emit_arith(proc, Token_Or, ir_emit_load(proc, ptr), v, int_type); - ir_emit_store(proc, ptr, v); + ir_emit_store(proc, ptr, v, true); return; } } else if (addr.kind == irAddr_Context) { @@ -6492,7 +6605,8 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { } } } - return ir_emit_call(proc, value, args, ce->inlining); + + return ir_emit_call(proc, value, args, ce->inlining, proc->return_ptr_hint_ast == expr); } isize arg_index = 0; @@ -6686,7 +6800,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { } auto call_args = array_slice(args, 0, final_count); - return ir_emit_call(proc, value, call_args, ce->inlining); + return ir_emit_call(proc, value, call_args, ce->inlining, proc->return_ptr_hint_ast == expr); case_end; case_ast_node(se, SliceExpr, expr); @@ -6756,6 +6870,14 @@ irAddr ir_build_addr_from_entity(irProcedure *proc, Entity *e, Ast *expr) { return ir_addr(v); } + +struct irCompoundLitElemTempData { + Ast *expr; + irValue *value; + i32 elem_index; + irValue *gep; +}; + irAddr ir_build_addr(irProcedure *proc, Ast *expr) { switch (expr->kind) { case_ast_node(i, Implicit, expr); @@ -7225,6 +7347,103 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) { break; } + case Type_Array: { + if (cl->elems.count > 0) { + // ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr))); + + auto temp_data = array_make<irCompoundLitElemTempData>(heap_allocator(), 0, cl->elems.count); + defer (array_free(&temp_data)); + + // NOTE(bill): Separate value, gep, store into their own chunks + for_array(i, cl->elems) { + Ast *elem = cl->elems[i]; + if (ir_is_elem_const(proc->module, elem, et)) { + continue; + } + irCompoundLitElemTempData data = {}; + data.expr = elem; + data.elem_index = cast(i32)i; + array_add(&temp_data, data); + } + + for_array(i, temp_data) { + temp_data[i].gep = ir_emit_array_epi(proc, v, temp_data[i].elem_index); + } + + for_array(i, temp_data) { + auto return_ptr_hint_ast = proc->return_ptr_hint_ast; + auto return_ptr_hint_value = proc->return_ptr_hint_value; + auto return_ptr_hint_used = proc->return_ptr_hint_used; + defer (proc->return_ptr_hint_ast = return_ptr_hint_ast); + defer (proc->return_ptr_hint_value = return_ptr_hint_value); + defer (proc->return_ptr_hint_used = return_ptr_hint_used); + + Ast *expr = temp_data[i].expr; + + proc->return_ptr_hint_value = temp_data[i].gep; + proc->return_ptr_hint_ast = unparen_expr(expr); + + irValue *field_expr = ir_build_expr(proc, expr); + Type *t = ir_type(field_expr); + GB_ASSERT(t->kind != Type_Tuple); + irValue *ev = ir_emit_conv(proc, field_expr, et); + + if (!proc->return_ptr_hint_used) { + temp_data[i].value = ev; + } + } + + for_array(i, temp_data) { + if (temp_data[i].value != nullptr) { + ir_emit_store(proc, temp_data[i].gep, temp_data[i].value, false); + } + } + } + break; + } + case Type_Slice: { + if (cl->elems.count > 0) { + Type *elem_type = bt->Slice.elem; + Type *elem_ptr_type = alloc_type_pointer(elem_type); + Type *elem_ptr_ptr_type = alloc_type_pointer(elem_ptr_type); + irValue *slice = ir_add_module_constant(proc->module, type, exact_value_compound(expr)); + GB_ASSERT(slice->kind == irValue_ConstantSlice); + + irValue *data = ir_emit_array_ep(proc, slice->ConstantSlice.backing_array, v_zero32); + + auto temp_data = array_make<irCompoundLitElemTempData>(heap_allocator(), 0, cl->elems.count); + defer (array_free(&temp_data)); + + for_array(i, cl->elems) { + Ast *elem = cl->elems[i]; + if (ir_is_elem_const(proc->module, elem, et)) { + continue; + } + irValue *field_expr = ir_build_expr(proc, elem); + Type *t = ir_type(field_expr); + GB_ASSERT(t->kind != Type_Tuple); + irValue *ev = ir_emit_conv(proc, field_expr, et); + + irCompoundLitElemTempData data = {}; + data.value = ev; + data.elem_index = cast(i32)i; + array_add(&temp_data, data); + } + + for_array(i, temp_data) { + temp_data[i].gep = ir_emit_ptr_offset(proc, data, ir_const_int(temp_data[i].elem_index)); + } + + for_array(i, temp_data) { + ir_emit_store(proc, temp_data[i].gep, temp_data[i].value); + } + + irValue *count = ir_const_int(slice->ConstantSlice.count); + ir_fill_slice(proc, v, data, count); + } + break; + } + case Type_DynamicArray: { if (cl->elems.count == 0) { break; @@ -7266,54 +7485,6 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) { break; } - case Type_Array: { - if (cl->elems.count > 0) { - ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr))); - for_array(i, cl->elems) { - Ast *elem = cl->elems[i]; - if (ir_is_elem_const(proc->module, elem, et)) { - continue; - } - irValue *field_expr = ir_build_expr(proc, elem); - Type *t = ir_type(field_expr); - GB_ASSERT(t->kind != Type_Tuple); - irValue *ev = ir_emit_conv(proc, field_expr, et); - irValue *gep = ir_emit_array_epi(proc, v, cast(i32)i); - ir_emit_store(proc, gep, ev); - } - } - break; - } - case Type_Slice: { - if (cl->elems.count > 0) { - Type *elem_type = bt->Slice.elem; - Type *elem_ptr_type = alloc_type_pointer(elem_type); - Type *elem_ptr_ptr_type = alloc_type_pointer(elem_ptr_type); - irValue *slice = ir_add_module_constant(proc->module, type, exact_value_compound(expr)); - GB_ASSERT(slice->kind == irValue_ConstantSlice); - - irValue *data = ir_emit_array_ep(proc, slice->ConstantSlice.backing_array, v_zero32); - - for_array(i, cl->elems) { - Ast *elem = cl->elems[i]; - if (ir_is_elem_const(proc->module, elem, et)) { - continue; - } - - irValue *field_expr = ir_build_expr(proc, elem); - Type *t = ir_type(field_expr); - GB_ASSERT(t->kind != Type_Tuple); - irValue *ev = ir_emit_conv(proc, field_expr, elem_type); - irValue *offset = ir_emit_ptr_offset(proc, data, ir_const_int(i)); - ir_emit_store(proc, offset, ev); - } - - irValue *count = ir_const_int(slice->ConstantSlice.count); - ir_fill_slice(proc, v, data, count); - } - break; - } - case Type_Basic: { GB_ASSERT(is_type_any(bt)); if (cl->elems.count > 0) { @@ -8908,6 +9079,23 @@ void ir_begin_procedure_body(irProcedure *proc) { } +void ir_remove_dead_instr(irProcedure *proc) { + for_array(i, proc->blocks) { + irBlock *b = proc->blocks[i]; + b->index = cast(i32)i; + for (isize j = 0; j < b->instrs.count; j += 1) { + irValue *value = b->instrs[j]; + GB_ASSERT_MSG(value->kind == irValue_Instr, "%.*s", LIT(proc->name)); + irInstr *instr = &value->Instr; + if (instr->kind == irInstr_Load && value->uses == 0) { + gb_memmove(b->instrs.data+j, b->instrs.data+j+1, gb_size_of(irValue *)*(b->instrs.count-j-1)); + b->instrs.count -= 1; + continue; + } + } + } +} + void ir_end_procedure_body(irProcedure *proc) { if (proc->type->Proc.result_count == 0) { ir_emit_return(proc, nullptr); @@ -8923,6 +9111,8 @@ void ir_end_procedure_body(irProcedure *proc) { ir_emit_jump(proc, proc->entry_block); proc->curr_block = nullptr; + ir_remove_dead_instr(proc); + ir_number_proc_registers(proc); ir_pop_debug_location(proc->module); diff --git a/src/ir_opt.cpp b/src/ir_opt.cpp index b266ffa10..414cf4767 100644 --- a/src/ir_opt.cpp +++ b/src/ir_opt.cpp @@ -284,6 +284,7 @@ void ir_opt_build_referrers(irProcedure *proc) { irValue *instr = b->instrs[j]; array_clear(&ops); ir_opt_add_operands(&ops, &instr->Instr); + for_array(k, ops) { irValue *op = ops[k]; if (op == nullptr) { diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 0587a2977..0cde805d8 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -676,7 +676,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * ir_write_str_lit(f, "* "); ir_print_encoded_global(f, str_array->Global.entity->token.string, false); ir_write_str_lit(f, ", "); - ir_print_type(f, m, t_int); + ir_print_type(f, m, t_i32); ir_write_str_lit(f, " 0, i32 0)"); } else { // HACK NOTE(bill): This is a hack but it works because strings are created at the very end @@ -689,7 +689,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * ir_write_str_lit(f, "* "); ir_print_encoded_global(f, str_array->Global.entity->token.string, false); ir_write_str_lit(f, ", "); - ir_print_type(f, m, t_int); + ir_print_type(f, m, t_i32); ir_write_str_lit(f, " 0, i32 0), "); ir_print_type(f, m, t_int); ir_fprintf(f, " %lld}", cast(i64)str.len); @@ -985,9 +985,7 @@ void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hin ir_print_type(f, m, at); ir_write_str_lit(f, "* "); ir_print_value(f, m, cs->backing_array, at); - ir_write_str_lit(f, ", "); - ir_print_type(f, m, t_int); - ir_write_str_lit(f, " 0, i32 0), "); + ir_write_str_lit(f, ", i32 0, i32 0), "); ir_print_type(f, m, t_int); ir_fprintf(f, " %lld}", cs->count); } @@ -1061,6 +1059,7 @@ void ir_print_calling_convention(irFileBuffer *f, irModule *m, ProcCallingConven void ir_print_context_parameter_prefix(irFileBuffer *f, irModule *m) { ir_print_type(f, m, t_context_ptr); ir_write_str_lit(f, " noalias nonnull nocapture inreg "); + // ir_write_str_lit(f, " noalias nonnull nocapture "); } void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { @@ -1103,6 +1102,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { case irInstr_ZeroInit: { Type *type = type_deref(ir_type(instr->ZeroInit.address)); + ir_write_str_lit(f, "; ZeroInit\n\t"); ir_write_str_lit(f, "store "); ir_print_type(f, m, type); ir_write_byte(f, ' '); @@ -1116,6 +1116,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { case irInstr_Store: { Type *type = type_deref(ir_type(instr->Store.address)); ir_write_str_lit(f, "store "); + if (instr->Store.is_volatile) { + ir_write_str_lit(f, "volatile "); + } ir_print_type(f, m, type); ir_write_byte(f, ' '); ir_print_value(f, m, instr->Store.value, type); @@ -1417,9 +1420,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->ArrayElementPtr.address, et); - ir_write_str_lit(f, ", "); - ir_print_type(f, m, t_int); - ir_write_str_lit(f, " 0, "); + ir_write_str_lit(f, ", i32 0, "); irValue *index =instr->ArrayElementPtr.elem_index; Type *t = ir_type(index); @@ -1447,9 +1448,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->StructElementPtr.address, et); - ir_write_str_lit(f, ", "); - ir_print_type(f, m, t_int); - ir_write_str_lit(f, " 0, "); + ir_write_str_lit(f, ", i32 0, "); ir_print_type(f, m, t_i32); ir_fprintf(f, " %d", index); break; @@ -1779,9 +1778,10 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { ir_write_byte(f, ' '); ir_print_value(f, m, call->value, call->type); + bool return_by_pointer = proc_type->Proc.return_by_pointer; ir_write_byte(f, '('); - if (proc_type->Proc.return_by_pointer) { + if (return_by_pointer) { GB_ASSERT(call->return_ptr != nullptr); ir_print_type(f, m, proc_type->Proc.results); ir_write_str_lit(f, "* "); @@ -1850,7 +1850,7 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { } } if (proc_type->Proc.calling_convention == ProcCC_Odin) { - if (param_index > 0) ir_write_str_lit(f, ", "); + if (param_index > 0 || return_by_pointer) ir_write_str_lit(f, ", "); ir_print_context_parameter_prefix(f, m); ir_print_value(f, m, call->context_ptr, t_context_ptr); @@ -1952,7 +1952,6 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) { ir_print_encoded_global(f, proc->name, ir_print_is_proc_global(m, proc)); ir_write_byte(f, '('); - if (proc_type->return_by_pointer) { ir_print_type(f, m, reduce_tuple_to_single_type(proc_type->results)); ir_write_str_lit(f, "* sret noalias "); @@ -1993,7 +1992,7 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) { } } if (proc_type->calling_convention == ProcCC_Odin) { - if (param_index > 0) ir_write_str_lit(f, ", "); + if (param_index > 0 || proc_type->return_by_pointer) ir_write_str_lit(f, ", "); ir_print_context_parameter_prefix(f, m); ir_write_str_lit(f, "%__.context_ptr"); @@ -2098,10 +2097,6 @@ void ir_print_type_name(irFileBuffer *f, irModule *m, irValue *v) { ir_write_byte(f, '\n'); } -void foo_bar(void) { - -} - void print_llvm_ir(irGen *ir) { irModule *m = &ir->module; @@ -2115,6 +2110,9 @@ void print_llvm_ir(irGen *ir) { ir_write_str_lit(f, "target triple = \"x86_64-apple-macosx10.8\"\n\n"); } else if (build_context.ODIN_OS == "windows") { ir_fprintf(f, "target triple = \"x86%s-pc-windows-msvc\"\n\n", word_bits == 64 ? "_64" : ""); + if (word_bits == 64 && build_context.metrics.arch == TargetArch_amd64) { + ir_fprintf(f, "target datalayout = \"e-m:w-i64:64-f80:128-n8:16:32:64-S128\"\n\n"); + } } ir_print_encoded_local(f, str_lit("..opaque")); |