@@ -89,7 +89,8 @@ function abstract_call_gf_by_type(@nospecialize(f), argtypes::Vector{Any}, @nosp
8989 this_rt === Any && break
9090 end
9191 else
92- this_rt, edgecycle, edge = abstract_call_method (method, sig, match[2 ]:: SimpleVector , sv)
92+ this_rt, edgecycle1, edge = abstract_call_method (method, sig, match[2 ]:: SimpleVector , sv)
93+ edgecycle |= edgecycle1:: Bool
9394 if edge != = nothing
9495 push! (edges, edge)
9596 end
@@ -170,53 +171,58 @@ function abstract_call_method_with_const_args(@nospecialize(rettype), @nospecial
170171 method. isva && (nargs -= 1 )
171172 length (argtypes) >= nargs || return Any
172173 haveconst = false
174+ allconst = true
175+ # see if any or all of the arguments are constant and propagating constants may be worthwhile
173176 for a in argtypes
174177 a = widenconditional (a)
175- if has_nontrivial_const_info (a)
176- haveconst = const_prop_profitable (a)
177- haveconst && break
178+ if allconst && ! isa (a, Const) && ! isconstType (a) && ! isa (a, PartialStruct)
179+ allconst = false
180+ end
181+ if ! haveconst && has_nontrivial_const_info (a) && const_prop_profitable (a)
182+ haveconst = true
183+ end
184+ if haveconst && ! allconst
185+ break
178186 end
179187 end
180188 haveconst || improvable_via_constant_propagation (rettype) || return Any
181189 sig = match[1 ]
182190 sparams = match[2 ]:: SimpleVector
183- code = code_for_method (method, sig, sparams, sv. params. world)
184- code === nothing && return Any
185- code = code:: MethodInstance
186- # decide if it's likely to be worthwhile
187- declared_inline = isdefined (method, :source ) && ccall (:jl_ast_flag_inlineable , Bool, (Any,), method. source)
188- cache_inlineable = declared_inline
189- if isdefined (code, :inferred ) && ! cache_inlineable
190- cache_inf = code. inferred
191- if ! (cache_inf === nothing )
192- cache_src_inferred = ccall (:jl_ast_flag_inferred , Bool, (Any,), cache_inf)
193- cache_src_inlineable = ccall (:jl_ast_flag_inlineable , Bool, (Any,), cache_inf)
194- cache_inlineable = cache_src_inferred && cache_src_inlineable
195- end
191+ force_inference = allconst || sv. params. aggressive_constant_propagation
192+ if istopfunction (f, :getproperty ) || istopfunction (f, :setproperty! )
193+ force_inference = true
196194 end
197- if ! cache_inlineable && ! sv. params. aggressive_constant_propagation
198- tm = _topmod (sv)
199- if ! istopfunction (f, :getproperty ) && ! istopfunction (f, :setproperty! )
200- # in this case, see if all of the arguments are constants
201- for a in argtypes
202- a = widenconditional (a)
203- if ! isa (a, Const) && ! isconstType (a) && ! isa (a, PartialStruct)
204- return Any
205- end
195+ mi = specialize_method (method, sig, sparams, ! force_inference)
196+ mi === nothing && return Any
197+ mi = mi:: MethodInstance
198+ # decide if it's likely to be worthwhile
199+ if ! force_inference
200+ code = inf_for_methodinstance (mi, sv. params. world)
201+ declared_inline = isdefined (method, :source ) && ccall (:jl_ast_flag_inlineable , Bool, (Any,), method. source)
202+ cache_inlineable = declared_inline
203+ if isdefined (code, :inferred ) && ! cache_inlineable
204+ cache_inf = code. inferred
205+ if ! (cache_inf === nothing )
206+ cache_src_inferred = ccall (:jl_ast_flag_inferred , Bool, (Any,), cache_inf)
207+ cache_src_inlineable = ccall (:jl_ast_flag_inlineable , Bool, (Any,), cache_inf)
208+ cache_inlineable = cache_src_inferred && cache_src_inlineable
206209 end
207210 end
211+ if ! cache_inlineable
212+ return Any
213+ end
208214 end
209- inf_result = cache_lookup (code , argtypes, sv. params. cache)
215+ inf_result = cache_lookup (mi , argtypes, sv. params. cache)
210216 if inf_result === nothing
211- inf_result = InferenceResult (code , argtypes)
217+ inf_result = InferenceResult (mi , argtypes)
212218 frame = InferenceState (inf_result, #= cache=# false , sv. params)
213219 frame. limited = true
214220 frame. parent = sv
215221 push! (sv. params. cache, inf_result)
216222 typeinf (frame) || return Any
217223 end
218224 result = inf_result. result
219- isa (result, InferenceState) && return Any # TODO : is this recursive constant inference?
225+ isa (result, InferenceState) && return Any # TODO : unexpected, is this recursive constant inference?
220226 add_backedge! (inf_result. linfo, sv)
221227 return result
222228end
@@ -237,7 +243,7 @@ function abstract_call_method(method::Method, @nospecialize(sig), sparams::Simpl
237243 # necessary in order to retrieve this field from the generated `CodeInfo`, if it exists.
238244 # The other `CodeInfo`s we inspect will already have this field inflated, so we just
239245 # access it directly instead (to avoid regeneration).
240- method2 = method_for_inference_heuristics (method, sig, sparams, sv . params . world ) # Union{Method, Nothing}
246+ method2 = method_for_inference_heuristics (method, sig, sparams) # Union{Method, Nothing}
241247 sv_method2 = sv. src. method_for_inference_limit_heuristics # limit only if user token match
242248 sv_method2 isa Method || (sv_method2 = nothing ) # Union{Method, Nothing}
243249 while ! (infstate === nothing )
0 commit comments