[llvm] [AMDGPU] NFC: Provide RPTracker interface for external iterators (PR #93088)

Jeffrey Byrnes via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 23 15:43:30 PDT 2024


================
@@ -288,6 +288,72 @@ collectVirtualRegUses(SmallVectorImpl<RegisterMaskPair> &RegMaskPairs,
   }
 }
 
+static LaneBitmask getRegLanes(ArrayRef<RegisterMaskPair> RegUnits,
+                               Register RegUnit) {
+  auto I = llvm::find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
+    return Other.RegUnit == RegUnit;
+  });
+  if (I == RegUnits.end())
+    return LaneBitmask::getNone();
+  return I->LaneMask;
+}
+
+static LaneBitmask
+getLanesWithProperty(const LiveIntervals &LIS, const MachineRegisterInfo &MRI,
+                     bool TrackLaneMasks, Register RegUnit, SlotIndex Pos,
+                     LaneBitmask SafeDefault,
+                     bool (*Property)(const LiveRange &LR, SlotIndex Pos)) {
+  if (RegUnit.isVirtual()) {
+    const LiveInterval &LI = LIS.getInterval(RegUnit);
+    LaneBitmask Result;
+    if (TrackLaneMasks && LI.hasSubRanges()) {
+      for (const LiveInterval::SubRange &SR : LI.subranges()) {
+        if (Property(SR, Pos))
+          Result |= SR.LaneMask;
+      }
+    } else if (Property(LI, Pos)) {
+      Result = TrackLaneMasks ? MRI.getMaxLaneMaskForVReg(RegUnit)
+                              : LaneBitmask::getAll();
+    }
+
+    return Result;
+  } else {
+    const LiveRange *LR = LIS.getCachedRegUnit(RegUnit);
+    // Be prepared for missing liveranges: We usually do not compute liveranges
+    // for physical registers on targets with many registers (GPUs).
+    if (LR == nullptr)
+      return SafeDefault;
+    return Property(*LR, Pos) ? LaneBitmask::getAll() : LaneBitmask::getNone();
+  }
+}
+
+/// Helper to find a vreg use between two indices [PriorUseIdx, NextUseIdx).
+/// The query starts with a lane bitmask which gets lanes/bits removed for every
+/// use we find.
+static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
+                                  SlotIndex PriorUseIdx, SlotIndex NextUseIdx,
+                                  const MachineRegisterInfo &MRI,
+                                  const LiveIntervals *LIS,
+                                  bool Upward = false) {
+  const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
+  for (const MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
+    if (MO.isUndef())
+      continue;
----------------
jrbyrnes wrote:

Ultimately, RP should agree with RA interference. AFAICT, RA interference is determined by the subrange segments, rather than the main range with the strange liveness concerns -- I'm still analyzing.

In https://godbolt.org/z/MdTEG44a4 we have a use `%49.sub0:areg_1024` occuring before a def of the same superreg `%49.sub1:areg_1024`. According to the subreg def is a use of other subregs, `%49.sub0:areg_1024` should be live until the def `%49.sub1:areg_1024`. However, when assigning `%2:agpr_32`, RA sees there is no interference with `%49.sub0:areg_1024` and assigns to the same PhysReg.

This is consistent with how the GCNTrackers currently calculate RP: we consider the use subrange and whether or not it is live at some given index https://github.com/llvm/llvm-project/blob/10407be542aeb2b59477b167bbba3716538dc722/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp#L458 and don't check if there is some reaching subreg def.


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


More information about the llvm-commits mailing list