Skip to content

Commit 94603a7

Browse files
authored
Merge pull request #48733 from JuliaLang/backports-release-1.9
Backports for 1.9.0-rc1
2 parents 3850e88 + 9ced070 commit 94603a7

File tree

86 files changed

+2007
-1315
lines changed

Some content is hidden

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

86 files changed

+2007
-1315
lines changed

Make.inc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,10 @@ SANITIZE_LDFLAGS :=
691691
ifeq ($(SANITIZE_MEMORY),1)
692692
SANITIZE_OPTS += -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer
693693
SANITIZE_LDFLAGS += $(SANITIZE_OPTS)
694-
endif
694+
ifneq ($(findstring $(OS),Linux FreeBSD),)
695+
SANITIZE_LDFLAGS += -Wl,--warn-unresolved-symbols
696+
endif # OS Linux or FreeBSD
697+
endif # SANITIZE_MEMORY=1
695698
ifeq ($(SANITIZE_ADDRESS),1)
696699
SANITIZE_OPTS += -fsanitize=address
697700
SANITIZE_LDFLAGS += -fsanitize=address
@@ -848,7 +851,6 @@ endif
848851
# If we are running on powerpc64le or ppc64le, set certain options automatically
849852
ifneq (,$(filter $(ARCH), powerpc64le ppc64le))
850853
JCFLAGS += -fsigned-char
851-
OPENBLAS_DYNAMIC_ARCH:=0
852854
OPENBLAS_TARGET_ARCH:=POWER8
853855
BINARY:=64
854856
# GCC doesn't do -march= on ppc64le
@@ -1036,6 +1038,10 @@ PATCHELF := patchelf
10361038
else
10371039
PATCHELF := $(build_depsbindir)/patchelf
10381040
endif
1041+
# In the standard build system we want to patch files with `--set-rpath`, but downstream
1042+
# packagers like Spack may want to use `--add-rpath` instead, leave them the possibility to
1043+
# choose the command.
1044+
PATCHELF_SET_RPATH_ARG := --set-rpath
10391045

10401046
ifeq ($(USE_SYSTEM_LIBWHICH), 1)
10411047
LIBWHICH := libwhich

Makefile

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ endif
317317
# Install `lld` into libexec/
318318
$(INSTALL_M) $(build_depsbindir)/lld$(EXE) $(DESTDIR)$(libexecdir)/
319319

