From bb2e57bca908556d65edfb3c45d6805592ecc7c2 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 25 Jan 2022 21:53:18 -0500 Subject: [PATCH 1/4] Add adjustPassManager for PMB --- deps/LLVMExtra/include/LLVMExtra.h | 5 +++++ deps/LLVMExtra/lib/llvm-api.cpp | 7 +++++++ lib/libLLVM_extra.jl | 3 +++ 3 files changed, 15 insertions(+) diff --git a/deps/LLVMExtra/include/LLVMExtra.h b/deps/LLVMExtra/include/LLVMExtra.h index 543c2c14..4f8a4905 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,7 @@ LLVMValueRef LLVMBuildCallWithOpBundle(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, LLVMOperandBundleDefRef *Bundles, unsigned NumBundles, const char *Name); +void LLVMAdjustPassManager(LLVMTargetMachineRef TM, LLVMPassManagerBuilderRef PMB); LLVM_C_EXTERN_C_END #endif diff --git a/deps/LLVMExtra/lib/llvm-api.cpp b/deps/LLVMExtra/lib/llvm-api.cpp index c937dac5..5c7a5d91 100644 --- a/deps/LLVMExtra/lib/llvm-api.cpp +++ b/deps/LLVMExtra/lib/llvm-api.cpp @@ -21,6 +21,7 @@ #endif #include #include +#include using namespace llvm; using namespace llvm::legacy; @@ -548,3 +549,9 @@ 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) +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PassManagerBuilder, LLVMPassManagerBuilderRef) +void LLVMAdjustPassManager(LLVMTargetMachineRef TM, LLVMPassManagerBuilderRef PMB) { + unwrap(TM)->adjustPassManager(*unwrap(PMB)); +} diff --git a/lib/libLLVM_extra.jl b/lib/libLLVM_extra.jl index e739b5f1..034a4cfd 100644 --- a/lib/libLLVM_extra.jl +++ b/lib/libLLVM_extra.jl @@ -419,3 +419,6 @@ 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 From 73eed388f9621040ff05d660f5965df05051db62 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Tue, 25 Jan 2022 22:00:27 -0500 Subject: [PATCH 2/4] test adjust! --- src/targetmachine.jl | 6 ++++++ src/transform.jl | 4 +++- test/transform.jl | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) 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..3ce2539a 100644 --- a/src/transform.jl +++ b/src/transform.jl @@ -3,7 +3,7 @@ export PassManagerBuilder, dispose, optlevel!, sizelevel!, unit_at_a_time!, unroll_loops!, simplify_libcalls!, inliner!, - populate! + populate!, adjust! @checked struct PassManagerBuilder ref::API.LLVMPassManagerBuilderRef @@ -50,6 +50,8 @@ populate!(fpm::FunctionPassManager, pmb::PassManagerBuilder) = populate!(mpm::ModulePassManager, pmb::PassManagerBuilder) = API.LLVMPassManagerBuilderPopulateModulePassManager(pmb, mpm) +adjust!(pmb::PassManagerBuilder, tm::TargetMachine) = + API.LLVMAdjustPassManager(tm, pmb) ## auxiliary diff --git a/test/transform.jl b/test/transform.jl index f91b262d..c1b74844 100644 --- a/test/transform.jl +++ b/test/transform.jl @@ -14,6 +14,10 @@ PassManagerBuilder() do pmb simplify_libcalls!(pmb, false) inliner!(pmb, 0) + TargetMachine() do tm + adjust!(pmb, tm) + end + Context() do ctx LLVM.Module("SomeModule"; ctx) do mod FunctionPassManager(mod) do fpm From 86ab0cec047dd1d30a2853ee47e0a254bb3439b5 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 26 Jan 2022 07:59:14 -0500 Subject: [PATCH 3/4] add PassManagerBuilder.addExtension --- deps/LLVMExtra/include/LLVMExtra.h | 22 ++++++++++++++++++++++ deps/LLVMExtra/lib/llvm-api.cpp | 11 ++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/deps/LLVMExtra/include/LLVMExtra.h b/deps/LLVMExtra/include/LLVMExtra.h index 4f8a4905..cf6f61b5 100644 --- a/deps/LLVMExtra/include/LLVMExtra.h +++ b/deps/LLVMExtra/include/LLVMExtra.h @@ -165,5 +165,27 @@ LLVMValueRef LLVMBuildCallWithOpBundle(LLVMBuilderRef B, LLVMValueRef Fn, 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 5c7a5d91..ce7ff270 100644 --- a/deps/LLVMExtra/lib/llvm-api.cpp +++ b/deps/LLVMExtra/lib/llvm-api.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace llvm; using namespace llvm::legacy; @@ -551,7 +552,15 @@ LLVMValueRef LLVMBuildCallWithOpBundle(LLVMBuilderRef B, LLVMValueRef Fn, } DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PassManagerBuilder, LLVMPassManagerBuilderRef) 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 From 96e5a4b7386093e329f85c453a3a95bd347ca9ea Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 26 Jan 2022 08:53:47 -0500 Subject: [PATCH 4/4] WIP add Julia extend interface --- lib/libLLVM_extra.jl | 22 ++++++++++++++++++++++ src/transform.jl | 23 ++++++++++++++++++++++- test/transform.jl | 4 ++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/libLLVM_extra.jl b/lib/libLLVM_extra.jl index 034a4cfd..baa57c08 100644 --- a/lib/libLLVM_extra.jl +++ b/lib/libLLVM_extra.jl @@ -422,3 +422,25 @@ 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/transform.jl b/src/transform.jl index 3ce2539a..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!, adjust! + 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 @@ -53,6 +59,21 @@ populate!(mpm::ModulePassManager, pmb::PassManagerBuilder) = 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 function define_transforms(transforms, available=true; exported=true) diff --git a/test/transform.jl b/test/transform.jl index c1b74844..3ccefbab 100644 --- a/test/transform.jl +++ b/test/transform.jl @@ -18,6 +18,10 @@ PassManagerBuilder() do pmb 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