[llvm] [MCP][NFC] Refactor eliminateSpillageCopies (PR #208210)

Gaƫtan Bossu via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 13 06:48:22 PDT 2026


================
@@ -1263,304 +1263,271 @@ void MachineCopyPropagation::backwardCopyPropagateBlock(
   Tracker.clear();
 }
 
-[[maybe_unused]] static void printSpillReloadChain(
-    DenseMap<MachineInstr *, SmallVector<MachineInstr *>> &SpillChain,
-    DenseMap<MachineInstr *, SmallVector<MachineInstr *>> &ReloadChain,
-    MachineInstr *Leader) {
-  auto &SC = SpillChain[Leader];
-  auto &RC = ReloadChain[Leader];
-  for (auto I = SC.rbegin(), E = SC.rend(); I != E; ++I)
-    (*I)->dump();
-  for (MachineInstr *MI : RC)
-    MI->dump();
-}
+struct SpillReloadPair {
+  MachineInstr *Spill = nullptr;
+  MachineInstr *Reload = nullptr;
+};
 
-// Remove spill-reload like copy chains. For example
-// r0 = COPY r1
-// r1 = COPY r2
-// r2 = COPY r3
-// r3 = COPY r4
-// <def-use r4>
-// r4 = COPY r3
-// r3 = COPY r2
-// r2 = COPY r1
-// r1 = COPY r0
-// will be folded into
-// r0 = COPY r1
-// r1 = COPY r4
-// <def-use r4>
-// r4 = COPY r1
-// r1 = COPY r0
-// TODO: Currently we don't track usage of r0 outside the chain, so we
-// conservatively keep its value as it was before the rewrite.
-//
-// The algorithm is trying to keep
-// property#1: No Dst of spill COPY in the chain is used or defined until the
-// paired reload COPY in the chain uses the Dst.
-//
-// property#2: NO Source of COPY in the chain is used or defined until the next
-// COPY in the chain defines the Source, except the innermost spill-reload
-// pair.
-//
-// The algorithm is conducted by checking every COPY inside the MBB, assuming
-// the COPY is a reload COPY, then try to find paired spill COPY by searching
-// the COPY defines the Src of the reload COPY backward. If such pair is found,
-// it either belongs to an existing chain or a new chain depends on
-// last available COPY uses the Dst of the reload COPY.
-// Implementation notes, we use CopyTracker::findLastDefCopy(Reg, ...) to find
-// out last COPY that defines Reg; we use CopyTracker::findLastUseCopy(Reg, ...)
-// to find out last COPY that uses Reg. When we are encountered with a Non-COPY
-// instruction, we check registers in the operands of this instruction. If this
-// Reg is defined by a COPY, we untrack this Reg via
-// CopyTracker::clobberRegister(Reg, ...).
-void MachineCopyPropagation::eliminateSpillageCopies(MachineBasicBlock &MBB) {
+struct SpillReloadChain {
----------------
gbossu wrote:

What is a chain? Does this mean all the spill/reload pairs in there are related and somehow follow each other? It would help to add a short example of what to expect in that chain.

The code below refers to this example:
```
// r0 = COPY r1
// r1 = COPY r2
// r2 = COPY r3
// r3 = COPY r4
// <def-use r4>
// r4 = COPY r3
// r3 = COPY r2
// r2 = COPY r1
// r1 = COPY r0
```

Would we have a chain like this?
```
Chain = {
  Spill="r0 = COPY r1", Reload = "r1 = COPY r0",
  Spill="r1 = COPY r2", Reload = "r2 = COPY r1",
  ...
}
```
And is there a hidden assumption that the scratch register used in `Chain[i]` is the one being spilled/reloaded by `Chain[i+1]`?

https://github.com/llvm/llvm-project/pull/208210


More information about the llvm-commits mailing list