Skip to content

Commit 752eeb6

Browse files
vtjnashaviatesk
authored andcommitted
compute edges post-inference, from info available there
1 parent a04c1d6 commit 752eeb6

File tree

12 files changed

+86
-210
lines changed

12 files changed

+86
-210
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,6 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
248248
# and avoid keeping track of a more complex result type.
249249
rettype = Any
250250
end
251-
any_slot_refined = slotrefinements !== nothing
252-
add_call_backedges!(interp, rettype, all_effects, any_slot_refined, edges, matches, atype, sv)
253251
if isa(sv, InferenceState)
254252
# TODO (#48913) implement a proper recursion handling for irinterp:
255253
# This works just because currently the `:terminate` condition guarantees that
@@ -573,31 +571,6 @@ function collect_slot_refinements(𝕃ᵢ::AbstractLattice, applicable::Vector{A
573571
return slotrefinements
574572
end
575573

576-
function add_call_backedges!(interp::AbstractInterpreter, @nospecialize(rettype),
577-
all_effects::Effects, any_slot_refined::Bool, edges::Vector{MethodInstance},
578-
matches::Union{MethodMatches,UnionSplitMethodMatches}, @nospecialize(atype),
579-
sv::AbsIntState)
580-
# don't bother to add backedges when both type and effects information are already
581-
# maximized to the top since a new method couldn't refine or widen them anyway
582-
if rettype === Any
583-
# ignore the `:nonoverlayed` property if `interp` doesn't use overlayed method table
584-
# since it will never be tainted anyway
585-
if !isoverlayed(method_table(interp))
586-
all_effects = Effects(all_effects; nonoverlayed=ALWAYS_FALSE)
587-
end
588-
if all_effects === Effects() && !any_slot_refined
589-
return nothing
590-
end
591-
end
592-
for edge in edges
593-
add_backedge!(sv, edge)
594-
end
595-
# also need an edge to the method table in case something gets
596-
# added that did not intersect with any existing method
597-
add_uncovered_edges!(sv, matches, atype)
598-
return nothing
599-
end
600-
601574
const RECURSION_UNUSED_MSG = "Bounded recursion detected with unused result. Annotated return type may be wider than true result."
602575
const RECURSION_MSG = "Bounded recursion detected. Call was widened to force convergence."
603576
const RECURSION_MSG_HARDLIMIT = "Bounded recursion detected under hardlimit. Call was widened to force convergence."
@@ -2189,7 +2162,6 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt
21892162
end
21902163
rt = from_interprocedural!(interp, rt, sv, arginfo, sig)
21912164
info = InvokeCallInfo(match, const_result, lookupsig)
2192-
edge !== nothing && add_invoke_backedge!(sv, lookupsig, edge)
21932165
if !match.fully_covers
21942166
effects = Effects(effects; nothrow=false)
21952167
exct = exct TypeError
@@ -2396,7 +2368,6 @@ function abstract_call_opaque_closure(interp::AbstractInterpreter,
23962368
end
23972369
rt = from_interprocedural!(interp, rt, sv, arginfo, match.spec_types)
23982370
info = OpaqueClosureCallInfo(match, const_result)
2399-
edge !== nothing && add_backedge!(sv, edge)
24002371
return CallMeta(rt, exct, effects, info)
24012372
end
24022373

@@ -3401,7 +3372,6 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
34013372

34023373
for currpc in bbstart:bbend
34033374
frame.currpc = currpc
3404-
empty_backedges!(frame, currpc)
34053375
stmt = frame.src.code[currpc]
34063376
# If we're at the end of the basic block ...
34073377
if currpc == bbend

base/compiler/inferencestate.jl

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ mutable struct InferenceState
247247
# TODO: Could keep this sparsely by doing structural liveness analysis ahead of time.
248248
bb_vartables::Vector{Union{Nothing,VarTable}} # nothing if not analyzed yet
249249
ssavaluetypes::Vector{Any}
250-
stmt_edges::Vector{Vector{Any}}
250+
edges::Vector{Any}
251251
stmt_info::Vector{CallInfo}
252252

253253
#= intermediate states for interprocedural abstract interpretation =#
@@ -301,7 +301,7 @@ mutable struct InferenceState
301301
nssavalues = src.ssavaluetypes::Int
302302
ssavalue_uses = find_ssavalue_uses(code, nssavalues)
303303
nstmts = length(code)
304-
stmt_edges = Vector{Vector{Any}}(undef, nstmts)
304+
edges = []
305305
stmt_info = CallInfo[ NoCallInfo() for i = 1:nstmts ]
306306

307307
nslots = length(src.slotflags)
@@ -350,7 +350,7 @@ mutable struct InferenceState
350350

351351
this = new(
352352
mi, world, mod, sptypes, slottypes, src, cfg, method_info,
353-
currbb, currpc, ip, handler_info, ssavalue_uses, bb_vartables, ssavaluetypes, stmt_edges, stmt_info,
353+
currbb, currpc, ip, handler_info, ssavalue_uses, bb_vartables, ssavaluetypes, edges, stmt_info,
354354
pclimitations, limitations, cycle_backedges, callstack, 0, 0, 0,
355355
result, unreachable, valid_worlds, bestguess, exc_bestguess, ipo_effects,
356356
restrict_abstract_call_sites, cache_mode, insert_coverage,
@@ -756,26 +756,9 @@ function add_cycle_backedge!(caller::InferenceState, frame::InferenceState)
756756
update_valid_age!(caller, frame.valid_worlds)
757757
backedge = (caller, caller.currpc)
758758
contains_is(frame.cycle_backedges, backedge) || push!(frame.cycle_backedges, backedge)
759-
add_backedge!(caller, frame.linfo)
760759
return frame
761760
end
762761

763-
function get_stmt_edges!(caller::InferenceState, currpc::Int=caller.currpc)
764-
stmt_edges = caller.stmt_edges
765-
if !isassigned(stmt_edges, currpc)
766-
return stmt_edges[currpc] = Any[]
767-
else
768-
return stmt_edges[currpc]
769-
end
770-
end
771-
772-
function empty_backedges!(frame::InferenceState, currpc::Int=frame.currpc)
773-
if isassigned(frame.stmt_edges, currpc)
774-
empty!(frame.stmt_edges[currpc])
775-
end
776-
return nothing
777-
end
778-
779762
function narguments(sv::InferenceState, include_va::Bool=true)
780763
nargs = Int(sv.src.nargs)
781764
if !include_va
@@ -1001,32 +984,6 @@ function callers_in_cycle(sv::InferenceState)
1001984
end
1002985
callers_in_cycle(sv::IRInterpretationState) = AbsIntCycle(sv.callstack::Vector{AbsIntState}, 0, 0)
1003986

1004-
# temporarily accumulate our edges to later add as backedges in the callee
1005-
function add_backedge!(caller::InferenceState, mi::MethodInstance)
1006-
isa(caller.linfo.def, Method) || return nothing # don't add backedges to toplevel method instance
1007-
return push!(get_stmt_edges!(caller), mi)
1008-
end
1009-
function add_backedge!(irsv::IRInterpretationState, mi::MethodInstance)
1010-
return push!(irsv.edges, mi)
1011-
end
1012-
1013-
function add_invoke_backedge!(caller::InferenceState, @nospecialize(invokesig::Type), mi::MethodInstance)
1014-
isa(caller.linfo.def, Method) || return nothing # don't add backedges to toplevel method instance
1015-
return push!(get_stmt_edges!(caller), invokesig, mi)
1016-
end
1017-
function add_invoke_backedge!(irsv::IRInterpretationState, @nospecialize(invokesig::Type), mi::MethodInstance)
1018-
return push!(irsv.edges, invokesig, mi)
1019-
end
1020-
1021-
# used to temporarily accumulate our no method errors to later add as backedges in the callee method table
1022-
function add_mt_backedge!(caller::InferenceState, mt::MethodTable, @nospecialize(typ))
1023-
isa(caller.linfo.def, Method) || return nothing # don't add backedges to toplevel method instance
1024-
return push!(get_stmt_edges!(caller), mt, typ)
1025-
end
1026-
function add_mt_backedge!(irsv::IRInterpretationState, mt::MethodTable, @nospecialize(typ))
1027-
return push!(irsv.edges, mt, typ)
1028-
end
1029-
1030987
get_curr_ssaflag(sv::InferenceState) = sv.src.ssaflags[sv.currpc]
1031988
get_curr_ssaflag(sv::IRInterpretationState) = sv.ir.stmts[sv.curridx][:flag]
1032989

base/compiler/optimize.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ struct InliningState{Interp<:AbstractInterpreter}
141141
interp::Interp
142142
end
143143
function InliningState(sv::InferenceState, interp::AbstractInterpreter)
144-
edges = sv.stmt_edges[1]
145-
return InliningState(edges, sv.world, interp)
144+
return InliningState(sv.edges, sv.world, interp)
146145
end
147146
function InliningState(interp::AbstractInterpreter)
148147
return InliningState(Any[], get_inference_world(interp), interp)
@@ -225,6 +224,7 @@ include("compiler/ssair/irinterp.jl")
225224
function ir_to_codeinf!(opt::OptimizationState)
226225
(; linfo, src) = opt
227226
src = ir_to_codeinf!(src, opt.ir::IRCode)
227+
src.edges = opt.inlining.edges
228228
opt.ir = nothing
229229
maybe_validate_code(linfo, src, "optimized")
230230
return src

base/compiler/ssair/inlining.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ struct InliningEdgeTracker
6666
new(state.edges, invokesig)
6767
end
6868

69-
function add_inlining_backedge!((; edges, invokesig)::InliningEdgeTracker, mi::MethodInstance)
69+
function add_inlining_edge!((; edges, invokesig)::InliningEdgeTracker, mi::MethodInstance)
7070
if invokesig === nothing
71-
push!(edges, mi)
71+
add_one_edge!(edges, mi)
7272
else # invoke backedge
73-
push!(edges, invoke_signature(invokesig), mi)
73+
add_invoke_edge!(edges, invoke_signature(invokesig), mi)
7474
end
7575
return nothing
7676
end
@@ -802,8 +802,8 @@ function compileable_specialization(mi::MethodInstance, effects::Effects,
802802
return nothing
803803
end
804804
end
805-
add_inlining_backedge!(et, mi) # to the dispatch lookup
806-
mi_invoke !== mi && push!(et.edges, method.sig, mi_invoke) # add_inlining_backedge to the invoke call, if that is different
805+
add_inlining_edge!(et, mi) # to the dispatch lookup
806+
mi_invoke !== mi && add_invoke_edge!(et.edges, method.sig, mi_invoke) # add_inlining_edge to the invoke call, if that is different
807807
return InvokeCase(mi_invoke, effects, info)
808808
end
809809

@@ -858,7 +858,7 @@ function resolve_todo(mi::MethodInstance, result::Union{Nothing,InferenceResult,
858858
inferred_result = get_cached_result(state, mi)
859859
end
860860
if inferred_result isa ConstantCase
861-
add_inlining_backedge!(et, mi)
861+
add_inlining_edge!(et, mi)
862862
return inferred_result
863863
end
864864
if inferred_result isa InferredResult
@@ -882,7 +882,7 @@ function resolve_todo(mi::MethodInstance, result::Union{Nothing,InferenceResult,
882882
return compileable_specialization(mi, effects, et, info;
883883
compilesig_invokes=OptimizationParams(state.interp).compilesig_invokes)
884884

885-
add_inlining_backedge!(et, mi)
885+
add_inlining_edge!(et, mi)
886886
ir = inferred_result isa CodeInstance ? retrieve_ir_for_inlining(inferred_result, src) :
887887
retrieve_ir_for_inlining(mi, src, preserve_local_sources)
888888
return InliningTodo(mi, ir, effects)
@@ -899,7 +899,7 @@ function resolve_todo(mi::MethodInstance, @nospecialize(info::CallInfo), flag::U
899899

900900
cached_result = get_cached_result(state, mi)
901901
if cached_result isa ConstantCase
902-
add_inlining_backedge!(et, mi)
902+
add_inlining_edge!(et, mi)
903903
return cached_result
904904
end
905905
if cached_result isa InferredResult
@@ -916,7 +916,7 @@ function resolve_todo(mi::MethodInstance, @nospecialize(info::CallInfo), flag::U
916916
src_inlining_policy(state.interp, src, info, flag) || return nothing
917917
ir = cached_result isa CodeInstance ? retrieve_ir_for_inlining(cached_result, src) :
918918
retrieve_ir_for_inlining(mi, src, preserve_local_sources)
919-
add_inlining_backedge!(et, mi)
919+
add_inlining_edge!(et, mi)
920920
return InliningTodo(mi, ir, effects)
921921
end
922922

@@ -1464,7 +1464,7 @@ function semiconcrete_result_item(result::SemiConcreteResult,
14641464
return compileable_specialization(mi, result.effects, et, info;
14651465
compilesig_invokes=OptimizationParams(state.interp).compilesig_invokes)
14661466

1467-
add_inlining_backedge!(et, mi)
1467+
add_inlining_edge!(et, mi)
14681468
preserve_local_sources = OptimizationParams(state.interp).preserve_local_sources
14691469
ir = retrieve_ir_for_inlining(mi, result.ir, preserve_local_sources)
14701470
return InliningTodo(mi, ir, result.effects)

base/compiler/ssair/irinterp.jl

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -435,12 +435,6 @@ function _ir_abstract_constant_propagation(interp::AbstractInterpreter, irsv::IR
435435
(nothrow | noub) || break
436436
end
437437

438-
if last(irsv.valid_worlds) >= get_world_counter()
439-
# if we aren't cached, we don't need this edge
440-
# but our caller might, so let's just make it anyways
441-
store_backedges(frame_instance(irsv), irsv.edges)
442-
end
443-
444438
if irsv.frameid != 0
445439
callstack = irsv.callstack::Vector{AbsIntState}
446440
@assert callstack[end] === irsv && length(callstack) == irsv.frameid

base/compiler/ssair/passes.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,7 +1523,7 @@ function try_inline_finalizer!(ir::IRCode, argexprs::Vector{Any}, idx::Int,
15231523
if code isa CodeInstance
15241524
if use_const_api(code)
15251525
# No code in the function - Nothing to do
1526-
add_inlining_backedge!(et, mi)
1526+
add_inlining_edge!(et, mi)
15271527
return true
15281528
end
15291529
src = @atomic :monotonic code.inferred
@@ -1538,7 +1538,7 @@ function try_inline_finalizer!(ir::IRCode, argexprs::Vector{Any}, idx::Int,
15381538
length(src.cfg.blocks) == 1 || return false
15391539

15401540
# Ok, we're committed to inlining the finalizer
1541-
add_inlining_backedge!(et, mi)
1541+
add_inlining_edge!(et, mi)
15421542

15431543
# TODO: Should there be a special line number node for inlined finalizers?
15441544
inline_at = ir[SSAValue(idx)][:line]

base/compiler/tfuncs.jl

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,14 +2988,7 @@ function abstract_applicable(interp::AbstractInterpreter, argtypes::Vector{Any},
29882988
else
29892989
rt = Const(true) # has applicable matches
29902990
end
2991-
for i in 1:napplicable
2992-
match = applicable[i]::MethodMatch
2993-
edge = specialize_method(match)::MethodInstance
2994-
add_backedge!(sv, edge)
2995-
end
2996-
# also need an edge to the method table in case something gets
2997-
# added that did not intersect with any existing method
2998-
add_uncovered_edges!(sv, matches, atype)
2991+
add_edges!(sv.edges, matches.info)
29992992
end
30002993
return CallMeta(rt, Union{}, EFFECTS_TOTAL, NoCallInfo())
30012994
end
@@ -3031,11 +3024,10 @@ function _hasmethod_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, sv
30313024
update_valid_age!(sv, valid_worlds)
30323025
if match === nothing
30333026
rt = Const(false)
3034-
add_mt_backedge!(sv, mt, types) # this should actually be an invoke-type backedge
3027+
add_edges!(sv.edges, MethodMatchInfo(MethodLookupResult(Any[], valid_worlds, true), types, mt)) # XXX: this should actually be an invoke-type backedge
30353028
else
30363029
rt = Const(true)
3037-
edge = specialize_method(match)::MethodInstance
3038-
add_invoke_backedge!(sv, types, edge)
3030+
add_edges!(sv.edges, InvokeCallInfo(match, nothing, types))
30393031
end
30403032
return CallMeta(rt, Any, EFFECTS_TOTAL, NoCallInfo())
30413033
end

0 commit comments

Comments
 (0)