xref: /llvm-project/llvm/lib/Passes/PassBuilderBindings.cpp (revision 00def06c6e9a0582e85bef5f3a186839c48d1ae2)
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, PassOpts->AAPipeline))
69       return wrap(std::move(Err));
70     FAM.registerPass([&] { 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);
80 
81   // Run the pipeline.
82   if (Fun) {
83     FunctionPassManager FPM;
84     if (VerifyEach)
85       FPM.addPass(VerifierPass());
86     if (auto Err = PB.parsePassPipeline(FPM, Passes))
87       return wrap(std::move(Err));
88     FPM.run(*Fun, FAM);
89   } else {
90     ModulePassManager MPM;
91     if (VerifyEach)
92       MPM.addPass(VerifierPass());
93     if (auto Err = PB.parsePassPipeline(MPM, Passes))
94       return wrap(std::move(Err));
95     MPM.run(*Mod, 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(TM);
105   LLVMPassBuilderOptions *PassOpts = unwrap(Options);
106   Module *Mod = unwrap(M);
107   return runPasses(Mod, nullptr, Passes, Machine, PassOpts);
108 }
109 
110 LLVMErrorRef LLVMRunPassesOnFunction(LLVMValueRef F, const char *Passes,
111                                      LLVMTargetMachineRef TM,
112                                      LLVMPassBuilderOptionsRef Options) {
113   TargetMachine *Machine = unwrap(TM);
114   LLVMPassBuilderOptions *PassOpts = unwrap(Options);
115   Function *Fun = unwrap<Function>(F);
116   return runPasses(Fun->getParent(), Fun, Passes, Machine, PassOpts);
117 }
118 
119 LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions() {
120   return wrap(new LLVMPassBuilderOptions());
121 }
122 
123 void LLVMPassBuilderOptionsSetVerifyEach(LLVMPassBuilderOptionsRef Options,
124                                          LLVMBool VerifyEach) {
125   unwrap(Options)->VerifyEach = VerifyEach;
126 }
127 
128 void LLVMPassBuilderOptionsSetDebugLogging(LLVMPassBuilderOptionsRef Options,
129                                            LLVMBool DebugLogging) {
130   unwrap(Options)->DebugLogging = DebugLogging;
131 }
132 
133 void LLVMPassBuilderOptionsSetAAPipeline(LLVMPassBuilderOptionsRef Options,
134                                          const char *AAPipeline) {
135   unwrap(Options)->AAPipeline = AAPipeline;
136 }
137 
138 void LLVMPassBuilderOptionsSetLoopInterleaving(
139     LLVMPassBuilderOptionsRef Options, LLVMBool LoopInterleaving) {
140   unwrap(Options)->PTO.LoopInterleaving = LoopInterleaving;
141 }
142 
143 void LLVMPassBuilderOptionsSetLoopVectorization(
144     LLVMPassBuilderOptionsRef Options, LLVMBool LoopVectorization) {
145   unwrap(Options)->PTO.LoopVectorization = LoopVectorization;
146 }
147 
148 void LLVMPassBuilderOptionsSetSLPVectorization(
149     LLVMPassBuilderOptionsRef Options, LLVMBool SLPVectorization) {
150   unwrap(Options)->PTO.SLPVectorization = SLPVectorization;
151 }
152 
153 void LLVMPassBuilderOptionsSetLoopUnrolling(LLVMPassBuilderOptionsRef Options,
154                                             LLVMBool LoopUnrolling) {
155   unwrap(Options)->PTO.LoopUnrolling = LoopUnrolling;
156 }
157 
158 void LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll(
159     LLVMPassBuilderOptionsRef Options, LLVMBool ForgetAllSCEVInLoopUnroll) {
160   unwrap(Options)->PTO.ForgetAllSCEVInLoopUnroll = ForgetAllSCEVInLoopUnroll;
161 }
162 
163 void LLVMPassBuilderOptionsSetLicmMssaOptCap(LLVMPassBuilderOptionsRef Options,
164                                              unsigned LicmMssaOptCap) {
165   unwrap(Options)->PTO.LicmMssaOptCap = LicmMssaOptCap;
166 }
167 
168 void LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap(
169     LLVMPassBuilderOptionsRef Options, unsigned LicmMssaNoAccForPromotionCap) {
170   unwrap(Options)->PTO.LicmMssaNoAccForPromotionCap =
171       LicmMssaNoAccForPromotionCap;
172 }
173 
174 void LLVMPassBuilderOptionsSetCallGraphProfile(
175     LLVMPassBuilderOptionsRef Options, LLVMBool CallGraphProfile) {
176   unwrap(Options)->PTO.CallGraphProfile = CallGraphProfile;
177 }
178 
179 void LLVMPassBuilderOptionsSetMergeFunctions(LLVMPassBuilderOptionsRef Options,
180                                              LLVMBool MergeFunctions) {
181   unwrap(Options)->PTO.MergeFunctions = MergeFunctions;
182 }
183 
184 void LLVMPassBuilderOptionsSetInlinerThreshold(
185     LLVMPassBuilderOptionsRef Options, int Threshold) {
186   unwrap(Options)->PTO.InlinerThreshold = Threshold;
187 }
188 
189 void LLVMDisposePassBuilderOptions(LLVMPassBuilderOptionsRef Options) {
190   delete unwrap(Options);
191 }
192