Skip to content

Commit b4867b3

Browse files
committed
Add TargetPassBuilder.
1 parent 4cc152c commit b4867b3

File tree

9 files changed

+1375
-0
lines changed

9 files changed

+1375
-0
lines changed

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,13 @@ DUMMY_MACHINE_MODULE_PASS("pseudo-probe-inserter", PseudoProbeInserterPass)
288288
DUMMY_MACHINE_MODULE_PASS("mir-debugify", DebugifyMachineModule)
289289
DUMMY_MACHINE_MODULE_PASS("mir-check-debugify", CheckDebugMachineModulePass)
290290
DUMMY_MACHINE_MODULE_PASS("mir-strip-debug", StripDebugMachineModulePass)
291+
DUMMY_MACHINE_MODULE_PASS("static-data-annotator", StaticDataAnnotatorPass)
291292
#undef DUMMY_MACHINE_MODULE_PASS
292293

293294
#ifndef DUMMY_MACHINE_FUNCTION_PASS
294295
#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME)
295296
#endif
297+
DUMMY_MACHINE_FUNCTION_PASS("bb-path-cloning", BasicBlockPathCloningPass)
296298
DUMMY_MACHINE_FUNCTION_PASS("bbsections-prepare", BasicBlockSectionsPass)
297299
DUMMY_MACHINE_FUNCTION_PASS("bbsections-profile-reader", BasicBlockSectionsProfileReaderPass)
298300
DUMMY_MACHINE_FUNCTION_PASS("break-false-deps", BreakFalseDepsPass)
@@ -325,5 +327,6 @@ DUMMY_MACHINE_FUNCTION_PASS("regallocscoringpass", RegAllocScoringPass)
325327
DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass)
326328
DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass)
327329
DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass)
330+
DUMMY_MACHINE_FUNCTION_PASS("static-data-splitter", StaticDataSplitterPass)
328331
DUMMY_MACHINE_FUNCTION_PASS("unpack-mi-bundles", UnpackMachineBundlesPass)
329332
#undef DUMMY_MACHINE_FUNCTION_PASS

