192 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8/// \file9///10/// This file defines the C bindings to the new pass manager11///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. This26/// structure is used to keep LLVMRunPasses backwards compatible with future27/// 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 llvm43 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_ calling66 // 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 101LLVMErrorRef 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 110LLVMErrorRef 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 119LLVMPassBuilderOptionsRef LLVMCreatePassBuilderOptions() {120 return wrap(new LLVMPassBuilderOptions());121}122 123void LLVMPassBuilderOptionsSetVerifyEach(LLVMPassBuilderOptionsRef Options,124 LLVMBool VerifyEach) {125 unwrap(Options)->VerifyEach = VerifyEach;126}127 128void LLVMPassBuilderOptionsSetDebugLogging(LLVMPassBuilderOptionsRef Options,129 LLVMBool DebugLogging) {130 unwrap(Options)->DebugLogging = DebugLogging;131}132 133void LLVMPassBuilderOptionsSetAAPipeline(LLVMPassBuilderOptionsRef Options,134 const char *AAPipeline) {135 unwrap(Options)->AAPipeline = AAPipeline;136}137 138void LLVMPassBuilderOptionsSetLoopInterleaving(139 LLVMPassBuilderOptionsRef Options, LLVMBool LoopInterleaving) {140 unwrap(Options)->PTO.LoopInterleaving = LoopInterleaving;141}142 143void LLVMPassBuilderOptionsSetLoopVectorization(144 LLVMPassBuilderOptionsRef Options, LLVMBool LoopVectorization) {145 unwrap(Options)->PTO.LoopVectorization = LoopVectorization;146}147 148void LLVMPassBuilderOptionsSetSLPVectorization(149 LLVMPassBuilderOptionsRef Options, LLVMBool SLPVectorization) {150 unwrap(Options)->PTO.SLPVectorization = SLPVectorization;151}152 153void LLVMPassBuilderOptionsSetLoopUnrolling(LLVMPassBuilderOptionsRef Options,154 LLVMBool LoopUnrolling) {155 unwrap(Options)->PTO.LoopUnrolling = LoopUnrolling;156}157 158void LLVMPassBuilderOptionsSetForgetAllSCEVInLoopUnroll(159 LLVMPassBuilderOptionsRef Options, LLVMBool ForgetAllSCEVInLoopUnroll) {160 unwrap(Options)->PTO.ForgetAllSCEVInLoopUnroll = ForgetAllSCEVInLoopUnroll;161}162 163void LLVMPassBuilderOptionsSetLicmMssaOptCap(LLVMPassBuilderOptionsRef Options,164 unsigned LicmMssaOptCap) {165 unwrap(Options)->PTO.LicmMssaOptCap = LicmMssaOptCap;166}167 168void LLVMPassBuilderOptionsSetLicmMssaNoAccForPromotionCap(169 LLVMPassBuilderOptionsRef Options, unsigned LicmMssaNoAccForPromotionCap) {170 unwrap(Options)->PTO.LicmMssaNoAccForPromotionCap =171 LicmMssaNoAccForPromotionCap;172}173 174void LLVMPassBuilderOptionsSetCallGraphProfile(175 LLVMPassBuilderOptionsRef Options, LLVMBool CallGraphProfile) {176 unwrap(Options)->PTO.CallGraphProfile = CallGraphProfile;177}178 179void LLVMPassBuilderOptionsSetMergeFunctions(LLVMPassBuilderOptionsRef Options,180 LLVMBool MergeFunctions) {181 unwrap(Options)->PTO.MergeFunctions = MergeFunctions;182}183 184void LLVMPassBuilderOptionsSetInlinerThreshold(185 LLVMPassBuilderOptionsRef Options, int Threshold) {186 unwrap(Options)->PTO.InlinerThreshold = Threshold;187}188 189void LLVMDisposePassBuilderOptions(LLVMPassBuilderOptionsRef Options) {190 delete unwrap(Options);191}192