Skip to content

Commit 2f356a3

Browse files
committed
Fixes to be upstreamed - 13
port of llvm#135149, it is not really necessary to enable npm on clang, however there few lit tests which use custom regallocs in pipeline and would be good to have in NPM too.
1 parent 69f45fc commit 2f356a3

19 files changed

+287
-125
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,7 @@ void EmitAssemblyHelper::RunCodegenPipelineWithNewPM(BackendAction Action,
13101310
FunctionPassManager FPM;
13111311

13121312
if (!TM.buildCodeGenPipeline(MPM, *OS, DwoOS ? &DwoOS->os() : nullptr,
1313-
getCodeGenFileType(Action), Opt, MMI.getContext(), &PIC)) {
1313+
getCodeGenFileType(Action), Opt, MMI.getContext(), &PIC, PB)) {
13141314
Diags.Report(diag::err_fe_unable_to_interface_with_target);
13151315
return;
13161316
}

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
131131
#include "llvm/Transforms/Utils/LowerInvoke.h"
132132
#include <cassert>
133+
#include <tuple>
133134
#include <type_traits>
134135
#include <utility>
135136

@@ -171,8 +172,9 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
171172
public:
172173
explicit CodeGenPassBuilder(TargetMachineT &TM,
173174
const CGPassBuilderOption &Opts,
174-
PassInstrumentationCallbacks *PIC)
175-
: TM(TM), Opt(Opts), PIC(PIC) {
175+
PassInstrumentationCallbacks *PIC,
176+
PassBuilder &PB)
177+
: TM(TM), Opt(Opts), PIC(PIC), PB(PB) {
176178
// Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
177179
// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
178180

@@ -359,6 +361,7 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
359361
TargetMachineT &TM;
360362
CGPassBuilderOption Opt;
361363
PassInstrumentationCallbacks *PIC;
364+
PassBuilder &PB;
362365
mutable IntrusiveRefCntPtr<AsmPrinter> PrinterImpl;
363366

364367
template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
@@ -569,6 +572,15 @@ template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
569572
/// addMachinePasses helper to create the target-selected or overriden
570573
/// regalloc pass.
571574
void addRegAllocPass(AddMachinePass &, bool Optimized) const;
575+
/// Read the --regalloc-npm option to add the next pass in line.
576+
/// Returns false if no pass is left in the option.
577+
bool addRegAllocPassFromOpt(AddMachinePass &,
578+
StringRef MatchPassTo = StringRef{}) const;
579+
/// Add the next pass in the cli option or the pass specified if no pass is
580+
/// left in the option.
581+
template <typename RegAllocPassBuilderT>
582+
void addRegAllocPassOrOpt(AddMachinePass &,
583+
RegAllocPassBuilderT PassBuilder) const;
572584

573585
/// Add core register alloator passes which do the actual register assignment
574586
/// and rewriting. \returns true if any passes were added.
@@ -688,6 +700,11 @@ Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
688700

689701
PrinterImpl.reset();
690702

703+
if (!Opt.RegAllocPipeline.empty())
704+
return make_error<StringError>(
705+
"extra passes in regalloc pipeline: " + Opt.RegAllocPipeline,
706+
std::make_error_code(std::errc::invalid_argument));
707+
691708
return verifyStartStop(*StartStopInfo);
692709
}
693710

@@ -1187,6 +1204,48 @@ void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
11871204
addPass(RegAllocFastPass());
11881205
}
11891206

