Skip to content

Commit 1dfdf66

Browse files
authored
Backports for 1.10.1 (#52755)
Backported PRs: - [x] #51095 <!-- Fix edge cases where inexact conversions to UInt don't throw --> - [x] #52583 <!-- Don't access parent of triangular matrix in powm --> - [x] #52645 <!-- update --gcthreads section in command line options --> - [x] #52423 <!-- update nthreads info in versioninfo --> - [x] #52721 <!-- inference: Guard TypeVar special case against vararg --> - [x] #52637 <!-- fix finding bundled stdlibs even if they are e.g. devved in an environment higher in the load path --> - [x] #52752 <!-- staticdata: handle cycles in datatypes --> - [x] #52758 <!-- use a Dict instead of an IdDict for caching of the `cwstring` for Windows env variables --> - [x] #51375 <!-- Insert hardcoded backlinks to stdlib doc pages --> - [x] #52994 <!-- place work-stealing queue indices on different cache lines to avoid false-sharing --> - [x] #53015 <!-- Add type assertion in iterate for logicalindex --> - [x] #53032 <!-- Fix a list in GC devdocs --> - [x] #52748 - [x] #52856 - [x] #52878 - [x] #52754 - [x] #52228 - [x] #52924 - [x] #52569 <!-- Fix GC rooting during rehashing of iddict --> - [x] #52605 <!-- Default uplo in symmetric/hermitian --> - [x] #52618 <!-- heap snapshot: add gc roots and gc finalist roots to fix unrooted nodes --> - [x] #52781 <!-- fix type-stability bugs in Ryu code --> - [x] #53055 <!-- Profile: use full terminal cols to show function name --> - [x] #53096 - [x] #53076 - [x] #52841 <!-- Extensions: make loading of extensions independent of what packages are in the sysimage --> - [x] #52078 <!-- Replace `&hArr;` by `&harr;` in documentation --> - [x] #53035 <!-- use proper cache-line size variable in work-stealing queue --> - [x] #53066 <!-- doc: replace harr HTML entity by unicode --> - [x] #52996 <!-- Apple silicon has 128 byte alignment so fix our defines to match --> - [x] #53121 Non-merged PRs with backport label: - [ ] #52694 <!-- Reinstate similar for AbstractQ for backward compatibility --> - [ ] #51479 <!-- prevent code loading from lookin in the versioned environment when building Julia -->
2 parents 7a96210 + 0627076 commit 1dfdf66

File tree

95 files changed

+1525
-818
lines changed

Some content is hidden

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

95 files changed

+1525
-818
lines changed

Make.inc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,7 @@ LIBGFORTRAN_VERSION := $(subst libgfortran,,$(filter libgfortran%,$(subst -,$(SP
12331233
# shipped with CSL. Although we do not depend on any of the symbols, it is entirely
12341234
# possible that a user might choose to install a library which depends on symbols provided
12351235
# by a newer libstdc++. Without runtime detection, those libraries would break.
1236-
CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.31|GLIBCXX_3\.5\.|GLIBCXX_4\.
1236+
CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.33|GLIBCXX_3\.5\.|GLIBCXX_4\.
12371237

12381238

12391239
# This is the set of projects that BinaryBuilder dependencies are hooked up for.

Makefile

+3-6
Original file line numberDiff line numberDiff line change
@@ -281,16 +281,13 @@ else ifeq ($(JULIA_BUILD_MODE),debug)
281281
-$(INSTALL_M) $(build_libdir)/libjulia-debug.dll.a $(DESTDIR)$(libdir)/
282282
-$(INSTALL_M) $(build_libdir)/libjulia-internal-debug.dll.a $(DESTDIR)$(libdir)/
283283
endif
284+
-$(INSTALL_M) $(wildcard $(build_private_libdir)/*.a) $(DESTDIR)$(private_libdir)/
284285

285-
# We have a single exception; we want 7z.dll to live in private_libexecdir, not bindir, so that 7z.exe can find it.
286+
# We have a single exception; we want 7z.dll to live in private_libexecdir,
287+
# not bindir, so that 7z.exe can find it.
286288
-mv $(DESTDIR)$(bindir)/7z.dll $(DESTDIR)$(private_libexecdir)/
287289
-$(INSTALL_M) $(build_bindir)/libopenlibm.dll.a $(DESTDIR)$(libdir)/
288290
-$(INSTALL_M) $(build_libdir)/libssp.dll.a $(DESTDIR)$(libdir)/
289-
# The rest are compiler dependencies, as an example memcpy is exported by msvcrt
290-
# These are files from mingw32 and required for creating shared libraries like our caches.
291-
-$(INSTALL_M) $(build_libdir)/libgcc_s.a $(DESTDIR)$(libdir)/
292-
-$(INSTALL_M) $(build_libdir)/libgcc.a $(DESTDIR)$(libdir)/
293-
-$(INSTALL_M) $(build_libdir)/libmsvcrt.a $(DESTDIR)$(libdir)/
294291
else
295292

296293
# Copy over .dSYM directories directly for Darwin

base/compiler/abstractinterpretation.jl

+37-33
Original file line numberDiff line numberDiff line change
@@ -785,11 +785,7 @@ end
785785
function abstract_call_method_with_const_args(interp::AbstractInterpreter,
786786
result::MethodCallResult, @nospecialize(f), arginfo::ArgInfo, si::StmtInfo,
787787
match::MethodMatch, sv::AbsIntState, invokecall::Union{Nothing,InvokeCall}=nothing)
788-
if !const_prop_enabled(interp, sv, match)
789-
return nothing
790-
end
791-
if bail_out_const_call(interp, result, si)
792-
add_remark!(interp, sv, "[constprop] No more information to be gained")
788+
if !const_prop_enabled(interp, match, sv) || bail_out_const_call(interp, result, si, sv)
793789
return nothing
794790
end
795791
eligibility = concrete_eval_eligible(interp, f, result, arginfo, sv)
@@ -822,7 +818,7 @@ function abstract_call_method_with_const_args(interp::AbstractInterpreter,
822818
return const_prop_call(interp, mi, result, arginfo, sv, concrete_eval_result)
823819
end
824820

825-
function const_prop_enabled(interp::AbstractInterpreter, sv::AbsIntState, match::MethodMatch)
821+
function const_prop_enabled(interp::AbstractInterpreter, match::MethodMatch, sv::AbsIntState)
826822
if !InferenceParams(interp).ipo_constant_propagation
827823
add_remark!(interp, sv, "[constprop] Disabled by parameter")
828824
return false
@@ -834,9 +830,11 @@ function const_prop_enabled(interp::AbstractInterpreter, sv::AbsIntState, match:
834830
return true
835831
end
836832

837-
function bail_out_const_call(interp::AbstractInterpreter, result::MethodCallResult, si::StmtInfo)
833+
function bail_out_const_call(interp::AbstractInterpreter, result::MethodCallResult,
834+
si::StmtInfo, sv::AbsIntState)
838835
if is_removable_if_unused(result.effects)
839836
if isa(result.rt, Const) || call_result_unused(si)
837+
add_remark!(interp, sv, "[constprop] No more information to be gained (const)")
840838
return true
841839
end
842840
end
@@ -937,7 +935,10 @@ function maybe_get_const_prop_profitable(interp::AbstractInterpreter,
937935
match::MethodMatch, sv::AbsIntState)
938936
method = match.method
939937
force = force_const_prop(interp, f, method)
940-
force || const_prop_entry_heuristic(interp, result, si, sv) || return nothing
938+
if !const_prop_entry_heuristic(interp, result, si, sv, force)
939+
# N.B. remarks are emitted within `const_prop_entry_heuristic`
940+
return nothing
941+
end
941942
nargs::Int = method.nargs
942943
method.isva && (nargs -= 1)
943944
length(arginfo.argtypes) < nargs && return nothing
@@ -964,8 +965,17 @@ function maybe_get_const_prop_profitable(interp::AbstractInterpreter,
964965
return mi
965966
end
966967

967-
function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodCallResult, si::StmtInfo, sv::AbsIntState)
968-
if call_result_unused(si) && result.edgecycle
968+
function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodCallResult,
969+
si::StmtInfo, sv::AbsIntState, force::Bool)
970+
if result.rt isa LimitedAccuracy
971+
# optimizations like inlining are disabled for limited frames,
972+
# thus there won't be much benefit in constant-prop' here
973+
# N.B. don't allow forced constprop' for safety (xref #52763)
974+
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (limited accuracy)")
975+
return false
976+
elseif force
977+
return true
978+
elseif call_result_unused(si) && result.edgecycle
969979
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (edgecycle with unused result)")
970980
return false
971981
end
@@ -978,27 +988,21 @@ function const_prop_entry_heuristic(interp::AbstractInterpreter, result::MethodC
978988
if rt === Bottom
979989
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (erroneous result)")
980990
return false
981-
else
982-
return true
983991
end
992+
return true
984993
elseif isa(rt, PartialStruct) || isa(rt, InterConditional) || isa(rt, InterMustAlias)
985994
# could be improved to `Const` or a more precise wrapper
986995
return true
987-
elseif isa(rt, LimitedAccuracy)
988-
# optimizations like inlining are disabled for limited frames,
989-
# thus there won't be much benefit in constant-prop' here
990-
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (limited accuracy)")
991-
return false
992-
else
993-
if isa(rt, Const)
994-
if !is_nothrow(result.effects)
995-
# Could still be improved to Bottom (or at least could see the effects improved)
996-
return true
997-
end
996+
elseif isa(rt, Const)
997+
if is_nothrow(result.effects)
998+
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (nothrow const)")
999+
return false
9981000
end
999-
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (unimprovable result)")
1000-
return false
1001+
# Could still be improved to Bottom (or at least could see the effects improved)
1002+
return true
10011003
end
1004+
add_remark!(interp, sv, "[constprop] Disabled by entry heuristic (unimprovable result)")
1005+
return false
10021006
end
10031007

10041008
# determines heuristically whether if constant propagation can be worthwhile
@@ -2021,10 +2025,10 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
20212025
elseif isa(f, Core.OpaqueClosure)
20222026
# calling an OpaqueClosure about which we have no information returns no information
20232027
return CallMeta(typeof(f).parameters[2], Effects(), NoCallInfo())
2024-
elseif f === TypeVar
2028+
elseif f === TypeVar && !isvarargtype(argtypes[end])
20252029
# Manually look through the definition of TypeVar to
20262030
# make sure to be able to get `PartialTypeVar`s out.
2027-
(la < 2 || la > 4) && return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
2031+
2 la 4 || return CallMeta(Bottom, EFFECTS_THROWS, NoCallInfo())
20282032
n = argtypes[2]
20292033
ub_var = Const(Any)
20302034
lb_var = Const(Union{})
@@ -2267,11 +2271,7 @@ function abstract_eval_value_expr(interp::AbstractInterpreter, e::Expr, vtypes::
22672271
end
22682272

22692273
function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize(e), vtypes::Union{VarTable,Nothing}, sv::AbsIntState)
2270-
if isa(e, QuoteNode)
2271-
merge_effects!(interp, sv, Effects(EFFECTS_TOTAL;
2272-
inaccessiblememonly = is_mutation_free_argtype(typeof(e.value)) ? ALWAYS_TRUE : ALWAYS_FALSE))
2273-
return Const(e.value)
2274-
elseif isa(e, SSAValue)
2274+
if isa(e, SSAValue)
22752275
return abstract_eval_ssavalue(e, sv)
22762276
elseif isa(e, SlotNumber)
22772277
if vtypes !== nothing
@@ -2293,7 +2293,11 @@ function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize(
22932293
elseif isa(e, GlobalRef)
22942294
return abstract_eval_globalref(interp, e, sv)
22952295
end
2296-
2296+
if isa(e, QuoteNode)
2297+
e = e.value
2298+
end
2299+
merge_effects!(interp, sv, Effects(EFFECTS_TOTAL;
2300+
inaccessiblememonly = is_mutation_free_argtype(typeof(e)) ? ALWAYS_TRUE : ALWAYS_FALSE))
22972301
return Const(e)
22982302
end
22992303

base/compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1615,7 +1615,7 @@ function escape_builtin!(::typeof(arrayref), astate::AnalysisState, pc::Int, arg
16151615
argtypes = Any[argextype(args[i], astate.ir) for i in 2:length(args)]
16161616
boundcheckt = argtypes[1]
16171617
aryt = argtypes[2]
1618-
if !array_builtin_common_typecheck(boundcheckt, aryt, argtypes, 3)
1618+
if !array_builtin_common_typecheck(𝕃ₒ, boundcheckt, aryt, argtypes, 3)
16191619
add_thrown_escapes!(astate, pc, args, 2)
16201620
end
16211621
ary = args[3]
@@ -1679,7 +1679,7 @@ function escape_builtin!(::typeof(arrayset), astate::AnalysisState, pc::Int, arg
16791679
boundcheckt = argtypes[1]
16801680
aryt = argtypes[2]
16811681
valt = argtypes[3]
1682-
if !(array_builtin_common_typecheck(boundcheckt, aryt, argtypes, 4) &&
1682+
if !(array_builtin_common_typecheck(𝕃ₒ, boundcheckt, aryt, argtypes, 4) &&
16831683
arrayset_typecheck(aryt, valt))
16841684
add_thrown_escapes!(astate, pc, args, 2)
16851685
end

base/compiler/ssair/inlining.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ function compileable_specialization(mi::MethodInstance, effects::Effects,
837837
end
838838
end
839839
add_inlining_backedge!(et, mi) # to the dispatch lookup
840-
push!(et.edges, method.sig, mi_invoke) # add_inlining_backedge to the invoke call
840+
mi_invoke !== mi && push!(et.edges, method.sig, mi_invoke) # add_inlining_backedge to the invoke call, if that is different
841841
return InvokeCase(mi_invoke, effects, info)
842842
end
843843

@@ -1408,7 +1408,7 @@ function compute_inlining_cases(@nospecialize(info::CallInfo), flag::UInt8, sig:
14081408
fully_covered &= split_fully_covered
14091409
end
14101410

1411-
fully_covered || (joint_effects = Effects(joint_effects; nothrow=false))
1411+
(handled_all_cases & fully_covered) || (joint_effects = Effects(joint_effects; nothrow=false))
14121412

14131413
if handled_all_cases && revisit_idx !== nothing
14141414
# we handled everything except one match with unmatched sparams,

base/compiler/tfuncs.jl

+17-10
Original file line numberDiff line numberDiff line change
@@ -95,25 +95,31 @@ add_tfunc(throw, 1, 1, @nospecs((𝕃::AbstractLattice, x)->Bottom), 0)
9595
# if isexact is false, the actual runtime type may (will) be a subtype of t
9696
# if isconcrete is true, the actual runtime type is definitely concrete (unreachable if not valid as a typeof)
9797
# if istype is true, the actual runtime value will definitely be a type (e.g. this is false for Union{Type{Int}, Int})
98-
function instanceof_tfunc(@nospecialize(t))
98+
function instanceof_tfunc(@nospecialize(t), @nospecialize(troot) = t)
9999
if isa(t, Const)
100100
if isa(t.val, Type) && valid_as_lattice(t.val)
101101
return t.val, true, isconcretetype(t.val), true
102102
end
103103
return Bottom, true, false, false # runtime throws on non-Type
104104
end
105105
t = widenconst(t)
106+
troot = widenconst(troot)
106107
if t === Bottom
107108
return Bottom, true, true, false # runtime unreachable
108109
elseif t === typeof(Bottom) || !hasintersect(t, Type)
109110
return Bottom, true, false, false # literal Bottom or non-Type
110111
elseif isType(t)
111112
tp = t.parameters[1]
112113
valid_as_lattice(tp) || return Bottom, true, false, false # runtime unreachable / throws on non-Type
114+
if troot isa UnionAll
115+
# Free `TypeVar`s inside `Type` has violated the "diagonal" rule.
116+
# Widen them before `UnionAll` rewraping to relax concrete constraint.
117+
tp = widen_diagonal(tp, troot)
118+
end
113119
return tp, !has_free_typevars(tp), isconcretetype(tp), true
114120
elseif isa(t, UnionAll)
115121
t′ = unwrap_unionall(t)
116-
t′′, isexact, isconcrete, istype = instanceof_tfunc(t′)
122+
t′′, isexact, isconcrete, istype = instanceof_tfunc(t′, rewrap_unionall(t, troot))
117123
tr = rewrap_unionall(t′′, t)
118124
if t′′ isa DataType && t′′.name !== Tuple.name && !has_free_typevars(tr)
119125
# a real instance must be within the declared bounds of the type,
@@ -128,8 +134,8 @@ function instanceof_tfunc(@nospecialize(t))
128134
end
129135
return tr, isexact, isconcrete, istype
130136
elseif isa(t, Union)
131-
ta, isexact_a, isconcrete_a, istype_a = instanceof_tfunc(t.a)
132-
tb, isexact_b, isconcrete_b, istype_b = instanceof_tfunc(t.b)
137+
ta, isexact_a, isconcrete_a, istype_a = instanceof_tfunc(t.a, troot)
138+
tb, isexact_b, isconcrete_b, istype_b = instanceof_tfunc(t.b, troot)
133139
isconcrete = isconcrete_a && isconcrete_b
134140
istype = istype_a && istype_b
135141
# most users already handle the Union case, so here we assume that
@@ -2034,12 +2040,12 @@ function array_type_undefable(@nospecialize(arytype))
20342040
end
20352041
end
20362042

2037-
function array_builtin_common_nothrow(argtypes::Vector{Any}, isarrayref::Bool)
2043+
function array_builtin_common_nothrow(𝕃::AbstractLattice, argtypes::Vector{Any}, isarrayref::Bool)
20382044
first_idx_idx = isarrayref ? 3 : 4
20392045
length(argtypes) first_idx_idx || return false
20402046
boundscheck = argtypes[1]
20412047
arytype = argtypes[2]
2042-
array_builtin_common_typecheck(boundscheck, arytype, argtypes, first_idx_idx) || return false
2048+
array_builtin_common_typecheck(𝕃, boundscheck, arytype, argtypes, first_idx_idx) || return false
20432049
if isarrayref
20442050
# If we could potentially throw undef ref errors, bail out now.
20452051
arytype = widenconst(arytype)
@@ -2056,8 +2062,9 @@ function array_builtin_common_nothrow(argtypes::Vector{Any}, isarrayref::Bool)
20562062
return false
20572063
end
20582064

2059-
@nospecs function array_builtin_common_typecheck(boundscheck, arytype,
2060-
argtypes::Vector{Any}, first_idx_idx::Int)
2065+
@nospecs function array_builtin_common_typecheck(𝕃::AbstractLattice,
2066+
boundscheck, arytype, argtypes::Vector{Any}, first_idx_idx::Int)
2067+
= Core.Compiler.:(𝕃)
20612068
(boundscheck Bool && arytype Array) || return false
20622069
for i = first_idx_idx:length(argtypes)
20632070
argtypes[i] Int || return false
@@ -2080,11 +2087,11 @@ end
20802087
@nospecs function _builtin_nothrow(𝕃::AbstractLattice, f, argtypes::Vector{Any}, rt)
20812088
= Core.Compiler.:(𝕃)
20822089
if f === arrayset
2083-
array_builtin_common_nothrow(argtypes, #=isarrayref=#false) || return false
2090+
array_builtin_common_nothrow(𝕃, argtypes, #=isarrayref=#false) || return false
20842091
# Additionally check element type compatibility
20852092
return arrayset_typecheck(argtypes[2], argtypes[3])
20862093
elseif f === arrayref || f === const_arrayref
2087-
return array_builtin_common_nothrow(argtypes, #=isarrayref=#true)
2094+
return array_builtin_common_nothrow(𝕃, argtypes, #=isarrayref=#true)
20882095
elseif f === Core._expr
20892096
length(argtypes) >= 1 || return false
20902097
return argtypes[1] Symbol

base/env.jl

+7-6
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@
33
if Sys.iswindows()
44
const ERROR_ENVVAR_NOT_FOUND = UInt32(203)
55

6-
const env_dict = IdDict{String, Vector{Cwchar_t}}()
6+
const env_dict = Dict{String, Vector{Cwchar_t}}()
77
const env_lock = ReentrantLock()
88

99
function memoized_env_lookup(str::AbstractString)
1010
# Windows environment variables have a different format from Linux / MacOS, and previously
1111
# incurred allocations because we had to convert a String to a Vector{Cwchar_t} each time
1212
# an environment variable was looked up. This function memoizes that lookup process, storing
1313
# the String => Vector{Cwchar_t} pairs in env_dict
14-
var = get(env_dict, str, nothing)
15-
if isnothing(var)
16-
var = @lock env_lock begin
17-
env_dict[str] = cwstring(str)
14+
@lock env_lock begin
15+
var = get(env_dict, str, nothing)
16+
if isnothing(var)
17+
var = cwstring(str)
18+
env_dict[str] = var
1819
end
20+
return var
1921
end
20-
var
2122
end
2223

2324
_getenvlen(var::Vector{UInt16}) = ccall(:GetEnvironmentVariableW,stdcall,UInt32,(Ptr{UInt16},Ptr{UInt16},UInt32),var,C_NULL,0)

base/essentials.jl

+5
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,11 @@ function rename_unionall(@nospecialize(u))
411411
return UnionAll(nv, body{nv})
412412
end
413413

414+
# remove concrete constraint on diagonal TypeVar if it comes from troot
415+
function widen_diagonal(@nospecialize(t), troot::UnionAll)
416+
body = ccall(:jl_widen_diagonal, Any, (Any, Any), t, troot)
417+
end
418+
414419
function isvarargtype(@nospecialize(t))
415420
return isa(t, Core.TypeofVararg)
416421
end

base/float.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,10 @@ for Ti in (Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UIn
882882
end
883883
end
884884
function (::Type{$Ti})(x::$Tf)
885-
if ($(Tf(typemin(Ti))) <= x <= $(Tf(typemax(Ti)))) && isinteger(x)
885+
# When typemax(Ti) is not representable by Tf but typemax(Ti) + 1 is,
886+
# then < Tf(typemax(Ti) + 1) is stricter than <= Tf(typemax(Ti)). Using
887+
# the former causes us to throw on UInt64(Float64(typemax(UInt64))+1)
888+
if ($(Tf(typemin(Ti))) <= x < $(Tf(typemax(Ti))+one(Tf))) && isinteger(x)
886889
return unsafe_trunc($Ti,x)
887890
else
888891
throw(InexactError($(Expr(:quote,Ti.name.name)), $Ti, x))

0 commit comments

Comments
 (0)