1 | //===-------------- PassBuilder bindings for LLVM-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 | /// This file defines the C bindings to the new pass manager |
11 | /// |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "llvm-c/Transforms/PassBuilder.h" |
15 | #include "llvm/Analysis/AliasAnalysis.h" |
16 | #include "llvm/IR/Module.h" |
17 | #include "llvm/IR/Verifier.h" |
18 | #include "llvm/Passes/PassBuilder.h" |
19 | #include "llvm/Passes/StandardInstrumentations.h" |
20 | #include "llvm/Support/CBindingWrapping.h" |
21 | |
22 | using namespace llvm; |
23 | |
24 | namespace llvm { |
25 | /// Helper struct for holding a set of builder options for LLVMRunPasses. This |
26 | /// structure is used to keep LLVMRunPasses backwards compatible with future |
27 | /// versions in case we modify the options the new Pass Manager utilizes. |
28 | class LLVMPassBuilderOptions { |
29 | public: |
30 | explicit LLVMPassBuilderOptions( |
31 | bool DebugLogging = false, bool VerifyEach = false, |
32 | const char *AAPipeline = nullptr, |
33 | PipelineTuningOptions PTO = PipelineTuningOptions()) |
34 | : DebugLogging(DebugLogging), VerifyEach(VerifyEach), |
35 | AAPipeline(AAPipeline), PTO(PTO) {} |
36 | |
37 | bool DebugLogging; |
38 | bool VerifyEach; |
39 | const char *AAPipeline; |
40 | PipelineTuningOptions PTO; |
41 | }; |
42 | } // namespace llvm |
43 | |
44 | static TargetMachine *unwrap(LLVMTargetMachineRef P) { |
45 | return reinterpret_cast<TargetMachine *>(P); |
46 | } |
47 | |
48 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMPassBuilderOptions, |
49 | LLVMPassBuilderOptionsRef) |
50 | |
51 | static LLVMErrorRef runPasses(Module *Mod, Function *Fun, const char *Passes, |
52 | TargetMachine *Machine, |
53 | LLVMPassBuilderOptions *PassOpts) { |
54 | bool Debug = PassOpts->DebugLogging; |
55 | bool VerifyEach = PassOpts->VerifyEach; |
56 | |
57 | PassInstrumentationCallbacks PIC; |
58 | PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC); |
59 | |
60 | LoopAnalysisManager LAM; |
61 | FunctionAnalysisManager FAM; |
62 | CGSCCAnalysisManager CGAM; |
63 | ModuleAnalysisManager MAM; |
64 | if (PassOpts->AAPipeline) { |
65 | // If we have a custom AA pipeline, we need to register it _before_ calling |
66 | // registerFunctionAnalyses, or the default alias analysis pipeline is used. |
67 | AAManager AA; |
68 | if (auto Err = PB.parseAAPipeline(AA, PipelineText: PassOpts->AAPipeline)) |
69 | return wrap(Err: std::move(Err)); |
70 | FAM.registerPass(PassBuilder: [&] { return std::move(AA); }); |
71 | } |
72 | PB.registerLoopAnalyses(LAM); |
73 | PB.registerFunctionAnalyses(FAM); |
74 | PB.registerCGSCCAnalyses(CGAM); |
75 | PB.registerModuleAnalyses(MAM); |
76 | PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); |
77 | |
78 | StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach); |
79 | SI.registerCallbacks(PIC, MAM: &MAM); |
80 | |
81 | // Run the pipeline. |
82 | if (Fun) { |
83 | FunctionPassManager FPM; |
84 | if (VerifyEach) |
85 | FPM.addPass(Pass: VerifierPass()); |
86 | if (auto Err = PB.parsePassPipeline(FPM, PipelineText: Passes)) |
87 | return wrap(Err: std::move(Err)); |
88 | FPM.run(IR&: *Fun, AM&: FAM); |
89 | } else { |
90 | ModulePassManager MPM; |
91 | if (VerifyEach) |
92 | MPM.addPass(Pass: VerifierPass()); |
93 | if (auto Err = PB.parsePassPipeline(MPM, PipelineText: Passes)) |
94 | return wrap(Err: std::move(Err)); |
95 | MPM.run(IR&: *Mod, AM&: MAM); |
96 | } |
97 | |
98 | return LLVMErrorSuccess; |
99 | } |
100 | |
101 | LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes, |
102 | LLVMTargetMachineRef TM, |
103 | LLVMPassBuilderOptionsRef Options) { |
104 | TargetMachine *Machine = unwrap(P: TM); |
105 | LLVMPassBuilderOptions *PassOpts = unwrap(P: Options); |
106 | Module *Mod = unwrap(P: M); |
107 | return runPasses(Mod, Fun: nullptr, Passes, Machine, PassOpts); |
108 | } |
109 | |
110 | LLVMErrorRef LLVMRunPassesOnFunction(LLVMValueRef F, const char *Passes, |
111 | LLVMTargetMachineRef TM, |
112 | LLVMPassBuilderOptionsRef Options) { |
113 | TargetMachine *Machine = unwrap(P: TM); |
114 | LLVMPassBuilderOptions *PassOpts = unwrap(P: Options); |
115 | Function *Fun = unwrap<Function>(P: F); |
116 | return runPasses(Mod: Fun->getParent(), Fun, Passes, Machine, PassOpts); |
117 | } |
118 | |
119 | LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions() { |
120 | return wrap(P: new LLVMPassBuilderOptions()); |
121 | } |
122 | |
123 | void LLVMPassBuilderOptionsSetVerifyEach(LLVMPassBuilderOptionsRef Options, |
124 | LLVMBool VerifyEach) { |
125 | unwrap(P: Options)->VerifyEach = VerifyEach; |
126 | } |
127 | |
128 | void LLVMPassBuilderOptionsSetDebugLogging(LLVMPassBuilderOptionsRef Options, |
129 | LLVMBool DebugLogging) { |
130 | unwrap(P: Options)->DebugLogging = DebugLogging; |
131 | } |
132 | |
133 | void LLVMPassBuilderOptionsSetAAPipeline(LLVMPassBuilderOptionsRef Options, |
134 | const char *AAPipeline) { |
135 | unwrap(P: Options)->AAPipeline = AAPipeline; |
136 | } |
137 | |
138 | void LLVMPassBuilderOptionsSetLoopInterleaving( |
139 | LLVMPassBuilderOptionsRef Options, LLVMBool LoopInterleaving) { |
140 | unwrap(P: Options)->PTO.LoopInterleaving = LoopInterleaving; |
141 | } |
142 | |
143 | void LLVMPassBuilderOptionsSetLoopVectorization( |
144 | LLVMPassBuilderOptionsRef Options, LLVMBool LoopVectorization) { |
145 | unwrap(P: Options)->PTO.LoopVectorization = LoopVectorization; |
146 | } |
147 | |
148 | void LLVMPassBuilderOptionsSetSLPVectorization( |
149 | LLVMPassBuilderOptionsRef Options, LLVMBool SLPVectorization) { |
150 | unwrap(P: Options)->PTO.SLPVectorization = SLPVectorization; |
151 | } |
152 | |
153 | void LLVMPassBuilderOptionsSetLoopUnrolling(LLVMPassBuilderOptionsRef Options, |
154 | LLVMBool LoopUnrolling) { |
155 | unwrap(P: Options)->PTO.LoopUnrolling = LoopUnrolling; |
156 | } |
157 | |
158 | void LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll( |
159 | LLVMPassBuilderOptionsRef Options, LLVMBool ForgetAllSCEVInLoopUnroll) { |
160 | unwrap(P: Options)->PTO.ForgetAllSCEVInLoopUnroll = ForgetAllSCEVInLoopUnroll; |
161 | } |
162 | |
163 | void LLVMPassBuilderOptionsSetLicmMssaOptCap(LLVMPassBuilderOptionsRef Options, |
164 | unsigned LicmMssaOptCap) { |
165 | unwrap(P: Options)->PTO.LicmMssaOptCap = LicmMssaOptCap; |
166 | } |
167 | |
168 | void LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap( |
169 | LLVMPassBuilderOptionsRef Options, unsigned LicmMssaNoAccForPromotionCap) { |
170 | unwrap(P: Options)->PTO.LicmMssaNoAccForPromotionCap = |
171 | LicmMssaNoAccForPromotionCap; |
172 | } |
173 | |
174 | void LLVMPassBuilderOptionsSetCallGraphProfile( |
175 | LLVMPassBuilderOptionsRef Options, LLVMBool CallGraphProfile) { |
176 | unwrap(P: Options)->PTO.CallGraphProfile = CallGraphProfile; |
177 | } |
178 | |
179 | void LLVMPassBuilderOptionsSetMergeFunctions(LLVMPassBuilderOptionsRef Options, |
180 | LLVMBool MergeFunctions) { |
181 | unwrap(P: Options)->PTO.MergeFunctions = MergeFunctions; |
182 | } |
183 | |
184 | void LLVMPassBuilderOptionsSetInlinerThreshold( |
185 | LLVMPassBuilderOptionsRef Options, int Threshold) { |
186 | unwrap(P: Options)->PTO.InlinerThreshold = Threshold; |
187 | } |
188 | |
189 | void LLVMDisposePassBuilderOptions(LLVMPassBuilderOptionsRef Options) { |
190 | delete unwrap(P: Options); |
191 | } |
192 | |