Skip to content

Commit 7730fa2

Browse files
committed
Add RegAlloc support
1 parent df8863f commit 7730fa2

File tree

10 files changed

+109
-114
lines changed

10 files changed

+109
-114
lines changed

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 27 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include "llvm/IRPrinter/IRPrintingPasses.h"
5757
#include "llvm/MC/MCAsmInfo.h"
5858
#include "llvm/MC/MCTargetOptions.h"
59+
#include "llvm/Passes/PassBuilder.h"
5960
#include "llvm/Support/CodeGen.h"
6061
#include "llvm/Support/Debug.h"
6162
#include "llvm/Support/Error.h"
@@ -121,7 +122,7 @@ namespace llvm {
121122
} \
122123
static AnalysisKey Key; \
123124
};
124-
#include "llvm/CodeGen/MachinePassRegistry.def"
125+
#include "llvm/Passes/MachinePassRegistry.def"
125126

126127
/// This class provides access to building LLVM's passes.
127128
///
@@ -142,9 +143,10 @@ namespace llvm {
142143

143144
template <typename DerivedT> class CodeGenPassBuilder {
144145
public:
145-
explicit CodeGenPassBuilder(LLVMTargetMachine &TM, CGPassBuilderOption Opts,
146+
explicit CodeGenPassBuilder(LLVMTargetMachine &TM, PassBuilder &PB,
147+
CGPassBuilderOption Opts,
146148
PassInstrumentationCallbacks *PIC)
147-
: TM(TM), Opt(Opts), PIC(PIC) {
149+
: TM(TM), PB(PB), Opt(Opts), PIC(PIC) {
148150
// Target could set CGPassBuilderOption::MISchedPostRA to true to achieve
149151
// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)
150152

@@ -164,28 +166,6 @@ template <typename DerivedT> class CodeGenPassBuilder {
164166
raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
165167
CodeGenFileType FileType) const;
166168

167-
/// Parse single non-target-specific MIR pass
168-
/// @param Name the pass name
169-
/// @return true if failed
170-
bool parseMIRPass(MachineFunctionPassManager &MFPM, StringRef Name) const;
171-
172-
/// Parse MIR pass pipeline. Unlike IR pass pipeline,
173-
/// there is only one pass manager for machine function
174-
/// so there is no need to specify the pass nesting.
175-
/// @param Text a comma separated pass name list
176-
Error parseMIRPipeline(MachineFunctionPassManager &MFPM,
177-
StringRef Text) const {
178-
for (auto [LHS, RHS] = Text.split(','); LHS != "";
179-
std::tie(LHS, RHS) = RHS.split(',')) {
180-
if (parseMIRPass(MFPM, LHS) && derived().parseTargetMIRPass(MFPM, LHS)) {
181-
return createStringError(
182-
std::make_error_code(std::errc::invalid_argument),
183-
Twine('\"') + Twine(LHS) + Twine("\" pass could not be found."));
184-
}
185-
}
186-
return Error::success();
187-
}
188-
189169
void registerModuleAnalyses(ModuleAnalysisManager &) const;
190170
void registerFunctionAnalyses(FunctionAnalysisManager &) const;
191171
void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &) const;
@@ -279,6 +259,8 @@ template <typename DerivedT> class CodeGenPassBuilder {
279259
});
280260
}
281261

262+
MachineFunctionPassManager &getPM() { return PM; }
263+
282264
MachineFunctionPassManager releasePM() { return std::move(PM); }
283265

284266
private:
@@ -311,14 +293,10 @@ template <typename DerivedT> class CodeGenPassBuilder {
311293
}
312294

313295
LLVMTargetMachine &TM;
296+
PassBuilder &PB;
314297
CGPassBuilderOption Opt;
315298
PassInstrumentationCallbacks *PIC;
316299

317-
/// Target override these hooks to parse target-specific analyses.
318-
void registerTargetAnalysis(ModuleAnalysisManager &) const {}
319-
void registerTargetAnalysis(FunctionAnalysisManager &) const {}
320-
void registerTargetAnalysis(MachineFunctionAnalysisManager &) const {}
321-
322300
template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }
323301
CodeGenOptLevel getOptLevel() const { return TM.getOptLevel(); }
324302

@@ -556,14 +534,6 @@ template <typename DerivedT> class CodeGenPassBuilder {
556534
/// Utilities for targets to add passes to the pass manager.
557535
///
558536

559-
/// createTargetRegisterAllocator - Create the register allocator pass for
560-
/// this target at the current optimization level.
561-
void addTargetRegisterAllocator(AddMachinePass &, bool Optimized) const;
562-
563-
/// addMachinePasses helper to create the target-selected or overriden
564-
/// regalloc pass.
565-
void addRegAllocPass(AddMachinePass &, bool Optimized) const;
566-
567537
/// Add core register allocator passes which do the actual register assignment
568538
/// and rewriting. \returns Error::success() if any passes were added.
569539
Error addRegAssignAndRewriteFast(AddMachinePass &addPass) const;
@@ -1257,54 +1227,16 @@ void CodeGenPassBuilder<Derived>::addMachineSSAOptimization(
12571227
/// Register Allocation Pass Configuration
12581228
//===---------------------------------------------------------------------===//
12591229

1260-
/// Instantiate the default register allocator pass for this target for either
1261-
/// the optimized or unoptimized allocation path. This will be added to the pass
1262-
/// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
1263-
/// in the optimized case.
1264-
///
1265-
/// A target that uses the standard regalloc pass order for fast or optimized
1266-
/// allocation may still override this for per-target regalloc
1267-
/// selection. But -regalloc=... always takes precedence.
1268-
template <typename Derived>
1269-
void CodeGenPassBuilder<Derived>::addTargetRegisterAllocator(
1270-
AddMachinePass &addPass, bool Optimized) const {
1271-
if (Optimized)
1272-
addPass(RAGreedyPass());
1273-
else
1274-
addPass(RAFastPass());
1275-
}
1276-
1277-
/// Find and instantiate the register allocation pass requested by this target
1278-
/// at the current optimization level. Different register allocators are
1279-
/// defined as separate passes because they may require different analysis.
1280-
template <typename Derived>
1281-
void CodeGenPassBuilder<Derived>::addRegAllocPass(AddMachinePass &addPass,
1282-
bool Optimized) const {
1283-
if (Opt.RegAlloc == RegAllocType::Default)
1284-
// With no -regalloc= override, ask the target for a regalloc pass.
1285-
derived().addTargetRegisterAllocator(addPass, Optimized);
1286-
else if (Opt.RegAlloc == RegAllocType::Basic)
1287-
addPass(RABasicPass());
1288-
else if (Opt.RegAlloc == RegAllocType::Fast)
1289-
addPass(RAFastPass());
1290-
else if (Opt.RegAlloc == RegAllocType::Greedy)
1291-
addPass(RAGreedyPass());
1292-
else if (Opt.RegAlloc == RegAllocType::PBQP)
1293-
addPass(RAPBQPPass());
1294-
else
1295-
llvm_unreachable("unknonwn register allocator type");
1296-
}
1297-
12981230
template <typename Derived>
12991231
Error CodeGenPassBuilder<Derived>::addRegAssignAndRewriteFast(
13001232
AddMachinePass &addPass) const {
1301-
if (Opt.RegAlloc != RegAllocType::Default &&
1302-
Opt.RegAlloc != RegAllocType::Fast)
1233+
if (Opt.RegAlloc != "default" && !Opt.RegAlloc.starts_with("fast"))
13031234
return make_error<StringError>(
13041235
"Must use fast (default) register allocator for unoptimized regalloc.",
13051236
inconvertibleErrorCode());
13061237

1307-
addPass(RegAllocPass(false));
1238+
if (Error Err = PB.parseRegAllocPass(addPass.getPM(), Opt.RegAlloc, false))
1239+
return Err;
13081240

13091241
// Allow targets to change the register assignments after
13101242
// fast register allocation.
@@ -1315,7 +1247,8 @@ template <typename DerivedT>
13151247
Error CodeGenPassBuilder<DerivedT>::addRegAssignAndRewriteOptimized(
13161248
AddMachinePass &addPass) const {
13171249
// Add the selected register allocation pass.
1318-
addRegAllocPass(addPass, true);
1250+
if (Error Err = PB.parseRegAllocPass(addPass.getPM(), Opt.RegAlloc, true))
1251+
return Err;
13191252
// Allow targets to change the register assignments before rewriting.
13201253
addPreRewrite(addPass);
13211254

@@ -1367,22 +1300,22 @@ Error CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
13671300
// PreRA instruction scheduling.
13681301
addPass(MachineSchedulerPass());
13691302

1370-
Error E = derived().addRegAssignAndRewriteOptimized(addPass);
1371-
if (!E) {
1372-
// Allow targets to expand pseudo instructions depending on the choice of
1373-
// registers before MachineCopyPropagation.
1374-
derived().addPostRewrite(addPass);
1303+
if (Error Err = derived().addRegAssignAndRewriteOptimized(addPass))
1304+
return Err;
13751305

1376-
// Copy propagate to forward register uses and try to eliminate COPYs that
1377-
// were not coalesced.
1378-
addPass(MachineCopyPropagationPass());
1306+
// Allow targets to expand pseudo instructions depending on the choice of
1307+
// registers before MachineCopyPropagation.
1308+
derived().addPostRewrite(addPass);
13791309

1380-
// Run post-ra machine LICM to hoist reloads / remats.
1381-
//
1382-
// FIXME: can this move into MachineLateOptimization?
1383-
addPass(MachineLICMPass());
1384-
}
1385-
return E;
1310+
// Copy propagate to forward register uses and try to eliminate COPYs that
1311+
// were not coalesced.
1312+
addPass(MachineCopyPropagationPass());
1313+
1314+
// Run post-ra machine LICM to hoist reloads / remats.
1315+
//
1316+
// FIXME: can this move into MachineLateOptimization?
1317+
addPass(MachineLICMPass());
1318+
return Error::success();
13861319
}
13871320

13881321
//===---------------------------------------------------------------------===//

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,23 @@ MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis,
129129
// MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass, ())
130130
#undef MACHINE_FUNCTION_PASS
131131

132+
#ifndef RA_PASS
133+
#define RA_PASS(NAME, PASS_NAME, CONSTRUCTOR)
134+
#endif
135+
// RA_PASS("ra-basic", RABasicPass, ())
136+
#undef RA_PASS
137+
138+
#ifndef RA_PASS_WITH_PARAMS
139+
#define RA_PASS_WITH_PARAMS(NAME, PASS_NAME, CREATE_PASS, PARSER, PARAMS)
140+
#endif
141+
// RA_PASS_WITH_PARAMS("fast", RAFastPass,
142+
// [](Option Opts){ return RAFastPass(Opts); }, parseRAFastPassOptions, "")
143+
// RA_PASS_WITH_PARAMS("greedy", RAGreedyPass,
144+
// [](Option Opts) { return RAGreedyPass(Opts); }, parseRAGreedyPassOptions, "")
145+
// RA_PASS_WITH_PARAMS("pbqp", RAPBQPPass,
146+
// [](Option Opts) { return RAPBQPPass(Opts); }, parseRAPBQPPassOptions, "")
147+
#undef RA_PASS_WITH_PARAMS
148+
132149
// After a pass is converted to new pass manager, its entry should be moved from
133150
// dummy table to the normal one. For example, for a machine function pass,
134151
// DUMMY_MACHINE_FUNCTION_PASS to MACHINE_FUNCTION_PASS.
@@ -225,15 +242,10 @@ DUMMY_MACHINE_FUNCTION_PASS("processimpdefs", ProcessImplicitDefsPass, ())
225242
DUMMY_MACHINE_FUNCTION_PASS("prologepilog", PrologEpilogInserterPass, ())
226243
DUMMY_MACHINE_FUNCTION_PASS("prologepilog-code", PrologEpilogCodeInserterPass,
227244
())
228-
DUMMY_MACHINE_FUNCTION_PASS("ra-basic", RABasicPass, ())
229-
DUMMY_MACHINE_FUNCTION_PASS("ra-fast", RAFastPass, ())
230-
DUMMY_MACHINE_FUNCTION_PASS("ra-greedy", RAGreedyPass, ())
231-
DUMMY_MACHINE_FUNCTION_PASS("ra-pbqp", RAPBQPPass, ())
232245
DUMMY_MACHINE_FUNCTION_PASS("reg-usage-collector", RegUsageInfoCollectorPass,
233246
())
234247
DUMMY_MACHINE_FUNCTION_PASS("reg-usage-propagation",
235248
RegUsageInfoPropagationPass, ())
236-
DUMMY_MACHINE_FUNCTION_PASS("regalloc", RegAllocPass, ())
237249
DUMMY_MACHINE_FUNCTION_PASS("regallocscoringpass", RegAllocScoringPass, ())
238250
DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass, ())
239251
DUMMY_MACHINE_FUNCTION_PASS("removeredundantdebugvalues",

llvm/include/llvm/Passes/PassBuilder.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,11 @@ class PassBuilder {
370370
Error parsePassPipeline(MachineFunctionPassManager &MFPM,
371371
StringRef PipelineText);
372372

373+
/// Parse textual regalloc pass into the provided \c MachineFunctionPass
374+
/// the PassText should contain only one regalloc pass text.
375+
Error parseRegAllocPass(MachineFunctionPassManager &MFPM, StringRef PassText,
376+
bool Optimized);
377+
373378
/// Parse a textual alias analysis pipeline into the provided AA manager.
374379
///
375380
/// The format of the textual AA pipeline is a comma separated list of AA
@@ -575,6 +580,12 @@ class PassBuilder {
575580
}
576581
/// @}}
577582

583+
void registerRegAllocParsingCallback(
584+
const std::function<bool(StringRef, MachineFunctionPassManager &, bool)>
585+
&C) {
586+
RegAllocPassParsingCallbacks.push_back(C);
587+
}
588+
578589
/// Register a callback for a top-level pipeline entry.
579590
///
580591
/// If the PassManager type is not given at the top level of the pipeline
@@ -735,6 +746,9 @@ class PassBuilder {
735746
MachineFunctionAnalysisRegistrationCallbacks;
736747
SmallVector<std::function<bool(StringRef, MachineFunctionPassManager &)>, 2>
737748
MachinePipelineParsingCallbacks;
749+
SmallVector<
750+
std::function<bool(StringRef, MachineFunctionPassManager &, bool)>, 2>
751+
RegAllocPassParsingCallbacks;
738752
};
739753

740754
/// This utility template takes care of adding require<> and invalidate<>

llvm/include/llvm/Target/TargetMachine.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,9 +457,9 @@ class LLVMTargetMachine : public TargetMachine {
457457

458458
virtual Error buildCodeGenPipeline(ModulePassManager &,
459459
MachineFunctionPassManager &,
460-
MachineFunctionAnalysisManager &,
461-
raw_pwrite_stream &, raw_pwrite_stream *,
462-
CodeGenFileType, CGPassBuilderOption,
460+
PassBuilder &, raw_pwrite_stream &,
461+
raw_pwrite_stream *, CodeGenFileType,
462+
CGPassBuilderOption,
463463
PassInstrumentationCallbacks *) {
464464
return make_error<StringError>("buildCodeGenPipeline is not overridden",
465465
inconvertibleErrorCode());

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,6 +2081,43 @@ Error PassBuilder::parsePassPipeline(MachineFunctionPassManager &MFPM,
20812081
return Error::success();
20822082
}
20832083

2084+
Error PassBuilder::parseRegAllocPass(MachineFunctionPassManager &MFPM,
2085+
StringRef PassText, bool Optimized) {
2086+
// Targets may have their own default pipeline.
2087+
for (const auto &C : RegAllocPassParsingCallbacks) {
2088+
if (C(PassText, MFPM, Optimized))
2089+
return Error::success();
2090+
}
2091+
2092+
if (PassText == "default") {
2093+
if (Optimized) {
2094+
// TODO: MFPM.addPass(GreedyRegisterAllocatorPass());
2095+
} else {
2096+
// TODO: MFPM.addPass(FastRegisterAllocatorPass());
2097+
}
2098+
return Error::success();
2099+
}
2100+
2101+
#define RA_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
2102+
if (PassText == NAME) { \
2103+
MFPM.addPass(PASS_NAME CONSTRUCTOR); \
2104+
return Error::success(); \
2105+
}
2106+
#define RA_PASS_WITH_PARAMS(NAME, PASS_NAME, CREATE_PASS, PARSER, PARAMS) \
2107+
if (checkParametrizedPassName(PassText, NAME)) { \
2108+
auto Params = parsePassParameters(PARSER, PassText, NAME); \
2109+
if (!Params) \
2110+
return Params.takeError(); \
2111+
MFPM.addPass(CREATE_PASS(Params.get())); \
2112+
return Error::success(); \
2113+
}
2114+
#include "llvm/Passes/MachinePassRegistry.def"
2115+
2116+
return make_error<StringError>(
2117+
formatv("invalid regalloc pass '{0}'", PassText).str(),
2118+
inconvertibleErrorCode());
2119+
}
2120+
20842121
Error PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
20852122
// If the pipeline just consists of the word 'default' just replace the AA
20862123
// manager with our default one.

llvm/lib/Target/X86/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ add_llvm_target(X86CodeGen ${sources}
102102
IRPrinter
103103
Instrumentation
104104
MC
105+
Passes
105106
ProfileData
106107
Scalar
107108
SelectionDAG

llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ namespace {
2121

2222
class X86CodeGenPassBuilder : public CodeGenPassBuilder<X86CodeGenPassBuilder> {
2323
public:
24-
explicit X86CodeGenPassBuilder(LLVMTargetMachine &TM,
24+
explicit X86CodeGenPassBuilder(LLVMTargetMachine &TM, PassBuilder &PB,
2525
CGPassBuilderOption Opts,
2626
PassInstrumentationCallbacks *PIC)
27-
: CodeGenPassBuilder(TM, Opts, PIC) {}
27+
: CodeGenPassBuilder(TM, PB, Opts, PIC) {}
2828
void addPreISel(AddIRPass &addPass) const;
2929
void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
3030
Error addInstSelector(AddMachinePass &) const;
@@ -47,10 +47,9 @@ Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &) const {
4747
} // namespace
4848

4949
Error X86TargetMachine::buildCodeGenPipeline(
50-
ModulePassManager &MPM, MachineFunctionPassManager &MFPM,
51-
MachineFunctionAnalysisManager &, raw_pwrite_stream &Out,
52-
raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
50+
ModulePassManager &MPM, MachineFunctionPassManager &MFPM, PassBuilder &PB,
51+
raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
5352
CGPassBuilderOption Opt, PassInstrumentationCallbacks *PIC) {
54-
auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC);
53+
auto CGPB = X86CodeGenPassBuilder(*this, PB, Opt, PIC);
5554
return CGPB.buildPipeline(MPM, MFPM, Out, DwoOut, FileType);
5655
}

llvm/lib/Target/X86/X86TargetMachine.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ class X86TargetMachine final : public LLVMTargetMachine {
5959
const TargetSubtargetInfo *STI) const override;
6060

6161
Error buildCodeGenPipeline(ModulePassManager &, MachineFunctionPassManager &,
62-
MachineFunctionAnalysisManager &,
63-
raw_pwrite_stream &, raw_pwrite_stream *,
64-
CodeGenFileType, CGPassBuilderOption,
62+
PassBuilder &, raw_pwrite_stream &,
63+
raw_pwrite_stream *, CodeGenFileType,
64+
CGPassBuilderOption,
6565
PassInstrumentationCallbacks *) override;
6666

6767
bool isJIT() const { return IsJIT; }
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -filetype=null %s | FileCheck %s
22

33
; CHECK: require<profile-summary>,require<collector-metadata>
4-
; CHECK: MachineSanitizerBinaryMetadata,FreeMachineFunctionPass
5-
4+
; CHECK: StackFrameLayoutAnalysisPass,FreeMachineFunctionPass

llvm/tools/llc/NewPMDriver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ int llvm::compileModuleWithNewPM(
191191
ModulePassManager MPM;
192192
MachineFunctionPassManager MFPM;
193193

194-
ExitOnErr(LLVMTM.buildCodeGenPipeline(MPM, MFPM, MFAM, *OS,
194+
ExitOnErr(LLVMTM.buildCodeGenPipeline(MPM, MFPM, PB, *OS,
195195
DwoOut ? &DwoOut->os() : nullptr,
196196
FileType, Opt, &PIC));
197197

0 commit comments

Comments
 (0)