[llvm] [CodeGen] Remove unsatisfiable hints in RegAllocGreedy. (PR #190983)
Mikhail Gudim via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 8 07:49:25 PDT 2026
https://github.com/mgudim created https://github.com/llvm/llvm-project/pull/190983
If a virtual register's live range `LR` is hinted to `PhysReg` but at the same time `PhysReg` and `LR` interfere, the hint can never be satisfied, so it should be removed.
>From 48aa91ba85225590c65e04c6056e261edd143d80 Mon Sep 17 00:00:00 2001
From: Mikhail Gudim <mgudim at qti.qualcomm.com>
Date: Mon, 6 Apr 2026 09:15:12 -0700
Subject: [PATCH] [CodeGen] Remove unsatisfiable hints in RegAllocGreedy.
If a virtual register's live range `LR` is hinted to `PhysReg` but at the same
time `PhysReg` and `LR` interfere, the hint can never be satisfied, so
it should be removed.
---
llvm/lib/CodeGen/RegAllocGreedy.cpp | 27 +++++++++++++++++++++++++++
llvm/lib/CodeGen/RegAllocGreedy.h | 1 +
2 files changed, 28 insertions(+)
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 8565a7233d32c..6e01793acb9dd 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -81,6 +81,8 @@ using namespace llvm;
STATISTIC(NumGlobalSplits, "Number of split global live ranges");
STATISTIC(NumLocalSplits, "Number of split local live ranges");
STATISTIC(NumEvicted, "Number of interferences evicted");
+STATISTIC(NumUnsatisfiableHintsRemoved,
+ "Number of unsatisfiable hints removed");
static cl::opt<SplitEditor::ComplementSpillMode> SplitSpillMode(
"split-spill-mode", cl::Hidden,
@@ -2454,6 +2456,30 @@ void RAGreedy::initializeCSRCost() {
}
}
+/// For each virtual register whose simple hint is a physical register,
+/// check whether that physreg's live range overlaps the vreg's live range.
+/// If it does the hint can never be satisfied; clear it so the vreg does not
+/// receive a spurious priority boost and does not trigger futile evictions.
+void RAGreedy::removeUnsatisfiableHints() {
+ for (unsigned Idx = 0, End = MRI->getNumVirtRegs(); Idx < End; ++Idx) {
+ Register VReg = Register::index2VirtReg(Idx);
+ if (MRI->reg_nodbg_empty(VReg))
+ continue;
+ Register HintReg = MRI->getSimpleHint(VReg);
+ if (!HintReg.isPhysical())
+ continue;
+ const LiveInterval &LI = LIS->getInterval(VReg);
+ for (MCRegUnit Unit : TRI->regunits(HintReg.asMCReg())) {
+ const LiveRange &PhysLR = LIS->getRegUnit(Unit);
+ if (PhysLR.overlaps(LI)) {
+ MRI->clearSimpleHint(VReg);
+ ++NumUnsatisfiableHintsRemoved;
+ break;
+ }
+ }
+ }
+}
+
/// Collect the hint info for \p Reg.
/// The results are stored into \p Out.
/// \p Out is not cleared before being populated.
@@ -2971,6 +2997,7 @@ bool RAGreedy::run(MachineFunction &mf) {
*VRM, *VRAI, Matrix));
VRAI->calculateSpillWeightsAndHints();
+ removeUnsatisfiableHints();
LLVM_DEBUG(LIS->dump());
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h
index 465be0d76809e..c16bca452c01a 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.h
+++ b/llvm/lib/CodeGen/RegAllocGreedy.h
@@ -362,6 +362,7 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public RegAllocBase,
SmallVectorImpl<Register> &NewVRegs);
BlockFrequency calcSpillCost(const LiveInterval &LI);
void initializeCSRCost();
+ void removeUnsatisfiableHints();
MCRegister tryBlockSplit(const LiveInterval &, AllocationOrder &,
SmallVectorImpl<Register> &);
MCRegister tryInstructionSplit(const LiveInterval &, AllocationOrder &,
More information about the llvm-commits
mailing list