[llvm] [Codegen][NewPM] Explicitly Nest Passes in CodegenPassBuilder (PR #169867)

Aiden Grossman via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 16 00:27:06 PST 2025


https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/169867

>From 14d1f7c2c0b5743860c5e0d512f11b18ada86e6c Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Fri, 28 Nov 2025 03:18:14 +0000
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.7
---
 llvm/include/llvm/Passes/CodeGenPassBuilder.h | 635 ++++++++----------
 .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 286 ++++----
 llvm/lib/Target/AMDGPU/R600TargetMachine.cpp  |  12 +-
 llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp |  14 +-
 4 files changed, 452 insertions(+), 495 deletions(-)

diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 03777c7fcb45f..9e9a3d0104bfa 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -108,6 +108,7 @@
 #include "llvm/IRPrinter/IRPrintingPasses.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Pass.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Error.h"
@@ -189,6 +190,12 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
       Opt.OptimizeRegAlloc = getOptLevel() != CodeGenOptLevel::None;
   }
 
+  ~CodeGenPassBuilder() {
+    assert(FPM.isEmpty() && MFPM.isEmpty() &&
+           "There are passes that have not been flushed from the function "
+           "pipelines.");
+  }
+
   Error buildPipeline(ModulePassManager &MPM, raw_pwrite_stream &Out,
                       raw_pwrite_stream *DwoOut,
                       CodeGenFileType FileType) const;
@@ -211,147 +218,72 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
       std::declval<MachineFunction &>(),
       std::declval<MachineFunctionAnalysisManager &>()));
 
-  // Function object to maintain state while adding codegen IR passes.
-  // TODO: add a Function -> MachineFunction adaptor and merge
-  // AddIRPass/AddMachinePass so we can have a function pipeline that runs both
-  // function passes and machine function passes.
-  class AddIRPass {
-  public:
-    AddIRPass(ModulePassManager &MPM, const DerivedT &PB) : MPM(MPM), PB(PB) {}
-    ~AddIRPass() { flushFPMToMPM(); }
-
-    template <typename PassT>
-    void operator()(PassT &&Pass, bool Force = false,
-                    StringRef Name = PassT::name()) {
-      static_assert((is_detected<is_function_pass_t, PassT>::value ||
-                     is_detected<is_module_pass_t, PassT>::value) &&
-                    "Only module pass and function pass are supported.");
-      if (!Force && !PB.runBeforeAdding(Name))
-        return;
-
-      // Add Function Pass
-      if constexpr (is_detected<is_function_pass_t, PassT>::value) {
-        FPM.addPass(std::forward<PassT>(Pass));
-      } else {
-        // Add Module Pass
-        flushFPMToMPM();
-        MPM.addPass(std::forward<PassT>(Pass));
-      }
-    }
-
-    /// Setting this will add passes to the CGSCC pass manager.
-    void requireCGSCCOrder() {
-      if (PB.AddInCGSCCOrder)
-        return;
-      flushFPMToMPM();
-      PB.AddInCGSCCOrder = true;
-    }
-
-    /// Stop adding passes to the CGSCC pass manager.
-    /// Existing passes won't be removed.
-    void stopAddingInCGSCCOrder() {
-      if (!PB.AddInCGSCCOrder)
-        return;
-      flushFPMToMPM();
-      PB.AddInCGSCCOrder = false;
-    }
+  template <typename PassT>
+  void addFunctionPass(PassT &&Pass, bool Force = false,
+                       StringRef Name = PassT::name()) const {
+    static_assert(is_detected<is_function_pass_t, PassT>::value &&
+                  "Only function passes are supported.");
+    if (!Force && !runBeforeAdding(Name))
+      return;
+    FPM.addPass(std::forward<PassT>(Pass));
+  }
 
-  private:
-    void flushFPMToMPM() {
-      if (FPM.isEmpty())
-        return;
-      if (PB.AddInCGSCCOrder) {
-        MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
-            createCGSCCToFunctionPassAdaptor(std::move(FPM))));
-      } else {
-        MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
-      }
-      FPM = FunctionPassManager();
-    }
-    ModulePassManager &MPM;
-    FunctionPassManager FPM;
-    const DerivedT &PB;
-  };
+  template <typename PassT>
+  void addModulePass(PassT &&Pass, ModulePassManager &MPM, bool Force = false,
+                     StringRef Name = PassT::name()) const {
+    static_assert(is_detected<is_module_pass_t, PassT>::value &&
+                  "Only module passes are suported.");
+    assert(FPM.isEmpty() && MFPM.isEmpty() &&
+           "You cannot insert a module pass without first flushing the current "
+           "function pipelines to the module pipeline.");
+    if (!Force && !runBeforeAdding(Name))
+      return;
+    MPM.addPass(std::forward<PassT>(Pass));
+  }
 
-  // Function object to maintain state while adding codegen machine passes.
-  class AddMachinePass {
-  public:
-    AddMachinePass(ModulePassManager &MPM, const DerivedT &PB)
-        : MPM(MPM), PB(PB) {}
-    ~AddMachinePass() {
-      if (MFPM.isEmpty())
-        return;
+  template <typename PassT>
+  void addMachineFunctionPass(PassT &&Pass, bool Force = false,
+                              StringRef Name = PassT::name()) const {
+    static_assert(is_detected<is_machine_function_pass_t, PassT>::value &&
+                  "Only machine function passes are supported.");
+
+    if (!Force && !runBeforeAdding(Name))
+      return;
+    MFPM.addPass(std::forward<PassT>(Pass));
+    for (auto &C : AfterCallbacks)
+      C(Name, MFPM);
+  }
 
-      FunctionPassManager FPM;
+  void flushFPMsToMPM(ModulePassManager &MPM,
+                      bool FreeMachineFunctions = false) const {
+    if (FPM.isEmpty() && MFPM.isEmpty())
+      return;
+    if (!MFPM.isEmpty()) {
       FPM.addPass(createFunctionToMachineFunctionPassAdaptor(std::move(MFPM)));
-      FPM.addPass(FreeMachineFunctionPass());
-      if (this->PB.AddInCGSCCOrder) {
-        MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
-            createCGSCCToFunctionPassAdaptor(std::move(FPM))));
-      } else
-        MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
-    }
-
-    template <typename PassT>
-    void operator()(PassT &&Pass, bool Force = false,
-                    StringRef Name = PassT::name()) {
-      static_assert((is_detected<is_machine_function_pass_t, PassT>::value ||
-                     is_detected<is_module_pass_t, PassT>::value) &&
-                    "Only module pass and function pass are supported.");
-
-      if (!Force && !PB.runBeforeAdding(Name))
-        return;
-
-      // Add Function Pass
-      if constexpr (is_detected<is_machine_function_pass_t, PassT>::value) {
-        MFPM.addPass(std::forward<PassT>(Pass));
-      } else {
-        // Add Module Pass
-        flushMFPMToMPM();
-        MPM.addPass(std::forward<PassT>(Pass));
-      }
-
-      for (auto &C : PB.AfterCallbacks)
-        C(Name, MFPM);
-    }
-
-    /// Setting this will add passes to the CGSCC pass manager.
-    void requireCGSCCOrder() {
-      if (PB.AddInCGSCCOrder)
-        return;
-      flushMFPMToMPM();
-      PB.AddInCGSCCOrder = true;
+      MFPM = MachineFunctionPassManager();
     }
-
-    /// Stop adding passes to the CGSCC pass manager.
-    /// Existing passes won't be removed.
-    void stopAddingInCGSCCOrder() {
-      if (!PB.AddInCGSCCOrder)
-        return;
-      flushMFPMToMPM();
-      PB.AddInCGSCCOrder = false;
+    if (FreeMachineFunctions)
+      FPM.addPass(FreeMachineFunctionPass());
+    if (AddInCGSCCOrder) {
+      MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
+          createCGSCCToFunctionPassAdaptor(std::move(FPM))));
+    } else {
+      MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
     }
+    FPM = FunctionPassManager();
+  }
 
-  private:
-    void flushMFPMToMPM() {
-      if (MFPM.isEmpty())
-        return;
-
-      if (PB.AddInCGSCCOrder) {
-        MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
-            createCGSCCToFunctionPassAdaptor(
-                createFunctionToMachineFunctionPassAdaptor(std::move(MFPM)))));
-      } else {
-        MPM.addPass(createModuleToFunctionPassAdaptor(
-            createFunctionToMachineFunctionPassAdaptor(std::move(MFPM))));
-      }
-      MFPM = MachineFunctionPassManager();
-    }
+  void requireCGSCCOrder(ModulePassManager &MPM) const {
+    assert(!AddInCGSCCOrder);
+    flushFPMsToMPM(MPM);
+    AddInCGSCCOrder = true;
+  }
 
-    ModulePassManager &MPM;
-    MachineFunctionPassManager MFPM;
-    const DerivedT &PB;
-  };
+  void stopAddingInCGSCCOrder(ModulePassManager &MPM) const {
+    assert(AddInCGSCCOrder);
+    flushFPMsToMPM(MPM);
+    AddInCGSCCOrder = false;
+  }
 
   TargetMachineT &TM;
   CGPassBuilderOption Opt;
@@ -376,13 +308,13 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   /// addInstSelector - This method should install an instruction selector pass,
   /// which converts from LLVM code to machine instructions.
