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

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 18 02:03:23 PDT 2026


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

>From 51c229589572f6cc18a22195a37ab0b4bd5e3089 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 | 238 ++++++++++++++++++
 llvm/lib/Passes/CMakeLists.txt                |   1 +
 llvm/lib/Passes/CodeGenPassManager.cpp        | 227 +++++++++++++++++
 3 files changed, 466 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..3ebec5c345d74
--- /dev/null
+++ b/llvm/include/llvm/Passes/CodeGenPassManager.h
@@ -0,0 +1,238 @@
+//===- 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<PassConceptT::unique_ptr> 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<LoopPassConceptT::unique_ptr,
+                         LoopNestPassConceptT::unique_ptr>>
+      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<PassConceptT::unique_ptr, 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<PassConceptT::unique_ptr, 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..2804e7fed0fb1
--- /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](LoopPassConceptT::unique_ptr &P) {
+        LPM.LoopPasses.push_back(std::move(P));
+        LPM.IsLoopNestPass.push_back(false);
+      },
+      [&LPM](LoopNestPassConceptT::unique_ptr &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](PassConceptT::unique_ptr &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](PassConceptT::unique_ptr &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{[&](PassConceptT::unique_ptr &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{[&](PassConceptT::unique_ptr &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)>,
+                              PassConceptT::unique_ptr>) {
+              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 e2dbaaa61b821f43f1d12ff3536c2e84cc4a8d70 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 | 757 +++++++++---------
 llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp |   5 +-
 .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 373 ++++-----
 llvm/lib/Target/AMDGPU/R600TargetMachine.cpp  |  25 +-
 llvm/lib/Target/BPF/BPFCodeGenPassBuilder.cpp |  63 +-
 llvm/lib/Target/Lanai/CMakeLists.txt          |   1 +
 .../Target/Lanai/LanaiCodeGenPassBuilder.cpp  |  52 +-
 llvm/lib/Target/MSP430/CMakeLists.txt         |   1 +
 .../MSP430/MSP430CodeGenPassBuilder.cpp       |  45 +-
 llvm/lib/Target/WebAssembly/CMakeLists.txt    |   1 +
 .../WebAssemblyCodeGenPassBuilder.cpp         |  75 +-
 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      |  32 +-
 15 files changed, 842 insertions(+), 783 deletions(-)

diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 6a93e61ea111d..0d371455c5fab 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,107 @@ 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); });
+
+  StringSet<> NotSkippable = {
+      FreeMachineFunctionPass::name(),
+      PrintMIRPass::name(),
+      PrintMIRPreparePass::name(),
+      RequireAnalysisPass<MachineModuleAnalysis, Module>::name(),
+      RequireAnalysisPass<ProfileSummaryAnalysis, Module>::name(),
+      RequireAnalysisPass<RuntimeLibraryAnalysis, Module>::name(),
+      RequireAnalysisPass<CollectorMetadataAnalysis, Module>::name(),
+      RequireAnalysisPass<LibcallLoweringModuleAnalysis, Module>::name(),
+      RequireAnalysisPass<PhysicalRegisterUsageAnalysis, Module>::name(),
+  };
+  CGMPM.eraseIf([this, &StartStopInfo, &NotSkippable, 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;
+        }
+      }
+    }
+    if (!Stopped && !StartStopInfo->StopPass.empty()) {
+      if (StopCount == StartStopInfo->StopInstanceNum)
+        Stopped = true;
+      if (PassName == StartStopInfo->StopPass) {
+        ++StopCount;
+        if (StopCount == StartStopInfo->StopInstanceNum) {
+          Stopped = !StartStopInfo->StopAfter;
         }
-        return Started;
       }
+    }
 
