[llvm] [AMDGPU] Introduce Next-Use Analysis for SSA-based Register Allocation (PR #156079)

via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 2 13:11:15 PST 2025


================
@@ -0,0 +1,398 @@
+//===------- VRegMaskPair.h ----------------------------------------*-
+// C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// ile
+/// rief Defines VRegMaskPair and VRegMaskPairSet for managing sets of
+/// virtual registers and their lane masks.
+///
+/// Set operations (union, intersection, subtraction) are implemented based on
+/// *subregister coverage logic* rather than exact equality. This means:
+/// - Two VRegMaskPairs are considered overlapping if their LaneMasks overlap.
+/// - Intersection and subtraction operate on *overlapping masks*, not exact
+/// matches.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_TARGET_VREGMASKPAIR_H
+#define LLVM_LIB_TARGET_VREGMASKPAIR_H
+
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Register.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/MC/LaneBitmask.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+
+class VRegMaskPairSet;
+
+class VRegMaskPair {
+  friend class VRegMaskPairSet;
+
+  Register VReg;
+  LaneBitmask LaneMask;
+
+public:
+  VRegMaskPair(Register VReg, LaneBitmask LaneMask)
+      : VReg(VReg), LaneMask(LaneMask) {}
+
+  VRegMaskPair() : VReg(AMDGPU::NoRegister), LaneMask(LaneBitmask::getNone()) {}
+  VRegMaskPair(const VRegMaskPair &Other) = default;
+  VRegMaskPair(VRegMaskPair &&Other) = default;
+  VRegMaskPair &operator=(const VRegMaskPair &Other) = default;
+  VRegMaskPair &operator=(VRegMaskPair &&Other) = default;
+
+  VRegMaskPair(const MachineOperand MO, const SIRegisterInfo *TRI,
+               const MachineRegisterInfo *MRI) {
+    assert(MO.isReg() && "Not a register operand!");
+    assert(MO.getReg().isVirtual() && "Not a virtual register!");
+    VReg = MO.getReg();
+    LaneMask = MO.getSubReg() ? TRI->getSubRegIndexLaneMask(MO.getSubReg())
+                              : MRI->getMaxLaneMaskForVReg(VReg);
+  }
+
+  const Register getVReg() const { return VReg; }
+  const LaneBitmask getLaneMask() const { return LaneMask; }
+
+  unsigned getSubReg(const MachineRegisterInfo *MRI,
+                     const SIRegisterInfo *TRI) const {
+    LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(VReg);
+    if (LaneMask == Mask)
+      return AMDGPU::NoRegister;
+    return getSubRegIndexForLaneMask(LaneMask, TRI);
+  }
+
+  const TargetRegisterClass *getRegClass(const MachineRegisterInfo *MRI,
+                                         const SIRegisterInfo *TRI) const {
+    const TargetRegisterClass *RC = TRI->getRegClassForReg(*MRI, VReg);
+    LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(VReg);
+    if (LaneMask != Mask) {
+      unsigned SubRegIdx = getSubRegIndexForLaneMask(LaneMask, TRI);
+      return TRI->getSubRegisterClass(RC, SubRegIdx);
+    }
+    return RC;
+  }
+
+  unsigned getSizeInRegs(const SIRegisterInfo *TRI) const {
+    return TRI->getNumCoveredRegs(LaneMask);
+  }
+
+  bool operator==(const VRegMaskPair &other) const {
+    return VReg == other.VReg && LaneMask == other.LaneMask;
+  }
+};
+
+class LaneCoverageResult {
+  friend class VRegMaskPairSet;
+  LaneBitmask Data;
+  LaneBitmask Covered;
+  LaneBitmask NotCovered;
+
+public:
+  LaneCoverageResult() = default;
+  LaneCoverageResult(const LaneBitmask Mask) : Data(Mask), NotCovered(Mask){};
+  bool isFullyCovered() { return Data == Covered; }
+  bool isFullyUncovered() { return Data == NotCovered; }
+  LaneBitmask getCovered() { return Covered; }
+  LaneBitmask getNotCovered() { return NotCovered; }
+};
+
+class VRegMaskPairSet {
+
+  using MaskSet = std::set<LaneBitmask>;
----------------
alex-t wrote:

Please see an updates comment explaining why std::set was chosen

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


More information about the llvm-commits mailing list