[llvm] [CodeGen][NewPM] Introduce CodeGenPassManager (PR #210473)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 17 18:16:53 PDT 2026


https://github.com/paperchalice created https://github.com/llvm/llvm-project/pull/210473

I still believe that coupling CodeGenPassBuilder with pass managers is not a good idea. It currently can't handle {start,stop}-{before,after} with insertPass and is unfriendly with pass extension.
This pull request introduces CodeGenPassManagers dedicated to build CodeGen pass pipeline, which decouples pipeline building and pass element filtering. This also can detect return type from hooks like `addAsmPrinter` etc. to avoid unexpected usage, see also addISelPrepare, which might return CodeGenModulePassManager.

>From c0ea429e0404e272911db9fd7435eb13670a8619 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 17 Jul 2026 21:13:52 +0800
Subject: [PATCH 1/2] introduce CodeGenPassManager

---
 llvm/include/llvm/Passes/CodeGenPassManager.h | 239 ++++++++++++++++++
 llvm/lib/Passes/CMakeLists.txt                |   1 +
 llvm/lib/Passes/CodeGenPassManager.cpp        | 227 +++++++++++++++++
 3 files changed, 467 insertions(+)
 create mode 100644 llvm/include/llvm/Passes/CodeGenPassManager.h
 create mode 100644 llvm/lib/Passes/CodeGenPassManager.cpp

diff --git a/llvm/include/llvm/Passes/CodeGenPassManager.h b/llvm/include/llvm/Passes/CodeGenPassManager.h
new file mode 100644
index 0000000000000..3ac2df654cd3a
--- /dev/null
+++ b/llvm/include/llvm/Passes/CodeGenPassManager.h
@@ -0,0 +1,239 @@
+//===- CodeGenPassManager.h -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// PassManager wrappers for building CodeGen pipeline.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSES_CODEGENPASSMANAGER_H
+#define LLVM_PASSES_CODEGENPASSMANAGER_H
+
+#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+#include <list>
+#include <variant>
+
+namespace llvm {
+
+class LLVM_ABI CodeGenMachineFunctionPassManager
+    : protected MachineFunctionPassManager {
+  friend class CodeGenModulePassManager;
+  friend class CodeGenFunctionPassManager;
+
+public:
+  template <typename PassT> void addPass(PassT &&Pass) {
+    static_assert(!std::is_same_v<PassT, MachineFunctionPassManager>,
+                  "Use CodeGenMachineFunctionPassManager instead!");
+    MachineFunctionPassManager::addPass(std::forward<PassT>(Pass));
+    PassList.push_back(std::move(Passes.back()));
+    Passes.pop_back();
+  }
+
+  void addPass(CodeGenMachineFunctionPassManager &&CGPM) {
+    for (auto &P : CGPM.PassList)
+      PassList.push_back(std::move(P));
+    CGPM.PassList.clear();
+  }
+
+  bool isEmpty() const { return PassList.empty(); }
+
+private:
+  MachineFunctionPassManager getMachineFunctionPassManager() {
+    CodeGenMachineFunctionPassManager MFPM;
+    for (auto &P : PassList)
+      MFPM.Passes.push_back(std::move(P));
+    PassList.clear();
+    return MFPM;
+  }
+
+  void eraseIf(function_ref<bool(StringRef)> Pred) {
+    for (auto I = PassList.begin(), E = PassList.end(); I != E;) {
+      if (Pred((*I)->name()))
+        I = PassList.erase(I);
+      else
+        ++I;
+    }
+  }
+
+  void handleInsert(
+      function_ref<void(StringRef, CodeGenMachineFunctionPassManager &)> F) {
+    for (auto I = PassList.begin(), E = PassList.end(); I != E; ++I) {
+      CodeGenMachineFunctionPassManager CGFPM;
+      F((*I)->name(), CGFPM);
+      if (CGFPM.isEmpty())
+        continue;
+      for (auto J = CGFPM.PassList.rbegin(), End = CGFPM.PassList.rend();
+           J != End; ++J)
+        PassList.insert(std::next(I), std::move(*J));
+    }
+  }
+
+private:
+  std::list<std::unique_ptr<PassConceptT>> PassList;
+};
+
+class LLVM_ABI CodeGenLoopPassManager : public LoopPassManager {
+  friend class CodeGenFunctionPassManager;
+
+public:
+  template <typename PassT> void addPass(PassT &&Pass) {
+    static_assert(!std::is_same_v<PassT, LoopPassManager>,
+                  "Use CodeGenLoopPassManager instead!");
+    LoopPassManager::addPass(std::forward<PassT>(Pass));
+    bool IsLoopNest = IsLoopNestPass.back();
+    IsLoopNestPass.pop_back();
+    if (IsLoopNest) {
+      PassList.push_back(std::move(LoopNestPasses.back()));
+      LoopNestPasses.pop_back();
+    } else {
+      PassList.push_back(std::move(LoopPasses.back()));
+      LoopPasses.pop_back();
+    }
+  }
+
+  void addPass(CodeGenLoopPassManager &&CGPM) {
+    for (auto &P : CGPM.PassList)
+      PassList.push_back(std::move(P));
+    CGPM.PassList.clear();
+  }
+
+  bool isEmpty() const { return PassList.empty(); }
+
+private:
+  LoopPassManager getLoopPassManager();
+
+  void eraseIf(function_ref<bool(StringRef)> Pred);
+
+  bool isSimilarWith(const CodeGenLoopPassManager &CGLPM) const {
+    return UseMemorySSA == CGLPM.UseMemorySSA;
+  }
+
+private:
+  bool UseMemorySSA = false;
+  std::list<std::variant<std::unique_ptr<LoopPassConceptT>,
+                         std::unique_ptr<LoopNestPassConceptT>>>
+      PassList;
+};
+
+class LLVM_ABI CodeGenFunctionPassManager : protected FunctionPassManager {
+  friend class CodeGenModulePassManager;
+
+public:
+  template <typename PassT> void addPass(PassT &&Pass) {
+    static_assert(!std::is_same_v<PassT, FunctionPassManager>,
+                  "Use CodeGenFunctionPassManager instead!");
+    static_assert(!std::is_same_v<PassT, FunctionToMachineFunctionPassAdaptor>,
+                  "Use addCodeGenMachineFunctionPassManager instead!");
+    static_assert(!std::is_same_v<PassT, FunctionToLoopPassAdaptor>,
+                  "Use addCodeGenLoopPassManager instead!");
+    FunctionPassManager::addPass(std::forward<PassT>(Pass));
+    PassList.push_back(std::move(Passes.back()));
+    Passes.pop_back();
+  }
+
+  void addPass(CodeGenFunctionPassManager &&CGPM) {
+    for (auto &P : CGPM.PassList)
+      PassList.push_back(std::move(P));
+    CGPM.PassList.clear();
+  }
+
+  void addCodeGenLoopPassManager(CodeGenLoopPassManager &&CGLPM,
+                                 bool UseMemorySSA = false) {
+    CGLPM.UseMemorySSA = UseMemorySSA;
+    PassList.push_back(std::move(CGLPM));
+  }
+
+  void addCodeGenMachineFunctionPassManager(
+      CodeGenMachineFunctionPassManager &&CGMFPM) {
+    PassList.push_back(std::move(CGMFPM));
+  }
+
+  bool isEmpty() const { return PassList.empty(); }
+
+private:
+  FunctionPassManager getFunctionPassManager();
+
+  void eraseIf(function_ref<bool(StringRef)>);
+
+  void combineSimilarPassManagers();
+
+  bool isSimilarWith(const CodeGenFunctionPassManager &CGFPM) const {
+    return EagerlyInvalidate == CGFPM.EagerlyInvalidate &&
+           RequireCGSCCOrder == CGFPM.RequireCGSCCOrder;
+  }
+
+private:
+  bool EagerlyInvalidate = false;
+  bool RequireCGSCCOrder = false;
+  std::list<std::variant<std::unique_ptr<PassConceptT>, CodeGenLoopPassManager,
+                         CodeGenMachineFunctionPassManager>>
+      PassList;
+};
+
+class LLVM_ABI CodeGenModulePassManager : public ModulePassManager {
+  template <typename DerivedT, typename TargetMachineT>
+  friend class CodeGenPassBuilder;
+
+public:
+  template <typename PassT> void addPass(PassT &&Pass) {
+    static_assert(!std::is_same_v<PassT, ModulePassManager>,
+                  "Use CodeGenModulePassManager instead!");
+    static_assert(!std::is_same_v<PassT, ModuleToFunctionPassAdaptor>,
+                  "Use addCodeGenFunctionPassManager instead!");
+    static_assert(!std::is_same_v<PassT, ModuleToPostOrderCGSCCPassAdaptor>,
+                  "Use addCodeGenFunctionPassManagerInCGSCCOrder instead!");
+    ModulePassManager::addPass(std::forward<PassT>(Pass));
+    PassList.push_back(std::move(Passes.back()));
+    Passes.pop_back();
+  }
+
+  void addPass(CodeGenModulePassManager &&CGPM) {
+    for (auto &P : CGPM.PassList)
+      PassList.push_back(std::move(P));
+    CGPM.PassList.clear();
+  }
+
+  void addCodeGenFunctionPassManager(CodeGenFunctionPassManager &&CGFPM,
+                                     bool EagerlyInvalidate = false) {
+    CGFPM.EagerlyInvalidate = EagerlyInvalidate;
+    PassList.push_back(std::move(CGFPM));
+  }
+
+  void addCodeGenFunctionPassManagerInCGSCCOrder(
+      CodeGenFunctionPassManager &&CGFPM) {
+    CGFPM.RequireCGSCCOrder = true;
+    PassList.push_back(std::move(CGFPM));
+  }
+
+  bool isEmpty() const { return PassList.empty(); }
+
+private:
+  ModulePassManager getModulePassManager();
+
+  void eraseIf(function_ref<bool(StringRef)> Pred);
+
+  /**
+   * @brief Merge pass managers which have the same type and options.
+   */
+  void combineSimilarPassManagers();
+
+  void handleInsert(
+      function_ref<void(StringRef, CodeGenMachineFunctionPassManager &)> F);
+
+private:
+  std::list<
+      std::variant<std::unique_ptr<PassConceptT>, CodeGenFunctionPassManager>>
+      PassList;
+};
+
+} // namespace llvm
+
+#endif // LLVM_PASSES_CODEGENPASSMANAGER_H
diff --git a/llvm/lib/Passes/CMakeLists.txt b/llvm/lib/Passes/CMakeLists.txt
index eaabf60b018fd..50c18a51881e3 100644
--- a/llvm/lib/Passes/CMakeLists.txt
+++ b/llvm/lib/Passes/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_llvm_component_library(LLVMPasses
   CodeGenPassBuilder.cpp
+  CodeGenPassManager.cpp
   PassBuilder.cpp
   PassBuilderBindings.cpp
   PassBuilderPipelines.cpp
diff --git a/llvm/lib/Passes/CodeGenPassManager.cpp b/llvm/lib/Passes/CodeGenPassManager.cpp
new file mode 100644
index 0000000000000..2dba5e421e24a
--- /dev/null
+++ b/llvm/lib/Passes/CodeGenPassManager.cpp
@@ -0,0 +1,227 @@
+//===- Pass manager wrappers for building CodeGen pass pipeline -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Passes/CodeGenPassManager.h"
+#include <algorithm>
+
+using namespace llvm;
+
+namespace {
+// helper type for the visitor
+template <class... Ts> struct overloads : Ts... {
+  using Ts::operator()...;
+};
+template <class... Ts> overloads(Ts...) -> overloads<Ts...>;
+} // namespace
+
+LoopPassManager CodeGenLoopPassManager::getLoopPassManager() {
+  CodeGenLoopPassManager LPM;
+  const auto Visitor = overloads{
+      [&LPM](std::unique_ptr<LoopPassConceptT> &P) {
+        LPM.LoopPasses.push_back(std::move(P));
+        LPM.IsLoopNestPass.push_back(false);
+      },
+      [&LPM](std::unique_ptr<LoopNestPassConceptT> &P) {
+        LPM.LoopNestPasses.push_back(std::move(P));
+        LPM.IsLoopNestPass.push_back(true);
+      },
+  };
+  for (auto &P : PassList)
+    std::visit(Visitor, P);
+  PassList.clear();
+  return LPM;
+}
+
+FunctionPassManager CodeGenFunctionPassManager::getFunctionPassManager() {
+  CodeGenFunctionPassManager FPM;
+  const auto Visitor = overloads{
+      [&FPM](std::unique_ptr<PassConceptT> &P) {
+        FPM.Passes.push_back(std::move(P));
+      },
+      [&FPM](CodeGenLoopPassManager &CGLPM) {
+        FPM.FunctionPassManager::addPass(createFunctionToLoopPassAdaptor(
+            CGLPM.getLoopPassManager(), CGLPM.UseMemorySSA));
+      },
+      [&FPM](CodeGenMachineFunctionPassManager &CGMFPM) {
+        FPM.FunctionPassManager::addPass(
+            createFunctionToMachineFunctionPassAdaptor(
+                CGMFPM.getMachineFunctionPassManager()));
+      }};
+  for (auto &P : PassList)
+    std::visit(Visitor, P);
+  PassList.clear();
+  return FPM;
+}
+
+ModulePassManager CodeGenModulePassManager::getModulePassManager() {
+  CodeGenModulePassManager MPM;
+  const auto Visitor = overloads{
+      [&MPM](std::unique_ptr<PassConceptT> &P) {
+        MPM.Passes.push_back(std::move(P));
+      },
+      [&MPM](CodeGenFunctionPassManager &CGFPM) {
+        if (CGFPM.RequireCGSCCOrder) {
+          MPM.ModulePassManager::addPass(
+              createModuleToPostOrderCGSCCPassAdaptor(
+                  createCGSCCToFunctionPassAdaptor(
+                      CGFPM.getFunctionPassManager())));
+        } else {
+          MPM.ModulePassManager::addPass(createModuleToFunctionPassAdaptor(
+              CGFPM.getFunctionPassManager(), CGFPM.EagerlyInvalidate));
+        }
+      }};
+  for (auto &P : PassList)
+    std::visit(Visitor, P);
+  return MPM;
+}
+
+void CodeGenLoopPassManager::eraseIf(function_ref<bool(StringRef)> Pred) {
+  for (auto I = PassList.begin(), E = PassList.end(); I != E;) {
+    std::visit(
+        [&](auto &P) {
+          if (Pred(P->name()))
+            I = PassList.erase(I);
+          else
+            ++I;
+        },
+        *I);
+  }
+}
+
+void CodeGenFunctionPassManager::eraseIf(function_ref<bool(StringRef)> Pred) {
+  for (auto I = PassList.begin(), E = PassList.end(); I != E;) {
+    const auto Visitor =
+        overloads{[&](std::unique_ptr<PassConceptT> &P) {
+                    if (Pred(P->name()))
+                      I = PassList.erase(I);
+                    else
+                      ++I;
+                  },
+                  [&](CodeGenLoopPassManager &CGLPM) {
+                    CGLPM.eraseIf(Pred);
+                    if (CGLPM.isEmpty())
+                      I = PassList.erase(I);
+                    else
+                      ++I;
+                  },
+                  [&](CodeGenMachineFunctionPassManager &CGMFPM) {
+                    CGMFPM.eraseIf(Pred);
+                    if (CGMFPM.isEmpty())
+                      I = PassList.erase(I);
+                    else
+                      ++I;
+                  }};
+    std::visit(Visitor, *I);
+  }
+}
+
+void CodeGenModulePassManager::eraseIf(function_ref<bool(StringRef)> Pred) {
+  for (auto I = PassList.begin(), E = PassList.end(); I != E;) {
+    const auto Visitor = overloads{[&](std::unique_ptr<PassConceptT> &P) {
+                                     if (Pred(P->name()))
+                                       I = PassList.erase(I);
+                                     else
+                                       ++I;
+                                   },
+                                   [&](CodeGenFunctionPassManager &CGFPM) {
+                                     CGFPM.eraseIf(Pred);
+                                     if (CGFPM.isEmpty())
+                                       I = PassList.erase(I);
+                                     else
+                                       ++I;
+                                   }};
+    std::visit(Visitor, *I);
+  }
+}
+
+void CodeGenFunctionPassManager::combineSimilarPassManagers() {
+  auto B = PassList.begin(), End = PassList.end();
+  auto I = B;
+  while (I != End) {
+    I = std::find_if(I, End, [](const decltype(PassList)::value_type &V) {
+      return std::holds_alternative<CodeGenLoopPassManager>(V) ||
+             std::holds_alternative<CodeGenMachineFunctionPassManager>(V);
+    });
+    auto MergeEnd =
+        std::find_if_not(I, End, [&](const decltype(PassList)::value_type &V) {
+          if (V.index() != I->index())
+            return false;
+          if (auto *CGPM = std::get_if<CodeGenLoopPassManager>(&V))
+            return CGPM->isSimilarWith(std::get<CodeGenLoopPassManager>(*I));
+          else
+            return true;
+        });
+
+    for (auto J = I; J != MergeEnd;) {
+      if (J == I) {
+        ++J;
+        continue;
+      }
+      std::visit(
+          [&](auto &JPM) {
+            if constexpr (!std::is_same_v<
+                              std::remove_reference_t<decltype(JPM)>,
+                              std::unique_ptr<PassConceptT>>) {
+              auto &CGPM = std::get<std::remove_reference_t<decltype(JPM)>>(*I);
+              CGPM.addPass(std::move(JPM));
+            }
+          },
+          *J);
+      J = PassList.erase(J);
+    }
+    I = MergeEnd;
+  }
+}
+
+void CodeGenModulePassManager::handleInsert(
+    function_ref<void(StringRef, CodeGenMachineFunctionPassManager &)> F) {
+  for (auto &P : PassList) {
+    auto *CGFPM = std::get_if<CodeGenFunctionPassManager>(&P);
+    if (!CGFPM)
+      continue;
+    for (auto &PV : CGFPM->PassList) {
+      auto *CGMFPM = std::get_if<CodeGenMachineFunctionPassManager>(&PV);
+      if (!CGMFPM)
+        continue;
+      CGMFPM->handleInsert(F);
+    }
+  }
+}
+
+void CodeGenModulePassManager::combineSimilarPassManagers() {
+  auto B = PassList.begin(), End = PassList.end();
+  auto I = B;
+  while (I != End) {
+    I = std::find_if(I, End, [](const decltype(PassList)::value_type &V) {
+      return std::holds_alternative<CodeGenFunctionPassManager>(V);
+    });
+    auto MergeEnd =
+        std::find_if_not(I, End, [&](const decltype(PassList)::value_type &V) {
+          auto *CGPM = std::get_if<CodeGenFunctionPassManager>(&V);
+          if (!CGPM)
+            return false;
+          return CGPM->isSimilarWith(std::get<CodeGenFunctionPassManager>(*I));
+        });
+
+    if (I != MergeEnd) {
+      auto &CGPM = std::get<CodeGenFunctionPassManager>(*I);
+      for (auto J = I; J != MergeEnd;) {
+        if (J == I) {
+          ++J;
+          continue;
+        }
+
+        CGPM.addPass(std::move(std::get<CodeGenFunctionPassManager>(*J)));
+        J = PassList.erase(J);
+      }
+      CGPM.combineSimilarPassManagers();
+    }
+
+    I = MergeEnd;
+  }
+}

>From e4c84369389ca6360caaf5e22c1e76a8863b213a Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 17 Jul 2026 21:14:04 +0800
Subject: [PATCH 2/2] use CodeGenPassManager

---
 llvm/include/llvm/Passes/CodeGenPassBuilder.h | 751 +++++++++---------
 .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 372 ++++-----
 llvm/lib/Target/AMDGPU/R600TargetMachine.cpp  |  25 +-
 llvm/lib/Target/X86/CMakeLists.txt            |   1 +
 llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 188 +++--
 .../tools/llc/new-pm/start-stop-inserted.ll   |   6 +-
 llvm/test/tools/llc/new-pm/start-stop.ll      |   4 +-
 7 files changed, 672 insertions(+), 675 deletions(-)

diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 6a93e61ea111d..cb4c94fde0b92 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -106,6 +106,7 @@
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCTargetOptions.h"
 #include "llvm/MC/TargetRegistry.h"
+#include "llvm/Passes/CodeGenPassManager.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Error.h"
@@ -155,18 +156,6 @@ namespace llvm {
   };
 #include "llvm/Passes/MachinePassRegistry.def"
 
-class PassManagerWrapper {
-private:
-  PassManagerWrapper(ModulePassManager &ModulePM) : MPM(ModulePM) {};
-
-  ModulePassManager &MPM;
-  FunctionPassManager FPM;
-  MachineFunctionPassManager MFPM;
-
-  template <typename DerivedT, typename TargetMachineT>
-  friend class CodeGenPassBuilder;
-};
-
 /// This class provides access to building LLVM's passes.
 ///
 /// Its members provide the baseline state available to passes during their
@@ -209,93 +198,6 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   }
 
 protected:
-  template <typename PassT>
-  using is_module_pass_t = decltype(std::declval<PassT &>().run(
-      std::declval<Module &>(), std::declval<ModuleAnalysisManager &>()));
-
-  template <typename PassT>
-  using is_function_pass_t = decltype(std::declval<PassT &>().run(
-      std::declval<Function &>(), std::declval<FunctionAnalysisManager &>()));
-
-  template <typename PassT>
-  using is_machine_function_pass_t = decltype(std::declval<PassT &>().run(
-      std::declval<MachineFunction &>(),
-      std::declval<MachineFunctionAnalysisManager &>()));
-
-  template <typename PassT>
-  void addFunctionPass(PassT &&Pass, PassManagerWrapper &PMW,
-                       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;
-    PMW.FPM.addPass(std::forward<PassT>(Pass));
-  }
-
-  template <typename PassT>
-  void addModulePass(PassT &&Pass, PassManagerWrapper &PMW, bool Force = false,
-                     StringRef Name = PassT::name()) const {
-    static_assert(is_detected<is_module_pass_t, PassT>::value &&
-                  "Only module passes are suported.");
-    assert(PMW.FPM.isEmpty() && PMW.MFPM.isEmpty() &&
-           "You cannot insert a module pass without first flushing the current "
-           "function pipelines to the module pipeline.");
-    if (!Force && !runBeforeAdding(Name))
-      return;
-    PMW.MPM.addPass(std::forward<PassT>(Pass));
-  }
-
-  template <typename PassT>
-  void addMachineFunctionPass(PassT &&Pass, PassManagerWrapper &PMW,
-                              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;
-    PMW.MFPM.addPass(std::forward<PassT>(Pass));
-    for (auto &C : AfterCallbacks)
-      C(Name, PMW.MFPM);
-  }
-
-  void flushFPMsToMPM(PassManagerWrapper &PMW,
-                      bool FreeMachineFunctions = false) const {
-    if (PMW.FPM.isEmpty() && PMW.MFPM.isEmpty())
-      return;
-    if (!PMW.MFPM.isEmpty()) {
-      PMW.FPM.addPass(
-          createFunctionToMachineFunctionPassAdaptor(std::move(PMW.MFPM)));
-      PMW.MFPM = MachineFunctionPassManager();
-    }
-    if (FreeMachineFunctions)
-      PMW.FPM.addPass(FreeMachineFunctionPass());
-    if (AddInCGSCCOrder) {
-      PMW.MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
-          createCGSCCToFunctionPassAdaptor(std::move(PMW.FPM))));
-    } else {
-      PMW.MPM.addPass(createModuleToFunctionPassAdaptor(std::move(PMW.FPM)));
-    }
-    PMW.FPM = FunctionPassManager();
-  }
-
-  void requireCGSCCOrder(PassManagerWrapper &PMW) const {
-    assert(!AddInCGSCCOrder);
-    assert(PMW.FPM.isEmpty() && PMW.MFPM.isEmpty() &&
-           "Requiring CGSCC ordering requires flushing the current function "
-           "pipelines to the MPM.");
-    AddInCGSCCOrder = true;
-  }
-
-  void stopAddingInCGSCCOrder(PassManagerWrapper &PMW) const {
-    assert(AddInCGSCCOrder);
-    assert(PMW.FPM.isEmpty() && PMW.MFPM.isEmpty() &&
-           "Stopping CGSCC ordering requires flushing the current function "
-           "pipelines to the MPM.");
-    AddInCGSCCOrder = false;
-  }
-
   TargetMachineT &TM;
   CGPassBuilderOption Opt;
   PassInstrumentationCallbacks *PIC;
