[llvm] [NewPM][CodeGen] add TargetPassConfig like API (PR #70906)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 23 22:53:50 PST 2024


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

>From d9bb84d2ce03689a5e6d8ad3d20fe0e37ac28628 Mon Sep 17 00:00:00 2001
From: paperchalice <liujunchang97 at outlook.com>
Date: Wed, 1 Nov 2023 10:41:58 +0800
Subject: [PATCH 1/3] [NewPM][CodeGen] add TargetPassConfig like API

---
 .../include/llvm/CodeGen/MachinePassManager.h |  11 +-
 llvm/include/llvm/Passes/CodeGenPassBuilder.h | 328 ++++++++++++++----
 llvm/lib/CodeGen/MachinePassManager.cpp       |  18 +-
 3 files changed, 266 insertions(+), 91 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h
index a2641a8223646d..c55b7ed157b4e3 100644
--- a/llvm/include/llvm/CodeGen/MachinePassManager.h
+++ b/llvm/include/llvm/CodeGen/MachinePassManager.h
@@ -27,6 +27,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Target/CGPassBuilderOption.h"
 
 #include <map>
 
@@ -150,10 +151,7 @@ class MachineFunctionPassManager
   using Base = PassManager<MachineFunction, MachineFunctionAnalysisManager>;
 
 public:
-  MachineFunctionPassManager(bool RequireCodeGenSCCOrder = false,
-                             bool VerifyMachineFunction = false)
-      : RequireCodeGenSCCOrder(RequireCodeGenSCCOrder),
-        VerifyMachineFunction(VerifyMachineFunction) {}
+  MachineFunctionPassManager() : Opt(getCGPassBuilderOption()) {}
   MachineFunctionPassManager(MachineFunctionPassManager &&) = default;
   MachineFunctionPassManager &
   operator=(MachineFunctionPassManager &&) = default;
@@ -261,10 +259,7 @@ class MachineFunctionPassManager
   using PassIndex = decltype(Passes)::size_type;
   std::map<PassIndex, llvm::unique_function<FuncTy>> MachineModulePasses;
 
-  // Run codegen in the SCC order.
-  bool RequireCodeGenSCCOrder;
-
-  bool VerifyMachineFunction;
+  CGPassBuilderOption Opt;
 };
 
 } // end namespace llvm
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 07afac3bcf8401..9800f4dd519428 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -12,8 +12,8 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_PASSES_CODEGENPASSBUILDER_H
-#define LLVM_PASSES_CODEGENPASSBUILDER_H
+#ifndef LLVM_CODEGEN_CODEGENPASSBUILDER_H
+#define LLVM_CODEGEN_CODEGENPASSBUILDER_H
 
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -27,8 +27,11 @@
 #include "llvm/CodeGen/CallBrPrepare.h"
 #include "llvm/CodeGen/CodeGenPrepare.h"
 #include "llvm/CodeGen/DwarfEHPrepare.h"
+#include "llvm/CodeGen/ExpandLargeDivRem.h"
+#include "llvm/CodeGen/ExpandLargeFpConvert.h"
 #include "llvm/CodeGen/ExpandMemCmp.h"
 #include "llvm/CodeGen/ExpandReductions.h"
+#include "llvm/CodeGen/ExpandVectorPredication.h"
 #include "llvm/CodeGen/GCMetadata.h"
 #include "llvm/CodeGen/GlobalMerge.h"
 #include "llvm/CodeGen/IndirectBrExpand.h"
@@ -57,6 +60,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/WithColor.h"
 #include "llvm/Target/CGPassBuilderOption.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/CFGuard.h"
@@ -67,7 +71,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>
@@ -116,7 +123,7 @@ namespace llvm {
     }                                                                          \
     static AnalysisKey Key;                                                    \
   };
-#include "llvm/Passes/MachinePassRegistry.def"
+#include "llvm/CodeGen/MachinePassRegistry.def"
 
 /// This class provides access to building LLVM's passes.
 ///
