Skip to content

Commit

Permalink
some inlining cost model updates
Browse files Browse the repository at this point in the history
- treat arrayset like arrayref
- higher cost for passing unknown things to builtins
- add small cost for forward branches
- add small cost for sizeof, nfields, isa, subtype
- remove `nkw` meta after it's consumed
  • Loading branch information
JeffBezanson committed Mar 26, 2020
1 parent 1f78749 commit 05dfb5c
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 13 deletions.
21 changes: 17 additions & 4 deletions base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -315,17 +315,30 @@ function statement_cost(ex::Expr, line::Int, src::CodeInfo, sptypes::Vector{Any}
# tuple iteration/destructuring makes that impossible
# return plus_saturate(argcost, isknowntype(extyp) ? 1 : params.inline_nonleaf_penalty)
return 0
elseif (f === Main.Core.arrayref || f === Main.Core.const_arrayref) && length(ex.args) >= 3
elseif (f === Main.Core.arrayref || f === Main.Core.const_arrayref || f === Main.Core.arrayset) && length(ex.args) >= 3
atyp = argextype(ex.args[3], src, sptypes, slottypes)
return isknowntype(atyp) ? 4 : params.inline_nonleaf_penalty
elseif (f === isa || f === typeassert) && isconstType(widenconst(argextype(ex.args[3], src, sptypes, slottypes)))
return 1
elseif f === typeof
return 1
end
fidx = find_tfunc(f)
if fidx === nothing
# unknown/unhandled builtin or anonymous function
# unknown/unhandled builtin
# Use the generic cost of a direct function call
return 20
end
return T_FFUNC_COST[fidx]
cost = T_FFUNC_COST[fidx]
if cost < 20
for i = 2:length(ex.args)
argtyp = argextype(ex.args[i], src, sptypes, slottypes)
if !(isknowntype(argtyp) || isType(argtyp))
return 20
end
end
end
return cost
end
return params.inline_nonleaf_penalty
elseif head === :foreigncall || head === :invoke
Expand Down Expand Up @@ -366,7 +379,7 @@ function statement_cost(ex::Expr, line::Int, src::CodeInfo, sptypes::Vector{Any}
# loops are generally always expensive
# but assume that forward jumps are already counted for from
# summing the cost of the not-taken branch
return target < line ? 40 : 0
return target < line ? 40 : 1
end
return 0
end
Expand Down
8 changes: 4 additions & 4 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ function sizeof_tfunc(@nospecialize(x),)
isprimitivetype(x) && return _const_sizeof(x)
return Int
end
add_tfunc(Core.sizeof, 1, 1, sizeof_tfunc, 0)
add_tfunc(Core.sizeof, 1, 1, sizeof_tfunc, 1)
function nfields_tfunc(@nospecialize(x))
isa(x, Const) && return Const(nfields(x.val))
isa(x, Conditional) && return Const(0)
Expand All @@ -354,7 +354,7 @@ function nfields_tfunc(@nospecialize(x))
end
return Int
end
add_tfunc(nfields, 1, 1, nfields_tfunc, 0)
add_tfunc(nfields, 1, 1, nfields_tfunc, 1)
add_tfunc(Core._expr, 1, INT_INF, (@nospecialize args...)->Expr, 100)
function typevar_tfunc(@nospecialize(n), @nospecialize(lb_arg), @nospecialize(ub_arg))
lb = Union{}
Expand Down Expand Up @@ -537,7 +537,7 @@ function isa_tfunc(@nospecialize(v), @nospecialize(tt))
# TODO: handle non-leaftype(t) by testing against lower and upper bounds
return Bool
end
add_tfunc(isa, 2, 2, isa_tfunc, 0)
add_tfunc(isa, 2, 2, isa_tfunc, 1)

function subtype_tfunc(@nospecialize(a), @nospecialize(b))
a, isexact_a = instanceof_tfunc(a)
Expand All @@ -555,7 +555,7 @@ function subtype_tfunc(@nospecialize(a), @nospecialize(b))
end
return Bool
end
add_tfunc(<:, 2, 2, subtype_tfunc, 0)
add_tfunc(<:, 2, 2, subtype_tfunc, 1)

is_dt_const_field(fld::Int) = (
fld == DATATYPE_NAME_FIELDINDEX ||
Expand Down
6 changes: 3 additions & 3 deletions base/iddict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function get(d::IdDict{K,V}, @nospecialize(key), @nospecialize(default)) where {
val === default ? default : val::V
end
function getindex(d::IdDict{K,V}, @nospecialize(key)) where {K, V}
val = get(d, key, secret_table_token)
val = ccall(:jl_eqtable_get, Any, (Any, Any, Any), d.ht, key, secret_table_token)
val === secret_table_token && throw(KeyError(key))
return val::V
end
Expand Down Expand Up @@ -137,15 +137,15 @@ copy(d::IdDict) = typeof(d)(d)
get!(d::IdDict{K,V}, @nospecialize(key), @nospecialize(default)) where {K, V} = (d[key] = get(d, key, default))::V

function get(default::Callable, d::IdDict{K,V}, @nospecialize(key)) where {K, V}
val = get(d, key, secret_table_token)
val = ccall(:jl_eqtable_get, Any, (Any, Any, Any), d.ht, key, secret_table_token)
if val === secret_table_token
val = default()
end
return val
end

function get!(default::Callable, d::IdDict{K,V}, @nospecialize(key)) where {K, V}
val = get(d, key, secret_table_token)
val = ccall(:jl_eqtable_get, Any, (Any, Any, Any), d.ht, key, secret_table_token)
if val === secret_table_token
val = default()
setindex!(d, val, key)
Expand Down
4 changes: 2 additions & 2 deletions doc/src/devdocs/inference.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ cst = map(cost, ci.code)
1
1
1
0
1
0
0
Expand All @@ -133,7 +133,7 @@ cst = map(cost, ci.code)
0
0
1
0
1
0
0
0
Expand Down
1 change: 1 addition & 0 deletions src/method.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ static void jl_method_set_source(jl_method_t *m, jl_code_info_t *src)
}
else if (nargs == 2 && jl_exprarg(st, 0) == (jl_value_t*)jl_symbol("nkw")) {
m->nkw = jl_unbox_long(jl_exprarg(st, 1));
st = jl_nothing;
}
}
else {
Expand Down

0 comments on commit 05dfb5c

Please sign in to comment.