authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-01 01:56:06-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-30 17:11:14-04:00
log5e1003bc81466b8ca0e3a3adb613bac8f34f2712
treeef7de5e4cb6dfeaad96fee7b935e1459a6dce063
parent0ccd91faea5ec27a1dce9d3bae84e1feca7fc0ea
signature Commit is signed but in an unrecognized format.

no-copy semantics for basic runtime function call variable init

```zig export fn entry() void { var x: Foo = foo(); } ``` ```llvm define void @entry() #2 !dbg !37 { Entry: %x = alloca %Foo, align 4 call fastcc void @foo(%Foo* sret %x), !dbg !48 call void @llvm.dbg.declare(metadata %Foo* %x, metadata !41, metadata !DIExpression()), !dbg !49 ret void, !dbg !50 } ```

6 files changed, 521 insertions(+), 151 deletions(-)

BRANCH_TODO created+10
......@@ -0,0 +1,10 @@
1Scratch pad for stuff to do before merging master
2=================================================
3
4look at all the ir_gen_node ir_gen_node_extra calls and make sure result locations are properly propagated
5
6migrate all the alloca_list to alloca_gen_list
7
8migrate ir_build_var_decl_src to use ir_build_alloca_src and explicitly initialize
9
10inferred comptime
CMakeLists.txt+1
......@@ -6728,6 +6728,7 @@ add_custom_command(
67286728 "-Doutput-dir=${CMAKE_BINARY_DIR}"
67296729 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
67306730 DEPENDS
6731 zig0
67316732 "${CMAKE_SOURCE_DIR}/src-self-hosted/dep_tokenizer.zig"
67326733 "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"
67336734 "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"
src/all_types.hpp+76-6
......@@ -34,12 +34,14 @@ struct CodeGen;
3434struct ConstExprValue;
3535struct IrInstruction;
3636struct IrInstructionCast;
37struct IrInstructionAllocaGen;
3738struct IrBasicBlock;
3839struct ScopeDecls;
3940struct ZigWindowsSDK;
4041struct Tld;
4142struct TldExport;
4243struct IrAnalyze;
44struct ResultLoc;
4345
4446enum X64CABIClass {
4547 X64CABIClass_Unknown,
......@@ -1359,6 +1361,7 @@ struct ZigFn {
13591361 AstNode *fn_static_eval_set_node;
13601362
13611363 ZigList<IrInstruction *> alloca_list;
1364 ZigList<IrInstructionAllocaGen *> alloca_gen_list;
13621365 ZigList<ZigVar *> variable_list;
13631366
13641367 Buf *section_name;
......@@ -2171,7 +2174,9 @@ enum IrInstructionId {
21712174 IrInstructionIdUnionFieldPtr,
21722175 IrInstructionIdElemPtr,
21732176 IrInstructionIdVarPtr,
2174 IrInstructionIdCall,
2177 IrInstructionIdReturnPtr,
2178 IrInstructionIdCallSrc,
2179 IrInstructionIdCallGen,
21752180 IrInstructionIdConst,
21762181 IrInstructionIdReturn,
21772182 IrInstructionIdCast,
......@@ -2308,6 +2313,8 @@ enum IrInstructionId {
23082313 IrInstructionIdAssertNonNull,
23092314 IrInstructionIdHasDecl,
23102315 IrInstructionIdUndeclaredIdent,
2316 IrInstructionIdAllocaSrc,
2317 IrInstructionIdAllocaGen,
23112318};
23122319
23132320struct IrInstruction {
......@@ -2335,14 +2342,14 @@ struct IrInstructionDeclVarSrc {
23352342 ZigVar *var;
23362343 IrInstruction *var_type;
23372344 IrInstruction *align_value;
2338 IrInstruction *init_value;
2345 IrInstruction *ptr;
23392346};
23402347
23412348struct IrInstructionDeclVarGen {
23422349 IrInstruction base;
23432350
23442351 ZigVar *var;
2345 IrInstruction *init_value;
2352 IrInstruction *var_ptr;
23462353};
23472354
23482355struct IrInstructionCondBr {
......@@ -2528,14 +2535,21 @@ struct IrInstructionVarPtr {
25282535 ScopeFnDef *crossed_fndef_scope;
25292536};
25302537
2531struct IrInstructionCall {
2538// For functions that have a return type for which handle_is_ptr is true, a
2539// result location pointer is the secret first parameter ("sret"). This
2540// instruction returns that pointer.
2541struct IrInstructionReturnPtr {
2542 IrInstruction base;
2543};
2544
2545struct IrInstructionCallSrc {
25322546 IrInstruction base;
25332547
25342548 IrInstruction *fn_ref;
25352549 ZigFn *fn_entry;
25362550 size_t arg_count;
25372551 IrInstruction **args;
2538 LLVMValueRef tmp_ptr;
2552 ResultLoc *result_loc;
25392553
25402554 IrInstruction *async_allocator;
25412555 IrInstruction *new_stack;
......@@ -2544,6 +2558,21 @@ struct IrInstructionCall {
25442558 bool is_comptime;
25452559};
25462560
2561struct IrInstructionCallGen {
2562 IrInstruction base;
2563
2564 IrInstruction *fn_ref;
2565 ZigFn *fn_entry;
2566 size_t arg_count;
2567 IrInstruction **args;
2568 IrInstruction *result_loc;
2569
2570 IrInstruction *async_allocator;
2571 IrInstruction *new_stack;
2572 FnInline fn_inline;
2573 bool is_async;
2574};
2575
25472576struct IrInstructionConst {
25482577 IrInstruction base;
25492578};
......@@ -3527,6 +3556,47 @@ struct IrInstructionUndeclaredIdent {
35273556 Buf *name;
35283557};
35293558
3559struct IrInstructionAllocaSrc {
3560 IrInstruction base;
3561
3562 IrInstruction *align;
3563 IrInstruction *is_comptime;
3564 const char *name_hint;
3565};
3566
3567struct IrInstructionAllocaGen {
3568 IrInstruction base;
3569
3570 uint32_t align;
3571 const char *name_hint;
3572};
3573
3574enum ResultLocId {
3575 ResultLocIdInvalid,
3576 ResultLocIdNone,
3577 ResultLocIdVar,
3578 ResultLocIdReturn,
3579};
3580
3581struct ResultLoc {
3582 ResultLocId id;
3583 IrInstruction *source_instruction;
3584};
3585
3586struct ResultLocNone {
3587 ResultLoc base;
3588};
3589
3590struct ResultLocVar {
3591 ResultLoc base;
3592
3593 ZigVar *var;
3594};
3595
3596struct ResultLocReturn {
3597 ResultLoc base;
3598};
3599
35303600static const size_t slice_ptr_index = 0;
35313601static const size_t slice_len_index = 1;
35323602
......@@ -3574,7 +3644,7 @@ struct FnWalkAttrs {
35743644
35753645struct FnWalkCall {
35763646 ZigList<LLVMValueRef> *gen_param_values;
3577 IrInstructionCall *inst;
3647 IrInstructionCallGen *inst;
35783648 bool is_var_args;
35793649};
35803650
src/codegen.cpp+54-36
......@@ -1982,6 +1982,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
19821982}
19831983
19841984static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
1985 if (g->strip_debug_symbols) return;
19851986 assert(var->di_loc_var != nullptr);
19861987 AstNode *source_node = var->decl_node;
19871988 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1,
......@@ -2288,7 +2289,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
22882289 return;
22892290 }
22902291 if (fn_walk->id == FnWalkIdCall) {
2291 IrInstructionCall *instruction = fn_walk->data.call.inst;
2292 IrInstructionCallGen *instruction = fn_walk->data.call.inst;
22922293 bool is_var_args = fn_walk->data.call.is_var_args;
22932294 for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
22942295 IrInstruction *param_instruction = instruction->args[call_i];
......@@ -3328,10 +3329,8 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrI
33283329 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");
33293330}
33303331
3331static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
3332 IrInstructionDeclVarGen *decl_var_instruction)
3333{
3334 ZigVar *var = decl_var_instruction->var;
3332static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, IrInstructionDeclVarGen *instruction) {
3333 ZigVar *var = instruction->var;
33353334
33363335 if (!type_has_bits(var->var_type))
33373336 return nullptr;
......@@ -3339,20 +3338,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
33393338 if (var->ref_count == 0 && g->build_mode != BuildModeDebug)
33403339 return nullptr;
33413340
3342 IrInstruction *init_value = decl_var_instruction->init_value;
3343
3344 bool have_init_expr = !value_is_all_undef(&init_value->value);
3345
3346 if (have_init_expr) {
3347 ZigType *var_ptr_type = get_pointer_to_type_extra(g, var->var_type, false, false,
3348 PtrLenSingle, var->align_bytes, 0, 0, false);
3349 LLVMValueRef llvm_init_val = ir_llvm_value(g, init_value);
3350 gen_assign_raw(g, var->value_ref, var_ptr_type, llvm_init_val);
3351 } else if (ir_want_runtime_safety(g, &decl_var_instruction->base)) {
3352 uint32_t align_bytes = (var->align_bytes == 0) ? get_abi_alignment(g, var->var_type) : var->align_bytes;
3353 gen_undef_init(g, align_bytes, var->var_type, var->value_ref);
3354 }
3355
3341 var->value_ref = ir_llvm_value(g, instruction->var_ptr);
33563342 gen_var_debug_decl(g, var);
33573343 return nullptr;
33583344}
......@@ -3568,6 +3554,13 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrIn
35683554 }
35693555}
35703556
3557static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutable *executable,
3558 IrInstructionReturnPtr *instruction)
3559{
3560 assert(g->cur_ret_ptr != nullptr || !type_has_bits(instruction->base.value.type));
3561 return g->cur_ret_ptr;
3562}
3563
35713564static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrInstructionElemPtr *instruction) {
35723565 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);
35733566 ZigType *array_ptr_type = instruction->array_ptr->value.type;
......@@ -3719,7 +3712,7 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) {
37193712 LLVMAddCallSiteAttribute(call_instr, 1, sret_attr);
37203713}
37213714
3722static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
3715static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCallGen *instruction) {
37233716 LLVMValueRef fn_val;
37243717 ZigType *fn_type;
37253718 if (instruction->fn_entry) {
......@@ -3742,8 +3735,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
37423735 bool prefix_arg_err_ret_stack = get_prefix_arg_err_ret_stack(g, fn_type_id);
37433736 bool is_var_args = fn_type_id->is_var_args;
37443737 ZigList<LLVMValueRef> gen_param_values = {};
3738 LLVMValueRef result_loc = first_arg_ret ? ir_llvm_value(g, instruction->result_loc) : nullptr;
37453739 if (first_arg_ret) {
3746 gen_param_values.append(instruction->tmp_ptr);
3740 gen_param_values.append(result_loc);
37473741 }
37483742 if (prefix_arg_err_ret_stack) {
37493743 gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));
......@@ -3751,7 +3745,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
37513745 if (instruction->is_async) {
37523746 gen_param_values.append(ir_llvm_value(g, instruction->async_allocator));
37533747
3754 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
3748 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
37553749 gen_param_values.append(err_val_ptr);
37563750 }
37573751 FnWalk fn_walk = {};
......@@ -3794,9 +3788,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
37943788
37953789
37963790 if (instruction->is_async) {
3797 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");
3791 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
37983792 LLVMBuildStore(g->builder, result, payload_ptr);
3799 return instruction->tmp_ptr;
3793 return result_loc;
38003794 }
38013795
38023796 if (src_return_type->id == ZigTypeIdUnreachable) {
......@@ -3805,11 +3799,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
38053799 return nullptr;
38063800 } else if (first_arg_ret) {
38073801 set_call_instr_sret(g, result);
3808 return instruction->tmp_ptr;
3802 return result_loc;
38093803 } else if (handle_is_ptr(src_return_type)) {
3810 auto store_instr = LLVMBuildStore(g->builder, result, instruction->tmp_ptr);
3811 LLVMSetAlignment(store_instr, LLVMGetAlignment(instruction->tmp_ptr));
3812 return instruction->tmp_ptr;
3804 LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc);
3805 LLVMSetAlignment(store_instr, LLVMGetAlignment(result_loc));
3806 return result_loc;
38133807 } else {
38143808 return result;
38153809 }
......@@ -5535,7 +5529,9 @@ static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
55355529}
55365530
55375531static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
5538 set_debug_location(g, instruction);
5532 if (!g->strip_debug_symbols) {
5533 set_debug_location(g, instruction);
5534 }
55395535
55405536 switch (instruction->id) {
55415537 case IrInstructionIdInvalid:
......@@ -5608,8 +5604,13 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56085604 case IrInstructionIdGlobalAsm:
56095605 case IrInstructionIdHasDecl:
56105606 case IrInstructionIdUndeclaredIdent:
5607 case IrInstructionIdCallSrc:
5608 case IrInstructionIdAllocaSrc:
56115609 zig_unreachable();
56125610
5611 case IrInstructionIdAllocaGen:
5612 return nullptr;
5613
56135614 case IrInstructionIdDeclVarGen:
56145615 return ir_render_decl_var(g, executable, (IrInstructionDeclVarGen *)instruction);
56155616 case IrInstructionIdReturn:
......@@ -5632,10 +5633,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56325633 return ir_render_store_ptr(g, executable, (IrInstructionStorePtr *)instruction);
56335634 case IrInstructionIdVarPtr:
56345635 return ir_render_var_ptr(g, executable, (IrInstructionVarPtr *)instruction);
5636 case IrInstructionIdReturnPtr:
5637 return ir_render_return_ptr(g, executable, (IrInstructionReturnPtr *)instruction);
56355638 case IrInstructionIdElemPtr:
56365639 return ir_render_elem_ptr(g, executable, (IrInstructionElemPtr *)instruction);
5637 case IrInstructionIdCall:
5638 return ir_render_call(g, executable, (IrInstructionCall *)instruction);
5640 case IrInstructionIdCallGen:
5641 return ir_render_call(g, executable, (IrInstructionCallGen *)instruction);
56395642 case IrInstructionIdStructFieldPtr:
56405643 return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction);
56415644 case IrInstructionIdUnionFieldPtr:
......@@ -6851,6 +6854,26 @@ static void do_code_gen(CodeGen *g) {
68516854 }
68526855
68536856 // allocate temporary stack data
6857 for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_gen_list.length; alloca_i += 1) {
6858 IrInstructionAllocaGen *instruction = fn_table_entry->alloca_gen_list.at(alloca_i);
6859 ZigType *ptr_type = instruction->base.value.type;
6860 assert(ptr_type->id == ZigTypeIdPointer);
6861 ZigType *child_type = ptr_type->data.pointer.child_type;
6862 if (!type_has_bits(child_type))
6863 continue;
6864 if (instruction->base.ref_count == 0)
6865 continue;
6866 if (instruction->base.value.special != ConstValSpecialRuntime) {
6867 if (const_ptr_pointee(nullptr, g, &instruction->base.value, nullptr)->special !=
6868 ConstValSpecialRuntime)
6869 {
6870 continue;
6871 }
6872 }
6873 instruction->base.llvm_value = build_alloca(g, child_type, instruction->name_hint,
6874 get_ptr_align(g, ptr_type));
6875 }
6876
68546877 for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_list.length; alloca_i += 1) {
68556878 IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i);
68566879 LLVMValueRef *slot;
......@@ -6873,9 +6896,6 @@ static void do_code_gen(CodeGen *g) {
68736896 } else if (instruction->id == IrInstructionIdUnionInit) {
68746897 IrInstructionUnionInit *union_init_instruction = (IrInstructionUnionInit *)instruction;
68756898 slot = &union_init_instruction->tmp_ptr;
6876 } else if (instruction->id == IrInstructionIdCall) {
6877 IrInstructionCall *call_instruction = (IrInstructionCall *)instruction;
6878 slot = &call_instruction->tmp_ptr;
68796899 } else if (instruction->id == IrInstructionIdSlice) {
68806900 IrInstructionSlice *slice_instruction = (IrInstructionSlice *)instruction;
68816901 slot = &slice_instruction->tmp_ptr;
......@@ -6939,8 +6959,6 @@ static void do_code_gen(CodeGen *g) {
69396959 }
69406960
69416961 if (var->src_arg_index == SIZE_MAX) {
6942 var->value_ref = build_alloca(g, var->var_type, buf_ptr(&var->name), var->align_bytes);
6943
69446962 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
69456963 buf_ptr(&var->name), import->data.structure.root_struct->di_file, (unsigned)(var->decl_node->line + 1),
69466964 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
src/ir.cpp+298-103
......@@ -157,7 +157,8 @@ enum UndefAllowed {
157157};
158158
159159static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
160static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval);
160static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
161 ResultLoc *result_loc);
161162static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction);
162163static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type);
163164static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr);
......@@ -475,8 +476,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) {
475476 return IrInstructionIdVarPtr;
476477}
477478
478static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) {
479 return IrInstructionIdCall;
479static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnPtr *) {
480 return IrInstructionIdReturnPtr;
481}
482
483static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) {
484 return IrInstructionIdCallSrc;
485}
486
487static constexpr IrInstructionId ir_instruction_id(IrInstructionCallGen *) {
488 return IrInstructionIdCallGen;
480489}
481490
482491static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) {
......@@ -1019,6 +1028,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent
10191028 return IrInstructionIdUndeclaredIdent;
10201029}
10211030
1031static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaSrc *) {
1032 return IrInstructionIdAllocaSrc;
1033}
1034
1035static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaGen *) {
1036 return IrInstructionIdAllocaGen;
1037}
1038
10221039template<typename T>
10231040static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
10241041 T *special_instruction = allocate<T>(1);
......@@ -1254,6 +1271,13 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so
12541271 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr);
12551272}
12561273
1274static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) {
1275 IrInstructionReturnPtr *instruction = ir_build_instruction<IrInstructionReturnPtr>(&ira->new_irb,
1276 source_instruction->scope, source_instruction->source_node);
1277 instruction->base.value.type = ty;
1278 return &instruction->base;
1279}
1280
12571281static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr,
12581282 IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len)
12591283{
......@@ -1320,12 +1344,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast
13201344 return &instruction->base;
13211345}
13221346
1323static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,
1347static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
13241348 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
13251349 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator,
1326 IrInstruction *new_stack)
1350 IrInstruction *new_stack, ResultLoc *result_loc)
13271351{
1328 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);
1352 IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node);
13291353 call_instruction->fn_entry = fn_entry;
13301354 call_instruction->fn_ref = fn_ref;
13311355 call_instruction->is_comptime = is_comptime;
......@@ -1335,6 +1359,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
13351359 call_instruction->is_async = is_async;
13361360 call_instruction->async_allocator = async_allocator;
13371361 call_instruction->new_stack = new_stack;
1362 call_instruction->result_loc = result_loc;
13381363
13391364 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block);
13401365 for (size_t i = 0; i < arg_count; i += 1)
......@@ -1345,6 +1370,33 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
13451370 return &call_instruction->base;
13461371}
13471372
1373static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction,
1374 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
1375 FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack,
1376 IrInstruction *result_loc)
1377{
1378 IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb,
1379 source_instruction->scope, source_instruction->source_node);
1380 call_instruction->fn_entry = fn_entry;
1381 call_instruction->fn_ref = fn_ref;
1382 call_instruction->fn_inline = fn_inline;
1383 call_instruction->args = args;
1384 call_instruction->arg_count = arg_count;
1385 call_instruction->is_async = is_async;
1386 call_instruction->async_allocator = async_allocator;
1387 call_instruction->new_stack = new_stack;
1388 call_instruction->result_loc = result_loc;
1389
1390 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block);
1391 for (size_t i = 0; i < arg_count; i += 1)
1392 ir_ref_instruction(args[i], ira->new_irb.current_basic_block);
1393 if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block);
1394 if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block);
1395 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
1396
1397 return &call_instruction->base;
1398}
1399
13481400static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node,
13491401 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values)
13501402{
......@@ -1511,7 +1563,7 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *
15111563}
15121564
15131565static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
1514 ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value)
1566 ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *ptr)
15151567{
15161568 IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node);
15171569 decl_var_instruction->base.value.special = ConstValSpecialStatic;
......@@ -1519,26 +1571,26 @@ static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNod
15191571 decl_var_instruction->var = var;
15201572 decl_var_instruction->var_type = var_type;
15211573 decl_var_instruction->align_value = align_value;
1522 decl_var_instruction->init_value = init_value;
1574 decl_var_instruction->ptr = ptr;
15231575
15241576 if (var_type != nullptr) ir_ref_instruction(var_type, irb->current_basic_block);
15251577 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
1526 ir_ref_instruction(init_value, irb->current_basic_block);
1578 ir_ref_instruction(ptr, irb->current_basic_block);
15271579
15281580 return &decl_var_instruction->base;
15291581}
15301582
15311583static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction,
1532 ZigVar *var, IrInstruction *init_value)
1584 ZigVar *var, IrInstruction *var_ptr)
15331585{
15341586 IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb,
15351587 source_instruction->scope, source_instruction->source_node);
15361588 decl_var_instruction->base.value.special = ConstValSpecialStatic;
15371589 decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void;
15381590 decl_var_instruction->var = var;
1539 decl_var_instruction->init_value = init_value;
1591 decl_var_instruction->var_ptr = var_ptr;
15401592
1541 ir_ref_instruction(init_value, ira->new_irb.current_basic_block);
1593 ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block);
15421594
15431595 return &decl_var_instruction->base;
15441596}
......@@ -3109,6 +3161,32 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so
31093161 return &instruction->base;
31103162}
31113163
3164static IrInstruction *ir_build_alloca_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
3165 IrInstruction *align, const char *name_hint, IrInstruction *is_comptime)
3166{
3167 IrInstructionAllocaSrc *instruction = ir_build_instruction<IrInstructionAllocaSrc>(irb, scope, source_node);
3168 instruction->base.is_gen = true;
3169 instruction->align = align;
3170 instruction->name_hint = name_hint;
3171 instruction->is_comptime = is_comptime;
3172
3173 if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block);
3174 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block);
3175
3176 return &instruction->base;
3177}
3178
3179static IrInstructionAllocaGen *ir_create_alloca_gen(IrAnalyze *ira, IrInstruction *source_instruction,
3180 uint32_t align, const char *name_hint)
3181{
3182 IrInstructionAllocaGen *instruction = ir_create_instruction<IrInstructionAllocaGen>(&ira->new_irb,
3183 source_instruction->scope, source_instruction->source_node);
3184 instruction->align = align;
3185 instruction->name_hint = name_hint;
3186
3187 return instruction;
3188}
3189
31123190static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
31133191 results[ReturnKindUnconditional] = 0;
31143192 results[ReturnKindError] = 0;
......@@ -3321,12 +3399,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
33213399 switch (node->data.return_expr.kind) {
33223400 case ReturnKindUnconditional:
33233401 {
3402 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1);
3403 result_loc_ret->base.id = ResultLocIdReturn;
3404
33243405 IrInstruction *return_value;
33253406 if (expr_node) {
33263407 // Temporarily set this so that if we return a type it gets the name of the function
33273408 ZigFn *prev_name_fn = irb->exec->name_fn;
33283409 irb->exec->name_fn = exec_fn_entry(irb->exec);
3329 return_value = ir_gen_node(irb, expr_node, scope);
3410 return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base);
33303411 irb->exec->name_fn = prev_name_fn;
33313412 if (return_value == irb->codegen->invalid_instruction)
33323413 return irb->codegen->invalid_instruction;
......@@ -3373,17 +3454,21 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
33733454 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
33743455
33753456 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);
3376 return ir_gen_async_return(irb, scope, node, return_value, false);
3457 IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false);
3458 result_loc_ret->base.source_instruction = result;
3459 return result;
33773460 } else {
33783461 // generate unconditional defers
33793462 ir_gen_defers_for_block(irb, scope, outer_scope, false);
3380 return ir_gen_async_return(irb, scope, node, return_value, false);
3463 IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false);
3464 result_loc_ret->base.source_instruction = result;
3465 return result;
33813466 }
33823467 }
33833468 case ReturnKindError:
33843469 {
33853470 assert(expr_node);
3386 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
3471 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
33873472 if (err_union_ptr == irb->codegen->invalid_instruction)
33883473 return irb->codegen->invalid_instruction;
33893474 IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr);
......@@ -3592,7 +3677,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no
35923677}
35933678
35943679static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) {
3595 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr);
3680 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr);
35963681 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
35973682
35983683 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction)
......@@ -3603,7 +3688,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node)
36033688}
36043689
36053690static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
3606 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr);
3691 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr);
36073692 if (lvalue == irb->codegen->invalid_instruction)
36083693 return lvalue;
36093694 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue);
......@@ -3705,7 +3790,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
37053790 AstNode *op1_node = node->data.bin_op_expr.op1;
37063791 AstNode *op2_node = node->data.bin_op_expr.op2;
37073792
3708 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr);
3793 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr);
37093794 if (maybe_ptr == irb->codegen->invalid_instruction)
37103795 return irb->codegen->invalid_instruction;
37113796
......@@ -3968,7 +4053,7 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode
39684053 assert(node->type == NodeTypeArrayAccessExpr);
39694054
39704055 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
3971 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr);
4056 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr);
39724057 if (array_ref_instruction == irb->codegen->invalid_instruction)
39734058 return array_ref_instruction;
39744059
......@@ -3991,7 +4076,7 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode
39914076 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
39924077 Buf *field_name = node->data.field_access_expr.field_name;
39934078
3994 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr);
4079 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr);
39954080 if (container_ref_instruction == irb->codegen->invalid_instruction)
39964081 return container_ref_instruction;
39974082
......@@ -4041,7 +4126,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no
40414126 zig_unreachable();
40424127}
40434128
4044static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
4129static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
4130 ResultLoc *result_loc)
4131{
40454132 assert(node->type == NodeTypeFnCallExpr);
40464133
40474134 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
......@@ -4625,7 +4712,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46254712 case BuiltinFnIdField:
46264713 {
46274714 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4628 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr);
4715 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr);
46294716 if (arg0_value == irb->codegen->invalid_instruction)
46304717 return arg0_value;
46314718
......@@ -4855,7 +4942,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
48554942 }
48564943 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;
48574944
4858 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr);
4945 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
4946 fn_inline, false, nullptr, nullptr, result_loc);
48594947 return ir_lval_wrap(irb, scope, call, lval);
48604948 }
48614949 case BuiltinFnIdNewStackCall:
......@@ -4885,7 +4973,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
48854973 return args[i];
48864974 }
48874975
4888 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack);
4976 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
4977 FnInlineAuto, false, nullptr, new_stack, result_loc);
48894978 return ir_lval_wrap(irb, scope, call, lval);
48904979 }
48914980 case BuiltinFnIdTypeId:
......@@ -5148,11 +5237,13 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
51485237 zig_unreachable();
51495238}
51505239
5151static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
5240static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
5241 ResultLoc *result_loc)
5242{
51525243 assert(node->type == NodeTypeFnCallExpr);
51535244
51545245 if (node->data.fn_call_expr.is_builtin)
5155 return ir_gen_builtin_fn_call(irb, scope, node, lval);
5246 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);
51565247
51575248 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
51585249 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
......@@ -5178,8 +5269,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
51785269 }
51795270 }
51805271
5181 IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto,
5182 is_async, async_allocator, nullptr);
5272 IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto,
5273 is_async, async_allocator, nullptr, result_loc);
51835274 return ir_lval_wrap(irb, scope, fn_call, lval);
51845275}
51855276
......@@ -5244,7 +5335,7 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, Ast
52445335 assert(node->type == NodeTypePrefixOpExpr);
52455336 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
52465337
5247 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
5338 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr);
52485339 if (value == irb->codegen->invalid_instruction)
52495340 return value;
52505341
......@@ -5339,7 +5430,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
53395430static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node,
53405431 LVal lval)
53415432{
5342 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
5433 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
53435434 if (err_union_ptr == irb->codegen->invalid_instruction)
53445435 return irb->codegen->invalid_instruction;
53455436
......@@ -5384,7 +5475,7 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
53845475 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval);
53855476 case PrefixOpAddrOf: {
53865477 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
5387 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval);
5478 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval);
53885479 }
53895480 }
53905481 zig_unreachable();
......@@ -5486,17 +5577,27 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
54865577 // Parser should ensure that this never happens
54875578 assert(variable_declaration->threadlocal_tok == nullptr);
54885579
5580 IrInstruction *alloca = ir_build_alloca_src(irb, scope, node, align_value,
5581 buf_ptr(variable_declaration->symbol), is_comptime);
5582
5583 // Create a result location for the initialization expression.
5584 ResultLocVar *result_loc_var = allocate<ResultLocVar>(1);
5585 result_loc_var->base.id = ResultLocIdVar;
5586 result_loc_var->base.source_instruction = alloca;
5587 result_loc_var->var = var;
5588
54895589 // Temporarily set the name of the IrExecutable to the VariableDeclaration
54905590 // so that the struct or enum from the init expression inherits the name.
54915591 Buf *old_exec_name = irb->exec->name;
54925592 irb->exec->name = variable_declaration->symbol;
5493 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope);
5593 IrInstruction *init_value = ir_gen_node_extra(irb, variable_declaration->expr, scope, LValNone,
5594 &result_loc_var->base);
54945595 irb->exec->name = old_exec_name;
54955596
54965597 if (init_value == irb->codegen->invalid_instruction)
54975598 return init_value;
54985599
5499 return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, init_value);
5600 return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, alloca);
55005601}
55015602
55025603static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -5534,7 +5635,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
55345635 } else {
55355636 payload_scope = subexpr_scope;
55365637 }
5537 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr);
5638 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope,
5639 LValPtr, nullptr);
55385640 if (err_val_ptr == irb->codegen->invalid_instruction)
55395641 return err_val_ptr;
55405642 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr);
......@@ -5621,7 +5723,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
56215723 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol,
56225724 true, false, false, is_comptime);
56235725 Scope *child_scope = payload_var->child_scope;
5624 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr);
5726 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope,
5727 LValPtr, nullptr);
56255728 if (maybe_val_ptr == irb->codegen->invalid_instruction)
56265729 return maybe_val_ptr;
56275730 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr);
......@@ -5775,7 +5878,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
57755878 }
57765879 assert(elem_node->type == NodeTypeSymbol);
57775880
5778 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr);
5881 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr, nullptr);
57795882 if (array_val_ptr == irb->codegen->invalid_instruction)
57805883 return array_val_ptr;
57815884
......@@ -6182,7 +6285,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
61826285 AstNode *else_node = node->data.test_expr.else_node;
61836286 bool var_is_ptr = node->data.test_expr.var_is_ptr;
61846287
6185 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
6288 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
61866289 if (maybe_val_ptr == irb->codegen->invalid_instruction)
61876290 return maybe_val_ptr;
61886291
......@@ -6261,7 +6364,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
62616364 Buf *var_symbol = node->data.if_err_expr.var_symbol;
62626365 Buf *err_symbol = node->data.if_err_expr.err_symbol;
62636366
6264 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr);
6367 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr);
62656368 if (err_val_ptr == irb->codegen->invalid_instruction)
62666369 return err_val_ptr;
62676370
......@@ -6397,7 +6500,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
63976500 assert(node->type == NodeTypeSwitchExpr);
63986501
63996502 AstNode *target_node = node->data.switch_expr.expr;
6400 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr);
6503 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr);
64016504 if (target_value_ptr == irb->codegen->invalid_instruction)
64026505 return target_value_ptr;
64036506 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr);
......@@ -6597,7 +6700,7 @@ static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNo
65976700 assert(node->type == NodeTypeCompTime);
65986701
65996702 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope);
6600 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval);
6703 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
66016704}
66026705
66036706static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {
......@@ -6776,7 +6879,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
67766879 AstNode *start_node = slice_expr->start;
67776880 AstNode *end_node = slice_expr->end;
67786881
6779 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr);
6882 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr);
67806883 if (ptr_value == irb->codegen->invalid_instruction)
67816884 return irb->codegen->invalid_instruction;
67826885
......@@ -6814,7 +6917,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
68146917 }
68156918
68166919
6817 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr);
6920 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr);
68186921 if (err_union_ptr == irb->codegen->invalid_instruction)
68196922 return irb->codegen->invalid_instruction;
68206923
......@@ -7560,7 +7663,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
75607663}
75617664
75627665static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
7563 LVal lval)
7666 LVal lval, ResultLoc *result_loc)
75647667{
75657668 assert(scope);
75667669 switch (node->type) {
......@@ -7576,7 +7679,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
75767679 case NodeTypeBlock:
75777680 return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval);
75787681 case NodeTypeGroupedExpr:
7579 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval);
7682 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc);
75807683 case NodeTypeBinOpExpr:
75817684 return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval);
75827685 case NodeTypeIntLiteral:
......@@ -7588,7 +7691,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
75887691 case NodeTypeSymbol:
75897692 return ir_gen_symbol(irb, scope, node, lval);
75907693 case NodeTypeFnCallExpr:
7591 return ir_gen_fn_call(irb, scope, node, lval);
7694 return ir_gen_fn_call(irb, scope, node, lval, result_loc);
75927695 case NodeTypeIfBoolExpr:
75937696 return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval);
75947697 case NodeTypePrefixOpExpr:
......@@ -7617,7 +7720,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
76177720 }
76187721 case NodeTypePtrDeref: {
76197722 AstNode *expr_node = node->data.ptr_deref_expr.target;
7620 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
7723 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr);
76217724 if (value == irb->codegen->invalid_instruction)
76227725 return value;
76237726
......@@ -7629,7 +7732,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
76297732 case NodeTypeUnwrapOptional: {
76307733 AstNode *expr_node = node->data.unwrap_optional.expr;
76317734
7632 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);
7735 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
76337736 if (maybe_ptr == irb->codegen->invalid_instruction)
76347737 return irb->codegen->invalid_instruction;
76357738
......@@ -7697,14 +7800,23 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
76977800 zig_unreachable();
76987801}
76997802
7700static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) {
7701 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval);
7803static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
7804 ResultLoc *result_loc)
7805{
7806 if (result_loc == nullptr) {
7807 // Create a result location indicating there is none - but if one gets created
7808 // it will be properly distributed.
7809 ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
7810 result_loc_none->base.id = ResultLocIdNone;
7811 result_loc = &result_loc_none->base;
7812 }
7813 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc);
77027814 irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction);
77037815 return result;
77047816}
77057817
77067818static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {
7707 return ir_gen_node_extra(irb, node, scope, LValNone);
7819 return ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
77087820}
77097821
77107822static void invalidate_exec(IrExecutable *exec) {
......@@ -7837,7 +7949,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
78377949 irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup");
78387950 }
78397951
7840 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone);
7952 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
78417953 assert(result);
78427954 if (irb->exec->invalid)
78437955 return false;
......@@ -7946,7 +8058,10 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
79468058 // non-allocating. Basically coroutines are not supported right now until they are reworked.
79478059 args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size
79488060 args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align
7949 ir_build_call(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr);
8061 ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
8062 result_loc_none->base.id = ResultLocIdNone;
8063 ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr,
8064 nullptr, &result_loc_none->base);
79508065
79518066 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
79528067 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);
......@@ -13641,12 +13756,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1364113756 Error err;
1364213757 ZigVar *var = decl_var_instruction->var;
1364313758
13644 IrInstruction *init_value = decl_var_instruction->init_value->child;
13645 if (type_is_invalid(init_value->value.type)) {
13646 var->var_type = ira->codegen->builtin_types.entry_invalid;
13647 return ira->codegen->invalid_instruction;
13648 }
13649
1365013759 ZigType *explicit_type = nullptr;
1365113760 IrInstruction *var_type = nullptr;
1365213761 if (decl_var_instruction->var_type != nullptr) {
......@@ -13661,12 +13770,19 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1366113770
1366213771 AstNode *source_node = decl_var_instruction->base.source_node;
1366313772
13664 IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type);
1366513773 bool is_comptime_var = ir_get_var_is_comptime(var);
1366613774
1366713775 bool var_class_requires_const = false;
1366813776
13669 ZigType *result_type = casted_init_value->value.type;
13777 IrInstruction *var_ptr = decl_var_instruction->ptr->child;
13778 if (type_is_invalid(var_ptr->value.type)) {
13779 var->var_type = ira->codegen->builtin_types.entry_invalid;
13780 return ira->codegen->invalid_instruction;
13781 }
13782
13783 assert(var_ptr->value.type->id == ZigTypeIdPointer);
13784
13785 ZigType *result_type = var_ptr->value.type->data.pointer.child_type;
1367013786 if (type_is_invalid(result_type)) {
1367113787 result_type = ira->codegen->builtin_types.entry_invalid;
1367213788 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) {
......@@ -13675,6 +13791,14 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1367513791 result_type = ira->codegen->builtin_types.entry_invalid;
1367613792 }
1367713793
13794 ConstExprValue *init_val = nullptr;
13795 if (instr_is_comptime(var_ptr) && var_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {
13796 init_val = const_ptr_pointee(ira, ira->codegen, &var_ptr->value, decl_var_instruction->base.source_node);
13797 if (is_comptime_var) {
13798 var->const_value = init_val;
13799 }
13800 }
13801
1367813802 switch (type_requires_comptime(ira->codegen, result_type)) {
1367913803 case ReqCompTimeInvalid:
1368013804 result_type = ira->codegen->builtin_types.entry_invalid;
......@@ -13689,18 +13813,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1368913813 }
1369013814 break;
1369113815 case ReqCompTimeNo:
13692 if (casted_init_value->value.special == ConstValSpecialStatic &&
13693 casted_init_value->value.type->id == ZigTypeIdFn &&
13694 casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
13695 casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
13696 {
13697 var_class_requires_const = true;
13698 if (!var->src_is_const && !is_comptime_var) {
13699 ErrorMsg *msg = ir_add_error_node(ira, source_node,
13700 buf_sprintf("functions marked inline must be stored in const or comptime var"));
13701 AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node;
13702 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here"));
13703 result_type = ira->codegen->builtin_types.entry_invalid;
13816 if (init_val != nullptr) {
13817 if (init_val->special == ConstValSpecialStatic &&
13818 init_val->type->id == ZigTypeIdFn &&
13819 init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
13820 init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
13821 {
13822 var_class_requires_const = true;
13823 if (!var->src_is_const && !is_comptime_var) {
13824 ErrorMsg *msg = ir_add_error_node(ira, source_node,
13825 buf_sprintf("functions marked inline must be stored in const or comptime var"));
13826 AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node;
13827 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here"));
13828 result_type = ira->codegen->builtin_types.entry_invalid;
13829 }
1370413830 }
1370513831 }
1370613832 break;
......@@ -13747,11 +13873,11 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1374713873 }
1374813874 }
1374913875
13750 if (casted_init_value->value.special != ConstValSpecialRuntime) {
13876 if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) {
1375113877 if (var->mem_slot_index != SIZE_MAX) {
1375213878 assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length);
1375313879 ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index);
13754 copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const);
13880 copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const);
1375513881
1375613882 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) {
1375713883 return ir_const_void(ira, &decl_var_instruction->base);
......@@ -13768,7 +13894,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1376813894 if (fn_entry)
1376913895 fn_entry->variable_list.append(var);
1377013896
13771 return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value);
13897 return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr);
1377213898}
1377313899
1377413900static VarLinkage global_linkage_to_var_linkage(GlobalLinkageId id) {
......@@ -14076,7 +14202,67 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
1407614202 zig_unreachable();
1407714203}
1407814204
14079static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry,
14205static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type,
14206 uint32_t align, const char *name_hint, bool force_comptime)
14207{
14208 Error err;
14209
14210 ConstExprValue *pointee = create_const_vals(1);
14211 pointee->special = ConstValSpecialUndef;
14212
14213 IrInstructionAllocaGen *result = ir_create_alloca_gen(ira, source_inst, align, name_hint);
14214 result->base.value.special = force_comptime ? ConstValSpecialStatic : ConstValSpecialRuntime;
14215 result->base.value.data.x_ptr.special = ConstPtrSpecialRef;
14216 result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutRuntimeVar;
14217 result->base.value.data.x_ptr.data.ref.pointee = pointee;
14218
14219 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown)))
14220 return ira->codegen->invalid_instruction;
14221 assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid);
14222
14223 pointee->type = var_type;
14224 result->base.value.type = get_pointer_to_type_extra(ira->codegen, var_type, false, false,
14225 PtrLenSingle, align, 0, 0, false);
14226
14227 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
14228 if (fn_entry != nullptr) {
14229 fn_entry->alloca_gen_list.append(result);
14230 }
14231 result->base.is_gen = true;
14232 return &result->base;
14233}
14234
14235static IrInstruction *ir_resolve_result_loc(IrAnalyze *ira, ResultLoc *result_loc, ZigType *elem_type) {
14236 switch (result_loc->id) {
14237 case ResultLocIdInvalid:
14238 zig_unreachable();
14239 case ResultLocIdNone:
14240 return nullptr;
14241 case ResultLocIdVar: {
14242 // TODO implicit cast?
14243 //ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc);
14244 assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc);
14245 IrInstructionAllocaSrc *alloca_src =
14246 reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction);
14247 if (alloca_src->base.child == nullptr) {
14248 uint32_t align = 0; // TODO
14249 bool force_comptime = false; // TODO
14250 IrInstruction *alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, elem_type, align,
14251 alloca_src->name_hint, force_comptime);
14252 alloca_src->base.child = alloca_gen;
14253 }
14254 return alloca_src->base.child;
14255 }
14256 case ResultLocIdReturn: {
14257 //ResultLocReturn *result_loc_ret = reinterpret_cast<ResultLocReturn *>(result_loc);
14258 // TODO implicit cast?
14259 return ir_build_return_ptr(ira, result_loc->source_instruction, elem_type);
14260 }
14261 }
14262 zig_unreachable();
14263}
14264
14265static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,
1408014266 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,
1408114267 IrInstruction *async_allocator_inst)
1408214268{
......@@ -14109,8 +14295,10 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c
1410914295 ZigType *promise_type = get_promise_type(ira->codegen, return_type);
1411014296 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
1411114297
14112 IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node,
14113 fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr);
14298 IrInstruction *result_loc = ir_resolve_result_loc(ira, call_instruction->result_loc, async_return_type);
14299
14300 IrInstruction *result = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count,
14301 casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, result_loc);
1411414302 result->value.type = async_return_type;
1411514303 return result;
1411614304}
......@@ -14416,7 +14604,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1441614604 return result;
1441714605}
1441814606
14419static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction,
14607static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction,
1442014608 ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref,
1442114609 IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline)
1442214610{
......@@ -14861,19 +15049,17 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1486115049 if (call_instruction->is_async) {
1486215050 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry,
1486315051 fn_ref, casted_args, impl_param_count, async_allocator_inst);
14864 ir_add_alloca(ira, result, result->value.type);
1486515052 return ir_finish_anal(ira, result);
1486615053 }
1486715054
1486815055 assert(async_allocator_inst == nullptr);
14869 IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb,
14870 call_instruction->base.scope, call_instruction->base.source_node,
14871 impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline,
14872 call_instruction->is_async, nullptr, casted_new_stack);
15056 IrInstruction *result_loc = ir_resolve_result_loc(ira, call_instruction->result_loc,
15057 impl_fn_type_id->return_type);
15058 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
15059 impl_fn, nullptr, impl_param_count, casted_args, fn_inline,
15060 call_instruction->is_async, nullptr, casted_new_stack, result_loc);
1487315061 new_call_instruction->value.type = impl_fn_type_id->return_type;
1487415062
14875 ir_add_alloca(ira, new_call_instruction, impl_fn_type_id->return_type);
14876
1487715063 return ir_finish_anal(ira, new_call_instruction);
1487815064 }
1487915065
......@@ -14957,7 +15143,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1495715143
1495815144 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref,
1495915145 casted_args, call_param_count, async_allocator_inst);
14960 ir_add_alloca(ira, result, result->value.type);
1496115146 return ir_finish_anal(ira, result);
1496215147 }
1496315148
......@@ -14967,15 +15152,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1496715152 return ira->codegen->invalid_instruction;
1496815153 }
1496915154
14970 IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb,
14971 call_instruction->base.scope, call_instruction->base.source_node,
14972 fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack);
15155 IrInstruction *result_loc = ir_resolve_result_loc(ira, call_instruction->result_loc, return_type);
15156 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref,
15157 call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack, result_loc);
1497315158 new_call_instruction->value.type = return_type;
14974 ir_add_alloca(ira, new_call_instruction, return_type);
1497515159 return ir_finish_anal(ira, new_call_instruction);
1497615160}
1497715161
14978static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) {
15162static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) {
1497915163 IrInstruction *fn_ref = call_instruction->fn_ref->child;
1498015164 if (type_is_invalid(fn_ref->value.type))
1498115165 return ira->codegen->invalid_instruction;
......@@ -23304,6 +23488,9 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2330423488 case IrInstructionIdResizeSlice:
2330523489 case IrInstructionIdLoadPtrGen:
2330623490 case IrInstructionIdBitCastGen:
23491 case IrInstructionIdCallGen:
23492 case IrInstructionIdReturnPtr:
23493 case IrInstructionIdAllocaGen:
2330723494 zig_unreachable();
2330823495
2330923496 case IrInstructionIdReturn:
......@@ -23326,8 +23513,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2332623513 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);
2332723514 case IrInstructionIdFieldPtr:
2332823515 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);
23329 case IrInstructionIdCall:
23330 return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction);
23516 case IrInstructionIdCallSrc:
23517 return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction);
2333123518 case IrInstructionIdBr:
2333223519 return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction);
2333323520 case IrInstructionIdCondBr:
......@@ -23580,13 +23767,15 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2358023767 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);
2358123768 case IrInstructionIdUndeclaredIdent:
2358223769 return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction);
23770 case IrInstructionIdAllocaSrc:
23771 return nullptr;
2358323772 }
2358423773 zig_unreachable();
2358523774}
2358623775
2358723776static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) {
2358823777 IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction);
23589 ir_assert(new_instruction->value.type != nullptr, old_instruction);
23778 ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);
2359023779 old_instruction->child = new_instruction;
2359123780 return new_instruction;
2359223781}
......@@ -23637,13 +23826,15 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
2363723826 }
2363823827
2363923828 IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction);
23640 if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) {
23641 return ira->codegen->builtin_types.entry_invalid;
23642 }
23829 if (new_instruction != nullptr) {
23830 if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) {
23831 return ira->codegen->builtin_types.entry_invalid;
23832 }
2364323833
23644 // unreachable instructions do their own control flow.
23645 if (new_instruction->value.type->id == ZigTypeIdUnreachable)
23646 continue;
23834 // unreachable instructions do their own control flow.
23835 if (new_instruction->value.type->id == ZigTypeIdUnreachable)
23836 continue;
23837 }
2364723838
2364823839 ira->instruction_index += 1;
2364923840 }
......@@ -23668,7 +23859,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2366823859 case IrInstructionIdDeclVarSrc:
2366923860 case IrInstructionIdDeclVarGen:
2367023861 case IrInstructionIdStorePtr:
23671 case IrInstructionIdCall:
23862 case IrInstructionIdCallSrc:
23863 case IrInstructionIdCallGen:
2367223864 case IrInstructionIdReturn:
2367323865 case IrInstructionIdUnreachable:
2367423866 case IrInstructionIdSetCold:
......@@ -23731,6 +23923,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2373123923 case IrInstructionIdFieldPtr:
2373223924 case IrInstructionIdElemPtr:
2373323925 case IrInstructionIdVarPtr:
23926 case IrInstructionIdReturnPtr:
2373423927 case IrInstructionIdTypeOf:
2373523928 case IrInstructionIdToPtrType:
2373623929 case IrInstructionIdPtrTypeChild:
......@@ -23818,6 +24011,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2381824011 case IrInstructionIdVectorToArray:
2381924012 case IrInstructionIdArrayToVector:
2382024013 case IrInstructionIdHasDecl:
24014 case IrInstructionIdAllocaSrc:
24015 case IrInstructionIdAllocaGen:
2382124016 return false;
2382224017
2382324018 case IrInstructionIdAsm:
src/ir_print.cpp+82-6
......@@ -188,7 +188,7 @@ static void ir_print_decl_var_src(IrPrint *irp, IrInstructionDeclVarSrc *decl_va
188188 fprintf(irp->f, " ");
189189 }
190190 fprintf(irp->f, "= ");
191 ir_print_other_instruction(irp, decl_var_instruction->init_value);
191 ir_print_other_instruction(irp, decl_var_instruction->ptr);
192192 if (decl_var_instruction->var->is_comptime != nullptr) {
193193 fprintf(irp->f, " // comptime = ");
194194 ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);
......@@ -201,7 +201,29 @@ static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) {
201201 fprintf(irp->f, " to %s", buf_ptr(&cast_instruction->dest_type->name));
202202}
203203
204static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
204static void ir_print_result_loc_var(IrPrint *irp, ResultLocVar *result_loc_var) {
205 fprintf(irp->f, "var(");
206 ir_print_other_instruction(irp, result_loc_var->base.source_instruction);
207 fprintf(irp->f, ")");
208}
209
210static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
211 switch (result_loc->id) {
212 case ResultLocIdInvalid:
213 zig_unreachable();
214 case ResultLocIdNone:
215 fprintf(irp->f, "none");
216 return;
217 case ResultLocIdReturn:
218 fprintf(irp->f, "return");
219 return;
220 case ResultLocIdVar:
221 return ir_print_result_loc_var(irp, (ResultLocVar *)result_loc);
222 }
223 zig_unreachable();
224}
225
226static void ir_print_call_src(IrPrint *irp, IrInstructionCallSrc *call_instruction) {
205227 if (call_instruction->is_async) {
206228 fprintf(irp->f, "async");
207229 if (call_instruction->async_allocator != nullptr) {
......@@ -224,7 +246,35 @@ static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
224246 fprintf(irp->f, ", ");
225247 ir_print_other_instruction(irp, arg);
226248 }
227 fprintf(irp->f, ")");
249 fprintf(irp->f, ")result=");
250 ir_print_result_loc(irp, call_instruction->result_loc);
251}
252
253static void ir_print_call_gen(IrPrint *irp, IrInstructionCallGen *call_instruction) {
254 if (call_instruction->is_async) {
255 fprintf(irp->f, "async");
256 if (call_instruction->async_allocator != nullptr) {
257 fprintf(irp->f, "<");
258 ir_print_other_instruction(irp, call_instruction->async_allocator);
259 fprintf(irp->f, ">");
260 }
261 fprintf(irp->f, " ");
262 }
263 if (call_instruction->fn_entry) {
264 fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name));
265 } else {
266 assert(call_instruction->fn_ref);
267 ir_print_other_instruction(irp, call_instruction->fn_ref);
268 }
269 fprintf(irp->f, "(");
270 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
271 IrInstruction *arg = call_instruction->args[i];
272 if (i != 0)
273 fprintf(irp->f, ", ");
274 ir_print_other_instruction(irp, arg);
275 }
276 fprintf(irp->f, ")result=");
277 ir_print_other_instruction(irp, call_instruction->result_loc);
228278}
229279
230280static void ir_print_cond_br(IrPrint *irp, IrInstructionCondBr *cond_br_instruction) {
......@@ -331,6 +381,10 @@ static void ir_print_var_ptr(IrPrint *irp, IrInstructionVarPtr *instruction) {
331381 fprintf(irp->f, "&%s", buf_ptr(&instruction->var->name));
332382}
333383
384static void ir_print_return_ptr(IrPrint *irp, IrInstructionReturnPtr *instruction) {
385 fprintf(irp->f, "@ReturnPtr");
386}
387
334388static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {
335389 ir_print_other_instruction(irp, instruction->ptr);
336390 fprintf(irp->f, ".*");
......@@ -1064,6 +1118,16 @@ static void ir_print_resize_slice(IrPrint *irp, IrInstructionResizeSlice *instru
10641118 fprintf(irp->f, ")");
10651119}
10661120
1121static void ir_print_alloca_src(IrPrint *irp, IrInstructionAllocaSrc *instruction) {
1122 fprintf(irp->f, "Alloca(align=");
1123 ir_print_other_instruction(irp, instruction->align);
1124 fprintf(irp->f, ",name=%s)", instruction->name_hint);
1125}
1126
1127static void ir_print_alloca_gen(IrPrint *irp, IrInstructionAllocaGen *instruction) {
1128 fprintf(irp->f, "Alloca(align=%" PRIu32 ",name=%s)", instruction->align, instruction->name_hint);
1129}
1130
10671131static void ir_print_int_to_err(IrPrint *irp, IrInstructionIntToErr *instruction) {
10681132 fprintf(irp->f, "inttoerr ");
10691133 ir_print_other_instruction(irp, instruction->target);
......@@ -1446,7 +1510,7 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va
14461510 fprintf(irp->f, "%s %s: %s align(%u) = ", var_or_const, name, buf_ptr(&var->var_type->name),
14471511 var->align_bytes);
14481512
1449 ir_print_other_instruction(irp, decl_var_instruction->init_value);
1513 ir_print_other_instruction(irp, decl_var_instruction->var_ptr);
14501514 if (decl_var_instruction->var->is_comptime != nullptr) {
14511515 fprintf(irp->f, " // comptime = ");
14521516 ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);
......@@ -1485,8 +1549,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
14851549 case IrInstructionIdCast:
14861550 ir_print_cast(irp, (IrInstructionCast *)instruction);
14871551 break;
1488 case IrInstructionIdCall:
1489 ir_print_call(irp, (IrInstructionCall *)instruction);
1552 case IrInstructionIdCallSrc:
1553 ir_print_call_src(irp, (IrInstructionCallSrc *)instruction);
1554 break;
1555 case IrInstructionIdCallGen:
1556 ir_print_call_gen(irp, (IrInstructionCallGen *)instruction);
14901557 break;
14911558 case IrInstructionIdUnOp:
14921559 ir_print_un_op(irp, (IrInstructionUnOp *)instruction);
......@@ -1521,6 +1588,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
15211588 case IrInstructionIdVarPtr:
15221589 ir_print_var_ptr(irp, (IrInstructionVarPtr *)instruction);
15231590 break;
1591 case IrInstructionIdReturnPtr:
1592 ir_print_return_ptr(irp, (IrInstructionReturnPtr *)instruction);
1593 break;
15241594 case IrInstructionIdLoadPtr:
15251595 ir_print_load_ptr(irp, (IrInstructionLoadPtr *)instruction);
15261596 break;
......@@ -1938,6 +2008,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
19382008 case IrInstructionIdUndeclaredIdent:
19392009 ir_print_undeclared_ident(irp, (IrInstructionUndeclaredIdent *)instruction);
19402010 break;
2011 case IrInstructionIdAllocaSrc:
2012 ir_print_alloca_src(irp, (IrInstructionAllocaSrc *)instruction);
2013 break;
2014 case IrInstructionIdAllocaGen:
2015 ir_print_alloca_gen(irp, (IrInstructionAllocaGen *)instruction);
2016 break;
19412017 }
19422018 fprintf(irp->f, "\n");
19432019}