@@ -124,6 +131,17 @@ namespace llvm {
 /// construction. The \c MachinePassRegistry.def file specifies how to construct
 /// all of the built-in passes, and those may reference these members during
 /// construction.
+///
+/// Target should provide following methods:
+/// Parse single target-specific MIR pass
+/// @param Name the pass name
+/// @return true if failed
+/// addPreISel - This method should add any "last minute" LLVM->LLVM
+/// passes (which are run just before instruction selector).
+/// void addPreISel(AddIRPass &) const;
+///
+/// void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
+
 template <typename DerivedT> class CodeGenPassBuilder {
 public:
   explicit CodeGenPassBuilder(LLVMTargetMachine &TM, CGPassBuilderOption Opts,
@@ -148,6 +166,28 @@ template <typename DerivedT> class CodeGenPassBuilder {
                       raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
                       CodeGenFileType FileType) const;
 
+  /// Parse single non-target-specific MIR pass
+  /// @param Name the pass name
+  /// @return true if failed
+  bool parseMIRPass(MachineFunctionPassManager &MFPM, StringRef Name) const;
+
+  /// 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
+  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;
@@ -160,12 +200,12 @@ template <typename DerivedT> class CodeGenPassBuilder {
   }
 
   PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
-    return PIC;
+    static PassInstrumentationCallbacks PseudoPIC;
+    return PIC ? PIC : &PseudoPIC;
   }
 
 protected:
   template <typename PassT> using has_key_t = decltype(PassT::Key);
-
   template <typename PassT>
   using is_module_pass_t = decltype(std::declval<PassT &>().run(
       std::declval<Module &>(), std::declval<ModuleAnalysisManager &>()));
@@ -253,6 +293,30 @@ template <typename DerivedT> class CodeGenPassBuilder {
     const DerivedT &PB;
   };
 
+  // Find the FSProfile file name. The internal option takes the precedence
+  // before getting from TargetMachine.
+  // TODO: Use PGOOptions only.
+  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.
+  // TODO: Use PGOOptions only.
+  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;
+  }
+
   LLVMTargetMachine &TM;
   CGPassBuilderOption Opt;
   PassInstrumentationCallbacks *PIC;
@@ -261,9 +325,6 @@ template <typename DerivedT> class CodeGenPassBuilder {
   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(); }
@@ -334,12 +395,14 @@ 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
-  // position and remove the `2` suffix here as this callback is what
-  // `addPreEmitPass` *should* be but in reality isn't.
-  void addPreEmitPass2(AddMachinePass &) const {}
+  /// This function replaces `addPreEmitPass2` in TargetConfig.
+  void addPrecedingEmitPass(AddMachinePass &) const {}
 
   /// {{@ For GlobalISel
   ///
@@ -399,7 +462,7 @@ template <typename DerivedT> class CodeGenPassBuilder {
   /// representation to the MI representation.
   /// Adds IR based lowering and target specific optimization passes and finally
   /// the core instruction selection passes.
-  void addISelPasses(AddIRPass &) const;
+  Error addISelPasses(AddIRPass &, AddMachinePass &) const;
 
   /// Add the actual instruction selection passes. This does not include
   /// preparation passes on IR.
@@ -439,21 +502,58 @@ 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;
+  Error addOptimizedRegAlloc(AddMachinePass &) const;
 
   /// 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(AddMachinePass &addPass, const std::string &Banner) const {
+    bool Verify = Opt.VerifyMachineCode.value_or(false);
+#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);
+  }
+
   using CreateMCStreamer =
       std::function<Expected<std::unique_ptr<MCStreamer>>(MCContext &)>;
   void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const {
@@ -471,10 +571,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); }
@@ -515,10 +615,8 @@ Error CodeGenPassBuilder<Derived>::buildPipeline(
   // `ProfileSummaryInfo` is always valid.
   addIRPass(RequireAnalysisPass<ProfileSummaryAnalysis, Module>());
   addIRPass(RequireAnalysisPass<CollectorMetadataAnalysis, Module>());
-  addISelPasses(addIRPass);
-
   AddMachinePass addPass(MFPM, derived());
-  if (auto Err = addCoreISelPasses(addPass))
+  if (auto Err = addISelPasses(addIRPass, addPass))
     return std::move(Err);
 
   if (auto Err = derived().addMachinePasses(addPass))
@@ -619,12 +717,14 @@ void CodeGenPassBuilder<Derived>::registerModuleAnalyses(
   MAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });
 #include "MachinePassRegistry.def"
   derived().registerTargetAnalysis(MAM);
+  // TODO: add SCC order codegen
 }
 
 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; });
@@ -676,7 +776,7 @@ CodeGenPassBuilder<Derived>::getPassNameFromLegacyName(StringRef Name) const {
 #define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \
   if (Name == NAME)                                                            \
     Ret = {#PASS_NAME, true};
-#include "llvm/Passes/MachinePassRegistry.def"
+#include "llvm/CodeGen/MachinePassRegistry.def"
 
   if (Ret.first.empty())
     Ret = derived().getTargetPassNameFromLegacyName(Name);
@@ -689,17 +789,24 @@ CodeGenPassBuilder<Derived>::getPassNameFromLegacyName(StringRef Name) const {
 }
 
 template <typename Derived>
-void CodeGenPassBuilder<Derived>::addISelPasses(AddIRPass &addPass) const {
+Error CodeGenPassBuilder<Derived>::addISelPasses(
+    AddIRPass &addPass, AddMachinePass &addMachinePass) const {
   derived().addGlobalMergePass(addPass);
   if (TM.useEmulatedTLS())
     addPass(LowerEmuTLSPass());
 
   addPass(PreISelIntrinsicLoweringPass(TM));
+  addPass(ExpandLargeDivRemPass(&TM));
+  addPass(ExpandLargeFpConvertPass(&TM));
 
   derived().addIRPasses(addPass);
   derived().addCodeGenPrepare(addPass);
   addPassesToHandleExceptions(addPass);
   derived().addISelPrepare(addPass);
+
+  if (auto Err = addCoreISelPasses(addMachinePass))
+    return std::move(Err);
+  return Error::success();
 }
 
 /// Add common target configurable passes that perform LLVM IR to IR transforms
@@ -711,16 +818,15 @@ 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));
-    // 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));
+      addPass(createFunctionToLoopPassAdaptor(LoopStrengthReducePass(),
+                                              /*UseMemorySSA=*/true));
+    }
+
     // 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
@@ -736,6 +842,12 @@ void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
   addPass(ShadowStackGCLoweringPass());
   addPass(LowerConstantIntrinsicsPass());
 
+  // 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());
 
