Skip to content

Commit

Permalink
fix edges type
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Oct 28, 2024
1 parent cca330d commit 2fd705b
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 30 deletions.
2 changes: 1 addition & 1 deletion base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,7 @@ function const_prop_call(interp::AbstractInterpreter,
pop!(callstack)
return nothing
end
inf_result.ci_as_edge = codeinst_as_edge(interp, mi, Core.svec(frame.edges...))
inf_result.ci_as_edge = codeinst_as_edge(interp, frame)
@assert frame.frameid != 0 && frame.cycleid == frame.frameid
@assert frame.parentid == sv.frameid
@assert inf_result.result !== nothing
Expand Down
24 changes: 12 additions & 12 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ struct InliningEdgeTracker
new(state.edges, invokesig)
end

function add_inlining_edge!(et::InliningEdgeTracker, edge::CodeInstance)
function add_inlining_edge!(et::InliningEdgeTracker, edge::Union{CodeInstance,MethodInstance})
(; edges, invokesig) = et
if invokesig === nothing
add_one_edge!(edges, edge)
Expand Down Expand Up @@ -785,9 +785,9 @@ function rewrite_apply_exprargs!(todo::Vector{Pair{Int,Any}},
return new_argtypes
end

function compileable_specialization(edge::CodeInstance, effects::Effects,
function compileable_specialization(mi::MethodInstance, effects::Effects,
et::InliningEdgeTracker, @nospecialize(info::CallInfo), state::InliningState)
mi_invoke = mi = edge.def
mi_invoke = mi
method, atype, sparams = mi.def::Method, mi.specTypes, mi.sparam_vals
if OptimizationParams(state.interp).compilesig_invokes
new_atype = get_compileable_sig(method, atype, sparams)
Expand All @@ -807,10 +807,9 @@ function compileable_specialization(edge::CodeInstance, effects::Effects,
return nothing
end
end
add_inlining_edge!(et, edge) # to the dispatch lookup
add_inlining_edge!(et, mi) # to the dispatch lookup
if mi_invoke !== mi
edge_invoke = codeinst_as_invoke_edge(state.interp, mi_invoke)
add_invoke_edge!(et.edges, method.sig, edge_invoke) # add_inlining_edge to the invoke call, if that is different
add_invoke_edge!(et.edges, method.sig, mi_invoke) # add_inlining_edge to the invoke call, if that is different
end
return InvokeCase(mi_invoke, effects, info)
end
Expand Down Expand Up @@ -871,18 +870,17 @@ function resolve_todo(mi::MethodInstance, result::Union{Nothing,InferenceResult,
effects = decode_effects(inferred_result.ipo_purity_bits)
edge = inferred_result
else # there is no cached source available, bail out
edge = codeinst_as_invoke_edge(state.interp, mi)
return compileable_specialization(edge, Effects(), et, info, state)
return compileable_specialization(mi, Effects(), et, info, state)
end

# the duplicated check might have been done already within `analyze_method!`, but still
# we need it here too since we may come here directly using a constant-prop' result
if !OptimizationParams(state.interp).inlining || is_stmt_noinline(flag)
return compileable_specialization(edge, effects, et, info, state)
return compileable_specialization(edge.def, effects, et, info, state)
end

src_inlining_policy(state.interp, src, info, flag) ||
return compileable_specialization(edge, effects, et, info, state)
return compileable_specialization(edge.def, effects, et, info, state)

add_inlining_edge!(et, edge)
if inferred_result isa CodeInstance
Expand Down Expand Up @@ -1500,7 +1498,7 @@ function concrete_result_item(result::ConcreteResult, @nospecialize(info::CallIn
invokesig::Union{Nothing,Vector{Any}}=nothing)
if !may_inline_concrete_result(result)
et = InliningEdgeTracker(state, invokesig)
return compileable_specialization(result.edge, result.effects, et, info, state)
return compileable_specialization(result.edge.def, result.effects, et, info, state)
end
@assert result.effects === EFFECTS_TOTAL
return ConstantCase(quoted(result.result), result.edge)
Expand Down Expand Up @@ -1557,7 +1555,9 @@ function handle_modifyop!_call!(ir::IRCode, idx::Int, stmt::Expr, info::ModifyOp
match.fully_covers || return nothing
edge = info.edges[1]
if edge === nothing
edge = codeinst_as_invoke_edge(state.interp, specialize_method(match))
edge = specialize_method(match)
else
edge = edge.def
end
case = compileable_specialization(edge, Effects(), InliningEdgeTracker(state), info, state)
case === nothing && return nothing
Expand Down
32 changes: 29 additions & 3 deletions base/compiler/stmtinfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -296,18 +296,44 @@ struct InvokeCallInfo <: CallInfo
end
function add_edges_impl(edges::Vector{Any}, info::InvokeCallInfo)
edge = info.edge
if edge !== nothing
if edge === nothing
mi = specialize_method(info.match)
add_invoke_edge!(edges, info.atype, mi)
else
add_invoke_edge!(edges, info.atype, edge)
end
nothing
end
function add_invoke_edge!(edges::Vector{Any}, @nospecialize(atype), edge::MethodInstance)
for i in 2:length(edges)
edgeᵢ = edges[i]
edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ.def)
edgeᵢ isa MethodInstance || continue
if edgeᵢ === edge
edge_minus_1 = edges[i-1]
if edge_minus_1 isa Type && edge_minus_1 == atype
return # found existing covered edge
end
end
end
push!(edges, atype, edge)
nothing
end
function add_invoke_edge!(edges::Vector{Any}, @nospecialize(atype), edge::CodeInstance)
for i in 2:length(edges)
edgeᵢ = edges[i]
if edgeᵢ isa CodeInstance && edgeᵢ.def === edge.def # XXX compare `CodeInstance` identify?
edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ.def)
edgeᵢ isa MethodInstance || continue
if edgeᵢ === edge.def
edge_minus_1 = edges[i-1]
if edge_minus_1 isa Type && edge_minus_1 == atype
return nothing
if edges[i] isa MethodInstance
# found edge we can upgrade
edges[i] = edge
return
elseif true # XXX compare `CodeInstance` identify?
return
end
end
end
end
Expand Down
7 changes: 1 addition & 6 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3010,10 +3010,6 @@ function abstract_applicable(interp::AbstractInterpreter, argtypes::Vector{Any},
rt = Const(true) # has applicable matches
end
if rt !== Bool
for i = 1:napplicable
(; match, edges, edge_idx) = applicable[i]
edges[edge_idx] = codeinst_as_invoke_edge(interp, specialize_method(match))
end
info = VirtualMethodMatchInfo(matches.info)
end
end
Expand Down Expand Up @@ -3055,8 +3051,7 @@ function _hasmethod_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, sv
vinfo = MethodMatchInfo(vresults, mt, types, false) # XXX: this should actually be an info with invoke-type edge
else
rt = Const(true)
edge = codeinst_as_invoke_edge(interp, specialize_method(match))
vinfo = InvokeCallInfo(edge, match, nothing, types)
vinfo = InvokeCallInfo(nothing, match, nothing, types)
end
info = VirtualMethodMatchInfo(vinfo)
return CallMeta(rt, Union{}, EFFECTS_TOTAL, info)
Expand Down
8 changes: 2 additions & 6 deletions base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -739,12 +739,8 @@ function codeinst_as_edge(edge::MethodInstance, edges::SimpleVector, @nospeciali
return CodeInstance(edge, owner, Any, Any, nothing, nothing, zero(Int32),
min_world, max_world, zero(UInt32), nothing, zero(UInt8), nothing, edges)
end
codeinst_as_edge(interp::AbstractInterpreter, edge::MethodInstance, edges::SimpleVector) =
codeinst_as_edge(edge, edges, cache_owner(interp), get_inference_world(interp), get_inference_world(interp))
codeinst_as_invoke_edge(edge::MethodInstance, @nospecialize(owner), min_world::UInt, max_world::UInt) =
codeinst_as_edge(edge, empty_edges, owner, min_world, max_world)
codeinst_as_invoke_edge(interp::AbstractInterpreter, edge::MethodInstance) =
codeinst_as_edge(interp, edge, empty_edges)
codeinst_as_edge(interp::AbstractInterpreter, sv::InferenceState) =
codeinst_as_edge(sv.linfo, Core.svec(sv.edges...), cache_owner(interp), first(sv.valid_worlds), last(sv.valid_worlds))

# compute (and cache) an inferred AST and return the current best estimate of the result type
function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize(atype), sparams::SimpleVector, caller::AbsIntState, edgecycle::Bool, edgelimited::Bool)
Expand Down
3 changes: 1 addition & 2 deletions test/compiler/contextual.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ module MiniCassette
@assert isa(src, CodeInfo)
src = copy(src)
@assert src.edges === Core.svec()
self_edge = Core.Compiler.codeinst_as_invoke_edge(mi, #=owner=#nothing, world, world)
src.edges = CodeInstance[self_edge]
src.edges = Any[mi]
transform!(mi, src, length(args), match.sparams)
# TODO: this is mandatory: code_info.min_world = max(code_info.min_world, min_world[])
# TODO: this is mandatory: code_info.max_world = min(code_info.max_world, max_world[])
Expand Down

0 comments on commit 2fd705b

Please sign in to comment.