From: Heejin Ahn Date: Mon, 27 Mar 2023 03:52:22 +0000 (-0700) Subject: [WebAssembly] Handle DebugLoc in DebugValueManager X-Git-Tag: upstream/17.0.6~11827 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d20a1b87f689a716e16477b8562fd820a72a6a8b;p=platform%2Fupstream%2Fllvm.git [WebAssembly] Handle DebugLoc in DebugValueManager According to https://llvm.org/docs/HowToUpdateDebugInfo.html#when-to-preserve-an-instruction-location, when moving (and in our case cloning) within the same BB, the debug location is preserved. But when moving / cloning to a different BB, we preserve the debug location only if the destination BB contains the same location. Currently we preserve the debug loc unconditionally in all cases. This CL correctly handles the debug locs in DebugValueManager. Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D148115 --- diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp index 90051d0..9e97e44 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp @@ -226,6 +226,15 @@ bool WebAssemblyDebugValueManager::isInsertSamePlace( 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. // @@ -263,6 +272,12 @@ void WebAssemblyDebugValueManager::sink(MachineInstr *Insert) { 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()) @@ -344,6 +359,11 @@ void WebAssemblyDebugValueManager::cloneSink(MachineInstr *Insert, // 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); diff --git a/llvm/test/DebugInfo/WebAssembly/dbg-loc-reg-stackify.mir b/llvm/test/DebugInfo/WebAssembly/dbg-loc-reg-stackify.mir new file mode 100644 index 0000000..7b4b500e8 --- /dev/null +++ b/llvm/test/DebugInfo/WebAssembly/dbg-loc-reg-stackify.mir @@ -0,0 +1,125 @@ +# 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 +...