[llvm] [MCP][NFC] Refactor eliminateSpillageCopies (PR #208210)
Jack Styles via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 02:46:45 PDT 2026
================
@@ -1578,20 +1545,88 @@ void MachineCopyPropagation::eliminateSpillageCopies(MachineBasicBlock &MBB) {
LLVM_DEBUG(dbgs() << "MCP: Not paired spill-reload:\n");
LLVM_DEBUG(MaybeSpill->dump());
LLVM_DEBUG(MI.dump());
- Tracker.clobberRegister(Src, *TRI, *TII, UseCopyInstr);
- LLVM_DEBUG(dbgs() << "MCP: Removed tracking of " << printReg(Src, TRI)
+ Tracker.clobberRegister(Src, TRI, TII, UseCopyInstr);
+ LLVM_DEBUG(dbgs() << "MCP: Removed tracking of " << printReg(Src, &TRI)
<< "\n");
}
- Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr);
}
- for (auto I = SpillChain.begin(), E = SpillChain.end(); I != E; ++I) {
- auto &SC = I->second;
- assert(ReloadChain.count(I->first) &&
- "Reload chain of the same leader should exist");
- auto &RC = ReloadChain[I->first];
- TryFoldSpillageCopies(SC, RC);
+public:
+ SpillageCopyEliminator(const TargetRegisterInfo &TRI,
+ const TargetInstrInfo &TII, CopyTracker &Tracker,
+ bool UseCopyInstr)
+ : TRI(TRI), TII(TII), Tracker(Tracker), UseCopyInstr(UseCopyInstr) {}
+
+ void run(MachineBasicBlock &MBB) {
+ for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
+ std::optional<DestSourcePair> CopyOperands =
+ isCopyInstr(MI, TII, UseCopyInstr);
+ if (!CopyOperands) {
+ processNonCopy(MI);
+ continue;
+ }
+
+ processCopy(MI, *CopyOperands);
+ Tracker.trackCopy(&MI, TRI, TII, UseCopyInstr);
+ }
+
+ for (auto &Chain : Chains)
+ tryFoldChain(Chain.Pairs);
+ }
+};
+
+// 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) {
+
+ // Perform some cost modelling to ensure that only MBB's with more
+ // than 6 copies are checked. To create a chain that can be optimised,
+ // 6 copies are needed.
+ unsigned CopyCount = 0;
+ for (const MachineInstr &MI : MBB) {
+ if (isCopyInstr(MI, *TII, UseCopyInstr) && ++CopyCount > 6)
+ break;
}
+ if (CopyCount < 6)
----------------
Stylie777 wrote:
I missed a comment here when I initially added this. `6` is the magic number as it's the number of `COPY`'s in which we can reliably form a chain that can be simplified. Previously we would do alot of intensive work on MBB's that could never include a chain which can be optimised.
Adding it as a `cl::opt` I am open to as it would make it more strict, but the user has an option to disable this pass all together too. I'm open to either approach but I have added a comment here to explain why `6` is the magic number for this.
https://github.com/llvm/llvm-project/pull/208210
More information about the llvm-commits
mailing list