@@ -752,8 +864,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,
@@ -761,7 +875,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)
@@ -821,8 +940,6 @@ template <typename Derived>
 void CodeGenPassBuilder<Derived>::addCodeGenPrepare(AddIRPass &addPass) const {
   if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableCGP)
     addPass(CodeGenPreparePass(&TM));
-  // TODO: Default ctor'd RewriteSymbolPass is no-op.
-  // addPass(RewriteSymbolPass());
 }
 
 /// Add common passes that perform LLVM IR to IR transforms in preparation for
@@ -919,8 +1036,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();
 }
 
@@ -957,10 +1073,24 @@ Error CodeGenPassBuilder<Derived>::addMachinePasses(
   // Run pre-ra passes.
   derived().addPreRegAlloc(addPass);
 
+  // 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(MIRProfileLoaderNewPass(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) {
-    derived().addOptimizedRegAlloc(addPass);
+  bool IsOptimizeRegAlloc =
+      Opt.OptimizeRegAlloc.value_or(getOptLevel() != CodeGenOptLevel::None);
+  if (IsOptimizeRegAlloc) {
+    if (auto Err = derived().addOptimizedRegAlloc(addPass))
+      return Err;
   } else {
     if (auto Err = derived().addFastRegAlloc(addPass))
       return Err;
@@ -971,12 +1101,16 @@ 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());
   }
 
+  // Prolog/Epilog inserter needs a TargetMachine to instantiate.
   addPass(PrologEpilogInserterPass());
 
   /// Add passes that optimize machine instructions after register allocation.
@@ -1003,9 +1137,6 @@ Error CodeGenPassBuilder<Derived>::addMachinePasses(
       addPass(PostRASchedulerPass());
   }
 
-  // GC
-  derived().addGCPasses(addPass);
-
   // Basic block placement.
   if (getOptLevel() != CodeGenOptLevel::None)
     derived().addBlockPlacement(addPass);
@@ -1039,8 +1170,51 @@ 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(MIRProfileLoaderNewPass(
+            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);
+  derived().addPrecedingEmitPass(addPass);
 
   return Error::success();
 }
