Skip to content

Commit

Permalink
Merge pull request #18754 from JuliaLang/jn/foreigncall
Browse files Browse the repository at this point in the history
eliminate Intrinsic Functions
  • Loading branch information
vtjnash authored Jan 20, 2017
2 parents e5e5c12 + b34f47b commit 5112619
Show file tree
Hide file tree
Showing 59 changed files with 2,700 additions and 2,316 deletions.
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ Library improvements
Compiler/Runtime improvements
-----------------------------

* `ccall` is now implemented as a macro, removing the need for special code-generator support for Intrinsics.

* `ccall` gained limited support for a `llvmcall` calling-convention. This can replace many uses of `llvmcall` with a simpler, shorter declaration.

* All Intrinsics are now Builtin functions instead and have proper error checking and fall-back static compilation support.

Deprecated or removed
---------------------

Expand Down
8 changes: 4 additions & 4 deletions base/Enums.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

module Enums

import Core.Intrinsics.box
import Core.Intrinsics.bitcast
export Enum, @enum

function basetype end

abstract Enum{T<:Integer}

Base.convert{T<:Integer}(::Type{Integer}, x::Enum{T}) = box(T, x)
Base.convert{T<:Integer,T2<:Integer}(::Type{T}, x::Enum{T2}) = convert(T, box(T2, x))
Base.convert{T<:Integer}(::Type{Integer}, x::Enum{T}) = bitcast(T, x)
Base.convert{T<:Integer,T2<:Integer}(::Type{T}, x::Enum{T2}) = convert(T, bitcast(T2, x))
Base.write{T<:Integer}(io::IO, x::Enum{T}) = write(io, T(x))
Base.read{T<:Enum}(io::IO, ::Type{T}) = T(read(io, Enums.basetype(T)))

Expand Down Expand Up @@ -106,7 +106,7 @@ macro enum(T,syms...)
Base.@__doc__(bitstype $(sizeof(basetype) * 8) $(esc(typename)) <: Enum{$(basetype)})
function Base.convert(::Type{$(esc(typename))}, x::Integer)
$(membershiptest(:x, values)) || enum_argument_error($(Expr(:quote, typename)), x)
box($(esc(typename)), convert($(basetype), x))
return bitcast($(esc(typename)), convert($(basetype), x))
end
Enums.basetype(::Type{$(esc(typename))}) = $(esc(basetype))
Base.typemin(x::Type{$(esc(typename))}) = $(esc(typename))($lo)
Expand Down
4 changes: 2 additions & 2 deletions base/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ end
finalize(o::ANY) = ccall(:jl_finalize_th, Void, (Ptr{Void}, Any,),
Core.getptls(), o)

gc(full::Bool=true) = ccall(:jl_gc_collect, Void, (Cint,), full)
gc_enable(on::Bool) = ccall(:jl_gc_enable, Cint, (Cint,), on)!=0
gc(full::Bool=true) = ccall(:jl_gc_collect, Void, (Int32,), full)
gc_enable(on::Bool) = ccall(:jl_gc_enable, Int32, (Int32,), on) != 0

immutable Nullable{T}
hasvalue::Bool
Expand Down
8 changes: 4 additions & 4 deletions base/bool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ julia> ![true false true]
function !(x::Bool)
## We need a better heuristic to detect this automatically
@_pure_meta
return box(Bool,not_int(unbox(Bool,x)))
return not_int(x)
end

(~)(x::Bool) = !x
(&)(x::Bool, y::Bool) = box(Bool,and_int(unbox(Bool,x),unbox(Bool,y)))
(|)(x::Bool, y::Bool) = box(Bool,or_int(unbox(Bool,x),unbox(Bool,y)))
(&)(x::Bool, y::Bool) = and_int(x, y)
(|)(x::Bool, y::Bool) = or_int(x, y)

"""
xor(x, y)
Expand All @@ -58,7 +58,7 @@ julia> [true; true; false] ⊻ [true; false; false]
false
```
"""
xor(x::Bool, y::Bool) = (x!=y)
xor(x::Bool, y::Bool) = (x != y)

>>(x::Bool, c::Unsigned) = Int(x) >> c
<<(x::Bool, c::Unsigned) = Int(x) << c
Expand Down
2 changes: 0 additions & 2 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@
# runnable::Bool
# end

import Core.Intrinsics.ccall

export
# key types
Any, DataType, Vararg, ANY, NTuple,
Expand Down
15 changes: 9 additions & 6 deletions base/c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# definitions related to C interface

import Core.Intrinsics: cglobal, box
import Core.Intrinsics: cglobal, bitcast

cfunction(f::Function, r, a) = ccall(:jl_function_ptr, Ptr{Void}, (Any, Any, Any), f, r, a)

Expand All @@ -27,18 +27,21 @@ else
typealias Culong UInt
typealias Cwchar_t Int32
end

"""
Clong
Equivalent to the native `signed long` c-type.
"""
Clong

"""
Culong
Equivalent to the native `unsigned long` c-type.
"""
Culong

