summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/MachineSink.cpp61
-rw-r--r--llvm/test/CodeGen/X86/postra-ignore-dbg-instrs.mir88
2 files changed, 124 insertions, 25 deletions
diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp
index c09539d9903..354f46e9e62 100644
--- a/llvm/lib/CodeGen/MachineSink.cpp
+++ b/llvm/lib/CodeGen/MachineSink.cpp
@@ -753,6 +753,37 @@ static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI,
MBP.LHS.getReg() == BaseReg;
}
+/// Sink an instruction and its associated debug instructions.
+static void performSink(MachineInstr &MI, MachineBasicBlock &SuccToSinkTo,
+ MachineBasicBlock::iterator InsertPos) {
+ // Collect matching debug values.
+ SmallVector<MachineInstr *, 2> DbgValuesToSink;
+ collectDebugValues(MI, DbgValuesToSink);
+
+ // If we cannot find a location to use (merge with), then we erase the debug
+ // location to prevent debug-info driven tools from potentially reporting
+ // wrong location information.
+ if (!SuccToSinkTo.empty() && InsertPos != SuccToSinkTo.end())
+ MI.setDebugLoc(DILocation::getMergedLocation(MI.getDebugLoc(),
+ InsertPos->getDebugLoc()));
+ else
+ MI.setDebugLoc(DebugLoc());
+
+ // Move the instruction.
+ MachineBasicBlock *ParentBlock = MI.getParent();
+ SuccToSinkTo.splice(InsertPos, ParentBlock, MI,
+ ++MachineBasicBlock::iterator(MI));
+
+ // Move previously adjacent debug value instructions to the insert position.
+ for (SmallVectorImpl<MachineInstr *>::iterator DBI = DbgValuesToSink.begin(),
+ DBE = DbgValuesToSink.end();
+ DBI != DBE; ++DBI) {
+ MachineInstr *DbgMI = *DBI;
+ SuccToSinkTo.splice(InsertPos, ParentBlock, DbgMI,
+ ++MachineBasicBlock::iterator(DbgMI));
+ }
+}
+
/// SinkInstruction - Determine whether it is safe to sink the specified machine
/// instruction out of its current block into a successor.
bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
@@ -866,30 +897,7 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,
while (InsertPos != SuccToSinkTo->end() && InsertPos->isPHI())
++InsertPos;
- // collect matching debug values.
- SmallVector<MachineInstr *, 2> DbgValuesToSink;
- collectDebugValues(MI, DbgValuesToSink);
-
- // Merge or erase debug location to ensure consistent stepping in profilers
- // and debuggers.
- if (!SuccToSinkTo->empty() && InsertPos != SuccToSinkTo->end())
- MI.setDebugLoc(DILocation::getMergedLocation(MI.getDebugLoc(),
- InsertPos->getDebugLoc()));
- else
- MI.setDebugLoc(DebugLoc());
-
-
- // Move the instruction.
- SuccToSinkTo->splice(InsertPos, ParentBlock, MI,
- ++MachineBasicBlock::iterator(MI));
-
- // Move previously adjacent debug value instructions to the insert position.
- for (SmallVectorImpl<MachineInstr *>::iterator DBI = DbgValuesToSink.begin(),
- DBE = DbgValuesToSink.end(); DBI != DBE; ++DBI) {
- MachineInstr *DbgMI = *DBI;
- SuccToSinkTo->splice(InsertPos, ParentBlock, DbgMI,
- ++MachineBasicBlock::iterator(DbgMI));
- }
+ performSink(MI, *SuccToSinkTo, InsertPos);
// Conservatively, clear any kill flags, since it's possible that they are no
// longer correct.
@@ -1118,6 +1126,9 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
MachineInstr *MI = &*I;
++I;
+ if (MI->isDebugInstr())
+ continue;
+
// Do not move any instruction across function call.
if (MI->isCall())
return false;
@@ -1158,7 +1169,7 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB,
// block.
clearKillFlags(MI, CurBB, UsedOpsInCopy, UsedRegUnits, TRI);
MachineBasicBlock::iterator InsertPos = SuccBB->getFirstNonPHI();
- SuccBB->splice(InsertPos, &CurBB, MI);
+ performSink(*MI, *SuccBB, InsertPos);
updateLiveIn(MI, SuccBB, UsedOpsInCopy, DefedRegsInCopy);
Changed = true;
diff --git a/llvm/test/CodeGen/X86/postra-ignore-dbg-instrs.mir b/llvm/test/CodeGen/X86/postra-ignore-dbg-instrs.mir
new file mode 100644
index 00000000000..0286e6e68bf
--- /dev/null
+++ b/llvm/test/CodeGen/X86/postra-ignore-dbg-instrs.mir
@@ -0,0 +1,88 @@
+# RUN: llc -mtriple=x86_64-none-linux-gnu -run-pass=postra-machine-sink -verify-machineinstrs -o - %s | FileCheck %s
+#
+# This test was originally generated from the following sample:
+#
+# int x0;
+# extern void x3(int, int);
+# void x1(int x2) {
+# if (x0)
+# x3(0, x2);
+# }
+#
+# The code generates a COPY instruction which the PostRA Machine Sink pass will
+# try to sink. Earlier versions were not performing the sink due to a
+# DBG_VALUE instruction confusing the sinking algorithm.
+
+--- |
+ @x0 = common dso_local global i32 0, align 4, !dbg !0
+
+ define dso_local void @x1(i32) !dbg !11 {
+ %2 = alloca i32, align 4
+ store i32 %0, i32* %2, align 4
+ call void @llvm.dbg.declare(metadata i32* %2, metadata !14, metadata !DIExpression()), !dbg !16
+ %3 = load i32, i32* @x0, align 4, !dbg !16
+ %4 = icmp ne i32 %3, 0, !dbg !16
+ br i1 %4, label %5, label %7, !dbg !16
+
+ ; <label>:5: ; preds = %1
+ %6 = load i32, i32* %2, align 4, !dbg !16
+ call void @x3(i32 0, i32 %6), !dbg !16
+ br label %7, !dbg !16
+
+ ; <label>:7: ; preds = %5, %1
+ ret void, !dbg !16
+ }
+
+ declare void @llvm.dbg.declare(metadata, metadata, metadata)
+ declare dso_local void @x3(i32, i32)
+
+ !llvm.dbg.cu = !{!2}
+ !llvm.module.flags = !{!7, !8}
+
+ !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+ !1 = distinct !DIGlobalVariable(name: "x0", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true)
+ !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+ !3 = !DIFile(filename: "test.c", directory: "")
+ !4 = !{}
+ !5 = !{!0}
+ !6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+ !7 = !{i32 2, !"Dwarf Version", i32 4}
+ !8 = !{i32 2, !"Debug Info Version", i32 3}
+ !11 = distinct !DISubprogram(name: "x1", scope: !3, file: !3, line: 3, type: !12, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !2)
+ !12 = !DISubroutineType(types: !13)
+ !13 = !{null, !6}
+ !14 = !DILocalVariable(name: "x2", arg: 1, scope: !11, file: !3, line: 3, type: !6)
+ !15 = distinct !DILexicalBlock(scope: !11, file: !3, line: 4, column: 7)
+ !16 = !DILocation(line: 4, column: 7, scope: !15)
+
+...
+---
+# CHECK: name: x1
+# CHECK: bb.0:
+# CHECK-NOT: $eax = COPY $edi
+# CHECK: bb.1:
+# CHECK: renamable $eax = COPY $edi
+# CHECK-NEXT: DBG_VALUE debug-use $eax,
+# CHECK: bb.2:
+name: x1
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ successors: %bb.2, %bb.1; %bb.2, %bb.1
+ liveins: $edi
+ DBG_VALUE debug-use $edi, debug-use $noreg, !14, !DIExpression(), debug-location !16
+ renamable $eax = COPY $edi
+ DBG_VALUE debug-use $eax, debug-use $noreg, !14, !DIExpression(), debug-location !16
+ CMP32mi8 $rip, 1, $noreg, @x0, $noreg, 0, implicit-def $eflags, debug-location !16
+ JE_1 %bb.2, implicit killed $eflags, debug-location !16
+ JMP_1 %bb.1, debug-location !16
+
+ bb.1:
+ liveins: $eax
+ $edi = MOV32r0 implicit-def dead $eflags, debug-location !16
+ $esi = COPY killed renamable $eax, debug-location !16
+
+ bb.2:
+ RET 0, debug-location !16
+...
OpenPOWER on IntegriCloud