Skip to content

Commit 4b95442

Browse files
authored
inference: model Core._svec_ref (#57973)
1 parent 9f8ae16 commit 4b95442

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

Compiler/src/tfuncs.jl

+22-5
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,16 @@ end
573573
add_tfunc(nfields, 1, 1, nfields_tfunc, 1)
574574
add_tfunc(Core._expr, 1, INT_INF, @nospecs((𝕃::AbstractLattice, args...)->Expr), 100)
575575
add_tfunc(svec, 0, INT_INF, @nospecs((𝕃::AbstractLattice, args...)->SimpleVector), 20)
576+
@nospecs function _svec_ref_tfunc(𝕃::AbstractLattice, s, i)
577+
if isa(s, Const) && isa(i, Const)
578+
s, i = s.val, i.val
579+
if isa(s, SimpleVector) && isa(i, Int)
580+
return 1 i length(s) ? Const(s[i]) : Bottom
581+
end
582+
end
583+
return Any
584+
end
585+
add_tfunc(Core._svec_ref, 2, 2, _svec_ref_tfunc, 1)
576586
@nospecs function typevar_tfunc(𝕃::AbstractLattice, n, lb_arg, ub_arg)
577587
lb = Union{}
578588
ub = Any
@@ -2316,6 +2326,9 @@ function _builtin_nothrow(𝕃::AbstractLattice, @nospecialize(f::Builtin), argt
23162326
elseif f === Core.compilerbarrier
23172327
na == 2 || return false
23182328
return compilerbarrier_nothrow(argtypes[1], nothing)
2329+
elseif f === Core._svec_ref
2330+
na == 2 || return false
2331+
return _svec_ref_tfunc(𝕃, argtypes[1], argtypes[2]) isa Const
23192332
end
23202333
return false
23212334
end
@@ -2346,7 +2359,9 @@ const _CONSISTENT_BUILTINS = Any[
23462359
throw,
23472360
Core.throw_methoderror,
23482361
setfield!,
2349-
donotdelete
2362+
donotdelete,
2363+
memoryrefnew,
2364+
memoryrefoffset,
23502365
]
23512366

23522367
# known to be effect-free (but not necessarily nothrow)
@@ -2371,6 +2386,7 @@ const _EFFECT_FREE_BUILTINS = [
23712386
Core.throw_methoderror,
23722387
getglobal,
23732388
compilerbarrier,
2389+
Core._svec_ref,
23742390
]
23752391

23762392
const _INACCESSIBLEMEM_BUILTINS = Any[
@@ -2404,6 +2420,7 @@ const _ARGMEM_BUILTINS = Any[
24042420
replacefield!,
24052421
setfield!,
24062422
swapfield!,
2423+
Core._svec_ref,
24072424
]
24082425

24092426
const _INCONSISTENT_INTRINSICS = Any[
@@ -2546,7 +2563,7 @@ const _EFFECTS_KNOWN_BUILTINS = Any[
25462563
# Core._primitivetype,
25472564
# Core._setsuper!,
25482565
# Core._structtype,
2549-
# Core._svec_ref,
2566+
Core._svec_ref,
25502567
# Core._typebody!,
25512568
Core._typevar,
25522569
apply_type,
@@ -2650,9 +2667,7 @@ function builtin_effects(𝕃::AbstractLattice, @nospecialize(f::Builtin), argty
26502667
else
26512668
if contains_is(_CONSISTENT_BUILTINS, f)
26522669
consistent = ALWAYS_TRUE
2653-
elseif f === memoryrefnew || f === memoryrefoffset
2654-
consistent = ALWAYS_TRUE
2655-
elseif f === memoryrefget || f === memoryrefset! || f === memoryref_isassigned
2670+
elseif f === memoryrefget || f === memoryrefset! || f === memoryref_isassigned || f === Core._svec_ref
26562671
consistent = CONSISTENT_IF_INACCESSIBLEMEMONLY
26572672
elseif f === Core._typevar || f === Core.memorynew
26582673
consistent = CONSISTENT_IF_NOTRETURNED
@@ -2838,6 +2853,8 @@ _istypemin(@nospecialize x) = !_iszero(x) && Intrinsics.neg_int(x) === x
28382853
function builtin_exct(𝕃::AbstractLattice, @nospecialize(f::Builtin), argtypes::Vector{Any}, @nospecialize(rt))
28392854
if isa(f, IntrinsicFunction)
28402855
return intrinsic_exct(𝕃, f, argtypes)
2856+
elseif f === Core._svec_ref
2857+
return BoundsError
28412858
end
28422859
return Any
28432860
end

Compiler/test/effects.jl

+10
Original file line numberDiff line numberDiff line change
@@ -1467,3 +1467,13 @@ end
14671467
@test Base.infer_effects(Core.invoke_in_world, Tuple{Vararg{Any}}) == Compiler.Effects()
14681468
@test Base.infer_effects(invokelatest, Tuple{Vararg{Any}}) == Compiler.Effects()
14691469
@test Base.infer_effects(invoke, Tuple{Vararg{Any}}) == Compiler.Effects()
1470+
1471+
# Core._svec_ref effects modeling (required for external abstract interpreter that doesn't run optimization)
1472+
let effects = Base.infer_effects((Core.SimpleVector,Int); optimize=false) do svec, i
1473+
Core._svec_ref(svec, i)
1474+
end
1475+
@test !Compiler.is_consistent(effects)
1476+
@test Compiler.is_effect_free(effects)
1477+
@test !Compiler.is_nothrow(effects)
1478+
@test Compiler.is_terminates(effects)
1479+
end

src/jltypes.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3885,7 +3885,7 @@ void jl_init_types(void) JL_GC_DISABLED
38853885
// override ismutationfree for builtin types that are mutable for identity
38863886
jl_string_type->ismutationfree = jl_string_type->isidentityfree = 1;
38873887
jl_symbol_type->ismutationfree = jl_symbol_type->isidentityfree = 1;
3888-
jl_simplevector_type->ismutationfree = jl_simplevector_type->isidentityfree = 1;
3888+
jl_simplevector_type->isidentityfree = 1;
38893889
jl_typename_type->ismutationfree = 1;
38903890
jl_datatype_type->ismutationfree = 1;
38913891
jl_uniontype_type->ismutationfree = 1;

test/reflection.jl

+2
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,8 @@ end
12111211

12121212
@test Base.ismutationfree(Type{Union{}})
12131213

1214+
@test !Base.ismutationfree(Core.SimpleVector)
1215+
12141216
module TestNames
12151217

12161218
public publicized

0 commit comments

Comments
 (0)