[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 {
+ SmallVector<SpillReloadPair> Pairs;
- // 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;
+ SpillReloadChain(MachineInstr *Spill, MachineInstr *Reload) {
+ append(Spill, Reload);
}
- if (CopyCount < 6)
- return;
- // ChainLeader maps MI inside a spill-reload chain to its innermost reload COPY.
- // Thus we can track if a MI belongs to an existing spill-reload chain.
- DenseMap<MachineInstr *, MachineInstr *> ChainLeader;
- // SpillChain maps innermost reload COPY of a spill-reload chain to a sequence
- // of COPYs that forms spills of a spill-reload chain.
- // ReloadChain maps innermost reload COPY of a spill-reload chain to a
- // sequence of COPYs that forms reloads of a spill-reload chain.
- DenseMap<MachineInstr *, SmallVector<MachineInstr *>> SpillChain, ReloadChain;
- // If a COPY's Source has use or def until next COPY defines the Source,
- // we put the COPY in this set to keep property#2.
- DenseSet<const MachineInstr *> CopySourceInvalid;
+ bool contains(const MachineInstr *MI) {
----------------
gbossu wrote:
I think it's worth a docstring. We consider `MI` part of the set if it's a spill **OR** reload tracked by the chain.
https://github.com/llvm/llvm-project/pull/208210
More information about the llvm-commits
mailing list