Skip to content

Commit

Permalink
Add nothrow modeling for global assignment
Browse files Browse the repository at this point in the history
Currently global assignment conservatively taints nothrow.
We can do better by looking at whether the global exists,
isconst, its type, etc. and determine whether there is
any possibility that the assignment will throw and taint
the effect accordingly.
  • Loading branch information
Keno committed May 22, 2022
1 parent a37dd16 commit 15cbf8f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
17 changes: 14 additions & 3 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2089,6 +2089,19 @@ function abstract_eval_global(M::Module, s::Symbol, frame::InferenceState)
return ty
end

function abstract_eval_global_assignment(interp::AbstractInterpreter, frame::InferenceState, lhs::GlobalRef, @nospecialize(rhs))
M = lhs.mod
s = lhs.name
nothrow = false
if isdefined(M, s) && !isconst(M, s)
ty = ccall(:jl_binding_type, Any, (Any, Any), M, s)
nothrow = ty === nothing || rhs ty
end
tristate_merge!(frame, Effects(EFFECTS_TOTAL,
effect_free=TRISTATE_UNKNOWN,
nothrow=nothrow ? ALWAYS_TRUE : TRISTATE_UNKNOWN))
end

abstract_eval_ssavalue(s::SSAValue, sv::InferenceState) = abstract_eval_ssavalue(s, sv.src)
function abstract_eval_ssavalue(s::SSAValue, src::CodeInfo)
typ = (src.ssavaluetypes::Vector{Any})[s.id]
Expand Down Expand Up @@ -2321,9 +2334,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
if isa(lhs, SlotNumber)
changes = StateUpdate(lhs, VarState(t, false), changes, false)
elseif isa(lhs, GlobalRef)
tristate_merge!(frame, Effects(EFFECTS_TOTAL,
effect_free=TRISTATE_UNKNOWN,
nothrow=TRISTATE_UNKNOWN))
abstract_eval_global_assignment(interp, frame, lhs, t)
elseif !isa(lhs, SSAValue)
tristate_merge!(frame, EFFECTS_UNKNOWN)
end
Expand Down
8 changes: 8 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4133,3 +4133,11 @@ end |> !Core.Compiler.is_concrete_eval_eligible
@test !fully_eliminated() do
entry_to_be_invalidated('a')
end

# Nothrow for assignment to globals
global glob_assign_int::Int = 0
f_glob_assign_int() = global glob_assign_int += 1
let effects = Base.infer_effects(f_glob_assign_int, ())
@test !Core.Compiler.is_effect_free(effects)
@test Core.Compiler.is_nothrow(effects)
end

0 comments on commit 15cbf8f

Please sign in to comment.