Skip to content

Commit

Permalink
Support enabling opaque pointers.
Browse files Browse the repository at this point in the history
  • Loading branch information
maleadt committed Oct 24, 2023
1 parent 217819a commit 97cf7d3
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 33 deletions.
15 changes: 11 additions & 4 deletions src/core/context.jl
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/interop/pointer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions test/core_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -716,15 +716,15 @@ 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"
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))"
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
36 changes: 18 additions & 18 deletions test/instructions_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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\)"
Expand All @@ -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"
Expand All @@ -193,15 +193,15 @@
@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"
end
@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"
Expand All @@ -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"
Expand Down Expand Up @@ -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"
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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.
Expand All @@ -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\)"
Expand Down Expand Up @@ -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"]
Expand Down Expand Up @@ -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)"
Expand Down
2 changes: 1 addition & 1 deletion test/interop_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 97cf7d3

Please sign in to comment.