Skip to content

Commit 6e1c1da

Browse files
committed
[WebAssembly] Nullify DBG_VALUE_LISTs in DebugValueManager
WebAssemblyDebugValueManager class currently does not handle DBG_VALUE_LIST instructions correctly for two reasons, which are explained in https://bugs.llvm.org/show_bug.cgi?id=50361. This effectively nullifies DBG_VALUE_LISTs in WebAssemblyDebugValueManager so that the info will appear as "optimized out" in debuggers but still be at least correct in the meantime. Reviewed By: dschuff, jmorse Differential Revision: https://reviews.llvm.org/D102589
1 parent e2e1a78 commit 6e1c1da

File tree

3 files changed

+76
-6
lines changed

3 files changed

+76
-6
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,38 @@ using namespace llvm;
2020

2121
WebAssemblyDebugValueManager::WebAssemblyDebugValueManager(
2222
MachineInstr *Instr) {
23+
const auto *MF = Instr->getParent()->getParent();
24+
const auto *TII = MF->getSubtarget<WebAssemblySubtarget>().getInstrInfo();
25+
2326
// This code differs from MachineInstr::collectDebugValues in that it scans
2427
// the whole BB, not just contiguous DBG_VALUEs.
2528
if (!Instr->getOperand(0).isReg())
2629
return;
2730
CurrentReg = Instr->getOperand(0).getReg();
2831

32+
SmallVector<MachineInstr *, 2> DbgValueLists;
2933
MachineBasicBlock::iterator DI = *Instr;
3034
++DI;
3135
for (MachineBasicBlock::iterator DE = Instr->getParent()->end(); DI != DE;
3236
++DI) {
3337
if (DI->isDebugValue() &&
3438
DI->hasDebugOperandForReg(Instr->getOperand(0).getReg()))
35-
DbgValues.push_back(&*DI);
39+
DI->getOpcode() == TargetOpcode::DBG_VALUE
40+
? DbgValues.push_back(&*DI)
41+
: DbgValueLists.push_back(&*DI);
42+
}
43+
44+
// This class currently cannot handle DBG_VALUE_LISTs correctly. So this
45+
// converts DBG_VALUE_LISTs to "DBG_VALUE $noreg", which will appear as
46+
// "optimized out". This can invalidate existing iterators pointing to
47+
// instructions within this BB from the caller.
48+
// See https://bugs.llvm.org/show_bug.cgi?id=50361
49+
// TODO Correctly handle DBG_VALUE_LISTs
50+
for (auto *DVL : DbgValueLists) {
51+
BuildMI(*DVL->getParent(), DVL, DVL->getDebugLoc(),
52+
TII->get(TargetOpcode::DBG_VALUE), false, Register(),
53+
DVL->getOperand(0).getMetadata(), DVL->getOperand(1).getMetadata());
54+
DVL->eraseFromParent();
3655
}
3756
}
3857

llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -305,12 +305,11 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
305305
if (!MFI.isVRegStackified(OldReg)) {
306306
const TargetRegisterClass *RC = MRI.getRegClass(OldReg);
307307
Register NewReg = MRI.createVirtualRegister(RC);
308-
auto InsertPt = std::next(MI.getIterator());
309308
if (UseEmpty[Register::virtReg2Index(OldReg)]) {
310309
unsigned Opc = getDropOpcode(RC);
311-
MachineInstr *Drop =
312-
BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
313-
.addReg(NewReg);
310+
MachineInstr *Drop = BuildMI(MBB, std::next(MI.getIterator()),
311+
MI.getDebugLoc(), TII->get(Opc))
312+
.addReg(NewReg);
314313
// After the drop instruction, this reg operand will not be used
315314
Drop->getOperand(0).setIsKill();
316315
if (MFI.isFrameBaseVirtual() && OldReg == MFI.getFrameBaseVreg())
@@ -321,7 +320,8 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
321320

322321
WebAssemblyDebugValueManager(&MI).replaceWithLocal(LocalId);
323322

324-
BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
323+
BuildMI(MBB, std::next(MI.getIterator()), MI.getDebugLoc(),
324+
TII->get(Opc))
325325
.addImm(LocalId)
326326
.addReg(NewReg);
327327
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-reg-stackify %s -o - | FileCheck %s
2+
3+
--- |
4+
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5+
target triple = "wasm32-unknown-unknown"
6+
7+
define void @dbg_value_list_test() {
8+
ret void
9+
}
10+
11+
!llvm.module.flags = !{!0}
12+
!llvm.dbg.cu = !{!1}
13+
14+
!0 = !{i32 2, !"Debug Info Version", i32 3}
15+
!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang version 3.9.0 (trunk 266005) (llvm/trunk 266105)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3)
16+
!2 = !DIFile(filename: "test.c", directory: "/")
17+
!3 = !{}
18+
!4 = distinct !DISubprogram(name: "dbg_value_list_test", scope: !2, file: !2, line: 10, type: !5, isLocal: false, isDefinition: true, scopeLine: 11, flags: DIFlagPrototyped, isOptimized: true, unit: !1, retainedNodes: !3)
19+
!5 = !DISubroutineType(types: !3)
20+
!6 = !DILocalVariable(name: "var", scope: !4, file: !2, line: 15, type: !7)
21+
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
22+
!8 = !DILocation(line: 15, column: 6, scope: !4)
23+
...
24+
25+
# WebAssemblyDebugValueManager currently does not handle DBG_VALUE_LIST
26+
# instructions correctly and instead effectively nullifying them by turning them
27+
# into "DBG_VALUE $noreg". See https://bugs.llvm.org/show_bug.cgi?id=50361.
28+
# (Otherwise DBG_VALUE_LIST instructions can be exponentially and possibly
29+
# incorrectly copied.)
30+
# This tests if DBG_VALUE_LIST is nullified as intended.
31+
32+
# CHECK-LABEL: name: dbg_value_list_test
33+
name: dbg_value_list_test
34+
liveins:
35+
- { reg: '$arguments' }
36+
body: |
37+
bb.0:
38+
; CHECK: DBG_VALUE $noreg, $noreg
39+
%0:i32 = ARGUMENT_i32 0, implicit $arguments
40+
%1:i32 = ARGUMENT_i32 1, implicit $arguments
41+
%2:i32 = ARGUMENT_i32 2, implicit $arguments
42+
%3:i32 = LOAD_I32_A32 2, 0, %0:i32, implicit-def dead $arguments
43+
%4:i32 = LT_U_I32 %3:i32, %1:i32, implicit-def dead $arguments
44+
%5:i32 = GE_U_I32 %4:i32, %2:i32, implicit-def dead $arguments
45+
%6:i32 = OR_I32 %5:i32, %4:i32, implicit-def dead $arguments
46+
; This should become "DBG_VALUE $noreg" and should not be copied when %4 is
47+
; tee'd
48+
; CHECK-NOT: DBG_VALUE_LIST
49+
DBG_VALUE_LIST !6, !DIExpression(), %4:i32, debug-location !8
50+
RETURN %6:i32, implicit-def dead $arguments
51+
...

0 commit comments

Comments
 (0)