Skip to content

Commit

Permalink
inference: cleans up abstract interpretation code (JuliaLang#55308)
Browse files Browse the repository at this point in the history
- propagate the lattice that was not propagated
- remove unused `condargs` allocation
  • Loading branch information
aviatesk committed Jul 30, 2024
1 parent 6bc2c55 commit 125bac4
Showing 1 changed file with 21 additions and 24 deletions.
45 changes: 21 additions & 24 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
arginfo::ArgInfo, si::StmtInfo, @nospecialize(atype),
sv::AbsIntState, max_methods::Int)
𝕃ₚ, 𝕃ᵢ = ipo_lattice(interp), typeinf_lattice(interp)
= (𝕃ₚ)
, ₚ, = partialorder(𝕃ₚ), join(𝕃ₚ), join(𝕃ᵢ)
if !should_infer_this_call(interp, sv)
add_remark!(interp, sv, "Skipped call in throw block")
# At this point we are guaranteed to end up throwing on this path,
Expand All @@ -37,7 +37,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
(; valid_worlds, applicable, info) = matches
update_valid_age!(sv, valid_worlds)
napplicable = length(applicable)
rettype = excttype = Bottom
rettype = exctype = Bottom
edges = MethodInstance[]
conditionals = nothing # keeps refinement information of call argument types when the return type is boolean
seen = 0 # number of signatures actually inferred
Expand Down Expand Up @@ -96,8 +96,8 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
const_results[i] = const_result
end
edge === nothing || push!(edges, edge)
this_rt = tmerge(this_rt, rt)
this_exct = tmerge(this_exct, exct)
this_rt = this_rt ₚ rt
this_exct = this_exct exct
if bail_out_call(interp, this_rt, sv)
break
end
Expand Down Expand Up @@ -156,17 +156,17 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
end
@assert !(this_conditional isa Conditional || this_rt isa MustAlias) "invalid lattice element returned from inter-procedural context"
seen += 1
rettype = tmerge(𝕃ₚ, rettype, this_rt)
excttype = tmerge(𝕃ₚ, excttype, this_exct)
rettype = rettype this_rt
exctype = exctype this_exct
if has_conditional(𝕃ₚ, sv) && this_conditional !== Bottom && is_lattice_bool(𝕃ₚ, rettype) && fargs !== nothing
if conditionals === nothing
conditionals = Any[Bottom for _ in 1:length(argtypes)],
Any[Bottom for _ in 1:length(argtypes)]
end
for i = 1:length(argtypes)
cnd = conditional_argtype(𝕃ᵢ, this_conditional, sig, argtypes, i)
conditionals[1][i] = tmerge(𝕃ᵢ, conditionals[1][i], cnd.thentype)
conditionals[2][i] = tmerge(𝕃ᵢ, conditionals[2][i], cnd.elsetype)
conditionals[1][i] = conditionals[1][i] cnd.thentype
conditionals[2][i] = conditionals[2][i] cnd.elsetype
end
end
if bail_out_call(interp, InferenceLoopState(sig, rettype, all_effects), sv)
Expand All @@ -182,14 +182,14 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),

if seen napplicable
# there is unanalyzed candidate, widen type and effects to the top
rettype = excttype = Any
rettype = exctype = Any
all_effects = Effects()
else
if (matches isa MethodMatches ? (!matches.fullmatch || any_ambig(matches)) :
(!all(matches.fullmatches) || any_ambig(matches)))
# Account for the fact that we may encounter a MethodError with a non-covered or ambiguous signature.
all_effects = Effects(all_effects; nothrow=false)
excttype = tmerge(𝕃ₚ, excttype, MethodError)
exctype = exctype MethodError
end
if sv isa InferenceState && fargs !== nothing
slotrefinements = collect_slot_refinements(𝕃ᵢ, applicable, argtypes, fargs, sv)
Expand Down Expand Up @@ -240,7 +240,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
end
end

return CallMeta(rettype, excttype, all_effects, info, slotrefinements)
return CallMeta(rettype, exctype, all_effects, info, slotrefinements)
end

