Skip to content

Commit

Permalink
Merge pull request #39614 from JuliaLang/backports-release-1.6
Browse files Browse the repository at this point in the history
Backports for 1.6-RC2
  • Loading branch information
KristofferC authored Mar 10, 2021
2 parents a58bdd9 + f731fbb commit fe2311a
Show file tree
Hide file tree
Showing 117 changed files with 1,816 additions and 838 deletions.
4 changes: 3 additions & 1 deletion Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1556,9 +1556,11 @@ endif
LIBGCC_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_shlibdir)/$(LIBGCC_NAME))
LIBGCC_INSTALL_DEPLIB := $(call dep_lib_path,$(libdir),$(private_shlibdir)/$(LIBGCC_NAME))

# USE_SYSTEM_LIBM causes it to get symlinked into build_private_shlibdir
# USE_SYSTEM_LIBM and USE_SYSTEM_OPENLIBM causes it to get symlinked into build_private_shlibdir
ifeq ($(USE_SYSTEM_LIBM),1)
LIBM_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_private_shlibdir)/$(LIBMNAME).$(SHLIB_EXT))
else ifeq ($(USE_SYSTEM_OPENLIBM),1)
LIBM_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_private_shlibdir)/$(LIBMNAME).$(SHLIB_EXT))
else
LIBM_BUILD_DEPLIB := $(call dep_lib_path,$(build_libdir),$(build_shlibdir)/$(LIBMNAME).$(SHLIB_EXT))
endif
Expand Down
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -344,16 +344,16 @@ else ifneq (,$(findstring $(OS),Linux FreeBSD))
done
endif

# Overwrite JL_SYSTEM_IMAGE_PATH in julia library
if [ $(DARWIN_FRAMEWORK) = 0 ]; then \
RELEASE_TARGET=$(DESTDIR)$(libdir)/libjulia.$(SHLIB_EXT); \
DEBUG_TARGET=$(DESTDIR)$(libdir)/libjulia-debug.$(SHLIB_EXT); \
# Overwrite JL_SYSTEM_IMAGE_PATH in libjulia-internal
if [ "$(DARWIN_FRAMEWORK)" = "0" ]; then \
RELEASE_TARGET=$(DESTDIR)$(private_libdir)/libjulia-internal.$(SHLIB_EXT); \
DEBUG_TARGET=$(DESTDIR)$(private_libdir)/libjulia-internal-debug.$(SHLIB_EXT); \
else \
RELEASE_TARGET=$(DESTDIR)$(prefix)/$(framework_dylib); \
DEBUG_TARGET=$(DESTDIR)$(prefix)/$(framework_dylib)_debug; \
fi; \
$(call stringreplace,$${RELEASE_TARGET},sys.$(SHLIB_EXT)$$,$(private_libdir_rel)/sys.$(SHLIB_EXT)); \
if [ $(BUNDLE_DEBUG_LIBS) = 1 ]; then \
if [ "$(BUNDLE_DEBUG_LIBS)" = "1" ]; then \
$(call stringreplace,$${DEBUG_TARGET},sys-debug.$(SHLIB_EXT)$$,$(private_libdir_rel)/sys-debug.$(SHLIB_EXT)); \
fi;
endif
Expand Down
6 changes: 6 additions & 0 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,9 @@ end
Get the first `n` elements of the iterable collection `itr`, or fewer elements if `v` is not
long enough.
!!! compat "Julia 1.6"
This method requires at least Julia 1.6.
# Examples
```jldoctest
julia> first(["foo", "bar", "qux"], 2)
Expand Down Expand Up @@ -439,6 +442,9 @@ last(a) = a[end]
Get the last `n` elements of the iterable collection `itr`, or fewer elements if `v` is not
long enough.
!!! compat "Julia 1.6"
This method requires at least Julia 1.6.
# Examples
```jldoctest
julia> last(["foo", "bar", "qux"], 2)
Expand Down
7 changes: 4 additions & 3 deletions base/arrayshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,9 @@ function _show_nonempty(io::IO, X::AbstractMatrix, prefix::String)
indr, indc = axes(X,1), axes(X,2)
nr, nc = length(indr), length(indc)
rdots, cdots = false, false
rr1, rr2 = UnitRange{Int}(indr), 1:0
cr1, cr2 = UnitRange{Int}(indc), 1:0
rr1, rr2 = unitrange(indr), 1:0
cr1 = unitrange(indc)
cr2 = first(cr1) .+ (0:-1)
if limit
if nr > 4
rr1, rr2 = rr1[1:2], rr1[nr-1:nr]
Expand Down Expand Up @@ -417,7 +418,7 @@ function _show_nonempty(io::IO, X::AbstractMatrix, prefix::String)
end
end
end
last(rr) != nr && rdots && print(io, "\u2026 ; ")
last(rr) != last(indr) && rdots && print(io, "\u2026 ; ")
end
print(io, "]")
end
Expand Down
2 changes: 1 addition & 1 deletion base/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ gen_bitarrayN(::Type{BitVector}, itsz, itr) = gen_bitarra
gen_bitarrayN(::Type{BitVector}, itsz::HasShape{1}, itr) = gen_bitarray(itsz, itr)
gen_bitarrayN(::Type{BitArray{N}}, itsz::HasShape{N}, itr) where N = gen_bitarray(itsz, itr)
# The first of these is just for ambiguity resolution
gen_bitarrayN(::Type{BitVector}, itsz::HasShape{N}, itr) where N = throw(DimensionMismatch("cannot create a $T from a $N-dimensional iterator"))
gen_bitarrayN(::Type{BitVector}, itsz::HasShape{N}, itr) where N = throw(DimensionMismatch("cannot create a BitVector from a $N-dimensional iterator"))
gen_bitarrayN(@nospecialize(T::Type), itsz::HasShape{N}, itr) where N = throw(DimensionMismatch("cannot create a $T from a $N-dimensional iterator"))
gen_bitarrayN(@nospecialize(T::Type), itsz, itr) = throw(DimensionMismatch("cannot create a $T from a generic iterator"))

