authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-08 18:51:31-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-08 18:51:31-04:00
log771e88951a9af48335abe14e4c44b5c4f5b252de
treec6b4831bd61ba18dc819e6ebce1f50b841b4ad80
parent52eb34718862928b5d83c58990d5d7a6b07e20e2
signaturelock-open Commit is signed but in an unrecognized format.

result location mechanism for struct initialization

```zig export fn entry() void { const static = Foo{ .x = 9, .bar = Bar{ .y = 10 }, }; const runtime = foo(true); } fn foo(c: bool) Foo { return Foo{ .x = 12, .bar = if (c) bar1() else bar2(), }; } fn bar1() Bar { return Bar{ .y = 34 }; } fn bar2() Bar { return Bar{ .y = 56 }; } ``` ```llvm @0 = internal unnamed_addr constant %Foo { i32 9, %Bar { i32 10 } }, align 4 @1 = internal unnamed_addr constant %Bar { i32 34 }, align 4 @2 = internal unnamed_addr constant %Bar { i32 56 }, align 4 define void @entry() #2 !dbg !35 { Entry: %runtime = alloca %Foo, align 4 call void @llvm.dbg.declare(metadata %Foo* @0, metadata !39, metadata !DIExpression()), !dbg !50 call fastcc void @foo(%Foo* sret %runtime, i1 true), !dbg !51 call void @llvm.dbg.declare(metadata %Foo* %runtime, metadata !49, metadata !DIExpression()), !dbg !52 ret void, !dbg !53 } define internal fastcc void @foo(%Foo* nonnull sret, i1) unnamed_addr #2 !dbg !54 { Entry: %c = alloca i1, align 1 store i1 %1, i1* %c, align 1 call void @llvm.dbg.declare(metadata i1* %c, metadata !60, metadata !DIExpression()), !dbg !61 %2 = getelementptr inbounds %Foo, %Foo* %0, i32 0, i32 0, !dbg !62 store i32 12, i32* %2, align 4, !dbg !62 %3 = getelementptr inbounds %Foo, %Foo* %0, i32 0, i32 1, !dbg !64 %4 = load i1, i1* %c, align 1, !dbg !65 br i1 %4, label %Then, label %Else, !dbg !65 Then: ; preds = %Entry call fastcc void @bar1(%Bar* sret %3), !dbg !66 br label %EndIf, !dbg !64 Else: ; preds = %Entry call fastcc void @bar2(%Bar* sret %3), !dbg !67 br label %EndIf, !dbg !64 EndIf: ; preds = %Else, %Then ret void, !dbg !68 } define internal fastcc void @bar1(%Bar* nonnull sret) unnamed_addr #2 !dbg !69 { Entry: %1 = bitcast %Bar* %0 to i8*, !dbg !73 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 bitcast (%Bar* @1 to i8*), i64 4, i1 false), !dbg !73 ret void, !dbg !73 } define internal fastcc void @bar2(%Bar* nonnull sret) unnamed_addr #2 !dbg !75 { Entry: %1 = bitcast %Bar* %0 to i8*, !dbg !76 call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 bitcast (%Bar* @2 to i8*), i64 4, i1 false), !dbg !76 ret void, !dbg !76 } !39 = !DILocalVariable(name: "static", scope: !40, file: !5, line: 2, type: !41) !49 = !DILocalVariable(name: "runtime", scope: !40, file: !5, line: 6, type: !41) ```

7 files changed, 270 insertions(+), 143 deletions(-)

