zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit e6fa2ee70632ef1efbe3ebc54214abf30d6d40c1 (tree)
parent 1526d89711c90a4a98dfecb6d3c64f28c3ab7da6
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Wed, 12 Jun 2019 18:08:56 -0400

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
}
```

Diffstat:
Msrc/all_types.hpp | 1+
Msrc/ir.cpp | 27++++++++++++++++-----------
2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/src/all_types.hpp b/src/all_types.hpp @@ -3652,6 +3652,7 @@ struct ResultLocReturn { struct ResultLocPeerParent { ResultLoc base; + bool skipped; ResultLoc *parent; ResultLocPeer *peers; size_t peer_count; diff --git a/src/ir.cpp b/src/ir.cpp @@ -14899,7 +14899,10 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s bool is_comptime; if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) return ira->codegen->invalid_instruction; - if (is_comptime) return nullptr; + peer_parent->skipped = is_comptime; + if (peer_parent->skipped) { + return nullptr; + } if (peer_parent->resolved_type == nullptr) { 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 { return parent_result_loc; } + result_loc->written = true; result_loc->resolved_loc = parent_result_loc; return result_loc->resolved_loc; } @@ -16385,16 +16389,15 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh } ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; - if (peer_parent != nullptr && peer_parent->resolved_type == nullptr) { - bool is_comptime; - if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) - return ira->codegen->invalid_instruction; - if (is_comptime) goto skip_peer_stuff; - + if (peer_parent != nullptr && peer_parent->resolved_type == nullptr && !peer_parent->skipped) { // Suspend the phi first so that it gets resumed last - IrSuspendPosition suspend_pos; - ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); - ira->resume_stack.append(suspend_pos); + ira->resume_stack.add_one(); + for (size_t i = ira->resume_stack.length;;) { + if (i <= 1) break; + i -= 1; + ira->resume_stack.items[i] = ira->resume_stack.items[i-1]; + } + ira_suspend(ira, &phi_instruction->base, nullptr, &ira->resume_stack.items[0]); IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count); 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 return ira_resume(ira); } -skip_peer_stuff: ZigList<IrBasicBlock*> new_incoming_blocks = {0}; ZigList<IrInstruction*> new_incoming_values = {0}; @@ -24598,6 +24600,9 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_ continue; } + if (ira->codegen->verbose_ir) { + fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id); + } IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction); if (new_instruction != nullptr) { ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);