llvm/include/llvm/Passes/PassBuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ class PassBuilder {
112112
std::optional<PGOOptions> PGOOpt;
113113
PassInstrumentationCallbacks *PIC;
114114

115+
friend class TargetPassBuilder;
116+
115117
public:
116118
/// A struct to capture parsed pass pipeline names.
117119
///
Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
//===- Parsing, selection, and construction of pass pipelines --*- C++ -*--===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
/// \file
9+
///
10+
/// Interfaces for registering analysis passes, producing common pass manager
11+
/// configurations, and parsing of pass pipelines.
12+
///
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_PASSES_TARGETPASSBUILDER_H
16+
#define LLVM_PASSES_TARGETPASSBUILDER_H
17+
18+
#include "llvm/ADT/SmallVector.h"
19+
#include "llvm/ADT/StringSet.h"
20+
#include "llvm/ADT/identity.h"
21+
#include "llvm/Analysis/CGSCCPassManager.h"
22+
#include "llvm/CodeGen/MachinePassManager.h"
23+
#include "llvm/Target/CGPassBuilderOption.h"
24+
#include "llvm/Transforms/Scalar/LoopPassManager.h"
25+
#include <list>
26+
#include <type_traits>
27+
#include <unordered_set>
28+
#include <utility>
29+
#include <variant>
30+
#include <vector>
31+
32+
namespace llvm {
33+
34+
class PassBuilder;
35+
class TargetMachine;
36+
class SelectionDAGISel;
37+
38+
/// @brief Build CodeGen pipeline
39+
///
40+
class TargetPassBuilder {
41+
public:
42+
TargetPassBuilder(PassBuilder &PB);
43+
44+
virtual ~TargetPassBuilder() = default;
45+
46+
// TODO: Add necessary parameters once AsmPrinter is ported to new pass
47+
// manager.
48+
llvm::ModulePassManager buildPipeline(raw_pwrite_stream &Out,
49+
raw_pwrite_stream *DwoOut,
50+
CodeGenFileType FileType,
51+
MCContext &Ctx);
52+
53+
private:
54+
struct PassWrapper {
55+
StringRef Name;
56+
std::variant<llvm::ModulePassManager, llvm::FunctionPassManager,
57+
llvm::LoopPassManager, llvm::MachineFunctionPassManager>
58+
InternalPass;
59+
bool InCGSCC = false;
60+
61+
template <typename PassManagerT>
62+
PassWrapper(StringRef Name, PassManagerT &&PM)
63+
: Name(Name), InternalPass(std::forward<PassManagerT>(PM)) {}
64+
65+
template <typename PassT> PassWrapper(PassT &&P) : Name(PassT::name()) {
66+
// FIXME: This can't handle the case when `run` is template.
67+
if constexpr (isModulePass<PassT>) {
68+
llvm::ModulePassManager MPM;
69+
MPM.addPass(std::forward<PassT>(P));
70+
InternalPass.emplace<llvm::ModulePassManager>(std::move(MPM));
71+
} else if constexpr (isFunctionPass<PassT>) {
72+
llvm::FunctionPassManager FPM;
73+
FPM.addPass(std::forward<PassT>(P));
74+
InternalPass.emplace<llvm::FunctionPassManager>(std::move(FPM));
75+
} else {
76+
static_assert(isMachineFunctionPass<PassT>, "Invalid pass type!");
77+
llvm::MachineFunctionPassManager MFPM;
78+
MFPM.addPass(std::forward<PassT>(P));
79+
InternalPass.emplace<llvm::MachineFunctionPassManager>(std::move(MFPM));
80+
}
81+
}
82+
};
83+
84+
public:
85+
using PassList = std::list<PassWrapper>;
86+
87+
private:
88+
template <typename InternalPassT> struct AdaptorWrapper : InternalPassT {
89+
using InternalPassT::Passes;
90+
};
91+
92+
template <typename PassManagerT, typename InternalPassT = void>
93+
class PassManagerWrapper {
94+
friend class TargetPassBuilder;
95+
96+
public:
97+
bool isEmpty() const { return Passes.empty(); }
98+
99+
template <typename PassT> void addPass(PassT &&P) {
100+
PassManagerT PM;
101+
PM.addPass(std::forward<PassT>(P));
102+
// Injection point doesn't add real pass.
103+
if constexpr (std::is_base_of_v<InjectionPointMixin, PassT>)
104+
PM = PassManagerT();
105+
PassWrapper PW(PassT::name(), std::move(PM));
106+
Passes.push_back(std::move(PW));
107+
}
108+
109+
void addPass(PassManagerWrapper &&PM) {
110+
for (auto &P : PM.Passes)
111+
Passes.push_back(std::move(P));
112+
}
113+
114+
void addPass(AdaptorWrapper<InternalPassT> &&Adaptor) {
115+
for (auto &P : Adaptor.Passes)
116+
Passes.push_back(std::move(P));
117+
}
118+
119+
void addPass(llvm::ModulePassManager &&) = delete;
120+
void addPass(llvm::FunctionPassManager &&) = delete;
121+
void addPass(llvm::LoopPassManager &&) = delete;
122+
void addPass(llvm::MachineFunctionPassManager &&) = delete;
123+
124+
private:
125+
PassList Passes;
126+
};
127+
128+
template <typename NestedPassManagerT, typename PassT>
129+
AdaptorWrapper<NestedPassManagerT> createPassAdaptor(PassT &&P) {
130+
AdaptorWrapper<NestedPassManagerT> Adaptor;
131+
Adaptor.addPass(std::forward<PassT>(P));
132+
return Adaptor;
133+
}
134+
135+
private:
136+
template <typename PassT, typename IRUnitT>
137+
using HasRunOnIRUnit = decltype(std::declval<PassT>().run(
138+
std::declval<IRUnitT &>(), std::declval<AnalysisManager<IRUnitT> &>()));
139+
template <typename PassT>
140+
static constexpr bool isModulePass =
141+
is_detected<HasRunOnIRUnit, PassT, Module>::value;
142+
template <typename PassT>
143+
static constexpr bool isFunctionPass =
144+
is_detected<HasRunOnIRUnit, PassT, Function>::value;
145+
template <typename PassT>
146+
static constexpr bool isMachineFunctionPass =
147+
is_detected<HasRunOnIRUnit, PassT, MachineFunction>::value;
148+
149+
protected:
150+
// Hijack real pass managers intentionally.
151+
using MachineFunctionPassManager =
152+
PassManagerWrapper<llvm::MachineFunctionPassManager>;
153+
using FunctionPassManager =
154+
PassManagerWrapper<llvm::FunctionPassManager, MachineFunctionPassManager>;
155+
using ModulePassManager =
156+
PassManagerWrapper<llvm::ModulePassManager, FunctionPassManager>;
157+
158+
struct CGSCCAdaptorWrapper : AdaptorWrapper<FunctionPassManager> {};
159+
160+
protected:
161+
template <typename FunctionPassT>
162+
AdaptorWrapper<FunctionPassManager>
163+
createModuleToFunctionPassAdaptor(FunctionPassT &&P) {
164+
return createPassAdaptor<FunctionPassManager>(
165+
std::forward<FunctionPassT>(P));
166+
}
167+
168+
AdaptorWrapper<FunctionPassManager>
169+
createModuleToPostOrderCGSCCPassAdaptor(CGSCCAdaptorWrapper &&PM) {
170+
AdaptorWrapper<FunctionPassManager> AW;
171+
AW.Passes = std::move(PM.Passes);
172+
return AW;
173+
}
174+
175+
template <typename FunctionPassT>
176+
CGSCCAdaptorWrapper createCGSCCToFunctionPassAdaptor(FunctionPassT &&PM) {
177+
for (auto &P : PM.Passes)
178+
P.InCGSCC = true;
179+
CGSCCAdaptorWrapper AW;
180+
AW.Passes = std::move(PM.Passes);
181+
return AW;
182+
}
183+
184+
template <typename MachineFunctionPassT>
185+
AdaptorWrapper<MachineFunctionPassManager>
186+
createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&P) {
187+
return createPassAdaptor<MachineFunctionPassManager>(
188+
std::forward<MachineFunctionPassT>(P));
189+
}
190+
191+
struct InjectionPointMixin {};
192+
// When run is template, injectBefore can't recognize pass type correctly.
193+
struct DummyFunctionPassBase : InjectionPointMixin {
194+
PreservedAnalyses run(Function &, FunctionAnalysisManager &) {
195+
return PreservedAnalyses();
196+
}
197+
};
198+
struct DummyMachineFunctionPassBase : InjectionPointMixin {
199+
PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) {
200+
return PreservedAnalyses();
201+
}
202+
};
203+
struct PreISel : PassInfoMixin<PreISel>, DummyFunctionPassBase {};
204+
struct PostBBSections : PassInfoMixin<PostBBSections>,
205+
DummyMachineFunctionPassBase {};
206+
struct PreEmit : PassInfoMixin<PreEmit>, DummyMachineFunctionPassBase {};
207+
208+
protected:
209+
PassBuilder &PB;
210+
TargetMachine *TM;
211+
CodeGenOptLevel OptLevel;
212+
CGPassBuilderOption CGPBO = getCGPassBuilderOption();
213+
214+
/// @brief The only method to extend pipeline
215+
/// @tparam PassT The injection point
216+
/// @tparam PassManagerT Returned pass manager, by default it depends on the
217+
/// injection point.
218+
/// @param F Callback to build the pipeline.
219+
template <typename PassT,
220+
typename PassManagerT = std::conditional_t<
221+
isModulePass<PassT>, ModulePassManager,
222+
std::conditional_t<isFunctionPass<PassT>, FunctionPassManager,
223+
MachineFunctionPassManager>>>
224+
void injectBefore(
225+
typename llvm::identity<std::function<PassManagerT()>>::argument_type F) {
226+
InjectionCallbacks.push_back(
227+
[Accessed = false, F](PassList &Passes, PassList::iterator I) mutable {
228+
if (Accessed)
229+
return I;
230+
if (PassT::name() != I->Name)
231+
return I;
232+
Accessed = true;
233+
auto PMPasses = F().Passes;
234+
return Passes.insert(I, std::make_move_iterator(PMPasses.begin()),
235+
std::make_move_iterator(PMPasses.end()));
236+
});
237+
}
238+
239+
/// @brief Register selection dag isel pass
240+
/// @tparam BuilderFuncT
241+
/// @param F A function returns a selection dag isel pass.
242+
template <typename BuilderFuncT>
243+
void registerSelectionDAGISelPass(BuilderFuncT F) {
244+
AddSelectionDAGISelPass = [=](MachineFunctionPassManager &MFPM) {
245+
using ResultT = std::invoke_result_t<BuilderFuncT>;
246+
static_assert(isMachineFunctionPass<ResultT> &&
247+
!std::is_same_v<MachineFunctionPassManager, ResultT>,
248+
"Please add only SelectionDAGISelPass!");
249+
MFPM.addPass(F());
250+
};
251+
}
252+
253+
template <typename PassTs> void disablePass() {
254+
DisabedPasses.insert(PassTs::name());
255+
}
256+
257+
void disablePass(StringRef Name) { DisabedPasses.insert(Name); }
258+
259+
template <typename PassT> bool isPassDisabled() const {
260+
return DisabedPasses.contains(PassT::name());
261+
}
262+
263+
bool isPassDisabled(StringRef Name) const {
264+
return DisabedPasses.contains(Name);
265+
}
266+
267+
template <typename PassT> bool isPassEnabled() const {
268+
return !isPassDisabled<PassT>();
269+
}
270+
271+
bool isPassEnabled(StringRef Name) const { return !isPassDisabled(Name); }
272+
273+
private:
274+
void buildCoreCodeGenPipeline(ModulePassManager &MPM);
275+
276+
ModulePassManager buildCodeGenIRPipeline();
277+
278+
/// Add passes that optimize machine instructions in SSA form.
279+
void addISelPasses(MachineFunctionPassManager &MFPM);
280+
void addMachineSSAOptimizationPasses(MachineFunctionPassManager &MFPM);
281+
void addRegAllocPipeline(MachineFunctionPassManager &MFPM);
282+
void addRegAllocPass(MachineFunctionPassManager &MFPM, bool Optimized);
283+
ModulePassManager buildCodeGenMIRPipeline();
284+
285+
void addExceptionHandlingPasses(FunctionPassManager &FPM);
286+
287+
void filtPassList(ModulePassManager &MPM) const;
288+
289+
void addPrinterPassesAndFreeMachineFunction(ModulePassManager &MPM,
290+
raw_pwrite_stream &Out,
291+
raw_pwrite_stream *DwoOut,
292+
CodeGenFileType FileType,
293+
MCContext &Ctx);
294+
295+
llvm::ModulePassManager constructRealPassManager(ModulePassManager &&MPMW);
296+
297+
private:
298+
virtual void anchor();
299+
300+
StringSet<> DisabedPasses;
301+
std::vector<std::function<PassList::iterator(PassList &, PassList::iterator)>>
302+
InjectionCallbacks;
303+
std::function<void(MachineFunctionPassManager &)> AddSelectionDAGISelPass;
304+
305+
void invokeInjectionCallbacks(ModulePassManager &MPM) const;
306+
307+
// Only Loop Strength Reduction need this, shadow LoopPassManager
308+
// in future if it is necessary.
309+
template <typename PassT>
310+
void addLoopPass(FunctionPassManager &FPM, PassT &&P) {
311+
LoopPassManager LPM;
312+
LPM.addPass(std::forward<PassT>(P));
313+
FPM.Passes.push_back(PassWrapper(PassT::name(), std::move(LPM)));
314+
}
315+
};
316+
317+
template <> struct TargetPassBuilder::AdaptorWrapper<void> {};
318+
319+
} // namespace llvm
320+
321+
#endif