-      auto PassName = PIC->getPassNameForClassName(ClassName);
-      if (Info.StartPass == PassName && ++Count == Info.StartInstanceNum)
-        Started = !Info.StartAfter;
+    if (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 +630,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 +639,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 +751,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 +786,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 +866,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 +927,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 +991,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 +1070,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 +1124,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 +1139,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 +1156,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 +1191,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 +1202,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 +1219,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 +1270,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/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
index 97004dd6f743a..b7b502911e8fc 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
@@ -996,10 +996,13 @@ AMDGPUISelDAGToDAGPass::AMDGPUISelDAGToDAGPass(TargetMachine &TM)
 PreservedAnalyses
 AMDGPUISelDAGToDAGPass::run(MachineFunction &MF,
                             MachineFunctionAnalysisManager &MFAM) {
-#ifdef EXPENSIVE_CHECKS
   auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
                   .getManager();
   auto &F = MF.getFunction();
+  // Ensure UniformityInfoAnalysis::Result exist, this is optional
+  // in generic dag isel but required in AMDGPU isel.
+  FAM.getResult<UniformityInfoAnalysis>(F);
+#ifdef EXPENSIVE_CHECKS
   DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
   LoopInfo &LI = FAM.getResult<LoopAnalysis>(F);
   for (auto &L : LI.getLoopsInPreorder())
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 8c2732630e2e6..2afd2faf91225 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,167 @@ 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);
+  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 +2596,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 +2709,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 +2730,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/BPF/BPFCodeGenPassBuilder.cpp b/llvm/lib/Target/BPF/BPFCodeGenPassBuilder.cpp
index 089c926189c83..427db3d8f90b7 100644
--- a/llvm/lib/Target/BPF/BPFCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/BPF/BPFCodeGenPassBuilder.cpp
@@ -36,59 +36,66 @@ class BPFCodeGenPassBuilder
                                  PassInstrumentationCallbacks *PIC)
       : CodeGenPassBuilder(TM, Opts, PIC) {}
 
-  void addIRPasses(PassManagerWrapper &PMW) const;
-  Error addInstSelector(PassManagerWrapper &PMW) const;
-  void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
-  void addPreEmitPass(PassManagerWrapper &PMW) const;
-  void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
-  void addAsmPrinter(PassManagerWrapper &PMW) const;
-  void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
+  void addIRPasses(CodeGenModulePassManager &CGMPM) const;
+  Error addInstSelector(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void
+  addMachineSSAOptimization(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreEmitPass(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addAsmPrinterBegin(CodeGenModulePassManager &CGMPM) const;
+  void addAsmPrinter(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addAsmPrinterEnd(CodeGenModulePassManager &CGMPM) const;
 };
 
-void BPFCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
-  addFunctionPass(AtomicExpandPass(TM), PMW);
-  flushFPMsToMPM(PMW);
-  addModulePass(BPFCheckAndAdjustIRPass(), PMW);
+void BPFCodeGenPassBuilder::addIRPasses(CodeGenModulePassManager &CGMPM) const {
+  CodeGenFunctionPassManager CGFPM;
+  CGFPM.addPass(AtomicExpandPass(TM));
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+  CGMPM.addPass(BPFCheckAndAdjustIRPass());
 
-  Base::addIRPasses(PMW);
+  Base::addIRPasses(CGMPM);
 }
 
-Error BPFCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(BPFISelDAGToDAGPass(TM), PMW);
+Error BPFCodeGenPassBuilder::addInstSelector(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(BPFISelDAGToDAGPass(TM));
   return Error::success();
 }
 
 void BPFCodeGenPassBuilder::addMachineSSAOptimization(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(BPFMISimplifyPatchablePass(), PMW);
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(BPFMISimplifyPatchablePass());
 
-  Base::addMachineSSAOptimization(PMW);
+  Base::addMachineSSAOptimization(CGMFPM);
 
   const BPFSubtarget *Subtarget = TM.getSubtargetImpl();
   if (!DisableMIPeephole) {
     if (Subtarget->getHasAlu32())
-      addMachineFunctionPass(BPFMIPeepholePass(), PMW);
+      CGMFPM.addPass(BPFMIPeepholePass());
   }
 }
 
-void BPFCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(BPFMIPreEmitCheckingPass(), PMW);
+void BPFCodeGenPassBuilder::addPreEmitPass(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(BPFMIPreEmitCheckingPass());
   if (!DisableMIPeephole) {
-    addMachineFunctionPass(BPFMIExpandStackArgPseudosPass(), PMW);
-    addMachineFunctionPass(BPFMIPreEmitPeepholePass(), PMW);
+    CGMFPM.addPass(BPFMIExpandStackArgPseudosPass());
+    CGMFPM.addPass(BPFMIPreEmitPeepholePass());
   }
 }
 
-void BPFCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
-  addModulePass(BPFAsmPrinterBeginPass(), PMW, /*Force=*/true);
+void BPFCodeGenPassBuilder::addAsmPrinterBegin(
+    CodeGenModulePassManager &CGMPM) const {
+  CGMPM.addPass(BPFAsmPrinterBeginPass());
 }
 
-void BPFCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(BPFAsmPrinterPass(), PMW);
+void BPFCodeGenPassBuilder::addAsmPrinter(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(BPFAsmPrinterPass());
 }
 
-void BPFCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
-  addModulePass(BPFAsmPrinterEndPass(), PMW);
+void BPFCodeGenPassBuilder::addAsmPrinterEnd(
+    CodeGenModulePassManager &CGMPM) const {
+  CGMPM.addPass(BPFAsmPrinterEndPass());
 }
 
 } // namespace
diff --git a/llvm/lib/Target/Lanai/CMakeLists.txt b/llvm/lib/Target/Lanai/CMakeLists.txt
index bba75dd96ceb6..79ac0d049d533 100644
--- a/llvm/lib/Target/Lanai/CMakeLists.txt
+++ b/llvm/lib/Target/Lanai/CMakeLists.txt
@@ -44,6 +44,7 @@ add_llvm_target(LanaiCodeGen
   LanaiInfo
   MC
   ObjCARC
+  Passes
   Scalar
   SelectionDAG
   Support
diff --git a/llvm/lib/Target/Lanai/LanaiCodeGenPassBuilder.cpp b/llvm/lib/Target/Lanai/LanaiCodeGenPassBuilder.cpp
index 735a5f0386056..609e19800f361 100644
--- a/llvm/lib/Target/Lanai/LanaiCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/Lanai/LanaiCodeGenPassBuilder.cpp
@@ -30,45 +30,53 @@ class LanaiCodeGenPassBuilder
                                    PassInstrumentationCallbacks *PIC)
       : CodeGenPassBuilder(TM, Opts, PIC) {}
 
-  void addIRPasses(PassManagerWrapper &PMW) const;
-  Error addInstSelector(PassManagerWrapper &PMW) const;
-  void addPreSched2(PassManagerWrapper &PMW) const;
-  void addPreEmitPass(PassManagerWrapper &PMW) const;
-  void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
-  void addAsmPrinter(PassManagerWrapper &PMW) const;
-  void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
+  void addIRPasses(CodeGenModulePassManager &CGMPM) const;
+  Error addInstSelector(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreSched2(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreEmitPass(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addAsmPrinterBegin(CodeGenModulePassManager &CGMPM) const;
+  void addAsmPrinter(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addAsmPrinterEnd(CodeGenModulePassManager &CGMPM) const;
 };
 
-void LanaiCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
-  addFunctionPass(AtomicExpandPass(TM), PMW);
+void LanaiCodeGenPassBuilder::addIRPasses(
+    CodeGenModulePassManager &CGMPM) const {
+  CodeGenFunctionPassManager CGFPM;
+  CGFPM.addPass(AtomicExpandPass(TM));
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 
-  Base::addIRPasses(PMW);
+  Base::addIRPasses(CGMPM);
 }
 
-Error LanaiCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(LanaiISelDAGToDAGPass(TM), PMW);
+Error LanaiCodeGenPassBuilder::addInstSelector(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(LanaiISelDAGToDAGPass(TM));
   return Error::success();
 }
 
-void LanaiCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(LanaiMemAluCombinerPass(), PMW);
+void LanaiCodeGenPassBuilder::addPreSched2(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(LanaiMemAluCombinerPass());
 }
 
-void LanaiCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(LanaiDelaySlotFillerPass(), PMW);
+void LanaiCodeGenPassBuilder::addPreEmitPass(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(LanaiDelaySlotFillerPass());
 }
 
 void LanaiCodeGenPassBuilder::addAsmPrinterBegin(
-    PassManagerWrapper &PMW) const {
-  addModulePass(LanaiAsmPrinterBeginPass(), PMW, /*Force=*/true);
+    CodeGenModulePassManager &CGMPM) const {
+  CGMPM.addPass(LanaiAsmPrinterBeginPass());
 }
 
-void LanaiCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(LanaiAsmPrinterPass(), PMW);
+void LanaiCodeGenPassBuilder::addAsmPrinter(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(LanaiAsmPrinterPass());
 }
 
-void LanaiCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
-  addModulePass(LanaiAsmPrinterEndPass(), PMW, /*Force=*/true);
+void LanaiCodeGenPassBuilder::addAsmPrinterEnd(
+    CodeGenModulePassManager &CGMPM) const {
+  CGMPM.addPass(LanaiAsmPrinterEndPass());
 }
 
 } // namespace
diff --git a/llvm/lib/Target/MSP430/CMakeLists.txt b/llvm/lib/Target/MSP430/CMakeLists.txt
index 562adbbd5b369..efe0222fe42ec 100644
--- a/llvm/lib/Target/MSP430/CMakeLists.txt
+++ b/llvm/lib/Target/MSP430/CMakeLists.txt
@@ -41,6 +41,7 @@ add_llvm_target(MSP430CodeGen
   MSP430Desc
   MSP430Info
   ObjCARC
+  Passes
   Scalar
   SelectionDAG
   Support
diff --git a/llvm/lib/Target/MSP430/MSP430CodeGenPassBuilder.cpp b/llvm/lib/Target/MSP430/MSP430CodeGenPassBuilder.cpp
index a15ae42891268..48d70f53f44d0 100644
--- a/llvm/lib/Target/MSP430/MSP430CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/MSP430/MSP430CodeGenPassBuilder.cpp
@@ -32,40 +32,47 @@ class MSP430CodeGenPassBuilder
                                     PassInstrumentationCallbacks *PIC)
       : CodeGenPassBuilder(TM, Opts, PIC) {}
 
-  void addIRPasses(PassManagerWrapper &PMW) const;
-  Error addInstSelector(PassManagerWrapper &PMW) const;
-  void addPreEmitPass(PassManagerWrapper &PMW) const;
-  void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
-  void addAsmPrinter(PassManagerWrapper &PMW) const;
-  void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
+  void addIRPasses(CodeGenModulePassManager &CGMPM) const;
+  Error addInstSelector(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreEmitPass(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addAsmPrinterBegin(CodeGenModulePassManager &CGMPM) const;
+  void addAsmPrinter(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addAsmPrinterEnd(CodeGenModulePassManager &CGMPM) const;
 };
 
-void MSP430CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
-  addFunctionPass(AtomicExpandPass(TM), PMW);
+void MSP430CodeGenPassBuilder::addIRPasses(
+    CodeGenModulePassManager &CGMPM) const {
+  CodeGenFunctionPassManager CGFPM;
+  CGFPM.addPass(AtomicExpandPass(TM));
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 
-  Base::addIRPasses(PMW);
+  Base::addIRPasses(CGMPM);
 }
 
-Error MSP430CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(MSP430ISelDAGToDAGPass(TM, getOptLevel()), PMW);
+Error MSP430CodeGenPassBuilder::addInstSelector(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(MSP430ISelDAGToDAGPass(TM, getOptLevel()));
   return Error::success();
 }
 
-void MSP430CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(MSP430BranchSelectPass(), PMW);
+void MSP430CodeGenPassBuilder::addPreEmitPass(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(MSP430BranchSelectPass());
 }
 
 void MSP430CodeGenPassBuilder::addAsmPrinterBegin(
-    PassManagerWrapper &PMW) const {
-  addModulePass(MSP430AsmPrinterBeginPass(), PMW, /*Force=*/true);
+    CodeGenModulePassManager &CGMPM) const {
+  CGMPM.addPass(MSP430AsmPrinterBeginPass());
 }
 
-void MSP430CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(MSP430AsmPrinterPass(), PMW);
+void MSP430CodeGenPassBuilder::addAsmPrinter(
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(MSP430AsmPrinterPass());
 }
 
-void MSP430CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
-  addModulePass(MSP430AsmPrinterEndPass(), PMW);
+void MSP430CodeGenPassBuilder::addAsmPrinterEnd(
+    CodeGenModulePassManager &CGMPM) const {
+  CGMPM.addPass(MSP430AsmPrinterEndPass());
 }
 
 } // namespace
diff --git a/llvm/lib/Target/WebAssembly/CMakeLists.txt b/llvm/lib/Target/WebAssembly/CMakeLists.txt
index 1a73567f535bb..6bd8988d10363 100644
--- a/llvm/lib/Target/WebAssembly/CMakeLists.txt
+++ b/llvm/lib/Target/WebAssembly/CMakeLists.txt
@@ -92,6 +92,7 @@ add_llvm_target(WebAssemblyCodeGen
   GlobalISel
   MC
   ObjCARC
+  Passes
   Scalar
   SelectionDAG
   Support
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
index afd970ea8f577..53b231e6c847e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
@@ -75,27 +75,30 @@ class WebAssemblyCodeGenPassBuilder
       disablePass<RegisterCoalescerPass>();
   }
 
-  void addIRPasses(PassManagerWrapper &PMW) const;
-  void addISelPrepare(PassManagerWrapper &PMW) const;
-  Error addInstSelector(PassManagerWrapper &PMW) const;
-  void addPreEmitPass(PassManagerWrapper &PMW) const;
+  void addIRPasses(CodeGenModulePassManager &CGMPM) const;
+  void addISelPrepare(CodeGenModulePassManager &CGMPM) const;
+  Error addInstSelector(CodeGenMachineFunctionPassManager &CGMFPM) const;
+  void addPreEmitPass(CodeGenMachineFunctionPassManager &CGMFPM) const;
 };
 
-void WebAssemblyCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
+void WebAssemblyCodeGenPassBuilder::addIRPasses(
+    CodeGenModulePassManager &CGMPM) const {
+  CodeGenFunctionPassManager CGFPM;
   // Add signatures to prototype-less function declarations
-  flushFPMsToMPM(PMW);
-  addModulePass(WebAssemblyAddMissingPrototypesPass(), PMW);
+  CGMPM.addPass(WebAssemblyAddMissingPrototypesPass());
 
   // Lower .llvm.global_dtors into .llvm.global_ctors with __cxa_atexit calls.
-  addModulePass(LowerGlobalDtorsPass(), PMW);
+  CGMPM.addPass(LowerGlobalDtorsPass());
 
   // Fix function bitcasts, as WebAssembly requires caller and callee signatures
   // to match.
-  addModulePass(WebAssemblyFixFunctionBitcastsPass(), PMW);
+  CGMPM.addPass(WebAssemblyFixFunctionBitcastsPass());
+
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 
   // Optimize "returned" function attributes.
   if (getOptLevel() != CodeGenOptLevel::None)
-    addFunctionPass(WebAssemblyOptimizeReturnedPass(), PMW);
+    CGFPM.addPass(WebAssemblyOptimizeReturnedPass());
 
   // If exception handling is not enabled and setjmp/longjmp handling is
   // enabled, we lower invokes into calls and delete unreachable landingpad
@@ -104,10 +107,10 @@ void WebAssemblyCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
   // passes and Emscripten SjLj handling expects all invokes to be lowered
   // before.
   if (!WasmEnableEmEH && !WasmEnableEH) {
-    addFunctionPass(LowerInvokePass(), PMW);
+    CGFPM.addPass(LowerInvokePass());
     // The lower invoke pass may create unreachable code. Remove it in order not
     // to process dead blocks in setjmp/longjmp handling.
-    addFunctionPass(UnreachableBlockElimPass(), PMW);
+    CGFPM.addPass(UnreachableBlockElimPass());
   }
 
   // Handle exceptions and setjmp/longjmp if enabled. Unlike Wasm EH preparation
@@ -115,71 +118,75 @@ void WebAssemblyCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
   // transformation algorithms with Emscripten SjLj, so we run
   // LowerEmscriptenEHSjLj pass also when Wasm SjLj is enabled.
   if (WasmEnableEmEH || WasmEnableEmSjLj || WasmEnableSjLj) {
-    flushFPMsToMPM(PMW);
-    addModulePass(WebAssemblyLowerEmscriptenEHSjLjPass(), PMW);
+    CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+    CGMPM.addPass(WebAssemblyLowerEmscriptenEHSjLjPass());
   }
 
   // Expand indirectbr instructions to switches.
-  addFunctionPass(IndirectBrExpandPass(TM), PMW);
+  CGFPM.addPass(IndirectBrExpandPass(TM));
 
   // Try to expand `vecreduce_{and, or}` into `{any, all}_true`.
-  addFunctionPass(WebAssemblyReduceToAnyAllTruePass(TM), PMW);
+  CGFPM.addPass(WebAssemblyReduceToAnyAllTruePass(TM));
+
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
 
-  Base::addIRPasses(PMW);
+  Base::addIRPasses(CGMPM);
 }
 
 void WebAssemblyCodeGenPassBuilder::addISelPrepare(
-    PassManagerWrapper &PMW) const {
+    CodeGenModulePassManager &CGMPM) const {
+  CodeGenFunctionPassManager CGFPM;
   // We need to move reference type allocas to WASM_ADDRESS_SPACE_VAR so that
   // loads and stores are promoted to local.gets/local.sets.
-  addFunctionPass(WebAssemblyRefTypeMem2LocalPass(), PMW);
+  CGFPM.addPass(WebAssemblyRefTypeMem2LocalPass());
   // Lower atomics and TLS if necessary
-  flushFPMsToMPM(PMW);
-  addModulePass(WebAssemblyCoalesceFeaturesAndStripAtomicsPass(TM), PMW);
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+  CGMPM.addPass(WebAssemblyCoalesceFeaturesAndStripAtomicsPass(TM));
 
   // This is a no-op if atomics are not used in the module
-  addFunctionPass(AtomicExpandPass(TM), PMW);
+  CGFPM.addPass(AtomicExpandPass(TM));
 
-  Base::addISelPrepare(PMW);
+  CGMPM.addCodeGenFunctionPassManager(std::move(CGFPM));
+  Base::addISelPrepare(CGMPM);
 }
 
 Error WebAssemblyCodeGenPassBuilder::addInstSelector(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(WebAssemblyISelDAGToDAGPass(TM, getOptLevel()), PMW);
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  CGMFPM.addPass(WebAssemblyISelDAGToDAGPass(TM, getOptLevel()));
 
   // Run the argument-move pass immediately after the ScheduleDAG scheduler
   // so that we can fix up the ARGUMENT instructions before anything else
   // sees them in the wrong place.
-  addMachineFunctionPass(WebAssemblyArgumentMovePass(), PMW);
+  CGMFPM.addPass(WebAssemblyArgumentMovePass());
 
   // Set the p2align operands. This information is present during ISel, however
   // it's inconvenient to collect. Collect it now, and update the immediate
   // operands.
-  addMachineFunctionPass(WebAssemblySetP2AlignOperandsPass(), PMW);
+  CGMFPM.addPass(WebAssemblySetP2AlignOperandsPass());
 
   // Eliminate range checks and add default targets to br_table instructions.
-  addMachineFunctionPass(WebAssemblyFixBrTableDefaultsPass(), PMW);
+  CGMFPM.addPass(WebAssemblyFixBrTableDefaultsPass());
 
   // unreachable is terminator, non-terminator instruction after it is not
   // allowed.
-  addMachineFunctionPass(WebAssemblyCleanCodeAfterTrapPass(), PMW);
+  CGMFPM.addPass(WebAssemblyCleanCodeAfterTrapPass());
 
   return Error::success();
 }
 
 void WebAssemblyCodeGenPassBuilder::addPreEmitPass(
-    PassManagerWrapper &PMW) const {
-  Base::addPreEmitPass(PMW);
+    CodeGenMachineFunctionPassManager &CGMFPM) const {
+  Base::addPreEmitPass(CGMFPM);
 
   // Nullify DBG_VALUE_LISTs that we cannot handle.
-  addMachineFunctionPass(WebAssemblyNullifyDebugValueListsPass(), PMW);
+  CGMFPM.addPass(WebAssemblyNullifyDebugValueListsPass());
 
   // Remove any unreachable blocks that may be left floating around.
   // Rare, but possible. Needed for WebAssemblyFixIrreducibleControlFlow.
-  addMachineFunctionPass(UnreachableMachineBlockElimPass(), PMW);
+  CGMFPM.addPass(UnreachableMachineBlockElimPass());
 
   // Eliminate multiple-entry loops.
-  addMachineFunctionPass(WebAssemblyFixIrreducibleControlFlowPass(), PMW);
+  CGMFPM.addPass(WebAssemblyFixIrreducibleControlFlowPass());
 
   // Do various transformations for exception handling.
   // Every CFG-changing optimizations should come before this.
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..624fc712c217c 100644
--- a/llvm/test/tools/llc/new-pm/start-stop.ll
+++ b/llvm/test/tools/llc/new-pm/start-stop.ll
@@ -1,5 +1,29 @@
-; 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
+; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes=tree -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=tree -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>
+; NULL-NEXT: require<profile-summary>
+; NULL-NEXT: require<collector-metadata>
+; NULL-NEXT: require<runtime-libcall-info>
+; NULL-NEXT: require<libcall-lowering-info>
+; NULL-NEXT: function
+; NULL-NEXT:   verify
+; NULL-NEXT:   gc-lowering
+; NULL-NEXT:   verify
+; NULL-NEXT:   free-machine-function
+
+; OBJ:      require<MachineModuleAnalysis>
+; OBJ-NEXT: require<profile-summary>
+; OBJ-NEXT: require<collector-metadata>
+; OBJ-NEXT: require<runtime-libcall-info>
+; OBJ-NEXT: require<libcall-lowering-info>
+; OBJ-NEXT: function
+; OBJ-NEXT:   verify
+; OBJ-NEXT:   gc-lowering
+; OBJ-NEXT:   verify
+; OBJ-NEXT: PrintMIRPreparePass
+; OBJ-NEXT: function
+; OBJ-NEXT:   machine-function
+; OBJ-NEXT:     verify
+; OBJ-NEXT:     print
+; OBJ-NEXT:   free-machine-function



More information about the llvm-commits mailing list