diff --git a/deps/LLVMExtra/include/LLVMExtra.h b/deps/LLVMExtra/include/LLVMExtra.h index 5bca5b52..15dbc6b3 100644 --- a/deps/LLVMExtra/include/LLVMExtra.h +++ b/deps/LLVMExtra/include/LLVMExtra.h @@ -186,6 +186,9 @@ void LLVMReplaceMDNodeOperandWith(LLVMMetadataRef MD, unsigned I, LLVMMetadataRe #if LLVM_VERSION_MAJOR >= 13 LLVMBool LLVMContextSupportsTypedPointers(LLVMContextRef C); #endif +#if LLVM_VERSION_MAJOR >= 15 +LLVMBool LLVMContextHasSetOpaquePointersValue(LLVMContextRef C); +#endif // constant data LLVMValueRef LLVMConstDataArray(LLVMTypeRef ElementTy, const void *Data, unsigned NumElements); diff --git a/deps/LLVMExtra/lib/llvm-api.cpp b/deps/LLVMExtra/lib/llvm-api.cpp index e08a6c70..cb333b0a 100644 --- a/deps/LLVMExtra/lib/llvm-api.cpp +++ b/deps/LLVMExtra/lib/llvm-api.cpp @@ -619,6 +619,11 @@ LLVMBool LLVMContextSupportsTypedPointers(LLVMContextRef C) { return unwrap(C)->supportsTypedPointers(); } #endif +#if LLVM_VERSION_MAJOR >= 15 +LLVMBool LLVMContextHasSetOpaquePointersValue(LLVMContextRef C) { + return unwrap(C)->hasSetOpaquePointersValue(); +} +#endif LLVMValueRef LLVMConstDataArray(LLVMTypeRef ElementTy, const void *Data, unsigned NumElements) { StringRef S((const char *)Data, NumElements * unwrap(ElementTy)->getPrimitiveSizeInBits() / 8); diff --git a/lib/libLLVM_extra.jl b/lib/libLLVM_extra.jl index faf1d25e..62baf598 100644 --- a/lib/libLLVM_extra.jl +++ b/lib/libLLVM_extra.jl @@ -452,11 +452,16 @@ function LLVMPostDominatorTreeInstructionDominates(Tree, InstA, InstB) ccall((:LLVMPostDominatorTreeInstructionDominates, libLLVMExtra), LLVMBool, (LLVMPostDominatorTreeRef, LLVMValueRef, LLVMValueRef), Tree, InstA, InstB) end -if version() > v"12" +if version() >= v"13" function LLVMContextSupportsTypedPointers(Ctx) ccall((:LLVMContextSupportsTypedPointers, libLLVMExtra), LLVMBool, (LLVMContextRef,), Ctx) end end +if version() >= v"15" +function LLVMContextHasSetOpaquePointersValue(Ctx) + ccall((:LLVMContextHasSetOpaquePointersValue, libLLVMExtra), LLVMBool, (LLVMContextRef,), Ctx) +end +end function LLVMConstDataArray(ElementTy, Data, NumElements) ccall((:LLVMConstDataArray, libLLVMExtra), LLVMValueRef, (LLVMTypeRef, Ptr{Cvoid}, Cuint), ElementTy, Data, NumElements) diff --git a/src/core/context.jl b/src/core/context.jl index feb24be6..1d2ae384 100644 --- a/src/core/context.jl +++ b/src/core/context.jl @@ -1,6 +1,6 @@ # Contexts are execution states for the core LLVM IR system. -export Context, dispose, GlobalContext, typed_pointers, opaque_pointers! +export Context, dispose, GlobalContext @checked struct Context ref::API.LLVMContextRef @@ -8,8 +8,11 @@ end Base.unsafe_convert(::Type{API.LLVMContextRef}, ctx::Context) = ctx.ref -function Context() +function Context(; opaque_pointers=nothing) ctx = Context(API.LLVMContextCreate()) + if opaque_pointers !== nothing + opaque_pointers!(ctx, opaque_pointers) + end _install_handlers(ctx) activate(ctx) ctx @@ -20,8 +23,8 @@ function dispose(ctx::Context) API.LLVMContextDispose(ctx) end -function Context(f::Core.Function) - ctx = Context() +function Context(f::Core.Function; kwargs...) + ctx = Context(; kwargs...) try f(ctx) finally @@ -31,19 +34,6 @@ end GlobalContext() = Context(API.LLVMGetGlobalContext()) -if version() >= v"13" - typed_pointers(ctx::Context) = - convert(Core.Bool, API.LLVMContextSupportsTypedPointers(ctx)) - - opaque_pointers!(ctx::Context, enable::Core.Bool) = - API.LLVMContextSetOpaquePointers(ctx, enable) -else - typed_pointers(ctx::Context) = true - - opaque_pointers!(ctx::Context, enable::Bool) = - error("Opaque pointers not supported") -end - function Base.show(io::IO, ctx::Context) @printf(io, "LLVM.Context(%p", ctx.ref) if ctx == GlobalContext() @@ -64,6 +54,50 @@ end argument, or use an environment that sypports typed pointers.""") +## opaque pointer handling + +export typed_pointers + +if version() >= v"13" + typed_pointers(ctx::Context) = + convert(Core.Bool, API.LLVMContextSupportsTypedPointers(ctx)) + + if version() >= v"15" + has_set_opaque_pointers_value(ctx::Context) = + convert(Core.Bool, API.LLVMContextHasSetOpaquePointersValue(ctx)) + end + + function unsafe_opaque_pointers!(ctx::Context, enable::Core.Bool) + @static if version() >= v"15" + if has_set_opaque_pointers_value(ctx) && typed_pointers(ctx) != !enable + error("Cannot $(enable ? "enable" : "disable") opaque pointers, as the context has already been configured to use $(typed_pointers(ctx) ? "typed" : "opaque") pointers") + end + end + API.LLVMContextSetOpaquePointers(ctx, enable) + end +else + typed_pointers(ctx::Context) = true +end + +function opaque_pointers!(ctx::Context, opaque_pointers::Core.Bool) + @static if version() < v"13" + if opaque_pointers + error("LLVM <13 does not support opaque pointers") + end + end + + @static if version() >= v"17" + if !opaque_pointers + error("LLVM >=17 does not support typed pointers") + end + end + + @static if v"13" <= version() < v"17" + unsafe_opaque_pointers!(ctx, opaque_pointers) + end +end + + ## wrapper exception type export LLVMException diff --git a/src/executionengine/ts_module.jl b/src/executionengine/ts_module.jl index 15ed48a0..fa679992 100644 --- a/src/executionengine/ts_module.jl +++ b/src/executionengine/ts_module.jl @@ -3,14 +3,17 @@ end Base.unsafe_convert(::Type{API.LLVMOrcThreadSafeContextRef}, ctx::ThreadSafeContext) = ctx.ref -function ThreadSafeContext() +function ThreadSafeContext(; opaque_pointers=nothing) ts_ctx = ThreadSafeContext(API.LLVMOrcCreateNewThreadSafeContext()) + if opaque_pointers !== nothing + opaque_pointers!(context(ts_ctx), opaque_pointers) + end activate(ts_ctx) ts_ctx end -function ThreadSafeContext(f::Core.Function) - ctx = ThreadSafeContext() +function ThreadSafeContext(f::Core.Function; kwargs...) + ctx = ThreadSafeContext(; kwargs...) try f(ctx) finally