[llvm] [MachineCopyPropagation][NFC] Refactor EliminateSpillageCopies (PR #192609)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 17 01:29:23 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-regalloc
Author: Jack Styles (Stylie777)
<details>
<summary>Changes</summary>
This patch builds on the original implementation to address areas that may impact compile time regression if enabled. The aim of the patch is to streamline and improve the implementation for better compile time impact. A summary of the changes is as follows:
- Cost modelling that does an initial scan of the block, any blocks with less than 6 copies are immediately skipped.
- RegMask scan in `findLastSeenDefInCopy` removed. This now only checks the recorded copies to ensure that RegMasks are clobbered when they are seen if they clobber a Reg
- Streamlining of `IsSpillReloadPair` and `IsChainedCopy` to reduce the need for a second call to isCopyInstr to get the DestSourcePair, these are now returned from the lamdba function
- Use of TRI API to get the CommonRegClass
Assisted-by: Claude Sonnet 4.6 (Co-Pilot)
---
Full diff: https://github.com/llvm/llvm-project/pull/192609.diff
1 Files Affected:
- (modified) llvm/lib/CodeGen/MachineCopyPropagation.cpp (+55-42)
``````````diff
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index 58ff6f77830b3..1111c68b24575 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -421,20 +421,20 @@ class CopyTracker {
if (!TRI.isSubRegisterEq(Def, Reg))
return nullptr;
- for (const MachineInstr &MI :
- make_range(static_cast<const MachineInstr *>(DefCopy)->getIterator(),
- Current.getIterator()))
- for (const MachineOperand &MO : MI.operands())
- if (MO.isRegMask())
- if (MO.clobbersPhysReg(Def)) {
- LLVM_DEBUG(dbgs() << "MCP: Removed tracking of "
- << printReg(Def, &TRI) << "\n");
- return nullptr;
- }
-
return DefCopy;
}
+ void clobberNonPreservedRegs(const BitVector &PreservedRegUnits,
+ const TargetRegisterInfo &TRI,
+ const TargetInstrInfo &TII, bool UseCopyInstr) {
+ SmallVector<MCRegUnit, 8> UnitsToClobber;
+ for (auto &[Unit, _] : Copies)
+ if (!PreservedRegUnits.test(static_cast<unsigned>(Unit)))
+ UnitsToClobber.push_back(Unit);
+ for (MCRegUnit Unit : UnitsToClobber)
+ clobberRegUnit(Unit, TRI, TII, UseCopyInstr);
+ }
+
// Find last COPY that uses Reg.
MachineInstr *findLastSeenUseInCopy(MCRegister Reg,
const TargetRegisterInfo &TRI) {
@@ -1298,6 +1298,18 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock(
// 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)
+ 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;
@@ -1337,10 +1349,8 @@ void MachineCopyPropagation::EliminateSpillageCopies(MachineBasicBlock &MBB) {
return;
auto CheckCopyConstraint = [this](Register Def, Register Src) {
- for (const TargetRegisterClass *RC : TRI->regclasses()) {
- if (RC->contains(Def) && RC->contains(Src))
- return true;
- }
+ if (TRI->getCommonMinimalPhysRegClass(Def, Src))
+ return true;
return false;
};
@@ -1380,45 +1390,44 @@ void MachineCopyPropagation::EliminateSpillageCopies(MachineBasicBlock &MBB) {
}
};
- auto IsFoldableCopy = [this](const MachineInstr &MaybeCopy) {
+ auto GetFoldableCopy =
+ [this](const MachineInstr &MaybeCopy) -> std::optional<DestSourcePair> {
if (MaybeCopy.getNumImplicitOperands() > 0)
- return false;
+ return std::nullopt;
std::optional<DestSourcePair> CopyOperands =
isCopyInstr(MaybeCopy, *TII, UseCopyInstr);
if (!CopyOperands)
- return false;
+ return std::nullopt;
Register Src = CopyOperands->Source->getReg();
Register Def = CopyOperands->Destination->getReg();
- return Src && Def && !TRI->regsOverlap(Src, Def) &&
- CopyOperands->Source->isRenamable() &&
- CopyOperands->Destination->isRenamable();
+ if (Src && Def && !TRI->regsOverlap(Src, Def) &&
+ CopyOperands->Source->isRenamable() &&
+ CopyOperands->Destination->isRenamable())
+ return CopyOperands;
+ return std::nullopt;
};
- auto IsSpillReloadPair = [&, this](const MachineInstr &Spill,
- const MachineInstr &Reload) {
- if (!IsFoldableCopy(Spill) || !IsFoldableCopy(Reload))
- return false;
- std::optional<DestSourcePair> SpillCopy =
- isCopyInstr(Spill, *TII, UseCopyInstr);
- std::optional<DestSourcePair> ReloadCopy =
- isCopyInstr(Reload, *TII, UseCopyInstr);
- if (!SpillCopy || !ReloadCopy)
+ auto IsSpillReloadPair = [&](const MachineInstr &Spill,
+ const MachineInstr &Reload) {
+ std::optional<DestSourcePair> FoldableSpillCopy = GetFoldableCopy(Spill);
+ std::optional<DestSourcePair> FoldableReloadCopy = GetFoldableCopy(Reload);
+ if (!FoldableReloadCopy || !FoldableSpillCopy)
return false;
- return SpillCopy->Source->getReg() == ReloadCopy->Destination->getReg() &&
- SpillCopy->Destination->getReg() == ReloadCopy->Source->getReg();
+ return FoldableSpillCopy->Source->getReg() ==
+ FoldableReloadCopy->Destination->getReg() &&
+ FoldableSpillCopy->Destination->getReg() ==
+ FoldableReloadCopy->Source->getReg();
};
- auto IsChainedCopy = [&, this](const MachineInstr &Prev,
- const MachineInstr &Current) {
- if (!IsFoldableCopy(Prev) || !IsFoldableCopy(Current))
+ auto IsChainedCopy = [&](const MachineInstr &Prev,
+ const MachineInstr &Current) {
+ std::optional<DestSourcePair> FoldablePrevCopy = GetFoldableCopy(Prev);
+ std::optional<DestSourcePair> FoldableCurrentCopy =
+ GetFoldableCopy(Current);
+ if (!FoldablePrevCopy || !FoldableCurrentCopy)
return false;
- std::optional<DestSourcePair> PrevCopy =
- isCopyInstr(Prev, *TII, UseCopyInstr);
- std::optional<DestSourcePair> CurrentCopy =
- isCopyInstr(Current, *TII, UseCopyInstr);
- if (!PrevCopy || !CurrentCopy)
- return false;
- return PrevCopy->Source->getReg() == CurrentCopy->Destination->getReg();
+ return FoldablePrevCopy->Source->getReg() ==
+ FoldableCurrentCopy->Destination->getReg();
};
for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
@@ -1429,6 +1438,10 @@ void MachineCopyPropagation::EliminateSpillageCopies(MachineBasicBlock &MBB) {
SmallSet<Register, 8> RegsToClobber;
if (!CopyOperands) {
for (const MachineOperand &MO : MI.operands()) {
+ if (MO.isRegMask()) {
+ BitVector &PreservedRegUnits = Tracker.getPreservedRegUnits(MO, *TRI);
+ Tracker.clobberNonPreservedRegs(PreservedRegUnits, *TRI, *TII, UseCopyInstr);
+ }
if (!MO.isReg())
continue;
Register Reg = MO.getReg();
``````````
</details>
https://github.com/llvm/llvm-project/pull/192609
More information about the llvm-commits
mailing list