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

Jeffrey Byrnes via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 21 15:39:36 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:

Actually, I'm not quite sure what we're trying to accomplish here?

```
  // Definitions

  1.  undef %63.sub1:vreg_128 = COPY %49.sub18:areg_1024 
  2.  %49.sub1:areg_1024 = COPY %63.sub1:vreg_128
  3.  undef %63.sub0:vreg_128 = COPY %49.sub19:areg_1024

  // No uses of %49.sub19 or defs of %49.subx
```

If we were speculating the RP from schedule (1, 3, ..)  we would invoke findUseBetween to find any uses of %49 between 3s original position and its candidate position. I think you are saying that we should consider the %49.sub1 def in 2. as an implicit use of %49.sub19? I know that the LIS requires subregister liveness to be modeled in this way somewhat (e.g. no multiple connected components), but from the perspective of RegisterPressure, It seems more accurate (and safe) to not model it this way -- that is, to only check use operands.

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


More information about the llvm-commits mailing list