BRANCH_TODO+2-6
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1Scratch pad for stuff to do before merging master1Scratch pad for stuff to do before merging master
2=================================================2=================================================
33
4 * struct initializations4 * array initializations
5 * function call parameters5 * union initializations
6 * bitCast6 * bitCast
77
8look at all the ir_gen_node ir_gen_node_extra calls and make sure result locations are properly propagated8look at all the ir_gen_node ir_gen_node_extra calls and make sure result locations are properly propagated
...@@ -25,7 +25,3 @@ inferred comptime...@@ -25,7 +25,3 @@ inferred comptime
25 return ir_build_ref(irb, scope, value->source_node, value, false, false);25 return ir_build_ref(irb, scope, value->source_node, value, false, false);
2626
27handle if with no else27handle if with no else
28
29
30
31
src/all_types.hpp+34-15
...@@ -1957,6 +1957,7 @@ enum ScopeId {...@@ -1957,6 +1957,7 @@ enum ScopeId {
1957 ScopeIdCompTime,1957 ScopeIdCompTime,
1958 ScopeIdCoroPrelude,1958 ScopeIdCoroPrelude,
1959 ScopeIdRuntime,1959 ScopeIdRuntime,
1960 ScopeIdElide,
1960};1961};
19611962
1962struct Scope {1963struct Scope {
...@@ -1970,6 +1971,14 @@ struct Scope {...@@ -1970,6 +1971,14 @@ struct Scope {
1970 ScopeId id;1971 ScopeId id;
1971};1972};
19721973
1974// This scope, when activated, causes all the instructions in the scope to be omitted
1975// from the generated code.
1976struct ScopeElide {
1977 Scope base;
1978
1979 bool activated;
1980};
1981
1973// This scope comes from global declarations or from1982// This scope comes from global declarations or from
1974// declarations in a container declaration1983// declarations in a container declaration
1975// NodeTypeContainerDecl1984// NodeTypeContainerDecl
...@@ -2189,7 +2198,6 @@ enum IrInstructionId {...@@ -2189,7 +2198,6 @@ enum IrInstructionId {
2189 IrInstructionIdResizeSlice,2198 IrInstructionIdResizeSlice,
2190 IrInstructionIdContainerInitList,2199 IrInstructionIdContainerInitList,
2191 IrInstructionIdContainerInitFields,2200 IrInstructionIdContainerInitFields,
2192 IrInstructionIdStructInit,
2193 IrInstructionIdUnionInit,2201 IrInstructionIdUnionInit,
2194 IrInstructionIdUnreachable,2202 IrInstructionIdUnreachable,
2195 IrInstructionIdTypeOf,2203 IrInstructionIdTypeOf,
...@@ -2279,6 +2287,7 @@ enum IrInstructionId {...@@ -2279,6 +2287,7 @@ enum IrInstructionId {
2279 IrInstructionIdPtrType,2287 IrInstructionIdPtrType,
2280 IrInstructionIdAlignCast,2288 IrInstructionIdAlignCast,
2281 IrInstructionIdImplicitCast,2289 IrInstructionIdImplicitCast,
2290 IrInstructionIdResolveResult,
2282 IrInstructionIdOpaqueType,2291 IrInstructionIdOpaqueType,
2283 IrInstructionIdSetAlignStack,2292 IrInstructionIdSetAlignStack,
2284 IrInstructionIdArgType,2293 IrInstructionIdArgType,
...@@ -2366,6 +2375,7 @@ struct IrInstructionCondBr {...@@ -2366,6 +2375,7 @@ struct IrInstructionCondBr {
2366 IrBasicBlock *then_block;2375 IrBasicBlock *then_block;
2367 IrBasicBlock *else_block;2376 IrBasicBlock *else_block;
2368 IrInstruction *is_comptime;2377 IrInstruction *is_comptime;
2378 ResultLoc *result_loc;
2369};2379};
23702380
2371struct IrInstructionBr {2381struct IrInstructionBr {
...@@ -2646,20 +2656,6 @@ struct IrInstructionContainerInitFields {...@@ -2646,20 +2656,6 @@ struct IrInstructionContainerInitFields {
2646 IrInstructionContainerInitFieldsField *fields;2656 IrInstructionContainerInitFieldsField *fields;
2647};2657};
26482658
2649struct IrInstructionStructInitField {
2650 IrInstruction *value;
2651 TypeStructField *type_struct_field;
2652};
2653
2654struct IrInstructionStructInit {
2655 IrInstruction base;
2656
2657 ZigType *struct_type;
2658 size_t field_count;
2659 IrInstructionStructInitField *fields;
2660 LLVMValueRef tmp_ptr;
2661};
2662
2663struct IrInstructionUnionInit {2659struct IrInstructionUnionInit {
2664 IrInstruction base;2660 IrInstruction base;
26652661
...@@ -3581,13 +3577,22 @@ struct IrInstructionImplicitCast {...@@ -3581,13 +3577,22 @@ struct IrInstructionImplicitCast {
3581 IrInstruction *target;3577 IrInstruction *target;
3582};3578};
35833579
3580struct IrInstructionResolveResult {
3581 IrInstruction base;
3582
3583 ResultLoc *result_loc;
3584 IrInstruction *ty;
3585};
3586
3584enum ResultLocId {3587enum ResultLocId {
3585 ResultLocIdInvalid,3588 ResultLocIdInvalid,
3586 ResultLocIdNone,3589 ResultLocIdNone,
3587 ResultLocIdVar,3590 ResultLocIdVar,
3591 ResultLocIdField,
3588 ResultLocIdReturn,3592 ResultLocIdReturn,
3589 ResultLocIdPeer,3593 ResultLocIdPeer,
3590 ResultLocIdPeerParent,3594 ResultLocIdPeerParent,
3595 ResultLocIdInstruction,
3591};3596};
35923597
3593struct ResultLoc {3598struct ResultLoc {
...@@ -3597,6 +3602,7 @@ struct ResultLoc {...@@ -3597,6 +3602,7 @@ struct ResultLoc {
3597 IrInstruction *source_instruction;3602 IrInstruction *source_instruction;
3598 IrInstruction *gen_instruction; // value to store to the result loc3603 IrInstruction *gen_instruction; // value to store to the result loc
3599 ZigType *implicit_elem_type;3604 ZigType *implicit_elem_type;
3605 ScopeElide *scope_elide;
3600};3606};
36013607
3602struct ResultLocNone {3608struct ResultLocNone {
...@@ -3609,6 +3615,14 @@ struct ResultLocVar {...@@ -3609,6 +3615,14 @@ struct ResultLocVar {
3609 ZigVar *var;3615 ZigVar *var;
3610};3616};
36113617
3618struct ResultLocField {
3619 ResultLoc base;
3620
3621 ResultLoc *parent;
3622 Buf *name;
3623 IrInstruction *container_type;
3624};
3625
3612struct ResultLocReturn {3626struct ResultLocReturn {
3613 ResultLoc base;3627 ResultLoc base;
3614};3628};
...@@ -3636,6 +3650,11 @@ struct ResultLocPeer {...@@ -3636,6 +3650,11 @@ struct ResultLocPeer {
3636 IrSuspendPosition suspend_pos;3650 IrSuspendPosition suspend_pos;
3637};3651};
36383652
3653// The result location is the source instruction
3654struct ResultLocInstruction {
3655 ResultLoc base;
3656};
3657
3639static const size_t slice_ptr_index = 0;3658static const size_t slice_ptr_index = 0;
3640static const size_t slice_len_index = 1;3659static const size_t slice_len_index = 1;
36413660
src/analyze.cpp+6
...@@ -166,6 +166,12 @@ Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruct...@@ -166,6 +166,12 @@ Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruct
166 return &scope->base;166 return &scope->base;
167}167}
168168
169ScopeElide *create_elide_scope(CodeGen *g, AstNode *node, Scope *parent) {
170 ScopeElide *scope = allocate<ScopeElide>(1);
171 init_scope(g, &scope->base, ScopeIdElide, node, parent);
172 return scope;
173}
174
169ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent) {175ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent) {
170 assert(node->type == NodeTypeSuspend);176 assert(node->type == NodeTypeSuspend);
171 ScopeSuspend *scope = allocate<ScopeSuspend>(1);177 ScopeSuspend *scope = allocate<ScopeSuspend>(1);
src/analyze.hpp+1
...@@ -121,6 +121,7 @@ ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *...@@ -121,6 +121,7 @@ ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *
121Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);121Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
122Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent);122Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent);
123Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime);123Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime);
124ScopeElide *create_elide_scope(CodeGen *g, AstNode *node, Scope *parent);
124125
125void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str);126void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str);
126ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str);127ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str);
src/codegen.cpp+39-34
...@@ -715,6 +715,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -715,6 +715,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
715 case ScopeIdCompTime:715 case ScopeIdCompTime:
716 case ScopeIdCoroPrelude:716 case ScopeIdCoroPrelude:
717 case ScopeIdRuntime:717 case ScopeIdRuntime:
718 case ScopeIdElide:
718 return get_di_scope(g, scope->parent);719 return get_di_scope(g, scope->parent);
719 }720 }
720 zig_unreachable();721 zig_unreachable();
...@@ -2383,7 +2384,6 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut...@@ -2383,7 +2384,6 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut
2383}2384}
23842385
2385static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {2386static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {
2386 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2387 ZigType *return_type = return_instruction->value->value.type;2387 ZigType *return_type = return_instruction->value->value.type;
23882388
2389 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {2389 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
...@@ -2391,13 +2391,16 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns...@@ -2391,13 +2391,16 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
2391 if (return_instruction->value->value.special != ConstValSpecialRuntime) {2391 if (return_instruction->value->value.special != ConstValSpecialRuntime) {
2392 // if it's comptime we have to do this but if it's runtime trust that2392 // if it's comptime we have to do this but if it's runtime trust that
2393 // result location mechanism took care of it.2393 // result location mechanism took care of it.
2394 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2394 gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);2395 gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);
2395 }2396 }
2396 LLVMBuildRetVoid(g->builder);2397 LLVMBuildRetVoid(g->builder);
2397 } else if (handle_is_ptr(return_type)) {2398 } else if (handle_is_ptr(return_type)) {
2399 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2398 LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");2400 LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");
2399 LLVMBuildRet(g->builder, by_val_value);2401 LLVMBuildRet(g->builder, by_val_value);
2400 } else {2402 } else {
2403 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2401 LLVMBuildRet(g->builder, value);2404 LLVMBuildRet(g->builder, value);
2402 }2405 }
2403 return nullptr;2406 return nullptr;
...@@ -5032,29 +5035,6 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, Ir...@@ -5032,29 +5035,6 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, Ir
5032 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);5035 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);
5033}5036}
50345037
5035static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable, IrInstructionStructInit *instruction) {
5036 for (size_t i = 0; i < instruction->field_count; i += 1) {
5037 IrInstructionStructInitField *field = &instruction->fields[i];
5038 TypeStructField *type_struct_field = field->type_struct_field;
5039 if (!type_has_bits(type_struct_field->type_entry))
5040 continue;
5041
5042 LLVMValueRef field_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
5043 (unsigned)type_struct_field->gen_index, "");
5044 LLVMValueRef value = ir_llvm_value(g, field->value);
5045
5046 uint32_t field_align_bytes = get_abi_alignment(g, type_struct_field->type_entry);
5047 uint32_t host_int_bytes = get_host_int_bytes(g, instruction->struct_type, type_struct_field);
5048
5049 ZigType *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry,
5050 false, false, PtrLenSingle, field_align_bytes,
5051 (uint32_t)type_struct_field->bit_offset_in_host, host_int_bytes, false);
5052
5053 gen_assign_raw(g, field_ptr, ptr_type, value);
5054 }
5055 return instruction->tmp_ptr;
5056}
5057
5058static LLVMValueRef ir_render_union_init(CodeGen *g, IrExecutable *executable, IrInstructionUnionInit *instruction) {5038static LLVMValueRef ir_render_union_init(CodeGen *g, IrExecutable *executable, IrInstructionUnionInit *instruction) {
5059 TypeUnionField *type_union_field = instruction->field;5039 TypeUnionField *type_union_field = instruction->field;
50605040
...@@ -5531,10 +5511,6 @@ static void set_debug_location(CodeGen *g, IrInstruction *instruction) {...@@ -5531,10 +5511,6 @@ static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
5531}5511}
55325512
5533static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {5513static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
5534 if (!g->strip_debug_symbols) {
5535 set_debug_location(g, instruction);
5536 }
5537
5538 switch (instruction->id) {5514 switch (instruction->id) {
5539 case IrInstructionIdInvalid:5515 case IrInstructionIdInvalid:
5540 case IrInstructionIdConst:5516 case IrInstructionIdConst:
...@@ -5609,6 +5585,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5609,6 +5585,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5609 case IrInstructionIdEndExpr:5585 case IrInstructionIdEndExpr:
5610 case IrInstructionIdAllocaGen:5586 case IrInstructionIdAllocaGen:
5611 case IrInstructionIdImplicitCast:5587 case IrInstructionIdImplicitCast:
5588 case IrInstructionIdResolveResult:
5612 zig_unreachable();5589 zig_unreachable();
56135590
5614 case IrInstructionIdDeclVarGen:5591 case IrInstructionIdDeclVarGen:
...@@ -5705,8 +5682,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5705,8 +5682,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5705 return ir_render_err_wrap_payload(g, executable, (IrInstructionErrWrapPayload *)instruction);5682 return ir_render_err_wrap_payload(g, executable, (IrInstructionErrWrapPayload *)instruction);
5706 case IrInstructionIdUnionTag:5683 case IrInstructionIdUnionTag:
5707 return ir_render_union_tag(g, executable, (IrInstructionUnionTag *)instruction);5684 return ir_render_union_tag(g, executable, (IrInstructionUnionTag *)instruction);
5708 case IrInstructionIdStructInit:
5709 return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
5710 case IrInstructionIdUnionInit:5685 case IrInstructionIdUnionInit:
5711 return ir_render_union_init(g, executable, (IrInstructionUnionInit *)instruction);5686 return ir_render_union_init(g, executable, (IrInstructionUnionInit *)instruction);
5712 case IrInstructionIdPtrCastGen:5687 case IrInstructionIdPtrCastGen:
...@@ -5791,6 +5766,34 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5791,6 +5766,34 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5791 zig_unreachable();5766 zig_unreachable();
5792}5767}
57935768
5769static bool scope_is_elided(Scope *scope) {
5770 for (;;) {
5771 switch (scope->id) {
5772 case ScopeIdDecls:
5773 case ScopeIdCompTime:
5774 case ScopeIdCImport:
5775 zig_unreachable();
5776 case ScopeIdElide:
5777 if (reinterpret_cast<ScopeElide *>(scope)->activated)
5778 return true;
5779 // fallthrough
5780 case ScopeIdBlock:
5781 case ScopeIdDefer:
5782 case ScopeIdDeferExpr:
5783 case ScopeIdVarDecl:
5784 case ScopeIdLoop:
5785 case ScopeIdSuspend:
5786 case ScopeIdCoroPrelude:
5787 case ScopeIdRuntime:
5788 scope = scope->parent;
5789 continue;
5790 case ScopeIdFnDef:
5791 return false;
5792 }
5793 zig_unreachable();
5794 }
5795}
5796
5794static void ir_render(CodeGen *g, ZigFn *fn_entry) {5797static void ir_render(CodeGen *g, ZigFn *fn_entry) {
5795 assert(fn_entry);5798 assert(fn_entry);
57965799
...@@ -5806,7 +5809,12 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {...@@ -5806,7 +5809,12 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
5806 if (instruction->ref_count == 0 && !ir_has_side_effects(instruction))5809 if (instruction->ref_count == 0 && !ir_has_side_effects(instruction))
5807 continue;5810 continue;
58085811
5809 instruction->llvm_value = ir_render_instruction(g, executable, instruction);5812 if (!scope_is_elided(instruction->scope)) {
5813 if (!g->strip_debug_symbols) {
5814 set_debug_location(g, instruction);
5815 }
5816 instruction->llvm_value = ir_render_instruction(g, executable, instruction);
5817 }
5810 }5818 }
5811 current_block->llvm_exit_block = LLVMGetInsertBlock(g->builder);5819 current_block->llvm_exit_block = LLVMGetInsertBlock(g->builder);
5812 }5820 }
...@@ -6891,9 +6899,6 @@ static void do_code_gen(CodeGen *g) {...@@ -6891,9 +6899,6 @@ static void do_code_gen(CodeGen *g) {
6891 } else if (instruction->id == IrInstructionIdContainerInitList) {6899 } else if (instruction->id == IrInstructionIdContainerInitList) {
6892 IrInstructionContainerInitList *container_init_list_instruction = (IrInstructionContainerInitList *)instruction;6900 IrInstructionContainerInitList *container_init_list_instruction = (IrInstructionContainerInitList *)instruction;
6893 slot = &container_init_list_instruction->tmp_ptr;6901 slot = &container_init_list_instruction->tmp_ptr;
6894 } else if (instruction->id == IrInstructionIdStructInit) {
6895 IrInstructionStructInit *struct_init_instruction = (IrInstructionStructInit *)instruction;
6896 slot = &struct_init_instruction->tmp_ptr;
6897 } else if (instruction->id == IrInstructionIdUnionInit) {6902 } else if (instruction->id == IrInstructionIdUnionInit) {
6898 IrInstructionUnionInit *union_init_instruction = (IrInstructionUnionInit *)instruction;6903 IrInstructionUnionInit *union_init_instruction = (IrInstructionUnionInit *)instruction;
6899 slot = &union_init_instruction->tmp_ptr;6904 slot = &union_init_instruction->tmp_ptr;
src/ir.cpp+163-73
...@@ -616,10 +616,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) {...@@ -616,10 +616,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) {
616 return IrInstructionIdRef;616 return IrInstructionIdRef;
617}617}
618618
619static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) {
620 return IrInstructionIdStructInit;
621}
622
623static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit *) {619static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit *) {
624 return IrInstructionIdUnionInit;620 return IrInstructionIdUnionInit;
625}621}
...@@ -888,6 +884,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionImplicitCast *)...@@ -888,6 +884,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionImplicitCast *)
888 return IrInstructionIdImplicitCast;884 return IrInstructionIdImplicitCast;
889}885}
890886
887static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *) {
888 return IrInstructionIdResolveResult;
889}
890
891static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) {891static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) {
892 return IrInstructionIdOpaqueType;892 return IrInstructionIdOpaqueType;
893}893}
...@@ -1517,20 +1517,6 @@ static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scop...@@ -1517,20 +1517,6 @@ static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scop
1517 return &container_init_fields_instruction->base;1517 return &container_init_fields_instruction->base;
1518}1518}
15191519
1520static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node,
1521 ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields)
1522{
1523 IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node);
1524 struct_init_instruction->struct_type = struct_type;
1525 struct_init_instruction->field_count = field_count;
1526 struct_init_instruction->fields = fields;
1527
1528 for (size_t i = 0; i < field_count; i += 1)
1529 ir_ref_instruction(fields[i].value, irb->current_basic_block);
1530
1531 return &struct_init_instruction->base;
1532}
1533
1534static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node,1520static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node,
1535 ZigType *union_type, TypeUnionField *field, IrInstruction *init_value)1521 ZigType *union_type, TypeUnionField *field, IrInstruction *init_value)
1536{1522{
...@@ -2764,6 +2750,18 @@ static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNo...@@ -2764,6 +2750,18 @@ static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNo
2764 return &instruction->base;2750 return &instruction->base;
2765}2751}
27662752
2753static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node,
2754 ResultLoc *result_loc, IrInstruction *ty)
2755{
2756 IrInstructionResolveResult *instruction = ir_build_instruction<IrInstructionResolveResult>(irb, scope, source_node);
2757 instruction->result_loc = result_loc;
2758 instruction->ty = ty;
2759
2760 ir_ref_instruction(ty, irb->current_basic_block);
2761
2762 return &instruction->base;
2763}
2764
2767static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) {2765static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) {
2768 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node);2766 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node);
27692767
...@@ -3220,6 +3218,7 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco...@@ -3220,6 +3218,7 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco
3220 case ScopeIdSuspend:3218 case ScopeIdSuspend:
3221 case ScopeIdCompTime:3219 case ScopeIdCompTime:
3222 case ScopeIdRuntime:3220 case ScopeIdRuntime:
3221 case ScopeIdElide:
3223 scope = scope->parent;3222 scope = scope->parent;
3224 continue;3223 continue;
3225 case ScopeIdDeferExpr:3224 case ScopeIdDeferExpr:
...@@ -3276,6 +3275,7 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o...@@ -3276,6 +3275,7 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o
3276 case ScopeIdSuspend:3275 case ScopeIdSuspend:
3277 case ScopeIdCompTime:3276 case ScopeIdCompTime:
3278 case ScopeIdRuntime:3277 case ScopeIdRuntime:
3278 case ScopeIdElide:
3279 scope = scope->parent;3279 scope = scope->parent;
3280 continue;3280 continue;
3281 case ScopeIdDeferExpr:3281 case ScopeIdDeferExpr:
...@@ -5549,7 +5549,9 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod...@@ -5549,7 +5549,9 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
5549 zig_unreachable();5549 zig_unreachable();
5550}5550}
55515551
5552static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node) {5552static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
5553 ResultLoc *result_loc)
5554{
5553 assert(node->type == NodeTypeContainerInitExpr);5555 assert(node->type == NodeTypeContainerInitExpr);
55545556
5555 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;5557 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
...@@ -5559,39 +5561,61 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A...@@ -5559,39 +5561,61 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
5559 if (container_type == irb->codegen->invalid_instruction)5561 if (container_type == irb->codegen->invalid_instruction)
5560 return container_type;5562 return container_type;
55615563
5562 if (kind == ContainerInitKindStruct) {5564 switch (kind) {
5563 size_t field_count = container_init_expr->entries.length;5565 case ContainerInitKindStruct: {
5564 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count);5566 src_assert(result_loc->scope_elide == nullptr, node);
5565 for (size_t i = 0; i < field_count; i += 1) {5567 result_loc->scope_elide = create_elide_scope(irb->codegen, node, scope);
5566 AstNode *entry_node = container_init_expr->entries.at(i);5568 size_t field_count = container_init_expr->entries.length;
5567 assert(entry_node->type == NodeTypeStructValueField);5569 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count);
55685570 for (size_t i = 0; i < field_count; i += 1) {
5569 Buf *name = entry_node->data.struct_val_field.name;5571 AstNode *entry_node = container_init_expr->entries.at(i);
5570 AstNode *expr_node = entry_node->data.struct_val_field.expr;5572 assert(entry_node->type == NodeTypeStructValueField);
5571 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope);5573
5572 if (expr_value == irb->codegen->invalid_instruction)5574 Buf *name = entry_node->data.struct_val_field.name;
5573 return expr_value;5575 AstNode *expr_node = entry_node->data.struct_val_field.expr;
55745576
5575 fields[i].name = name;5577 ResultLoc *child_result_loc = nullptr;
5576 fields[i].value = expr_value;5578 if (result_loc != nullptr) {
5577 fields[i].source_node = entry_node;5579 IrInstruction *container_ptr = ir_build_resolve_result(irb, &result_loc->scope_elide->base,
5578 }5580 expr_node, result_loc, container_type);
5579 return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields);5581 IrInstruction *field_ptr = ir_build_field_ptr(irb, &result_loc->scope_elide->base, expr_node,
5580 } else if (kind == ContainerInitKindArray) {5582 container_ptr, name);
5581 size_t item_count = container_init_expr->entries.length;5583 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
5582 IrInstruction **values = allocate<IrInstruction *>(item_count);5584 result_loc_inst->base.id = ResultLocIdInstruction;
5583 for (size_t i = 0; i < item_count; i += 1) {5585 result_loc_inst->base.source_instruction = field_ptr;
5584 AstNode *expr_node = container_init_expr->entries.at(i);5586 ir_ref_instruction(field_ptr, irb->current_basic_block);
5585 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope);5587 child_result_loc = &result_loc_inst->base;
5586 if (expr_value == irb->codegen->invalid_instruction)5588 }
5587 return expr_value;5589
55885590 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, &result_loc->scope_elide->base,
5589 values[i] = expr_value;5591 LValNone, child_result_loc);
5590 }5592 if (expr_value == irb->codegen->invalid_instruction)
5591 return ir_build_container_init_list(irb, scope, node, container_type, item_count, values);5593 return expr_value;
5592 } else {5594
5593 zig_unreachable();5595 fields[i].name = name;
5596 fields[i].value = expr_value;
5597 fields[i].source_node = entry_node;
5598 }
5599 IrInstruction *init_fields = ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields);
5600
5601 return ir_lval_wrap(irb, scope, init_fields, lval, result_loc);
5602 }
5603 case ContainerInitKindArray: {
5604 size_t item_count = container_init_expr->entries.length;
5605 IrInstruction **values = allocate<IrInstruction *>(item_count);
5606 for (size_t i = 0; i < item_count; i += 1) {
5607 AstNode *expr_node = container_init_expr->entries.at(i);
5608 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope);
5609 if (expr_value == irb->codegen->invalid_instruction)
5610 return expr_value;
5611
5612 values[i] = expr_value;
5613 }
5614 IrInstruction *init_list = ir_build_container_init_list(irb, scope, node, container_type, item_count, values);
5615 return ir_lval_wrap(irb, scope, init_list, lval, result_loc);
5616 }
5594 }5617 }
5618 zig_unreachable();
5595}5619}
55965620
5597static ResultLocVar *create_var_result_loc(IrInstruction *alloca, ZigVar *var) {5621static ResultLocVar *create_var_result_loc(IrInstruction *alloca, ZigVar *var) {
...@@ -7885,7 +7909,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -7885,7 +7909,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
7885 case NodeTypePrefixOpExpr:7909 case NodeTypePrefixOpExpr:
7886 return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc);7910 return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc);
7887 case NodeTypeContainerInitExpr:7911 case NodeTypeContainerInitExpr:
7888 return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval, result_loc);7912 return ir_gen_container_init_expr(irb, scope, node, lval, result_loc);
7889 case NodeTypeVariableDeclaration:7913 case NodeTypeVariableDeclaration:
7890 return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval, result_loc);7914 return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval, result_loc);
7891 case NodeTypeWhileExpr:7915 case NodeTypeWhileExpr:
...@@ -14468,7 +14492,9 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in...@@ -14468,7 +14492,9 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in
14468 return &result->base;14492 return &result->base;
14469}14493}
1447014494
14471static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, ResultLoc *result_loc) {14495static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspend_source_instr,
14496 ResultLoc *result_loc)
14497{
14472 switch (result_loc->id) {14498 switch (result_loc->id) {
14473 case ResultLocIdInvalid:14499 case ResultLocIdInvalid:
14474 case ResultLocIdPeerParent:14500 case ResultLocIdPeerParent:
...@@ -14476,6 +14502,30 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, ResultLoc *result_lo...@@ -14476,6 +14502,30 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, ResultLoc *result_lo
14476 case ResultLocIdNone:14502 case ResultLocIdNone:
14477 case ResultLocIdVar:14503 case ResultLocIdVar:
14478 return nullptr;14504 return nullptr;
14505 case ResultLocIdInstruction:
14506 return result_loc->source_instruction->child->value.type;
14507 case ResultLocIdField: {
14508 if (result_loc->resolved_loc != nullptr) {
14509 ZigType *ptr_type = result_loc->resolved_loc->value.type;
14510 assert(ptr_type->id == ZigTypeIdPointer);
14511 return ptr_type->data.pointer.child_type;
14512 }
14513 ResultLocField *result_loc_field = reinterpret_cast<ResultLocField *>(result_loc);
14514 ZigType *container_type = ir_resolve_type(ira, result_loc_field->container_type->child);
14515 if (type_is_invalid(container_type))
14516 return ira->codegen->builtin_types.entry_invalid;
14517 if (container_type->id == ZigTypeIdStruct) {
14518 TypeStructField *field = find_struct_type_field(container_type, result_loc_field->name);
14519 if (field == nullptr) {
14520 return ira->codegen->builtin_types.entry_invalid;
14521 }
14522 return field->type_entry;
14523 } else if (container_type->id == ZigTypeIdUnion) {
14524 zig_panic("TODO");
14525 } else {
14526 zig_unreachable();
14527 }
14528 }
14479 case ResultLocIdReturn:14529 case ResultLocIdReturn:
14480 return ira->explicit_return_type;14530 return ira->explicit_return_type;
14481 case ResultLocIdPeer:14531 case ResultLocIdPeer:
...@@ -14491,7 +14541,10 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s...@@ -14491,7 +14541,10 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
14491 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value)14541 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value)
14492{14542{
14493 if (result_loc->resolved_loc != nullptr) {14543 if (result_loc->resolved_loc != nullptr) {
14494 return result_loc->resolved_loc;14544 // allow to redo the result location if the value is known and comptime and the previous one isn't
14545 if (value == nullptr || !instr_is_comptime(value) || instr_is_comptime(result_loc->resolved_loc)) {
14546 return result_loc->resolved_loc;
14547 }
14495 }14548 }
14496 result_loc->gen_instruction = value;14549 result_loc->gen_instruction = value;
14497 result_loc->implicit_elem_type = value_type;14550 result_loc->implicit_elem_type = value_type;
...@@ -14524,7 +14577,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s...@@ -14524,7 +14577,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
14524 return ira->codegen->invalid_instruction;14577 return ira->codegen->invalid_instruction;
14525 bool is_comptime = force_comptime || (value != nullptr &&14578 bool is_comptime = force_comptime || (value != nullptr &&
14526 value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const);14579 value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const);
14527 if (alloca_src->base.child == nullptr) {14580 if (alloca_src->base.child == nullptr || is_comptime) {
14528 uint32_t align = 0;14581 uint32_t align = 0;
14529 if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, &align)) {14582 if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, &align)) {
14530 return ira->codegen->invalid_instruction;14583 return ira->codegen->invalid_instruction;
...@@ -14539,12 +14592,40 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s...@@ -14539,12 +14592,40 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
14539 alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align,14592 alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align,
14540 alloca_src->name_hint, force_comptime);14593 alloca_src->name_hint, force_comptime);
14541 }14594 }
14595 if (alloca_src->base.child != nullptr) {
14596 alloca_src->base.child->ref_count = 0;
14597 }
14542 alloca_src->base.child = alloca_gen;14598 alloca_src->base.child = alloca_gen;
14543 }14599 }
14544 result_loc->written = true;14600 result_loc->written = true;
14545 result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child;14601 result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child;
14546 return result_loc->resolved_loc;14602 return result_loc->resolved_loc;
14547 }14603 }
14604 case ResultLocIdInstruction: {
14605 result_loc->written = true;
14606 result_loc->resolved_loc = result_loc->source_instruction->child;
14607 return result_loc->resolved_loc;
14608 }
14609 case ResultLocIdField: {
14610 ResultLocField *result_loc_field = reinterpret_cast<ResultLocField *>(result_loc);
14611
14612 ZigType *container_type = ir_resolve_type(ira, result_loc_field->container_type->child);
14613 if (type_is_invalid(container_type))
14614 return ira->codegen->invalid_instruction;
14615
14616 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr,
14617 result_loc_field->parent, container_type, nullptr);
14618 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
14619 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
14620 {
14621 return parent_result_loc;
14622 }
14623
14624 result_loc->written = true;
14625 result_loc->resolved_loc = ir_analyze_container_field_ptr(ira, result_loc_field->name,
14626 suspend_source_instr, parent_result_loc, container_type);
14627 return result_loc->resolved_loc;
14628 }
14548 case ResultLocIdReturn: {14629 case ResultLocIdReturn: {
14549 bool is_comptime = value != nullptr && value->value.special != ConstValSpecialRuntime;14630 bool is_comptime = value != nullptr && value->value.special != ConstValSpecialRuntime;
14550 if (is_comptime) return nullptr;14631 if (is_comptime) return nullptr;
...@@ -14593,7 +14674,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s...@@ -14593,7 +14674,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
14593 ira->resume_stack.append(opposite_peer->suspend_pos);14674 ira->resume_stack.append(opposite_peer->suspend_pos);
14594 }14675 }
14595 }14676 }
14596 ZigType *expected_type = ir_result_loc_expected_type(ira, peer_parent->parent);14677 ZigType *expected_type = ir_result_loc_expected_type(ira, suspend_source_instr, peer_parent->parent);
14597 peer_parent->resolved_type = ir_resolve_peer_types(ira,14678 peer_parent->resolved_type = ir_resolve_peer_types(ira,
14598 peer_parent->base.source_instruction->source_node, expected_type, instructions,14679 peer_parent->base.source_instruction->source_node, expected_type, instructions,
14599 peer_parent->peer_count);14680 peer_parent->peer_count);
...@@ -14626,6 +14707,12 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns...@@ -14626,6 +14707,12 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns
14626 return ir_implicit_cast(ira, target, dest_type);14707 return ir_implicit_cast(ira, target, dest_type);
14627}14708}
1462814709
14710static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {
14711 ZigType *ty = ir_resolve_type(ira, instruction->ty->child);
14712 if (type_is_invalid(ty))
14713 return ira->codegen->invalid_instruction;
14714 return ir_resolve_result(ira, &instruction->base, instruction->result_loc, ty, nullptr);
14715}
1462914716
14630static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,14717static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,
14631 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,14718 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,
...@@ -18330,8 +18417,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -18330,8 +18417,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1833018417
18331 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count);18418 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count);
1833218419
18333 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count);
18334
18335 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)18420 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)
18336 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;18421 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;
1833718422
...@@ -18371,9 +18456,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -18371,9 +18456,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
18371 }18456 }
18372 field_assign_nodes[field_index] = field->source_node;18457 field_assign_nodes[field_index] = field->source_node;
1837318458
18374 new_fields[field_index].value = casted_field_value;
18375 new_fields[field_index].type_struct_field = type_field;
18376
18377 if (const_val.special == ConstValSpecialStatic) {18459 if (const_val.special == ConstValSpecialStatic) {
18378 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) {18460 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) {
18379 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk);18461 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk);
...@@ -18416,9 +18498,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -18416,9 +18498,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
18416 IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type);18498 IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type);
18417 copy_const_val(&runtime_inst->value, field->init_val, true);18499 copy_const_val(&runtime_inst->value, field->init_val, true);
1841818500
18419 new_fields[i].value = runtime_inst;
18420 new_fields[i].type_struct_field = field;
18421
18422 if (const_val.special == ConstValSpecialStatic) {18501 if (const_val.special == ConstValSpecialStatic) {
18423 copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true);18502 copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true);
18424 }18503 }
...@@ -18451,12 +18530,11 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -18451,12 +18530,11 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
18451 return ira->codegen->invalid_instruction;18530 return ira->codegen->invalid_instruction;
18452 }18531 }
1845318532
18454 IrInstruction *new_instruction = ir_build_struct_init(&ira->new_irb,18533 // this instruction should not get to codegen
18455 instruction->scope, instruction->source_node,18534 IrInstruction *result = ir_const(ira, instruction, container_type);
18456 container_type, actual_field_count, new_fields);18535 // this is how we signal to EndExpr the value is not comptime known
18457 new_instruction->value.type = container_type;18536 result->value.special = ConstValSpecialRuntime;
18458 ir_add_alloca(ira, new_instruction, container_type);18537 return result;
18459 return new_instruction;
18460}18538}
1846118539
18462static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,18540static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
...@@ -23794,7 +23872,18 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct...@@ -23794,7 +23872,18 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct
23794 if (type_is_invalid(value->value.type))23872 if (type_is_invalid(value->value.type))
23795 return ira->codegen->invalid_instruction;23873 return ira->codegen->invalid_instruction;
2379623874
23797 if (!instruction->result_loc->written) {23875 bool want_resolve_result = instruction->result_loc->written;
23876 if (instruction->result_loc->written) {
23877 if (instruction->result_loc->scope_elide != nullptr && instr_is_comptime(value)) {
23878 want_resolve_result = true;
23879 instruction->result_loc->scope_elide->activated = true;
23880 } else {
23881 want_resolve_result = false;
23882 }
23883 } else {
23884 want_resolve_result = true;
23885 }
23886 if (want_resolve_result) {
23798 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,23887 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
23799 value->value.type, value);23888 value->value.type, value);
23800 if (result_loc != nullptr) {23889 if (result_loc != nullptr) {
...@@ -23815,7 +23904,6 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction...@@ -23815,7 +23904,6 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
23815 switch (instruction->id) {23904 switch (instruction->id) {
23816 case IrInstructionIdInvalid:23905 case IrInstructionIdInvalid:
23817 case IrInstructionIdWidenOrShorten:23906 case IrInstructionIdWidenOrShorten:
23818 case IrInstructionIdStructInit:
23819 case IrInstructionIdUnionInit:23907 case IrInstructionIdUnionInit:
23820 case IrInstructionIdStructFieldPtr:23908 case IrInstructionIdStructFieldPtr:
23821 case IrInstructionIdUnionFieldPtr:23909 case IrInstructionIdUnionFieldPtr:
...@@ -24036,6 +24124,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction...@@ -24036,6 +24124,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
24036 return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction);24124 return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction);
24037 case IrInstructionIdImplicitCast:24125 case IrInstructionIdImplicitCast:
24038 return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction);24126 return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction);
24127 case IrInstructionIdResolveResult:
24128 return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction);
24039 case IrInstructionIdOpaqueType:24129 case IrInstructionIdOpaqueType:
24040 return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction);24130 return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction);
24041 case IrInstructionIdSetAlignStack:24131 case IrInstructionIdSetAlignStack:
...@@ -24260,7 +24350,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24260,7 +24350,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24260 case IrInstructionIdCast:24350 case IrInstructionIdCast:
24261 case IrInstructionIdContainerInitList:24351 case IrInstructionIdContainerInitList:
24262 case IrInstructionIdContainerInitFields:24352 case IrInstructionIdContainerInitFields:
24263 case IrInstructionIdStructInit:
24264 case IrInstructionIdUnionInit:24353 case IrInstructionIdUnionInit:
24265 case IrInstructionIdFieldPtr:24354 case IrInstructionIdFieldPtr:
24266 case IrInstructionIdElemPtr:24355 case IrInstructionIdElemPtr:
...@@ -24326,6 +24415,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24326,6 +24415,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24326 case IrInstructionIdTypeId:24415 case IrInstructionIdTypeId:
24327 case IrInstructionIdAlignCast:24416 case IrInstructionIdAlignCast:
24328 case IrInstructionIdImplicitCast:24417 case IrInstructionIdImplicitCast:
24418 case IrInstructionIdResolveResult:
24329 case IrInstructionIdOpaqueType:24419 case IrInstructionIdOpaqueType:
24330 case IrInstructionIdArgType:24420 case IrInstructionIdArgType:
24331 case IrInstructionIdTagType:24421 case IrInstructionIdTagType:
src/ir_print.cpp+25-15
...@@ -207,6 +207,18 @@ static void ir_print_result_loc_var(IrPrint *irp, ResultLocVar *result_loc_var)...@@ -207,6 +207,18 @@ static void ir_print_result_loc_var(IrPrint *irp, ResultLocVar *result_loc_var)
207 fprintf(irp->f, ")");207 fprintf(irp->f, ")");
208}208}
209209
210static void ir_print_result_loc_instruction(IrPrint *irp, ResultLocInstruction *result_loc_inst) {
211 fprintf(irp->f, "inst(");
212 ir_print_other_instruction(irp, result_loc_inst->base.source_instruction);
213 fprintf(irp->f, ")");
214}
215
216static void ir_print_result_loc_field(IrPrint *irp, ResultLocField *result_loc_field) {
217 fprintf(irp->f, "field(name=%s,type=", buf_ptr(result_loc_field->name));
218 ir_print_other_instruction(irp, result_loc_field->container_type);
219 fprintf(irp->f, ")");
220}
221
210static void ir_print_result_loc_peer(IrPrint *irp, ResultLocPeer *result_loc_peer) {222static void ir_print_result_loc_peer(IrPrint *irp, ResultLocPeer *result_loc_peer) {
211 fprintf(irp->f, "peer(next=");223 fprintf(irp->f, "peer(next=");
212 ir_print_other_block(irp, result_loc_peer->next_bb);224 ir_print_other_block(irp, result_loc_peer->next_bb);
...@@ -225,6 +237,10 @@ static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {...@@ -225,6 +237,10 @@ static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
225 return;237 return;
226 case ResultLocIdVar:238 case ResultLocIdVar:
227 return ir_print_result_loc_var(irp, (ResultLocVar *)result_loc);239 return ir_print_result_loc_var(irp, (ResultLocVar *)result_loc);
240 case ResultLocIdInstruction:
241 return ir_print_result_loc_instruction(irp, (ResultLocInstruction *)result_loc);
242 case ResultLocIdField:
243 return ir_print_result_loc_field(irp, (ResultLocField *)result_loc);
228 case ResultLocIdPeer:244 case ResultLocIdPeer:
229 return ir_print_result_loc_peer(irp, (ResultLocPeer *)result_loc);245 return ir_print_result_loc_peer(irp, (ResultLocPeer *)result_loc);
230 case ResultLocIdPeerParent:246 case ResultLocIdPeerParent:
...@@ -352,18 +368,6 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI...@@ -352,18 +368,6 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI
352 fprintf(irp->f, "} // container init");368 fprintf(irp->f, "} // container init");
353}369}
354370
355static void ir_print_struct_init(IrPrint *irp, IrInstructionStructInit *instruction) {
356 fprintf(irp->f, "%s {", buf_ptr(&instruction->struct_type->name));
357 for (size_t i = 0; i < instruction->field_count; i += 1) {
358 IrInstructionStructInitField *field = &instruction->fields[i];
359 Buf *field_name = field->type_struct_field->name;
360 const char *comma = (i == 0) ? "" : ", ";
361 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field_name));
362 ir_print_other_instruction(irp, field->value);
363 }
364 fprintf(irp->f, "} // struct init");
365}
366
367static void ir_print_union_init(IrPrint *irp, IrInstructionUnionInit *instruction) {371static void ir_print_union_init(IrPrint *irp, IrInstructionUnionInit *instruction) {
368 Buf *field_name = instruction->field->enum_field->name;372 Buf *field_name = instruction->field->enum_field->name;
369373
...@@ -1265,6 +1269,12 @@ static void ir_print_implicit_cast(IrPrint *irp, IrInstructionImplicitCast *inst...@@ -1265,6 +1269,12 @@ static void ir_print_implicit_cast(IrPrint *irp, IrInstructionImplicitCast *inst
1265 fprintf(irp->f, ")");1269 fprintf(irp->f, ")");
1266}1270}
12671271
1272static void ir_print_resolve_result(IrPrint *irp, IrInstructionResolveResult *instruction) {
1273 fprintf(irp->f, "ResolveResult(");
1274 ir_print_result_loc(irp, instruction->result_loc);
1275 fprintf(irp->f, ")");
1276}
1277
1268static void ir_print_opaque_type(IrPrint *irp, IrInstructionOpaqueType *instruction) {1278static void ir_print_opaque_type(IrPrint *irp, IrInstructionOpaqueType *instruction) {
1269 fprintf(irp->f, "@OpaqueType()");1279 fprintf(irp->f, "@OpaqueType()");
1270}1280}
...@@ -1588,9 +1598,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1588,9 +1598,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1588 case IrInstructionIdContainerInitFields:1598 case IrInstructionIdContainerInitFields:
1589 ir_print_container_init_fields(irp, (IrInstructionContainerInitFields *)instruction);1599 ir_print_container_init_fields(irp, (IrInstructionContainerInitFields *)instruction);
1590 break;1600 break;
1591 case IrInstructionIdStructInit:
1592 ir_print_struct_init(irp, (IrInstructionStructInit *)instruction);
1593 break;
1594 case IrInstructionIdUnionInit:1601 case IrInstructionIdUnionInit:
1595 ir_print_union_init(irp, (IrInstructionUnionInit *)instruction);1602 ir_print_union_init(irp, (IrInstructionUnionInit *)instruction);
1596 break;1603 break;
...@@ -1900,6 +1907,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1900,6 +1907,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1900 case IrInstructionIdImplicitCast:1907 case IrInstructionIdImplicitCast:
1901 ir_print_implicit_cast(irp, (IrInstructionImplicitCast *)instruction);1908 ir_print_implicit_cast(irp, (IrInstructionImplicitCast *)instruction);
1902 break;1909 break;
1910 case IrInstructionIdResolveResult:
1911 ir_print_resolve_result(irp, (IrInstructionResolveResult *)instruction);
1912 break;
1903 case IrInstructionIdOpaqueType:1913 case IrInstructionIdOpaqueType:
1904 ir_print_opaque_type(irp, (IrInstructionOpaqueType *)instruction);1914 ir_print_opaque_type(irp, (IrInstructionOpaqueType *)instruction);
1905 break;1915 break;