Skip to content

Commit 8b09da8

Browse files
committed
Move needtree/optimize/inlining into InferenceParams.
1 parent bb6ccf8 commit 8b09da8

File tree

2 files changed

+49
-37
lines changed

2 files changed

+49
-37
lines changed

base/inference.jl

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
import Core: _apply, svec, apply_type, Builtin, IntrinsicFunction
44

5-
immutable InferenceParams
5+
type InferenceParams
6+
# optimization
7+
optimize::Bool
8+
inlining::Bool
9+
needtree::Bool # assigned to, hence not immutable
10+
611
# parameters limiting potentially-infinite types
712
MAX_TYPEUNION_LEN::Int
813
MAX_TYPE_DEPTH::Int
@@ -11,8 +16,13 @@ immutable InferenceParams
1116

1217
MAX_TUPLE_SPLAT::Int
1318
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)
1425
end
15-
const DEFAULT_PARAMS = InferenceParams(3, 7, 15, 16, 4, 4)
1626

1727
const UNION_SPLIT_MISMATCH_ERROR = false
1828

@@ -85,14 +95,10 @@ type InferenceState
8595
# iteration fixed-point detection
8696
fixedpoint::Bool
8797
inworkq::Bool
88-
# optimization
89-
optimize::Bool
90-
inlining::Bool
91-
needtree::Bool
98+
9299
inferred::Bool
93100

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)
96102
@assert isa(linfo.code,Array{Any,1})
97103
nslots = length(linfo.slotnames)
98104
nl = label_counter(linfo.code)+1
@@ -178,7 +184,7 @@ type InferenceState
178184
ssavalue_uses, ssavalue_init,
179185
ObjectIdDict(), #Dict{InferenceState, Vector{LineNum}}(),
180186
Vector{Tuple{InferenceState, Vector{LineNum}}}(),
181-
false, false, optimize, inlining, needtree, false)
187+
false, false, false)
182188
push!(active, frame)
183189
nactive[] += 1
184190
return frame
@@ -1081,7 +1087,7 @@ function abstract_call(f::ANY, fargs, argtypes::Vector{Any}, vtypes::VarTable, s
10811087
return Type
10821088
end
10831089

1084-
if sv.inlining
1090+
if sv.params.inlining
10851091
# need to model the special inliner for ^
10861092
# to ensure we have added the same edge
10871093
if isdefined(Main, :Base) &&
@@ -1474,7 +1480,8 @@ inlining_enabled() = (JLOptions().can_inline == 1)
14741480
coverage_enabled() = (JLOptions().code_coverage != 0)
14751481

14761482
#### 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)
14781485
local code = nothing
14791486
local frame = nothing
14801487
if isa(caller, LambdaInfo)
@@ -1488,14 +1495,14 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
14881495
# something completely new
14891496
elseif isa(code, LambdaInfo)
14901497
# something existing
1491-
if code.inferred && !(needtree && code.code === nothing)
1498+
if code.inferred && !(params.needtree && code.code === nothing)
14921499
return (code, code.rettype, true)
14931500
end
14941501
else
14951502
# sometimes just a return type is stored here. if a full AST
14961503
# is not needed, we can return it.
14971504
typeassert(code, Type)
1498-
if !needtree
1505+
if !params.needtree
14991506
return (nothing, code, true)
15001507
end
15011508
code = nothing
@@ -1574,13 +1581,13 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
15741581
end
15751582
# TODO: this assertion seems iffy
15761583
assert(frame !== nothing)
1577-
if needtree
1578-
frame.needtree = true
1584+
if params.needtree
1585+
frame.params.needtree = true
15791586
end
15801587
else
15811588
# inference not started yet, make a new frame for a new lambda
15821589
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)
15841591
end
15851592
frame = frame::InferenceState
15861593

@@ -1606,26 +1613,33 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, needtr
16061613
end
16071614

