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
22using namespace llvm;
23
24namespace 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.
28class LLVMPassBuilderOptions {
29public:
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
44static TargetMachine *unwrap(LLVMTargetMachineRef P) {
45 return reinterpret_cast<TargetMachine *>(P);
46}
47
48DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMPassBuilderOptions,
49 LLVMPassBuilderOptionsRef)
50
51static 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
101LLVMErrorRef 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
110LLVMErrorRef 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
119LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions() {
120 return wrap(P: new LLVMPassBuilderOptions());
121}
122
123void LLVMPassBuilderOptionsSetVerifyEach(LLVMPassBuilderOptionsRef Options,
124 LLVMBool VerifyEach) {
125 unwrap(P: Options)->VerifyEach = VerifyEach;
126}
127
128void LLVMPassBuilderOptionsSetDebugLogging(LLVMPassBuilderOptionsRef Options,
129 LLVMBool DebugLogging) {
130 unwrap(P: Options)->DebugLogging = DebugLogging;
131}
132
133void LLVMPassBuilderOptionsSetAAPipeline(LLVMPassBuilderOptionsRef Options,
134 const char *AAPipeline) {
135 unwrap(P: Options)->AAPipeline = AAPipeline;
136}
137
138void LLVMPassBuilderOptionsSetLoopInterleaving(
139 LLVMPassBuilderOptionsRef Options, LLVMBool LoopInterleaving) {
140 unwrap(P: Options)->PTO.LoopInterleaving = LoopInterleaving;
141}
142
143void LLVMPassBuilderOptionsSetLoopVectorization(
144 LLVMPassBuilderOptionsRef Options, LLVMBool LoopVectorization) {
145 unwrap(P: Options)->PTO.LoopVectorization = LoopVectorization;
146}
147
148void LLVMPassBuilderOptionsSetSLPVectorization(
149 LLVMPassBuilderOptionsRef Options, LLVMBool SLPVectorization) {
150 unwrap(P: Options)->PTO.SLPVectorization = SLPVectorization;
151}
152
153void LLVMPassBuilderOptionsSetLoopUnrolling(LLVMPassBuilderOptionsRef Options,
154 LLVMBool LoopUnrolling) {
155 unwrap(P: Options)->PTO.LoopUnrolling = LoopUnrolling;
156}
157
158void LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll(
159 LLVMPassBuilderOptionsRef Options, LLVMBool ForgetAllSCEVInLoopUnroll) {
160 unwrap(P: Options)->PTO.ForgetAllSCEVInLoopUnroll = ForgetAllSCEVInLoopUnroll;
161}
162
163void LLVMPassBuilderOptionsSetLicmMssaOptCap(LLVMPassBuilderOptionsRef Options,
164 unsigned LicmMssaOptCap) {
165 unwrap(P: Options)->PTO.LicmMssaOptCap = LicmMssaOptCap;
166}
167
168void LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap(
169 LLVMPassBuilderOptionsRef Options, unsigned LicmMssaNoAccForPromotionCap) {
170 unwrap(P: Options)->PTO.LicmMssaNoAccForPromotionCap =
171 LicmMssaNoAccForPromotionCap;
172}
173
174void LLVMPassBuilderOptionsSetCallGraphProfile(
175 LLVMPassBuilderOptionsRef Options, LLVMBool CallGraphProfile) {
176 unwrap(P: Options)->PTO.CallGraphProfile = CallGraphProfile;
177}
178
179void LLVMPassBuilderOptionsSetMergeFunctions(LLVMPassBuilderOptionsRef Options,
180 LLVMBool MergeFunctions) {
181 unwrap(P: Options)->PTO.MergeFunctions = MergeFunctions;
182}
183
184void LLVMPassBuilderOptionsSetInlinerThreshold(
185 LLVMPassBuilderOptionsRef Options, int Threshold) {
186 unwrap(P: Options)->PTO.InlinerThreshold = Threshold;
187}
188
189void LLVMDisposePassBuilderOptions(LLVMPassBuilderOptionsRef Options) {
190 delete unwrap(P: Options);
191}
192