llvm/include/llvm/Target/CGPassBuilderOption.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,11 @@ struct CGPassBuilderOption {
5151
bool EnableMachineFunctionSplitter = false;
5252
bool EnableSinkAndFold = false;
5353
bool EnableTailMerge = true;
54+
bool EnableLoopTermFold = false;
5455
bool MISchedPostRA = false;
5556
bool EarlyLiveIntervals = false;
5657
bool GCEmptyBlocks = false;
58+
bool SplitStaticData = false;
5759

5860
bool DisableLSR = false;
5961
bool DisableCGP = false;
@@ -65,6 +67,9 @@ struct CGPassBuilderOption {
6567
bool DisableExpandReductions = false;
6668
bool DisableRAFSProfileLoader = false;
6769
bool DisableCFIFixup = false;
70+
bool DisableReplaceWithVecLib = false;
71+
bool DisableLayoutFSProfileLoader = false;
72+
bool DisablePrologEpilogInserterPass = false;
6873
bool PrintAfterISel = false;
6974
bool PrintISelInput = false;
7075
bool RequiresCodeGenSCCOrder = false;

llvm/lib/CodeGen/TargetPassConfig.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,12 +506,15 @@ CGPassBuilderOption llvm::getCGPassBuilderOption() {
506506
SET_BOOLEAN_OPTION(DisableCGP)
507507
SET_BOOLEAN_OPTION(DisablePartialLibcallInlining)
508508
SET_BOOLEAN_OPTION(DisableSelectOptimize)
509+
SET_BOOLEAN_OPTION(DisableReplaceWithVecLib)
510+
SET_BOOLEAN_OPTION(DisableLayoutFSProfileLoader)
509511
SET_BOOLEAN_OPTION(PrintISelInput)
510512
SET_BOOLEAN_OPTION(DebugifyAndStripAll)
511513
SET_BOOLEAN_OPTION(DebugifyCheckAndStripAll)
512514
SET_BOOLEAN_OPTION(DisableRAFSProfileLoader)
513515
SET_BOOLEAN_OPTION(DisableCFIFixup)
514516
SET_BOOLEAN_OPTION(EnableMachineFunctionSplitter)
517+
SET_BOOLEAN_OPTION(SplitStaticData)
515518

516519
return Opt;
517520
}

llvm/lib/Passes/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_llvm_component_library(LLVMPasses
66
PassBuilderPipelines.cpp
77
PassPlugin.cpp
88
StandardInstrumentations.cpp
9+
TargetPassBuilder.cpp
910

1011
ADDITIONAL_HEADER_DIRS
1112
${LLVM_MAIN_INCLUDE_DIR}/llvm

0 commit comments

Comments
 (0)