[PATCH] D148368: [RemoveRedundantDebugValues] Track registers to efficiently handle many DBG_VALUEs.

Jordan Rupprecht via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 14 12:51:37 PDT 2023


rupprecht created this revision.
rupprecht added reviewers: djtodoro, Orlando, StephenTozer.
Herald added a subscriber: hiraditya.
Herald added a project: All.
rupprecht requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

When checking if instructions clobber any locations, we do so by looking at each entry in `VariableMap` and call `MI.modifiesRegister()` on that variable. If the size of `VariableMap` is large, this can be very slow, because `modifiesRegister` isn't very fast.

Instead, we track just the specified registers, and only call `MI.modifiesRegister()` for each entry in that much smaller set. If there are no matches, we avoid needing to iterate over `VariableMap` entirely. If there are any matches, we can then iterate over `VariableMap` and do the much cheaper equality comparison for registers to decide if remove it.

This brings compilation of a seemingly-simle file from 5 minutes to 10 seconds. The stats added in this patch show the relative sizes of data sets:

  $ llc -run-pass=removeredundantdebugvalues /tmp/repro.O3.mir -o /dev/null -stats
  ===-------------------------------------------------------------------------===
                            ... Statistics Collected ...
  ===-------------------------------------------------------------------------===
  
       6 removeredundantdebugvalues - Maximum size of RegisterSet (forward scan)
  183077 removeredundantdebugvalues - Maximum size of VariableMap (forward scan)

This patch is purely a compile time improvement. It is not intended to have any visible effect on the output IR.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148368

Files:
  llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp


Index: llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
===================================================================
--- llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
+++ llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
@@ -12,6 +12,7 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/Register.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/Function.h"
@@ -30,6 +31,8 @@
 
 STATISTIC(NumRemovedBackward, "Number of DBG_VALUEs removed (backward scan)");
 STATISTIC(NumRemovedForward, "Number of DBG_VALUEs removed (forward scan)");
+STATISTIC(PeakVariableMapSize, "Maximum size of VariableMap (forward scan)");
+STATISTIC(PeakRegisterSetSize, "Maximum size of RegisterSet (forward scan)");
 
 namespace {
 
@@ -87,6 +90,11 @@
       VariableMap;
   const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
 
+  // Checking if an MI modifies a register is not trivial, so instead of
+  // directly checking the register of everything in VariableMap, we collect all
+  // the registers here and only check this set. If any register is clobbered,
+  // we can do a trivial register comparison to remove it from VariableMap.
+  DenseSet<Register> RegisterSet;
   for (auto &MI : MBB) {
     if (MI.isDebugValue()) {
       DebugVariable Var(MI.getDebugVariable(), std::nullopt,
@@ -116,6 +124,10 @@
           VMI->second.first->getReg() != Loc.getReg() ||
           VMI->second.second != MI.getDebugExpression()) {
         VariableMap[Var] = {&Loc, MI.getDebugExpression()};
+        PeakVariableMapSize.updateMax(VariableMap.size());
+
+        RegisterSet.insert(Loc.getReg());
+        PeakRegisterSetSize.updateMax(RegisterSet.size());
         continue;
       }
 
@@ -128,10 +140,15 @@
       continue;
 
     // Stop tracking any location that is clobbered by this instruction.
-    for (auto &Var : VariableMap) {
-      auto &LocOp = Var.second.first;
-      if (MI.modifiesRegister(LocOp->getReg(), TRI))
-        VariableMap.erase(Var.first);
+    for (const Register reg : RegisterSet) {
+      if (MI.modifiesRegister(reg, TRI)) {
+        for (auto &Var : VariableMap) {
+          const auto &LocOp = Var.second.first;
+          if (LocOp->getReg() == reg)
+            VariableMap.erase(Var.first);
+        }
+        RegisterSet.erase(reg);
+      }
     }
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D148368.513719.patch
Type: text/x-patch
Size: 2464 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230414/f7962175/attachment.bin>


More information about the llvm-commits mailing list