<div dir="ltr"><a class="gmail_plusreply" id="plusReplyChip-0" href="mailto:arsenm2@gmail.com" tabindex="-1">+Matt Arsenault</a>  FYI (not that I expect anyone could/should've caught this in review - I wouldn't've, but just so everyone's aware of what's going on)<br><br>I'll revert this in an hour or so if there's no other direction.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Sep 11, 2020 at 6:40 PM David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">This commit introduces a circular dependency between llvm/lib/Target and llvm/lib/CodeGen (prior to this patch, CodeGen depended on Target, but not the other way around - with this patch, TargetMachine.h includes 





<p style="margin:0px;font-variant-numeric:normal;font-variant-east-asian:normal;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,0,0)"><span style="font-variant-ligatures:no-common-ligatures">llvm/CodeGen/CGPassBuilderOption.h and </span><span style="font-variant-ligatures:no-common-ligatures">llvm/CodeGen/MachinePassManager.h)<br></span><span style="font-family:Arial,Helvetica,sans-serif;font-size:small;color:rgb(34,34,34)"><br>Could you revert this patch to revisit the layering here before continuing? (that is, assuming fixing the layering would be more complicated than a few minutes/maybe an hour?)</span></p>





</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Sep 11, 2020 at 4:41 PM Yuanfang Chen via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Author: Yuanfang Chen<br>
Date: 2020-09-11T16:41:17-07:00<br>
New Revision: 31ecf8d29d81d196374a562c6d2bd2c25a62861e<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/31ecf8d29d81d196374a562c6d2bd2c25a62861e" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/31ecf8d29d81d196374a562c6d2bd2c25a62861e</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/31ecf8d29d81d196374a562c6d2bd2c25a62861e.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/31ecf8d29d81d196374a562c6d2bd2c25a62861e.diff</a><br>
<br>
LOG: [NewPM][CodeGen] Introduce CodeGenPassBuilder to help build codegen pipeline<br>
<br>
Following up on D67687.<br>
Please refer to the RFC here <a href="http://lists.llvm.org/pipermail/llvm-dev/2020-July/143309.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/llvm-dev/2020-July/143309.html</a><br>
<br>
`CodeGenPassBuilder` is the NPM counterpart of `TargetPassConfig` with below differences.<br>
- Debugging features (MIR print/verify, disable pass, start/stop-before/after, etc.) living in `TargetPassConfig` are moved to use PassInstrument as much as possible. (Implementation also lives in `TargetPassConfig.cpp`)<br>
- `TargetPassConfig` is a polymorphic base (virtual inheritance) to build the target-dependent pipeline whereas `CodeGenPassBuilder` is the CRTP base/helper to implement the target-dependent pipeline. The motivation is flexibility for targets to customize the pipeline, inlining opportunity, and fits the overall NPM value semantics design.<br>
- `TargetPassConfig` is a legacy immutable pass to declare hooks for targets to customize some target-independent codegen layer behavior. This is partially ported to TargetMachine::options. The rest, such as `createMachineScheduler/createPostMachineScheduler`, are left out for now. They should be implemented in LLVMTargetMachine in the future.<br>
<br>
Reviewed By: arsenm<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D83608" rel="noreferrer" target="_blank">https://reviews.llvm.org/D83608</a><br>
<br>
Added: <br>
    llvm/include/llvm/CodeGen/CGPassBuilderOption.h<br>
    llvm/include/llvm/CodeGen/CodeGenPassBuilder.h<br>
    llvm/include/llvm/CodeGen/MachinePassRegistry.def<br>
    llvm/lib/CodeGen/CodeGenPassBuilder.cpp<br>
<br>
Modified: <br>
    llvm/include/llvm/Passes/StandardInstrumentations.h<br>
    llvm/include/llvm/Target/TargetMachine.h<br>
    llvm/lib/CodeGen/CMakeLists.txt<br>
    llvm/lib/CodeGen/LLVMTargetMachine.cpp<br>
    llvm/lib/CodeGen/TargetPassConfig.cpp<br>
