diff --git a/base/broadcast.jl b/base/broadcast.jl index d7546643220ba..ebb67774a860b 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -839,7 +839,7 @@ julia> string.(("one","two","three","four"), ": ", 1:4) ``` """ -broadcast(f::Tf, As...) where {Tf} = materialize(broadcasted(f, As...)) +broadcast(f::Tf, As::Vararg{Any,N}) where {Tf,N} = materialize(broadcasted(f, As...)) # special cases defined for performance @inline broadcast(f, x::Number...) = f(x...) @@ -1314,33 +1314,34 @@ macro __dot__(x) esc(__dot__(x)) end -@inline function broadcasted_kwsyntax(f, args...; kwargs...) + +@inline function broadcasted_kwsyntax(f, args::Vararg{Any,N}; kwargs...) where N if isempty(kwargs) # some BroadcastStyles dispatch on `f`, so try to preserve its type return broadcasted(f, args...) else return broadcasted((args...) -> f(args...; kwargs...), args...) end end -@inline function broadcasted(f, args...) - args′ = map(broadcastable, args) - broadcasted(combine_styles(args′...), f, args′...) +@inline function broadcasted(f) + args′ = map(broadcastable, ()) + return broadcasted(combine_styles(args′...), f, args′...) end # Due to the current Type{T}/DataType specialization heuristics within Tuples, # the totally generic varargs broadcasted(f, args...) method above loses Type{T}s in # mapping broadcastable across the args. These additional methods with explicit # arguments ensure we preserve Type{T}s in the first or second argument position. -@inline function broadcasted(f, arg1, args...) +@inline function broadcasted(f, arg1) arg1′ = broadcastable(arg1) - args′ = map(broadcastable, args) - broadcasted(combine_styles(arg1′, args′...), f, arg1′, args′...) + args′ = map(broadcastable, ()) + return broadcasted(combine_styles(arg1′, args′...), f, arg1′, args′...) end -@inline function broadcasted(f, arg1, arg2, args...) +@inline function broadcasted(f, arg1, arg2, args::Vararg{Any,N}) where N arg1′ = broadcastable(arg1) arg2′ = broadcastable(arg2) args′ = map(broadcastable, args) - broadcasted(combine_styles(arg1′, arg2′, args′...), f, arg1′, arg2′, args′...) + return broadcasted(combine_styles(arg1′, arg2′, args′...), f, arg1′, arg2′, args′...) end -@inline broadcasted(::S, f, args...) where S<:BroadcastStyle = Broadcasted{S}(f, args) +@inline broadcasted(::S, f, args::Vararg{Any,N}) where {S<:BroadcastStyle,N} = Broadcasted{S}(f, args) """ BroadcastFunction{F} <: Function diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index a472ae773f6b1..3011f4064ff49 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -351,10 +351,10 @@ function statement_cost(ex::Expr, line::Int, src::Union{CodeInfo, IRCode}, sptyp # depend strongly on whether the result can be # inferred, so check the type of ex if f === Core.getfield || f === Core.tuple - # we might like to penalize non-inferrability, but + # we might like to heavily penalize non-inferrability, but # tuple iteration/destructuring makes that impossible # return plus_saturate(argcost, isknowntype(extyp) ? 1 : params.inline_nonleaf_penalty) - return 0 + return 1 elseif (f === Core.arrayref || f === Core.const_arrayref || f === Core.arrayset) && length(ex.args) >= 3 atyp = argextype(ex.args[3], src, sptypes, slottypes) return isknowntype(atyp) ? 4 : error_path ? params.inline_error_path_cost : params.inline_nonleaf_penalty @@ -424,9 +424,9 @@ function statement_or_branch_cost(@nospecialize(stmt), line::Int, src::Union{Cod # loops are generally always expensive # but assume that forward jumps are already counted for from # summing the cost of the not-taken branch - thiscost = dst(stmt.label) < line ? 40 : 0 + thiscost = dst(stmt.label) < line ? 40 : 1 elseif stmt isa GotoIfNot - thiscost = dst(stmt.dest) < line ? 40 : 0 + thiscost = dst(stmt.dest) < line ? 40 : 1 end return thiscost end diff --git a/doc/src/devdocs/inference.md b/doc/src/devdocs/inference.md index a9c4ec5c726ed..94e785eb1a606 100644 --- a/doc/src/devdocs/inference.md +++ b/doc/src/devdocs/inference.md @@ -101,16 +101,16 @@ as follows: ```jldoctest; filter=r"tuple.jl:\d+" julia> Base.print_statement_costs(stdout, map, (typeof(sqrt), Tuple{Int},)) # map(sqrt, (2,)) map(f, t::Tuple{Any}) in Base at tuple.jl:179 - 0 1 ─ %1 = Base.getfield(_3, 1, true)::Int64 + 1 1 ─ %1 = Base.getfield(_3, 1, true)::Int64 1 │ %2 = Base.sitofp(Float64, %1)::Float64 2 │ %3 = Base.lt_float(%2, 0.0)::Bool - 0 └── goto #3 if not %3 + 1 └── goto #3 if not %3 0 2 ─ invoke Base.Math.throw_complex_domainerror(:sqrt::Symbol, %2::Float64)::Union{} 0 └── unreachable 20 3 ─ %7 = Base.Math.sqrt_llvm(%2)::Float64 - 0 └── goto #4 - 0 4 ─ goto #5 - 0 5 ─ %10 = Core.tuple(%7)::Tuple{Float64} + 1 └── goto #4 + 1 4 ─ goto #5 + 1 5 ─ %10 = Core.tuple(%7)::Tuple{Float64} 0 └── return %10 ```