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

via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 8 02:33:36 PDT 2024


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

>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 1/3] [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) {

>From 4f1ae8c9175dced1d0a74b822a34bf4024057d33 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 7 Jun 2024 21:11:52 +0800
Subject: [PATCH 2/3] Address comments, and fix getFilterName issue

---
 llvm/lib/Passes/PassBuilder.cpp                |  5 +++--
 llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 14 +++++---------
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 7ae398ce87dbb..98371f11071ab 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -2240,8 +2240,9 @@ Error PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
 }
 
 static StringRef getFilterName(StringRef PassName) {
-  PassName = PassName.drop_until([](char C) { return C == '<'; });
-  StringRef Params = PassName.drop_front().drop_back();
+  StringRef Params = PassName.drop_until([](char C) { return C == '<'; });
+  if (!Params.empty())
+    Params = Params.drop_front().drop_back();
   while (!Params.empty()) {
     StringRef ParamName;
     std::tie(ParamName, Params) = Params.split(';');
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 577dca0d2cded..6cf76e1724629 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -760,19 +760,15 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(
                                            CodeGenOptLevel::None)) {
           // TODO: Add greedy register allocator.
         } else {
-          RegAllocFastPassOptions Opts;
-          Opts.Filter = onlyAllocateSGPRs;
-          Opts.FilterName = "sgpr";
-          Opts.ClearVRegs = false;
+          RegAllocFastPassOptions SGPRRunOpts{allocateAllRegClasses, "sgpr",
+                                              false};
           MachineFunctionPassManager MFPM;
-          MFPM.addPass(RegAllocFastPass(Opts));
+          MFPM.addPass(RegAllocFastPass(SGPRRunOpts));
           RegAllocMap["sgpr"] = std::move(MFPM);
 
-          Opts.Filter = onlyAllocateVGPRs;
-          Opts.FilterName = "vgpr";
-          Opts.ClearVRegs = true;
+          RegAllocFastPassOptions VGPRRunOpts{onlyAllocateVGPRs, "vgpr", true};
           MFPM = MachineFunctionPassManager();
-          MFPM.addPass(RegAllocFastPass(Opts));
+          MFPM.addPass(RegAllocFastPass(VGPRRunOpts));
           RegAllocMap["vgpr"] = std::move(MFPM);
         }
       });

>From 51df332f036db59e31a0af2ff418769ac2c80e76 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Sat, 8 Jun 2024 16:38:34 +0800
Subject: [PATCH 3/3] Fix more issues in CodeGenPassBuilder

---
 llvm/include/llvm/Passes/CodeGenPassBuilder.h | 34 +++++++++++--------
 .../AMDGPU/AMDGPUCodeGenPassBuilder.cpp       |  6 ++++
 .../Target/AMDGPU/AMDGPUCodeGenPassBuilder.h  |  1 +
 3 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index efef647cfd4df..54343f96b5cb3 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -433,7 +433,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
 
   /// 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;
@@ -896,7 +896,8 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addMachinePasses(
   // Run register allocation and passes that are tightly coupled with it,
   // including phi elimination and scheduling.
   if (*Opt.OptimizeRegAlloc) {
-    derived().addOptimizedRegAlloc(addPass);
+    if (auto Err = derived().addOptimizedRegAlloc(addPass))
+      return Err;
   } else {
     if (auto Err = derived().addFastRegAlloc(addPass))
       return Err;
@@ -1089,7 +1090,7 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::addFastRegAlloc(
 /// optimized register allocation, including coalescing, machine instruction
 /// scheduling, and register allocation itself.
 template <typename Derived, typename TargetMachineT>
-void CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
+Error CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
     AddMachinePass &addPass) const {
   addPass(DetectDeadLanesPass());
 
@@ -1115,20 +1116,23 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
   // PreRA instruction scheduling.
   addPass(MachineSchedulerPass());
 
-  if (derived().addRegAssignmentOptimized(addPass)) {
-    // Allow targets to expand pseudo instructions depending on the choice of
-    // registers before MachineCopyPropagation.
-    derived().addPostRewrite(addPass);
+  if (auto Err = derived().addRegAssignmentOptimized(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());
-  }
+  // 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/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp
index 4cf19434dea4c..3a93c498fd9dd 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.cpp
@@ -49,3 +49,9 @@ Error AMDGPUCodeGenPassBuilder::addRegAssignmentFast(
     return Err;
   return Error::success();
 }
+
+Error AMDGPUCodeGenPassBuilder::addRegAssignmentOptimized(
+    AddMachinePass &addPass) const {
+  // TODO: Add greedy register allocator.
+  return Error::success();
+}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.h b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.h
index d233da863ec1e..351225c0d041c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPassBuilder.h
@@ -26,6 +26,7 @@ class AMDGPUCodeGenPassBuilder
   void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
   Error addInstSelector(AddMachinePass &) const;
   Error addRegAssignmentFast(AddMachinePass &addPass) const;
+  Error addRegAssignmentOptimized(AddMachinePass &) const;
 };
 
 } // namespace llvm



More information about the llvm-commits mailing list