Skip to content

Commit f8bd622

Browse files
committed
[CodeGen] Let PassBuilder support machine passes
`PassBuilder` would be a better place to parse MIR pipeline. We can reuse the code to support parsing pass with parameters and targets can reuse `registerPassBuilderCallbacks` to register the target specific passes. `PassBuilder` also has ability to check whether a Pass is a machine pass, so it can replace part of the work of `LLVMTargetMachine::getPassNameFromLegacyName`.
1 parent 76482b7 commit f8bd622

File tree

4 files changed

+622
-0
lines changed

4 files changed

+622
-0
lines changed

llvm/include/llvm/Passes/PassBuilder.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define LLVM_PASSES_PASSBUILDER_H
1717

1818
#include "llvm/Analysis/CGSCCPassManager.h"
19+
#include "llvm/CodeGen/MachinePassManager.h"
1920
#include "llvm/IR/PassManager.h"
2021
#include "llvm/Passes/OptimizationLevel.h"
2122
#include "llvm/Support/Error.h"
@@ -165,6 +166,14 @@ class PassBuilder {
165166
/// additional analyses.
166167
void registerLoopAnalyses(LoopAnalysisManager &LAM);
167168

169+
/// Registers all available machine function analysis passes.
170+
///
171+
/// This is an interface that can be used to populate a \c
172+
/// MachineFunctionAnalysisManager with all registered function analyses.
173+
/// Callers can still manually register any additional analyses. Callers can
174+
/// also pre-register analyses and this will not override those.
175+
void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM);
176+
168177
/// Construct the core LLVM function canonicalization and simplification
169178
/// pipeline.
170179
///
@@ -352,6 +361,18 @@ class PassBuilder {
352361
Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText);
353362
/// @}}
354363

364+
/// Parse a textual MIR pipeline into the provided \c MachineFunctionPass
365+
/// manager.
366+
/// The format of the textual machine pipeline is a comma separated list of
367+
/// machine pass names:
368+
///
369+
/// machine-funciton-pass,machine-module-pass,...
370+
///
371+
/// There is no need to specify the pass nesting, and this function
372+
/// currently cannot handle the pass nesting.
373+
Error parsePassPipeline(MachineFunctionPassManager &MFPM,
374+
StringRef PipelineText);
375+
355376
/// Parse a textual alias analysis pipeline into the provided AA manager.
356377
///
357378
/// The format of the textual AA pipeline is a comma separated list of AA
@@ -520,6 +541,10 @@ class PassBuilder {
520541
const std::function<void(ModuleAnalysisManager &)> &C) {
521542
ModuleAnalysisRegistrationCallbacks.push_back(C);
522543
}
544+
void registerAnalysisRegistrationCallback(
545+
const std::function<void(MachineFunctionAnalysisManager &)> &C) {
546+
MachineFunctionAnalysisRegistrationCallbacks.push_back(C);
547+
}
523548
/// @}}
524549

525550
/// {{@ Register pipeline parsing callbacks with this pass builder instance.
@@ -546,6 +571,11 @@ class PassBuilder {
546571
ArrayRef<PipelineElement>)> &C) {
547572
ModulePipelineParsingCallbacks.push_back(C);
548573
}
574+
void registerPipelineParsingCallback(
575+
const std::function<bool(StringRef Name, MachineFunctionPassManager &)>
576+
&C) {
577+
MachinePipelineParsingCallbacks.push_back(C);
578+
}
549579
/// @}}
550580

551581
/// Register a callback for a top-level pipeline entry.
@@ -616,8 +646,12 @@ class PassBuilder {
616646
Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E);
617647
Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E);
618648
Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E);
649+
Error parseMachinePass(MachineFunctionPassManager &MFPM,
650+
const PipelineElement &E);
619651
bool parseAAPassName(AAManager &AA, StringRef Name);
620652

653+
Error parseMachinePassPipeline(MachineFunctionPassManager &MFPM,
654+
ArrayRef<PipelineElement> Pipeline);
621655
Error parseLoopPassPipeline(LoopPassManager &LPM,
622656
ArrayRef<PipelineElement> Pipeline);
623657
Error parseFunctionPassPipeline(FunctionPassManager &FPM,
@@ -699,6 +733,11 @@ class PassBuilder {
699733
// AA callbacks
700734
SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2>
701735
AAParsingCallbacks;
736+
// Machine pass callbackcs
737+
SmallVector<std::function<void(MachineFunctionAnalysisManager &)>, 2>
738+
MachineFunctionAnalysisRegistrationCallbacks;
739+
SmallVector<std::function<bool(StringRef, MachineFunctionPassManager &)>, 2>
740+
MachinePipelineParsingCallbacks;
702741
};
703742

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

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,12 @@ PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO,
488488
#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
489489
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
490490
#include "PassRegistry.def"
491+
492+
#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
493+
PIC->addClassToPassName(PASS_NAME::name(), NAME);
494+
#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
495+
PIC->addClassToPassName(PASS_NAME::name(), NAME);
496+
#include "llvm/CodeGen/MachinePassRegistry.def"
491497
}
492498
}
493499

