Skip to content

Commit baebaa8

Browse files
authored
Improve opaque pointer support. (#337)
1 parent 6af3a76 commit baebaa8

File tree

10 files changed

+163
-122
lines changed

10 files changed

+163
-122
lines changed

deps/LLVMExtra/include/LLVMExtra.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,5 +169,11 @@ LLVMBool LLVMContextSupportsTypedPointers(LLVMContextRef C);
169169
// constant data
170170
LLVMValueRef LLVMConstDataArray(LLVMTypeRef ElementTy, const void *Data, unsigned NumElements);
171171

172+
// missing opaque pointer APIs
173+
#if LLVM_VERSION_MAJOR >= 13 && LLVM_VERSION_MAJOR < 15
174+
LLVMBool LLVMPointerTypeIsOpaque(LLVMTypeRef Ty);
175+
LLVMTypeRef LLVMPointerTypeInContext(LLVMContextRef C, unsigned AddressSpace);
176+
#endif
177+
172178
LLVM_C_EXTERN_C_END
173179
#endif

deps/LLVMExtra/lib/llvm-api.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -518,24 +518,14 @@ LLVMValueRef LLVMBuildCallWithOpBundle(LLVMBuilderRef B, LLVMValueRef Fn,
518518
LLVMValueRef *Args, unsigned NumArgs,
519519
LLVMOperandBundleDefRef *Bundles, unsigned NumBundles,
520520
const char *Name) {
521-
522-
// TODO make opaque pointer compatibly
523-
Value *V = unwrap(Fn);
524-
#if LLVM_VERSION_MAJOR <= 14
525-
FunctionType *FnT =
526-
cast<FunctionType>(cast<PointerType>(V->getType())->getElementType());
527-
#else
528-
FunctionType *FnT =
529-
cast<FunctionType>(cast<PointerType>(V->getType())->getPointerElementType()); // deprecated
530-
#endif
531-
532521
SmallVector<OperandBundleDef, 1> BundleArray;
533522
for (auto *Bundle : makeArrayRef(Bundles, NumBundles))
534523
BundleArray.push_back(*unwrap<OperandBundleDef>(Bundle));
535524

536525
llvm::IRBuilder<> *Builder = unwrap(B);
537526
llvm::ArrayRef<llvm::Value*> args = makeArrayRef(unwrap(Args), NumArgs);
538527

528+
FunctionType *FnT = unwrap<Function>(Fn)->getFunctionType();
539529
llvm::CallInst *CI = Builder->CreateCall(FnT, unwrap(Fn), args ,BundleArray, Name);
540530
return wrap(CI);
541531
}
@@ -576,3 +566,12 @@ LLVMTypeRef LLVMGetGlobalValueType(LLVMValueRef GV) {
576566
auto Ftype = unwrap<GlobalValue>(GV)->getValueType();
577567
return wrap(Ftype);
578568
}
569+
570+
#if LLVM_VERSION_MAJOR >= 13 && LLVM_VERSION_MAJOR < 15
571+
LLVMBool LLVMPointerTypeIsOpaque(LLVMTypeRef Ty) {
572+
return unwrap(Ty)->isOpaquePointerTy();
573+
}
574+
LLVMTypeRef LLVMPointerTypeInContext(LLVMContextRef C, unsigned AddressSpace) {
575+
return wrap(PointerType::get(*unwrap(C), AddressSpace));
576+
}
577+
#endif

lib/libLLVM_extra.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,3 +432,12 @@ end
432432
function LLVMGetBuilderContext(B)
433433
ccall((:LLVMGetBuilderContext, libLLVMExtra), LLVMContextRef, (LLVMBuilderRef,), B)
434434
end
435+
436+
if v"13" <= version() < v"15"
437+
function LLVMPointerTypeIsOpaque(Ty)
438+
ccall((:LLVMPointerTypeIsOpaque, libLLVMExtra), LLVMBool, (LLVMTypeRef,), Ty)
439+
end
440+
function LLVMPointerTypeInContext(C, AddressSpace)
441+
ccall((:LLVMPointerTypeInContext, libLLVMExtra), LLVMTypeRef, (LLVMContextRef, Cuint), C, AddressSpace)
442+
end
443+
end

src/core/type.jl

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ abstract type CompositeType <: LLVMType end
134134

135135
## sequential types
136136

137-
export addrspace
137+
export addrspace, is_opaque
138138

139139
abstract type SequentialType <: CompositeType end
140140

@@ -150,12 +150,20 @@ function PointerType(eltyp::LLVMType, addrspace=0)
150150
return PointerType(API.LLVMPointerType(eltyp, addrspace))
151151
end
152152

153-
if version() >= v"15"
154-
function PointerType(ctx::Context, addrspace=0)
155-
return PointerType(API.LLVMPointerTypeInContext(ctx, addrspace))
156-
end
153+
function PointerType(addrspace=0; ctx::Context)
154+
return PointerType(API.LLVMPointerTypeInContext(ctx, addrspace))
155+
end
157156

158-
Base.eltype(typ::PointerType) = throw(error("Taking the type of an opaque pointer is illegal"))
157+
if version() >= v"13"
158+
is_opaque(ptrtyp::PointerType) =
159+
convert(Core.Bool, API.LLVMPointerTypeIsOpaque(ptrtyp))
160+
161+
function Base.eltype(typ::PointerType)
162+
is_opaque(typ) && throw(error("Taking the type of an opaque pointer is illegal"))
163+
invoke(eltype, Tuple{SequentialType}, typ)
164+
end
165+
else
166+
is_opaque(ptrtyp::PointerType) = false
159167
end
160168

161169
addrspace(ptrtyp::PointerType) =

test/core.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ Context() do ctx end
2727

2828
@dispose ctx=Context() begin
2929
@test supports_typed_pointers(ctx) isa Bool
30-
if LLVM.version() > v"15"
30+
if LLVM.version() > v"17"
3131
@test supports_typed_pointers(ctx) == false
32-
else
32+
elseif LLVM.version() < v"13"
3333
@test supports_typed_pointers(ctx) == true
3434
end
3535
end
@@ -90,7 +90,7 @@ end
9090
eltyp = LLVM.Int32Type(ctx)
9191

9292
ptrtyp = LLVM.PointerType(eltyp)
93-
if supports_typed_ptrs
93+
if supports_typed_pointers(ctx)
9494
@test eltype(ptrtyp) == eltyp
9595
end
9696

@@ -545,7 +545,7 @@ end
545545
@testset "constant expressions" begin
546546

547547
# inline assembly
548-
if supports_typed_ptrs
548+
if supports_typed_pointers(ctx)
549549
let
550550
ft = LLVM.FunctionType(LLVM.VoidType(ctx))
551551
asm = InlineAsm(ft, "nop", "", false)
@@ -587,7 +587,7 @@ end
587587
ce = f(val, other_val)::LLVM.Constant
588588
@check_ir ce "i32 84"
589589
end
590-
if supports_typed_ptrs
590+
if supports_typed_pointers(ctx)
591591
for f in [const_udiv, const_sdiv]
592592
ce = f(val, other_val)::LLVM.Constant
593593
@check_ir ce "i32 21"
@@ -655,7 +655,7 @@ end
655655
@check_ir ce "float -4.200000e+01"
656656

657657
other_val = LLVM.ConstantFP(Float32(2.); ctx)
658-
if supports_typed_ptrs
658+
if supports_typed_pointers(ctx)
659659
ce = const_fadd(val, other_val)::LLVM.Constant
660660
@check_ir ce "float 4.400000e+01"
661661

@@ -698,15 +698,15 @@ end
698698
@check_ir ce "i32 0"
699699

700700
ce = const_inttoptr(ce, value_type(ptr))::LLVM.Constant
701-
if supports_typed_ptrs
701+
if supports_typed_pointers(ctx)
702702
@check_ir ce "i32* null"
703703
else
704704
@check_ir ce "ptr null"
705705
end
706706
@test isempty(uses(ptr))
707707
for f in [const_addrspacecast, const_pointercast]
708708
ce = f(ptr, LLVM.PointerType(LLVM.Int32Type(ctx), 1))::LLVM.Constant
709-
if supports_typed_ptrs
709+
if supports_typed_pointers(ctx)
710710
@check_ir ce "i32 addrspace(1)* addrspacecast (i32* null to i32 addrspace(1)*)"
711711
else
712712
@check_ir ce "ptr addrspace(1) addrspacecast (ptr null to ptr addrspace(1))"
@@ -1167,7 +1167,7 @@ end
11671167
fn = LLVM.Function(mod, intr)
11681168
@test fn isa LLVM.Function
11691169

1170-
if supports_typed_ptrs
1170+
if supports_typed_pointers(ctx)
11711171
@test eltype(value_type(fn)) == ft
11721172
end
11731173
@test isintrinsic(fn)
@@ -1194,7 +1194,7 @@ end
11941194

11951195
fn = LLVM.Function(mod, intr, [LLVM.DoubleType(ctx)])
11961196
@test fn isa LLVM.Function
1197-
if supports_typed_ptrs
1197+
if supports_typed_pointers(ctx)
11981198
@test eltype(value_type(fn)) == ft
11991199
end
12001200
@test isintrinsic(fn)

test/helpers.jl

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,3 @@ macro check_ir(inst, str)
44
@test occursin($(str), inst)
55
end
66
end
7-
8-
const supports_typed_ptrs = begin
9-
@dispose ctx=Context() begin
10-
supports_typed_pointers(ctx)
11-
end
12-
end

0 commit comments

Comments
 (0)