[llvm] r351216 - [WebAssembly] Fix updating/moving DBG_VALUEs in RegStackify

Yury Delendik via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 15 10:14:12 PST 2019


Author: yurydelendik
Date: Tue Jan 15 10:14:12 2019
New Revision: 351216

URL: http://llvm.org/viewvc/llvm-project?rev=351216&view=rev
Log:
[WebAssembly] Fix updating/moving DBG_VALUEs in RegStackify

Summary:
As described in PR40209, there can be issues in DBG_VALUEs handling when multiple defs present in a BB. This patch
adds logic for detection of related to def DBG_VALUEs and localizes register update and movement to found DBG_VALUEs.

Reviewers: aheejin

Subscribers: mgorny, dschuff, sbc100, jgravelle-google, sunfish, llvm-commits

Differential Revision: https://reviews.llvm.org/D56401

Added:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h
    llvm/trunk/test/DebugInfo/WebAssembly/dbg-value-move-clone.mir
    llvm/trunk/test/DebugInfo/WebAssembly/dbg-value-move-reg-stackify.mir
Modified:
    llvm/trunk/lib/Target/WebAssembly/CMakeLists.txt
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp

Modified: llvm/trunk/lib/Target/WebAssembly/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/CMakeLists.txt?rev=351216&r1=351215&r2=351216&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/WebAssembly/CMakeLists.txt Tue Jan 15 10:14:12 2019
@@ -19,6 +19,7 @@ add_llvm_target(WebAssemblyCodeGen
   WebAssemblyCallIndirectFixup.cpp
   WebAssemblyCFGStackify.cpp
   WebAssemblyCFGSort.cpp
+  WebAssemblyDebugValueManager.cpp
   WebAssemblyLateEHPrepare.cpp
   WebAssemblyEHRestoreStackPointer.cpp
   WebAssemblyExceptionInfo.cpp

Added: llvm/trunk/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp?rev=351216&view=auto
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp (added)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp Tue Jan 15 10:14:12 2019
@@ -0,0 +1,46 @@
+//===-- WebAssemblyDebugValueManager.cpp - WebAssembly DebugValue Manager -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements the manager for MachineInstr DebugValues.
+///
+//===----------------------------------------------------------------------===//
+
+#include "WebAssemblyDebugValueManager.h"
+#include "WebAssemblyMachineFunctionInfo.h"
+#include "llvm/CodeGen/MachineInstr.h"
+
+using namespace llvm;
+
+WebAssemblyDebugValueManager::WebAssemblyDebugValueManager(
+    MachineInstr *Instr) {
+  Instr->collectDebugValues(DbgValues);
+}
+
+void WebAssemblyDebugValueManager::move(MachineInstr *Insert) {
+  MachineBasicBlock *MBB = Insert->getParent();
+  for (MachineInstr *DBI : reverse(DbgValues))
+    MBB->splice(Insert, DBI->getParent(), DBI);
+}
+
+void WebAssemblyDebugValueManager::updateReg(unsigned Reg) {
+  for (auto *DBI : DbgValues)
+    DBI->getOperand(0).setReg(Reg);
+}
+
+void WebAssemblyDebugValueManager::clone(MachineInstr *Insert,
+                                         unsigned NewReg) {
+  MachineBasicBlock *MBB = Insert->getParent();
+  MachineFunction *MF = MBB->getParent();
+  for (MachineInstr *DBI : reverse(DbgValues)) {
+    MachineInstr *Clone = MF->CloneMachineInstr(DBI);
+    Clone->getOperand(0).setReg(NewReg);
+    MBB->insert(Insert, Clone);
+  }
+}

Added: llvm/trunk/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h?rev=351216&view=auto
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h (added)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h Tue Jan 15 10:14:12 2019
@@ -0,0 +1,38 @@
+// WebAssemblyDebugValueManager.h - WebAssembly DebugValue Manager -*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the declaration of the WebAssembly-specific
+/// manager for DebugValues associated with the specific MachineInstr.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYDEBUGVALUEMANAGER_H
+#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYDEBUGVALUEMANAGER_H
+
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class MachineInstr;
+
+class WebAssemblyDebugValueManager {
+  SmallVector<MachineInstr *, 2> DbgValues;
+
+public:
+  WebAssemblyDebugValueManager(MachineInstr *Instr);
+
+  void move(MachineInstr *Insert);
+  void updateReg(unsigned Reg);
+  void clone(MachineInstr *Insert, unsigned NewReg);
+};
+
+} // end namespace llvm
+
+#endif

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp?rev=351216&r1=351215&r2=351216&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp Tue Jan 15 10:14:12 2019
@@ -22,6 +22,7 @@
 
 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_*
 #include "WebAssembly.h"
