[llvm] dbd8727 - [AMDGPU][NFC] Refine the representation of MODE register values. (#177574)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 26 05:10:30 PST 2026


Author: Ivan Kosarev
Date: 2026-01-26T13:10:24Z
New Revision: dbd87270885d1a23edab75ca6b840f209dac2134

URL: https://github.com/llvm/llvm-project/commit/dbd87270885d1a23edab75ca6b840f209dac2134
DIFF: https://github.com/llvm/llvm-project/commit/dbd87270885d1a23edab75ca6b840f209dac2134.diff

LOG: [AMDGPU][NFC] Refine the representation of MODE register values. (#177574)

- Eliminate the field masks.
- Segregate the encoding logic.
- Simplify and clarify the user code.

This is supposed to help updating downstream branches where we
have a more advanced version of the same facility.

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp
index 9505f98287c62..f4872ec63f7c3 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerVGPREncoding.cpp
@@ -43,10 +43,8 @@
 #include "AMDGPULowerVGPREncoding.h"
 #include "AMDGPU.h"
 #include "GCNSubtarget.h"
-#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
 #include "SIDefines.h"
 #include "SIInstrInfo.h"
-#include "llvm/ADT/PackedVector.h"
 #include "llvm/ADT/bit.h"
 #include "llvm/Support/MathExtras.h"
 
@@ -60,26 +58,44 @@ class AMDGPULowerVGPREncoding {
   static constexpr unsigned OpNum = 4;
   static constexpr unsigned BitsPerField = 2;
   static constexpr unsigned NumFields = 4;
-  static constexpr unsigned FieldMask = (1 << BitsPerField) - 1;
   static constexpr unsigned ModeWidth = NumFields * BitsPerField;
   static constexpr unsigned ModeMask = (1 << ModeWidth) - 1;
-  using ModeType = PackedVector<unsigned, BitsPerField,
-                                std::bitset<BitsPerField * NumFields>>;
-
   static constexpr unsigned VGPRMSBShift =
       llvm::countr_zero_constexpr<unsigned>(AMDGPU::Hwreg::DST_VGPR_MSB);
 
-  class ModeTy : public ModeType {
-  public:
-    // bitset constructor will set all bits to zero
-    ModeTy() : ModeType(0) {}
+  struct OpMode {
+    // No MSBs set means they are not required to be of a particular value.
+    std::optional<unsigned> MSBits;
+
+    bool update(const OpMode &New, bool &Rewritten) {
+      bool Updated = false;
+      if (New.MSBits) {
+        if (*New.MSBits != MSBits.value_or(0)) {
+          Updated = true;
+          Rewritten |= MSBits.has_value();
+        }
+        MSBits = New.MSBits;
+      }
+      return Updated;
+    }
+  };
+
+  struct ModeTy {
+    OpMode Ops[OpNum];
 
-    operator int64_t() const { return raw_bits().to_ulong(); }
+    bool update(const ModeTy &New, bool &Rewritten) {
+      bool Updated = false;
+      for (unsigned I : seq(OpNum))
+        Updated |= Ops[I].update(New.Ops[I], Rewritten);
+      return Updated;
+    }
 
-    static ModeTy fullMask() {
-      ModeTy M;
-      M.raw_bits().flip();
-      return M;
+    unsigned encode() const {
+      // Layout: [src0 msb, src1 msb, src2 msb, dst msb].
+      unsigned V = 0;
+      for (const auto &[I, Op] : enumerate(Ops))
+        V |= Op.MSBits.value_or(0) << (I * 2);
+      return V;
     }
   };
 
@@ -99,10 +115,6 @@ class AMDGPULowerVGPREncoding {
   /// Current mode bits.
   ModeTy CurrentMode;
 
-  /// Current mask of mode bits that instructions since MostRecentModeSet care
-  /// about.
-  ModeTy CurrentMask;
-
   /// Number of current hard clause instructions.
   unsigned ClauseLen;
 
@@ -116,12 +128,14 @@ class AMDGPULowerVGPREncoding {
   MachineInstr *Clause;
 
   /// Insert mode change before \p I. \returns true if mode was changed.
-  bool setMode(ModeTy NewMode, ModeTy Mask,
-               MachineBasicBlock::instr_iterator I);
+  bool setMode(ModeTy NewMode, MachineBasicBlock::instr_iterator I);
 
   /// Reset mode to default.
   void resetMode(MachineBasicBlock::instr_iterator I) {
-    setMode(ModeTy(), ModeTy::fullMask(), I);
+    ModeTy Mode;
+    for (OpMode &Op : Mode.Ops)
+      Op.MSBits = 0;
+    setMode(Mode, I);
   }
 
   /// If \p MO references VGPRs, return the MSBs. Otherwise, return nullopt.
@@ -130,11 +144,11 @@ class AMDGPULowerVGPREncoding {
   /// Handle single \p MI. \return true if changed.
   bool runOnMachineInstr(MachineInstr &MI);
 
-  /// Compute the mode and mode mask for a single \p MI given \p Ops operands
+  /// Compute the mode for a single \p MI given \p Ops operands
   /// bit mapping. Optionally takes second array \p Ops2 for VOPD.
   /// If provided and an operand from \p Ops is not a VGPR, then \p Ops2
   /// is checked.
-  void computeMode(ModeTy &NewMode, ModeTy &Mask, MachineInstr &MI,
+  void computeMode(ModeTy &NewMode, MachineInstr &MI,
                    const AMDGPU::OpName Ops[OpNum],
                    const AMDGPU::OpName *Ops2 = nullptr);
 
@@ -161,49 +175,38 @@ class AMDGPULowerVGPREncoding {
   bool updateSetregModeImm(MachineInstr &MI, int64_t ModeValue);
 };
 
-bool AMDGPULowerVGPREncoding::setMode(ModeTy NewMode, ModeTy Mask,
+bool AMDGPULowerVGPREncoding::setMode(ModeTy NewMode,
                                       MachineBasicBlock::instr_iterator I) {
-  assert((NewMode.raw_bits() & ~Mask.raw_bits()).none());
-  assert((CurrentMode.raw_bits() & ~CurrentMask.raw_bits()).none());
-
-  auto Delta = NewMode.raw_bits() ^ CurrentMode.raw_bits();
+  // Record previous mode into high 8 bits of the immediate.
+  int64_t OldModeBits = CurrentMode.encode() << ModeWidth;
 
-  if ((Delta & Mask.raw_bits()).none()) {
-    CurrentMask |= Mask;
+  bool Rewritten = false;
+  if (!CurrentMode.update(NewMode, Rewritten))
     return false;
-  }
-
-  if (MostRecentModeSet &&
-      ((Delta & Mask.raw_bits()) & CurrentMask.raw_bits()).none()) {
-    CurrentMode |= NewMode;
-    CurrentMask |= Mask;
 
+  if (MostRecentModeSet && !Rewritten) {
     // Update MostRecentModeSet with the new mode. It can be either
     // S_SET_VGPR_MSB or S_SETREG_IMM32_B32 (with Size <= 12).
     if (MostRecentModeSet->getOpcode() == AMDGPU::S_SET_VGPR_MSB) {
       MachineOperand &Op = MostRecentModeSet->getOperand(0);
       // Carry old mode bits from the existing instruction.
       int64_t OldModeBits = Op.getImm() & (ModeMask << ModeWidth);
-      Op.setImm(CurrentMode | OldModeBits);
+      Op.setImm(CurrentMode.encode() | OldModeBits);
     } else {
       assert(MostRecentModeSet->getOpcode() == AMDGPU::S_SETREG_IMM32_B32 &&
              "unexpected MostRecentModeSet opcode");
-      updateSetregModeImm(*MostRecentModeSet, CurrentMode);
+      updateSetregModeImm(*MostRecentModeSet, CurrentMode.encode());
     }
 
     return true;
   }
 
-  // Record previous mode into high 8 bits of the immediate.
-  int64_t OldModeBits = CurrentMode << ModeWidth;
-
   I = handleClause(I);
   I = handleCoissue(I);
   MostRecentModeSet = BuildMI(*MBB, I, {}, TII->get(AMDGPU::S_SET_VGPR_MSB))
-                          .addImm(NewMode | OldModeBits);
+                          .addImm(NewMode.encode() | OldModeBits);
 
   CurrentMode = NewMode;
-  CurrentMask = Mask;
   return true;
 }
 
@@ -221,12 +224,10 @@ AMDGPULowerVGPREncoding::getMSBs(const MachineOperand &MO) const {
   return Idx >> 8;
 }
 
-void AMDGPULowerVGPREncoding::computeMode(ModeTy &NewMode, ModeTy &Mask,
-                                          MachineInstr &MI,
+void AMDGPULowerVGPREncoding::computeMode(ModeTy &NewMode, MachineInstr &MI,
                                           const AMDGPU::OpName Ops[OpNum],
                                           const AMDGPU::OpName *Ops2) {
   NewMode = {};
-  Mask = {};
 
   for (unsigned I = 0; I < OpNum; ++I) {
     MachineOperand *Op = TII->getNamedOperand(MI, Ops[I]);
@@ -265,17 +266,16 @@ void AMDGPULowerVGPREncoding::computeMode(ModeTy &NewMode, ModeTy &Mask,
           TII->hasVALU32BitEncoding(MI.getOpcode()))))
       continue;
 
-    NewMode[I] = MSBits.value();
-    Mask[I] = FieldMask;
+    NewMode.Ops[I].MSBits = MSBits.value();
   }
 }
 
 bool AMDGPULowerVGPREncoding::runOnMachineInstr(MachineInstr &MI) {
   auto Ops = AMDGPU::getVGPRLoweringOperandTables(MI.getDesc());
   if (Ops.first) {
-    ModeTy NewMode, Mask;
-    computeMode(NewMode, Mask, MI, Ops.first, Ops.second);
-    return setMode(NewMode, Mask, MI.getIterator());
+    ModeTy NewMode;
+    computeMode(NewMode, MI, Ops.first, Ops.second);
+    return setMode(NewMode, MI.getIterator());
   }
   assert(!TII->hasVGPRUses(MI) || MI.isMetaInstruction() || MI.isPseudo());
 
@@ -377,7 +377,7 @@ bool AMDGPULowerVGPREncoding::handleSetregMode(MachineInstr &MI) {
   if (HwRegId != ID_MODE)
     return false;
 
-  int64_t ModeValue = static_cast<int64_t>(CurrentMode);
+  int64_t ModeValue = CurrentMode.encode();
 
   // Case 1: Size <= 12 - the original instruction uses imm32[0:Size-1], so
   // imm32[12:19] is unused. Safe to set imm32[12:19] to the correct VGPR
@@ -425,8 +425,7 @@ bool AMDGPULowerVGPREncoding::run(MachineFunction &MF) {
 
   bool Changed = false;
   ClauseLen = ClauseRemaining = 0;
-  CurrentMode.reset();
-  CurrentMask.reset();
+  CurrentMode = {};
   for (auto &MBB : MF) {
     MostRecentModeSet = nullptr;
     this->MBB = &MBB;
@@ -438,7 +437,7 @@ bool AMDGPULowerVGPREncoding::run(MachineFunction &MF) {
       if (MI.isTerminator() || MI.isCall()) {
         if (MI.getOpcode() == AMDGPU::S_ENDPGM ||
             MI.getOpcode() == AMDGPU::S_ENDPGM_SAVED)
-          CurrentMode.reset();
+          CurrentMode = {};
         else
           resetMode(MI.getIterator());
         continue;


        


More information about the llvm-commits mailing list