@@ -319,13 +221,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(PassManagerWrapper &PMW) const {
+  Error addInstSelector(CodeGenMachineFunctionPassManager &CGMFPM) const {
     return make_error<StringError>("addInstSelector is not overridden",
                                    inconvertibleErrorCode());
   }
 
   /// Target can override this to add GlobalMergePass before all IR passes.
-  void addGlobalMergePass(PassManagerWrapper &PMW) const {}
+  void addGlobalMergePass(CodeGenModulePassManager &CGMPM) 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
@@ -333,11 +235,11 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   ///
   /// All passes added here should preserve the MachineDominatorTree,
   /// MachineLoopInfo, and MachineTraceMetrics analyses.
-  void addILPOpts(PassManagerWrapper &PMW) const {}
+  void addILPOpts(CodeGenMachineFunctionPassManager &CGMFPM) const {}
 
   /// This method may be implemented by targets that want to run passes
   /// immediately before register allocation.
-  void addPreRegAlloc(PassManagerWrapper &PMW) const {}
+  void addPreRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) const {}
 
   /// addPreRewrite - Add passes to the optimized register allocation pipeline
   /// after register allocation is complete, but before virtual registers are
@@ -351,77 +253,82 @@ 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(PassManagerWrapper &PMW) const {}
+  void addPreRewrite(CodeGenMachineFunctionPassManager &CGMFPM) const {}
 
   /// Add passes to be run immediately after virtual registers are rewritten
   /// to physical registers.
-  void addPostRewrite(PassManagerWrapper &PMW) const {}
+  void addPostRewrite(CodeGenMachineFunctionPassManager &CGMFPM) 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(PassManagerWrapper &PMW) const {}
+  void addPostRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) 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(PassManagerWrapper &PMW) const {}
+  void addPreSched2(CodeGenMachineFunctionPassManager &CGMFPM) const {}
 
   /// This pass may be implemented by targets that want to run passes
   /// immediately before machine code is emitted.
-  void addPreEmitPass(PassManagerWrapper &PMW) const {}
+  void addPreEmitPass(CodeGenMachineFunctionPassManager &CGMFPM) 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(PassManagerWrapper &PMW) const {}
+  void addPreEmitPass2(CodeGenMachineFunctionPassManager &CGMFPM) const {}
 
   /// {{@ For GlobalISel
   ///
 
   /// addPreISel - This method should add any "last minute" LLVM->LLVM
   /// passes (which are run just before instruction selector).
-  void addPreISel(PassManagerWrapper &PMW) const {}
+  CodeGenFunctionPassManager addPreISel() const {
+    return CodeGenFunctionPassManager();
+  }
 
   /// This method should install an IR translator pass, which converts from
   /// LLVM code to machine instructions with possibly generic opcodes.
