diff --git a/src/core/context.jl b/src/core/context.jl index 6747b59b..feb24be6 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, supports_typed_pointers +export Context, dispose, GlobalContext, typed_pointers, opaque_pointers! @checked struct Context ref::API.LLVMContextRef @@ -32,9 +32,16 @@ end GlobalContext() = Context(API.LLVMGetGlobalContext()) if version() >= v"13" - supports_typed_pointers(ctx::Context) = API.LLVMContextSupportsTypedPointers(ctx) == 1 + typed_pointers(ctx::Context) = + convert(Core.Bool, API.LLVMContextSupportsTypedPointers(ctx)) + + opaque_pointers!(ctx::Context, enable::Core.Bool) = + API.LLVMContextSetOpaquePointers(ctx, enable) else - supports_typed_pointers(ctx::Context) = true + typed_pointers(ctx::Context) = true + + opaque_pointers!(ctx::Context, enable::Bool) = + error("Opaque pointers not supported") end function Base.show(io::IO, ctx::Context) @@ -44,7 +51,7 @@ function Base.show(io::IO, ctx::Context) end if v"14" <= version() < v"17" # migration to opaque pointers - print(io, ", ", supports_typed_pointers(ctx) ? "typed ptrs" : "opaque ptrs") + print(io, ", ", typed_pointers(ctx) ? "typed ptrs" : "opaque ptrs") end print(io, ")") end diff --git a/src/interop/pointer.jl b/src/interop/pointer.jl index 543061e3..d6506f1f 100644 --- a/src/interop/pointer.jl +++ b/src/interop/pointer.jl @@ -24,7 +24,7 @@ using Core: LLVMPtr @dispose builder=IRBuilder() begin entry = BasicBlock(llvm_f, "entry") position!(builder, entry) - ptr = if supports_typed_pointers(ctx) + ptr = if typed_pointers(ctx) typed_ptr = bitcast!(builder, parameters(llvm_f)[1], T_typed_ptr) inbounds_gep!(builder, eltyp, typed_ptr, [parameters(llvm_f)[2]]) else @@ -61,7 +61,7 @@ end @dispose builder=IRBuilder() begin entry = BasicBlock(llvm_f, "entry") position!(builder, entry) - ptr = if supports_typed_pointers(ctx) + ptr = if typed_pointers(ctx) typed_ptr = bitcast!(builder, parameters(llvm_f)[1], T_typed_ptr) inbounds_gep!(builder, eltyp, typed_ptr, [parameters(llvm_f)[3]]) else diff --git a/test/core_tests.jl b/test/core_tests.jl index 98e91438..7f2251de 100644 --- a/test/core_tests.jl +++ b/test/core_tests.jl @@ -32,9 +32,9 @@ Context() do ctx end @dispose ctx=Context() begin end @dispose ctx=Context() begin - @test supports_typed_pointers(ctx) isa Bool + @test typed_pointers(ctx) isa Bool if LLVM.version() > v"17" - @test supports_typed_pointers(ctx) == false + @test typed_pointers(ctx) == false end end @@ -96,7 +96,7 @@ end eltyp = LLVM.Int32Type() ptrtyp = LLVM.PointerType(eltyp) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @test eltype(ptrtyp) == eltyp end @@ -562,7 +562,7 @@ end @testset "constant expressions" begin # inline assembly - if supports_typed_pointers(ctx) + if typed_pointers(ctx) let ft = LLVM.FunctionType(LLVM.VoidType()) asm = InlineAsm(ft, "nop", "", false) @@ -716,7 +716,7 @@ end @check_ir ce "i32 0" ce = const_inttoptr(ce, value_type(ptr))::LLVM.Constant - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir ce "i32* null" else @check_ir ce "ptr null" @@ -724,7 +724,7 @@ end @test isempty(uses(ptr)) for f in [const_addrspacecast, const_pointercast] ce = f(ptr, LLVM.PointerType(LLVM.Int32Type(), 1))::LLVM.Constant - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir ce "i32 addrspace(1)* addrspacecast (i32* null to i32 addrspace(1)*)" else @check_ir ce "ptr addrspace(1) addrspacecast (ptr null to ptr addrspace(1))" @@ -1185,7 +1185,7 @@ end fn = LLVM.Function(mod, intr) @test fn isa LLVM.Function - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @test eltype(value_type(fn)) == ft end @test isintrinsic(fn) @@ -1212,7 +1212,7 @@ end fn = LLVM.Function(mod, intr, [LLVM.DoubleType()]) @test fn isa LLVM.Function - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @test eltype(value_type(fn)) == ft end @test isintrinsic(fn) diff --git a/test/instructions_tests.jl b/test/instructions_tests.jl index 74366403..a1f5a967 100644 --- a/test/instructions_tests.jl +++ b/test/instructions_tests.jl @@ -141,7 +141,7 @@ @check_ir array_allocainst "alloca i32, i32 %0" mallocinst = malloc!(builder, LLVM.Int32Type()) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir mallocinst r"bitcast i8\* %.+ to i32\*" @check_ir operands(mallocinst)[1] r"call i8\* @malloc\(.+\)" else @@ -151,28 +151,28 @@ ptr = parameters(fn)[6] array_mallocinst = array_malloc!(builder, LLVM.Int8Type(), ConstantInt(Int32(42))) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir array_mallocinst r"call i8\* @malloc\(.+, i32 42\)" else @check_ir array_mallocinst r"call ptr @malloc\(.+, i32 42\)" end memsetisnt = memset!(builder, ptr, ConstantInt(Int8(1)), ConstantInt(Int32(2)), 4) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir memsetisnt r"call void @llvm.memset.p0i8.i32\(i8\* align 4 %.+, i8 1, i32 2, i1 false\)" else @check_ir memsetisnt r"call void @llvm.memset.p0.i32\(ptr align 4 %.+, i8 1, i32 2, i1 false\)" end memcpyinst = memcpy!(builder, allocainst, 4, ptr, 8, ConstantInt(Int32(32))) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir memcpyinst r"call void @llvm.memcpy.p0i8.p0i8.i32\(i8\* align 4 %.+, i8\* align 8 %.+, i32 32, i1 false\)" else @check_ir memcpyinst r"call void @llvm.memcpy.p0.p0.i32\(ptr align 4 %.+, ptr align 8 %.+, i32 32, i1 false\)" end memmoveinst = memmove!(builder, allocainst, 4, ptr, 8, ConstantInt(Int32(32))) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir memmoveinst r"call void @llvm.memmove.p0i8.p0i8.i32\(i8\* align 4 %.+, i8\* align 8 %.+, i32 32, i1 false\)" else @check_ir memmoveinst r"call void @llvm.memmove.p0.p0.i32\(ptr align 4 %.+, ptr align 8 %.+, i32 32, i1 false\)" @@ -184,7 +184,7 @@ @check_ir freeinst "tail call void @free" loadinst = load!(builder, LLVM.Int32Type(), ptr1) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir loadinst "load i32, i32* %4" else @check_ir loadinst "load i32, ptr %4" @@ -193,7 +193,7 @@ @test alignment(loadinst) == 4 ordering!(loadinst, LLVM.API.LLVMAtomicOrderingSequentiallyConsistent) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir loadinst "load atomic i32, i32* %4 seq_cst" else @check_ir loadinst "load atomic i32, ptr %4 seq_cst" @@ -201,7 +201,7 @@ @test ordering(loadinst) == LLVM.API.LLVMAtomicOrderingSequentiallyConsistent storeinst = store!(builder, int1, ptr1) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir storeinst "store i32 %0, i32* %4" else @check_ir storeinst "store i32 %0, ptr %4" @@ -211,14 +211,14 @@ @check_ir fenceinst "fence" gepinst = gep!(builder, LLVM.Int32Type(), ptr1, [int1]) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir gepinst "getelementptr i32, i32* %4, i32 %0" else @check_ir gepinst "getelementptr i32, ptr %4, i32 %0" end gepinst1 = inbounds_gep!(builder, LLVM.Int32Type(), ptr1, [int1]) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir gepinst1 "getelementptr inbounds i32, i32* %4, i32 %0" else @check_ir gepinst1 "getelementptr inbounds i32, ptr %4, i32 %0" @@ -252,14 +252,14 @@ @check_ir fpextinst "fpext float %2 to double" ptrtointinst = ptrtoint!(builder, parameters(fn)[5], LLVM.Int32Type()) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir ptrtointinst "ptrtoint i32* %4 to i32" else @check_ir ptrtointinst "ptrtoint ptr %4 to i32" end inttoptrinst = inttoptr!(builder, int1, LLVM.PointerType(LLVM.Int32Type())) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir inttoptrinst "inttoptr i32 %0 to i32*" else @check_ir inttoptrinst "inttoptr i32 %0 to ptr" @@ -268,7 +268,7 @@ bitcastinst = bitcast!(builder, int1, LLVM.FloatType()) @check_ir bitcastinst "bitcast i32 %0 to float" ptr1 = parameters(fn)[5] - if supports_typed_pointers(ctx) + if typed_pointers(ctx) typ1 = value_type(ptr1) ptr2 = LLVM.PointerType(eltype(typ1), 2) addrspacecastinst = addrspacecast!(builder, ptr1, ptr2) @@ -292,7 +292,7 @@ castinst = cast!(builder, LLVM.API.LLVMBitCast, int1, LLVM.FloatType()) @check_ir castinst "bitcast i32 %0 to float" - if supports_typed_pointers(ctx) + if typed_pointers(ctx) floatptrtyp = LLVM.PointerType(LLVM.FloatType()) pointercastinst = pointercast!(builder, ptr1, floatptrtyp) @@ -344,7 +344,7 @@ @check_ir strinst "private unnamed_addr constant [7 x i8] c\"foobar\\00\"" strptrinst = globalstring_ptr!(builder, "foobar") - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir strptrinst "i8* getelementptr inbounds ([7 x i8], [7 x i8]* @1, i32 0, i32 0)" elseif LLVM.version() < v"15" # globalstring_ptr! returns a i8* ptr instead of a ptr to an i8 array. @@ -364,7 +364,7 @@ ptr1 = parameters(fn)[5] ptr2 = parameters(fn)[6] ptrdiffinst = ptrdiff!(builder, LLVM.Int32Type(), ptr1, ptr2) - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @check_ir ptrdiffinst r"sdiv exact i64 %.+, ptrtoint \(i32\* getelementptr \(i32, i32\* null, i32 1\) to i64\)" else @check_ir ptrdiffinst r"sdiv exact i64 %.+, ptrtoint \(ptr getelementptr \(i32, ptr null, i32 1\) to i64\)" @@ -408,7 +408,7 @@ end ret void }""" @dispose ctx=Context() begin - mod = parse(LLVM.Module, supports_typed_pointers(ctx) ? typed_ir : opaque_ir) + mod = parse(LLVM.Module, typed_pointers(ctx) ? typed_ir : opaque_ir) @testset "iteration" begin f = functions(mod)["f"] @@ -451,7 +451,7 @@ end let bundle = bundles[2] inputs = LLVM.inputs(bundle) @test length(inputs) == 1 - if supports_typed_pointers(ctx) + if typed_pointers(ctx) @test string(bundle) == "\"unknown\"(i8* null)" else @test string(bundle) == "\"unknown\"(ptr null)" diff --git a/test/interop_tests.jl b/test/interop_tests.jl index 670c0a61..102d22a4 100644 --- a/test/interop_tests.jl +++ b/test/interop_tests.jl @@ -6,7 +6,7 @@ using InteractiveUtils # many of these tests don't use explicit contexts, as they rely on high-level functionality. # that functionality should be using default context options, so query those here. supports_typed_ptrs = @dispose ctx=Context() begin - supports_typed_pointers(ctx) + typed_pointers(ctx) end @testset "base" begin