-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[CodeGen][NewPM] Handle --regalloc-npm
option
#94748
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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/pr-subscribers-backend-x86 @llvm/pr-subscribers-backend-amdgpu Author: None (paperchalice) ChangesThe final register allocation pass is now determined by Patch is 24.89 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/94748.diff 17 Files Affected:
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,
+ ...
[truncated]
|
RegAllocFastPassOptions Opts; | ||
Opts.Filter = onlyAllocateSGPRs; | ||
Opts.FilterName = "sgpr"; | ||
Opts.ClearVRegs = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use initializer list?
4e1e1f0
to
7f9c2cd
Compare
7f9c2cd
to
51df332
Compare
@@ -409,13 +409,33 @@ class RequireAllMachineFunctionPropertiesPass | |||
|
|||
} // namespace | |||
|
|||
static void defaultRegAllocBuilder(TargetMachine *TM, | |||
StringMap<MachineFunctionPassManager> &M) { | |||
if (!TM) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should always be non-null here
|
||
/// Used by CodeGenPassBuilder to add correct regalloc pass. | ||
/// Should only be called by CodeGenPassBuilder. | ||
StringMap<MachineFunctionPassManager> &getRegAllocMap() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems very roundabout to use a map that creates a MachineFunctionPassManager. can this instead be a callback that takes a MachineFunctionPassManager and adds a regalloc pass to it? like the optimization pipeline callbacks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requirements for register allocation passes from backends are somewhat complex. Some targets (DirectX, NVPTX etc) shall not contain them. AMDGPU needs register allocators with correct parameters if pass supports it, here is the register filter. Callbacks may not suitable for this situation, callbacks may add some unexpected passes. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you mean callbacks may add unexpected passes?
basically my suggestion is replace std::function<void(StringMap<MachineFunctionPassManager> &)>
with std::function<void(MachineFunctionPassManager &, StringRef, bool)>
, where StringRef
is the filter and bool
is optimized or not (or maybe that's part of filter? structure however makes most sense). the default callback adds Fast/GreedyRegAlloc based on IsOptimized
bool. AMDGPU can set the callback to add its custom regallocs based on the filter, and backends that don't need a regalloc can override the callback to be empty
does that make sense? or is there a benefit of the StringMap over that approach?
Is superseded by #108690. |
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.