@@ -72,11 +72,13 @@ type InferenceState
7272 fixedpoint:: Bool
7373 typegotoredo:: Bool
7474 inworkq:: Bool
75+ # optimization
7576 optimize:: Bool
77+ inlining:: Bool
7678 needtree:: Bool
7779 inferred:: Bool
7880
79- function InferenceState (linfo:: LambdaInfo , optimize:: Bool , needtree:: Bool )
81+ function InferenceState (linfo:: LambdaInfo , optimize:: Bool , inlining :: Bool , needtree:: Bool )
8082 @assert isa (linfo. code,Array{Any,1 })
8183 nslots = length (linfo. slotnames)
8284 nl = label_counter (linfo. code)+ 1
@@ -161,7 +163,7 @@ type InferenceState
161163 ssavalue_uses, ssavalue_init,
162164 ObjectIdDict (), # Dict{InferenceState, Vector{LineNum}}(),
163165 Vector {Tuple{InferenceState, Vector{LineNum}}} (),
164- false , false , false , optimize, needtree, false )
166+ false , false , false , optimize, inlining, needtree, false )
165167 push! (active, frame)
166168 nactive[] += 1
167169 return frame
@@ -1408,6 +1410,8 @@ function unshare_linfo!(li::LambdaInfo)
14081410 return li
14091411end
14101412
1413+ inlining_enabled () = (JLOptions (). can_inline == 1 )
1414+
14111415# ### entry points for inferring a LambdaInfo given a type signature ####
14121416function typeinf_edge (method:: Method , atypes:: ANY , sparams:: SimpleVector , needtree:: Bool , optimize:: Bool , cached:: Bool , caller)
14131417 local code = nothing
@@ -1510,7 +1514,7 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
15101514 else
15111515 # inference not started yet, make a new frame for a new lambda
15121516 linfo. inInference = true
1513- frame = InferenceState (unshare_linfo! (linfo:: LambdaInfo ), optimize, needtree)
1517+ frame = InferenceState (unshare_linfo! (linfo:: LambdaInfo ), optimize, inlining_enabled (), needtree)
15141518 end
15151519 frame = frame:: InferenceState
15161520
@@ -1571,7 +1575,7 @@ function typeinf_ext(linfo::LambdaInfo)
15711575 else
15721576 # toplevel lambda - infer directly
15731577 linfo. inInference = true
1574- frame = InferenceState (linfo, true , true )
1578+ frame = InferenceState (linfo, true , inlining_enabled (), true )
15751579 typeinf_loop (frame)
15761580 @assert frame. inferred # TODO : deal with this better
15771581 return linfo
@@ -1921,10 +1925,8 @@ function finish(me::InferenceState)
19211925 # if we start to create `SSAValue` in type inference when not
19221926 # optimizing and use unoptimized IR in codegen.
19231927 gotoifnot_elim_pass! (me. linfo, me)
1924- if JLOptions (). can_inline == 1
1925- inlining_pass! (me. linfo, me)
1926- inbounds_meta_elim_pass! (me. linfo. code)
1927- end
1928+ inlining_pass! (me. linfo, me)
1929+ inbounds_meta_elim_pass! (me. linfo. code)
19281930 alloc_elim_pass! (me. linfo, me)
19291931 getfield_elim_pass! (me. linfo, me)
19301932 reindex_labels! (me. linfo, me)
@@ -2322,28 +2324,30 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
23222324 end
23232325 end
23242326 topmod = _topmod (sv)
2325- if istopfunction (topmod, f, :isbits ) && length (atypes)== 2 && isType (atypes[2 ]) &&
2326- effect_free (argexprs[2 ],sv,true ) && isleaftype (atypes[2 ]. parameters[1 ])
2327- return (isbits (atypes[2 ]. parameters[1 ]),())
2328- end
23292327 # special-case inliners for known pure functions that compute types
2330- if isType (e. typ) && ! has_typevars (e. typ. parameters[1 ],true )
2331- if (is (f, apply_type) || is (f, fieldtype) || is (f, typeof) ||
2332- istopfunction (topmod, f, :typejoin ) ||
2333- istopfunction (topmod, f, :promote_type ))
2334- # XXX : compute effect_free for the actual arguments
2335- if length (argexprs) < 2 || effect_free (argexprs[2 ], sv, true )
2336- return (e. typ. parameters[1 ],())
2337- else
2338- return (e. typ. parameters[1 ], Any[argexprs[2 ]])
2328+ if sv. inlining
2329+ if isType (e. typ) && ! has_typevars (e. typ. parameters[1 ],true )
2330+ if (is (f, apply_type) || is (f, fieldtype) || is (f, typeof) ||
2331+ istopfunction (topmod, f, :typejoin ) ||
2332+ istopfunction (topmod, f, :promote_type ))
2333+ # XXX : compute effect_free for the actual arguments
2334+ if length (argexprs) < 2 || effect_free (argexprs[2 ], sv, true )
2335+ return (e. typ. parameters[1 ],())
2336+ else
2337+ return (e. typ. parameters[1 ], Any[argexprs[2 ]])
2338+ end
23392339 end
23402340 end
2341- end
2342- if is (f, Core. kwfunc) && length (argexprs) == 2 && isa (e. typ, Const)
2343- if effect_free (argexprs[2 ], sv, true )
2344- return (e. typ. val, ())
2345- else
2346- return (e. typ. val, Any[argexprs[2 ]])
2341+ if istopfunction (topmod, f, :isbits ) && length (atypes)== 2 && isType (atypes[2 ]) &&
2342+ effect_free (argexprs[2 ],sv,true ) && isleaftype (atypes[2 ]. parameters[1 ])
2343+ return (isbits (atypes[2 ]. parameters[1 ]),())
2344+ end
2345+ if is (f, Core. kwfunc) && length (argexprs) == 2 && isa (e. typ, Const)
2346+ if effect_free (argexprs[2 ], sv, true )
2347+ return (e. typ. val, ())
2348+ else
2349+ return (e. typ. val, Any[argexprs[2 ]])
2350+ end
23472351 end
23482352 end
23492353 if isa (f, IntrinsicFunction) || ft ⊑ IntrinsicFunction ||
@@ -2352,11 +2356,6 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
23522356 end
23532357
23542358 atype_unlimited = argtypes_to_type (atypes)
2355- if length (atype_unlimited. parameters) - 1 > MAX_TUPLETYPE_LEN
2356- atype = limit_tuple_type (atype_unlimited)
2357- else
2358- atype = atype_unlimited
2359- end
23602359 function invoke_NF ()
23612360 # converts a :call to :invoke
23622361 cache_linfo = ccall (:jl_get_spec_lambda , Any, (Any,), atype_unlimited)
@@ -2366,6 +2365,15 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
23662365 end
23672366 return NF
23682367 end
2368+ if ! sv. inlining
2369+ return invoke_NF ()
2370+ end
2371+
2372+ if length (atype_unlimited. parameters) - 1 > MAX_TUPLETYPE_LEN
2373+ atype = limit_tuple_type (atype_unlimited)
2374+ else
2375+ atype = atype_unlimited
2376+ end
23692377 meth = _methods_by_ftype (atype, 1 )
23702378 if meth === false || length (meth) != 1
23712379 return invoke_NF ()
@@ -2943,7 +2951,7 @@ function inlining_pass(e::Expr, sv, linfo)
29432951 end
29442952 end
29452953
2946- if isdefined (Main, :Base ) &&
2954+ if sv . inlining && isdefined (Main, :Base ) &&
29472955 ((isdefined (Main. Base, :^ ) && is (f, Main. Base.:^ )) ||
29482956 (isdefined (Main. Base, :.^ ) && is (f, Main. Base.:.^ )))
29492957 if length (e. args) == 3 && isa (e. args[3 ],Union{Int32,Int64})
0 commit comments