320+
# Install `dsymutil` into libexec/
321+
$(INSTALL_M) $(build_depsbindir)/dsymutil$(EXE) $(DESTDIR)$(libexecdir)/
322+
320323
# Copy public headers
321324
cp -R -L $(build_includedir)/julia/* $(DESTDIR)$(includedir)/julia
322325
# Copy system image
@@ -365,7 +368,7 @@ ifneq ($(DARWIN_FRAMEWORK),1)
365368
endif
366369
else ifneq (,$(findstring $(OS),Linux FreeBSD))
367370
for j in $(JL_TARGETS) ; do \
368-
$(PATCHELF) --set-rpath '$$ORIGIN/$(private_libdir_rel):$$ORIGIN/$(libdir_rel)' $(DESTDIR)$(bindir)/$$j; \
371+
$(PATCHELF) $(PATCHELF_SET_RPATH_ARG) '$$ORIGIN/$(private_libdir_rel):$$ORIGIN/$(libdir_rel)' $(DESTDIR)$(bindir)/$$j; \
369372
done
370373
endif
371374

@@ -397,17 +400,17 @@ endif
397400
endif
398401
else ifneq (,$(findstring $(OS),Linux FreeBSD))
399402
ifeq ($(JULIA_BUILD_MODE),release)
400-
$(PATCHELF) --set-rpath '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-internal.$(SHLIB_EXT)
401-
$(PATCHELF) --set-rpath '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-codegen.$(SHLIB_EXT)
403+
$(PATCHELF) $(PATCHELF_SET_RPATH_ARG) '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-internal.$(SHLIB_EXT)
404+
$(PATCHELF) $(PATCHELF_SET_RPATH_ARG) '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-codegen.$(SHLIB_EXT)
402405
else ifeq ($(JULIA_BUILD_MODE),debug)
403-
$(PATCHELF) --set-rpath '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-internal-debug.$(SHLIB_EXT)
404-
$(PATCHELF) --set-rpath '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-codegen-debug.$(SHLIB_EXT)
406+
$(PATCHELF) $(PATCHELF_SET_RPATH_ARG) '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-internal-debug.$(SHLIB_EXT)
407+
$(PATCHELF) $(PATCHELF_SET_RPATH_ARG) '$$ORIGIN:$$ORIGIN/$(reverse_private_libdir_rel)' $(DESTDIR)$(private_libdir)/libjulia-codegen-debug.$(SHLIB_EXT)
405408
endif
406409
endif
407410

408411
# Fix rpaths for dependencies. This should be fixed in BinaryBuilder later.
409412
ifeq ($(OS), Linux)
410-
-$(PATCHELF) --set-rpath '$$ORIGIN' $(DESTDIR)$(private_shlibdir)/libLLVM.$(SHLIB_EXT)
413+
-$(PATCHELF) $(PATCHELF_SET_RPATH_ARG) '$$ORIGIN' $(DESTDIR)$(private_shlibdir)/libLLVM.$(SHLIB_EXT)
411414
endif
412415

413416
ifneq ($(LOADER_BUILD_DEP_LIBS),$(LOADER_INSTALL_DEP_LIBS))
@@ -437,7 +440,7 @@ ifeq ($(OS),FreeBSD)
437440
# don't set libgfortran's RPATH, it won't be able to find its friends on systems
438441
# that don't have the exact GCC port installed used for the build.
439442
for lib in $(DESTDIR)$(private_libdir)/libgfortran*$(SHLIB_EXT)*; do \
440-
$(PATCHELF) --set-rpath '$$ORIGIN' $$lib; \
443+
$(PATCHELF) $(PATCHELF_SET_RPATH_ARG) '$$ORIGIN' $$lib; \
441444
done
442445
endif
443446

base/compiler/abstractinterpretation.jl

Lines changed: 183 additions & 84 deletions
Large diffs are not rendered by default.

base/compiler/inferencestate.jl

Lines changed: 117 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,23 @@ is_effect_overridden(override::EffectsOverride, effect::Symbol) = getfield(overr
221221

222222
add_remark!(::AbstractInterpreter, sv::Union{InferenceState, IRCode}, remark) = return
223223

224-
function bail_out_toplevel_call(::AbstractInterpreter, @nospecialize(callsig), sv::Union{InferenceState, IRCode})
225-
return isa(sv, InferenceState) && sv.restrict_abstract_call_sites && !isdispatchtuple(callsig)
224+
struct InferenceLoopState
225+
sig
226+
rt
227+
effects::Effects
228+
function InferenceLoopState(@nospecialize(sig), @nospecialize(rt), effects::Effects)
229+
new(sig, rt, effects)
230+
end
231+
end
232+
233+
function bail_out_toplevel_call(::AbstractInterpreter, state::InferenceLoopState, sv::Union{InferenceState, IRCode})
234+
return isa(sv, InferenceState) && sv.restrict_abstract_call_sites && !isdispatchtuple(state.sig)
226235
end
227-
function bail_out_call(::AbstractInterpreter, @nospecialize(rt), sv::Union{InferenceState, IRCode})
228-
return rt === Any
236+
function bail_out_call(::AbstractInterpreter, state::InferenceLoopState, sv::Union{InferenceState, IRCode})
237+
return state.rt === Any
229238
end
230-
function bail_out_apply(::AbstractInterpreter, @nospecialize(rt), sv::Union{InferenceState, IRCode})
231-
return rt === Any
239+
function bail_out_apply(::AbstractInterpreter, state::InferenceLoopState, sv::Union{InferenceState, IRCode})
240+
return state.rt === Any
232241
end
233242

234243
was_reached(sv::InferenceState, pc::Int) = sv.ssavaluetypes[pc] !== NOT_FOUND
@@ -348,15 +357,100 @@ function InferenceState(result::InferenceResult, cache::Symbol, interp::Abstract
348357
return InferenceState(result, src, cache, interp)
349358
end
350359

360+
"""
361+
constrains_param(var::TypeVar, sig, covariant::Bool, type_constrains::Bool)
362+
363+
Check if `var` will be constrained to have a definite value
364+
in any concrete leaftype subtype of `sig`.
365+
366+
It is used as a helper to determine whether type intersection is guaranteed to be able to
367+
find a value for a particular type parameter.
368+
A necessary condition for type intersection to not assign a parameter is that it only
369+
appears in a `Union[All]` and during subtyping some other union component (that does not
370+
constrain the type parameter) is selected.
371+
372+
The `type_constrains` flag determines whether Type{T} is considered to be constraining
373+
`T`. This is not true in general, because of the existence of types with free type
374+
parameters, however, some callers would like to ignore this corner case.
375+
"""
376+
function constrains_param(var::TypeVar, @nospecialize(typ), covariant::Bool, type_constrains::Bool=false)
377+
typ === var && return true
378+
while typ isa UnionAll
379+
covariant && constrains_param(var, typ.var.ub, covariant, type_constrains) && return true
380+
# typ.var.lb doesn't constrain var
381+
typ = typ.body
382+
end
383+
if typ isa Union
384+
# for unions, verify that both options would constrain var
385+
ba = constrains_param(var, typ.a, covariant, type_constrains)
386+
bb = constrains_param(var, typ.b, covariant, type_constrains)
387+
(ba && bb) && return true
388+
elseif typ isa DataType
389+
# return true if any param constrains var
390+
fc = length(typ.parameters)
391+
if fc > 0
392+
if typ.name === Tuple.name
393+
# vararg tuple needs special handling
394+
for i in 1:(fc - 1)
395+
p = typ.parameters[i]
396+
constrains_param(var, p, covariant, type_constrains) && return true
397+
end
398+
lastp = typ.parameters[fc]
399+
vararg = unwrap_unionall(lastp)
400+
if vararg isa Core.TypeofVararg && isdefined(vararg, :N)
401+
constrains_param(var, vararg.N, covariant, type_constrains) && return true
402+
# T = vararg.parameters[1] doesn't constrain var
403+
else
404+
constrains_param(var, lastp, covariant, type_constrains) && return true
405+
end
406+
else
407+
if typ.name === typename(Type) && typ.parameters[1] === var && var.ub === Any
408+
# Types with free type parameters are <: Type cause the typevar
409+
# to be unconstrained because Type{T} with free typevars is illegal
410+
return type_constrains
411+
end
412+
for i in 1:fc
413+
p = typ.parameters[i]
414+
constrains_param(var, p, false, type_constrains) && return true
415+
end
416+
end
417+
end
418+
end
419+
return false
420+
end
421+
422+
"""
423+
MaybeUndefSP(typ)
424+
is_maybeundefsp(typ) -> Bool
425+
unwrap_maybeundefsp(typ) -> Any
426+
427+
A special wrapper that represents a static parameter that could be undefined at runtime.
428+
This does not participate in the native type system nor the inference lattice,
429+
and it thus should be always unwrapped when performing any type or lattice operations on it.
430+
"""
431+
struct MaybeUndefSP
432+
typ
433+
MaybeUndefSP(@nospecialize typ) = new(typ)
434+
end
435+
is_maybeundefsp(@nospecialize typ) = isa(typ, MaybeUndefSP)
436+
unwrap_maybeundefsp(@nospecialize typ) = isa(typ, MaybeUndefSP) ? typ.typ : typ
437+
is_maybeundefsp(sptypes::Vector{Any}, idx::Int) = is_maybeundefsp(sptypes[idx])
438+
unwrap_maybeundefsp(sptypes::Vector{Any}, idx::Int) = unwrap_maybeundefsp(sptypes[idx])
439+
440+
const EMPTY_SPTYPES = Any[]
441+
351442
function sptypes_from_meth_instance(linfo::MethodInstance)
352-
toplevel = !isa(linfo.def, Method)
353-
if !toplevel && isempty(linfo.sparam_vals) && isa(linfo.def.sig, UnionAll)
443+
def = linfo.def
444+
isa(def, Method) || return EMPTY_SPTYPES # toplevel
445+
sig = def.sig
446+
if isempty(linfo.sparam_vals)
447+
isa(sig, UnionAll) || return EMPTY_SPTYPES
354448
# linfo is unspecialized
355449
sp = Any[]
356-
sig = linfo.def.sig
357-
while isa(sig, UnionAll)
358-
push!(sp, sig.var)
359-
sig = sig.body
450+
sig = sig
451+
while isa(sig, UnionAll)
452+
push!(sp, sig.var)
453+
sig = sig.body
360454
end
361455
else
362456
sp = collect(Any, linfo.sparam_vals)
@@ -365,9 +459,7 @@ function sptypes_from_meth_instance(linfo::MethodInstance)
365459
v = sp[i]
366460
if v isa TypeVar
367461
fromArg = 0
368-
# if this parameter came from arg::Type{T}, then `arg` is more precise than
369-
# Type{T} where lb<:T<:ub
370-
sig = linfo.def.sig
462+
maybe_undef = !constrains_param(v, linfo.specTypes, #=covariant=#true)
371463
temp = sig
372464
for j = 1:i-1
373465
temp = temp.body
@@ -408,6 +500,8 @@ function sptypes_from_meth_instance(linfo::MethodInstance)
408500
ty = UnionAll(tv, Type{tv})
409501
end
410502
end
503+
@label ty_computed
504+
maybe_undef && (ty = MaybeUndefSP(ty))
411505
elseif isvarargtype(v)
412506
ty = Int
413507
else
@@ -429,14 +523,14 @@ end
429523

430524
update_valid_age!(edge::InferenceState, sv::InferenceState) = update_valid_age!(sv, edge.valid_worlds)
431525

432-
function record_ssa_assign!(ssa_id::Int, @nospecialize(new), frame::InferenceState)
526+
function record_ssa_assign!(𝕃ᵢ::AbstractLattice, ssa_id::Int, @nospecialize(new), frame::InferenceState)
433527
ssavaluetypes = frame.ssavaluetypes
434528
old = ssavaluetypes[ssa_id]
435-
if old === NOT_FOUND || !(new old)
529+
if old === NOT_FOUND || !(𝕃ᵢ, new, old)
436530
# typically, we expect that old ⊑ new (that output information only
437531
# gets less precise with worse input information), but to actually
438532
# guarantee convergence we need to use tmerge here to ensure that is true
439-
ssavaluetypes[ssa_id] = old === NOT_FOUND ? new : tmerge(old, new)
533+
ssavaluetypes[ssa_id] = old === NOT_FOUND ? new : tmerge(𝕃ᵢ, old, new)
440534
W = frame.ip
441535
for r in frame.ssavalue_uses[ssa_id]
442536
if was_reached(frame, r)
@@ -519,9 +613,11 @@ end
519613

520614
get_curr_ssaflag(sv::InferenceState) = sv.src.ssaflags[sv.currpc]
521615

522-
function narguments(sv::InferenceState)
616+
function narguments(sv::InferenceState, include_va::Bool=true)
523617
def = sv.linfo.def
524-
isva = isa(def, Method) && def.isva
525-
nargs = length(sv.result.argtypes) - isva
618+
nargs = length(sv.result.argtypes)
619+
if !include_va
620+
nargs -= isa(def, Method) && def.isva
621+
end
526622
return nargs
527623
end

base/compiler/optimize.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,9 @@ function stmt_effect_flags(lattice::AbstractLattice, @nospecialize(stmt), @nospe
235235
if isa(stmt, Expr)
236236
(; head, args) = stmt
237237
if head === :static_parameter
238-
etyp = (isa(src, IRCode) ? src.sptypes : src.ir.sptypes)[args[1]::Int]
239238
# if we aren't certain enough about the type, it might be an UndefVarError at runtime
240-
nothrow = isa(etyp, Const)
239+
sptypes = isa(src, IRCode) ? src.sptypes : src.ir.sptypes
240+
nothrow = !is_maybeundefsp(sptypes, args[1]::Int)
241241
return (true, nothrow, nothrow)
242242
end
243243
if head === :call
@@ -343,7 +343,7 @@ function argextype(
343343
sptypes::Vector{Any}, slottypes::Vector{Any})
344344
if isa(x, Expr)
345345
if x.head === :static_parameter
346-
return sptypes[x.args[1]::Int]
346+
return unwrap_maybeundefsp(sptypes, x.args[1]::Int)
347347
elseif x.head === :boundscheck
348348
return Bool
349349
elseif x.head === :copyast

base/compiler/ssair/irinterp.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,9 @@ function reprocess_instruction!(interp::AbstractInterpreter,
237237
# Handled at the very end
238238
return false
239239
elseif isa(inst, PiNode)
240-
rt = tmeet(typeinf_lattice(interp), argextype(inst.val, ir), inst.typ)
240+
rt = tmeet(typeinf_lattice(interp), argextype(inst.val, ir), widenconst(inst.typ))
241+
elseif inst === nothing
242+
return false
241243
else
242244
ccall(:jl_, Cvoid, (Any,), inst)
243245
error()

base/compiler/ssair/slot2ssa.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ end
215215
function typ_for_val(@nospecialize(x), ci::CodeInfo, sptypes::Vector{Any}, idx::Int, slottypes::Vector{Any})
216216
if isa(x, Expr)
217217
if x.head === :static_parameter
218-
return sptypes[x.args[1]::Int]
218+
return unwrap_maybeundefsp(sptypes, x.args[1]::Int)
219219
elseif x.head === :boundscheck
220220
return Bool
221221
elseif x.head === :copyast
@@ -337,7 +337,9 @@ function iterated_dominance_frontier(cfg::CFG, liveness::BlockLiveness, domtree:
337337
end
338338

339339
function rename_incoming_edge(old_edge::Int, old_to::Int, result_order::Vector{Int}, bb_rename::Vector{Int})
340+
old_edge == 0 && return 0
340341
new_edge_from = bb_rename[old_edge]
342+
new_edge_from < 0 && return new_edge_from
341343
if old_edge == old_to - 1
342344
# Could have been a crit edge break
343345
if new_edge_from < length(result_order) && result_order[new_edge_from + 1] == 0
@@ -363,7 +365,7 @@ function rename_phinode_edges(node::PhiNode, bb::Int, result_order::Vector{Int},
363365
new_edges = Int32[]
364366
for (idx, edge) in pairs(node.edges)
365367
edge = Int(edge)
366-
(edge == 0 || bb_rename[edge] != 0) || continue
368+
(edge == 0 || bb_rename[edge] != -1) || continue
367369
new_edge_from = edge == 0 ? 0 : rename_incoming_edge(edge, bb, result_order, bb_rename)
368370
push!(new_edges, new_edge_from)
369371
if isassigned(node.values, idx)
@@ -386,7 +388,7 @@ function domsort_ssa!(ir::IRCode, domtree::DomTree)
386388
# First compute the new order of basic blocks
387389
result_order = Int[]
388390
stack = Int[]
389-
bb_rename = zeros(Int, length(ir.cfg.blocks))
391+
bb_rename = fill(-1, length(ir.cfg.blocks))
390392
node = 1
391393
ncritbreaks = 0
392394
nnewfallthroughs = 0
@@ -497,7 +499,7 @@ function domsort_ssa!(ir::IRCode, domtree::DomTree)
497499
bb_start_off += length(inst_range)
498500
local new_preds, new_succs
499501
let bb = bb, bb_rename = bb_rename, result_order = result_order
500-
new_preds = Int[i == 0 ? 0 : rename_incoming_edge(i, bb, result_order, bb_rename) for i in ir.cfg.blocks[bb].preds]
502+
new_preds = Int[bb for bb in (rename_incoming_edge(i, bb, result_order, bb_rename) for i in ir.cfg.blocks[bb].preds) if bb != -1]
501503
new_succs = Int[ rename_outgoing_edge(i, bb, result_order, bb_rename) for i in ir.cfg.blocks[bb].succs]
502504
end
503505
new_bbs[new_bb] = BasicBlock(inst_range, new_preds, new_succs)

base/compiler/ssair/verify.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ function verify_ir(ir::IRCode, print::Bool=true, allow_frontend_forms::Bool=fals
267267
elseif stmt.head === :foreigncall
268268
isforeigncall = true
269269
elseif stmt.head === :isdefined && length(stmt.args) == 1 &&
270-
(stmt.args[1] isa GlobalRef || (stmt.args[1] isa Expr && stmt.args[1].head === :static_parameter))
270+
(stmt.args[1] isa GlobalRef || isexpr(stmt.args[1], :static_parameter))
271271
# a GlobalRef or static_parameter isdefined check does not evaluate its argument
272272
continue
273273
elseif stmt.head === :call

0 commit comments

Comments
 (0)