<br>
Removed: <br>
<br>
<br>
<br>
################################################################################<br>
diff  --git a/llvm/include/llvm/CodeGen/CGPassBuilderOption.h b/llvm/include/llvm/CodeGen/CGPassBuilderOption.h<br>
new file mode 100644<br>
index 000000000000..4553060e687b<br>
--- /dev/null<br>
+++ b/llvm/include/llvm/CodeGen/CGPassBuilderOption.h<br>
@@ -0,0 +1,110 @@<br>
+//===- CGPassBuilderOption.h - Options for pass builder ---------*- C++ -*-===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file declares the options influencing building of codegen pipeline.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_CODEGEN_CGPASSBUILDEROPTION_H<br>
+#define LLVM_CODEGEN_CGPASSBUILDEROPTION_H<br>
+<br>
+#include "llvm/ADT/Optional.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include "llvm/Target/TargetOptions.h"<br>
+#include <vector><br>
+<br>
+namespace llvm {<br>
+class TargetMachine;<br>
+<br>
+enum class RunOutliner { TargetDefault, AlwaysOutline, NeverOutline };<br>
+enum class RegAllocType { Default, Basic, Fast, Greedy, PBQP };<br>
+enum class CFLAAType { None, Steensgaard, Andersen, Both };<br>
+<br>
+// Not one-on-one but mostly corresponding to commandline options in<br>
+// TargetPassConfig.cpp<br>
+struct CGPassBuilderOption {<br>
+  // Enable optimized register allocation compilation path<br>
+  Optional<bool> OptimizeRegAlloc;<br>
+<br>
+  // Enable interprocedural register allocation to reduce load/store at<br>
+  // procedure calls<br>
+  Optional<bool> EnableIPRA;<br>
+<br>
+  // Enable debug logging of pass pipeline<br>
+  bool DebugPM = false;<br>
+<br>
+  // Disable machine function verification<br>
+  bool DisableVerify = false;<br>
+<br>
+  // Fold null checks into faulting memory operations<br>
+  bool EnableImplicitNullChecksPass = false;<br>
+<br>
+  // Collect probability-driven block placement stats<br>
+  bool EnableMachineBlockPlacementStatsPass = false;<br>
+<br>
+  // Run MachineScheduler post regalloc (independent of preRA sched)<br>
+  bool EnablePostMachineSchedulerPass = false;<br>
+<br>
+  // Run live interval analysis earlier in the pipeline<br>
+  bool EnableLiveIntervalsPass = false;<br>
+<br>
+  // Disable Loop Strength Reduction Pass<br>
+  bool DisableLoopStrengthReducePass = false;<br>
+<br>
+  // Disable Codegen Prepare<br>
+  bool DisableCodeGenPreparePass = false;<br>
+<br>
+  // Disable MergeICmps Pass<br>
+  bool DisableMergeICmpsPass = false;<br>
+<br>
+  // Disable Partial Libcall Inlining Pass<br>
+  bool DisablePartiallyInlineLibCallsPass = false;<br>
+<br>
+  // Disable ConstantHoisting Pass<br>
+  bool DisableConstantHoistingPass = false;<br>
+<br>
+  // Print LLVM IR produced by the loop-reduce pass<br>
+  bool PrintAfterLSR = false;<br>
+<br>
+  // Print LLVM IR input to isel pass<br>
+  bool PrintISelInput = false;<br>
+<br>
+  // Dump garbage collector data<br>
+  bool PrintGCInfo = false;<br>
+<br>
+  // Enable codegen in SCC order.<br>
+  bool RequiresCodeGenSCCOrder = false;<br>
+<br>
+  // Enable the machine outliner<br>
+  RunOutliner EnableMachineOutliner = RunOutliner::TargetDefault;<br>
+<br>
+  // Register allocator to use<br>
+  RegAllocType RegAlloc = RegAllocType::Default;<br>
+<br>
+  // Experimental option to use CFL-AA in codegen<br>
+  CFLAAType UseCFLAA = CFLAAType::None;<br>
+<br>
+  // Enable abort calls when "global" instruction selection fails to<br>
+  // lower/select an instruction<br>
+  Optional<GlobalISelAbortMode> EnableGlobalISelAbort;<br>
+<br>
+  // Verify generated machine code"<br>
+  Optional<bool> VerifyMachineCode;<br>
+<br>
+  // Enable the "fast" instruction selector<br>
+  Optional<bool> EnableFastISelOption;<br>
+<br>
+  // Enable the "global" instruction selector<br>
+  Optional<bool> EnableGlobalISelOption;<br>
+};<br>
+<br>
+CGPassBuilderOption getCGPassBuilderOption();<br>
+<br>
+} // namespace llvm<br>
+<br>
+#endif // LLVM_CODEGEN_CGPASSBUILDEROPTION_H<br>
<br>
diff  --git a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h<br>
new file mode 100644<br>
index 000000000000..0c679eb174b7<br>
--- /dev/null<br>
+++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h<br>
@@ -0,0 +1,1171 @@<br>
+//===- Construction of codegen pass pipelines ------------------*- C++ -*--===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+/// \file<br>
+///<br>
+/// Interfaces for registering analysis passes, producing common pass manager<br>
+/// configurations, and parsing of pass pipelines.<br>
+///<br>
+/// TODO: handle addRequiredID where, in legacy PM, one pass require other pass<br>
+///       to run as prerequisite.<br>
+///<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_CODEGEN_CODEGENPASSBUILDER_H<br>
+#define LLVM_CODEGEN_CODEGENPASSBUILDER_H<br>
+<br>
+#include "llvm/ADT/FunctionExtras.h"<br>
+#include "llvm/ADT/SmallVector.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include "llvm/Analysis/AliasAnalysis.h"<br>
+#include "llvm/Analysis/BasicAliasAnalysis.h"<br>
+#include "llvm/Analysis/CFLAndersAliasAnalysis.h"<br>
+#include "llvm/Analysis/CFLSteensAliasAnalysis.h"<br>
+#include "llvm/Analysis/ScopedNoAliasAA.h"<br>
+#include "llvm/Analysis/TargetTransformInfo.h"<br>
+#include "llvm/Analysis/TypeBasedAliasAnalysis.h"<br>
+#include "llvm/CodeGen/CGPassBuilderOption.h"<br>
+#include "llvm/CodeGen/ExpandReductions.h"<br>
+#include "llvm/CodeGen/MIRPrinter.h"<br>
+#include "llvm/CodeGen/MachineModuleInfo.h"<br>
+#include "llvm/CodeGen/MachinePassManager.h"<br>
+#include "llvm/CodeGen/PreISelIntrinsicLowering.h"<br>
+#include "llvm/CodeGen/UnreachableBlockElim.h"<br>
+#include "llvm/IR/IRPrintingPasses.h"<br>
+#include "llvm/IR/PassManager.h"<br>
+#include "llvm/IR/Verifier.h"<br>
+#include "llvm/MC/MCAsmInfo.h"<br>
+#include "llvm/MC/MCStreamer.h"<br>
+#include "llvm/MC/MCTargetOptions.h"<br>
+#include "llvm/Support/CodeGen.h"<br>
+#include "llvm/Support/Debug.h"<br>
+#include "llvm/Support/Error.h"<br>
+#include "llvm/Support/ErrorHandling.h"<br>
+#include "llvm/Target/TargetMachine.h"<br>
+#include "llvm/Transforms/Scalar.h"<br>
+#include "llvm/Transforms/Scalar/ConstantHoisting.h"<br>
+#include "llvm/Transforms/Scalar/LoopPassManager.h"<br>
+#include "llvm/Transforms/Scalar/LoopStrengthReduce.h"<br>
+#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"<br>
+#include "llvm/Transforms/Scalar/MergeICmps.h"<br>
+#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"<br>
+#include "llvm/Transforms/Utils.h"<br>
+#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"<br>
+#include "llvm/Transforms/Utils/LowerInvoke.h"<br>
+#include <cassert><br>
+#include <string><br>
+#include <type_traits><br>
+#include <utility><br>
+#include <vector><br>
+<br>
+namespace llvm {<br>
+<br>
+// FIXME: Dummy target independent passes definitions that have not yet been<br>
+// ported to new pass manager. Once they do, remove these.<br>
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)                      \<br>
+  struct PASS_NAME : public PassInfoMixin<PASS_NAME> {                         \<br>
+    template <typename... Ts> PASS_NAME(Ts &&...) {}                           \<br>
+    PreservedAnalyses run(Function &, FunctionAnalysisManager &) {             \<br>
+      return PreservedAnalyses::all();                                         \<br>
+    }                                                                          \<br>
+  };<br>
+#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                        \<br>
+  struct PASS_NAME : public PassInfoMixin<PASS_NAME> {                         \<br>
+    template <typename... Ts> PASS_NAME(Ts &&...) {}                           \<br>
+    PreservedAnalyses run(Module &, ModuleAnalysisManager &) {                 \<br>
+      return PreservedAnalyses::all();                                         \<br>
+    }                                                                          \<br>
+  };<br>
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                \<br>
+  struct PASS_NAME : public PassInfoMixin<PASS_NAME> {                         \<br>
+    template <typename... Ts> PASS_NAME(Ts &&...) {}                           \<br>
+    Error run(Module &, MachineFunctionAnalysisManager &) {                    \<br>
+      return Error::success();                                                 \<br>
+    }                                                                          \<br>
+    PreservedAnalyses run(MachineFunction &,                                   \<br>
+                          MachineFunctionAnalysisManager &) {                  \<br>
+      llvm_unreachable("this api is to make new PM api happy");                \<br>
+    }                                                                          \<br>
+    static AnalysisKey Key;                                                    \<br>
+  };<br>
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \<br>
+  struct PASS_NAME : public PassInfoMixin<PASS_NAME> {                         \<br>
+    template <typename... Ts> PASS_NAME(Ts &&...) {}                           \<br>
+    PreservedAnalyses run(MachineFunction &,                                   \<br>
+                          MachineFunctionAnalysisManager &) {                  \<br>
+      return PreservedAnalyses::all();                                         \<br>
+    }                                                                          \<br>
+    static AnalysisKey Key;                                                    \<br>
+  };<br>
+#include "MachinePassRegistry.def"<br>
+<br>
+/// This class provides access to building LLVM's passes.<br>
+///<br>
+/// Its members provide the baseline state available to passes during their<br>
+/// construction. The \c MachinePassRegistry.def file specifies how to construct<br>
+/// all of the built-in passes, and those may reference these members during<br>
+/// construction.<br>
+template <typename DerivedT> class CodeGenPassBuilder {<br>
+public:<br>
+  explicit CodeGenPassBuilder(LLVMTargetMachine &TM, CGPassBuilderOption Opts,<br>
+                              PassInstrumentationCallbacks *PIC)<br>
+      : TM(TM), Opt(Opts), PIC(PIC) {<br>
+    // Target could set CGPassBuilderOption::MISchedPostRA to true to achieve<br>
+    //     substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)<br>
+<br>
+    // Target should override TM.Options.EnableIPRA in their target-specific<br>
+    // LLVMTM ctor. See TargetMachine::setGlobalISel for example.<br>
+    if (Opt.EnableIPRA)<br>
+      TM.Options.EnableIPRA = *Opt.EnableIPRA;<br>
+<br>
+    if (Opt.EnableGlobalISelAbort)<br>
+      TM.Options.GlobalISelAbort = *Opt.EnableGlobalISelAbort;<br>
+<br>
+    if (!Opt.OptimizeRegAlloc)<br>
+      Opt.OptimizeRegAlloc = getOptLevel() != CodeGenOpt::None;<br>
+<br>
+    if (!Opt.VerifyMachineCode) {<br>
+#ifdef EXPENSIVE_CHECKS<br>
+      Opt.VerifyMachineCode = TM->isMachineVerifierClean();<br>
+#else<br>
+      Opt.VerifyMachineCode = false;<br>
+#endif<br>
+    }<br>
+  }<br>
+<br>
+  Expected<std::pair<ModulePassManager, MachineFunctionPassManager>><br>
+  buildPipeline(raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,<br>
+                CodeGenFileType FileType) const;<br>
+<br>
+  void registerModuleAnalyses(ModuleAnalysisManager &) const;<br>
+  void registerFunctionAnalyses(FunctionAnalysisManager &) const;<br>
+  void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &) const;<br>
+  std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) const;<br>
+<br>
+  void registerAnalyses(MachineFunctionAnalysisManager &MFAM) const {<br>
+    registerModuleAnalyses(*MFAM.MAM);<br>
+    registerFunctionAnalyses(*MFAM.FAM);<br>
+    registerMachineFunctionAnalyses(MFAM);<br>
+  }<br>
+<br>
+  PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {<br>
+    return PIC;<br>
+  }<br>
+<br>
+protected:<br>
+  template <typename PassT> using has_key_t = decltype(PassT::Key);<br>
+<br>
+  template <typename PassT><br>
+  using is_module_pass_t = decltype(std::declval<PassT &>().run(<br>
+      std::declval<Module &>(), std::declval<ModuleAnalysisManager &>()));<br>
+<br>
+  template <typename PassT><br>
+  using is_function_pass_t = decltype(std::declval<PassT &>().run(<br>
+      std::declval<Function &>(), std::declval<FunctionAnalysisManager &>()));<br>
+<br>
+  // Function object to maintain state while adding codegen IR passes.<br>
+  class AddIRPass {<br>
+  public:<br>
+    AddIRPass(bool DebugPM) : MPM(DebugPM), FPM(DebugPM) {<br>
+      AddingFunctionPasses = false;<br>
+    }<br>
+<br>
+    // Add Function Pass<br>
+    template <typename PassT><br>
+    std::enable_if_t<is_detected<is_function_pass_t, PassT>::value><br>
+    operator()(PassT &&Pass) {<br>
+      if (!AddingFunctionPasses)<br>
+        AddingFunctionPasses = true;<br>
+      FPM.addPass(std::forward<PassT>(Pass));<br>
+    }<br>
+<br>
+    // Add Module Pass<br>
+    template <typename PassT><br>
+    std::enable_if_t<is_detected<is_module_pass_t, PassT>::value &&<br>
+                     !is_detected<is_function_pass_t, PassT>::value><br>
+    operator()(PassT &&Pass) {<br>
+      assert((!AddingFunctionPasses) &&<br>
+             "could not add module pass after adding function pass");<br>
+      MPM.addPass(std::forward<PassT>(Pass));<br>
+    }<br>
+<br>
+    ModulePassManager releasePM() {<br>
+      MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));<br>
+      return std::move(MPM);<br>
+    }<br>
+<br>
+  private:<br>
+    ModulePassManager MPM;<br>
+    FunctionPassManager FPM;<br>
+    // The codegen IR pipeline are mostly function passes with the exceptions of<br>
+    // a few loop and module passes. `AddingFunctionPasses` makes sure that<br>
+    // we could only add module passes at the beginning of the pipeline. Once<br>
+    // we begin adding function passes, we could no longer add module passes.<br>
+    // This special-casing introduces less adaptor passes. If we have the need<br>
+    // of adding module passes after function passes, we could change the<br>
+    // implementation to accommodate that.<br>
+    bool AddingFunctionPasses;<br>
+  };<br>
+<br>
+  // Function object to maintain state while adding codegen machine passes.<br>
+  class AddMachinePass {<br>
+  public:<br>
+    AddMachinePass(bool DebugPM, bool RequiresCodeGenSCCOrder,<br>
+                   bool VerifyMachineCode)<br>
+        : PM(DebugPM, RequiresCodeGenSCCOrder, VerifyMachineCode) {}<br>
+<br>
+    template <typename PassT> void operator()(PassT &&Pass) {<br>
+      static_assert(<br>
+          is_detected<has_key_t, PassT>::value,<br>
+          "Machine function pass must define a static member variable `Key`.");<br>
+      for (auto &C : BeforeCallbacks) {<br>
+        if (!C(&PassT::Key))<br>
+          return;<br>
+      }<br>
+      PM.addPass(std::forward<PassT>(Pass));<br>
+      for (auto &C : AfterCallbacks)<br>
+        C(&PassT::Key);<br>
+    }<br>
+<br>
+    template <typename PassT> void insertPass(AnalysisKey *ID, PassT Pass) {<br>
+      AfterCallbacks.emplace_back(<br>
+          [this, ID, Pass = std::move(Pass)](AnalysisKey *PassID) {<br>
+            if (PassID == ID)<br>
+              this->PM.addPass(std::move(Pass));<br>
+          });<br>
+    }<br>
+<br>
+    void disablePass(AnalysisKey *ID) {<br>
+      BeforeCallbacks.emplace_back(<br>
+          [ID](AnalysisKey *PassID) { return PassID != ID; });<br>
+    }<br>
+<br>
+    MachineFunctionPassManager releasePM() { return std::move(PM); }<br>
+<br>
+  private:<br>
+    MachineFunctionPassManager PM;<br>
+    SmallVector<llvm::unique_function<bool(AnalysisKey *)>, 4> BeforeCallbacks;<br>
+    SmallVector<llvm::unique_function<void(AnalysisKey *)>, 4> AfterCallbacks;<br>
+  };<br>
+<br>
+  LLVMTargetMachine &TM;<br>
+  CGPassBuilderOption Opt;<br>
+  PassInstrumentationCallbacks *PIC;<br>
+<br>
+  /// Target override these hooks to parse target-specific analyses.<br>
+  void registerTargetAnalysis(ModuleAnalysisManager &) const {}<br>
+  void registerTargetAnalysis(FunctionAnalysisManager &) const {}<br>
+  void registerTargetAnalysis(MachineFunctionAnalysisManager &) const {}<br>
+  std::pair<StringRef, bool> getTargetPassNameFromLegacyName(StringRef) const {<br>
+    return {"", false};<br>
+  }<br>
+<br>
+  template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }<br>
+  CodeGenOpt::Level getOptLevel() const { return TM.getOptLevel(); }<br>
+<br>
+  /// Check whether or not GlobalISel should abort on error.<br>
+  /// When this is disabled, GlobalISel will fall back on SDISel instead of<br>
+  /// erroring out.<br>
+  bool isGlobalISelAbortEnabled() const {<br>
+    return TM.Options.GlobalISelAbort == GlobalISelAbortMode::Enable;<br>
+  }<br>
+<br>
+  /// Check whether or not a diagnostic should be emitted when GlobalISel<br>
+  /// uses the fallback path. In other words, it will emit a diagnostic<br>
+  /// when GlobalISel failed and isGlobalISelAbortEnabled is false.<br>
+  bool reportDiagnosticWhenGlobalISelFallback() const {<br>
+    return TM.Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag;<br>
+  }<br>
+<br>
+  /// addInstSelector - This method should install an instruction selector pass,<br>
+  /// which converts from LLVM code to machine instructions.<br>
+  Error addInstSelector(AddMachinePass &) const {<br>
+    return make_error<StringError>("addInstSelector is not overridden",<br>
+                                   inconvertibleErrorCode());<br>
+  }<br>
+<br>
+  /// Add passes that optimize instruction level parallelism for out-of-order<br>
+  /// targets. These passes are run while the machine code is still in SSA<br>
+  /// form, so they can use MachineTraceMetrics to control their heuristics.<br>
+  ///<br>
+  /// All passes added here should preserve the MachineDominatorTree,<br>
+  /// MachineLoopInfo, and MachineTraceMetrics analyses.<br>
+  void addILPOpts(AddMachinePass &) const {}<br>
+<br>
+  /// This method may be implemented by targets that want to run passes<br>
+  /// immediately before register allocation.<br>
+  void addPreRegAlloc(AddMachinePass &) const {}<br>
+<br>
+  /// addPreRewrite - Add passes to the optimized register allocation pipeline<br>
+  /// after register allocation is complete, but before virtual registers are<br>
+  /// rewritten to physical registers.<br>
+  ///<br>
+  /// These passes must preserve VirtRegMap and LiveIntervals, and when running<br>
+  /// after RABasic or RAGreedy, they should take advantage of LiveRegMatrix.<br>
+  /// When these passes run, VirtRegMap contains legal physreg assignments for<br>
+  /// all virtual registers.<br>
+  ///<br>
+  /// Note if the target overloads addRegAssignAndRewriteOptimized, this may not<br>
+  /// be honored. This is also not generally used for the the fast variant,<br>
+  /// where the allocation and rewriting are done in one pass.<br>
+  void addPreRewrite(AddMachinePass &) const {}<br>
+<br>
+  /// Add passes to be run immediately after virtual registers are rewritten<br>
+  /// to physical registers.<br>
+  void addPostRewrite(AddMachinePass &) const {}<br>
+<br>
+  /// This method may be implemented by targets that want to run passes after<br>
+  /// register allocation pass pipeline but before prolog-epilog insertion.<br>
+  void addPostRegAlloc(AddMachinePass &) const {}<br>
+<br>
+  /// This method may be implemented by targets that want to run passes after<br>
+  /// prolog-epilog insertion and before the second instruction scheduling pass.<br>
+  void addPreSched2(AddMachinePass &) const {}<br>
+<br>
+  /// This pass may be implemented by targets that want to run passes<br>
+  /// immediately before machine code is emitted.<br>
+  void addPreEmitPass(AddMachinePass &) const {}<br>
+<br>
+  /// Targets may add passes immediately before machine code is emitted in this<br>
+  /// callback. This is called even later than `addPreEmitPass`.<br>
+  // FIXME: Rename `addPreEmitPass` to something more sensible given its actual<br>
+  // position and remove the `2` suffix here as this callback is what<br>
+  // `addPreEmitPass` *should* be but in reality isn't.<br>
+  void addPreEmitPass2(AddMachinePass &) const {}<br>
+<br>
+  /// {{@ For GlobalISel<br>
+  ///<br>
+<br>
+  /// addPreISel - This method should add any "last minute" LLVM->LLVM<br>
+  /// passes (which are run just before instruction selector).<br>
+  void addPreISel(AddIRPass &) const {<br>
+    llvm_unreachable("addPreISel is not overridden");<br>
+  }<br>
+<br>
+  /// This method should install an IR translator pass, which converts from<br>
+  /// LLVM code to machine instructions with possibly generic opcodes.<br>
+  Error addIRTranslator(AddMachinePass &) const {<br>
+    return make_error<StringError>("addIRTranslator is not overridden",<br>
+                                   inconvertibleErrorCode());<br>
+  }<br>
+<br>
+  /// This method may be implemented by targets that want to run passes<br>
+  /// immediately before legalization.<br>
+  void addPreLegalizeMachineIR(AddMachinePass &) const {}<br>
+<br>
+  /// This method should install a legalize pass, which converts the instruction<br>
+  /// sequence into one that can be selected by the target.<br>
+  Error addLegalizeMachineIR(AddMachinePass &) const {<br>
+    return make_error<StringError>("addLegalizeMachineIR is not overridden",<br>
+                                   inconvertibleErrorCode());<br>
+  }<br>
+<br>
+  /// This method may be implemented by targets that want to run passes<br>
+  /// immediately before the register bank selection.<br>
+  void addPreRegBankSelect(AddMachinePass &) const {}<br>
+<br>
+  /// This method should install a register bank selector pass, which<br>
+  /// assigns register banks to virtual registers without a register<br>
+  /// class or register banks.<br>
+  Error addRegBankSelect(AddMachinePass &) const {<br>
+    return make_error<StringError>("addRegBankSelect is not overridden",<br>
+                                   inconvertibleErrorCode());<br>
+  }<br>
+<br>
+  /// This method may be implemented by targets that want to run passes<br>
+  /// immediately before the (global) instruction selection.<br>
+  void addPreGlobalInstructionSelect(AddMachinePass &) const {}<br>
+<br>
+  /// This method should install a (global) instruction selector pass, which<br>
+  /// converts possibly generic instructions to fully target-specific<br>
+  /// instructions, thereby constraining all generic virtual registers to<br>
+  /// register classes.<br>
+  Error addGlobalInstructionSelect(AddMachinePass &) const {<br>
+    return make_error<StringError>(<br>
+        "addGlobalInstructionSelect is not overridden",<br>
+        inconvertibleErrorCode());<br>
+  }<br>
+  /// @}}<br>
+<br>
+  /// High level function that adds all passes necessary to go from llvm IR<br>
+  /// representation to the MI representation.<br>
+  /// Adds IR based lowering and target specific optimization passes and finally<br>
+  /// the core instruction selection passes.<br>
+  /// \returns true if an error occurred, false otherwise.<br>
+  ModulePassManager addISelPasses() const;<br>
+<br>
+  /// Add the actual instruction selection passes. This does not include<br>
+  /// preparation passes on IR.<br>
+  Expected<AddMachinePass> addCoreISelPasses() const;<br>
+<br>
+  /// Add the complete, standard set of LLVM CodeGen passes.<br>
+  /// Fully developed targets will not generally override this.<br>
+  Error addMachinePasses(AddMachinePass &) const;<br>
+<br>
+  /// Add passes to lower exception handling for the code generator.<br>
+  void addPassesToHandleExceptions(AddIRPass &) const;<br>
+<br>
+  /// Add common target configurable passes that perform LLVM IR to IR<br>
+  /// transforms following machine independent optimization.<br>
+  void addIRPasses(AddIRPass &) const;<br>
+<br>
+  /// Add pass to prepare the LLVM IR for code generation. This should be done<br>
+  /// before exception handling preparation passes.<br>
+  void addCodeGenPrepare(AddIRPass &) const;<br>
+<br>
+  /// Add common passes that perform LLVM IR to IR transforms in preparation for<br>
+  /// instruction selection.<br>
+  void addISelPrepare(AddIRPass &) const;<br>
+<br>
+  /// Methods with trivial inline returns are convenient points in the common<br>
+  /// codegen pass pipeline where targets may insert passes. Methods with<br>
+  /// out-of-line standard implementations are major CodeGen stages called by<br>
+  /// addMachinePasses. Some targets may override major stages when inserting<br>
+  /// passes is insufficient, but maintaining overriden stages is more work.<br>
+  ///<br>
+<br>
+  /// addMachineSSAOptimization - Add standard passes that optimize machine<br>
+  /// instructions in SSA form.<br>
+  void addMachineSSAOptimization(AddMachinePass &) const;<br>
+<br>
+  /// addFastRegAlloc - Add the minimum set of target-independent passes that<br>
+  /// are required for fast register allocation.<br>
+  Error addFastRegAlloc(AddMachinePass &) const;<br>
+<br>
+  /// addOptimizedRegAlloc - Add passes related to register allocation.<br>
+  /// LLVMTargetMachine provides standard regalloc passes for most targets.<br>
+  void addOptimizedRegAlloc(AddMachinePass &) const;<br>
+<br>
+  /// Add passes that optimize machine instructions after register allocation.<br>
+  void addMachineLateOptimization(AddMachinePass &) const;<br>
+<br>
+  /// addGCPasses - Add late codegen passes that analyze code for garbage<br>
+  /// collection. This should return true if GC info should be printed after<br>
+  /// these passes.<br>
+  void addGCPasses(AddMachinePass &) const {}<br>
+<br>
+  /// Add standard basic block placement passes.<br>
+  void addBlockPlacement(AddMachinePass &) const;<br>
+<br>
+  using CreateMCStreamer =<br>
+      std::function<Expected<std::unique_ptr<MCStreamer>>(MCContext &)>;<br>
+  void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const {<br>
+    llvm_unreachable("addAsmPrinter is not overridden");<br>
+  }<br>
+<br>
+  /// Utilities for targets to add passes to the pass manager.<br>
+  ///<br>
+<br>
+  /// createTargetRegisterAllocator - Create the register allocator pass for<br>
+  /// this target at the current optimization level.<br>
+  void addTargetRegisterAllocator(AddMachinePass &, bool Optimized) const;<br>
+<br>
+  /// addMachinePasses helper to create the target-selected or overriden<br>
+  /// regalloc pass.<br>
+  void addRegAllocPass(AddMachinePass &, bool Optimized) const;<br>
+<br>
+  /// Add core register alloator passes which do the actual register assignment<br>
+  /// and rewriting. \returns true if any passes were added.<br>
+  Error addRegAssignmentFast(AddMachinePass &) const;<br>
+  Error addRegAssignmentOptimized(AddMachinePass &) const;<br>
+<br>
+private:<br>
+  DerivedT &derived() { return static_cast<DerivedT &>(*this); }<br>
+  const DerivedT &derived() const {<br>
+    return static_cast<const DerivedT &>(*this);<br>
+  }<br>
+};<br>
+<br>
+template <typename Derived><br>
+Expected<std::pair<ModulePassManager, MachineFunctionPassManager>><br>
+CodeGenPassBuilder<Derived>::buildPipeline(raw_pwrite_stream &Out,<br>
+                                           raw_pwrite_stream *DwoOut,<br>
+                                           CodeGenFileType FileType) const {<br>
+  Expected<AddMachinePass> AddPassOrErr = addCoreISelPasses();<br>
+  if (!AddPassOrErr)<br>
+    return AddPassOrErr.takeError();<br>
+<br>
+  AddMachinePass &addPass = *AddPassOrErr;<br>
+<br>
+  if (auto Err = derived().addMachinePasses(addPass))<br>
+    return std::move(Err);<br>
+<br>
+  derived().addAsmPrinter(<br>
+      addPass, [this, &Out, DwoOut, FileType](MCContext &Ctx) {<br>
+        return this->TM.createMCStreamer(Out, DwoOut, FileType, Ctx);<br>
+      });<br>
+<br>
+  addPass(FreeMachineFunctionPass());<br>
+<br>
+  return std::pair<ModulePassManager, MachineFunctionPassManager>{<br>
+      addISelPasses(), addPass.releasePM()};<br>
+}<br>
+<br>
+static inline AAManager registerAAAnalyses(CFLAAType UseCFLAA) {<br>
+  AAManager AA;<br>
+<br>
+  // The order in which these are registered determines their priority when<br>
+  // being queried.<br>
+<br>
+  switch (UseCFLAA) {<br>
+  case CFLAAType::Steensgaard:<br>
+    AA.registerFunctionAnalysis<CFLSteensAA>();<br>
+    break;<br>
+  case CFLAAType::Andersen:<br>
+    AA.registerFunctionAnalysis<CFLAndersAA>();<br>
+    break;<br>
+  case CFLAAType::Both:<br>
+    AA.registerFunctionAnalysis<CFLAndersAA>();<br>
+    AA.registerFunctionAnalysis<CFLSteensAA>();<br>
+    break;<br>
+  default:<br>
+    break;<br>
+  }<br>
+<br>
+  // Basic AliasAnalysis support.<br>
+  // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that<br>
+  // BasicAliasAnalysis wins if they disagree. This is intended to help<br>
+  // support "obvious" type-punning idioms.<br>
+  AA.registerFunctionAnalysis<TypeBasedAA>();<br>
+  AA.registerFunctionAnalysis<ScopedNoAliasAA>();<br>
+  AA.registerFunctionAnalysis<BasicAA>();<br>
+<br>
+  return AA;<br>
+}<br>
+<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::registerModuleAnalyses(<br>
+    ModuleAnalysisManager &MAM) const {<br>
+#define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)                          \<br>
+  MAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });<br>
+#include "MachinePassRegistry.def"<br>
+  derived().registerTargetAnalysis(MAM);<br>
+}<br>
+<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::registerFunctionAnalyses(<br>
+    FunctionAnalysisManager &FAM) const {<br>
+  FAM.registerPass([this] { return registerAAAnalyses(this->Opt.UseCFLAA); });<br>
+<br>
+#define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)                        \<br>
+  FAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });<br>
+#include "MachinePassRegistry.def"<br>
+  derived().registerTargetAnalysis(FAM);<br>
+}<br>
+<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::registerMachineFunctionAnalyses(<br>
+    MachineFunctionAnalysisManager &MFAM) const {<br>
+#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)                \<br>
+  MFAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });<br>
+#include "MachinePassRegistry.def"<br>
+  derived().registerTargetAnalysis(MFAM);<br>
+}<br>
+<br>
+// FIXME: For new PM, use pass name directly in commandline seems good.<br>
+// Translate stringfied pass name to its old commandline name. Returns the<br>
+// matching legacy name and a boolean value indicating if the pass is a machine<br>
+// pass.<br>
+template <typename Derived><br>
+std::pair<StringRef, bool><br>
+CodeGenPassBuilder<Derived>::getPassNameFromLegacyName(StringRef Name) const {<br>
+  std::pair<StringRef, bool> Ret;<br>
+  if (Name.empty())<br>
+    return Ret;<br>
+<br>
+#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)                            \<br>
+  if (Name == NAME)                                                            \<br>
+    Ret = {#PASS_NAME, false};<br>
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)                      \<br>
+  if (Name == NAME)                                                            \<br>
+    Ret = {#PASS_NAME, false};<br>
+#define MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                              \<br>
+  if (Name == NAME)                                                            \<br>
+    Ret = {#PASS_NAME, false};<br>
+#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                        \<br>
+  if (Name == NAME)                                                            \<br>
+    Ret = {#PASS_NAME, false};<br>
+#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                      \<br>
+  if (Name == NAME)                                                            \<br>
+    Ret = {#PASS_NAME, true};<br>
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                \<br>
+  if (Name == NAME)                                                            \<br>
+    Ret = {#PASS_NAME, true};<br>
+#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)                    \<br>
+  if (Name == NAME)                                                            \<br>
+    Ret = {#PASS_NAME, true};<br>
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \<br>
+  if (Name == NAME)                                                            \<br>
+    Ret = {#PASS_NAME, true};<br>
+#include "llvm/CodeGen/MachinePassRegistry.def"<br>
+<br>
+  if (Ret.first.empty())<br>
+    Ret = derived().getTargetPassNameFromLegacyName(Name);<br>
+<br>
+  if (Ret.first.empty())<br>
+    report_fatal_error(Twine('\"') + Twine(Name) +<br>
+                       Twine("\" pass could not be found."));<br>
+<br>
+  return Ret;<br>
+}<br>
+<br>
+template <typename Derived><br>
+ModulePassManager CodeGenPassBuilder<Derived>::addISelPasses() const {<br>
+  AddIRPass addPass(Opt.DebugPM);<br>
+<br>
+  if (TM.useEmulatedTLS())<br>
+    addPass(LowerEmuTLSPass());<br>
+<br>
+  addPass(PreISelIntrinsicLoweringPass());<br>
+<br>
+  derived().addIRPasses(addPass);<br>
+  derived().addCodeGenPrepare(addPass);<br>
+  addPassesToHandleExceptions(addPass);<br>
+  derived().addISelPrepare(addPass);<br>
+  return addPass.releasePM();<br>
+}<br>
+<br>
+/// Add common target configurable passes that perform LLVM IR to IR transforms<br>
+/// following machine independent optimization.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {<br>
+  // Before running any passes, run the verifier to determine if the input<br>
+  // coming from the front-end and/or optimizer is valid.<br>
+  if (!Opt.DisableVerify)<br>
+    addPass(VerifierPass());<br>
+<br>
+  // Run loop strength reduction before anything else.<br>
+  if (getOptLevel() != CodeGenOpt::None && !Opt.DisableLoopStrengthReducePass) {<br>
+    addPass(createFunctionToLoopPassAdaptor(<br>
+        LoopStrengthReducePass(), /*UseMemorySSA*/ true, Opt.DebugPM));<br>
+    // FIXME: use -stop-after so we could remove PrintAfterLSR<br>
+    if (Opt.PrintAfterLSR)<br>
+      addPass(PrintFunctionPass(dbgs(), "\n\n*** Code after LSR ***\n"));<br>
+  }<br>
+<br>
+  if (getOptLevel() != CodeGenOpt::None) {<br>
+    // The MergeICmpsPass tries to create memcmp calls by grouping sequences of<br>
+    // loads and compares. ExpandMemCmpPass then tries to expand those calls<br>
+    // into optimally-sized loads and compares. The transforms are enabled by a<br>
+    // target lowering hook.<br>
+    if (!Opt.DisableMergeICmpsPass)<br>
+      addPass(MergeICmpsPass());<br>
+    addPass(ExpandMemCmpPass());<br>
+  }<br>
+<br>
+  // Run GC lowering passes for builtin collectors<br>
+  // TODO: add a pass insertion point here<br>
+  addPass(GCLoweringPass());<br>
+  addPass(ShadowStackGCLoweringPass());<br>
+  addPass(LowerConstantIntrinsicsPass());<br>
+<br>
+  // Make sure that no unreachable blocks are instruction selected.<br>
+  addPass(UnreachableBlockElimPass());<br>
+<br>
+  // Prepare expensive constants for SelectionDAG.<br>
+  if (getOptLevel() != CodeGenOpt::None && !Opt.DisableConstantHoistingPass)<br>
+    addPass(ConstantHoistingPass());<br>
+<br>
+  if (getOptLevel() != CodeGenOpt::None &&<br>
+      !Opt.DisablePartiallyInlineLibCallsPass)<br>
+    addPass(PartiallyInlineLibCallsPass());<br>
+<br>
+  // Instrument function entry and exit, e.g. with calls to mcount().<br>
+  addPass(EntryExitInstrumenterPass(/*PostInlining=*/true));<br>
+<br>
+  // Add scalarization of target's unsupported masked memory intrinsics pass.<br>
+  // the unsupported intrinsic will be replaced with a chain of basic blocks,<br>
+  // that stores/loads element one-by-one if the appropriate mask bit is set.<br>
+  addPass(ScalarizeMaskedMemIntrinPass());<br>
+<br>
+  // Expand reduction intrinsics into shuffle sequences if the target wants to.<br>
+  addPass(ExpandReductionsPass());<br>
+}<br>
+<br>
+/// Turn exception handling constructs into something the code generators can<br>
+/// handle.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addPassesToHandleExceptions(<br>
+    AddIRPass &addPass) const {<br>
+  const MCAsmInfo *MCAI = TM.getMCAsmInfo();<br>
+  assert(MCAI && "No MCAsmInfo");<br>
+  switch (MCAI->getExceptionHandlingType()) {<br>
+  case ExceptionHandling::SjLj:<br>
+    // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both<br>
+    // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,<br>
+    // catch info can get misplaced when a selector ends up more than one block<br>
+    // removed from the parent invoke(s). This could happen when a landing<br>
+    // pad is shared by multiple invokes and is also a target of a normal<br>
+    // edge from elsewhere.<br>
+    addPass(SjLjEHPreparePass());<br>
+    LLVM_FALLTHROUGH;<br>
+  case ExceptionHandling::DwarfCFI:<br>
+  case ExceptionHandling::ARM:<br>
+    addPass(DwarfEHPass());<br>
+    break;<br>
+  case ExceptionHandling::WinEH:<br>
+    // We support using both GCC-style and MSVC-style exceptions on Windows, so<br>
+    // add both preparation passes. Each pass will only actually run if it<br>
+    // recognizes the personality function.<br>
+    addPass(WinEHPass());<br>
+    addPass(DwarfEHPass());<br>
+    break;<br>
+  case ExceptionHandling::Wasm:<br>
+    // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs<br>
+    // on catchpads and cleanuppads because it does not outline them into<br>
+    // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we<br>
+    // should remove PHIs there.<br>
+    addPass(WinEHPass(/*DemoteCatchSwitchPHIOnly=*/false));<br>
+    addPass(WasmEHPass());<br>
+    break;<br>
+  case ExceptionHandling::None:<br>
+    addPass(LowerInvokePass());<br>
+<br>
+    // The lower invoke pass may create unreachable code. Remove it.<br>
+    addPass(UnreachableBlockElimPass());<br>
+    break;<br>
+  }<br>
+}<br>
+<br>
+/// Add pass to prepare the LLVM IR for code generation. This should be done<br>
+/// before exception handling preparation passes.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addCodeGenPrepare(AddIRPass &addPass) const {<br>
+  if (getOptLevel() != CodeGenOpt::None && !Opt.DisableCodeGenPreparePass)<br>
+    addPass(CodeGenPreparePass());<br>
+  // TODO: Default ctor'd RewriteSymbolPass is no-op.<br>
+  // addPass(RewriteSymbolPass());<br>
+}<br>
+<br>
+/// Add common passes that perform LLVM IR to IR transforms in preparation for<br>
+/// instruction selection.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addISelPrepare(AddIRPass &addPass) const {<br>
+  derived().addPreISel(addPass);<br>
+<br>
+  // Add both the safe stack and the stack protection passes: each of them will<br>
+  // only protect functions that have corresponding attributes.<br>
+  addPass(SafeStackPass());<br>
+  addPass(StackProtectorPass());<br>
+<br>
+  if (Opt.PrintISelInput)<br>
+    addPass(PrintFunctionPass(dbgs(),<br>
+                              "\n\n*** Final LLVM Code input to ISel ***\n"));<br>
+<br>
+  // All passes which modify the LLVM IR are now complete; run the verifier<br>
+  // to ensure that the IR is valid.<br>
+  if (!Opt.DisableVerify)<br>
+    addPass(VerifierPass());<br>
+}<br>
+<br>
+template <typename Derived><br>
+Expected<typename CodeGenPassBuilder<Derived>::AddMachinePass><br>
+CodeGenPassBuilder<Derived>::addCoreISelPasses() const {<br>
+  // Enable FastISel with -fast-isel, but allow that to be overridden.<br>
+  TM.setO0WantsFastISel(Opt.EnableFastISelOption.getValueOr(true));<br>
+<br>
+  // Determine an instruction selector.<br>
+  enum class SelectorType { SelectionDAG, FastISel, GlobalISel };<br>
+  SelectorType Selector;<br>
+<br>
+  if (Opt.EnableFastISelOption && *Opt.EnableFastISelOption == true)<br>
+    Selector = SelectorType::FastISel;<br>
+  else if ((Opt.EnableGlobalISelOption &&<br>
+            *Opt.EnableGlobalISelOption == true) ||<br>
+           (TM.Options.EnableGlobalISel &&<br>
+            (!Opt.EnableGlobalISelOption ||<br>
+             *Opt.EnableGlobalISelOption == false)))<br>
+    Selector = SelectorType::GlobalISel;<br>
+  else if (TM.getOptLevel() == CodeGenOpt::None && TM.getO0WantsFastISel())<br>
+    Selector = SelectorType::FastISel;<br>
+  else<br>
+    Selector = SelectorType::SelectionDAG;<br>
+<br>
+  // Set consistently TM.Options.EnableFastISel and EnableGlobalISel.<br>
+  if (Selector == SelectorType::FastISel) {<br>
+    TM.setFastISel(true);<br>
+    TM.setGlobalISel(false);<br>
+  } else if (Selector == SelectorType::GlobalISel) {<br>
+    TM.setFastISel(false);<br>
+    TM.setGlobalISel(true);<br>
+  }<br>
+<br>
+  AddMachinePass addPass(Opt.DebugPM, Opt.RequiresCodeGenSCCOrder,<br>
+                         *Opt.VerifyMachineCode);<br>
+<br>
+  // Add instruction selector passes.<br>
+  if (Selector == SelectorType::GlobalISel) {<br>
+    if (auto Err = derived().addIRTranslator(addPass))<br>
+      return std::move(Err);<br>
+<br>
+    derived().addPreLegalizeMachineIR(addPass);<br>
+<br>
+    if (auto Err = derived().addLegalizeMachineIR(addPass))<br>
+      return std::move(Err);<br>
+<br>
+    // Before running the register bank selector, ask the target if it<br>
+    // wants to run some passes.<br>
+    derived().addPreRegBankSelect(addPass);<br>
+<br>
+    if (auto Err = derived().addRegBankSelect(addPass))<br>
+      return std::move(Err);<br>
+<br>
+    derived().addPreGlobalInstructionSelect(addPass);<br>
+<br>
+    if (auto Err = derived().addGlobalInstructionSelect(addPass))<br>
+      return std::move(Err);<br>
+<br>
+    // Pass to reset the MachineFunction if the ISel failed.<br>
+    addPass(ResetMachineFunctionPass(reportDiagnosticWhenGlobalISelFallback(),<br>
+                                     isGlobalISelAbortEnabled()));<br>
+<br>
+    // Provide a fallback path when we do not want to abort on<br>
+    // not-yet-supported input.<br>
+    if (!isGlobalISelAbortEnabled()) {<br>
+      if (auto Err = derived().addInstSelector(addPass))<br>
+        return std::move(Err);<br>
+    }<br>
+<br>
+  } else if (auto Err = derived().addInstSelector(addPass))<br>
+    return std::move(Err);<br>
+<br>
+  // Expand pseudo-instructions emitted by ISel. Don't run the verifier before<br>
+  // FinalizeISel.<br>
+  addPass(FinalizeISelPass());<br>
+<br>
+  return addPass;<br>
+}<br>
+<br>
+/// Add the complete set of target-independent postISel code generator passes.<br>
+///<br>
+/// This can be read as the standard order of major LLVM CodeGen stages. Stages<br>
+/// with nontrivial configuration or multiple passes are broken out below in<br>
+/// add%Stage routines.<br>
+///<br>
+/// Any CodeGenPassBuilder<Derived>::addXX routine may be overriden by the<br>
+/// Target. The addPre/Post methods with empty header implementations allow<br>
+/// injecting target-specific fixups just before or after major stages.<br>
+/// Additionally, targets have the flexibility to change pass order within a<br>
+/// stage by overriding default implementation of add%Stage routines below. Each<br>
+/// technique has maintainability tradeoffs because alternate pass orders are<br>
+/// not well supported. addPre/Post works better if the target pass is easily<br>
+/// tied to a common pass. But if it has subtle dependencies on multiple passes,<br>
+/// the target should override the stage instead.<br>
+template <typename Derived><br>
+Error CodeGenPassBuilder<Derived>::addMachinePasses(<br>
+    AddMachinePass &addPass) const {<br>
+  // Add passes that optimize machine instructions in SSA form.<br>
+  if (getOptLevel() != CodeGenOpt::None) {<br>
+    derived().addMachineSSAOptimization(addPass);<br>
+  } else {<br>
+    // If the target requests it, assign local variables to stack slots relative<br>
+    // to one another and simplify frame index references where possible.<br>
+    addPass(LocalStackSlotPass());<br>
+  }<br>
+<br>
+  if (TM.Options.EnableIPRA)<br>
+    addPass(RegUsageInfoPropagationPass());<br>
+<br>
+  // Run pre-ra passes.<br>
+  derived().addPreRegAlloc(addPass);<br>
+<br>
+  // Run register allocation and passes that are tightly coupled with it,<br>
+  // including phi elimination and scheduling.<br>
+  if (*Opt.OptimizeRegAlloc) {<br>
+    derived().addOptimizedRegAlloc(addPass);<br>
+  } else {<br>
+    if (auto Err = derived().addFastRegAlloc(addPass))<br>
+      return Err;<br>
+  }<br>
+<br>
+  // Run post-ra passes.<br>
+  derived().addPostRegAlloc(addPass);<br>
+<br>
+  // Insert prolog/epilog code.  Eliminate abstract frame index references...<br>
+  if (getOptLevel() != CodeGenOpt::None) {<br>
+    addPass(PostRAMachineSinkingPass());<br>
+    addPass(ShrinkWrapPass());<br>
+  }<br>
+<br>
+  addPass(PrologEpilogInserterPass());<br>
+<br>
+  /// Add passes that optimize machine instructions after register allocation.<br>
+  if (getOptLevel() != CodeGenOpt::None)<br>
+    derived().addMachineLateOptimization(addPass);<br>
+<br>
+  // Expand pseudo instructions before second scheduling pass.<br>
+  addPass(ExpandPostRAPseudosPass());<br>
+<br>
+  // Run pre-sched2 passes.<br>
+  derived().addPreSched2(addPass);<br>
+<br>
+  if (Opt.EnableImplicitNullChecksPass)<br>
+    addPass(ImplicitNullChecksPass());<br>
+<br>
+  // Second pass scheduler.<br>
+  // Let Target optionally insert this pass by itself at some other point.<br>
+  if (getOptLevel() != CodeGenOpt::None &&<br>
+      !TM.targetSchedulesPostRAScheduling()) {<br>
+    if (Opt.EnablePostMachineSchedulerPass)<br>
+      addPass(PostMachineSchedulerPass());<br>
+    else<br>
+      addPass(PostRASchedulerPass());<br>
+  }<br>
+<br>
+  // GC<br>
+  derived().addGCPasses(addPass);<br>
+<br>
+  // Basic block placement.<br>
+  if (getOptLevel() != CodeGenOpt::None)<br>
+    derived().addBlockPlacement(addPass);<br>
+<br>
+  // Insert before XRay Instrumentation.<br>
+  addPass(FEntryInserterPass());<br>
+<br>
+  addPass(XRayInstrumentationPass());<br>
+  addPass(PatchableFunctionPass());<br>
+<br>
+  derived().addPreEmitPass(addPass);<br>
+<br>
+  if (TM.Options.EnableIPRA) {<br>
+    // Collect register usage information and produce a register mask of<br>
+    // clobbered registers, to be used to optimize call sites.<br>
+    addPass(RegUsageInfoCollectorPass());<br>
+  }<br>
+<br>
+  addPass(FuncletLayoutPass());<br>
+<br>
+  addPass(StackMapLivenessPass());<br>
+  addPass(LiveDebugValuesPass());<br>
+<br>
+  if (TM.Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&<br>
+      Opt.EnableMachineOutliner != RunOutliner::NeverOutline) {<br>
+    bool RunOnAllFunctions =<br>
+        (Opt.EnableMachineOutliner == RunOutliner::AlwaysOutline);<br>
+    bool AddOutliner = RunOnAllFunctions || TM.Options.SupportsDefaultOutlining;<br>
+    if (AddOutliner)<br>
+      addPass(MachineOutlinerPass(RunOnAllFunctions));<br>
+  }<br>
+<br>
+  // Add passes that directly emit MI after all other MI passes.<br>
+  derived().addPreEmitPass2(addPass);<br>
+<br>
+  return Error::success();<br>
+}<br>
+<br>
+/// Add passes that optimize machine instructions in SSA form.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addMachineSSAOptimization(<br>
+    AddMachinePass &addPass) const {<br>
+  // Pre-ra tail duplication.<br>
+  addPass(EarlyTailDuplicatePass());<br>
+<br>
+  // Optimize PHIs before DCE: removing dead PHI cycles may make more<br>
+  // instructions dead.<br>
+  addPass(OptimizePHIsPass());<br>
+<br>
+  // This pass merges large allocas. StackSlotColoring is a <br>
diff erent pass<br>
+  // which merges spill slots.<br>
+  addPass(StackColoringPass());<br>
+<br>
+  // If the target requests it, assign local variables to stack slots relative<br>
+  // to one another and simplify frame index references where possible.<br>
+  addPass(LocalStackSlotPass());<br>
+<br>
+  // With optimization, dead code should already be eliminated. However<br>
+  // there is one known exception: lowered code for arguments that are only<br>
+  // used by tail calls, where the tail calls reuse the incoming stack<br>
+  // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).<br>
+  addPass(DeadMachineInstructionElimPass());<br>
+<br>
+  // Allow targets to insert passes that improve instruction level parallelism,<br>
+  // like if-conversion. Such passes will typically need dominator trees and<br>
+  // loop info, just like LICM and CSE below.<br>
+  derived().addILPOpts(addPass);<br>
+<br>
+  addPass(EarlyMachineLICMPass());<br>
+  addPass(MachineCSEPass());<br>
+<br>
+  addPass(MachineSinkingPass());<br>
+<br>
+  addPass(PeepholeOptimizerPass());<br>
+  // Clean-up the dead code that may have been generated by peephole<br>
+  // rewriting.<br>
+  addPass(DeadMachineInstructionElimPass());<br>
+}<br>
+<br>
+//===---------------------------------------------------------------------===//<br>
+/// Register Allocation Pass Configuration<br>
+//===---------------------------------------------------------------------===//<br>
+<br>
+/// Instantiate the default register allocator pass for this target for either<br>
+/// the optimized or unoptimized allocation path. This will be added to the pass<br>
+/// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc<br>
+/// in the optimized case.<br>
+///<br>
+/// A target that uses the standard regalloc pass order for fast or optimized<br>
+/// allocation may still override this for per-target regalloc<br>
+/// selection. But -regalloc=... always takes precedence.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addTargetRegisterAllocator(<br>
+    AddMachinePass &addPass, bool Optimized) const {<br>
+  if (Optimized)<br>
+    addPass(RAGreedyPass());<br>
+  else<br>
+    addPass(RAFastPass());<br>
+}<br>
+<br>
+/// Find and instantiate the register allocation pass requested by this target<br>
+/// at the current optimization level.  Different register allocators are<br>
+/// defined as separate passes because they may require <br>
diff erent analysis.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addRegAllocPass(AddMachinePass &addPass,<br>
+                                                  bool Optimized) const {<br>
+  switch (Opt.RegAlloc) {<br>
+  case RegAllocType::Default:<br>
+    // With no -regalloc= override, ask the target for a regalloc pass.<br>
+    derived().addTargetRegisterAllocator(addPass, Optimized);<br>
+    break;<br>
+  case RegAllocType::Basic:<br>
+    addPass(RABasicPass());<br>
+    break;<br>
+  case RegAllocType::Fast:<br>
+    addPass(RAFastPass());<br>
+    break;<br>
+  case RegAllocType::Greedy:<br>
+    addPass(RAGreedyPass());<br>
+    break;<br>
+  case RegAllocType::PBQP:<br>
+    addPass(RAPBQPPass());<br>
+    break;<br>
+  default:<br>
+    llvm_unreachable("unknonwn register allocator type");<br>
+  }<br>
+}<br>
+<br>
+template <typename Derived><br>
+Error CodeGenPassBuilder<Derived>::addRegAssignmentFast(<br>
+    AddMachinePass &addPass) const {<br>
+  if (Opt.RegAlloc != RegAllocType::Default &&<br>
+      Opt.RegAlloc != RegAllocType::Fast)<br>
+    return make_error<StringError>(<br>
+        "Must use fast (default) register allocator for unoptimized regalloc.",<br>
+        inconvertibleErrorCode());<br>
+<br>
+  addRegAllocPass(addPass, false);<br>
+  return Error::success();<br>
+}<br>
+<br>
+template <typename Derived><br>
+Error CodeGenPassBuilder<Derived>::addRegAssignmentOptimized(<br>
+    AddMachinePass &addPass) const {<br>
+  // Add the selected register allocation pass.<br>
+  addRegAllocPass(addPass, true);<br>
+<br>
+  // Allow targets to change the register assignments before rewriting.<br>
+  derived().addPreRewrite(addPass);<br>
+<br>
+  // Finally rewrite virtual registers.<br>
+  addPass(VirtRegRewriterPass());<br>
+  // Perform stack slot coloring and post-ra machine LICM.<br>
+  //<br>
+  // FIXME: Re-enable coloring with register when it's capable of adding<br>
+  // kill markers.<br>
+  addPass(StackSlotColoringPass());<br>
+<br>
+  return Error::success();<br>
+}<br>
+<br>
+/// Add the minimum set of target-independent passes that are required for<br>
+/// register allocation. No coalescing or scheduling.<br>
+template <typename Derived><br>
+Error CodeGenPassBuilder<Derived>::addFastRegAlloc(<br>
+    AddMachinePass &addPass) const {<br>
+  addPass(PHIEliminationPass());<br>
+  addPass(TwoAddressInstructionPass());<br>
+  return derived().addRegAssignmentFast(addPass);<br>
+}<br>
+<br>
+/// Add standard target-independent passes that are tightly coupled with<br>
+/// optimized register allocation, including coalescing, machine instruction<br>
+/// scheduling, and register allocation itself.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(<br>
+    AddMachinePass &addPass) const {<br>
+  addPass(DetectDeadLanesPass());<br>
+<br>
+  addPass(ProcessImplicitDefsPass());<br>
+<br>
+  // Edge splitting is smarter with machine loop info.<br>
+  addPass(PHIEliminationPass());<br>
+<br>
+  // Eventually, we want to run LiveIntervals before PHI elimination.<br>
+  if (Opt.EnableLiveIntervalsPass)<br>
+    addPass(LiveIntervalsPass());<br>
+<br>
+  addPass(TwoAddressInstructionPass());<br>
+  addPass(RegisterCoalescerPass());<br>
+<br>
+  // The machine scheduler may accidentally create disconnected components<br>
+  // when moving subregister definitions around, avoid this by splitting them to<br>
+  // separate vregs before. Splitting can also improve reg. allocation quality.<br>
+  addPass(RenameIndependentSubregsPass());<br>
+<br>
+  // PreRA instruction scheduling.<br>
+  addPass(MachineSchedulerPass());<br>
+<br>
+  if (derived().addRegAssignmentOptimized(addPass)) {<br>
+    // Allow targets to expand pseudo instructions depending on the choice of<br>
+    // registers before MachineCopyPropagation.<br>
+    derived().addPostRewrite(addPass);<br>
+<br>
+    // Copy propagate to forward register uses and try to eliminate COPYs that<br>
+    // were not coalesced.<br>
+    addPass(MachineCopyPropagationPass());<br>
+<br>
+    // Run post-ra machine LICM to hoist reloads / remats.<br>
+    //<br>
+    // FIXME: can this move into MachineLateOptimization?<br>
+    addPass(MachineLICMPass());<br>
+  }<br>
+}<br>
+<br>
+//===---------------------------------------------------------------------===//<br>
+/// Post RegAlloc Pass Configuration<br>
+//===---------------------------------------------------------------------===//<br>
+<br>
+/// Add passes that optimize machine instructions after register allocation.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addMachineLateOptimization(<br>
+    AddMachinePass &addPass) const {<br>
+  // Branch folding must be run after regalloc and prolog/epilog insertion.<br>
+  addPass(BranchFolderPass());<br>
+<br>
+  // Tail duplication.<br>
+  // Note that duplicating tail just increases code size and degrades<br>
+  // performance for targets that require Structured Control Flow.<br>
+  // In addition it can also make CFG irreducible. Thus we disable it.<br>
+  if (!TM.requiresStructuredCFG())<br>
+    addPass(TailDuplicatePass());<br>
+<br>
+  // Copy propagation.<br>
+  addPass(MachineCopyPropagationPass());<br>
+}<br>
+<br>
+/// Add standard basic block placement passes.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addBlockPlacement(<br>
+    AddMachinePass &addPass) const {<br>
+  addPass(MachineBlockPlacementPass());<br>
+  // Run a separate pass to collect block placement statistics.<br>
+  if (Opt.EnableMachineBlockPlacementStatsPass)<br>
+    addPass(MachineBlockPlacementStatsPass());<br>
+}<br>
+<br>
+} // namespace llvm<br>
+<br>
+#endif // LLVM_CODEGEN_CODEGENPASSBUILDER_H<br>
<br>
diff  --git a/llvm/include/llvm/CodeGen/MachinePassRegistry.def b/llvm/include/llvm/CodeGen/MachinePassRegistry.def<br>
new file mode 100644<br>
index 000000000000..734bbebc76de<br>
--- /dev/null<br>
+++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def<br>
@@ -0,0 +1,195 @@<br>
+//===- MachinePassRegistry.def - Registry of passes -------------*- C++ -*-===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file is used as the registry of passes that are for target-independent<br>
+// code generator.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+// NOTE: NO INCLUDE GUARD DESIRED!<br>
+<br>
+#ifndef MODULE_ANALYSIS<br>
+#define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))<br>
+#undef MODULE_ANALYSIS<br>
+<br>
+#ifndef MODULE_PASS<br>
+#define MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass, ())<br>
+#undef MODULE_PASS<br>
+<br>
+#ifndef FUNCTION_ANALYSIS<br>
+#define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))<br>
+FUNCTION_ANALYSIS("targetir", TargetIRAnalysis, (std::move(TM.getTargetIRAnalysis())))<br>
+#undef FUNCTION_ANALYSIS<br>
+<br>
+#ifndef FUNCTION_PASS<br>
+#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+FUNCTION_PASS("mergeicmps", MergeICmpsPass, ())<br>
+FUNCTION_PASS("lower-constant-intrinsics", LowerConstantIntrinsicsPass, ())<br>
+FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass, ())<br>
+FUNCTION_PASS("consthoist", ConstantHoistingPass, ())<br>
+FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass, ())<br>
+FUNCTION_PASS("ee-instrument", EntryExitInstrumenterPass, (false))<br>
+FUNCTION_PASS("post-inline-ee-instrument", EntryExitInstrumenterPass, (true))<br>
+FUNCTION_PASS("expand-reductions", ExpandReductionsPass, ())<br>
+FUNCTION_PASS("lowerinvoke", LowerInvokePass, ())<br>
+FUNCTION_PASS("verify", VerifierPass, ())<br>
+#undef FUNCTION_PASS<br>
+<br>
+#ifndef LOOP_PASS<br>
+#define LOOP_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+LOOP_PASS("loop-reduce", LoopStrengthReducePass, ())<br>
+#undef LOOP_PASS<br>
+<br>
+#ifndef MACHINE_MODULE_PASS<br>
+#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+#undef MACHINE_MODULE_PASS<br>
+<br>
+#ifndef MACHINE_FUNCTION_ANALYSIS<br>
+#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))<br>
+// LiveVariables currently requires pure SSA form.<br>
+// FIXME: Once TwoAddressInstruction pass no longer uses kill flags,<br>
+// LiveVariables can be removed completely, and LiveIntervals can be directly<br>
+// computed. (We still either need to regenerate kill flags after regalloc, or<br>
+// preferably fix the scavenger to not depend on them).<br>
+// MACHINE_FUNCTION_ANALYSIS("live-vars", LiveVariablesAnalysis())<br>
+<br>
+// MACHINE_FUNCTION_ANALYSIS("live-stacks", LiveStacksPass())<br>
+// MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("edge-bundles", EdgeBundlesAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("lazy-machine-bfi", LazyMachineBlockFrequencyInfoAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-bfi", MachineBlockFrequencyInfoAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-loops", MachineLoopInfoAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-dom-frontier", MachineDominanceFrontierAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-dom-tree", MachineDominatorTreeAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-ore", MachineOptimizationRemarkEmitterPassAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree", MachinePostDominatorTreeAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-region-info", MachineRegionInfoPassAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("reaching-def", ReachingDefAnalysisAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("live-reg-matrix", LiveRegMatrixAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("gc-analysis", GCMachineCodeAnalysisPass())<br>
+#undef MACHINE_FUNCTION_ANALYSIS<br>
+<br>
+#ifndef MACHINE_FUNCTION_PASS<br>
+#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+MACHINE_FUNCTION_PASS("mir-printer", PrintMIRPass, ())<br>
+#undef MACHINE_FUNCTION_PASS<br>
+<br>
+// After a pass is converted to new pass manager, its entry should be moved from<br>
+// dummy table to the normal one. For example, for a machine function pass,<br>
+// DUMMY_MACHINE_FUNCTION_PASS to MACHINE_FUNCTION_PASS.<br>
+<br>
+#ifndef DUMMY_FUNCTION_PASS<br>
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+DUMMY_FUNCTION_PASS("expandmemcmp", ExpandMemCmpPass, ())<br>
+DUMMY_FUNCTION_PASS("gc-lowering", GCLoweringPass, ())<br>
+DUMMY_FUNCTION_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass, ())<br>
+DUMMY_FUNCTION_PASS("scalarize-masked-mem-intrin", ScalarizeMaskedMemIntrinPass, ())<br>
+DUMMY_FUNCTION_PASS("sjljehprepare", SjLjEHPreparePass, ())<br>
+DUMMY_FUNCTION_PASS("dwarfehprepare", DwarfEHPass, ())<br>
+DUMMY_FUNCTION_PASS("winehprepare", WinEHPass, ())<br>
+DUMMY_FUNCTION_PASS("wasmehprepare", WasmEHPass, ())<br>
+DUMMY_FUNCTION_PASS("codegenprepare", CodeGenPreparePass, ())<br>
+DUMMY_FUNCTION_PASS("safe-stack", SafeStackPass, ())<br>
+DUMMY_FUNCTION_PASS("stack-protector", StackProtectorPass, ())<br>
+DUMMY_FUNCTION_PASS("atomic-expand", AtomicExpandPass, ())<br>
+DUMMY_FUNCTION_PASS("interleaved-access", InterleavedAccessPass, ())<br>
+DUMMY_FUNCTION_PASS("indirectbr-expand", IndirectBrExpandPass, ())<br>
+DUMMY_FUNCTION_PASS("cfguard-dispatch", CFGuardDispatchPass, ())<br>
+DUMMY_FUNCTION_PASS("cfguard-check", CFGuardCheckPass, ())<br>
+DUMMY_FUNCTION_PASS("gc-info-printer", GCInfoPrinterPass, ())<br>
+#undef DUMMY_FUNCTION_PASS<br>
+<br>
+#ifndef DUMMY_MODULE_PASS<br>
+#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+DUMMY_MODULE_PASS("lower-emutls", LowerEmuTLSPass, ())<br>
+#undef DUMMY_MODULE_PASS<br>
+<br>
+#ifndef DUMMY_MACHINE_MODULE_PASS<br>
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+DUMMY_MACHINE_MODULE_PASS("machine-outliner", MachineOutlinerPass, ())<br>
+#undef DUMMY_MACHINE_MODULE_PASS<br>
+<br>
+#ifndef DUMMY_MACHINE_FUNCTION_PASS<br>
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+DUMMY_MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("finalize-isel", FinalizeISelPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("localstackalloc", LocalStackSlotPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("shrink-wrap", ShrinkWrapPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("prologepilog", PrologEpilogInserterPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("postrapseudos", ExpandPostRAPseudosPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("implicit-null-checks", ImplicitNullChecksPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("postmisched", PostMachineSchedulerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machine-scheduler", MachineSchedulerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machine-cp", MachineCopyPropagationPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("post-RA-sched", PostRASchedulerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("fentry-insert", FEntryInserterPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("xray-instrumentation", XRayInstrumentationPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("patchable-function", PatchableFunctionPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("reg-usage-propagation", RegUsageInfoPropagationPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("reg-usage-collector", RegUsageInfoCollectorPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("funclet-layout", FuncletLayoutPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("livedebugvalues", LiveDebugValuesPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("early-tailduplication", EarlyTailDuplicatePass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("opt-phis", OptimizePHIsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("stack-coloring", StackColoringPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("dead-mi-elimination", DeadMachineInstructionElimPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("early-machinelicm", EarlyMachineLICMPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machinelicm", MachineLICMPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machine-cse", MachineCSEPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machine-sink", MachineSinkingPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("postra-machine-sink", PostRAMachineSinkingPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("peephole-opt", PeepholeOptimizerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("regalloc", RegAllocPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("phi-node-elimination", PHIEliminationPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("twoaddressinstruction", TwoAddressInstructionPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("detect-dead-lanes", DetectDeadLanesPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("processimpdefs", ProcessImplicitDefsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("liveintervals", LiveIntervalsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("simple-register-coalescing", RegisterCoalescerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("rename-independent-subregs", RenameIndependentSubregsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("branch-folder", BranchFolderPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("tailduplication", TailDuplicatePass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("block-placement", MachineBlockPlacementPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("block-placement-stats", MachineBlockPlacementStatsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("early-ifcvt", EarlyIfConverterPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machine-combiner", MachineCombinerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("lrshrink", LiveRangeShrinkPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("break-false-deps", BreakFalseDepsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("cfi-instr-inserter", CFIInstrInserterPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("cfguard-longjmp", CFGuardLongjmpPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("ra-basic", RABasicPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("ra-fast", RAFastPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("ra-greedy", RAGreedyPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("ra-pbqp", RAPBQPPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("legalizer", LegalizerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("irtranslator", IRTranslatorPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("instruction-select", InstructionSelectPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machineverifier", MachineVerifierPass, ())<br>
+#undef DUMMY_MACHINE_FUNCTION_PASS<br>
<br>
diff  --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h<br>
index 76e217c89974..457eae26fd47 100644<br>
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h<br>
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h<br>
@@ -28,6 +28,7 @@<br>
<br>
 namespace llvm {<br>
<br>
+class LLVMTargetMachine;<br>
 class Module;<br>
 class Function;<br>
<br>
@@ -140,6 +141,10 @@ class StandardInstrumentations {<br>
<br>
   TimePassesHandler &getTimePasses() { return TimePasses; }<br>
 };<br>
+<br>
+void registerCodeGenCallback(PassInstrumentationCallbacks &PIC,<br>
+                             LLVMTargetMachine &);<br>
+<br>
 } // namespace llvm<br>
<br>
 #endif<br>
<br>
diff  --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h<br>
index 2a422341fdc8..c7673d3e74e4 100644<br>
--- a/llvm/include/llvm/Target/TargetMachine.h<br>
+++ b/llvm/include/llvm/Target/TargetMachine.h<br>
@@ -15,9 +15,12 @@<br>
<br>
 #include "llvm/ADT/StringRef.h"<br>
 #include "llvm/ADT/Triple.h"<br>
+#include "llvm/CodeGen/CGPassBuilderOption.h"<br>
+#include "llvm/CodeGen/MachinePassManager.h"<br>
 #include "llvm/IR/DataLayout.h"<br>
 #include "llvm/Pass.h"<br>
 #include "llvm/Support/CodeGen.h"<br>
+#include "llvm/Support/Error.h"<br>
 #include "llvm/Target/TargetOptions.h"<br>
 #include <string><br>
<br>
@@ -367,6 +370,20 @@ class LLVMTargetMachine : public TargetMachine {<br>
                       bool DisableVerify = true,<br>
                       MachineModuleInfoWrapperPass *MMIWP = nullptr) override;<br>
<br>
+  virtual Expected<std::pair<ModulePassManager, MachineFunctionPassManager>><br>
+  buildCodeGenPipeline(raw_pwrite_stream &, raw_pwrite_stream *,<br>
+                       CodeGenFileType, CGPassBuilderOption,<br>
+                       MachineFunctionAnalysisManager &,<br>
+                       PassInstrumentationCallbacks *) {<br>
+    return make_error<StringError>("buildCodeGenPipeline is not overriden",<br>
+                                   inconvertibleErrorCode());<br>
+  }<br>
+<br>
+  virtual std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) {<br>
+    llvm_unreachable(<br>
+        "getPassNameFromLegacyName parseMIRPipeline is not overriden");<br>
+  }<br>
+<br>
   /// Add passes to the specified pass manager to get machine code emitted with<br>
   /// the MCJIT. This method returns true if machine code is not supported. It<br>
   /// fills the MCContext Ctx pointer which can be used to build custom<br>
@@ -387,6 +404,10 @@ class LLVMTargetMachine : public TargetMachine {<br>
                      raw_pwrite_stream *DwoOut, CodeGenFileType FileType,<br>
                      MCContext &Context);<br>
<br>
+  Expected<std::unique_ptr<MCStreamer>><br>
+  createMCStreamer(raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,<br>
+                   CodeGenFileType FileType, MCContext &Ctx);<br>
+<br>
   /// True if the target uses physical regs (as nearly all targets do). False<br>
   /// for stack machines such as WebAssembly and other virtual-register<br>
   /// machines. If true, all vregs must be allocated before PEI. If false, then<br>
<br>
diff  --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt<br>
index 617692a34792..83b3655441fe 100644<br>
--- a/llvm/lib/CodeGen/CMakeLists.txt<br>
+++ b/llvm/lib/CodeGen/CMakeLists.txt<br>
@@ -14,6 +14,7 @@ add_llvm_component_library(LLVMCodeGen<br>
   CFGuardLongjmp.cpp<br>
   CFIInstrInserter.cpp<br>
   CodeGen.cpp<br>
+  CodeGenPassBuilder.cpp<br>
   CodeGenPrepare.cpp<br>
   CommandFlags.cpp<br>
   CriticalAntiDepBreaker.cpp<br>
<br>
diff  --git a/llvm/lib/CodeGen/CodeGenPassBuilder.cpp b/llvm/lib/CodeGen/CodeGenPassBuilder.cpp<br>
new file mode 100644<br>
index 000000000000..7f37f2069a3b<br>
--- /dev/null<br>
+++ b/llvm/lib/CodeGen/CodeGenPassBuilder.cpp<br>
@@ -0,0 +1,25 @@<br>
+//===--- CodeGenPassBuilder.cpp --------------------------------------- ---===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file defines interfaces to access the target independent code<br>
+// generation passes provided by the LLVM backend.<br>
+//<br>
+//===---------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/CodeGen/CodeGenPassBuilder.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+namespace llvm {<br>
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                \<br>
+  AnalysisKey PASS_NAME::Key;<br>
+#include "llvm/CodeGen/MachinePassRegistry.def"<br>
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \<br>
+  AnalysisKey PASS_NAME::Key;<br>
+#include "llvm/CodeGen/MachinePassRegistry.def"<br>
+} // namespace llvm<br>
<br>
diff  --git a/llvm/lib/CodeGen/LLVMTargetMachine.cpp b/llvm/lib/CodeGen/LLVMTargetMachine.cpp<br>
index e94b7ed4de03..e86f25512999 100644<br>
--- a/llvm/lib/CodeGen/LLVMTargetMachine.cpp<br>
+++ b/llvm/lib/CodeGen/LLVMTargetMachine.cpp<br>
@@ -118,6 +118,24 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,<br>
                                       raw_pwrite_stream *DwoOut,<br>
                                       CodeGenFileType FileType,<br>
                                       MCContext &Context) {<br>
+  Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =<br>
+      createMCStreamer(Out, DwoOut, FileType, Context);<br>
+  if (auto Err = MCStreamerOrErr.takeError())<br>
+    return true;<br>
+<br>
+  // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.<br>
+  FunctionPass *Printer =<br>
+      getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));<br>
+  if (!Printer)<br>
+    return true;<br>
+<br>
+  PM.add(Printer);<br>
+  return false;<br>
+}<br>
+<br>
+Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(<br>
+    raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,<br>
+    MCContext &Context) {<br>
   if (Options.MCOptions.MCSaveTempLabels)<br>
     Context.setAllowTemporaryLabels(false);<br>
<br>
@@ -152,10 +170,14 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,<br>
     // Create the code emitter for the target if it exists.  If not, .o file<br>
     // emission fails.<br>
     MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, Context);<br>
+    if (!MCE)<br>
+      return make_error<StringError>("createMCCodeEmitter failed",<br>
+                                     inconvertibleErrorCode());<br>
     MCAsmBackend *MAB =<br>
         getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);<br>
-    if (!MCE || !MAB)<br>
-      return true;<br>
+    if (!MAB)<br>
+      return make_error<StringError>("createMCAsmBackend failed",<br>
+                                     inconvertibleErrorCode());<br>
<br>
     Triple T(getTargetTriple().str());<br>
     AsmStreamer.reset(getTarget().createMCObjectStreamer(<br>
@@ -174,14 +196,7 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,<br>
     break;<br>
   }<br>
<br>
-  // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.<br>
-  FunctionPass *Printer =<br>
-      getTarget().createAsmPrinter(*this, std::move(AsmStreamer));<br>
-  if (!Printer)<br>
-    return true;<br>
-<br>
-  PM.add(Printer);<br>
-  return false;<br>
+  return std::move(AsmStreamer);<br>
 }<br>
<br>
 bool LLVMTargetMachine::addPassesToEmitFile(<br>
<br>
diff  --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp<br>
index 19db8eb480ca..03a567e3d443 100644<br>
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp<br>
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp<br>
@@ -22,6 +22,7 @@<br>
 #include "llvm/Analysis/ScopedNoAliasAA.h"<br>
 #include "llvm/Analysis/TargetTransformInfo.h"<br>
 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"<br>
+#include "llvm/CodeGen/CGPassBuilderOption.h"<br>
 #include "llvm/CodeGen/CSEConfigBase.h"<br>
 #include "llvm/CodeGen/MachineFunctionPass.h"<br>
 #include "llvm/CodeGen/MachinePassRegistry.h"<br>
@@ -29,11 +30,13 @@<br>
 #include "llvm/CodeGen/RegAllocRegistry.h"<br>
 #include "llvm/IR/IRPrintingPasses.h"<br>
 #include "llvm/IR/LegacyPassManager.h"<br>
+#include "llvm/IR/PassInstrumentation.h"<br>
 #include "llvm/IR/Verifier.h"<br>
 #include "llvm/InitializePasses.h"<br>
 #include "llvm/MC/MCAsmInfo.h"<br>
 #include "llvm/MC/MCTargetOptions.h"<br>
 #include "llvm/Pass.h"<br>
+#include "llvm/Passes/StandardInstrumentations.h"<br>
 #include "llvm/Support/CodeGen.h"<br>
 #include "llvm/Support/CommandLine.h"<br>
 #include "llvm/Support/Compiler.h"<br>
@@ -120,16 +123,17 @@ static cl::opt<cl::boolOrDefault> DebugifyAndStripAll(<br>
         "Debugify MIR before and Strip debug after "<br>
         "each pass except those known to be unsafe when debug info is present"),<br>
     cl::ZeroOrMore);<br>
-enum RunOutliner { AlwaysOutline, NeverOutline, TargetDefault };<br>
+<br>
 // Enable or disable the MachineOutliner.<br>
 static cl::opt<RunOutliner> EnableMachineOutliner(<br>
     "enable-machine-outliner", cl::desc("Enable the machine outliner"),<br>
-    cl::Hidden, cl::ValueOptional, cl::init(TargetDefault),<br>
-    cl::values(clEnumValN(AlwaysOutline, "always",<br>
+    cl::Hidden, cl::ValueOptional, cl::init(RunOutliner::TargetDefault),<br>
+    cl::values(clEnumValN(RunOutliner::AlwaysOutline, "always",<br>
                           "Run on all functions guaranteed to be beneficial"),<br>
-               clEnumValN(NeverOutline, "never", "Disable all outlining"),<br>
+               clEnumValN(RunOutliner::NeverOutline, "never",<br>
+                          "Disable all outlining"),<br>
                // Sentinel value for unspecified option.<br>
-               clEnumValN(AlwaysOutline, "", "")));<br>
+               clEnumValN(RunOutliner::AlwaysOutline, "", "")));<br>
 // Enable or disable FastISel. Both options are needed, because<br>
 // FastISel is enabled by default with -fast, and we wish to be<br>
 // able to enable or disable fast-isel independently from -O0.<br>
@@ -172,7 +176,6 @@ static cl::opt<bool> EarlyLiveIntervals("early-live-intervals", cl::Hidden,<br>
     cl::desc("Run live interval analysis earlier in the pipeline"));<br>
<br>
 // Experimental option to use CFL-AA in codegen<br>
-enum class CFLAAType { None, Steensgaard, Andersen, Both };<br>
 static cl::opt<CFLAAType> UseCFLAA(<br>
     "use-cfl-aa-in-codegen", cl::init(CFLAAType::None), cl::Hidden,<br>
     cl::desc("Enable the new, experimental CFL alias analysis in CodeGen"),<br>
@@ -404,6 +407,143 @@ void TargetPassConfig::setStartStopPasses() {<br>
   Started = (StartAfter == nullptr) && (StartBefore == nullptr);<br>
 }<br>
<br>
+CGPassBuilderOption llvm::getCGPassBuilderOption() {<br>
+  CGPassBuilderOption Opt;<br>
+<br>
+#define SET_OPTION(Option)                                                     \<br>
+  if (Option.getNumOccurrences())                                              \<br>
+    Opt.Option = Option;<br>
+<br>
+  SET_OPTION(EnableFastISelOption)<br>
+  SET_OPTION(EnableGlobalISelAbort)<br>
+  SET_OPTION(EnableGlobalISelOption)<br>
+  SET_OPTION(EnableIPRA)<br>
+  SET_OPTION(OptimizeRegAlloc)<br>
+  SET_OPTION(VerifyMachineCode)<br>
+<br>
+  Opt.EnableMachineOutliner = EnableMachineOutliner;<br>
+  Opt.UseCFLAA = UseCFLAA;<br>
+  Opt.PrintISelInput = PrintISelInput;<br>
+  Opt.PrintGCInfo = PrintGCInfo;<br>
+  Opt.EnablePostMachineSchedulerPass = MISchedPostRA;<br>
+  Opt.EnableLiveIntervalsPass = EarlyLiveIntervals;<br>
+  Opt.EnableMachineBlockPlacementStatsPass = EnableBlockPlacementStats;<br>
+  Opt.EnableImplicitNullChecksPass = EnableImplicitNullChecks;<br>
+  Opt.DisableLoopStrengthReducePass = DisableLSR;<br>
+  Opt.DisableCodeGenPreparePass = DisableCGP;<br>
+  Opt.DisableMergeICmpsPass = DisableMergeICmps;<br>
+  Opt.DisablePartiallyInlineLibCallsPass = DisablePartialLibcallInlining;<br>
+  Opt.DisableConstantHoistingPass = DisableConstantHoisting;<br>
+  Opt.PrintAfterLSR = PrintLSR;<br>
+<br>
+  return Opt;<br>
+}<br>
+<br>
+static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,<br>
+                                            LLVMTargetMachine &LLVMTM) {<br>
+  StringRef StartBefore;<br>
+  StringRef StartAfter;<br>
+  StringRef StopBefore;<br>
+  StringRef StopAfter;<br>
+<br>
+  unsigned StartBeforeInstanceNum = 0;<br>
+  unsigned StartAfterInstanceNum = 0;<br>
+  unsigned StopBeforeInstanceNum = 0;<br>
+  unsigned StopAfterInstanceNum = 0;<br>
+<br>
+  std::tie(StartBefore, StartBeforeInstanceNum) =<br>
+      getPassNameAndInstanceNum(StartBeforeOpt);<br>
+  std::tie(StartAfter, StartAfterInstanceNum) =<br>
+      getPassNameAndInstanceNum(StartAfterOpt);<br>
+  std::tie(StopBefore, StopBeforeInstanceNum) =<br>
+      getPassNameAndInstanceNum(StopBeforeOpt);<br>
+  std::tie(StopAfter, StopAfterInstanceNum) =<br>
+      getPassNameAndInstanceNum(StopAfterOpt);<br>
+<br>
+  if (StartBefore.empty() && StartAfter.empty() && StopBefore.empty() &&<br>
+      StopAfter.empty())<br>
+    return;<br>
+<br>
+  std::tie(StartBefore, std::ignore) =<br>
+      LLVMTM.getPassNameFromLegacyName(StartBefore);<br>
+  std::tie(StartAfter, std::ignore) =<br>
+      LLVMTM.getPassNameFromLegacyName(StartAfter);<br>
+  std::tie(StopBefore, std::ignore) =<br>
+      LLVMTM.getPassNameFromLegacyName(StopBefore);<br>
+  std::tie(StopAfter, std::ignore) =<br>
+      LLVMTM.getPassNameFromLegacyName(StopAfter);<br>
+  if (!StartBefore.empty() && !StartAfter.empty())<br>
+    report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +<br>
+                       Twine(StartAfterOptName) + Twine(" specified!"));<br>
+  if (!StopBefore.empty() && !StopAfter.empty())<br>
+    report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +<br>
+                       Twine(StopAfterOptName) + Twine(" specified!"));<br>
+<br>
+  PIC.registerBeforePassCallback(<br>
+      [=, EnableCurrent = StartBefore.empty() && StartAfter.empty(),<br>
+       EnableNext = Optional<bool>(), StartBeforeCount = 0u,<br>
+       StartAfterCount = 0u, StopBeforeCount = 0u,<br>
+       StopAfterCount = 0u](StringRef P, Any) mutable {<br>
+        bool StartBeforePass = !StartBefore.empty() && P.contains(StartBefore);<br>
+        bool StartAfterPass = !StartAfter.empty() && P.contains(StartAfter);<br>
+        bool StopBeforePass = !StopBefore.empty() && P.contains(StopBefore);<br>
+        bool StopAfterPass = !StopAfter.empty() && P.contains(StopAfter);<br>
+<br>
+        // Implement -start-after/-stop-after<br>
+        if (EnableNext) {<br>
+          EnableCurrent = *EnableNext;<br>
+          EnableNext.reset();<br>
+        }<br>
+<br>
+        // Using PIC.registerAfterPassCallback won't work because if this<br>
+        // callback returns false, AfterPassCallback is also skipped.<br>
+        if (StartAfterPass && StartAfterCount++ == StartAfterInstanceNum) {<br>
+          assert(!EnableNext && "Error: assign to EnableNext more than once");<br>
+          EnableNext = true;<br>
+        }<br>
+        if (StopAfterPass && StopAfterCount++ == StopAfterInstanceNum) {<br>
+          assert(!EnableNext && "Error: assign to EnableNext more than once");<br>
+          EnableNext = false;<br>
+        }<br>
+<br>
+        if (StartBeforePass && StartBeforeCount++ == StartBeforeInstanceNum)<br>
+          EnableCurrent = true;<br>
+        if (StopBeforePass && StopBeforeCount++ == StopBeforeInstanceNum)<br>
+          EnableCurrent = false;<br>
+        return EnableCurrent;<br>
+      });<br>
+}<br>
+<br>
+void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,<br>
+                                   LLVMTargetMachine &LLVMTM) {<br>
+<br>
+  // Register a callback for disabling passes.<br>
+  PIC.registerBeforePassCallback([](StringRef P, Any) {<br>
+<br>
+#define DISABLE_PASS(Option, Name)                                             \<br>
+  if (Option && P.contains(#Name))                                             \<br>
+    return false;<br>
+    DISABLE_PASS(DisableBlockPlacement, MachineBlockPlacementPass)<br>
+    DISABLE_PASS(DisableBranchFold, BranchFolderPass)<br>
+    DISABLE_PASS(DisableCopyProp, MachineCopyPropagationPass)<br>
+    DISABLE_PASS(DisableEarlyIfConversion, EarlyIfConverterPass)<br>
+    DISABLE_PASS(DisableEarlyTailDup, EarlyTailDuplicatePass)<br>
+    DISABLE_PASS(DisableMachineCSE, MachineCSEPass)<br>
+    DISABLE_PASS(DisableMachineDCE, DeadMachineInstructionElimPass)<br>
+    DISABLE_PASS(DisableMachineLICM, EarlyMachineLICMPass)<br>
+    DISABLE_PASS(DisableMachineSink, MachineSinkingPass)<br>
+    DISABLE_PASS(DisablePostRAMachineLICM, MachineLICMPass)<br>
+    DISABLE_PASS(DisablePostRAMachineSink, PostRAMachineSinkingPass)<br>
+    DISABLE_PASS(DisablePostRASched, PostRASchedulerPass)<br>
+    DISABLE_PASS(DisableSSC, StackSlotColoringPass)<br>
+    DISABLE_PASS(DisableTailDuplicate, TailDuplicatePass)<br>
+<br>
+    return true;<br>
+  });<br>
+<br>
+  registerPartialPipelineCallback(PIC, LLVMTM);<br>
+}<br>
+<br>
 // Out of line constructor provides default values for pass options and<br>
 // registers all common codegen passes.<br>
 TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)<br>
@@ -1012,10 +1152,11 @@ void TargetPassConfig::addMachinePasses() {<br>
   addPass(&LiveDebugValuesID, false);<br>
<br>
   if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&<br>
-      EnableMachineOutliner != NeverOutline) {<br>
-    bool RunOnAllFunctions = (EnableMachineOutliner == AlwaysOutline);<br>
-    bool AddOutliner = RunOnAllFunctions ||<br>
-                       TM->Options.SupportsDefaultOutlining;<br>
+      EnableMachineOutliner != RunOutliner::NeverOutline) {<br>
+    bool RunOnAllFunctions =<br>
+        (EnableMachineOutliner == RunOutliner::AlwaysOutline);<br>
+    bool AddOutliner =<br>
+        RunOnAllFunctions || TM->Options.SupportsDefaultOutlining;<br>
     if (AddOutliner)<br>
       addPass(createMachineOutlinerPass(RunOnAllFunctions));<br>
   }<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>
</blockquote></div>