2
2
3
3
import Core: _apply, svec, apply_type, Builtin, IntrinsicFunction
4
4
5
- immutable InferenceParams
5
+ type InferenceParams
6
+ # optimization
7
+ optimize:: Bool
8
+ inlining:: Bool
9
+ needtree:: Bool # assigned to, hence not immutable
10
+
6
11
# parameters limiting potentially-infinite types
7
12
MAX_TYPEUNION_LEN:: Int
8
13
MAX_TYPE_DEPTH:: Int
@@ -11,8 +16,13 @@ immutable InferenceParams
11
16
12
17
MAX_TUPLE_SPLAT:: Int
13
18
MAX_UNION_SPLITTING:: Int
19
+
20
+ InferenceParams (;optimize:: Bool = true , inlining:: Bool = inlining_enabled (), needtree:: Bool = true ,
21
+ typeunion_len= 3 :: Int , type_depth= 7 :: Int , tupletype_len= 15 :: Int ,
22
+ tuple_depth= 16 :: Int , tuple_splat= 4 :: Int , union_splitting= 4 :: Int ) =
23
+ new (optimize, inlining, needtree, typeunion_len, type_depth, tupletype_len,
24
+ tuple_depth, tuple_splat, union_splitting)
14
25
end
15
- const DEFAULT_PARAMS = InferenceParams (3 , 7 , 15 , 16 , 4 , 4 )
16
26
17
27
const UNION_SPLIT_MISMATCH_ERROR = false
18
28
@@ -85,14 +95,10 @@ type InferenceState
85
95
# iteration fixed-point detection
86
96
fixedpoint:: Bool
87
97
inworkq:: Bool
88
- # optimization
89
- optimize:: Bool
90
- inlining:: Bool
91
- needtree:: Bool
98
+
92
99
inferred:: Bool
93
100
94
- function InferenceState (linfo:: LambdaInfo , optimize:: Bool , inlining:: Bool , needtree:: Bool ,
95
- params:: InferenceParams , hooks:: InferenceHooks )
101
+ function InferenceState (linfo:: LambdaInfo , params:: InferenceParams , hooks:: InferenceHooks )
96
102
@assert isa (linfo. code,Array{Any,1 })
97
103
nslots = length (linfo. slotnames)
98
104
nl = label_counter (linfo. code)+ 1
@@ -178,7 +184,7 @@ type InferenceState
178
184
ssavalue_uses, ssavalue_init,
179
185
ObjectIdDict (), # Dict{InferenceState, Vector{LineNum}}(),
180
186
Vector {Tuple{InferenceState, Vector{LineNum}}} (),
181
- false , false , optimize, inlining, needtree, false )
187
+ false , false , false )
182
188
push! (active, frame)
183
189
nactive[] += 1
184
190
return frame
@@ -1081,7 +1087,7 @@ function abstract_call(f::ANY, fargs, argtypes::Vector{Any}, vtypes::VarTable, s
1081
1087
return Type
1082
1088
end
1083
1089
1084
- if sv. inlining
1090
+ if sv. params . inlining
1085
1091
# need to model the special inliner for ^
1086
1092
# to ensure we have added the same edge
1087
1093
if isdefined (Main, :Base ) &&
@@ -1474,7 +1480,8 @@ inlining_enabled() = (JLOptions().can_inline == 1)
1474
1480
coverage_enabled () = (JLOptions (). code_coverage != 0 )
1475
1481
1476
1482
# ### entry points for inferring a LambdaInfo given a type signature ####
1477
- function typeinf_edge (method:: Method , atypes:: ANY , sparams:: SimpleVector , needtree:: Bool , optimize:: Bool , cached:: Bool , caller, params:: InferenceParams = DEFAULT_PARAMS, hooks:: InferenceHooks = InferenceHooks ())
1483
+ function typeinf_edge (method:: Method , atypes:: ANY , sparams:: SimpleVector , cached:: Bool , caller,
1484
+ params:: InferenceParams , hooks:: InferenceHooks )
1478
1485
local code = nothing
1479
1486
local frame = nothing
1480
1487
if isa (caller, LambdaInfo)
@@ -1488,14 +1495,14 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
1488
1495
# something completely new
1489
1496
elseif isa (code, LambdaInfo)
1490
1497
# something existing
1491
- if code. inferred && ! (needtree && code. code === nothing )
1498
+ if code. inferred && ! (params . needtree && code. code === nothing )
1492
1499
return (code, code. rettype, true )
1493
1500
end
1494
1501
else
1495
1502
# sometimes just a return type is stored here. if a full AST
1496
1503
# is not needed, we can return it.
1497
1504
typeassert (code, Type)
1498
- if ! needtree
1505
+ if ! params . needtree
1499
1506
return (nothing , code, true )
1500
1507
end
1501
1508
code = nothing
@@ -1574,13 +1581,13 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
1574
1581
end
1575
1582
# TODO : this assertion seems iffy
1576
1583
assert (frame != = nothing )
1577
- if needtree
1578
- frame. needtree = true
1584
+ if params . needtree
1585
+ frame. params . needtree = true
1579
1586
end
1580
1587
else
1581
1588
# inference not started yet, make a new frame for a new lambda
1582
1589
linfo. inInference = true
1583
- frame = InferenceState (unshare_linfo! (linfo:: LambdaInfo ), optimize, inlining_enabled (), needtree, params, hooks)
1590
+ frame = InferenceState (unshare_linfo! (linfo:: LambdaInfo ), params, hooks)
1584
1591
end
1585
1592
frame = frame:: InferenceState
1586
1593
@@ -1606,26 +1613,33 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
1606
1613
end
1607
1614
1608
1615
function typeinf_edge (method:: Method , atypes:: ANY , sparams:: SimpleVector , caller)
1609
- return typeinf_edge (method, atypes, sparams, false , true , true , caller)
1616
+ return typeinf_edge (method, atypes, sparams, true , caller,
1617
+ InferenceParams (needtree= false ), InferenceHooks ())
1610
1618
end
1611
1619
function typeinf (method:: Method , atypes:: ANY , sparams:: SimpleVector , needtree:: Bool = false )
1612
- return typeinf_edge (method, atypes, sparams, needtree, true , true , nothing )
1620
+ return typeinf_edge (method, atypes, sparams, true , nothing ,
1621
+ InferenceParams (needtree= needtree), InferenceHooks ())
1613
1622
end
1614
1623
# compute an inferred (optionally optimized) AST without global effects (i.e. updating the cache)
1615
1624
# TODO : make this use a custom cache, which we then can either keep around or throw away
1616
- function typeinf_uncached (method:: Method , atypes:: ANY , sparams:: ANY ; optimize:: Bool = true , params= DEFAULT_PARAMS, hooks= InferenceHooks ())
1617
- return typeinf_edge (method, atypes, sparams, true , optimize, false , nothing , params, hooks)
1625
+ function typeinf_uncached (method:: Method , atypes:: ANY , sparams:: ANY ;
1626
+ params:: InferenceParams = InferenceParams (),
1627
+ hooks:: InferenceHooks = InferenceHooks ())
1628
+ return typeinf_edge (method, atypes, sparams, false , nothing , params, hooks)
1618
1629
end
1619
- function typeinf_uncached (method:: Method , atypes:: ANY , sparams:: SimpleVector , optimize:: Bool , params= DEFAULT_PARAMS, hooks= InferenceHooks ())
1620
- return typeinf_edge (method, atypes, sparams, true , optimize, false , nothing , params, hooks)
1630
+ function typeinf_uncached (method:: Method , atypes:: ANY , sparams:: SimpleVector ,
1631
+ params:: InferenceParams = InferenceParams (),
1632
+ hooks:: InferenceHooks = InferenceHooks ())
1633
+ return typeinf_edge (method, atypes, sparams, false , nothing , params, hooks)
1621
1634
end
1622
1635
function typeinf_ext (linfo:: LambdaInfo )
1623
1636
if isdefined (linfo, :def )
1624
1637
# method lambda - infer this specialization via the method cache
1625
1638
if linfo. inferred && linfo. code != = nothing
1626
1639
return linfo
1627
1640
end
1628
- (code, _t, inferred) = typeinf_edge (linfo. def, linfo. specTypes, linfo. sparam_vals, true , true , true , linfo)
1641
+ (code, _t, inferred) = typeinf_edge (linfo. def, linfo. specTypes, linfo. sparam_vals, true , linfo,
1642
+ InferenceParams (), InferenceHooks ())
1629
1643
if inferred && code. inferred && linfo != = code
1630
1644
# This case occurs when the IR for a function has been deleted.
1631
1645
# `code` will be a newly-created LambdaInfo, and we need to copy its
@@ -1652,7 +1666,7 @@ function typeinf_ext(linfo::LambdaInfo)
1652
1666
# toplevel lambda - infer directly
1653
1667
linfo. inInference = true
1654
1668
ccall (:jl_typeinf_begin , Void, ())
1655
- frame = InferenceState (linfo, true , inlining_enabled (), true , DEFAULT_PARAMS , InferenceHooks ())
1669
+ frame = InferenceState (linfo, InferenceParams () , InferenceHooks ())
1656
1670
typeinf_loop (frame)
1657
1671
ccall (:jl_typeinf_end , Void, ())
1658
1672
@assert frame. inferred # TODO : deal with this better
@@ -1938,10 +1952,10 @@ function finish(me::InferenceState)
1938
1952
1939
1953
# run optimization passes on fulltree
1940
1954
force_noinline = false
1941
- if me. optimize
1955
+ if me. params . optimize
1942
1956
# This pass is required for the AST to be valid in codegen
1943
1957
# if any `SSAValue` is created by type inference. Ref issue #6068
1944
- # This (and `reindex_labels!`) needs to be run for `!me.optimize`
1958
+ # This (and `reindex_labels!`) needs to be run for `!me.params. optimize`
1945
1959
# if we start to create `SSAValue` in type inference when not
1946
1960
# optimizing and use unoptimized IR in codegen.
1947
1961
gotoifnot_elim_pass! (me. linfo, me)
@@ -1992,12 +2006,12 @@ function finish(me::InferenceState)
1992
2006
me. linfo. inlineable = me. linfo. jlcall_api== 2 || isinlineable (me. linfo)
1993
2007
end
1994
2008
1995
- if ! me. needtree
1996
- me. needtree = me. linfo. inlineable || ccall (:jl_is_cacheable_sig , Int32, (Any, Any, Any),
2009
+ if ! me. params . needtree
2010
+ me. params . needtree = me. linfo. inlineable || ccall (:jl_is_cacheable_sig , Int32, (Any, Any, Any),
1997
2011
me. linfo. specTypes, me. linfo. def. sig, me. linfo. def) != 0
1998
2012
end
1999
2013
2000
- if me. needtree
2014
+ if me. params . needtree
2001
2015
if isdefined (me. linfo, :def )
2002
2016
# compress code for non-toplevel thunks
2003
2017
compressedtree = ccall (:jl_compress_ast , Any, (Any,Any), me. linfo, me. linfo. code)
@@ -2094,7 +2108,6 @@ function type_annotate!(linfo::LambdaInfo, states::Array{Any,1}, sv::ANY, nargs)
2094
2108
body = linfo. code:: Array{Any,1}
2095
2109
nexpr = length (body)
2096
2110
i = 1
2097
- optimize = sv. optimize:: Bool
2098
2111
while i <= nexpr
2099
2112
st_i = states[i]
2100
2113
expr = body[i]
@@ -2107,7 +2120,7 @@ function type_annotate!(linfo::LambdaInfo, states::Array{Any,1}, sv::ANY, nargs)
2107
2120
id = expr. args[1 ]. id
2108
2121
record_slot_type! (id, widenconst (states[i+ 1 ][id]. typ), linfo. slottypes)
2109
2122
end
2110
- elseif optimize
2123
+ elseif sv . params . optimize
2111
2124
if ((isa (expr, Expr) && is_meta_expr (expr:: Expr )) ||
2112
2125
isa (expr, LineNumberNode))
2113
2126
i += 1
@@ -2383,7 +2396,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
2383
2396
end
2384
2397
topmod = _topmod (sv)
2385
2398
# special-case inliners for known pure functions that compute types
2386
- if sv. inlining
2399
+ if sv. params . inlining
2387
2400
if isType (e. typ) && ! has_typevars (e. typ. parameters[1 ],true )
2388
2401
if (is (f, apply_type) || is (f, fieldtype) || is (f, typeof) ||
2389
2402
istopfunction (topmod, f, :typejoin ) ||
@@ -2517,7 +2530,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
2517
2530
end
2518
2531
return NF
2519
2532
end
2520
- if ! sv. inlining
2533
+ if ! sv. params . inlining
2521
2534
return invoke_NF ()
2522
2535
end
2523
2536
@@ -2977,7 +2990,7 @@ function inlining_pass(e::Expr, sv, linfo)
2977
2990
end
2978
2991
end
2979
2992
2980
- if sv. inlining
2993
+ if sv. params . inlining
2981
2994
if isdefined (Main, :Base ) &&
2982
2995
((isdefined (Main. Base, :^ ) && is (f, Main. Base.:^ )) ||
2983
2996
(isdefined (Main. Base, :.^ ) && is (f, Main. Base.:.^ ))) &&
0 commit comments