Skip to content

Commit 8566cd6

Browse files
authored
[CodeGen] Let PassBuilder support machine passes (#76320)
`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.
1 parent a08402f commit 8566cd6

File tree

4 files changed

+623
-0
lines changed

4 files changed

+623
-0
lines changed

llvm/include/llvm/Passes/PassBuilder.h

+39
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

+82
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,12 @@ PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO,
392392
#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
393393
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
394394
#include "PassRegistry.def"
395+
396+
#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
397+
PIC->addClassToPassName(PASS_NAME::name(), NAME);
398+
#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
399+
PIC->addClassToPassName(PASS_NAME::name(), NAME);
400+
#include "llvm/CodeGen/MachinePassRegistry.def"
395401
}
396402
}
397403

@@ -427,6 +433,17 @@ void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
427433
C(FAM);
428434
}
429435

436+
void PassBuilder::registerMachineFunctionAnalyses(
437+
MachineFunctionAnalysisManager &MFAM) {
438+
439+
#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
440+
MFAM.registerPass([&] { return PASS_NAME(); });
441+
#include "llvm/CodeGen/MachinePassRegistry.def"
442+
443+
for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
444+
C(MFAM);
445+
}
446+
430447
void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
431448
#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
432449
LAM.registerPass([&] { return CREATE_PASS; });
@@ -1781,6 +1798,33 @@ Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
17811798
inconvertibleErrorCode());
17821799
}
17831800

1801+
Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
1802+
const PipelineElement &E) {
1803+
StringRef Name = E.Name;
1804+
if (!E.InnerPipeline.empty())
1805+
return make_error<StringError>("invalid pipeline",
1806+
inconvertibleErrorCode());
1807+
1808+
#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
1809+
if (Name == NAME) { \
1810+
MFPM.addPass(PASS_NAME()); \
1811+
return Error::success(); \
1812+
}
1813+
#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
1814+
if (Name == NAME) { \
1815+
MFPM.addPass(PASS_NAME()); \
1816+
return Error::success(); \
1817+
}
1818+
#include "llvm/CodeGen/MachinePassRegistry.def"
1819+
1820+
for (auto &C : MachinePipelineParsingCallbacks)
1821+
if (C(Name, MFPM))
1822+
return Error::success();
1823+
return make_error<StringError>(
1824+
formatv("unknown machine pass '{0}'", Name).str(),
1825+
inconvertibleErrorCode());
1826+
}
1827+
17841828
bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
17851829
#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
17861830
if (Name == NAME) { \
@@ -1802,6 +1846,15 @@ bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
18021846
return false;
18031847
}
18041848

1849+
Error PassBuilder::parseMachinePassPipeline(
1850+
MachineFunctionPassManager &MFPM, ArrayRef<PipelineElement> Pipeline) {
1851+
for (const auto &Element : Pipeline) {
1852+
if (auto Err = parseMachinePass(MFPM, Element))
1853+
return Err;
1854+
}
1855+
return Error::success();
1856+
}
1857+
18051858
Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
18061859
ArrayRef<PipelineElement> Pipeline) {
18071860
for (const auto &Element : Pipeline) {
@@ -1961,6 +2014,20 @@ Error PassBuilder::parsePassPipeline(LoopPassManager &CGPM,
19612014
return Error::success();
19622015
}
19632016

2017+
Error PassBuilder::parsePassPipeline(MachineFunctionPassManager &MFPM,
2018+
StringRef PipelineText) {
2019+
auto Pipeline = parsePipelineText(PipelineText);
2020+
if (!Pipeline || Pipeline->empty())
2021+
return make_error<StringError>(
2022+
formatv("invalid machine pass pipeline '{0}'", PipelineText).str(),
2023+
inconvertibleErrorCode());
2024+
2025+
if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2026+
return Err;
2027+
2028+
return Error::success();
2029+
}
2030+
19642031
Error PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
19652032
// If the pipeline just consists of the word 'default' just replace the AA
19662033
// manager with our default one.
@@ -2055,6 +2122,21 @@ void PassBuilder::printPassNames(raw_ostream &OS) {
20552122
OS << "Loop analyses:\n";
20562123
#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
20572124
#include "PassRegistry.def"
2125+
2126+
OS << "Machine module passes (WIP):\n";
2127+
#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
2128+
printPassName(NAME, OS);
2129+
#include "llvm/CodeGen/MachinePassRegistry.def"
2130+
2131+
OS << "Machine function passes (WIP):\n";
2132+
#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \
2133+
printPassName(NAME, OS);
2134+
#include "llvm/CodeGen/MachinePassRegistry.def"
2135+
2136+
OS << "Machine function analyses (WIP):\n";
2137+
#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \
2138+
printPassName(NAME, OS);
2139+
#include "llvm/CodeGen/MachinePassRegistry.def"
20582140
}
20592141

20602142
void PassBuilder::registerParseTopLevelPipelineCallback(

llvm/unittests/MIR/CMakeLists.txt

+2
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)