Skip to content

Commit

Permalink
AbstractInterpreter: remove `method_table(::AbstractInterpreter, ::…
Browse files Browse the repository at this point in the history
…InferenceState)` interface

In #44240 we removed the `CachedMethodTable` support as it turned out to
be ineffective under the current compiler infrastructure.
Because of this, there is no strong reason to keep a method table per `InferenceState`.
This commit simply removes the `method_table(::AbstractInterpreter, ::InferenceState)`
interface and should make it clearer which interface should be overloaded to
implement a contextual dispatch.
  • Loading branch information
aviatesk committed Mar 1, 2022
1 parent 394af38 commit 3f1efb4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 32 deletions.
14 changes: 7 additions & 7 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
end

argtypes = arginfo.argtypes
matches = find_matching_methods(argtypes, atype, method_table(interp, sv), InferenceParams(interp).MAX_UNION_SPLITTING, max_methods)
matches = find_matching_methods(argtypes, atype, method_table(interp), InferenceParams(interp).MAX_UNION_SPLITTING, max_methods)
if isa(matches, FailedMethodMatch)
add_remark!(interp, sv, matches.reason)
tristate_merge!(sv, Effects())
Expand Down Expand Up @@ -637,7 +637,7 @@ end

function pure_eval_eligible(interp::AbstractInterpreter,
@nospecialize(f), applicable::Vector{Any}, arginfo::ArgInfo, sv::InferenceState)
return !isoverlayed(method_table(interp, sv)) &&
return !isoverlayed(method_table(interp)) &&
f !== nothing &&
length(applicable) == 1 &&
is_method_pure(applicable[1]::MethodMatch) &&
Expand Down Expand Up @@ -674,7 +674,7 @@ end

function concrete_eval_eligible(interp::AbstractInterpreter,
@nospecialize(f), result::MethodCallResult, arginfo::ArgInfo, sv::InferenceState)
return !isoverlayed(method_table(interp, sv)) &&
return !isoverlayed(method_table(interp)) &&
f !== nothing &&
result.edge !== nothing &&
is_total_or_error(result.edge_effects) &&
Expand Down Expand Up @@ -2110,14 +2110,14 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
frame.dont_work_on_me = true # mark that this function is currently on the stack
W = frame.ip
states = frame.stmt_types
n = frame.nstmts
nstmts = frame.nstmts
nargs = frame.nargs
def = frame.linfo.def
isva = isa(def, Method) && def.isva
nslots = nargs - isva
slottypes = frame.slottypes
ssavaluetypes = frame.src.ssavaluetypes::Vector{Any}
while frame.pc´´ <= n
while frame.pc´´ <= nstmts
# make progress on the active ip set
local pc::Int = frame.pc´´
while true # inner loop optimizes the common case where it can run straight from pc to pc + 1
Expand Down Expand Up @@ -2189,7 +2189,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
end
end
elseif isa(stmt, ReturnNode)
pc´ = n + 1
pc´ = nstmts + 1
bestguess = frame.bestguess
rt = abstract_eval_value(interp, stmt.val, changes, frame)
rt = widenreturn(rt, bestguess, nslots, slottypes, changes)
Expand Down Expand Up @@ -2310,7 +2310,7 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
ssavaluetypes[pc] = Any
end

pc´ > n && break # can't proceed with the fast-path fall-through
pc´ > nstmts && break # can't proceed with the fast-path fall-through
newstate = stupdate!(states[pc´], changes)
if isa(stmt, GotoNode) && frame.pc´´ < pc´
# if we are processing a goto node anyways,
Expand Down
41 changes: 16 additions & 25 deletions base/compiler/inferencestate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,6 @@ mutable struct InferenceState
# Inferred purity flags
ipo_effects::Effects

# The place to look up methods while working on this function.
# In particular, we cache method lookup results for the same function to
# fast path repeated queries.
method_table::InternalMethodTable

# The interpreter that created this inference state. Not looked at by
# NativeInterpreter. But other interpreters may use this to detect cycles
interp::AbstractInterpreter
Expand All @@ -85,9 +80,9 @@ mutable struct InferenceState
src.ssavaluetypes = Any[ NOT_FOUND for i = 1:nssavalues ]
stmt_info = Any[ nothing for i = 1:length(code) ]

n = length(code)
s_types = Union{Nothing, VarTable}[ nothing for i = 1:n ]
s_edges = Union{Nothing, Vector{Any}}[ nothing for i = 1:n ]
nstmts = length(code)
s_types = Union{Nothing, VarTable}[ nothing for i = 1:nstmts ]
s_edges = Union{Nothing, Vector{Any}}[ nothing for i = 1:nstmts ]

# initial types
nslots = length(src.slotflags)
Expand Down Expand Up @@ -128,21 +123,19 @@ mutable struct InferenceState

@assert cache === :no || cache === :local || cache === :global
frame = new(
params, result, linfo,
sp, slottypes, mod, 0,
IdSet{InferenceState}(), IdSet{InferenceState}(),
src, get_world_counter(interp), valid_worlds,
nargs, s_types, s_edges, stmt_info,
Union{}, ip, 1, n, handler_at,
ssavalue_uses,
Vector{Tuple{InferenceState,LineNum}}(), # cycle_backedges
Vector{InferenceState}(), # callers_in_cycle
#=parent=#nothing,
cache === :global, false, false,
Effects(consistent, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE,
inbounds_taints_consistency),
method_table(interp),
interp)
params, result, linfo,
sp, slottypes, mod, #=currpc=#0,
#=pclimitations=#IdSet{InferenceState}(), #=limitations=#IdSet{InferenceState}(),
src, get_world_counter(interp), valid_worlds,
nargs, s_types, s_edges, stmt_info,
#=bestguess=#Union{}, ip, #=pc´´=#1, nstmts, handler_at, ssavalue_uses,
#=cycle_backedges=#Vector{Tuple{InferenceState,LineNum}}(),
#=callers_in_cycle=#Vector{InferenceState}(),
#=parent=#nothing,
#=cached=#cache === :global,
#=inferred=#false, #=dont_work_on_me=#false,
#=ipo_effects=#Effects(consistent, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, inbounds_taints_consistency),
interp)
result.result = frame
cache !== :no && push!(get_inference_cache(interp), result)
return frame
Expand Down Expand Up @@ -267,8 +260,6 @@ function iterate(unw::InfStackUnwind, (infstate, cyclei)::Tuple{InferenceState,
(infstate::InferenceState, (infstate, cyclei))
end

method_table(interp::AbstractInterpreter, sv::InferenceState) = sv.method_table

function InferenceState(result::InferenceResult, cache::Symbol, interp::AbstractInterpreter)
# prepare an InferenceState object for inferring lambda
src = retrieve_code_info(result.linfo)
Expand Down
7 changes: 7 additions & 0 deletions base/compiler/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,13 @@ may_compress(::AbstractInterpreter) = true
may_discard_trees(::AbstractInterpreter) = true
verbose_stmt_info(::AbstractInterpreter) = false

"""
method_table(interp::AbstractInterpreter) -> MethodTableView
Returns a method table this `interp` uses for method lookup.
External `AbstractInterpreter` can optionally return `OverlayMethodTable` here
to incorporate customized dispatches for the overridden methods.
"""
method_table(interp::AbstractInterpreter) = InternalMethodTable(get_world_counter(interp))

"""
Expand Down

0 comments on commit 3f1efb4

Please sign in to comment.