Skip to content

Commit c1573d9

Browse files
committed
Get rid of get_mi, eagerly infer CodeInstance for task calls
1 parent d3ff821 commit c1573d9

File tree

7 files changed

+60
-82
lines changed

7 files changed

+60
-82
lines changed

src/Cthulhu.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -507,10 +507,9 @@ function _descend(term::AbstractTerminal, interp::AbstractInterpreter, curs::Abs
507507
display_CI = true
508508
view_cmd = cthulhu_typed
509509
iostream = term.out_stream::IO
510-
function additional_descend(new_mi::MethodInstance)
510+
function additional_descend(new_ci::CodeInstance)
511511
new_interp = CthulhuInterpreter(interp)
512-
do_typeinf!(new_interp, new_mi)
513-
_descend(term, new_interp, new_mi;
512+
_descend(term, new_interp, new_ci;
514513
debuginfo, optimize, interruptexc, iswarn, hide_type_stable, remarks,
515514
with_effects, exception_type,
516515
inline_cost, type_annotations, annotate_source,
@@ -538,20 +537,21 @@ function _descend(term::AbstractTerminal, interp::AbstractInterpreter, curs::Abs
538537
# but make something up that looks plausible.
539538
callsites = Callsite[]
540539
if display_CI
541-
exct = @static VERSION v"1.11.0-DEV.945" ? codeinst.exct : nothing
540+
exct = @static VERSION v"1.11.0-DEV.945" ? codeinst.exctype : nothing
542541
callsite = Callsite(-1, EdgeCallInfo(codeinst, codeinst.rettype, get_effects(codeinst), exct), :invoke)
543542
println(iostream)
544543
println(iostream, "│ ─ $callsite")
545544
println(iostream, "│ return ", Const(codeinst.rettype_const))
546545
println(iostream)
547546
end
547+
mi = codeinst.def
548548
@goto show_menu
549549
else
550550
@info """
551551
Inference discarded the source for this call because of recursion:
552552
Cthulhu nevertheless is trying to retrieve the source for further inspection.
553553
"""
554-
additional_descend(get_mi(curs))
554+
additional_descend(get_ci(curs))
555555
break
556556
end
557557
end
@@ -575,7 +575,7 @@ function _descend(term::AbstractTerminal, interp::AbstractInterpreter, curs::Abs
575575
end
576576
pc2excts = nothing
577577
end
578-
callsites, sourcenodes = find_callsites(interp, src, infos, mi, slottypes, optimize & !annotate_source, annotate_source, pc2excts)
578+
callsites, sourcenodes = find_callsites(interp, src, infos, ci, slottypes, optimize & !annotate_source, annotate_source, pc2excts)
579579

580580
if jump_always
581581
if isdefined(Main, :VSCodeServer) && Main.VSCodeServer isa Module && isdefined(Main.VSCodeServer, :openfile)
@@ -671,7 +671,7 @@ function _descend(term::AbstractTerminal, interp::AbstractInterpreter, curs::Abs
671671
if sourcenode !== nothing
672672
show_sub_callsites = let callsite=callsite
673673
map(info.callinfos) do ci
674-
p = Base.unwrap_unionall(get_mi(ci).specTypes).parameters
674+
p = Base.unwrap_unionall(ci.def.specTypes).parameters
675675
if isa(sourcenode, TypedSyntax.MaybeTypedSyntaxNode) && length(p) == length(JuliaSyntax.children(sourcenode)) + 1
676676
newnode = copy(sourcenode)
677677
for (i, child) in enumerate(JuliaSyntax.children(newnode))
@@ -705,7 +705,7 @@ function _descend(term::AbstractTerminal, interp::AbstractInterpreter, curs::Abs
705705
Inference didn't analyze this call because it is a dynamic call:
706706
Cthulhu nevertheless is trying to descend into it for further inspection.
707707
"""
708-
additional_descend(get_mi(info)::MethodInstance)
708+
additional_descend(get_ci(info)::CodeInstance)
709709
continue
710710
elseif info isa RTCallInfo
711711
@info """

src/callsite.jl

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,21 @@ using Unicode
22

33
abstract type CallInfo end
44

5-
get_mi(ci::CallInfo) = get_ci(ci).def
6-
75
# Call could be resolved to a singular MI
86
struct EdgeCallInfo <: CallInfo
9-
ci::Union{CodeInstance,Nothing}
10-
mi::MethodInstance
7+
edge::CodeInstance
118
rt
129
effects::Effects
1310
exct
14-
function EdgeCallInfo(edge::Union{MethodInstance, CodeInstance}, @nospecialize(rt), effects::Effects, @nospecialize(exct=nothing))
15-
ci, mi = isa(edge, MethodInstance) ? (nothing, edge) : (edge, edge.def)
11+
function EdgeCallInfo(edge::CodeInstance, @nospecialize(rt), effects::Effects, @nospecialize(exct=nothing))
1612
if isa(rt, LimitedAccuracy)
17-
return LimitedCallInfo(new(ci, mi, ignorelimited(rt), effects, exct))
13+
return LimitedCallInfo(new(edge, ignorelimited(rt), effects, exct))
1814
else
19-
return new(ci, mi, rt, effects, exct)
15+
return new(edge, rt, effects, exct)
2016
end
2117
end
2218
end
23-
get_ci(ci::EdgeCallInfo) = ci.ci
24-
get_mi(ci::EdgeCallInfo) = ci.mi
19+
get_ci(ci::EdgeCallInfo) = ci.edge
2520
get_rt(ci::EdgeCallInfo) = ci.rt
2621
get_effects(ci::EdgeCallInfo) = ci.effects
2722
get_exct(ci::EdgeCallInfo) = ci.exct
@@ -278,7 +273,7 @@ function Base.show(io::IO, (;exct)::ExctWrapper)
278273
end
279274

280275
function show_callinfo(limiter, ci::EdgeCallInfo)
281-
mi = ci.mi
276+
mi = ci.edge.def
282277
tt = (Base.unwrap_unionall(mi.specTypes)::DataType).parameters[2:end]
283278
if !isa(mi.def, Method)
284279
name = ":toplevel"
@@ -460,12 +455,12 @@ _wrapped_callinfo(limiter, ::LimitedCallInfo) = print(limiter, "limited")
460455

461456
# is_callsite returns true if `call` dispatches to `callee`
462457
# See also `maybe_callsite` below
463-
is_callsite(call::MethodInstance, callee::MethodInstance) = call === callee
458+
is_callsite(call::CodeInstance, callee::MethodInstance) = call.def === callee
464459
is_callsite(::Nothing, callee::MethodInstance) = false # for when `get_mi` returns `nothing`
465460

466461
# is_callsite for higher-level inputs
467462
is_callsite(cs::Callsite, callee::MethodInstance) = is_callsite(cs.info, callee)
468-
is_callsite(info::CallInfo, callee::MethodInstance) = is_callsite(get_mi(info), callee)
463+
is_callsite(info::CallInfo, callee::MethodInstance) = is_callsite(get_ci(info), callee)
469464
# special CallInfo cases:
470465
function is_callsite(info::MultiCallInfo, callee::MethodInstance)
471466
for csi in info.callinfos
@@ -476,7 +471,7 @@ end
476471

477472
# maybe_callsite returns true if `call` *might* dispatch to `callee`
478473
# See also `is_callsite` above
479-
function maybe_callsite(call::MethodInstance, callee::MethodInstance)
474+
function maybe_callsite(call::CodeInstance, callee::MethodInstance)
480475
# handle comparison among Varargs
481476
function generalized_va_subtype(@nospecialize(Tshort), @nospecialize(Tlong))
482477
nshort, nlong = length(Tshort.parameters), length(Tlong.parameters)
@@ -491,7 +486,7 @@ function maybe_callsite(call::MethodInstance, callee::MethodInstance)
491486
return T <: unwrapva(Tlong.parameters[end])
492487
end
493488

494-
Tcall, Tcallee = call.specTypes, callee.specTypes
489+
Tcall, Tcallee = call.def.specTypes, callee.specTypes
495490
Tcall <: Tcallee && return true
496491
# Make sure we handle Tcall = Tuple{Vararg{String}}, Tcallee = Tuple{String,Vararg{String}}
497492
if Base.isvatuple(Tcall) && Base.isvatuple(Tcallee)
@@ -506,7 +501,7 @@ end
506501
# maybe_callsite for higher-level inputs
507502
maybe_callsite(cs::Callsite, callee::MethodInstance) = maybe_callsite(cs.info, callee)
508503
maybe_callsite(cs::Callsite, @nospecialize(tt::Type)) = maybe_callsite(cs.info, tt)
509-
maybe_callsite(info::CallInfo, callee::MethodInstance) = maybe_callsite(get_mi(info), callee)
504+
maybe_callsite(info::CallInfo, callee::MethodInstance) = maybe_callsite(get_ci(info), callee)
510505
# Special CallInfo cases:
511506
function maybe_callsite(info::MultiCallInfo, callee::MethodInstance)
512507
for csi in info.callinfos

src/codeview.jl

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,10 @@ function cthulhu_typed(io::IO, debuginfo::Symbol,
182182
callsite_diagnostics = TypedSyntax.Diagnostic[]
183183
if (diagnostics_vscode || inlay_types_vscode)
184184
vscode_io = IOContext(devnull, :inlay_hints=>vscode_io[:inlay_hints], :diagnostics=>vscode_io[:diagnostics])
185-
callsite_mis = Dict() # type annotation is a bit long so I skipped it, doesn't seem to affect performance
186-
visited_mis = Set{MethodInstance}((mi,))
187-
add_callsites!(callsite_mis, visited_mis, callsite_diagnostics, mi; optimize, annotate_source, interp)
188-
for callsite in values(callsite_mis)
185+
callsite_cis = Dict() # type annotation is a bit long so I skipped it, doesn't seem to affect performance
186+
visited_cis = Set{CodeInstance}((codeinst,))
187+
add_callsites!(callsite_cis, visited_cis, callsite_diagnostics, codeinst; optimize, annotate_source, interp)
188+
for callsite in values(callsite_cis)
189189
if !isnothing(callsite)
190190
descend_into_callsite!(vscode_io, callsite.tsn; iswarn, hide_type_stable, type_annotations)
191191
end
@@ -333,13 +333,14 @@ function descend_into_callsite!(io::IO, tsn::TypedSyntaxNode;
333333
end
334334
end
335335

336-
function add_callsites!(d::AbstractDict, visited_mis::AbstractSet, diagnostics::AbstractVector,
337-
mi::MethodInstance, source_mi::MethodInstance=mi;
336+
function add_callsites!(d::AbstractDict, visited_cis::AbstractSet, diagnostics::AbstractVector,
337+
ci::CodeInstance, source_ci::CodeInstance=ci;
338338
optimize::Bool=true, annotate_source::Bool=false,
339339
interp::AbstractInterpreter=CthulhuInterpreter())
340+
mi = ci.def
340341

341342
callsites, src, rt = try
342-
(; src, rt, infos, slottypes, effects, codeinf) = lookup(interp, mi, optimize & !annotate_source)
343+
(; src, rt, infos, slottypes, effects, codeinf) = lookup(interp, ci, optimize & !annotate_source)
343344

344345
src = preprocess_ci!(src, mi, optimize & !annotate_source, CONFIG)
345346
if (optimize & !annotate_source) || isa(src, IRCode) # optimization might have deleted some statements
@@ -350,23 +351,25 @@ function add_callsites!(d::AbstractDict, visited_mis::AbstractSet, diagnostics::
350351

351352
# We pass false as it doesn't affect callsites and skips fetching the method definition
352353
# using CodeTracking which is slow
353-
callsites, _ = find_callsites(interp, src, infos, mi, slottypes, optimize & !annotate_source, false)
354+
callsites, _ = find_callsites(interp, src, infos, ci, slottypes, optimize & !annotate_source, false)
354355
callsites, src, rt
355356
catch
356357
return nothing
357358
end
358359

359360
for callsite in callsites
360-
callsite_mi = callsite.info isa MultiCallInfo ? nothing : get_mi(callsite)
361+
callsite_ci = callsite.info isa MultiCallInfo ? nothing : get_ci(callsite)
361362

362-
if !isnothing(callsite_mi) && callsite_mi visited_mis
363-
push!(visited_mis, callsite_mi)
364-
add_callsites!(d, visited_mis, diagnostics, callsite_mi, source_mi; optimize, annotate_source, interp)
363+
if !isnothing(callsite_ci) && callsite_ci visited_cis
364+
push!(visited_cis, callsite_ci)
365+
# TODO: figure out why this `CodeInstance` is not present in the unoptimized cache.
366+
callsite_ci.def.def.sig === Tuple{typeof(getproperty), Module, Symbol} && continue
367+
add_callsites!(d, visited_cis, diagnostics, callsite_ci, source_ci; optimize, annotate_source, interp)
365368
end
366369
end
367370

368-
# Check if callsite is not just filling in default arguments and defined in same file as source_mi
369-
if mi == source_mi || mi.def.file != source_mi.def.file
371+
# Check if callsite is not just filling in default arguments and defined in same file as source_ci
372+
if ci == source_ci || ci.def.def.file != source_ci.def.def.file
370373
return nothing
371374
end
372375
tsn, _ = get_typed_sourcetext(mi, src, rt; warn=false)
@@ -390,7 +393,7 @@ function add_callsites!(d::AbstractDict, visited_mis::AbstractSet, diagnostics::
390393
)
391394
end
392395
else
393-
d[key] = (mi=mi, tsn=tsn)
396+
d[key] = (ci=ci, tsn=tsn)
394397
end
395398
end
396399

src/interface.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ get_pc_exct(interp::CthulhuInterpreter, key::InferenceKey) = get(interp.exceptio
7474
# a sensible default cursor for a MethodInstance
7575
AbstractCursor(interp::AbstractInterpreter, ci::CodeInstance) = CthulhuCursor(ci)
7676

77-
get_mi(curs::AbstractCursor) = get_ci(curs).def
78-
7977
mutable struct CustomToggle
8078
onoff::Bool
8179
key::UInt32

src/reflection.jl

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,20 @@ using Base.Meta
66
using Base: may_invoke_generator
77

88
transform(::Val, callsite) = callsite
9-
function transform(::Val{:CuFunction}, callsite, callexpr, CI, mi, slottypes; world=get_world_counter())
9+
function transform(::Val{:CuFunction}, interp, callsite, callexpr, CI, mi, slottypes; world=get_world_counter())
1010
sptypes = sptypes_from_meth_instance(mi)
1111
tt = argextype(callexpr.args[4], CI, sptypes, slottypes)
1212
ft = argextype(callexpr.args[3], CI, sptypes, slottypes)
1313
isa(tt, Const) || return callsite
14-
return Callsite(callsite.id, CuCallInfo(callinfo(Tuple{widenconst(ft), tt.val.parameters...}, Nothing; world)), callsite.head)
14+
sig = Tuple{widenconst(ft), tt.val.parameters...}
15+
return Callsite(callsite.id, CuCallInfo(callinfo(interp, sig, Nothing; world)), callsite.head)
1516
end
1617

1718
function find_callsites(interp::AbstractInterpreter, CI::Union{CodeInfo,IRCode},
18-
stmt_infos::Union{Vector{CCCallInfo}, Nothing}, mi::MethodInstance,
19+
stmt_infos::Union{Vector{CCCallInfo}, Nothing}, ci::CodeInstance,
1920
slottypes::Vector{Any}, optimize::Bool=true, annotate_source::Bool=false,
2021
pc2excts::Union{Nothing,PC2Excts}=nothing)
22+
mi = ci.def
2123
sptypes = sptypes_from_meth_instance(mi)
2224
callsites, sourcenodes = Callsite[], Union{TypedSyntax.MaybeTypedSyntaxNode,Callsite}[]
2325
if isa(CI, IRCode)
@@ -89,7 +91,7 @@ function find_callsites(interp::AbstractInterpreter, CI::Union{CodeInfo,IRCode},
8991
func = args[6]
9092
ftype = widenconst(argextype(func, CI, sptypes, slottypes))
9193
sig = Tuple{ftype}
92-
callsite = Callsite(id, TaskCallInfo(callinfo(sig, nothing; world=get_inference_world(interp))), head)
94+
callsite = Callsite(id, TaskCallInfo(callinfo(interp, sig, nothing; world=get_inference_world(interp))), head)
9395
end
9496
end
9597
end
@@ -101,7 +103,7 @@ function find_callsites(interp::AbstractInterpreter, CI::Union{CodeInfo,IRCode},
101103
ci = get_ci(info)
102104
meth = ci.def.def
103105
if isa(meth, Method) && nameof(meth.module) === :CUDAnative && meth.name === :cufunction
104-
callsite = transform(Val(:CuFunction), callsite, c, CI, ci.def, slottypes; world=get_inference_world(interp))
106+
callsite = transform(Val(:CuFunction), interp, callsite, c, CI, ci.def, slottypes; world=get_inference_world(interp))
105107
end
106108
end
107109

@@ -281,7 +283,7 @@ function preprocess_ci!(ir::IRCode, _::MethodInstance, optimize::Bool, config::C
281283
return ir
282284
end
283285

284-
function callinfo(sig, rt, max_methods=-1; world=get_world_counter())
286+
function callinfo(interp, sig, rt, max_methods=-1; world=get_world_counter())
285287
methds = Base._methods_by_ftype(sig, max_methods, world)
286288
methds isa Bool && return FailedCallInfo(sig, rt)
287289
length(methds) < 1 && return FailedCallInfo(sig, rt)
@@ -295,7 +297,8 @@ function callinfo(sig, rt, max_methods=-1; world=get_world_counter())
295297
else
296298
mi = specialize_method(meth, atypes, sparams)
297299
if mi !== nothing
298-
push!(callinfos, EdgeCallInfo(mi, rt, Effects()))
300+
edge = do_typeinf!(interp, mi)
301+
push!(callinfos, EdgeCallInfo(edge, rt, Effects()))
299302
else
300303
push!(callinfos, FailedCallInfo(sig, rt))
301304
end
@@ -315,7 +318,7 @@ function find_caller_of(interp::AbstractInterpreter, callee::Union{MethodInstanc
315318
for optimize in (true, false)
316319
(; src, rt, infos, slottypes) = lookup(interp′, codeinst, optimize)
317320
src = preprocess_ci!(src, caller, optimize, CONFIG)
318-
callsites, _ = find_callsites(interp′, src, infos, caller, slottypes, optimize)
321+
callsites, _ = find_callsites(interp′, src, infos, codeinst, slottypes, optimize)
319322
callsites = allow_unspecialized ? filter(cs->maybe_callsite(cs, callee), callsites) :
320323
filter(cs->is_callsite(cs, callee), callsites)
321324
foreach(cs -> add_sourceline!(locs, src, cs.id, caller), callsites)

test/setup.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@ end
2222
function find_callsites_by_ftt(@nospecialize(f), @nospecialize(TT=Tuple{}); optimize=true)
2323
(; interp, src, infos, codeinst, slottypes) = cthulhu_info(f, TT; optimize)
2424
src === nothing && return Cthulhu.Callsite[]
25-
callsites, _ = Cthulhu.find_callsites(interp, src, infos, codeinst.def, slottypes, optimize)
25+
callsites, _ = Cthulhu.find_callsites(interp, src, infos, codeinst, slottypes, optimize)
2626
@test all(c -> Cthulhu.get_effects(c) isa Cthulhu.Effects, callsites)
2727
return callsites
2828
end
2929

3030
macro find_callsites_by_ftt(ex0...)
3131
return InteractiveUtils.gen_call_with_extracted_types_and_kwargs(__module__, :find_callsites_by_ftt, ex0)
3232
end
33+
34+
get_mi(callsite::Cthulhu.Callsite) = Cthulhu.get_ci(callsite).def
35+
get_method(callsite::Cthulhu.Callsite) = get_mi(callsite).def

0 commit comments

Comments
 (0)