Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2308,7 +2308,7 @@ findall(testf::Function, A) = collect(first(p) for p in pairs(A) if testf(last(p

# Broadcasting is much faster for small testf, and computing
# integer indices from logical index using findall has a negligible cost
findall(testf::Function, A::AbstractArray) = findall(testf.(A))
findall(testf::F, A::AbstractArray) where {F<:Function} = findall(testf.(A))

"""
findall(A)
Expand Down
72 changes: 46 additions & 26 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
result = abstract_call_method(interp, method, sig_n, svec(), multiple_matches, sv)
rt = result.rt
edge = result.edge
edge !== nothing && push!(edges, edge)
edge === nothing || push!(edges, edge)
this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i]
this_arginfo = ArgInfo(fargs, this_argtypes)
const_call_result = abstract_call_method_with_const_args(interp, result,
Expand All @@ -136,25 +136,11 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
this_conditional = ignorelimited(this_rt)
this_rt = widenwrappedconditional(this_rt)
else
if infer_compilation_signature(interp)
# Also infer the compilation signature for this method, so it's available
# to the compiler in case it ends up needing it (which is likely).
csig = get_compileable_sig(method, sig, match.sparams)
if csig !== nothing && csig !== sig
# The result of this inference is not directly used, so temporarily empty
# the use set for the current SSA value.
saved_uses = sv.ssavalue_uses[sv.currpc]
sv.ssavalue_uses[sv.currpc] = empty_bitset
abstract_call_method(interp, method, csig, match.sparams, multiple_matches, sv)
sv.ssavalue_uses[sv.currpc] = saved_uses
end
end

result = abstract_call_method(interp, method, sig, match.sparams, multiple_matches, sv)
this_conditional = ignorelimited(result.rt)
this_rt = widenwrappedconditional(result.rt)
edge = result.edge
edge !== nothing && push!(edges, edge)
edge === nothing || push!(edges, edge)
# try constant propagation with argtypes for this match
# this is in preparation for inlining, or improving the return result
this_argtypes = isa(matches, MethodMatches) ? argtypes : matches.applicable_argtypes[i]
Expand Down Expand Up @@ -214,6 +200,26 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),

rettype = from_interprocedural!(rettype, sv, arginfo, conditionals)

# Also considering inferring the compilation signature for this method, so
# it is available to the compiler in case it ends up needing it.
if infer_compilation_signature(interp) && 1 == seen == napplicable && rettype !== Any && rettype !== Union{} && !is_removable_if_unused(all_effects)
match = applicable[1]::MethodMatch
method = match.method
sig = match.spec_types
mi = specialize_method(match; preexisting=true)
if mi !== nothing && !const_prop_methodinstance_heuristic(interp, match, mi::MethodInstance, arginfo, sv)
csig = get_compileable_sig(method, sig, match.sparams)
if csig !== nothing && csig !== sig
# The result of this inference is not directly used, so temporarily empty
# the use set for the current SSA value.
saved_uses = sv.ssavalue_uses[sv.currpc]
sv.ssavalue_uses[sv.currpc] = empty_bitset
abstract_call_method(interp, method, csig, match.sparams, multiple_matches, sv)
sv.ssavalue_uses[sv.currpc] = saved_uses
end
end
end

if call_result_unused(sv) && !(rettype === Bottom)
add_remark!(interp, sv, "Call result type was widened because the return value is unused")
# We're mainly only here because the optimizer might want this code,
Expand Down Expand Up @@ -765,13 +771,25 @@ function collect_const_args((; argtypes)::ArgInfo)
isa(a, Const) ? a.val :
isconstType(a) ? (a::DataType).parameters[1] :
(a::DataType).instance
end for i in 2:length(argtypes) ]
end for i = 2:length(argtypes) ]
end

struct InvokeCall
types # ::Type
lookupsig # ::Type
InvokeCall(@nospecialize(types), @nospecialize(lookupsig)) = new(types, lookupsig)
end

function concrete_eval_call(interp::AbstractInterpreter,
@nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState)
@nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState,
invokecall::Union{Nothing,InvokeCall}=nothing)
concrete_eval_eligible(interp, f, result, arginfo, sv) || return nothing
args = collect_const_args(arginfo)
if invokecall !== nothing
# this call should be `invoke`d, rewrite `args` back now
pushfirst!(args, f, invokecall.types)
f = invoke
end
world = get_world_counter(interp)
value = try
Core._call_in_world_total(world, f, args...)
Expand Down Expand Up @@ -811,13 +829,13 @@ struct ConstCallResults
new(rt, const_result, effects)
end

function abstract_call_method_with_const_args(interp::AbstractInterpreter, result::MethodCallResult,
@nospecialize(f), arginfo::ArgInfo, match::MethodMatch,
sv::InferenceState)
function abstract_call_method_with_const_args(interp::AbstractInterpreter,
result::MethodCallResult, @nospecialize(f), arginfo::ArgInfo, match::MethodMatch,
sv::InferenceState, invokecall::Union{Nothing,InvokeCall}=nothing)
if !const_prop_enabled(interp, sv, match)
return nothing
end
val = concrete_eval_call(interp, f, result, arginfo, sv)
val = concrete_eval_call(interp, f, result, arginfo, sv, invokecall)
if val !== nothing
add_backedge!(result.edge, sv)
return val
Expand Down Expand Up @@ -1547,10 +1565,10 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
nargtype isa DataType || return CallMeta(Any, Effects(), false) # other cases are not implemented below
isdispatchelem(ft) || return CallMeta(Any, Effects(), false) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
ft = ft::DataType
types = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type
lookupsig = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type
nargtype = Tuple{ft, nargtype.parameters...}
argtype = Tuple{ft, argtype.parameters...}
match, valid_worlds, overlayed = findsup(types, method_table(interp))
match, valid_worlds, overlayed = findsup(lookupsig, method_table(interp))
match === nothing && return CallMeta(Any, Effects(), false)
update_valid_age!(sv, valid_worlds)
method = match.method
Expand All @@ -1569,8 +1587,10 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
# t, a = ti.parameters[i], argtypes′[i]
# argtypes′[i] = t ⊑ a ? t : a
# end
const_call_result = abstract_call_method_with_const_args(interp, result,
overlayed ? nothing : singleton_type(ft′), arginfo, match, sv)
f = overlayed ? nothing : singleton_type(ft′)
invokecall = InvokeCall(types, lookupsig)
const_call_result = abstract_call_method_with_const_args(interp,
result, f, arginfo, match, sv, invokecall)
const_result = nothing
if const_call_result !== nothing
if const_call_result.rt ⊑ rt
Expand Down
5 changes: 5 additions & 0 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,11 @@ function inline_invoke!(
return nothing
end

function invoke_signature(invokesig::Vector{Any})
ft, argtyps = widenconst(invokesig[2]), instanceof_tfunc(widenconst(invokesig[3]))[1]
return rewrap_unionall(Tuple{ft, unwrap_unionall(argtyps).parameters...}, argtyps)
end

function narrow_opaque_closure!(ir::IRCode, stmt::Expr, @nospecialize(info), state::InliningState)
if isa(info, OpaqueClosureCreateInfo)
lbt = argextype(stmt.args[2], ir)
Expand Down
8 changes: 6 additions & 2 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,12 @@ function prod(arr::AbstractArray{BigInt})
# to account for the rounding to limbs in MPZ.mul!
# (BITS_PER_LIMB-1 would typically be enough, to which we add
# 1 for the initial multiplication by init=1 in foldl)
nbits = GC.@preserve arr sum(arr; init=BITS_PER_LIMB) do x
abs(x.size) * BITS_PER_LIMB - leading_zeros(unsafe_load(x.d))
nbits = BITS_PER_LIMB
for x in arr
iszero(x) && return zero(BigInt)
xsize = abs(x.size)
lz = GC.@preserve x leading_zeros(unsafe_load(x.d, xsize))
nbits += xsize * BITS_PER_LIMB - lz
end
init = BigInt(; nbits)
MPZ.set_si!(init, 1)
Expand Down
3 changes: 2 additions & 1 deletion base/namedtuple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ function NamedTuple{names}(nt::NamedTuple) where {names}
types = Tuple{(fieldtype(nt, idx[n]) for n in 1:length(idx))...}
Expr(:new, :(NamedTuple{names, $types}), Any[ :(getfield(nt, $(idx[n]))) for n in 1:length(idx) ]...)
else
types = Tuple{(fieldtype(typeof(nt), names[n]) for n in 1:length(names))...}
length_names = length(names)::Integer
types = Tuple{(fieldtype(typeof(nt), names[n]) for n in 1:length_names)...}
NamedTuple{names, types}(map(Fix1(getfield, nt), names))
end
end
Expand Down
2 changes: 1 addition & 1 deletion base/ordering.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ lt(o::Lt, a, b) = o.lt(a,b)
@propagate_inbounds function lt(p::Perm, a::Integer, b::Integer)
da = p.data[a]
db = p.data[b]
lt(p.order, da, db) | (!lt(p.order, db, da) & (a < b))
(lt(p.order, da, db)::Bool) | (!(lt(p.order, db, da)::Bool) & (a < b))
end

_ord(lt::typeof(isless), by::typeof(identity), order::Ordering) = order
Expand Down
3 changes: 2 additions & 1 deletion base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,8 @@ const SMALL_ALGORITHM = InsertionSort
const SMALL_THRESHOLD = 20

function sort!(v::AbstractVector, lo::Integer, hi::Integer, ::InsertionSortAlg, o::Ordering)
@inbounds for i = lo+1:hi
lo_plus_1 = (lo + 1)::Integer
@inbounds for i = lo_plus_1:hi
j = i
x = v[i]
while j > lo
Expand Down
2 changes: 1 addition & 1 deletion base/special/exp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ const J_TABLE = (0x0000000000000000, 0xaac00b1afa5abcbe, 0x9b60163da9fb3335, 0xa
# XXX we want to mark :consistent-cy here so that this function can be concrete-folded,
# because the effect analysis currently can't prove it in the presence of `@inbounds` or
# `:boundscheck`, but still the access to `J_TABLE` is really safe here
@noinline Base.@assume_effects :consistent @inline function table_unpack(ind::Int32)
Base.@assume_effects :consistent function table_unpack(ind::Int32)
ind = ind & 255 + 1 # 255 == length(J_TABLE) - 1
j = @inbounds J_TABLE[ind]
jU = reinterpret(Float64, JU_CONST | (j&JU_MASK))
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
47f02b8f77000fc3aa53c48fadc07f58
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0aa074c752083c7c1357060c34e161356fcbe9bc27a2dd9bf1c5f0f51fe7bf2ea1b6dc2227c873a2605fa28332e98ff1fb1077f7870dc3e944590e47e38b7f6b
2 changes: 1 addition & 1 deletion stdlib/Artifacts/src/Artifacts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ function process_overrides(artifact_dict::Dict, pkg_uuid::Base.UUID)
# override for this UUID, and inserting new overrides for those hashes.
overrides = load_overrides()
if haskey(overrides[:UUID], pkg_uuid)
pkg_overrides = overrides[:UUID][pkg_uuid]
pkg_overrides = overrides[:UUID][pkg_uuid]::Dict{String, <:Any}

for name in keys(artifact_dict)
# Skip names that we're not overriding
Expand Down
3 changes: 2 additions & 1 deletion stdlib/InteractiveUtils/src/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ function recursive_dotcalls!(ex, args, i=1)
end
end
(start, branches) = ex.head === :. ? (1, ex.args[2].args) : (2, ex.args)
for j in start:length(branches)
length_branches = length(branches)::Integer
for j in start:length_branches
branch, i = recursive_dotcalls!(branches[j], args, i)
branches[j] = branch
end
Expand Down
5 changes: 5 additions & 0 deletions stdlib/LibGit2/src/consts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@ const RESET_HARD = Cint(3) # MIXED plus changes in working tree discarded
REBASE_OPERATION_FIXUP = Cint(4),
REBASE_OPERATION_EXEC = Cint(5))

# git_remote_redirect_t
const GIT_REMOTE_REDIRECT_NONE = Cint(0)
const GIT_REMOTE_REDIRECT_INITIAL = Cint(1)
const GIT_REMOTE_REDIRECT_ALL = Cint(2)

# fetch_prune
const FETCH_PRUNE_UNSPECIFIED = Cint(0)
const FETCH_PRUNE = Cint(1)
Expand Down
6 changes: 6 additions & 0 deletions stdlib/LibGit2/src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ The fields represent:
@static if LibGit2.VERSION >= v"0.25.0"
proxy_opts::ProxyOptions = ProxyOptions()
end
@static if LibGit2.VERSION >= v"1.4.0"
follow_redirects::Cint = Consts.GIT_REMOTE_REDIRECT_INITIAL
end
@static if LibGit2.VERSION >= v"0.24.0"
custom_headers::StrArrayStruct = StrArrayStruct()
end
Expand Down Expand Up @@ -677,6 +680,9 @@ The fields represent:
@static if LibGit2.VERSION >= v"0.25.0"
proxy_opts::ProxyOptions = ProxyOptions()
end
@static if LibGit2.VERSION >= v"1.4.0"
follow_redirects::Cint = Consts.GIT_REMOTE_REDIRECT_INITIAL
end
@static if LibGit2.VERSION >= v"0.24.0"
custom_headers::StrArrayStruct = StrArrayStruct()
end
Expand Down
2 changes: 1 addition & 1 deletion stdlib/Printf/src/Printf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ end
@inline function fmt(buf, pos, arg, spec::Spec{T}) where {T <: Strings}
leftalign, hash, width, prec = spec.leftalign, spec.hash, spec.width, spec.precision
str = string(arg)
slen = textwidth(str) + (hash ? arg isa AbstractString ? 2 : 1 : 0)
slen = textwidth(str)::Int + (hash ? arg isa AbstractString ? 2 : 1 : 0)
op = p = prec == -1 ? slen : min(slen, prec)
if !leftalign && width > p
for _ = 1:(width - p)
Expand Down
4 changes: 2 additions & 2 deletions stdlib/Tar.version
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
TAR_BRANCH = master
TAR_SHA1 = 0f8a73d5cd4b0c8f1f3c36799c96e9515e9dc595
TAR_BRANCH = release-1.10
TAR_SHA1 = c9e71856688bffacda56e1e2926a741bbb6e4784
TAR_GIT_URL := https://github.com/JuliaIO/Tar.jl.git
TAR_TAR_URL = https://api.github.com/repos/JuliaIO/Tar.jl/tarball/$1
21 changes: 21 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4074,3 +4074,24 @@ end)[2] == Union{}
@time 1
end
end)[2] == Union{}

invoke_concretized1(a::Int) = a > 0 ? :int : nothing
invoke_concretized1(a::Integer) = a > 0 ? "integer" : nothing
# check if `invoke(invoke_concretized1, Tuple{Integer}, ::Int)` is foldable
@test Base.infer_effects((Int,)) do a
Base.@invoke invoke_concretized1(a::Integer)
end |> Core.Compiler.is_foldable
@test Base.return_types() do
Base.@invoke invoke_concretized1(42::Integer)
end |> only === String

invoke_concretized2(a::Int) = a > 0 ? :int : nothing
invoke_concretized2(a::Integer) = a > 0 ? :integer : nothing
# check if `invoke(invoke_concretized2, Tuple{Integer}, ::Int)` is foldable
@test Base.infer_effects((Int,)) do a
Base.@invoke invoke_concretized2(a::Integer)
end |> Core.Compiler.is_foldable
@test let
Base.Experimental.@force_compile
Base.@invoke invoke_concretized2(42::Integer)
end === :integer
1 change: 1 addition & 0 deletions test/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ let a, b
@test 0 == sum(BigInt[]) isa BigInt
@test prod(b) == foldl(*, b)
@test 1 == prod(BigInt[]) isa BigInt
@test prod(BigInt[0, 0, 0]) == 0 # issue #46665
end

@testset "Iterated arithmetic" begin
Expand Down