Skip to content

Commit

Permalink
Merge pull request #18546 from JuliaLang/tk/backports-0.5.0
Browse files Browse the repository at this point in the history
[release-0.5] final backports for 0.5.0
  • Loading branch information
tkelman authored Sep 19, 2016
2 parents 9c76c3e + feb57e6 commit db7eaf9
Show file tree
Hide file tree
Showing 32 changed files with 415 additions and 143 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ matrix:
- gfortran-5
- os: osx
env: ARCH="x86_64"
osx_image: xcode7
cache:
directories:
- $TRAVIS_BUILD_DIR/deps/srccache
Expand Down Expand Up @@ -78,7 +79,7 @@ before_install:
contrib/travis_fastfail.sh || exit 1;
brew tap staticfloat/julia;
brew rm --force $(brew deps --HEAD julia);
brew install -v staticfloat/juliadeps/libgfortran;
brew install -v cmake staticfloat/juliadeps/libgfortran;
brew install -v --only-dependencies --HEAD julia;
BUILDOPTS="-j3 USECLANG=1 LLVM_CONFIG=$(brew --prefix llvm37-julia)/bin/llvm-config-3.7 LLVM_SIZE=$(brew --prefix llvm37-julia)/bin/llvm-size-3.7";
BUILDOPTS="$BUILDOPTS VERBOSE=1 USE_BLAS64=0 SUITESPARSE_INC=-I$(brew --prefix suite-sparse-julia)/include FORCE_ASSERTIONS=1";
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ CORE_SRCS := $(addprefix $(JULIAHOME)/, \
base/reduce.jl \
base/reflection.jl \
base/tuple.jl)
BASE_SRCS := $(shell find $(JULIAHOME)/base -name \*.jl)
BASE_SRCS := $(sort $(shell find $(JULIAHOME)/base -name \*.jl) $(shell find $(BUILDROOT)/base -name \*.jl))

