[llvm] 2c88996 - [SPIR-V][NewPM] Port SPIRVModuleAnalysis (#227376)

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 7 03:49:36 PDT 2026


Author: Arseniy Obolenskiy
Date: 2026-10-07T10:49:21Z
New Revision: 2c8899609919bbc8afd59b69424ea8487f9396db

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

LOG: [SPIR-V][NewPM] Port SPIRVModuleAnalysis (#227376)

This step enables us with e2e compilation with new pass manager

Added: 
    

Modified: 
    llvm/lib/Target/SPIRV/SPIRV.h
    llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
    llvm/lib/Target/SPIRV/SPIRVCodeGenPassBuilder.cpp
    llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
    llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
    llvm/lib/Target/SPIRV/SPIRVPassRegistry.def
    llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
    llvm/test/CodeGen/SPIRV/llc-pipeline.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SPIRV/SPIRV.h b/llvm/lib/Target/SPIRV/SPIRV.h
index ccc7aa52ec52c..1c8e881c307b7 100644
--- a/llvm/lib/Target/SPIRV/SPIRV.h
+++ b/llvm/lib/Target/SPIRV/SPIRV.h
@@ -178,7 +178,7 @@ createSPIRVInstructionSelector(const SPIRVTargetMachine &TM,
                                const SPIRVSubtarget &Subtarget,
                                const RegisterBankInfo &RBI);
 
-void initializeSPIRVModuleAnalysisPass(PassRegistry &);
+void initializeSPIRVModuleAnalysisWrapperPassPass(PassRegistry &);
 void initializeSPIRVAsmPrinterPass(PassRegistry &);
 void initializeSPIRVConvergenceRegionAnalysisWrapperPassPass(PassRegistry &);
 void initializeSPIRVPreLegalizerLegacyPass(PassRegistry &);

diff  --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index 11f8674730a2e..685a4f553ca2a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -74,7 +74,11 @@ class SPIRVAsmPrinter : public AsmPrinter {
   explicit SPIRVAsmPrinter(TargetMachine &TM,
                            std::unique_ptr<MCStreamer> Streamer)
       : AsmPrinter(TM, std::move(Streamer), ID), ModuleSectionsEmitted(false),
-        ST(nullptr), TII(nullptr), MAI(nullptr) {}
+        ST(nullptr), TII(nullptr), MAI(nullptr) {
+    GetMAI = [this] {
+      return &getAnalysis<SPIRVModuleAnalysisWrapperPass>().MAI;
+    };
+  }
   static char ID;
   bool ModuleSectionsEmitted;
   const SPIRVSubtarget *ST;
@@ -129,6 +133,7 @@ class SPIRVAsmPrinter : public AsmPrinter {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override;
   SPIRV::ModuleAnalysisInfo *MAI;
+  std::function<SPIRV::ModuleAnalysisInfo *()> GetMAI;
 
   // Non-owning pointer to the NSDI handler registered via addAsmPrinterHandler.
   // The handler's lifetime is managed by AsmPrinter (the base class of this
@@ -143,8 +148,8 @@ class SPIRVAsmPrinter : public AsmPrinter {
 } // namespace
 
 void SPIRVAsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
-  AU.addRequired<SPIRVModuleAnalysis>();
-  AU.addPreserved<SPIRVModuleAnalysis>();
+  AU.addRequired<SPIRVModuleAnalysisWrapperPass>();
+  AU.addPreserved<SPIRVModuleAnalysisWrapperPass>();
   AsmPrinter::getAnalysisUsage(AU);
 }
 
@@ -890,7 +895,7 @@ void SPIRVAsmPrinter::outputModuleSections() {
   // Get the global subtarget to output module-level info.
   ST = static_cast<const SPIRVTargetMachine &>(TM).getSubtargetImpl();
   TII = ST->getInstrInfo();
-  MAI = &getAnalysis<SPIRVModuleAnalysis>().MAI;
+  MAI = GetMAI();
   assert(ST && TII && MAI && M && "Module analysis is required");
 
   if (!AuxDataHandler) {
@@ -998,6 +1003,10 @@ SPIRVAsmPrinterPass::run(MachineFunction &MF,
           .getCachedResult<AsmPrinterAnalysis>(*MF.getFunction().getParent())
           ->getPrinter());
   setupMachineFunctionAsmPrinter(MFAM, MF, AsmPrinter);
+  AsmPrinter.GetMAI = [&MFAM, &MF] {
+    return MFAM.getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF)
+        .getCachedResult<SPIRVModuleAnalysis>(*MF.getFunction().getParent());
+  };
   AsmPrinter.runOnMachineFunction(MF);
   return PreservedAnalyses::all();
 }
@@ -1007,6 +1016,9 @@ PreservedAnalyses SPIRVAsmPrinterEndPass::run(Module &M,
   SPIRVAsmPrinter &AsmPrinter = static_cast<SPIRVAsmPrinter &>(
       MAM.getResult<AsmPrinterAnalysis>(M).getPrinter());
   setupModuleAsmPrinter(M, MAM, AsmPrinter);
+  AsmPrinter.GetMAI = [&MAM, &M] {
+    return MAM.getCachedResult<SPIRVModuleAnalysis>(M);
+  };
   AsmPrinter.doFinalization(M);
   return PreservedAnalyses::all();
 }

diff  --git a/llvm/lib/Target/SPIRV/SPIRVCodeGenPassBuilder.cpp b/llvm/lib/Target/SPIRV/SPIRVCodeGenPassBuilder.cpp
index 4feb8ee2a4699..6481a20217342 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCodeGenPassBuilder.cpp
@@ -9,6 +9,7 @@
 #include "Analysis/SPIRVConvergenceRegionAnalysis.h"
 #include "SPIRV.h"
 #include "SPIRVAsmPrinter.h"
+#include "SPIRVModuleAnalysis.h"
 #include "SPIRVTargetMachine.h"
 #include "llvm/CodeGen/AtomicExpand.h"
 #include "llvm/CodeGen/BranchFoldingPass.h"
@@ -193,6 +194,12 @@ void SPIRVCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
 }
 
 void SPIRVCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
+  // SPIRVModuleAnalysis needs every MachineFunction before printing starts.
+  if (TargetPassConfig::willCompleteCodeGenPipeline()) {
+    flushFPMsToMPM(PMW);
+    addModulePass(RequireAnalysisPass<SPIRVModuleAnalysis, Module>(), PMW,
+                  /*Force=*/true);
+  }
   addMachineFunctionPass(SPIRVAsmPrinterPass(), PMW);
 }
 

diff  --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index bbf457ea78224..0ba4174615b56 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -26,6 +26,7 @@
 #include "SPIRVTargetMachine.h"
 #include "SPIRVUtils.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/MachineFunctionAnalysis.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 
@@ -51,10 +52,10 @@ struct AvoidCapabilitiesSet {
   AvoidCapabilitiesSet() { S.insert_range(AvoidCapabilities); }
 };
 
-char llvm::SPIRVModuleAnalysis::ID = 0;
+char llvm::SPIRVModuleAnalysisWrapperPass::ID = 0;
 
-INITIALIZE_PASS(SPIRVModuleAnalysis, DEBUG_TYPE, "SPIRV module analysis", true,
-                true)
+INITIALIZE_PASS(SPIRVModuleAnalysisWrapperPass, DEBUG_TYPE,
+                "SPIRV module analysis", true, true)
 
 static void reportUnsupported(const MachineInstr &MI, const char *Msg) {
   const Function &Func = MI.getMF()->getFunction();
@@ -141,7 +142,7 @@ getSymbolicOperandRequirements(SPIRV::OperandCategory::OperandCategory Category,
   return {false, {}, {}, VersionTuple(), VersionTuple()};
 }
 
-void SPIRVModuleAnalysis::setBaseInfo(const Module &M) {
+void SPIRVModuleAnalysisImpl::setBaseInfo(const Module &M) {
   MAI.MaxID = 0;
   for (int i = 0; i < SPIRV::NUM_MODULE_SECTIONS; i++)
     MAI.MS[i].clear();
@@ -348,8 +349,8 @@ static unsigned getInvokeOperandIdx(unsigned Opcode) {
   }
 }
 
-bool SPIRVModuleAnalysis::isDeclSection(const MachineRegisterInfo &MRI,
-                                        const MachineInstr &MI) {
+bool SPIRVModuleAnalysisImpl::isDeclSection(const MachineRegisterInfo &MRI,
+                                            const MachineInstr &MI) {
   unsigned Opcode = MI.getOpcode();
   switch (Opcode) {
   case SPIRV::OpTypeForwardPointer:
@@ -402,7 +403,7 @@ bool SPIRVModuleAnalysis::isDeclSection(const MachineRegisterInfo &MRI,
 // FunPtrOp is the MachineOperand previously recorded via
 // SPIRVGlobalRegistry::recordFunctionPointer, identifying which Function
 // this placeholder refers to.
-void SPIRVModuleAnalysis::visitFunPtrUse(
+void SPIRVModuleAnalysisImpl::visitFunPtrUse(
     Register OpReg, const MachineOperand *FunPtrOp,
     InstrGRegsMap &SignatureToGReg,
     std::map<const Value *, unsigned> &GlobalToGReg,
@@ -429,7 +430,7 @@ void SPIRVModuleAnalysis::visitFunPtrUse(
 
 // Depth first recursive traversal of dependencies. Repeated visits are guarded
 // by MAI.hasRegisterAlias().
-void SPIRVModuleAnalysis::visitDecl(
+void SPIRVModuleAnalysisImpl::visitDecl(
     const MachineRegisterInfo &MRI, InstrGRegsMap &SignatureToGReg,
     std::map<const Value *, unsigned> &GlobalToGReg, const MachineFunction *MF,
     const MachineInstr &MI) {
@@ -511,7 +512,7 @@ void SPIRVModuleAnalysis::visitDecl(
     MAI.setSkipEmission(&MI);
 }
 
-MCRegister SPIRVModuleAnalysis::handleFunctionOrParameter(
+MCRegister SPIRVModuleAnalysisImpl::handleFunctionOrParameter(
     const MachineFunction *MF, const MachineInstr &MI,
     std::map<const Value *, unsigned> &GlobalToGReg, bool &IsFunDef) {
   const Value *GObj = GR->getGlobalObject(MF, MI.getOperand(0).getReg());
@@ -531,9 +532,8 @@ MCRegister SPIRVModuleAnalysis::handleFunctionOrParameter(
   return GReg;
 }
 
-MCRegister
-SPIRVModuleAnalysis::handleTypeDeclOrConstant(const MachineInstr &MI,
-                                              InstrGRegsMap &SignatureToGReg) {
+MCRegister SPIRVModuleAnalysisImpl::handleTypeDeclOrConstant(
+    const MachineInstr &MI, InstrGRegsMap &SignatureToGReg) {
   InstrSignature MISign = instrToSignature(MI, MAI, false);
   auto [It, Inserted] = SignatureToGReg.try_emplace(MISign);
   if (!Inserted)
@@ -544,7 +544,7 @@ SPIRVModuleAnalysis::handleTypeDeclOrConstant(const MachineInstr &MI,
   return GReg;
 }
 
-MCRegister SPIRVModuleAnalysis::handleVariable(
+MCRegister SPIRVModuleAnalysisImpl::handleVariable(
     const MachineFunction *MF, const MachineInstr &MI,
     std::map<const Value *, unsigned> &GlobalToGReg) {
   MAI.GlobalVarList.push_back(&MI);
@@ -561,11 +561,11 @@ MCRegister SPIRVModuleAnalysis::handleVariable(
   return GReg;
 }
 
-void SPIRVModuleAnalysis::collectDeclarations(const Module &M) {
+void SPIRVModuleAnalysisImpl::collectDeclarations(const Module &M) {
   InstrGRegsMap SignatureToGReg;
   std::map<const Value *, unsigned> GlobalToGReg;
   for (const Function &F : M) {
-    MachineFunction *MF = MMI->getMachineFunction(F);
+    MachineFunction *MF = GetMF(F);
     if (!MF)
       continue;
     const MachineRegisterInfo &MRI = MF->getRegInfo();
@@ -633,8 +633,8 @@ void SPIRVModuleAnalysis::collectDeclarations(const Module &M) {
 // to the register defining that variable (which will usually be the result of
 // an OpFunction). This lets us call externally imported functions using
 // the correct ID registers.
-void SPIRVModuleAnalysis::collectFuncNames(MachineInstr &MI,
-                                           const Function *F) {
+void SPIRVModuleAnalysisImpl::collectFuncNames(MachineInstr &MI,
+                                               const Function *F) {
   if (MI.getOpcode() == SPIRV::OpDecorate) {
     // If it's got Import linkage.
     auto Dec = MI.getOperand(1).getImm();
@@ -723,12 +723,12 @@ static void collectOtherInstr(MachineInstr &MI, SPIRV::ModuleAnalysisInfo &MAI,
 
 // Some global instructions make reference to function-local ID regs, so cannot
 // be correctly collected until these registers are globally numbered.
-void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
+void SPIRVModuleAnalysisImpl::processOtherInstrs(const Module &M) {
   InstrTraces IS;
   for (const Function &F : M) {
     if (F.isDeclaration())
       continue;
-    MachineFunction *MF = MMI->getMachineFunction(F);
+    MachineFunction *MF = GetMF(F);
     assert(MF);
 
     for (MachineBasicBlock &MBB : *MF)
@@ -802,11 +802,11 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) {
 // Number registers in all functions globally from 0 onwards and store
 // the result in global register alias table. Some registers are already
 // numbered.
-void SPIRVModuleAnalysis::numberRegistersGlobally(const Module &M) {
+void SPIRVModuleAnalysisImpl::numberRegistersGlobally(const Module &M) {
   for (const Function &F : M) {
     if (F.isDeclaration())
       continue;
-    MachineFunction *MF = MMI->getMachineFunction(F);
+    MachineFunction *MF = GetMF(F);
     assert(MF);
     for (MachineBasicBlock &MBB : *MF) {
       for (MachineInstr &MI : MBB) {
@@ -2680,10 +2680,10 @@ void addInstrRequirements(const MachineInstr &MI,
 }
 
 static void collectReqs(const Module &M, SPIRV::ModuleAnalysisInfo &MAI,
-                        MachineModuleInfo *MMI, const SPIRVSubtarget &ST) {
+                        MachineFunctionGetter GetMF, const SPIRVSubtarget &ST) {
   // Collect requirements for existing instructions.
   for (const Function &F : M) {
-    MachineFunction *MF = MMI->getMachineFunction(F);
+    MachineFunction *MF = GetMF(F);
     if (!MF)
       continue;
     for (const MachineBasicBlock &MBB : *MF)
@@ -2947,11 +2947,12 @@ static void handleMIFlagDecoration(
 
 // Walk all functions and add decorations related to MI flags.
 static void addDecorations(const Module &M, const SPIRVInstrInfo &TII,
-                           MachineModuleInfo *MMI, const SPIRVSubtarget &ST,
+                           MachineFunctionGetter GetMF,
+                           const SPIRVSubtarget &ST,
                            SPIRV::ModuleAnalysisInfo &MAI,
                            const SPIRVGlobalRegistry *GR) {
   for (const Function &F : M) {
-    MachineFunction *MF = MMI->getMachineFunction(F);
+    MachineFunction *MF = GetMF(F);
     if (!MF)
       continue;
 
@@ -2963,10 +2964,10 @@ static void addDecorations(const Module &M, const SPIRVInstrInfo &TII,
 }
 
 static void addMBBNames(const Module &M, const SPIRVInstrInfo &TII,
-                        MachineModuleInfo *MMI, const SPIRVSubtarget &ST,
+                        MachineFunctionGetter GetMF, const SPIRVSubtarget &ST,
                         SPIRV::ModuleAnalysisInfo &MAI) {
   for (const Function &F : M) {
-    MachineFunction *MF = MMI->getMachineFunction(F);
+    MachineFunction *MF = GetMF(F);
     if (!MF)
       continue;
     if (MF->getFunction()
@@ -2989,9 +2990,9 @@ static void addMBBNames(const Module &M, const SPIRVInstrInfo &TII,
 
 // patching Instruction::PHI to SPIRV::OpPhi
 static void patchPhis(const Module &M, SPIRVGlobalRegistry *GR,
-                      const SPIRVInstrInfo &TII, MachineModuleInfo *MMI) {
+                      const SPIRVInstrInfo &TII, MachineFunctionGetter GetMF) {
   for (const Function &F : M) {
-    MachineFunction *MF = MMI->getMachineFunction(F);
+    MachineFunction *MF = GetMF(F);
     if (!MF)
       continue;
     for (auto &MBB : *MF) {
@@ -3113,29 +3114,22 @@ static void collectFPFastMathDefaults(const Module &M,
   }
 }
 
-void SPIRVModuleAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
-  AU.addRequired<TargetPassConfig>();
-  AU.addRequired<MachineModuleInfoWrapperPass>();
-}
-
-bool SPIRVModuleAnalysis::runOnModule(Module &M) {
-  SPIRVTargetMachine &TM =
-      getAnalysis<TargetPassConfig>().getTM<SPIRVTargetMachine>();
-  ST = TM.getSubtargetImpl();
-  GR = ST->getSPIRVGlobalRegistry();
-  TII = ST->getInstrInfo();
-
-  MMI = &getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
+SPIRVModuleAnalysisImpl::SPIRVModuleAnalysisImpl(const SPIRVSubtarget &ST,
+                                                 SPIRV::ModuleAnalysisInfo &MAI,
+                                                 MachineFunctionGetter GetMF)
+    : ST(&ST), GR(ST.getSPIRVGlobalRegistry()), TII(ST.getInstrInfo()),
+      MAI(MAI), GetMF(GetMF) {}
 
+void SPIRVModuleAnalysisImpl::run(const Module &M) {
   setBaseInfo(M);
 
-  patchPhis(M, GR, *TII, MMI);
+  patchPhis(M, GR, *TII, GetMF);
 
-  addMBBNames(M, *TII, MMI, *ST, MAI);
+  addMBBNames(M, *TII, GetMF, *ST, MAI);
   collectFPFastMathDefaults(M, MAI, *ST);
-  addDecorations(M, *TII, MMI, *ST, MAI, GR);
+  addDecorations(M, *TII, GetMF, *ST, MAI, GR);
 
-  collectReqs(M, MAI, MMI, *ST);
+  collectReqs(M, MAI, GetMF, *ST);
 
   // Process type/const/global var/func decl instructions, number their
   // destination registers from 0 to N, collect Extensions and Capabilities.
@@ -3153,6 +3147,42 @@ bool SPIRVModuleAnalysis::runOnModule(Module &M) {
 
   // Set maximum ID used.
   GR->setBound(MAI.MaxID);
+}
 
+void SPIRVModuleAnalysisWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired<TargetPassConfig>();
+  AU.addRequired<MachineModuleInfoWrapperPass>();
+}
+
+bool SPIRVModuleAnalysisWrapperPass::runOnModule(Module &M) {
+  SPIRVTargetMachine &TM =
+      getAnalysis<TargetPassConfig>().getTM<SPIRVTargetMachine>();
+  MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI();
+  SPIRVModuleAnalysisImpl(
+      *TM.getSubtargetImpl(), MAI,
+      [&MMI](const Function &F) { return MMI.getMachineFunction(F); })
+      .run(M);
   return false;
 }
+
+AnalysisKey SPIRVModuleAnalysis::Key;
+
+SPIRVModuleAnalysis::Result
+SPIRVModuleAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
+  const auto &TM = static_cast<const SPIRVTargetMachine &>(
+      MAM.getResult<MachineModuleAnalysis>(M).getMMI().getTarget());
+  FunctionAnalysisManager &FAM =
+      MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+  Result MAI;
+  SPIRVModuleAnalysisImpl(*TM.getSubtargetImpl(), MAI,
+                          [&FAM](const Function &F) -> MachineFunction * {
+                            MachineFunctionAnalysis::Result *MFA =
+                                FAM.getCachedResult<MachineFunctionAnalysis>(
+                                    const_cast<Function &>(F));
+                            assert((MFA || F.isDeclaration()) &&
+                                   "Missing MachineFunction for definition");
+                            return MFA ? &MFA->getMF() : nullptr;
+                          })
+      .run(M);
+  return MAI;
+}

diff  --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
index 6559b5cfc7457..6f939894337b0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
@@ -20,11 +20,11 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/PassManager.h"
 
 namespace llvm {
 class SPIRVSubtarget;
 class MachineFunction;
-class MachineModuleInfo;
 
 namespace SPIRV {
 // The enum contains logical module sections for the instruction collection.
@@ -211,23 +211,26 @@ struct ModuleAnalysisInfo {
       It->second = getNextIDRegister();
     return It->second;
   }
+  // Must stay alive until the AsmPrinter consumes it.
+  bool invalidate(Module &, const PreservedAnalyses &,
+                  ModuleAnalysisManager::Invalidator &) {
+    return false;
+  }
 };
 } // namespace SPIRV
 
 using InstrSignature = SmallVector<size_t>;
 using InstrTraces = std::set<InstrSignature>;
 using InstrGRegsMap = std::map<SmallVector<size_t>, unsigned>;
+using MachineFunctionGetter = function_ref<MachineFunction *(const Function &)>;
 
-struct SPIRVModuleAnalysis : public ModulePass {
-  static char ID;
-
+class SPIRVModuleAnalysisImpl {
 public:
-  SPIRVModuleAnalysis()
-      : ModulePass(ID), ST(nullptr), GR(nullptr), TII(nullptr), MMI(nullptr) {}
+  SPIRVModuleAnalysisImpl(const SPIRVSubtarget &ST,
+                          SPIRV::ModuleAnalysisInfo &MAI,
+                          MachineFunctionGetter GetMF);
 
-  bool runOnModule(Module &M) override;
-  void getAnalysisUsage(AnalysisUsage &AU) const override;
-  SPIRV::ModuleAnalysisInfo MAI;
+  void run(const Module &M);
 
 private:
   void setBaseInfo(const Module &M);
@@ -257,7 +260,29 @@ struct SPIRVModuleAnalysis : public ModulePass {
   const SPIRVSubtarget *ST;
   SPIRVGlobalRegistry *GR;
   const SPIRVInstrInfo *TII;
-  MachineModuleInfo *MMI;
+  SPIRV::ModuleAnalysisInfo &MAI;
+  MachineFunctionGetter GetMF;
+};
+
+struct SPIRVModuleAnalysisWrapperPass : public ModulePass {
+  static char ID;
+
+public:
+  SPIRVModuleAnalysisWrapperPass() : ModulePass(ID) {}
+
+  bool runOnModule(Module &M) override;
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+  SPIRV::ModuleAnalysisInfo MAI;
+};
+
+class SPIRVModuleAnalysis : public AnalysisInfoMixin<SPIRVModuleAnalysis> {
+  friend AnalysisInfoMixin<SPIRVModuleAnalysis>;
+  static AnalysisKey Key;
+
+public:
+  using Result = SPIRV::ModuleAnalysisInfo;
+
+  Result run(Module &M, ModuleAnalysisManager &MAM);
 };
 } // namespace llvm
 #endif // LLVM_LIB_TARGET_SPIRV_SPIRVMODULEANALYSIS_H

diff  --git a/llvm/lib/Target/SPIRV/SPIRVPassRegistry.def b/llvm/lib/Target/SPIRV/SPIRVPassRegistry.def
index 4cd3a94b017b4..6236c03f5cbef 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPassRegistry.def
+++ b/llvm/lib/Target/SPIRV/SPIRVPassRegistry.def
@@ -13,6 +13,12 @@
 
 // NOTE: NO INCLUDE GUARD DESIRED!
 
+#ifndef MODULE_ANALYSIS
+#define MODULE_ANALYSIS(NAME, CREATE_PASS)
+#endif
+MODULE_ANALYSIS("spirv-module-analysis", SPIRVModuleAnalysis())
+#undef MODULE_ANALYSIS
+
 #ifndef MODULE_PASS
 #define MODULE_PASS(NAME, CREATE_PASS)
 #endif

diff  --git a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
index 7df3f9881fe73..ddf9889c5c521 100644
--- a/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVTargetMachine.cpp
@@ -46,7 +46,7 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTarget() {
 
   PassRegistry &PR = *PassRegistry::getPassRegistry();
   initializeGlobalISel(PR);
-  initializeSPIRVModuleAnalysisPass(PR);
+  initializeSPIRVModuleAnalysisWrapperPassPass(PR);
   initializeSPIRVAsmPrinterPass(PR);
   initializeSPIRVConvergenceRegionAnalysisWrapperPassPass(PR);
   initializeSPIRVStructurizerPass(PR);

diff  --git a/llvm/test/CodeGen/SPIRV/llc-pipeline.ll b/llvm/test/CodeGen/SPIRV/llc-pipeline.ll
index 406641b2aa753..2aa5a18fdab94 100644
--- a/llvm/test/CodeGen/SPIRV/llc-pipeline.ll
+++ b/llvm/test/CodeGen/SPIRV/llc-pipeline.ll
@@ -7,9 +7,9 @@
 ; RUN:   | FileCheck -match-full-lines -strict-whitespace -check-prefix=SPIRV-Opt %s
 ; RUN:llc -O3 -mtriple=spirv-- -disable-verify -debug-pass=Structure < %s 2>&1 \
 ; RUN:   | FileCheck -match-full-lines -strict-whitespace -check-prefix=SPIRV-Opt %s
-; RUN:llc -O0 -mtriple=spirv-- -enable-new-pm -stop-before=spirv-asm-printer < %s \
+; RUN:llc -O0 -mtriple=spirv-- -enable-new-pm < %s \
 ; RUN:   | FileCheck -check-prefix=SPIRV-NPM %s
-; RUN:llc -O3 -mtriple=spirv-- -enable-new-pm -stop-before=spirv-asm-printer < %s \
+; RUN:llc -O3 -mtriple=spirv-- -enable-new-pm < %s \
 ; RUN:   | FileCheck -check-prefix=SPIRV-NPM %s
 ; REQUIRES:asserts
 
@@ -230,13 +230,12 @@
 ; SPIRV-Opt-NEXT:      SPIRV Assembly Printer
 ; SPIRV-Opt-NEXT:      Free MachineFunction
 
-; SPIR-V NewPM skips RegBankSelect, so instruction selection must not require it.
-; SPIRV-NPM:legalized:       true
-; SPIRV-NPM-NEXT:regBankSelected: false
-; SPIRV-NPM-NEXT:selected:        true
-; SPIRV-NPM:%[[#VOID:]]:type = OpTypeVoid
-; SPIRV-NPM:%[[#]]:iid = OpFunction %[[#VOID]], 0, %[[#]]
+; SPIRV-NPM:OpCapability Linkage
+; SPIRV-NPM:OpName %[[#FN:]] "empty"
+; SPIRV-NPM:%[[#VOID:]] = OpTypeVoid
+; SPIRV-NPM:%[[#FN]] = OpFunction %[[#VOID]] None %[[#]]
 ; SPIRV-NPM:OpReturn
+; SPIRV-NPM:OpFunctionEnd
 
 define void @empty() {
   ret void


        


More information about the llvm-commits mailing list