+#include "WebAssemblyDebugValueManager.h"
 #include "WebAssemblyMachineFunctionInfo.h"
 #include "WebAssemblySubtarget.h"
 #include "WebAssemblyUtilities.h"
@@ -466,27 +467,6 @@ static void ShrinkToUses(LiveInterval &L
   }
 }
 
-static void MoveDebugValues(unsigned Reg, MachineInstr *Insert,
-                            MachineBasicBlock &MBB, MachineRegisterInfo &MRI) {
-  for (auto &Op : MRI.reg_operands(Reg)) {
-    MachineInstr *MI = Op.getParent();
-    assert(MI != nullptr);
-    if (MI->isDebugValue() && MI->getParent() == &MBB)
-      MBB.splice(Insert, &MBB, MI);
-  }
-}
-
-static void UpdateDebugValuesReg(unsigned Reg, unsigned NewReg,
-                                 MachineBasicBlock &MBB,
-                                 MachineRegisterInfo &MRI) {
-  for (auto &Op : MRI.reg_operands(Reg)) {
-    MachineInstr *MI = Op.getParent();
-    assert(MI != nullptr);
-    if (MI->isDebugValue() && MI->getParent() == &MBB)
-      Op.setReg(NewReg);
-  }
-}
-
 /// A single-use def in the same block with no intervening memory or register
 /// dependencies; move the def down and nest it with the current instruction.
 static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand &Op,
@@ -496,8 +476,9 @@ static MachineInstr *MoveForSingleUse(un
                                       MachineRegisterInfo &MRI) {
   LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
 
+  WebAssemblyDebugValueManager DefDIs(Def);
   MBB.splice(Insert, &MBB, Def);
-  MoveDebugValues(Reg, Insert, MBB, MRI);
+  DefDIs.move(Insert);
   LIS.handleMove(*Def);
 
   if (MRI.hasOneDef(Reg) && MRI.hasOneUse(Reg)) {
@@ -522,7 +503,7 @@ static MachineInstr *MoveForSingleUse(un
 
     MFI.stackifyVReg(NewReg);
 
-    UpdateDebugValuesReg(Reg, NewReg, MBB, MRI);
+    DefDIs.updateReg(NewReg);
 
     LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
   }
@@ -531,29 +512,6 @@ static MachineInstr *MoveForSingleUse(un
   return Def;
 }
 
-static void CloneDebugValues(unsigned Reg, MachineInstr *Insert,
-                             unsigned TargetReg, MachineBasicBlock &MBB,
-                             MachineRegisterInfo &MRI,
-                             const WebAssemblyInstrInfo *TII) {
-  SmallPtrSet<MachineInstr *, 4> Instrs;
-  for (auto &Op : MRI.reg_operands(Reg)) {
-    MachineInstr *MI = Op.getParent();
-    assert(MI != nullptr);
-    if (MI->isDebugValue() && MI->getParent() == &MBB &&
-        Instrs.find(MI) == Instrs.end())
-      Instrs.insert(MI);
-  }
-  for (const auto &MI : Instrs) {
-    MachineInstr &Clone = TII->duplicate(MBB, Insert, *MI);
-    for (unsigned i = 0, e = Clone.getNumOperands(); i != e; ++i) {
-      MachineOperand &MO = Clone.getOperand(i);
-      if (MO.isReg() && MO.getReg() == Reg)
-        MO.setReg(TargetReg);
-    }
-    LLVM_DEBUG(dbgs() << " - - Cloned DBG_VALUE: "; Clone.dump());
-  }
-}
-
 /// A trivially cloneable instruction; clone it and nest the new copy with the
 /// current instruction.
 static MachineInstr *RematerializeCheapDef(
@@ -564,6 +522,8 @@ static MachineInstr *RematerializeCheapD
   LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());
   LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump());
 
+  WebAssemblyDebugValueManager DefDIs(&Def);
+
   unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));
   TII->reMaterialize(MBB, Insert, NewReg, 0, Def, *TRI);
   Op.setReg(NewReg);
@@ -593,10 +553,10 @@ static MachineInstr *RematerializeCheapD
     LIS.RemoveMachineInstrFromMaps(Def);
     Def.eraseFromParent();
 
-    MoveDebugValues(Reg, &*Insert, MBB, MRI);
-    UpdateDebugValuesReg(Reg, NewReg, MBB, MRI);
+    DefDIs.move(&*Insert);
+    DefDIs.updateReg(NewReg);
   } else {
-    CloneDebugValues(Reg, &*Insert, NewReg, MBB, MRI, TII);
+    DefDIs.clone(&*Insert, NewReg);
   }
 
   return Clone;
