authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-12 18:08:56-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-12 18:08:56-04:00
loge6fa2ee70632ef1efbe3ebc54214abf30d6d40c1
treed9185c839d2efae13b5a7a35e34364914a7a52b7
parent1526d89711c90a4a98dfecb6d3c64f28c3ab7da6
signature Commit is signed but in an unrecognized format.

fix nested peer result locs with no memory loc

```zig export fn entry2(c: bool) i32 { return if (c) i32(0) else if (c) i32(1) else i32(2); } ``` ```llvm define i32 @entry2(i1) #2 !dbg !35 { Entry: %c = alloca i1, align 1 store i1 %0, i1* %c, align 1 call void @llvm.dbg.declare(metadata i1* %c, metadata !41, metadata !DIExpression()), !dbg !42 %1 = load i1, i1* %c, align 1, !dbg !43 br i1 %1, label %Then, label %Else, !dbg !43 Then: ; preds = %Entry br label %EndIf3, !dbg !45 Else: ; preds = %Entry %2 = load i1, i1* %c, align 1, !dbg !46 br i1 %2, label %Then1, label %Else2, !dbg !46 Then1: ; preds = %Else br label %EndIf, !dbg !47 Else2: ; preds = %Else br label %EndIf, !dbg !47 EndIf: ; preds = %Else2, %Then1 %3 = phi i32 [ 1, %Then1 ], [ 2, %Else2 ], !dbg !47 br label %EndIf3, !dbg !45 EndIf3: ; preds = %EndIf, %Then %4 = phi i32 [ 0, %Then ], [ %3, %EndIf ], !dbg !45 ret i32 %4, !dbg !48 } ```

2 files changed, 17 insertions(+), 11 deletions(-)

src/all_types.hpp+1
...@@ -3652,6 +3652,7 @@ struct ResultLocReturn {...@@ -3652,6 +3652,7 @@ struct ResultLocReturn {
3652struct ResultLocPeerParent {3652struct ResultLocPeerParent {
3653 ResultLoc base;3653 ResultLoc base;
36543654
3655 bool skipped;
3655 ResultLoc *parent;3656 ResultLoc *parent;
3656 ResultLocPeer *peers;3657 ResultLocPeer *peers;
3657 size_t peer_count;3658 size_t peer_count;
src/ir.cpp+16-11
...@@ -14899,7 +14899,10 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s...@@ -14899,7 +14899,10 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
14899 bool is_comptime;14899 bool is_comptime;
14900 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime))14900 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime))
14901 return ira->codegen->invalid_instruction;14901 return ira->codegen->invalid_instruction;
14902 if (is_comptime) return nullptr;14902 peer_parent->skipped = is_comptime;
14903 if (peer_parent->skipped) {
14904 return nullptr;
14905 }
1490314906
14904 if (peer_parent->resolved_type == nullptr) {14907 if (peer_parent->resolved_type == nullptr) {
14905 ResultLocPeer *last_peer = &peer_parent->peers[peer_parent->peer_count - 1];14908 ResultLocPeer *last_peer = &peer_parent->peers[peer_parent->peer_count - 1];
...@@ -14916,6 +14919,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s...@@ -14916,6 +14919,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
14916 {14919 {
14917 return parent_result_loc;14920 return parent_result_loc;
14918 }14921 }
14922 result_loc->written = true;
14919 result_loc->resolved_loc = parent_result_loc;14923 result_loc->resolved_loc = parent_result_loc;
14920 return result_loc->resolved_loc;14924 return result_loc->resolved_loc;
14921 }14925 }
...@@ -16385,16 +16389,15 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh...@@ -16385,16 +16389,15 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
16385 }16389 }
1638616390
16387 ResultLocPeerParent *peer_parent = phi_instruction->peer_parent;16391 ResultLocPeerParent *peer_parent = phi_instruction->peer_parent;
16388 if (peer_parent != nullptr && peer_parent->resolved_type == nullptr) {16392 if (peer_parent != nullptr && peer_parent->resolved_type == nullptr && !peer_parent->skipped) {
16389 bool is_comptime;
16390 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime))
16391 return ira->codegen->invalid_instruction;
16392 if (is_comptime) goto skip_peer_stuff;
16393
16394 // Suspend the phi first so that it gets resumed last16393 // Suspend the phi first so that it gets resumed last
16395 IrSuspendPosition suspend_pos;16394 ira->resume_stack.add_one();
16396 ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos);16395 for (size_t i = ira->resume_stack.length;;) {
16397 ira->resume_stack.append(suspend_pos);16396 if (i <= 1) break;
16397 i -= 1;
16398 ira->resume_stack.items[i] = ira->resume_stack.items[i-1];
16399 }
16400 ira_suspend(ira, &phi_instruction->base, nullptr, &ira->resume_stack.items[0]);
1639816401
16399 IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count);16402 IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count);
16400 for (size_t i = 0; i < peer_parent->peer_count; i += 1) {16403 for (size_t i = 0; i < peer_parent->peer_count; i += 1) {
...@@ -16427,7 +16430,6 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh...@@ -16427,7 +16430,6 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
1642716430
16428 return ira_resume(ira);16431 return ira_resume(ira);
16429 }16432 }
16430skip_peer_stuff:
1643116433
16432 ZigList<IrBasicBlock*> new_incoming_blocks = {0};16434 ZigList<IrBasicBlock*> new_incoming_blocks = {0};
16433 ZigList<IrInstruction*> new_incoming_values = {0};16435 ZigList<IrInstruction*> new_incoming_values = {0};
...@@ -24598,6 +24600,9 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_...@@ -24598,6 +24600,9 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
24598 continue;24600 continue;
24599 }24601 }
2460024602
24603 if (ira->codegen->verbose_ir) {
24604 fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id);
24605 }
24601 IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction);24606 IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction);
24602 if (new_instruction != nullptr) {24607 if (new_instruction != nullptr) {
24603 ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);24608 ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);