[llvm] [AMDGPU] Add SSA-form memory clause pass (AMDGPUFormSSAMemoryClauses) (PR #209656)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 31 08:09:38 PDT 2026


================
@@ -0,0 +1,434 @@
+//===-- AMDGPUFormSSAMemoryClauses.cpp ------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This pass is a clone of SIFormMemoryClauses intended to run in SSA
+/// form, before PHI elimination. It extends the live ranges of registers used
+/// as pointers in sequences of adjacent SMEM and VMEM instructions when XNACK
+/// is enabled, preventing a load from overwriting a pointer and requiring a
+/// soft clause break.
+///
+//===----------------------------------------------------------------------===//
+
+#include "AMDGPUFormSSAMemoryClauses.h"
+#include "AMDGPU.h"
+#include "GCNRegPressure.h"
+#include "SIMachineFunctionInfo.h"
+#include "llvm/CodeGen/LiveIntervals.h"
+#include "llvm/InitializePasses.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "amdgpu-form-ssa-memory-clauses"
+
+// Clauses longer then 15 instructions would overflow one of the counters
+// and stall. They can stall even earlier if there are outstanding counters.
+static cl::opt<unsigned> SSAMaxClause(
+    "amdgpu-ssa-max-memory-clause", cl::Hidden, cl::init(15),
+    cl::desc("Maximum length of a memory clause for SSA form pass, "
+             "instructions"));
+
+namespace {
+
+class AMDGPUFormSSAMemoryClausesImpl {
+  using RegUse = DenseMap<unsigned, std::pair<RegState, LaneBitmask>>;
+
+  bool canBundle(const MachineInstr &MI, const RegUse &Defs,
+                 const RegUse &Uses) const;
+  bool checkPressure(const MachineInstr &MI, GCNDownwardRPTracker &RPT);
+  void collectRegUses(const MachineInstr &MI, RegUse &Defs, RegUse &Uses) const;
+  bool processRegUses(const MachineInstr &MI, RegUse &Defs, RegUse &Uses,
+                      GCNDownwardRPTracker &RPT);
+
+  const GCNSubtarget *ST;
+  const SIRegisterInfo *TRI;
+  const MachineRegisterInfo *MRI;
+  SIMachineFunctionInfo *MFI;
+  LiveIntervals *LIS;
+
+  unsigned LastRecordedOccupancy;
+  unsigned MaxVGPRs;
+  unsigned MaxSGPRs;
+
+public:
+  AMDGPUFormSSAMemoryClausesImpl(LiveIntervals *LS) : LIS(LS) {}
+  bool run(MachineFunction &MF);
+};
+
+class AMDGPUFormSSAMemoryClausesLegacy : public MachineFunctionPass {
+public:
+  static char ID;
+
+  AMDGPUFormSSAMemoryClausesLegacy() : MachineFunctionPass(ID) {}
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+  StringRef getPassName() const override {
+    return "AMDGPU Form SSA Memory Clauses";
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.addRequired<LiveIntervalsWrapperPass>();
+    AU.setPreservesAll();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+
+  // Unlike SIFormMemoryClauses, we do NOT clear the IsSSA property because
+  // this pass is designed to run while the function is still in SSA form.
+};
+
+} // End anonymous namespace.
+
+INITIALIZE_PASS_BEGIN(AMDGPUFormSSAMemoryClausesLegacy, DEBUG_TYPE,
+                      "AMDGPU Form SSA Memory Clauses", false, false)
+INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
+INITIALIZE_PASS_END(AMDGPUFormSSAMemoryClausesLegacy, DEBUG_TYPE,
+                    "AMDGPU Form SSA Memory Clauses", false, false)
+
+char AMDGPUFormSSAMemoryClausesLegacy::ID = 0;
+
+char &llvm::AMDGPUFormSSAMemoryClausesID = AMDGPUFormSSAMemoryClausesLegacy::ID;
+
+FunctionPass *llvm::createAMDGPUFormSSAMemoryClausesLegacyPass() {
+  return new AMDGPUFormSSAMemoryClausesLegacy();
+}
+
+static bool isVMEMClauseInst(const MachineInstr &MI) {
----------------
arsenm wrote:

Or just define both in the same file 

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


More information about the llvm-commits mailing list