-  Error addIRTranslator(PassManagerWrapper &PMW) const {
+  Error addIRTranslator(CodeGenMachineFunctionPassManager &CGMFPM) 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(PassManagerWrapper &PMW) const {}
+  void
+  addPreLegalizeMachineIR(CodeGenMachineFunctionPassManager &CGMFPM) const {}
 
   /// This method should install a legalize pass, which converts the instruction
   /// sequence into one that can be selected by the target.
-  Error addLegalizeMachineIR(PassManagerWrapper &PMW) const {
+  Error addLegalizeMachineIR(CodeGenMachineFunctionPassManager &CGMFPM) 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(PassManagerWrapper &PMW) const {}
+  void addPreRegBankSelect(CodeGenMachineFunctionPassManager &CGMFPM) 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(PassManagerWrapper &PMW) const {
+  Error addRegBankSelect(CodeGenMachineFunctionPassManager &CGMFPM) 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(PassManagerWrapper &PMW) const {}
+  void addPreGlobalInstructionSelect(
+      CodeGenMachineFunctionPassManager &CGMFPM) 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(PassManagerWrapper &PMWM) const {
+  Error
+  addGlobalInstructionSelect(CodeGenMachineFunctionPassManager &CGMFPM) const {
     return make_error<StringError>(
         "addGlobalInstructionSelect is not overridden",
         inconvertibleErrorCode());
@@ -432,30 +339,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(PassManagerWrapper &PMW) const;
+  void addISelPasses(CodeGenModulePassManager &CGMPM) const;
 
   /// Add the actual instruction selection passes. This does not include
   /// preparation passes on IR.
-  Error addCoreISelPasses(PassManagerWrapper &PMW) const;
+  Error addCoreISelPasses(CodeGenMachineFunctionPassManager &CGMFPM) const;
 
   /// Add the complete, standard set of LLVM CodeGen passes.
   /// Fully developed targets will not generally override this.
-  Error addMachinePasses(PassManagerWrapper &PMW) const;
+  Error addMachinePasses(CodeGenModulePassManager &CGMPM) const;
 
   /// Add passes to lower exception handling for the code generator.
-  void addPassesToHandleExceptions(PassManagerWrapper &PMW) const;
+  void addPassesToHandleExceptions(CodeGenFunctionPassManager &CGFPM) const;
 
   /// Add common target configurable passes that perform LLVM IR to IR
   /// transforms following machine independent optimization.
-  void addIRPasses(PassManagerWrapper &PMW) const;
+  void addIRPasses(CodeGenModulePassManager &CGMPM) const;
 
   /// Add pass to prepare the LLVM IR for code generation. This should be done
   /// before exception handling preparation passes.
-  void addCodeGenPrepare(PassManagerWrapper &PMW) const;
+  CodeGenFunctionPassManager addCodeGenPrepare() const;
 
   /// Add common passes that perform LLVM IR to IR transforms in preparation for
   /// instruction selection.
-  void addISelPrepare(PassManagerWrapper &PMW) const;
+  void addISelPrepare(CodeGenModulePassManager &CGMPM) const;
 
   /// Methods with trivial inline returns are convenient points in the common
   /// codegen pass pipeline where targets may insert passes. Methods with
@@ -466,39 +373,41 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   /// addMachineSSAOptimization - Add standard passes that optimize machine
   /// instructions in SSA form.
-  void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
+  void
+  addMachineSSAOptimization(CodeGenMachineFunctionPassManager &CGMFPM) const;
 
   /// addFastRegAlloc - Add the minimum set of target-independent passes that
   /// are required for fast register allocation.
-  Error addFastRegAlloc(PassManagerWrapper &PMW) const;
+  Error addFastRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) const;
 
   /// addOptimizedRegAlloc - Add passes related to register allocation.
   /// CodeGenTargetMachineImpl provides standard regalloc passes for most
   /// targets.
-  Error addOptimizedRegAlloc(PassManagerWrapper &PMW) const;
+  Error addOptimizedRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) const;
 
   /// Add passes that optimize machine instructions after register allocation.
-  void addMachineLateOptimization(PassManagerWrapper &PMW) const;
+  void
+  addMachineLateOptimization(CodeGenMachineFunctionPassManager &CGMFPM) 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(PassManagerWrapper &PMW) const {}
+  void addGCPasses(CodeGenMachineFunctionPassManager &CGMFPM) const {}
 
   /// Add standard basic block placement passes.
-  void addBlockPlacement(PassManagerWrapper &PMW) const;
+  void addBlockPlacement(CodeGenMachineFunctionPassManager &CGMFPM) const;
 
-  void addPostBBSections(PassManagerWrapper &PMW) const {}
+  void addPostBBSections(CodeGenMachineFunctionPassManager &CGMFPM) const {}
 
-  void addAsmPrinterBegin(PassManagerWrapper &PMW) const {
+  void addAsmPrinterBegin(CodeGenModulePassManager &CGMPM) const {
     llvm_unreachable("addAsmPrinterBegin is not overriden");
   }
 
-  void addAsmPrinter(PassManagerWrapper &PMW) const {
+  void addAsmPrinter(CodeGenMachineFunctionPassManager &CGMFPM) const {
     llvm_unreachable("addAsmPrinter is not overridden");
   }
 
-  void addAsmPrinterEnd(PassManagerWrapper &PMW) const {
+  void addAsmPrinterEnd(CodeGenModulePassManager &CGMPM) const {
     llvm_unreachable("addAsmPrinterEnd is not overriden");
   }
 
@@ -507,34 +416,38 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   /// createTargetRegisterAllocator - Create the register allocator pass for
   /// this target at the current optimization level.
-  void addTargetRegisterAllocator(PassManagerWrapper &PMW,
+  void addTargetRegisterAllocator(CodeGenMachineFunctionPassManager &CGMFPM,
                                   bool Optimized) const;
 
   /// addMachinePasses helper to create the target-selected or overriden
   /// regalloc pass.
-  void addRegAllocPass(PassManagerWrapper &PMW, bool Optimized) const;
+  void addRegAllocPass(CodeGenMachineFunctionPassManager &CGMFPM,
+                       bool Optimized) const;
 
   /// Add core register allocator passes which do the actual register assignment
   /// and rewriting.
-  Error addRegAssignmentFast(PassManagerWrapper &PMW) const;
-  Error addRegAssignmentOptimized(PassManagerWrapper &PMW) const;
+  Error addRegAssignmentFast(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  Error
+  addRegAssignmentOptimized(CodeGenMachineFunctionPassManager &CGMFPM) const;
 
   /// Allow the target to disable a specific pass by default.
   /// Backend can declare unwanted passes in constructor.
   template <typename... PassTs> void disablePass() {
-    BeforeCallbacks.emplace_back(
-        [](StringRef Name) { return ((Name != PassTs::name()) && ...); });
+    (DisabledPasses.insert(PassTs::name()), ...);
   }
 
   /// Insert InsertedPass pass after TargetPass pass.
   /// Only machine function passes are supported.
   template <typename TargetPassT, typename InsertedPassT>
   void insertPass(InsertedPassT &&Pass) const {
-    AfterCallbacks.emplace_back(
-        [&](StringRef Name, MachineFunctionPassManager &MFPM) mutable {
-          if (Name == TargetPassT::name() &&
-              runBeforeAdding(InsertedPassT::name())) {
-            MFPM.addPass(std::forward<InsertedPassT>(Pass));
+    InsertPassCallbacks.emplace_back(
+        [&, Visited = false](
+            StringRef Name, CodeGenMachineFunctionPassManager &CGMFPM) mutable {
+          if (Visited)
+            return;
+          if (Name == TargetPassT::name()) {
+            Visited = true;
+            CGMFPM.addPass(std::forward<InsertedPassT>(Pass));
           }
         });
   }
@@ -556,11 +469,16 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   Error verifyStartStop(const TargetPassConfig::StartStopInfo &Info) const;
 
+  StringSet<> DisabledPasses;
   mutable SmallVector<llvm::unique_function<bool(StringRef)>, 4>
       BeforeCallbacks;
   mutable SmallVector<
       llvm::unique_function<void(StringRef, MachineFunctionPassManager &)>, 4>
       AfterCallbacks;
+  mutable SmallVector<llvm::unique_function<void(
+                          StringRef, CodeGenMachineFunctionPassManager &)>,
+                      4>
+      InsertPassCallbacks;
 
   /// Helper variable for `-start-before/-start-after/-stop-before/-stop-after`
   mutable bool Started = true;
@@ -580,21 +498,14 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
   bool PrintAsm = TargetPassConfig::willCompleteCodeGenPipeline();
   bool PrintMIR = !PrintAsm && FileType != CodeGenFileType::Null;
 
-  PassManagerWrapper PMW(MPM);
-
-  addModulePass(RequireAnalysisPass<MachineModuleAnalysis, Module>(), PMW,
-                /*Force=*/true);
-  addModulePass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>(), PMW,
-                /*Force=*/true);
-  addModulePass(RequireAnalysisPass<CollectorMetadataAnalysis, Module>(), PMW,
-                /*Force=*/true);
-  addModulePass(RequireAnalysisPass<RuntimeLibraryAnalysis, Module>(), PMW,
-                /*Force=*/true);
-  addModulePass(RequireAnalysisPass<LibcallLoweringModuleAnalysis, Module>(),
-                PMW,
-                /*Force=*/true);
-  addISelPasses(PMW);
-  flushFPMsToMPM(PMW);
+  CodeGenModulePassManager CGMPM;
+  CGMPM.addPass(RequireAnalysisPass<MachineModuleAnalysis, Module>());
+  CGMPM.addPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
+  CGMPM.addPass(RequireAnalysisPass<CollectorMetadataAnalysis, Module>());
+  CGMPM.addPass(RequireAnalysisPass<RuntimeLibraryAnalysis, Module>());
+  CGMPM.addPass(RequireAnalysisPass<LibcallLoweringModuleAnalysis, Module>());
+
+  addISelPasses(CGMPM);
 
   if (PrintAsm) {
     Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
@@ -606,75 +517,101 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
     if (!Printer)
       return createStringError("failed to create AsmPrinter");
     MAM.registerPass([&] { return AsmPrinterAnalysis(std::move(Printer)); });
-    derived().addAsmPrinterBegin(PMW);
+    derived().addAsmPrinterBegin(CGMPM);
   }
 
   if (PrintMIR)
-    addModulePass(PrintMIRPreparePass(Out), PMW, /*Force=*/true);
+    CGMPM.addPass(PrintMIRPreparePass(Out));
 
-  if (auto Err = addCoreISelPasses(PMW))
+  CodeGenMachineFunctionPassManager CGMFPM;
+  if (auto Err = addCoreISelPasses(CGMFPM))
     return std::move(Err);
+  CodeGenFunctionPassManager CGFPM;
+  CGFPM.addCodeGenMachineFunctionPassManager(std::move(CGMFPM));
+  if (Opt.RequiresCodeGenSCCOrder)
+    CGMPM.addCodeGenFunctionPassManagerInCGSCCOrder(std::move(CGFPM));
+  else
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 
-  if (auto Err = derived().addMachinePasses(PMW))
+  if (auto Err = derived().addMachinePasses(CGMPM))
     return std::move(Err);
 
   if (!Opt.DisableVerify && TM.Options.EnableDefaultMachineVerifier)
-    addMachineFunctionPass(MachineVerifierPass(), PMW);
+    CGMFPM.addPass(MachineVerifierPass());
 
   if (PrintAsm) {
-    derived().addAsmPrinter(PMW);
-    flushFPMsToMPM(PMW, /*FreeMachineFunctions=*/true);
-    derived().addAsmPrinterEnd(PMW);
+    derived().addAsmPrinter(CGMFPM);
+    CGFPM.addCodeGenMachineFunctionPassManager(std::move(CGMFPM));
+    CGFPM.addPass(FreeMachineFunctionPass());
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+    derived().addAsmPrinterEnd(CGMPM);
+  } else if (PrintMIR) {
+    CGMFPM.addPass(PrintMIRPass(Out));
+    CGFPM.addCodeGenMachineFunctionPassManager(std::move(CGMFPM));
+    CGFPM.addPass(FreeMachineFunctionPass());
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
   } else {
-    if (PrintMIR)
-      addMachineFunctionPass(PrintMIRPass(Out), PMW, /*Force=*/true);
-    flushFPMsToMPM(PMW, /*FreeMachineFunctions=*/true);
+    CGFPM.addPass(FreeMachineFunctionPass());
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
   }
 
-  return verifyStartStop(*StartStopInfo);
-}
-
-template <typename Derived, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::setStartStopPasses(
-    const TargetPassConfig::StartStopInfo &Info) const {
-  if (!Info.StartPass.empty()) {
-    Started = false;
-    BeforeCallbacks.emplace_back([this, &Info, AfterFlag = Info.StartAfter,
-                                  Count = 0u](StringRef ClassName) mutable {
-      if (Count == Info.StartInstanceNum) {
-        if (AfterFlag) {
-          AfterFlag = false;
-          Started = true;
+  // Build the final pass manager.
+  CGMPM.handleInsert(
+      [this](StringRef Name, CodeGenMachineFunctionPassManager &CGMFPM) {
+        for (auto &CB : InsertPassCallbacks)
+          CB(Name, CGMFPM);
+      });
+  CGMPM.eraseIf(
+      [this](StringRef Name) { return DisabledPasses.contains(Name); });
+  CGMPM.eraseIf([this, &StartStopInfo, StartCount = 0ul,
+                 StopCount = 0ul](StringRef ClassName) mutable {
+    StringRef PassName = PIC->getPassNameForClassName(ClassName);
+    if (!Started) {
+      if (StartCount == StartStopInfo->StartInstanceNum)
+        Started = true;
+      if (PassName == StartStopInfo->StartPass) {
+        ++StartCount;
+        if (StartCount == StartStopInfo->StartInstanceNum) {
+          Started = !StartStopInfo->StartAfter;
         }
-        return Started;
       }
+    }
+    if (!Stopped && !StartStopInfo->StopPass.empty()) {
+      if (StopCount == StartStopInfo->StopInstanceNum)
+        Stopped = true;
+      if (PassName == StartStopInfo->StopPass) {
+        ++StopCount;
+        if (StopCount == StartStopInfo->StopInstanceNum) {
+          Stopped = !StartStopInfo->StopAfter;
+        }
+      }
+    }
 
-      auto PassName = PIC->getPassNameForClassName(ClassName);
-      if (Info.StartPass == PassName && ++Count == Info.StartInstanceNum)
-        Started = !Info.StartAfter;
+    StringSet<> NotSkippable = {
+        FreeMachineFunctionPass::name(),
+        PrintMIRPass::name(),
+        PrintMIRPreparePass::name(),
+    };
+    if (ClassName.contains("RequireAnalysisPass<") ||
+        ClassName.contains("AsmPrinter") || PassName == "verify" ||
+        NotSkippable.contains(ClassName))
+      return false;
 
-      return Started;
-    });
-  }
+    return !Started || Stopped;
+  });
 
-  if (!Info.StopPass.empty()) {
-    Stopped = false;
-    BeforeCallbacks.emplace_back([this, &Info, AfterFlag = Info.StopAfter,
-                                  Count = 0u](StringRef ClassName) mutable {
-      if (Count == Info.StopInstanceNum) {
-        if (AfterFlag) {
-          AfterFlag = false;
-          Stopped = true;
-        }
-        return !Stopped;
-      }
+  CGMPM.combineSimilarPassManagers();
 
-      auto PassName = PIC->getPassNameForClassName(ClassName);
-      if (Info.StopPass == PassName && ++Count == Info.StopInstanceNum)
-        Stopped = !Info.StopAfter;
-      return !Stopped;
-    });
-  }
+  MPM = CGMPM.getModulePassManager();
+
+  return verifyStartStop(*StartStopInfo);
+}
+
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::setStartStopPasses(
+    const TargetPassConfig::StartStopInfo &Info) const {
+  Started = Info.StartPass.empty();
+  Stopped = false;
 }
 
 template <typename Derived, typename TargetMachineT>
@@ -687,7 +624,7 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::verifyStartStop(
     return make_error<StringError>(
         "Can't find start pass \"" + Info.StartPass + "\".",
         std::make_error_code(std::errc::invalid_argument));
-  if (!Stopped)
+  if (!Stopped && !Info.StopPass.empty())
     return make_error<StringError>(
         "Can't find stop pass \"" + Info.StopPass + "\".",
         std::make_error_code(std::errc::invalid_argument));
@@ -696,102 +633,109 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::verifyStartStop(
 
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addISelPasses(
-    PassManagerWrapper &PMW) const {
-  derived().addGlobalMergePass(PMW);
+    CodeGenModulePassManager &CGMPM) const {
+  derived().addGlobalMergePass(CGMPM);
   if (TM.useEmulatedTLS())
-    addModulePass(LowerEmuTLSPass(), PMW);
+    CGMPM.addPass(LowerEmuTLSPass());
 
   // ObjCARCContract operates on ObjC intrinsics and must run before
   // PreISelIntrinsicLowering.
   if (getOptLevel() != CodeGenOptLevel::None) {
-    addFunctionPass(ObjCARCContractPass(), PMW);
-    flushFPMsToMPM(PMW);
+    CodeGenFunctionPassManager CGFPM;
+    CGFPM.addPass(ObjCARCContractPass());
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
   }
-  addModulePass(PreISelIntrinsicLoweringPass(&TM), PMW);
-  addFunctionPass(ExpandIRInstsPass(TM, getOptLevel()), PMW);
-
-  derived().addIRPasses(PMW);
-  derived().addCodeGenPrepare(PMW);
-  addPassesToHandleExceptions(PMW);
-  derived().addISelPrepare(PMW);
+  CGMPM.addPass(PreISelIntrinsicLoweringPass(&TM));
+  CodeGenFunctionPassManager CGFPM;
+  CGFPM.addPass(ExpandIRInstsPass(TM, getOptLevel()));
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+
+  derived().addIRPasses(CGMPM);
+  if constexpr (std::is_same_v<decltype(derived().addCodeGenPrepare()),
+                               CodeGenFunctionPassManager>)
+    CGMPM.addCodeGenFunctionPassManager(derived().addCodeGenPrepare());
+  else
+    CGMPM.addPass(derived().addCodeGenPrepare());
+  addPassesToHandleExceptions(CGFPM);
+  if (Opt.RequiresCodeGenSCCOrder)
+    CGMPM.addCodeGenFunctionPassManagerInCGSCCOrder(std::move(CGFPM));
+  else
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+  derived().addISelPrepare(CGMPM);
 }
 
 /// 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(
-    PassManagerWrapper &PMW) const {
+    CodeGenModulePassManager &CGMPM) const {
+  CodeGenFunctionPassManager CGFPM;
   // 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)
-    addFunctionPass(VerifierPass(), PMW, /*Force=*/true);
+    CGFPM.addPass(VerifierPass());
 
   // Run loop strength reduction before anything else.
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableLSR) {
     // These passes do not use MSSA.
-    LoopPassManager LPM;
-    LPM.addPass(CanonicalizeFreezeInLoopsPass());
-    LPM.addPass(LoopStrengthReducePass());
+    CodeGenLoopPassManager CGLPM;
+    CGLPM.addPass(CanonicalizeFreezeInLoopsPass());
+    CGLPM.addPass(LoopStrengthReducePass());
     if (Opt.EnableLoopTermFold)
-      LPM.addPass(LoopTermFoldPass());
-    addFunctionPass(createFunctionToLoopPassAdaptor(std::move(LPM),
-                                                    /*UseMemorySSA=*/false),
-                    PMW);
+      CGLPM.addPass(LoopTermFoldPass());
+    CGFPM.addCodeGenLoopPassManager(std::move(CGLPM));
   }
 
   // Run GC lowering passes for builtin collectors
   // TODO: add a pass insertion point here
-  addFunctionPass(GCLoweringPass(), PMW);
-  // 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(PMW);
-    addModulePass(ShadowStackGCLoweringPass(), PMW);
-  }
+  CGFPM.addPass(GCLoweringPass());
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+  CGMPM.addPass(ShadowStackGCLoweringPass());
 
   // Make sure that no unreachable blocks are instruction selected.
-  addFunctionPass(UnreachableBlockElimPass(), PMW);
+  CGFPM.addPass(UnreachableBlockElimPass());
 
   // Prepare expensive constants for SelectionDAG.
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableConstantHoisting)
-    addFunctionPass(ConstantHoistingPass(), PMW);
+    CGFPM.addPass(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)
-    addFunctionPass(ReplaceWithVeclib(), PMW);
+    CGFPM.addPass(ReplaceWithVeclib());
 
   if (getOptLevel() != CodeGenOptLevel::None &&
       !Opt.DisablePartialLibcallInlining)
-    addFunctionPass(PartiallyInlineLibCallsPass(), PMW);
+    CGFPM.addPass(PartiallyInlineLibCallsPass());
 
   // Instrument function entry and exit, e.g. with calls to mcount().
-  addFunctionPass(EntryExitInstrumenterPass(/*PostInlining=*/true), PMW);
+  CGFPM.addPass(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.
-  addFunctionPass(ScalarizeMaskedMemIntrinPass(), PMW);
+  CGFPM.addPass(ScalarizeMaskedMemIntrinPass());
 
   // Expand reduction intrinsics into shuffle sequences if the target wants to.
   if (!Opt.DisableExpandReductions)
-    addFunctionPass(ExpandReductionsPass(), PMW);
+    CGFPM.addPass(ExpandReductionsPass());
 
   // Convert conditional moves to conditional jumps when profitable.
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableSelectOptimize)
-    addFunctionPass(SelectOptimizePass(TM), PMW);
+    CGFPM.addPass(SelectOptimizePass(TM));
 
   if (Opt.EnableGlobalMergeFunc) {
-    flushFPMsToMPM(PMW);
-    addModulePass(GlobalMergeFuncPass(), PMW);
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+    CGMPM.addPass(GlobalMergeFuncPass());
   }
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 }
 
 /// Turn exception handling constructs into something the code generators can
 /// handle.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addPassesToHandleExceptions(
-    PassManagerWrapper &PMW) const {
+    CodeGenFunctionPassManager &CGFPM) const {
   const MCAsmInfo &MCAI = TM.getMCAsmInfo();
   switch (MCAI.getExceptionHandlingType()) {
   case ExceptionHandling::SjLj:
@@ -801,34 +745,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.
-    addFunctionPass(SjLjEHPreparePass(&TM), PMW);
+    CGFPM.addPass(SjLjEHPreparePass(&TM));
     [[fallthrough]];
   case ExceptionHandling::DwarfCFI:
   case ExceptionHandling::ARM:
   case ExceptionHandling::AIX:
   case ExceptionHandling::ZOS:
-    addFunctionPass(DwarfEHPreparePass(TM), PMW);
+    CGFPM.addPass(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.
-    addFunctionPass(WinEHPreparePass(), PMW);
-    addFunctionPass(DwarfEHPreparePass(TM), PMW);
+    CGFPM.addPass(WinEHPreparePass());
+    CGFPM.addPass(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.
-    addFunctionPass(WinEHPreparePass(/*DemoteCatchSwitchPHIOnly=*/false), PMW);
-    addFunctionPass(WasmEHPreparePass(), PMW);
+    CGFPM.addPass(WinEHPreparePass(/*DemoteCatchSwitchPHIOnly=*/false));
+    CGFPM.addPass(WasmEHPreparePass());
     break;
   case ExceptionHandling::None:
-    addFunctionPass(LowerInvokePass(), PMW);
+    CGFPM.addPass(LowerInvokePass());
 
     // The lower invoke pass may create unreachable code. Remove it.
-    addFunctionPass(UnreachableBlockElimPass(), PMW);
+    CGFPM.addPass(UnreachableBlockElimPass());
     break;
   }
 }
@@ -836,44 +780,56 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addPassesToHandleExceptions(
 /// Add pass to prepare the LLVM IR for code generation. This should be done
 /// before exception handling preparation passes.
 template <typename Derived, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addCodeGenPrepare(
-    PassManagerWrapper &PMW) const {
+CodeGenFunctionPassManager
+CodeGenPassBuilder<Derived, TargetMachineT>::addCodeGenPrepare() const {
+  CodeGenFunctionPassManager CGFPM;
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableCGP)
-    addFunctionPass(CodeGenPreparePass(TM), PMW);
+    CGFPM.addPass(CodeGenPreparePass(TM));
   // TODO: Default ctor'd RewriteSymbolPass is no-op.
   // addPass(RewriteSymbolPass());
+  return CGFPM;
 }
 
 /// Add common passes that perform LLVM IR to IR transforms in preparation for
 /// instruction selection.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addISelPrepare(
-    PassManagerWrapper &PMW) const {
-  derived().addPreISel(PMW);
-
-  if (Opt.RequiresCodeGenSCCOrder && !AddInCGSCCOrder)
-    requireCGSCCOrder(PMW);
+    CodeGenModulePassManager &CGMPM) const {
+  CodeGenFunctionPassManager CGFPM;
+  if constexpr (std::is_same_v<decltype(derived().addPreISel()),
+                               CodeGenModulePassManager>) {
+    CGMPM.addPass(derived().addPreISel());
+  } else {
+    if (Opt.RequiresCodeGenSCCOrder)
+      CGMPM.addCodeGenFunctionPassManagerInCGSCCOrder(derived().addPreISel());
+    else
+      CGMPM.addCodeGenFunctionPassManager(derived().addPreISel());
+  }
 
-  addFunctionPass(InlineAsmPreparePass(), PMW);
+  CGFPM.addPass(InlineAsmPreparePass());
   // Add both the safe stack and the stack protection passes: each of them will
   // only protect functions that have corresponding attributes.
-  addFunctionPass(SafeStackPass(TM), PMW);
-  addFunctionPass(StackProtectorPass(TM), PMW);
+  CGFPM.addPass(SafeStackPass(TM));
+  CGFPM.addPass(StackProtectorPass(TM));
 
   if (Opt.PrintISelInput)
-    addFunctionPass(PrintFunctionPass(
-                        dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"),
-                    PMW);
+    CGFPM.addPass(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)
-    addFunctionPass(VerifierPass(), PMW, /*Force=*/true);
+    CGFPM.addPass(VerifierPass());
+
+  if (Opt.RequiresCodeGenSCCOrder)
+    CGMPM.addCodeGenFunctionPassManagerInCGSCCOrder(std::move(CGFPM));
+  else
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 }
 
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addCoreISelPasses(
-    PassManagerWrapper &PMW) const {
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   // Enable FastISel with -fast-isel, but allow that to be overridden.
   TM.setO0WantsFastISel(Opt.EnableFastISelOption !=
                         cl::boolOrDefault::BOU_FALSE);
@@ -904,44 +860,42 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addCoreISelPasses(
 
   // Add instruction selector passes.
   if (Selector == SelectorType::GlobalISel) {
-    if (auto Err = derived().addIRTranslator(PMW))
+    if (auto Err = derived().addIRTranslator(CGMFPM))
       return std::move(Err);
 
-    derived().addPreLegalizeMachineIR(PMW);
+    derived().addPreLegalizeMachineIR(CGMFPM);
 
-    if (auto Err = derived().addLegalizeMachineIR(PMW))
+    if (auto Err = derived().addLegalizeMachineIR(CGMFPM))
       return std::move(Err);
 
     // Before running the register bank selector, ask the target if it
     // wants to run some passes.
-    derived().addPreRegBankSelect(PMW);
+    derived().addPreRegBankSelect(CGMFPM);
 
-    if (auto Err = derived().addRegBankSelect(PMW))
+    if (auto Err = derived().addRegBankSelect(CGMFPM))
       return std::move(Err);
 
-    derived().addPreGlobalInstructionSelect(PMW);
+    derived().addPreGlobalInstructionSelect(CGMFPM);
 
-    if (auto Err = derived().addGlobalInstructionSelect(PMW))
+    if (auto Err = derived().addGlobalInstructionSelect(CGMFPM))
       return std::move(Err);
 
     // Pass to reset the MachineFunction if the ISel failed.
-    addMachineFunctionPass(
-        ResetMachineFunctionPass(reportDiagnosticWhenGlobalISelFallback(),
-                                 isGlobalISelAbortEnabled()),
-        PMW);
+    CGMFPM.addPass(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(PMW))
+      if (auto Err = derived().addInstSelector(CGMFPM))
         return std::move(Err);
 
-  } else if (auto Err = derived().addInstSelector(PMW))
+  } else if (auto Err = derived().addInstSelector(CGMFPM))
     return std::move(Err);
 
   // Expand pseudo-instructions emitted by ISel. Don't run the verifier before
   // FinalizeISel.
-  addMachineFunctionPass(FinalizeISelPass(), PMW);
+  CGMFPM.addPass(FinalizeISelPass());
 
   // // Print the instruction selected machine code...
   // printAndVerify("After Instruction Selection");
@@ -967,58 +921,63 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addCoreISelPasses(
 /// instead.
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addMachinePasses(
-    PassManagerWrapper &PMW) const {
+    CodeGenModulePassManager &CGMPM) const {
+  CodeGenMachineFunctionPassManager CGMFPM;
   // Add passes that optimize machine instructions in SSA form.
   if (getOptLevel() != CodeGenOptLevel::None) {
-    derived().addMachineSSAOptimization(PMW);
+    derived().addMachineSSAOptimization(CGMFPM);
   } else {
     // If the target requests it, assign local variables to stack slots relative
     // to one another and simplify frame index references where possible.
-    addMachineFunctionPass(LocalStackSlotAllocationPass(), PMW);
+    CGMFPM.addPass(LocalStackSlotAllocationPass());
   }
 
   if (TM.Options.EnableIPRA) {
-    flushFPMsToMPM(PMW);
-    addModulePass(RequireAnalysisPass<PhysicalRegisterUsageAnalysis, Module>(),
-                  PMW, /*Force=*/true);
-    addMachineFunctionPass(RegUsageInfoPropagationPass(), PMW);
+    CodeGenFunctionPassManager CGFPM;
+    CGFPM.addCodeGenMachineFunctionPassManager(std::move(CGMFPM));
+    if (Opt.RequiresCodeGenSCCOrder)
+      CGMPM.addCodeGenFunctionPassManagerInCGSCCOrder(std::move(CGFPM));
+    else
+      CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+    CGMPM.addPass(RequireAnalysisPass<PhysicalRegisterUsageAnalysis, Module>());
+    CGMFPM.addPass(RegUsageInfoPropagationPass());
   }
   // Run pre-ra passes.
-  derived().addPreRegAlloc(PMW);
+  derived().addPreRegAlloc(CGMFPM);
 
   // Run register allocation and passes that are tightly coupled with it,
   // including phi elimination and scheduling.
   if (auto Err = Opt.OptimizeRegAlloc == cl::boolOrDefault::BOU_TRUE
-                     ? derived().addOptimizedRegAlloc(PMW)
-                     : derived().addFastRegAlloc(PMW))
+                     ? derived().addOptimizedRegAlloc(CGMFPM)
+                     : derived().addFastRegAlloc(CGMFPM))
     return std::move(Err);
 
   // Run post-ra passes.
-  derived().addPostRegAlloc(PMW);
+  derived().addPostRegAlloc(CGMFPM);
 
-  addMachineFunctionPass(RemoveRedundantDebugValuesPass(), PMW);
-  addMachineFunctionPass(FixupStatepointCallerSavedPass(), PMW);
+  CGMFPM.addPass(RemoveRedundantDebugValuesPass());
+  CGMFPM.addPass(FixupStatepointCallerSavedPass());
 
   // Insert prolog/epilog code.  Eliminate abstract frame index references...
   if (getOptLevel() != CodeGenOptLevel::None) {
-    addMachineFunctionPass(PostRAMachineSinkingPass(), PMW);
-    addMachineFunctionPass(ShrinkWrapPass(), PMW);
+    CGMFPM.addPass(PostRAMachineSinkingPass());
+    CGMFPM.addPass(ShrinkWrapPass());
   }
 
-  addMachineFunctionPass(PrologEpilogInserterPass(), PMW);
+  CGMFPM.addPass(PrologEpilogInserterPass());
 
   /// Add passes that optimize machine instructions after register allocation.
   if (getOptLevel() != CodeGenOptLevel::None)
-    derived().addMachineLateOptimization(PMW);
+    derived().addMachineLateOptimization(CGMFPM);
 
   // Expand pseudo instructions before second scheduling pass.
-  addMachineFunctionPass(ExpandPostRAPseudosPass(), PMW);
+  CGMFPM.addPass(ExpandPostRAPseudosPass());
 
   // Run pre-sched2 passes.
-  derived().addPreSched2(PMW);
+  derived().addPreSched2(CGMFPM);
 
   if (Opt.EnableImplicitNullChecks)
-    addMachineFunctionPass(ImplicitNullChecksPass(), PMW);
+    CGMFPM.addPass(ImplicitNullChecksPass());
 
   // Second pass scheduler.
   // Let Target optionally insert this pass by itself at some other
@@ -1026,66 +985,78 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addMachinePasses(
   if (getOptLevel() != CodeGenOptLevel::None &&
       !TM.targetSchedulesPostRAScheduling()) {
     if (Opt.MISchedPostRA)
-      addMachineFunctionPass(PostMachineSchedulerPass(&TM), PMW);
+      CGMFPM.addPass(PostMachineSchedulerPass(&TM));
     else
-      addMachineFunctionPass(PostRASchedulerPass(&TM), PMW);
+      CGMFPM.addPass(PostRASchedulerPass(&TM));
   }
 
   // GC
-  derived().addGCPasses(PMW);
+  derived().addGCPasses(CGMFPM);
 
   // Basic block placement.
   if (getOptLevel() != CodeGenOptLevel::None)
-    derived().addBlockPlacement(PMW);
+    derived().addBlockPlacement(CGMFPM);
 
   // Insert before XRay Instrumentation.
-  addMachineFunctionPass(FEntryInserterPass(), PMW);
+  CGMFPM.addPass(FEntryInserterPass());
 
-  addMachineFunctionPass(XRayInstrumentationPass(), PMW);
-  addMachineFunctionPass(PatchableFunctionPass(), PMW);
+  CGMFPM.addPass(XRayInstrumentationPass());
+  CGMFPM.addPass(PatchableFunctionPass());
 
-  derived().addPreEmitPass(PMW);
+  derived().addPreEmitPass(CGMFPM);
 
   if (TM.Options.EnableIPRA) {
     // Collect register usage information and produce a register mask of
     // clobbered registers, to be used to optimize call sites.
-    addMachineFunctionPass(RegUsageInfoCollectorPass(), PMW);
+    CGMFPM.addPass(RegUsageInfoCollectorPass());
     // If -print-regusage is specified, print the collected register usage info.
     if (Opt.PrintRegUsage) {
-      flushFPMsToMPM(PMW);
-      addModulePass(PhysicalRegisterUsageInfoPrinterPass(errs()), PMW);
+      CodeGenFunctionPassManager CGFPM;
+      CGFPM.addCodeGenMachineFunctionPassManager(std::move(CGMFPM));
+      CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+      CGMPM.addPass(PhysicalRegisterUsageInfoPrinterPass(errs()));
     }
   }
 
-  addMachineFunctionPass(FuncletLayoutPass(), PMW);
+  CGMFPM.addPass(FuncletLayoutPass());
 
-  addMachineFunctionPass(RemoveLoadsIntoFakeUsesPass(), PMW);
-  addMachineFunctionPass(StackMapLivenessPass(), PMW);
-  addMachineFunctionPass(
-      LiveDebugValuesPass(
-          getTM<TargetMachine>().Options.ShouldEmitDebugEntryValues()),
-      PMW);
-  addMachineFunctionPass(MachineSanitizerBinaryMetadataPass(), PMW);
+  CGMFPM.addPass(RemoveLoadsIntoFakeUsesPass());
+  CGMFPM.addPass(StackMapLivenessPass());
+  CGMFPM.addPass(LiveDebugValuesPass(
+      getTM<TargetMachine>().Options.ShouldEmitDebugEntryValues()));
+  CGMFPM.addPass(MachineSanitizerBinaryMetadataPass());
 
   if (TM.Options.EnableMachineOutliner &&
       getOptLevel() != CodeGenOptLevel::None &&
       Opt.EnableMachineOutliner != RunOutliner::NeverOutline) {
     if (Opt.EnableMachineOutliner != RunOutliner::TargetDefault ||
         TM.Options.SupportsDefaultOutlining) {
-      flushFPMsToMPM(PMW);
-      addModulePass(MachineOutlinerPass(Opt.EnableMachineOutliner), PMW);
+      CodeGenFunctionPassManager CGFPM;
+      CGFPM.addCodeGenMachineFunctionPassManager(std::move(CGMFPM));
+      if (Opt.RequiresCodeGenSCCOrder)
+        CGMPM.addCodeGenFunctionPassManagerInCGSCCOrder(std::move(CGFPM));
+      else
+        CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+      CGMPM.addPass(MachineOutlinerPass(Opt.EnableMachineOutliner));
     }
   }
 
   if (Opt.EnableGCEmptyBlocks)
-    addMachineFunctionPass(GCEmptyBasicBlocksPass(), PMW);
+    CGMFPM.addPass(GCEmptyBasicBlocksPass());
 
-  derived().addPostBBSections(PMW);
+  derived().addPostBBSections(CGMFPM);
 
-  addMachineFunctionPass(StackFrameLayoutAnalysisPass(), PMW);
+  CGMFPM.addPass(StackFrameLayoutAnalysisPass());
 
   // Add passes that directly emit MI after all other MI passes.
-  derived().addPreEmitPass2(PMW);
+  derived().addPreEmitPass2(CGMFPM);
+
+  CodeGenFunctionPassManager CGFPM;
+  CGFPM.addCodeGenMachineFunctionPassManager(std::move(CGMFPM));
+  if (Opt.RequiresCodeGenSCCOrder)
+    CGMPM.addCodeGenFunctionPassManagerInCGSCCOrder(std::move(CGFPM));
+  else
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 
   return Error::success();
 }
@@ -1093,42 +1064,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(
-    PassManagerWrapper &PMW) const {
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   // Pre-ra tail duplication.
-  addMachineFunctionPass(EarlyTailDuplicatePass(), PMW);
+  CGMFPM.addPass(EarlyTailDuplicatePass());
 
   // Optimize PHIs before DCE: removing dead PHI cycles may make more
   // instructions dead.
-  addMachineFunctionPass(OptimizePHIsPass(), PMW);
+  CGMFPM.addPass(OptimizePHIsPass());
 
   // This pass merges large allocas. StackSlotColoring is a different pass
   // which merges spill slots.
-  addMachineFunctionPass(StackColoringPass(), PMW);
+  CGMFPM.addPass(StackColoringPass());
 
   // If the target requests it, assign local variables to stack slots relative
   // to one another and simplify frame index references where possible.
-  addMachineFunctionPass(LocalStackSlotAllocationPass(), PMW);
+  CGMFPM.addPass(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).
-  addMachineFunctionPass(DeadMachineInstructionElimPass(), PMW);
+  CGMFPM.addPass(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(PMW);
+  derived().addILPOpts(CGMFPM);
 
-  addMachineFunctionPass(EarlyMachineLICMPass(), PMW);
-  addMachineFunctionPass(MachineCSEPass(), PMW);
+  CGMFPM.addPass(EarlyMachineLICMPass());
+  CGMFPM.addPass(MachineCSEPass());
 
-  addMachineFunctionPass(MachineSinkingPass(Opt.EnableSinkAndFold), PMW);
+  CGMFPM.addPass(MachineSinkingPass(Opt.EnableSinkAndFold));
 
-  addMachineFunctionPass(PeepholeOptimizerPass(), PMW);
+  CGMFPM.addPass(PeepholeOptimizerPass());
   // Clean-up the dead code that may have been generated by peephole
   // rewriting.
-  addMachineFunctionPass(DeadMachineInstructionElimPass(), PMW);
+  CGMFPM.addPass(DeadMachineInstructionElimPass());
 }
 
 //===---------------------------------------------------------------------===//
@@ -1147,11 +1118,11 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineSSAOptimization(
 /// check if Opt.RegAlloc == RegAllocType::Unset.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
-    PassManagerWrapper &PMW, bool Optimized) const {
+    CodeGenMachineFunctionPassManager &CGMFPM, bool Optimized) const {
   if (Optimized)
-    addMachineFunctionPass(RAGreedyPass(), PMW);
+    CGMFPM.addPass(RAGreedyPass());
   else
-    addMachineFunctionPass(RegAllocFastPass(), PMW);
+    CGMFPM.addPass(RegAllocFastPass());
 }
 
 /// Find and instantiate the register allocation pass requested by this target
@@ -1162,15 +1133,15 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
 /// even for targets that override the default allocator.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
-    PassManagerWrapper &PMW, bool Optimized) const {
+    CodeGenMachineFunctionPassManager &CGMFPM, bool Optimized) const {
   // Use the specified -regalloc-npm={basic|greedy|fast|pbqp}
   if (Opt.RegAlloc > RegAllocType::Default) {
     switch (Opt.RegAlloc) {
     case RegAllocType::Fast:
-      addMachineFunctionPass(RegAllocFastPass(), PMW);
+      CGMFPM.addPass(RegAllocFastPass());
       break;
     case RegAllocType::Greedy:
-      addMachineFunctionPass(RAGreedyPass(), PMW);
+      CGMFPM.addPass(RAGreedyPass());
       break;
     default:
       reportFatalUsageError("register allocator not supported yet");
@@ -1179,33 +1150,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(PMW, Optimized);
+  derived().addTargetRegisterAllocator(CGMFPM, Optimized);
 }
 
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignmentFast(
-    PassManagerWrapper &PMW) const {
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   // TODO: Ensure allocator is default or fast.
-  addRegAllocPass(PMW, false);
+  addRegAllocPass(CGMFPM, false);
   return Error::success();
 }
 
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignmentOptimized(
-    PassManagerWrapper &PMW) const {
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   // Add the selected register allocation pass.
-  addRegAllocPass(PMW, true);
+  addRegAllocPass(CGMFPM, true);
 
   // Allow targets to change the register assignments before rewriting.
-  derived().addPreRewrite(PMW);
+  derived().addPreRewrite(CGMFPM);
 
   // Finally rewrite virtual registers.
-  addMachineFunctionPass(VirtRegRewriterPass(), PMW);
+  CGMFPM.addPass(VirtRegRewriterPass());
   // Perform stack slot coloring and post-ra machine LICM.
   //
   // FIXME: Re-enable coloring with register when it's capable of adding
   // kill markers.
-  addMachineFunctionPass(StackSlotColoringPass(), PMW);
+  CGMFPM.addPass(StackSlotColoringPass());
 
   return Error::success();
 }
@@ -1214,10 +1185,10 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignmentOptimized(
 /// register allocation. No coalescing or scheduling.
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addFastRegAlloc(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(PHIEliminationPass(), PMW);
-  addMachineFunctionPass(TwoAddressInstructionPass(), PMW);
-  return derived().addRegAssignmentFast(PMW);
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(PHIEliminationPass());
+  CGMFPM.addPass(TwoAddressInstructionPass());
+  return derived().addRegAssignmentFast(CGMFPM);
 }
 
 /// Add standard target-independent passes that are tightly coupled with
@@ -1225,12 +1196,12 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addFastRegAlloc(
 /// scheduling, and register allocation itself.
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(DetectDeadLanesPass(), PMW);
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(DetectDeadLanesPass());
 
-  addMachineFunctionPass(InitUndefPass(), PMW);
+  CGMFPM.addPass(InitUndefPass());
 
-  addMachineFunctionPass(ProcessImplicitDefsPass(), PMW);
+  CGMFPM.addPass(ProcessImplicitDefsPass());
 
   // LiveVariables currently requires pure SSA form.
   //
@@ -1242,48 +1213,46 @@ Error 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.
-  addMachineFunctionPass(UnreachableMachineBlockElimPass(), PMW);
-  addMachineFunctionPass(
-      RequireAnalysisPass<LiveVariablesAnalysis, MachineFunction>(), PMW);
+  CGMFPM.addPass(UnreachableMachineBlockElimPass());
+  CGMFPM.addPass(RequireAnalysisPass<LiveVariablesAnalysis, MachineFunction>());
 
   // Edge splitting is smarter with machine loop info.
-  addMachineFunctionPass(
-      RequireAnalysisPass<MachineLoopAnalysis, MachineFunction>(), PMW);
-  addMachineFunctionPass(PHIEliminationPass(), PMW);
+  CGMFPM.addPass(RequireAnalysisPass<MachineLoopAnalysis, MachineFunction>());
+  CGMFPM.addPass(PHIEliminationPass());
 
   // Eventually, we want to run LiveIntervals before PHI elimination.
   if (Opt.EarlyLiveIntervals)
-    addMachineFunctionPass(
-        RequireAnalysisPass<LiveIntervalsAnalysis, MachineFunction>(), PMW);
+    CGMFPM.addPass(
+        RequireAnalysisPass<LiveIntervalsAnalysis, MachineFunction>());
 
-  addMachineFunctionPass(TwoAddressInstructionPass(), PMW);
-  addMachineFunctionPass(RegisterCoalescerPass(), PMW);
+  CGMFPM.addPass(TwoAddressInstructionPass());
+  CGMFPM.addPass(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.
-  addMachineFunctionPass(RenameIndependentSubregsPass(), PMW);
+  CGMFPM.addPass(RenameIndependentSubregsPass());
 
   // PreRA instruction scheduling.
-  addMachineFunctionPass(MachineSchedulerPass(&TM), PMW);
+  CGMFPM.addPass(MachineSchedulerPass(&TM));
 
-  if (auto E = derived().addRegAssignmentOptimized(PMW))
+  if (auto E = derived().addRegAssignmentOptimized(CGMFPM))
     return std::move(E);
 
-  addMachineFunctionPass(StackSlotColoringPass(), PMW);
+  CGMFPM.addPass(StackSlotColoringPass());
 
   // Allow targets to expand pseudo instructions depending on the choice of
   // registers before MachineCopyPropagation.
-  derived().addPostRewrite(PMW);
+  derived().addPostRewrite(CGMFPM);
 
   // Copy propagate to forward register uses and try to eliminate COPYs that
   // were not coalesced.
-  addMachineFunctionPass(MachineCopyPropagationPass(), PMW);
+  CGMFPM.addPass(MachineCopyPropagationPass());
 
   // Run post-ra machine LICM to hoist reloads / remats.
   //
   // FIXME: can this move into MachineLateOptimization?
-  addMachineFunctionPass(MachineLICMPass(), PMW);
+  CGMFPM.addPass(MachineLICMPass());
 
   return Error::success();
 }
@@ -1295,32 +1264,32 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
 /// Add passes that optimize machine instructions after register allocation.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineLateOptimization(
-    PassManagerWrapper &PMW) const {
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   // Cleanup of redundant (identical) address/immediate loads.
-  addMachineFunctionPass(MachineLateInstrsCleanupPass(), PMW);
+  CGMFPM.addPass(MachineLateInstrsCleanupPass());
 
   // Branch folding must be run after regalloc and prolog/epilog insertion.
-  addMachineFunctionPass(BranchFolderPass(Opt.EnableTailMerge), PMW);
+  CGMFPM.addPass(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())
-    addMachineFunctionPass(TailDuplicatePass(), PMW);
+    CGMFPM.addPass(TailDuplicatePass());
 
   // Copy propagation.
-  addMachineFunctionPass(MachineCopyPropagationPass(), PMW);
+  CGMFPM.addPass(MachineCopyPropagationPass());
 }
 
 /// Add standard basic block placement passes.
 template <typename Derived, typename TargetMachineT>
 void CodeGenPassBuilder<Derived, TargetMachineT>::addBlockPlacement(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(MachineBlockPlacementPass(Opt.EnableTailMerge), PMW);
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(MachineBlockPlacementPass(Opt.EnableTailMerge));
   // Run a separate pass to collect block placement statistics.
   if (Opt.EnableBlockPlacementStats)
-    addMachineFunctionPass(MachineBlockPlacementStatsPass(), PMW);
+    CGMFPM.addPass(MachineBlockPlacementStatsPass());
 }
 
 } // namespace llvm
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 8c2732630e2e6..a8e70f8603fb6 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -149,26 +149,28 @@ class AMDGPUCodeGenPassBuilder
                            const CGPassBuilderOption &Opts,
                            PassInstrumentationCallbacks *PIC);
 
-  void addIRPasses(PassManagerWrapper &PMW) const;
-  void addCodeGenPrepare(PassManagerWrapper &PMW) const;
-  void addPreISel(PassManagerWrapper &PMW) const;
-  void addILPOpts(PassManagerWrapper &PMWM) const;
-  void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
-  void addAsmPrinter(PassManagerWrapper &PMW) const;
-  void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
-  Error addInstSelector(PassManagerWrapper &PMW) const;
-  void addPreRewrite(PassManagerWrapper &PMW) const;
-  void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
-  void addPostRegAlloc(PassManagerWrapper &PMW) const;
-  void addPreEmitPass(PassManagerWrapper &PMWM) const;
-  void addPreEmitRegAlloc(PassManagerWrapper &PMW) const;
-  Error addRegAssignmentFast(PassManagerWrapper &PMW) const;
-  Error addRegAssignmentOptimized(PassManagerWrapper &PMW) const;
-  void addPreRegAlloc(PassManagerWrapper &PMW) const;
-  Error addFastRegAlloc(PassManagerWrapper &PMW) const;
-  Error addOptimizedRegAlloc(PassManagerWrapper &PMW) const;
-  void addPreSched2(PassManagerWrapper &PMW) const;
-  void addPostBBSections(PassManagerWrapper &PMW) const;
+  void addIRPasses(CodeGenModulePassManager &CGMPM) const;
+  CodeGenModulePassManager addCodeGenPrepare() const;
+  CodeGenModulePassManager addPreISel() const;
+  void addILPOpts(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addAsmPrinterBegin(CodeGenModulePassManager &CGMPM) const;
+  void addAsmPrinter(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addAsmPrinterEnd(CodeGenModulePassManager &CGMPM) const;
+  Error addInstSelector(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreRewrite(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void
+  addMachineSSAOptimization(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPostRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreEmitPass(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreEmitRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  Error addRegAssignmentFast(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  Error
+  addRegAssignmentOptimized(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  Error addFastRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  Error addOptimizedRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreSched2(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPostBBSections(CodeGenMachineFunctionPassManager &CGMFPM) const;
 
 private:
   Error validateRegAllocOptions() const;
@@ -179,8 +181,9 @@ class AMDGPUCodeGenPassBuilder
   /// 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(PassManagerWrapper &PMW) const;
-  void addStraightLineScalarOptimizationPasses(PassManagerWrapper &PMW) const;
+  void addEarlyCSEOrGVNPass(CodeGenFunctionPassManager &CGMFPM) const;
+  void addStraightLineScalarOptimizationPasses(
+      CodeGenFunctionPassManager &CGFPM) const;
 };
 
 class SGPRRegisterRegAlloc : public RegisterRegAllocBase<SGPRRegisterRegAlloc> {
@@ -2292,73 +2295,72 @@ AMDGPUCodeGenPassBuilder::AMDGPUCodeGenPassBuilder(
               ShadowStackGCLoweringPass, GCLoweringPass>();
 }
 
-void AMDGPUCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addIRPasses(
+    CodeGenModulePassManager &CGMPM) const {
   if (RemoveIncompatibleFunctions && TM.getTargetTriple().isAMDGCN()) {
-    flushFPMsToMPM(PMW);
-    addModulePass(AMDGPURemoveIncompatibleFunctionsPass(TM), PMW);
+    CGMPM.addPass(AMDGPURemoveIncompatibleFunctionsPass(TM));
   }
 
-  flushFPMsToMPM(PMW);
-
   if (TM.getTargetTriple().isAMDGCN())
-    addModulePass(AMDGPUPrintfRuntimeBindingPass(), PMW);
+    CGMPM.addPass(AMDGPUPrintfRuntimeBindingPass());
 
   if (LowerCtorDtor)
-    addModulePass(AMDGPUCtorDtorLoweringPass(), PMW);
+    CGMPM.addPass(AMDGPUCtorDtorLoweringPass());
 
+  CodeGenFunctionPassManager CGFPM;
   if (isPassEnabled(EnableImageIntrinsicOptimizer))
-    addFunctionPass(AMDGPUImageIntrinsicOptimizerPass(TM), PMW);
+    CGFPM.addPass(AMDGPUImageIntrinsicOptimizerPass(TM));
 
   if (EnableUniformIntrinsicCombine)
-    addFunctionPass(AMDGPUUniformIntrinsicCombinePass(), PMW);
+    CGFPM.addPass(AMDGPUUniformIntrinsicCombinePass());
   // This can be disabled by passing ::Disable here or on the command line
   // with --expand-variadics-override=disable.
-  flushFPMsToMPM(PMW);
-  addModulePass(ExpandVariadicsPass(ExpandVariadicsMode::Lowering), PMW);
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+  CGMPM.addPass(ExpandVariadicsPass(ExpandVariadicsMode::Lowering));
 
-  addModulePass(AMDGPUAlwaysInlinePass(), PMW);
-  addModulePass(AlwaysInlinerPass(), PMW);
+  CGMPM.addPass(AMDGPUAlwaysInlinePass());
+  CGMPM.addPass(AlwaysInlinerPass());
 
-  addModulePass(AMDGPUExportKernelRuntimeHandlesPass(), PMW);
+  CGMPM.addPass(AMDGPUExportKernelRuntimeHandlesPass());
 
   if (EnableLowerExecSync)
-    addModulePass(AMDGPULowerExecSyncPass(), PMW);
+    CGMPM.addPass(AMDGPULowerExecSyncPass());
 
   if (EnableSwLowerLDS)
-    addModulePass(AMDGPUSwLowerLDSPass(), PMW);
+    CGMPM.addPass(AMDGPUSwLowerLDSPass());
 
   // Runs before PromoteAlloca so the latter can account for function uses
   if (EnableLowerModuleLDS)
-    addModulePass(AMDGPULowerModuleLDSPass(TM), PMW);
+    CGMPM.addPass(AMDGPULowerModuleLDSPass(TM));
 
   // Run atomic optimizer before Atomic Expand
   if (TM.getOptLevel() >= CodeGenOptLevel::Less &&
       (AMDGPUAtomicOptimizerStrategy != ScanOptions::None))
-    addFunctionPass(
-        AMDGPUAtomicOptimizerPass(TM, AMDGPUAtomicOptimizerStrategy), PMW);
+    CGFPM.addPass(AMDGPUAtomicOptimizerPass(TM, AMDGPUAtomicOptimizerStrategy));
 
-  addFunctionPass(AtomicExpandPass(TM), PMW);
+  CGFPM.addPass(AtomicExpandPass(TM));
 
   if (TM.getOptLevel() > CodeGenOptLevel::None) {
-    addFunctionPass(AMDGPUPromoteAllocaPass(TM), PMW);
+    CGFPM.addPass(AMDGPUPromoteAllocaPass(TM));
     if (isPassEnabled(EnableScalarIRPasses))
-      addStraightLineScalarOptimizationPasses(PMW);
+      addStraightLineScalarOptimizationPasses(CGFPM);
 
     // TODO: Handle EnableAMDGPUAliasAnalysis
 
     // TODO: May want to move later or split into an early and late one.
-    addFunctionPass(AMDGPUCodeGenPreparePass(TM), PMW);
+    CGFPM.addPass(AMDGPUCodeGenPreparePass(TM));
 
     // Try to hoist loop invariant parts of divisions AMDGPUCodeGenPrepare may
     // have expanded.
     if (TM.getOptLevel() > CodeGenOptLevel::Less) {
-      addFunctionPass(createFunctionToLoopPassAdaptor(LICMPass(LICMOptions()),
-                                                      /*UseMemorySSA=*/true),
-                      PMW);
+      CodeGenLoopPassManager CGLPM;
+      CGLPM.addPass(LICMPass(LICMOptions()));
+      CGFPM.addCodeGenLoopPassManager(std::move(CGLPM), /*UseMemorySSA=*/true);
     }
   }
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 
-  Base::addIRPasses(PMW);
+  Base::addIRPasses(CGMPM);
 
   // EarlyCSE is not always strong enough to clean up what LSR produces. For
   // example, GVN can combine
@@ -2373,23 +2375,24 @@ void AMDGPUCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
   //
   // but EarlyCSE can do neither of them.
   if (isPassEnabled(EnableScalarIRPasses))
-    addEarlyCSEOrGVNPass(PMW);
+    addEarlyCSEOrGVNPass(CGFPM);
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 }
 
-void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(
-    PassManagerWrapper &PMW) const {
+CodeGenModulePassManager AMDGPUCodeGenPassBuilder::addCodeGenPrepare() const {
+  CodeGenModulePassManager CGMPM;
   if (TM.getOptLevel() > CodeGenOptLevel::None) {
-    flushFPMsToMPM(PMW);
-    addModulePass(AMDGPUPreloadKernelArgumentsPass(TM), PMW);
+    CGMPM.addPass(AMDGPUPreloadKernelArgumentsPass(TM));
   }
 
+  CodeGenFunctionPassManager CGFPM;
   if (EnableLowerKernelArguments)
-    addFunctionPass(AMDGPULowerKernelArgumentsPass(TM), PMW);
+    CGFPM.addPass(AMDGPULowerKernelArgumentsPass(TM));
 
-  Base::addCodeGenPrepare(PMW);
+  CGFPM.addPass(Base::addCodeGenPrepare());
 
   if (isPassEnabled(EnableLoadStoreVectorizer))
-    addFunctionPass(LoadStoreVectorizerPass(), PMW);
+    CGFPM.addPass(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).
@@ -2398,165 +2401,170 @@ void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(
   // 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.
-  flushFPMsToMPM(PMW);
-  addModulePass(AMDGPULowerBufferFatPointersPass(TM), PMW);
-  flushFPMsToMPM(PMW);
-  requireCGSCCOrder(PMW);
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+  CGMPM.addPass(AMDGPULowerBufferFatPointersPass(TM));
 
-  addModulePass(AMDGPULowerIntrinsicsPass(TM), PMW);
+  CGMPM.addPass(AMDGPULowerIntrinsicsPass(TM));
 
   // 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.
-  addFunctionPass(LowerSwitchPass(), PMW);
+  CGFPM.addPass(LowerSwitchPass());
+  CGMPM.addCodeGenFunctionPassManagerInCGSCCOrder(std::move(CGFPM));
+  return CGMPM;
 }
 
-void AMDGPUCodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
-
+CodeGenModulePassManager AMDGPUCodeGenPassBuilder::addPreISel() const {
+  CodeGenModulePassManager CGMPM;
+  CodeGenFunctionPassManager CGFPM;
   if (TM.getOptLevel() > CodeGenOptLevel::None) {
-    addFunctionPass(FlattenCFGPass(), PMW);
-    addFunctionPass(SinkingPass(), PMW);
-    addFunctionPass(AMDGPULateCodeGenPreparePass(TM), PMW);
+    CGFPM.addPass(FlattenCFGPass());
+    CGFPM.addPass(SinkingPass());
+    CGFPM.addPass(AMDGPULateCodeGenPreparePass(TM));
   }
 
   // Merge divergent exit nodes. StructurizeCFG won't recognize the multi-exit
   // regions formed by them.
 
-  addFunctionPass(AMDGPUUnifyDivergentExitNodesPass(), PMW);
-  addFunctionPass(FixIrreduciblePass(), PMW);
-  addFunctionPass(UnifyLoopExitsPass(), PMW);
-  addFunctionPass(StructurizeCFGPass(/*SkipUniformRegions=*/false), PMW);
+  CGFPM.addPass(AMDGPUUnifyDivergentExitNodesPass());
+  CGFPM.addPass(FixIrreduciblePass());
+  CGFPM.addPass(UnifyLoopExitsPass());
+  CGFPM.addPass(StructurizeCFGPass(/*SkipUniformRegions=*/false));
 
-  addFunctionPass(AMDGPUAnnotateUniformValuesPass(), PMW);
+  CGFPM.addPass(AMDGPUAnnotateUniformValuesPass());
 
-  addFunctionPass(SIAnnotateControlFlowPass(TM), PMW);
+  CGFPM.addPass(SIAnnotateControlFlowPass(TM));
 
   // TODO: Move this right after structurizeCFG to avoid extra divergence
   // analysis. This depends on stopping SIAnnotateControlFlow from making
   // control flow modifications.
-  addFunctionPass(AMDGPURewriteUndefForPHIPass(), PMW);
+  CGFPM.addPass(AMDGPURewriteUndefForPHIPass());
 
   if (getCGPassBuilderOption().EnableGlobalISelOption !=
           cl::boolOrDefault::BOU_TRUE ||
       !isGlobalISelAbortEnabled())
-    addFunctionPass(LCSSAPass(), PMW);
+    CGFPM.addPass(LCSSAPass());
 
   if (TM.getOptLevel() > CodeGenOptLevel::Less) {
-    flushFPMsToMPM(PMW);
-    addModulePass(AMDGPUPerfHintAnalysisPass(TM), PMW);
+    CGMPM.addCodeGenFunctionPassManagerInCGSCCOrder(std::move(CGFPM));
+    CGMPM.addPass(AMDGPUPerfHintAnalysisPass(TM));
   }
 
   // FIXME: Why isn't this queried as required from AMDGPUISelDAGToDAG, and why
   // isn't this in addInstSelector?
-  addFunctionPass(RequireAnalysisPass<UniformityInfoAnalysis, Function>(), PMW,
-                  /*Force=*/true);
+  CGFPM.addPass(RequireAnalysisPass<UniformityInfoAnalysis, Function>());
+  CGMPM.addCodeGenFunctionPassManagerInCGSCCOrder(std::move(CGFPM));
+  return CGMPM;
 }
 
-void AMDGPUCodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addILPOpts(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   if (EnableEarlyIfConversion)
-    addMachineFunctionPass(EarlyIfConverterPass(), PMW);
+    CGMFPM.addPass(EarlyIfConverterPass());
 
-  Base::addILPOpts(PMW);
+  Base::addILPOpts(CGMFPM);
 }
 
 void AMDGPUCodeGenPassBuilder::addAsmPrinterBegin(
-    PassManagerWrapper &PMW) const {
-  addModulePass(AMDGPUAsmPrinterBeginPass(), PMW,
-                /*Force=*/true);
+    CodeGenModulePassManager &CGMPM) const {
+  CGMPM.addPass(AMDGPUAsmPrinterBeginPass());
 }
 
-void AMDGPUCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(AMDGPUAsmPrinterPass(), PMW);
+void AMDGPUCodeGenPassBuilder::addAsmPrinter(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(AMDGPUAsmPrinterPass());
 }
 
-void AMDGPUCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
-  addModulePass(AMDGPUAsmPrinterEndPass(), PMW);
+void AMDGPUCodeGenPassBuilder::addAsmPrinterEnd(
+    CodeGenModulePassManager &CGMPM) const {
+  CGMPM.addPass(AMDGPUAsmPrinterEndPass());
 }
 
-Error AMDGPUCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(AMDGPUISelDAGToDAGPass(TM), PMW);
-  addMachineFunctionPass(SIFixSGPRCopiesPass(), PMW);
-  addMachineFunctionPass(SILowerI1CopiesPass(), PMW);
+Error AMDGPUCodeGenPassBuilder::addInstSelector(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(AMDGPUISelDAGToDAGPass(TM));
+  CGMFPM.addPass(SIFixSGPRCopiesPass());
+  CGMFPM.addPass(SILowerI1CopiesPass());
   return Error::success();
 }
 
-void AMDGPUCodeGenPassBuilder::addPreRewrite(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPreRewrite(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   if (EnableRegReassign) {
-    addMachineFunctionPass(GCNNSAReassignPass(), PMW);
+    CGMFPM.addPass(GCNNSAReassignPass());
   }
 
-  addMachineFunctionPass(AMDGPURewriteAGPRCopyMFMAPass(), PMW);
+  CGMFPM.addPass(AMDGPURewriteAGPRCopyMFMAPass());
 }
 
 void AMDGPUCodeGenPassBuilder::addMachineSSAOptimization(
-    PassManagerWrapper &PMW) const {
-  Base::addMachineSSAOptimization(PMW);
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  Base::addMachineSSAOptimization(CGMFPM);
 
-  addMachineFunctionPass(SIFoldOperandsPass(), PMW);
+  CGMFPM.addPass(SIFoldOperandsPass());
   if (EnableDPPCombine) {
-    addMachineFunctionPass(GCNDPPCombinePass(), PMW);
+    CGMFPM.addPass(GCNDPPCombinePass());
   }
-  addMachineFunctionPass(SILoadStoreOptimizerPass(), PMW);
+  CGMFPM.addPass(SILoadStoreOptimizerPass());
   if (isPassEnabled(EnableSDWAPeephole)) {
-    addMachineFunctionPass(SIPeepholeSDWAPass(), PMW);
-    addMachineFunctionPass(EarlyMachineLICMPass(), PMW);
-    addMachineFunctionPass(MachineCSEPass(), PMW);
-    addMachineFunctionPass(SIFoldOperandsPass(), PMW);
+    CGMFPM.addPass(SIPeepholeSDWAPass());
+    CGMFPM.addPass(EarlyMachineLICMPass());
+    CGMFPM.addPass(MachineCSEPass());
+    CGMFPM.addPass(SIFoldOperandsPass());
   }
-  addMachineFunctionPass(DeadMachineInstructionElimPass(), PMW);
-  addMachineFunctionPass(SIShrinkInstructionsPass(), PMW);
+  CGMFPM.addPass(DeadMachineInstructionElimPass());
+  CGMFPM.addPass(SIShrinkInstructionsPass());
 }
 
-Error AMDGPUCodeGenPassBuilder::addFastRegAlloc(PassManagerWrapper &PMW) const {
+Error AMDGPUCodeGenPassBuilder::addFastRegAlloc(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   insertPass<PHIEliminationPass>(SILowerControlFlowPass());
 
   insertPass<TwoAddressInstructionPass>(SIWholeQuadModePass());
 
-  return Base::addFastRegAlloc(PMW);
+  return Base::addFastRegAlloc(CGMFPM);
 }
 
 Error AMDGPUCodeGenPassBuilder::addRegAssignmentFast(
-    PassManagerWrapper &PMW) const {
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   if (auto Err = validateRegAllocOptions())
     return Err;
 
-  addMachineFunctionPass(GCNPreRALongBranchRegPass(), PMW);
+  CGMFPM.addPass(GCNPreRALongBranchRegPass());
 
   // SGPR allocation - default to fast at -O0.
   if (SGPRRegAllocNPM == RegAllocType::Greedy)
-    addMachineFunctionPass(RAGreedyPass({onlyAllocateSGPRs, "sgpr"}), PMW);
+    CGMFPM.addPass(RAGreedyPass({onlyAllocateSGPRs, "sgpr"}));
   else
-    addMachineFunctionPass(RegAllocFastPass({onlyAllocateSGPRs, "sgpr", false}),
-                           PMW);
+    CGMFPM.addPass(RegAllocFastPass({onlyAllocateSGPRs, "sgpr", false}));
 
   // Equivalent of PEI for SGPRs.
-  addMachineFunctionPass(SILowerSGPRSpillsPass(), PMW);
+  CGMFPM.addPass(SILowerSGPRSpillsPass());
 
   // To Allocate wwm registers used in whole quad mode operations (for shaders).
-  addMachineFunctionPass(SIPreAllocateWWMRegsPass(), PMW);
+  CGMFPM.addPass(SIPreAllocateWWMRegsPass());
 
   // WWM allocation - default to fast at -O0.
   if (WWMRegAllocNPM == RegAllocType::Greedy)
-    addMachineFunctionPass(RAGreedyPass({onlyAllocateWWMRegs, "wwm"}), PMW);
+    CGMFPM.addPass(RAGreedyPass({onlyAllocateWWMRegs, "wwm"}));
   else
-    addMachineFunctionPass(
-        RegAllocFastPass({onlyAllocateWWMRegs, "wwm", false}), PMW);
+    CGMFPM.addPass(RegAllocFastPass({onlyAllocateWWMRegs, "wwm", false}));
 
-  addMachineFunctionPass(SILowerWWMCopiesPass(), PMW);
-  addMachineFunctionPass(AMDGPUReserveWWMRegsPass(), PMW);
+  CGMFPM.addPass(SILowerWWMCopiesPass());
+  CGMFPM.addPass(AMDGPUReserveWWMRegsPass());
 
   // VGPR allocation - default to fast at -O0.
   if (VGPRRegAllocNPM == RegAllocType::Greedy)
-    addMachineFunctionPass(RAGreedyPass({onlyAllocateVGPRs, "vgpr"}), PMW);
+    CGMFPM.addPass(RAGreedyPass({onlyAllocateVGPRs, "vgpr"}));
   else
-    addMachineFunctionPass(RegAllocFastPass({onlyAllocateVGPRs, "vgpr"}), PMW);
+    CGMFPM.addPass(RegAllocFastPass({onlyAllocateVGPRs, "vgpr"}));
 
   return Error::success();
 }
 
 Error AMDGPUCodeGenPassBuilder::addOptimizedRegAlloc(
-    PassManagerWrapper &PMW) const {
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   if (EnableDCEInRA)
     insertPass<DetectDeadLanesPass>(DeadMachineInstructionElimPass());
 
@@ -2591,108 +2599,110 @@ Error AMDGPUCodeGenPassBuilder::addOptimizedRegAlloc(
   if (TM.getOptLevel() > CodeGenOptLevel::Less)
     insertPass<MachineSchedulerPass>(SIFormMemoryClausesPass());
 
-  return Base::addOptimizedRegAlloc(PMW);
+  return Base::addOptimizedRegAlloc(CGMFPM);
 }
 
-void AMDGPUCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPreRegAlloc(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   if (getOptLevel() != CodeGenOptLevel::None)
-    addMachineFunctionPass(AMDGPUPrepareAGPRAllocPass(), PMW);
+    CGMFPM.addPass(AMDGPUPrepareAGPRAllocPass());
 }
 
 Error AMDGPUCodeGenPassBuilder::addRegAssignmentOptimized(
-    PassManagerWrapper &PMW) const {
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   if (auto Err = validateRegAllocOptions())
     return Err;
 
-  addMachineFunctionPass(GCNPreRALongBranchRegPass(), PMW);
+  CGMFPM.addPass(GCNPreRALongBranchRegPass());
 
   // SGPR allocation - default to greedy at -O1 and above.
   if (SGPRRegAllocNPM == RegAllocType::Fast)
-    addMachineFunctionPass(RegAllocFastPass({onlyAllocateSGPRs, "sgpr", false}),
-                           PMW);
+    CGMFPM.addPass(RegAllocFastPass({onlyAllocateSGPRs, "sgpr", false}));
   else
-    addMachineFunctionPass(RAGreedyPass({onlyAllocateSGPRs, "sgpr"}), PMW);
+    CGMFPM.addPass(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.
-  addMachineFunctionPass(VirtRegRewriterPass(false), PMW);
+  CGMFPM.addPass(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.
-  addMachineFunctionPass(StackSlotColoringPass(), PMW);
+  CGMFPM.addPass(StackSlotColoringPass());
 
   // Equivalent of PEI for SGPRs.
-  addMachineFunctionPass(SILowerSGPRSpillsPass(), PMW);
+  CGMFPM.addPass(SILowerSGPRSpillsPass());
 
   // To Allocate wwm registers used in whole quad mode operations (for shaders).
-  addMachineFunctionPass(SIPreAllocateWWMRegsPass(), PMW);
+  CGMFPM.addPass(SIPreAllocateWWMRegsPass());
 
   // WWM allocation - default to greedy at -O1 and above.
   if (WWMRegAllocNPM == RegAllocType::Fast)
-    addMachineFunctionPass(
-        RegAllocFastPass({onlyAllocateWWMRegs, "wwm", false}), PMW);
+    CGMFPM.addPass(RegAllocFastPass({onlyAllocateWWMRegs, "wwm", false}));
   else
-    addMachineFunctionPass(RAGreedyPass({onlyAllocateWWMRegs, "wwm"}), PMW);
-  addMachineFunctionPass(SILowerWWMCopiesPass(), PMW);
-  addMachineFunctionPass(VirtRegRewriterPass(false), PMW);
-  addMachineFunctionPass(AMDGPUReserveWWMRegsPass(), PMW);
+    CGMFPM.addPass(RAGreedyPass({onlyAllocateWWMRegs, "wwm"}));
+  CGMFPM.addPass(SILowerWWMCopiesPass());
+  CGMFPM.addPass(VirtRegRewriterPass(false));
+  CGMFPM.addPass(AMDGPUReserveWWMRegsPass());
 
   // VGPR allocation - default to greedy at -O1 and above.
   if (VGPRRegAllocNPM == RegAllocType::Fast)
-    addMachineFunctionPass(RegAllocFastPass({onlyAllocateVGPRs, "vgpr"}), PMW);
+    CGMFPM.addPass(RegAllocFastPass({onlyAllocateVGPRs, "vgpr"}));
   else
-    addMachineFunctionPass(RAGreedyPass({onlyAllocateVGPRs, "vgpr"}), PMW);
+    CGMFPM.addPass(RAGreedyPass({onlyAllocateVGPRs, "vgpr"}));
 
-  addPreRewrite(PMW);
-  addMachineFunctionPass(VirtRegRewriterPass(true), PMW);
+  addPreRewrite(CGMFPM);
+  CGMFPM.addPass(VirtRegRewriterPass(true));
 
-  addMachineFunctionPass(AMDGPUMarkLastScratchLoadPass(), PMW);
+  CGMFPM.addPass(AMDGPUMarkLastScratchLoadPass());
   return Error::success();
 }
 
-void AMDGPUCodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(SIFixVGPRCopiesPass(), PMW);
+void AMDGPUCodeGenPassBuilder::addPostRegAlloc(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(SIFixVGPRCopiesPass());
   if (TM.getOptLevel() > CodeGenOptLevel::None)
-    addMachineFunctionPass(SIOptimizeExecMaskingPass(), PMW);
-  Base::addPostRegAlloc(PMW);
+    CGMFPM.addPass(SIOptimizeExecMaskingPass());
+  Base::addPostRegAlloc(CGMFPM);
 }
 
-void AMDGPUCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPreSched2(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   if (TM.getOptLevel() > CodeGenOptLevel::None)
-    addMachineFunctionPass(SIShrinkInstructionsPass(), PMW);
-  addMachineFunctionPass(SIPostRABundlerPass(), PMW);
+    CGMFPM.addPass(SIShrinkInstructionsPass());
+  CGMFPM.addPass(SIPostRABundlerPass());
 }
 
 void AMDGPUCodeGenPassBuilder::addPostBBSections(
-    PassManagerWrapper &PMW) const {
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   // We run this later to avoid passes like livedebugvalues and BBSections
   // having to deal with the apparent multi-entry functions we may generate.
-  addMachineFunctionPass(AMDGPUPreloadKernArgPrologPass(), PMW);
+  CGMFPM.addPass(AMDGPUPreloadKernArgPrologPass());
 }
 
-void AMDGPUCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPreEmitPass(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   if (isPassEnabled(EnableVOPD, CodeGenOptLevel::Less)) {
-    addMachineFunctionPass(GCNCreateVOPDPass(), PMW);
+    CGMFPM.addPass(GCNCreateVOPDPass());
   }
 
-  addMachineFunctionPass(SIMemoryLegalizerPass(), PMW);
-  addMachineFunctionPass(SIInsertWaitcntsPass(), PMW);
+  CGMFPM.addPass(SIMemoryLegalizerPass());
+  CGMFPM.addPass(SIInsertWaitcntsPass());
 
-  addMachineFunctionPass(SIModeRegisterPass(), PMW);
+  CGMFPM.addPass(SIModeRegisterPass());
 
   if (TM.getOptLevel() > CodeGenOptLevel::None)
-    addMachineFunctionPass(SIInsertHardClausesPass(), PMW);
+    CGMFPM.addPass(SIInsertHardClausesPass());
 
-  addMachineFunctionPass(SILateBranchLoweringPass(), PMW);
+  CGMFPM.addPass(SILateBranchLoweringPass());
 
   if (isPassEnabled(EnableSetWavePriority, CodeGenOptLevel::Less))
-    addMachineFunctionPass(AMDGPUSetWavePriorityPass(), PMW);
+    CGMFPM.addPass(AMDGPUSetWavePriorityPass());
 
   if (TM.getOptLevel() > CodeGenOptLevel::None)
-    addMachineFunctionPass(SIPreEmitPeepholePass(), PMW);
+    CGMFPM.addPass(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
@@ -2702,15 +2712,15 @@ void AMDGPUCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
   //
   // Here we add a stand-alone hazard recognizer pass which can handle all
   // cases.
-  addMachineFunctionPass(PostRAHazardRecognizerPass(), PMW);
-  addMachineFunctionPass(AMDGPUWaitSGPRHazardsPass(), PMW);
-  addMachineFunctionPass(AMDGPULowerVGPREncodingPass(), PMW);
+  CGMFPM.addPass(PostRAHazardRecognizerPass());
+  CGMFPM.addPass(AMDGPUWaitSGPRHazardsPass());
+  CGMFPM.addPass(AMDGPULowerVGPREncodingPass());
 
   if (isPassEnabled(EnableInsertDelayAlu, CodeGenOptLevel::Less)) {
-    addMachineFunctionPass(AMDGPUInsertDelayAluPass(), PMW);
+    CGMFPM.addPass(AMDGPUInsertDelayAluPass());
   }
 
-  addMachineFunctionPass(BranchRelaxationPass(), PMW);
+  CGMFPM.addPass(BranchRelaxationPass());
 }
 
 bool AMDGPUCodeGenPassBuilder::isPassEnabled(const cl::opt<bool> &Opt,
@@ -2723,32 +2733,32 @@ bool AMDGPUCodeGenPassBuilder::isPassEnabled(const cl::opt<bool> &Opt,
 }
 
 void AMDGPUCodeGenPassBuilder::addEarlyCSEOrGVNPass(
-    PassManagerWrapper &PMW) const {
+    CodeGenFunctionPassManager &CGFPM) const {
   if (TM.getOptLevel() == CodeGenOptLevel::Aggressive)
-    addFunctionPass(GVNPass(), PMW);
+    CGFPM.addPass(GVNPass());
   else
-    addFunctionPass(EarlyCSEPass(), PMW);
+    CGFPM.addPass(EarlyCSEPass());
 }
 
 void AMDGPUCodeGenPassBuilder::addStraightLineScalarOptimizationPasses(
-    PassManagerWrapper &PMW) const {
+    CodeGenFunctionPassManager &CGFPM) const {
   if (isPassEnabled(EnableLoopPrefetch, CodeGenOptLevel::Aggressive))
-    addFunctionPass(LoopDataPrefetchPass(), PMW);
+    CGFPM.addPass(LoopDataPrefetchPass());
 
-  addFunctionPass(SeparateConstOffsetFromGEPPass(), PMW);
+  CGFPM.addPass(SeparateConstOffsetFromGEPPass());
 
   // ReassociateGEPs exposes more opportunities for SLSR. See
   // the example in reassociate-geps-and-slsr.ll.
-  addFunctionPass(StraightLineStrengthReducePass(), PMW);
+  CGFPM.addPass(StraightLineStrengthReducePass());
 
   // SeparateConstOffsetFromGEP and SLSR creates common expressions which GVN or
   // EarlyCSE can reuse.
-  addEarlyCSEOrGVNPass(PMW);
+  addEarlyCSEOrGVNPass(CGFPM);
 
   // Run NaryReassociate after EarlyCSE/GVN to be more effective.
-  addFunctionPass(NaryReassociatePass(), PMW);
+  CGFPM.addPass(NaryReassociatePass());
 
   // NaryReassociate on GEPs creates redundant common expressions, so run
   // EarlyCSE after it.
-  addFunctionPass(EarlyCSEPass(), PMW);
+  CGFPM.addPass(EarlyCSEPass());
 }
diff --git a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
index 2d7dd12a94a56..d0d355c6e6f06 100644
--- a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
@@ -57,11 +57,11 @@ class R600CodeGenPassBuilder
   R600CodeGenPassBuilder(R600TargetMachine &TM, const CGPassBuilderOption &Opts,
                          PassInstrumentationCallbacks *PIC);
 
-  void addPreISel(PassManagerWrapper &PMW) const;
-  void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
-  void addAsmPrinter(PassManagerWrapper &PMW) const;
-  void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
-  Error addInstSelector(PassManagerWrapper &PMW) const;
+  CodeGenFunctionPassManager addPreISel() const;
+  void addAsmPrinterBegin(CodeGenModulePassManager &CGMPM) const;
+  void addAsmPrinter(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addAsmPrinterEnd(CodeGenModulePassManager &CGMPM) const;
+  Error addInstSelector(CodeGenMachineFunctionPassManager &CGMFPM) const;
 };
 
 //===----------------------------------------------------------------------===//
@@ -186,23 +186,28 @@ R600CodeGenPassBuilder::R600CodeGenPassBuilder(
   Opt.RequiresCodeGenSCCOrder = true;
 }
 
-void R600CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
+CodeGenFunctionPassManager R600CodeGenPassBuilder::addPreISel() const {
   // TODO: Add passes pre instruction selection.
+  return CodeGenFunctionPassManager();
 }
 
-void R600CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
+void R600CodeGenPassBuilder::addAsmPrinterBegin(
+    CodeGenModulePassManager &CGMPM) const {
   // TODO: Add AsmPrinterBegin
 }
 
-void R600CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
+void R600CodeGenPassBuilder::addAsmPrinter(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   // TODO: Add AsmPrinter.
 }
 
-void R600CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
+void R600CodeGenPassBuilder::addAsmPrinterEnd(
+    CodeGenModulePassManager &CGMPM) const {
   // TODO: Add AsmPrinterEnd
 }
 
-Error R600CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
+Error R600CodeGenPassBuilder::addInstSelector(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   // TODO: Add instruction selector.
   return Error::success();
 }
diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 62987bdbd1c2b..bbf9b7d0c1767 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -112,6 +112,7 @@ add_llvm_target(X86CodeGen ${sources}
   Instrumentation
   MC
   ObjCARC
+  Passes
   ProfileData
   Scalar
   SelectionDAG
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index e1762de764671..0381e694e8334 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -43,164 +43,176 @@ class X86CodeGenPassBuilder
                                  PassInstrumentationCallbacks *PIC)
       : CodeGenPassBuilder(TM, Opts, PIC) {}
 
-  void addIRPasses(PassManagerWrapper &PMW) const;
-  void addPreISel(PassManagerWrapper &PMW) const;
-  Error addInstSelector(PassManagerWrapper &PMW) const;
-  void addPreLegalizeMachineIR(PassManagerWrapper &PMW) const;
-  void addILPOpts(PassManagerWrapper &PMW) const;
-  void addPreRegBankSelect(PassManagerWrapper &PMW) const;
-  void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
-  void addPreRegAlloc(PassManagerWrapper &PMW) const;
+  void addIRPasses(CodeGenModulePassManager &CGMPM) const;
+  CodeGenModulePassManager addPreISel() const;
+  Error addInstSelector(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreLegalizeMachineIR(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addILPOpts(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreRegBankSelect(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void
+  addMachineSSAOptimization(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) const;
   // TODO(boomanaiden154): We need to add addPostFastRegAllocRewrite here once
   // it is available to support AMX.
-  void addPostRegAlloc(PassManagerWrapper &PMW) const;
-  void addPreSched2(PassManagerWrapper &PMW) const;
-  void addPreEmitPass(PassManagerWrapper &PMW) const;
-  void addPreEmitPass2(PassManagerWrapper &PMW) const;
+  void addPostRegAlloc(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreSched2(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreEmitPass(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreEmitPass2(CodeGenMachineFunctionPassManager &CGMFPM) const;
   // TODO(boomanaiden154): We need to add addRegAssignAndRewriteOptimized here
   // once it is available to support AMX.
-  void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
-  void addAsmPrinter(PassManagerWrapper &PMW) const;
-  void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
+  void addAsmPrinterBegin(CodeGenModulePassManager &CGMPM) const;
+  void addAsmPrinter(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addAsmPrinterEnd(CodeGenModulePassManager &CGMPM) const;
 };
 
-void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
-  addFunctionPass(AtomicExpandPass(TM), PMW);
+void X86CodeGenPassBuilder::addIRPasses(CodeGenModulePassManager &CGMPM) const {
+  CodeGenFunctionPassManager CGFPM;
+  CGFPM.addPass(AtomicExpandPass(TM));
 
   // We add both pass anyway and when these two passes run, one will be a
   // no-op based on the optimization level/attributes.
-  addFunctionPass(X86LowerAMXIntrinsicsPass(&TM), PMW);
-  addFunctionPass(X86LowerAMXTypePass(&TM), PMW);
+  CGFPM.addPass(X86LowerAMXIntrinsicsPass(&TM));
+  CGFPM.addPass(X86LowerAMXTypePass(&TM));
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 
-  Base::addIRPasses(PMW);
+  Base::addIRPasses(CGMPM);
 
   if (getOptLevel() != CodeGenOptLevel::None) {
-    addFunctionPass(InterleavedAccessPass(TM), PMW);
-    addFunctionPass(X86PartialReductionPass(&TM), PMW);
+    CGFPM.addPass(InterleavedAccessPass(TM));
+    CGFPM.addPass(X86PartialReductionPass(&TM));
   }
 
   // Add passes that handle indirect branch removal and insertion of a retpoline
   // thunk. These will be a no-op unless a function subtarget has the retpoline
   // feature enabled.
-  addFunctionPass(IndirectBrExpandPass(TM), PMW);
+  CGFPM.addPass(IndirectBrExpandPass(TM));
 
   // Add Control Flow Guard checks.
   const Triple &TT = TM.getTargetTriple();
   if (TT.isOSWindows())
-    addFunctionPass(CFGuardPass(), PMW);
+    CGFPM.addPass(CFGuardPass());
 
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
   if (TM.Options.JMCInstrument) {
-    flushFPMsToMPM(PMW);
-    addModulePass(JMCInstrumenterPass(), PMW);
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+    CGMPM.addPass(JMCInstrumenterPass());
   }
 }
 
-void X86CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
+CodeGenModulePassManager X86CodeGenPassBuilder::addPreISel() const {
+  CodeGenModulePassManager CGMPM;
   // Only add this pass for 32-bit x86 Windows.
   const Triple &TT = TM.getTargetTriple();
-  if (TT.isOSWindows() && TT.isX86_32()) {
-    flushFPMsToMPM(PMW);
-    addModulePass(X86WinEHStatePass(), PMW);
-  }
+  if (TT.isOSWindows() && TT.isX86_32())
+    CGMPM.addPass(X86WinEHStatePass());
+  return CGMPM;
 }
 
-Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(X86ISelDAGToDAGPass(TM), PMW);
+Error X86CodeGenPassBuilder::addInstSelector(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(X86ISelDAGToDAGPass(TM));
 
   // For ELF, cleanup any local-dynamic TLS accesses
   if (TM.getTargetTriple().isOSBinFormatELF() &&
       getOptLevel() != CodeGenOptLevel::None) {
-    addMachineFunctionPass(X86CleanupLocalDynamicTLSPass(), PMW);
+    CGMFPM.addPass(X86CleanupLocalDynamicTLSPass());
   }
 
-  addMachineFunctionPass(X86GlobalBaseRegPass(), PMW);
-  addMachineFunctionPass(X86ArgumentStackSlotPass(), PMW);
+  CGMFPM.addPass(X86GlobalBaseRegPass());
+  CGMFPM.addPass(X86ArgumentStackSlotPass());
   return Error::success();
 }
 
 void X86CodeGenPassBuilder::addPreLegalizeMachineIR(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(X86PreLegalizerCombinerPass(), PMW);
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(X86PreLegalizerCombinerPass());
 }
 
-void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(EarlyIfConverterPass(), PMW);
+void X86CodeGenPassBuilder::addILPOpts(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(EarlyIfConverterPass());
   if (X86EnableMachineCombinerPass) {
     // TODO(boomanaiden154): Add the MachineCombinerPass here once it has been
     // ported to the new pass manager.
   }
-  addMachineFunctionPass(X86CmovConversionPass(), PMW);
+  CGMFPM.addPass(X86CmovConversionPass());
 }
 
-void X86CodeGenPassBuilder::addPreRegBankSelect(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(X86PostLegalizerCombinerPass(), PMW);
+void X86CodeGenPassBuilder::addPreRegBankSelect(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(X86PostLegalizerCombinerPass());
 }
 
 void X86CodeGenPassBuilder::addMachineSSAOptimization(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(X86DomainReassignmentPass(), PMW);
-  Base::addMachineSSAOptimization(PMW);
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(X86DomainReassignmentPass());
+  Base::addMachineSSAOptimization(CGMFPM);
 }
 
-void X86CodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPreRegAlloc(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   if (getOptLevel() != CodeGenOptLevel::None) {
-    addMachineFunctionPass(LiveRangeShrinkPass(), PMW);
-    addMachineFunctionPass(X86FixupSetCCPass(), PMW);
-    addMachineFunctionPass(X86CallFrameOptimizationPass(), PMW);
-    addMachineFunctionPass(X86AvoidStoreForwardingBlocksPass(), PMW);
+    CGMFPM.addPass(LiveRangeShrinkPass());
+    CGMFPM.addPass(X86FixupSetCCPass());
+    CGMFPM.addPass(X86CallFrameOptimizationPass());
+    CGMFPM.addPass(X86AvoidStoreForwardingBlocksPass());
   }
 
-  addMachineFunctionPass(X86SuppressAPXForRelocationPass(), PMW);
-  addMachineFunctionPass(X86SpeculativeLoadHardeningPass(), PMW);
-  addMachineFunctionPass(X86FlagsCopyLoweringPass(), PMW);
-  addMachineFunctionPass(X86DynAllocaExpanderPass(), PMW);
+  CGMFPM.addPass(X86SuppressAPXForRelocationPass());
+  CGMFPM.addPass(X86SpeculativeLoadHardeningPass());
+  CGMFPM.addPass(X86FlagsCopyLoweringPass());
+  CGMFPM.addPass(X86DynAllocaExpanderPass());
 
   if (getOptLevel() != CodeGenOptLevel::None)
-    addMachineFunctionPass(X86PreTileConfigPass(), PMW);
+    CGMFPM.addPass(X86PreTileConfigPass());
   else
-    addMachineFunctionPass(X86FastPreTileConfigPass(), PMW);
+    CGMFPM.addPass(X86FastPreTileConfigPass());
 }
 
-void X86CodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(X86LowerTileCopyPass(), PMW);
-  addMachineFunctionPass(X86FPStackifierPass(), PMW);
+void X86CodeGenPassBuilder::addPostRegAlloc(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(X86LowerTileCopyPass());
+  CGMFPM.addPass(X86FPStackifierPass());
   // When -O0 is enabled, the Load Value Injection Hardening pass will fall back
   // to using the Speculative Execution Side Effect Suppression pass for
   // mitigation. This is to prevent slow downs due to
   // analyses needed by the LVIHardening pass when compiling at -O0.
   if (getOptLevel() != CodeGenOptLevel::None) {
-    addMachineFunctionPass(X86LoadValueInjectionLoadHardeningPass(), PMW);
+    CGMFPM.addPass(X86LoadValueInjectionLoadHardeningPass());
   }
 }
 
-void X86CodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(X86ExpandPseudoPass(), PMW);
-  addMachineFunctionPass(MachineKCFIPass(), PMW);
+void X86CodeGenPassBuilder::addPreSched2(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(X86ExpandPseudoPass());
+  CGMFPM.addPass(MachineKCFIPass());
 }
 
-void X86CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPreEmitPass(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   if (getOptLevel() != CodeGenOptLevel::None) {
     // TODO(boomanaiden154): Add X86ExecutionDomainFixPass here once it has
     // been ported.
-    addMachineFunctionPass(BreakFalseDepsPass(), PMW);
+    CGMFPM.addPass(BreakFalseDepsPass());
   }
 
-  addMachineFunctionPass(X86IndirectBranchTrackingPass(), PMW);
-  addMachineFunctionPass(X86InsertVZeroUpperPass(), PMW);
+  CGMFPM.addPass(X86IndirectBranchTrackingPass());
+  CGMFPM.addPass(X86InsertVZeroUpperPass());
 
   if (getOptLevel() != CodeGenOptLevel::None) {
-    addMachineFunctionPass(X86FixupBWInstsPass(), PMW);
+    CGMFPM.addPass(X86FixupBWInstsPass());
     // TODO(boomanaiden154): Add X86PadShortFunctionsPass here once it has been
     // ported.
-    addMachineFunctionPass(X86FixupLEAsPass(), PMW);
-    addMachineFunctionPass(X86FixupInstTuningPass(), PMW);
-    addMachineFunctionPass(X86FixupVectorConstantsPass(), PMW);
+    CGMFPM.addPass(X86FixupLEAsPass());
+    CGMFPM.addPass(X86FixupInstTuningPass());
+    CGMFPM.addPass(X86FixupVectorConstantsPass());
   }
-  addMachineFunctionPass(X86CompressEVEXPass(), PMW);
-  addMachineFunctionPass(X86InsertX87WaitPass(), PMW);
+  CGMFPM.addPass(X86CompressEVEXPass());
+  CGMFPM.addPass(X86InsertX87WaitPass());
 }
 
-void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPreEmitPass2(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
   const Triple &TT = TM.getTargetTriple();
   const MCAsmInfo &MAI = TM.getMCAsmInfo();
 
@@ -213,16 +225,15 @@ void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
   // passes don't move the code around the LFENCEs in a way that will hurt the
   // correctness of this pass. This placement has been shown to work based on
   // hand inspection of the codegen output.
-  addMachineFunctionPass(X86SpeculativeExecutionSideEffectSuppressionPass(),
-                         PMW);
+  CGMFPM.addPass(X86SpeculativeExecutionSideEffectSuppressionPass());
   // TODO(boomanaiden154): Add X86IndirectThunksPass here
   // once it has been ported.
-  addMachineFunctionPass(X86ReturnThunksPass(), PMW);
+  CGMFPM.addPass(X86ReturnThunksPass());
 
   // Insert extra int3 instructions after trailing call instructions to avoid
   // issues in the unwinder.
   if (TT.isOSWindows() && TT.isX86_64())
-    addMachineFunctionPass(X86AvoidTrailingCallPass(), PMW);
+    CGMFPM.addPass(X86AvoidTrailingCallPass());
 
   // Verify basic block incoming and outgoing cfa offset and register values and
   // correct CFA calculation rule where needed by inserting appropriate CFI
@@ -243,7 +254,7 @@ void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
     // ported.
   }
 
-  addMachineFunctionPass(X86LoadValueInjectionRetHardeningPass(), PMW);
+  CGMFPM.addPass(X86LoadValueInjectionRetHardeningPass());
 
   // Insert pseudo probe annotation for callsite profiling
   // TODO(boomanaiden154): Add PseudoProberInserterPass here once it has been
@@ -257,20 +268,23 @@ void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
   // Analyzes and emits pseudos to support Win x64 Unwind V2. This pass must run
   // after all real instructions have been added to the epilog.
   if (TT.isOSWindows() && TT.isX86_64()) {
-    addMachineFunctionPass(X86WinEHUnwindV2Pass(), PMW);
+    CGMFPM.addPass(X86WinEHUnwindV2Pass());
   }
 }
 
-void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
-  addModulePass(X86AsmPrinterBeginPass(), PMW, /*Force=*/true);
+void X86CodeGenPassBuilder::addAsmPrinterBegin(
+    CodeGenModulePassManager &CGMPM) const {
+  CGMPM.addPass(X86AsmPrinterBeginPass());
 }
 
-void X86CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(X86AsmPrinterPass(), PMW);
+void X86CodeGenPassBuilder::addAsmPrinter(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(X86AsmPrinterPass());
 }
 
-void X86CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
-  addModulePass(X86AsmPrinterEndPass(), PMW, /*Force=*/true);
+void X86CodeGenPassBuilder::addAsmPrinterEnd(
+    CodeGenModulePassManager &CGMPM) const {
+  CGMPM.addPass(X86AsmPrinterEndPass());
 }
 
 } // namespace
diff --git a/llvm/test/tools/llc/new-pm/start-stop-inserted.ll b/llvm/test/tools/llc/new-pm/start-stop-inserted.ll
index ce5ad2d9e5065..857127bbd62f8 100644
--- a/llvm/test/tools/llc/new-pm/start-stop-inserted.ll
+++ b/llvm/test/tools/llc/new-pm/start-stop-inserted.ll
@@ -3,10 +3,8 @@
 ; AMDGPU inserts the fourth instance of dead-mi-elimination pass after detect-dead-lanes
 ; This checks that the pipeline stops before that.
 
-; RUN: llc -mtriple=amdgcn-amd-amdhsa -O3 -enable-new-pm -stop-before=dead-mi-elimination,4 --print-pipeline-passes -filetype=null %s | FileCheck %s
-
-; There is no way to -start-after an inserted pass right now.
-; RUN: not llc -mtriple=amdgcn-amd-amdhsa -O3 -enable-new-pm -start-after=dead-mi-elimination,4 --print-pipeline-passes -filetype=null %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -O3 -enable-new-pm -stop-before=dead-mi-elimination,4 --print-pipeline-passes=tree -filetype=null %s | FileCheck %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -O3 -enable-new-pm -start-after=dead-mi-elimination,4 --print-pipeline-passes=tree -filetype=null %s
 
 
 ; CHECK: dead-mi-elimination
diff --git a/llvm/test/tools/llc/new-pm/start-stop.ll b/llvm/test/tools/llc/new-pm/start-stop.ll
index 829432238d626..29dee167fb07d 100644
--- a/llvm/test/tools/llc/new-pm/start-stop.ll
+++ b/llvm/test/tools/llc/new-pm/start-stop.ll
@@ -1,5 +1,5 @@
 ; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -start-before=gc-lowering -stop-after=gc-lowering -filetype=null %s | FileCheck --match-full-lines %s --check-prefix=NULL
 ; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -start-before=gc-lowering -stop-after=gc-lowering -o /dev/null %s | FileCheck --match-full-lines %s --check-prefix=OBJ
 
-; NULL: require<MachineModuleAnalysis>,require<profile-summary>,require<collector-metadata>,require<runtime-libcall-info>,require<libcall-lowering-info>,function(verify,gc-lowering,verify)
-; OBJ: require<MachineModuleAnalysis>,require<profile-summary>,require<collector-metadata>,require<runtime-libcall-info>,require<libcall-lowering-info>,function(verify,gc-lowering,verify),PrintMIRPreparePass,function(machine-function(print),free-machine-function)
+; NULL: require<MachineModuleAnalysis>,require<profile-summary>,require<collector-metadata>,require<runtime-libcall-info>,require<libcall-lowering-info>,function(verify,gc-lowering,verify,machine-function(require<live-vars>,require<machine-loops>),free-machine-function)
+; OBJ: require<MachineModuleAnalysis>,require<profile-summary>,require<collector-metadata>,require<runtime-libcall-info>,require<libcall-lowering-info>,function(verify,gc-lowering,verify),PrintMIRPreparePass,function(machine-function(require<live-vars>,require<machine-loops>,verify,print),free-machine-function)



More information about the llvm-commits mailing list