|  | //===-------------- PassBuilder bindings for LLVM-C -----------------------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | /// \file | 
|  | /// | 
|  | /// This file defines the C bindings to the new pass manager | 
|  | /// | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "llvm-c/Transforms/PassBuilder.h" | 
|  | #include "llvm/Analysis/AliasAnalysis.h" | 
|  | #include "llvm/IR/Module.h" | 
|  | #include "llvm/IR/Verifier.h" | 
|  | #include "llvm/Passes/PassBuilder.h" | 
|  | #include "llvm/Passes/StandardInstrumentations.h" | 
|  | #include "llvm/Support/CBindingWrapping.h" | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | namespace llvm { | 
|  | /// Helper struct for holding a set of builder options for LLVMRunPasses. This | 
|  | /// structure is used to keep LLVMRunPasses backwards compatible with future | 
|  | /// versions in case we modify the options the new Pass Manager utilizes. | 
|  | class LLVMPassBuilderOptions { | 
|  | public: | 
|  | explicit LLVMPassBuilderOptions( | 
|  | bool DebugLogging = false, bool VerifyEach = false, | 
|  | const char *AAPipeline = nullptr, | 
|  | PipelineTuningOptions PTO = PipelineTuningOptions()) | 
|  | : DebugLogging(DebugLogging), VerifyEach(VerifyEach), | 
|  | AAPipeline(AAPipeline), PTO(PTO) {} | 
|  |  | 
|  | bool DebugLogging; | 
|  | bool VerifyEach; | 
|  | const char *AAPipeline; | 
|  | PipelineTuningOptions PTO; | 
|  | }; | 
|  | } // namespace llvm | 
|  |  | 
|  | static TargetMachine *unwrap(LLVMTargetMachineRef P) { | 
|  | return reinterpret_cast<TargetMachine *>(P); | 
|  | } | 
|  |  | 
|  | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMPassBuilderOptions, | 
|  | LLVMPassBuilderOptionsRef) | 
|  |  | 
|  | static LLVMErrorRef runPasses(Module *Mod, Function *Fun, const char *Passes, | 
|  | TargetMachine *Machine, | 
|  | LLVMPassBuilderOptions *PassOpts) { | 
|  | bool Debug = PassOpts->DebugLogging; | 
|  | bool VerifyEach = PassOpts->VerifyEach; | 
|  |  | 
|  | PassInstrumentationCallbacks PIC; | 
|  | PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC); | 
|  |  | 
|  | LoopAnalysisManager LAM; | 
|  | FunctionAnalysisManager FAM; | 
|  | CGSCCAnalysisManager CGAM; | 
|  | ModuleAnalysisManager MAM; | 
|  | if (PassOpts->AAPipeline) { | 
|  | // If we have a custom AA pipeline, we need to register it _before_ calling | 
|  | // registerFunctionAnalyses, or the default alias analysis pipeline is used. | 
|  | AAManager AA; | 
|  | if (auto Err = PB.parseAAPipeline(AA, PassOpts->AAPipeline)) | 
|  | return wrap(std::move(Err)); | 
|  | FAM.registerPass([&] { return std::move(AA); }); | 
|  | } | 
|  | PB.registerLoopAnalyses(LAM); | 
|  | PB.registerFunctionAnalyses(FAM); | 
|  | PB.registerCGSCCAnalyses(CGAM); | 
|  | PB.registerModuleAnalyses(MAM); | 
|  | PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); | 
|  |  | 
|  | StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach); | 
|  | SI.registerCallbacks(PIC, &MAM); | 
|  |  | 
|  | // Run the pipeline. | 
|  | if (Fun) { | 
|  | FunctionPassManager FPM; | 
|  | if (VerifyEach) | 
|  | FPM.addPass(VerifierPass()); | 
|  | if (auto Err = PB.parsePassPipeline(FPM, Passes)) | 
|  | return wrap(std::move(Err)); | 
|  | FPM.run(*Fun, FAM); | 
|  | } else { | 
|  | ModulePassManager MPM; | 
|  | if (VerifyEach) | 
|  | MPM.addPass(VerifierPass()); | 
|  | if (auto Err = PB.parsePassPipeline(MPM, Passes)) | 
|  | return wrap(std::move(Err)); | 
|  | MPM.run(*Mod, MAM); | 
|  | } | 
|  |  | 
|  | return LLVMErrorSuccess; | 
|  | } | 
|  |  | 
|  | LLVMErrorRef LLVMRunPasses(LLVMModuleRef M, const char *Passes, | 
|  | LLVMTargetMachineRef TM, | 
|  | LLVMPassBuilderOptionsRef Options) { | 
|  | TargetMachine *Machine = unwrap(TM); | 
|  | LLVMPassBuilderOptions *PassOpts = unwrap(Options); | 
|  | Module *Mod = unwrap(M); | 
|  | return runPasses(Mod, nullptr, Passes, Machine, PassOpts); | 
|  | } | 
|  |  | 
|  | LLVMErrorRef LLVMRunPassesOnFunction(LLVMValueRef F, const char *Passes, | 
|  | LLVMTargetMachineRef TM, | 
|  | LLVMPassBuilderOptionsRef Options) { | 
|  | TargetMachine *Machine = unwrap(TM); | 
|  | LLVMPassBuilderOptions *PassOpts = unwrap(Options); | 
|  | Function *Fun = unwrap<Function>(F); | 
|  | return runPasses(Fun->getParent(), Fun, Passes, Machine, PassOpts); | 
|  | } | 
|  |  | 
|  | LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions() { | 
|  | return wrap(new LLVMPassBuilderOptions()); | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetVerifyEach(LLVMPassBuilderOptionsRef Options, | 
|  | LLVMBool VerifyEach) { | 
|  | unwrap(Options)->VerifyEach = VerifyEach; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetDebugLogging(LLVMPassBuilderOptionsRef Options, | 
|  | LLVMBool DebugLogging) { | 
|  | unwrap(Options)->DebugLogging = DebugLogging; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetAAPipeline(LLVMPassBuilderOptionsRef Options, | 
|  | const char *AAPipeline) { | 
|  | unwrap(Options)->AAPipeline = AAPipeline; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetLoopInterleaving( | 
|  | LLVMPassBuilderOptionsRef Options, LLVMBool LoopInterleaving) { | 
|  | unwrap(Options)->PTO.LoopInterleaving = LoopInterleaving; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetLoopVectorization( | 
|  | LLVMPassBuilderOptionsRef Options, LLVMBool LoopVectorization) { | 
|  | unwrap(Options)->PTO.LoopVectorization = LoopVectorization; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetSLPVectorization( | 
|  | LLVMPassBuilderOptionsRef Options, LLVMBool SLPVectorization) { | 
|  | unwrap(Options)->PTO.SLPVectorization = SLPVectorization; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetLoopUnrolling(LLVMPassBuilderOptionsRef Options, | 
|  | LLVMBool LoopUnrolling) { | 
|  | unwrap(Options)->PTO.LoopUnrolling = LoopUnrolling; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll( | 
|  | LLVMPassBuilderOptionsRef Options, LLVMBool ForgetAllSCEVInLoopUnroll) { | 
|  | unwrap(Options)->PTO.ForgetAllSCEVInLoopUnroll = ForgetAllSCEVInLoopUnroll; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetLicmMssaOptCap(LLVMPassBuilderOptionsRef Options, | 
|  | unsigned LicmMssaOptCap) { | 
|  | unwrap(Options)->PTO.LicmMssaOptCap = LicmMssaOptCap; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap( | 
|  | LLVMPassBuilderOptionsRef Options, unsigned LicmMssaNoAccForPromotionCap) { | 
|  | unwrap(Options)->PTO.LicmMssaNoAccForPromotionCap = | 
|  | LicmMssaNoAccForPromotionCap; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetCallGraphProfile( | 
|  | LLVMPassBuilderOptionsRef Options, LLVMBool CallGraphProfile) { | 
|  | unwrap(Options)->PTO.CallGraphProfile = CallGraphProfile; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetMergeFunctions(LLVMPassBuilderOptionsRef Options, | 
|  | LLVMBool MergeFunctions) { | 
|  | unwrap(Options)->PTO.MergeFunctions = MergeFunctions; | 
|  | } | 
|  |  | 
|  | void LLVMPassBuilderOptionsSetInlinerThreshold( | 
|  | LLVMPassBuilderOptionsRef Options, int Threshold) { | 
|  | unwrap(Options)->PTO.InlinerThreshold = Threshold; | 
|  | } | 
|  |  | 
|  | void LLVMDisposePassBuilderOptions(LLVMPassBuilderOptionsRef Options) { | 
|  | delete unwrap(Options); | 
|  | } |