$(build_private_libdir)/inference.ji: $(CORE_SRCS) | $(build_private_libdir)
@$(call PRINT_JULIA, cd $(JULIAHOME)/base && \
Expand Down Expand Up @@ -375,7 +375,8 @@ ifeq ($(OS),WINNT)
endif
$(INSTALL_F) $(build_includedir)/uv* $(DESTDIR)$(includedir)/julia
endif
$(INSTALL_F) $(addprefix $(JULIAHOME)/,src/julia.h src/julia_threads.h src/julia_version.h src/support/*.h) $(DESTDIR)$(includedir)/julia
$(INSTALL_F) $(addprefix $(JULIAHOME)/,src/julia.h src/julia_threads.h src/support/*.h) $(DESTDIR)$(includedir)/julia
$(INSTALL_F) $(BUILDROOT)/src/julia_version.h $(DESTDIR)$(includedir)/julia
# Copy system image
-$(INSTALL_F) $(build_private_libdir)/sys.ji $(DESTDIR)$(private_libdir)
$(INSTALL_M) $(build_private_libdir)/sys.$(SHLIB_EXT) $(DESTDIR)$(private_libdir)
Expand Down
11 changes: 8 additions & 3 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1366,7 +1366,7 @@ function typed_hvcat{T}(::Type{T}, rows::Tuple{Vararg{Int}}, as...)
rs = Array{Any,1}(nbr)
a = 1
for i = 1:nbr
rs[i] = hcat(as[a:a-1+rows[i]]...)
rs[i] = typed_hcat(T, as[a:a-1+rows[i]]...)
a += rows[i]
end
T[rs...;]
Expand Down Expand Up @@ -1478,7 +1478,12 @@ _div(ind, d::Integer) = div(ind, d), 1, d
_div(ind, r::AbstractUnitRange) = (d = unsafe_length(r); (div(ind, d), first(r), d))

# Vectorized forms
function sub2ind{N,T<:Integer}(inds::Union{Dims{N},Indices{N}}, I::AbstractVector{T}...)
function sub2ind{T<:Integer}(inds::Indices{1}, I1::AbstractVector{T}, I::AbstractVector{T}...)
throw(ArgumentError("Linear indexing is not defined for one-dimensional arrays"))
end
sub2ind{T<:Integer}(inds::Tuple{OneTo}, I1::AbstractVector{T}, I::AbstractVector{T}...) = _sub2ind_vecs(inds, I1, I...)
sub2ind{T<:Integer}(inds::Union{DimsInteger,Indices}, I1::AbstractVector{T}, I::AbstractVector{T}...) = _sub2ind_vecs(inds, I1, I...)
function _sub2ind_vecs(inds, I::AbstractVector...)
I1 = I[1]
Iinds = indices1(I1)
for j = 2:length(I)
Expand All @@ -1502,7 +1507,7 @@ sub2ind_vec(inds, i, I) = (@_inline_meta; _sub2ind_vec(inds, (), i, I...))
_sub2ind_vec(inds, out, i, I1, I...) = (@_inline_meta; _sub2ind_vec(inds, (out..., I1[i]), i, I...))
_sub2ind_vec(inds, out, i) = (@_inline_meta; sub2ind(inds, out...))

function ind2sub{N,T<:Integer}(inds::Union{Dims{N},Indices{N}}, ind::AbstractVector{T})
function ind2sub{N,T<:Integer}(inds::Union{DimsInteger{N},Indices{N}}, ind::AbstractVector{T})
M = length(ind)
t = ntuple(n->similar(ind),Val{N})
for (i,idx) in enumerate(ind) # FIXME: change to eachindexvalue
Expand Down
7 changes: 0 additions & 7 deletions base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2571,13 +2571,6 @@ faster and more accurate.
"""
log(x)

"""
log(b,x)
Compute the base `b` logarithm of `x`. Throws `DomainError` for negative `Real` arguments.
"""
log(b, x)

"""
trunc([T,] x, [digits, [base]])
Expand Down
158 changes: 108 additions & 50 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -777,57 +777,68 @@ function abstract_call_gf_by_type(f::ANY, argtype::ANY, sv)
return Any
end
for (m::SimpleVector) in x
sig = m[1]
sig = m[1]::DataType
method = m[3]::Method
sparams = m[2]::SimpleVector
recomputesvec = false

# limit argument type tuple growth
lsig = length(m[3].sig.parameters)
ls = length(sig.parameters)
td = type_depth(sig)
# look at the existing edges to detect growing argument lists
mightlimitlength = ls > lsig + 1
mightlimitdepth = td > 2

limitlength = false
for (callee, _) in sv.edges
callee = callee::InferenceState
if method === callee.linfo.def && ls > length(callee.linfo.specTypes.parameters)
limitlength = true
break
if mightlimitlength
for (callee, _) in sv.edges
callee = callee::InferenceState
if method === callee.linfo.def && ls > length(callee.linfo.specTypes.parameters)
limitlength = true
break
end
end
end

# limit argument type size growth
# TODO: FIXME: this heuristic depends on non-local state making type-inference unpredictable
for infstate in active
infstate === nothing && continue
infstate = infstate::InferenceState
if isdefined(infstate.linfo, :def) && method === infstate.linfo.def
td = type_depth(sig)
if ls > length(infstate.linfo.specTypes.parameters)
limitlength = true
end
if td > type_depth(infstate.linfo.specTypes)
# impose limit if we recur and the argument types grow beyond MAX_TYPE_DEPTH
if td > MAX_TYPE_DEPTH
sig = limit_type_depth(sig, 0, true, [])
break
else
p1, p2 = sig.parameters, infstate.linfo.specTypes.parameters
if length(p2) == ls
limitdepth = false
newsig = Array{Any}(ls)
for i = 1:ls
if p1[i] <: Function && type_depth(p1[i]) > type_depth(p2[i]) &&
isa(p1[i],DataType)
# if a Function argument is growing (e.g. nested closures)
# then widen to the outermost function type. without this
# inference fails to terminate on do_quadgk.
newsig[i] = p1[i].name.primary
limitdepth = true
else
newsig[i] = limit_type_depth(p1[i], 1, true, [])
if mightlimitlength || mightlimitdepth
# TODO: FIXME: this heuristic depends on non-local state making type-inference unpredictable
for infstate in active
infstate === nothing && continue
infstate = infstate::InferenceState
if isdefined(infstate.linfo, :def) && method === infstate.linfo.def
if mightlimitlength && ls > length(infstate.linfo.specTypes.parameters)
limitlength = true
end
if mightlimitdepth && td > type_depth(infstate.linfo.specTypes)
# impose limit if we recur and the argument types grow beyond MAX_TYPE_DEPTH
if td > MAX_TYPE_DEPTH
sig = limit_type_depth(sig, 0, true, [])
recomputesvec = true
break
else
p1, p2 = sig.parameters, infstate.linfo.specTypes.parameters
if length(p2) == ls
limitdepth = false
newsig = Array{Any}(ls)
for i = 1:ls
if p1[i] <: Function && type_depth(p1[i]) > type_depth(p2[i]) &&
isa(p1[i],DataType)
# if a Function argument is growing (e.g. nested closures)
# then widen to the outermost function type. without this
# inference fails to terminate on do_quadgk.
newsig[i] = p1[i].name.primary
limitdepth = true
else
newsig[i] = limit_type_depth(p1[i], 1, true, [])
end
end
if limitdepth
sig = Tuple{newsig...}
recomputesvec = true
break
end
end
if limitdepth
sig = Tuple{newsig...}
break
end
end
end
Expand All @@ -844,26 +855,37 @@ function abstract_call_gf_by_type(f::ANY, argtype::ANY, sv)
# limit length based on size of definition signature.
# for example, given function f(T, Any...), limit to 3 arguments
# instead of the default (MAX_TUPLETYPE_LEN)
if limitlength && ls > lsig + 1
if limitlength
if !istopfunction(tm, f, :promote_typeof)
fst = sig.parameters[lsig+1]
fst = sig.parameters[lsig + 1]
allsame = true
# allow specializing on longer arglists if all the trailing
# arguments are the same, since there is no exponential
# blowup in this case.
for i = lsig+2:ls
for i = (lsig + 2):ls
if sig.parameters[i] != fst
allsame = false
break
end
end
if !allsame
sig = limit_tuple_type_n(sig, lsig+1)
sig = limit_tuple_type_n(sig, lsig + 1)
recomputesvec = true
end
end
end
#print(m,"\n")
(_tree, rt) = typeinf_edge(method, sig, m[2], sv)

# if sig changed, may need to recompute the sparams environment
if recomputesvec && !isempty(sparams)
recomputed = ccall(:jl_type_intersection_env, Ref{SimpleVector}, (Any, Any, Any), sig, method.sig, method.tvars)
if !isa(recomputed[1], DataType) # probably Union{}
rettype = Any
break
end
sig = recomputed[1]::DataType
sparams = recomputed[2]::SimpleVector
end
(_tree, rt) = typeinf_edge(method, sig, sparams, sv)
rettype = tmerge(rettype, rt)
if is(rettype,Any)
break
Expand Down Expand Up @@ -1417,7 +1439,7 @@ end
# create a specialized LambdaInfo from a method
function specialize_method(method::Method, types::ANY, sp::SimpleVector, cached)
if cached
return ccall(:jl_specializations_get_linfo, Ref{LambdaInfo}, (Any, Any, Any), method, types, sp)
return ccall(:jl_specializations_get_linfo, Ref{LambdaInfo}, (Any, Any, Any, Cint), method, types, sp, true)
else
return ccall(:jl_get_specialized, Ref{LambdaInfo}, (Any, Any, Any), method, types, sp)
end
Expand Down Expand Up @@ -3368,10 +3390,17 @@ function alloc_elim_pass!(linfo::LambdaInfo, sv::InferenceState)
end
else
vals = Vector{Any}(nv)
local new_slots::Vector{Int}
if !is_ssa
new_slots = Vector{Int}(nv)
end
for j=1:nv
tupelt = tup[j+1]
if (isa(tupelt,Number) || isa(tupelt,AbstractString) ||
isa(tupelt,QuoteNode) || isa(tupelt, SSAValue))
# If `!is_ssa` we have to create new variables for each
# (used) fields in order to preserve the undef check.
if is_ssa && (isa(tupelt,Number) ||
isa(tupelt,AbstractString) ||
isa(tupelt,QuoteNode) || isa(tupelt, SSAValue))
vals[j] = tupelt
else
elty = exprtype(tupelt, linfo)
Expand All @@ -3381,7 +3410,9 @@ function alloc_elim_pass!(linfo::LambdaInfo, sv::InferenceState)
var = var::Slot
tmpv = add_slot!(linfo, elty, false,
linfo.slotnames[var.id])
linfo.slotflags[tmpv.id] |= Slot_UsedUndef
slot_id = tmpv.id
new_slots[j] = slot_id
linfo.slotflags[slot_id] |= Slot_UsedUndef
end
tmp = Expr(:(=), tmpv, tupelt)
insert!(body, i+n_ins, tmp)
Expand All @@ -3390,7 +3421,10 @@ function alloc_elim_pass!(linfo::LambdaInfo, sv::InferenceState)
end
end
replace_getfield!(linfo, bexpr, var, vals, field_names, sv)
if isa(var, Slot) && is_ssa
if !is_ssa
i += replace_newvar_node!(body, (var::Slot).id,
new_slots, i)
elseif isa(var, Slot)
# occurs_outside_getfield might have allowed
# void use of the slot, we need to delete them too
i -= delete_void_use!(body, var::Slot, i)
Expand All @@ -3406,6 +3440,30 @@ function alloc_elim_pass!(linfo::LambdaInfo, sv::InferenceState)
end
end

# Return the number of expressions added before `i0`
function replace_newvar_node!(body, orig, new_slots, i0)
nvars = length(new_slots)
nvars == 0 && return 0
narg = length(body)
i = 1
nins = 0
newvars = [NewvarNode(SlotNumber(id)) for id in new_slots]
while i <= narg
a = body[i]
if isa(a, NewvarNode) && (a::NewvarNode).slot.id == orig
splice!(body, i, newvars)
if i - nins < i0
nins += nvars - 1
end
narg += nvars - 1
i += nvars
else
i += 1
end
end
return nins
end

# Return the number of expressions deleted before `i0`
function delete_void_use!(body, var::Slot, i0)
narg = length(body)
Expand Down
2 changes: 1 addition & 1 deletion base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ function stale_cachefile(modpath::String, cachefile::String)
end

# now check if this file is fresh relative to its source files
if files[1][1] != modpath
if !samefile(files[1][1], modpath)
DEBUG_LOADING[] && info("JL_DEBUG_LOADING: Rejecting cache file $cachefile because it is for file $(files[1][1])) not file $modpath.")
return true # cache file was compiled from a different path
end
Expand Down
1 change: 1 addition & 0 deletions base/markdown/Common/block.jl
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ isordered(list::List) = list.ordered >= 0
const BULLETS = r"^ {0,3}(\*|\+|-)( |$)"
const NUM_OR_BULLETS = r"^ {0,3}(\*|\+|-|\d+(\.|\)))( |$)"

@breaking true ->
function list(stream::IO, block::MD)
withstream(stream) do
bullet = startswith(stream, NUM_OR_BULLETS; eat = false)
Expand Down
26 changes: 26 additions & 0 deletions base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,32 @@ deg2rad(z::Real) = deg2rad(float(z))
@vectorize_1arg Real deg2rad

log{T<:Number}(b::T, x::T) = log(x)/log(b)

"""
log(b,x)
Compute the base `b` logarithm of `x`. Throws `DomainError` for negative `Real` arguments.
```jldoctest
julia> log(4,8)
1.5
julia> log(4,2)
0.5
```
!!! note
If `b` is a power of 2 or 10, `log2` or `log10` should be used, as these will
typically be faster and more accurate. For example,
```jldoctest
julia> log(100,1000000)
2.9999999999999996
julia> log10(1000000)/2
3.0
```
"""
log(b::Number, x::Number) = log(promote(b,x)...)
@vectorize_2arg Number log

Expand Down
19 changes: 10 additions & 9 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1357,15 +1357,16 @@ function print_matrix_vdots(io::IO, vdots::AbstractString,
end

"""
`print_matrix(io, X)` composes an entire matrix, taking into account the screen size.
If X is too big, it will be nine-sliced with vertical, horizontal, or diagonal
ellipsis inserted as appropriate.
Optional parameters are screen size tuple sz such as (24,80),
string pre prior to the matrix (e.g. opening bracket), which will cause
a corresponding same-size indent on following rows,
string post on the end of the last row of the matrix.
Also options to use different ellipsis characters hdots,
vdots, ddots. These are repeated every hmod or vmod elements.
print_matrix(io::IO, mat, pre, sep, post, hdots, vdots, ddots, hmod, vmod)
Prints a matrix with limited output size. If `io` sets `:limit` to true,
then only the corners of the matrix are printed, separated with vertical,
horizontal, and diagonal ellipses as appropriate.
Optional arguments are string pre (printed before the matrix, e.g. an opening bracket)
which will cause a corresponding same-size indent on following rows, and
string post (printed at the end of the last row of the matrix).
Also options to use different ellipsis characters hdots, vdots, ddots.
These are repeated every hmod or vmod elements.
"""
function print_matrix(io::IO, X::AbstractVecOrMat,
pre::AbstractString = " ", # pre-matrix string
Expand Down
Loading

0 comments on commit db7eaf9

Please sign in to comment.