Last active
February 24, 2017 01:15
-
-
Save andyferris/67c5c163160efeea20a9ada49fdb6fba to your computer and use it in GitHub Desktop.
Comparison of direct generated functions vs. `unroll_tuple` as a utility function to unroll expressions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# "bespoke" generated functions | |
Pkg.checkout("StaticArrays","master") | |
using StaticArrays | |
f(v) = @inbounds return v[v] | |
v = SVector{3,Int}((1,2,3)) | |
# results: | |
julia> @code_native f(v) | |
.text | |
Filename: REPL[3] | |
pushq %rbp | |
movq %rsp, %rbp | |
Source line: 25 | |
movq (%rsi), %rax | |
movq 8(%rsi), %rcx | |
movq -8(%rsi,%rax,8), %rax | |
movq -8(%rsi,%rcx,8), %rcx | |
movq 16(%rsi), %rdx | |
movq -8(%rsi,%rdx,8), %rdx | |
Source line: 1 | |
movq %rax, (%rdi) | |
movq %rcx, 8(%rdi) | |
movq %rdx, 16(%rdi) | |
movq %rdi, %rax | |
popq %rbp | |
retq | |
nop | |
julia> @code_warntype f(v) | |
Variables: | |
#self#::#f | |
v::StaticArrays.SVector{3,Int64} | |
Body: | |
begin | |
$(Expr(:inbounds, true)) | |
# meta: location /home/ferris/.julia/v0.6/StaticArrays/src/indexing.jl getindex 20 | |
# meta: location /home/ferris/.julia/v0.6/StaticArrays/src/indexing.jl # line 25: | |
SSAValue(0) = $(Expr(:new, :($(QuoteNode(StaticArrays.SVector{3,Int64}))), :((Core.tuple)((Base.getfield)((Core.getfield)(v, :data)::Tuple{Int64,Int64,Int64}, (Base.getfield)((Core.getfield)(v, :data)::Tuple{Int64,Int64,Int64}, 1)::Int64)::Int64, (Base.getfield)((Core.getfield)(v, :data)::Tuple{Int64,Int64,Int64}, (Base.getfield)((Core.getfield)(v, :data)::Tuple{Int64,Int64,Int64}, 2)::Int64)::Int64, (Base.getfield)((Core.getfield)(v, :data)::Tuple{Int64,Int64,Int64}, (Base.getfield)((Core.getfield)(v, :data)::Tuple{Int64,Int64,Int64}, 3)::Int64)::Int64)::Tuple{Int64,Int64,Int64}))) | |
# meta: pop location | |
# meta: pop location | |
return SSAValue(0) | |
$(Expr(:inbounds, :pop)) | |
end::StaticArrays.SVector{3,Int64} | |
# "centralized" generated functions | |
Pkg.checkout("StaticArrays","julia-0.6") | |
using StaticArrays | |
f(v) = @inbounds return v[v] | |
v = SVector{3,Int}((1,2,3)) | |
# results: | |
julia> @code_native f(v) | |
.text | |
Filename: REPL[3] | |
pushq %rbp | |
movq %rsp, %rbp | |
Source line: 7 | |
movq 16(%rsi), %rax | |
movq %rax, -80(%rbp) | |
vmovups (%rsi), %xmm0 | |
vmovaps %xmm0, -96(%rbp) | |
movq 16(%rsi), %rax | |
movq %rax, -56(%rbp) | |
vmovups (%rsi), %xmm0 | |
vmovups %xmm0, -72(%rbp) | |
vmovups -96(%rbp), %ymm0 | |
vmovups -80(%rbp), %ymm1 | |
vmovups %ymm1, -32(%rbp) | |
vmovups %ymm0, -48(%rbp) | |
Source line: 13 | |
movq -24(%rbp), %rax | |
movq -16(%rbp), %rcx | |
movq -56(%rbp,%rax,8), %rax | |
movq -56(%rbp,%rcx,8), %rcx | |
movq -8(%rbp), %rdx | |
movq -56(%rbp,%rdx,8), %rdx | |
Source line: 1 | |
movq %rax, (%rdi) | |
movq %rcx, 8(%rdi) | |
movq %rdx, 16(%rdi) | |
movq %rdi, %rax | |
popq %rbp | |
vzeroupper | |
retq | |
nopl (%rax,%rax) | |
julia> @code_warntype f(v) | |
Variables: | |
#self#::#f | |
v::StaticArrays.SVector{3,Int64} | |
#151::StaticArrays.##151#152{StaticArrays.SVector{3,Int64},StaticArrays.SVector{3,Int64}} | |
Body: | |
begin | |
$(Expr(:inbounds, true)) | |
# meta: location /home/ferris/.julia/v0.6/StaticArrays/src/indexing.jl getindex 7 | |
SSAValue(0) = $(QuoteNode(StaticArrays.SVector{3,Int64})) | |
#151::StaticArrays.##151#152{StaticArrays.SVector{3,Int64},StaticArrays.SVector{3,Int64}} = $(Expr(:new, :($(QuoteNode(StaticArrays.##151#152{StaticArrays.SVector{3,Int64},StaticArrays.SVector{3,Int64}}))), :(v), :(v))) | |
SSAValue(1) = #151::StaticArrays.##151#152{StaticArrays.SVector{3,Int64},StaticArrays.SVector{3,Int64}} | |
SSAValue(2) = $(QuoteNode(Length(3))) | |
# meta: location /home/ferris/.julia/v0.6/StaticArrays/src/traits.jl unroll_tuple 105 | |
# meta: location /home/ferris/.julia/v0.6/StaticArrays/src/generated.jl unroll_tuple 9 | |
# meta: location /home/ferris/.julia/v0.6/StaticArrays/src/generated.jl # line 13: | |
SSAValue(4) = (Core.tuple)((Base.getfield)((Core.getfield)((Core.getfield)(SSAValue(1), :a)::StaticArrays.SVector{3,Int64}, :data)::Tuple{Int64,Int64,Int64}, (Base.getfield)((Core.getfield)((Core.getfield)(SSAValue(1), :inds)::StaticArrays.SVector{3,Int64}, :data)::Tuple{Int64,Int64,Int64}, 1)::Int64)::Int64, (Base.getfield)((Core.getfield)((Core.getfield)(SSAValue(1), :a)::StaticArrays.SVector{3,Int64}, :data)::Tuple{Int64,Int64,Int64}, (Base.getfield)((Core.getfield)((Core.getfield)(SSAValue(1), :inds)::StaticArrays.SVector{3,Int64}, :data)::Tuple{Int64,Int64,Int64}, 2)::Int64)::Int64, (Base.getfield)((Core.getfield)((Core.getfield)(SSAValue(1), :a)::StaticArrays.SVector{3,Int64}, :data)::Tuple{Int64,Int64,Int64}, (Base.getfield)((Core.getfield)((Core.getfield)(SSAValue(1), :inds)::StaticArrays.SVector{3,Int64}, :data)::Tuple{Int64,Int64,Int64}, 3)::Int64)::Int64)::Tuple{Int64,Int64,Int64} | |
# meta: pop location | |
# meta: pop location | |
# meta: pop location | |
SSAValue(3) = SSAValue(4) | |
# meta: pop location | |
return $(Expr(:new, :($(QuoteNode(StaticArrays.SVector{3,Int64}))), SSAValue(3))) | |
$(Expr(:inbounds, :pop)) | |
end::StaticArrays.SVector{3,Int64} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For reference, this is the "thunk-based" system that does generate good code:
This just takes what is on master and moves the
Size
computation to a thunk and movessimilar_type
to the generated body.