11# This file is a part of Julia. License is MIT: https://julialang.org/license
22
3- """
4- matching_cache_argtypes(𝕃::AbstractLattice, mi::MethodInstance) ->
5- (cache_argtypes::Vector{Any}, overridden_by_const::BitVector)
6-
7- Returns argument types `cache_argtypes::Vector{Any}` for `mi` that are in the native
8- Julia type domain. `overridden_by_const::BitVector` is all `false` meaning that
9- there is no additional extended lattice information there.
10-
11- matching_cache_argtypes(𝕃::AbstractLattice, mi::MethodInstance, argtypes::ForwardableArgtypes) ->
12- (cache_argtypes::Vector{Any}, overridden_by_const::BitVector)
13-
14- Returns cache-correct extended lattice argument types `cache_argtypes::Vector{Any}`
15- for `mi` given some `argtypes` accompanied by `overridden_by_const::BitVector`
16- that marks which argument contains additional extended lattice information.
17-
18- In theory, there could be a `cache` containing a matching `InferenceResult`
19- for the provided `mi` and `given_argtypes`. The purpose of this function is
20- to return a valid value for `cache_lookup(𝕃, mi, argtypes, cache).argtypes`,
21- so that we can construct cache-correct `InferenceResult`s in the first place.
22- """
23- function matching_cache_argtypes end
24-
253function matching_cache_argtypes (𝕃:: AbstractLattice , mi:: MethodInstance )
26- method = isa (mi. def, Method) ? mi. def:: Method : nothing
27- cache_argtypes = most_general_argtypes (method, mi. specTypes)
28- overridden_by_const = falses (length (cache_argtypes))
29- return cache_argtypes, overridden_by_const
4+ (; def, specTypes) = mi
5+ return most_general_argtypes (isa (def, Method) ? def : nothing , specTypes)
306end
317
32- struct SimpleArgtypes <: ForwardableArgtypes
8+ struct SimpleArgtypes
339 argtypes:: Vector{Any}
3410end
3511
36- """
37- matching_cache_argtypes(𝕃::AbstractLattice, mi::MethodInstance, argtypes::SimpleArgtypes)
38-
39- The implementation for `argtypes` with general extended lattice information.
40- This is supposed to be used for debugging and testing or external `AbstractInterpreter`
41- usages and in general `matching_cache_argtypes(::MethodInstance, ::ConditionalArgtypes)`
42- is more preferred it can forward `Conditional` information.
43- """
44- function matching_cache_argtypes (𝕃:: AbstractLattice , mi:: MethodInstance , simple_argtypes:: SimpleArgtypes )
12+ function matching_cache_argtypes (𝕃:: AbstractLattice , mi:: MethodInstance ,
13+ simple_argtypes:: SimpleArgtypes ,
14+ cache_argtypes:: Vector{Any} )
4515 (; argtypes) = simple_argtypes
4616 given_argtypes = Vector {Any} (undef, length (argtypes))
4717 for i = 1 : length (argtypes)
4818 given_argtypes[i] = widenslotwrapper (argtypes[i])
4919 end
5020 given_argtypes = va_process_argtypes (𝕃, given_argtypes, mi)
51- return pick_const_args (𝕃, mi, given_argtypes )
21+ return pick_const_args! (𝕃, given_argtypes, cache_argtypes )
5222end
5323
54- function pick_const_args (𝕃:: AbstractLattice , mi:: MethodInstance , given_argtypes:: Vector{Any} )
55- cache_argtypes, overridden_by_const = matching_cache_argtypes (𝕃, mi)
56- return pick_const_args! (𝕃, cache_argtypes, overridden_by_const, given_argtypes)
57- end
58-
59- function pick_const_args! (𝕃:: AbstractLattice , cache_argtypes:: Vector{Any} , overridden_by_const:: BitVector , given_argtypes:: Vector{Any} )
60- for i = 1 : length (given_argtypes)
24+ function pick_const_args! (𝕃:: AbstractLattice , given_argtypes:: Vector{Any} , cache_argtypes:: Vector{Any} )
25+ nargtypes = length (given_argtypes)
26+ @assert nargtypes == length (cache_argtypes) #= == nargs =# " invalid `given_argtypes` for `mi`"
27+ for i = 1 : nargtypes
6128 given_argtype = given_argtypes[i]
6229 cache_argtype = cache_argtypes[i]
6330 if ! is_argtype_match (𝕃, given_argtype, cache_argtype, false )
@@ -66,13 +33,13 @@ function pick_const_args!(𝕃::AbstractLattice, cache_argtypes::Vector{Any}, ov
6633 ! ⊏ (𝕃, given_argtype, cache_argtype))
6734 # if the type information of this `PartialStruct` is less strict than
6835 # declared method signature, narrow it down using `tmeet`
69- given_argtype = tmeet (𝕃, given_argtype, cache_argtype)
36+ given_argtypes[i] = tmeet (𝕃, given_argtype, cache_argtype)
7037 end
71- cache_argtypes[i] = given_argtype
72- overridden_by_const [i] = true
38+ else
39+ given_argtypes [i] = cache_argtype
7340 end
7441 end
75- return cache_argtypes, overridden_by_const
42+ return given_argtypes
7643end
7744
7845function is_argtype_match (𝕃:: AbstractLattice ,
8956va_process_argtypes (𝕃:: AbstractLattice , given_argtypes:: Vector{Any} , mi:: MethodInstance ) =
9057 va_process_argtypes (Returns (nothing ), 𝕃, given_argtypes, mi)
9158function va_process_argtypes (@specialize (va_handler!), 𝕃:: AbstractLattice , given_argtypes:: Vector{Any} , mi:: MethodInstance )
92- def = mi. def
93- isva = isa ( def, Method) ? def . isva : false
94- nargs = isa (def, Method) ? Int (def. nargs) : length (mi . specTypes . parameters )
59+ def = mi. def:: Method
60+ isva = def. isva
61+ nargs = Int (def. nargs)
9562 if isva || isvarargtype (given_argtypes[end ])
9663 isva_given_argtypes = Vector {Any} (undef, nargs)
9764 for i = 1 : (nargs- isva)
@@ -112,14 +79,11 @@ function va_process_argtypes(@specialize(va_handler!), 𝕃::AbstractLattice, gi
11279 return given_argtypes
11380end
11481
115- function most_general_argtypes (method:: Union{Method, Nothing} , @nospecialize (specTypes),
116- withfirst:: Bool = true )
82+ function most_general_argtypes (method:: Union{Method,Nothing} , @nospecialize (specTypes))
11783 toplevel = method === nothing
11884 isva = ! toplevel && method. isva
11985 mi_argtypes = Any[(unwrap_unionall (specTypes):: DataType ). parameters... ]
12086 nargs:: Int = toplevel ? 0 : method. nargs
121- # For opaque closure, the closure environment is processed elsewhere
122- withfirst || (nargs -= 1 )
12387 cache_argtypes = Vector {Any} (undef, nargs)
12488 # First, if we're dealing with a varargs method, then we set the last element of `args`
12589 # to the appropriate `Tuple` type or `PartialStruct` instance.
@@ -162,17 +126,16 @@ function most_general_argtypes(method::Union{Method, Nothing}, @nospecialize(spe
162126 cache_argtypes[nargs] = vargtype
163127 nargs -= 1
164128 end
165- # Now, we propagate type info from `linfo_argtypes ` into `cache_argtypes`, improving some
129+ # Now, we propagate type info from `mi_argtypes ` into `cache_argtypes`, improving some
166130 # type info as we go (where possible). Note that if we're dealing with a varargs method,
167131 # we already handled the last element of `cache_argtypes` (and decremented `nargs` so that
168132 # we don't overwrite the result of that work here).
169133 if mi_argtypes_length > 0
170- n = mi_argtypes_length > nargs ? nargs : mi_argtypes_length
171- tail_index = n
134+ tail_index = nargtypes = min (mi_argtypes_length, nargs)
172135 local lastatype
173- for i = 1 : n
136+ for i = 1 : nargtypes
174137 atyp = mi_argtypes[i]
175- if i == n && isvarargtype (atyp)
138+ if i == nargtypes && isvarargtype (atyp)
176139 atyp = unwrapva (atyp)
177140 tail_index -= 1
178141 end
@@ -185,16 +148,16 @@ function most_general_argtypes(method::Union{Method, Nothing}, @nospecialize(spe
185148 else
186149 atyp = elim_free_typevars (rewrap_unionall (atyp, specTypes))
187150 end
188- i == n && (lastatype = atyp)
151+ i == nargtypes && (lastatype = atyp)
189152 cache_argtypes[i] = atyp
190153 end
191- for i = (tail_index + 1 ): nargs
154+ for i = (tail_index+ 1 ): nargs
192155 cache_argtypes[i] = lastatype
193156 end
194157 else
195158 @assert nargs == 0 " invalid specialization of method" # wrong number of arguments
196159 end
197- cache_argtypes
160+ return cache_argtypes
198161end
199162
200163# eliminate free `TypeVar`s in order to make the life much easier down the road:
@@ -213,22 +176,15 @@ end
213176function cache_lookup (𝕃:: AbstractLattice , mi:: MethodInstance , given_argtypes:: Vector{Any} ,
214177 cache:: Vector{InferenceResult} )
215178 method = mi. def:: Method
216- nargs = Int (method. nargs)
217- method. isva && (nargs -= 1 )
218- length (given_argtypes) ≥ nargs || return nothing
179+ nargtypes = length (given_argtypes)
180+ @assert nargtypes == Int (method. nargs) " invalid `given_argtypes` for `mi`"
219181 for cached_result in cache
220- cached_result. linfo === mi || continue
182+ cached_result. linfo === mi || @goto next_cache
221183 cache_argtypes = cached_result. argtypes
222- cache_overridden_by_const = cached_result. overridden_by_const
223- for i in 1 : nargs
224- if ! is_argtype_match (𝕃, widenmustalias (given_argtypes[i]),
225- cache_argtypes[i], cache_overridden_by_const[i])
226- @goto next_cache
227- end
228- end
229- if method. isva
230- if ! is_argtype_match (𝕃, tuple_tfunc (𝕃, given_argtypes[(nargs + 1 ): end ]),
231- cache_argtypes[end ], cache_overridden_by_const[end ])
184+ @assert length (cache_argtypes) == nargtypes " invalid `cache_argtypes` for `mi`"
185+ cache_overridden_by_const = cached_result. overridden_by_const:: BitVector
186+ for i in 1 : nargtypes
187+ if ! is_argtype_match (𝕃, given_argtypes[i], cache_argtypes[i], cache_overridden_by_const[i])
232188 @goto next_cache
233189 end
234190 end
0 commit comments