Skip to content

Commit 848b0b8

Browse files
authored
Merge branch 'master' into mime-docstring-update
2 parents 4031f1e + 71bfbb3 commit 848b0b8

File tree

189 files changed

+3887
-1648
lines changed

Some content is hidden

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

189 files changed

+3887
-1648
lines changed

Diff for: .devcontainer/Dockerfile

-3
This file was deleted.

Diff for: .devcontainer/devcontainer.json

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
{
2-
"extensions": [
3-
"julialang.language-julia",
4-
"ms-vscode.cpptools"
5-
],
6-
7-
"dockerFile": "Dockerfile"
2+
"image": "docker.io/library/julia:latest",
3+
"customizations": {
4+
"vscode": {
5+
"extensions": [
6+
"julialang.language-julia",
7+
"ms-vscode.cpptools"
8+
]
9+
}
10+
},
11+
"onCreateCommand": "apt-get update && apt-get install -y build-essential libatomic1 python3 gfortran perl wget m4 cmake pkg-config git"
812
}

Diff for: Compiler/src/Compiler.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ using Core: ABIOverride, Builtin, CodeInstance, IntrinsicFunction, MethodInstanc
4949

5050
using Base
5151
using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospecializeinfer,
52-
BINDING_KIND_GLOBAL, Base, BitVector, Bottom, Callable, DataTypeFieldDesc,
52+
BINDING_KIND_GLOBAL, BINDING_KIND_UNDEF_CONST, Base, BitVector, Bottom, Callable, DataTypeFieldDesc,
5353
EffectsOverride, Filter, Generator, IteratorSize, JLOptions, NUM_EFFECTS_OVERRIDES,
5454
OneTo, Ordering, RefValue, SizeUnknown, _NAMEDTUPLE_NAME,
5555
_array_for, _bits_findnext, _methods_by_ftype, _uniontypes, all, allocatedinline, any,
@@ -58,7 +58,7 @@ using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospeciali
5858
datatype_pointerfree, decode_effects_override, diff_names, fieldindex,
5959
generating_output, get_nospecializeinfer_sig, get_world_counter, has_free_typevars,
6060
hasgenerator, hasintersect, indexed_iterate, isType, is_file_tracked, is_function_def,
61-
is_meta_expr, is_meta_expr_head, is_nospecialized, is_nospecializeinfer,
61+
is_meta_expr, is_meta_expr_head, is_nospecialized, is_nospecializeinfer, is_defined_const_binding,
6262
is_some_const_binding, is_some_guard, is_some_imported, is_valid_intrinsic_elptr,
6363
isbitsunion, isconcretedispatch, isdispatchelem, isexpr, isfieldatomic, isidentityfree,
6464
iskindtype, ismutabletypename, ismutationfree, issingletontype, isvarargtype, isvatuple,

Diff for: Compiler/src/abstractinterpretation.jl

+101-58
Original file line numberDiff line numberDiff line change
@@ -2395,7 +2395,8 @@ function abstract_eval_getglobal(interp::AbstractInterpreter, sv::AbsIntState, s
23952395
if M isa Const && s isa Const
23962396
M, s = M.val, s.val
23972397
if M isa Module && s isa Symbol
2398-
return CallMeta(abstract_eval_globalref(interp, GlobalRef(M, s), saw_latestworld, sv), NoCallInfo())
2398+
(ret, bpart) = abstract_eval_globalref(interp, GlobalRef(M, s), saw_latestworld, sv)
2399+
return CallMeta(ret, bpart === nothing ? NoCallInfo() : GlobalAccessInfo(bpart))
23992400
end
24002401
return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo())
24012402
elseif !hasintersect(widenconst(M), Module) || !hasintersect(widenconst(s), Symbol)
@@ -2473,8 +2474,8 @@ function abstract_eval_setglobal!(interp::AbstractInterpreter, sv::AbsIntState,
24732474
if isa(M, Const) && isa(s, Const)
24742475
M, s = M.val, s.val
24752476
if M isa Module && s isa Symbol
2476-
rt, exct = global_assignment_rt_exct(interp, sv, saw_latestworld, GlobalRef(M, s), v)
2477-
return CallMeta(rt, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), NoCallInfo())
2477+
(rt, exct), partition = global_assignment_rt_exct(interp, sv, saw_latestworld, GlobalRef(M, s), v)
2478+
return CallMeta(rt, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), GlobalAccessInfo(partition))
24782479
end
24792480
return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo())
24802481
end
@@ -2512,15 +2513,15 @@ function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState,
25122513
scm = abstract_eval_setglobal!(interp, sv, saw_latestworld, M, s, v)
25132514
scm.rt === Bottom && return scm
25142515
gcm = abstract_eval_getglobal(interp, sv, saw_latestworld, M, s)
2515-
return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), NoCallInfo())
2516+
return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), scm.info)
25162517
end
25172518