@@ -523,6 +529,17 @@ void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
523529
C(FAM);
524530
}
525531

532+
void PassBuilder::registerMachineFunctionAnalyses(
533+
MachineFunctionAnalysisManager &MFAM) {
534+
535+
#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
536+
MFAM.registerPass([&] { return PASS_NAME(); });
537+
#include "llvm/CodeGen/MachinePassRegistry.def"
538+
539+
for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
540+
C(MFAM);
541+
}
542+
526543
void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
527544
#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
528545
LAM.registerPass([&] { return CREATE_PASS; });
@@ -1877,6 +1894,33 @@ Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
18771894
inconvertibleErrorCode());
18781895
}
18791896

1897+
Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
1898+
const PipelineElement &E) {
1899+
StringRef Name = E.Name;
1900+
if (!E.InnerPipeline.empty())
1901+
return make_error<StringError>("invalid pipeline",
1902+
inconvertibleErrorCode());
1903+
1904+
#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
1905+
if (Name == NAME) { \
1906+
MFPM.addPass(PASS_NAME()); \
1907+
return Error::success(); \
1908+
}
1909+
#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
1910+
if (Name == NAME) { \
1911+
MFPM.addPass(PASS_NAME()); \
1912+
return Error::success(); \
1913+
}
1914+
#include "llvm/CodeGen/MachinePassRegistry.def"
1915+
1916+
for (auto &C : MachinePipelineParsingCallbacks)
1917+
if (C(Name, MFPM))
1918+
return Error::success();
1919+
return make_error<StringError>(
1920+
formatv("unknown machine pass '{0}'", Name).str(),
1921+
inconvertibleErrorCode());
1922+
}
1923+
18801924
bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
18811925
#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
18821926
if (Name == NAME) { \
@@ -1898,6 +1942,15 @@ bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
18981942
return false;
18991943
}
19001944

1945+
Error PassBuilder::parseMachinePassPipeline(
1946+
MachineFunctionPassManager &MFPM, ArrayRef<PipelineElement> Pipeline) {
1947+
for (const auto &Element : Pipeline) {
1948+
if (auto Err = parseMachinePass(MFPM, Element))
1949+
return Err;
1950+
}
1951+
return Error::success();
1952+
}
1953+
19011954
Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
19021955
ArrayRef<PipelineElement> Pipeline) {
19031956
for (const auto &Element : Pipeline) {
@@ -2057,6 +2110,20 @@ Error PassBuilder::parsePassPipeline(LoopPassManager &CGPM,
20572110
return Error::success();
20582111
}
20592112

2113+
Error PassBuilder::parsePassPipeline(MachineFunctionPassManager &MFPM,
2114+
StringRef PipelineText) {
2115+
auto Pipeline = parsePipelineText(PipelineText);
2116+
if (!Pipeline || Pipeline->empty())
2117+
return make_error<StringError>(
2118+
formatv("invalid machine pass pipeline '{0}'", PipelineText).str(),
2119+
inconvertibleErrorCode());
2120+
2121+
if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2122+
return Err;
2123+
2124+
return Error::success();
2125+
}
2126+
20602127
Error PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
20612128
// If the pipeline just consists of the word 'default' just replace the AA
20622129
// manager with our default one.
@@ -2151,6 +2218,21 @@ void PassBuilder::printPassNames(raw_ostream &OS) {
21512218
OS << "Loop analyses:\n";
21522219
#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
21532220
#include "PassRegistry.def"
2221+
2222+
OS << "Machine module passes (WIP):\n";
2223+
#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
2224+
printPassName(NAME, OS);
2225+
#include "llvm/CodeGen/MachinePassRegistry.def"
2226+
2227+
OS << "Machine function passes (WIP):\n";
2228+
#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
2229+
printPassName(NAME, OS);
2230+
#include "llvm/CodeGen/MachinePassRegistry.def"
2231+
2232+
OS << "Machine function analyses (WIP):\n";
2233+
#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
2234+
printPassName(NAME, OS);
2235+
#include "llvm/CodeGen/MachinePassRegistry.def"
21542236
}
21552237

21562238
void PassBuilder::registerParseTopLevelPipelineCallback(

llvm/unittests/MIR/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ set(LLVM_LINK_COMPONENTS
66
FileCheck
77
MC
88
MIRParser
9+
Passes
910
Support
1011
Target
1112
TargetParser
1213
)
1314

1415
add_llvm_unittest(MIRTests
1516
MachineMetadata.cpp
17+
PassBuilderCallbacksTest.cpp
1618
)
1719

1820
target_link_libraries(MIRTests PRIVATE LLVMTestingSupport)

0 commit comments

Comments
 (0)