[llvm] [CodeGen][NewPM] Handle `--regalloc-npm` option (PR #94748)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 7 05:42:23 PDT 2024


https://github.com/paperchalice created https://github.com/llvm/llvm-project/pull/94748

The final register allocation pass is now determined by `PassBuilder`. It uses a string map to support register class filter. Two keys are preserved, "all" and "none", "all" will allocate all register classes which is the default behavior, "none" indicates that the target doesn't need register allocation (e.g. DirectX, WASM).
However, register allocation passes are now wrapped by pass manager, start/stop options will no longer work for these passes, because I'm not sure will LLVM allow plugins to replace register allocator.
`--regalloc-npm` reuses the syntax of passes, see the test case.

>From 976c581d53e988e5fe1b67fdda0715b537456486 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 7 Jun 2024 19:42:23 +0800
Subject: [PATCH] [CodeGen][NewPM] Handle `--regalloc-npm` option The final
 register allocation pass is now determined by `PassBuilder`. However,
 register allocation passes are now wrapped by pass manager, start/stop
 options will no longer works for these passes, becuase I'm not sure will LLVM
 allow plugins to replace register allocator.

---
 llvm/include/llvm/Passes/CodeGenPassBuilder.h | 60 +++++++--------
 llvm/include/llvm/Passes/PassBuilder.h        | 21 +++++-
 llvm/include/llvm/Target/TargetMachine.h      |  2 +-
 llvm/lib/Passes/PassBuilder.cpp               | 73 ++++++++++++++++++-
 .../AMDGPU/AMDGPUCodeGenPassBuilder.cpp       | 15 +++-
 .../Target/AMDGPU/AMDGPUCodeGenPassBuilder.h  |  4 +-
 .../lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 37 ++++++++--
 llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h  |  2 +-
 .../Target/AMDGPU/R600CodeGenPassBuilder.cpp  |  8 +-
 .../Target/AMDGPU/R600CodeGenPassBuilder.h    |  2 +-
 llvm/lib/Target/AMDGPU/R600TargetMachine.cpp  | 12 +--
 llvm/lib/Target/AMDGPU/R600TargetMachine.h    |  2 +-
 llvm/lib/Target/X86/CMakeLists.txt            |  1 +
 llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp |  9 +--
 llvm/lib/Target/X86/X86TargetMachine.h        |  2 +-
 .../test/tools/llc/new-pm/regalloc-amdgpu.mir |  8 ++
 llvm/tools/llc/NewPMDriver.cpp                |  2 +-
 17 files changed, 196 insertions(+), 64 deletions(-)

diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index eef1709bce5df..efef647cfd4df 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -59,10 +59,12 @@
 #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"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Target/CGPassBuilderOption.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/CFGuard.h"
@@ -116,9 +118,8 @@ namespace llvm {
 template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 public:
   explicit CodeGenPassBuilder(TargetMachineT &TM,
-                              const CGPassBuilderOption &Opts,
-                              PassInstrumentationCallbacks *PIC)
-      : TM(TM), Opt(Opts), PIC(PIC) {
+                              const CGPassBuilderOption &Opts, PassBuilder &PB)
+      : TM(TM), Opt(Opts), PB(PB), PIC(PB.getPassInstrumentationCallbacks()) {
     // Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
     //     substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
 
@@ -253,6 +254,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   TargetMachineT &TM;
   CGPassBuilderOption Opt;
+  PassBuilder &PB;
   PassInstrumentationCallbacks *PIC;
 
   template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
@@ -453,13 +455,9 @@ template <typename DerivedT, typename TargetMachineT> 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;
+  Error addRegAllocPass(AddMachinePass &, StringRef FilterName = "all") const;
 
   /// Add core register alloator passes which do the actual register assignment
   /// and rewriting. \returns true if any passes were added.
@@ -521,6 +519,9 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
     return StartStopInfo.takeError();
   setStartStopPasses(*StartStopInfo);
 
+  if (auto Err = PB.parseRegAllocOpt(Opt.RegAlloc))
+    return Err;
+
   bool PrintAsm = TargetPassConfig::willCompleteCodeGenPipeline();
   bool PrintMIR = !PrintAsm && FileType != CodeGenFileType::Null;
 
@@ -1025,45 +1026,40 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::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, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
-    AddMachinePass &addPass, bool Optimized) const {
-  if (Optimized)
-    addPass(RAGreedyPass());
-  else
-    addPass(RegAllocFastPass());
-}
-
 /// 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, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
-    AddMachinePass &addPass, bool Optimized) const {
-  // TODO: Parse Opt.RegAlloc to add register allocator.
+Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
+    AddMachinePass &addPass, StringRef FilterName) const {
+  auto &RegAllocMap = PB.getRegAllocMap();
+  if (RegAllocMap.contains("none"))
+    return Error::success();
+
+  if (!RegAllocMap.contains(FilterName)) {
+    return make_error<StringError>(
+        formatv("No register allocator for register class filter '{0}'",
+                FilterName)
+            .str(),
+        inconvertibleErrorCode());
+  }
+
+  addPass(std::move(RegAllocMap[FilterName]));
+  return Error::success();
 }
 
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignmentFast(
     AddMachinePass &addPass) const {
-  // TODO: Ensure allocator is default or fast.
-  addRegAllocPass(addPass, false);
-  return Error::success();
+  return addRegAllocPass(addPass);
 }
 
 template <typename Derived, typename TargetMachineT>
 Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignmentOptimized(
     AddMachinePass &addPass) const {
   // Add the selected register allocation pass.
-  addRegAllocPass(addPass, true);
+  if (auto Err = addRegAllocPass(addPass))
+    return Err;
 
   // Allow targets to change the register assignments before rewriting.
   derived().addPreRewrite(addPass);
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index ed817127c3db1..7dac72a80a7f7 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -107,6 +107,7 @@ class PassBuilder {
   PipelineTuningOptions PTO;
   std::optional<PGOOptions> PGOOpt;
   PassInstrumentationCallbacks *PIC;
+  StringMap<MachineFunctionPassManager> RegAllocMap;
 
 public:
   /// A struct to capture parsed pass pipeline names.
@@ -582,12 +583,28 @@ class PassBuilder {
 
   /// Register callbacks to parse target specific filter field if regalloc pass
   /// needs it. E.g. AMDGPU requires regalloc passes can handle sgpr and vgpr
-  /// separately.
+  /// separately. Currently "all" and "none" are preserved filter name.
   void registerRegClassFilterParsingCallback(
       const std::function<RegClassFilterFunc(StringRef)> &C) {
     RegClassFilterParsingCallbacks.push_back(C);
   }
 
+  /// Parse command line option `--regalloc-npm`
+  /// Should only be called by CodeGenPassBuilder.
+  Error parseRegAllocOpt(StringRef Text);
+
+  /// Target hook to set default regalloc.
+  void setDefaultRegAllocBuilder(
+      const std::function<void(StringMap<MachineFunctionPassManager> &)> &C) {
+    DefaultRegAllocBuilder = C;
+  }
+
+  /// Used by CodeGenPassBuilder to add correct regalloc pass.
+  /// Should only be called by CodeGenPassBuilder.
+  StringMap<MachineFunctionPassManager> &getRegAllocMap() {
+    return RegAllocMap;
+  }
+
   /// Register a callback for a top-level pipeline entry.
   ///
   /// If the PassManager type is not given at the top level of the pipeline
@@ -807,6 +824,8 @@ class PassBuilder {
   // Callbacks to parse `filter` parameter in register allocation passes
   SmallVector<std::function<RegClassFilterFunc(StringRef)>, 2>
       RegClassFilterParsingCallbacks;
+  std::function<void(StringMap<MachineFunctionPassManager> &)>
+      DefaultRegAllocBuilder;
 };
 
 /// 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 1ba99730ca702..509db15088123 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -472,7 +472,7 @@ class LLVMTargetMachine : public TargetMachine {
   virtual Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
                                      raw_pwrite_stream *, CodeGenFileType,
                                      const CGPassBuilderOption &,
-                                     PassInstrumentationCallbacks *) {
+                                     PassBuilder &) {
     return make_error<StringError>("buildCodeGenPipeline is not overridden",
                                    inconvertibleErrorCode());
   }
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 2c56b04a1d9c8..7ae398ce87dbb 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -409,13 +409,33 @@ class RequireAllMachineFunctionPropertiesPass
 
 } // namespace
 
+static void defaultRegAllocBuilder(TargetMachine *TM,
+                                   StringMap<MachineFunctionPassManager> &M) {
+  if (!TM)
+    return;
+
+  MachineFunctionPassManager MFPM;
+  auto Opts = getCGPassBuilderOption();
+  if (Opts.OptimizeRegAlloc.value_or(TM->getOptLevel() !=
+                                     CodeGenOptLevel::None)) {
+    // TODO: Add greedy register allocator.
+  } else {
+    MFPM.addPass(RegAllocFastPass());
+  }
+  M["all"] = std::move(MFPM);
+}
+
 PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO,
                          std::optional<PGOOptions> PGOOpt,
                          PassInstrumentationCallbacks *PIC)
     : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {
   bool ShouldPopulateClassToPassNames = PIC && shouldPopulateClassToPassNames();
-  if (TM)
+  if (TM) {
+    DefaultRegAllocBuilder = [TM](StringMap<MachineFunctionPassManager> &M) {
+      defaultRegAllocBuilder(TM, M);
+    };
     TM->registerPassBuilderCallbacks(*this, ShouldPopulateClassToPassNames);
+  }
   if (ShouldPopulateClassToPassNames) {
 #define MODULE_PASS(NAME, CREATE_PASS)                                         \
   PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
@@ -2219,6 +2239,18 @@ Error PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
   return Error::success();
 }
 
+static StringRef getFilterName(StringRef PassName) {
+  PassName = PassName.drop_until([](char C) { return C == '<'; });
+  StringRef Params = PassName.drop_front().drop_back();
+  while (!Params.empty()) {
+    StringRef ParamName;
+    std::tie(ParamName, Params) = Params.split(';');
+    if (ParamName.consume_front("filter="))
+      return ParamName;
+  }
+  return "all";
+}
+
 RegClassFilterFunc PassBuilder::parseRegAllocFilter(StringRef FilterName) {
   if (FilterName == "all")
     return allocateAllRegClasses;
@@ -2228,6 +2260,45 @@ RegClassFilterFunc PassBuilder::parseRegAllocFilter(StringRef FilterName) {
   return nullptr;
 }
 
+Error PassBuilder::parseRegAllocOpt(StringRef Text) {
+  assert(TM && "Need target machine to parse this option!");
+  if (RegAllocMap.empty())
+    DefaultRegAllocBuilder(RegAllocMap);
+
+  MachineFunctionPassManager MFPM;
+  if (Text == "default") {
+    // Add nothing when target inserts "none" into the map.
+    if (RegAllocMap.contains("none"))
+      RegAllocMap["all"] = MachineFunctionPassManager();
+    return Error::success();
+  }
+
+  if (RegAllocMap.contains("none")) {
+    return make_error<StringError>(
+        "Target doesn't support register allocation!",
+        inconvertibleErrorCode());
+  }
+
+  bool IsOptimized = TM->getOptLevel() != CodeGenOptLevel::None;
+  while (!Text.empty()) {
+    StringRef PassName;
+    std::tie(PassName, Text) = Text.split(',');
+    if (!IsOptimized &&
+        !PassBuilder::checkParametrizedPassName(PassName, "regallocfast")) {
+      return make_error<StringError>(
+          "Must use fast (default) register allocator for "
+          "unoptimized regalloc.",
+          inconvertibleErrorCode());
+    }
+    // FIXME: Should only accept reg-alloc passes.
+    if (auto Err = parsePassPipeline(MFPM, PassName))
+      return Err;
+    RegAllocMap[getFilterName(PassName)] = std::move(MFPM);
+    MFPM = MachineFunctionPassManager();
+  }
+  return Error::success();
+}
+
 static void printPassName(StringRef PassName, raw_ostream &OS) {
   OS << "  " << PassName << "\n";
 }
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp
index 7c353fd102848..4cf19434dea4c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp
@@ -14,9 +14,8 @@
 using namespace llvm;
 
 AMDGPUCodeGenPassBuilder::AMDGPUCodeGenPassBuilder(
-    AMDGPUTargetMachine &TM, const CGPassBuilderOption &Opts,
-    PassInstrumentationCallbacks *PIC)
-    : CodeGenPassBuilder(TM, Opts, PIC) {
+    AMDGPUTargetMachine &TM, const CGPassBuilderOption &Opts, PassBuilder &PB)
+    : CodeGenPassBuilder(TM, Opts, PB) {
   Opt.RequiresCodeGenSCCOrder = true;
   // Exceptions and StackMaps are not supported, so these passes will never do
   // anything.
@@ -40,3 +39,13 @@ Error AMDGPUCodeGenPassBuilder::addInstSelector(AddMachinePass &addPass) const {
   addPass(AMDGPUISelDAGToDAGPass(TM));
   return Error::success();
 }
+
+Error AMDGPUCodeGenPassBuilder::addRegAssignmentFast(
+    AddMachinePass &addPass) const {
+  if (auto Err = addRegAllocPass(addPass, "sgpr"))
+    return Err;
+  // TODO: Add other passes.
+  if (auto Err = addRegAllocPass(addPass, "vgpr"))
+    return Err;
+  return Error::success();
+}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.h b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.h
index 5f79e309703a3..d233da863ec1e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.h
@@ -20,12 +20,12 @@ class AMDGPUCodeGenPassBuilder
     : public CodeGenPassBuilder<AMDGPUCodeGenPassBuilder, AMDGPUTargetMachine> {
 public:
   AMDGPUCodeGenPassBuilder(AMDGPUTargetMachine &TM,
-                           const CGPassBuilderOption &Opts,
-                           PassInstrumentationCallbacks *PIC);
+                           const CGPassBuilderOption &Opts, PassBuilder &PB);
 
   void addPreISel(AddIRPass &addPass) const;
   void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
   Error addInstSelector(AddMachinePass &) const;
+  Error addRegAssignmentFast(AddMachinePass &addPass) const;
 };
 
 } // namespace llvm
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index ce997c659094a..577dca0d2cded 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -46,6 +46,7 @@
 #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
 #include "llvm/CodeGen/MIRParser/MIParser.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/RegAllocFast.h"
 #include "llvm/CodeGen/RegAllocRegistry.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/IR/IntrinsicsAMDGPU.h"
@@ -650,11 +651,13 @@ parseAMDGPUAtomicOptimizerStrategy(StringRef Params) {
   return make_error<StringError>("invalid parameter", inconvertibleErrorCode());
 }
 
-Error AMDGPUTargetMachine::buildCodeGenPipeline(
-    ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
-    CodeGenFileType FileType, const CGPassBuilderOption &Opts,
-    PassInstrumentationCallbacks *PIC) {
-  AMDGPUCodeGenPassBuilder CGPB(*this, Opts, PIC);
+Error AMDGPUTargetMachine::buildCodeGenPipeline(ModulePassManager &MPM,
+                                                raw_pwrite_stream &Out,
+                                                raw_pwrite_stream *DwoOut,
+                                                CodeGenFileType FileType,
+                                                const CGPassBuilderOption &Opts,
+                                                PassBuilder &PB) {
+  AMDGPUCodeGenPassBuilder CGPB(*this, Opts, PB);
   return CGPB.buildPipeline(MPM, Out, DwoOut, FileType);
 }
 
@@ -749,6 +752,30 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(
           return onlyAllocateVGPRs;
         return nullptr;
       });
+
+  PB.setDefaultRegAllocBuilder(
+      [TM = this](StringMap<MachineFunctionPassManager> &RegAllocMap) {
+        auto Opts = getCGPassBuilderOption();
+        if (Opts.OptimizeRegAlloc.value_or(TM->getOptLevel() !=
+                                           CodeGenOptLevel::None)) {
+          // TODO: Add greedy register allocator.
+        } else {
+          RegAllocFastPassOptions Opts;
+          Opts.Filter = onlyAllocateSGPRs;
+          Opts.FilterName = "sgpr";
+          Opts.ClearVRegs = false;
+          MachineFunctionPassManager MFPM;
+          MFPM.addPass(RegAllocFastPass(Opts));
+          RegAllocMap["sgpr"] = std::move(MFPM);
+
+          Opts.Filter = onlyAllocateVGPRs;
+          Opts.FilterName = "vgpr";
+          Opts.ClearVRegs = true;
+          MFPM = MachineFunctionPassManager();
+          MFPM.addPass(RegAllocFastPass(Opts));
+          RegAllocMap["vgpr"] = std::move(MFPM);
+        }
+      });
 }
 
 int64_t AMDGPUTargetMachine::getNullPointerValue(unsigned AddrSpace) {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
index 2cfd232483a8a..2385e6ce6c6b3 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h
@@ -56,7 +56,7 @@ class AMDGPUTargetMachine : public LLVMTargetMachine {
                              raw_pwrite_stream *DwoOut,
                              CodeGenFileType FileType,
                              const CGPassBuilderOption &Opts,
-                             PassInstrumentationCallbacks *PIC) override;
+                             PassBuilder &PB) override;
 
   void registerPassBuilderCallbacks(PassBuilder &PB,
                                     bool PopulateClassToPassNames) override;
diff --git a/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.cpp b/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.cpp
index a57b3aa0adb15..183ffe56181ce 100644
--- a/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.cpp
@@ -11,10 +11,10 @@
 
 using namespace llvm;
 
-R600CodeGenPassBuilder::R600CodeGenPassBuilder(
-    R600TargetMachine &TM, const CGPassBuilderOption &Opts,
-    PassInstrumentationCallbacks *PIC)
-    : CodeGenPassBuilder(TM, Opts, PIC) {
+R600CodeGenPassBuilder::R600CodeGenPassBuilder(R600TargetMachine &TM,
+                                               const CGPassBuilderOption &Opts,
+                                               PassBuilder &PB)
+    : CodeGenPassBuilder(TM, Opts, PB) {
   Opt.RequiresCodeGenSCCOrder = true;
 }
 
diff --git a/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.h b/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.h
index be7c935c094d9..06820f5258266 100644
--- a/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.h
+++ b/llvm/lib/Target/AMDGPU/R600CodeGenPassBuilder.h
@@ -20,7 +20,7 @@ class R600CodeGenPassBuilder
     : public CodeGenPassBuilder<R600CodeGenPassBuilder, R600TargetMachine> {
 public:
   R600CodeGenPassBuilder(R600TargetMachine &TM, const CGPassBuilderOption &Opts,
-                         PassInstrumentationCallbacks *PIC);
+                         PassBuilder &PB);
 
   void addPreISel(AddIRPass &addPass) const;
   void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
diff --git a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
index c550cfaf06c10..f4eb0d5692a6e 100644
--- a/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/R600TargetMachine.cpp
@@ -146,10 +146,12 @@ TargetPassConfig *R600TargetMachine::createPassConfig(PassManagerBase &PM) {
   return new R600PassConfig(*this, PM);
 }
 
-Error R600TargetMachine::buildCodeGenPipeline(
-    ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
-    CodeGenFileType FileType, const CGPassBuilderOption &Opts,
-    PassInstrumentationCallbacks *PIC) {
-  R600CodeGenPassBuilder CGPB(*this, Opts, PIC);
+Error R600TargetMachine::buildCodeGenPipeline(ModulePassManager &MPM,
+                                              raw_pwrite_stream &Out,
+                                              raw_pwrite_stream *DwoOut,
+                                              CodeGenFileType FileType,
+                                              const CGPassBuilderOption &Opts,
+                                              PassBuilder &PB) {
+  R600CodeGenPassBuilder CGPB(*this, Opts, PB);
   return CGPB.buildPipeline(MPM, Out, DwoOut, FileType);
 }
diff --git a/llvm/lib/Target/AMDGPU/R600TargetMachine.h b/llvm/lib/Target/AMDGPU/R600TargetMachine.h
index 29e370edef2c6..9f49c8189d53f 100644
--- a/llvm/lib/Target/AMDGPU/R600TargetMachine.h
+++ b/llvm/lib/Target/AMDGPU/R600TargetMachine.h
@@ -42,7 +42,7 @@ class R600TargetMachine final : public AMDGPUTargetMachine {
                              raw_pwrite_stream *DwoOut,
                              CodeGenFileType FileType,
                              const CGPassBuilderOption &Opt,
-                             PassInstrumentationCallbacks *PIC) override;
+                             PassBuilder &PB) override;
 
   const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override;
 
diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 44a54c8ec62cb..4540169fe6de4 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 9819bfd129855..66afe31074b1a 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -26,8 +26,8 @@ class X86CodeGenPassBuilder
 public:
   explicit X86CodeGenPassBuilder(X86TargetMachine &TM,
                                  const CGPassBuilderOption &Opts,
-                                 PassInstrumentationCallbacks *PIC)
-      : CodeGenPassBuilder(TM, Opts, PIC) {}
+                                 PassBuilder &PB)
+      : CodeGenPassBuilder(TM, Opts, PB) {}
   void addPreISel(AddIRPass &addPass) const;
   void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
   Error addInstSelector(AddMachinePass &) const;
@@ -58,8 +58,7 @@ void X86TargetMachine::registerPassBuilderCallbacks(
 
 Error X86TargetMachine::buildCodeGenPipeline(
     ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
-    CodeGenFileType FileType, const CGPassBuilderOption &Opt,
-    PassInstrumentationCallbacks *PIC) {
-  auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC);
+    CodeGenFileType FileType, const CGPassBuilderOption &Opt, PassBuilder &PB) {
+  auto CGPB = X86CodeGenPassBuilder(*this, Opt, PB);
   return CGPB.buildPipeline(MPM, Out, DwoOut, FileType);
 }
diff --git a/llvm/lib/Target/X86/X86TargetMachine.h b/llvm/lib/Target/X86/X86TargetMachine.h
index 4a5f20fcc0172..54f5a8a58a3bc 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.h
+++ b/llvm/lib/Target/X86/X86TargetMachine.h
@@ -64,7 +64,7 @@ class X86TargetMachine final : public LLVMTargetMachine {
   Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
                              raw_pwrite_stream *, CodeGenFileType,
                              const CGPassBuilderOption &,
-                             PassInstrumentationCallbacks *) override;
+                             PassBuilder &PB) override;
 
   bool isJIT() const { return IsJIT; }
 
