1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[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
This commit is contained in:
Heejin Ahn 2021-05-16 03:17:16 -07:00
parent c43a4a465c
commit 6eb058e5ac
3 changed files with 76 additions and 6 deletions

View File

@ -20,19 +20,38 @@ using namespace llvm;
WebAssemblyDebugValueManager::WebAssemblyDebugValueManager(
MachineInstr *Instr) {
const auto *MF = Instr->getParent()->getParent();
const auto *TII = MF->getSubtarget<WebAssemblySubtarget>().getInstrInfo();
// This code differs from MachineInstr::collectDebugValues in that it scans
// the whole BB, not just contiguous DBG_VALUEs.
if (!Instr->getOperand(0).isReg())
return;
CurrentReg = Instr->getOperand(0).getReg();
SmallVector<MachineInstr *, 2> DbgValueLists;
MachineBasicBlock::iterator DI = *Instr;
++DI;
for (MachineBasicBlock::iterator DE = Instr->getParent()->end(); DI != DE;
++DI) {
if (DI->isDebugValue() &&
DI->hasDebugOperandForReg(Instr->getOperand(0).getReg()))
DbgValues.push_back(&*DI);
DI->getOpcode() == TargetOpcode::DBG_VALUE
? DbgValues.push_back(&*DI)
: DbgValueLists.push_back(&*DI);
}
// This class currently cannot handle DBG_VALUE_LISTs correctly. So this
// converts DBG_VALUE_LISTs to "DBG_VALUE $noreg", which will appear as
// "optimized out". This can invalidate existing iterators pointing to
// instructions within this BB from the caller.
// See https://bugs.llvm.org/show_bug.cgi?id=50361
// TODO Correctly handle DBG_VALUE_LISTs
for (auto *DVL : DbgValueLists) {
BuildMI(*DVL->getParent(), DVL, DVL->getDebugLoc(),
TII->get(TargetOpcode::DBG_VALUE), false, Register(),
DVL->getOperand(0).getMetadata(), DVL->getOperand(1).getMetadata());
DVL->eraseFromParent();
}
}

View File

@ -305,12 +305,11 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
if (!MFI.isVRegStackified(OldReg)) {
const TargetRegisterClass *RC = MRI.getRegClass(OldReg);
Register NewReg = MRI.createVirtualRegister(RC);
auto InsertPt = std::next(MI.getIterator());
if (UseEmpty[Register::virtReg2Index(OldReg)]) {
unsigned Opc = getDropOpcode(RC);
MachineInstr *Drop =
BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
.addReg(NewReg);
MachineInstr *Drop = BuildMI(MBB, std::next(MI.getIterator()),
MI.getDebugLoc(), TII->get(Opc))
.addReg(NewReg);
// After the drop instruction, this reg operand will not be used
Drop->getOperand(0).setIsKill();
if (MFI.isFrameBaseVirtual() && OldReg == MFI.getFrameBaseVreg())
@ -321,7 +320,8 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
WebAssemblyDebugValueManager(&MI).replaceWithLocal(LocalId);
BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc))
BuildMI(MBB, std::next(MI.getIterator()), MI.getDebugLoc(),
TII->get(Opc))
.addImm(LocalId)
.addReg(NewReg);
}

View File

@ -0,0 +1,51 @@
# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-reg-stackify %s -o - | FileCheck %s
--- |
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
define void @dbg_value_list_test() {
ret void
}
!llvm.module.flags = !{!0}
!llvm.dbg.cu = !{!1}
!0 = !{i32 2, !"Debug Info Version", i32 3}
!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)
!2 = !DIFile(filename: "test.c", directory: "/")
!3 = !{}
!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)
!5 = !DISubroutineType(types: !3)
!6 = !DILocalVariable(name: "var", scope: !4, file: !2, line: 15, type: !7)
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!8 = !DILocation(line: 15, column: 6, scope: !4)
...
# WebAssemblyDebugValueManager currently does not handle DBG_VALUE_LIST
# instructions correctly and instead effectively nullifying them by turning them
# into "DBG_VALUE $noreg". See https://bugs.llvm.org/show_bug.cgi?id=50361.
# (Otherwise DBG_VALUE_LIST instructions can be exponentially and possibly
# incorrectly copied.)
# This tests if DBG_VALUE_LIST is nullified as intended.
# CHECK-LABEL: name: dbg_value_list_test
name: dbg_value_list_test
liveins:
- { reg: '$arguments' }
body: |
bb.0:
; CHECK: DBG_VALUE $noreg, $noreg
%0:i32 = ARGUMENT_i32 0, implicit $arguments
%1:i32 = ARGUMENT_i32 1, implicit $arguments
%2:i32 = ARGUMENT_i32 2, implicit $arguments
%3:i32 = LOAD_I32_A32 2, 0, %0:i32, implicit-def dead $arguments
%4:i32 = LT_U_I32 %3:i32, %1:i32, implicit-def dead $arguments
%5:i32 = GE_U_I32 %4:i32, %2:i32, implicit-def dead $arguments
%6:i32 = OR_I32 %5:i32, %4:i32, implicit-def dead $arguments
; This should become "DBG_VALUE $noreg" and should not be copied when %4 is
; tee'd
; CHECK-NOT: DBG_VALUE_LIST
DBG_VALUE_LIST !6, !DIExpression(), %4:i32, debug-location !8
RETURN %6:i32, implicit-def dead $arguments
...