[llvm] [NewPM][CodeGen] Add NPM support to llc (PR #69879)

via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 3 02:56:46 PDT 2023


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

>From cdbd6d381e39bea1cd61d94220411ef6c8710c5b Mon Sep 17 00:00:00 2001
From: liujunchang <lgamma at 163.com>
Date: Wed, 1 Nov 2023 09:16:46 +0800
Subject: [PATCH 1/8] [Pass] Support MachineFunction in getIRName It is
 necessary in MachinePassManager

---
 llvm/lib/Passes/StandardInstrumentations.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 06cc58c0219632d..8cae1235487f13b 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -19,6 +19,7 @@
 #include "llvm/Analysis/CallGraphSCCPass.h"
 #include "llvm/Analysis/LazyCallGraph.h"
 #include "llvm/Analysis/LoopInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Module.h"
@@ -222,6 +223,9 @@ std::string getIRName(Any IR) {
   if (const auto **L = llvm::any_cast<const Loop *>(&IR))
     return (*L)->getName().str();
 
+  if (const auto **MF = llvm::any_cast<const MachineFunction *>(&IR))
+    return (*MF)->getName().str();
+
   llvm_unreachable("Unknown wrapped IR type");
 }
 

>From dcab7361abaa8adfad7461bfc8a93dcc73cb9068 Mon Sep 17 00:00:00 2001
From: liujunchang <lgamma at 163.com>
Date: Wed, 1 Nov 2023 09:25:39 +0800
Subject: [PATCH 2/8] [Pass][CodeGen] Add some necessary passes

---
 .../include/llvm/CodeGen/CodeGenPassBuilder.h | 13 +++++++-
 .../llvm/CodeGen/MachinePassRegistry.def      | 30 +++++++++++++++++--
 llvm/lib/CodeGen/CodeGenPassBuilder.cpp       |  2 ++
 3 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
index d7739e8bb597e4e..aefd12527378ea0 100644
--- a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
@@ -90,7 +90,18 @@ namespace llvm {
     }                                                                          \
     static AnalysisKey Key;                                                    \
   };
-#include "MachinePassRegistry.def"
+#define DUMMY_MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)          \
+  struct PASS_NAME : public AnalysisInfoMixin<PASS_NAME> {                     \
+    template <typename... Ts> PASS_NAME(Ts &&...) {}                           \
+    using Result = struct {};                                                  \
+    template <typename IRUnitT, typename AnalysisManagerT,                     \
+              typename... ExtraArgTs>                                          \
+    Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {              \
+      return {};                                                               \
+    }                                                                          \
+    static AnalysisKey Key;                                                    \
+  };
+#include "llvm/CodeGen/MachinePassRegistry.def"
 
 /// This class provides access to building LLVM's passes.
 ///
diff --git a/llvm/include/llvm/CodeGen/MachinePassRegistry.def b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
index a29269644ea1dc0..6ddd86412ed5a04 100644
--- a/llvm/include/llvm/CodeGen/MachinePassRegistry.def
+++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
@@ -43,8 +43,8 @@ FUNCTION_PASS("replace-with-veclib", ReplaceWithVeclib, ())
 FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass, ())
 FUNCTION_PASS("ee-instrument", EntryExitInstrumenterPass, (false))
 FUNCTION_PASS("post-inline-ee-instrument", EntryExitInstrumenterPass, (true))
-FUNCTION_PASS("expand-large-div-rem", ExpandLargeDivRemPass, ())
-FUNCTION_PASS("expand-large-fp-convert", ExpandLargeFpConvertPass, ())
+FUNCTION_PASS("expand-large-div-rem", ExpandLargeDivRemPass, (TM))
+FUNCTION_PASS("expand-large-fp-convert", ExpandLargeFpConvertPass, (TM))
 FUNCTION_PASS("expand-reductions", ExpandReductionsPass, ())
 FUNCTION_PASS("expandvp", ExpandVectorPredicationPass, ())
 FUNCTION_PASS("lowerinvoke", LowerInvokePass, ())
@@ -136,6 +136,10 @@ DUMMY_MODULE_PASS("lower-emutls", LowerEmuTLSPass, ())
 #define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)
 #endif
 DUMMY_MACHINE_MODULE_PASS("machine-outliner", MachineOutlinerPass, ())
+DUMMY_MACHINE_MODULE_PASS("pseudo-probe-inserter", PseudoProbeInserterPass, ())
+DUMMY_MACHINE_MODULE_PASS("mir-debugify", DebugifyMachineModule, ())
+DUMMY_MACHINE_MODULE_PASS("mir-check-debugify", CheckDebugMachineModulePass, ())
+DUMMY_MACHINE_MODULE_PASS("mir-strip-debug", StripDebugMachineModulePass, (OnlyDebugified))
 #undef DUMMY_MACHINE_MODULE_PASS
 
 #ifndef DUMMY_MACHINE_FUNCTION_PASS