struct FailedMethodMatch
Expand Down Expand Up @@ -367,7 +367,7 @@ function from_interprocedural!(interp::AbstractInterpreter, @nospecialize(rt), s
arginfo::ArgInfo, @nospecialize(maybecondinfo))
rt = collect_limitations!(rt, sv)
if isa(rt, InterMustAlias)
rt = from_intermustalias(rt, arginfo, sv)
rt = from_intermustalias(typeinf_lattice(interp), rt, arginfo, sv)
elseif is_lattice_bool(ipo_lattice(interp), rt)
if maybecondinfo === nothing
rt = widenconditional(rt)
Expand All @@ -387,12 +387,13 @@ function collect_limitations!(@nospecialize(typ), sv::InferenceState)
return typ
end

function from_intermustalias(rt::InterMustAlias, arginfo::ArgInfo, sv::AbsIntState)
function from_intermustalias(𝕃ᵢ::AbstractLattice, rt::InterMustAlias, arginfo::ArgInfo, sv::AbsIntState)
fargs = arginfo.fargs
if fargs !== nothing && 1 rt.slot length(fargs)
arg = ssa_def_slot(fargs[rt.slot], sv)
if isa(arg, SlotNumber)
argtyp = widenslotwrapper(arginfo.argtypes[rt.slot])
= partialorder(𝕃ᵢ)
if rt.vartyp argtyp
return MustAlias(arg, rt.vartyp, rt.fldidx, rt.fldtyp)
else
Expand All @@ -412,6 +413,7 @@ function from_interconditional(𝕃ᵢ::AbstractLattice, @nospecialize(rt), sv::
alias = nothing
thentype = elsetype = Any
condval = maybe_extract_const_bool(rt)
, , = partialorder(𝕃ᵢ), strictneqpartialorder(𝕃ᵢ), meet(𝕃ᵢ)
for i in 1:length(fargs)
# find the first argument which supports refinement,
# and intersect all equivalent arguments with it
Expand Down Expand Up @@ -447,24 +449,24 @@ function from_interconditional(𝕃ᵢ::AbstractLattice, @nospecialize(rt), sv::
end
if condval === false
thentype = Bottom
elseif (𝕃ᵢ, new_thentype, thentype)
elseif new_thentype thentype
thentype = new_thentype
else
thentype = tmeet(𝕃ᵢ, thentype, widenconst(new_thentype))
thentype = thentype widenconst(new_thentype)
end
if condval === true
elsetype = Bottom
elseif (𝕃ᵢ, new_elsetype, elsetype)
elseif new_elsetype elsetype
elsetype = new_elsetype
else
elsetype = tmeet(𝕃ᵢ, elsetype, widenconst(new_elsetype))
elsetype = elsetype widenconst(new_elsetype)
end
if (slot > 0 || condval !== false) && (𝕃ᵢ, thentype, old)
if (slot > 0 || condval !== false) && thentype old
slot = id
if !(arg isa SlotNumber) && argtyp isa MustAlias
alias = argtyp
end
elseif (slot > 0 || condval !== true) && (𝕃ᵢ, elsetype, old)
elseif (slot > 0 || condval !== true) && elsetype old
slot = id
if !(arg isa SlotNumber) && argtyp isa MustAlias
alias = argtyp
Expand Down Expand Up @@ -1368,7 +1370,6 @@ function matching_cache_argtypes(𝕃::AbstractLattice, mi::MethodInstance,
given_argtypes = Vector{Any}(undef, length(argtypes))
def = mi.def::Method
nargs = Int(def.nargs)
local condargs = nothing
for i in 1:length(argtypes)
argtype = argtypes[i]
# forward `Conditional` if it conveys a constraint on any other argument
Expand All @@ -1385,10 +1386,6 @@ function matching_cache_argtypes(𝕃::AbstractLattice, mi::MethodInstance,
# TODO bail out here immediately rather than just propagating Bottom ?
given_argtypes[i] = Bottom
else
if condargs === nothing
condargs = Tuple{Int,Int}[]
end
push!(condargs, (slotid, i))
given_argtypes[i] = Conditional(slotid, thentype, elsetype)
end
continue
Expand Down

0 comments on commit 125bac4

Please sign in to comment.