|
1 | 1 | export unsafe_delete!, |
2 | 2 | personality, personality!, |
3 | 3 | callconv, callconv!, |
4 | | - gc, gc!, intrinsic_id, |
| 4 | + gc, gc!, |
5 | 5 | entry |
6 | 6 |
|
7 | 7 | # forward declaration of Function in src/core/basicblock.jl |
|
19 | 19 | personality!(f::Function, persfn::Union{Nothing,Function}) = |
20 | 20 | API.LLVMSetPersonalityFn(ref(f), persfn===nothing ? C_NULL : ref(persfn)) |
21 | 21 |
|
22 | | -intrinsic_id(f::Function) = API.LLVMGetIntrinsicID(ref(f)) |
23 | | - |
24 | 22 | callconv(f::Function) = API.LLVMGetFunctionCallConv(ref(f)) |
25 | 23 | callconv!(f::Function, cc) = API.LLVMSetFunctionCallConv(ref(f), cc) |
26 | 24 |
|
@@ -142,3 +140,66 @@ function Base.collect(iter::FunctionBlockSet) |
142 | 140 | API.LLVMGetBasicBlocks(ref(iter.f), elems) |
143 | 141 | return BasicBlock[BasicBlock(elem) for elem in elems] |
144 | 142 | 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(f::Function) |
| 154 | + id = API.LLVMGetIntrinsicID(ref(f)) |
| 155 | + id == 0 && throw(ArgumentError("Function is not an intrinsic")) |
| 156 | + new(id) |
| 157 | + end |
| 158 | + |
| 159 | + function Intrinsic(name::String) |
| 160 | + @assert version() >= v"9" |
| 161 | + new(API.LLVMLookupIntrinsicID(name, length(name))) |
| 162 | + end |
| 163 | +end |
| 164 | + |
| 165 | +Base.convert(::Type{UInt32}, intr::Intrinsic) = intr.id |
| 166 | + |
| 167 | +function name(intr::Intrinsic) |
| 168 | + @assert version() >= v"8" |
| 169 | + len = Ref{Csize_t}() |
| 170 | + str = API.LLVMIntrinsicGetName(intr, len) |
| 171 | + unsafe_string(convert(Ptr{Cchar}, str), len[]) |
| 172 | +end |
| 173 | + |
| 174 | +function name(intr::Intrinsic, params::Vector{<:LLVMType}) |
| 175 | + @assert version() >= v"8" |
| 176 | + len = Ref{Csize_t}() |
| 177 | + str = API.LLVMIntrinsicCopyOverloadedName(intr, ref.(params), length(params), len) |
| 178 | + unsafe_message(convert(Ptr{Cchar}, str), len[]) |
| 179 | +end |
| 180 | + |
| 181 | +function isoverloaded(intr::Intrinsic) |
| 182 | + @assert version() >= v"8" |
| 183 | + convert(Core.Bool, API.LLVMIntrinsicIsOverloaded(intr)) |
| 184 | +end |
| 185 | + |
| 186 | +function Function(mod::Module, intr::Intrinsic, params::Vector{<:LLVMType}=LLVMType[]) |
| 187 | + @assert version() >= v"8" |
| 188 | + Value(API.LLVMGetIntrinsicDeclaration(ref(mod), intr, ref.(params), length(params))) |
| 189 | +end |
| 190 | + |
| 191 | +function FunctionType(intr::Intrinsic, params::Vector{<:LLVMType}=LLVMType[]; |
| 192 | + ctx::Context=GlobalContext()) |
| 193 | + @assert version() >= v"8" |
| 194 | + LLVMType(API.LLVMIntrinsicGetType(ref(ctx), intr, ref.(params), length(params))) |
| 195 | +end |
| 196 | + |
| 197 | +function Base.show(io::IO, intr::Intrinsic) |
| 198 | + print(io, "Intrinsic($(intr.id))") |
| 199 | + if version() >= v"8" |
| 200 | + print(io, ": \"$(name(intr))\"") |
| 201 | + if isoverloaded(intr) |
| 202 | + print(io, " (overloaded)") |
| 203 | + end |
| 204 | + end |
| 205 | +end |
0 commit comments