Skip to content

Commit 89711d5

Browse files
committed
[CodeGen][NPM] Support generic regalloc-npm option
1 parent f46d641 commit 89711d5

18 files changed

+276
-120
lines changed

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
#include "llvm/IRPrinter/IRPrintingPasses.h"
9797
#include "llvm/MC/MCAsmInfo.h"
9898
#include "llvm/MC/MCTargetOptions.h"
99+
#include "llvm/Passes/PassBuilder.h"
99100
#include "llvm/Support/CodeGen.h"
100101
#include "llvm/Support/Debug.h"
101102
#include "llvm/Support/Error.h"
@@ -113,6 +114,7 @@
113114
#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
114115
#include "llvm/Transforms/Utils/LowerInvoke.h"
115116
#include <cassert>
117+
#include <tuple>
116118
#include <type_traits>
117119
#include <utility>
118120

@@ -154,8 +156,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
154156
public:
155157
explicit CodeGenPassBuilder(TargetMachineT &TM,
156158
const CGPassBuilderOption &Opts,
157-
PassInstrumentationCallbacks *PIC)
158-
: TM(TM), Opt(Opts), PIC(PIC) {
159+
PassInstrumentationCallbacks *PIC,
160+
PassBuilder &PB)
161+
: TM(TM), Opt(Opts), PIC(PIC), PB(PB) {
159162
// Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
160163
// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
161164

@@ -291,6 +294,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
291294
TargetMachineT &TM;
292295
CGPassBuilderOption Opt;
293296
PassInstrumentationCallbacks *PIC;
297+
PassBuilder &PB;
294298

295299
template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
296300
CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
@@ -498,6 +502,13 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
498502
/// addMachinePasses helper to create the target-selected or overriden
499503
/// regalloc pass.
500504
void addRegAllocPass(AddMachinePass &, bool Optimized) const;
505+
/// Read the --regalloc-npm option to add the next pass in line.
506+
bool addRegAllocPassFromOpt(AddMachinePass &,
507+
StringRef MatchPassTo = StringRef{}) const;
508+
/// Add the next pass in the cli option, or return false if there is no pass
509+
/// left in the option.
510+
template <typename RegAllocPassT>
511+
void addRegAllocPassOrOpt(AddMachinePass &, RegAllocPassT Pass) const;
501512

502513
/// Add core register alloator passes which do the actual register assignment
503514
/// and rewriting. \returns true if any passes were added.
@@ -594,6 +605,11 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
594605
if (PrintMIR)
595606
addPass(PrintMIRPass(Out), /*Force=*/true);
596607

608+
if (!Opt.RegAllocPipeline.empty())
609+
return make_error<StringError>(
610+
"Extra passes in regalloc pipeline: " + Opt.RegAllocPipeline,
611+
std::make_error_code(std::errc::invalid_argument));
612+
597613
return verifyStartStop(*StartStopInfo);
598614
}
599615

@@ -1088,6 +1104,49 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
10881104
addPass(RegAllocFastPass());
10891105
}
10901106

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

11191169
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
@@ -209,8 +209,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
209209
MACHINE_FUNCTION_PASS_WITH_PARAMS(
210210
"branch-folder", "BranchFolderPass",
211211
[](bool EnableTailMerge) { return BranchFolderPass(EnableTailMerge); },
212-
[](StringRef Params) {
213-
return parseSinglePassOption(Params, "enable-tail-merge",
212+
[](StringRef Params, const PassBuilder &) {
213+
return PassBuilder::parseSinglePassOption(Params, "enable-tail-merge",
214214
"BranchFolderPass");
215215
},
216216
"enable-tail-merge")
@@ -220,8 +220,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
220220
[](bool ShouldEmitDebugEntryValues) {
221221
return LiveDebugValuesPass(ShouldEmitDebugEntryValues);
222222
},
223-
[](StringRef Params) {
224-
return parseSinglePassOption(Params, "emit-debug-entry-values",
223+
[](StringRef Params, const PassBuilder &) {
224+
return PassBuilder::parseSinglePassOption(Params, "emit-debug-entry-values",
225225
"LiveDebugValuesPass");
226226
},
227227
"emit-debug-entry-values")
@@ -236,17 +236,17 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
236236
MACHINE_FUNCTION_PASS_WITH_PARAMS(
237237
"regallocfast", "RegAllocFastPass",
238238
[](RegAllocFastPass::Options Opts) { return RegAllocFastPass(Opts); },
239-
[PB = this](StringRef Params) {
240-
return parseRegAllocFastPassOptions(*PB, Params);
239+
[](StringRef Params, const PassBuilder &PB) {
240+
return parseRegAllocFastPassOptions(PB, Params);
241241
},
242242
"filter=reg-filter;no-clear-vregs")
243243

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