[PATCH] D115400: RegScavenger: Remove used regs from scavenge candidates

Matt Arsenault via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 8 14:03:27 PST 2021


arsenm created this revision.
arsenm added reviewers: qcolombet, MatzeB, kparzysz, craig.topper.
Herald added subscribers: hiraditya, tpr.
arsenm requested review of this revision.
Herald added a subscriber: wdng.
Herald added a project: LLVM.

In a future change, AMDGPU will have 2 emergency scavenging indexes in
some situations. The secondary scavenging index ends up being used
recursively when the scavenger calls eliminateFrameIndex for the
emergency spill slot. Without this, it would end up seeing the same
register which was just scavenged in the parent call as free, inserts
a second emergency spill to the same location and returns the same
register when 2 unique free registers are required.

      

We need to only do this if the register is used. SystemZ uses 2
scavenging slots, but calls the scavenger twice in sequence and not
recursively. In this case the previously scavenged register can be
re-clobbered, but is still tracked in the scavenger until it sees the
deferred restore instruction.


https://reviews.llvm.org/D115400

Files:
  llvm/lib/CodeGen/RegisterScavenging.cpp


Index: llvm/lib/CodeGen/RegisterScavenging.cpp
===================================================================
--- llvm/lib/CodeGen/RegisterScavenging.cpp
+++ llvm/lib/CodeGen/RegisterScavenging.cpp
@@ -533,6 +533,22 @@
         Candidates.reset(*AI);
   }
 
+  // If we have already scavenged some registers, remove them from the
+  // candidates. If we end up recursively calling eliminateFrameIndex, we don't
+  // want to be clobbering previously scavenged registers or their associated
+  // stack slots.
+  for (ScavengedInfo &SI : Scavenged) {
+    if (SI.Reg) {
+      if (isRegUsed(SI.Reg)) {
+        LLVM_DEBUG(
+          dbgs() << "Removing " << printReg(SI.Reg, TRI) <<
+          " from scavenging candidates since it was already scavenged\n");
+        for (MCRegAliasIterator AI(SI.Reg, TRI, true); AI.isValid(); ++AI)
+          Candidates.reset(*AI);
+      }
+    }
+  }
+
   // Try to find a register that's unused if there is one, as then we won't
   // have to spill.
   BitVector Available = getRegsAvailable(RC);
@@ -553,6 +569,12 @@
   if (!AllowSpill)
     return 0;
 
+#ifndef NDEBUG
+  for (ScavengedInfo &SI : Scavenged) {
+    assert(SI.Reg != SReg && "scavenged a previously scavenged register");
+  }
+#endif
+
   ScavengedInfo &Scavenged = spill(SReg, *RC, SPAdj, I, UseMI);
   Scavenged.Restore = &*std::prev(UseMI);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D115400.392931.patch
Type: text/x-patch
Size: 1358 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211208/59e70094/attachment.bin>


More information about the llvm-commits mailing list