[llvm] 6e1c1da - [WebAssembly] Nullify DBG_VALUE_LISTs in DebugValueManager

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Mon May 17 13:48:26 PDT 2021


Author: Heejin Ahn
Date: 2021-05-17T13:47:36-07:00
New Revision: 6e1c1dac4c72cc57f4cd2bc8554e8ac9f2f50b6e

URL: https://github.com/llvm/llvm-project/commit/6e1c1dac4c72cc57f4cd2bc8554e8ac9f2f50b6e
DIFF: https://github.com/llvm/llvm-project/commit/6e1c1dac4c72cc57f4cd2bc8554e8ac9f2f50b6e.diff

LOG: [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

Added: 
    llvm/test/CodeGen/WebAssembly/reg-stackify-dbg.mir

Modified: 
    llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
index 55be64ad7da01..fc7a72edf5f2e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
@@ -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 
diff ers 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();
   }
 }
 

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
index 7ed224de1db5a..9bea20389809a 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
@@ -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);
           }

diff  --git a/llvm/test/CodeGen/WebAssembly/reg-stackify-dbg.mir b/llvm/test/CodeGen/WebAssembly/reg-stackify-dbg.mir
new file mode 100644
index 0000000000000..63be70b5ded43
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/reg-stackify-dbg.mir
@@ -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
+...


        


More information about the llvm-commits mailing list