"""
Cwchar_t
Expand All @@ -58,13 +61,13 @@ if !is_windows()
end

# construction from typed pointers
convert{T<:Union{Int8,UInt8}}(::Type{Cstring}, p::Ptr{T}) = box(Cstring, p)
convert(::Type{Cwstring}, p::Ptr{Cwchar_t}) = box(Cwstring, p)
convert{T<:Union{Int8,UInt8}}(::Type{Ptr{T}}, p::Cstring) = box(Ptr{T}, p)
convert(::Type{Ptr{Cwchar_t}}, p::Cwstring) = box(Ptr{Cwchar_t}, p)
convert{T<:Union{Int8,UInt8}}(::Type{Cstring}, p::Ptr{T}) = bitcast(Cstring, p)
convert(::Type{Cwstring}, p::Ptr{Cwchar_t}) = bitcast(Cwstring, p)
convert{T<:Union{Int8,UInt8}}(::Type{Ptr{T}}, p::Cstring) = bitcast(Ptr{T}, p)
convert(::Type{Ptr{Cwchar_t}}, p::Cwstring) = bitcast(Ptr{Cwchar_t}, p)

# construction from untyped pointers
convert{T<:Union{Cstring,Cwstring}}(::Type{T}, p::Ptr{Void}) = box(T, p)
convert{T<:Union{Cstring,Cwstring}}(::Type{T}, p::Ptr{Void}) = bitcast(T, p)

pointer(p::Cstring) = convert(Ptr{UInt8}, p)
pointer(p::Cwstring) = convert(Ptr{Cwchar_t}, p)
Expand Down
2 changes: 1 addition & 1 deletion base/checked.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export checked_neg, checked_abs, checked_add, checked_sub, checked_mul,
checked_div, checked_rem, checked_fld, checked_mod, checked_cld,
add_with_overflow, sub_with_overflow, mul_with_overflow

import Core.Intrinsics: box, unbox,
import Core.Intrinsics:
checked_sadd_int, checked_ssub_int, checked_smul_int, checked_sdiv_int,
checked_srem_int,
checked_uadd_int, checked_usub_int, checked_umul_int, checked_udiv_int,
Expand Down
26 changes: 26 additions & 0 deletions base/ctypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,78 +9,104 @@
Equivalent to the native `unsigned char` c-type (`UInt8`).
"""
typealias Cuchar UInt8


"""
Cshort
Equivalent to the native `signed short` c-type (`Int16`).
"""
typealias Cshort Int16


"""
Cushort
Equivalent to the native `unsigned short` c-type (`UInt16`).
"""
typealias Cushort UInt16


"""
Cint
Equivalent to the native `signed int` c-type (`Int32`).
"""
typealias Cint Int32


"""
Cuint
Equivalent to the native `unsigned int` c-type (`UInt32`).
"""
typealias Cuint UInt32


"""
Cptrdiff_t
Equivalent to the native `ptrdiff_t` c-type (`Int`).
"""
typealias Cptrdiff_t Int


"""
Csize_t
Equivalent to the native `size_t` c-type (`UInt`).
"""
typealias Csize_t UInt


"""
Cssize_t
Equivalent to the native `ssize_t` c-type.
"""
typealias Cssize_t Int


"""
Cintmax_t
Equivalent to the native `intmax_t` c-type (`Int64`).
"""
typealias Cintmax_t Int64


"""
Cuintmax_t
Equivalent to the native `uintmax_t` c-type (`UInt64`).
"""
typealias Cuintmax_t UInt64


"""
Clonglong
Equivalent to the native `signed long long` c-type (`Int64`).
"""
typealias Clonglong Int64


"""
Culonglong
Equivalent to the native `unsigned long long` c-type (`UInt64`).
"""
typealias Culonglong UInt64


"""
Cfloat
Equivalent to the native `float` c-type (`Float32`).
"""
typealias Cfloat Float32


"""
Cdouble
Expand Down
5 changes: 5 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1758,4 +1758,9 @@ end)
@deprecate(SharedArray{T}(filename::AbstractString, ::Type{T}, dims::NTuple, offset; kwargs...),
SharedArray{T,length(dims)}(filename, dims, offset; kwargs...))

@noinline function is_intrinsic_expr(x::ANY)
Base.depwarn("is_intrinsic_expr is deprecated. There are no intrinsic functions anymore.", :is_intrinsic_expr)
return false
end

# End deprecations scheduled for 0.6
6 changes: 3 additions & 3 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ unsafe_convert{T}(::Type{T}, x::T) = x # unsafe_convert (like convert) defaults
unsafe_convert{T<:Ptr}(::Type{T}, x::T) = x # to resolve ambiguity with the next method
unsafe_convert{P<:Ptr}(::Type{P}, x::Ptr) = convert(P, x)

reinterpret{T}(::Type{T}, x) = box(T, x)
reinterpret{T}(::Type{T}, x) = bitcast(T, x)
reinterpret(::Type{Unsigned}, x::Float16) = reinterpret(UInt16,x)
reinterpret(::Type{Signed}, x::Float16) = reinterpret(Int16,x)

Expand Down Expand Up @@ -148,11 +148,11 @@ setindex!(A::Array{Any}, x::ANY, i::Int) = Core.arrayset(A, x, i)
map(f::Function, a::Array{Any,1}) = Any[ f(a[i]) for i=1:length(a) ]

function precompile(f::ANY, args::Tuple)
ccall(:jl_compile_hint, Cint, (Any,), Tuple{Core.Typeof(f), args...}) != 0
ccall(:jl_compile_hint, Int32, (Any,), Tuple{Core.Typeof(f), args...}) != 0
end

function precompile(argt::Type)
ccall(:jl_compile_hint, Cint, (Any,), argt) != 0
ccall(:jl_compile_hint, Int32, (Any,), argt) != 0
end

"""
Expand Down
38 changes: 15 additions & 23 deletions base/fastmath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ module FastMath

