I am optimizing the following simple function:
"""
Calculate ``∑ₖ cₖ fₖ, k=1,...,n`` where ``fₖ₊₁ = α fₖ + β fₖ₋₁`` and
the first two elements are given. Uses the reverse Clenshaw algorithm,
stability is assumed.
"""
function clenshaw{T}(c::AbstractVector{T}, α::T, β::T, f1::T, f2::T)
bnn = bn = zero(T)
for k in length(c):-1:2
bn, bnn = c[k] + α*bn + β*bnn, bn
end
f1*(c[1]+β*bnn) + f2*bn
end
and I think my problem is what happens to SSAValue(6)
below, but don’t know what I can do about it:
julia> @code_warntype clenshaw(rand(10), 1.0, -1.0, 1.0, 0.5)
Variables:
#self#::#clenshaw
c::Array{Float64,1}
α::Float64
β::Float64
f1::Float64
f2::Float64
bn::Float64
bnn::Float64
#temp#::Int64
k::Int64
Body:
begin
SSAValue(0) = (Base.box)(Float64,(Base.sitofp)(Float64,0))
bn::Float64 = SSAValue(0)
bnn::Float64 = SSAValue(0) # line 8:
SSAValue(5) = (Base.arraylen)(c::Array{Float64,1})::Int64
# meta: location range.jl colon 115
# meta: location range.jl Type 70
# meta: location range.jl Type 18
SSAValue(6) = $(Expr(:invoke, LambdaInfo for steprange_last(::Int64, ::Int64, ::Int64), :(Base.steprange_last), SSAValue(5), -1, 2))
# meta: pop location
# meta: pop location
# meta: pop location
#temp#::Int64 = SSAValue(5)
14:
unless (Base.box)(Base.Bool,(Base.not_int)((Base.box)(Base.Bool,(Base.or_int)((Base.box)(Base.Bool,(Base.and_int)((Base.box)(Base.Bool,(Base.not_int)((SSAValue(5) === SSAValue(6))::Bool)),(Base.box)(Base.Bool,(Base.not_int)(((Base.slt_int)(0,-1)::Bool === (Base.slt_int)(SSAValue(5),SSAValue(6))::Bool)::Bool)))),(#temp#::Int64 === (Base.box)(Int64,(Base.add_int)(SSAValue(6),-1)))::Bool)))) goto 27
SSAValue(7) = #temp#::Int64
SSAValue(8) = (Base.box)(Int64,(Base.add_int)(#temp#::Int64,-1))
k::Int64 = SSAValue(7)
#temp#::Int64 = SSAValue(8) # line 9:
SSAValue(3) = (Base.box)(Base.Float64,(Base.add_float)((Base.box)(Base.Float64,(Base.add_float)((Base.arrayref)(c::Array{Float64,1},k::Int64)::Float64,(Base.box)(Base.Float64,(Base.mul_float)(α::Float64,bn::Float64)))),(Base.box)(Base.Float64,(Base.mul_float)(β::Float64,bnn::Float64))))
SSAValue(4) = bn::Float64
bn::Float64 = SSAValue(3)
bnn::Float64 = SSAValue(4)
25:
goto 14
27: # line 11:
return (Base.box)(Base.Float64,(Base.add_float)((Base.box)(Base.Float64,(Base.mul_float)(f1::Float64,(Base.box)(Base.Float64,(Base.add_float)((Base.arrayref)(c::Array{Float64,1},1)::Float64,(Base.box)(Base.Float64,(Base.mul_float)(β::Float64,bnn::Float64)))))),(Base.box)(Base.Float64,(Base.mul_float)(f2::Float64,bn::Float64))))
end::Float64
I would like to speed this up (it is used in an inner loop a lot in my code), but at the same time I would also like to understand what is going on with SSAValue(6)
.