@@ -175,6 +179,7 @@ DUMMY_MACHINE_FUNCTION_PASS("machine-sink", MachineSinkingPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("postra-machine-sink", PostRAMachineSinkingPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("peephole-opt", PeepholeOptimizerPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("regalloc", RegAllocPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("regallocscoringpass", RegAllocScoringPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("phi-node-elimination", PHIEliminationPass, ())
@@ -203,9 +208,28 @@ DUMMY_MACHINE_FUNCTION_PASS("irtranslator", IRTranslatorPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("instruction-select", InstructionSelectPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("machineverifier", MachineVerifierPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("machineverifier", MachineVerifierPass, (Banner))
 DUMMY_MACHINE_FUNCTION_PASS("print-machine-cycles", MachineCycleInfoPrinterPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("machine-sanmd", MachineSanitizerBinaryMetadata, ())
 DUMMY_MACHINE_FUNCTION_PASS("machine-uniformity", MachineUniformityInfoWrapperPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("print-machine-uniformity", MachineUniformityInfoPrinterPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("unpack-mi-bundles", UnpackMachineBundlesPass, (Ftor))
+DUMMY_MACHINE_FUNCTION_PASS("machineinstr-printer", MachineFunctionPrinterPass, (OS, Banner))
+DUMMY_MACHINE_FUNCTION_PASS("kcfi", KCFIPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("cfi-fixup", CFIFixupPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("mirfs-discriminators", MIRAddFSDiscriminatorsPass, (P))
+DUMMY_MACHINE_FUNCTION_PASS("fs-profile-loader", MIRProfileLoaderPass, (File, ProfileFile, P, FS))
+DUMMY_MACHINE_FUNCTION_PASS("machine-function-splitter", MachineFunctionSplitterPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("bbsections-prepare", BasicBlockSectionsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("bbsections-profile-reader", BasicBlockSectionsProfileReaderPass, (Buf))
+DUMMY_MACHINE_FUNCTION_PASS("fixup-statepoint-caller-saved", FixupStatepointCallerSavedPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("gc-empty-basic-blocks", GCEmptyBasicBlocksPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("stack-frame-layout", StackFrameLayoutAnalysisPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("prologepilog", PrologEpilogCodeInserterPass, ())
 #undef DUMMY_MACHINE_FUNCTION_PASS
+
+#ifndef DUMMY_MACHINE_FUNCTION_ANALYSIS
+#define DUMMY_MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+DUMMY_MACHINE_FUNCTION_ANALYSIS("gc-analysis", GCMachineCodeAnalysisPass, ())
+#undef DUMMY_MACHINE_FUNCTION_ANALYSIS
diff --git a/llvm/lib/CodeGen/CodeGenPassBuilder.cpp b/llvm/lib/CodeGen/CodeGenPassBuilder.cpp
index 7f37f2069a3ba79..5919caa45b9bdfe 100644
--- a/llvm/lib/CodeGen/CodeGenPassBuilder.cpp
+++ b/llvm/lib/CodeGen/CodeGenPassBuilder.cpp
@@ -21,5 +21,7 @@ namespace llvm {
 #include "llvm/CodeGen/MachinePassRegistry.def"
 #define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \
   AnalysisKey PASS_NAME::Key;
+#define DUMMY_MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)          \
+  AnalysisKey PASS_NAME::Key;
 #include "llvm/CodeGen/MachinePassRegistry.def"
 } // namespace llvm

>From 91a7589c3803c76ed66cb2212a89d7d0ad671aa3 Mon Sep 17 00:00:00 2001
From: liujunchang <lgamma at 163.com>
Date: Wed, 1 Nov 2023 09:34:56 +0800
Subject: [PATCH 3/8] [CodeGen][NewPM] Add necessary codegen options

Theses options are used by TargetPassConfig
to build codegen pass pipeline,
add them to CGPassBuilderOption
so CodeGenPassBuilder can use them.
---
 llvm/include/llvm/Target/CGPassBuilderOption.h | 11 +++++++++++
 llvm/lib/CodeGen/TargetPassConfig.cpp          | 10 ++++++++++
 2 files changed, 21 insertions(+)

diff --git a/llvm/include/llvm/Target/CGPassBuilderOption.h b/llvm/include/llvm/Target/CGPassBuilderOption.h
index bf297ae498b2de5..2c98bea4b60e048 100644
--- a/llvm/include/llvm/Target/CGPassBuilderOption.h
+++ b/llvm/include/llvm/Target/CGPassBuilderOption.h
@@ -32,8 +32,10 @@ struct CGPassBuilderOption {
   bool DisableVerify = false;
   bool EnableImplicitNullChecks = false;
   bool EnableBlockPlacementStats = false;
+  bool EnableMachineFunctionSplitter = false;
   bool MISchedPostRA = false;
   bool EarlyLiveIntervals = false;
+  bool GCEmptyBlocks = false;
 
   bool DisableLSR = false;
   bool DisableCGP = false;
@@ -42,6 +44,11 @@ struct CGPassBuilderOption {
   bool DisablePartialLibcallInlining = false;
   bool DisableConstantHoisting = false;
   bool DisableSelectOptimize = true;
+  bool DisableAtExitBasedGlobalDtorLowering = false;
+  bool DisableExpandReductions = false;
+  bool DisableRAFSProfileLoader = false;
+  bool DisableCFIFixup = false;
+  bool PrintAfterISel = false;
   bool PrintISelInput = false;
   bool PrintGCInfo = false;
   bool RequiresCodeGenSCCOrder = false;
@@ -49,10 +56,14 @@ struct CGPassBuilderOption {
   RunOutliner EnableMachineOutliner = RunOutliner::TargetDefault;
   RegAllocType RegAlloc = RegAllocType::Default;
   std::optional<GlobalISelAbortMode> EnableGlobalISelAbort;
+  std::string FSProfileFile;
+  std::string FSRemappingFile;
 
   std::optional<bool> VerifyMachineCode;
   std::optional<bool> EnableFastISelOption;
   std::optional<bool> EnableGlobalISelOption;
+  std::optional<bool> DebugifyAndStripAll;
+  std::optional<bool> DebugifyCheckAndStripAll;
 };
 
 CGPassBuilderOption getCGPassBuilderOption();
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 1f7c949cd6031b1..230e3cd945916f8 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -475,6 +475,11 @@ CGPassBuilderOption llvm::getCGPassBuilderOption() {
   SET_OPTION(EnableIPRA)
   SET_OPTION(OptimizeRegAlloc)
   SET_OPTION(VerifyMachineCode)
+  SET_OPTION(DisableAtExitBasedGlobalDtorLowering)
+  SET_OPTION(DisableExpandReductions)
+  SET_OPTION(PrintAfterISel)
+  SET_OPTION(FSProfileFile)
+  SET_OPTION(GCEmptyBlocks)
 
 #define SET_BOOLEAN_OPTION(Option) Opt.Option = Option;
 
@@ -492,6 +497,11 @@ CGPassBuilderOption llvm::getCGPassBuilderOption() {
   SET_BOOLEAN_OPTION(PrintLSR)
   SET_BOOLEAN_OPTION(PrintISelInput)
   SET_BOOLEAN_OPTION(PrintGCInfo)
+  SET_BOOLEAN_OPTION(DebugifyAndStripAll)
+  SET_BOOLEAN_OPTION(DebugifyCheckAndStripAll)
+  SET_BOOLEAN_OPTION(DisableRAFSProfileLoader)
+  SET_BOOLEAN_OPTION(DisableCFIFixup)
+  SET_BOOLEAN_OPTION(EnableMachineFunctionSplitter)
 
   return Opt;
 }

>From 69775f0d505667c3e143f72d5cb29b606d3c2e0f Mon Sep 17 00:00:00 2001
From: liujunchang <lgamma at 163.com>
Date: Wed, 1 Nov 2023 10:41:58 +0800
Subject: [PATCH 4/8] [NewPM][CodeGen] add TargetPassConfig like API

---
 .../include/llvm/CodeGen/CodeGenPassBuilder.h | 435 +++++++++++++++---
 llvm/include/llvm/Target/TargetMachine.h      |  18 +-
 2 files changed, 388 insertions(+), 65 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
index aefd12527378ea0..9bef55664cc061b 100644
--- a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
@@ -19,10 +19,14 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/CallGraph.h"
 #include "llvm/Analysis/ScopedNoAliasAA.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
+#include "llvm/CodeGen/ExpandLargeDivRem.h"
+#include "llvm/CodeGen/ExpandLargeFpConvert.h"
 #include "llvm/CodeGen/ExpandReductions.h"
+#include "llvm/CodeGen/ExpandVectorPredication.h"
 #include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/PreISelIntrinsicLowering.h"
 #include "llvm/CodeGen/ReplaceWithVeclib.h"
@@ -36,6 +40,8 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/WithColor.h"
 #include "llvm/Target/CGPassBuilderOption.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/Scalar/ConstantHoisting.h"
@@ -45,7 +51,10 @@
 #include "llvm/Transforms/Scalar/MergeICmps.h"
 #include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
 #include "llvm/Transforms/Scalar/ScalarizeMaskedMemIntrin.h"
+#include "llvm/Transforms/Scalar/TLSVariableHoist.h"
+#include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h"
 #include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
+#include "llvm/Transforms/Utils/LowerGlobalDtors.h"
 #include "llvm/Transforms/Utils/LowerInvoke.h"
 #include <cassert>
 #include <type_traits>
@@ -133,6 +142,30 @@ template <typename DerivedT> class CodeGenPassBuilder {
                       raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
                       CodeGenFileType FileType) const;
 
+  bool parseTargetMIRPass(MachineFunctionPassManager &MFPM,
+                          StringRef Name) const {
+    llvm_unreachable("parseTargetMIRPass is not overridden");
+  }
+
+  /// Parse MIR pass pipeline. Unlike IR pass pipeline
+  /// there is only one pass manager for machine function
+  /// so there is no need to specify the pass nesting.
+  /// @param Text a comma separated pass name list
+  bool parseMIRPass(MachineFunctionPassManager &MFPM, StringRef Name) const;
+
+  Error parseMIRPipeline(MachineFunctionPassManager &MFPM,
+                         StringRef Text) const {
+    for (auto [LHS, RHS] = Text.split(','); LHS != "";
+         std::tie(LHS, RHS) = RHS.split(',')) {
+      if (parseMIRPass(MFPM, LHS) && derived().parseTargetMIRPass(MFPM, LHS)) {
+        return createStringError(
+            std::make_error_code(std::errc::invalid_argument),
+            Twine('\"') + Twine(LHS) + Twine("\" pass could not be found."));
+      }
+    }
+    return Error::success();
+  }
+
   void registerModuleAnalyses(ModuleAnalysisManager &) const;
   void registerFunctionAnalyses(FunctionAnalysisManager &) const;
   void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &) const;
@@ -145,7 +178,19 @@ template <typename DerivedT> class CodeGenPassBuilder {
   }
 
   PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
-    return PIC;
+    static PassInstrumentationCallbacks PseudoPIC;
+    return PIC ? PIC : &PseudoPIC;
+  }
+
+  /// Allow the target to enable a specific standard pass by default.
+  // TODO: implement it
+  template <typename PassT> void enablePass() {}
+
+  /// Allow the target to disable a specific standard pass by default.
+  template <typename PassT> void disablePass() {
+    DisabledPasses.insert(&PassT::Key);
+    getPassInstrumentationCallbacks()->registerShouldRunOptionalPassCallback(
+        [](StringRef P, Any IR) { return P != PassT::name(); });
   }
 
 protected:
@@ -206,7 +251,22 @@ template <typename DerivedT> class CodeGenPassBuilder {
   // Function object to maintain state while adding codegen machine passes.
   class AddMachinePass {
   public:
-    AddMachinePass(MachineFunctionPassManager &PM) : PM(PM) {}
+    AddMachinePass(const CodeGenPassBuilder &Builder,
+                   MachineFunctionPassManager &PM, bool AddPrePostHook = false)
+        : AddPrePostHook(AddPrePostHook), Builder(Builder), PM(PM) {
+      BeforeCallbacks.emplace_back([this](AnalysisKey *) {
+        if (this->AddPrePostHook)
+          this->Builder.addMachinePrePasses(this->PM);
+        return true;
+      });
+
+      AfterCallbacks.emplace_back([this](AnalysisKey *, StringRef Name) {
+        if (this->AddPrePostHook) {
+          std::string Banner = "After " + Name.str();
+          this->Builder.addMachinePostPasses(this->PM, Banner);
+        }
+      });
+    }
 
     template <typename PassT> void operator()(PassT &&Pass) {
       static_assert(
@@ -217,41 +277,62 @@ template <typename DerivedT> class CodeGenPassBuilder {
           return;
       PM.addPass(std::forward<PassT>(Pass));
       for (auto &C : AfterCallbacks)
-        C(&PassT::Key);
+        C(&PassT::Key, PassT::name());
     }
 
     template <typename PassT> void insertPass(AnalysisKey *ID, PassT Pass) {
       AfterCallbacks.emplace_back(
-          [this, ID, Pass = std::move(Pass)](AnalysisKey *PassID) {
+          [this, ID, Pass = std::move(Pass)](AnalysisKey *PassID, StringRef) {
             if (PassID == ID)
               this->PM.addPass(std::move(Pass));
           });
     }
 
-    void disablePass(AnalysisKey *ID) {
-      BeforeCallbacks.emplace_back(
-          [ID](AnalysisKey *PassID) { return PassID != ID; });
-    }
-
     MachineFunctionPassManager releasePM() { return std::move(PM); }
 
+    bool AddPrePostHook;
+
   private:
+    const CodeGenPassBuilder &Builder;
     MachineFunctionPassManager &PM;
     SmallVector<llvm::unique_function<bool(AnalysisKey *)>, 4> BeforeCallbacks;
-    SmallVector<llvm::unique_function<void(AnalysisKey *)>, 4> AfterCallbacks;
+    SmallVector<llvm::unique_function<void(AnalysisKey *, StringRef)>, 4>
+        AfterCallbacks;
   };
 
+  // Find the FSProfile file name. The internal option takes the precedence
+  // before getting from TargetMachine.
+  std::string getFSProfileFile() const {
+    if (!Opt.FSProfileFile.empty())
+      return Opt.FSProfileFile;
+    const std::optional<PGOOptions> &PGOOpt = TM.getPGOOption();
+    if (PGOOpt == std::nullopt || PGOOpt->Action != PGOOptions::SampleUse)
+      return std::string();
+    return PGOOpt->ProfileFile;
+  }
+
+  // Find the Profile remapping file name. The internal option takes the
+  // precedence before getting from TargetMachine.
+  std::string getFSRemappingFile() const {
+    if (!Opt.FSRemappingFile.empty())
+      return Opt.FSRemappingFile;
+    const std::optional<PGOOptions> &PGOOpt = TM.getPGOOption();
+    if (PGOOpt == std::nullopt || PGOOpt->Action != PGOOptions::SampleUse)
+      return std::string();
+    return PGOOpt->ProfileRemappingFile;
+  }
+
+  DenseSet<AnalysisKey *> DisabledPasses;
   LLVMTargetMachine &TM;
   CGPassBuilderOption Opt;
   PassInstrumentationCallbacks *PIC;
+  mutable bool DebugifyIsSafe = true;
+  mutable bool AddGCInfoPrinter = false;
 
   /// Target override these hooks to parse target-specific analyses.
   void registerTargetAnalysis(ModuleAnalysisManager &) const {}
   void registerTargetAnalysis(FunctionAnalysisManager &) const {}
   void registerTargetAnalysis(MachineFunctionAnalysisManager &) const {}
-  std::pair<StringRef, bool> getTargetPassNameFromLegacyName(StringRef) const {
-    return {"", false};
-  }
 
   template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
   CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
@@ -319,6 +400,10 @@ template <typename DerivedT> class CodeGenPassBuilder {
   /// immediately before machine code is emitted.
   void addPreEmitPass(AddMachinePass &) const {}
 
+  /// This pass may be implemented by targets that want to run passes
+  /// immediately after basic block sections are assigned.
+  void addPostBBSections(AddMachinePass &) const {}
+
   /// Targets may add passes immediately before machine code is emitted in this
   /// callback. This is called even later than `addPreEmitPass`.
   // FIXME: Rename `addPreEmitPass` to something more sensible given its actual
@@ -394,6 +479,15 @@ template <typename DerivedT> class CodeGenPassBuilder {
   /// Fully developed targets will not generally override this.
   Error addMachinePasses(AddMachinePass &) const;
 
+  /// Add single pass to pass manager from `llc -passes=` option
+  template <typename PassT>
+  void addMachinePass(MachineFunctionPassManager &MFPM, PassT &&Pass) const {
+    addMachinePrePasses(MFPM);
+    std::string Banner = "After " + PassT::name().str();
+    MFPM.addPass(std::forward<PassT>(Pass));
+    addMachinePostPasses(MFPM, Banner);
+  }
+
   /// Add passes to lower exception handling for the code generator.
   void addPassesToHandleExceptions(AddIRPass &) const;
 
@@ -424,6 +518,14 @@ template <typename DerivedT> class CodeGenPassBuilder {
   /// are required for fast register allocation.
   Error addFastRegAlloc(AddMachinePass &) const;
 
+  /// addPostFastRegAllocRewrite - Add passes to the optimized register
+  /// allocation pipeline after fast register allocation is complete.
+  Error addPostFastRegAllocRewrite(AddMachinePass &) const {
+    return make_error<StringError>(
+        "addPostFastRegAllocRewrite is not overridden",
+        inconvertibleErrorCode());
+  }
+
   /// addOptimizedRegAlloc - Add passes related to register allocation.
   /// LLVMTargetMachine provides standard regalloc passes for most targets.
   void addOptimizedRegAlloc(AddMachinePass &) const;
@@ -431,14 +533,63 @@ template <typename DerivedT> class CodeGenPassBuilder {
   /// Add passes that optimize machine instructions after register allocation.
   void addMachineLateOptimization(AddMachinePass &) const;
 
-  /// addGCPasses - Add late codegen passes that analyze code for garbage
+  /// registerGCPasses - Add late codegen passes that analyze code for garbage
   /// collection. This should return true if GC info should be printed after
   /// these passes.
-  void addGCPasses(AddMachinePass &) const {}
+  bool registerGCPasses(MachineFunctionAnalysisManager &MFAM) const {
+    MFAM.registerPass([] { return GCMachineCodeAnalysisPass(); });
+    return true;
+  }
 
   /// Add standard basic block placement passes.
   void addBlockPlacement(AddMachinePass &) const;
 
+  /// Add a pass to print the machine function if printing is enabled.
+  void addPrintPass(AddMachinePass &addPass, const std::string &Banner) const {
+    if (Opt.PrintAfterISel)
+      addPass(MachineFunctionPrinterPass(dbgs(), Banner));
+  }
+
+  /// Add a pass to perform basic verification of the machine function if
+  /// verification is enabled.
+  void addVerifyPass(MachineFunctionPassManager &MFPM,
+                     const std::string &Banner) const {
+    bool Verify = Opt.VerifyMachineCode.value_or(true);
+#ifdef EXPENSIVE_CHECKS
+    if (!Opt.VerifyMachineCode)
+      Verify = TM->isMachineVerifierClean();
+#endif
+    if (Verify)
+      MFPM.addPass(MachineVerifierPass(Banner));
+  }
+
+  void addVerifyPass(AddMachinePass &addPass, const std::string &Banner) const {
+    bool Verify = Opt.VerifyMachineCode.value_or(true);
+#ifdef EXPENSIVE_CHECKS
+    if (!Opt.VerifyMachineCode)
+      Verify = TM->isMachineVerifierClean();
+#endif
+    if (Verify)
+      addPass(MachineVerifierPass(Banner));
+  }
+
+  /// printAndVerify - Add a pass to dump then verify the machine function, if
+  /// those steps are enabled.
+  void printAndVerify(AddMachinePass &addPass,
+                      const std::string &Banner) const {
+    addPrintPass(addPass, Banner);
+    addVerifyPass(addPass, Banner);
+  }
+
+  /// Add standard passes before a pass that's about to be added. For example,
+  /// the DebugifyMachineModulePass if it is enabled.
+  void addMachinePrePasses(MachineFunctionPassManager &MFPM) const;
+
+  /// Add standard passes after a pass that has just been added. For example,
+  /// the MachineVerifier if it is enabled.
+  void addMachinePostPasses(MachineFunctionPassManager &addPass,
+                            const std::string &Banner) const;
+
   using CreateMCStreamer =
       std::function<Expected<std::unique_ptr<MCStreamer>>(MCContext &)>;
   void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const {
@@ -456,10 +607,10 @@ template <typename DerivedT> class CodeGenPassBuilder {
   /// regalloc pass.
   void addRegAllocPass(AddMachinePass &, bool Optimized) const;
 
-  /// Add core register alloator passes which do the actual register assignment
-  /// and rewriting. \returns true if any passes were added.
-  Error addRegAssignmentFast(AddMachinePass &) const;
-  Error addRegAssignmentOptimized(AddMachinePass &) const;
+  /// Add core register allocator passes which do the actual register assignment
+  /// and rewriting. \returns Error::success() if any passes were added.
+  Error addRegAssignAndRewriteFast(AddMachinePass &addPass) const;
+  Error addRegAssignAndRewriteOptimized(AddMachinePass &addPass) const;
 
 private:
   DerivedT &derived() { return static_cast<DerivedT &>(*this); }
@@ -476,12 +627,14 @@ Error CodeGenPassBuilder<Derived>::buildPipeline(
   AddIRPass addIRPass(MPM, Opt.DebugPM);
   addISelPasses(addIRPass);
 
-  AddMachinePass addPass(MFPM);
+  AddMachinePass addPass(*this, MFPM);
   if (auto Err = addCoreISelPasses(addPass))
     return std::move(Err);
 
+  addPass.AddPrePostHook = true;
   if (auto Err = derived().addMachinePasses(addPass))
     return std::move(Err);
+  addPass.AddPrePostHook = false;
 
   derived().addAsmPrinter(
       addPass, [this, &Out, DwoOut, FileType](MCContext &Ctx) {
@@ -514,18 +667,21 @@ void CodeGenPassBuilder<Derived>::registerModuleAnalyses(
     ModuleAnalysisManager &MAM) const {
 #define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)                          \
   MAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });
-#include "MachinePassRegistry.def"
+#include "llvm/CodeGen/MachinePassRegistry.def"
   derived().registerTargetAnalysis(MAM);
+  if (Opt.RequiresCodeGenSCCOrder)
+    MAM.registerPass([&] { return CallGraphAnalysis(); });
 }
 
 template <typename Derived>
 void CodeGenPassBuilder<Derived>::registerFunctionAnalyses(
     FunctionAnalysisManager &FAM) const {
-  FAM.registerPass([this] { return registerAAAnalyses(); });
+  if (getOptLevel() != CodeGenOptLevel::None)
+    FAM.registerPass([this] { return registerAAAnalyses(); });
 
 #define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)                        \
   FAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });
-#include "MachinePassRegistry.def"
+#include "llvm/CodeGen/MachinePassRegistry.def"
   derived().registerTargetAnalysis(FAM);
 }
 
@@ -534,7 +690,9 @@ void CodeGenPassBuilder<Derived>::registerMachineFunctionAnalyses(
     MachineFunctionAnalysisManager &MFAM) const {
 #define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)                \
   MFAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });
-#include "MachinePassRegistry.def"
+#include "llvm/CodeGen/MachinePassRegistry.def"
+
+  AddGCInfoPrinter = derived().registerGCPasses(MFAM) && Opt.PrintGCInfo;
   derived().registerTargetAnalysis(MFAM);
 }
 
@@ -585,12 +743,47 @@ CodeGenPassBuilder<Derived>::getPassNameFromLegacyName(StringRef Name) const {
   return Ret;
 }
 
+template <typename DerivedT>
+bool llvm::CodeGenPassBuilder<DerivedT>::parseMIRPass(
+    MachineFunctionPassManager &MFPM, StringRef Name) const {
+#define ADD_PASS(NAME, PASS_NAME, CONSTRUCTOR)                                 \
+  if (Name == NAME) {                                                          \
+    {                                                                          \
+      addMachinePass(MFPM, PASS_NAME CONSTRUCTOR);                             \
+    }                                                                          \
+    return false;                                                              \
+  }
+#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                      \
+  ADD_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)                    \
+  ADD_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                \
+  if (Name == NAME) {                                                          \
+    {                                                                          \
+      addMachinePass(MFPM, PASS_NAME());                                       \
+    }                                                                          \
+    return false;                                                              \
+  }
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \
+  if (Name == NAME) {                                                          \
+    {                                                                          \
+      addMachinePass(MFPM, PASS_NAME());                                       \
+    }                                                                          \
+    return false;                                                              \
+  }
+#include "llvm/CodeGen/MachinePassRegistry.def"
+#undef ADD_PASS
+  return true;
+}
+
 template <typename Derived>
 void CodeGenPassBuilder<Derived>::addISelPasses(AddIRPass &addPass) const {
   if (TM.useEmulatedTLS())
     addPass(LowerEmuTLSPass());
 
   addPass(PreISelIntrinsicLoweringPass(TM));
+  addPass(createModuleToFunctionPassAdaptor(ExpandLargeDivRemPass(&TM)));
+  addPass(createModuleToFunctionPassAdaptor(ExpandLargeFpConvertPass(&TM)));
 
   derived().addIRPasses(addPass);
   derived().addCodeGenPrepare(addPass);
@@ -607,16 +800,18 @@ void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
   if (!Opt.DisableVerify)
     addPass(VerifierPass());
 
-  // Run loop strength reduction before anything else.
-  if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableLSR) {
-    addPass(createFunctionToLoopPassAdaptor(
-        LoopStrengthReducePass(), /*UseMemorySSA*/ true, Opt.DebugPM));
-    // FIXME: use -stop-after so we could remove PrintLSR
-    if (Opt.PrintLSR)
-      addPass(PrintFunctionPass(dbgs(), "\n\n*** Code after LSR ***\n"));
-  }
-
   if (getOptLevel() != CodeGenOptLevel::None) {
+    // Run loop strength reduction before anything else.
+    if (!Opt.DisableLSR) {
+      addPass(createFunctionToLoopPassAdaptor(
+          CanonicalizeFreezeInLoopsPass(), /*UseMemorySSA*/ true, Opt.DebugPM));
+      addPass(createFunctionToLoopPassAdaptor(
+          LoopStrengthReducePass(), /*UseMemorySSA*/ true, Opt.DebugPM));
+      // FIXME: use -stop-after so we could remove PrintLSR
+      if (Opt.PrintLSR)
+        addPass(PrintFunctionPass(dbgs(), "\n\n*** Code after LSR ***\n"));
+    }
+
     // The MergeICmpsPass tries to create memcmp calls by grouping sequences of
     // loads and compares. ExpandMemCmpPass then tries to expand those calls
     // into optimally-sized loads and compares. The transforms are enabled by a
@@ -632,6 +827,15 @@ void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
   addPass(ShadowStackGCLoweringPass());
   addPass(LowerConstantIntrinsicsPass());
 
+  if (AddGCInfoPrinter)
+    addPass(GCInfoPrinterPass(dbgs()));
+
+  // For MachO, lower @llvm.global_dtors into @llvm.global_ctors with
+  // __cxa_atexit() calls to avoid emitting the deprecated __mod_term_func.
+  if (TM.getTargetTriple().isOSBinFormatMachO() &&
+      !Opt.DisableAtExitBasedGlobalDtorLowering)
+    addPass(LowerGlobalDtorsPass());
+
   // Make sure that no unreachable blocks are instruction selected.
   addPass(UnreachableBlockElimPass());
 
@@ -648,8 +852,10 @@ void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
       !Opt.DisablePartialLibcallInlining)
     addPass(PartiallyInlineLibCallsPass());
 
-  // Instrument function entry and exit, e.g. with calls to mcount().
-  addPass(EntryExitInstrumenterPass(/*PostInlining=*/true));
+  // Expand vector predication intrinsics into standard IR instructions.
+  // This pass has to run before ScalarizeMaskedMemIntrin and ExpandReduction
+  // passes since it emits those kinds of intrinsics.
+  addPass(ExpandVectorPredicationPass());
 
   // Add scalarization of target's unsupported masked memory intrinsics pass.
   // the unsupported intrinsic will be replaced with a chain of basic blocks,
@@ -657,7 +863,12 @@ void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
   addPass(ScalarizeMaskedMemIntrinPass());
 
   // Expand reduction intrinsics into shuffle sequences if the target wants to.
-  addPass(ExpandReductionsPass());
+  // Allow disabling it for testing purposes.
+  if (!Opt.DisableExpandReductions)
+    addPass(ExpandReductionsPass());
+
+  if (getOptLevel() != CodeGenOptLevel::None)
+    addPass(TLSVariableHoistPass());
 
   // Convert conditional moves to conditional jumps when profitable.
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableSelectOptimize)
@@ -716,8 +927,6 @@ template <typename Derived>
 void CodeGenPassBuilder<Derived>::addCodeGenPrepare(AddIRPass &addPass) const {
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableCGP)
     addPass(CodeGenPreparePass());
-  // TODO: Default ctor'd RewriteSymbolPass is no-op.
-  // addPass(RewriteSymbolPass());
 }
 
 /// Add common passes that perform LLVM IR to IR transforms in preparation for
@@ -727,6 +936,7 @@ void CodeGenPassBuilder<Derived>::addISelPrepare(AddIRPass &addPass) const {
   derived().addPreISel(addPass);
 
   addPass(CallBrPrepare());
+
   // Add both the safe stack and the stack protection passes: each of them will
   // only protect functions that have corresponding attributes.
   addPass(SafeStackPass());
@@ -765,6 +975,19 @@ Error CodeGenPassBuilder<Derived>::addCoreISelPasses(
   else
     Selector = SelectorType::SelectionDAG;
 
+  // FIXME: Injecting into the DAGISel pipeline seems to cause issues with
+  //        analyses needing to be re-run. This can result in being unable to
+  //        schedule passes (particularly with 'Function Alias Analysis
+  //        Results'). It's not entirely clear why but AFAICT this seems to be
+  //        due to one FunctionPassManager not being able to use analyses from a
+  //        previous one. As we're injecting a ModulePass we break the usual
+  //        pass manager into two. GlobalISel with the fallback path disabled
+  //        and -run-pass seem to be unaffected. The majority of GlobalISel
+  //        testing uses -run-pass so this probably isn't too bad.
+  SaveAndRestore SavedDebugifyIsSafe(DebugifyIsSafe);
+  if (Selector != SelectorType::GlobalISel || !isGlobalISelAbortEnabled())
+    DebugifyIsSafe = false;
+
   // Set consistently TM.Options.EnableFastISel and EnableGlobalISel.
   if (Selector == SelectorType::FastISel) {
     TM.setFastISel(true);
@@ -776,6 +999,7 @@ Error CodeGenPassBuilder<Derived>::addCoreISelPasses(
 
   // Add instruction selector passes.
   if (Selector == SelectorType::GlobalISel) {
+    SaveAndRestore SavedAddingMachinePasses(addPass.AddPrePostHook, true);
     if (auto Err = derived().addIRTranslator(addPass))
       return std::move(Err);
 
@@ -814,8 +1038,7 @@ Error CodeGenPassBuilder<Derived>::addCoreISelPasses(
   addPass(FinalizeISelPass());
 
   // // Print the instruction selected machine code...
-  // printAndVerify("After Instruction Selection");
-
+  printAndVerify(addPass, "After Instruction Selection");
   return Error::success();
 }
 
@@ -852,9 +1075,28 @@ Error CodeGenPassBuilder<Derived>::addMachinePasses(
   // Run pre-ra passes.
   derived().addPreRegAlloc(addPass);
 
+  // Debugifying the register allocator passes seems to provoke some
+  // non-determinism that affects CodeGen and there doesn't seem to be a point
+  // where it becomes safe again so stop debugifying here.
+  DebugifyIsSafe = false;
+
+  // Add a FSDiscriminator pass right before RA, so that we could get
+  // more precise SampleFDO profile for RA.
+  if (EnableFSDiscriminator) {
+    addPass(MIRAddFSDiscriminatorsPass(sampleprof::FSDiscriminatorPass::Pass1));
+    const std::string ProfileFile = getFSProfileFile();
+    if (!ProfileFile.empty() && !Opt.DisableRAFSProfileLoader)
+      addPass(MIRProfileLoaderPass(ProfileFile, getFSRemappingFile(),
+                                   sampleprof::FSDiscriminatorPass::Pass1,
+                                   nullptr));
+  }
+
   // Run register allocation and passes that are tightly coupled with it,
   // including phi elimination and scheduling.
-  if (*Opt.OptimizeRegAlloc) {
+  bool IsOptimizeRegAlloc = Opt.OptimizeRegAlloc.has_value()
+                                ? *Opt.OptimizeRegAlloc
+                                : getOptLevel() != CodeGenOptLevel::None;
+  if (IsOptimizeRegAlloc) {
     derived().addOptimizedRegAlloc(addPass);
   } else {
     if (auto Err = derived().addFastRegAlloc(addPass))
@@ -866,13 +1108,20 @@ Error CodeGenPassBuilder<Derived>::addMachinePasses(
 
   addPass(RemoveRedundantDebugValuesPass());
 
-  // Insert prolog/epilog code.  Eliminate abstract frame index references...
+  addPass(FixupStatepointCallerSavedPass());
+
+  // Insert prolog/epilog code.  Eliminate abstract frame index
+  // references...
   if (getOptLevel() != CodeGenOptLevel::None) {
     addPass(PostRAMachineSinkingPass());
     addPass(ShrinkWrapPass());
   }
 
-  addPass(PrologEpilogInserterPass());
+  // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only
+  // do so if it hasn't been disabled, substituted, or overridden.
+
+  if (!DisabledPasses.contains(&PrologEpilogCodeInserterPass::Key))
+    addPass(PrologEpilogInserterPass());
 
   /// Add passes that optimize machine instructions after register allocation.
   if (getOptLevel() != CodeGenOptLevel::None)
@@ -898,9 +1147,6 @@ Error CodeGenPassBuilder<Derived>::addMachinePasses(
       addPass(PostRASchedulerPass());
   }
 
-  // GC
-  derived().addGCPasses(addPass);
-
   // Basic block placement.
   if (getOptLevel() != CodeGenOptLevel::None)
     derived().addBlockPlacement(addPass);
@@ -918,6 +1164,8 @@ Error CodeGenPassBuilder<Derived>::addMachinePasses(
     // clobbered registers, to be used to optimize call sites.
     addPass(RegUsageInfoCollectorPass());
 
+  // FIXME: Some backends are incompatible with running the verifier after
+  // addPreEmitPass.  Maybe only pass "false" here for those targets?
   addPass(FuncletLayoutPass());
 
   addPass(StackMapLivenessPass());
@@ -934,12 +1182,77 @@ Error CodeGenPassBuilder<Derived>::addMachinePasses(
       addPass(MachineOutlinerPass(RunOnAllFunctions));
   }
 
+  if (Opt.GCEmptyBlocks)
+    addPass(GCEmptyBasicBlocksPass());
+
+  if (EnableFSDiscriminator)
+    addPass(
+        MIRAddFSDiscriminatorsPass(sampleprof::FSDiscriminatorPass::PassLast));
+
+  // Machine function splitter uses the basic block sections feature. Both
+  // cannot be enabled at the same time. Basic block sections takes precedence.
+  // FIXME: In principle, BasicBlockSection::Labels and splitting can used
+  // together. Update this check once we have addressed any issues.
+  if (TM.getBBSectionsType() != llvm::BasicBlockSection::None) {
+    if (TM.getBBSectionsType() == llvm::BasicBlockSection::List) {
+      addPass(
+          BasicBlockSectionsProfileReaderPass(TM.getBBSectionsFuncListBuf()));
+    }
+    addPass(BasicBlockSectionsPass());
+  } else if (TM.Options.EnableMachineFunctionSplitter ||
+             Opt.EnableMachineFunctionSplitter) {
+    const std::string ProfileFile = getFSProfileFile();
+    if (!ProfileFile.empty()) {
+      if (EnableFSDiscriminator) {
+        addPass(MIRProfileLoaderPass(ProfileFile, getFSRemappingFile(),
+                                     sampleprof::FSDiscriminatorPass::PassLast,
+                                     nullptr));
+      } else {
+        // Sample profile is given, but FSDiscriminator is not
+        // enabled, this may result in performance regression.
+        WithColor::warning()
+            << "Using AutoFDO without FSDiscriminator for MFS may regress "
+               "performance.";
+      }
+    }
+    addPass(MachineFunctionSplitterPass());
+  }
+
+  derived().addPostBBSections(addPass);
+
+  if (!Opt.DisableCFIFixup && TM.Options.EnableCFIFixup)
+    addPass(CFIFixupPass());
+
+  addPass(StackFrameLayoutAnalysisPass());
+
   // Add passes that directly emit MI after all other MI passes.
   derived().addPreEmitPass2(addPass);
 
   return Error::success();
 }
 
+template <typename DerivedT>
+void CodeGenPassBuilder<DerivedT>::addMachinePrePasses(
+    MachineFunctionPassManager &MFPM) const {
+  if (DebugifyIsSafe &&
+      ((Opt.DebugifyAndStripAll && *Opt.DebugifyAndStripAll) ||
+       (Opt.DebugifyCheckAndStripAll && *Opt.DebugifyCheckAndStripAll)))
+    MFPM.addPass(DebugifyMachineModule());
+}
+
+template <typename DerivedT>
+void llvm::CodeGenPassBuilder<DerivedT>::addMachinePostPasses(
+    MachineFunctionPassManager &MFPM, const std::string &Banner) const {
+  if (DebugifyIsSafe) {
+    if (Opt.DebugifyCheckAndStripAll && *Opt.DebugifyCheckAndStripAll) {
+      MFPM.addPass(CheckDebugMachineModulePass());
+      MFPM.addPass(StripDebugMachineModulePass(/*OnlyDebugified=*/true));
+    } else if (Opt.DebugifyAndStripAll && *Opt.DebugifyAndStripAll)
+      MFPM.addPass(StripDebugMachineModulePass(/*OnlyDebugified=*/true));
+  }
+  addVerifyPass(MFPM, Banner);
+}
+
 /// Add passes that optimize machine instructions in SSA form.
 template <typename Derived>
 void CodeGenPassBuilder<Derived>::addMachineSSAOptimization(
@@ -1024,7 +1337,7 @@ void CodeGenPassBuilder<Derived>::addRegAllocPass(AddMachinePass &addPass,
 }
 
 template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addRegAssignmentFast(
+Error CodeGenPassBuilder<Derived>::addRegAssignAndRewriteFast(
     AddMachinePass &addPass) const {
   if (Opt.RegAlloc != RegAllocType::Default &&
       Opt.RegAlloc != RegAllocType::Fast)
@@ -1032,26 +1345,27 @@ Error CodeGenPassBuilder<Derived>::addRegAssignmentFast(
         "Must use fast (default) register allocator for unoptimized regalloc.",
         inconvertibleErrorCode());
 
-  addRegAllocPass(addPass, false);
-  return Error::success();
+  addPass(RegAllocPass(false));
+
+  // Allow targets to change the register assignments after
+  // fast register allocation.
+  return derived().addPostFastRegAllocRewrite(addPass);
 }
 
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addRegAssignmentOptimized(
+template <typename DerivedT>
+Error llvm::CodeGenPassBuilder<DerivedT>::addRegAssignAndRewriteOptimized(
     AddMachinePass &addPass) const {
   // Add the selected register allocation pass.
   addRegAllocPass(addPass, true);
-
   // Allow targets to change the register assignments before rewriting.
-  derived().addPreRewrite(addPass);
+  addPreRewrite(addPass);
 
   // Finally rewrite virtual registers.
   addPass(VirtRegRewriterPass());
-  // Perform stack slot coloring and post-ra machine LICM.
-  //
-  // FIXME: Re-enable coloring with register when it's capable of adding
-  // kill markers.
-  addPass(StackSlotColoringPass());
+
+  // Regalloc scoring for ML-driven eviction - noop except when learning a new
+  // eviction policy.
+  addPass(RegAllocScoringPass());
 
   return Error::success();
 }
@@ -1063,7 +1377,7 @@ Error CodeGenPassBuilder<Derived>::addFastRegAlloc(
     AddMachinePass &addPass) const {
   addPass(PHIEliminationPass());
   addPass(TwoAddressInstructionPass());
-  return derived().addRegAssignmentFast(addPass);
+  return derived().addRegAssignAndRewriteFast(addPass);
 }
 
 /// Add standard target-independent passes that are tightly coupled with
@@ -1094,7 +1408,8 @@ void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
   // PreRA instruction scheduling.
   addPass(MachineSchedulerPass());
 
-  if (derived().addRegAssignmentOptimized(addPass)) {
+  Error Err = derived().addRegAssignAndRewriteOptimized(addPass);
+  if (!Err) {
     // Allow targets to expand pseudo instructions depending on the choice of
     // registers before MachineCopyPropagation.
     derived().addPostRewrite(addPass);
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index c1d05b25ea21f8a..e28a5c00f7c9a6d 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -14,6 +14,7 @@
 #define LLVM_TARGET_TARGETMACHINE_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/Support/Allocator.h"
@@ -450,19 +451,26 @@ class LLVMTargetMachine : public TargetMachine {
                       bool DisableVerify = true,
                       MachineModuleInfoWrapperPass *MMIWP = nullptr) override;
 
-  virtual Error buildCodeGenPipeline(ModulePassManager &,
-                                     MachineFunctionPassManager &,
-                                     MachineFunctionAnalysisManager &,
+  virtual Error buildCodeGenPipeline(ModulePassManager &MPM,
+                                     MachineFunctionPassManager &MFPM,
                                      raw_pwrite_stream &, raw_pwrite_stream *,
                                      CodeGenFileType, CGPassBuilderOption,
+                                     MachineFunctionAnalysisManager &,
                                      PassInstrumentationCallbacks *) {
     return make_error<StringError>("buildCodeGenPipeline is not overridden",
                                    inconvertibleErrorCode());
   }
 
   virtual std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) {
-    llvm_unreachable(
-        "getPassNameFromLegacyName parseMIRPipeline is not overridden");
+    llvm_unreachable("getPassNameFromLegacyName is not overridden");
+  }
+
+  virtual Error parseMIRPipeline(MachineFunctionPassManager &MFPM,
+                                 StringRef PipelineText,
+                                 CGPassBuilderOption Opts,
+                                 MachineFunctionAnalysisManager &MFAM,
+                                 PassInstrumentationCallbacks *PIC) {
+    llvm_unreachable("parseMIRPipeline is not overridden");
   }
 
   /// Add passes to the specified pass manager to get machine code emitted with

>From b51721635334f847f769836f9ed2b23d2afc63ae Mon Sep 17 00:00:00 2001
From: Yuanfang Chen <455423+yuanfang-chen at users.noreply.github.com>
Date: Wed, 1 Nov 2023 10:44:15 +0800
Subject: [PATCH 5/8] [X86][CodeGen] Add NPM pipeline builder

---
 llvm/lib/Target/X86/CMakeLists.txt       |   2 +
 llvm/lib/Target/X86/X86PassRegistry.def  |  76 +++++
 llvm/lib/Target/X86/X86TargetMachine.cpp | 345 +++++++++++++++++++++++
 llvm/lib/Target/X86/X86TargetMachine.h   |  13 +
 4 files changed, 436 insertions(+)
 create mode 100644 llvm/lib/Target/X86/X86PassRegistry.def

diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 0b7a98ad6341dde..ef54ca3e435c54e 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -99,8 +99,10 @@ add_llvm_target(X86CodeGen ${sources}
   Core
   GlobalISel
   Instrumentation
+  IRPrinter
   MC
   ProfileData
+  ScalarOpts
   SelectionDAG
   Support
   Target
diff --git a/llvm/lib/Target/X86/X86PassRegistry.def b/llvm/lib/Target/X86/X86PassRegistry.def
new file mode 100644
index 000000000000000..3b1fc88dcc166da
--- /dev/null
+++ b/llvm/lib/Target/X86/X86PassRegistry.def
@@ -0,0 +1,76 @@
+//===- X86PassRegistry.def - Registry of passes for X86 ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// X86 pass registry
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+#ifndef FUNCTION_PASS
+#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+
+#undef FUNCTION_PASS
+
+#ifndef DUMMY_FUNCTION_PASS
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+DUMMY_FUNCTION_PASS("x86-win-eh-state", X86WinEHStatePass, ())
+#undef DUMMY_FUNCTION_PASS
+
+#ifndef MACHINE_FUNCTION_PASS
+#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+
+#undef MACHINE_FUNCTION_PASS
+
+// PASS_NAME is for mocking machine passes, remove it after all machine passes
+// are added new pass manager interface.
+#ifndef DUMMY_MACHINE_FUNCTION_PASS
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+DUMMY_MACHINE_FUNCTION_PASS("x86-isel-dag", X86ISelDagPass, (getTM<X86TargetMachine>(), getOptLevel()))
+DUMMY_MACHINE_FUNCTION_PASS("x86-global-basereg", X86GlobalBaseRegPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-cmov-converter", X86CmovConverterDummyPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-fixup-setcc", X86FixupSetCCPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-opt-leas", X86OptimizeLEAsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-callframe-opt", X86CallFrameOptimizationPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-avoid-store-foword-block", X86AvoidStoreForwardingBlocksPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-speculative-load-hardening", X86SpeculativeLoadHardeningPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-flags-copy-lowering", X86FlagsCopyLoweringDummyPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-domain-reassign", X86DomainReassignmentPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-fp-stackifier", X86FloatingPointStackifierPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-expand-pseudo", X86ExpandPseudoPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-exec-domain-fix", X86ExecutionDomainFixPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-indirectbr-tracking", X86IndirectBranchTrackingPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-issue-vzero-upper", X86IssueVZeroUpperPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-fixup-bwinsts", X86FixupBWInstsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-pad-short-funcs", X86PadShortFunctionsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-fixup-leas", X86FixupLEAsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-evex-to-vex-insts", X86EvexToVexInstsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-discriminate-memops", X86DiscriminateMemOpsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-insert-prefetch", X86InsertPrefetchPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-insert-x87-wait", X86InsertX87waitPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-avoid-trailing-call", X86AvoidTrailingCallPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-asm-printer", X86AsmPrinterPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("cleanup-local-dyn-tls", CleanupLocalDynamicTLSPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-fixup-inst-tuning", X86FixupInstTuningPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-fixup-vector-constants", X86FixupVectorConstantsPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("ehcontguard-catchret", EHContGuardCatchretPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-lvi-ret", X86LoadValueInjectionRetHardeningPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-lower-tile-copy", X86LowerTileCopyPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-seses", X86SpeculativeExecutionSideEffectSuppressionPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-retpoline-thunks", X86IndirectThunksPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-return-thunks", X86ReturnThunksPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("tileconfig", X86TileConfigPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("tile-pre-config", X86PreTileConfigPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("fastpretileconfig", X86FastPreTileConfigPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("fasttileconfig", X86FastTileConfigPass, ())
+DUMMY_MACHINE_FUNCTION_PASS("x86-dyn-alloca-expander", X86DynAllocaExpanderPass, ())
+#undef DUMMY_MACHINE_FUNCTION_PASS
\ No newline at end of file
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 5668b514d6dec07..60d36a43a6f2318 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -23,6 +23,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/CodeGenPassBuilder.h"
 #include "llvm/CodeGen/ExecutionDomainFix.h"
 #include "llvm/CodeGen/GlobalISel/CSEInfo.h"
 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
@@ -39,6 +40,7 @@
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Function.h"
 #include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CodeGen.h"
@@ -659,3 +661,346 @@ bool X86PassConfig::addRegAssignAndRewriteOptimized() {
   }
   return TargetPassConfig::addRegAssignAndRewriteOptimized();
 }
+
+namespace {
+
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)                      \
+  struct PASS_NAME : public PassInfoMixin<PASS_NAME> {                         \
+    template <typename... Ts> PASS_NAME(Ts &&...) {}                           \
+    PreservedAnalyses run(Function &, FunctionAnalysisManager &) {             \
+      return PreservedAnalyses::all();                                         \
+    }                                                                          \
+  };
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \
+  struct PASS_NAME : public PassInfoMixin<PASS_NAME> {                         \
+    template <typename... Ts> PASS_NAME(Ts &&...) {}                           \
+    PreservedAnalyses run(MachineFunction &,                                   \
+                          MachineFunctionAnalysisManager &) {                  \
+      return PreservedAnalyses::all();                                         \
+    }                                                                          \
+    static AnalysisKey Key;                                                    \
+  };                                                                           \
+  AnalysisKey PASS_NAME::Key;
+#include "X86PassRegistry.def"
+
+/// X86 Code Generator Pass Configuration Options.
+struct X86CodeGenPassBuilder
+    : public CodeGenPassBuilder<X86CodeGenPassBuilder> {
+  X86CodeGenPassBuilder(X86TargetMachine &TM,
+                        CGPassBuilderOption Opt = CGPassBuilderOption(),
+                        PassInstrumentationCallbacks *PIC = nullptr)
+      : CodeGenPassBuilder<X86CodeGenPassBuilder>(TM, Opt, PIC) {
+    // Target-specific `CGPassBuilderOption` could be overridden here.
+  }
+
+  std::pair<StringRef, bool> getTargetPassNameFromLegacyName(StringRef) const;
+
+  bool parseTargetMIRPass(MachineFunctionPassManager &MFPM,
+                          StringRef Text) const;
+  void addIRPasses(AddIRPass &) const;
+  void addPreISel(AddIRPass &) const;
+  Error addInstSelector(AddMachinePass &) const;
+  Error addIRTranslator(AddMachinePass &) const;
+  Error addLegalizeMachineIR(AddMachinePass &) const;
+  Error addRegBankSelect(AddMachinePass &) const;
+  Error addGlobalInstructionSelect(AddMachinePass &) const;
+  void addILPOpts(AddMachinePass &) const;
+  void addMachineSSAOptimization(AddMachinePass &) const;
+  void addPreRegAlloc(AddMachinePass &) const;
+  Error addPostFastRegAllocRewrite(AddMachinePass &) const;
+  void addPostRegAlloc(AddMachinePass &) const;
+  void addPreEmitPass(AddMachinePass &) const;
+  void addPreEmitPass2(AddMachinePass &) const;
+  void addPreSched2(AddMachinePass &) const;
+  Error addRegAssignAndRewriteOptimized(AddMachinePass &) const;
+  void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
+};
+
+} // namespace
+
+void X86CodeGenPassBuilder::addIRPasses(AddIRPass &addPass) const {
+  addPass(AtomicExpandPass());
+
+  CodeGenPassBuilder::addIRPasses(addPass);
+
+  if (TM.getOptLevel() != CodeGenOptLevel::None)
+    addPass(InterleavedAccessPass());
+
+  // Add passes that handle indirect branch removal and insertion of a retpoline
+  // thunk. These will be a no-op unless a function subtarget has the retpoline
+  // feature enabled.
+  addPass(IndirectBrExpandPass());
+
+  // Add Control Flow Guard checks.
+  const Triple &TT = TM.getTargetTriple();
+  if (TT.isOSWindows()) {
+    if (TT.getArch() == Triple::x86_64)
+      addPass(CFGuardDispatchPass());
+    else
+      addPass(CFGuardCheckPass());
+  }
+}
+
+Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &addPass) const {
+  // Install an instruction selector.
+  addPass(X86ISelDagPass(getTM<X86TargetMachine>(), getOptLevel()));
+
+  // For ELF, cleanup any local-dynamic TLS accesses.
+  if (TM.getTargetTriple().isOSBinFormatELF() &&
+      TM.getOptLevel() != CodeGenOptLevel::None)
+    addPass(CleanupLocalDynamicTLSPass());
+
+  addPass(X86GlobalBaseRegPass());
+  return Error::success();
+}
+
+Error X86CodeGenPassBuilder::addIRTranslator(AddMachinePass &addPass) const {
+  addPass(IRTranslatorPass());
+  return Error::success();
+}
+
+Error X86CodeGenPassBuilder::addLegalizeMachineIR(
+    AddMachinePass &addPass) const {
+  addPass(LegalizerPass());
+  return Error::success();
+}
+
+Error X86CodeGenPassBuilder::addRegBankSelect(AddMachinePass &addPass) const {
+  addPass(RegBankSelectPass());
+  return Error::success();
+}
+
+Error X86CodeGenPassBuilder::addGlobalInstructionSelect(
+    AddMachinePass &addPass) const {
+  addPass(InstructionSelectPass());
+  return Error::success();
+}
+
+void X86CodeGenPassBuilder::addILPOpts(AddMachinePass &addPass) const {
+  addPass(EarlyIfConverterPass());
+  if (EnableMachineCombinerPass)
+    addPass(MachineCombinerPass());
+  addPass(X86CmovConverterDummyPass());
+}
+
+void X86CodeGenPassBuilder::addPreISel(AddIRPass &addPass) const {
+  // Only add this pass for 32-bit x86 Windows.
+  const Triple &TT = TM.getTargetTriple();
+  if (TT.isOSWindows() && TT.getArch() == Triple::x86)
+    addPass(X86WinEHStatePass());
+}
+
+void X86CodeGenPassBuilder::addPreRegAlloc(AddMachinePass &addPass) const {
+  if (TM.getOptLevel() != CodeGenOptLevel::None) {
+    addPass(LiveRangeShrinkPass());
+    addPass(X86FixupSetCCPass());
+    addPass(X86OptimizeLEAsPass());
+    addPass(X86CallFrameOptimizationPass());
+    addPass(X86AvoidStoreForwardingBlocksPass());
+  }
+
+  addPass(X86SpeculativeLoadHardeningPass());
+  addPass(X86FlagsCopyLoweringDummyPass()); // TODO: port to NPM and rename
+  addPass(X86DynAllocaExpanderPass());
+
+  if (getOptLevel() != CodeGenOptLevel::None)
+    addPass(X86PreTileConfigPass());
+  else
+    addPass(X86FastPreTileConfigPass());
+}
+
+Error X86CodeGenPassBuilder::addPostFastRegAllocRewrite(
+    AddMachinePass &addPass) const {
+  addPass(X86FastTileConfigPass());
+  return Error::success();
+}
+
+void X86CodeGenPassBuilder::addMachineSSAOptimization(
+    AddMachinePass &addPass) const {
+  addPass(X86DomainReassignmentPass());
+  CodeGenPassBuilder::addMachineSSAOptimization(addPass);
+}
+
+void X86CodeGenPassBuilder::addPostRegAlloc(AddMachinePass &addPass) const {
+  addPass(X86LowerTileCopyPass());
+  addPass(X86FloatingPointStackifierPass());
+  // When -O0 is enabled, the Load Value Injection Hardening pass will fall back
+  // to using the Speculative Execution Side Effect Suppression pass for
+  // mitigation. This is to prevent slow downs due to
+  // analyses needed by the LVIHardening pass when compiling at -O0.
+  if (getOptLevel() != CodeGenOptLevel::None)
+    addPass(X86LoadValueInjectionRetHardeningPass());
+}
+
+void X86CodeGenPassBuilder::addPreSched2(AddMachinePass &addPass) const {
+  addPass(X86ExpandPseudoPass());
+  addPass(KCFIPass());
+}
+
+void X86CodeGenPassBuilder::addPreEmitPass(AddMachinePass &addPass) const {
+  if (getOptLevel() != CodeGenOptLevel::None) {
+    addPass(X86ExecutionDomainFixPass());
+    addPass(BreakFalseDepsPass());
+  }
+
+  addPass(X86IndirectBranchTrackingPass());
+
+  addPass(X86IssueVZeroUpperPass());
+
+  if (getOptLevel() != CodeGenOptLevel::None) {
+    addPass(X86FixupBWInstsPass());
+    addPass(X86PadShortFunctionsPass());
+    addPass(X86FixupLEAsPass());
+    addPass(X86FixupInstTuningPass());
+    addPass(X86FixupVectorConstantsPass());
+  }
+  addPass(X86EvexToVexInstsPass());
+  addPass(X86DiscriminateMemOpsPass());
+  addPass(X86InsertPrefetchPass());
+  addPass(X86InsertX87waitPass());
+}
+
+void X86CodeGenPassBuilder::addPreEmitPass2(AddMachinePass &addPass) const {
+  const Triple &TT = TM.getTargetTriple();
+  const MCAsmInfo *MAI = TM.getMCAsmInfo();
+
+  // The X86 Speculative Execution Pass must run after all control
+  // flow graph modifying passes. As a result it was listed to run right before
+  // the X86 Retpoline Thunks pass. The reason it must run after control flow
+  // graph modifications is that the model of LFENCE in LLVM has to be updated
+  // (FIXME: https://bugs.llvm.org/show_bug.cgi?id=45167). Currently the
+  // placement of this pass was hand checked to ensure that the subsequent
+  // passes don't move the code around the LFENCEs in a way that will hurt the
+  // correctness of this pass. This placement has been shown to work based on
+  // hand inspection of the codegen output.
+  addPass(X86SpeculativeExecutionSideEffectSuppressionPass());
+  addPass(X86IndirectThunksPass());
+  addPass(X86ReturnThunksPass());
+
+  // Insert extra int3 instructions after trailing call instructions to avoid
+  // issues in the unwinder.
+  if (TT.isOSWindows() && TT.getArch() == Triple::x86_64)
+    addPass(X86AvoidTrailingCallPass());
+
+  // Verify basic block incoming and outgoing cfa offset and register values and
+  // correct CFA calculation rule where needed by inserting appropriate CFI
+  // instructions.
+  if (!TT.isOSDarwin() &&
+      (!TT.isOSWindows() ||
+       MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI))
+    addPass(CFIInstrInserterPass());
+  // Identify valid longjmp targets for Windows Control Flow Guard.
+  if (TT.isOSWindows()) {
+    // Identify valid longjmp targets for Windows Control Flow Guard.
+    addPass(CFGuardLongjmpPass());
+    // Identify valid eh continuation targets for Windows EHCont Guard.
+    addPass(EHContGuardCatchretPass());
+  }
+  addPass(X86LoadValueInjectionRetHardeningPass());
+
+  // Insert pseudo probe annotation for callsite profiling
+  addPass(PseudoProbeInserterPass());
+
+  // KCFI indirect call checks are lowered to a bundle, and on Darwin platforms,
+  // also CALL_RVMARKER.
+  addPass(UnpackMachineBundlesPass([&TT](const MachineFunction &MF) {
+    // Only run bundle expansion if the module uses kcfi, or there are relevant
+    // ObjC runtime functions present in the module.
+    const Function &F = MF.getFunction();
+    const Module *M = F.getParent();
+    return M->getModuleFlag("kcfi") ||
+           (TT.isOSDarwin() &&
+            (M->getFunction("objc_retainAutoreleasedReturnValue") ||
+             M->getFunction("objc_unsafeClaimAutoreleasedReturnValue")));
+  }));
+}
+
+Error X86CodeGenPassBuilder::addRegAssignAndRewriteOptimized(
+    AddMachinePass &addPass) const {
+  if (Opt.RegAlloc != RegAllocType::Default && EnableTileRAPass) {
+    addPass(RAGreedyPass(onlyAllocateTileRegisters));
+    addPass(X86TileConfigPass());
+  }
+  return CodeGenPassBuilder::addRegAssignAndRewriteFast(addPass);
+}
+
+void X86CodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass,
+                                          CreateMCStreamer callback) const {
+  addPass(X86AsmPrinterPass(callback));
+}
+
+std::pair<StringRef, bool>
+X86CodeGenPassBuilder::getTargetPassNameFromLegacyName(StringRef Name) const {
+  std::pair<StringRef, bool> Ret;
+
+#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)                            \
+  if (Name == NAME)                                                            \
+    Ret = {#PASS_NAME, false};
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)                      \
+  if (Name == NAME)                                                            \
+    Ret = {#PASS_NAME, false};
+#define MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                              \
+  if (Name == NAME)                                                            \
+    Ret = {#PASS_NAME, false};
+#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                        \
+  if (Name == NAME)                                                            \
+    Ret = {#PASS_NAME, false};
+#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)                    \
+  if (Name == NAME)                                                            \
+    Ret = {#PASS_NAME, true};
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \
+  if (Name == NAME)                                                            \
+    Ret = {#PASS_NAME, true};
+#include "X86PassRegistry.def"
+
+  return Ret;
+}
+
+Error X86TargetMachine::buildCodeGenPipeline(
+    ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
+    raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
+    CGPassBuilderOption Opts, MachineFunctionAnalysisManager &MFAM,
+    PassInstrumentationCallbacks *PIC) {
+  X86CodeGenPassBuilder X86CGPB{*this, Opts, PIC};
+  X86CGPB.registerAnalyses(MFAM);
+  return X86CGPB.buildPipeline(MPM, MFPM, Out, DwoOut, FileType);
+}
+
+std::pair<StringRef, bool>
+X86TargetMachine::getPassNameFromLegacyName(StringRef Name) {
+  X86CodeGenPassBuilder X86CGPB{*this};
+  return X86CGPB.getPassNameFromLegacyName(Name);
+}
+
+bool X86CodeGenPassBuilder::parseTargetMIRPass(MachineFunctionPassManager &MFPM,
+                                               StringRef Name) const {
+#define ADD_PASS(NAME, PASS_NAME, CONSTRUCTOR)                                 \
+  if (Name == NAME) {                                                          \
+    {                                                                          \
+      addMachinePass(MFPM, PASS_NAME CONSTRUCTOR);                             \
+    }                                                                          \
+    return false;                                                              \
+  }
+
+#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                      \
+  ADD_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)                    \
+  ADD_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                \
+  ADD_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \
+  ADD_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#include "X86PassRegistry.def"
+#undef ADD_PASS
+  return true;
+}
+
+Error X86TargetMachine::parseMIRPipeline(MachineFunctionPassManager &MFPM,
+                                         StringRef PipelineText,
+                                         CGPassBuilderOption Opts,
+                                         MachineFunctionAnalysisManager &MFAM,
+                                         PassInstrumentationCallbacks *PIC) {
+  X86CodeGenPassBuilder X86CGPB{*this, Opts, PIC};
+  X86CGPB.registerAnalyses(MFAM);
+  return X86CGPB.parseMIRPipeline(MFPM, PipelineText);
+}
diff --git a/llvm/lib/Target/X86/X86TargetMachine.h b/llvm/lib/Target/X86/X86TargetMachine.h
index 4836be4db0e8e84..bb06cedd10b47d5 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.h
+++ b/llvm/lib/Target/X86/X86TargetMachine.h
@@ -50,6 +50,19 @@ class X86TargetMachine final : public LLVMTargetMachine {
   // Set up the pass pipeline.
   TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
 
+  Error buildCodeGenPipeline(ModulePassManager &MPM,
+                             MachineFunctionPassManager &MFPM,
+                             raw_pwrite_stream &, raw_pwrite_stream *,
+                             CodeGenFileType, CGPassBuilderOption,
+                             MachineFunctionAnalysisManager &,
+                             PassInstrumentationCallbacks *) override;
+
+  std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) override;
+
+  Error parseMIRPipeline(MachineFunctionPassManager &MFPM, StringRef,
+                         CGPassBuilderOption, MachineFunctionAnalysisManager &,
+                         PassInstrumentationCallbacks *) override;
+
   TargetLoweringObjectFile *getObjFileLowering() const override {
     return TLOF.get();
   }

>From ca313e52edf4b61c9940352e42c7e1a6d5af09ed Mon Sep 17 00:00:00 2001
From: liujunchang <lgamma at 163.com>
Date: Wed, 1 Nov 2023 10:46:27 +0800
Subject: [PATCH 6/8] [Pass] Support start/stop in instrumentation

---
 llvm/include/llvm/IR/PassInstrumentation.h   | 33 ++++++++++++++++++++
 llvm/lib/CodeGen/TargetPassConfig.cpp        | 19 +++++++++--
 llvm/lib/Passes/StandardInstrumentations.cpp |  7 +++--
 3 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/IR/PassInstrumentation.h b/llvm/include/llvm/IR/PassInstrumentation.h
index 519a5e46b4373b7..3f70fcf180af81a 100644
--- a/llvm/include/llvm/IR/PassInstrumentation.h
+++ b/llvm/include/llvm/IR/PassInstrumentation.h
@@ -84,6 +84,23 @@ class PassInstrumentationCallbacks {
   using AfterAnalysisFunc = void(StringRef, Any);
   using AnalysisInvalidatedFunc = void(StringRef, Any);
   using AnalysesClearedFunc = void(StringRef);
+  using StartStopFunc = bool(StringRef, Any);
+
+  struct CodeGenStartStopInfo {
+    StringRef Start;
+    StringRef Stop;
+
+    bool IsStopMachinePass = false;
+
+    llvm::unique_function<StartStopFunc> StartStopCallback;
+
+    bool operator()(StringRef PassID, Any IR) {
+      return StartStopCallback(PassID, IR);
+    }
+    bool isStopMachineFunctionPass() const { return IsStopMachinePass; }
+    bool willCompleteCodeGenPipeline() const { return Stop.empty(); }
+    StringRef getStop() const { return Stop; }
+  };
 
 public:
   PassInstrumentationCallbacks() = default;
@@ -148,6 +165,17 @@ class PassInstrumentationCallbacks {
     AnalysesClearedCallbacks.emplace_back(std::move(C));
   }
 
+  void registerStartStopInfo(CodeGenStartStopInfo &&C) {
+    StartStopInfo = std::move(C);
+  }
+
+  bool isStartStopInfoRegistered() const { return StartStopInfo.has_value(); }
+
+  CodeGenStartStopInfo &getStartStopInfo() {
+    assert(StartStopInfo.has_value() && "StartStopInfo is unregistered!");
+    return *StartStopInfo;
+  }
+
   /// Add a class name to pass name mapping for use by pass instrumentation.
   void addClassToPassName(StringRef ClassName, StringRef PassName);
   /// Get the pass name for a given pass class name.
@@ -183,6 +211,8 @@ class PassInstrumentationCallbacks {
   /// These are run on analyses that have been cleared.
   SmallVector<llvm::unique_function<AnalysesClearedFunc>, 4>
       AnalysesClearedCallbacks;
+  /// For `llc` -start-* -stop-* options.
+  std::optional<CodeGenStartStopInfo> StartStopInfo;
 
   StringMap<std::string> ClassToPassName;
 };
@@ -236,6 +266,9 @@ class PassInstrumentation {
         ShouldRun &= C(Pass.name(), llvm::Any(&IR));
     }
 
+    if (Callbacks->StartStopInfo)
+      ShouldRun &= (*Callbacks->StartStopInfo)(Pass.name(), llvm::Any(&IR));
+
     if (ShouldRun) {
       for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)
         C(Pass.name(), llvm::Any(&IR));
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 230e3cd945916f8..a1d134f2ce70705 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -518,6 +518,9 @@ static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
   unsigned StopBeforeInstanceNum = 0;
   unsigned StopAfterInstanceNum = 0;
 
+  bool IsStopBeforeMachinePass = false;
+  bool IsStopAfterMachinePass = false;
+
   std::tie(StartBefore, StartBeforeInstanceNum) =
       getPassNameAndInstanceNum(StartBeforeOpt);
   std::tie(StartAfter, StartAfterInstanceNum) =
@@ -546,7 +549,15 @@ static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
     report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
                        Twine(StopAfterOptName) + Twine(" specified!"));
 
-  PIC.registerShouldRunOptionalPassCallback(
+  std::vector<StringRef> SpecialPasses = {"PassManager", "PassAdaptor",
+                                          "PrintMIRPass", "PrintModulePass"};
+
+  PassInstrumentationCallbacks::CodeGenStartStopInfo Info;
+  Info.Start = StartBefore.empty() ? StartAfter : StartBefore;
+  Info.Stop = StopBefore.empty() ? StopAfter : StopBefore;
+
+  Info.IsStopMachinePass = IsStopBeforeMachinePass || IsStopAfterMachinePass;
+  Info.StartStopCallback =
       [=, EnableCurrent = StartBefore.empty() && StartAfter.empty(),
        EnableNext = std::optional<bool>(), StartBeforeCount = 0u,
        StartAfterCount = 0u, StopBeforeCount = 0u,
@@ -577,8 +588,10 @@ static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
           EnableCurrent = true;
         if (StopBeforePass && StopBeforeCount++ == StopBeforeInstanceNum)
           EnableCurrent = false;
-        return EnableCurrent;
-      });
+        return EnableCurrent || isSpecialPass(P, SpecialPasses);
+      };
+
+  PIC.registerStartStopInfo(std::move(Info));
 }
 
 void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 8cae1235487f13b..24360c638b7803b 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -1040,9 +1040,10 @@ void PrintPassInstrumentation::registerCallbacks(
     SpecialPasses.emplace_back("PassAdaptor");
   }
 
-  PIC.registerBeforeSkippedPassCallback([this, SpecialPasses](StringRef PassID,
-                                                              Any IR) {
-    assert(!isSpecialPass(PassID, SpecialPasses) &&
+  PIC.registerBeforeSkippedPassCallback([this, SpecialPasses,
+                                         &PIC](StringRef PassID, Any IR) {
+    assert((!isSpecialPass(PassID, SpecialPasses) ||
+            PIC.isStartStopInfoRegistered()) &&
            "Unexpectedly skipping special pass");
 
     print() << "Skipping pass: " << PassID << " on " << getIRName(IR) << "\n";

>From 3b96d781ca85bb165995ee2e75d9f2d7147cb0d6 Mon Sep 17 00:00:00 2001
From: liujunchang <lgamma at 163.com>
Date: Wed, 1 Nov 2023 10:47:44 +0800
Subject: [PATCH 7/8] [MachinePass] Run instrumentation before/after module
 pass

---
 llvm/lib/CodeGen/MachinePassManager.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/MachinePassManager.cpp b/llvm/lib/CodeGen/MachinePassManager.cpp
index a13f820e457766f..914e6b19fde9ac8 100644
--- a/llvm/lib/CodeGen/MachinePassManager.cpp
+++ b/llvm/lib/CodeGen/MachinePassManager.cpp
@@ -33,10 +33,11 @@ Error MachineFunctionPassManager::run(Module &M,
   (void)RequireCodeGenSCCOrder;
   assert(!RequireCodeGenSCCOrder && "not implemented");
 
+  // M is unused here
+  PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(M);
+
   // Add a PIC to verify machine functions.
   if (VerifyMachineFunction) {
-    PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(M);
-
     // No need to pop this callback later since MIR pipeline is flat which means
     // current pipeline is the top-level pipeline. Callbacks are not used after
     // current pipeline.
@@ -59,8 +60,11 @@ Error MachineFunctionPassManager::run(Module &M,
   do {
     // Run machine module passes
     for (; MachineModulePasses.count(Idx) && Idx != Size; ++Idx) {
+      if (!PI.runBeforePass<Module>(*Passes[Idx], M))
+        continue;
       if (auto Err = MachineModulePasses.at(Idx)(M, MFAM))
         return Err;
+      PI.runAfterPass(*Passes[Idx], M, PreservedAnalyses::all());
     }
 
     // Finish running all passes.
@@ -81,7 +85,6 @@ Error MachineFunctionPassManager::run(Module &M,
         continue;
 
       MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
-      PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(MF);
 
       for (unsigned I = Begin, E = Idx; I != E; ++I) {
         auto *P = Passes[I].get();

>From b776345d8b1b77379e6f1149c53a2a0e614c8277 Mon Sep 17 00:00:00 2001
From: Yuanfang Chen <455423+yuanfang-chen at users.noreply.github.com>
Date: Wed, 1 Nov 2023 10:48:45 +0800
Subject: [PATCH 8/8] [NewPM][CodeGen] Add NPM support to llc

---
 .../Generic/llc-start-stop-instance-errors.ll |   2 +
 .../CodeGen/Generic/new-pm/llc-start-stop.ll  |  47 ++++
 llvm/test/CodeGen/X86/new-pm/O0-pipeline.ll   | 116 ++++++++
 .../X86/new-pm/llc-start-stop-instance.ll     |  35 +++
 llvm/test/CodeGen/X86/new-pm/opt-pipeline.ll  | 243 ++++++++++++++++
 llvm/tools/llc/CMakeLists.txt                 |   3 +
 llvm/tools/llc/NewPMDriver.cpp                | 264 ++++++++++++++++++
 llvm/tools/llc/NewPMDriver.h                  |  49 ++++
 llvm/tools/llc/llc.cpp                        |  90 +++---
 9 files changed, 793 insertions(+), 56 deletions(-)
 create mode 100644 llvm/test/CodeGen/Generic/new-pm/llc-start-stop.ll
 create mode 100644 llvm/test/CodeGen/X86/new-pm/O0-pipeline.ll
 create mode 100644 llvm/test/CodeGen/X86/new-pm/llc-start-stop-instance.ll
 create mode 100644 llvm/test/CodeGen/X86/new-pm/opt-pipeline.ll
 create mode 100644 llvm/tools/llc/NewPMDriver.cpp
 create mode 100644 llvm/tools/llc/NewPMDriver.h

diff --git a/llvm/test/CodeGen/Generic/llc-start-stop-instance-errors.ll b/llvm/test/CodeGen/Generic/llc-start-stop-instance-errors.ll
index 76cc8b681b6a785..8cad70b5d9ede10 100644
--- a/llvm/test/CodeGen/Generic/llc-start-stop-instance-errors.ll
+++ b/llvm/test/CodeGen/Generic/llc-start-stop-instance-errors.ll
@@ -1,4 +1,6 @@
 ; RUN: not --crash llc -debug-pass=Structure -stop-after=dead-mi-elimination,arst %s -o /dev/null 2>&1 \
 ; RUN:   | FileCheck -check-prefix=NOT-NUM %s
+; RUN: not --crash llc -enable-new-pm -debug-pass-manager -stop-after=dead-mi-elimination,arst %s -o /dev/null 2>&1 \
+; RUN:   | FileCheck -check-prefix=NOT-NUM %s
 
 ; NOT-NUM: LLVM ERROR: invalid pass instance specifier dead-mi-elimination,arst
diff --git a/llvm/test/CodeGen/Generic/new-pm/llc-start-stop.ll b/llvm/test/CodeGen/Generic/new-pm/llc-start-stop.ll
new file mode 100644
index 000000000000000..5245563763d81bf
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/new-pm/llc-start-stop.ll
@@ -0,0 +1,47 @@
+; RUN: llc < %s -enable-new-pm -debug-pass-manager -stop-after=verify \
+; RUN:     -o /dev/null 2>&1 | FileCheck %s -check-prefix=STOP-AFTER
+; STOP-AFTER: Running pass: VerifierPass
+; STOP-AFTER-NEXT: Running analysis: VerifierAnalysis
+; STOP-AFTER-NEXT: Skipping pass:
+
+; RUN: llc < %s -enable-new-pm -debug-pass-manager -stop-before=verify \
+; RUN:     -o /dev/null 2>&1 | FileCheck %s -check-prefix=STOP-BEFORE
+; STOP-BEFORE: Running pass: AtomicExpandPass
+; STOP-BEFORE-NEXT: Skipping pass:
+
+; RUN: llc < %s -enable-new-pm -debug-pass-manager -start-after=verify \
+; RUN:     -o /dev/null 2>&1 | FileCheck %s -check-prefix=START-AFTER
+; START-AFTER: Skipping pass: VerifierPass
+; START-AFTER-NEXT: Running pass:
+
+; RUN: llc < %s -enable-new-pm -debug-pass-manager -start-before=verify \
+; RUN:    -o /dev/null 2>&1 | FileCheck %s -check-prefix=START-BEFORE
+; START-BEFORE-NOT: Running pass:
+; START-BEFORE: Running pass: VerifierPass
+
+; RUN: not --crash llc < %s -enable-new-pm -start-before=nonexistent -o /dev/null 2>&1 \
+; RUN:    | FileCheck %s -check-prefix=NONEXISTENT-START-BEFORE
+; RUN: not --crash llc < %s -enable-new-pm -stop-before=nonexistent -o /dev/null 2>&1 \
+; RUN:    | FileCheck %s -check-prefix=NONEXISTENT-STOP-BEFORE
+; RUN: not --crash llc < %s -enable-new-pm -start-after=nonexistent -o /dev/null 2>&1 \
+; RUN:    | FileCheck %s -check-prefix=NONEXISTENT-START-AFTER
+; RUN: not --crash llc < %s -enable-new-pm -stop-after=nonexistent -o /dev/null 2>&1 \
+; RUN:    | FileCheck %s -check-prefix=NONEXISTENT-STOP-AFTER
+; NONEXISTENT-START-BEFORE: "nonexistent" pass could not be found.
+; NONEXISTENT-STOP-BEFORE: "nonexistent" pass could not be found.
+; NONEXISTENT-START-AFTER: "nonexistent" pass could not be found.
+; NONEXISTENT-STOP-AFTER: "nonexistent" pass could not be found.
+
+; RUN: not --crash llc < %s -enable-new-pm -start-before=verify -start-after=verify \
+; RUN:    -o /dev/null 2>&1 | FileCheck %s -check-prefix=DOUBLE-START
+; RUN: not --crash llc < %s -enable-new-pm -stop-before=verify -stop-after=verify \
+; RUN:    -o /dev/null 2>&1 | FileCheck %s -check-prefix=DOUBLE-STOP
+; DOUBLE-START: start-before and start-after specified!
+; DOUBLE-STOP: stop-before and stop-after specified!
+
+define void @f() {
+  br label %b
+b:
+  br label %b
+  ret void
+}
diff --git a/llvm/test/CodeGen/X86/new-pm/O0-pipeline.ll b/llvm/test/CodeGen/X86/new-pm/O0-pipeline.ll
new file mode 100644
index 000000000000000..d2b3d333ba27266
--- /dev/null
+++ b/llvm/test/CodeGen/X86/new-pm/O0-pipeline.ll
@@ -0,0 +1,116 @@
+; When EXPENSIVE_CHECKS are enabled, the machine verifier appears between each
+; pass. Ignore it with 'grep -v'.
+; RUN: llc -mtriple=x86_64-- -O0 -debug-pass-manager -enable-new-pm < %s \
+; RUN:    -o /dev/null 2>&1 | grep -v 'Verify generated machine code' | FileCheck %s
+
+; REQUIRES: asserts
+
+; CHECK-LABEL: Running pass: PreISelIntrinsicLoweringPass on [module]
+; CHECK-NEXT: Running analysis: {{.*InnerAnalysisManagerProxy.*|UNKNOWN_TYPE}}
+; CHECK-NEXT: Running pass: ExpandLargeDivRemPass on f (1 instruction)
+; CHECK-NEXT: Running pass: ExpandLargeFpConvertPass on f (1 instruction)
+; CHECK-NEXT: Running pass: AtomicExpandPass on f (1 instruction)
+; CHECK-NEXT: Running pass: VerifierPass on f (1 instruction)
+; CHECK-NEXT: Running analysis: VerifierAnalysis on f
+; CHECK-NEXT: Running pass: GCLoweringPass on f (1 instruction)
+; CHECK-NEXT: Running pass: ShadowStackGCLoweringPass on f (1 instruction)
+; CHECK-NEXT: Running pass: LowerConstantIntrinsicsPass on f (1 instruction)
+; CHECK-NEXT: Running analysis: TargetLibraryAnalysis on f
+; CHECK-NEXT: Running pass: UnreachableBlockElimPass on f (1 instruction)
+; CHECK-NEXT: Running pass: ExpandVectorPredicationPass on f (1 instruction)
+; CHECK-NEXT: Running analysis: TargetIRAnalysis on f
+; CHECK-NEXT: Running pass: ScalarizeMaskedMemIntrinPass on f (1 instruction)
+; CHECK-NEXT: Running pass: ExpandReductionsPass on f (1 instruction)
+; CHECK-NEXT: Running pass: IndirectBrExpandPass on f (1 instruction)
+; CHECK-NEXT: Running pass: DwarfEHPass on f (1 instruction)
+; CHECK-NEXT: Running pass: CallBrPrepare on f (1 instruction)
+; CHECK-NEXT: Running pass: SafeStackPass on f (1 instruction)
+; CHECK-NEXT: Running pass: StackProtectorPass on f (1 instruction)
+; CHECK-NEXT: Running pass: VerifierPass on f (1 instruction)
+; CHECK-NEXT: Running analysis: MachineModuleAnalysis on [module]
+; CHECK-NEXT: Running pass: {{.*}}::X86ISelDagPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86GlobalBaseRegPass on f
+; CHECK-NEXT: Running pass: FinalizeISelPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: LocalStackSlotPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86SpeculativeLoadHardeningPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FlagsCopyLoweringDummyPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86DynAllocaExpanderPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FastPreTileConfigPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PHIEliminationPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: TwoAddressInstructionPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: RegAllocPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FastTileConfigPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86LowerTileCopyPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FloatingPointStackifierPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: RemoveRedundantDebugValuesPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: FixupStatepointCallerSavedPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PrologEpilogInserterPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: ExpandPostRAPseudosPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86ExpandPseudoPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: KCFIPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: FEntryInserterPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: XRayInstrumentationPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PatchableFunctionPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86IndirectBranchTrackingPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86IssueVZeroUpperPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86EvexToVexInstsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86DiscriminateMemOpsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86InsertPrefetchPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86InsertX87waitPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: FuncletLayoutPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: StackMapLivenessPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: LiveDebugValuesPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineSanitizerBinaryMetadata on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: StackFrameLayoutAnalysisPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86SpeculativeExecutionSideEffectSuppressionPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86IndirectThunksPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86ReturnThunksPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: CFIInstrInserterPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86LoadValueInjectionRetHardeningPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PseudoProbeInserterPass on [module]
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: UnpackMachineBundlesPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86AsmPrinterPass on f
+; CHECK-NEXT: Running pass: FreeMachineFunctionPass on f
+
+define void @f() {
+  ret void
+}
diff --git a/llvm/test/CodeGen/X86/new-pm/llc-start-stop-instance.ll b/llvm/test/CodeGen/X86/new-pm/llc-start-stop-instance.ll
new file mode 100644
index 000000000000000..a6d5cf2fd8aff58
--- /dev/null
+++ b/llvm/test/CodeGen/X86/new-pm/llc-start-stop-instance.ll
@@ -0,0 +1,35 @@
+; RUN: llc -mtriple=x86_64-- -enable-new-pm -debug-pass-manager -stop-after=verify,1 \
+; RUN:      %s -o /dev/null 2>&1 | FileCheck -check-prefix=STOP-AFTER-1 %s
+
+; RUN: llc -mtriple=x86_64-- -enable-new-pm -debug-pass-manager -stop-after=verify,0 \
+; RUN:      %s -o /dev/null 2>&1 | FileCheck -check-prefix=STOP-AFTER-0 %s
+
+; RUN: llc -mtriple=x86_64-- -enable-new-pm -debug-pass-manager -stop-before=verify,1 \
+; RUN:      %s -o /dev/null 2>&1 | FileCheck -check-prefix=STOP-BEFORE-1 %s
+
+; RUN: llc -mtriple=x86_64-- -enable-new-pm -debug-pass-manager -start-before=verify,1 \
+; RUN:      %s -o /dev/null 2>&1 | FileCheck -check-prefix=START-BEFORE-1 %s
+
+; RUN: llc -mtriple=x86_64-- -enable-new-pm -debug-pass-manager -start-after=verify,1 \
+; RUN:      %s -o /dev/null 2>&1 | FileCheck -check-prefix=START-AFTER-1 %s
+
+
+; STOP-AFTER-1: Running pass: VerifierPass
+; STOP-AFTER-1: Running pass: VerifierPass
+
+; STOP-AFTER-0-NOT: Running pass: VerifierPass
+; STOP-AFTER-0: Running pass: VerifierPass
+; STOP-AFTER-0-NOT: Running pass: VerifierPass
+
+; STOP-BEFORE-1: Running pass: VerifierPass
+; STOP-BEFORE-1-NOT: Running pass: VerifierPass
+
+; START-BEFORE-1-NOT: Running pass: VerifierPass
+; START-BEFORE-1: Running pass: VerifierPass
+; START-BEFORE-1-NOT: Running pass: VerifierPass
+
+; START-AFTER-1-NOT: Running pass: VerifierPass
+
+define void @f() {
+  ret void
+}
diff --git a/llvm/test/CodeGen/X86/new-pm/opt-pipeline.ll b/llvm/test/CodeGen/X86/new-pm/opt-pipeline.ll
new file mode 100644
index 000000000000000..73b074a5e67f967
--- /dev/null
+++ b/llvm/test/CodeGen/X86/new-pm/opt-pipeline.ll
@@ -0,0 +1,243 @@
+; When EXPENSIVE_CHECKS are enabled, the machine verifier appears between each
+; pass. Ignore it with 'grep -v'.
+; RUN: llc -mtriple=x86_64-- -O1 -debug-pass-manager -enable-new-pm < %s \
+; RUN:    -o /dev/null 2>&1 | FileCheck %s
+; RUN: llc -mtriple=x86_64-- -O2 -debug-pass-manager -enable-new-pm < %s \
+; RUN:    -o /dev/null 2>&1 | FileCheck %s
+; RUN: llc -mtriple=x86_64-- -O3 -debug-pass-manager -enable-new-pm < %s \
+; RUN:    -o /dev/null 2>&1 | FileCheck %s
+
+; REQUIRES: asserts
+
+; CHECK-LABEL: Running pass: PreISelIntrinsicLoweringPass on [module]
+; CHECK-NEXT: Running analysis: {{.*InnerAnalysisManagerProxy.*|UNKNOWN_TYPE}}
+; CHECK-NEXT: Running pass: ExpandLargeDivRemPass on f (3 instructions)
+; CHECK-NEXT: Running pass: ExpandLargeFpConvertPass on f (3 instructions)
+; CHECK-NEXT: Running pass: AtomicExpandPass on f (3 instructions)
+; CHECK-NEXT: Running pass: VerifierPass on f (3 instructions)
+; CHECK-NEXT: Running analysis: VerifierAnalysis on f
+; CHECK-NEXT: Running pass: LoopSimplifyPass on f (3 instructions)
+; CHECK-NEXT: Running analysis: LoopAnalysis on f
+; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on f
+; CHECK-NEXT: Running analysis: AssumptionAnalysis on f
+; CHECK-NEXT: Running analysis: TargetIRAnalysis on f
+; CHECK-NEXT: Running pass: LCSSAPass on f (3 instructions)
+; CHECK-NEXT: Running analysis: MemorySSAAnalysis on f
+; CHECK-NEXT: Running analysis: AAManager on f
+; CHECK-NEXT: Running analysis: TargetLibraryAnalysis on f
+; CHECK-NEXT: Running analysis: BasicAA on f
+; CHECK-NEXT: Running analysis: ScopedNoAliasAA on f
+; CHECK-NEXT: Running analysis: TypeBasedAA on f
+; CHECK-NEXT: Running analysis: {{.*OuterAnalysisManagerProxy.*|UNKNOWN_TYPE}}
+; CHECK-NEXT: Running analysis: ScalarEvolutionAnalysis on f
+; CHECK-NEXT: Running analysis: {{.*InnerAnalysisManagerProxy.*|UNKNOWN_TYPE}}
+; CHECK-NEXT: Running pass: CanonicalizeFreezeInLoopsPass on b
+; CHECK-NEXT: Running pass: LoopSimplifyPass on f (3 instructions)
+; CHECK-NEXT: Running pass: LCSSAPass on f (3 instructions)
+; CHECK-NEXT: Running pass: LoopStrengthReducePass on b
+; CHECK-NEXT: Running analysis: IVUsersAnalysis on b
+; CHECK-NEXT: Running pass: MergeICmpsPass on f (3 instructions)
+; CHECK-NEXT: Running pass: ExpandMemCmpPass on f (3 instructions)
+; CHECK-NEXT: Running pass: GCLoweringPass on f (3 instructions)
+; CHECK-NEXT: Running pass: ShadowStackGCLoweringPass on f (3 instructions)
+; CHECK-NEXT: Running pass: LowerConstantIntrinsicsPass on f (3 instructions)
+; CHECK-NEXT: Running pass: UnreachableBlockElimPass on f (3 instructions)
+; CHECK-NEXT: Clearing all analysis results for: <possibly invalidated loop>
+; CHECK-NEXT: Invalidating analysis: VerifierAnalysis on f
+; CHECK-NEXT: Invalidating analysis: LoopAnalysis on f
+; CHECK-NEXT: Invalidating analysis: MemorySSAAnalysis on f
+; CHECK-NEXT: Invalidating analysis: ScalarEvolutionAnalysis on f
+; CHECK-NEXT: Invalidating analysis: {{.*InnerAnalysisManagerProxy.*|UNKNOWN_TYPE}}
+; CHECK-NEXT: Running pass: ConstantHoistingPass on f (2 instructions)
+; CHECK-NEXT: Running analysis: BlockFrequencyAnalysis on f
+; CHECK-NEXT: Running analysis: BranchProbabilityAnalysis on f
+; CHECK-NEXT: Running analysis: LoopAnalysis on f
+; CHECK-NEXT: Running analysis: PostDominatorTreeAnalysis on f
+; CHECK-NEXT: Running pass: ReplaceWithVeclib on f (2 instructions)
+; CHECK-NEXT: Running pass: PartiallyInlineLibCallsPass on f (2 instructions)
+; CHECK-NEXT: Running pass: ExpandVectorPredicationPass on f (2 instructions)
+; CHECK-NEXT: Running pass: ScalarizeMaskedMemIntrinPass on f (2 instructions)
+; CHECK-NEXT: Running pass: ExpandReductionsPass on f (2 instructions)
+; CHECK-NEXT: Running pass: TLSVariableHoistPass on f (2 instructions)
+; CHECK-NEXT: Running pass: InterleavedAccessPass on f (2 instructions)
+; CHECK-NEXT: Running pass: IndirectBrExpandPass on f (2 instructions)
+; CHECK-NEXT: Running pass: CodeGenPreparePass on f (2 instructions)
+; CHECK-NEXT: Running pass: DwarfEHPass on f (2 instructions)
+; CHECK-NEXT: Running pass: CallBrPrepare on f (2 instructions)
+; CHECK-NEXT: Running pass: SafeStackPass on f (2 instructions)
+; CHECK-NEXT: Running pass: StackProtectorPass on f (2 instructions)
+; CHECK-NEXT: Running pass: VerifierPass on f (2 instructions)
+; CHECK-NEXT: Running analysis: VerifierAnalysis on f
+; CHECK-NEXT: Running analysis: MachineModuleAnalysis on [module]
+; CHECK-NEXT: Running pass: {{.*}}::X86ISelDagPass on f
+; CHECK-NEXT: Running pass: {{.*}}::CleanupLocalDynamicTLSPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86GlobalBaseRegPass on f
+; CHECK-NEXT: Running pass: FinalizeISelPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86DomainReassignmentPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: EarlyTailDuplicatePass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: OptimizePHIsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: StackColoringPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: LocalStackSlotPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: DeadMachineInstructionElimPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: EarlyIfConverterPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineCombinerPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86CmovConverterDummyPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: EarlyMachineLICMPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineCSEPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineSinkingPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PeepholeOptimizerPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: DeadMachineInstructionElimPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: LiveRangeShrinkPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FixupSetCCPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86OptimizeLEAsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86CallFrameOptimizationPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86AvoidStoreForwardingBlocksPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86SpeculativeLoadHardeningPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FlagsCopyLoweringDummyPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86DynAllocaExpanderPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86PreTileConfigPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: DetectDeadLanesPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: ProcessImplicitDefsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PHIEliminationPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: TwoAddressInstructionPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: RegisterCoalescerPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: RenameIndependentSubregsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineSchedulerPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: RegAllocPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FastTileConfigPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineCopyPropagationPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineLICMPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86LowerTileCopyPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FloatingPointStackifierPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86LoadValueInjectionRetHardeningPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: RemoveRedundantDebugValuesPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: FixupStatepointCallerSavedPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PostRAMachineSinkingPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: ShrinkWrapPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PrologEpilogInserterPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: BranchFolderPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: TailDuplicatePass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineLateInstrsCleanupPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineCopyPropagationPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: ExpandPostRAPseudosPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86ExpandPseudoPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: KCFIPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PostRASchedulerPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineBlockPlacementPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: FEntryInserterPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: XRayInstrumentationPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PatchableFunctionPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86ExecutionDomainFixPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: BreakFalseDepsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86IndirectBranchTrackingPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86IssueVZeroUpperPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FixupBWInstsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86PadShortFunctionsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FixupLEAsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FixupInstTuningPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86FixupVectorConstantsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86EvexToVexInstsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86DiscriminateMemOpsPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86InsertPrefetchPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86InsertX87waitPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: FuncletLayoutPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: StackMapLivenessPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: LiveDebugValuesPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: MachineSanitizerBinaryMetadata on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: StackFrameLayoutAnalysisPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86SpeculativeExecutionSideEffectSuppressionPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86IndirectThunksPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86ReturnThunksPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: CFIInstrInserterPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86LoadValueInjectionRetHardeningPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: PseudoProbeInserterPass on [module]
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: UnpackMachineBundlesPass on f
+; CHECK-NEXT: Running pass: MachineVerifierPass on f
+; CHECK-NEXT: Running pass: {{.*}}::X86AsmPrinterPass on f
+; CHECK-NEXT: Running pass: FreeMachineFunctionPass on f
+
+define void @f() {
+  br label %b
+b:
+  br label %b
+  ret void
+}
diff --git a/llvm/tools/llc/CMakeLists.txt b/llvm/tools/llc/CMakeLists.txt
index 257d5b519f0406f..01825c6e4c64c77 100644
--- a/llvm/tools/llc/CMakeLists.txt
+++ b/llvm/tools/llc/CMakeLists.txt
@@ -8,9 +8,11 @@ set(LLVM_LINK_COMPONENTS
   CodeGen
   CodeGenTypes
   Core
+  IRPrinter
   IRReader
   MC
   MIRParser
+  Passes
   Remarks
   ScalarOpts
   SelectionDAG
@@ -23,6 +25,7 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_tool(llc
   llc.cpp
+  NewPMDriver.cpp
 
   DEPENDS
   intrinsics_gen
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
new file mode 100644
index 000000000000000..83e8c60ade93f71
--- /dev/null
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -0,0 +1,264 @@
+//===- NewPMDriver.cpp - Driver for llc using new PM ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file is just a split of the code that logically belongs in llc.cpp but
+/// that includes the new pass manager headers.
+///
+//===----------------------------------------------------------------------===//
+
+#include "NewPMDriver.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/CodeGen/CodeGenPassBuilder.h"
+#include "llvm/CodeGen/CommandFlags.h"
+#include "llvm/CodeGen/MIRParser/MIRParser.h"
+#include "llvm/CodeGen/MIRPrinter.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/IRReader/IRReader.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/StandardInstrumentations.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Target/CGPassBuilderOption.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+
+using namespace llvm;
+
+static cl::opt<RegAllocType> RegAlloc(
+    "regalloc-npm", cl::desc("Register allocator to use for new pass manager"),
+    cl::Hidden, cl::ValueOptional, cl::init(RegAllocType::Default),
+    cl::values(
+        clEnumValN(RegAllocType::Default, "default",
+                   "pick register allocator based on -O option"),
+        clEnumValN(RegAllocType::Basic, "basic", "basic register allocator"),
+        clEnumValN(RegAllocType::Fast, "fast", "fast register allocator"),
+        clEnumValN(RegAllocType::Greedy, "greedy", "greedy register allocator"),
+        clEnumValN(RegAllocType::PBQP, "pbqp", "PBQP register allocator")));
+
+static cl::opt<bool>
+    DebugPM("debug-pass-manager", cl::Hidden,
+            cl::desc("Print pass management debugging information"));
+
+bool LLCDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) {
+  if (DI.getKind() == llvm::DK_SrcMgr) {
+    const auto &DISM = cast<DiagnosticInfoSrcMgr>(DI);
+    const SMDiagnostic &SMD = DISM.getSMDiag();
+
+    if (SMD.getKind() == SourceMgr::DK_Error)
+      *HasError = true;
+
+    SMD.print(nullptr, errs());
+
+    // For testing purposes, we print the LocCookie here.
+    if (DISM.isInlineAsmDiag() && DISM.getLocCookie())
+      WithColor::note() << "!srcloc = " << DISM.getLocCookie() << "\n";
+
+    return true;
+  }
+
+  if (DI.getSeverity() == DS_Error)
+    *HasError = true;
+
+  if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
+    if (!Remark->isEnabled())
+      return true;
+
+  DiagnosticPrinterRawOStream DP(errs());
+  errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
+  DI.print(DP);
+  errs() << "\n";
+  return true;
+}
+
+static llvm::ExitOnError ExitOnErr;
+
+static void RunPasses(bool CompileTwice, bool BOS, ToolOutputFile *Out,
+                      Module *M, LLVMContext &Context,
+                      SmallVector<char, 0> &Buffer, ModulePassManager *MPM,
+                      ModuleAnalysisManager *MAM,
+                      MachineFunctionPassManager &MFPM,
+                      MachineFunctionAnalysisManager &MFAM) {
+  auto RunPM = [=, &MFPM, &MFAM]() {
+    if (MPM) {
+      assert(MAM);
+      MPM->run(*M, *MAM);
+    }
+
+    ExitOnErr(MFPM.run(*M, MFAM));
+  };
+
+  assert(M && "invalid input module!");
+
+  // Before executing passes, print the final values of the LLVM options.
+  cl::PrintOptionValues();
+
+  // If requested, run the pass manager over the same module again,
+  // to catch any bugs due to persistent state in the passes. Note that
+  // opt has the same functionality, so it may be worth abstracting this out
+  // in the future.
+  SmallVector<char, 0> CompileTwiceBuffer;
+  if (CompileTwice) {
+    std::unique_ptr<Module> M2(llvm::CloneModule(*M));
+    RunPM();
+    CompileTwiceBuffer = Buffer;
+    Buffer.clear();
+  }
+
+  RunPM();
+
+  auto HasError =
+      ((const LLCDiagnosticHandler *)(Context.getDiagHandlerPtr()))->HasError;
+  if (*HasError)
+    exit(1);
+
+  // Compare the two outputs and make sure they're the same
+  if (CompileTwice) {
+    if (Buffer.size() != CompileTwiceBuffer.size() ||
+        (memcmp(Buffer.data(), CompileTwiceBuffer.data(), Buffer.size()) !=
+         0)) {
+      errs() << "Running the pass manager twice changed the output.\n"
+                "Writing the result of the second run to the specified output\n"
+                "To generate the one-run comparison binary, just run without\n"
+                "the compile-twice option\n";
+      Out->os() << Buffer;
+      Out->keep();
+      exit(1);
+    }
+  }
+
+  if (BOS)
+    Out->os() << Buffer;
+}
+
+int llvm::compileModuleWithNewPM(
+    StringRef Arg0, std::unique_ptr<Module> M, std::unique_ptr<MIRParser> MIR,
+    std::unique_ptr<TargetMachine> Target, std::unique_ptr<ToolOutputFile> Out,
+    std::unique_ptr<ToolOutputFile> DwoOut, LLVMContext &Context,
+    const TargetLibraryInfoImpl &TLII, bool NoVerify, bool CompileTwice,
+    const std::vector<std::string> &RunPassNames, CodeGenFileType FileType) {
+
+  if (!RunPassNames.empty() && TargetPassConfig::hasLimitedCodeGenPipeline()) {
+    WithColor::warning(errs(), Arg0)
+        << "run-pass cannot be used with "
+        << TargetPassConfig::getLimitedCodeGenPipelineReason(" and ") << ".\n";
+    return 1;
+  }
+
+  LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine &>(*Target);
+
+  {
+    raw_pwrite_stream *OS = &Out->os();
+
+    // Manually do the buffering rather than using buffer_ostream,
+    // so we can memcmp the contents in CompileTwice mode
+    SmallVector<char, 0> Buffer;
+    std::unique_ptr<raw_svector_ostream> BOS;
+    if ((codegen::getFileType() != CodeGenFileType::AssemblyFile &&
+         !Out->os().supportsSeeking()) ||
+        CompileTwice) {
+      BOS = std::make_unique<raw_svector_ostream>(Buffer);
+      OS = BOS.get();
+    }
+
+    // Fetch options from TargetPassConfig
+    CGPassBuilderOption Opt = getCGPassBuilderOption();
+    Opt.DisableVerify = NoVerify;
+    Opt.DebugPM = DebugPM;
+    Opt.RegAlloc = RegAlloc;
+
+    PassInstrumentationCallbacks PIC;
+    StandardInstrumentations SI(Context, Opt.DebugPM);
+    SI.registerCallbacks(PIC);
+    registerCodeGenCallback(PIC, LLVMTM);
+
+    LoopAnalysisManager LAM;
+    FunctionAnalysisManager FAM;
+    CGSCCAnalysisManager CGAM;
+    ModuleAnalysisManager MAM;
+    PassBuilder PB(Target.get(), PipelineTuningOptions(), std::nullopt, &PIC);
+    PB.registerModuleAnalyses(MAM);
+    PB.registerCGSCCAnalyses(CGAM);
+    PB.registerFunctionAnalyses(FAM);
+    PB.registerLoopAnalyses(LAM);
+    PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+
+    FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
+    MAM.registerPass([&] { return MachineModuleAnalysis(&LLVMTM); });
+
+    MachineFunctionAnalysisManager MFAM(FAM, MAM);
+
+    if (!RunPassNames.empty()) {
+      // Construct a custom pass pipeline that starts after instruction
+      // selection.
+
+      if (!MIR) {
+        WithColor::warning(errs(), Arg0) << "run-pass is for .mir file only.\n";
+        return 1;
+      }
+
+      MachineFunctionPassManager MFPM;
+      ExitOnErr(LLVMTM.parseMIRPipeline(MFPM, llvm::join(RunPassNames, ","),
+                                        Opt, MFAM, &PIC));
+      MFPM.addPass(PrintMIRPass(*OS));
+      MFPM.addPass(FreeMachineFunctionPass());
+
+      auto &MMI = MFAM.getResult<MachineModuleAnalysis>(*M);
+      if (MIR->parseMachineFunctions(*M, MMI))
+        return 1;
+
+      RunPasses(CompileTwice, BOS.get(), Out.get(), M.get(), Context, Buffer,
+                nullptr, nullptr, MFPM, MFAM);
+    } else {
+      ModulePassManager MPM;
+      MachineFunctionPassManager MFPM;
+
+      ExitOnErr(LLVMTM.buildCodeGenPipeline(MPM, MFPM, *OS,
+                                            DwoOut ? &DwoOut->os() : nullptr,
+                                            FileType, Opt, MFAM, &PIC));
+
+      // Add IR or MIR printing pass according the pass type.
+      if (PIC.isStartStopInfoRegistered()) {
+        auto &Info = PIC.getStartStopInfo();
+        if (!Info.willCompleteCodeGenPipeline()) {
+          if (Info.isStopMachineFunctionPass())
+            MFPM.addPass(PrintMIRPass(*OS));
+          else
+            MPM.addPass(PrintModulePass(*OS));
+        }
+      }
+
+      RunPasses(CompileTwice, BOS.get(), Out.get(), M.get(), Context, Buffer,
+                &MPM, &MAM, MFPM, MFAM);
+    }
+  }
+
+  // Declare success.
+  Out->keep();
+  if (DwoOut)
+    DwoOut->keep();
+
+  return 0;
+}
diff --git a/llvm/tools/llc/NewPMDriver.h b/llvm/tools/llc/NewPMDriver.h
new file mode 100644
index 000000000000000..d8310a996284cab
--- /dev/null
+++ b/llvm/tools/llc/NewPMDriver.h
@@ -0,0 +1,49 @@
+//===- NewPMDriver.h - Function to drive llc with the new PM --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// A single function which is called to drive the llc behavior for the new
+/// PassManager.
+///
+/// This is only in a separate TU with a header to avoid including all of the
+/// old pass manager headers and the new pass manager headers into the same
+/// file. Eventually all of the routines here will get folded back into
+/// llc.cpp.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TOOLS_OPT_NEWPMDRIVER_H
+#define LLVM_TOOLS_OPT_NEWPMDRIVER_H
+
+#include "llvm/IR/DiagnosticHandler.h"
+#include "llvm/Support/CodeGen.h"
+#include <memory>
+#include <vector>
+
+namespace llvm {
+class Module;
+class TargetLibraryInfoImpl;
+class TargetMachine;
+class ToolOutputFile;
+class LLVMContext;
+class MIRParser;
+
+struct LLCDiagnosticHandler : public DiagnosticHandler {
+  bool *HasError;
+  LLCDiagnosticHandler(bool *HasErrorPtr) : HasError(HasErrorPtr) {}
+  bool handleDiagnostics(const DiagnosticInfo &DI) override;
+};
+
+int compileModuleWithNewPM(
+    StringRef Arg0, std::unique_ptr<Module> M, std::unique_ptr<MIRParser> MIR,
+    std::unique_ptr<TargetMachine> Target, std::unique_ptr<ToolOutputFile> Out,
+    std::unique_ptr<ToolOutputFile> DwoOut, LLVMContext &Context,
+    const TargetLibraryInfoImpl &TLII, bool NoVerify, bool CompileTwice,
+    const std::vector<std::string> &RunPassNames, CodeGenFileType FileType);
+} // namespace llvm
+
+#endif
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index 0b174afc22ddced..c3cc47dc58b610d 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "NewPMDriver.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
@@ -66,23 +67,22 @@ static codegen::RegisterCodeGenFlags CGF;
 // and back-end code generation options are specified with the target machine.
 //
 static cl::opt<std::string>
-InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
+    InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
 
 static cl::opt<std::string>
-InputLanguage("x", cl::desc("Input language ('ir' or 'mir')"));
+    InputLanguage("x", cl::desc("Input language ('ir' or 'mir')"));
 
-static cl::opt<std::string>
-OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
+static cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"),
+                                           cl::value_desc("filename"));
 
 static cl::opt<std::string>
-    SplitDwarfOutputFile("split-dwarf-output",
-                         cl::desc(".dwo output filename"),
+    SplitDwarfOutputFile("split-dwarf-output", cl::desc(".dwo output filename"),
                          cl::value_desc("filename"));
 
 static cl::opt<unsigned>
-TimeCompilations("time-compilations", cl::Hidden, cl::init(1u),
-                 cl::value_desc("N"),
-                 cl::desc("Repeat compilation N times for timing"));
+    TimeCompilations("time-compilations", cl::Hidden, cl::init(1u),
+                     cl::value_desc("N"),
+                     cl::desc("Repeat compilation N times for timing"));
 
 static cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace"));
 
@@ -119,7 +119,7 @@ static cl::opt<char>
              cl::Prefix, cl::init('2'));
 
 static cl::opt<std::string>
-TargetTriple("mtriple", cl::desc("Override target triple for module"));
+    TargetTriple("mtriple", cl::desc("Override target triple for module"));
 
 static cl::opt<std::string> SplitDwarfFile(
     "split-dwarf-file",
@@ -129,8 +129,9 @@ static cl::opt<std::string> SplitDwarfFile(
 static cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
                               cl::desc("Do not verify input module"));
 
-static cl::opt<bool> DisableSimplifyLibCalls("disable-simplify-libcalls",
-                                             cl::desc("Disable simplify-libcalls"));
+static cl::opt<bool>
+    DisableSimplifyLibCalls("disable-simplify-libcalls",
+                            cl::desc("Disable simplify-libcalls"));
 
 static cl::opt<bool> ShowMCEncoding("show-mc-encoding", cl::Hidden,
                                     cl::desc("Show encoding in .s output"));
@@ -186,6 +187,8 @@ static cl::opt<std::string> RemarksFormat(
     cl::desc("The format used for serializing remarks (default: YAML)"),
     cl::value_desc("format"), cl::init("yaml"));
 
+static cl::opt<bool> EnableNewPassManager(
+    "enable-new-pm", cl::desc("Enable the new pass manager"), cl::init(false));
 namespace {
 
 std::vector<std::string> &getRunPassNames() {
@@ -203,7 +206,7 @@ struct RunPassOption {
       getRunPassNames().push_back(std::string(PassName));
   }
 };
-}
+} // namespace
 
 static RunPassOption RunPassOpt;
 
@@ -299,41 +302,6 @@ static std::unique_ptr<ToolOutputFile> GetOutputStream(const char *TargetName,
   return FDOut;
 }
 
-struct LLCDiagnosticHandler : public DiagnosticHandler {
-  bool *HasError;
-  LLCDiagnosticHandler(bool *HasErrorPtr) : HasError(HasErrorPtr) {}
-  bool handleDiagnostics(const DiagnosticInfo &DI) override {
-    if (DI.getKind() == llvm::DK_SrcMgr) {
-      const auto &DISM = cast<DiagnosticInfoSrcMgr>(DI);
-      const SMDiagnostic &SMD = DISM.getSMDiag();
-
-      if (SMD.getKind() == SourceMgr::DK_Error)
-        *HasError = true;
-
-      SMD.print(nullptr, errs());
-
-      // For testing purposes, we print the LocCookie here.
-      if (DISM.isInlineAsmDiag() && DISM.getLocCookie())
-        WithColor::note() << "!srcloc = " << DISM.getLocCookie() << "\n";
-
-      return true;
-    }
-
-    if (DI.getSeverity() == DS_Error)
-      *HasError = true;
-
-    if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
-      if (!Remark->isEnabled())
-        return true;
-
-    DiagnosticPrinterRawOStream DP(errs());
-    errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
-    DI.print(DP);
-    errs() << "\n";
-    return true;
-  }
-};
-
 // main - Entry point for the llc compiler.
 //
 int main(int argc, char **argv) {
@@ -421,8 +389,8 @@ int main(int argc, char **argv) {
   return 0;
 }
 
-static bool addPass(PassManagerBase &PM, const char *argv0,
-                    StringRef PassName, TargetPassConfig &TPC) {
+static bool addPass(PassManagerBase &PM, const char *argv0, StringRef PassName,
+                    TargetPassConfig &TPC) {
   if (PassName == "none")
     return false;
 
@@ -619,7 +587,8 @@ static int compileModule(char **argv, LLVMContext &Context) {
   // Figure out where we are going to send the output.
   std::unique_ptr<ToolOutputFile> Out =
       GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]);
-  if (!Out) return 1;
+  if (!Out)
+    return 1;
 
   // Ensure the filename is passed down to CodeViewDebug.
   Target->Options.ObjectFilenameForDebug = Out->outputFilename();
@@ -628,21 +597,17 @@ static int compileModule(char **argv, LLVMContext &Context) {
   if (!SplitDwarfOutputFile.empty()) {
     std::error_code EC;
     DwoOut = std::make_unique<ToolOutputFile>(SplitDwarfOutputFile, EC,
-                                               sys::fs::OF_None);
+                                              sys::fs::OF_None);
     if (EC)
       reportError(EC.message(), SplitDwarfOutputFile);
   }
 
-  // Build up all of the passes that we want to do to the module.
-  legacy::PassManager PM;
-
   // Add an appropriate TargetLibraryInfo pass for the module's triple.
   TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple()));
 
   // The -disable-simplify-libcalls flag actually disables all builtin optzns.
   if (DisableSimplifyLibCalls)
     TLII.disableAllFunctions();
-  PM.add(new TargetLibraryInfoWrapperPass(TLII));
 
   // Verify module immediately to catch problems before doInitialization() is
   // called on any passes.
@@ -658,6 +623,19 @@ static int compileModule(char **argv, LLVMContext &Context) {
     WithColor::warning(errs(), argv[0])
         << ": warning: ignoring -mc-relax-all because filetype != obj";
 
+  bool RunPassNone =
+      !getRunPassNames().empty() && getRunPassNames().at(0) == "none";
+  if (EnableNewPassManager && !RunPassNone) {
+    return compileModuleWithNewPM(
+        argv[0], std::move(M), std::move(MIR), std::move(Target),
+        std::move(Out), std::move(DwoOut), Context, TLII, NoVerify,
+        CompileTwice, getRunPassNames(), codegen::getFileType());
+  }
+
+  // Build up all of the passes that we want to do to the module.
+  legacy::PassManager PM;
+  PM.add(new TargetLibraryInfoWrapperPass(TLII));
+
   {
     raw_pwrite_stream *OS = &Out->os();
 



More information about the llvm-commits mailing list