[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