Skip to content

Commit a0c2223

Browse files
committed
[CodeGen][NPM] Support generic regalloc-npm option
1 parent a09fd9c commit a0c2223

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
@@ -99,6 +99,7 @@
9999
#include "llvm/IRPrinter/IRPrintingPasses.h"
100100
#include "llvm/MC/MCAsmInfo.h"
101101
#include "llvm/MC/MCTargetOptions.h"
102+
#include "llvm/Passes/PassBuilder.h"
102103
#include "llvm/Support/CodeGen.h"
103104
#include "llvm/Support/Debug.h"
104105
#include "llvm/Support/Error.h"
@@ -116,6 +117,7 @@
116117
#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
117118
#include "llvm/Transforms/Utils/LowerInvoke.h"
118119
#include <cassert>
120+
#include <tuple>
119121
#include <type_traits>
120122
#include <utility>
121123

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

@@ -294,6 +297,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
294297
TargetMachineT &TM;
295298
CGPassBuilderOption Opt;
296299
PassInstrumentationCallbacks *PIC;
300+
PassBuilder &PB;
297301

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

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

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

@@ -1094,6 +1110,49 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
10941110
addPass(RegAllocFastPass());
10951111
}
10961112

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

11251175
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
@@ -215,8 +215,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
215215
MACHINE_FUNCTION_PASS_WITH_PARAMS(
216216
"branch-folder", "BranchFolderPass",
217217
[](bool EnableTailMerge) { return BranchFolderPass(EnableTailMerge); },
218-
[](StringRef Params) {
219-
return parseSinglePassOption(Params, "enable-tail-merge",
218+
[](StringRef Params, const PassBuilder &) {
219+
return PassBuilder::parseSinglePassOption(Params, "enable-tail-merge",
220220
"BranchFolderPass");
221221
},
222222
"enable-tail-merge")
@@ -226,8 +226,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
226226
[](bool ShouldEmitDebugEntryValues) {
227227
return LiveDebugValuesPass(ShouldEmitDebugEntryValues);
228228
},
229-
[](StringRef Params) {
230-
return parseSinglePassOption(Params, "emit-debug-entry-values",
229+
[](StringRef Params, const PassBuilder &) {
230+
return PassBuilder::parseSinglePassOption(Params, "emit-debug-entry-values",
231231
"LiveDebugValuesPass");
232232
},
233233
"emit-debug-entry-values")
@@ -242,17 +242,17 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
242242
MACHINE_FUNCTION_PASS_WITH_PARAMS(
243243
"regallocfast", "RegAllocFastPass",
244244
[](RegAllocFastPass::Options Opts) { return RegAllocFastPass(Opts); },
245-
[PB = this](StringRef Params) {
246-
return parseRegAllocFastPassOptions(*PB, Params);
245+
[](StringRef Params, const PassBuilder &PB) {
246+
return parseRegAllocFastPassOptions(PB, Params);
247247
},
248248
"filter=reg-filter;no-clear-vregs")
249249

250250
// 'all' is the default filter.
251251
MACHINE_FUNCTION_PASS_WITH_PARAMS(
252252
"greedy", "RAGreedyPass",
253253
[](RAGreedyPass::Options Opts) { return RAGreedyPass(Opts); },
254-
[PB = this](StringRef Params) {
255-
return parseRegAllocGreedyFilterFunc(*PB, Params);
254+
[](StringRef Params, const PassBuilder &PB) {
255+
return parseRegAllocGreedyFilterFunc(PB, Params);
256256
}, "reg-filter"
257257
)
258258
#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)