Expand Down
3 changes: 3 additions & 0 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -800,4 +800,7 @@ Integer(x::Union{Float16, Float32, Float64}) = Int(x)
# The internal jl_parse which will call into Core._parse if not `nothing`.
_parse = nothing

# support for deprecated uses of internal _apply function
_apply(x...) = Core._apply_iterate(Main.Base.iterate, x...)

ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Core, true)
3 changes: 3 additions & 0 deletions base/cmd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ setenv(cmd::Cmd; dir="") = Cmd(cmd; dir=dir)
Merge new environment mappings into the given `Cmd` object, returning a new `Cmd` object.
Duplicate keys are replaced. If `command` does not contain any environment values set already,
it inherits the current environment at time of `addenv()` call if `inherit` is `true`.
!!! compat "Julia 1.6"
This function requires Julia 1.6 or later.
"""
function addenv(cmd::Cmd, env::Dict; inherit::Bool = true)
new_env = Dict{String,String}()
Expand Down
81 changes: 47 additions & 34 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ function abstract_call_method(interp::AbstractInterpreter, method::Method, @nosp
# Under direct self-recursion, permit much greater use of reducers.
# here we assume that complexity(specTypes) :>= complexity(sig)
comparison = sv.linfo.specTypes
l_comparison = length(unwrap_unionall(comparison).parameters)
l_comparison = length(unwrap_unionall(comparison).parameters)::Int
spec_len = max(spec_len, l_comparison)
else
comparison = method.sig
Expand Down Expand Up @@ -589,13 +589,7 @@ end

# simulate iteration protocol on container type up to fixpoint
function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @nospecialize(itertype), sv::InferenceState)
if !isdefined(Main, :Base) || !isdefined(Main.Base, :iterate) || !isconst(Main.Base, :iterate)
return Any[Vararg{Any}], nothing
end
if itft === nothing
iteratef = getfield(Main.Base, :iterate)
itft = Const(iteratef)
elseif isa(itft, Const)
if isa(itft, Const)
iteratef = itft.val
else
return Any[Vararg{Any}], nothing
Expand All @@ -607,6 +601,7 @@ function abstract_iteration(interp::AbstractInterpreter, @nospecialize(itft), @n
# Return Bottom if this is not an iterator.
# WARNING: Changes to the iteration protocol must be reflected here,
# this is not just an optimization.
# TODO: this doesn't realize that Array, SimpleVector, Tuple, and NamedTuple do not use the iterate protocol
stateordonet === Bottom && return Any[Bottom], AbstractIterationInfo(CallMeta[CallMeta(Bottom, info)])
valtype = statetype = Bottom
ret = Any[]
Expand Down Expand Up @@ -670,7 +665,7 @@ function abstract_apply(interp::AbstractInterpreter, @nospecialize(itft), @nospe
aftw = widenconst(aft)
if !isa(aft, Const) && (!isType(aftw) || has_free_typevars(aftw))
if !isconcretetype(aftw) || (aftw <: Builtin)
add_remark!(interp, sv, "Core._apply called on a function of a non-concrete type")
add_remark!(interp, sv, "Core._apply_iterate called on a function of a non-concrete type")
# bail now, since it seems unlikely that abstract_call will be able to do any better after splitting
# this also ensures we don't call abstract_call_gf_by_type below on an IntrinsicFunction or Builtin
return CallMeta(Any, false)
Expand All @@ -679,16 +674,20 @@ function abstract_apply(interp::AbstractInterpreter, @nospecialize(itft), @nospe
res = Union{}
nargs = length(aargtypes)
splitunions = 1 < unionsplitcost(aargtypes) <= InferenceParams(interp).MAX_APPLY_UNION_ENUM
ctypes = Any[Any[aft]]
ctypes = [Any[aft]]
infos = [Union{Nothing, AbstractIterationInfo}[]]
for i = 1:nargs
ctypes´ = []
infos′ = []
ctypes´ = Vector{Any}[]
infos′ = Vector{Union{Nothing, AbstractIterationInfo}}[]
for ti in (splitunions ? uniontypes(aargtypes[i]) : Any[aargtypes[i]])
if !isvarargtype(ti)
cti, info = precise_container_type(interp, itft, ti, sv)
cti_info = precise_container_type(interp, itft, ti, sv)
cti = cti_info[1]::Vector{Any}
info = cti_info[2]::Union{Nothing,AbstractIterationInfo}
else
cti, info = precise_container_type(interp, itft, unwrapva(ti), sv)
cti_info = precise_container_type(interp, itft, unwrapva(ti), sv)
cti = cti_info[1]::Vector{Any}
info = cti_info[2]::Union{Nothing,AbstractIterationInfo}
# We can't represent a repeating sequence of the same types,
# so tmerge everything together to get one type that represents
# everything.
Expand All @@ -705,7 +704,7 @@ function abstract_apply(interp::AbstractInterpreter, @nospecialize(itft), @nospe
continue
end
for j = 1:length(ctypes)
ct = ctypes[j]
ct = ctypes[j]::Vector{Any}
if isvarargtype(ct[end])
# This is vararg, we're not gonna be able to do any inling,
# drop the info
Expand Down Expand Up @@ -826,7 +825,8 @@ function abstract_call_builtin(interp::AbstractInterpreter, f::Builtin, fargs::U
end
rt = builtin_tfunction(interp, f, argtypes[2:end], sv)
if f === getfield && isa(fargs, Vector{Any}) && la == 3 && isa(argtypes[3], Const) && isa(argtypes[3].val, Int) && argtypes[2] Tuple
cti, _ = precise_container_type(interp, nothing, argtypes[2], sv)
# TODO: why doesn't this use the getfield_tfunc?
cti, _ = precise_container_type(interp, iterate, argtypes[2], sv)
idx = argtypes[3].val::Int
if 1 <= idx <= length(cti)
rt = unwrapva(cti[idx])
Expand Down Expand Up @@ -945,11 +945,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
la = length(argtypes)

if isa(f, Builtin)
if f === _apply
ft = argtype_by_index(argtypes, 2)
ft === Bottom && return CallMeta(Bottom, false)
return abstract_apply(interp, nothing, ft, argtype_tail(argtypes, 3), sv, max_methods)
elseif f === _apply_iterate
if f === _apply_iterate
itft = argtype_by_index(argtypes, 2)
ft = argtype_by_index(argtypes, 3)
(itft === Bottom || ft === Bottom) && return CallMeta(Bottom, false)
Expand Down Expand Up @@ -1304,6 +1300,28 @@ function abstract_eval_ssavalue(s::SSAValue, src::CodeInfo)
return typ
end

function widenreturn(@nospecialize rt)
# only propagate information we know we can store
# and is valid and good inter-procedurally
rt = widenconditional(rt)
isa(rt, Const) && return rt
isa(rt, Type) && return rt
if isa(rt, PartialStruct)
fields = copy(rt.fields)
haveconst = false
for i in 1:length(fields)
a = widenreturn(fields[i])
if !haveconst && has_const_info(a)
# TODO: consider adding && const_prop_profitable(a) here?
haveconst = true
end
fields[i] = a
end
haveconst && return PartialStruct(rt.typ, fields)
end
return widenconst(rt)
end

# make as much progress on `frame` as possible (without handling cycles)
function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
@assert !frame.inferred
Expand All @@ -1326,6 +1344,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
frame.currpc = pc
frame.cur_hand = frame.handler_at[pc]
frame.stmt_edges[pc] === nothing || empty!(frame.stmt_edges[pc])
frame.stmt_info[pc] = nothing
stmt = frame.src.code[pc]
changes = s[pc]::VarTable
t = nothing
Expand All @@ -1338,7 +1357,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
elseif isa(stmt, GotoNode)
pc´ = (stmt::GotoNode).label
elseif isa(stmt, GotoIfNot)
condt = abstract_eval_value(interp, stmt.cond, s[pc], frame)
condt = abstract_eval_value(interp, stmt.cond, changes, frame)
if condt === Bottom
empty!(frame.pclimitations)
break
Expand Down Expand Up @@ -1369,7 +1388,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
end
end
newstate_else = stupdate!(s[l], changes_else)
if newstate_else !== false
if newstate_else !== nothing
# add else branch to active IP list
if l < frame.pc´´
frame.pc´´ = l
Expand All @@ -1380,12 +1399,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
end
elseif isa(stmt, ReturnNode)
pc´ = n + 1
rt = widenconditional(abstract_eval_value(interp, stmt.val, s[pc], frame))
if !isa(rt, Const) && !isa(rt, Type) && !isa(rt, PartialStruct)
# only propagate information we know we can store
# and is valid inter-procedurally
rt = widenconst(rt)
end
rt = widenreturn(abstract_eval_value(interp, stmt.val, changes, frame))
# copy limitations to return value
if !isempty(frame.pclimitations)
union!(frame.limitations, frame.pclimitations)
Expand Down Expand Up @@ -1414,9 +1428,8 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
frame.cur_hand = Pair{Any,Any}(l, frame.cur_hand)
# propagate type info to exception handler
old = s[l]
new = s[pc]::Array{Any,1}
newstate_catch = stupdate!(old, new)
if newstate_catch !== false
newstate_catch = stupdate!(old, changes)
if newstate_catch !== nothing
if l < frame.pc´´
frame.pc´´ = l
end
Expand Down Expand Up @@ -1483,12 +1496,12 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
# (such as a terminator for a loop, if-else, or try block),
# consider whether we should jump to an older backedge first,
# to try to traverse the statements in approximate dominator order
if newstate !== false
if newstate !== nothing
s[pc´] = newstate
end
push!(W, pc´)
pc = frame.pc´´
elseif newstate !== false
elseif newstate !== nothing
s[pc´] = newstate
pc = pc´
elseif pc´ in W
Expand Down
4 changes: 2 additions & 2 deletions base/compiler/compiler.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

getfield(getfield(Main, :Core), :eval)(getfield(Main, :Core), :(baremodule Compiler
getfield(Core, :eval)(Core, :(baremodule Compiler

using Core.Intrinsics, Core.IR

import Core: print, println, show, write, unsafe_write, stdout, stderr,
_apply, _apply_iterate, svec, apply_type, Builtin, IntrinsicFunction,
_apply_iterate, svec, apply_type, Builtin, IntrinsicFunction,
MethodInstance, CodeInstance, MethodMatch

const getproperty = Core.getfield
Expand Down
10 changes: 5 additions & 5 deletions base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -326,19 +326,19 @@ function statement_cost(ex::Expr, line::Int, src::CodeInfo, sptypes::Vector{Any}
# The efficiency of operations like a[i] and s.b
# depend strongly on whether the result can be
# inferred, so check the type of ex
if f === Main.Core.getfield || f === Main.Core.tuple
if f === Core.getfield || f === Core.tuple
# we might like to penalize non-inferrability, but
# tuple iteration/destructuring makes that impossible
# return plus_saturate(argcost, isknowntype(extyp) ? 1 : params.inline_nonleaf_penalty)
return 0
elseif f === Main.Core.isa
elseif f === Core.isa
# If we're in a union context, we penalize type computations
# on union types. In such cases, it is usually better to perform
# union splitting on the outside.
if union_penalties && isa(argextype(ex.args[2], src, sptypes, slottypes), Union)
return params.inline_nonleaf_penalty
end
elseif (f === Main.Core.arrayref || f === Main.Core.const_arrayref) && length(ex.args) >= 3
elseif (f === Core.arrayref || f === Core.const_arrayref) && length(ex.args) >= 3
atyp = argextype(ex.args[3], src, sptypes, slottypes)
return isknowntype(atyp) ? 4 : error_path ? params.inline_error_path_cost : params.inline_nonleaf_penalty
end
Expand Down Expand Up @@ -371,7 +371,7 @@ function statement_cost(ex::Expr, line::Int, src::CodeInfo, sptypes::Vector{Any}
end
a = ex.args[2]
if a isa Expr
cost = plus_saturate(cost, statement_cost(a, -1, src, sptypes, slottypes, params, error_path))
cost = plus_saturate(cost, statement_cost(a, -1, src, sptypes, slottypes, union_penalties, params, error_path))
end
return cost
elseif head === :copyast
Expand All @@ -392,7 +392,7 @@ function statement_or_branch_cost(@nospecialize(stmt), line::Int, src::CodeInfo,
thiscost = 0
if stmt isa Expr
thiscost = statement_cost(stmt, line, src, sptypes, slottypes, union_penalties, params,
params.unoptimize_throw_blocks && line in throw_blocks)::Int
throw_blocks !== nothing && line in throw_blocks)::Int
elseif stmt isa GotoNode
# loops are generally always expensive
# but assume that forward jumps are already counted for from
Expand Down
7 changes: 4 additions & 3 deletions base/compiler/ssair/driver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@ function convert_to_ircode(ci::CodeInfo, code::Vector{Any}, coverage::Bool, narg
labelmap = coverage ? fill(0, length(code)) : changemap
prevloc = zero(eltype(ci.codelocs))
stmtinfo = sv.stmt_info
ssavaluetypes = ci.ssavaluetypes::Vector{Any}
while idx <= length(code)
codeloc = ci.codelocs[idx]
if coverage && codeloc != prevloc && codeloc != 0
# insert a side-effect instruction before the current instruction in the same basic block
insert!(code, idx, Expr(:code_coverage_effect))
insert!(ci.codelocs, idx, codeloc)
insert!(ci.ssavaluetypes, idx, Nothing)
insert!(ssavaluetypes, idx, Nothing)
insert!(stmtinfo, idx, nothing)
changemap[oldidx] += 1
if oldidx < length(labelmap)
Expand All @@ -58,12 +59,12 @@ function convert_to_ircode(ci::CodeInfo, code::Vector{Any}, coverage::Bool, narg
idx += 1
prevloc = codeloc
end
if code[idx] isa Expr && ci.ssavaluetypes[idx] === Union{}
if code[idx] isa Expr && ssavaluetypes[idx] === Union{}
if !(idx < length(code) && isa(code[idx + 1], ReturnNode) && !isdefined((code[idx + 1]::ReturnNode), :val))
# insert unreachable in the same basic block after the current instruction (splitting it)
insert!(code, idx + 1, ReturnNode())
insert!(ci.codelocs, idx + 1, ci.codelocs[idx])
insert!(ci.ssavaluetypes, idx + 1, Union{})
insert!(ssavaluetypes, idx + 1, Union{})
insert!(stmtinfo, idx + 1, nothing)
if oldidx < length(changemap)
changemap[oldidx + 1] += 1
Expand Down
Loading

0 comments on commit fe2311a

Please sign in to comment.