diff --git a/llvm/test/tools/llc/new-pm/regalloc-amdgpu.mir b/llvm/test/tools/llc/new-pm/regalloc-amdgpu.mir
index 0603ffc4c5ea2..152d81e95eeb1 100644
--- a/llvm/test/tools/llc/new-pm/regalloc-amdgpu.mir
+++ b/llvm/test/tools/llc/new-pm/regalloc-amdgpu.mir
@@ -1,10 +1,18 @@
 # REQUIRES: amdgpu-registered-target
 # RUN: llc -mtriple=amdgcn --passes='regallocfast<filter=sgpr>' --print-pipeline-passes %s | FileCheck %s --check-prefix=PASS
 # RUN: not llc -mtriple=amdgcn --passes='regallocfast<filter=bad-filter>' --print-pipeline-passes --filetype=null %s 2>&1 | FileCheck %s --check-prefix=BAD-FILTER
+# RUN: llc -mtriple=amdgcn-- -enable-new-pm -print-pipeline-passes --filetype=null -O0 %s | FileCheck %s --check-prefix=DEFAULT-O0-REG-ALLOC
+# RUN: llc -mtriple=amdgcn-- --regalloc-npm='regallocfast<filter=sgpr>' -enable-new-pm -print-pipeline-passes --filetype=null -O0 %s | FileCheck %s --check-prefix=REG-ALLOC-NPM
 
 # PASS: regallocfast<filter=sgpr>
 # BAD-FILTER: invalid regallocfast register filter 'bad-filter'
 
+# DEFAULT-O0-REG-ALLOC: regallocfast<filter=sgpr;no-clear-vregs>
+# DEFAULT-O0-REG-ALLOC: regallocfast<filter=vgpr>
+
+# REG-ALLOC-NPM: regallocfast<filter=sgpr>
+# REG-ALLOC-NPM: regallocfast<filter=vgpr>
+
 ---
 name: f
 ...
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index fb1959c6457f4..2eb8293c8fe7b 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -159,7 +159,7 @@ int llvm::compileModuleWithNewPM(
       return 1;
   } else {
     ExitOnErr(LLVMTM.buildCodeGenPipeline(
-        MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, &PIC));
+        MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, PB));
   }
 
   if (PrintPipelinePasses) {



More information about the llvm-commits mailing list