From e7b2499112c5911fb7e9953af00fe5bb8b8ab890 Mon Sep 17 00:00:00 2001 From: Andy Ferris Date: Sun, 3 Jun 2018 14:58:40 +1000 Subject: [PATCH 1/2] Bump tuple inference length cutoff from 16 to 32 --- base/compiler/params.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/compiler/params.jl b/base/compiler/params.jl index 546423e57da6c..8e30d62784c7f 100644 --- a/base/compiler/params.jl +++ b/base/compiler/params.jl @@ -63,7 +63,7 @@ struct Params #=inline_tupleret_bonus, max_methods, union_splitting, apply_union_enum=# 400, 4, 4, 8, #=tupletype_len, tupletype_depth, tuple_splat=# - 15, 3, 16) + 31, 3, 32) end end const DEFAULT_PARAMS = Params(UInt(0)) From 978c39fc7d3cc6b7c302d4252cad8c58d79b3653 Mon Sep 17 00:00:00 2001 From: Andy Ferris Date: Tue, 26 Jun 2018 21:57:52 +1000 Subject: [PATCH 2/2] Remove tupletype_len heuristic --- base/compiler/abstractinterpretation.jl | 10 ++-------- base/compiler/params.jl | 8 +++----- base/compiler/ssair/inlining.jl | 19 ++++++------------- base/compiler/tfuncs.jl | 2 +- base/compiler/typelimits.jl | 15 --------------- test/compiler/compiler.jl | 2 +- 6 files changed, 13 insertions(+), 43 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 1914d72be40c3..400d86ecd8b3e 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -15,7 +15,6 @@ const _REF_NAME = Ref.body.name ######### function abstract_call_gf_by_type(@nospecialize(f), argtypes::Vector{Any}, @nospecialize(atype), sv::InferenceState) - atype = limit_tuple_type(atype, sv.params) atype_params = unwrap_unionall(atype).parameters ft = unwrap_unionall(atype_params[1]) # TODO: ccall jl_first_argument_datatype here isa(ft, DataType) || return Any # the function being called is unknown. can't properly handle this backedge right now @@ -114,7 +113,7 @@ function abstract_call_method_with_const_args(@nospecialize(f), argtypes::Vector method = match[3]::Method nargs::Int = method.nargs method.isva && (nargs -= 1) - length(argtypes) >= nargs || return Any # probably limit_tuple_type made this non-matching method apparently match + length(argtypes) >= nargs || return Any haveconst = false for a in argtypes if isa(a, Const) && !isdefined(typeof(a.val), :instance) && !(isa(a.val, Type) && issingletontype(a.val)) @@ -388,7 +387,7 @@ function abstract_iteration(@nospecialize(itertype), vtypes::VarTable, sv::Infer valtype = statetype = Bottom ret = Any[] stateordonet = widenconst(stateordonet) - while !(Nothing <: stateordonet) && length(ret) < sv.params.MAX_TUPLETYPE_LEN + while !(Nothing <: stateordonet) && length(ret) < sv.params.MAX_TUPLE_SPLAT if !isa(stateordonet, DataType) || !(stateordonet <: Tuple) || isvatuple(stateordonet) || length(stateordonet.parameters) != 2 break end @@ -457,11 +456,6 @@ function abstract_apply(@nospecialize(aft), fargs::Vector{Any}, aargtypes::Vecto ctypes = ctypes´ end for ct in ctypes - if length(ct) > sv.params.MAX_TUPLETYPE_LEN - tail = tuple_tail_elem(Bottom, ct[sv.params.MAX_TUPLETYPE_LEN:end]) - resize!(ct, sv.params.MAX_TUPLETYPE_LEN) - ct[end] = tail - end if isa(aft, Const) rt = abstract_call(aft.val, (), ct, vtypes, sv) elseif isconstType(aft) diff --git a/base/compiler/params.jl b/base/compiler/params.jl index 8e30d62784c7f..8f87feb73484b 100644 --- a/base/compiler/params.jl +++ b/base/compiler/params.jl @@ -28,7 +28,6 @@ struct Params MAX_APPLY_UNION_ENUM::Int # parameters limiting large (tuple) types - MAX_TUPLETYPE_LEN::Int TUPLE_COMPLEXITY_LIMIT_DEPTH::Int # when attempting to inlining _apply, abort the optimization if the tuple @@ -43,7 +42,6 @@ struct Params inline_nonleaf_penalty::Int = DEFAULT_PARAMS.inline_nonleaf_penalty, inline_tupleret_bonus::Int = DEFAULT_PARAMS.inline_tupleret_bonus, max_methods::Int = DEFAULT_PARAMS.MAX_METHODS, - tupletype_len::Int = DEFAULT_PARAMS.MAX_TUPLETYPE_LEN, tupletype_depth::Int = DEFAULT_PARAMS.TUPLE_COMPLEXITY_LIMIT_DEPTH, tuple_splat::Int = DEFAULT_PARAMS.MAX_TUPLE_SPLAT, union_splitting::Int = DEFAULT_PARAMS.MAX_UNION_SPLITTING, @@ -52,7 +50,7 @@ struct Params world, false, inlining, true, false, inline_cost_threshold, inline_nonleaf_penalty, inline_tupleret_bonus, max_methods, union_splitting, apply_union_enum, - tupletype_len, tupletype_depth, tuple_splat) + tupletype_depth, tuple_splat) end function Params(world::UInt) inlining = inlining_enabled() @@ -62,8 +60,8 @@ struct Params inlining, true, false, 100, 1000, #=inline_tupleret_bonus, max_methods, union_splitting, apply_union_enum=# 400, 4, 4, 8, - #=tupletype_len, tupletype_depth, tuple_splat=# - 31, 3, 32) + #=tupletype_depth, tuple_splat=# + 3, 32) end end const DEFAULT_PARAMS = Params(UInt(0)) diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index e904326516bca..d0832f4fe7471 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -838,11 +838,11 @@ function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv:: end isinvoke = (invoke_data !== nothing) - atype_unlimited = argtypes_to_type(atypes) + atype = argtypes_to_type(atypes) # In :invoke, make sure that the arguments we're passing are a subtype of the # signature we're invoking. - (invoke_data === nothing || atype_unlimited <: invoke_data.types0) || continue + (invoke_data === nothing || atype <: invoke_data.types0) || continue # Bail out here if inlining is disabled sv.params.inlining || continue @@ -852,20 +852,13 @@ function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv:: continue end - # Compute the limited type if necessary - if length(atype_unlimited.parameters) - 1 > sv.params.MAX_TUPLETYPE_LEN - atype = limit_tuple_type(atype_unlimited, sv.params) - else - atype = atype_unlimited - end - # Ok, now figure out what method to call if invoke_data !== nothing method = invoke_data.entry.func (metharg, methsp) = ccall(:jl_type_intersection_with_env, Any, (Any, Any), - atype_unlimited, method.sig)::SimpleVector + atype, method.sig)::SimpleVector methsp = methsp::SimpleVector - result = analyze_method!(idx, f, ft, metharg, methsp, method, stmt, atypes, sv, atype_unlimited, isinvoke, isapply, invoke_data, + result = analyze_method!(idx, f, ft, metharg, methsp, method, stmt, atypes, sv, atype, isinvoke, isapply, invoke_data, calltype) handle_single_case!(ir, stmt, idx, result, isinvoke, todo, sv) continue @@ -942,7 +935,7 @@ function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv:: methsp = meth[1][2]::SimpleVector method = meth[1][3]::Method fully_covered = true - case = analyze_method!(idx, f, ft, metharg, methsp, method, stmt, atypes, sv, atype_unlimited, isinvoke, isapply, invoke_data, calltype) + case = analyze_method!(idx, f, ft, metharg, methsp, method, stmt, atypes, sv, atype, isinvoke, isapply, invoke_data, calltype) case === nothing && continue push!(cases, Pair{Any,Any}(metharg, case)) end @@ -955,7 +948,7 @@ function assemble_inline_todo!(ir::IRCode, linetable::Vector{LineInfoNode}, sv:: continue end length(cases) == 0 && continue - push!(todo, UnionSplit(idx, fully_covered, atype_unlimited, isinvoke, cases)) + push!(todo, UnionSplit(idx, fully_covered, atype, isinvoke, cases)) end todo end diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 9fc15e731238d..13279e27326fe 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -843,7 +843,7 @@ add_tfunc(apply_type, 1, INT_INF, apply_type_tfunc, 10) function invoke_tfunc(@nospecialize(ft), @nospecialize(types), @nospecialize(argtype), sv::InferenceState) argument_mt(ft) === nothing && return Any - argtype = typeintersect(types, limit_tuple_type(argtype, sv.params)) + argtype = typeintersect(types, argtype) if argtype === Bottom return Bottom end diff --git a/base/compiler/typelimits.jl b/base/compiler/typelimits.jl index e3a355c6c170f..6cbca28b97738 100644 --- a/base/compiler/typelimits.jl +++ b/base/compiler/typelimits.jl @@ -11,21 +11,6 @@ const MAX_INLINE_CONST_SIZE = 256 # limitation heuristics # ######################### -limit_tuple_type(@nospecialize(t), params::Params) = limit_tuple_type_n(t, params.MAX_TUPLETYPE_LEN) - -function limit_tuple_type_n(@nospecialize(t), lim::Int) - if isa(t, UnionAll) - return UnionAll(t.var, limit_tuple_type_n(t.body, lim)) - end - p = t.parameters - n = length(p) - if n > lim - tail = reduce(typejoin, Bottom, Any[p[lim:(n-1)]..., unwrapva(p[n])]) - return Tuple{p[1:(lim-1)]..., Vararg{tail}} - end - return t -end - # limit the complexity of type `t` to be simpler than the comparison type `compare` # no new values may be introduced, so the parameter `source` encodes the set of all values already present # the outermost tuple type is permitted to have up to `allowed_tuplelen` parameters diff --git a/test/compiler/compiler.jl b/test/compiler/compiler.jl index 909600f418b37..96b14f9b81333 100644 --- a/test/compiler/compiler.jl +++ b/test/compiler/compiler.jl @@ -1030,7 +1030,7 @@ function count_specializations(method::Method) return n::Int end -# demonstrate that inference can complete without waiting for MAX_TUPLETYPE_LEN or MAX_TYPE_DEPTH +# demonstrate that inference can complete without waiting for MAX_TYPE_DEPTH copy_dims_out(out) = () copy_dims_out(out, dim::Int, tail...) = copy_dims_out((out..., dim), tail...) copy_dims_out(out, dim::Colon, tail...) = copy_dims_out((out..., dim), tail...)