@@ -628,6 +588,8 @@ static MachineInstr *MoveAndTeeForMultiU
     MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII) {
   LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump());
 
+  WebAssemblyDebugValueManager DefDIs(Def);
+
   // Move Def into place.
   MBB.splice(Insert, &MBB, Def);
   LIS.handleMove(*Def);
@@ -646,7 +608,7 @@ static MachineInstr *MoveAndTeeForMultiU
   SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot();
   SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot();
 
-  MoveDebugValues(Reg, Insert, MBB, MRI);
+  DefDIs.move(Insert);
 
   // Tell LiveIntervals we moved the original vreg def from Def to Tee.
   LiveInterval &LI = LIS.getInterval(Reg);
@@ -664,8 +626,8 @@ static MachineInstr *MoveAndTeeForMultiU
   ImposeStackOrdering(Def);
   ImposeStackOrdering(Tee);
 
-  CloneDebugValues(Reg, Tee, DefReg, MBB, MRI, TII);
-  CloneDebugValues(Reg, Insert, TeeReg, MBB, MRI, TII);
+  DefDIs.clone(Tee, DefReg);
+  DefDIs.clone(Insert, TeeReg);
 
   LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
   LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump());

Added: llvm/trunk/test/DebugInfo/WebAssembly/dbg-value-move-clone.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/WebAssembly/dbg-value-move-clone.mir?rev=351216&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/WebAssembly/dbg-value-move-clone.mir (added)
+++ llvm/trunk/test/DebugInfo/WebAssembly/dbg-value-move-clone.mir Tue Jan 15 10:14:12 2019
@@ -0,0 +1,65 @@
+# RUN: llc < %s -run-pass=wasm-reg-stackify -x=mir 2>&1 | FileCheck %s
+
+# CHECK: body:
+# CHECK: bb.0:
+# CHECK: %[[REG1:[0-9]+]]:i32 = CONST_I32 0,
+# CHECK-NEXT: DBG_VALUE %[[REG1]],
+# CHECK-NEXT: CALL_VOID @foo, %[[REG1]],
+# CHECK: bb.1:
+# CHECK: %[[REG2:[0-9]+]]:i32 = CONST_I32 0,
+# CHECK-NEXT: DBG_VALUE %[[REG2]],
+# CHECK-NEXT: CALL_VOID @foo, %[[REG2]],
+# CHECK: %[[REG3:[0-9]+]]:i32 = CONST_I32 0,
+# CHECK-NEXT: DBG_VALUE %[[REG3]],
+# CHECK-NEXT: CALL_VOID @foo, %[[REG3]],
+
+--- |
+  target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+  target triple = "wasm32-unknown-unknown"
+
+  declare void @foo(i32)
+  declare i32 @bar()
+
+  define void @test(i64 %arg) {
+    unreachable
+  }
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!4}
+  !0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !2, producer: "clang LLVM (rustc version 1.30.0-dev)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !1, globals: !1)
+  !1 = !{}
+  !2 = !DIFile(filename: "<unknown>", directory: "")
+  !3 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "&str", file: !2, size: 64, align: 32, elements: !{}, identifier: "111094d970b097647de579f9c509ef08")
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = distinct !DILexicalBlock(scope: !6, file: !2, line: 357, column: 8)
+  !6 = distinct !DISubprogram(name: "testfoo", linkageName: "_testba", scope: !7, file: !2, line: 353, type: !8, isLocal: true, isDefinition: true, scopeLine: 353, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !1, retainedNodes: !9)
+  !7 = !DINamespace(name: "ptr", scope: null)
+  !8 = !DISubroutineType(types: !1)
+  !9 = !{!10}
+  !10 = !DILocalVariable(name: "val0", scope: !5, file: !2, line: 357, type: !3, align: 4)
+  !11 = !DILocalVariable(name: "val1", scope: !5, file: !2, line: 358, type: !3, align: 4)
+  !12 = !DILocalVariable(name: "val2", scope: !5, file: !2, line: 359, type: !3, align: 4)
+  !13 = !DILocation(line: 357, column: 12, scope: !5)
+  !14 = !DILocation(line: 358, column: 12, scope: !5)
+  !15 = !DILocation(line: 359, column: 12, scope: !5)
+
+---
+name: test
+liveins:
+  - { reg: '$arguments' }
+tracksRegLiveness: true
+body: |
+  bb.0:
+    successors: %bb.1
+    liveins: $arguments
+    %0:i64 = ARGUMENT_i64 0, implicit $arguments
+    %1:i32 = CONST_I32 0, implicit-def dead $arguments
+    DBG_VALUE %1:i32, $noreg, !10, !DIExpression(), debug-location !13; <unknown>:357:12 line no:357
+    CALL_VOID @foo, %1:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
+
+  bb.1:
+    CALL_VOID @foo, %1:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
+    CALL_VOID @foo, %1:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
+    RETURN_VOID implicit-def dead $arguments
+
+...

