[PATCH] D114587: [DebugInfo][InstrRef] Avoid some quadratic behaviour in LiveDebugVariables

Jeremy Morse via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 25 05:40:37 PST 2021


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

This is a performance patch -- over in D94981 <https://reviews.llvm.org/D94981>, it was observed that LiveDebugVariables can behave quadratically if a lot of debug instructions are inserted back into the same place. We would:

- Pick out a slot index,
- Step through all the debug instructions after it,
- Then insert a debug instruction there

And if you have ~10,000 debug instructions to insert in one place (which can regrettably happen with lots of inlining), this becomes expensive very quickly.

This problem affects instruction referencing too. To get around it, whenever we insert a debug instruction at a slot index, check whether there are more debug instructions to insert at this point, and insert them too. That avoids the repeated lookup and stepping through. It relies on the container for unlinked debug instructions being recorded in-order, which is how LiveDebugVariables currently does it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D114587

Files:
  llvm/lib/CodeGen/LiveDebugVariables.cpp


Index: llvm/lib/CodeGen/LiveDebugVariables.cpp
===================================================================
--- llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -1875,34 +1875,56 @@
 
   LLVM_DEBUG(dbgs() << "********** EMITTING INSTR REFERENCES **********\n");
 
-  // Re-insert any debug instrs back in the position they were. Ordering
-  // is preserved by vector. We must re-insert in the same order to ensure that
-  // debug instructions don't swap, which could re-order assignments.
-  for (auto &P : StashedDebugInstrs) {
-    SlotIndex Idx = P.Idx;
+  // Re-insert any debug instrs back in the position they were. We must
+  // re-insert in the same order to ensure that debug instructions don't swap,
+  // which could re-order assignments. Do so in a batch -- once we find the
+  // insert position, insert all instructions at the same SlotIdx. They are
+  // guaranteed to appear in-sequence in StashedDebugInstrs because we insert
+  // them in order.
+  for (auto StashIt = StashedDebugInstrs.begin();
+       StashIt != StashedDebugInstrs.end(); ++StashIt) {
+    SlotIndex Idx = StashIt->Idx;
+    MachineBasicBlock *MBB = StashIt->MBB;
+    MachineInstr *MI = StashIt->MI;
+
+    auto EmitInstsHere = [this, &StashIt, MBB, Idx,
+                          MI](MachineBasicBlock::iterator InsertPos) {
+      // Insert this debug instruction.
+      MBB->insert(InsertPos, MI);
+
+      // Look at subsequent stashed debug instructions: if they're at the same
+      // index, insert those too.
+      auto NextItem = std::next(StashIt);
+      while (NextItem != StashedDebugInstrs.end() && NextItem->Idx == Idx) {
+        assert(NextItem->MBB == MBB);
+        MBB->insert(InsertPos, NextItem->MI);
+        StashIt = NextItem;
+        NextItem = std::next(StashIt);
+      };
+    };
 
     // Start block index: find the first non-debug instr in the block, and
     // insert before it.
-    if (Idx == Slots->getMBBStartIdx(P.MBB)) {
+    if (Idx == Slots->getMBBStartIdx(MBB)) {
       MachineBasicBlock::iterator InsertPos =
-          findInsertLocation(P.MBB, Idx, *LIS, BBSkipInstsMap);
-      P.MBB->insert(InsertPos, P.MI);
+          findInsertLocation(MBB, Idx, *LIS, BBSkipInstsMap);
+      EmitInstsHere(InsertPos);
       continue;
     }
 
     if (MachineInstr *Pos = Slots->getInstructionFromIndex(Idx)) {
       // Insert at the end of any debug instructions.
       auto PostDebug = std::next(Pos->getIterator());
-      PostDebug = skipDebugInstructionsForward(PostDebug, P.MBB->instr_end());
-      P.MBB->insert(PostDebug, P.MI);
+      PostDebug = skipDebugInstructionsForward(PostDebug, MBB->instr_end());
+      EmitInstsHere(PostDebug);
     } else {
       // Insert position disappeared; walk forwards through slots until we
       // find a new one.
-      SlotIndex End = Slots->getMBBEndIdx(P.MBB);
+      SlotIndex End = Slots->getMBBEndIdx(MBB);
       for (; Idx < End; Idx = Slots->getNextNonNullIndex(Idx)) {
         Pos = Slots->getInstructionFromIndex(Idx);
         if (Pos) {
-          P.MBB->insert(Pos->getIterator(), P.MI);
+          EmitInstsHere(Pos->getIterator());
           break;
         }
       }
@@ -1911,8 +1933,8 @@
       // insert! It's not safe to discard any debug instructions; place them
       // in front of the first terminator, or in front of end().
       if (Idx >= End) {
-        auto TermIt = P.MBB->getFirstTerminator();
-        P.MBB->insert(TermIt, P.MI);
+        auto TermIt = MBB->getFirstTerminator();
+        EmitInstsHere(TermIt);
       }
     }
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114587.389746.patch
Type: text/x-patch
Size: 3602 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211125/51155cba/attachment.bin>


More information about the llvm-commits mailing list