Skip to content

Commit

Permalink
Update Base to use JLL-vendored binaries
Browse files Browse the repository at this point in the history
  • Loading branch information
staticfloat committed Jun 30, 2020
1 parent cb4ae78 commit d347b47
Show file tree
Hide file tree
Showing 11 changed files with 273 additions and 203 deletions.
76 changes: 55 additions & 21 deletions base/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,29 @@ include("strings/substring.jl")
include(string((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "build_h.jl")) # include($BUILDROOT/base/build_h.jl)
include(string((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "version_git.jl")) # include($BUILDROOT/base/version_git.jl)

# Initialize DL_LOAD_PATH as early as possible. We are defining things here in
# a slightly more verbose fashion than usual, because we're running so early.
const DL_LOAD_PATH = String[]
let os = ccall(:jl_get_UNAME, Any, ()),
pathsep = (os == :Windows || os == :NT) ? "\\" : "/"

if (os == :Darwin || os == :Apple)
if Base.DARWIN_FRAMEWORK
push!(DL_LOAD_PATH, "@loader_path/Frameworks")
else
push!(DL_LOAD_PATH, "@loader_path/julia")
end
push!(DL_LOAD_PATH, "@loader_path")
end

# Include some paths for JLL libraries that we need (like pcre) that are so early
# in our boot-up process that we can't use even rewritten JLL packages. We use
# the `@executable_path` format here, having taught `dlload.c` to
if !isempty(Base.PCRE_JLL_LIBDIR)
push!(DL_LOAD_PATH, string("@executable_path", pathsep, Base.PCRE_JLL_LIBDIR))
end
end

include("osutils.jl")
include("c.jl")

Expand Down Expand Up @@ -203,15 +226,13 @@ include("version.jl")
include("sysinfo.jl")
include("libc.jl")
using .Libc: getpid, gethostname, time

const DL_LOAD_PATH = String[]
if Sys.isapple()
if Base.DARWIN_FRAMEWORK
push!(DL_LOAD_PATH, "@loader_path/Frameworks")
else
push!(DL_LOAD_PATH, "@loader_path/julia")
macro include_stdlib_jll(name)
quote
Core.include($(esc(__module__)), relpath(
joinpath(Sys.STDLIB, $(esc(name)), "src", string($(esc(name)), ".jl")),
pwd(),
))
end
push!(DL_LOAD_PATH, "@loader_path")
end

include("env.jl")
Expand Down Expand Up @@ -245,7 +266,24 @@ include("ttyhascolor.jl")
include("grisu/grisu.jl")
include("secretbuffer.jl")

# core math functions
# basic data structures
include("ordering.jl")
using .Order

# Combinatorics
include("sort.jl")
using .Sort

# reduction along dims
include("reducedim.jl") # macros in this file relies on string.jl
include("accumulate.jl")



# core math functions. They occasionally need to ccall() out to Libm
@include_stdlib_jll("Libm_jll")
using .Libm_jll
Libm_jll.__init__()
include("floatfuncs.jl")
include("math.jl")
using .Math
Expand All @@ -268,18 +306,6 @@ let SOURCE_PATH = ""
end
end

# reduction along dims
include("reducedim.jl") # macros in this file relies on string.jl
include("accumulate.jl")

# basic data structures
include("ordering.jl")
using .Order

# Combinatorics
include("sort.jl")
using .Sort

# Fast math
include("fastmath.jl")
using .FastMath
Expand All @@ -293,6 +319,7 @@ using .Enums
# BigInts
include("gmp.jl")
using .GMP
import .GMP: libgmp # We need this for hashing

# float printing: requires BigInt
include("ryu/Ryu.jl")
Expand Down Expand Up @@ -354,6 +381,13 @@ include("docs/basedocs.jl")

include("client.jl")

# Ensure we are including two important JLLs; CompilerSupportLibraries and libLLVM
@include_stdlib_jll("CompilerSupportLibraries_jll")
using .CompilerSupportLibraries_jll
CompilerSupportLibraries_jll.__init__()
@include_stdlib_jll("libLLVM_jll")
using .libLLVM_jll

# Documentation -- should always be included last in sysimg.
include("docs/Docs.jl")
using .Docs
Expand Down
2 changes: 2 additions & 0 deletions base/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ifeq ($(OS),WINNT)
@printf 'const LIBEXECDIR = "%s"\n' '$(subst /,\\,$(libexecdir_rel))' >> $@
@printf 'const PRIVATE_LIBDIR = "%s"\n' '$(subst /,\\,$(private_libdir_rel))' >> $@
@printf 'const INCLUDEDIR = "%s"\n' '$(subst /,\\,$(includedir_rel))' >> $@
@printf 'const PCRE_JLL_LIBDIR = "%s"\n' '$(subst /,\\,$(PCRE_LIBDIR_rel))' >> $@
else
@echo "const SYSCONFDIR = \"$(sysconfdir_rel)\"" >> $@
@echo "const DATAROOTDIR = \"$(datarootdir_rel)\"" >> $@
Expand All @@ -67,6 +68,7 @@ else
@echo "const LIBEXECDIR = \"$(libexecdir_rel)\"" >> $@
@echo "const PRIVATE_LIBDIR = \"$(private_libdir_rel)\"" >> $@
@echo "const INCLUDEDIR = \"$(includedir_rel)\"" >> $@
@echo "const PCRE_JLL_LIBDIR = \"$(PCRE_LIBDIR_rel)\"" >> $@
endif
ifeq ($(DARWIN_FRAMEWORK), 1)
@echo "const DARWIN_FRAMEWORK = true" >> $@
Expand Down
5 changes: 2 additions & 3 deletions base/fastmath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import Core.Intrinsics: 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

using Base.Libm_jll

const fast_op =
Dict(# basic arithmetic
:+ => :add_fast,
Expand Down Expand Up @@ -280,9 +282,6 @@ pow_fast(x::FloatTypes, ::Val{p}) where {p} = pow_fast(x, p) # inlines already v
sqrt_fast(x::FloatTypes) = sqrt_llvm_fast(x)

# libm

const libm = Base.libm_name

for f in (:acosh, :asinh, :atanh, :cbrt,
:cosh, :exp2, :expm1, :log10, :log1p, :log2,
:log, :sinh, :tanh)
Expand Down
4 changes: 2 additions & 2 deletions base/floatfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,9 @@ algorithms. See [`muladd`](@ref).
function fma end

fma_libm(x::Float32, y::Float32, z::Float32) =
ccall(("fmaf", libm_name), Float32, (Float32,Float32,Float32), x, y, z)
ccall(("fmaf", libm), Float32, (Float32,Float32,Float32), x, y, z)
fma_libm(x::Float64, y::Float64, z::Float64) =
ccall(("fma", libm_name), Float64, (Float64,Float64,Float64), x, y, z)
ccall(("fma", libm), Float64, (Float64,Float64,Float64), x, y, z)
fma_llvm(x::Float32, y::Float32, z::Float32) = fma_float(x, y, z)
fma_llvm(x::Float64, y::Float64, z::Float64) = fma_float(x, y, z)
# Disable LLVM's fma if it is incorrect, e.g. because LLVM falls back
Expand Down
68 changes: 36 additions & 32 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import .Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, (~), (&), (|), xor,
widen, signed, unsafe_trunc, trunc, iszero, isone, big, flipsign, signbit,
sign, hastypemax

Base.@include_stdlib_jll("GMP_jll")
using .GMP_jll
GMP_jll.__init__()

if Clong == Int32
const ClongMax = Union{Int8, Int16, Int32}
const CulongMax = Union{UInt8, UInt16, UInt32}
Expand All @@ -21,8 +25,8 @@ else
end
const CdoubleMax = Union{Float16, Float32, Float64}

version() = VersionNumber(unsafe_string(unsafe_load(cglobal((:__gmp_version, :libgmp), Ptr{Cchar}))))
bits_per_limb() = Int(unsafe_load(cglobal((:__gmp_bits_per_limb, :libgmp), Cint)))
version() = VersionNumber(unsafe_string(unsafe_load(cglobal((:__gmp_version, libgmp), Ptr{Cchar}))))
bits_per_limb() = Int(unsafe_load(cglobal((:__gmp_bits_per_limb, libgmp), Cint)))

const VERSION = version()
const BITS_PER_LIMB = bits_per_limb()
Expand Down Expand Up @@ -54,7 +58,7 @@ mutable struct BigInt <: Signed

function BigInt(; nbits::Integer=0)
b = MPZ.init2!(new(), nbits)
finalizer(cglobal((:__gmpz_clear, :libgmp)), b)
finalizer(cglobal((:__gmpz_clear, libgmp)), b)
return b
end
end
Expand Down Expand Up @@ -100,7 +104,7 @@ function __init__()
"Please rebuild Julia.")
end

ccall((:__gmp_set_memory_functions, :libgmp), Cvoid,
ccall((:__gmp_set_memory_functions, libgmp), Cvoid,
(Ptr{Cvoid},Ptr{Cvoid},Ptr{Cvoid}),
cglobal(:jl_gc_counted_malloc),
cglobal(:jl_gc_counted_realloc_with_old_size),
Expand All @@ -112,7 +116,7 @@ function __init__()
end
# This only works with a patched version of GMP, ignore otherwise
try
ccall((:__gmp_set_alloc_overflow_function, :libgmp), Cvoid,
ccall((:__gmp_set_alloc_overflow_function, libgmp), Cvoid,
(Ptr{Cvoid},),
cglobal(:jl_throw_out_of_memory_error))
ALLOC_OVERFLOW_FUNCTION[] = true
Expand All @@ -132,20 +136,20 @@ module MPZ
# - a method modifying its input has a "!" appendend to its name, according to Julia's conventions
# - some convenient methods are added (in addition to the pure MPZ ones), e.g. `add(a, b) = add!(BigInt(), a, b)`
# and `add!(x, a) = add!(x, x, a)`.
using .Base.GMP: BigInt, Limb, BITS_PER_LIMB
using .Base.GMP: BigInt, Limb, BITS_PER_LIMB, libgmp

const mpz_t = Ref{BigInt}
const bitcnt_t = Culong

gmpz(op::Symbol) = (Symbol(:__gmpz_, op), :libgmp)
gmpz(op::Symbol) = (Symbol(:__gmpz_, op), libgmp)

init!(x::BigInt) = (ccall((:__gmpz_init, :libgmp), Cvoid, (mpz_t,), x); x)
init2!(x::BigInt, a) = (ccall((:__gmpz_init2, :libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x)
init!(x::BigInt) = (ccall((:__gmpz_init, libgmp), Cvoid, (mpz_t,), x); x)
init2!(x::BigInt, a) = (ccall((:__gmpz_init2, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x)

realloc2!(x, a) = (ccall((:__gmpz_realloc2, :libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x)
realloc2!(x, a) = (ccall((:__gmpz_realloc2, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x)
realloc2(a) = realloc2!(BigInt(), a)

sizeinbase(a::BigInt, b) = Int(ccall((:__gmpz_sizeinbase, :libgmp), Csize_t, (mpz_t, Cint), a, b))
sizeinbase(a::BigInt, b) = Int(ccall((:__gmpz_sizeinbase, libgmp), Csize_t, (mpz_t, Cint), a, b))

for (op, nbits) in (:add => :(BITS_PER_LIMB*(1 + max(abs(a.size), abs(b.size)))),
:sub => :(BITS_PER_LIMB*(1 + max(abs(a.size), abs(b.size)))),
Expand All @@ -161,7 +165,7 @@ for (op, nbits) in (:add => :(BITS_PER_LIMB*(1 + max(abs(a.size), abs(b.size))))
end

invert!(x::BigInt, a::BigInt, b::BigInt) =
ccall((:__gmpz_invert, :libgmp), Cint, (mpz_t, mpz_t, mpz_t), x, a, b)
ccall((:__gmpz_invert, libgmp), Cint, (mpz_t, mpz_t, mpz_t), x, a, b)
invert(a::BigInt, b::BigInt) = invert!(BigInt(), a, b)
invert!(x::BigInt, b::BigInt) = invert!(x, x, b)

Expand All @@ -174,14 +178,14 @@ for op in (:add_ui, :sub_ui, :mul_ui, :mul_2exp, :fdiv_q_2exp, :pow_ui, :bin_ui)
end
end

ui_sub!(x::BigInt, a, b::BigInt) = (ccall((:__gmpz_ui_sub, :libgmp), Cvoid, (mpz_t, Culong, mpz_t), x, a, b); x)
ui_sub!(x::BigInt, a, b::BigInt) = (ccall((:__gmpz_ui_sub, libgmp), Cvoid, (mpz_t, Culong, mpz_t), x, a, b); x)
ui_sub(a, b::BigInt) = ui_sub!(BigInt(), a, b)

for op in (:scan1, :scan0)
@eval $op(a::BigInt, b) = Int(ccall($(gmpz(op)), Culong, (mpz_t, Culong), a, b))
end

mul_si!(x::BigInt, a::BigInt, b) = (ccall((:__gmpz_mul_si, :libgmp), Cvoid, (mpz_t, mpz_t, Clong), x, a, b); x)
mul_si!(x::BigInt, a::BigInt, b) = (ccall((:__gmpz_mul_si, libgmp), Cvoid, (mpz_t, mpz_t, Clong), x, a, b); x)
mul_si(a::BigInt, b) = mul_si!(BigInt(), a, b)
mul_si!(x::BigInt, b) = mul_si!(x, x, b)

Expand All @@ -203,47 +207,47 @@ for (op, T) in ((:fac_ui, Culong), (:set_ui, Culong), (:set_si, Clong), (:set_d,
end
end

popcount(a::BigInt) = Int(ccall((:__gmpz_popcount, :libgmp), Culong, (mpz_t,), a))
popcount(a::BigInt) = Int(ccall((:__gmpz_popcount, libgmp), Culong, (mpz_t,), a))

mpn_popcount(d::Ptr{Limb}, s::Integer) = Int(ccall((:__gmpn_popcount, :libgmp), Culong, (Ptr{Limb}, Csize_t), d, s))
mpn_popcount(d::Ptr{Limb}, s::Integer) = Int(ccall((:__gmpn_popcount, libgmp), Culong, (Ptr{Limb}, Csize_t), d, s))
mpn_popcount(a::BigInt) = mpn_popcount(a.d, abs(a.size))

function tdiv_qr!(x::BigInt, y::BigInt, a::BigInt, b::BigInt)
ccall((:__gmpz_tdiv_qr, :libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, y, a, b)
ccall((:__gmpz_tdiv_qr, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, y, a, b)
x, y
end
tdiv_qr(a::BigInt, b::BigInt) = tdiv_qr!(BigInt(), BigInt(), a, b)

powm!(x::BigInt, a::BigInt, b::BigInt, c::BigInt) =
(ccall((:__gmpz_powm, :libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, a, b, c); x)
(ccall((:__gmpz_powm, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t), x, a, b, c); x)
powm(a::BigInt, b::BigInt, c::BigInt) = powm!(BigInt(), a, b, c)
powm!(x::BigInt, b::BigInt, c::BigInt) = powm!(x, x, b, c)

function gcdext!(x::BigInt, y::BigInt, z::BigInt, a::BigInt, b::BigInt)
ccall((:__gmpz_gcdext, :libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t, mpz_t), x, y, z, a, b)
ccall((:__gmpz_gcdext, libgmp), Cvoid, (mpz_t, mpz_t, mpz_t, mpz_t, mpz_t), x, y, z, a, b)
x, y, z
end
gcdext(a::BigInt, b::BigInt) = gcdext!(BigInt(), BigInt(), BigInt(), a, b)

cmp(a::BigInt, b::BigInt) = Int(ccall((:__gmpz_cmp, :libgmp), Cint, (mpz_t, mpz_t), a, b))
cmp_si(a::BigInt, b) = Int(ccall((:__gmpz_cmp_si, :libgmp), Cint, (mpz_t, Clong), a, b))
cmp_ui(a::BigInt, b) = Int(ccall((:__gmpz_cmp_ui, :libgmp), Cint, (mpz_t, Culong), a, b))
cmp_d(a::BigInt, b) = Int(ccall((:__gmpz_cmp_d, :libgmp), Cint, (mpz_t, Cdouble), a, b))
cmp(a::BigInt, b::BigInt) = Int(ccall((:__gmpz_cmp, libgmp), Cint, (mpz_t, mpz_t), a, b))
cmp_si(a::BigInt, b) = Int(ccall((:__gmpz_cmp_si, libgmp), Cint, (mpz_t, Clong), a, b))
cmp_ui(a::BigInt, b) = Int(ccall((:__gmpz_cmp_ui, libgmp), Cint, (mpz_t, Culong), a, b))
cmp_d(a::BigInt, b) = Int(ccall((:__gmpz_cmp_d, libgmp), Cint, (mpz_t, Cdouble), a, b))

mpn_cmp(a::Ptr{Limb}, b::Ptr{Limb}, c) = ccall((:__gmpn_cmp, :libgmp), Cint, (Ptr{Limb}, Ptr{Limb}, Clong), a, b, c)
mpn_cmp(a::Ptr{Limb}, b::Ptr{Limb}, c) = ccall((:__gmpn_cmp, libgmp), Cint, (Ptr{Limb}, Ptr{Limb}, Clong), a, b, c)
mpn_cmp(a::BigInt, b::BigInt, c) = mpn_cmp(a.d, b.d, c)

get_str!(x, a, b::BigInt) = (ccall((:__gmpz_get_str,:libgmp), Ptr{Cchar}, (Ptr{Cchar}, Cint, mpz_t), x, a, b); x)
set_str!(x::BigInt, a, b) = Int(ccall((:__gmpz_set_str, :libgmp), Cint, (mpz_t, Ptr{UInt8}, Cint), x, a, b))
get_d(a::BigInt) = ccall((:__gmpz_get_d, :libgmp), Cdouble, (mpz_t,), a)
get_str!(x, a, b::BigInt) = (ccall((:__gmpz_get_str,libgmp), Ptr{Cchar}, (Ptr{Cchar}, Cint, mpz_t), x, a, b); x)
set_str!(x::BigInt, a, b) = Int(ccall((:__gmpz_set_str, libgmp), Cint, (mpz_t, Ptr{UInt8}, Cint), x, a, b))
get_d(a::BigInt) = ccall((:__gmpz_get_d, libgmp), Cdouble, (mpz_t,), a)

limbs_write!(x::BigInt, a) = ccall((:__gmpz_limbs_write, :libgmp), Ptr{Limb}, (mpz_t, Clong), x, a)
limbs_finish!(x::BigInt, a) = ccall((:__gmpz_limbs_finish, :libgmp), Cvoid, (mpz_t, Clong), x, a)
import!(x::BigInt, a, b, c, d, e, f) = ccall((:__gmpz_import, :libgmp), Cvoid,
limbs_write!(x::BigInt, a) = ccall((:__gmpz_limbs_write, libgmp), Ptr{Limb}, (mpz_t, Clong), x, a)
limbs_finish!(x::BigInt, a) = ccall((:__gmpz_limbs_finish, libgmp), Cvoid, (mpz_t, Clong), x, a)
import!(x::BigInt, a, b, c, d, e, f) = ccall((:__gmpz_import, libgmp), Cvoid,
(mpz_t, Csize_t, Cint, Csize_t, Cint, Csize_t, Ptr{Cvoid}), x, a, b, c, d, e, f)

setbit!(x, a) = (ccall((:__gmpz_setbit, :libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x)
tstbit(a::BigInt, b) = ccall((:__gmpz_tstbit, :libgmp), Cint, (mpz_t, bitcnt_t), a, b) % Bool
setbit!(x, a) = (ccall((:__gmpz_setbit, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x)
tstbit(a::BigInt, b) = ccall((:__gmpz_tstbit, libgmp), Cint, (mpz_t, bitcnt_t), a, b) % Bool

end # module MPZ

Expand Down
2 changes: 1 addition & 1 deletion base/hashing2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ function decompose(x::BigFloat)::Tuple{BigInt, Int, Int}
s = BigInt()
s.size = cld(x.prec, 8*sizeof(GMP.Limb)) # limbs
b = s.size * sizeof(GMP.Limb) # bytes
ccall((:__gmpz_realloc2, :libgmp), Cvoid, (Ref{BigInt}, Culong), s, 8b) # bits
ccall((:__gmpz_realloc2, libgmp), Cvoid, (Ref{BigInt}, Culong), s, 8b) # bits
ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t), s.d, x.d, b) # bytes
s, x.exp - 8b, x.sign
end
Expand Down
4 changes: 2 additions & 2 deletions base/irrationals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ macro irrational(sym, val, def)
qsym = esc(Expr(:quote, sym))
bigconvert = isa(def,Symbol) ? quote
function Base.BigFloat(::Irrational{$qsym}, r::MPFR.MPFRRoundingMode=MPFR.ROUNDING_MODE[]; precision=precision(BigFloat))
c = BigFloat(;precision=precision)
ccall(($(string("mpfr_const_", def)), :libmpfr),
c = BigFloat(;precision=precision)
ccall(($(string("mpfr_const_", def)), MPFR.libmpfr),
Cint, (Ref{BigFloat}, MPFR.MPFRRoundingMode), c, r)
return c
end
Expand Down
5 changes: 2 additions & 3 deletions base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ using .Base: sign_mask, exponent_mask, exponent_one,

using Core.Intrinsics: sqrt_llvm

using .Base: IEEEFloat
using .Base: IEEEFloat, Libm_jll
const libm = Libm_jll.libm

@noinline function throw_complex_domainerror(f::Symbol, x)
throw(DomainError(x, string("$f will only return a complex result if called with a ",
Expand Down Expand Up @@ -309,8 +310,6 @@ log(b::Number, x::Number) = log(promote(b,x)...)

# type specific math functions

const libm = Base.libm_name

# functions with no domain error
"""
sinh(x)
Expand Down
Loading

0 comments on commit d347b47

Please sign in to comment.