Added: llvm/trunk/test/DebugInfo/WebAssembly/dbg-value-move-reg-stackify.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/WebAssembly/dbg-value-move-reg-stackify.mir?rev=351216&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/WebAssembly/dbg-value-move-reg-stackify.mir (added)
+++ llvm/trunk/test/DebugInfo/WebAssembly/dbg-value-move-reg-stackify.mir Tue Jan 15 10:14:12 2019
@@ -0,0 +1,60 @@
+# RUN: llc < %s -run-pass=wasm-reg-stackify -x=mir 2>&1 | FileCheck %s
+
+# CHECK: body:
+# CHECK: %1:i32 = I32_WRAP_I64 %0,
+# CHECK-NEXT: DBG_VALUE %1,
+# CHECK-NEXT: %1:i32 = CALL_I32 @bar,
+# CHECK-NEXT: DBG_VALUE %1,
+# CHECK-NEXT: %[[NEWREG:.*]]:i32 = CALL_I32 @bar,
+# CHECK-NEXT: DBG_VALUE %[[NEWREG]],
+# CHECK-NEXT: CALL_VOID @foo, %[[NEWREG]],
+
+--- |
+  target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+  target triple = "wasm32-unknown-unknown"
+
+  declare void @foo(i32)
+  declare i32 @bar()
+
+  define void @test(i64 %arg) {
+    unreachable
+  }
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!4}
+  !0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !2, producer: "clang LLVM (rustc version 1.30.0-dev)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !1, globals: !1)
+  !1 = !{}
+  !2 = !DIFile(filename: "<unknown>", directory: "")
+  !3 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "&str", file: !2, size: 64, align: 32, elements: !{}, identifier: "111094d970b097647de579f9c509ef08")
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = distinct !DILexicalBlock(scope: !6, file: !2, line: 357, column: 8)
+  !6 = distinct !DISubprogram(name: "testfoo", linkageName: "_testba", scope: !7, file: !2, line: 353, type: !8, isLocal: true, isDefinition: true, scopeLine: 353, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !1, retainedNodes: !9)
+  !7 = !DINamespace(name: "ptr", scope: null)
+  !8 = !DISubroutineType(types: !1)
+  !9 = !{!10}
+  !10 = !DILocalVariable(name: "val0", scope: !5, file: !2, line: 357, type: !3, align: 4)
+  !11 = !DILocalVariable(name: "val1", scope: !5, file: !2, line: 358, type: !3, align: 4)
+  !12 = !DILocalVariable(name: "val2", scope: !5, file: !2, line: 359, type: !3, align: 4)
+  !13 = !DILocation(line: 357, column: 12, scope: !5)
+  !14 = !DILocation(line: 358, column: 12, scope: !5)
+  !15 = !DILocation(line: 359, column: 12, scope: !5)
+
+---
+name: test
+liveins:
+  - { reg: '$arguments' }
+tracksRegLiveness: true
+body: |
+  bb.0:
+    liveins: $arguments
+    %0:i64 = ARGUMENT_i64 0, implicit $arguments
+    %1:i32 = I32_WRAP_I64 %0:i64, implicit-def dead $arguments
+    DBG_VALUE %1:i32, $noreg, !10, !DIExpression(), debug-location !13; <unknown>:357:12 line no:357
+    %1:i32 = CALL_I32 @bar, implicit-def dead $arguments, implicit $sp32, implicit $sp64
+    DBG_VALUE %1:i32, $noreg, !11, !DIExpression(), debug-location !14; <unknown>:357:12 line no:357
+    %1:i32 = CALL_I32 @bar, implicit-def dead $arguments, implicit $sp32, implicit $sp64
+    DBG_VALUE %1:i32, $noreg, !12, !DIExpression(), debug-location !15; <unknown>:357:12 line no:357
+    CALL_VOID @foo, %1:i32, implicit-def dead $arguments, implicit $sp32, implicit $sp64
+    RETURN_VOID implicit-def dead $arguments
+
+...




More information about the llvm-commits mailing list