Skip to content

Commit 61993c0

Browse files
committed
[CodeGen][NPM] Support generic regalloc-npm option
1 parent 630a0ff commit 61993c0

18 files changed

+281
-122
lines changed

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
#include "llvm/IRPrinter/IRPrintingPasses.h"
104104
#include "llvm/MC/MCAsmInfo.h"
105105
#include "llvm/MC/MCTargetOptions.h"
106+
#include "llvm/Passes/PassBuilder.h"
106107
#include "llvm/Support/CodeGen.h"
107108
#include "llvm/Support/Debug.h"
108109
#include "llvm/Support/Error.h"
@@ -120,6 +121,7 @@
120121
#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
121122
#include "llvm/Transforms/Utils/LowerInvoke.h"
122123
#include <cassert>
124+
#include <tuple>
123125
#include <type_traits>
124126
#include <utility>
125127

@@ -161,8 +163,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
161163
public:
162164
explicit CodeGenPassBuilder(TargetMachineT &TM,
163165
const CGPassBuilderOption &Opts,
164-
PassInstrumentationCallbacks *PIC)
165-
: TM(TM), Opt(Opts), PIC(PIC) {
166+
PassInstrumentationCallbacks *PIC,
167+
PassBuilder &PB)
168+
: TM(TM), Opt(Opts), PIC(PIC), PB(PB) {
166169
// Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
167170
// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
168171

@@ -298,6 +301,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
298301
TargetMachineT &TM;
299302
CGPassBuilderOption Opt;
300303
PassInstrumentationCallbacks *PIC;
304+
PassBuilder &PB;
301305

302306
template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
303307
CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
@@ -505,6 +509,13 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
505509
/// addMachinePasses helper to create the target-selected or overriden
506510
/// regalloc pass.
507511
void addRegAllocPass(AddMachinePass &, bool Optimized) const;
512+
/// Read the --regalloc-npm option to add the next pass in line.
513+
bool addRegAllocPassFromOpt(AddMachinePass &,
514+
StringRef MatchPassTo = StringRef{}) const;
515+
/// Add the next pass in the cli option, or return false if there is no pass
516+
/// left in the option.
517+
template <typename RegAllocPassT>
518+
void addRegAllocPassOrOpt(AddMachinePass &, RegAllocPassT Pass) const;
508519

509520
/// Add core register alloator passes which do the actual register assignment
510521
/// and rewriting. \returns true if any passes were added.
@@ -601,6 +612,11 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
601612
if (PrintMIR)
602613
addPass(PrintMIRPass(Out), /*Force=*/true);
603614

615+
if (!Opt.RegAllocPipeline.empty())
616+
return make_error<StringError>(
617+
"Extra passes in regalloc pipeline: " + Opt.RegAllocPipeline,
618+
std::make_error_code(std::errc::invalid_argument));
619+
604620
return verifyStartStop(*StartStopInfo);
605621
}
606622

@@ -1098,6 +1114,49 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
10981114
addPass(RegAllocFastPass());
10991115
}
11001116

