summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/CodeGen/MachineBasicBlock.h9
-rw-r--r--llvm/lib/CodeGen/InlineSpiller.cpp2
-rw-r--r--llvm/lib/CodeGen/LiveDebugVariables.cpp2
-rw-r--r--llvm/lib/CodeGen/MachineBasicBlock.cpp15
-rw-r--r--llvm/lib/CodeGen/PHIEliminationUtils.cpp3
-rw-r--r--llvm/lib/CodeGen/SplitKit.cpp2
-rw-r--r--llvm/lib/Target/PowerPC/PPCEarlyReturn.cpp2
-rw-r--r--llvm/test/CodeGen/AArch64/phi-dbg.ll75
8 files changed, 102 insertions, 8 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index 57e599118d3..9ecfc420fba 100644
--- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/llvm/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/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp
index 15f77c620c7..3ccc18d120f 100644
--- a/llvm/lib/CodeGen/InlineSpiller.cpp
+++ b/llvm/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/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 966b4f1f4e4..97531971c9d 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/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/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index b43a253e2df..55138f64198 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -149,12 +149,25 @@ 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/llvm/lib/CodeGen/PHIEliminationUtils.cpp b/llvm/lib/CodeGen/PHIEliminationUtils.cpp
index 4cabc3a8c1f..4e67ff2e508 100644
--- a/llvm/lib/CodeGen/PHIEliminationUtils.cpp
+++ b/llvm/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/llvm/lib/CodeGen/SplitKit.cpp b/llvm/lib/CodeGen/SplitKit.cpp
index e06bc4a3614..2d5a9d6a92c 100644
--- a/llvm/lib/CodeGen/SplitKit.cpp
+++ b/llvm/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/llvm/lib/Target/PowerPC/PPCEarlyReturn.cpp b/llvm/lib/Target/PowerPC/PPCEarlyReturn.cpp
index cad4f4f2289..6bd229625fc 100644
--- a/llvm/lib/Target/PowerPC/PPCEarlyReturn.cpp
+++ b/llvm/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/llvm/test/CodeGen/AArch64/phi-dbg.ll b/llvm/test/CodeGen/AArch64/phi-dbg.ll
new file mode 100644
index 00000000000..a1adf0f50d9
--- /dev/null
+++ b/llvm/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
+
+; <label>:3: ; preds = %1
+ call void @llvm.dbg.value(metadata i32 12, i64 0, metadata !15, metadata !13), !dbg !16
+ br label %4, !dbg !20
+
+; <label>:4: ; preds = %3, %1
+ %.0 = phi i32 [ 12, %3 ], [ 1, %1 ]
+; CHECK: ldr w[[REG:[0-9]+]], [sp, #8]
+; CHECK-NEXT: .Ltmp
+ call void @llvm.dbg.value(metadata i32 %.0, i64 0, metadata !15, metadata !13), !dbg !16
+; CHECK-NEXT: //DEBUG_VALUE: func:c <- %W[[REG]]
+ %5 = add nsw i32 %.0, %0, !dbg !22
+ call void @llvm.dbg.value(metadata i32 %5, i64 0, metadata !15, metadata !13), !dbg !16
+ ret i32 %5, !dbg !23
+}
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5, !6}
+!llvm.ident = !{!7}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "a.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{i32 1, !"min_enum_size", i32 4}
+!7 = !{!"clang"}
+!8 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
+!9 = !DISubroutineType(types: !10)
+!10 = !{!11, !11}
+!11 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+!12 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 1, type: !11)
+!13 = !DIExpression()
+!14 = !DILocation(line: 1, column: 14, scope: !8)
+!15 = !DILocalVariable(name: "c", scope: !8, file: !1, line: 3, type: !11)
+!16 = !DILocation(line: 3, column: 13, scope: !8)
+!17 = !DILocation(line: 4, column: 15, scope: !18)
+!18 = distinct !DILexicalBlock(scope: !8, file: !1, line: 4, column: 13)
+!19 = !DILocation(line: 4, column: 13, scope: !8)
+!20 = !DILocation(line: 6, column: 9, scope: !21)
+!21 = distinct !DILexicalBlock(scope: !18, file: !1, line: 4, column: 21)
+!22 = !DILocation(line: 7, column: 4, scope: !8)
+!23 = !DILocation(line: 8, column: 9, scope: !8)
OpenPOWER on IntegriCloud