25182519
function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool,
25192520
@nospecialize(M), @nospecialize(s), @nospecialize(v), @nospecialize(order))
25202521
scm = abstract_eval_setglobal!(interp, sv, saw_latestworld, M, s, v, order)
25212522
scm.rt === Bottom && return scm
25222523
gcm = abstract_eval_getglobal(interp, sv, saw_latestworld, M, s, order)
2523-
return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), NoCallInfo())
2524+
return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), scm.info)
25242525
end
25252526

25262527
function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, argtypes::Vector{Any})
@@ -2569,7 +2570,7 @@ function abstract_eval_replaceglobal!(interp::AbstractInterpreter, sv::AbsIntSta
25692570
end
25702571
exct = Union{rte.exct, global_assignment_binding_rt_exct(interp, partition, v)[2]}
25712572
effects = merge_effects(rte.effects, Effects(setglobal!_effects, nothrow=exct===Bottom))
2572-
sg = CallMeta(Any, exct, effects, NoCallInfo())
2573+
sg = CallMeta(Any, exct, effects, GlobalAccessInfo(partition))
25732574
else
25742575
sg = abstract_eval_setglobal!(interp, sv, saw_latestworld, M, s, v)
25752576
end
@@ -2637,21 +2638,14 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
26372638
elseif f === Core.getfield && argtypes_are_actually_getglobal(argtypes)
26382639
return Future(abstract_eval_getglobal(interp, sv, si.saw_latestworld, argtypes))
26392640
elseif f === Core.isdefined && argtypes_are_actually_getglobal(argtypes)
2640-
exct = Bottom
2641-
if length(argtypes) == 4
2642-
order = argtypes[4]
2643-
exct = global_order_exct(order, #=loading=#true, #=storing=#false)
2644-
if !(isa(order, Const) && get_atomic_order(order.val, #=loading=#true, #=storing=#false).x >= MEMORY_ORDER_UNORDERED.x)
2645-
exct = Union{exct, ConcurrencyViolationError}
2646-
end
2647-
end
2648-
return Future(merge_exct(CallMeta(abstract_eval_isdefined(
2649-
interp,
2650-
GlobalRef((argtypes[2]::Const).val::Module,
2651-
(argtypes[3]::Const).val::Symbol),
2652-
si.saw_latestworld,
2653-
sv),
2654-
NoCallInfo()), exct))
2641+
return Future(abstract_eval_isdefinedglobal(interp, argtypes[2], argtypes[3], Const(true),
2642+
length(argtypes) == 4 ? argtypes[4] : Const(:unordered),
2643+
si.saw_latestworld, sv))
2644+
elseif f === Core.isdefinedglobal && 3 <= length(argtypes) <= 5
2645+
return Future(abstract_eval_isdefinedglobal(interp, argtypes[2], argtypes[3],
2646+
length(argtypes) >= 4 ? argtypes[4] : Const(true),
2647+
length(argtypes) >= 5 ? argtypes[5] : Const(:unordered),
2648+
si.saw_latestworld, sv))
26552649
elseif f === Core.get_binding_type
26562650
return Future(abstract_eval_get_binding_type(interp, sv, argtypes))
26572651
end
@@ -2944,7 +2938,8 @@ function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize(
29442938
return RTEffects(sv.ir.argtypes[e.n], Union{}, EFFECTS_TOTAL) # TODO frame_argtypes(sv)[e.n] and remove the assertion
29452939
end
29462940
elseif isa(e, GlobalRef)
2947-
return abstract_eval_globalref(interp, e, sstate.saw_latestworld, sv)
2941+
# No need for an edge since an explicit GlobalRef will be picked up by the source scan
2942+
return abstract_eval_globalref(interp, e, sstate.saw_latestworld, sv)[1]
29482943
end
29492944
if isa(e, QuoteNode)
29502945
e = e.value
@@ -3200,24 +3195,10 @@ function abstract_eval_isdefined_expr(interp::AbstractInterpreter, e::Expr, ssta
32003195
end
32013196
return RTEffects(rt, Union{}, EFFECTS_TOTAL)
32023197
end
3203-
return abstract_eval_isdefined(interp, sym, sstate.saw_latestworld, sv)
3204-
end
3205-
3206-
function abstract_eval_isdefined(interp::AbstractInterpreter, @nospecialize(sym), saw_latestworld::Bool, sv::AbsIntState)
32073198
rt = Bool
32083199
effects = EFFECTS_TOTAL
32093200
exct = Union{}
3210-
isa(sym, Symbol) && (sym = GlobalRef(frame_module(sv), sym))
3211-
if isa(sym, GlobalRef)
3212-
rte = abstract_eval_globalref(interp, sym, saw_latestworld, sv)
3213-
if rte.exct == Union{}
3214-
rt = Const(true)
3215-
elseif rte.rt === Union{} && rte.exct === UndefVarError
3216-
rt = Const(false)
3217-
else
3218-
effects = Effects(EFFECTS_TOTAL; consistent=ALWAYS_FALSE)
3219-
end
3220-
elseif isexpr(sym, :static_parameter)
3201+
if isexpr(sym, :static_parameter)
32213202
n = sym.args[1]::Int
32223203
if 1 <= n <= length(sv.sptypes)
32233204
sp = sv.sptypes[n]
@@ -3229,10 +3210,73 @@ function abstract_eval_isdefined(interp::AbstractInterpreter, @nospecialize(sym)
32293210
end
32303211
else
32313212
effects = EFFECTS_UNKNOWN
3213+
exct = Any
32323214
end
32333215
return RTEffects(rt, exct, effects)
32343216
end
32353217

3218+
const generic_isdefinedglobal_effects = Effects(EFFECTS_TOTAL, consistent=ALWAYS_FALSE, nothrow=false)
3219+
function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, mod::Module, sym::Symbol, allow_import::Union{Bool, Nothing}, saw_latestworld::Bool, sv::AbsIntState)
3220+
rt = Bool
3221+
if saw_latestworld
3222+
return CallMeta(RTEffects(rt, Union{}, Effects(generic_isdefinedglobal_effects, nothrow=true)), NoCallInfo())
3223+
end
3224+
3225+
effects = EFFECTS_TOTAL
3226+
partition = lookup_binding_partition!(interp, GlobalRef(mod, sym), sv)
3227+
if allow_import !== true && is_some_imported(binding_kind(partition))
3228+
if allow_import === false
3229+
rt = Const(false)
3230+
else
3231+
effects = Effects(generic_isdefinedglobal_effects, nothrow=true)
3232+
end
3233+
else
3234+
partition = walk_binding_partition!(interp, partition, sv)
3235+
rte = abstract_eval_partition_load(interp, partition)
3236+
if rte.exct == Union{}
3237+
rt = Const(true)
3238+
elseif rte.rt === Union{} && rte.exct === UndefVarError
3239+
rt = Const(false)
3240+
else
3241+
effects = Effects(generic_isdefinedglobal_effects, nothrow=true)
3242+
end
3243+
end
3244+
return CallMeta(RTEffects(rt, Union{}, effects), GlobalAccessInfo(partition))
3245+
end
3246+
3247+
function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, @nospecialize(M), @nospecialize(s), @nospecialize(allow_import_arg), @nospecialize(order_arg), saw_latestworld::Bool, sv::AbsIntState)
3248+
exct = Bottom
3249+
allow_import = true
3250+
if allow_import_arg !== nothing
3251+
if !isa(allow_import_arg, Const)
3252+
allow_import = nothing
3253+
if widenconst(allow_import_arg) != Bool
3254+
exct = Union{exct, TypeError}
3255+
end
3256+
else
3257+
allow_import = allow_import_arg.val
3258+
end
3259+
end
3260+
if order_arg !== nothing
3261+
exct = global_order_exct(order_arg, #=loading=#true, #=storing=#false)
3262+
if !(isa(order_arg, Const) && get_atomic_order(order_arg.val, #=loading=#true, #=storing=#false).x >= MEMORY_ORDER_UNORDERED.x)
3263+
exct = Union{exct, ConcurrencyViolationError}
3264+
end
3265+
end
3266+
if M isa Const && s isa Const
3267+
M, s = M.val, s.val
3268+
if M isa Module && s isa Symbol
3269+
return merge_exct(abstract_eval_isdefinedglobal(interp, M, s, allow_import, saw_latestworld, sv), exct)
3270+
end
3271+
return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo())
3272+
elseif !hasintersect(widenconst(M), Module) || !hasintersect(widenconst(s), Symbol)
3273+
return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo())
3274+
elseif M Module && s Symbol
3275+
return CallMeta(Bool, Union{exct, UndefVarError}, generic_isdefinedglobal_effects, NoCallInfo())
3276+
end
3277+
return CallMeta(Bool, Union{exct, TypeError, UndefVarError}, generic_isdefinedglobal_effects, NoCallInfo())
3278+
end
3279+
32363280
function abstract_eval_throw_undef_if_not(interp::AbstractInterpreter, e::Expr, sstate::StatementState, sv::AbsIntState)
32373281
condt = abstract_eval_value(interp, e.args[2], sstate, sv)
32383282
condval = maybe_extract_const_bool(condt)
@@ -3443,22 +3487,31 @@ function abstract_eval_globalref_type(g::GlobalRef, src::Union{CodeInfo, IRCode,
34433487
return partition_restriction(partition)
34443488
end
34453489

3446-
function abstract_eval_binding_partition!(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState)
3490+
function lookup_binding_partition!(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState)
34473491
force_binding_resolution!(g)
34483492
partition = lookup_binding_partition(get_inference_world(interp), g)
34493493
update_valid_age!(sv, WorldRange(partition.min_world, partition.max_world))
3494+
partition
3495+
end
34503496

3497+
function walk_binding_partition!(interp::AbstractInterpreter, partition::Core.BindingPartition, sv::AbsIntState)
34513498
while is_some_imported(binding_kind(partition))
34523499
imported_binding = partition_restriction(partition)::Core.Binding
34533500
partition = lookup_binding_partition(get_inference_world(interp), imported_binding)
34543501
update_valid_age!(sv, WorldRange(partition.min_world, partition.max_world))
34553502
end
3503+
return partition
3504+
end
34563505

3506+
function abstract_eval_binding_partition!(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState)
3507+
partition = lookup_binding_partition!(interp, g, sv)
3508+
partition = walk_binding_partition!(interp, partition, sv)
34573509
return partition
34583510
end
34593511

34603512
function abstract_eval_partition_load(interp::AbstractInterpreter, partition::Core.BindingPartition)
3461-
if is_some_guard(binding_kind(partition))
3513+
kind = binding_kind(partition)
3514+
if is_some_guard(kind) || kind == BINDING_KIND_UNDEF_CONST
34623515
if InferenceParams(interp).assume_bindings_static
34633516
return RTEffects(Union{}, UndefVarError, EFFECTS_THROWS)
34643517
else
@@ -3468,38 +3521,40 @@ function abstract_eval_partition_load(interp::AbstractInterpreter, partition::Co
34683521
end
34693522
end
34703523

3471-
if is_some_const_binding(binding_kind(partition))
3524+
if is_defined_const_binding(kind)
34723525
rt = Const(partition_restriction(partition))
34733526
return RTEffects(rt, Union{}, Effects(EFFECTS_TOTAL, inaccessiblememonly=is_mutation_free_argtype(rt) ? ALWAYS_TRUE : ALWAYS_FALSE))
34743527
end
34753528

34763529
rt = partition_restriction(partition)
3477-
34783530
return RTEffects(rt, UndefVarError, generic_getglobal_effects)
34793531
end
34803532

34813533
function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, saw_latestworld::Bool, sv::AbsIntState)
34823534
if saw_latestworld
3483-
return RTEffects(Any, Any, generic_getglobal_effects)
3535+
return Pair{RTEffects, Union{Nothing, Core.BindingPartition}}(RTEffects(Any, Any, generic_getglobal_effects), nothing)
34843536
end
34853537
partition = abstract_eval_binding_partition!(interp, g, sv)
34863538
ret = abstract_eval_partition_load(interp, partition)
34873539
if ret.rt !== Union{} && ret.exct === UndefVarError && InferenceParams(interp).assume_bindings_static
34883540
if isdefined(g, :binding) && isdefined(g.binding, :value)
3489-
return RTEffects(ret.rt, Union{}, Effects(generic_getglobal_effects, nothrow=true))
3541+
ret = RTEffects(ret.rt, Union{}, Effects(generic_getglobal_effects, nothrow=true))
34903542
end
34913543
# We do not assume in general that assigned global bindings remain assigned.
34923544
# The existence of pkgimages allows them to revert in practice.
34933545
end
3494-
return ret
3546+
return Pair{RTEffects, Union{Nothing, Core.BindingPartition}}(ret, partition)
34953547
end
34963548

34973549
function global_assignment_rt_exct(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, g::GlobalRef, @nospecialize(newty))
34983550
if saw_latestworld
3499-
return Pair{Any,Any}(newty, Union{ErrorException, TypeError})
3551+
return Pair{Pair{Any,Any}, Union{Core.BindingPartition, Nothing}}(
3552+
Pair{Any,Any}(newty, Union{ErrorException, TypeError}), nothing)
35003553
end
35013554
partition = abstract_eval_binding_partition!(interp, g, sv)
3502-
return global_assignment_binding_rt_exct(interp, partition, newty)
3555+
return Pair{Pair{Any,Any}, Union{Core.BindingPartition, Nothing}}(
3556+
global_assignment_binding_rt_exct(interp, partition, newty),
3557+
partition)
35033558
end
35043559

35053560
function global_assignment_binding_rt_exct(interp::AbstractInterpreter, partition::Core.BindingPartition, @nospecialize(newty))
@@ -3520,18 +3575,6 @@ function global_assignment_binding_rt_exct(interp::AbstractInterpreter, partitio
35203575
return Pair{Any,Any}(newty, Bottom)
35213576
end
35223577

3523-
function handle_global_assignment!(interp::AbstractInterpreter, frame::InferenceState, saw_latestworld::Bool, lhs::GlobalRef, @nospecialize(newty))
3524-
effect_free = ALWAYS_FALSE
3525-
nothrow = global_assignment_rt_exct(interp, frame, saw_latestworld, lhs, ignorelimited(newty))[2] === Union{}
3526-
inaccessiblememonly = ALWAYS_FALSE
3527-
if !nothrow
3528-
sub_curr_ssaflag!(frame, IR_FLAG_NOTHROW)
3529-
end
3530-
sub_curr_ssaflag!(frame, IR_FLAG_EFFECT_FREE)
3531-
merge_effects!(interp, frame, Effects(EFFECTS_TOTAL; effect_free, nothrow, inaccessiblememonly))
3532-
return nothing
3533-
end
3534-
35353578
abstract_eval_ssavalue(s::SSAValue, sv::InferenceState) = abstract_eval_ssavalue(s, sv.ssavaluetypes)
35363579

35373580
function abstract_eval_ssavalue(s::SSAValue, ssavaluetypes::Vector{Any})

Diff for: Compiler/src/bootstrap.jl

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ function activate_codegen!()
1515
end)
1616
end
1717

18+
global bootstrapping_compiler::Bool = false
1819
function bootstrap!()
1920
global bootstrapping_compiler = true
2021
let time() = ccall(:jl_clock_now, Float64, ())

Diff for: Compiler/src/ssair/verify.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ function verify_ir(ir::IRCode, print::Bool=true,
366366
@verify_error "Assignment should have been removed during SSA conversion"
367367
raise_error()
368368
elseif stmt.head === :isdefined
369-
if length(stmt.args) > 2 || (length(stmt.args) == 2 && !isa(stmt.args[2], Bool))
369+
if length(stmt.args) > 2
370370
@verify_error "malformed isdefined"
371371
raise_error()
372372
end
@@ -382,7 +382,7 @@ function verify_ir(ir::IRCode, print::Bool=true,
382382
elseif stmt.head === :foreigncall
383383
isforeigncall = true
384384
elseif stmt.head === :isdefined && length(stmt.args) == 1 &&
385-
(stmt.args[1] isa GlobalRef || isexpr(stmt.args[1], :static_parameter))
385+
isexpr(stmt.args[1], :static_parameter)
386386
# a GlobalRef or static_parameter isdefined check does not evaluate its argument
387387
continue
388388
elseif stmt.head === :call

Diff for: Compiler/src/stmtinfo.jl

+14
Original file line numberDiff line numberDiff line change
@@ -481,4 +481,18 @@ end
481481
add_edges_impl(edges::Vector{Any}, info::VirtualMethodMatchInfo) =
482482
_add_edges_impl(edges, info.info, #=mi_edge=#true)
483483

484+
"""
485+
info::GlobalAccessInfo <: CallInfo
486+
487+
Represents access to a global through runtime reflection, rather than as a manifest
488+
`GlobalRef` in the source code. Used for builtins (getglobal/setglobal/etc.) that
489+
perform such accesses.
490+
"""
491+
struct GlobalAccessInfo <: CallInfo
492+
bpart::Core.BindingPartition
493+
end
494+
GlobalAccessInfo(::Nothing) = NoCallInfo()
495+
add_edges_impl(edges::Vector{Any}, info::GlobalAccessInfo) =
496+
push!(edges, info.bpart)
497+
484498
@specialize

0 commit comments

Comments
 (0)