Skip to content

Commit 013a23a

Browse files
committed
Wrap intrinsics API.
1 parent ef24b88 commit 013a23a

File tree

5 files changed

+77
-6
lines changed

5 files changed

+77
-6
lines changed

src/core/function.jl

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export unsafe_delete!,
22
personality, personality!,
33
callconv, callconv!,
4-
gc, gc!, intrinsic_id,
4+
gc, gc!,
55
entry
66

77
# forward declaration of Function in src/core/basicblock.jl
@@ -19,8 +19,6 @@ end
1919
personality!(f::Function, persfn::Union{Nothing,Function}) =
2020
API.LLVMSetPersonalityFn(ref(f), persfn===nothing ? C_NULL : ref(persfn))
2121

22-
intrinsic_id(f::Function) = API.LLVMGetIntrinsicID(ref(f))
23-
2422
callconv(f::Function) = API.LLVMGetFunctionCallConv(ref(f))
2523
callconv!(f::Function, cc) = API.LLVMSetFunctionCallConv(ref(f), cc)
2624

@@ -142,3 +140,55 @@ function Base.collect(iter::FunctionBlockSet)
142140
API.LLVMGetBasicBlocks(ref(iter.f), elems)
143141
return BasicBlock[BasicBlock(elem) for elem in elems]
144142
end
143+
144+
# intrinsics
145+
146+
export isintrinsic, Intrinsic, isoverloaded, declaration
147+
148+
isintrinsic(f::Function) = API.LLVMGetIntrinsicID(ref(f)) != 0
149+
150+
struct Intrinsic
151+
id::UInt32
152+
153+
function Intrinsic(name::String)
154+
new(API.LLVMLookupIntrinsicID(name, length(name)))
155+
end
156+
157+
function Intrinsic(f::Function)
158+
id = API.LLVMGetIntrinsicID(ref(f))
159+
id == 0 && throw(ArgumentError("Function is not an intrinsic"))
160+
new(id)
161+
end
162+
end
163+
164+
Base.convert(::Type{UInt32}, intr::Intrinsic) = intr.id
165+
166+
function name(intr::Intrinsic)
167+
len = Ref{Csize_t}()
168+
str = API.LLVMIntrinsicGetName(intr, len)
169+
unsafe_string(convert(Ptr{Cchar}, str), len[])
170+
end
171+
172+
function name(intr::Intrinsic, params::Vector{<:LLVMType})
173+
len = Ref{Csize_t}()
174+
str = API.LLVMIntrinsicCopyOverloadedName(intr, ref.(params), length(params), len)
175+
unsafe_message(convert(Ptr{Cchar}, str), len[])
176+
end
177+
178+
function FunctionType(intr::Intrinsic, params::Vector{<:LLVMType}=LLVMType[];
179+
ctx::Context=GlobalContext())
180+
LLVMType(API.LLVMIntrinsicGetType(ref(ctx), intr, ref.(params), length(params)))
181+
end
182+
183+
function Function(mod::Module, intr::Intrinsic, params::Vector{<:LLVMType}=LLVMType[])
184+
Value(API.LLVMGetIntrinsicDeclaration(ref(mod), intr, ref.(params), length(params)))
185+
end
186+
187+
function Base.show(io::IO, intr::Intrinsic)
188+
print(io, "Intrinsic($(intr.id)): \"$(name(intr))\"")
189+
if isoverloaded(intr)
190+
print(io, " (overloaded)")
191+
end
192+
end
193+
194+
isoverloaded(intr::Intrinsic) = convert(Core.Bool, API.LLVMIntrinsicIsOverloaded(intr))

src/deprecated.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ import Base: haskey, getindex, get
1111
@deprecate haskey(::TargetIterator, name::String) Target(;name=name) !== nothing
1212
@deprecate getindex(iter::TargetIterator, name::String) Target(;name=name)
1313
@deprecate get(::TargetIterator, name::String, default) try Target(;name=name) catch; default end
14+
15+
@deprecate intrinsic_id(f::Function) isintrinsic(f) ? Intrinsic(f) : 0

src/intrinsics.jl

Whitespace-only changes.

src/util.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# utilities
22

3-
function unsafe_message(ptr)
4-
str = unsafe_string(ptr)
3+
function unsafe_message(ptr, args...)
4+
str = unsafe_string(ptr, args...)
55
API.LLVMDisposeMessage(ptr)
66
str
77
end

test/core.jl

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ LLVM.Module("SomeModule", ctx) do mod
680680
@test personality(fn) === nothing
681681
unsafe_delete!(mod, pers_fn)
682682

683-
@test intrinsic_id(fn) == 0
683+
@test !isintrinsic(fn)
684684

685685
@test callconv(fn) == LLVM.API.LLVMCCallConv
686686
callconv!(fn, LLVM.API.LLVMFastCallConv)
@@ -698,6 +698,25 @@ LLVM.Module("SomeModule", ctx) do mod
698698
end
699699
end
700700

701+
Context() do ctx
702+
LLVM.Module("SomeModule", ctx) do mod
703+
intr = Intrinsic("llvm.sin")
704+
@test isoverloaded(intr)
705+
706+
@test name(intr) == "llvm.sin"
707+
@test name(intr, [LLVM.DoubleType(ctx)]) == "llvm.sin.f64"
708+
709+
ft = FunctionType(intr, [LLVM.DoubleType(ctx)])
710+
@test return_type(ft) == LLVM.DoubleType(ctx)
711+
@test isempty(functions(mod))
712+
713+
fn = LLVM.Function(mod, intr, [LLVM.DoubleType(ctx)])
714+
@test first(functions(mod)) == fn
715+
@test eltype(llvmtype(fn)) == ft
716+
@test isintrinsic(fn)
717+
end
718+
end
719+
701720
# attributes
702721
Context() do ctx
703722
LLVM.Module("SomeModule", ctx) do mod

0 commit comments

Comments
 (0)