From: Keith Walker Date: Fri, 16 Sep 2016 14:07:29 +0000 (+0000) Subject: Place the lowered phi instruction(s) before the DEBUG_VALUE entry X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7435b28542b3cd8f6df1a9d4efb54bd664799527;p=llvm Place the lowered phi instruction(s) before the DEBUG_VALUE entry When a phi node is finally lowered to a machine instruction it is important that the lowered "load" instruction is placed before the associated DEBUG_VALUE entry describing the value loaded. Renamed the existing SkipPHIsAndLabels to SkipPHIsLabelsAndDebug to more fully describe that it also skips debug entries. Then used the "new" function SkipPHIsAndLabels when the debug information should not be skipped when placing the lowered "load" instructions so that it is placed before the debug entries. Differential Revision: https://reviews.llvm.org/D23760 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281727 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 57e599118d3..9ecfc420fba 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -455,10 +455,15 @@ public: iterator getFirstNonPHI(); /// Return the first instruction in MBB after I that is not a PHI or a label. - /// This is the correct point to insert copies at the beginning of a basic - /// block. + /// This is the correct point to insert lowered copies at the beginning of a + /// basic block that must be before any debugging information. iterator SkipPHIsAndLabels(iterator I); + /// Return the first instruction in MBB after I that is not a PHI, label or + /// debug. This is the correct point to insert copies at the beginning of a + /// basic block. + iterator SkipPHIsLabelsAndDebug(iterator I); + /// Returns an iterator to the first terminator instruction of this basic /// block. If a terminator does not exist, it returns end(). iterator getFirstTerminator(); diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index 15f77c620c7..3ccc18d120f 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -377,7 +377,7 @@ bool InlineSpiller::hoistSpillInsideBB(LiveInterval &SpillLI, MachineBasicBlock *MBB = LIS.getMBBFromIndex(SrcVNI->def); MachineBasicBlock::iterator MII; if (SrcVNI->isPHIDef()) - MII = MBB->SkipPHIsAndLabels(MBB->begin()); + MII = MBB->SkipPHIsLabelsAndDebug(MBB->begin()); else { MachineInstr *DefMI = LIS.getInstructionFromIndex(SrcVNI->def); assert(DefMI && "Defining instruction disappeared"); diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 966b4f1f4e4..97531971c9d 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -951,7 +951,7 @@ findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, while (!(MI = LIS.getInstructionFromIndex(Idx))) { // We've reached the beginning of MBB. if (Idx == Start) { - MachineBasicBlock::iterator I = MBB->SkipPHIsAndLabels(MBB->begin()); + MachineBasicBlock::iterator I = MBB->SkipPHIsLabelsAndDebug(MBB->begin()); return I; } Idx = Idx.getPrevIndex(); diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index b43a253e2df..55138f64198 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -148,13 +148,26 @@ MachineBasicBlock::iterator MachineBasicBlock::getFirstNonPHI() { MachineBasicBlock::iterator MachineBasicBlock::SkipPHIsAndLabels(MachineBasicBlock::iterator I) { + iterator E = end(); + while (I != E && (I->isPHI() || I->isPosition())) + ++I; + // FIXME: This needs to change if we wish to bundle labels + // inside the bundle. + assert((I == E || !I->isInsideBundle()) && + "First non-phi / non-label instruction is inside a bundle!"); + return I; +} + +MachineBasicBlock::iterator +MachineBasicBlock::SkipPHIsLabelsAndDebug(MachineBasicBlock::iterator I) { iterator E = end(); while (I != E && (I->isPHI() || I->isPosition() || I->isDebugValue())) ++I; // FIXME: This needs to change if we wish to bundle labels / dbg_values // inside the bundle. assert((I == E || !I->isInsideBundle()) && - "First non-phi / non-label instruction is inside a bundle!"); + "First non-phi / non-label / non-debug " + "instruction is inside a bundle!"); return I; } diff --git a/lib/CodeGen/PHIEliminationUtils.cpp b/lib/CodeGen/PHIEliminationUtils.cpp index 4cabc3a8c1f..4e67ff2e508 100644 --- a/lib/CodeGen/PHIEliminationUtils.cpp +++ b/lib/CodeGen/PHIEliminationUtils.cpp @@ -54,6 +54,7 @@ llvm::findPHICopyInsertPoint(MachineBasicBlock* MBB, MachineBasicBlock* SuccMBB, ++InsertPoint; } - // Make sure the copy goes after any phi nodes however. + // Make sure the copy goes after any phi nodes but before + // any debug nodes. return MBB->SkipPHIsAndLabels(InsertPoint); } diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp index e06bc4a3614..2d5a9d6a92c 100644 --- a/lib/CodeGen/SplitKit.cpp +++ b/lib/CodeGen/SplitKit.cpp @@ -675,7 +675,7 @@ SlotIndex SplitEditor::leaveIntvAtTop(MachineBasicBlock &MBB) { } VNInfo *VNI = defFromParent(0, ParentVNI, Start, MBB, - MBB.SkipPHIsAndLabels(MBB.begin())); + MBB.SkipPHIsLabelsAndDebug(MBB.begin())); RegAssign.insert(Start, VNI->def, OpenIdx); DEBUG(dump()); return VNI->def; diff --git a/lib/Target/PowerPC/PPCEarlyReturn.cpp b/lib/Target/PowerPC/PPCEarlyReturn.cpp index cad4f4f2289..6bd229625fc 100644 --- a/lib/Target/PowerPC/PPCEarlyReturn.cpp +++ b/lib/Target/PowerPC/PPCEarlyReturn.cpp @@ -58,7 +58,7 @@ protected: bool Changed = false; MachineBasicBlock::iterator I = ReturnMBB.begin(); - I = ReturnMBB.SkipPHIsAndLabels(I); + I = ReturnMBB.SkipPHIsLabelsAndDebug(I); // The block must be essentially empty except for the blr. if (I == ReturnMBB.end() || diff --git a/test/CodeGen/AArch64/phi-dbg.ll b/test/CodeGen/AArch64/phi-dbg.ll new file mode 100644 index 00000000000..a1adf0f50d9 --- /dev/null +++ b/test/CodeGen/AArch64/phi-dbg.ll @@ -0,0 +1,75 @@ +; RUN: llc -O0 %s -mtriple=aarch64 -o - | FileCheck %s + +; Test that a DEBUG_VALUE node is create for variable c after the phi has been +; converted to a ldr. The DEBUG_VALUE must be *after* the ldr and not before it. + +; Created from the C code, compiled with -O0 -g and then passed through opt -mem2reg: +; +; int func(int a) +; { +; int c = 1; +; if (a < 0 ) { +; c = 12; +; } +; return c; +; } +; +; Function Attrs: nounwind +define i32 @func(i32) #0 !dbg !8 { + call void @llvm.dbg.value(metadata i32 %0, i64 0, metadata !12, metadata !13), !dbg !14 + call void @llvm.dbg.value(metadata i32 1, i64 0, metadata !15, metadata !13), !dbg !16 + %2 = icmp slt i32 %0, 0, !dbg !17 + br i1 %2, label %3, label %4, !dbg !19 + +;