return true;
}
+// Returns true if any instruction in MBB has the same debug location as DL.
+// Also returns true if DL is an empty location.
+static bool hasSameDebugLoc(const MachineBasicBlock *MBB, DebugLoc DL) {
+ for (const auto &MI : *MBB)
+ if (MI.getDebugLoc() == DL)
+ return true;
+ return false;
+}
+
// Sink 'Def', and also sink its eligible DBG_VALUEs to the place before
// 'Insert'. Convert the original DBG_VALUEs into undefs.
//
getSinkableDebugValues(Insert);
// Sink Def first.
+ //
+ // When moving to a different BB, we preserve the debug loc only if the
+ // destination BB contains the same location. See
+ // https://llvm.org/docs/HowToUpdateDebugInfo.html#when-to-preserve-an-instruction-location.
+ if (Def->getParent() != MBB && !hasSameDebugLoc(MBB, Def->getDebugLoc()))
+ Def->setDebugLoc(DebugLoc());
MBB->splice(Insert, Def->getParent(), Def);
if (DbgValues.empty())
// Clone Def first.
if (CloneDef) {
MachineInstr *Clone = MF->CloneMachineInstr(Def);
+ // When cloning to a different BB, we preserve the debug loc only if the
+ // destination BB contains the same location. See
+ // https://llvm.org/docs/HowToUpdateDebugInfo.html#when-to-preserve-an-instruction-location.
+ if (Def->getParent() != MBB && !hasSameDebugLoc(MBB, Def->getDebugLoc()))
+ Clone->setDebugLoc(DebugLoc());
if (NewReg != CurrentReg && NewReg.isValid())
Clone->getOperand(0).setReg(NewReg);
MBB->insert(Insert, Clone);
--- /dev/null
+# RUN: llc -run-pass wasm-reg-stackify %s -o - | FileCheck %s
+
+--- |
+ target triple = "wasm32-unknown-unknown"
+
+ declare void @use(i32)
+
+ define void @sink_same_bb() {
+ unreachable
+ }
+ define void @clone_same_bb() {
+ unreachable
+ }
+ define void @clone_different_bb_0() {
+ unreachable
+ }
+ define void @clone_different_bb_1() {
+ unreachable
+ }
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!2, !3, !4}
+
+ !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, emissionKind: FullDebug)
+ !1 = !DIFile(filename: "test.c", directory: "")
+ !2 = !{i32 7, !"Dwarf Version", i32 5}
+ !3 = !{i32 2, !"Debug Info Version", i32 3}
+ !4 = !{i32 1, !"wchar_size", i32 4}
+ !6 = distinct !DISubprogram(name: "sink_same_bb", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
+ !7 = !DISubroutineType(types: !8)
+ !8 = !{null}
+...
+
+---
+# Sinking within the same BB preserves the debug location.
+# CHECK-LABEL: name: sink_same_bb
+name: sink_same_bb
+liveins:
+ - { reg: '$arguments' }
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $arguments
+ %0:i32 = CONST_I32 1, implicit-def $arguments, debug-location !DILocation(line:10, scope:!6)
+ NOP implicit-def $arguments
+ CALL @use, %0:i32, implicit-def $arguments
+ RETURN implicit-def $arguments
+
+ ; CHECK: %0:i32 = CONST_I32 1, {{.*}}, debug-location !DILocation(line: 10
+ ; CHECK-NEXT: CALL @use
+...
+
+---
+# Cloning within the same BB preserves the debug location.
+# CHECK-LABEL: name: clone_same_bb
+name: clone_same_bb
+liveins:
+ - { reg: '$arguments' }
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $arguments
+ %0:i32 = CONST_I32 1, implicit-def $arguments, debug-location !DILocation(line:10, scope:!6)
+ NOP implicit-def $arguments
+ CALL @use, %0:i32, implicit-def $arguments
+ CALL @use, %0:i32, implicit-def $arguments
+ RETURN implicit-def $arguments
+
+ ; CHECK: CALL @use
+ ; CHECK-NEXT: %1:i32 = CONST_I32 1, {{.*}}, debug-location !DILocation(line: 10
+ ; CHECK-NEXT: CALL @use
+...
+
+---
+# Cloning to a different BB preserves the debug location in this case because
+# the destination BB has an instruction that has the same debug location
+# (test.c:10).
+# CHECK-LABEL: name: clone_different_bb_0
+name: clone_different_bb_0
+liveins:
+ - { reg: '$arguments' }
+tracksRegLiveness: true
+body: |
+ bb.0:
+ successors: %bb.1
+ liveins: $arguments
+ %0:i32 = CONST_I32 1, implicit-def $arguments, debug-location !DILocation(line:10, scope:!6)
+ BR %bb.1, implicit-def $arguments
+
+ bb.1:
+ ; predecessors: %bb.0
+ CALL @use, %0:i32, implicit-def $arguments, debug-location !DILocation(line:10, scope:!6)
+ RETURN implicit-def $arguments
+
+ ; CHECK: bb.1:
+ ; CHECK: %1:i32 = CONST_I32 1, {{.*}}, debug-location !DILocation(line: 10
+ ; CHECK-NEXT: CALL @use, %1, {{.*}}, debug-location !DILocation(line: 10
+...
+
+---
+# Cloning to a different BB does NOT preserve the debug location in this case
+# because the destination BB doesn't have an instruction that has the same debug
+# location (It has test.c:20 but not test.c:10).
+# CHECK-LABEL: name: clone_different_bb_1
+name: clone_different_bb_1
+liveins:
+ - { reg: '$arguments' }
+tracksRegLiveness: true
+body: |
+ bb.0:
+ successors: %bb.1
+ liveins: $arguments
+ %0:i32 = CONST_I32 1, implicit-def $arguments, debug-location !DILocation(line:10, scope:!6)
+ BR %bb.1, implicit-def $arguments
+
+ bb.1:
+ ; predecessors: %bb.0
+ CALL @use, %0:i32, implicit-def $arguments, debug-location !DILocation(line:20, scope:!6)
+ RETURN implicit-def $arguments
+
+ ; CHECK: bb.1:
+ ; CHECK: %1:i32 = CONST_I32 1
+ ; CHECK-NOT: %1:i32 = CONST_I32 1, {{.*}}, debug-location !DILocation(line: 10
+ ; CHECK-NEXT: CALL @use, %1, {{.*}}, debug-location !DILocation(line: 20
+...