5
5
using Base. Meta
6
6
import . Compiler: widenconst, argextype, Const, MethodMatchInfo,
7
7
UnionSplitApplyCallInfo, UnionSplitInfo, ConstCallInfo,
8
- MethodResultPure, ApplyCallInfo
8
+ MethodResultPure, ApplyCallInfo,
9
+ sptypes_from_meth_instance, argtypes_to_type
10
+ import Base: may_invoke_generator
9
11
10
- const sptypes_from_meth_instance = Core. Compiler. sptypes_from_meth_instance
11
- const may_invoke_generator = Base. may_invoke_generator
12
12
function code_for_method (method, metharg, methsp, world, preexisting= false )
13
13
@static if VERSION ≥ v " 1.8.0-DEV.369"
14
14
# https://github.com/JuliaLang/julia/pull/41920
15
- Core . Compiler . specialize_method (method, metharg, methsp; preexisting)
15
+ specialize_method (method, metharg, methsp; preexisting)
16
16
else
17
- Core . Compiler . specialize_method (method, metharg, methsp, preexisting)
17
+ specialize_method (method, metharg, methsp, preexisting)
18
18
end
19
19
end
20
20
@@ -27,6 +27,8 @@ function transform(::Val{:CuFunction}, callsite, callexpr, CI, mi, slottypes; pa
27
27
return Callsite (callsite. id, CuCallInfo (callinfo (Tuple{widenconst (ft), tt. val. parameters... }, Nothing, params)), callsite. head)
28
28
end
29
29
30
+ const ArgTypes = Vector{Any}
31
+
30
32
function find_callsites (interp:: CthulhuInterpreter , CI:: Union{Core.CodeInfo, IRCode} ,
31
33
stmt_info:: Union{Vector, Nothing} , mi:: Core.MethodInstance ,
32
34
slottypes:: Vector{Any} , optimize:: Bool = true ;
@@ -47,28 +49,17 @@ function find_callsites(interp::CthulhuInterpreter, CI::Union{Core.CodeInfo, IRC
47
49
if ! optimize
48
50
args = (ignorelhs (c):: Expr ). args
49
51
end
50
- types = mapany (function (@nospecialize (arg),)
51
- t = argextype (arg, CI, sptypes, slottypes)
52
- return widenconst (ignorelimited (t))
53
- end , args)
54
- was_return_type = false
55
- if isa (info, Core. Compiler. ReturnTypeCallInfo)
56
- info = info. info
57
- was_return_type = true
58
- end
59
-
60
- callinfos = process_info (interp, info, types, rt, optimize)
61
- if ! was_return_type && isempty (callinfos)
62
- continue
63
- end
52
+ argtypes = mapany (function (@nospecialize (arg),)
53
+ t = argextype (arg, CI, sptypes, slottypes)
54
+ return widenconst (ignorelimited (t))
55
+ end , args)
56
+ callinfos = process_info (interp, info, argtypes, rt, optimize)
57
+ isempty (callinfos) && continue
64
58
callsite = let
65
59
if length (callinfos) == 1
66
60
callinfo = callinfos[1 ]
67
61
else
68
- callinfo = MultiCallInfo (Compiler. argtypes_to_type (types), rt, callinfos)
69
- end
70
- if was_return_type
71
- callinfo = ReturnTypeCallInfo (callinfo)
62
+ callinfo = MultiCallInfo (argtypes_to_type (argtypes), rt, callinfos)
72
63
end
73
64
Callsite (id, callinfo, c. head)
74
65
end
@@ -113,10 +104,9 @@ function find_callsites(interp::CthulhuInterpreter, CI::Union{Core.CodeInfo, IRC
113
104
return callsites
114
105
end
115
106
116
- function process_info (interp, @nospecialize (info), types , @nospecialize (rt), optimize:: Bool )
107
+ function process_info (interp, @nospecialize (info), argtypes :: ArgTypes , @nospecialize (rt), optimize:: Bool )
117
108
is_cached (@nospecialize (key)) = haskey (optimize ? interp. opt : interp. unopt, key)
118
- process_recursive (@nospecialize (newinfo)) = process_info (interp, newinfo, types, rt, optimize)
119
-
109
+ process_recursive (@nospecialize (newinfo)) = process_info (interp, newinfo, argtypes, rt, optimize)
120
110
121
111
if isa (info, MethodMatchInfo)
122
112
if info. results === missing
@@ -125,12 +115,12 @@ function process_info(interp, @nospecialize(info), types, @nospecialize(rt), opt
125
115
126
116
matches = info. results. matches
127
117
return mapany (matches) do match:: Core.MethodMatch
128
- mi = Core . Compiler . specialize_method (match)
118
+ mi = specialize_method (match)
129
119
mici = MICallInfo (mi, rt)
130
120
return is_cached (mi) ? mici : UncachedCallInfo (mici)
131
121
end
132
122
elseif isa (info, MethodResultPure)
133
- return Any[PureCallInfo (types , rt)]
123
+ return Any[PureCallInfo (argtypes , rt)]
134
124
elseif isa (info, UnionSplitInfo)
135
125
return mapreduce (process_recursive, vcat, info. matches; init= []):: Vector{Any}
136
126
elseif isa (info, UnionSplitApplyCallInfo)
@@ -158,16 +148,33 @@ function process_info(interp, @nospecialize(info), types, @nospecialize(rt), opt
158
148
elseif (@static isdefined (Compiler, :OpaqueClosureCreateInfo ) && true ) && isa (info, Compiler. OpaqueClosureCreateInfo)
159
149
# TODO : Add ability to descend into OCs at creation site
160
150
return []
151
+ elseif isa (info, Compiler. ReturnTypeCallInfo)
152
+ newargtypes = argtypes[2 : end ]
153
+ callinfos = process_info (interp, info. info, newargtypes, unwrapType (widenconst (rt)), optimize)
154
+ if length (callinfos) == 1
155
+ vmi = only (callinfos)
156
+ else
157
+ @assert isempty (callinfos)
158
+ argt = unwrapType (widenconst (newargtypes[2 ])):: DataType
159
+ sig = Tuple{widenconst (newargtypes[1 ]), argt. parameters... }
160
+ vmi = FailedCallInfo (sig, Union{})
161
+ end
162
+ return Any[ReturnTypeCallInfo (vmi)]
161
163
elseif info == false
162
164
return []
163
165
else
164
- @show CI
165
- @show c
166
- @show info
167
- error ()
166
+ @eval Main begin
167
+ interp = $ interp
168
+ info = $ info
169
+ argtypes = $ argtypes
170
+ rt = $ rt
171
+ optimize = $ optimize
172
+ end
173
+ error (" inspect `Main.interp|info|argtypes|rt|optimize`" )
168
174
end
169
175
end
170
176
177
+ unwrapType (@nospecialize t) = Compiler. isType (t) ? t. parameters[1 ] : t
171
178
172
179
ignorelhs (@nospecialize (x)) = isexpr (x, :(= )) ? last (x. args) : x
173
180
function is_call_expr (x:: Expr , optimize:: Bool )
0 commit comments