Skip to content

Commit d30808d

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

File tree

9 files changed

+1361
-0
lines changed

9 files changed

+1361
-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: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
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+
class TargetPassBuilder {
39+
public:
40+
TargetPassBuilder(PassBuilder &PB);
41+
42+
virtual ~TargetPassBuilder() = default;
43+
44+
// TODO: Add necessary parameters once AsmPrinter is ported to new pass
45+
// manager.
46+
llvm::ModulePassManager buildPipeline(raw_pwrite_stream &Out,
47+
raw_pwrite_stream *DwoOut,
48+
CodeGenFileType FileType,
49+
MCContext &Ctx);
50+
51+
private:
52+
struct PassWrapper {
53+
StringRef Name;
54+
std::variant<llvm::ModulePassManager, llvm::FunctionPassManager,
55+
llvm::LoopPassManager, llvm::MachineFunctionPassManager>
56+
InternalPass;
57+
bool InCGSCC = false;
58+
59+
template <typename PassManagerT>
60+
PassWrapper(StringRef Name, PassManagerT &&PM)
61+
: Name(Name), InternalPass(std::forward<PassManagerT>(PM)) {}
62+
63+
template <typename PassT> PassWrapper(PassT &&P) : Name(PassT::name()) {
64+
if constexpr (isModulePass<PassT>) {
65+
llvm::ModulePassManager MPM;
66+
MPM.addPass(std::forward<PassT>(P));
67+
InternalPass.emplace<llvm::ModulePassManager>(std::move(MPM));
68+
} else if constexpr (isFunctionPass<PassT>) {
69+
llvm::FunctionPassManager FPM;
70+
FPM.addPass(std::forward<PassT>(P));
71+
InternalPass.emplace<llvm::FunctionPassManager>(std::move(FPM));
72+
} else {
73+
static_assert(isMachineFunctionPass<PassT>, "Invalid pass type!");
74+
llvm::MachineFunctionPassManager MFPM;
75+
MFPM.addPass(std::forward<PassT>(P));
76+
InternalPass.emplace<llvm::MachineFunctionPassManager>(std::move(MFPM));
77+
}
78+
}
79+
};
80+
81+
public:
82+
using PassList = std::list<PassWrapper>;
83+
84+
private:
85+
template <typename InternalPassT> struct AdaptorWrapper : InternalPassT {
86+
using InternalPassT::Passes;
87+
};
88+
89+
template <typename PassManagerT, typename InternalPassT = void>
90+
class PassManagerWrapper {
91+
friend class TargetPassBuilder;
92+
93+
public:
94+
bool isEmpty() const { return Passes.empty(); }
95+
96+
template <typename PassT> void addPass(PassT &&P) {
97+
Passes.emplace_back(std::forward<PassT>(P));
98+
}
99+
100+
void addPass(PassManagerWrapper &&PM) {
101+
for (auto &P : PM.Passes)
102+
Passes.push_back(std::move(P));
103+
}
104+
105+
void addPass(AdaptorWrapper<InternalPassT> &&Adaptor) {
106+
for (auto &P : Adaptor.Passes)
107+
Passes.push_back(std::move(P));
108+
}
109+
110+
void addPass(llvm::ModulePassManager &&) = delete;
111+
void addPass(llvm::FunctionPassManager &&) = delete;
112+
void addPass(llvm::LoopPassManager &&) = delete;
113+
void addPass(llvm::MachineFunctionPassManager &&) = delete;
114+
115+
private:
116+
PassList Passes;
117+
};
118+
119+
template <typename NestedPassManagerT, typename PassT>
120+
AdaptorWrapper<NestedPassManagerT> createPassAdaptor(PassT &&P) {
121+
AdaptorWrapper<NestedPassManagerT> Adaptor;
122+
Adaptor.addPass(std::forward<PassT>(P));
123+
return Adaptor;
124+
}
125+
126+
private:
127+
template <typename PassT, typename IRUnitT>
128+
using HasRunOnIRUnit = decltype(std::declval<PassT>().run(
129+
std::declval<IRUnitT &>(), std::declval<AnalysisManager<IRUnitT> &>()));
130+
template <typename PassT>
131+
static constexpr bool isModulePass =
132+
is_detected<HasRunOnIRUnit, PassT, Module>::value;
133+
template <typename PassT>
134+
static constexpr bool isFunctionPass =
135+
is_detected<HasRunOnIRUnit, PassT, Function>::value;
136+
template <typename PassT>
137+
static constexpr bool isMachineFunctionPass =
138+
is_detected<HasRunOnIRUnit, PassT, MachineFunction>::value;
139+
140+
protected:
141+
// Hijack real pass managers intentionally.
142+
using MachineFunctionPassManager =
143+
PassManagerWrapper<llvm::MachineFunctionPassManager>;
144+
using FunctionPassManager =
145+
PassManagerWrapper<llvm::FunctionPassManager, MachineFunctionPassManager>;
146+
using ModulePassManager =
147+
PassManagerWrapper<llvm::ModulePassManager, FunctionPassManager>;
148+
149+
struct CGSCCAdaptorWrapper : AdaptorWrapper<FunctionPassManager> {};
150+
151+
protected:
152+
template <typename FunctionPassT>
153+
AdaptorWrapper<FunctionPassManager>
154+
createModuleToFunctionPassAdaptor(FunctionPassT &&P) {
155+
return createPassAdaptor<FunctionPassManager>(
156+
std::forward<FunctionPassT>(P));
157+
}
158+
159+
AdaptorWrapper<FunctionPassManager>
160+
createModuleToPostOrderCGSCCPassAdaptor(CGSCCAdaptorWrapper &&PM) {
161+
AdaptorWrapper<FunctionPassManager> AW;
162+
AW.Passes = std::move(PM.Passes);
163+
return AW;
164+
}
165+
166+
template <typename FunctionPassT>
167+
CGSCCAdaptorWrapper createCGSCCToFunctionPassAdaptor(FunctionPassT &&PM) {
168+
for (auto &P : PM.Passes)
169+
P.InCGSCC = true;
170+
CGSCCAdaptorWrapper AW;
171+
AW.Passes = std::move(PM.Passes);
172+
return AW;
173+
}
174+
175+
template <typename MachineFunctionPassT>
176+
AdaptorWrapper<MachineFunctionPassManager>
177+
createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&P) {
178+
return createPassAdaptor<MachineFunctionPassManager>(
179+
std::forward<MachineFunctionPassT>(P));
180+
}
181+
182+
protected:
183+
PassBuilder &PB;
184+
TargetMachine *TM;
185+
CodeGenOptLevel OptLevel;
186+
CGPassBuilderOption CGPBO = getCGPassBuilderOption();
187+
188+
template <typename PassT,
189+
typename PassManagerT = std::conditional_t<
190+
isModulePass<PassT>, ModulePassManager,
191+
std::conditional_t<isFunctionPass<PassT>, FunctionPassManager,
192+
MachineFunctionPassManager>>>
193+
void injectBefore(
194+
typename llvm::identity<std::function<PassManagerT()>>::argument_type F) {
195+
InjectionCallbacks.push_back(
196+
[Accessed = false, F](PassList &Passes, PassList::iterator I) mutable {
197+
if (Accessed)
198+
return I;
199+
if (PassT::name() != I->Name)
200+
return I;
201+
Accessed = true;
202+
auto PMPasses = F().Passes;
203+
return Passes.insert(I, std::make_move_iterator(PMPasses.begin()),
204+
std::make_move_iterator(PMPasses.end()));
205+
});
206+
}
207+
208+
template <typename PassTs> void disablePass() {
209+
DisabedPasses.insert(PassTs::name());
210+
}
211+
212+
void disablePass(StringRef Name) { DisabedPasses.insert(Name); }
213+
214+
template <typename PassT> bool isPassDisabled() const {
215+
return DisabedPasses.contains(PassT::name());
216+
}
217+
218+
bool isPassDisabled(StringRef Name) const {
219+
return DisabedPasses.contains(Name);
220+
}
221+
222+
template <typename PassT> bool isPassEnabled() const {
223+
return !isPassDisabled<PassT>();
224+
}
225+
226+
bool isPassEnabled(StringRef Name) const { return !isPassDisabled(Name); }
227+
228+
protected:
229+
/// @brief Set target pass hook.
230+
/// @param Hook An instance provide pass getters
231+
/// It must implement getSelectionDAGISelPass
232+
/// TODO: Add ASM printer related hooks.
233+
template <typename HookT> void setTargetHook(HookT &&Hook) {
234+
TH = std::make_unique<TargetHookModel<HookT>>(std::forward<HookT>(Hook));
235+
}
236+
237+
private:
238+
class TargetHookConcept {
239+
virtual void anchor();
240+
241+
public:
242+
virtual void addSelectionDAGISelPass(MachineFunctionPassManager &MFPM) = 0;
243+
virtual void addAsmPrinterPass(ModulePassManager &MPM) = 0;
244+
virtual ~TargetHookConcept() = default;
245+
};
246+
247+
template <typename HookT> class TargetHookModel : public TargetHookConcept {
248+
HookT Hook;
249+
250+
public:
251+
TargetHookModel(HookT &&H) : Hook(H) {}
252+
253+
void addSelectionDAGISelPass(MachineFunctionPassManager &MFPM) override {
254+
using SelectionDAGISelPassT = decltype(Hook.getSelectionDAGISelPass());
255+
static_assert(isMachineFunctionPass<SelectionDAGISelPassT>,
256+
"Add machine function pass here.");
257+
static_assert(!std::is_same_v<llvm::MachineFunctionPassManager,
258+
SelectionDAGISelPassT>,
259+
"MachineFunctionPassManager is not allowed here.");
260+
MFPM.addPass(Hook.getSelectionDAGISelPass());
261+
}
262+
263+
void addAsmPrinterPass(ModulePassManager &MPM) override {
264+
// TODO: get AsmPrinterPass here.
265+
}
266+
};
267+
268+
std::unique_ptr<TargetHookConcept> TH;
269+
270+
void buildCoreCodeGenPipeline(ModulePassManager &MPM);
271+
272+
ModulePassManager buildCodeGenIRPipeline();
273+
274+
/// Add passes that optimize machine instructions in SSA form.
275+
void addISelPasses(MachineFunctionPassManager &MFPM);
276+
void addMachineSSAOptimizationPasses(MachineFunctionPassManager &MFPM);
277+
void addRegAllocPipeline(MachineFunctionPassManager &MFPM);
278+
void addRegAllocPass(MachineFunctionPassManager &MFPM, bool Optimized);
279+
ModulePassManager buildCodeGenMIRPipeline();
280+
281+
void addExceptionHandlingPasses(FunctionPassManager &FPM);
282+
283+
void filtPassList(ModulePassManager &MPM) const;
284+
285+
void addPrinterPasses(ModulePassManager &MPM, raw_pwrite_stream &Out,
286+
raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
287+
MCContext &Ctx);
288+
289+
llvm::ModulePassManager constructRealPassManager(ModulePassManager &&MPMW);
290+
291+
private:
292+
virtual void anchor();
293+
294+
StringSet<> DisabedPasses;
295+
std::vector<std::function<PassList::iterator(PassList &, PassList::iterator)>>
296+
InjectionCallbacks;
297+
298+
void invokeInjectionCallbacks(ModulePassManager &MPM) const;
299+
300+
// Only Loop Strength Reduction need this, shadow LoopPassManager
301+
// in future if it is necessary.
302+
template <typename PassT>
303+
void addLoopPass(FunctionPassManager &FPM, PassT &&P) {
304+
LoopPassManager LPM;
305+
LPM.addPass(std::forward<PassT>(P));
306+
FPM.Passes.push_back(PassWrapper(PassT::name(), std::move(LPM)));
307+
}
308+
};
309+
310+
template <> struct TargetPassBuilder::AdaptorWrapper<void> {};
311+
312+
} // namespace llvm
313+
314+
#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)