diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index b1cc75da70942..14b133b173fba 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -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 @@ -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 diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index 945b620abfa4e..afa3a36e8f595 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -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) @@ -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{} @@ -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) @@ -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 || diff --git a/base/iddict.jl b/base/iddict.jl index 23ba65799a395..52b5d9e9de6c3 100644 --- a/base/iddict.jl +++ b/base/iddict.jl @@ -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 @@ -137,7 +137,7 @@ 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 @@ -145,7 +145,7 @@ function get(default::Callable, d::IdDict{K,V}, @nospecialize(key)) where {K, V} 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) diff --git a/doc/src/devdocs/inference.md b/doc/src/devdocs/inference.md index e9974824aa651..e6f577a6995cb 100644 --- a/doc/src/devdocs/inference.md +++ b/doc/src/devdocs/inference.md @@ -124,7 +124,7 @@ cst = map(cost, ci.code) 1 1 1 - 0 + 1 0 0 ⋮ @@ -133,7 +133,7 @@ cst = map(cost, ci.code) 0 0 1 - 0 + 1 0 0 0