diff --git a/deps/LLVMExtra/include/LLVMExtra.h b/deps/LLVMExtra/include/LLVMExtra.h index 543c2c14..cf6f61b5 100644 --- a/deps/LLVMExtra/include/LLVMExtra.h +++ b/deps/LLVMExtra/include/LLVMExtra.h @@ -4,6 +4,10 @@ #include "llvm/Config/llvm-config.h" #include #include +typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef; +// Can't include TargetMachine since that would inclue LLVMInitializeNativeTarget +// #include +#include LLVM_C_EXTERN_C_BEGIN @@ -159,6 +163,29 @@ LLVMValueRef LLVMBuildCallWithOpBundle(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, LLVMOperandBundleDefRef *Bundles, unsigned NumBundles, const char *Name); +void LLVMAdjustPassManager(LLVMTargetMachineRef TM, LLVMPassManagerBuilderRef PMB); + +typedef void (*LLVMPassManagerBuilderExtensionFunction)( + void *Ctx, LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM); + +typedef enum { + EP_EarlyAsPossible, + EP_ModuleOptimizerEarly, + EP_LoopOptimizerEnd, + EP_ScalarOptimizerLate, + EP_OptimizerLast, + EP_VectorizerStart, + EP_EnabledOnOptLevel0, + EP_Peephole, + EP_LateLoopOptimizations, + EP_CGSCCOptimizerLate, + EP_FullLinkTimeOptimizationEarly, + EP_FullLinkTimeOptimizationLast, +} LLVMPassManagerBuilderExtensionPointTy; + +void LLVMPassManagerBuilderAddExtension(LLVMPassManagerBuilderRef PMB, + LLVMPassManagerBuilderExtensionPointTy Ty, + LLVMPassManagerBuilderExtensionFunction Fn, void *Ctx); LLVM_C_EXTERN_C_END #endif diff --git a/deps/LLVMExtra/lib/llvm-api.cpp b/deps/LLVMExtra/lib/llvm-api.cpp index c937dac5..ce7ff270 100644 --- a/deps/LLVMExtra/lib/llvm-api.cpp +++ b/deps/LLVMExtra/lib/llvm-api.cpp @@ -21,6 +21,8 @@ #endif #include #include +#include +#include using namespace llvm; using namespace llvm::legacy; @@ -548,3 +550,17 @@ LLVMValueRef LLVMBuildCallWithOpBundle(LLVMBuilderRef B, LLVMValueRef Fn, return wrap(unwrap(B)->CreateCall(FnT, unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), BundleArray, Name)); } + +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) +void LLVMAdjustPassManager(LLVMTargetMachineRef TM, LLVMPassManagerBuilderRef PMB) { + unwrap(TM)->adjustPassManager(*unwrap(PMB)); +} + +void LLVMPassManagerBuilderAddExtension(LLVMPassManagerBuilderRef PMB, + LLVMPassManagerBuilderExtensionPointTy Ty, + LLVMPassManagerBuilderExtensionFunction Fn, void *Ctx) { + PassManagerBuilder &Builder = *unwrap(PMB); + Builder.addExtension((PassManagerBuilder::ExtensionPointTy)Ty, + [&](const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { + Fn(Ctx, wrap(const_cast(&Builder)), wrap(&PM)); }); +} \ No newline at end of file diff --git a/lib/libLLVM_extra.jl b/lib/libLLVM_extra.jl index e739b5f1..baa57c08 100644 --- a/lib/libLLVM_extra.jl +++ b/lib/libLLVM_extra.jl @@ -419,3 +419,28 @@ function LLVMBuildCallWithOpBundle(B, Fn, Args, NumArgs, Bundles, NumBundles, Na ccall((:LLVMBuildCallWithOpBundle, libLLVMExtra), LLVMValueRef, (LLVMBuilderRef, LLVMValueRef, Ptr{LLVMValueRef}, Cuint, Ptr{LLVMOperandBundleDefRef}, Cuint, Cstring), B, Fn, Args, NumArgs, Bundles, NumBundles, Name) end +function LLVMAdjustPassManager(TM, PMB) + ccall((:LLVMAdjustPassManager, libLLVMExtra), Cvoid, (LLVMTargetMachineRef, LLVMPassManagerBuilderRef), TM, PMB) +end + +const LLVMPassManagerBuilderExtensionFunction = Ptr{Cvoid} + +# See llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h +@cenum LLVMPassManagerBuilderExtensionPointTy::UInt32 begin + EP_EarlyAsPossible = 0 + EP_ModuleOptimizerEarly = 1 + EP_LoopOptimizerEnd = 2 + EP_ScalarOptimizerLate = 3 + EP_OptimizerLast = 4 + EP_VectorizerStart = 5 + EP_EnabledOnOptLevel0 = 6 + EP_Peephole = 7 + EP_LateLoopOptimizations= 8 + EP_CGSCCOptimizerLate = 9 + EP_FullLinkTimeOptimizationEarly = 10 + EP_FullLinkTimeOptimizationLast = 11 +end + +function LLVMPassManagerBuilderAddExtension(PMB, Ty, Fn, Ctx) + ccall((:LLVMPassManagerBuilderAddExtension, libLLVMExtra), Cvoid, (LLVMPassManagerBuilderRef, LLVMPassManagerBuilderExtensionPointTy, LLVMPassManagerBuilderExtensionFunction, Ptr{Cvoid}), PMB, Ty, Fn, Ctx) +end \ No newline at end of file diff --git a/src/targetmachine.jl b/src/targetmachine.jl index ee3899d6..f1232abb 100644 --- a/src/targetmachine.jl +++ b/src/targetmachine.jl @@ -18,6 +18,12 @@ TargetMachine(t::Target, triple::String, cpu::String="", features::String=""; TargetMachine(API.LLVMCreateTargetMachine(t, triple, cpu, features, optlevel, reloc, code)) +function TargetMachine() + host_triple = triple() + host_t = Target(triple=host_triple) + TargetMachine(host_t, host_triple) +end + dispose(tm::TargetMachine) = API.LLVMDisposeTargetMachine(tm) function TargetMachine(f::Core.Function, args...; kwargs...) diff --git a/src/transform.jl b/src/transform.jl index c8d395b9..93f06144 100644 --- a/src/transform.jl +++ b/src/transform.jl @@ -3,11 +3,17 @@ export PassManagerBuilder, dispose, optlevel!, sizelevel!, unit_at_a_time!, unroll_loops!, simplify_libcalls!, inliner!, - populate! + populate!, adjust!, extend! + +mutable struct Callback + fn +end @checked struct PassManagerBuilder ref::API.LLVMPassManagerBuilderRef + rooted::Vector{Callback} end +PassManagerBuilder(ref) = PassManagerBuilder(ref, Callback[]) Base.unsafe_convert(::Type{API.LLVMPassManagerBuilderRef}, pmb::PassManagerBuilder) = pmb.ref @@ -50,6 +56,23 @@ populate!(fpm::FunctionPassManager, pmb::PassManagerBuilder) = populate!(mpm::ModulePassManager, pmb::PassManagerBuilder) = API.LLVMPassManagerBuilderPopulateModulePassManager(pmb, mpm) +adjust!(pmb::PassManagerBuilder, tm::TargetMachine) = + API.LLVMAdjustPassManager(tm, pmb) + +function extend_callback(ctx, pmb, pm) + cb = Base.unsafe_pointer_to_objref(ctx) + cb.fn(PassManagerBuilder(pmb), PassManager(pm)) + return nothing +end + +function extend!(pmb::PassManagerBuilder, ep, fn) + cb = Callback(fn) + push!(pmb.rooted, cb) # root through pmb + c_cb = @cfunction(extend_callback, Cvoid, (Ptr{Cvoid}, API.LLVMPassManagerBuilderRef, API.LLVMPassManagerRef)) + API.LLVMPassManagerBuilderAddExtension(pmb, ep, c_cb, Base.pointer_from_objref(cb)) +end + +extend!(fn, pmb::PassManagerBuilder, ep) = extend!(pmb, ep, fn) ## auxiliary diff --git a/test/transform.jl b/test/transform.jl index f91b262d..3ccefbab 100644 --- a/test/transform.jl +++ b/test/transform.jl @@ -14,6 +14,14 @@ PassManagerBuilder() do pmb simplify_libcalls!(pmb, false) inliner!(pmb, 0) + TargetMachine() do tm + adjust!(pmb, tm) + end + + extend!(pmb, LLVM.API.EP_EarlyAsPossible) do pmb, pm + verifier!(pm) + end + Context() do ctx LLVM.Module("SomeModule"; ctx) do mod FunctionPassManager(mod) do fpm