16081615
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())
16101618
end
16111619
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())
16131622
end
16141623
# compute an inferred (optionally optimized) AST without global effects (i.e. updating the cache)
16151624
# 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)
16181629
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)
16211634
end
16221635
function typeinf_ext(linfo::LambdaInfo)
16231636
if isdefined(linfo, :def)
16241637
# method lambda - infer this specialization via the method cache
16251638
if linfo.inferred && linfo.code !== nothing
16261639
return linfo
16271640
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())
16291643
if inferred && code.inferred && linfo !== code
16301644
# This case occurs when the IR for a function has been deleted.
16311645
# `code` will be a newly-created LambdaInfo, and we need to copy its
@@ -1652,7 +1666,7 @@ function typeinf_ext(linfo::LambdaInfo)
16521666
# toplevel lambda - infer directly
16531667
linfo.inInference = true
16541668
ccall(:jl_typeinf_begin, Void, ())
1655-
frame = InferenceState(linfo, true, inlining_enabled(), true, DEFAULT_PARAMS, InferenceHooks())
1669+
frame = InferenceState(linfo, InferenceParams(), InferenceHooks())
16561670
typeinf_loop(frame)
16571671
ccall(:jl_typeinf_end, Void, ())
16581672
@assert frame.inferred # TODO: deal with this better
@@ -1938,10 +1952,10 @@ function finish(me::InferenceState)
19381952

19391953
# run optimization passes on fulltree
19401954
force_noinline = false
1941-
if me.optimize
1955+
if me.params.optimize
19421956
# This pass is required for the AST to be valid in codegen
19431957
# 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`
19451959
# if we start to create `SSAValue` in type inference when not
19461960
# optimizing and use unoptimized IR in codegen.
19471961
gotoifnot_elim_pass!(me.linfo, me)
@@ -1992,12 +2006,12 @@ function finish(me::InferenceState)
19922006
me.linfo.inlineable = me.linfo.jlcall_api==2 || isinlineable(me.linfo)
19932007
end
19942008

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),
19972011
me.linfo.specTypes, me.linfo.def.sig, me.linfo.def) != 0
19982012
end
19992013

2000-
if me.needtree
2014+
if me.params.needtree
20012015
if isdefined(me.linfo, :def)
20022016
# compress code for non-toplevel thunks
20032017
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)
20942108
body = linfo.code::Array{Any,1}
20952109
nexpr = length(body)
20962110
i = 1
2097-
optimize = sv.optimize::Bool
20982111
while i <= nexpr
20992112
st_i = states[i]
21002113
expr = body[i]
@@ -2107,7 +2120,7 @@ function type_annotate!(linfo::LambdaInfo, states::Array{Any,1}, sv::ANY, nargs)
21072120
id = expr.args[1].id
21082121
record_slot_type!(id, widenconst(states[i+1][id].typ), linfo.slottypes)
21092122
end
2110-
elseif optimize
2123+
elseif sv.params.optimize
21112124
if ((isa(expr, Expr) && is_meta_expr(expr::Expr)) ||
21122125
isa(expr, LineNumberNode))
21132126
i += 1
@@ -2383,7 +2396,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
23832396
end
23842397
topmod = _topmod(sv)
23852398
# special-case inliners for known pure functions that compute types
2386-
if sv.inlining
2399+
if sv.params.inlining
23872400
if isType(e.typ) && !has_typevars(e.typ.parameters[1],true)
23882401
if (is(f, apply_type) || is(f, fieldtype) || is(f, typeof) ||
23892402
istopfunction(topmod, f, :typejoin) ||
@@ -2517,7 +2530,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
25172530
end
25182531
return NF
25192532
end
2520-
if !sv.inlining
2533+
if !sv.params.inlining
25212534
return invoke_NF()
25222535
end
25232536

@@ -2977,7 +2990,7 @@ function inlining_pass(e::Expr, sv, linfo)
29772990
end
29782991
end
29792992

2980-
if sv.inlining
2993+
if sv.params.inlining
29812994
if isdefined(Main, :Base) &&
29822995
((isdefined(Main.Base, :^) && is(f, Main.Base.:^)) ||
29832996
(isdefined(Main.Base, :.^) && is(f, Main.Base.:.^))) &&

demo.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,10 @@ end
4848
hooks = Core.Inference.InferenceHooks(call_hook)
4949

5050
# raise limits on inference parameters, performing a more exhaustive search
51-
params = Core.Inference.InferenceParams(3, 7, 15, 16, 4, 4)
51+
params = Core.Inference.InferenceParams(type_depth=64)
5252

5353
(linfo, rettyp, inferred) =
54-
Core.Inference.typeinf_uncached(m, sig, spvals, optimize=true,
55-
params=params, hooks=hooks)
54+
Core.Inference.typeinf_uncached(m, sig, spvals, params=params, hooks=hooks)
5655
inferred || error("inference not successful")
5756
println("Returns: $rettyp")
5857
replprint(linfo)

0 commit comments

Comments
 (0)