-  Error addInstSelector(AddMachinePass &) const {
+  Error addInstSelector(ModulePassManager &MPM) const {
     return make_error<StringError>("addInstSelector is not overridden",
                                    inconvertibleErrorCode());
   }
 
   /// Target can override this to add GlobalMergePass before all IR passes.
-  void addGlobalMergePass(AddIRPass &) const {}
+  void addGlobalMergePass(ModulePassManager &MPM) const {}
 
   /// Add passes that optimize instruction level parallelism for out-of-order
   /// targets. These passes are run while the machine code is still in SSA
@@ -390,11 +322,11 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   ///
   /// All passes added here should preserve the MachineDominatorTree,
   /// MachineLoopInfo, and MachineTraceMetrics analyses.
-  void addILPOpts(AddMachinePass &) const {}
+  void addILPOpts(ModulePassManager &MPM) const {}
 
   /// This method may be implemented by targets that want to run passes
   /// immediately before register allocation.
-  void addPreRegAlloc(AddMachinePass &) const {}
+  void addPreRegAlloc(ModulePassManager &MPM) const {}
 
   /// addPreRewrite - Add passes to the optimized register allocation pipeline
   /// after register allocation is complete, but before virtual registers are
@@ -408,79 +340,79 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   /// Note if the target overloads addRegAssignAndRewriteOptimized, this may not
   /// be honored. This is also not generally used for the fast variant,
   /// where the allocation and rewriting are done in one pass.
-  void addPreRewrite(AddMachinePass &) const {}
+  void addPreRewrite(ModulePassManager &MPM) const {}
 
   /// Add passes to be run immediately after virtual registers are rewritten
   /// to physical registers.
-  void addPostRewrite(AddMachinePass &) const {}
+  void addPostRewrite(ModulePassManager &MPM) const {}
 
   /// This method may be implemented by targets that want to run passes after
   /// register allocation pass pipeline but before prolog-epilog insertion.
-  void addPostRegAlloc(AddMachinePass &) const {}
+  void addPostRegAlloc(ModulePassManager &MPM) const {}
 
   /// This method may be implemented by targets that want to run passes after
   /// prolog-epilog insertion and before the second instruction scheduling pass.
-  void addPreSched2(AddMachinePass &) const {}
+  void addPreSched2(ModulePassManager &MPM) const {}
 
   /// This pass may be implemented by targets that want to run passes
   /// immediately before machine code is emitted.
-  void addPreEmitPass(AddMachinePass &) const {}
+  void addPreEmitPass(ModulePassManager &MPM) const {}
 
   /// Targets may add passes immediately before machine code is emitted in this
   /// callback. This is called even later than `addPreEmitPass`.
   // FIXME: Rename `addPreEmitPass` to something more sensible given its actual
   // position and remove the `2` suffix here as this callback is what
   // `addPreEmitPass` *should* be but in reality isn't.
-  void addPreEmitPass2(AddMachinePass &) const {}
+  void addPreEmitPass2(ModulePassManager &MPM) const {}
 
   /// {{@ For GlobalISel
   ///
 
   /// addPreISel - This method should add any "last minute" LLVM->LLVM
   /// passes (which are run just before instruction selector).
-  void addPreISel(AddIRPass &) const {
+  void addPreISel(ModulePassManager &MPM) const {
     llvm_unreachable("addPreISel is not overridden");
   }
 
   /// This method should install an IR translator pass, which converts from
   /// LLVM code to machine instructions with possibly generic opcodes.
-  Error addIRTranslator(AddMachinePass &) const {
+  Error addIRTranslator(ModulePassManager &MPM) const {
     return make_error<StringError>("addIRTranslator is not overridden",
                                    inconvertibleErrorCode());
   }
 
   /// This method may be implemented by targets that want to run passes
   /// immediately before legalization.
-  void addPreLegalizeMachineIR(AddMachinePass &) const {}
+  void addPreLegalizeMachineIR(ModulePassManager &MPM) const {}
 
   /// This method should install a legalize pass, which converts the instruction
   /// sequence into one that can be selected by the target.
-  Error addLegalizeMachineIR(AddMachinePass &) const {
+  Error addLegalizeMachineIR(ModulePassManager &MPM) const {
     return make_error<StringError>("addLegalizeMachineIR is not overridden",
                                    inconvertibleErrorCode());
   }
 
   /// This method may be implemented by targets that want to run passes
   /// immediately before the register bank selection.
-  void addPreRegBankSelect(AddMachinePass &) const {}
+  void addPreRegBankSelect(ModulePassManager &MPM) const {}
 
   /// This method should install a register bank selector pass, which
   /// assigns register banks to virtual registers without a register
   /// class or register banks.
-  Error addRegBankSelect(AddMachinePass &) const {
+  Error addRegBankSelect(ModulePassManager &MPM) const {
     return make_error<StringError>("addRegBankSelect is not overridden",
                                    inconvertibleErrorCode());
   }
 
   /// This method may be implemented by targets that want to run passes
   /// immediately before the (global) instruction selection.
-  void addPreGlobalInstructionSelect(AddMachinePass &) const {}
+  void addPreGlobalInstructionSelect(ModulePassManager &MPM) const {}
 
   /// This method should install a (global) instruction selector pass, which
   /// converts possibly generic instructions to fully target-specific
   /// instructions, thereby constraining all generic virtual registers to
   /// register classes.
-  Error addGlobalInstructionSelect(AddMachinePass &) const {
+  Error addGlobalInstructionSelect(ModulePassManager &MPM) const {
     return make_error<StringError>(
         "addGlobalInstructionSelect is not overridden",
         inconvertibleErrorCode());
@@ -491,30 +423,30 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   /// representation to the MI representation.
   /// Adds IR based lowering and target specific optimization passes and finally
   /// the core instruction selection passes.
-  void addISelPasses(AddIRPass &) const;
+  void addISelPasses(ModulePassManager &MPM) const;
 
   /// Add the actual instruction selection passes. This does not include
   /// preparation passes on IR.
-  Error addCoreISelPasses(AddMachinePass &) const;
+  Error addCoreISelPasses(ModulePassManager &MPM) const;
 
   /// Add the complete, standard set of LLVM CodeGen passes.
   /// Fully developed targets will not generally override this.
-  Error addMachinePasses(AddMachinePass &) const;
+  Error addMachinePasses(ModulePassManager &MPM) const;
 
   /// Add passes to lower exception handling for the code generator.
-  void addPassesToHandleExceptions(AddIRPass &) const;
+  void addPassesToHandleExceptions(ModulePassManager &MPM) const;
 
   /// Add common target configurable passes that perform LLVM IR to IR
   /// transforms following machine independent optimization.
-  void addIRPasses(AddIRPass &) const;
+  void addIRPasses(ModulePassManager &MPM) const;
 
   /// Add pass to prepare the LLVM IR for code generation. This should be done
   /// before exception handling preparation passes.
-  void addCodeGenPrepare(AddIRPass &) const;
+  void addCodeGenPrepare(ModulePassManager &MPM) const;
 
   /// Add common passes that perform LLVM IR to IR transforms in preparation for
   /// instruction selection.
-  void addISelPrepare(AddIRPass &) const;
+  void addISelPrepare(ModulePassManager &MPM) const;
 
   /// Methods with trivial inline returns are convenient points in the common
   /// codegen pass pipeline where targets may insert passes. Methods with
@@ -525,31 +457,31 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   /// addMachineSSAOptimization - Add standard passes that optimize machine
   /// instructions in SSA form.
-  void addMachineSSAOptimization(AddMachinePass &) const;
+  void addMachineSSAOptimization(ModulePassManager &MPM) const;
 
   /// addFastRegAlloc - Add the minimum set of target-independent passes that
   /// are required for fast register allocation.
-  Error addFastRegAlloc(AddMachinePass &) const;
+  Error addFastRegAlloc(ModulePassManager &MPM) const;
 
   /// addOptimizedRegAlloc - Add passes related to register allocation.
   /// CodeGenTargetMachineImpl provides standard regalloc passes for most
   /// targets.
-  void addOptimizedRegAlloc(AddMachinePass &) const;
+  void addOptimizedRegAlloc(ModulePassManager &MPM) const;
 
   /// Add passes that optimize machine instructions after register allocation.
-  void addMachineLateOptimization(AddMachinePass &) const;
+  void addMachineLateOptimization(ModulePassManager &MPM) const;
 
   /// addGCPasses - Add late codegen passes that analyze code for garbage
   /// collection. This should return true if GC info should be printed after
   /// these passes.
-  void addGCPasses(AddMachinePass &) const {}
+  void addGCPasses(ModulePassManager &MPM) const {}
 
   /// Add standard basic block placement passes.
-  void addBlockPlacement(AddMachinePass &) const;
+  void addBlockPlacement(ModulePassManager &MPM) const;
 
   using CreateMCStreamer =
       std::function<Expected<std::unique_ptr<MCStreamer>>(MCContext &)>;
-  void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const {
+  void addAsmPrinter(ModulePassManager &MPM, CreateMCStreamer) const {
     llvm_unreachable("addAsmPrinter is not overridden");
   }
 
@@ -558,16 +490,16 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   /// createTargetRegisterAllocator - Create the register allocator pass for
   /// this target at the current optimization level.
-  void addTargetRegisterAllocator(AddMachinePass &, bool Optimized) const;
+  void addTargetRegisterAllocator(ModulePassManager &MPM, bool Optimized) const;
 
   /// addMachinePasses helper to create the target-selected or overriden
   /// regalloc pass.
-  void addRegAllocPass(AddMachinePass &, bool Optimized) const;
+  void addRegAllocPass(ModulePassManager &MPM, bool Optimized) const;
 
   /// Add core register alloator passes which do the actual register assignment
   /// and rewriting. \returns true if any passes were added.
-  Error addRegAssignmentFast(AddMachinePass &) const;
-  Error addRegAssignmentOptimized(AddMachinePass &) const;
+  Error addRegAssignmentFast(ModulePassManager &MPM) const;
+  Error addRegAssignmentOptimized(ModulePassManager &MPM) const;
 
   /// Allow the target to disable a specific pass by default.
   /// Backend can declare unwanted passes in constructor.
@@ -616,6 +548,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   mutable bool Started = true;
   mutable bool Stopped = true;
   mutable bool AddInCGSCCOrder = false;
+
+  mutable FunctionPassManager FPM;
+  mutable MachineFunctionPassManager MFPM;
 };
 
 template <typename Derived, typename TargetMachineT>
@@ -630,42 +565,40 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
   bool PrintAsm = TargetPassConfig::willCompleteCodeGenPipeline();
   bool PrintMIR = !PrintAsm && FileType != CodeGenFileType::Null;
 
-  {
-    AddIRPass addIRPass(MPM, derived());
-    addIRPass(RequireAnalysisPass<MachineModuleAnalysis, Module>(),
-              /*Force=*/true);
-    addIRPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>(),
-              /*Force=*/true);
-    addIRPass(RequireAnalysisPass<CollectorMetadataAnalysis, Module>(),
-              /*Force=*/true);
-    addIRPass(RequireAnalysisPass<RuntimeLibraryAnalysis, Module>(),
-              /*Force=*/true);
-    addISelPasses(addIRPass);
-  }
-
-  AddMachinePass addPass(MPM, derived());
+  addModulePass(RequireAnalysisPass<MachineModuleAnalysis, Module>(), MPM,
+                /*Force=*/true);
+  addModulePass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>(), MPM,
+                /*Force=*/true);
+  addModulePass(RequireAnalysisPass<CollectorMetadataAnalysis, Module>(), MPM,
+                /*Force=*/true);
+  addModulePass(RequireAnalysisPass<RuntimeLibraryAnalysis, Module>(), MPM,
+                /*Force=*/true);
+  addISelPasses(MPM);
+  flushFPMsToMPM(MPM);
 
   if (PrintMIR)
-    addPass(PrintMIRPreparePass(Out), /*Force=*/true);
+    addModulePass(PrintMIRPreparePass(Out), MPM, /*Force=*/true);
 
-  if (auto Err = addCoreISelPasses(addPass))
+  if (auto Err = addCoreISelPasses(MPM))
     return std::move(Err);
 
-  if (auto Err = derived().addMachinePasses(addPass))
+  if (auto Err = derived().addMachinePasses(MPM))
     return std::move(Err);
 
   if (!Opt.DisableVerify)
-    addPass(MachineVerifierPass());
+    addMachineFunctionPass(MachineVerifierPass());
 
   if (PrintAsm) {
     derived().addAsmPrinter(
-        addPass, [this, &Out, DwoOut, FileType](MCContext &Ctx) {
+        MPM, [this, &Out, DwoOut, FileType](MCContext &Ctx) {
           return this->TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
         });
   }
 
   if (PrintMIR)
-    addPass(PrintMIRPass(Out), /*Force=*/true);
+    addMachineFunctionPass(PrintMIRPass(Out), /*Force=*/true);
+
+  flushFPMsToMPM(MPM, true);
 
   return verifyStartStop(*StartStopInfo);
 }
@@ -732,30 +665,30 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::verifyStartStop(
 
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addISelPasses(
-    AddIRPass &addPass) const {
-  derived().addGlobalMergePass(addPass);
+    ModulePassManager &MPM) const {
+  derived().addGlobalMergePass(MPM);
   if (TM.useEmulatedTLS())
-    addPass(LowerEmuTLSPass());
+    addModulePass(LowerEmuTLSPass(), MPM);
 
-  addPass(PreISelIntrinsicLoweringPass(&TM));
-  addPass(ExpandLargeDivRemPass(TM));
-  addPass(ExpandFpPass(TM, getOptLevel()));
+  addModulePass(PreISelIntrinsicLoweringPass(&TM), MPM);
+  addFunctionPass(ExpandLargeDivRemPass(TM));
+  addFunctionPass(ExpandFpPass(TM, getOptLevel()));
 
-  derived().addIRPasses(addPass);
-  derived().addCodeGenPrepare(addPass);
-  addPassesToHandleExceptions(addPass);
-  derived().addISelPrepare(addPass);
+  derived().addIRPasses(MPM);
+  derived().addCodeGenPrepare(MPM);
+  addPassesToHandleExceptions(MPM);
+  derived().addISelPrepare(MPM);
 }
 
 /// Add common target configurable passes that perform LLVM IR to IR transforms
 /// following machine independent optimization.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addIRPasses(
-    AddIRPass &addPass) const {
+    ModulePassManager &MPM) const {
   // Before running any passes, run the verifier to determine if the input
   // coming from the front-end and/or optimizer is valid.
   if (!Opt.DisableVerify)
-    addPass(VerifierPass(), /*Force=*/true);
+    addFunctionPass(VerifierPass(), /*Force=*/true);
 
   // Run loop strength reduction before anything else.
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableLSR) {
@@ -764,8 +697,8 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addIRPasses(
     LPM.addPass(LoopStrengthReducePass());
     if (Opt.EnableLoopTermFold)
       LPM.addPass(LoopTermFoldPass());
-    addPass(createFunctionToLoopPassAdaptor(std::move(LPM),
-                                            /*UseMemorySSA=*/true));
+    addFunctionPass(createFunctionToLoopPassAdaptor(std::move(LPM),
+                                                    /*UseMemorySSA=*/true));
   }
 
   if (getOptLevel() != CodeGenOptLevel::None) {
@@ -774,57 +707,64 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addIRPasses(
     // into optimally-sized loads and compares. The transforms are enabled by a
     // target lowering hook.
     if (!Opt.DisableMergeICmps)
-      addPass(MergeICmpsPass());
-    addPass(ExpandMemCmpPass(TM));
+      addFunctionPass(MergeICmpsPass());
+    addFunctionPass(ExpandMemCmpPass(TM));
   }
 
   // Run GC lowering passes for builtin collectors
   // TODO: add a pass insertion point here
-  addPass(GCLoweringPass());
-  addPass(ShadowStackGCLoweringPass());
-  addPass(LowerConstantIntrinsicsPass());
+  addFunctionPass(GCLoweringPass());
+  // Explicitly check to see if we should add ShadowStackGCLowering to avoid
+  // splitting the function pipeline if we do not have to.
+  if (runBeforeAdding(ShadowStackGCLoweringPass::name())) {
+    flushFPMsToMPM(MPM);
+    addModulePass(ShadowStackGCLoweringPass(), MPM);
+  }
+  addFunctionPass(LowerConstantIntrinsicsPass());
 
   // Make sure that no unreachable blocks are instruction selected.
-  addPass(UnreachableBlockElimPass());
+  addFunctionPass(UnreachableBlockElimPass());
 
   // Prepare expensive constants for SelectionDAG.
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableConstantHoisting)
-    addPass(ConstantHoistingPass());
+    addFunctionPass(ConstantHoistingPass());
 
   // Replace calls to LLVM intrinsics (e.g., exp, log) operating on vector
   // operands with calls to the corresponding functions in a vector library.
   if (getOptLevel() != CodeGenOptLevel::None)
-    addPass(ReplaceWithVeclib());
+    addFunctionPass(ReplaceWithVeclib());
 
   if (getOptLevel() != CodeGenOptLevel::None &&
       !Opt.DisablePartialLibcallInlining)
-    addPass(PartiallyInlineLibCallsPass());
+    addFunctionPass(PartiallyInlineLibCallsPass());
 
   // Instrument function entry and exit, e.g. with calls to mcount().
-  addPass(EntryExitInstrumenterPass(/*PostInlining=*/true));
+  addFunctionPass(EntryExitInstrumenterPass(/*PostInlining=*/true));
 
   // Add scalarization of target's unsupported masked memory intrinsics pass.
   // the unsupported intrinsic will be replaced with a chain of basic blocks,
   // that stores/loads element one-by-one if the appropriate mask bit is set.
-  addPass(ScalarizeMaskedMemIntrinPass());
+  addFunctionPass(ScalarizeMaskedMemIntrinPass());
 
   // Expand reduction intrinsics into shuffle sequences if the target wants to.
   if (!Opt.DisableExpandReductions)
-    addPass(ExpandReductionsPass());
+    addFunctionPass(ExpandReductionsPass());
 
   // Convert conditional moves to conditional jumps when profitable.
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableSelectOptimize)
-    addPass(SelectOptimizePass(TM));
+    addFunctionPass(SelectOptimizePass(TM));
 
-  if (Opt.EnableGlobalMergeFunc)
-    addPass(GlobalMergeFuncPass());
+  if (Opt.EnableGlobalMergeFunc) {
+    flushFPMsToMPM(MPM);
+    addModulePass(GlobalMergeFuncPass(), MPM);
+  }
 }
 
 /// Turn exception handling constructs into something the code generators can
 /// handle.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addPassesToHandleExceptions(
-    AddIRPass &addPass) const {
+    ModulePassManager &MPM) const {
   const MCAsmInfo *MCAI = TM.getMCAsmInfo();
   assert(MCAI && "No MCAsmInfo");
   switch (MCAI->getExceptionHandlingType()) {
@@ -835,34 +775,34 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addPassesToHandleExceptions(
     // removed from the parent invoke(s). This could happen when a landing
     // pad is shared by multiple invokes and is also a target of a normal
     // edge from elsewhere.
-    addPass(SjLjEHPreparePass(&TM));
+    addFunctionPass(SjLjEHPreparePass(&TM));
     [[fallthrough]];
   case ExceptionHandling::DwarfCFI:
   case ExceptionHandling::ARM:
   case ExceptionHandling::AIX:
   case ExceptionHandling::ZOS:
-    addPass(DwarfEHPreparePass(TM));
+    addFunctionPass(DwarfEHPreparePass(TM));
     break;
   case ExceptionHandling::WinEH:
     // We support using both GCC-style and MSVC-style exceptions on Windows, so
     // add both preparation passes. Each pass will only actually run if it
     // recognizes the personality function.
-    addPass(WinEHPreparePass());
-    addPass(DwarfEHPreparePass(TM));
+    addFunctionPass(WinEHPreparePass());
+    addFunctionPass(DwarfEHPreparePass(TM));
     break;
   case ExceptionHandling::Wasm:
     // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs
     // on catchpads and cleanuppads because it does not outline them into
     // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
     // should remove PHIs there.
-    addPass(WinEHPreparePass(/*DemoteCatchSwitchPHIOnly=*/false));
-    addPass(WasmEHPreparePass());
+    addFunctionPass(WinEHPreparePass(/*DemoteCatchSwitchPHIOnly=*/false));
+    addFunctionPass(WasmEHPreparePass());
     break;
   case ExceptionHandling::None:
-    addPass(LowerInvokePass());
+    addFunctionPass(LowerInvokePass());
 
     // The lower invoke pass may create unreachable code. Remove it.
-    addPass(UnreachableBlockElimPass());
+    addFunctionPass(UnreachableBlockElimPass());
     break;
   }
 }
@@ -871,9 +811,9 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addPassesToHandleExceptions(
 /// before exception handling preparation passes.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addCodeGenPrepare(
-    AddIRPass &addPass) const {
+    ModulePassManager &MPM) const {
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableCGP)
-    addPass(CodeGenPreparePass(TM));
+    addFunctionPass(CodeGenPreparePass(TM));
   // TODO: Default ctor'd RewriteSymbolPass is no-op.
   // addPass(RewriteSymbolPass());
 }
@@ -882,34 +822,34 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addCodeGenPrepare(
 /// instruction selection.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addISelPrepare(
-    AddIRPass &addPass) const {
-  derived().addPreISel(addPass);
+    ModulePassManager &MPM) const {
+  derived().addPreISel(MPM);
 
-  if (Opt.RequiresCodeGenSCCOrder)
-    addPass.requireCGSCCOrder();
+  if (Opt.RequiresCodeGenSCCOrder && !AddInCGSCCOrder)
+    requireCGSCCOrder(MPM);
 
   if (getOptLevel() != CodeGenOptLevel::None)
-    addPass(ObjCARCContractPass());
+    addFunctionPass(ObjCARCContractPass());
 
-  addPass(CallBrPreparePass());
+  addFunctionPass(CallBrPreparePass());
   // Add both the safe stack and the stack protection passes: each of them will
   // only protect functions that have corresponding attributes.
-  addPass(SafeStackPass(TM));
-  addPass(StackProtectorPass(TM));
+  addFunctionPass(SafeStackPass(TM));
+  addFunctionPass(StackProtectorPass(TM));
 
   if (Opt.PrintISelInput)
-    addPass(PrintFunctionPass(dbgs(),
-                              "\n\n*** Final LLVM Code input to ISel ***\n"));
+    addFunctionPass(PrintFunctionPass(
+        dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"));
 
   // All passes which modify the LLVM IR are now complete; run the verifier
   // to ensure that the IR is valid.
   if (!Opt.DisableVerify)
-    addPass(VerifierPass(), /*Force=*/true);
+    addFunctionPass(VerifierPass(), /*Force=*/true);
 }
 
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addCoreISelPasses(
-    AddMachinePass &addPass) const {
+    ModulePassManager &MPM) const {
   // Enable FastISel with -fast-isel, but allow that to be overridden.
   TM.setO0WantsFastISel(Opt.EnableFastISelOption.value_or(true));
 
@@ -941,42 +881,42 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addCoreISelPasses(
 
   // Add instruction selector passes.
   if (Selector == SelectorType::GlobalISel) {
-    if (auto Err = derived().addIRTranslator(addPass))
+    if (auto Err = derived().addIRTranslator(MPM))
       return std::move(Err);
 
-    derived().addPreLegalizeMachineIR(addPass);
+    derived().addPreLegalizeMachineIR(MPM);
 
-    if (auto Err = derived().addLegalizeMachineIR(addPass))
+    if (auto Err = derived().addLegalizeMachineIR(MPM))
       return std::move(Err);
 
     // Before running the register bank selector, ask the target if it
     // wants to run some passes.
-    derived().addPreRegBankSelect(addPass);
+    derived().addPreRegBankSelect(MPM);
 
-    if (auto Err = derived().addRegBankSelect(addPass))
+    if (auto Err = derived().addRegBankSelect(MPM))
       return std::move(Err);
 
-    derived().addPreGlobalInstructionSelect(addPass);
+    derived().addPreGlobalInstructionSelect(MPM);
 
-    if (auto Err = derived().addGlobalInstructionSelect(addPass))
+    if (auto Err = derived().addGlobalInstructionSelect(MPM))
       return std::move(Err);
 
     // Pass to reset the MachineFunction if the ISel failed.
-    addPass(ResetMachineFunctionPass(reportDiagnosticWhenGlobalISelFallback(),
-                                     isGlobalISelAbortEnabled()));
+    addMachineFunctionPass(ResetMachineFunctionPass(
+        reportDiagnosticWhenGlobalISelFallback(), isGlobalISelAbortEnabled()));
 
     // Provide a fallback path when we do not want to abort on
     // not-yet-supported input.
     if (!isGlobalISelAbortEnabled())
-      if (auto Err = derived().addInstSelector(addPass))
+      if (auto Err = derived().addInstSelector(MPM))
         return std::move(Err);
 
-  } else if (auto Err = derived().addInstSelector(addPass))
+  } else if (auto Err = derived().addInstSelector(MPM))
     return std::move(Err);
 
   // Expand pseudo-instructions emitted by ISel. Don't run the verifier before
   // FinalizeISel.
-  addPass(FinalizeISelPass());
+  addMachineFunctionPass(FinalizeISelPass());
 
   // // Print the instruction selected machine code...
   // printAndVerify("After Instruction Selection");
@@ -1002,58 +942,60 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addCoreISelPasses(
 /// instead.
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addMachinePasses(
-    AddMachinePass &addPass) const {
+    ModulePassManager &MPM) const {
   // Add passes that optimize machine instructions in SSA form.
   if (getOptLevel() != CodeGenOptLevel::None) {
-    derived().addMachineSSAOptimization(addPass);
+    derived().addMachineSSAOptimization(MPM);
   } else {
     // If the target requests it, assign local variables to stack slots relative
     // to one another and simplify frame index references where possible.
-    addPass(LocalStackSlotAllocationPass());
+    addMachineFunctionPass(LocalStackSlotAllocationPass());
   }
 
   if (TM.Options.EnableIPRA) {
-    addPass(RequireAnalysisPass<PhysicalRegisterUsageAnalysis, Module>());
-    addPass(RegUsageInfoPropagationPass());
+    flushFPMsToMPM(MPM);
+    addModulePass(RequireAnalysisPass<PhysicalRegisterUsageAnalysis, Module>(),
+                  MPM);
+    addMachineFunctionPass(RegUsageInfoPropagationPass());
   }
   // Run pre-ra passes.
-  derived().addPreRegAlloc(addPass);
+  derived().addPreRegAlloc(MPM);
 
   // Run register allocation and passes that are tightly coupled with it,
   // including phi elimination and scheduling.
   if (*Opt.OptimizeRegAlloc) {
-    derived().addOptimizedRegAlloc(addPass);
+    derived().addOptimizedRegAlloc(MPM);
   } else {
-    if (auto Err = derived().addFastRegAlloc(addPass))
+    if (auto Err = derived().addFastRegAlloc(MPM))
       return Err;
   }
 
   // Run post-ra passes.
-  derived().addPostRegAlloc(addPass);
+  derived().addPostRegAlloc(MPM);
 
-  addPass(RemoveRedundantDebugValuesPass());
-  addPass(FixupStatepointCallerSavedPass());
+  addMachineFunctionPass(RemoveRedundantDebugValuesPass());
+  addMachineFunctionPass(FixupStatepointCallerSavedPass());
 
   // Insert prolog/epilog code.  Eliminate abstract frame index references...
   if (getOptLevel() != CodeGenOptLevel::None) {
-    addPass(PostRAMachineSinkingPass());
-    addPass(ShrinkWrapPass());
+    addMachineFunctionPass(PostRAMachineSinkingPass());
+    addMachineFunctionPass(ShrinkWrapPass());
   }
 
-  addPass(PrologEpilogInserterPass());
+  addMachineFunctionPass(PrologEpilogInserterPass());
 
   /// Add passes that optimize machine instructions after register allocation.
   if (getOptLevel() != CodeGenOptLevel::None)
-    derived().addMachineLateOptimization(addPass);
+    derived().addMachineLateOptimization(MPM);
 
   // Expand pseudo instructions before second scheduling pass.
-  addPass(ExpandPostRAPseudosPass());
+  addMachineFunctionPass(ExpandPostRAPseudosPass());
 
   // Run pre-sched2 passes.
-  derived().addPreSched2(addPass);
+  derived().addPreSched2(MPM);
 
   if (Opt.EnableImplicitNullChecks)
-    addPass(ImplicitNullChecksPass());
+    addMachineFunctionPass(ImplicitNullChecksPass());
 
   // Second pass scheduler.
   // Let Target optionally insert this pass by itself at some other
@@ -1061,51 +1003,53 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addMachinePasses(
   if (getOptLevel() != CodeGenOptLevel::None &&
       !TM.targetSchedulesPostRAScheduling()) {
     if (Opt.MISchedPostRA)
-      addPass(PostMachineSchedulerPass(&TM));
+      addMachineFunctionPass(PostMachineSchedulerPass(&TM));
     else
-      addPass(PostRASchedulerPass(&TM));
+      addMachineFunctionPass(PostRASchedulerPass(&TM));
   }
 
   // GC
-  derived().addGCPasses(addPass);
+  derived().addGCPasses(MPM);
 
   // Basic block placement.
   if (getOptLevel() != CodeGenOptLevel::None)
-    derived().addBlockPlacement(addPass);
+    derived().addBlockPlacement(MPM);
 
   // Insert before XRay Instrumentation.
-  addPass(FEntryInserterPass());
+  addMachineFunctionPass(FEntryInserterPass());
 
-  addPass(XRayInstrumentationPass());
-  addPass(PatchableFunctionPass());
+  addMachineFunctionPass(XRayInstrumentationPass());
+  addMachineFunctionPass(PatchableFunctionPass());
 
-  derived().addPreEmitPass(addPass);
+  derived().addPreEmitPass(MPM);
 
   if (TM.Options.EnableIPRA)
     // Collect register usage information and produce a register mask of
     // clobbered registers, to be used to optimize call sites.
-    addPass(RegUsageInfoCollectorPass());
+    addMachineFunctionPass(RegUsageInfoCollectorPass());
 
-  addPass(FuncletLayoutPass());
+  addMachineFunctionPass(FuncletLayoutPass());
 
-  addPass(RemoveLoadsIntoFakeUsesPass());
-  addPass(StackMapLivenessPass());
-  addPass(LiveDebugValuesPass(
+  addMachineFunctionPass(RemoveLoadsIntoFakeUsesPass());
+  addMachineFunctionPass(StackMapLivenessPass());
+  addMachineFunctionPass(LiveDebugValuesPass(
       getTM<TargetMachine>().Options.ShouldEmitDebugEntryValues()));
-  addPass(MachineSanitizerBinaryMetadataPass());
+  addMachineFunctionPass(MachineSanitizerBinaryMetadataPass());
 
   if (TM.Options.EnableMachineOutliner &&
       getOptLevel() != CodeGenOptLevel::None &&
       Opt.EnableMachineOutliner != RunOutliner::NeverOutline) {
     if (Opt.EnableMachineOutliner != RunOutliner::TargetDefault ||
-        TM.Options.SupportsDefaultOutlining)
-      addPass(MachineOutlinerPass(Opt.EnableMachineOutliner));
+        TM.Options.SupportsDefaultOutlining) {
+      flushFPMsToMPM(MPM);
+      addModulePass(MachineOutlinerPass(Opt.EnableMachineOutliner), MPM);
+    }
   }
 
-  addPass(StackFrameLayoutAnalysisPass());
+  addMachineFunctionPass(StackFrameLayoutAnalysisPass());
 
   // Add passes that directly emit MI after all other MI passes.
-  derived().addPreEmitPass2(addPass);
+  derived().addPreEmitPass2(MPM);
 
   return Error::success();
 }
@@ -1113,42 +1057,42 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addMachinePasses(
 /// Add passes that optimize machine instructions in SSA form.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineSSAOptimization(
-    AddMachinePass &addPass) const {
+    ModulePassManager &MPM) const {
   // Pre-ra tail duplication.
-  addPass(EarlyTailDuplicatePass());
+  addMachineFunctionPass(EarlyTailDuplicatePass());
 
   // Optimize PHIs before DCE: removing dead PHI cycles may make more
   // instructions dead.
-  addPass(OptimizePHIsPass());
+  addMachineFunctionPass(OptimizePHIsPass());
 
   // This pass merges large allocas. StackSlotColoring is a different pass
   // which merges spill slots.
-  addPass(StackColoringPass());
+  addMachineFunctionPass(StackColoringPass());
 
   // If the target requests it, assign local variables to stack slots relative
   // to one another and simplify frame index references where possible.
-  addPass(LocalStackSlotAllocationPass());
+  addMachineFunctionPass(LocalStackSlotAllocationPass());
 
   // With optimization, dead code should already be eliminated. However
   // there is one known exception: lowered code for arguments that are only
   // used by tail calls, where the tail calls reuse the incoming stack
   // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
-  addPass(DeadMachineInstructionElimPass());
+  addMachineFunctionPass(DeadMachineInstructionElimPass());
 
   // Allow targets to insert passes that improve instruction level parallelism,
   // like if-conversion. Such passes will typically need dominator trees and
   // loop info, just like LICM and CSE below.
-  derived().addILPOpts(addPass);
+  derived().addILPOpts(MPM);
 
-  addPass(EarlyMachineLICMPass());
-  addPass(MachineCSEPass());
+  addMachineFunctionPass(EarlyMachineLICMPass());
+  addMachineFunctionPass(MachineCSEPass());
 
-  addPass(MachineSinkingPass(Opt.EnableSinkAndFold));
+  addMachineFunctionPass(MachineSinkingPass(Opt.EnableSinkAndFold));
 
-  addPass(PeepholeOptimizerPass());
+  addMachineFunctionPass(PeepholeOptimizerPass());
   // Clean-up the dead code that may have been generated by peephole
   // rewriting.
-  addPass(DeadMachineInstructionElimPass());
+  addMachineFunctionPass(DeadMachineInstructionElimPass());
 }
 
 //===---------------------------------------------------------------------===//
@@ -1167,11 +1111,11 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineSSAOptimization(
 /// check if Opt.RegAlloc == RegAllocType::Unset.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
-    AddMachinePass &addPass, bool Optimized) const {
+    ModulePassManager &MPM, bool Optimized) const {
   if (Optimized)
-    addPass(RAGreedyPass());
+    addMachineFunctionPass(RAGreedyPass());
   else
-    addPass(RegAllocFastPass());
+    addMachineFunctionPass(RegAllocFastPass());
 }
 
 /// Find and instantiate the register allocation pass requested by this target
@@ -1182,15 +1126,15 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
 /// even for targets that override the default allocator.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
-    AddMachinePass &addPass, bool Optimized) const {
+    ModulePassManager &MPM, bool Optimized) const {
   // Use the specified -regalloc-npm={basic|greedy|fast|pbqp}
   if (Opt.RegAlloc > RegAllocType::Default) {
     switch (Opt.RegAlloc) {
     case RegAllocType::Fast:
-      addPass(RegAllocFastPass());
+      addMachineFunctionPass(RegAllocFastPass());
       break;
     case RegAllocType::Greedy:
-      addPass(RAGreedyPass());
+      addMachineFunctionPass(RAGreedyPass());
       break;
     default:
       reportFatalUsageError("register allocator not supported yet");
@@ -1199,33 +1143,33 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
   }
   // -regalloc=default or unspecified, so pick based on the optimization level
   // or ask the target for the regalloc pass.
-  derived().addTargetRegisterAllocator(addPass, Optimized);
+  derived().addTargetRegisterAllocator(MPM, Optimized);
 }
 
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignmentFast(
-    AddMachinePass &addPass) const {
+    ModulePassManager &MPM) const {
   // TODO: Ensure allocator is default or fast.
-  addRegAllocPass(addPass, false);
+  addRegAllocPass(MPM, false);
   return Error::success();
 }
 
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignmentOptimized(
-    AddMachinePass &addPass) const {
+    ModulePassManager &MPM) const {
   // Add the selected register allocation pass.
-  addRegAllocPass(addPass, true);
+  addRegAllocPass(MPM, true);
 
   // Allow targets to change the register assignments before rewriting.
-  derived().addPreRewrite(addPass);
+  derived().addPreRewrite(MPM);
 
   // Finally rewrite virtual registers.
-  addPass(VirtRegRewriterPass());
+  addMachineFunctionPass(VirtRegRewriterPass());
   // Perform stack slot coloring and post-ra machine LICM.
   //
   // FIXME: Re-enable coloring with register when it's capable of adding
   // kill markers.
-  addPass(StackSlotColoringPass());
+  addMachineFunctionPass(StackSlotColoringPass());
 
   return Error::success();
 }
@@ -1234,10 +1178,10 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignmentOptimized(
 /// register allocation. No coalescing or scheduling.
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addFastRegAlloc(
-    AddMachinePass &addPass) const {
-  addPass(PHIEliminationPass());
-  addPass(TwoAddressInstructionPass());
-  return derived().addRegAssignmentFast(addPass);
+    ModulePassManager &MPM) const {
+  addMachineFunctionPass(PHIEliminationPass());
+  addMachineFunctionPass(TwoAddressInstructionPass());
+  return derived().addRegAssignmentFast(MPM);
 }
 
 /// Add standard target-independent passes that are tightly coupled with
@@ -1245,12 +1189,12 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addFastRegAlloc(
 /// scheduling, and register allocation itself.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
-    AddMachinePass &addPass) const {
-  addPass(DetectDeadLanesPass());
+    ModulePassManager &MPM) const {
+  addMachineFunctionPass(DetectDeadLanesPass());
 
-  addPass(InitUndefPass());
+  addMachineFunctionPass(InitUndefPass());
 
-  addPass(ProcessImplicitDefsPass());
+  addMachineFunctionPass(ProcessImplicitDefsPass());
 
   // LiveVariables currently requires pure SSA form.
   //
@@ -1262,44 +1206,47 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
   // When LiveVariables is removed this has to be removed/moved either.
   // Explicit addition of UnreachableMachineBlockElim allows stopping before or
   // after it with -stop-before/-stop-after.
-  addPass(UnreachableMachineBlockElimPass());
-  addPass(RequireAnalysisPass<LiveVariablesAnalysis, MachineFunction>());
+  addMachineFunctionPass(UnreachableMachineBlockElimPass());
+  addMachineFunctionPass(
+      RequireAnalysisPass<LiveVariablesAnalysis, MachineFunction>());
 
   // Edge splitting is smarter with machine loop info.
-  addPass(RequireAnalysisPass<MachineLoopAnalysis, MachineFunction>());
-  addPass(PHIEliminationPass());
+  addMachineFunctionPass(
+      RequireAnalysisPass<MachineLoopAnalysis, MachineFunction>());
+  addMachineFunctionPass(PHIEliminationPass());
 
   // Eventually, we want to run LiveIntervals before PHI elimination.
   if (Opt.EarlyLiveIntervals)
-    addPass(RequireAnalysisPass<LiveIntervalsAnalysis, MachineFunction>());
+    addMachineFunctionPass(
+        RequireAnalysisPass<LiveIntervalsAnalysis, MachineFunction>());
 
-  addPass(TwoAddressInstructionPass());
-  addPass(RegisterCoalescerPass());
+  addMachineFunctionPass(TwoAddressInstructionPass());
+  addMachineFunctionPass(RegisterCoalescerPass());
 
   // The machine scheduler may accidentally create disconnected components
   // when moving subregister definitions around, avoid this by splitting them to
   // separate vregs before. Splitting can also improve reg. allocation quality.
-  addPass(RenameIndependentSubregsPass());
+  addMachineFunctionPass(RenameIndependentSubregsPass());
 
   // PreRA instruction scheduling.
-  addPass(MachineSchedulerPass(&TM));
+  addMachineFunctionPass(MachineSchedulerPass(&TM));
 
-  if (auto E = derived().addRegAssignmentOptimized(addPass)) {
+  if (auto E = derived().addRegAssignmentOptimized(MPM)) {
     // addRegAssignmentOptimized did not add a reg alloc pass, so do nothing.
     return;
   }
   // Allow targets to expand pseudo instructions depending on the choice of
   // registers before MachineCopyPropagation.
-  derived().addPostRewrite(addPass);
+  derived().addPostRewrite(MPM);
 
   // Copy propagate to forward register uses and try to eliminate COPYs that
   // were not coalesced.
-  addPass(MachineCopyPropagationPass());
+  addMachineFunctionPass(MachineCopyPropagationPass());
 
   // Run post-ra machine LICM to hoist reloads / remats.
   //
   // FIXME: can this move into MachineLateOptimization?
-  addPass(MachineLICMPass());
+  addMachineFunctionPass(MachineLICMPass());
 }
 
 //===---------------------------------------------------------------------===//
@@ -1309,32 +1256,32 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
 /// Add passes that optimize machine instructions after register allocation.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineLateOptimization(
-    AddMachinePass &addPass) const {
+    ModulePassManager &MPM) const {
   // Branch folding must be run after regalloc and prolog/epilog insertion.
-  addPass(BranchFolderPass(Opt.EnableTailMerge));
+  addMachineFunctionPass(BranchFolderPass(Opt.EnableTailMerge));
 
   // Tail duplication.
   // Note that duplicating tail just increases code size and degrades
   // performance for targets that require Structured Control Flow.
   // In addition it can also make CFG irreducible. Thus we disable it.
   if (!TM.requiresStructuredCFG())
-    addPass(TailDuplicatePass());
+    addMachineFunctionPass(TailDuplicatePass());
 
   // Cleanup of redundant (identical) address/immediate loads.
-  addPass(MachineLateInstrsCleanupPass());
+  addMachineFunctionPass(MachineLateInstrsCleanupPass());
 
   // Copy propagation.
-  addPass(MachineCopyPropagationPass());
+  addMachineFunctionPass(MachineCopyPropagationPass());
 }
 
 /// Add standard basic block placement passes.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addBlockPlacement(
-    AddMachinePass &addPass) const {
-  addPass(MachineBlockPlacementPass(Opt.EnableTailMerge));
+    ModulePassManager &MPM) const {
+  addMachineFunctionPass(MachineBlockPlacementPass(Opt.EnableTailMerge));
   // Run a separate pass to collect block placement statistics.
   if (Opt.EnableBlockPlacementStats)
-    addPass(MachineBlockPlacementStatsPass());
+    addMachineFunctionPass(MachineBlockPlacementStatsPass());
 }
 
 } // namespace llvm
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index e5a35abe6da6b..722c6a4388836 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -141,29 +141,29 @@ class AMDGPUCodeGenPassBuilder
                            const CGPassBuilderOption &Opts,
                            PassInstrumentationCallbacks *PIC);
 
-  void addIRPasses(AddIRPass &) const;
-  void addCodeGenPrepare(AddIRPass &) const;
-  void addPreISel(AddIRPass &addPass) const;
-  void addILPOpts(AddMachinePass &) const;
-  void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
-  Error addInstSelector(AddMachinePass &) const;
-  void addPreRewrite(AddMachinePass &) const;
-  void addMachineSSAOptimization(AddMachinePass &) const;
-  void addPostRegAlloc(AddMachinePass &) const;
-  void addPreEmitPass(AddMachinePass &) const;
-  void addPreEmitRegAlloc(AddMachinePass &) const;
-  Error addRegAssignmentOptimized(AddMachinePass &) const;
-  void addPreRegAlloc(AddMachinePass &) const;
-  void addOptimizedRegAlloc(AddMachinePass &) const;
-  void addPreSched2(AddMachinePass &) const;
+  void addIRPasses(ModulePassManager &MPM) const;
+  void addCodeGenPrepare(ModulePassManager &MPM) const;
+  void addPreISel(ModulePassManager &MPM) const;
+  void addILPOpts(ModulePassManager &MPM) const;
+  void addAsmPrinter(ModulePassManager &MPM, CreateMCStreamer) const;
+  Error addInstSelector(ModulePassManager &MPM) const;
+  void addPreRewrite(ModulePassManager &MPM) const;
+  void addMachineSSAOptimization(ModulePassManager &MPM) const;
+  void addPostRegAlloc(ModulePassManager &MPM) const;
+  void addPreEmitPass(ModulePassManager &MPM) const;
+  void addPreEmitRegAlloc(ModulePassManager &MPM) const;
+  Error addRegAssignmentOptimized(ModulePassManager &MPM) const;
+  void addPreRegAlloc(ModulePassManager &MPM) const;
+  void addOptimizedRegAlloc(ModulePassManager &MPM) const;
+  void addPreSched2(ModulePassManager &MPM) const;
 
   /// Check if a pass is enabled given \p Opt option. The option always
   /// overrides defaults if explicitly used. Otherwise its default will be used
   /// given that a pass shall work at an optimization \p Level minimum.
   bool isPassEnabled(const cl::opt<bool> &Opt,
                      CodeGenOptLevel Level = CodeGenOptLevel::Default) const;
-  void addEarlyCSEOrGVNPass(AddIRPass &) const;
-  void addStraightLineScalarOptimizationPasses(AddIRPass &) const;
+  void addEarlyCSEOrGVNPass(ModulePassManager &MPM) const;
+  void addStraightLineScalarOptimizationPasses(ModulePassManager &MPM) const;
 };
 
 class SGPRRegisterRegAlloc : public RegisterRegAllocBase<SGPRRegisterRegAlloc> {
@@ -2099,64 +2099,69 @@ AMDGPUCodeGenPassBuilder::AMDGPUCodeGenPassBuilder(
               ShadowStackGCLoweringPass>();
 }
 
-void AMDGPUCodeGenPassBuilder::addIRPasses(AddIRPass &addPass) const {
-  if (RemoveIncompatibleFunctions && TM.getTargetTriple().isAMDGCN())
-    addPass(AMDGPURemoveIncompatibleFunctionsPass(TM));
+void AMDGPUCodeGenPassBuilder::addIRPasses(ModulePassManager &MPM) const {
+  if (RemoveIncompatibleFunctions && TM.getTargetTriple().isAMDGCN()) {
+    flushFPMsToMPM(MPM);
+    addModulePass(AMDGPURemoveIncompatibleFunctionsPass(TM), MPM);
+  }
 
-  addPass(AMDGPUPrintfRuntimeBindingPass());
+  flushFPMsToMPM(MPM);
+  addModulePass(AMDGPUPrintfRuntimeBindingPass(), MPM);
   if (LowerCtorDtor)
-    addPass(AMDGPUCtorDtorLoweringPass());
+    addModulePass(AMDGPUCtorDtorLoweringPass(), MPM);
 
   if (isPassEnabled(EnableImageIntrinsicOptimizer))
-    addPass(AMDGPUImageIntrinsicOptimizerPass(TM));
+    addFunctionPass(AMDGPUImageIntrinsicOptimizerPass(TM));
 
   if (EnableUniformIntrinsicCombine)
-    addPass(AMDGPUUniformIntrinsicCombinePass());
+    addFunctionPass(AMDGPUUniformIntrinsicCombinePass());
   // This can be disabled by passing ::Disable here or on the command line
   // with --expand-variadics-override=disable.
-  addPass(ExpandVariadicsPass(ExpandVariadicsMode::Lowering));
+  flushFPMsToMPM(MPM);
+  addModulePass(ExpandVariadicsPass(ExpandVariadicsMode::Lowering), MPM);
 
-  addPass(AMDGPUAlwaysInlinePass());
-  addPass(AlwaysInlinerPass());
+  addModulePass(AMDGPUAlwaysInlinePass(), MPM);
+  addModulePass(AlwaysInlinerPass(), MPM);
 
-  addPass(AMDGPUExportKernelRuntimeHandlesPass());
+  addModulePass(AMDGPUExportKernelRuntimeHandlesPass(), MPM);
 
   if (EnableLowerExecSync)
-    addPass(AMDGPULowerExecSyncPass());
+    addModulePass(AMDGPULowerExecSyncPass(), MPM);
 
   if (EnableSwLowerLDS)
-    addPass(AMDGPUSwLowerLDSPass(TM));
+    addModulePass(AMDGPUSwLowerLDSPass(TM), MPM);
 
   // Runs before PromoteAlloca so the latter can account for function uses
   if (EnableLowerModuleLDS)
-    addPass(AMDGPULowerModuleLDSPass(TM));
+    addModulePass(AMDGPULowerModuleLDSPass(TM), MPM);
 
   // Run atomic optimizer before Atomic Expand
   if (TM.getOptLevel() >= CodeGenOptLevel::Less &&
       (AMDGPUAtomicOptimizerStrategy != ScanOptions::None))
-    addPass(AMDGPUAtomicOptimizerPass(TM, AMDGPUAtomicOptimizerStrategy));
+    addFunctionPass(
+        AMDGPUAtomicOptimizerPass(TM, AMDGPUAtomicOptimizerStrategy));
 
-  addPass(AtomicExpandPass(TM));
+  addFunctionPass(AtomicExpandPass(TM));
 
   if (TM.getOptLevel() > CodeGenOptLevel::None) {
-    addPass(AMDGPUPromoteAllocaPass(TM));
+    addFunctionPass(AMDGPUPromoteAllocaPass(TM));
     if (isPassEnabled(EnableScalarIRPasses))
-      addStraightLineScalarOptimizationPasses(addPass);
+      addStraightLineScalarOptimizationPasses(MPM);
 
     // TODO: Handle EnableAMDGPUAliasAnalysis
 
     // TODO: May want to move later or split into an early and late one.
-    addPass(AMDGPUCodeGenPreparePass(TM));
+    addFunctionPass(AMDGPUCodeGenPreparePass(TM));
 
     // Try to hoist loop invariant parts of divisions AMDGPUCodeGenPrepare may
     // have expanded.
     if (TM.getOptLevel() > CodeGenOptLevel::Less) {
-      addPass(createFunctionToLoopPassAdaptor(LICMPass(LICMOptions()),
-                                              /*UseMemorySSA=*/true));
+      addFunctionPass(createFunctionToLoopPassAdaptor(LICMPass(LICMOptions()),
+                                                      /*UseMemorySSA=*/true));
     }
   }
 
-  Base::addIRPasses(addPass);
+  Base::addIRPasses(MPM);
 
   // EarlyCSE is not always strong enough to clean up what LSR produces. For
   // example, GVN can combine
@@ -2171,20 +2176,22 @@ void AMDGPUCodeGenPassBuilder::addIRPasses(AddIRPass &addPass) const {
   //
   // but EarlyCSE can do neither of them.
   if (isPassEnabled(EnableScalarIRPasses))
-    addEarlyCSEOrGVNPass(addPass);
+    addEarlyCSEOrGVNPass(MPM);
 }
 
-void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(AddIRPass &addPass) const {
-  if (TM.getOptLevel() > CodeGenOptLevel::None)
-    addPass(AMDGPUPreloadKernelArgumentsPass(TM));
+void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(ModulePassManager &MPM) const {
+  if (TM.getOptLevel() > CodeGenOptLevel::None) {
+    flushFPMsToMPM(MPM);
+    addModulePass(AMDGPUPreloadKernelArgumentsPass(TM), MPM);
+  }
 
   if (EnableLowerKernelArguments)
-    addPass(AMDGPULowerKernelArgumentsPass(TM));
+    addFunctionPass(AMDGPULowerKernelArgumentsPass(TM));
 
-  Base::addCodeGenPrepare(addPass);
+  Base::addCodeGenPrepare(MPM);
 
   if (isPassEnabled(EnableLoadStoreVectorizer))
-    addPass(LoadStoreVectorizerPass());
+    addFunctionPass(LoadStoreVectorizerPass());
 
   // This lowering has been placed after codegenprepare to take advantage of
   // address mode matching (which is why it isn't put with the LDS lowerings).
@@ -2193,102 +2200,105 @@ void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(AddIRPass &addPass) const {
   // but has been put before switch lowering and CFG flattening so that those
   // passes can run on the more optimized control flow this pass creates in
   // many cases.
-  addPass(AMDGPULowerBufferFatPointersPass(TM));
-  addPass.requireCGSCCOrder();
+  flushFPMsToMPM(MPM);
+  addModulePass(AMDGPULowerBufferFatPointersPass(TM), MPM);
+  requireCGSCCOrder(MPM);
 
-  addPass(AMDGPULowerIntrinsicsPass(TM));
+  addModulePass(AMDGPULowerIntrinsicsPass(TM), MPM);
 
   // LowerSwitch pass may introduce unreachable blocks that can cause unexpected
   // behavior for subsequent passes. Placing it here seems better that these
   // blocks would get cleaned up by UnreachableBlockElim inserted next in the
   // pass flow.
-  addPass(LowerSwitchPass());
+  addFunctionPass(LowerSwitchPass());
 }
 
-void AMDGPUCodeGenPassBuilder::addPreISel(AddIRPass &addPass) const {
+void AMDGPUCodeGenPassBuilder::addPreISel(ModulePassManager &MPM) const {
 
   if (TM.getOptLevel() > CodeGenOptLevel::None) {
-    addPass(FlattenCFGPass());
-    addPass(SinkingPass());
-    addPass(AMDGPULateCodeGenPreparePass(TM));
+    addFunctionPass(FlattenCFGPass());
+    addFunctionPass(SinkingPass());
+    addFunctionPass(AMDGPULateCodeGenPreparePass(TM));
   }
 
   // Merge divergent exit nodes. StructurizeCFG won't recognize the multi-exit
   // regions formed by them.
 
-  addPass(AMDGPUUnifyDivergentExitNodesPass());
-  addPass(FixIrreduciblePass());
-  addPass(UnifyLoopExitsPass());
-  addPass(StructurizeCFGPass(/*SkipUniformRegions=*/false));
+  addFunctionPass(AMDGPUUnifyDivergentExitNodesPass());
+  addFunctionPass(FixIrreduciblePass());
+  addFunctionPass(UnifyLoopExitsPass());
+  addFunctionPass(StructurizeCFGPass(/*SkipUniformRegions=*/false));
 
-  addPass(AMDGPUAnnotateUniformValuesPass());
+  addFunctionPass(AMDGPUAnnotateUniformValuesPass());
 
-  addPass(SIAnnotateControlFlowPass(TM));
+  addFunctionPass(SIAnnotateControlFlowPass(TM));
 
   // TODO: Move this right after structurizeCFG to avoid extra divergence
   // analysis. This depends on stopping SIAnnotateControlFlow from making
   // control flow modifications.
-  addPass(AMDGPURewriteUndefForPHIPass());
+  addFunctionPass(AMDGPURewriteUndefForPHIPass());
 
   if (!getCGPassBuilderOption().EnableGlobalISelOption ||
       !isGlobalISelAbortEnabled() || !NewRegBankSelect)
-    addPass(LCSSAPass());
+    addFunctionPass(LCSSAPass());
 
-  if (TM.getOptLevel() > CodeGenOptLevel::Less)
-    addPass(AMDGPUPerfHintAnalysisPass(TM));
+  if (TM.getOptLevel() > CodeGenOptLevel::Less) {
+    flushFPMsToMPM(MPM);
+    addModulePass(AMDGPUPerfHintAnalysisPass(TM), MPM);
+  }
 
   // FIXME: Why isn't this queried as required from AMDGPUISelDAGToDAG, and why
   // isn't this in addInstSelector?
-  addPass(RequireAnalysisPass<UniformityInfoAnalysis, Function>(),
-          /*Force=*/true);
+  addFunctionPass(RequireAnalysisPass<UniformityInfoAnalysis, Function>(),
+                  /*Force=*/true);
 }
 
-void AMDGPUCodeGenPassBuilder::addILPOpts(AddMachinePass &addPass) const {
+void AMDGPUCodeGenPassBuilder::addILPOpts(ModulePassManager &MPM) const {
   if (EnableEarlyIfConversion)
-    addPass(EarlyIfConverterPass());
+    addMachineFunctionPass(EarlyIfConverterPass());
 
-  Base::addILPOpts(addPass);
+  Base::addILPOpts(MPM);
 }
 
-void AMDGPUCodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass,
+void AMDGPUCodeGenPassBuilder::addAsmPrinter(ModulePassManager &MPM,
                                              CreateMCStreamer) const {
   // TODO: Add AsmPrinter.
 }
 
-Error AMDGPUCodeGenPassBuilder::addInstSelector(AddMachinePass &addPass) const {
-  addPass(AMDGPUISelDAGToDAGPass(TM));
-  addPass(SIFixSGPRCopiesPass());
-  addPass(SILowerI1CopiesPass());
+Error AMDGPUCodeGenPassBuilder::addInstSelector(ModulePassManager &MPM) const {
+  addMachineFunctionPass(AMDGPUISelDAGToDAGPass(TM));
+  addMachineFunctionPass(SIFixSGPRCopiesPass());
+  addMachineFunctionPass(SILowerI1CopiesPass());
   return Error::success();
 }
 
-void AMDGPUCodeGenPassBuilder::addPreRewrite(AddMachinePass &addPass) const {
+void AMDGPUCodeGenPassBuilder::addPreRewrite(ModulePassManager &MPM) const {
   if (EnableRegReassign) {
-    addPass(GCNNSAReassignPass());
+    addMachineFunctionPass(GCNNSAReassignPass());
   }
 }
 
 void AMDGPUCodeGenPassBuilder::addMachineSSAOptimization(
-    AddMachinePass &addPass) const {
-  Base::addMachineSSAOptimization(addPass);
+    ModulePassManager &MPM) const {
+  Base::addMachineSSAOptimization(MPM);
 
-  addPass(SIFoldOperandsPass());
+  addMachineFunctionPass(SIFoldOperandsPass());
   if (EnableDPPCombine) {
-    addPass(GCNDPPCombinePass());
+    addMachineFunctionPass(GCNDPPCombinePass());
   }
-  addPass(SILoadStoreOptimizerPass());
+  addMachineFunctionPass(SILoadStoreOptimizerPass());
   if (isPassEnabled(EnableSDWAPeephole)) {
-    addPass(SIPeepholeSDWAPass());
-    addPass(EarlyMachineLICMPass());
-    addPass(MachineCSEPass());
-    addPass(SIFoldOperandsPass());
+    addMachineFunctionPass(SIPeepholeSDWAPass());
+    addMachineFunctionPass(EarlyMachineLICMPass());
+    addMachineFunctionPass(MachineCSEPass());
+    addMachineFunctionPass(SIFoldOperandsPass());
   }
-  addPass(DeadMachineInstructionElimPass());
-  addPass(SIShrinkInstructionsPass());
+  addMachineFunctionPass(DeadMachineInstructionElimPass());
+  addMachineFunctionPass(SIShrinkInstructionsPass());
 }
 
 void AMDGPUCodeGenPassBuilder::addOptimizedRegAlloc(
-    AddMachinePass &addPass) const {
+    ModulePassManager &MPM) const {
   if (EnableDCEInRA)
     insertPass<DetectDeadLanesPass>(DeadMachineInstructionElimPass());
 
@@ -2323,90 +2333,89 @@ void AMDGPUCodeGenPassBuilder::addOptimizedRegAlloc(
   if (TM.getOptLevel() > CodeGenOptLevel::Less)
     insertPass<MachineSchedulerPass>(SIFormMemoryClausesPass());
 
-  Base::addOptimizedRegAlloc(addPass);
+  Base::addOptimizedRegAlloc(MPM);
 }
 
-void AMDGPUCodeGenPassBuilder::addPreRegAlloc(AddMachinePass &addPass) const {
+void AMDGPUCodeGenPassBuilder::addPreRegAlloc(ModulePassManager &MPM) const {
   if (getOptLevel() != CodeGenOptLevel::None)
-    addPass(AMDGPUPrepareAGPRAllocPass());
+    addMachineFunctionPass(AMDGPUPrepareAGPRAllocPass());
 }
 
 Error AMDGPUCodeGenPassBuilder::addRegAssignmentOptimized(
-    AddMachinePass &addPass) const {
+    ModulePassManager &MPM) const {
   // TODO: Check --regalloc-npm option
 
-  addPass(GCNPreRALongBranchRegPass());
+  addMachineFunctionPass(GCNPreRALongBranchRegPass());
 
-  addPass(RAGreedyPass({onlyAllocateSGPRs, "sgpr"}));
+  addMachineFunctionPass(RAGreedyPass({onlyAllocateSGPRs, "sgpr"}));
 
   // Commit allocated register changes. This is mostly necessary because too
   // many things rely on the use lists of the physical registers, such as the
   // verifier. This is only necessary with allocators which use LiveIntervals,
   // since FastRegAlloc does the replacements itself.
-  addPass(VirtRegRewriterPass(false));
+  addMachineFunctionPass(VirtRegRewriterPass(false));
 
   // At this point, the sgpr-regalloc has been done and it is good to have the
   // stack slot coloring to try to optimize the SGPR spill stack indices before
   // attempting the custom SGPR spill lowering.
-  addPass(StackSlotColoringPass());
+  addMachineFunctionPass(StackSlotColoringPass());
 
   // Equivalent of PEI for SGPRs.
-  addPass(SILowerSGPRSpillsPass());
+  addMachineFunctionPass(SILowerSGPRSpillsPass());
 
   // To Allocate wwm registers used in whole quad mode operations (for shaders).
-  addPass(SIPreAllocateWWMRegsPass());
+  addMachineFunctionPass(SIPreAllocateWWMRegsPass());
 
   // For allocating other wwm register operands.
-  addPass(RAGreedyPass({onlyAllocateWWMRegs, "wwm"}));
-  addPass(SILowerWWMCopiesPass());
-  addPass(VirtRegRewriterPass(false));
-  addPass(AMDGPUReserveWWMRegsPass());
+  addMachineFunctionPass(RAGreedyPass({onlyAllocateWWMRegs, "wwm"}));
+  addMachineFunctionPass(SILowerWWMCopiesPass());
+  addMachineFunctionPass(VirtRegRewriterPass(false));
+  addMachineFunctionPass(AMDGPUReserveWWMRegsPass());
 
   // For allocating per-thread VGPRs.
-  addPass(RAGreedyPass({onlyAllocateVGPRs, "vgpr"}));
-
+  addMachineFunctionPass(RAGreedyPass({onlyAllocateVGPRs, "vgpr"}));
 
-  addPreRewrite(addPass);
-  addPass(VirtRegRewriterPass(true));
+  addPreRewrite(MPM);
+  addMachineFunctionPass(VirtRegRewriterPass(true));
 
-  addPass(AMDGPUMarkLastScratchLoadPass());
+  addMachineFunctionPass(AMDGPUMarkLastScratchLoadPass());
   return Error::success();
 }
 
-void AMDGPUCodeGenPassBuilder::addPostRegAlloc(AddMachinePass &addPass) const {
-  addPass(SIFixVGPRCopiesPass());
+void AMDGPUCodeGenPassBuilder::addPostRegAlloc(ModulePassManager &MPM) const {
+  addMachineFunctionPass(SIFixVGPRCopiesPass());
   if (TM.getOptLevel() > CodeGenOptLevel::None)
-    addPass(SIOptimizeExecMaskingPass());
-  Base::addPostRegAlloc(addPass);
+    addMachineFunctionPass(SIOptimizeExecMaskingPass());
+  Base::addPostRegAlloc(MPM);
 }
 
-void AMDGPUCodeGenPassBuilder::addPreSched2(AddMachinePass &addPass) const {
+void AMDGPUCodeGenPassBuilder::addPreSched2(ModulePassManager &MPM) const {
   if (TM.getOptLevel() > CodeGenOptLevel::None)
-    addPass(SIShrinkInstructionsPass());
-  addPass(SIPostRABundlerPass());
+    addMachineFunctionPass(SIShrinkInstructionsPass());
+  addMachineFunctionPass(SIPostRABundlerPass());
 }
 
-void AMDGPUCodeGenPassBuilder::addPreEmitPass(AddMachinePass &addPass) const {
+void AMDGPUCodeGenPassBuilder::addPreEmitPass(ModulePassManager &MPM) const {
   if (isPassEnabled(EnableVOPD, CodeGenOptLevel::Less)) {
-    addPass(GCNCreateVOPDPass());
+    addMachineFunctionPass(GCNCreateVOPDPass());
   }
 
-  addPass(SIMemoryLegalizerPass());
-  addPass(SIInsertWaitcntsPass());
+  addMachineFunctionPass(SIMemoryLegalizerPass());
+  addMachineFunctionPass(SIInsertWaitcntsPass());
 
-  // TODO: addPass(SIModeRegisterPass());
+  // TODO: addMachineFunctionPass(SIModeRegisterPass());
 
   if (TM.getOptLevel() > CodeGenOptLevel::None) {
-    // TODO: addPass(SIInsertHardClausesPass());
+    // TODO: addMachineFunctionPass(SIInsertHardClausesPass());
   }
 
-  addPass(SILateBranchLoweringPass());
+  addMachineFunctionPass(SILateBranchLoweringPass());
 
   if (isPassEnabled(EnableSetWavePriority, CodeGenOptLevel::Less))
-    addPass(AMDGPUSetWavePriorityPass());
+    addMachineFunctionPass(AMDGPUSetWavePriorityPass());
 
   if (TM.getOptLevel() > CodeGenOptLevel::None)
-    addPass(SIPreEmitPeepholePass());
+    addMachineFunctionPass(SIPreEmitPeepholePass());
 
   // The hazard recognizer that runs as part of the post-ra scheduler does not
   // guarantee to be able handle all hazards correctly. This is because if there
@@ -2416,15 +2425,15 @@ void AMDGPUCodeGenPassBuilder::addPreEmitPass(AddMachinePass &addPass) const {
   //
   // Here we add a stand-alone hazard recognizer pass which can handle all
   // cases.
-  addPass(PostRAHazardRecognizerPass());
-  addPass(AMDGPUWaitSGPRHazardsPass());
-  addPass(AMDGPULowerVGPREncodingPass());
+  addMachineFunctionPass(PostRAHazardRecognizerPass());
+  addMachineFunctionPass(AMDGPUWaitSGPRHazardsPass());
+  addMachineFunctionPass(AMDGPULowerVGPREncodingPass());
 
   if (isPassEnabled(EnableInsertDelayAlu, CodeGenOptLevel::Less)) {
-    addPass(AMDGPUInsertDelayAluPass());
+    addMachineFunctionPass(AMDGPUInsertDelayAluPass());
   }
 
-  addPass(BranchRelaxationPass());
+  addMachineFunctionPass(BranchRelaxationPass());
 }
 
 bool AMDGPUCodeGenPassBuilder::isPassEnabled(const cl::opt<bool> &Opt,
@@ -2436,32 +2445,33 @@ bool AMDGPUCodeGenPassBuilder::isPassEnabled(const cl::opt<bool> &Opt,
   return Opt;
 }
 
-void AMDGPUCodeGenPassBuilder::addEarlyCSEOrGVNPass(AddIRPass &addPass) const {
+void AMDGPUCodeGenPassBuilder::addEarlyCSEOrGVNPass(
+    ModulePassManager &MPM) const {
   if (TM.getOptLevel() == CodeGenOptLevel::Aggressive)
-    addPass(GVNPass());
+    addFunctionPass(GVNPass());
   else
-    addPass(EarlyCSEPass());
+    addFunctionPass(EarlyCSEPass());
 }
 
 void AMDGPUCodeGenPassBuilder::addStraightLineScalarOptimizationPasses(
-    AddIRPass &addPass) const {
+    ModulePassManager &MPM) const {
   if (isPassEnabled(EnableLoopPrefetch, CodeGenOptLevel::Aggressive))
-    addPass(LoopDataPrefetchPass());
+    addFunctionPass(LoopDataPrefetchPass());
 
-  addPass(SeparateConstOffsetFromGEPPass());
+  addFunctionPass(SeparateConstOffsetFromGEPPass());
 
   // ReassociateGEPs exposes more opportunities for SLSR. See
   // the example in reassociate-geps-and-slsr.ll.
-  addPass(StraightLineStrengthReducePass());
+  addFunctionPass(StraightLineStrengthReducePass());
 
   // SeparateConstOffsetFromGEP and SLSR creates common expressions which GVN or
   // EarlyCSE can reuse.
-  addEarlyCSEOrGVNPass(addPass);
+  addEarlyCSEOrGVNPass(MPM);
 
   // Run NaryReassociate after EarlyCSE/GVN to be more effective.
-  addPass(NaryReassociatePass());
+  addFunctionPass(NaryReassociatePass());
 
   // NaryReassociate on GEPs creates redundant common expressions, so run
   // EarlyCSE after it.
-  addPass(EarlyCSEPass());
+  addFunctionPass(EarlyCSEPass());
 }
diff --git a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
index c20487ebd8fc9..a98ede81552c1 100644
--- a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
@@ -57,9 +57,9 @@ class R600CodeGenPassBuilder
   R600CodeGenPassBuilder(R600TargetMachine &TM, const CGPassBuilderOption &Opts,
                          PassInstrumentationCallbacks *PIC);
 
-  void addPreISel(AddIRPass &addPass) const;
-  void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
-  Error addInstSelector(AddMachinePass &) const;
+  void addPreISel(ModulePassManager &MPM) const;
+  void addAsmPrinter(ModulePassManager &MPM, CreateMCStreamer) const;
+  Error addInstSelector(ModulePassManager &MPM) const;
 };
 
 //===----------------------------------------------------------------------===//
@@ -188,16 +188,16 @@ R600CodeGenPassBuilder::R600CodeGenPassBuilder(
   Opt.RequiresCodeGenSCCOrder = true;
 }
 
-void R600CodeGenPassBuilder::addPreISel(AddIRPass &addPass) const {
+void R600CodeGenPassBuilder::addPreISel(ModulePassManager &MPM) const {
   // TODO: Add passes pre instruction selection.
 }
 
-void R600CodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass,
+void R600CodeGenPassBuilder::addAsmPrinter(ModulePassManager &MPM,
                                            CreateMCStreamer) const {
   // TODO: Add AsmPrinter.
 }
 
-Error R600CodeGenPassBuilder::addInstSelector(AddMachinePass &) const {
+Error R600CodeGenPassBuilder::addInstSelector(ModulePassManager &MPM) const {
   // TODO: Add instruction selector.
   return Error::success();
 }
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 2c0443da673a8..b3f3cce245d93 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -29,23 +29,23 @@ class X86CodeGenPassBuilder
                                  const CGPassBuilderOption &Opts,
                                  PassInstrumentationCallbacks *PIC)
       : CodeGenPassBuilder(TM, Opts, PIC) {}
-  void addPreISel(AddIRPass &addPass) const;
-  void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
-  Error addInstSelector(AddMachinePass &) const;
+  void addPreISel(ModulePassManager &MPM) const;
+  void addAsmPrinter(ModulePassManager &MPM, CreateMCStreamer) const;
+  Error addInstSelector(ModulePassManager &MPM) const;
 };
 
-void X86CodeGenPassBuilder::addPreISel(AddIRPass &addPass) const {
+void X86CodeGenPassBuilder::addPreISel(ModulePassManager &MPM) const {
   // TODO: Add passes pre instruction selection.
 }
 
-void X86CodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass,
+void X86CodeGenPassBuilder::addAsmPrinter(ModulePassManager &MPM,
                                           CreateMCStreamer) const {
   // TODO: Add AsmPrinter.
 }
 
-Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &addPass) const {
+Error X86CodeGenPassBuilder::addInstSelector(ModulePassManager &MPM) const {
   // TODO: Add instruction selector related passes.
-  addPass(X86ISelDAGToDAGPass(TM));
+  addMachineFunctionPass(X86ISelDAGToDAGPass(TM));
   return Error::success();
 }
 

>From dd9494b5abd623a4f9df9d3fce0dba6ec074b0b2 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Tue, 16 Dec 2025 08:26:55 +0000
Subject: [PATCH 2/2] feedback

Created using spr 1.3.7
---
 llvm/include/llvm/Passes/CodeGenPassBuilder.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 42f874e5d602e..eacfbc665d772 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -58,7 +58,6 @@
 #include "llvm/CodeGen/MachineCSE.h"
 #include "llvm/CodeGen/MachineCopyPropagation.h"
 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineLICM.h"
 #include "llvm/CodeGen/MachineLateInstrsCleanup.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
@@ -109,7 +108,6 @@
 #include "llvm/IRPrinter/IRPrintingPasses.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCTargetOptions.h"
-#include "llvm/Pass.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Error.h"



More information about the llvm-commits mailing list