Skip to content

Commit 77e7e73

Browse files
authored
Backports for julia v1.10.0-beta2 (#50708)
Backported PRs: - [x] #50637 <!-- Remove SparseArrays legacy code --> - [x] #50665 <!-- print `@time` msg into print buffer --> - [x] #50523 <!-- Avoid generic call in most cases for getproperty --> - [x] #50635 <!-- `versioninfo()`: include build info and unofficial warning --> - [x] #50670 <!-- Make reinterpret specialize fully. --> - [x] #50666 <!-- include `--pkgimage=no` caches for stdlibs --> - [x] #50765 - [x] #50764 - [x] #50768 - [x] #50767 - [x] #50618 <!-- inference: continue const-prop' when concrete-eval returns non-inlineable --> - [x] #50689 <!-- Attach `tanpi` docstring to method --> - [x] #50671 <!-- Fix rdiv of complex lhs by real factorizations --> - [x] #50598 <!-- only limit types in stack traces in the REPL --> - [x] #50766 <!-- Don't partition alwaysinline functions --> - [x] #50771 <!-- re-allow non-string values in ENV `get!` --> - [x] #50682 <!-- Add fallback if we have make a weird GC decision. --> - [x] #50781 <!-- fix `bit_map!` with aliasing --> - [x] #50172 <!-- print feature flags used for matching pkgimage --> - [x] #50844 <!-- Bump OpenBLAS binaries to use the new GEMM multithreading threshold --> - [x] #50826 <!-- Update dependency builds --> - [x] #50845 <!-- fix #50438, use default pool for at-threads --> - [x] #50568 <!-- `Array(::AbstractRange)` should return an `Array` --> - [x] #50655 <!-- fix hashing regression. --> - [x] #50779 <!-- Minor refactor to image generation --> - [x] #50791 <!-- Make symbols internal in jl_create_native, and only externalize them when partitioning --> - [x] #50724 <!-- Merge opaque closure modules with the rest of the workqueue --> - [x] #50738 <!-- Add alignment to constant globals --> - [x] #50871 <!-- macOS: Don't inspect dead threadtls during exception handling. --> Need manual backport: Contains multiple commits, manual intervention needed: Non-merged PRs with backport label: - [ ] #50850 <!-- Remove weird Rational dispatch and add pi functions to list --> - [ ] #50823 <!-- Make ranges more robust with unsigned indexes. --> - [ ] #50809 <!-- Limit type-printing in MethodError --> - [ ] #50663 <!-- Fix Expr(:loopinfo) codegen --> - [ ] #50594 <!-- Disallow non-index Integer types in isassigned --> - [ ] #50385 <!-- Precompile pidlocks: add to NEWS and docs --> - [ ] #49805 <!-- Limit TimeType subtraction to AbstractDateTime -->
2 parents c11763f + 1fc06f2 commit 77e7e73

File tree

113 files changed

+2248
-1742
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+2248
-1742
lines changed

Make.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1503,7 +1503,7 @@ endef
15031503
WINE ?= wine
15041504

15051505
ifeq ($(BINARY),32)
1506-
HEAPLIM := --heap-size-hint=500M
1506+
HEAPLIM := --heap-size-hint=1000M
15071507
else
15081508
HEAPLIM :=
15091509
endif

base/bitarray.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,9 +1791,10 @@ function bit_map!(f::F, dest::BitArray, A::BitArray) where F
17911791
dest_last = destc[len_Ac]
17921792
_msk = _msk_end(A)
17931793
# first zero out the bits mask is going to change
1794-
destc[len_Ac] = (dest_last & (~_msk))
17951794
# then update bits by `or`ing with a masked RHS
1796-
destc[len_Ac] |= f(Ac[len_Ac]) & _msk
1795+
# DO NOT SEPARATE ONTO TO LINES.
1796+
# Otherwise there will be bugs when Ac aliases destc
1797+
destc[len_Ac] = (dest_last & (~_msk)) | f(Ac[len_Ac]) & _msk
17971798
dest
17981799
end
17991800
function bit_map!(f::F, dest::BitArray, A::BitArray, B::BitArray) where F
@@ -1812,9 +1813,10 @@ function bit_map!(f::F, dest::BitArray, A::BitArray, B::BitArray) where F
18121813
dest_last = destc[len_Ac]
18131814
_msk = _msk_end(min_bitlen)
18141815
# first zero out the bits mask is going to change
1815-
destc[len_Ac] = (dest_last & ~(_msk))
18161816
# then update bits by `or`ing with a masked RHS
1817-
destc[len_Ac] |= f(Ac[end], Bc[end]) & _msk
1817+
# DO NOT SEPARATE ONTO TO LINES.
1818+
# Otherwise there will be bugs when Ac or Bc aliases destc
1819+
destc[len_Ac] = (dest_last & ~(_msk)) | f(Ac[end], Bc[end]) & _msk
18181820
dest
18191821
end
18201822

base/compiler/abstractinterpretation.jl

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -773,11 +773,13 @@ struct ConstCallResults
773773
const_result::ConstResult
774774
effects::Effects
775775
edge::MethodInstance
776-
ConstCallResults(@nospecialize(rt),
777-
const_result::ConstResult,
778-
effects::Effects,
779-
edge::MethodInstance) =
780-
new(rt, const_result, effects, edge)
776+
function ConstCallResults(
777+
@nospecialize(rt),
778+
const_result::ConstResult,
779+
effects::Effects,
780+
edge::MethodInstance)
781+
return new(rt, const_result, effects, edge)
782+
end
781783
end
782784

783785
function abstract_call_method_with_const_args(interp::AbstractInterpreter,
@@ -791,24 +793,33 @@ function abstract_call_method_with_const_args(interp::AbstractInterpreter,
791793
return nothing
792794
end
793795
eligibility = concrete_eval_eligible(interp, f, result, arginfo, sv)
796+
concrete_eval_result = nothing
794797
if eligibility === :concrete_eval
795-
return concrete_eval_call(interp, f, result, arginfo, sv, invokecall)
798+
concrete_eval_result = concrete_eval_call(interp, f, result, arginfo, sv, invokecall)
799+
# if we don't inline the result of this concrete evaluation,
800+
# give const-prop' a chance to inline a better method body
801+
if !may_optimize(interp) || (
802+
may_inline_concrete_result(concrete_eval_result.const_result::ConcreteResult) ||
803+
concrete_eval_result.rt === Bottom) # unless this call deterministically throws and thus is non-inlineable
804+
return concrete_eval_result
805+
end
806+
# TODO allow semi-concrete interp for this call?
796807
end
797808
mi = maybe_get_const_prop_profitable(interp, result, f, arginfo, si, match, sv)
798-
mi === nothing && return nothing
809+
mi === nothing && return concrete_eval_result
799810
if is_constprop_recursed(result, mi, sv)
800811
add_remark!(interp, sv, "[constprop] Edge cycle encountered")
801812
return nothing
802813
end
803814
# try semi-concrete evaluation
804815
if eligibility === :semi_concrete_eval
805-
res = semi_concrete_eval_call(interp, mi, result, arginfo, sv)
806-
if res !== nothing
807-
return res
816+
irinterp_result = semi_concrete_eval_call(interp, mi, result, arginfo, sv)
817+
if irinterp_result !== nothing
818+
return irinterp_result
808819
end
809820
end
810821
# try constant prop'
811-
return const_prop_call(interp, mi, result, arginfo, sv)
822+
return const_prop_call(interp, mi, result, arginfo, sv, concrete_eval_result)
812823
end
813824

814825
function const_prop_enabled(interp::AbstractInterpreter, sv::AbsIntState, match::MethodMatch)
@@ -900,7 +911,7 @@ function concrete_eval_call(interp::AbstractInterpreter,
900911
Core._call_in_world_total(world, f, args...)
901912
catch
902913
# The evaluation threw. By :consistent-cy, we're guaranteed this would have happened at runtime
903-
return ConstCallResults(Union{}, ConcreteResult(edge, result.effects), result.effects, edge)
914+
return ConstCallResults(Bottom, ConcreteResult(edge, result.effects), result.effects, edge)
904915
end
905916
return ConstCallResults(Const(value), ConcreteResult(edge, EFFECTS_TOTAL, value), EFFECTS_TOTAL, edge)
906917
end
@@ -1158,16 +1169,20 @@ function semi_concrete_eval_call(interp::AbstractInterpreter,
11581169
# that are newly resovled by irinterp
11591170
# state = InliningState(interp)
11601171
# ir = ssa_inlining_pass!(irsv.ir, state, propagate_inbounds(irsv))
1161-
new_effects = Effects(result.effects; nothrow)
1162-
return ConstCallResults(rt, SemiConcreteResult(mi, ir, new_effects), new_effects, mi)
1172+
effects = result.effects
1173+
if !is_nothrow(effects)
1174+
effects = Effects(effects; nothrow)
1175+
end
1176+
return ConstCallResults(rt, SemiConcreteResult(mi, ir, effects), effects, mi)
11631177
end
11641178
end
11651179
end
11661180
return nothing
11671181
end
11681182

11691183
function const_prop_call(interp::AbstractInterpreter,
1170-
mi::MethodInstance, result::MethodCallResult, arginfo::ArgInfo, sv::AbsIntState)
1184+
mi::MethodInstance, result::MethodCallResult, arginfo::ArgInfo, sv::AbsIntState,
1185+
concrete_eval_result::Union{Nothing,ConstCallResults}=nothing)
11711186
inf_cache = get_inference_cache(interp)
11721187
𝕃ᵢ = typeinf_lattice(interp)
11731188
inf_result = cache_lookup(𝕃ᵢ, mi, arginfo.argtypes, inf_cache)
@@ -1190,6 +1205,11 @@ function const_prop_call(interp::AbstractInterpreter,
11901205
return nothing
11911206
end
11921207
@assert inf_result.result !== nothing
1208+
if concrete_eval_result !== nothing
1209+
# override return type and effects with concrete evaluation result if available
1210+
inf_result.result = concrete_eval_result.rt
1211+
inf_result.ipo_effects = concrete_eval_result.effects
1212+
end
11931213
else
11941214
# found the cache for this constant prop'
11951215
if inf_result.result === nothing

base/compiler/ssair/ir.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,12 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr
13381338
return result_idx
13391339
end
13401340
end
1341-
ssa_rename[idx] = SSAValue(result_idx)
1341+
typ = inst[:type]
1342+
if isa(typ, Const) && is_inlineable_constant(typ.val)
1343+
ssa_rename[idx] = quoted(typ.val)
1344+
else
1345+
ssa_rename[idx] = SSAValue(result_idx)
1346+
end
13421347
result[result_idx][:inst] = stmt
13431348
result_idx += 1
13441349
elseif isa(stmt, PiNode)
@@ -1359,8 +1364,9 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr
13591364
return result_idx
13601365
end
13611366
elseif !isa(pi_val, AnySSAValue) && !isa(pi_val, GlobalRef)
1362-
valtyp = isa(pi_val, QuoteNode) ? typeof(pi_val.value) : typeof(pi_val)
1363-
if valtyp === stmt.typ
1367+
pi_val′ = isa(pi_val, QuoteNode) ? pi_val.value : pi_val
1368+
stmttyp = stmt.typ
1369+
if isa(stmttyp, Const) ? pi_val′ === stmttyp.val : typeof(pi_val′) === stmttyp
13641370
ssa_rename[idx] = pi_val
13651371
return result_idx
13661372
end

base/compiler/tfuncs.jl

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,19 +2347,18 @@ function getfield_effects(𝕃::AbstractLattice, arginfo::ArgInfo, @nospecialize
23472347
end
23482348

23492349
function getglobal_effects(argtypes::Vector{Any}, @nospecialize(rt))
2350+
2 length(argtypes) 3 || return EFFECTS_THROWS
23502351
consistent = inaccessiblememonly = ALWAYS_FALSE
23512352
nothrow = false
2352-
if length(argtypes) 2
2353-
M, s = argtypes[1], argtypes[2]
2354-
if getglobal_nothrow(M, s)
2355-
nothrow = true
2356-
# typeasserts below are already checked in `getglobal_nothrow`
2357-
Mval, sval = (M::Const).val::Module, (s::Const).val::Symbol
2358-
if isconst(Mval, sval)
2359-
consistent = ALWAYS_TRUE
2360-
if is_mutation_free_argtype(rt)
2361-
inaccessiblememonly = ALWAYS_TRUE
2362-
end
2353+
M, s = argtypes[1], argtypes[2]
2354+
if (length(argtypes) == 3 ? getglobal_nothrow(M, s, argtypes[3]) : getglobal_nothrow(M, s))
2355+
nothrow = true
2356+
# typeasserts below are already checked in `getglobal_nothrow`
2357+
Mval, sval = (M::Const).val::Module, (s::Const).val::Symbol
2358+
if isconst(Mval, sval)
2359+
consistent = ALWAYS_TRUE
2360+
if is_mutation_free_argtype(rt)
2361+
inaccessiblememonly = ALWAYS_TRUE
23632362
end
23642363
end
23652364
end

base/env.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ end
138138
getindex(::EnvDict, k::AbstractString) = access_env(k->throw(KeyError(k)), k)
139139
get(::EnvDict, k::AbstractString, def) = access_env(Returns(def), k)
140140
get(f::Callable, ::EnvDict, k::AbstractString) = access_env(k->f(), k)
141+
function get!(default::Callable, ::EnvDict, k::AbstractString)
142+
haskey(ENV, k) && return ENV[k]
143+
ENV[k] = default()
144+
end
141145
in(k::AbstractString, ::KeySet{String, EnvDict}) = _hasenv(k)
142146
pop!(::EnvDict, k::AbstractString) = (v = ENV[k]; _unsetenv(k); v)
143147
pop!(::EnvDict, k::AbstractString, def) = haskey(ENV,k) ? pop!(ENV,k) : def

base/errorshow.jl

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -772,9 +772,6 @@ function show_backtrace(io::IO, t::Vector)
772772
if haskey(io, :last_shown_line_infos)
773773
empty!(io[:last_shown_line_infos])
774774
end
775-
# this will be set to true if types in the stacktrace are truncated
776-
limitflag = Ref(false)
777-
io = IOContext(io, :stacktrace_types_limited => limitflag)
778775

779776
# t is a pre-processed backtrace (ref #12856)
780777
if t isa Vector{Any}
@@ -800,9 +797,6 @@ function show_backtrace(io::IO, t::Vector)
800797
# process_backtrace returns a Vector{Tuple{Frame, Int}}
801798
show_full_backtrace(io, filtered; print_linebreaks = stacktrace_linebreaks())
802799
end
803-
if limitflag[]
804-
print(io, "\nSome type information was truncated. Use `show(err)` to see complete types.")
805-
end
806800
nothing
807801
end
808802

base/essentials.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,8 @@ julia> reinterpret(Tuple{UInt16, UInt8}, (0x01, 0x0203))
571571
otherwise be prevented by the type's constructors and methods. Unexpected behavior
572572
may result without additional validation.
573573
"""
574-
function reinterpret(Out::Type, x::In) where {In}
575-
if isprimitivetype(Out) && isprimitivetype(In)
574+
function reinterpret(::Type{Out}, x) where {Out}
575+
if isprimitivetype(Out) && isprimitivetype(typeof(x))
576576
return bitcast(Out, x)
577577
end
578578
# only available when Base is fully loaded.

base/float.jl

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -688,22 +688,24 @@ function hash(x::Real, h::UInt)
688688
den_z = trailing_zeros(den)
689689
den >>= den_z
690690
pow += num_z - den_z
691-
692-
# handle values representable as Int64, UInt64, Float64
691+
# If the real can be represented as an Int64, UInt64, or Float64, hash as those types.
692+
# To be an Integer the denominator must be 1 and the power must be non-negative.
693693
if den == 1
694+
# left = ceil(log2(num*2^pow))
694695
left = top_set_bit(abs(num)) + pow
695-
right = pow + den_z
696-
if -1074 <= right
697-
if 0 <= right
696+
# 2^-1074 is the minimum Float64 so if the power is smaller, not a Float64
697+
if -1074 <= pow
698+
if 0 <= pow # if pow is non-negative, it is an integer
698699
left <= 63 && return hash(Int64(num) << Int(pow), h)
699700
left <= 64 && !signbit(num) && return hash(UInt64(num) << Int(pow), h)
700701
end # typemin(Int64) handled by Float64 case
701-
left <= 1024 && left - right <= 53 && return hash(ldexp(Float64(num), pow), h)
702+
# 2^1024 is the maximum Float64 so if the power is greater, not a Float64
703+
# Float64s only have 53 mantisa bits (including implicit bit)
704+
left <= 1024 && left - pow <= 53 && return hash(ldexp(Float64(num), pow), h)
702705
end
703706
else
704707
h = hash_integer(den, h)
705708
end
706-
707709
# handle generic rational values
708710
h = hash_integer(pow, h)
709711
h = hash_integer(num, h)

base/loading.jl

Lines changed: 91 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,11 +2841,9 @@ get_compiletime_preferences(m::Module) = get_compiletime_preferences(PkgId(m).uu
28412841
get_compiletime_preferences(::Nothing) = String[]
28422842

28432843
function check_clone_targets(clone_targets)
2844-
try
2845-
ccall(:jl_check_pkgimage_clones, Cvoid, (Ptr{Cchar},), clone_targets)
2846-
return true
2847-
catch
2848-
return false
2844+
rejection_reason = ccall(:jl_check_pkgimage_clones, Any, (Ptr{Cchar},), clone_targets)
2845+
if rejection_reason !== nothing
2846+
return rejection_reason
28492847
end
28502848
end
28512849

@@ -2877,6 +2875,88 @@ function show(io::IO, cf::CacheFlags)
28772875
print(io, ", opt_level = ", cf.opt_level)
28782876
end
28792877

2878+
struct ImageTarget
2879+
name::String
2880+
flags::Int32
2881+
ext_features::String
2882+
features_en::Vector{UInt8}
2883+
features_dis::Vector{UInt8}
2884+
end
2885+
2886+
function parse_image_target(io::IO)
2887+
flags = read(io, Int32)
2888+
nfeature = read(io, Int32)
2889+
feature_en = read(io, 4*nfeature)
2890+
feature_dis = read(io, 4*nfeature)
2891+
name_len = read(io, Int32)
2892+
name = String(read(io, name_len))
2893+
ext_features_len = read(io, Int32)
2894+
ext_features = String(read(io, ext_features_len))
2895+
ImageTarget(name, flags, ext_features, feature_en, feature_dis)
2896+
end
2897+
2898+
function parse_image_targets(targets::Vector{UInt8})
2899+
io = IOBuffer(targets)
2900+
ntargets = read(io, Int32)
2901+
targets = Vector{ImageTarget}(undef, ntargets)
2902+
for i in 1:ntargets
2903+
targets[i] = parse_image_target(io)
2904+
end
2905+
return targets
2906+
end
2907+
2908+
function current_image_targets()
2909+
targets = @ccall jl_reflect_clone_targets()::Vector{UInt8}
2910+
return parse_image_targets(targets)
2911+
end
2912+
2913+
struct FeatureName
2914+
name::Cstring
2915+
bit::UInt32 # bit index into a `uint32_t` array;
2916+
llvmver::UInt32 # 0 if it is available on the oldest LLVM version we support
2917+
end
2918+
2919+
function feature_names()
2920+
fnames = Ref{Ptr{FeatureName}}()
2921+
nf = Ref{Csize_t}()
2922+
@ccall jl_reflect_feature_names(fnames::Ptr{Ptr{FeatureName}}, nf::Ptr{Csize_t})::Cvoid
2923+
if fnames[] == C_NULL
2924+
@assert nf[] == 0
2925+
return Vector{FeatureName}(undef, 0)
2926+
end
2927+
Base.unsafe_wrap(Array, fnames[], nf[], own=false)
2928+
end
2929+
2930+
function test_feature(features::Vector{UInt8}, feat::FeatureName)
2931+
bitidx = feat.bit
2932+
u8idx = div(bitidx, 8) + 1
2933+
bit = bitidx % 8
2934+
return (features[u8idx] & (1 << bit)) != 0
2935+
end
2936+
2937+
function show(io::IO, it::ImageTarget)
2938+
print(io, it.name)
2939+
if !isempty(it.ext_features)
2940+
print(io, ",", it.ext_features)
2941+
end
2942+
print(io, "; flags=", it.flags)
2943+
print(io, "; features_en=(")
2944+
first = true
2945+
for feat in feature_names()
2946+
if test_feature(it.features_en, feat)
2947+
name = Base.unsafe_string(feat.name)
2948+
if first
2949+
first = false
2950+
print(io, name)
2951+
else
2952+
print(io, ", ", name)
2953+
end
2954+
end
2955+
end
2956+
print(io, ")")
2957+
# Is feature_dis useful?
2958+
end
2959+
28802960
# Set by FileWatching.__init__()
28812961
global mkpidlock_hook
28822962
global trymkpidlock_hook
@@ -2914,7 +2994,6 @@ function maybe_cachefile_lock(f, pkg::PkgId, srcpath::String; stale_age=300)
29142994
f()
29152995
end
29162996
end
2917-
29182997
# returns true if it "cachefile.ji" is stale relative to "modpath.jl" and build_id for modkey
29192998
# otherwise returns the list of dependencies to also check
29202999
@constprop :none function stale_cachefile(modpath::String, cachefile::String; ignore_loaded::Bool = false)
@@ -2948,8 +3027,12 @@ end
29483027
@debug "Rejecting cache file $cachefile for $modkey since it would require usage of pkgimage"
29493028
return true
29503029
end
2951-
if !check_clone_targets(clone_targets)
2952-
@debug "Rejecting cache file $cachefile for $modkey since pkgimage can't be loaded on this target"
3030+
rejection_reasons = check_clone_targets(clone_targets)
3031+
if !isnothing(rejection_reasons)
3032+
@debug("Rejecting cache file $cachefile for $modkey:",
3033+
Reasons=rejection_reasons,
3034+
var"Image Targets"=parse_image_targets(clone_targets),
3035+
var"Current Targets"=current_image_targets())
29533036
return true
29543037
end
29553038
if !isfile(ocachefile)

0 commit comments

Comments
 (0)