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