Skip to content

Commit 8edc1e3

Browse files
committed
[CodeGen][NPM] Support generic regalloc-npm option
1 parent f541a3a commit 8edc1e3

18 files changed

+280
-121
lines changed

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
#include "llvm/IRPrinter/IRPrintingPasses.h"
101101
#include "llvm/MC/MCAsmInfo.h"
102102
#include "llvm/MC/MCTargetOptions.h"
103+
#include "llvm/Passes/PassBuilder.h"
103104
#include "llvm/Support/CodeGen.h"
104105
#include "llvm/Support/Debug.h"
105106
#include "llvm/Support/Error.h"
@@ -117,6 +118,7 @@
117118
#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
118119
#include "llvm/Transforms/Utils/LowerInvoke.h"
119120
#include <cassert>
121+
#include <tuple>
120122
#include <type_traits>
121123
#include <utility>
122124

@@ -158,8 +160,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
158160
public:
159161
explicit CodeGenPassBuilder(TargetMachineT &TM,
160162
const CGPassBuilderOption &Opts,
161-
PassInstrumentationCallbacks *PIC)
162-
: TM(TM), Opt(Opts), PIC(PIC) {
163+
PassInstrumentationCallbacks *PIC,
164+
PassBuilder &PB)
165+
: TM(TM), Opt(Opts), PIC(PIC), PB(PB) {
163166
// Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
164167
// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
165168

@@ -295,6 +298,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
295298
TargetMachineT &TM;
296299
CGPassBuilderOption Opt;
297300
PassInstrumentationCallbacks *PIC;
301+
PassBuilder &PB;
298302

299303
template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
300304
CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
@@ -502,6 +506,13 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
502506
/// addMachinePasses helper to create the target-selected or overriden
503507
/// regalloc pass.
504508
void addRegAllocPass(AddMachinePass &, bool Optimized) const;
509+
/// Read the --regalloc-npm option to add the next pass in line.
510+
bool addRegAllocPassFromOpt(AddMachinePass &,
511+
StringRef MatchPassTo = StringRef{}) const;
512+
/// Add the next pass in the cli option, or return false if there is no pass
513+
/// left in the option.
514+
template <typename RegAllocPassT>
515+
void addRegAllocPassOrOpt(AddMachinePass &, RegAllocPassT Pass) const;
505516

506517
/// Add core register alloator passes which do the actual register assignment
507518
/// and rewriting. \returns true if any passes were added.
@@ -598,6 +609,11 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
598609
if (PrintMIR)
599610
addPass(PrintMIRPass(Out), /*Force=*/true);
600611

612+
if (!Opt.RegAllocPipeline.empty())
613+
return make_error<StringError>(
614+
"Extra passes in regalloc pipeline: " + Opt.RegAllocPipeline,
615+
std::make_error_code(std::errc::invalid_argument));
616+
601617
return verifyStartStop(*StartStopInfo);
602618
}
603619

@@ -1095,6 +1111,49 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
10951111
addPass(RegAllocFastPass());
10961112
}
10971113

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

11261176
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
@@ -217,8 +217,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
217217
MACHINE_FUNCTION_PASS_WITH_PARAMS(
218218
"branch-folder", "BranchFolderPass",
219219
[](bool EnableTailMerge) { return BranchFolderPass(EnableTailMerge); },
220-
[](StringRef Params) {
221-
return parseSinglePassOption(Params, "enable-tail-merge",
220+
[](StringRef Params, const PassBuilder &) {
221+
return PassBuilder::parseSinglePassOption(Params, "enable-tail-merge",
222222
"BranchFolderPass");
223223
},
224224
"enable-tail-merge")
@@ -228,8 +228,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
228228
[](bool ShouldEmitDebugEntryValues) {
229229
return LiveDebugValuesPass(ShouldEmitDebugEntryValues);
230230
},
231-
[](StringRef Params) {
232-
return parseSinglePassOption(Params, "emit-debug-entry-values",
231+
[](StringRef Params, const PassBuilder &) {
232+
return PassBuilder::parseSinglePassOption(Params, "emit-debug-entry-values",
233233
"LiveDebugValuesPass");
234234
},
235235
"emit-debug-entry-values")
@@ -244,17 +244,17 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
244244
MACHINE_FUNCTION_PASS_WITH_PARAMS(
245245
"regallocfast", "RegAllocFastPass",
246246
[](RegAllocFastPass::Options Opts) { return RegAllocFastPass(Opts); },
247-
[PB = this](StringRef Params) {
248-
return parseRegAllocFastPassOptions(*PB, Params);
247+
[](StringRef Params, const PassBuilder &PB) {
248+
return parseRegAllocFastPassOptions(PB, Params);
249249
},
250250
"filter=reg-filter;no-clear-vregs")
251251

252252
// 'all' is the default filter.
253253
MACHINE_FUNCTION_PASS_WITH_PARAMS(
254254
"greedy", "RAGreedyPass",
255255
[](RAGreedyPass::Options Opts) { return RAGreedyPass(Opts); },
256-
[PB = this](StringRef Params) {
257-
return parseRegAllocGreedyFilterFunc(*PB, Params);
256+
[](StringRef Params, const PassBuilder &PB) {
257+
return parseRegAllocGreedyFilterFunc(PB, Params);
258258
}, "reg-filter"
259259
)
260260
#undef MACHINE_FUNCTION_PASS_WITH_PARAMS

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
@@ -469,7 +469,8 @@ class TargetMachine {
469469
virtual Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
470470
raw_pwrite_stream *, CodeGenFileType,
471471
const CGPassBuilderOption &,
472-
PassInstrumentationCallbacks *) {
472+
PassInstrumentationCallbacks *,
473+
PassBuilder &) {
473474
return make_error<StringError>("buildCodeGenPipeline is not overridden",
474475
inconvertibleErrorCode());
475476
}

0 commit comments

Comments
 (0)