[WebAssembly] Do nothing when sinking to same place
authorHeejin Ahn <aheejin@gmail.com>
Fri, 24 Mar 2023 18:49:08 +0000 (11:49 -0700)
committerHeejin Ahn <aheejin@gmail.com>
Wed, 29 Mar 2023 19:50:39 +0000 (12:50 -0700)
In `DebugValueManager`, if a `Def` is requested to be sunk to the same
place (i.e., `Insert` is right after `Def`, not counting `DBG_VALUE`s)
currently we still do the sink. This can result in unnecessary creation
of `DBG_VALUE $noreg`. See comments for details. This CL detects this
case and do nothing and return, so we don't end up creating unnecessary
undef `DBG_VALUE`s.

Reviewed By: dschuff

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

llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.h
llvm/test/DebugInfo/WebAssembly/dbg-value-reg-stackify.mir

index c036ef0..c851b3f 100644 (file)
@@ -210,6 +210,22 @@ WebAssemblyDebugValueManager::getSinkableDebugValues(
   return SinkableDbgValues;
 }
 
+// Returns true if the insertion point is the same as the current place.
+// Following DBG_VALUEs for 'Def' are ignored.
+bool WebAssemblyDebugValueManager::isInsertSamePlace(
+    MachineInstr *Insert) const {
+  if (Def->getParent() != Insert->getParent())
+    return false;
+  for (MachineBasicBlock::iterator MI = std::next(Def->getIterator()),
+                                   ME = Insert;
+       MI != ME; ++MI) {
+    if (std::find(DbgValues.begin(), DbgValues.end(), MI) == DbgValues.end()) {
+      return false;
+    }
+  }
+  return true;
+}
+
 // Sink 'Def', and also sink its eligible DBG_VALUEs to the place before
 // 'Insert'. Convert the original DBG_VALUEs into undefs.
 //
@@ -221,6 +237,23 @@ WebAssemblyDebugValueManager::getSinkableDebugValues(
 // This DebugValueManager's new Def and DbgValues will be updated to the newly
 // sinked Def + DBG_VALUEs.
 void WebAssemblyDebugValueManager::sink(MachineInstr *Insert) {
+  // In case Def is requested to be sunk to
+  // the same place, we don't need to do anything. If we actually do the sink,
+  // it will create unnecessary undef DBG_VALUEs. For example, if the original
+  // code is:
+  //   %0 = someinst           // Def
+  //   DBG_VALUE %0, ...
+  //   %1 = anotherinst        // Insert
+  //
+  // If we actually sink %0 and the following DBG_VALUE and setting the original
+  // DBG_VALUE undef, the result will be:
+  //   DBG_VALUE %noreg, ...   // Unnecessary!
+  //   %0 = someinst           // Def
+  //   DBG_VALUE %0, ...
+  //   %1 = anotherinst        // Insert
+  if (isInsertSamePlace(Insert))
+    return;
+
   MachineBasicBlock *MBB = Insert->getParent();
   MachineFunction *MF = MBB->getParent();
 
index 3ca9290..78dc9c4 100644 (file)
@@ -31,6 +31,7 @@ class WebAssemblyDebugValueManager {
   Register CurrentReg;
   SmallVector<MachineInstr *>
   getSinkableDebugValues(MachineInstr *Insert) const;
+  bool isInsertSamePlace(MachineInstr *Insert) const;
 
 public:
   WebAssemblyDebugValueManager(MachineInstr *Def);
index cb78abd..bfb3f74 100644 (file)
@@ -191,9 +191,7 @@ body: |
     CALL @use, %0:i32, implicit-def $arguments
     RETURN implicit-def $arguments
 
-  ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
-  ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
-  ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
+  ; CHECK:      %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack