[llvm] [CodeGen] Replace CodeGenPassBuilder CRTP with virtual hooks (PR #216468)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 15 01:27:24 PDT 2026


https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/216468

Make the hooks that were dispatched through derived() virtual, drop both
template parameters, and outline the pipeline into
lib/Passes/CodeGenPassBuilder.cpp, mirroring TargetPassConfig. The pass
headers move out of CodeGenPassBuilder.h.

The outlined bodies are moved verbatim, apart from dropping now-redundant
std::move on returned Errors.

MSP430CodeGenPassBuilder.cpp.o .text: 84685 -> 11240 (-87%); compile
time: 1.75s -> 0.64s. llc .text: -293824 bytes; .data.rel.ro: +2784 (the
9 new vtables). The vtable slots are link-time constants in the default
non-PIE llc; with -pie they become 333 relative relocations, which RELR
packs into 40 bytes.

Overriding is now compiler-checked, which surfaced
AMDGPUCodeGenPassBuilder::addPreEmitRegAlloc (not a hook, never defined
or called); remove it. Add `Passes` dependency to targets that are
missing it.

A function pointer table in the builder, as `PassConcept` uses, avoids the
vtables but measures larger.

LLM-aided


>From c514424eb2627431c7e4b29250514efec652c3f7 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Fri, 14 Aug 2026 21:42:53 -0700
Subject: [PATCH] [CodeGen] Replace CodeGenPassBuilder CRTP with virtual hooks

Make the hooks that were dispatched through derived() virtual, drop both
template parameters, and outline the pipeline into
lib/Passes/CodeGenPassBuilder.cpp, mirroring TargetPassConfig. The pass
headers move out of CodeGenPassBuilder.h.

The outlined bodies are moved verbatim, apart from dropping now-redundant
std::move on returned Errors.

MSP430CodeGenPassBuilder.cpp.o .text: 84685 -> 11240 (-87%); compile
time: 1.75s -> 0.64s. llc .text: -293824 bytes; .data.rel.ro: +2784 (the
9 new vtables). The vtable slots are link-time constants in the default
non-PIE llc; with -pie they become 333 relative relocations, which RELR
packs into 40 bytes.

Overriding is now compiler-checked, which surfaced
AMDGPUCodeGenPassBuilder::addPreEmitRegAlloc (not a hook, never defined
or called); remove it. Add `Passes` dependency to targets that are
missing it.

A function pointer table in the builder, as `PassConcept` uses, avoids the
vtables but measures larger.

LLM-aided
---
 llvm/include/llvm/Passes/CodeGenPassBuilder.h | 1072 ++---------------
 llvm/lib/Passes/CodeGenPassBuilder.cpp        |  927 +++++++++++++-
 .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp |  120 +-
 llvm/lib/Target/AMDGPU/R600TargetMachine.cpp  |   23 +-
 llvm/lib/Target/BPF/BPFCodeGenPassBuilder.cpp |   42 +-
 llvm/lib/Target/Lanai/CMakeLists.txt          |    1 +
 .../Target/Lanai/LanaiCodeGenPassBuilder.cpp  |   40 +-
 llvm/lib/Target/MSP430/CMakeLists.txt         |    1 +
 .../MSP430/MSP430CodeGenPassBuilder.cpp       |   37 +-
 .../Target/RISCV/RISCVCodeGenPassBuilder.cpp  |   66 +-
 llvm/lib/Target/WebAssembly/CMakeLists.txt    |    1 +
 .../WebAssemblyCodeGenPassBuilder.cpp         |   60 +-
 llvm/lib/Target/X86/CMakeLists.txt            |    1 +
 llvm/lib/Target/X86/X86AsmPrinter.cpp         |    1 +
 llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp |   76 +-
 15 files changed, 1247 insertions(+), 1221 deletions(-)

diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 11e448dd7f78b..7eeab0db58f3c 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -14,116 +14,18 @@
 #ifndef LLVM_PASSES_CODEGENPASSBUILDER_H
 #define LLVM_PASSES_CODEGENPASSBUILDER_H
 
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/CGSCCPassManager.h"
-#include "llvm/Analysis/ProfileSummaryInfo.h"
-#include "llvm/Analysis/RuntimeLibcallInfo.h"
-#include "llvm/Analysis/ScopedNoAliasAA.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
-#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/AsmPrinterAnalysis.h"
-#include "llvm/CodeGen/BranchFoldingPass.h"
-#include "llvm/CodeGen/CodeGenPrepare.h"
-#include "llvm/CodeGen/DeadMachineInstructionElim.h"
-#include "llvm/CodeGen/DetectDeadLanes.h"
-#include "llvm/CodeGen/DwarfEHPrepare.h"
-#include "llvm/CodeGen/ExpandIRInsts.h"
-#include "llvm/CodeGen/ExpandPostRAPseudos.h"
-#include "llvm/CodeGen/ExpandReductions.h"
-#include "llvm/CodeGen/FEntryInserter.h"
-#include "llvm/CodeGen/FinalizeISel.h"
-#include "llvm/CodeGen/FixupStatepointCallerSaved.h"
-#include "llvm/CodeGen/GCEmptyBasicBlocks.h"
-#include "llvm/CodeGen/GCMetadata.h"
-#include "llvm/CodeGen/GlobalMerge.h"
-#include "llvm/CodeGen/GlobalMergeFunctions.h"
-#include "llvm/CodeGen/IndirectBrExpand.h"
-#include "llvm/CodeGen/InitUndef.h"
-#include "llvm/CodeGen/InlineAsmPrepare.h"
-#include "llvm/CodeGen/InterleavedAccess.h"
-#include "llvm/CodeGen/InterleavedLoadCombine.h"
-#include "llvm/CodeGen/LiveDebugValuesPass.h"
-#include "llvm/CodeGen/LiveIntervals.h"
-#include "llvm/CodeGen/LiveVariables.h"
-#include "llvm/CodeGen/LocalStackSlotAllocation.h"
-#include "llvm/CodeGen/LowerEmuTLS.h"
-#include "llvm/CodeGen/MIRPrinter.h"
-#include "llvm/CodeGen/MachineBlockPlacement.h"
-#include "llvm/CodeGen/MachineCSE.h"
-#include "llvm/CodeGen/MachineCopyPropagation.h"
-#include "llvm/CodeGen/MachineFunctionAnalysis.h"
-#include "llvm/CodeGen/MachineLICM.h"
-#include "llvm/CodeGen/MachineLateInstrsCleanup.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachinePassManager.h"
-#include "llvm/CodeGen/MachineScheduler.h"
-#include "llvm/CodeGen/MachineSink.h"
-#include "llvm/CodeGen/MachineVerifier.h"
-#include "llvm/CodeGen/OptimizePHIs.h"
-#include "llvm/CodeGen/PEI.h"
-#include "llvm/CodeGen/PHIElimination.h"
-#include "llvm/CodeGen/PatchableFunction.h"
-#include "llvm/CodeGen/PeepholeOptimizer.h"
-#include "llvm/CodeGen/PostRAMachineSink.h"
-#include "llvm/CodeGen/PostRASchedulerList.h"
-#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
-#include "llvm/CodeGen/ProcessImplicitDefs.h"
-#include "llvm/CodeGen/RegAllocEvictionAdvisor.h"
-#include "llvm/CodeGen/RegAllocFast.h"
-#include "llvm/CodeGen/RegAllocGreedyPass.h"
-#include "llvm/CodeGen/RegUsageInfoCollector.h"
-#include "llvm/CodeGen/RegUsageInfoPropagate.h"
-#include "llvm/CodeGen/RegisterCoalescerPass.h"
-#include "llvm/CodeGen/RegisterUsageInfo.h"
-#include "llvm/CodeGen/RemoveLoadsIntoFakeUses.h"
-#include "llvm/CodeGen/RemoveRedundantDebugValues.h"
-#include "llvm/CodeGen/RenameIndependentSubregs.h"
-#include "llvm/CodeGen/ReplaceWithVeclib.h"
-#include "llvm/CodeGen/SafeStack.h"
-#include "llvm/CodeGen/SanitizerBinaryMetadata.h"
-#include "llvm/CodeGen/SelectOptimize.h"
-#include "llvm/CodeGen/ShadowStackGCLowering.h"
-#include "llvm/CodeGen/ShrinkWrap.h"
-#include "llvm/CodeGen/SjLjEHPrepare.h"
-#include "llvm/CodeGen/StackColoring.h"
-#include "llvm/CodeGen/StackFrameLayoutAnalysisPass.h"
-#include "llvm/CodeGen/StackProtector.h"
-#include "llvm/CodeGen/StackSlotColoring.h"
-#include "llvm/CodeGen/TailDuplication.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
-#include "llvm/CodeGen/TwoAddressInstructionPass.h"
-#include "llvm/CodeGen/UnreachableBlockElim.h"
-#include "llvm/CodeGen/VirtRegMap.h"
-#include "llvm/CodeGen/WasmEHPrepare.h"
-#include "llvm/CodeGen/WinEHPrepare.h"
-#include "llvm/CodeGen/XRayInstrumentation.h"
 #include "llvm/IR/PassManager.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/IRPrinter/IRPrintingPasses.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCTargetOptions.h"
-#include "llvm/MC/TargetRegistry.h"
 #include "llvm/Support/CodeGen.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Error.h"
-#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Target/CGPassBuilderOption.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/ObjCARC.h"
-#include "llvm/Transforms/Scalar/ConstantHoisting.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
-#include "llvm/Transforms/Scalar/LoopStrengthReduce.h"
-#include "llvm/Transforms/Scalar/LoopTermFold.h"
-#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
-#include "llvm/Transforms/Scalar/MergeICmps.h"
-#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
-#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
-#include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
-#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
-#include "llvm/Transforms/Utils/LowerInvoke.h"
 #include <cassert>
 #include <utility>
 
@@ -163,7 +65,6 @@ class PassManagerWrapper {
   FunctionPassManager FPM;
   MachineFunctionPassManager MFPM;
 
-  template <typename DerivedT, typename TargetMachineT>
   friend class CodeGenPassBuilder;
 };
 
@@ -173,41 +74,26 @@ class PassManagerWrapper {
 /// construction. The \c MachinePassRegistry.def file specifies how to construct
 /// all of the built-in passes, and those may reference these members during
 /// construction.
-template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
+///
+/// Targets customize the pipeline by deriving from this class and overriding
+/// the virtual add* hooks below: the add%Stage hooks replace a whole stage of
+/// the pipeline, while the addPre%Stage / addPost%Stage hooks inject passes
+/// around one. See addMachinePasses for how they fit together.
+///
+/// Dispatch is virtual rather than templated on the derived builder so that the
+/// target-independent pipeline is emitted once for the whole build instead of
+/// once per target.
+class LLVM_ABI CodeGenPassBuilder {
 public:
-  explicit CodeGenPassBuilder(TargetMachineT &TM,
-                              const CGPassBuilderOption &Opts,
-                              PassInstrumentationCallbacks *PIC)
-      : TM(TM), Opt(Opts), PIC(PIC) {
-    // Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
-    //     substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
-
-    // Target should override TM.Options.EnableIPRA in their target-specific
-    // LLVMTM ctor. See TargetMachine::setGlobalISel for example.
-    if (Opt.EnableIPRA) {
-      TM.Options.EnableIPRA = *Opt.EnableIPRA;
-    } else {
-      // If not explicitly specified, use target default.
-      TM.Options.EnableIPRA |= TM.useIPRA();
-    }
-
-    if (Opt.EnableGlobalISelAbort)
-      TM.Options.GlobalISelAbort = *Opt.EnableGlobalISelAbort;
-
-    // An explicit RegAlloc choice implies its pipeline: only the fast
-    // allocator uses the unoptimized one.
-    if (Opt.OptimizeRegAlloc == cl::boolOrDefault::BOU_UNSET) {
-      bool Optimized = Opt.RegAlloc > RegAllocType::Default
-                           ? Opt.RegAlloc != RegAllocType::Fast
-                           : getOptLevel() != CodeGenOptLevel::None;
-      Opt.OptimizeRegAlloc = Optimized ? cl::boolOrDefault::BOU_TRUE
-                                       : cl::boolOrDefault::BOU_FALSE;
-    }
-  }
+  CodeGenPassBuilder(TargetMachine &TM, const CGPassBuilderOption &Opts,
+                     PassInstrumentationCallbacks *PIC);
+  CodeGenPassBuilder(const CodeGenPassBuilder &) = delete;
+  CodeGenPassBuilder &operator=(const CodeGenPassBuilder &) = delete;
+  virtual ~CodeGenPassBuilder();
 
   Error buildPipeline(ModulePassManager &MPM, ModuleAnalysisManager &MAM,
                       raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
-                      CodeGenFileType FileType, MCContext &Ctx) const;
+                      CodeGenFileType FileType, MCContext &Ctx);
 
   PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
     return PIC;
@@ -229,8 +115,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   template <typename PassT>
   void addFunctionPass(PassT &&Pass, PassManagerWrapper &PMW,
-                       bool Force = false,
-                       StringRef Name = PassT::name()) const {
+                       bool Force = false, StringRef Name = PassT::name()) {
     static_assert(is_detected<is_function_pass_t, PassT>::value &&
                   "Only function passes are supported.");
     if (!Force && !runBeforeAdding(Name))
@@ -240,7 +125,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   template <typename PassT>
   void addModulePass(PassT &&Pass, PassManagerWrapper &PMW, bool Force = false,
-                     StringRef Name = PassT::name()) const {
+                     StringRef Name = PassT::name()) {
     static_assert(is_detected<is_module_pass_t, PassT>::value &&
                   "Only module passes are suported.");
     assert(PMW.FPM.isEmpty() && PMW.MFPM.isEmpty() &&
@@ -254,7 +139,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   template <typename PassT>
   void addMachineFunctionPass(PassT &&Pass, PassManagerWrapper &PMW,
                               bool Force = false,
-                              StringRef Name = PassT::name()) const {
+                              StringRef Name = PassT::name()) {
     static_assert(is_detected<is_machine_function_pass_t, PassT>::value &&
                   "Only machine function passes are supported.");
 
@@ -266,26 +151,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   }
 
   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();
-  }
+                      bool FreeMachineFunctions = false);
 
-  void requireCGSCCOrder(PassManagerWrapper &PMW) const {
+  void requireCGSCCOrder(PassManagerWrapper &PMW) {
     assert(!AddInCGSCCOrder);
     assert(PMW.FPM.isEmpty() && PMW.MFPM.isEmpty() &&
            "Requiring CGSCC ordering requires flushing the current function "
@@ -293,7 +161,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
     AddInCGSCCOrder = true;
   }
 
-  void stopAddingInCGSCCOrder(PassManagerWrapper &PMW) const {
+  void stopAddingInCGSCCOrder(PassManagerWrapper &PMW) {
     assert(AddInCGSCCOrder);
     assert(PMW.FPM.isEmpty() && PMW.MFPM.isEmpty() &&
            "Stopping CGSCC ordering requires flushing the current function "
@@ -301,11 +169,10 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
     AddInCGSCCOrder = false;
   }
 
-  TargetMachineT &TM;
+  TargetMachine &TM;
   CGPassBuilderOption Opt;
   PassInstrumentationCallbacks *PIC;
 
-  template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
   CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
 
   /// Check whether or not GlobalISel should abort on error.
@@ -324,13 +191,10 @@ 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 {
-    return make_error<StringError>("addInstSelector is not overridden",
-                                   inconvertibleErrorCode());
-  }
+  virtual Error addInstSelector(PassManagerWrapper &PMW);
 
   /// Target can override this to add GlobalMergePass before all IR passes.
-  void addGlobalMergePass(PassManagerWrapper &PMW) const {}
+  virtual void addGlobalMergePass(PassManagerWrapper &PMW) {}
 
   /// Add passes that optimize instruction level parallelism for out-of-order
   /// targets. These passes are run while the machine code is still in SSA
@@ -338,11 +202,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 {}
+  virtual void addILPOpts(PassManagerWrapper &PMW) {}
 
   /// This method may be implemented by targets that want to run passes
   /// immediately before register allocation.
-  void addPreRegAlloc(PassManagerWrapper &PMW) const {}
+  virtual void addPreRegAlloc(PassManagerWrapper &PMW) {}
 
   /// addPreRewrite - Add passes to the optimized register allocation pipeline
   /// after register allocation is complete, but before virtual registers are
@@ -356,111 +220,98 @@ 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 {}
+  virtual void addPreRewrite(PassManagerWrapper &PMW) {}
 
   /// Add passes to be run immediately after virtual registers are rewritten
   /// to physical registers.
-  void addPostRewrite(PassManagerWrapper &PMW) const {}
+  virtual void addPostRewrite(PassManagerWrapper &PMW) {}
 
   /// 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 {}
+  virtual void addPostRegAlloc(PassManagerWrapper &PMW) {}
 
   /// 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 {}
+  virtual void addPreSched2(PassManagerWrapper &PMW) {}
 
   /// This pass may be implemented by targets that want to run passes
   /// immediately before machine code is emitted.
-  void addPreEmitPass(PassManagerWrapper &PMW) const {}
+  virtual void addPreEmitPass(PassManagerWrapper &PMW) {}
 
   /// 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 {}
+  virtual void addPreEmitPass2(PassManagerWrapper &PMW) {}
 
   /// {{@ 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 {}
+  virtual void addPreISel(PassManagerWrapper &PMW) {}
 
   /// 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 {
-    return make_error<StringError>("addIRTranslator is not overridden",
-                                   inconvertibleErrorCode());
-  }
+  virtual Error addIRTranslator(PassManagerWrapper &PMW);
 
   /// This method may be implemented by targets that want to run passes
   /// immediately before legalization.
-  void addPreLegalizeMachineIR(PassManagerWrapper &PMW) const {}
+  virtual void addPreLegalizeMachineIR(PassManagerWrapper &PMW) {}
 
   /// 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 {
-    return make_error<StringError>("addLegalizeMachineIR is not overridden",
-                                   inconvertibleErrorCode());
-  }
+  virtual Error addLegalizeMachineIR(PassManagerWrapper &PMW);
 
   /// This method may be implemented by targets that want to run passes
   /// immediately before the register bank selection.
-  void addPreRegBankSelect(PassManagerWrapper &PMW) const {}
+  virtual void addPreRegBankSelect(PassManagerWrapper &PMW) {}
 
   /// 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 {
-    return make_error<StringError>("addRegBankSelect is not overridden",
-                                   inconvertibleErrorCode());
-  }
+  virtual Error addRegBankSelect(PassManagerWrapper &PMW);
 
   /// This method may be implemented by targets that want to run passes
   /// immediately before the (global) instruction selection.
-  void addPreGlobalInstructionSelect(PassManagerWrapper &PMW) const {}
+  virtual void addPreGlobalInstructionSelect(PassManagerWrapper &PMW) {}
 
   /// 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 {
-    return make_error<StringError>(
-        "addGlobalInstructionSelect is not overridden",
-        inconvertibleErrorCode());
-  }
+  virtual Error addGlobalInstructionSelect(PassManagerWrapper &PMW);
   /// @}}
 
   /// High level function that adds all passes necessary to go from llvm IR
   /// 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(PassManagerWrapper &PMW);
 
   /// Add the actual instruction selection passes. This does not include
   /// preparation passes on IR.
-  Error addCoreISelPasses(PassManagerWrapper &PMW) const;
+  Error addCoreISelPasses(PassManagerWrapper &PMW);
 
   /// Add the complete, standard set of LLVM CodeGen passes.
   /// Fully developed targets will not generally override this.
-  Error addMachinePasses(PassManagerWrapper &PMW) const;
+  virtual Error addMachinePasses(PassManagerWrapper &PMW);
 
   /// Add passes to lower exception handling for the code generator.
-  void addPassesToHandleExceptions(PassManagerWrapper &PMW) const;
+  void addPassesToHandleExceptions(PassManagerWrapper &PMW);
 
   /// Add common target configurable passes that perform LLVM IR to IR
   /// transforms following machine independent optimization.
-  void addIRPasses(PassManagerWrapper &PMW) const;
+  virtual void addIRPasses(PassManagerWrapper &PMW);
 
   /// Add pass to prepare the LLVM IR for code generation. This should be done
   /// before exception handling preparation passes.
-  void addCodeGenPrepare(PassManagerWrapper &PMW) const;
+  virtual void addCodeGenPrepare(PassManagerWrapper &PMW);
 
   /// Add common passes that perform LLVM IR to IR transforms in preparation for
   /// instruction selection.
-  void addISelPrepare(PassManagerWrapper &PMW) const;
+  virtual void addISelPrepare(PassManagerWrapper &PMW);
 
   /// Methods with trivial inline returns are convenient points in the common
   /// codegen pass pipeline where targets may insert passes. Methods with
@@ -471,59 +322,54 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   /// addMachineSSAOptimization - Add standard passes that optimize machine
   /// instructions in SSA form.
-  void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
+  virtual void addMachineSSAOptimization(PassManagerWrapper &PMW);
 
   /// addFastRegAlloc - Add the minimum set of target-independent passes that
   /// are required for fast register allocation.
-  Error addFastRegAlloc(PassManagerWrapper &PMW) const;
+  virtual Error addFastRegAlloc(PassManagerWrapper &PMW);
 
   /// addOptimizedRegAlloc - Add passes related to register allocation.
   /// CodeGenTargetMachineImpl provides standard regalloc passes for most
   /// targets.
-  Error addOptimizedRegAlloc(PassManagerWrapper &PMW) const;
+  virtual Error addOptimizedRegAlloc(PassManagerWrapper &PMW);
 
   /// Add passes that optimize machine instructions after register allocation.
-  void addMachineLateOptimization(PassManagerWrapper &PMW) const;
+  virtual void addMachineLateOptimization(PassManagerWrapper &PMW);
 
   /// 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 {}
+  virtual void addGCPasses(PassManagerWrapper &PMW) {}
 
   /// Add standard basic block placement passes.
-  void addBlockPlacement(PassManagerWrapper &PMW) const;
+  virtual void addBlockPlacement(PassManagerWrapper &PMW);
 
-  void addPostBBSections(PassManagerWrapper &PMW) const {}
+  virtual void addPostBBSections(PassManagerWrapper &PMW) {}
 
-  void addAsmPrinterBegin(PassManagerWrapper &PMW) const {
-    llvm_unreachable("addAsmPrinterBegin is not overriden");
-  }
+  virtual void addAsmPrinterBegin(PassManagerWrapper &PMW);
 
-  void addAsmPrinter(PassManagerWrapper &PMW) const {
-    llvm_unreachable("addAsmPrinter is not overridden");
-  }
+  virtual void addAsmPrinter(PassManagerWrapper &PMW);
 
-  void addAsmPrinterEnd(PassManagerWrapper &PMW) const {
-    llvm_unreachable("addAsmPrinterEnd is not overriden");
-  }
+  virtual void addAsmPrinterEnd(PassManagerWrapper &PMW);
 
   /// Utilities for targets to add passes to the pass manager.
   ///
 
-  /// createTargetRegisterAllocator - Create the register allocator pass for
-  /// this target at the current optimization level.
-  void addTargetRegisterAllocator(PassManagerWrapper &PMW,
-                                  bool Optimized) const;
+  /// Create the register allocator pass for this target at the current
+  /// optimization level.
+  virtual void addTargetRegisterAllocator(PassManagerWrapper &PMW,
+                                          bool Optimized);
 
   /// addMachinePasses helper to create the target-selected or overriden
   /// regalloc pass.
-  void addRegAllocPass(PassManagerWrapper &PMW, bool Optimized) const;
+  void addRegAllocPass(PassManagerWrapper &PMW, bool Optimized);
 
   /// Add core register allocator passes which do the actual register assignment
   /// and rewriting. addRegAssignAndRewriteOptimized should return true if any
   /// passes were added.
-  Error addRegAssignAndRewriteFast(PassManagerWrapper &PMW) const;
-  Expected<bool> addRegAssignAndRewriteOptimized(PassManagerWrapper &PMW) const;
+  virtual Error addRegAssignAndRewriteFast(PassManagerWrapper &PMW);
+  virtual Expected<bool>
+  addRegAssignAndRewriteOptimized(PassManagerWrapper &PMW);
 
   /// Allow the target to disable a specific pass by default.
   /// Backend can declare unwanted passes in constructor.
@@ -535,7 +381,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   /// Insert InsertedPass pass after TargetPass pass.
   /// Only machine function passes are supported.
   template <typename TargetPassT, typename InsertedPassT>
-  void insertPass(InsertedPassT &&Pass) const {
+  void insertPass(InsertedPassT &&Pass) {
     AfterCallbacks.emplace_back(
         [&](StringRef Name, MachineFunctionPassManager &MFPM) mutable {
           if (Name == TargetPassT::name() &&
@@ -546,792 +392,28 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
   }
 
 private:
-  DerivedT &derived() { return static_cast<DerivedT &>(*this); }
-  const DerivedT &derived() const {
-    return static_cast<const DerivedT &>(*this);
-  }
-
-  bool runBeforeAdding(StringRef Name) const {
+  bool runBeforeAdding(StringRef Name) {
     bool ShouldAdd = true;
     for (auto &C : BeforeCallbacks)
       ShouldAdd &= C(Name);
     return ShouldAdd;
   }
 
-  void setStartStopPasses(const TargetPassConfig::StartStopInfo &Info) const;
+  void setStartStopPasses(const TargetPassConfig::StartStopInfo &Info);
 
   Error verifyStartStop(const TargetPassConfig::StartStopInfo &Info) const;
 
-  mutable SmallVector<llvm::unique_function<bool(StringRef)>, 4>
-      BeforeCallbacks;
-  mutable SmallVector<
+  SmallVector<llvm::unique_function<bool(StringRef)>, 4> BeforeCallbacks;
+  SmallVector<
       llvm::unique_function<void(StringRef, MachineFunctionPassManager &)>, 4>
       AfterCallbacks;
 
   /// Helper variable for `-start-before/-start-after/-stop-before/-stop-after`
-  mutable bool Started = true;
-  mutable bool Stopped = true;
-  mutable bool AddInCGSCCOrder = false;
+  bool Started = true;
+  bool Stopped = true;
+  bool AddInCGSCCOrder = false;
 };
 
-template <typename Derived, typename TargetMachineT>
-Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
-    ModulePassManager &MPM, ModuleAnalysisManager &MAM, raw_pwrite_stream &Out,
-    raw_pwrite_stream *DwoOut, CodeGenFileType FileType, MCContext &Ctx) const {
-  auto StartStopInfo = TargetPassConfig::getStartStopInfo(*PIC);
-  if (!StartStopInfo)
-    return StartStopInfo.takeError();
-  setStartStopPasses(*StartStopInfo);
-
-  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);
-
-  if (PrintAsm) {
-    Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
-        TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
-    if (!MCStreamerOrErr)
-      return MCStreamerOrErr.takeError();
-    std::unique_ptr<AsmPrinter> Printer(
-        TM.getTarget().createAsmPrinter(TM, std::move(*MCStreamerOrErr)));
-    if (!Printer)
-      return createStringError("failed to create AsmPrinter");
-    MAM.registerPass([&] { return AsmPrinterAnalysis(std::move(Printer)); });
-    derived().addAsmPrinterBegin(PMW);
-  }
-
-  if (PrintMIR)
-    addModulePass(PrintMIRPreparePass(Out), PMW, /*Force=*/true);
-
-  if (auto Err = addCoreISelPasses(PMW))
-    return std::move(Err);
-
-  if (auto Err = derived().addMachinePasses(PMW))
-    return std::move(Err);
-
-  if (!Opt.DisableVerify && TM.Options.EnableDefaultMachineVerifier)
-    addMachineFunctionPass(MachineVerifierPass(), PMW);
-
-  // We add AsmPrinter regardless if we are emitting MIR or Assembly as the
-  // final output so that -stop-before=<target>-asm-printer works. When printing
-  // MIR as the final output, we never end up running AsmPrinter.
-  derived().addAsmPrinter(PMW);
-
-  if (PrintAsm) {
-    flushFPMsToMPM(PMW, /*FreeMachineFunctions=*/true);
-    derived().addAsmPrinterEnd(PMW);
-  } else {
-    if (PrintMIR)
-      addMachineFunctionPass(PrintMIRPass(Out), PMW, /*Force=*/true);
-    flushFPMsToMPM(PMW, /*FreeMachineFunctions=*/true);
-  }
-
-  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;
-        }
-        return Started;
-      }
-
-      auto PassName = PIC->getPassNameForClassName(ClassName);
-      if (Info.StartPass == PassName && ++Count == Info.StartInstanceNum)
-        Started = !Info.StartAfter;
-
-      return Started;
-    });
-  }
-
-  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;
-      }
-
-      auto PassName = PIC->getPassNameForClassName(ClassName);
-      if (Info.StopPass == PassName && ++Count == Info.StopInstanceNum)
-        Stopped = !Info.StopAfter;
-      return !Stopped;
-    });
-  }
-}
-
-template <typename Derived, typename TargetMachineT>
-Error CodeGenPassBuilder<Derived, TargetMachineT>::verifyStartStop(
-    const TargetPassConfig::StartStopInfo &Info) const {
-  if (Started && Stopped)
-    return Error::success();
-
-  if (!Started)
-    return make_error<StringError>(
-        "Can't find start pass \"" + Info.StartPass + "\".",
-        std::make_error_code(std::errc::invalid_argument));
-  if (!Stopped)
-    return make_error<StringError>(
-        "Can't find stop pass \"" + Info.StopPass + "\".",
-        std::make_error_code(std::errc::invalid_argument));
-  return Error::success();
-}
-
-template <typename Derived, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addISelPasses(
-    PassManagerWrapper &PMW) const {
-  derived().addGlobalMergePass(PMW);
-  if (TM.useEmulatedTLS())
-    addModulePass(LowerEmuTLSPass(), PMW);
-
-  // ObjCARCContract operates on ObjC intrinsics and must run before
-  // PreISelIntrinsicLowering.
-  if (getOptLevel() != CodeGenOptLevel::None) {
-    addFunctionPass(ObjCARCContractPass(), PMW);
-    flushFPMsToMPM(PMW);
-  }
-  addModulePass(PreISelIntrinsicLoweringPass(&TM), PMW);
-  addFunctionPass(ExpandIRInstsPass(TM, getOptLevel()), PMW);
-
-  derived().addIRPasses(PMW);
-  derived().addCodeGenPrepare(PMW);
-  addPassesToHandleExceptions(PMW);
-  derived().addISelPrepare(PMW);
-}
-
-/// 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 {
-  // 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);
-
-  // 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());
-    if (Opt.EnableLoopTermFold)
-      LPM.addPass(LoopTermFoldPass());
-    addFunctionPass(createFunctionToLoopPassAdaptor(std::move(LPM),
-                                                    /*UseMemorySSA=*/false),
-                    PMW);
-  }
-
-  // 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);
-  }
-
-  // Make sure that no unreachable blocks are instruction selected.
-  addFunctionPass(UnreachableBlockElimPass(), PMW);
-
-  // Prepare expensive constants for SelectionDAG.
-  if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableConstantHoisting)
-    addFunctionPass(ConstantHoistingPass(), PMW);
-
-  // 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);
-
-  if (getOptLevel() != CodeGenOptLevel::None &&
-      !Opt.DisablePartialLibcallInlining)
-    addFunctionPass(PartiallyInlineLibCallsPass(), PMW);
-
-  // Instrument function entry and exit, e.g. with calls to mcount().
-  addFunctionPass(EntryExitInstrumenterPass(/*PostInlining=*/true), PMW);
-
-  // 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);
-
-  // Expand reduction intrinsics into shuffle sequences if the target wants to.
-  if (!Opt.DisableExpandReductions)
-    addFunctionPass(ExpandReductionsPass(), PMW);
-
-  // Convert conditional moves to conditional jumps when profitable.
-  if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableSelectOptimize)
-    addFunctionPass(SelectOptimizePass(TM), PMW);
-
-  if (Opt.EnableGlobalMergeFunc) {
-    flushFPMsToMPM(PMW);
-    addModulePass(GlobalMergeFuncPass(), PMW);
-  }
-}
-
-/// Turn exception handling constructs into something the code generators can
-/// handle.
-template <typename Derived, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addPassesToHandleExceptions(
-    PassManagerWrapper &PMW) const {
-  const MCAsmInfo &MCAI = TM.getMCAsmInfo();
-  switch (MCAI.getExceptionHandlingType()) {
-  case ExceptionHandling::SjLj:
-    // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
-    // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
-    // catch info can get misplaced when a selector ends up more than one block
-    // 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);
-    [[fallthrough]];
-  case ExceptionHandling::DwarfCFI:
-  case ExceptionHandling::ARM:
-  case ExceptionHandling::AIX:
-  case ExceptionHandling::ZOS:
-    addFunctionPass(DwarfEHPreparePass(TM), PMW);
-    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);
-    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);
-    break;
-  case ExceptionHandling::None:
-    addFunctionPass(LowerInvokePass(), PMW);
-
-    // The lower invoke pass may create unreachable code. Remove it.
-    addFunctionPass(UnreachableBlockElimPass(), PMW);
-    break;
-  }
-}
-
-/// 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 {
-  if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableCGP)
-    addFunctionPass(CodeGenPreparePass(TM), PMW);
-  // TODO: Default ctor'd RewriteSymbolPass is no-op.
-  // addPass(RewriteSymbolPass());
-}
-
-/// 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);
-
-  addFunctionPass(InlineAsmPreparePass(), PMW);
-  // 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);
-
-  if (Opt.PrintISelInput)
-    addFunctionPass(PrintFunctionPass(
-                        dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"),
-                    PMW);
-
-  // 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);
-}
-
-template <typename Derived, typename TargetMachineT>
-Error CodeGenPassBuilder<Derived, TargetMachineT>::addCoreISelPasses(
-    PassManagerWrapper &PMW) const {
-  // Enable FastISel with -fast-isel, but allow that to be overridden.
-  TM.setO0WantsFastISel(Opt.EnableFastISelOption !=
-                        cl::boolOrDefault::BOU_FALSE);
-
-  // Determine an instruction selector.
-  enum class SelectorType { SelectionDAG, FastISel, GlobalISel };
-  SelectorType Selector;
-
-  if (Opt.EnableFastISelOption == cl::boolOrDefault::BOU_TRUE)
-    Selector = SelectorType::FastISel;
-  else if (Opt.EnableGlobalISelOption == cl::boolOrDefault::BOU_TRUE ||
-           (TM.Options.EnableGlobalISel &&
-            Opt.EnableGlobalISelOption != cl::boolOrDefault::BOU_FALSE))
-    Selector = SelectorType::GlobalISel;
-  else if (TM.getOptLevel() == CodeGenOptLevel::None && TM.getO0WantsFastISel())
-    Selector = SelectorType::FastISel;
-  else
-    Selector = SelectorType::SelectionDAG;
-
-  // Set consistently TM.Options.EnableFastISel and EnableGlobalISel.
-  if (Selector == SelectorType::FastISel) {
-    TM.setFastISel(true);
-    TM.setGlobalISel(false);
-  } else if (Selector == SelectorType::GlobalISel) {
-    TM.setFastISel(false);
-    TM.setGlobalISel(true);
-  }
-
-  // Add instruction selector passes.
-  if (Selector == SelectorType::GlobalISel) {
-    if (auto Err = derived().addIRTranslator(PMW))
-      return std::move(Err);
-
-    derived().addPreLegalizeMachineIR(PMW);
-
-    if (auto Err = derived().addLegalizeMachineIR(PMW))
-      return std::move(Err);
-
-    // Before running the register bank selector, ask the target if it
-    // wants to run some passes.
-    derived().addPreRegBankSelect(PMW);
-
-    if (auto Err = derived().addRegBankSelect(PMW))
-      return std::move(Err);
-
-    derived().addPreGlobalInstructionSelect(PMW);
-
-    if (auto Err = derived().addGlobalInstructionSelect(PMW))
-      return std::move(Err);
-
-    // Pass to reset the MachineFunction if the ISel failed.
-    addMachineFunctionPass(
-        ResetMachineFunctionPass(reportDiagnosticWhenGlobalISelFallback(),
-                                 isGlobalISelAbortEnabled()),
-        PMW);
-
-    // Provide a fallback path when we do not want to abort on
-    // not-yet-supported input.
-    if (!isGlobalISelAbortEnabled())
-      if (auto Err = derived().addInstSelector(PMW))
-        return std::move(Err);
-
-  } else if (auto Err = derived().addInstSelector(PMW))
-    return std::move(Err);
-
-  // Expand pseudo-instructions emitted by ISel. Don't run the verifier before
-  // FinalizeISel.
-  addMachineFunctionPass(FinalizeISelPass(), PMW);
-
-  // // Print the instruction selected machine code...
-  // printAndVerify("After Instruction Selection");
-
-  return Error::success();
-}
-
-/// Add the complete set of target-independent postISel code generator passes.
-///
-/// This can be read as the standard order of major LLVM CodeGen stages. Stages
-/// with nontrivial configuration or multiple passes are broken out below in
-/// add%Stage routines.
-///
-/// Any CodeGenPassBuilder<Derived, TargetMachine>::addXX routine may be
-/// overriden by the Target. The addPre/Post methods with empty header
-/// implementations allow injecting target-specific fixups just before or after
-/// major stages. Additionally, targets have the flexibility to change pass
-/// order within a stage by overriding default implementation of add%Stage
-/// routines below. Each technique has maintainability tradeoffs because
-/// alternate pass orders are not well supported. addPre/Post works better if
-/// the target pass is easily tied to a common pass. But if it has subtle
-/// dependencies on multiple passes, the target should override the stage
-/// instead.
-template <typename Derived, typename TargetMachineT>
-Error CodeGenPassBuilder<Derived, TargetMachineT>::addMachinePasses(
-    PassManagerWrapper &PMW) const {
-  // Add passes that optimize machine instructions in SSA form.
-  if (getOptLevel() != CodeGenOptLevel::None) {
-    derived().addMachineSSAOptimization(PMW);
-  } 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);
-  }
-
-  if (TM.Options.EnableIPRA) {
-    flushFPMsToMPM(PMW);
-    addModulePass(RequireAnalysisPass<PhysicalRegisterUsageAnalysis, Module>(),
-                  PMW, /*Force=*/true);
-    addMachineFunctionPass(RegUsageInfoPropagationPass(), PMW);
-  }
-  // Run pre-ra passes.
-  derived().addPreRegAlloc(PMW);
-
-  // 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))
-    return std::move(Err);
-
-  // Run post-ra passes.
-  derived().addPostRegAlloc(PMW);
-
-  addMachineFunctionPass(RemoveRedundantDebugValuesPass(), PMW);
-  addMachineFunctionPass(FixupStatepointCallerSavedPass(), PMW);
-
-  // Insert prolog/epilog code.  Eliminate abstract frame index references...
-  if (getOptLevel() != CodeGenOptLevel::None) {
-    addMachineFunctionPass(PostRAMachineSinkingPass(), PMW);
-    addMachineFunctionPass(ShrinkWrapPass(), PMW);
-  }
-
-  addMachineFunctionPass(PrologEpilogInserterPass(), PMW);
-
-  /// Add passes that optimize machine instructions after register allocation.
-  if (getOptLevel() != CodeGenOptLevel::None)
-    derived().addMachineLateOptimization(PMW);
-
-  // Expand pseudo instructions before second scheduling pass.
-  addMachineFunctionPass(ExpandPostRAPseudosPass(), PMW);
-
-  // Run pre-sched2 passes.
-  derived().addPreSched2(PMW);
-
-  if (Opt.EnableImplicitNullChecks)
-    addMachineFunctionPass(ImplicitNullChecksPass(), PMW);
-
-  // Second pass scheduler.
-  // Let Target optionally insert this pass by itself at some other
-  // point.
-  if (getOptLevel() != CodeGenOptLevel::None &&
-      !TM.targetSchedulesPostRAScheduling()) {
-    if (Opt.MISchedPostRA)
-      addMachineFunctionPass(PostMachineSchedulerPass(&TM), PMW);
-    else
-      addMachineFunctionPass(PostRASchedulerPass(&TM), PMW);
-  }
-
-  // GC
-  derived().addGCPasses(PMW);
-
-  // Basic block placement.
-  if (getOptLevel() != CodeGenOptLevel::None)
-    derived().addBlockPlacement(PMW);
-
-  // Insert before XRay Instrumentation.
-  addMachineFunctionPass(FEntryInserterPass(), PMW);
-
-  addMachineFunctionPass(XRayInstrumentationPass(), PMW);
-  addMachineFunctionPass(PatchableFunctionPass(), PMW);
-
-  derived().addPreEmitPass(PMW);
-
-  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);
-    // If -print-regusage is specified, print the collected register usage info.
-    if (Opt.PrintRegUsage) {
-      flushFPMsToMPM(PMW);
-      addModulePass(PhysicalRegisterUsageInfoPrinterPass(errs()), PMW);
-    }
-  }
-
-  addMachineFunctionPass(FuncletLayoutPass(), PMW);
-
-  addMachineFunctionPass(RemoveLoadsIntoFakeUsesPass(), PMW);
-  addMachineFunctionPass(StackMapLivenessPass(), PMW);
-  addMachineFunctionPass(
-      LiveDebugValuesPass(
-          getTM<TargetMachine>().Options.ShouldEmitDebugEntryValues()),
-      PMW);
-  addMachineFunctionPass(MachineSanitizerBinaryMetadataPass(), PMW);
-
-  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);
-    }
-  }
-
-  if (Opt.EnableGCEmptyBlocks)
-    addMachineFunctionPass(GCEmptyBasicBlocksPass(), PMW);
-
-  derived().addPostBBSections(PMW);
-
-  addMachineFunctionPass(StackFrameLayoutAnalysisPass(), PMW);
-
-  // Add passes that directly emit MI after all other MI passes.
-  derived().addPreEmitPass2(PMW);
-
-  return Error::success();
-}
-
-/// Add passes that optimize machine instructions in SSA form.
-template <typename Derived, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineSSAOptimization(
-    PassManagerWrapper &PMW) const {
-  // Pre-ra tail duplication.
-  addMachineFunctionPass(EarlyTailDuplicatePass(), PMW);
-
-  // Optimize PHIs before DCE: removing dead PHI cycles may make more
-  // instructions dead.
-  addMachineFunctionPass(OptimizePHIsPass(), PMW);
-
-  // This pass merges large allocas. StackSlotColoring is a different pass
-  // which merges spill slots.
-  addMachineFunctionPass(StackColoringPass(), PMW);
-
-  // 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);
-
-  // 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);
-
-  // 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);
-
-  addMachineFunctionPass(EarlyMachineLICMPass(), PMW);
-  addMachineFunctionPass(MachineCSEPass(), PMW);
-
-  addMachineFunctionPass(MachineSinkingPass(Opt.EnableSinkAndFold), PMW);
-
-  addMachineFunctionPass(PeepholeOptimizerPass(), PMW);
-  // Clean-up the dead code that may have been generated by peephole
-  // rewriting.
-  addMachineFunctionPass(DeadMachineInstructionElimPass(), PMW);
-}
-
-//===---------------------------------------------------------------------===//
-/// Register Allocation Pass Configuration
-//===---------------------------------------------------------------------===//
-
-/// Instantiate the default register allocator pass for this target for either
-/// the optimized or unoptimized allocation path. This will be added to the pass
-/// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
-/// in the optimized case.
-///
-/// A target that uses the standard regalloc pass order for fast or optimized
-/// allocation may still override this for per-target regalloc
-/// selection. But -regalloc-npm=... always takes precedence.
-/// If a target does not want to allow users to set -regalloc-npm=... at all,
-/// check if Opt.RegAlloc == RegAllocType::Unset.
-template <typename Derived, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
-    PassManagerWrapper &PMW, bool Optimized) const {
-  if (Optimized)
-    addMachineFunctionPass(RAGreedyPass(), PMW);
-  else
-    addMachineFunctionPass(RegAllocFastPass(), PMW);
-}
-
-/// Find and instantiate the register allocation pass requested by this target
-/// at the current optimization level.  Different register allocators are
-/// defined as separate passes because they may require different analysis.
-///
-/// This helper ensures that the -regalloc-npm= option is always available,
-/// even for targets that override the default allocator.
-template <typename Derived, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
-    PassManagerWrapper &PMW, 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);
-      break;
-    case RegAllocType::Greedy:
-      addMachineFunctionPass(RAGreedyPass(), PMW);
-      break;
-    default:
-      reportFatalUsageError("register allocator not supported yet");
-    }
-    return;
-  }
-  // -regalloc=default or unspecified, so pick based on the optimization level
-  // or ask the target for the regalloc pass.
-  derived().addTargetRegisterAllocator(PMW, Optimized);
-}
-
-template <typename Derived, typename TargetMachineT>
-Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignAndRewriteFast(
-    PassManagerWrapper &PMW) const {
-  // TODO: Ensure allocator is default or fast.
-  addRegAllocPass(PMW, false);
-  return Error::success();
-}
-
-template <typename Derived, typename TargetMachineT>
-Expected<bool>
-CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignAndRewriteOptimized(
-    PassManagerWrapper &PMW) const {
-  // Add the selected register allocation pass.
-  addRegAllocPass(PMW, true);
-
-  // Allow targets to change the register assignments before rewriting.
-  derived().addPreRewrite(PMW);
-
-  // Finally rewrite virtual registers.
-  addMachineFunctionPass(VirtRegRewriterPass(), PMW);
-
-  return true;
-}
-
-/// Add the minimum set of target-independent passes that are required for
-/// 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().addRegAssignAndRewriteFast(PMW);
-}
-
-/// Add standard target-independent passes that are tightly coupled with
-/// optimized register allocation, including coalescing, machine instruction
-/// scheduling, and register allocation itself.
-template <typename Derived, typename TargetMachineT>
-Error CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(DetectDeadLanesPass(), PMW);
-
-  addMachineFunctionPass(InitUndefPass(), PMW);
-
-  addMachineFunctionPass(ProcessImplicitDefsPass(), PMW);
-
-  // LiveVariables currently requires pure SSA form.
-  //
-  // FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
-  // LiveVariables can be removed completely, and LiveIntervals can be directly
-  // computed. (We still either need to regenerate kill flags after regalloc, or
-  // preferably fix the scavenger to not depend on them).
-  // FIXME: UnreachableMachineBlockElim is a dependant pass of LiveVariables.
-  // 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);
-
-  // Edge splitting is smarter with machine loop info.
-  addMachineFunctionPass(
-      RequireAnalysisPass<MachineLoopAnalysis, MachineFunction>(), PMW);
-  addMachineFunctionPass(PHIEliminationPass(), PMW);
-
-  // Eventually, we want to run LiveIntervals before PHI elimination.
-  if (Opt.EarlyLiveIntervals)
-    addMachineFunctionPass(
-        RequireAnalysisPass<LiveIntervalsAnalysis, MachineFunction>(), PMW);
-
-  addMachineFunctionPass(TwoAddressInstructionPass(), PMW);
-  addMachineFunctionPass(RegisterCoalescerPass(), PMW);
-
-  // 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);
-
-  // PreRA instruction scheduling.
-  addMachineFunctionPass(MachineSchedulerPass(&TM), PMW);
-
-  Expected<bool> AddedPasses = derived().addRegAssignAndRewriteOptimized(PMW);
-  if (!AddedPasses)
-    return AddedPasses.takeError();
-  if (!AddedPasses.get())
-    return Error::success();
-
-  addMachineFunctionPass(StackSlotColoringPass(), PMW);
-
-  // Allow targets to expand pseudo instructions depending on the choice of
-  // registers before MachineCopyPropagation.
-  derived().addPostRewrite(PMW);
-
-  // Copy propagate to forward register uses and try to eliminate COPYs that
-  // were not coalesced.
-  addMachineFunctionPass(MachineCopyPropagationPass(), PMW);
-
-  // Run post-ra machine LICM to hoist reloads / remats.
-  //
-  // FIXME: can this move into MachineLateOptimization?
-  addMachineFunctionPass(MachineLICMPass(), PMW);
-
-  return Error::success();
-}
-
-//===---------------------------------------------------------------------===//
-/// Post RegAlloc Pass Configuration
-//===---------------------------------------------------------------------===//
-
-/// Add passes that optimize machine instructions after register allocation.
-template <typename Derived, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineLateOptimization(
-    PassManagerWrapper &PMW) const {
-  // Cleanup of redundant (identical) address/immediate loads.
-  addMachineFunctionPass(MachineLateInstrsCleanupPass(), PMW);
-
-  // Branch folding must be run after regalloc and prolog/epilog insertion.
-  addMachineFunctionPass(BranchFolderPass(Opt.EnableTailMerge), PMW);
-
-  // 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);
-
-  // Copy propagation.
-  addMachineFunctionPass(MachineCopyPropagationPass(), PMW);
-}
-
-/// Add standard basic block placement passes.
-template <typename Derived, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addBlockPlacement(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(MachineBlockPlacementPass(Opt.EnableTailMerge), PMW);
-  // Run a separate pass to collect block placement statistics.
-  if (Opt.EnableBlockPlacementStats)
-    addMachineFunctionPass(MachineBlockPlacementStatsPass(), PMW);
-}
-
 } // namespace llvm
 
 #endif // LLVM_PASSES_CODEGENPASSBUILDER_H
diff --git a/llvm/lib/Passes/CodeGenPassBuilder.cpp b/llvm/lib/Passes/CodeGenPassBuilder.cpp
index 16332200f9b4b..a6ebe184efc84 100644
--- a/llvm/lib/Passes/CodeGenPassBuilder.cpp
+++ b/llvm/lib/Passes/CodeGenPassBuilder.cpp
@@ -9,9 +9,122 @@
 // This file defines interfaces to access the target independent code
 // generation passes provided by the LLVM backend.
 //
-//===---------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
 
 #include "llvm/Passes/CodeGenPassBuilder.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/ProfileSummaryInfo.h"
+#include "llvm/Analysis/RuntimeLibcallInfo.h"
+#include "llvm/Analysis/ScopedNoAliasAA.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/AsmPrinterAnalysis.h"
+#include "llvm/CodeGen/BranchFoldingPass.h"
+#include "llvm/CodeGen/CodeGenPrepare.h"
+#include "llvm/CodeGen/DeadMachineInstructionElim.h"
+#include "llvm/CodeGen/DetectDeadLanes.h"
+#include "llvm/CodeGen/DwarfEHPrepare.h"
+#include "llvm/CodeGen/ExpandIRInsts.h"
+#include "llvm/CodeGen/ExpandPostRAPseudos.h"
+#include "llvm/CodeGen/ExpandReductions.h"
+#include "llvm/CodeGen/FEntryInserter.h"
+#include "llvm/CodeGen/FinalizeISel.h"
+#include "llvm/CodeGen/FixupStatepointCallerSaved.h"
+#include "llvm/CodeGen/GCEmptyBasicBlocks.h"
+#include "llvm/CodeGen/GCMetadata.h"
+#include "llvm/CodeGen/GlobalMerge.h"
+#include "llvm/CodeGen/GlobalMergeFunctions.h"
+#include "llvm/CodeGen/IndirectBrExpand.h"
+#include "llvm/CodeGen/InitUndef.h"
+#include "llvm/CodeGen/InlineAsmPrepare.h"
+#include "llvm/CodeGen/InterleavedAccess.h"
+#include "llvm/CodeGen/InterleavedLoadCombine.h"
+#include "llvm/CodeGen/LiveDebugValuesPass.h"
+#include "llvm/CodeGen/LiveIntervals.h"
+#include "llvm/CodeGen/LiveVariables.h"
+#include "llvm/CodeGen/LocalStackSlotAllocation.h"
+#include "llvm/CodeGen/LowerEmuTLS.h"
+#include "llvm/CodeGen/MIRPrinter.h"
+#include "llvm/CodeGen/MachineBlockPlacement.h"
+#include "llvm/CodeGen/MachineCSE.h"
+#include "llvm/CodeGen/MachineCopyPropagation.h"
+#include "llvm/CodeGen/MachineFunctionAnalysis.h"
+#include "llvm/CodeGen/MachineLICM.h"
+#include "llvm/CodeGen/MachineLateInstrsCleanup.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/MachineScheduler.h"
+#include "llvm/CodeGen/MachineSink.h"
+#include "llvm/CodeGen/MachineVerifier.h"
+#include "llvm/CodeGen/OptimizePHIs.h"
+#include "llvm/CodeGen/PEI.h"
+#include "llvm/CodeGen/PHIElimination.h"
+#include "llvm/CodeGen/PatchableFunction.h"
+#include "llvm/CodeGen/PeepholeOptimizer.h"
+#include "llvm/CodeGen/PostRAMachineSink.h"
+#include "llvm/CodeGen/PostRASchedulerList.h"
+#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
+#include "llvm/CodeGen/ProcessImplicitDefs.h"
+#include "llvm/CodeGen/RegAllocEvictionAdvisor.h"
+#include "llvm/CodeGen/RegAllocFast.h"
+#include "llvm/CodeGen/RegAllocGreedyPass.h"
+#include "llvm/CodeGen/RegUsageInfoCollector.h"
+#include "llvm/CodeGen/RegUsageInfoPropagate.h"
+#include "llvm/CodeGen/RegisterCoalescerPass.h"
+#include "llvm/CodeGen/RegisterUsageInfo.h"
+#include "llvm/CodeGen/RemoveLoadsIntoFakeUses.h"
+#include "llvm/CodeGen/RemoveRedundantDebugValues.h"
+#include "llvm/CodeGen/RenameIndependentSubregs.h"
+#include "llvm/CodeGen/ReplaceWithVeclib.h"
+#include "llvm/CodeGen/SafeStack.h"
+#include "llvm/CodeGen/SanitizerBinaryMetadata.h"
+#include "llvm/CodeGen/SelectOptimize.h"
+#include "llvm/CodeGen/ShadowStackGCLowering.h"
+#include "llvm/CodeGen/ShrinkWrap.h"
+#include "llvm/CodeGen/SjLjEHPrepare.h"
+#include "llvm/CodeGen/StackColoring.h"
+#include "llvm/CodeGen/StackFrameLayoutAnalysisPass.h"
+#include "llvm/CodeGen/StackProtector.h"
+#include "llvm/CodeGen/StackSlotColoring.h"
+#include "llvm/CodeGen/TailDuplication.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/TwoAddressInstructionPass.h"
+#include "llvm/CodeGen/UnreachableBlockElim.h"
+#include "llvm/CodeGen/VirtRegMap.h"
+#include "llvm/CodeGen/WasmEHPrepare.h"
+#include "llvm/CodeGen/WinEHPrepare.h"
+#include "llvm/CodeGen/XRayInstrumentation.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/IRPrinter/IRPrintingPasses.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/CGPassBuilderOption.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/ObjCARC.h"
+#include "llvm/Transforms/Scalar/ConstantHoisting.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+#include "llvm/Transforms/Scalar/LoopStrengthReduce.h"
+#include "llvm/Transforms/Scalar/LoopTermFold.h"
+#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
+#include "llvm/Transforms/Scalar/MergeICmps.h"
+#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
+#include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
+#include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
+#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
+#include "llvm/Transforms/Utils/LowerInvoke.h"
+#include <cassert>
+#include <utility>
 
 using namespace llvm;
 
@@ -20,3 +133,815 @@ namespace llvm {
   AnalysisKey PASS_NAME::Key;
 #include "llvm/Passes/MachinePassRegistry.def"
 } // namespace llvm
+
+CodeGenPassBuilder::CodeGenPassBuilder(TargetMachine &TM,
+                                       const CGPassBuilderOption &Opts,
+                                       PassInstrumentationCallbacks *PIC)
+    : TM(TM), Opt(Opts), PIC(PIC) {
+  // Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
+  //     substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
+
+  // Target should override TM.Options.EnableIPRA in their target-specific
+  // LLVMTM ctor. See TargetMachine::setGlobalISel for example.
+  if (Opt.EnableIPRA) {
+    TM.Options.EnableIPRA = *Opt.EnableIPRA;
+  } else {
+    // If not explicitly specified, use target default.
+    TM.Options.EnableIPRA |= TM.useIPRA();
+  }
+
+  if (Opt.EnableGlobalISelAbort)
+    TM.Options.GlobalISelAbort = *Opt.EnableGlobalISelAbort;
+
+  // An explicit RegAlloc choice implies its pipeline: only the fast
+  // allocator uses the unoptimized one.
+  if (Opt.OptimizeRegAlloc == cl::boolOrDefault::BOU_UNSET) {
+    bool Optimized = Opt.RegAlloc > RegAllocType::Default
+                         ? Opt.RegAlloc != RegAllocType::Fast
+                         : getOptLevel() != CodeGenOptLevel::None;
+    Opt.OptimizeRegAlloc =
+        Optimized ? cl::boolOrDefault::BOU_TRUE : cl::boolOrDefault::BOU_FALSE;
+  }
+}
+
+// Out-of-line to anchor the vtable in this translation unit.
+CodeGenPassBuilder::~CodeGenPassBuilder() = default;
+
+Error CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
+  return make_error<StringError>("addInstSelector is not overridden",
+                                 inconvertibleErrorCode());
+}
+
+Error CodeGenPassBuilder::addIRTranslator(PassManagerWrapper &PMW) {
+  return make_error<StringError>("addIRTranslator is not overridden",
+                                 inconvertibleErrorCode());
+}
+
+Error CodeGenPassBuilder::addLegalizeMachineIR(PassManagerWrapper &PMW) {
+  return make_error<StringError>("addLegalizeMachineIR is not overridden",
+                                 inconvertibleErrorCode());
+}
+
+Error CodeGenPassBuilder::addRegBankSelect(PassManagerWrapper &PMW) {
+  return make_error<StringError>("addRegBankSelect is not overridden",
+                                 inconvertibleErrorCode());
+}
+
+Error CodeGenPassBuilder::addGlobalInstructionSelect(PassManagerWrapper &PMW) {
+  return make_error<StringError>("addGlobalInstructionSelect is not overridden",
+                                 inconvertibleErrorCode());
+}
+
+void CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
+  llvm_unreachable("addAsmPrinterBegin is not overriden");
+}
+
+void CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
+  llvm_unreachable("addAsmPrinter is not overridden");
+}
+
+void CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
+  llvm_unreachable("addAsmPrinterEnd is not overriden");
+}
+
+void CodeGenPassBuilder::flushFPMsToMPM(PassManagerWrapper &PMW,
+                                        bool FreeMachineFunctions) {
+  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();
+}
+
+Error CodeGenPassBuilder::buildPipeline(
+    ModulePassManager &MPM, ModuleAnalysisManager &MAM, raw_pwrite_stream &Out,
+    raw_pwrite_stream *DwoOut, CodeGenFileType FileType, MCContext &Ctx) {
+  auto StartStopInfo = TargetPassConfig::getStartStopInfo(*PIC);
+  if (!StartStopInfo)
+    return StartStopInfo.takeError();
+  setStartStopPasses(*StartStopInfo);
+
+  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);
+
+  if (PrintAsm) {
+    Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
+        TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
+    if (!MCStreamerOrErr)
+      return MCStreamerOrErr.takeError();
+    std::unique_ptr<AsmPrinter> Printer(
+        TM.getTarget().createAsmPrinter(TM, std::move(*MCStreamerOrErr)));
+    if (!Printer)
+      return createStringError("failed to create AsmPrinter");
+    MAM.registerPass([&] { return AsmPrinterAnalysis(std::move(Printer)); });
+    addAsmPrinterBegin(PMW);
+  }
+
+  if (PrintMIR)
+    addModulePass(PrintMIRPreparePass(Out), PMW, /*Force=*/true);
+
+  if (auto Err = addCoreISelPasses(PMW))
+    return Err;
+
+  if (auto Err = addMachinePasses(PMW))
+    return Err;
+
+  if (!Opt.DisableVerify && TM.Options.EnableDefaultMachineVerifier)
+    addMachineFunctionPass(MachineVerifierPass(), PMW);
+
+  // We add AsmPrinter regardless if we are emitting MIR or Assembly as the
+  // final output so that -stop-before=<target>-asm-printer works. When printing
+  // MIR as the final output, we never end up running AsmPrinter.
+  addAsmPrinter(PMW);
+
+  if (PrintAsm) {
+    flushFPMsToMPM(PMW, /*FreeMachineFunctions=*/true);
+    addAsmPrinterEnd(PMW);
+  } else {
+    if (PrintMIR)
+      addMachineFunctionPass(PrintMIRPass(Out), PMW, /*Force=*/true);
+    flushFPMsToMPM(PMW, /*FreeMachineFunctions=*/true);
+  }
+
+  return verifyStartStop(*StartStopInfo);
+}
+
+void CodeGenPassBuilder::setStartStopPasses(
+    const TargetPassConfig::StartStopInfo &Info) {
+  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;
+        }
+        return Started;
+      }
+
+      auto PassName = PIC->getPassNameForClassName(ClassName);
+      if (Info.StartPass == PassName && ++Count == Info.StartInstanceNum)
+        Started = !Info.StartAfter;
+
+      return Started;
+    });
+  }
+
+  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;
+      }
+
+      auto PassName = PIC->getPassNameForClassName(ClassName);
+      if (Info.StopPass == PassName && ++Count == Info.StopInstanceNum)
+        Stopped = !Info.StopAfter;
+      return !Stopped;
+    });
+  }
+}
+
+Error CodeGenPassBuilder::verifyStartStop(
+    const TargetPassConfig::StartStopInfo &Info) const {
+  if (Started && Stopped)
+    return Error::success();
+
+  if (!Started)
+    return make_error<StringError>(
+        "Can't find start pass \"" + Info.StartPass + "\".",
+        std::make_error_code(std::errc::invalid_argument));
+  if (!Stopped)
+    return make_error<StringError>(
+        "Can't find stop pass \"" + Info.StopPass + "\".",
+        std::make_error_code(std::errc::invalid_argument));
+  return Error::success();
+}
+
+void CodeGenPassBuilder::addISelPasses(PassManagerWrapper &PMW) {
+  addGlobalMergePass(PMW);
+  if (TM.useEmulatedTLS())
+    addModulePass(LowerEmuTLSPass(), PMW);
+
+  // ObjCARCContract operates on ObjC intrinsics and must run before
+  // PreISelIntrinsicLowering.
+  if (getOptLevel() != CodeGenOptLevel::None) {
+    addFunctionPass(ObjCARCContractPass(), PMW);
+    flushFPMsToMPM(PMW);
+  }
+  addModulePass(PreISelIntrinsicLoweringPass(&TM), PMW);
+  addFunctionPass(ExpandIRInstsPass(TM, getOptLevel()), PMW);
+
+  addIRPasses(PMW);
+  addCodeGenPrepare(PMW);
+  addPassesToHandleExceptions(PMW);
+  addISelPrepare(PMW);
+}
+
+/// Add common target configurable passes that perform LLVM IR to IR transforms
+/// following machine independent optimization.
+void CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
+  // 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);
+
+  // 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());
+    if (Opt.EnableLoopTermFold)
+      LPM.addPass(LoopTermFoldPass());
+    addFunctionPass(createFunctionToLoopPassAdaptor(std::move(LPM),
+                                                    /*UseMemorySSA=*/false),
+                    PMW);
+  }
+
+  // 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);
+  }
+
+  // Make sure that no unreachable blocks are instruction selected.
+  addFunctionPass(UnreachableBlockElimPass(), PMW);
+
+  // Prepare expensive constants for SelectionDAG.
+  if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableConstantHoisting)
+    addFunctionPass(ConstantHoistingPass(), PMW);
+
+  // 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);
+
+  if (getOptLevel() != CodeGenOptLevel::None &&
+      !Opt.DisablePartialLibcallInlining)
+    addFunctionPass(PartiallyInlineLibCallsPass(), PMW);
+
+  // Instrument function entry and exit, e.g. with calls to mcount().
+  addFunctionPass(EntryExitInstrumenterPass(/*PostInlining=*/true), PMW);
+
+  // 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);
+
+  // Expand reduction intrinsics into shuffle sequences if the target wants to.
+  if (!Opt.DisableExpandReductions)
+    addFunctionPass(ExpandReductionsPass(), PMW);
+
+  // Convert conditional moves to conditional jumps when profitable.
+  if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableSelectOptimize)
+    addFunctionPass(SelectOptimizePass(TM), PMW);
+
+  if (Opt.EnableGlobalMergeFunc) {
+    flushFPMsToMPM(PMW);
+    addModulePass(GlobalMergeFuncPass(), PMW);
+  }
+}
+
+/// Turn exception handling constructs into something the code generators can
+/// handle.
+void CodeGenPassBuilder::addPassesToHandleExceptions(PassManagerWrapper &PMW) {
+  const MCAsmInfo &MCAI = TM.getMCAsmInfo();
+  switch (MCAI.getExceptionHandlingType()) {
+  case ExceptionHandling::SjLj:
+    // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
+    // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
+    // catch info can get misplaced when a selector ends up more than one block
+    // 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);
+    [[fallthrough]];
+  case ExceptionHandling::DwarfCFI:
+  case ExceptionHandling::ARM:
+  case ExceptionHandling::AIX:
+  case ExceptionHandling::ZOS:
+    addFunctionPass(DwarfEHPreparePass(TM), PMW);
+    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);
+    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);
+    break;
+  case ExceptionHandling::None:
+    addFunctionPass(LowerInvokePass(), PMW);
+
+    // The lower invoke pass may create unreachable code. Remove it.
+    addFunctionPass(UnreachableBlockElimPass(), PMW);
+    break;
+  }
+}
+
+/// Add pass to prepare the LLVM IR for code generation. This should be done
+/// before exception handling preparation passes.
+void CodeGenPassBuilder::addCodeGenPrepare(PassManagerWrapper &PMW) {
+  if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableCGP)
+    addFunctionPass(CodeGenPreparePass(TM), PMW);
+  // TODO: Default ctor'd RewriteSymbolPass is no-op.
+  // addPass(RewriteSymbolPass());
+}
+
+/// Add common passes that perform LLVM IR to IR transforms in preparation for
+/// instruction selection.
+void CodeGenPassBuilder::addISelPrepare(PassManagerWrapper &PMW) {
+  addPreISel(PMW);
+
+  if (Opt.RequiresCodeGenSCCOrder && !AddInCGSCCOrder)
+    requireCGSCCOrder(PMW);
+
+  addFunctionPass(InlineAsmPreparePass(), PMW);
+  // 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);
+
+  if (Opt.PrintISelInput)
+    addFunctionPass(PrintFunctionPass(
+                        dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"),
+                    PMW);
+
+  // 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);
+}
+
+Error CodeGenPassBuilder::addCoreISelPasses(PassManagerWrapper &PMW) {
+  // Enable FastISel with -fast-isel, but allow that to be overridden.
+  TM.setO0WantsFastISel(Opt.EnableFastISelOption !=
+                        cl::boolOrDefault::BOU_FALSE);
+
+  // Determine an instruction selector.
+  enum class SelectorType { SelectionDAG, FastISel, GlobalISel };
+  SelectorType Selector;
+
+  if (Opt.EnableFastISelOption == cl::boolOrDefault::BOU_TRUE)
+    Selector = SelectorType::FastISel;
+  else if (Opt.EnableGlobalISelOption == cl::boolOrDefault::BOU_TRUE ||
+           (TM.Options.EnableGlobalISel &&
+            Opt.EnableGlobalISelOption != cl::boolOrDefault::BOU_FALSE))
+    Selector = SelectorType::GlobalISel;
+  else if (TM.getOptLevel() == CodeGenOptLevel::None && TM.getO0WantsFastISel())
+    Selector = SelectorType::FastISel;
+  else
+    Selector = SelectorType::SelectionDAG;
+
+  // Set consistently TM.Options.EnableFastISel and EnableGlobalISel.
+  if (Selector == SelectorType::FastISel) {
+    TM.setFastISel(true);
+    TM.setGlobalISel(false);
+  } else if (Selector == SelectorType::GlobalISel) {
+    TM.setFastISel(false);
+    TM.setGlobalISel(true);
+  }
+
+  // Add instruction selector passes.
+  if (Selector == SelectorType::GlobalISel) {
+    if (auto Err = addIRTranslator(PMW))
+      return Err;
+
+    addPreLegalizeMachineIR(PMW);
+
+    if (auto Err = addLegalizeMachineIR(PMW))
+      return Err;
+
+    // Before running the register bank selector, ask the target if it
+    // wants to run some passes.
+    addPreRegBankSelect(PMW);
+
+    if (auto Err = addRegBankSelect(PMW))
+      return Err;
+
+    addPreGlobalInstructionSelect(PMW);
+
+    if (auto Err = addGlobalInstructionSelect(PMW))
+      return Err;
+
+    // Pass to reset the MachineFunction if the ISel failed.
+    addMachineFunctionPass(
+        ResetMachineFunctionPass(reportDiagnosticWhenGlobalISelFallback(),
+                                 isGlobalISelAbortEnabled()),
+        PMW);
+
+    // Provide a fallback path when we do not want to abort on
+    // not-yet-supported input.
+    if (!isGlobalISelAbortEnabled())
+      if (auto Err = addInstSelector(PMW))
+        return Err;
+
+  } else if (auto Err = addInstSelector(PMW))
+    return Err;
+
+  // Expand pseudo-instructions emitted by ISel. Don't run the verifier before
+  // FinalizeISel.
+  addMachineFunctionPass(FinalizeISelPass(), PMW);
+
+  // // Print the instruction selected machine code...
+  // printAndVerify("After Instruction Selection");
+
+  return Error::success();
+}
+
+/// Add the complete set of target-independent postISel code generator passes.
+///
+/// This can be read as the standard order of major LLVM CodeGen stages. Stages
+/// with nontrivial configuration or multiple passes are broken out below in
+/// add%Stage routines.
+///
+/// Any CodeGenPassBuilder::addXX routine may be overriden by the Target. The
+/// addPre/Post methods with empty header implementations allow injecting
+/// target-specific fixups just before or after major stages. Additionally,
+/// targets have the flexibility to change pass order within a stage by
+/// overriding default implementation of add%Stage routines below. Each
+/// technique has maintainability tradeoffs because alternate pass orders are
+/// not well supported. addPre/Post works better if the target pass is easily
+/// tied to a common pass. But if it has subtle dependencies on multiple passes,
+/// the target should override the stage instead.
+Error CodeGenPassBuilder::addMachinePasses(PassManagerWrapper &PMW) {
+  // Add passes that optimize machine instructions in SSA form.
+  if (getOptLevel() != CodeGenOptLevel::None) {
+    addMachineSSAOptimization(PMW);
+  } 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);
+  }
+
+  if (TM.Options.EnableIPRA) {
+    flushFPMsToMPM(PMW);
+    addModulePass(RequireAnalysisPass<PhysicalRegisterUsageAnalysis, Module>(),
+                  PMW, /*Force=*/true);
+    addMachineFunctionPass(RegUsageInfoPropagationPass(), PMW);
+  }
+  // Run pre-ra passes.
+  addPreRegAlloc(PMW);
+
+  // 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
+                     ? addOptimizedRegAlloc(PMW)
+                     : addFastRegAlloc(PMW))
+    return Err;
+
+  // Run post-ra passes.
+  addPostRegAlloc(PMW);
+
+  addMachineFunctionPass(RemoveRedundantDebugValuesPass(), PMW);
+  addMachineFunctionPass(FixupStatepointCallerSavedPass(), PMW);
+
+  // Insert prolog/epilog code.  Eliminate abstract frame index references...
+  if (getOptLevel() != CodeGenOptLevel::None) {
+    addMachineFunctionPass(PostRAMachineSinkingPass(), PMW);
+    addMachineFunctionPass(ShrinkWrapPass(), PMW);
+  }
+
+  addMachineFunctionPass(PrologEpilogInserterPass(), PMW);
+
+  /// Add passes that optimize machine instructions after register allocation.
+  if (getOptLevel() != CodeGenOptLevel::None)
+    addMachineLateOptimization(PMW);
+
+  // Expand pseudo instructions before second scheduling pass.
+  addMachineFunctionPass(ExpandPostRAPseudosPass(), PMW);
+
+  // Run pre-sched2 passes.
+  addPreSched2(PMW);
+
+  if (Opt.EnableImplicitNullChecks)
+    addMachineFunctionPass(ImplicitNullChecksPass(), PMW);
+
+  // Second pass scheduler.
+  // Let Target optionally insert this pass by itself at some other
+  // point.
+  if (getOptLevel() != CodeGenOptLevel::None &&
+      !TM.targetSchedulesPostRAScheduling()) {
+    if (Opt.MISchedPostRA)
+      addMachineFunctionPass(PostMachineSchedulerPass(&TM), PMW);
+    else
+      addMachineFunctionPass(PostRASchedulerPass(&TM), PMW);
+  }
+
+  // GC
+  addGCPasses(PMW);
+
+  // Basic block placement.
+  if (getOptLevel() != CodeGenOptLevel::None)
+    addBlockPlacement(PMW);
+
+  // Insert before XRay Instrumentation.
+  addMachineFunctionPass(FEntryInserterPass(), PMW);
+
+  addMachineFunctionPass(XRayInstrumentationPass(), PMW);
+  addMachineFunctionPass(PatchableFunctionPass(), PMW);
+
+  addPreEmitPass(PMW);
+
+  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);
+    // If -print-regusage is specified, print the collected register usage info.
+    if (Opt.PrintRegUsage) {
+      flushFPMsToMPM(PMW);
+      addModulePass(PhysicalRegisterUsageInfoPrinterPass(errs()), PMW);
+    }
+  }
+
+  addMachineFunctionPass(FuncletLayoutPass(), PMW);
+
+  addMachineFunctionPass(RemoveLoadsIntoFakeUsesPass(), PMW);
+  addMachineFunctionPass(StackMapLivenessPass(), PMW);
+  addMachineFunctionPass(
+      LiveDebugValuesPass(TM.Options.ShouldEmitDebugEntryValues()), PMW);
+  addMachineFunctionPass(MachineSanitizerBinaryMetadataPass(), PMW);
+
+  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);
+    }
+  }
+
+  if (Opt.EnableGCEmptyBlocks)
+    addMachineFunctionPass(GCEmptyBasicBlocksPass(), PMW);
+
+  addPostBBSections(PMW);
+
+  addMachineFunctionPass(StackFrameLayoutAnalysisPass(), PMW);
+
+  // Add passes that directly emit MI after all other MI passes.
+  addPreEmitPass2(PMW);
+
+  return Error::success();
+}
+
+/// Add passes that optimize machine instructions in SSA form.
+void CodeGenPassBuilder::addMachineSSAOptimization(PassManagerWrapper &PMW) {
+  // Pre-ra tail duplication.
+  addMachineFunctionPass(EarlyTailDuplicatePass(), PMW);
+
+  // Optimize PHIs before DCE: removing dead PHI cycles may make more
+  // instructions dead.
+  addMachineFunctionPass(OptimizePHIsPass(), PMW);
+
+  // This pass merges large allocas. StackSlotColoring is a different pass
+  // which merges spill slots.
+  addMachineFunctionPass(StackColoringPass(), PMW);
+
+  // 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);
+
+  // 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);
+
+  // 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.
+  addILPOpts(PMW);
+
+  addMachineFunctionPass(EarlyMachineLICMPass(), PMW);
+  addMachineFunctionPass(MachineCSEPass(), PMW);
+
+  addMachineFunctionPass(MachineSinkingPass(Opt.EnableSinkAndFold), PMW);
+
+  addMachineFunctionPass(PeepholeOptimizerPass(), PMW);
+  // Clean-up the dead code that may have been generated by peephole
+  // rewriting.
+  addMachineFunctionPass(DeadMachineInstructionElimPass(), PMW);
+}
+
+//===---------------------------------------------------------------------===//
+/// Register Allocation Pass Configuration
+//===---------------------------------------------------------------------===//
+
+/// Instantiate the default register allocator pass for this target for either
+/// the optimized or unoptimized allocation path. This will be added to the pass
+/// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
+/// in the optimized case.
+///
+/// A target that uses the standard regalloc pass order for fast or optimized
+/// allocation may still override this for per-target regalloc
+/// selection. But -regalloc-npm=... always takes precedence.
+/// If a target does not want to allow users to set -regalloc-npm=... at all,
+/// check if Opt.RegAlloc == RegAllocType::Unset.
+void CodeGenPassBuilder::addTargetRegisterAllocator(PassManagerWrapper &PMW,
+                                                    bool Optimized) {
+  if (Optimized)
+    addMachineFunctionPass(RAGreedyPass(), PMW);
+  else
+    addMachineFunctionPass(RegAllocFastPass(), PMW);
+}
+
+/// Find and instantiate the register allocation pass requested by this target
+/// at the current optimization level.  Different register allocators are
+/// defined as separate passes because they may require different analysis.
+///
+/// This helper ensures that the -regalloc-npm= option is always available,
+/// even for targets that override the default allocator.
+void CodeGenPassBuilder::addRegAllocPass(PassManagerWrapper &PMW,
+                                         bool Optimized) {
+  // Use the specified -regalloc-npm={basic|greedy|fast|pbqp}
+  if (Opt.RegAlloc > RegAllocType::Default) {
+    switch (Opt.RegAlloc) {
+    case RegAllocType::Fast:
+      addMachineFunctionPass(RegAllocFastPass(), PMW);
+      break;
+    case RegAllocType::Greedy:
+      addMachineFunctionPass(RAGreedyPass(), PMW);
+      break;
+    default:
+      reportFatalUsageError("register allocator not supported yet");
+    }
+    return;
+  }
+  // -regalloc=default or unspecified, so pick based on the optimization level
+  // or ask the target for the regalloc pass.
+  addTargetRegisterAllocator(PMW, Optimized);
+}
+
+Error CodeGenPassBuilder::addRegAssignAndRewriteFast(PassManagerWrapper &PMW) {
+  // TODO: Ensure allocator is default or fast.
+  addRegAllocPass(PMW, false);
+  return Error::success();
+}
+
+Expected<bool>
+CodeGenPassBuilder::addRegAssignAndRewriteOptimized(PassManagerWrapper &PMW) {
+  // Add the selected register allocation pass.
+  addRegAllocPass(PMW, true);
+
+  // Allow targets to change the register assignments before rewriting.
+  addPreRewrite(PMW);
+
+  // Finally rewrite virtual registers.
+  addMachineFunctionPass(VirtRegRewriterPass(), PMW);
+
+  return true;
+}
+
+/// Add the minimum set of target-independent passes that are required for
+/// register allocation. No coalescing or scheduling.
+Error CodeGenPassBuilder::addFastRegAlloc(PassManagerWrapper &PMW) {
+  addMachineFunctionPass(PHIEliminationPass(), PMW);
+  addMachineFunctionPass(TwoAddressInstructionPass(), PMW);
+  return addRegAssignAndRewriteFast(PMW);
+}
+
+/// Add standard target-independent passes that are tightly coupled with
+/// optimized register allocation, including coalescing, machine instruction
+/// scheduling, and register allocation itself.
+Error CodeGenPassBuilder::addOptimizedRegAlloc(PassManagerWrapper &PMW) {
+  addMachineFunctionPass(DetectDeadLanesPass(), PMW);
+
+  addMachineFunctionPass(InitUndefPass(), PMW);
+
+  addMachineFunctionPass(ProcessImplicitDefsPass(), PMW);
+
+  // LiveVariables currently requires pure SSA form.
+  //
+  // FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
+  // LiveVariables can be removed completely, and LiveIntervals can be directly
+  // computed. (We still either need to regenerate kill flags after regalloc, or
+  // preferably fix the scavenger to not depend on them).
+  // FIXME: UnreachableMachineBlockElim is a dependant pass of LiveVariables.
+  // 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);
+
+  // Edge splitting is smarter with machine loop info.
+  addMachineFunctionPass(
+      RequireAnalysisPass<MachineLoopAnalysis, MachineFunction>(), PMW);
+  addMachineFunctionPass(PHIEliminationPass(), PMW);
+
+  // Eventually, we want to run LiveIntervals before PHI elimination.
+  if (Opt.EarlyLiveIntervals)
+    addMachineFunctionPass(
+        RequireAnalysisPass<LiveIntervalsAnalysis, MachineFunction>(), PMW);
+
+  addMachineFunctionPass(TwoAddressInstructionPass(), PMW);
+  addMachineFunctionPass(RegisterCoalescerPass(), PMW);
+
+  // 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);
+
+  // PreRA instruction scheduling.
+  addMachineFunctionPass(MachineSchedulerPass(&TM), PMW);
+
+  Expected<bool> AddedPasses = addRegAssignAndRewriteOptimized(PMW);
+  if (!AddedPasses)
+    return AddedPasses.takeError();
+  if (!AddedPasses.get())
+    return Error::success();
+
+  addMachineFunctionPass(StackSlotColoringPass(), PMW);
+
+  // Allow targets to expand pseudo instructions depending on the choice of
+  // registers before MachineCopyPropagation.
+  addPostRewrite(PMW);
+
+  // Copy propagate to forward register uses and try to eliminate COPYs that
+  // were not coalesced.
+  addMachineFunctionPass(MachineCopyPropagationPass(), PMW);
+
+  // Run post-ra machine LICM to hoist reloads / remats.
+  //
+  // FIXME: can this move into MachineLateOptimization?
+  addMachineFunctionPass(MachineLICMPass(), PMW);
+
+  return Error::success();
+}
+
+//===---------------------------------------------------------------------===//
+/// Post RegAlloc Pass Configuration
+//===---------------------------------------------------------------------===//
+
+/// Add passes that optimize machine instructions after register allocation.
+void CodeGenPassBuilder::addMachineLateOptimization(PassManagerWrapper &PMW) {
+  // Cleanup of redundant (identical) address/immediate loads.
+  addMachineFunctionPass(MachineLateInstrsCleanupPass(), PMW);
+
+  // Branch folding must be run after regalloc and prolog/epilog insertion.
+  addMachineFunctionPass(BranchFolderPass(Opt.EnableTailMerge), PMW);
+
+  // 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);
+
+  // Copy propagation.
+  addMachineFunctionPass(MachineCopyPropagationPass(), PMW);
+}
+
+/// Add standard basic block placement passes.
+void CodeGenPassBuilder::addBlockPlacement(PassManagerWrapper &PMW) {
+  addMachineFunctionPass(MachineBlockPlacementPass(Opt.EnableTailMerge), PMW);
+  // Run a separate pass to collect block placement statistics.
+  if (Opt.EnableBlockPlacementStats)
+    addMachineFunctionPass(MachineBlockPlacementStatsPass(), PMW);
+}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 6b70838579c62..0e39bc266924d 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -77,7 +77,9 @@
 #include "llvm/CodeGen/AtomicExpand.h"
 #include "llvm/CodeGen/BranchRelaxation.h"
 #include "llvm/CodeGen/DeadMachineInstructionElim.h"
+#include "llvm/CodeGen/DetectDeadLanes.h"
 #include "llvm/CodeGen/EarlyIfConversion.h"
+#include "llvm/CodeGen/GCMetadata.h"
 #include "llvm/CodeGen/GlobalISel/CSEInfo.h"
 #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
 #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
@@ -88,10 +90,18 @@
 #include "llvm/CodeGen/MachineCSE.h"
 #include "llvm/CodeGen/MachineLICM.h"
 #include "llvm/CodeGen/MachineScheduler.h"
+#include "llvm/CodeGen/PHIElimination.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/PatchableFunction.h"
 #include "llvm/CodeGen/PostRAHazardRecognizer.h"
+#include "llvm/CodeGen/RegAllocFast.h"
+#include "llvm/CodeGen/RegAllocGreedyPass.h"
 #include "llvm/CodeGen/RegAllocRegistry.h"
+#include "llvm/CodeGen/RenameIndependentSubregs.h"
+#include "llvm/CodeGen/ShadowStackGCLowering.h"
+#include "llvm/CodeGen/StackSlotColoring.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/CodeGen/TwoAddressInstructionPass.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/IntrinsicsAMDGPU.h"
 #include "llvm/IR/Module.h"
@@ -140,35 +150,38 @@ namespace {
 // AMDGPU CodeGen Pass Builder interface.
 //===----------------------------------------------------------------------===//
 
-class AMDGPUCodeGenPassBuilder
-    : public CodeGenPassBuilder<AMDGPUCodeGenPassBuilder, GCNTargetMachine> {
-  using Base = CodeGenPassBuilder<AMDGPUCodeGenPassBuilder, GCNTargetMachine>;
+class AMDGPUCodeGenPassBuilder : public CodeGenPassBuilder {
+  using Base = CodeGenPassBuilder;
+
+  GCNTargetMachine &getTM() const {
+    return static_cast<GCNTargetMachine &>(TM);
+  }
 
 public:
   AMDGPUCodeGenPassBuilder(GCNTargetMachine &TM,
                            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 addRegAssignAndRewriteFast(PassManagerWrapper &PMW) const;
-  Expected<bool> addRegAssignAndRewriteOptimized(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(PassManagerWrapper &PMW) override;
+  void addCodeGenPrepare(PassManagerWrapper &PMW) override;
+  void addPreISel(PassManagerWrapper &PMW) override;
+  void addILPOpts(PassManagerWrapper &PMW) override;
+  void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
+  void addAsmPrinter(PassManagerWrapper &PMW) override;
+  void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
+  Error addInstSelector(PassManagerWrapper &PMW) override;
+  void addPreRewrite(PassManagerWrapper &PMW) override;
+  void addMachineSSAOptimization(PassManagerWrapper &PMW) override;
+  void addPostRegAlloc(PassManagerWrapper &PMW) override;
+  void addPreEmitPass(PassManagerWrapper &PMW) override;
+  Error addRegAssignAndRewriteFast(PassManagerWrapper &PMW) override;
+  Expected<bool>
+  addRegAssignAndRewriteOptimized(PassManagerWrapper &PMW) override;
+  void addPreRegAlloc(PassManagerWrapper &PMW) override;
+  Error addFastRegAlloc(PassManagerWrapper &PMW) override;
+  Error addOptimizedRegAlloc(PassManagerWrapper &PMW) override;
+  void addPreSched2(PassManagerWrapper &PMW) override;
+  void addPostBBSections(PassManagerWrapper &PMW) override;
 
 private:
   Error validateRegAllocOptions() const;
@@ -179,8 +192,8 @@ 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(PassManagerWrapper &PMW);
+  void addStraightLineScalarOptimizationPasses(PassManagerWrapper &PMW);
 };
 
 class SGPRRegisterRegAlloc : public RegisterRegAllocBase<SGPRRegisterRegAlloc> {
@@ -2333,7 +2346,7 @@ AMDGPUCodeGenPassBuilder::AMDGPUCodeGenPassBuilder(
               ShadowStackGCLoweringPass, GCLoweringPass>();
 }
 
-void AMDGPUCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
   if (RemoveIncompatibleFunctions && TM.getTargetTriple().isAMDGCN()) {
     flushFPMsToMPM(PMW);
     addModulePass(AMDGPURemoveIncompatibleFunctionsPass(TM), PMW);
@@ -2370,7 +2383,7 @@ void AMDGPUCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
 
   // Runs before PromoteAlloca so the latter can account for function uses
   if (EnableLowerModuleLDS)
-    addModulePass(AMDGPULowerModuleLDSPass(TM), PMW);
+    addModulePass(AMDGPULowerModuleLDSPass(getTM()), PMW);
 
   // Run atomic optimizer before Atomic Expand
   if (TM.getOptLevel() >= CodeGenOptLevel::Less &&
@@ -2417,8 +2430,7 @@ void AMDGPUCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
     addEarlyCSEOrGVNPass(PMW);
 }
 
-void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(
-    PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(PassManagerWrapper &PMW) {
   if (TM.getOptLevel() > CodeGenOptLevel::None) {
     flushFPMsToMPM(PMW);
     addModulePass(AMDGPUPreloadKernelArgumentsPass(TM), PMW);
@@ -2444,7 +2456,7 @@ void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(
   flushFPMsToMPM(PMW);
   requireCGSCCOrder(PMW);
 
-  addModulePass(AMDGPULowerIntrinsicsPass(TM), PMW);
+  addModulePass(AMDGPULowerIntrinsicsPass(getTM()), PMW);
 
   // LowerSwitch pass may introduce unreachable blocks that can cause unexpected
   // behavior for subsequent passes. Placing it here seems better that these
@@ -2453,12 +2465,12 @@ void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(
   addFunctionPass(LowerSwitchPass(), PMW);
 }
 
-void AMDGPUCodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) {
 
   if (TM.getOptLevel() > CodeGenOptLevel::None) {
     addFunctionPass(FlattenCFGPass(), PMW);
     addFunctionPass(SinkingPass(), PMW);
-    addFunctionPass(AMDGPULateCodeGenPreparePass(TM), PMW);
+    addFunctionPass(AMDGPULateCodeGenPreparePass(getTM()), PMW);
   }
 
   // Merge divergent exit nodes. StructurizeCFG won't recognize the multi-exit
@@ -2471,7 +2483,7 @@ void AMDGPUCodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
 
   addFunctionPass(AMDGPUAnnotateUniformValuesPass(), PMW);
 
-  addFunctionPass(SIAnnotateControlFlowPass(TM), PMW);
+  addFunctionPass(SIAnnotateControlFlowPass(getTM()), PMW);
 
   // TODO: Move this right after structurizeCFG to avoid extra divergence
   // analysis. This depends on stopping SIAnnotateControlFlow from making
@@ -2485,39 +2497,38 @@ void AMDGPUCodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
 
   if (TM.getOptLevel() > CodeGenOptLevel::Less) {
     flushFPMsToMPM(PMW);
-    addModulePass(AMDGPUPerfHintAnalysisPass(TM), PMW);
+    addModulePass(AMDGPUPerfHintAnalysisPass(getTM()), PMW);
   }
 }
 
-void AMDGPUCodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) {
   if (EnableEarlyIfConversion)
     addMachineFunctionPass(EarlyIfConverterPass(), PMW);
 
   Base::addILPOpts(PMW);
 }
 
-void AMDGPUCodeGenPassBuilder::addAsmPrinterBegin(
-    PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
   addModulePass(AMDGPUAsmPrinterBeginPass(), PMW,
                 /*Force=*/true);
 }
 
-void AMDGPUCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
   addMachineFunctionPass(AMDGPUAsmPrinterPass(), PMW);
 }
 
-void AMDGPUCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
   addModulePass(AMDGPUAsmPrinterEndPass(), PMW);
 }
 
-Error AMDGPUCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
+Error AMDGPUCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
   addMachineFunctionPass(AMDGPUISelDAGToDAGPass(TM), PMW);
   addMachineFunctionPass(SIFixSGPRCopiesPass(), PMW);
   addMachineFunctionPass(SILowerI1CopiesPass(), PMW);
   return Error::success();
 }
 
-void AMDGPUCodeGenPassBuilder::addPreRewrite(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPreRewrite(PassManagerWrapper &PMW) {
   if (EnableRegReassign) {
     addMachineFunctionPass(GCNNSAReassignPass(), PMW);
   }
@@ -2526,7 +2537,7 @@ void AMDGPUCodeGenPassBuilder::addPreRewrite(PassManagerWrapper &PMW) const {
 }
 
 void AMDGPUCodeGenPassBuilder::addMachineSSAOptimization(
-    PassManagerWrapper &PMW) const {
+    PassManagerWrapper &PMW) {
   Base::addMachineSSAOptimization(PMW);
 
   addMachineFunctionPass(SIFoldOperandsPass(), PMW);
@@ -2544,7 +2555,7 @@ void AMDGPUCodeGenPassBuilder::addMachineSSAOptimization(
   addMachineFunctionPass(SIShrinkInstructionsPass(), PMW);
 }
 
-Error AMDGPUCodeGenPassBuilder::addFastRegAlloc(PassManagerWrapper &PMW) const {
+Error AMDGPUCodeGenPassBuilder::addFastRegAlloc(PassManagerWrapper &PMW) {
   insertPass<PHIEliminationPass>(SILowerControlFlowPass());
 
   insertPass<TwoAddressInstructionPass>(SIWholeQuadModePass());
@@ -2553,7 +2564,7 @@ Error AMDGPUCodeGenPassBuilder::addFastRegAlloc(PassManagerWrapper &PMW) const {
 }
 
 Error AMDGPUCodeGenPassBuilder::addRegAssignAndRewriteFast(
-    PassManagerWrapper &PMW) const {
+    PassManagerWrapper &PMW) {
   if (auto Err = validateRegAllocOptions())
     return Err;
 
@@ -2591,8 +2602,7 @@ Error AMDGPUCodeGenPassBuilder::addRegAssignAndRewriteFast(
   return Error::success();
 }
 
-Error AMDGPUCodeGenPassBuilder::addOptimizedRegAlloc(
-    PassManagerWrapper &PMW) const {
+Error AMDGPUCodeGenPassBuilder::addOptimizedRegAlloc(PassManagerWrapper &PMW) {
   if (EnableDCEInRA)
     insertPass<DetectDeadLanesPass>(DeadMachineInstructionElimPass());
 
@@ -2630,13 +2640,13 @@ Error AMDGPUCodeGenPassBuilder::addOptimizedRegAlloc(
   return Base::addOptimizedRegAlloc(PMW);
 }
 
-void AMDGPUCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) {
   if (getOptLevel() != CodeGenOptLevel::None)
     addMachineFunctionPass(AMDGPUPrepareAGPRAllocPass(), PMW);
 }
 
 Expected<bool> AMDGPUCodeGenPassBuilder::addRegAssignAndRewriteOptimized(
-    PassManagerWrapper &PMW) const {
+    PassManagerWrapper &PMW) {
   if (auto Err = validateRegAllocOptions())
     return Err;
 
@@ -2689,27 +2699,26 @@ Expected<bool> AMDGPUCodeGenPassBuilder::addRegAssignAndRewriteOptimized(
   return true;
 }
 
-void AMDGPUCodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) {
   addMachineFunctionPass(SIFixVGPRCopiesPass(), PMW);
   if (TM.getOptLevel() > CodeGenOptLevel::None)
     addMachineFunctionPass(SIOptimizeExecMaskingPass(), PMW);
   Base::addPostRegAlloc(PMW);
 }
 
-void AMDGPUCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) {
   if (TM.getOptLevel() > CodeGenOptLevel::None)
     addMachineFunctionPass(SIShrinkInstructionsPass(), PMW);
   addMachineFunctionPass(SIPostRABundlerPass(), PMW);
 }
 
-void AMDGPUCodeGenPassBuilder::addPostBBSections(
-    PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPostBBSections(PassManagerWrapper &PMW) {
   // 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);
 }
 
-void AMDGPUCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
   if (isPassEnabled(EnableVOPD, CodeGenOptLevel::Less)) {
     addMachineFunctionPass(GCNCreateVOPDPass(), PMW);
   }
@@ -2758,8 +2767,7 @@ bool AMDGPUCodeGenPassBuilder::isPassEnabled(const cl::opt<bool> &Opt,
   return Opt;
 }
 
-void AMDGPUCodeGenPassBuilder::addEarlyCSEOrGVNPass(
-    PassManagerWrapper &PMW) const {
+void AMDGPUCodeGenPassBuilder::addEarlyCSEOrGVNPass(PassManagerWrapper &PMW) {
   if (TM.getOptLevel() == CodeGenOptLevel::Aggressive)
     addFunctionPass(GVNPass(), PMW);
   else
@@ -2767,7 +2775,7 @@ void AMDGPUCodeGenPassBuilder::addEarlyCSEOrGVNPass(
 }
 
 void AMDGPUCodeGenPassBuilder::addStraightLineScalarOptimizationPasses(
-    PassManagerWrapper &PMW) const {
+    PassManagerWrapper &PMW) {
   if (isPassEnabled(EnableLoopPrefetch, CodeGenOptLevel::Aggressive))
     addFunctionPass(LoopDataPrefetchPass(), PMW);
 
diff --git a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
index 2d7dd12a94a56..a8bf8ba152045 100644
--- a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
@@ -51,17 +51,16 @@ static MachineSchedRegistry R600SchedRegistry("r600",
 // R600 CodeGen Pass Builder interface.
 //===----------------------------------------------------------------------===//
 
-class R600CodeGenPassBuilder
-    : public CodeGenPassBuilder<R600CodeGenPassBuilder, R600TargetMachine> {
+class R600CodeGenPassBuilder : public CodeGenPassBuilder {
 public:
   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;
+  void addPreISel(PassManagerWrapper &PMW) override;
+  void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
+  void addAsmPrinter(PassManagerWrapper &PMW) override;
+  void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
+  Error addInstSelector(PassManagerWrapper &PMW) override;
 };
 
 //===----------------------------------------------------------------------===//
@@ -186,23 +185,23 @@ R600CodeGenPassBuilder::R600CodeGenPassBuilder(
   Opt.RequiresCodeGenSCCOrder = true;
 }
 
-void R600CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
+void R600CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) {
   // TODO: Add passes pre instruction selection.
 }
 
-void R600CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
+void R600CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
   // TODO: Add AsmPrinterBegin
 }
 
-void R600CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
+void R600CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
   // TODO: Add AsmPrinter.
 }
 
-void R600CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
+void R600CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
   // TODO: Add AsmPrinterEnd
 }
 
-Error R600CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
+Error R600CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
   // TODO: Add instruction selector.
   return Error::success();
 }
diff --git a/llvm/lib/Target/BPF/BPFCodeGenPassBuilder.cpp b/llvm/lib/Target/BPF/BPFCodeGenPassBuilder.cpp
index e9d8f2abc06f9..f70eda86dc580 100644
--- a/llvm/lib/Target/BPF/BPFCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/BPF/BPFCodeGenPassBuilder.cpp
@@ -26,9 +26,12 @@ extern cl::opt<bool> DisableMIPeephole;
 
 namespace {
 
-class BPFCodeGenPassBuilder
-    : public CodeGenPassBuilder<BPFCodeGenPassBuilder, BPFTargetMachine> {
-  using Base = CodeGenPassBuilder<BPFCodeGenPassBuilder, BPFTargetMachine>;
+class BPFCodeGenPassBuilder : public CodeGenPassBuilder {
+  using Base = CodeGenPassBuilder;
+
+  BPFTargetMachine &getTM() const {
+    return static_cast<BPFTargetMachine &>(TM);
+  }
 
 public:
   explicit BPFCodeGenPassBuilder(BPFTargetMachine &TM,
@@ -36,16 +39,16 @@ 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(PassManagerWrapper &PMW) override;
+  Error addInstSelector(PassManagerWrapper &PMW) override;
+  void addMachineSSAOptimization(PassManagerWrapper &PMW) override;
+  void addPreEmitPass(PassManagerWrapper &PMW) override;
+  void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
+  void addAsmPrinter(PassManagerWrapper &PMW) override;
+  void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
 };
 
-void BPFCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
+void BPFCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
   addFunctionPass(AtomicExpandPass(TM), PMW);
   flushFPMsToMPM(PMW);
   addModulePass(BPFCheckAndAdjustIRPass(), PMW);
@@ -53,25 +56,24 @@ void BPFCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
   Base::addIRPasses(PMW);
 }
 
-Error BPFCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(BPFISelDAGToDAGPass(TM), PMW);
+Error BPFCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
+  addMachineFunctionPass(BPFISelDAGToDAGPass(getTM()), PMW);
   return Error::success();
 }
 
-void BPFCodeGenPassBuilder::addMachineSSAOptimization(
-    PassManagerWrapper &PMW) const {
+void BPFCodeGenPassBuilder::addMachineSSAOptimization(PassManagerWrapper &PMW) {
   addMachineFunctionPass(BPFMISimplifyPatchablePass(), PMW);
 
   Base::addMachineSSAOptimization(PMW);
 
-  const BPFSubtarget *Subtarget = TM.getSubtargetImpl();
+  const BPFSubtarget *Subtarget = getTM().getSubtargetImpl();
   if (!DisableMIPeephole) {
     if (Subtarget->getHasAlu32())
       addMachineFunctionPass(BPFMIPeepholePass(), PMW);
   }
 }
 
-void BPFCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
+void BPFCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
   addMachineFunctionPass(BPFMIPreEmitCheckingPass(), PMW);
   if (!DisableMIPeephole) {
     addMachineFunctionPass(BPFMIExpandStackArgPseudosPass(), PMW);
@@ -79,15 +81,15 @@ void BPFCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
   }
 }
 
-void BPFCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
+void BPFCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
   addModulePass(BPFAsmPrinterBeginPass(), PMW, /*Force=*/true);
 }
 
-void BPFCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
+void BPFCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
   addMachineFunctionPass(BPFAsmPrinterPass(), PMW);
 }
 
-void BPFCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
+void BPFCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
   addModulePass(BPFAsmPrinterEndPass(), PMW);
 }
 
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 a082e9a807f76..858b410ba897c 100644
--- a/llvm/lib/Target/Lanai/LanaiCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/Lanai/LanaiCodeGenPassBuilder.cpp
@@ -20,9 +20,12 @@ using namespace llvm;
 
 namespace {
 
-class LanaiCodeGenPassBuilder
-    : public CodeGenPassBuilder<LanaiCodeGenPassBuilder, LanaiTargetMachine> {
-  using Base = CodeGenPassBuilder<LanaiCodeGenPassBuilder, LanaiTargetMachine>;
+class LanaiCodeGenPassBuilder : public CodeGenPassBuilder {
+  using Base = CodeGenPassBuilder;
+
+  LanaiTargetMachine &getTM() const {
+    return static_cast<LanaiTargetMachine &>(TM);
+  }
 
 public:
   explicit LanaiCodeGenPassBuilder(LanaiTargetMachine &TM,
@@ -30,44 +33,43 @@ 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(PassManagerWrapper &PMW) override;
+  Error addInstSelector(PassManagerWrapper &PMW) override;
+  void addPreSched2(PassManagerWrapper &PMW) override;
+  void addPreEmitPass(PassManagerWrapper &PMW) override;
+  void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
+  void addAsmPrinter(PassManagerWrapper &PMW) override;
+  void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
 };
 
-void LanaiCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
+void LanaiCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
   addFunctionPass(AtomicExpandPass(TM), PMW);
 
   Base::addIRPasses(PMW);
 }
 
-Error LanaiCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(LanaiISelDAGToDAGPass(TM), PMW);
+Error LanaiCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
+  addMachineFunctionPass(LanaiISelDAGToDAGPass(getTM()), PMW);
   return Error::success();
 }
 
-void LanaiCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
+void LanaiCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) {
   addMachineFunctionPass(LanaiMemAluCombinerPass(), PMW);
 }
 
-void LanaiCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
+void LanaiCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
   addMachineFunctionPass(LanaiDelaySlotFillerPass(), PMW);
 }
 
-void LanaiCodeGenPassBuilder::addAsmPrinterBegin(
-    PassManagerWrapper &PMW) const {
+void LanaiCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
   addModulePass(LanaiAsmPrinterBeginPass(), PMW, /*Force=*/true);
 }
 
-void LanaiCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
+void LanaiCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
   addMachineFunctionPass(LanaiAsmPrinterPass(), PMW);
 }
 
-void LanaiCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
+void LanaiCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
   addModulePass(LanaiAsmPrinterEndPass(), PMW, /*Force=*/true);
 }
 
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..72a4e11aa70c3 100644
--- a/llvm/lib/Target/MSP430/MSP430CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/MSP430/MSP430CodeGenPassBuilder.cpp
@@ -21,10 +21,12 @@ using namespace llvm;
 
 namespace {
 
-class MSP430CodeGenPassBuilder
-    : public CodeGenPassBuilder<MSP430CodeGenPassBuilder, MSP430TargetMachine> {
-  using Base =
-      CodeGenPassBuilder<MSP430CodeGenPassBuilder, MSP430TargetMachine>;
+class MSP430CodeGenPassBuilder : public CodeGenPassBuilder {
+  using Base = CodeGenPassBuilder;
+
+  MSP430TargetMachine &getTM() const {
+    return static_cast<MSP430TargetMachine &>(TM);
+  }
 
 public:
   explicit MSP430CodeGenPassBuilder(MSP430TargetMachine &TM,
@@ -32,39 +34,38 @@ 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(PassManagerWrapper &PMW) override;
+  Error addInstSelector(PassManagerWrapper &PMW) override;
+  void addPreEmitPass(PassManagerWrapper &PMW) override;
+  void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
+  void addAsmPrinter(PassManagerWrapper &PMW) override;
+  void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
 };
 
-void MSP430CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
+void MSP430CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
   addFunctionPass(AtomicExpandPass(TM), PMW);
 
   Base::addIRPasses(PMW);
 }
 
-Error MSP430CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(MSP430ISelDAGToDAGPass(TM, getOptLevel()), PMW);
+Error MSP430CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
+  addMachineFunctionPass(MSP430ISelDAGToDAGPass(getTM(), getOptLevel()), PMW);
   return Error::success();
 }
 
-void MSP430CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
+void MSP430CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
   addMachineFunctionPass(MSP430BranchSelectPass(), PMW);
 }
 
-void MSP430CodeGenPassBuilder::addAsmPrinterBegin(
-    PassManagerWrapper &PMW) const {
+void MSP430CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
   addModulePass(MSP430AsmPrinterBeginPass(), PMW, /*Force=*/true);
 }
 
-void MSP430CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
+void MSP430CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
   addMachineFunctionPass(MSP430AsmPrinterPass(), PMW);
 }
 
-void MSP430CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
+void MSP430CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
   addModulePass(MSP430AsmPrinterEndPass(), PMW);
 }
 
diff --git a/llvm/lib/Target/RISCV/RISCVCodeGenPassBuilder.cpp b/llvm/lib/Target/RISCV/RISCVCodeGenPassBuilder.cpp
index c614b5a7ff6e6..8dce04b92eefd 100644
--- a/llvm/lib/Target/RISCV/RISCVCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/RISCV/RISCVCodeGenPassBuilder.cpp
@@ -34,9 +34,12 @@ using namespace llvm;
 
 namespace {
 
-class RISCVCodeGenPassBuilder
-    : public CodeGenPassBuilder<RISCVCodeGenPassBuilder, RISCVTargetMachine> {
-  using Base = CodeGenPassBuilder<RISCVCodeGenPassBuilder, RISCVTargetMachine>;
+class RISCVCodeGenPassBuilder : public CodeGenPassBuilder {
+  using Base = CodeGenPassBuilder;
+
+  RISCVTargetMachine &getTM() const {
+    return static_cast<RISCVTargetMachine &>(TM);
+  }
 
 public:
   explicit RISCVCodeGenPassBuilder(RISCVTargetMachine &TM,
@@ -50,30 +53,30 @@ class RISCVCodeGenPassBuilder
     // uses the base class default (disabled).
   }
 
-  void addIRPasses(PassManagerWrapper &PMW) const;
-  void addCodeGenPrepare(PassManagerWrapper &PMW) const;
-  Error addInstSelector(PassManagerWrapper &PMW) const;
-  void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
-  void addPreRegAlloc(PassManagerWrapper &PMW) const;
-  void addPostRegAlloc(PassManagerWrapper &PMW) const;
-  void addPreSched2(PassManagerWrapper &PMW) const;
-  void addPreEmitPass(PassManagerWrapper &PMW) const;
-  void addPreEmitPass2(PassManagerWrapper &PMW) const;
-  void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
-  void addAsmPrinter(PassManagerWrapper &PMW) const;
-  void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
+  void addIRPasses(PassManagerWrapper &PMW) override;
+  void addCodeGenPrepare(PassManagerWrapper &PMW) override;
+  Error addInstSelector(PassManagerWrapper &PMW) override;
+  void addMachineSSAOptimization(PassManagerWrapper &PMW) override;
+  void addPreRegAlloc(PassManagerWrapper &PMW) override;
+  void addPostRegAlloc(PassManagerWrapper &PMW) override;
+  void addPreSched2(PassManagerWrapper &PMW) override;
+  void addPreEmitPass(PassManagerWrapper &PMW) override;
+  void addPreEmitPass2(PassManagerWrapper &PMW) override;
+  void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
+  void addAsmPrinter(PassManagerWrapper &PMW) override;
+  void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
 };
 
-void RISCVCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
+void RISCVCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
   addFunctionPass(AtomicExpandPass(TM), PMW);
-  addFunctionPass(RISCVZacasABIFixPass(&TM), PMW);
+  addFunctionPass(RISCVZacasABIFixPass(&getTM()), PMW);
 
   if (getOptLevel() != CodeGenOptLevel::None) {
     addFunctionPass(LoopDataPrefetchPass(), PMW);
 
-    addFunctionPass(RISCVGatherScatterLoweringPass(&TM), PMW);
+    addFunctionPass(RISCVGatherScatterLoweringPass(&getTM()), PMW);
     addFunctionPass(InterleavedAccessPass(TM), PMW);
-    addFunctionPass(RISCVCodeGenPreparePass(&TM), PMW);
+    addFunctionPass(RISCVCodeGenPreparePass(&getTM()), PMW);
   }
 
   Base::addIRPasses(PMW);
@@ -84,19 +87,19 @@ void RISCVCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
   // yet replicated here.
 }
 
-void RISCVCodeGenPassBuilder::addCodeGenPrepare(PassManagerWrapper &PMW) const {
+void RISCVCodeGenPassBuilder::addCodeGenPrepare(PassManagerWrapper &PMW) {
   if (getOptLevel() != CodeGenOptLevel::None)
     addFunctionPass(TypePromotionPass(TM), PMW);
   Base::addCodeGenPrepare(PMW);
 }
 
-Error RISCVCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(RISCVISelDAGToDAGPass(TM, getOptLevel()), PMW);
+Error RISCVCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
+  addMachineFunctionPass(RISCVISelDAGToDAGPass(getTM(), getOptLevel()), PMW);
   return Error::success();
 }
 
 void RISCVCodeGenPassBuilder::addMachineSSAOptimization(
-    PassManagerWrapper &PMW) const {
+    PassManagerWrapper &PMW) {
   // It's beneficial to reduce the VL to enable more
   // Machine SSA optimizations.
   if (getOptLevel() != CodeGenOptLevel::None) {
@@ -120,7 +123,7 @@ void RISCVCodeGenPassBuilder::addMachineSSAOptimization(
   }
 }
 
-void RISCVCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
+void RISCVCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) {
   // TODO: RISCVPreRAExpandPseudoPass
   if (getOptLevel() != CodeGenOptLevel::None) {
     // TODO: RISCVMergeBaseOffsetOptPass
@@ -136,13 +139,13 @@ void RISCVCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
   // TODO: RISCVVMV0EliminationPass
 }
 
-void RISCVCodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
+void RISCVCodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) {
   if (getOptLevel() != CodeGenOptLevel::None) {
     // TODO: RISCVRedundantCopyEliminationPass
   }
 }
 
-void RISCVCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
+void RISCVCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) {
   // TODO: RISCVPostRAExpandPseudoPass
 
   addMachineFunctionPass(MachineKCFIPass(), PMW);
@@ -151,7 +154,7 @@ void RISCVCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
   }
 }
 
-void RISCVCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
+void RISCVCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
   // TODO: It would potentially be better to schedule copy propagation after
   // expanding pseudos (in addPreEmitPass2). However, performing copy
   // propagation after the machine outliner (which runs after addPreEmitPass)
@@ -169,7 +172,7 @@ void RISCVCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
   // TODO: RISCVMakeCompressibleOptPass
 }
 
-void RISCVCodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
+void RISCVCodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) {
   if (getOptLevel() != CodeGenOptLevel::None) {
     // TODO: RISCVMoveMergePass
     // TODO: RISCVPushPopOptimizationPass
@@ -194,16 +197,15 @@ void RISCVCodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
   // TODO: CFIInstrInserterPass
 }
 
-void RISCVCodeGenPassBuilder::addAsmPrinterBegin(
-    PassManagerWrapper &PMW) const {
+void RISCVCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
   addModulePass(RISCVAsmPrinterBeginPass(), PMW, /*Force=*/true);
 }
 
-void RISCVCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
+void RISCVCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
   addMachineFunctionPass(RISCVAsmPrinterPass(), PMW);
 }
 
-void RISCVCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
+void RISCVCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
   addModulePass(RISCVAsmPrinterEndPass(), PMW, /*Force=*/true);
 }
 
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 140d0405e4239..e91ea84e44976 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCodeGenPassBuilder.cpp
@@ -50,11 +50,12 @@ using llvm::WebAssembly::WasmEnableSjLj;
 
 namespace {
 
-class WebAssemblyCodeGenPassBuilder
-    : public CodeGenPassBuilder<WebAssemblyCodeGenPassBuilder,
-                                WebAssemblyTargetMachine> {
-  using Base = CodeGenPassBuilder<WebAssemblyCodeGenPassBuilder,
-                                  WebAssemblyTargetMachine>;
+class WebAssemblyCodeGenPassBuilder : public CodeGenPassBuilder {
+  using Base = CodeGenPassBuilder;
+
+  WebAssemblyTargetMachine &getTM() const {
+    return static_cast<WebAssemblyTargetMachine &>(TM);
+  }
 
 public:
   explicit WebAssemblyCodeGenPassBuilder(WebAssemblyTargetMachine &TM,
@@ -78,18 +79,19 @@ class WebAssemblyCodeGenPassBuilder
       disablePass<RegisterCoalescerPass>();
   }
 
-  void addIRPasses(PassManagerWrapper &PMW) const;
-  void addISelPrepare(PassManagerWrapper &PMW) const;
-  Error addInstSelector(PassManagerWrapper &PMW) const;
-  Error addRegAssignAndRewriteFast(PassManagerWrapper &PMW) const;
-  Expected<bool> addRegAssignAndRewriteOptimized(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(PassManagerWrapper &PMW) override;
+  void addISelPrepare(PassManagerWrapper &PMW) override;
+  Error addInstSelector(PassManagerWrapper &PMW) override;
+  Error addRegAssignAndRewriteFast(PassManagerWrapper &PMW) override;
+  Expected<bool>
+  addRegAssignAndRewriteOptimized(PassManagerWrapper &PMW) override;
+  void addPreEmitPass(PassManagerWrapper &PMW) override;
+  void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
+  void addAsmPrinter(PassManagerWrapper &PMW) override;
+  void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
 };
 
-void WebAssemblyCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
+void WebAssemblyCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
   // Add signatures to prototype-less function declarations
   flushFPMsToMPM(PMW);
   addModulePass(WebAssemblyAddMissingPrototypesPass(), PMW);
@@ -131,19 +133,18 @@ void WebAssemblyCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
   addFunctionPass(IndirectBrExpandPass(TM), PMW);
 
   // Try to expand `vecreduce_{and, or}` into `{any, all}_true`.
-  addFunctionPass(WebAssemblyReduceToAnyAllTruePass(TM), PMW);
+  addFunctionPass(WebAssemblyReduceToAnyAllTruePass(getTM()), PMW);
 
   Base::addIRPasses(PMW);
 }
 
-void WebAssemblyCodeGenPassBuilder::addISelPrepare(
-    PassManagerWrapper &PMW) const {
+void WebAssemblyCodeGenPassBuilder::addISelPrepare(PassManagerWrapper &PMW) {
   // 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);
   // Lower atomics and TLS if necessary
   flushFPMsToMPM(PMW);
-  addModulePass(WebAssemblyCoalesceFeaturesAndStripAtomicsPass(TM), PMW);
+  addModulePass(WebAssemblyCoalesceFeaturesAndStripAtomicsPass(getTM()), PMW);
 
   // This is a no-op if atomics are not used in the module
   addFunctionPass(AtomicExpandPass(TM), PMW);
@@ -151,9 +152,9 @@ void WebAssemblyCodeGenPassBuilder::addISelPrepare(
   Base::addISelPrepare(PMW);
 }
 
-Error WebAssemblyCodeGenPassBuilder::addInstSelector(
-    PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(WebAssemblyISelDAGToDAGPass(TM, getOptLevel()), PMW);
+Error WebAssemblyCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
+  addMachineFunctionPass(WebAssemblyISelDAGToDAGPass(getTM(), getOptLevel()),
+                         PMW);
 
   // Run the argument-move pass immediately after the ScheduleDAG scheduler
   // so that we can fix up the ARGUMENT instructions before anything else
@@ -176,17 +177,16 @@ Error WebAssemblyCodeGenPassBuilder::addInstSelector(
 }
 
 Error WebAssemblyCodeGenPassBuilder::addRegAssignAndRewriteFast(
-    PassManagerWrapper &PMW) const {
+    PassManagerWrapper &PMW) {
   return Error::success();
 }
 
 Expected<bool> WebAssemblyCodeGenPassBuilder::addRegAssignAndRewriteOptimized(
-    PassManagerWrapper &PMW) const {
+    PassManagerWrapper &PMW) {
   return false;
 }
 
-void WebAssemblyCodeGenPassBuilder::addPreEmitPass(
-    PassManagerWrapper &PMW) const {
+void WebAssemblyCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
   Base::addPreEmitPass(PMW);
 
   // Nullify DBG_VALUE_LISTs that we cannot handle.
@@ -263,17 +263,15 @@ void WebAssemblyCodeGenPassBuilder::addPreEmitPass(
 }
 
 void WebAssemblyCodeGenPassBuilder::addAsmPrinterBegin(
-    PassManagerWrapper &PMW) const {
+    PassManagerWrapper &PMW) {
   addModulePass(WebAssemblyAsmPrinterBeginPass(), PMW, /*Force=*/true);
 }
 
-void WebAssemblyCodeGenPassBuilder::addAsmPrinter(
-    PassManagerWrapper &PMW) const {
+void WebAssemblyCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
   addMachineFunctionPass(WebAssemblyAsmPrinterPass(), PMW);
 }
 
-void WebAssemblyCodeGenPassBuilder::addAsmPrinterEnd(
-    PassManagerWrapper &PMW) const {
+void WebAssemblyCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
   addModulePass(WebAssemblyAsmPrinterEndPass(), PMW);
 }
 
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/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp
index f22b89b9b6e96..b0ea0850d2785 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.cpp
+++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp
@@ -25,6 +25,7 @@
 #include "llvm/Analysis/StaticDataProfileInfo.h"
 #include "llvm/BinaryFormat/COFF.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/CodeGen/AsmPrinterAnalysis.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
 #include "llvm/CodeGen/MachinePassManager.h"
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index fc2eb6134d1fd..3043c2268a52a 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/InterleavedAccess.h"
 #include "llvm/CodeGen/JMCInstrumenter.h"
 #include "llvm/CodeGen/KCFI.h"
+#include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/Passes/CodeGenPassBuilder.h"
 #include "llvm/Passes/PassBuilder.h"
@@ -33,9 +34,12 @@ extern cl::opt<bool> X86EnableMachineCombinerPass;
 
 namespace {
 
-class X86CodeGenPassBuilder
-    : public CodeGenPassBuilder<X86CodeGenPassBuilder, X86TargetMachine> {
-  using Base = CodeGenPassBuilder<X86CodeGenPassBuilder, X86TargetMachine>;
+class X86CodeGenPassBuilder : public CodeGenPassBuilder {
+  using Base = CodeGenPassBuilder;
+
+  X86TargetMachine &getTM() const {
+    return static_cast<X86TargetMachine &>(TM);
+  }
 
 public:
   explicit X86CodeGenPassBuilder(X86TargetMachine &TM,
@@ -43,28 +47,28 @@ 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(PassManagerWrapper &PMW) override;
+  void addPreISel(PassManagerWrapper &PMW) override;
+  Error addInstSelector(PassManagerWrapper &PMW) override;
+  void addPreLegalizeMachineIR(PassManagerWrapper &PMW) override;
+  void addILPOpts(PassManagerWrapper &PMW) override;
+  void addPreRegBankSelect(PassManagerWrapper &PMW) override;
+  void addMachineSSAOptimization(PassManagerWrapper &PMW) override;
+  void addPreRegAlloc(PassManagerWrapper &PMW) override;
   // 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(PassManagerWrapper &PMW) override;
+  void addPreSched2(PassManagerWrapper &PMW) override;
+  void addPreEmitPass(PassManagerWrapper &PMW) override;
+  void addPreEmitPass2(PassManagerWrapper &PMW) override;
   // 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(PassManagerWrapper &PMW) override;
+  void addAsmPrinter(PassManagerWrapper &PMW) override;
+  void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
 };
 
-void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
   addFunctionPass(AtomicExpandPass(TM), PMW);
 
   // We add both pass anyway and when these two passes run, one will be a
@@ -76,7 +80,7 @@ void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
 
   if (getOptLevel() != CodeGenOptLevel::None) {
     addFunctionPass(InterleavedAccessPass(TM), PMW);
-    addFunctionPass(X86PartialReductionPass(&TM), PMW);
+    addFunctionPass(X86PartialReductionPass(&getTM()), PMW);
   }
 
   // Add passes that handle indirect branch removal and insertion of a retpoline
@@ -95,7 +99,7 @@ void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
   }
 }
 
-void X86CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) {
   // Only add this pass for 32-bit x86 Windows.
   const Triple &TT = TM.getTargetTriple();
   if (TT.isOSWindows() && TT.isX86_32()) {
@@ -104,8 +108,8 @@ void X86CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
   }
 }
 
-Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
-  addMachineFunctionPass(X86ISelDAGToDAGPass(TM), PMW);
+Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
+  addMachineFunctionPass(X86ISelDAGToDAGPass(getTM()), PMW);
 
   // For ELF, cleanup any local-dynamic TLS accesses
   if (TM.getTargetTriple().isOSBinFormatELF() &&
@@ -118,12 +122,11 @@ Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
   return Error::success();
 }
 
-void X86CodeGenPassBuilder::addPreLegalizeMachineIR(
-    PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPreLegalizeMachineIR(PassManagerWrapper &PMW) {
   addMachineFunctionPass(X86PreLegalizerCombinerPass(), PMW);
 }
 
-void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) {
   addMachineFunctionPass(EarlyIfConverterPass(), PMW);
   if (X86EnableMachineCombinerPass) {
     // TODO(boomanaiden154): Add the MachineCombinerPass here once it has been
@@ -132,17 +135,16 @@ void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) const {
   addMachineFunctionPass(X86CmovConversionPass(), PMW);
 }
 
-void X86CodeGenPassBuilder::addPreRegBankSelect(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPreRegBankSelect(PassManagerWrapper &PMW) {
   addMachineFunctionPass(X86PostLegalizerCombinerPass(), PMW);
 }
 
-void X86CodeGenPassBuilder::addMachineSSAOptimization(
-    PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addMachineSSAOptimization(PassManagerWrapper &PMW) {
   addMachineFunctionPass(X86DomainReassignmentPass(), PMW);
   Base::addMachineSSAOptimization(PMW);
 }
 
-void X86CodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) {
   if (getOptLevel() != CodeGenOptLevel::None) {
     addMachineFunctionPass(LiveRangeShrinkPass(), PMW);
     addMachineFunctionPass(X86FixupSetCCPass(), PMW);
@@ -161,7 +163,7 @@ void X86CodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
     addMachineFunctionPass(X86FastPreTileConfigPass(), PMW);
 }
 
-void X86CodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) {
   addMachineFunctionPass(X86LowerTileCopyPass(), PMW);
   addMachineFunctionPass(X86FPStackifierPass(), PMW);
   // When -O0 is enabled, the Load Value Injection Hardening pass will fall back
@@ -173,12 +175,12 @@ void X86CodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
   }
 }
 
-void X86CodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) {
   addMachineFunctionPass(X86ExpandPseudoPass(), PMW);
   addMachineFunctionPass(MachineKCFIPass(), PMW);
 }
 
-void X86CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
   if (getOptLevel() != CodeGenOptLevel::None) {
     // TODO(boomanaiden154): Add X86ExecutionDomainFixPass here once it has
     // been ported.
@@ -200,7 +202,7 @@ void X86CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
   addMachineFunctionPass(X86InsertX87WaitPass(), PMW);
 }
 
-void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) {
   const Triple &TT = TM.getTargetTriple();
   const MCAsmInfo &MAI = TM.getMCAsmInfo();
 
@@ -261,15 +263,15 @@ void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
   }
 }
 
-void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
   addModulePass(X86AsmPrinterBeginPass(), PMW, /*Force=*/true);
 }
 
-void X86CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
   addMachineFunctionPass(X86AsmPrinterPass(), PMW);
 }
 
-void X86CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
+void X86CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
   addModulePass(X86AsmPrinterEndPass(), PMW, /*Force=*/true);
 }
 



More information about the llvm-commits mailing list