[llvm] [WIP] AMDGPU: VGPR bank conflict avoidance hints (PR #192140)

Shilei Tian via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 19 07:43:14 PDT 2026


================
@@ -3912,12 +3940,84 @@ bool SIRegisterInfo::getRegAllocationHints(Register VirtReg,
           Hints.push_back(PhysReg);
       }
     }
-    return false;
+    BaseImplRetVal = false;
+    break;
   }
-  default:
-    return TargetRegisterInfo::getRegAllocationHints(VirtReg, Order, Hints, MF,
-                                                     VRM);
+  default: {
+
+        BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(VirtReg, Order,
+                                                                   Hints, MF, VRM);
+        break;
+    }
   }
+
+  // Bank conflict avoidance for VGPRs
+  if (EnableVGPRBankConflictAvoidance && VRM && isVGPR(MRI, VirtReg)) {
+    // Track which banks are already in use by allocated operands
+    SmallDenseMap<unsigned, unsigned, 4> BankUsage; // bank_id -> use_count
+    bool HasRelevant3OpVALU = false;
+
+    // Scan all uses of this virtual register
+    for (const MachineInstr &Use : MRI.use_nodbg_instructions(VirtReg)) {
+      if (!is3OperandVALU(Use))
+        continue;
+
+      HasRelevant3OpVALU = true;
+
+      // Check which banks are used by other operands
+      for (const MachineOperand &MO : Use.uses()) {
+        if (!MO.isReg() || MO.getReg() == VirtReg)
+          continue;
+
+        Register OpReg = MO.getReg();
+
+        // Only care about already-allocated physical registers
+        if (OpReg.isVirtual()) {
+          if (VRM->hasPhys(OpReg))
+            OpReg = VRM->getPhys(OpReg);
+          else
+            continue;
+        }
+
+        if (OpReg.isPhysical() && isVGPR(MRI, OpReg)) {
+          unsigned Bank = getHWRegIndex(OpReg) % 4;
+          BankUsage[Bank]++;
+        }
+      }
+    }
+
+    if (HasRelevant3OpVALU && !BankUsage.empty()) {
+      constexpr unsigned MaxBankHints = 32; // Arbitrary limit to avoid excessive hints
+      unsigned Added = 0;
+
+      // Pass 1: conflict-free candidates (no operands on this bank)
+      for (MCPhysReg Cand : Order) {
+        if (Added >= MaxBankHints)
+          break;
+        unsigned CandBank = getHWRegIndex(Cand) % 4;
----------------
shiltian wrote:

I'd add a function to get the bank of a register. If in the future we have a different bank size, it can just be managed in one place.

https://github.com/llvm/llvm-project/pull/192140


More information about the llvm-commits mailing list