@@ -1113,33 +1287,51 @@ void CodeGenPassBuilder<Derived>::addTargetRegisterAllocator(
 template <typename Derived>
 void CodeGenPassBuilder<Derived>::addRegAllocPass(AddMachinePass &addPass,
                                                   bool Optimized) const {
-  // TODO: Parse Opt.RegAlloc to add register allocator.
+  if (Opt.RegAlloc == RegAllocType::Default)
+    // With no -regalloc= override, ask the target for a regalloc pass.
+    derived().addTargetRegisterAllocator(addPass, Optimized);
+  else if (Opt.RegAlloc == RegAllocType::Basic)
+    addPass(RABasicPass());
+  else if (Opt.RegAlloc == RegAllocType::Fast)
+    addPass(RAFastPass());
+  else if (Opt.RegAlloc == RegAllocType::Greedy)
+    addPass(RAGreedyPass());
+  else if (Opt.RegAlloc == RegAllocType::PBQP)
+    addPass(RAPBQPPass());
+  else
+    llvm_unreachable("unknonwn register allocator type");
 }
 
 template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addRegAssignmentFast(
+Error CodeGenPassBuilder<Derived>::addRegAssignAndRewriteFast(
     AddMachinePass &addPass) const {
-  // TODO: Ensure allocator is default or fast.
-  addRegAllocPass(addPass, false);
-  return Error::success();
+  if (Opt.RegAlloc != RegAllocType::Default &&
+      Opt.RegAlloc != RegAllocType::Fast)
+    return make_error<StringError>(
+        "Must use fast (default) register allocator for unoptimized regalloc.",
+        inconvertibleErrorCode());
+
+  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 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();
 }
@@ -1151,14 +1343,14 @@ 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
 /// optimized register allocation, including coalescing, machine instruction
 /// scheduling, and register allocation itself.
 template <typename Derived>
-void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
+Error CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
     AddMachinePass &addPass) const {
   addPass(DetectDeadLanesPass());
 
@@ -1182,7 +1374,8 @@ void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
   // PreRA instruction scheduling.
   addPass(MachineSchedulerPass());
 
-  if (derived().addRegAssignmentOptimized(addPass)) {
+  Error E = derived().addRegAssignAndRewriteOptimized(addPass);
+  if (!E) {
     // Allow targets to expand pseudo instructions depending on the choice of
     // registers before MachineCopyPropagation.
     derived().addPostRewrite(addPass);
@@ -1196,6 +1389,7 @@ void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
     // FIXME: can this move into MachineLateOptimization?
     addPass(MachineLICMPass());
   }
+  return E;
 }
 
 //===---------------------------------------------------------------------===//
@@ -1235,4 +1429,4 @@ void CodeGenPassBuilder<Derived>::addBlockPlacement(
 
 } // namespace llvm
 
-#endif // LLVM_PASSES_CODEGENPASSBUILDER_H
+#endif // LLVM_CODEGEN_CODEGENPASSBUILDER_H
diff --git a/llvm/lib/CodeGen/MachinePassManager.cpp b/llvm/lib/CodeGen/MachinePassManager.cpp
index 914e6b19fde9ac..52722cad0c2ce9 100644
--- a/llvm/lib/CodeGen/MachinePassManager.cpp
+++ b/llvm/lib/CodeGen/MachinePassManager.cpp
@@ -22,6 +22,7 @@ template class AllAnalysesOn<MachineFunction>;
 template class AnalysisManager<MachineFunction>;
 template class PassManager<MachineFunction>;
 
+// TODO: Add a way to run verifier and debugify passes.
 Error MachineFunctionPassManager::run(Module &M,
                                       MachineFunctionAnalysisManager &MFAM) {
   // MachineModuleAnalysis is a module analysis pass that is never invalidated
@@ -30,26 +31,11 @@ Error MachineFunctionPassManager::run(Module &M,
   // result of MachineModuleAnalysis. MMI should not be recomputed.
   auto &MMI = MFAM.getResult<MachineModuleAnalysis>(M);
 
-  (void)RequireCodeGenSCCOrder;
-  assert(!RequireCodeGenSCCOrder && "not implemented");
+  assert(!Opt.RequiresCodeGenSCCOrder && "not implemented");
 
   // M is unused here
   PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(M);
 
-  // Add a PIC to verify machine functions.
-  if (VerifyMachineFunction) {
-    // 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.
-    PI.pushBeforeNonSkippedPassCallback([&MFAM](StringRef PassID, Any IR) {
-      assert(llvm::any_cast<const MachineFunction *>(&IR));
-      const MachineFunction *MF = llvm::any_cast<const MachineFunction *>(IR);
-      assert(MF && "Machine function should be valid for printing");
-      std::string Banner = std::string("After ") + std::string(PassID);
-      verifyMachineFunction(&MFAM, Banner, *MF);
-    });
-  }
-
   for (auto &F : InitializationFuncs) {
     if (auto Err = F(M, MFAM))
       return Err;

>From df8863f91e0a8432d1ba6a2ca1037b2fe3d032ee Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Wed, 24 Jan 2024 11:54:58 +0800
Subject: [PATCH 2/3] Remove MachinePassKey

---
 llvm/include/llvm/CodeGen/MachinePassManager.h  |  9 +--------
 llvm/include/llvm/Passes/CodeGenPassBuilder.h   | 13 +++----------
 llvm/lib/Passes/CodeGenPassBuilder.cpp          |  5 -----
 llvm/unittests/MIR/PassBuilderCallbacksTest.cpp |  4 ----
 4 files changed, 4 insertions(+), 27 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h
index c55b7ed157b4e3..e69b10b7eaafde 100644
--- a/llvm/include/llvm/CodeGen/MachinePassManager.h
+++ b/llvm/include/llvm/CodeGen/MachinePassManager.h
@@ -38,20 +38,13 @@ class MachineFunction;
 
 extern template class AnalysisManager<MachineFunction>;
 
-/// Like \c AnalysisKey, but only for machine passes.
-struct alignas(8) MachinePassKey {};
-
 /// A CRTP mix-in that provides informational APIs needed for machine passes.
 ///
 /// This provides some boilerplate for types that are machine passes. It
 /// automatically mixes in \c PassInfoMixin.
 template <typename DerivedT>
 struct MachinePassInfoMixin : public PassInfoMixin<DerivedT> {
-  static MachinePassKey *ID() {
-    static_assert(std::is_base_of<MachinePassInfoMixin, DerivedT>::value,
-                  "Must pass the derived type as the template argument!");
-    return &DerivedT::Key;
-  }
+  // TODO: Add MachineFunctionProperties support.
 };
 
 /// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 9800f4dd519428..41740a916d9931 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -101,7 +101,6 @@ namespace llvm {
                           MachineFunctionAnalysisManager &) {                  \
       llvm_unreachable("this api is to make new PM api happy");                \
     }                                                                          \
-    static MachinePassKey Key;                                                 \
   };
 #define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \
   struct PASS_NAME : public MachinePassInfoMixin<PASS_NAME> {                  \
@@ -110,7 +109,6 @@ namespace llvm {
                           MachineFunctionAnalysisManager &) {                  \
       return PreservedAnalyses::all();                                         \
     }                                                                          \
-    static MachinePassKey Key;                                                 \
   };
 #define DUMMY_MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)          \
   struct PASS_NAME : public AnalysisInfoMixin<PASS_NAME> {                     \
@@ -205,7 +203,6 @@ template <typename DerivedT> class CodeGenPassBuilder {
   }
 
 protected:
-  template <typename PassT> using has_key_t = decltype(PassT::Key);
   template <typename PassT>
   using is_module_pass_t = decltype(std::declval<PassT &>().run(
       std::declval<Module &>(), std::declval<ModuleAnalysisManager &>()));
@@ -265,10 +262,6 @@ template <typename DerivedT> class CodeGenPassBuilder {
         : PM(PM), PB(PB) {}
 
     template <typename PassT> void operator()(PassT &&Pass) {
-      static_assert(
-          is_detected<has_key_t, PassT>::value,
-          "Machine function pass must define a static member variable `Key`.");
-
       if (!PB.runBeforeAdding(PassT::name()))
         return;
 
@@ -278,10 +271,10 @@ template <typename DerivedT> class CodeGenPassBuilder {
         C(PassT::name());
     }
 
-    template <typename PassT> void insertPass(MachinePassKey *ID, PassT Pass) {
+    template <typename PassT> void insertPass(StringRef Name, PassT Pass) {
       PB.AfterCallbacks.emplace_back(
-          [this, ID, Pass = std::move(Pass)](MachinePassKey *PassID) {
-            if (PassID == ID)
+          [this, Name, Pass = std::move(Pass)](StringRef PassName) {
+            if (Name == PassName)
               this->PM.addPass(std::move(Pass));
           });
     }
diff --git a/llvm/lib/Passes/CodeGenPassBuilder.cpp b/llvm/lib/Passes/CodeGenPassBuilder.cpp
index c0319e5d6e404a..927727cba6fc6c 100644
--- a/llvm/lib/Passes/CodeGenPassBuilder.cpp
+++ b/llvm/lib/Passes/CodeGenPassBuilder.cpp
@@ -16,11 +16,6 @@
 using namespace llvm;
 
 namespace llvm {
-#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)                \
-  MachinePassKey PASS_NAME::Key;
-#include "llvm/Passes/MachinePassRegistry.def"
-#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)              \
-  MachinePassKey PASS_NAME::Key;
 #define DUMMY_MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)          \
   AnalysisKey PASS_NAME::Key;
 #include "llvm/Passes/MachinePassRegistry.def"
diff --git a/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp b/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp
index 5ab4df1c26df3e..88522d45bc6bfa 100644
--- a/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp
+++ b/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp
@@ -248,7 +248,6 @@ template <typename DerivedT> class MockPassHandleBase {
     }
 
   public:
-    static MachinePassKey Key;
     PreservedAnalyses run(MachineFunction &IR,
                           MachineFunctionAnalysisManager::Base &AM) {
       return Handle->run(IR, AM);
@@ -279,9 +278,6 @@ struct MockAnalysisHandle : public MockAnalysisHandleBase<MockAnalysisHandle> {
   MockAnalysisHandle() { setDefaults(); }
 };
 
-template <typename DerivedT>
-MachinePassKey MockPassHandleBase<DerivedT>::Pass::Key;
-
 template <typename DerivedT>
 AnalysisKey MockAnalysisHandleBase<DerivedT>::Analysis::Key;
 

>From 7730fa240b77d59d7a67221c5bbec987c030cbe7 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Wed, 24 Jan 2024 14:49:59 +0800
Subject: [PATCH 3/3] Add RegAlloc support

---
 llvm/include/llvm/Passes/CodeGenPassBuilder.h | 121 ++++--------------
 .../llvm/Passes/MachinePassRegistry.def       |  22 +++-
 llvm/include/llvm/Passes/PassBuilder.h        |  14 ++
 llvm/include/llvm/Target/TargetMachine.h      |   6 +-
 llvm/lib/Passes/PassBuilder.cpp               |  37 ++++++
 llvm/lib/Target/X86/CMakeLists.txt            |   1 +
 llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp |  11 +-
 llvm/lib/Target/X86/X86TargetMachine.h        |   6 +-
 llvm/test/tools/llc/new-pm/pipeline.ll        |   3 +-
 llvm/tools/llc/NewPMDriver.cpp                |   2 +-
 10 files changed, 109 insertions(+), 114 deletions(-)

diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index 41740a916d9931..5db439881465fe 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -56,6 +56,7 @@
 #include "llvm/IRPrinter/IRPrintingPasses.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Passes/PassBuilder.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Error.h"
@@ -121,7 +122,7 @@ namespace llvm {
     }                                                                          \
     static AnalysisKey Key;                                                    \
   };
-#include "llvm/CodeGen/MachinePassRegistry.def"
+#include "llvm/Passes/MachinePassRegistry.def"
 
 /// This class provides access to building LLVM's passes.
 ///
@@ -142,9 +143,10 @@ namespace llvm {
 
 template <typename DerivedT> class CodeGenPassBuilder {
 public:
-  explicit CodeGenPassBuilder(LLVMTargetMachine &TM, CGPassBuilderOption Opts,
+  explicit CodeGenPassBuilder(LLVMTargetMachine &TM, PassBuilder &PB,
+                              CGPassBuilderOption Opts,
                               PassInstrumentationCallbacks *PIC)
-      : TM(TM), Opt(Opts), PIC(PIC) {
+      : TM(TM), PB(PB), Opt(Opts), PIC(PIC) {
     // Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
     //     substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
 
@@ -164,28 +166,6 @@ template <typename DerivedT> class CodeGenPassBuilder {
                       raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
                       CodeGenFileType FileType) const;
 
-  /// Parse single non-target-specific MIR pass
-  /// @param Name the pass name
-  /// @return true if failed
-  bool parseMIRPass(MachineFunctionPassManager &MFPM, StringRef Name) const;
-
-  /// 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
-  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;
@@ -279,6 +259,8 @@ template <typename DerivedT> class CodeGenPassBuilder {
           });
     }
 
+    MachineFunctionPassManager &getPM() { return PM; }
+
     MachineFunctionPassManager releasePM() { return std::move(PM); }
 
   private:
@@ -311,14 +293,10 @@ template <typename DerivedT> class CodeGenPassBuilder {
   }
 
   LLVMTargetMachine &TM;
+  PassBuilder &PB;
   CGPassBuilderOption Opt;
   PassInstrumentationCallbacks *PIC;
 
-  /// Target override these hooks to parse target-specific analyses.
-  void registerTargetAnalysis(ModuleAnalysisManager &) const {}
-  void registerTargetAnalysis(FunctionAnalysisManager &) const {}
-  void registerTargetAnalysis(MachineFunctionAnalysisManager &) const {}
-
   template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
   CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
 
@@ -556,14 +534,6 @@ template <typename DerivedT> class CodeGenPassBuilder {
   /// Utilities for targets to add passes to the pass manager.
   ///
 
-  /// createTargetRegisterAllocator - Create the register allocator pass for
-  /// this target at the current optimization level.
-  void addTargetRegisterAllocator(AddMachinePass &, bool Optimized) const;
-
-  /// addMachinePasses helper to create the target-selected or overriden
-  /// regalloc pass.
-  void addRegAllocPass(AddMachinePass &, bool Optimized) 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;
@@ -1257,54 +1227,16 @@ void CodeGenPassBuilder<Derived>::addMachineSSAOptimization(
 /// Register Allocation Pass Configuration
 //===---------------------------------------------------------------------===//
 
-/// Instantiate the default register allocator pass for this target for either
-/// the optimized or unoptimized allocation path. This will be added to the pass
-/// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
-/// in the optimized case.
-///
-/// A target that uses the standard regalloc pass order for fast or optimized
-/// allocation may still override this for per-target regalloc
-/// selection. But -regalloc=... always takes precedence.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addTargetRegisterAllocator(
-    AddMachinePass &addPass, bool Optimized) const {
-  if (Optimized)
-    addPass(RAGreedyPass());
-  else
-    addPass(RAFastPass());
-}
-
-/// Find and instantiate the register allocation pass requested by this target
-/// at the current optimization level.  Different register allocators are
-/// defined as separate passes because they may require different analysis.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addRegAllocPass(AddMachinePass &addPass,
-                                                  bool Optimized) const {
-  if (Opt.RegAlloc == RegAllocType::Default)
-    // With no -regalloc= override, ask the target for a regalloc pass.
-    derived().addTargetRegisterAllocator(addPass, Optimized);
-  else if (Opt.RegAlloc == RegAllocType::Basic)
-    addPass(RABasicPass());
-  else if (Opt.RegAlloc == RegAllocType::Fast)
-    addPass(RAFastPass());
-  else if (Opt.RegAlloc == RegAllocType::Greedy)
-    addPass(RAGreedyPass());
-  else if (Opt.RegAlloc == RegAllocType::PBQP)
-    addPass(RAPBQPPass());
-  else
-    llvm_unreachable("unknonwn register allocator type");
-}
-
 template <typename Derived>
 Error CodeGenPassBuilder<Derived>::addRegAssignAndRewriteFast(
     AddMachinePass &addPass) const {
-  if (Opt.RegAlloc != RegAllocType::Default &&
-      Opt.RegAlloc != RegAllocType::Fast)
+  if (Opt.RegAlloc != "default" && !Opt.RegAlloc.starts_with("fast"))
     return make_error<StringError>(
         "Must use fast (default) register allocator for unoptimized regalloc.",
         inconvertibleErrorCode());
 
-  addPass(RegAllocPass(false));
+  if (Error Err = PB.parseRegAllocPass(addPass.getPM(), Opt.RegAlloc, false))
+    return Err;
 
   // Allow targets to change the register assignments after
   // fast register allocation.
@@ -1315,7 +1247,8 @@ template <typename DerivedT>
 Error CodeGenPassBuilder<DerivedT>::addRegAssignAndRewriteOptimized(
     AddMachinePass &addPass) const {
   // Add the selected register allocation pass.
-  addRegAllocPass(addPass, true);
+  if (Error Err = PB.parseRegAllocPass(addPass.getPM(), Opt.RegAlloc, true))
+    return Err;
   // Allow targets to change the register assignments before rewriting.
   addPreRewrite(addPass);
 
@@ -1367,22 +1300,22 @@ Error CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
   // PreRA instruction scheduling.
   addPass(MachineSchedulerPass());
 
-  Error E = derived().addRegAssignAndRewriteOptimized(addPass);
-  if (!E) {
-    // Allow targets to expand pseudo instructions depending on the choice of
-    // registers before MachineCopyPropagation.
-    derived().addPostRewrite(addPass);
+  if (Error Err = derived().addRegAssignAndRewriteOptimized(addPass))
+    return Err;
 
-    // Copy propagate to forward register uses and try to eliminate COPYs that
-    // were not coalesced.
-    addPass(MachineCopyPropagationPass());
+  // Allow targets to expand pseudo instructions depending on the choice of
+  // registers before MachineCopyPropagation.
+  derived().addPostRewrite(addPass);
 
-    // Run post-ra machine LICM to hoist reloads / remats.
-    //
-    // FIXME: can this move into MachineLateOptimization?
-    addPass(MachineLICMPass());
-  }
-  return E;
+  // Copy propagate to forward register uses and try to eliminate COPYs that
+  // were not coalesced.
+  addPass(MachineCopyPropagationPass());
+
+  // Run post-ra machine LICM to hoist reloads / remats.
+  //
+  // FIXME: can this move into MachineLateOptimization?
+  addPass(MachineLICMPass());
+  return Error::success();
 }
 
 //===---------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 082e2e37c831ce..da81a7a279cda0 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -129,6 +129,23 @@ MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis,
 // MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass, ())
 #undef MACHINE_FUNCTION_PASS
 
+#ifndef RA_PASS
+#define RA_PASS(NAME, PASS_NAME, CONSTRUCTOR)
+#endif
+// RA_PASS("ra-basic", RABasicPass, ())
+#undef RA_PASS
+
+#ifndef RA_PASS_WITH_PARAMS
+#define RA_PASS_WITH_PARAMS(NAME, PASS_NAME, CREATE_PASS, PARSER, PARAMS)
+#endif
+// RA_PASS_WITH_PARAMS("fast", RAFastPass,
+//   [](Option Opts){ return RAFastPass(Opts); }, parseRAFastPassOptions, "")
+// RA_PASS_WITH_PARAMS("greedy", RAGreedyPass,
+// [](Option Opts) { return RAGreedyPass(Opts); }, parseRAGreedyPassOptions, "")
+// RA_PASS_WITH_PARAMS("pbqp", RAPBQPPass,
+//   [](Option Opts) { return  RAPBQPPass(Opts); }, parseRAPBQPPassOptions, "")
+#undef RA_PASS_WITH_PARAMS
+
 // After a pass is converted to new pass manager, its entry should be moved from
 // dummy table to the normal one. For example, for a machine function pass,
 // DUMMY_MACHINE_FUNCTION_PASS to MACHINE_FUNCTION_PASS.
@@ -225,15 +242,10 @@ DUMMY_MACHINE_FUNCTION_PASS("processimpdefs", ProcessImplicitDefsPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("prologepilog", PrologEpilogInserterPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("prologepilog-code", PrologEpilogCodeInserterPass,
                             ())
-DUMMY_MACHINE_FUNCTION_PASS("ra-basic", RABasicPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("ra-fast", RAFastPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("ra-greedy", RAGreedyPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("ra-pbqp", RAPBQPPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("reg-usage-collector", RegUsageInfoCollectorPass,
                             ())
 DUMMY_MACHINE_FUNCTION_PASS("reg-usage-propagation",
                             RegUsageInfoPropagationPass, ())
-DUMMY_MACHINE_FUNCTION_PASS("regalloc", RegAllocPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("regallocscoringpass", RegAllocScoringPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass, ())
 DUMMY_MACHINE_FUNCTION_PASS("removeredundantdebugvalues",
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 7339b8a988232d..56a2a0e56e9f34 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -370,6 +370,11 @@ class PassBuilder {
   Error parsePassPipeline(MachineFunctionPassManager &MFPM,
                           StringRef PipelineText);
 
+  /// Parse textual regalloc pass into the provided \c MachineFunctionPass
+  /// the PassText should contain only one regalloc pass text.
+  Error parseRegAllocPass(MachineFunctionPassManager &MFPM, StringRef PassText,
+                          bool Optimized);
+
   /// Parse a textual alias analysis pipeline into the provided AA manager.
   ///
   /// The format of the textual AA pipeline is a comma separated list of AA
@@ -575,6 +580,12 @@ class PassBuilder {
   }
   /// @}}
 
+  void registerRegAllocParsingCallback(
+      const std::function<bool(StringRef, MachineFunctionPassManager &, bool)>
+          &C) {
+    RegAllocPassParsingCallbacks.push_back(C);
+  }
+
   /// Register a callback for a top-level pipeline entry.
   ///
   /// If the PassManager type is not given at the top level of the pipeline
@@ -735,6 +746,9 @@ class PassBuilder {
       MachineFunctionAnalysisRegistrationCallbacks;
   SmallVector<std::function<bool(StringRef, MachineFunctionPassManager &)>, 2>
       MachinePipelineParsingCallbacks;
+  SmallVector<
+      std::function<bool(StringRef, MachineFunctionPassManager &, bool)>, 2>
+      RegAllocPassParsingCallbacks;
 };
 
 /// This utility template takes care of adding require<> and invalidate<>
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index a522a12299bb02..38109a106219d9 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -457,9 +457,9 @@ class LLVMTargetMachine : public TargetMachine {
 
   virtual Error buildCodeGenPipeline(ModulePassManager &,
                                      MachineFunctionPassManager &,
-                                     MachineFunctionAnalysisManager &,
-                                     raw_pwrite_stream &, raw_pwrite_stream *,
-                                     CodeGenFileType, CGPassBuilderOption,
+                                     PassBuilder &, raw_pwrite_stream &,
+                                     raw_pwrite_stream *, CodeGenFileType,
+                                     CGPassBuilderOption,
                                      PassInstrumentationCallbacks *) {
     return make_error<StringError>("buildCodeGenPipeline is not overridden",
                                    inconvertibleErrorCode());
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 2fe167bd439d48..b7609c4c5a03b3 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -2081,6 +2081,43 @@ Error PassBuilder::parsePassPipeline(MachineFunctionPassManager &MFPM,
   return Error::success();
 }
 
+Error PassBuilder::parseRegAllocPass(MachineFunctionPassManager &MFPM,
+                                     StringRef PassText, bool Optimized) {
+  // Targets may have their own default pipeline.
+  for (const auto &C : RegAllocPassParsingCallbacks) {
+    if (C(PassText, MFPM, Optimized))
+      return Error::success();
+  }
+
+  if (PassText == "default") {
+    if (Optimized) {
+      // TODO: MFPM.addPass(GreedyRegisterAllocatorPass());
+    } else {
+      // TODO: MFPM.addPass(FastRegisterAllocatorPass());
+    }
+    return Error::success();
+  }
+
+#define RA_PASS(NAME, PASS_NAME, CONSTRUCTOR)                                  \
+  if (PassText == NAME) {                                                      \
+    MFPM.addPass(PASS_NAME CONSTRUCTOR);                                       \
+    return Error::success();                                                   \
+  }
+#define RA_PASS_WITH_PARAMS(NAME, PASS_NAME, CREATE_PASS, PARSER, PARAMS)      \
+  if (checkParametrizedPassName(PassText, NAME)) {                             \
+    auto Params = parsePassParameters(PARSER, PassText, NAME);                 \
+    if (!Params)                                                               \
+      return Params.takeError();                                               \
+    MFPM.addPass(CREATE_PASS(Params.get()));                                   \
+    return Error::success();                                                   \
+  }
+#include "llvm/Passes/MachinePassRegistry.def"
+
+  return make_error<StringError>(
+      formatv("invalid regalloc pass '{0}'", PassText).str(),
+      inconvertibleErrorCode());
+}
+
 Error PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
   // If the pipeline just consists of the word 'default' just replace the AA
   // manager with our default one.
diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 610999f0cc3cf0..a8f8853f5d1fb6 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -102,6 +102,7 @@ add_llvm_target(X86CodeGen ${sources}
   IRPrinter
   Instrumentation
   MC
+  Passes
   ProfileData
   Scalar
   SelectionDAG
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 4a11dd2e31acde..38550c028ef3e3 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -21,10 +21,10 @@ namespace {
 
 class X86CodeGenPassBuilder : public CodeGenPassBuilder<X86CodeGenPassBuilder> {
 public:
-  explicit X86CodeGenPassBuilder(LLVMTargetMachine &TM,
+  explicit X86CodeGenPassBuilder(LLVMTargetMachine &TM, PassBuilder &PB,
                                  CGPassBuilderOption Opts,
                                  PassInstrumentationCallbacks *PIC)
-      : CodeGenPassBuilder(TM, Opts, PIC) {}
+      : CodeGenPassBuilder(TM, PB, Opts, PIC) {}
   void addPreISel(AddIRPass &addPass) const;
   void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
   Error addInstSelector(AddMachinePass &) const;
@@ -47,10 +47,9 @@ Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &) const {
 } // namespace
 
 Error X86TargetMachine::buildCodeGenPipeline(
-    ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
-    MachineFunctionAnalysisManager &, raw_pwrite_stream &Out,
-    raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
+    ModulePassManager &MPM, MachineFunctionPassManager &MFPM, PassBuilder &PB,
+    raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
     CGPassBuilderOption Opt, PassInstrumentationCallbacks *PIC) {
-  auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC);
+  auto CGPB = X86CodeGenPassBuilder(*this, PB, Opt, PIC);
   return CGPB.buildPipeline(MPM, MFPM, Out, DwoOut, FileType);
 }
diff --git a/llvm/lib/Target/X86/X86TargetMachine.h b/llvm/lib/Target/X86/X86TargetMachine.h
index f31c971df9584d..37d6f564ee3b88 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.h
+++ b/llvm/lib/Target/X86/X86TargetMachine.h
@@ -59,9 +59,9 @@ class X86TargetMachine final : public LLVMTargetMachine {
                             const TargetSubtargetInfo *STI) const override;
 
   Error buildCodeGenPipeline(ModulePassManager &, MachineFunctionPassManager &,
-                             MachineFunctionAnalysisManager &,
-                             raw_pwrite_stream &, raw_pwrite_stream *,
-                             CodeGenFileType, CGPassBuilderOption,
+                             PassBuilder &, raw_pwrite_stream &,
+                             raw_pwrite_stream *, CodeGenFileType,
+                             CGPassBuilderOption,
                              PassInstrumentationCallbacks *) override;
 
   bool isJIT() const { return IsJIT; }
diff --git a/llvm/test/tools/llc/new-pm/pipeline.ll b/llvm/test/tools/llc/new-pm/pipeline.ll
index 1ace5963e4ef8c..39953c68d97a07 100644
--- a/llvm/test/tools/llc/new-pm/pipeline.ll
+++ b/llvm/test/tools/llc/new-pm/pipeline.ll
@@ -1,5 +1,4 @@
 ; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -filetype=null %s | FileCheck %s
 
 ; CHECK: require<profile-summary>,require<collector-metadata>
-; CHECK: MachineSanitizerBinaryMetadata,FreeMachineFunctionPass
-
+; CHECK: StackFrameLayoutAnalysisPass,FreeMachineFunctionPass
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index 2f979f3081f795..b6338df7070f53 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -191,7 +191,7 @@ int llvm::compileModuleWithNewPM(
     ModulePassManager MPM;
     MachineFunctionPassManager MFPM;
 
-    ExitOnErr(LLVMTM.buildCodeGenPipeline(MPM, MFPM, MFAM, *OS,
+    ExitOnErr(LLVMTM.buildCodeGenPipeline(MPM, MFPM, PB, *OS,
                                           DwoOut ? &DwoOut->os() : nullptr,
                                           FileType, Opt, &PIC));
 



More information about the llvm-commits mailing list