export @fastmath

import Core.Intrinsics: box, unbox, powi_llvm, sqrt_llvm_fast
import Core.Intrinsics: powi_llvm, sqrt_llvm_fast, neg_float_fast,
add_float_fast, sub_float_fast, mul_float_fast, div_float_fast, rem_float_fast,
eq_float_fast, ne_float_fast, lt_float_fast, le_float_fast

const fast_op =
Dict(# basic arithmetic
Expand Down Expand Up @@ -131,18 +133,13 @@ end

FloatTypes = Union{Float32, Float64}

sub_fast{T<:FloatTypes}(x::T) = box(T,Base.neg_float_fast(unbox(T,x)))
sub_fast{T<:FloatTypes}(x::T) = neg_float_fast(x)

add_fast{T<:FloatTypes}(x::T, y::T) =
box(T,Base.add_float_fast(unbox(T,x), unbox(T,y)))
sub_fast{T<:FloatTypes}(x::T, y::T) =
box(T,Base.sub_float_fast(unbox(T,x), unbox(T,y)))
mul_fast{T<:FloatTypes}(x::T, y::T) =
box(T,Base.mul_float_fast(unbox(T,x), unbox(T,y)))
div_fast{T<:FloatTypes}(x::T, y::T) =
box(T,Base.div_float_fast(unbox(T,x), unbox(T,y)))
rem_fast{T<:FloatTypes}(x::T, y::T) =
box(T,Base.rem_float_fast(unbox(T,x), unbox(T,y)))
add_fast{T<:FloatTypes}(x::T, y::T) = add_float_fast(x, y)
sub_fast{T<:FloatTypes}(x::T, y::T) = sub_float_fast(x, y)
mul_fast{T<:FloatTypes}(x::T, y::T) = mul_float_fast(x, y)
div_fast{T<:FloatTypes}(x::T, y::T) = div_float_fast(x, y)
rem_fast{T<:FloatTypes}(x::T, y::T) = rem_float_fast(x, y)

add_fast{T<:FloatTypes}(x::T, y::T, zs::T...) =
add_fast(add_fast(x, y), zs...)
Expand All @@ -157,14 +154,10 @@ mul_fast{T<:FloatTypes}(x::T, y::T, zs::T...) =
end
end

eq_fast{T<:FloatTypes}(x::T, y::T) =
Base.eq_float_fast(unbox(T,x),unbox(T,y))
ne_fast{T<:FloatTypes}(x::T, y::T) =
Base.ne_float_fast(unbox(T,x),unbox(T,y))
lt_fast{T<:FloatTypes}(x::T, y::T) =
Base.lt_float_fast(unbox(T,x),unbox(T,y))
le_fast{T<:FloatTypes}(x::T, y::T) =
Base.le_float_fast(unbox(T,x),unbox(T,y))
eq_fast{T<:FloatTypes}(x::T, y::T) = eq_float_fast(x, y)
ne_fast{T<:FloatTypes}(x::T, y::T) = ne_float_fast(x, y)
lt_fast{T<:FloatTypes}(x::T, y::T) = lt_float_fast(x, y)
le_fast{T<:FloatTypes}(x::T, y::T) = le_float_fast(x, y)

isinf_fast(x) = false
isfinite_fast(x) = true
Expand Down Expand Up @@ -251,12 +244,11 @@ end
# builtins

pow_fast{T<:FloatTypes}(x::T, y::Integer) = pow_fast(x, Int32(y))
pow_fast{T<:FloatTypes}(x::T, y::Int32) =
box(T, Base.powi_llvm(unbox(T,x), unbox(Int32,y)))
pow_fast{T<:FloatTypes}(x::T, y::Int32) = Base.powi_llvm(x, y)

# TODO: Change sqrt_llvm intrinsic to avoid nan checking; add nan
# checking to sqrt in math.jl; remove sqrt_llvm_fast intrinsic
sqrt_fast{T<:FloatTypes}(x::T) = box(T, Base.sqrt_llvm_fast(unbox(T,x)))
sqrt_fast{T<:FloatTypes}(x::T) = sqrt_llvm_fast(x)

# libm

Expand Down
Loading

0 comments on commit 5112619

Please sign in to comment.