1207+
template <typename Derived, typename TargetMachineT>
1208+
template <typename RegAllocPassBuilderT>
1209+
void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPassOrOpt(
1210+
AddMachinePass &addPass, RegAllocPassBuilderT PassBuilder) const {
1211+
if (!addRegAllocPassFromOpt(addPass))
1212+
addPass(std::move(PassBuilder()));
1213+
}
1214+
1215+
template <typename Derived, typename TargetMachineT>
1216+
bool CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPassFromOpt(
1217+
AddMachinePass &addPass, StringRef MatchPassTo) const {
1218+
if (!Opt.RegAllocPipeline.empty()) {
1219+
StringRef PassOpt;
1220+
std::tie(PassOpt, Opt.RegAllocPipeline) = Opt.RegAllocPipeline.split(',');
1221+
// Reuse the registered parser to parse the pass name.
1222+
#define RA_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1223+
if (PB.checkParametrizedPassName(PassOpt, NAME)) { \
1224+
auto Params = PB.parsePassParameters(PARSER, PassOpt, NAME, \
1225+
const_cast<const PassBuilder &>(PB)); \
1226+
if (!Params) { \
1227+
auto Err = Params.takeError(); \
1228+
ExitOnError()(std::move(Err)); \
1229+
} \
1230+
if (!MatchPassTo.empty()) { \
1231+
if (MatchPassTo != CLASS) \
1232+
report_fatal_error("expected " + \
1233+
PIC->getPassNameForClassName(MatchPassTo) + \
1234+
" in option --regalloc-npm", \
1235+
false); \
1236+
} \
1237+
addPass(CREATE_PASS(Params.get())); \
1238+
return true; \
1239+
}
1240+
#include "llvm/Passes/MachinePassRegistry.def"
1241+
if (PassOpt != "default") {
1242+
report_fatal_error("unknown register allocator pass: " + PassOpt, false);
1243+
}
1244+
}
1245+
// If user did not give a specific pass, use the default provided.
1246+
return false;
1247+
}
1248+
11901249
/// Find and instantiate the register allocation pass requested by this target
11911250
/// at the current optimization level. Different register allocators are
11921251
/// defined as separate passes because they may require different analysis.
@@ -1197,22 +1256,13 @@ template <typename Derived, typename TargetMachineT>
11971256
void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
11981257
AddMachinePass &addPass, bool Optimized) const {
11991258
// Use the specified -regalloc-npm={basic|greedy|fast|pbqp}
1200-
if (Opt.RegAlloc > RegAllocType::Default) {
1201-
switch (Opt.RegAlloc) {
1202-
case RegAllocType::Fast:
1203-
addPass(RegAllocFastPass());
1204-
break;
1205-
case RegAllocType::Greedy:
1206-
addPass(RAGreedyPass());
1207-
break;
1208-
default:
1209-
reportFatalUsageError("register allocator not supported yet");
1210-
}
1211-
return;
1259+
StringRef RegAllocPassName;
1260+
if (!Optimized)
1261+
RegAllocPassName = RegAllocFastPass::name();
1262+
1263+
if (!addRegAllocPassFromOpt(addPass, RegAllocPassName)) {
1264+
derived().addTargetRegisterAllocator(addPass, Optimized);
12121265
}
1213-
// -regalloc=default or unspecified, so pick based on the optimization level
1214-
// or ask the target for the regalloc pass.
1215-
derived().addTargetRegisterAllocator(addPass, Optimized);
12161266
}
12171267

12181268
template <typename Derived, typename TargetMachineT>

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
194194
MACHINE_FUNCTION_PASS_WITH_PARAMS(
195195
"branch-folder", "BranchFolderPass",
196196
[](bool EnableTailMerge) { return BranchFolderPass(EnableTailMerge); },
197-
[](StringRef Params) {
198-
return parseSinglePassOption(Params, "enable-tail-merge",
197+
[](StringRef Params, const PassBuilder &) {
198+
return PassBuilder::parseSinglePassOption(Params, "enable-tail-merge",
199199
"BranchFolderPass");
200200
},
201201
"enable-tail-merge")
@@ -205,8 +205,8 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
205205
[](bool ShouldEmitDebugEntryValues) {
206206
return LiveDebugValuesPass(ShouldEmitDebugEntryValues);
207207
},
208-
[](StringRef Params) {
209-
return parseSinglePassOption(Params, "emit-debug-entry-values",
208+
[](StringRef Params, const PassBuilder &) {
209+
return PassBuilder::parseSinglePassOption(Params, "emit-debug-entry-values",
210210
"LiveDebugValuesPass");
211211
},
212212
"emit-debug-entry-values")
@@ -219,27 +219,36 @@ MACHINE_FUNCTION_PASS_WITH_PARAMS(
219219
parseMachineSinkingPassOptions, "enable-sink-fold")
220220

221221
MACHINE_FUNCTION_PASS_WITH_PARAMS(
222+
"virt-reg-rewriter", "VirtRegRewriterPass",
223+
[](bool ClearVirtRegs) { return VirtRegRewriterPass(ClearVirtRegs); },
224+
parseVirtRegRewriterPassOptions, "no-clear-vregs;clear-vregs")
225+
226+
#ifndef RA_PASS_WITH_PARAMS
227+
// Define MachineFunction passes that are register allocators.
228+
// This is to differentiate them from other MachineFunction passes
229+
// to be used in the --regalloc-npm option.
230+
#define RA_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
231+
MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS)
232+
#endif
233+
234+
RA_PASS_WITH_PARAMS(
222235
"regallocfast", "RegAllocFastPass",
223236
[](RegAllocFastPass::Options Opts) { return RegAllocFastPass(Opts); },
224-
[PB = this](StringRef Params) {
225-
return parseRegAllocFastPassOptions(*PB, Params);
237+
[](StringRef Params, const PassBuilder &PB) {
238+
return parseRegAllocFastPassOptions(PB, Params);
226239
},
227240
"filter=reg-filter;no-clear-vregs")
228241

229242
// 'all' is the default filter.
230-
MACHINE_FUNCTION_PASS_WITH_PARAMS(
243+
RA_PASS_WITH_PARAMS(
231244
"greedy", "RAGreedyPass",
232245
[](RAGreedyPass::Options Opts) { return RAGreedyPass(Opts); },
233-
[PB = this](StringRef Params) {
234-
return parseRegAllocGreedyFilterFunc(*PB, Params);
235-
}, "reg-filter"
236-
)
237-
238-
MACHINE_FUNCTION_PASS_WITH_PARAMS(
239-
"virt-reg-rewriter", "VirtRegRewriterPass",
240-
[](bool ClearVirtRegs) { return VirtRegRewriterPass(ClearVirtRegs); },
241-
parseVirtRegRewriterPassOptions, "no-clear-vregs;clear-vregs")
246+
[](StringRef Params, const PassBuilder &PB) {
247+
return parseRegAllocGreedyFilterFunc(PB, Params);
248+
},
249+
"reg-filter")
242250

251+
#undef RA_PASS_WITH_PARAMS
243252
#undef MACHINE_FUNCTION_PASS_WITH_PARAMS
244253

245254
// After a pass is converted to new pass manager, its entry should be moved from

llvm/include/llvm/Passes/PassBuilder.h

Lines changed: 23 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/Compiler.h"
@@ -406,7 +407,7 @@ class PassBuilder {
406407

407408
/// Parse RegAllocFilterName to get RegAllocFilterFunc.
408409
LLVM_ABI std::optional<RegAllocFilterFunc>
409-
parseRegAllocFilter(StringRef RegAllocFilterName);
410+
parseRegAllocFilter(StringRef RegAllocFilterName) const;
410411

411412
/// Print pass names.
412413
LLVM_ABI void printPassNames(raw_ostream &OS);
@@ -701,11 +702,13 @@ class PassBuilder {
701702
/// parameter list in a form of a custom parameters type, all wrapped into
702703
/// Expected<> template class.
703704
///
704-
template <typename ParametersParseCallableT>
705+
template <typename ParametersParseCallableT, typename... ExtraArgs>
705706
static auto parsePassParameters(ParametersParseCallableT &&Parser,
706-
StringRef Name, StringRef PassName)
707-
-> decltype(Parser(StringRef{})) {
708-
using ParametersT = typename decltype(Parser(StringRef{}))::value_type;
707+
StringRef Name, StringRef PassName,
708+
ExtraArgs &&...Args)
709+
-> decltype(Parser(StringRef{}, std::forward<ExtraArgs>(Args)...)) {
710+
using ParametersT = typename decltype(Parser(
711+
StringRef{}, std::forward<ExtraArgs>(Args)...))::value_type;
709712

710713
StringRef Params = Name;
711714
if (!Params.consume_front(PassName)) {
@@ -717,7 +720,8 @@ class PassBuilder {
717720
llvm_unreachable("invalid format for parametrized pass name");
718721
}
719722

720-
Expected<ParametersT> Result = Parser(Params);
723+
Expected<ParametersT> Result =
724+
Parser(Params, std::forward<ExtraArgs>(Args)...);
721725
assert((Result || Result.template errorIsA<StringError>()) &&
722726
"Pass parameter parser can only return StringErrors.");
723727
return Result;
@@ -994,6 +998,19 @@ class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
994998

995999
/// Common option used by multiple tools to print pipeline passes
9961000
LLVM_ABI extern cl::opt<bool> PrintPipelinePasses;
1001+
1002+
Expected<RAGreedyPass::Options>
1003+
parseRegAllocGreedyFilterFunc(const PassBuilder &PB, StringRef Params);
1004+
1005+
Expected<RegAllocFastPass::Options>
1006+
parseRegAllocFastPassOptions(const PassBuilder &PB, StringRef Params);
1007+
1008+
Expected<bool> parseMachineSinkingPassOptions(StringRef Params,
1009+
const PassBuilder &);
1010+
Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params,
1011+
const PassBuilder &);
1012+
Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params,
1013+
const PassBuilder &);
9971014
}
9981015

9991016
#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
@@ -79,7 +79,7 @@ struct CGPassBuilderOption {
7979
bool RequiresCodeGenSCCOrder = false;
8080

8181
RunOutliner EnableMachineOutliner = RunOutliner::TargetDefault;
82-
RegAllocType RegAlloc = RegAllocType::Unset;
82+
mutable StringRef RegAllocPipeline;
8383
std::optional<GlobalISelAbortMode> EnableGlobalISelAbort;
8484
std::string FSProfileFile;
8585
std::string FSRemappingFile;

llvm/include/llvm/Target/TargetMachine.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,8 @@ class LLVM_ABI TargetMachine {
492492
virtual Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
493493
raw_pwrite_stream *, CodeGenFileType,
494494
const CGPassBuilderOption &, MCContext &,
495-
PassInstrumentationCallbacks *) {
495+
PassInstrumentationCallbacks *,
496+
PassBuilder &) {
496497
return make_error<StringError>("buildCodeGenPipeline is not overridden",
497498
inconvertibleErrorCode());
498499
}

0 commit comments

Comments
 (0)