[llvm] [TableGen][SIInsertWaitcnts] use RegIntervals for AMDGPU (PR #174888)

Ryan Mitchell via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 8 17:50:11 PST 2026


================
@@ -1929,6 +1929,115 @@ void CodeGenRegBank::computeRegUnitWeights() {
   }
 }
 
+// Enforce that all registers are intervals of regunits if the target
+// requests this property. This will renumber regunits to ensure the
+// interval property holds, or error out if it cannot be satisfied.
+void CodeGenRegBank::enforceRegUnitIntervals() {
+  std::vector<const Record *> Targets =
+      Records.getAllDerivedDefinitions("Target");
+
+  if (Targets.empty())
+    return;
+
+  const Record *Target = Targets[0];
+  if (!Target->getValueAsBit("RegistersAreIntervals"))
+    return;
+
+  LLVM_DEBUG(dbgs() << "Enforcing regunit intervals for target\n");
+  std::vector<unsigned> RegUnitRenumbering(RegUnits.size(), ~0u);
+
+  // RegUnits that have been renumbered from X -> Y. Y is what is marked so that
+  // it doesn't create a chain of swaps.
+  SparseBitVector DontRenumberUnits;
+
+  std::function<unsigned(unsigned)> GetRenumberedUnit =
+      [&](unsigned NewUnit) -> unsigned {
+    if (RegUnitRenumbering[NewUnit] == ~0u)
+      return NewUnit;
+    else
+      return RegUnitRenumbering[NewUnit];
+  };
+
+  std::function<void(unsigned, unsigned)> UpdateRenumbering =
+      [&](unsigned PrevUnit, unsigned NewUnit) {
+        RegUnitRenumbering[NewUnit] = PrevUnit;
+        RegUnitRenumbering[PrevUnit] = NewUnit;
+        DontRenumberUnits.set(NewUnit);
+      };
+
+  std::function<unsigned(unsigned)> GetFinalRegUnit =
+      [&](unsigned CurrUnit) -> unsigned {
+    if (RegUnitRenumbering[CurrUnit] != ~0u)
+      return RegUnitRenumbering[CurrUnit];
+    return CurrUnit;
+  };
+
+  std::function<bool(CodeGenRegister::RegUnitList &)> IsContiguous =
+      [&](CodeGenRegister::RegUnitList &Units) -> bool {
+    unsigned LastUnit = Units.find_first();
+    for (auto ThisUnit : llvm::make_range(++Units.begin(), Units.end())) {
+      if (ThisUnit != LastUnit + 1)
+        return false;
+      LastUnit = ThisUnit;
+    }
+    return true;
+  };
+
+  // Process registers in definition order
+  for (CodeGenRegister &Reg : Registers) {
+    LLVM_DEBUG(dbgs() << "Processing register " << Reg.getName() << "\n");
+    const auto &Units = Reg.getNativeRegUnits();
+    if (Units.empty())
+      continue;
+    SparseBitVector RenumberedUnits;
+    // First renumber all the units for this register according to previous
+    // renumbering.
+    LLVM_DEBUG(dbgs() << "  Original (Renumbered) units:");
+    for (unsigned U : Units) {
+      LLVM_DEBUG(dbgs() << " " << U << "(" << GetRenumberedUnit(U) << "), ");
+      RenumberedUnits.set(GetRenumberedUnit(U));
+    }
+    LLVM_DEBUG(dbgs() << "\n");
+
+    unsigned LastUnit = RenumberedUnits.find_first();
+    for (auto ThisUnit :
+         llvm::make_range(++RenumberedUnits.begin(), RenumberedUnits.end())) {
+      if (ThisUnit != LastUnit + 1) {
+        if (DontRenumberUnits.test(LastUnit + 1)) {
+          LLVM_DEBUG(dbgs() << "  Cannot renumber unit " << LastUnit + 1
+                            << " because it is already a renumbered unit\n");
+          reportFatalInternalError("Cannot enforce regunit intervals, greedy "
+                                   "swapping of regunits failed.");
+        }
----------------
RyanRio wrote:

Are you asking for a better message here you mean?

Note to self to use PrintFatalError instead as well.

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


More information about the llvm-commits mailing list