1117+
template <typename Derived, typename TargetMachineT>
1118+
template <typename RegAllocPassT>
1119+
void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPassOrOpt(
1120+
AddMachinePass &addPass, RegAllocPassT Pass) const {
1121+
if (!addRegAllocPassFromOpt(addPass))
1122+
addPass(std::move(Pass));
1123+
}
1124+
1125+
template <typename Derived, typename TargetMachineT>
1126+
bool CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPassFromOpt(
1127+
AddMachinePass &addPass, StringRef MatchPassTo) const {
1128+
if (!Opt.RegAllocPipeline.empty()) {
1129+
StringRef PassOpt;
1130+
std::tie(PassOpt, Opt.RegAllocPipeline) = Opt.RegAllocPipeline.split(',');
1131+
// Reuse the registered parser to parse the pass name.
1132+
#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1133+
PARAMS) \
1134+
if (PB.checkParametrizedPassName(PassOpt, NAME)) { \
1135+
auto Params = PB.parsePassParameters(PARSER, PassOpt, NAME, \
1136+
const_cast<const PassBuilder &>(PB)); \
1137+
if (!Params) { \
1138+
auto Err = Params.takeError(); \
1139+
ExitOnError()(std::move(Err)); \
1140+
} \
1141+
if (!MatchPassTo.empty()) { \
1142+
if (MatchPassTo != CLASS) \
1143+
report_fatal_error("Expected " + \
1144+
PIC->getPassNameForClassName(MatchPassTo) + \
1145+
" in option -regalloc-npm", \
1146+
false); \
1147+
} \
1148+
addPass(CREATE_PASS(Params.get())); \
1149+
return true; \
1150+
}
1151+
#include "llvm/Passes/MachinePassRegistry.def"
1152+
if (PassOpt != "default") {
1153+
report_fatal_error("Unknown register allocator pass: " + PassOpt, false);
1154+
}
1155+
}
1156+
// If user did not give a specific pass, use the default provided.
1157+
return false;
1158+
}
1159+
11011160
/// Find and instantiate the register allocation pass requested by this target
11021161
/// at the current optimization level. Different register allocators are
11031162
/// defined as separate passes because they may require different analysis.
@@ -1108,22 +1167,13 @@ template <typename Derived, typename TargetMachineT>
11081167
void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
11091168
AddMachinePass &addPass, bool Optimized) const {
11101169
// Use the specified -regalloc-npm={basic|greedy|fast|pbqp}
1111-
if (Opt.RegAlloc > RegAllocType::Default) {
1112-
switch (Opt.RegAlloc) {
1113-
case RegAllocType::Fast:
1114-
addPass(RegAllocFastPass());
1115-
break;
1116-
case RegAllocType::Greedy:
1117-
addPass(RAGreedyPass());
1118-
break;
1119-
default:
1120-
report_fatal_error("register allocator not supported yet", false);
1121-
}
1122-
return;
1170+
StringRef RegAllocPassName;
1171+
if (!Optimized)
1172+
RegAllocPassName = RegAllocFastPass::name();
1173+
1174+
if (!addRegAllocPassFromOpt(addPass, RegAllocPassName)) {
1175+
derived().addTargetRegisterAllocator(addPass, Optimized);
11231176
}
1124-
// -regalloc=default or unspecified, so pick based on the optimization level
1125-
// or ask the target for the regalloc pass.
1126-
derived().addTargetRegisterAllocator(addPass, Optimized);
11271177
}
11281178

11291179
template <typename Derived, typename TargetMachineT>

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
222222
MACHINE_FUNCTION_PASS_WITH_PARAMS(
223223
"branch-folder", "BranchFolderPass",
224224
[](bool EnableTailMerge) { return BranchFolderPass(EnableTailMerge); },
225-
[](StringRef Params) {
226-
return parseSinglePassOption(Params, "enable-tail-merge",
225+
[](StringRef Params, const PassBuilder &) {
226+
return PassBuilder::parseSinglePassOption(Params, "enable-tail-merge",
227227
"BranchFolderPass");
228228
},
229229
"enable-tail-merge")
@@ -233,8 +233,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
233233
[](bool ShouldEmitDebugEntryValues) {
234234
return LiveDebugValuesPass(ShouldEmitDebugEntryValues);
235235
},
236-
[](StringRef Params) {
237-
return parseSinglePassOption(Params, "emit-debug-entry-values",
236+
[](StringRef Params, const PassBuilder &) {
237+
return PassBuilder::parseSinglePassOption(Params, "emit-debug-entry-values",
238238
"LiveDebugValuesPass");
239239
},
240240
"emit-debug-entry-values")
@@ -249,17 +249,17 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
249249
MACHINE_FUNCTION_PASS_WITH_PARAMS(
250250
"regallocfast", "RegAllocFastPass",
251251
[](RegAllocFastPass::Options Opts) { return RegAllocFastPass(Opts); },
252-
[PB = this](StringRef Params) {
253-
return parseRegAllocFastPassOptions(*PB, Params);
252+
[](StringRef Params, const PassBuilder &PB) {
253+
return parseRegAllocFastPassOptions(PB, Params);
254254
},
255255
"filter=reg-filter;no-clear-vregs")
256256

257257
// 'all' is the default filter.
258258
MACHINE_FUNCTION_PASS_WITH_PARAMS(
259259
"greedy", "RAGreedyPass",
260260
[](RAGreedyPass::Options Opts) { return RAGreedyPass(Opts); },
261-
[PB = this](StringRef Params) {
262-
return parseRegAllocGreedyFilterFunc(*PB, Params);
261+
[](StringRef Params, const PassBuilder &PB) {
262+
return parseRegAllocGreedyFilterFunc(PB, Params);
263263
}, "reg-filter"
264264
)
265265

llvm/include/llvm/Passes/PassBuilder.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/Analysis/CGSCCPassManager.h"
1919
#include "llvm/CodeGen/MachinePassManager.h"
2020
#include "llvm/CodeGen/RegAllocCommon.h"
21+
#include "llvm/CodeGen/RegAllocGreedyPass.h"
2122
#include "llvm/IR/PassManager.h"
2223
#include "llvm/Passes/OptimizationLevel.h"
2324
#include "llvm/Support/Error.h"
@@ -397,7 +398,7 @@ class PassBuilder {
397398

398399
/// Parse RegAllocFilterName to get RegAllocFilterFunc.
399400
std::optional<RegAllocFilterFunc>
400-
parseRegAllocFilter(StringRef RegAllocFilterName);
401+
parseRegAllocFilter(StringRef RegAllocFilterName) const;
401402

402403
/// Print pass names.
403404
void printPassNames(raw_ostream &OS);
@@ -688,11 +689,13 @@ class PassBuilder {
688689
/// parameter list in a form of a custom parameters type, all wrapped into
689690
/// Expected<> template class.
690691
///
691-
template <typename ParametersParseCallableT>
692+
template <typename ParametersParseCallableT, typename... ExtraArgs>
692693
static auto parsePassParameters(ParametersParseCallableT &&Parser,
693-
StringRef Name, StringRef PassName)
694-
-> decltype(Parser(StringRef{})) {
695-
using ParametersT = typename decltype(Parser(StringRef{}))::value_type;
694+
StringRef Name, StringRef PassName,
695+
ExtraArgs &&...Args)
696+
-> decltype(Parser(StringRef{}, std::forward<ExtraArgs>(Args)...)) {
697+
using ParametersT = typename decltype(Parser(
698+
StringRef{}, std::forward<ExtraArgs>(Args)...))::value_type;
696699

697700
StringRef Params = Name;
698701
if (!Params.consume_front(PassName)) {
@@ -704,7 +707,8 @@ class PassBuilder {
704707
llvm_unreachable("invalid format for parametrized pass name");
705708
}
706709

707-
Expected<ParametersT> Result = Parser(Params);
710+
Expected<ParametersT> Result =
711+
Parser(Params, std::forward<ExtraArgs>(Args)...);
708712
assert((Result || Result.template errorIsA<StringError>()) &&
709713
"Pass parameter parser can only return StringErrors.");
710714
return Result;
@@ -980,6 +984,16 @@ class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
980984
/// Common option used by multiple tools to print pipeline passes
981985
extern cl::opt<bool> PrintPipelinePasses;
982986

987+
Expected<RAGreedyPass::Options>
988+
parseRegAllocGreedyFilterFunc(const PassBuilder &PB, StringRef Params);
989+
990+
Expected<RegAllocFastPass::Options>
991+
parseRegAllocFastPassOptions(const PassBuilder &PB, StringRef Params);
992+
993+
Expected<bool> parseMachineSinkingPassOptions(StringRef Params,
994+
const PassBuilder &);
995+
Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params,
996+
const PassBuilder &);
983997
}
984998

985999
#endif

llvm/include/llvm/Passes/TargetPassRegistry.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ if (PIC) {
8383

8484
#define ADD_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \
8585
if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
86-
auto Params = PassBuilder::parsePassParameters(PARSER, Name, NAME); \
86+
auto Params = PassBuilder::parsePassParameters(PARSER, Name, NAME, PB); \
8787
if (!Params) { \
8888
errs() << NAME ": " << toString(Params.takeError()) << '\n'; \
8989
return false; \

llvm/include/llvm/Target/CGPassBuilderOption.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct CGPassBuilderOption {
7070
bool RequiresCodeGenSCCOrder = false;
7171

7272
RunOutliner EnableMachineOutliner = RunOutliner::TargetDefault;
73-
RegAllocType RegAlloc = RegAllocType::Unset;
73+
mutable StringRef RegAllocPipeline;
7474
std::optional<GlobalISelAbortMode> EnableGlobalISelAbort;
7575
std::string FSProfileFile;
7676
std::string FSRemappingFile;

llvm/include/llvm/Target/TargetMachine.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,8 @@ class TargetMachine {
472472
virtual Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
473473
raw_pwrite_stream *, CodeGenFileType,
474474
const CGPassBuilderOption &,
475-
PassInstrumentationCallbacks *) {
475+
PassInstrumentationCallbacks *,
476+
PassBuilder &) {
476477
return make_error<StringError>("buildCodeGenPipeline is not overridden",
477478
inconvertibleErrorCode());
478479
}

0 commit comments

Comments
 (0)