[llvm] [CodeGen] Remove experimental deferred spilling from GreedyRegAlloc (PR #137850)
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 29 10:42:21 PDT 2025
https://github.com/preames created https://github.com/llvm/llvm-project/pull/137850
This experimental option was introduced in 2015 via commit 1192294, and the target hook was added in 2020 via commit 99e865b6. There does not appear to have ever been a use of this target hook in tree.
This code is complicating one of the most complicated and hard to understand parts of our code base, and was an experiment introduced nearly 10 years ago. Let's get rid of it.
Note that the idea described in the original patch is not neccessarily a bad one, and we might return to it someday.
>From f3a8dd62408404851d25da97942d547a6e2dc839 Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
Date: Tue, 29 Apr 2025 10:19:38 -0700
Subject: [PATCH] [CodeGen] Remove experimental deferred spilling from
GreedyRegAlloc
This experimental option was introduced in 2015 via commit 1192294,
and the target hook was added in 2020 via commit 99e865b6. There
does not appear to have ever been a use of this target hook in
tree.
This code is complicating one of the most complicated and hard to
understand parts of our code base, and was an experiment introduced
nearly 10 years ago. Let's get rid of it.
Note that the idea described in the original patch is not neccessarily
a bad one, and we might return to it someday.
---
.../llvm/CodeGen/RegAllocEvictionAdvisor.h | 4 --
.../include/llvm/CodeGen/TargetRegisterInfo.h | 15 -----
llvm/lib/CodeGen/RegAllocGreedy.cpp | 58 +++++--------------
3 files changed, 15 insertions(+), 62 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/RegAllocEvictionAdvisor.h b/llvm/include/llvm/CodeGen/RegAllocEvictionAdvisor.h
index a14548ff6959e..e4f0932c3edc8 100644
--- a/llvm/include/llvm/CodeGen/RegAllocEvictionAdvisor.h
+++ b/llvm/include/llvm/CodeGen/RegAllocEvictionAdvisor.h
@@ -66,10 +66,6 @@ enum LiveRangeStage {
/// Live range will be spilled. No more splitting will be attempted.
RS_Spill,
- /// Live range is in memory. Because of other evictions, it might get moved
- /// in a register in the end.
- RS_Memory,
-
/// There is nothing more we can do to this live range. Abort compilation
/// if it can't be assigned.
RS_Done
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index ab3eaa92548ca..7d4f7aecd9df3 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -1192,21 +1192,6 @@ class TargetRegisterInfo : public MCRegisterInfo {
return true;
}
- /// Deferred spilling delays the spill insertion of a virtual register
- /// after every other allocation. By deferring the spilling, it is
- /// sometimes possible to eliminate that spilling altogether because
- /// something else could have been eliminated, thus leaving some space
- /// for the virtual register.
- /// However, this comes with a compile time impact because it adds one
- /// more stage to the greedy register allocator.
- /// This method is used to decide whether \p VirtReg should use the deferred
- /// spilling stage instead of being spilled right away.
- virtual bool
- shouldUseDeferredSpillingForVirtReg(const MachineFunction &MF,
- const LiveInterval &VirtReg) const {
- return false;
- }
-
/// When prioritizing live ranges in register allocation, if this hook returns
/// true then the AllocationPriority of the register class will be treated as
/// more important than whether the range is local to a basic block or global.
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 56d3bd953f57d..4157a485c6388 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -107,14 +107,6 @@ static cl::opt<bool> ExhaustiveSearch(
"and interference cutoffs of last chance recoloring"),
cl::Hidden);
-static cl::opt<bool> EnableDeferredSpilling(
- "enable-deferred-spilling", cl::Hidden,
- cl::desc("Instead of spilling a variable right away, defer the actual "
- "code insertion to the end of the allocation. That way the "
- "allocator might still find a suitable coloring for this "
- "variable because of other evicted variables."),
- cl::init(false));
-
// FIXME: Find a good default for this flag and remove the flag.
static cl::opt<unsigned>
CSRFirstTimeCost("regalloc-csr-first-time-cost",
@@ -328,7 +320,6 @@ const char *const RAGreedy::StageName[] = {
"RS_Split",
"RS_Split2",
"RS_Spill",
- "RS_Memory",
"RS_Done"
};
#endif
@@ -456,13 +447,6 @@ unsigned DefaultPriorityAdvisor::getPriority(const LiveInterval &LI) const {
// Unsplit ranges that couldn't be allocated immediately are deferred until
// everything else has been allocated.
Prio = Size;
- } else if (Stage == RS_Memory) {
- // Memory operand should be considered last.
- // Change the priority such that Memory operand are assigned in
- // the reverse order that they came in.
- // TODO: Make this a member variable and probably do something about hints.
- static unsigned MemOp = 0;
- Prio = MemOp++;
} else {
// Giant live ranges fall back to the global assignment heuristic, which
// prevents excessive spilling in pathological cases.
@@ -2650,34 +2634,22 @@ MCRegister RAGreedy::selectOrSplitImpl(const LiveInterval &VirtReg,
}
// Finally spill VirtReg itself.
- if ((EnableDeferredSpilling ||
- TRI->shouldUseDeferredSpillingForVirtReg(*MF, VirtReg)) &&
- ExtraInfo->getStage(VirtReg) < RS_Memory) {
- // TODO: This is experimental and in particular, we do not model
- // the live range splitting done by spilling correctly.
- // We would need a deep integration with the spiller to do the
- // right thing here. Anyway, that is still good for early testing.
- ExtraInfo->setStage(VirtReg, RS_Memory);
- LLVM_DEBUG(dbgs() << "Do as if this register is in memory\n");
- NewVRegs.push_back(VirtReg.reg());
- } else {
- NamedRegionTimer T("spill", "Spiller", TimerGroupName,
- TimerGroupDescription, TimePassesIsEnabled);
- LiveRangeEdit LRE(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
- spiller().spill(LRE);
- ExtraInfo->setStage(NewVRegs.begin(), NewVRegs.end(), RS_Done);
-
- // Tell LiveDebugVariables about the new ranges. Ranges not being covered by
- // the new regs are kept in LDV (still mapping to the old register), until
- // we rewrite spilled locations in LDV at a later stage.
- for (Register r : spiller().getSpilledRegs())
- DebugVars->splitRegister(r, LRE.regs(), *LIS);
- for (Register r : spiller().getReplacedRegs())
- DebugVars->splitRegister(r, LRE.regs(), *LIS);
+ NamedRegionTimer T("spill", "Spiller", TimerGroupName,
+ TimerGroupDescription, TimePassesIsEnabled);
+ LiveRangeEdit LRE(&VirtReg, NewVRegs, *MF, *LIS, VRM, this, &DeadRemats);
+ spiller().spill(LRE);
+ ExtraInfo->setStage(NewVRegs.begin(), NewVRegs.end(), RS_Done);
+
+ // Tell LiveDebugVariables about the new ranges. Ranges not being covered by
+ // the new regs are kept in LDV (still mapping to the old register), until
+ // we rewrite spilled locations in LDV at a later stage.
+ for (Register r : spiller().getSpilledRegs())
+ DebugVars->splitRegister(r, LRE.regs(), *LIS);
+ for (Register r : spiller().getReplacedRegs())
+ DebugVars->splitRegister(r, LRE.regs(), *LIS);
- if (VerifyEnabled)
- MF->verify(LIS, Indexes, "After spilling", &errs());
- }
+ if (VerifyEnabled)
+ MF->verify(LIS, Indexes, "After spilling", &errs());
// The live virtual register requesting allocation was spilled, so tell
// the caller not to allocate anything during this round.
More information about the llvm-commits
mailing list