[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