I was reading this question about performance involving global variables, and wanted to see how exactly Julia translates this code. I realized then that code_warntype
can't be used in the usual way here since the code isn't in a function, and wrapping it in a function would defeat the whole point of the exercise.
Is there an analogue or another version of @code_warntype
that will take some Julia code directly (eg. as a filename, or as a plain string) and show us the typed lowered version of that code? Or perhaps a command line flag that outputs lowered code? (There seemed to be flags for generating LLVM code or object files, but none for outputting code that's just type inferred and lowered.)
You can always wrap the code in question into a function and call @code_warntype
on that.
Here's an example for the linked question:
n=5000;
x=rand(n)
y=rand(n)
mn=ones(n)*1000;
function foo()
for i in 1:n;
for j in 1:n;
c=abs(x[j]-y[i]);
if(c<mn[i])
mn[i]=c;
end
end
end
end
julia> @code_warntype foo()
Variables:
#temp#@_2::Any
i::Any
#temp#@_4::Any
j::Any
c::Any
Body:
begin
Core.SSAValue(0) = (1:Main.n)::Any
#temp#@_2::Any = (Base.start)(Core.SSAValue(0))::Any
3:
Core.SSAValue(1) = (Base.done)(Core.SSAValue(0), #temp#@_2::Any)::Any
Core.SSAValue(2) = (Core.typeassert)(Core.SSAValue(1), Core.Bool)::Bool
Core.SSAValue(3) = (Base.not_int)(Core.SSAValue(2))::Bool
unless Core.SSAValue(3) goto 37
Core.SSAValue(4) = (Base.next)(Core.SSAValue(0), #temp#@_2::Any)::Any
i::Any = (Core.getfield)(Core.SSAValue(4), 1)::Any
#temp#@_2::Any = (Core.getfield)(Core.SSAValue(4), 2)::Any
#= line 2 =#
Core.SSAValue(5) = (1:Main.n)::Any
#temp#@_4::Any = (Base.start)(Core.SSAValue(5))::Any
14:
Core.SSAValue(6) = (Base.done)(Core.SSAValue(5), #temp#@_4::Any)::Any
Core.SSAValue(7) = (Core.typeassert)(Core.SSAValue(6), Core.Bool)::Bool
Core.SSAValue(8) = (Base.not_int)(Core.SSAValue(7))::Bool
unless Core.SSAValue(8) goto 35
Core.SSAValue(9) = (Base.next)(Core.SSAValue(5), #temp#@_4::Any)::Any
j::Any = (Core.getfield)(Core.SSAValue(9), 1)::Any
#temp#@_4::Any = (Core.getfield)(Core.SSAValue(9), 2)::Any
#= line 3 =#
Core.SSAValue(10) = (Base.getindex)(Main.x, j::Any)::Any
Core.SSAValue(11) = (Base.getindex)(Main.y, i::Any)::Any
Core.SSAValue(12) = (Core.SSAValue(10) - Core.SSAValue(11))::Any
c::Any = (Main.abs)(Core.SSAValue(12))::Any
#= line 5 =#
Core.SSAValue(14) = (Base.getindex)(Main.mn, i::Any)::Any
Core.SSAValue(15) = (c::Any < Core.SSAValue(14))::Any
unless Core.SSAValue(15) goto 33
#= line 6 =#
(Base.setindex!)(Main.mn, c::Any, i::Any)::Any
33:
goto 14
35:
goto 3
37:
return
end::Nothing
Compare the above with
function foo()
n=5000;
x=rand(n)
y=rand(n)
mn=ones(n)*1000;
for i in 1:n;
for j in 1:n;
c=abs(x[j]-y[i]);
if(c<mn[i])
mn[i]=c;
end
end
end
end
julia> @code_warntype foo()
Variables:
n<optimized out>
x<optimized out>
y<optimized out>
mn::Array{Float64,1}
#temp#@_6::Int64
i<optimized out>
#temp#@_8::Int64
j<optimized out>
c<optimized out>
#temp#@_13::Bool
#temp#@_16::Bool
Body:
begin
#= line 3 =#
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/Random.jl rand 224
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/Random.jl rand 236
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/Random.jl rand 235
# meta: location boot.jl Type 397
# meta: location boot.jl Type 389
# meta: location boot.jl Type 380
Core.SSAValue(46) = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Float64,1}, svec(Any, Int64), :(:ccall), 2, Array{Float64,1}, 5000, 5000))
# meta: pop locations (3)
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/Random.jl rand! 214
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/RNGs.jl rand! 447
# meta: location array.jl length 137
Core.SSAValue(53) = (Base.arraylen)(Core.SSAValue(46))::Int64
# meta: pop location
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/RNGs.jl _rand! 440
# meta: location int.jl * 54
Core.SSAValue(66) = (Base.mul_int)(8, Core.SSAValue(53))::Int64
# meta: pop location
# meta: location array.jl length 137
Core.SSAValue(67) = (Base.arraylen)(Core.SSAValue(46))::Int64
# meta: pop location
# meta: location int.jl * 54
Core.SSAValue(68) = (Base.mul_int)(8, Core.SSAValue(67))::Int64
# meta: pop location
# meta: location int.jl <= 419
Core.SSAValue(69) = (Base.sle_int)(Core.SSAValue(66), Core.SSAValue(68))::Bool
# meta: pop location
unless Core.SSAValue(69) goto 31
#temp#@_13::Bool = true
goto 33
31:
#temp#@_13::Bool = false
33:
unless #temp#@_13::Bool goto 36
goto 41
36:
# meta: location boot.jl Type 281
Core.SSAValue(71) = $(Expr(:new, :(Core.AssertionError), "sizeof(Float64) * n64 <= sizeof(T) * length(A) && isbits(T)"))
# meta: pop location
(Base.throw)(Core.SSAValue(71))::Union{}
41:
#= line 441 =#
# meta: location gcutils.jl
#= line 81 =#
Core.SSAValue(61) = $(Expr(:gc_preserve_begin, Core.SSAValue(46)))
#= line 82 =#
# meta: location abstractarray.jl pointer 911
# meta: location pointer.jl unsafe_convert 65
Core.SSAValue(74) = $(Expr(:foreigncall, :(:jl_array_ptr), Ptr{Float64}, svec(Any), :(:ccall), 1, Core.SSAValue(46)))
# meta: pop locations (2)
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/RNGs.jl Type 365
Core.SSAValue(79) = $(Expr(:new, Random.UnsafeView{Float64}, Core.SSAValue(74), Core.SSAValue(53)))
# meta: pop location
$(Expr(:invoke, MethodInstance for rand!(::Random.MersenneTwister, ::Random.UnsafeView{Float64}, ::Random.SamplerTrivial{Random.CloseOpen01{Float64},Float64}), :(Random.rand!), :(Random.GLOBAL_RNG), Core.SSAValue(79), :($(QuoteNode(Random.SamplerTrivial{Random.CloseOpen01{Float64},Float64}(Random.CloseOpen01{Float64}()))))))::Random.UnsafeView{Float64}
#= line 83 =#
$(Expr(:gc_preserve_end, Core.SSAValue(61)))
# meta: pop locations (7)
#= line 4 =#
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/Random.jl rand 224
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/Random.jl rand 236
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/Random.jl rand 235
# meta: location boot.jl Type 397
# meta: location boot.jl Type 389
# meta: location boot.jl Type 380
Core.SSAValue(109) = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Float64,1}, svec(Any, Int64), :(:ccall), 2, Array{Float64,1}, 5000, 5000))
# meta: pop locations (3)
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/Random.jl rand! 214
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/RNGs.jl rand! 447
# meta: location array.jl length 137
Core.SSAValue(116) = (Base.arraylen)(Core.SSAValue(109))::Int64
# meta: pop location
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/RNGs.jl _rand! 440
# meta: location int.jl * 54
Core.SSAValue(129) = (Base.mul_int)(8, Core.SSAValue(116))::Int64
# meta: pop location
# meta: location array.jl length 137
Core.SSAValue(130) = (Base.arraylen)(Core.SSAValue(109))::Int64
# meta: pop location
# meta: location int.jl * 54
Core.SSAValue(131) = (Base.mul_int)(8, Core.SSAValue(130))::Int64
# meta: pop location
# meta: location int.jl <= 419
Core.SSAValue(132) = (Base.sle_int)(Core.SSAValue(129), Core.SSAValue(131))::Bool
# meta: pop location
unless Core.SSAValue(132) goto 88
#temp#@_16::Bool = true
goto 90
88:
#temp#@_16::Bool = false
90:
unless #temp#@_16::Bool goto 93
goto 98
93:
# meta: location boot.jl Type 281
Core.SSAValue(134) = $(Expr(:new, :(Core.AssertionError), "sizeof(Float64) * n64 <= sizeof(T) * length(A) && isbits(T)"))
# meta: pop location
(Base.throw)(Core.SSAValue(134))::Union{}
98:
#= line 441 =#
# meta: location gcutils.jl
#= line 81 =#
Core.SSAValue(124) = $(Expr(:gc_preserve_begin, Core.SSAValue(109)))
#= line 82 =#
# meta: location abstractarray.jl pointer 911
# meta: location pointer.jl unsafe_convert 65
Core.SSAValue(137) = $(Expr(:foreigncall, :(:jl_array_ptr), Ptr{Float64}, svec(Any), :(:ccall), 1, Core.SSAValue(109)))
# meta: pop locations (2)
# meta: location /buildworker/worker/package_linux64/build/usr/share/julia/site/v0.7/Random/src/RNGs.jl Type 365
Core.SSAValue(142) = $(Expr(:new, Random.UnsafeView{Float64}, Core.SSAValue(137), Core.SSAValue(116)))
# meta: pop location
$(Expr(:invoke, MethodInstance for rand!(::Random.MersenneTwister, ::Random.UnsafeView{Float64}, ::Random.SamplerTrivial{Random.CloseOpen01{Float64},Float64}), :(Random.rand!), :(Random.GLOBAL_RNG), Core.SSAValue(142), :($(QuoteNode(Random.SamplerTrivial{Random.CloseOpen01{Float64},Float64}(Random.CloseOpen01{Float64}()))))))::Random.UnsafeView{Float64}
#= line 83 =#
$(Expr(:gc_preserve_end, Core.SSAValue(124)))
# meta: pop locations (7)
#= line 5 =#
# meta: location array.jl ones 398
# meta: location array.jl ones 396
# meta: location array.jl ones 395
# meta: location boot.jl Type 389
# meta: location boot.jl Type 380
Core.SSAValue(170) = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Float64,1}, svec(Any, Int64), :(:ccall), 2, Array{Float64,1}, 5000, 5000))
# meta: pop locations (2)
Core.SSAValue(151) = $(Expr(:invoke, MethodInstance for fill!(::Array{Float64,1}, ::Float64), :(Base.fill!), Core.SSAValue(170), 1.0))::Array{Float64,1}
# meta: pop locations (3)
mn::Array{Float64,1} = $(Expr(:invoke, MethodInstance for *(::Array{Float64,1}, ::Int64), :(Main.:*), Core.SSAValue(151), 1000))::Array{Float64,1}
#= line 6 =#
#temp#@_6::Int64 = 1
128:
# meta: location range.jl done 457
# meta: location int.jl + 53
Core.SSAValue(197) = (Base.add_int)(5000, 1)::Int64
# meta: pop location
# meta: location promotion.jl == 433
Core.SSAValue(198) = (#temp#@_6::Int64 === Core.SSAValue(197))::Bool
# meta: pop locations (2)
Core.SSAValue(4) = (Base.not_int)(Core.SSAValue(198))::Bool
unless Core.SSAValue(4) goto 193
# meta: location range.jl next 456
# meta: location int.jl + 53
Core.SSAValue(203) = (Base.add_int)(#temp#@_6::Int64, 1)::Int64
# meta: pop location
Core.SSAValue(246) = #temp#@_6::Int64
# meta: pop location
#temp#@_6::Int64 = Core.SSAValue(203)
#= line 6 =#
#temp#@_8::Int64 = 1
147:
# meta: location range.jl done 457
# meta: location int.jl + 53
Core.SSAValue(229) = (Base.add_int)(5000, 1)::Int64
# meta: pop location
# meta: location promotion.jl == 433
Core.SSAValue(230) = (#temp#@_8::Int64 === Core.SSAValue(229))::Bool
# meta: pop locations (2)
Core.SSAValue(9) = (Base.not_int)(Core.SSAValue(230))::Bool
unless Core.SSAValue(9) goto 191
# meta: location range.jl next 456
# meta: location int.jl + 53
Core.SSAValue(235) = (Base.add_int)(#temp#@_8::Int64, 1)::Int64
# meta: pop location
Core.SSAValue(245) = #temp#@_8::Int64
# meta: pop location
#temp#@_8::Int64 = Core.SSAValue(235)
#= line 7 =#
# meta: location array.jl getindex 661
Core.SSAValue(236) = (Base.arrayref)(true, Core.SSAValue(46), Core.SSAValue(245))::Float64
# meta: pop location
# meta: location array.jl getindex 661
Core.SSAValue(237) = (Base.arrayref)(true, Core.SSAValue(109), Core.SSAValue(246))::Float64
# meta: pop location
# meta: location float.jl - 395
Core.SSAValue(238) = (Base.sub_float)(Core.SSAValue(236), Core.SSAValue(237))::Float64
# meta: pop location
# meta: location float.jl abs 517
Core.SSAValue(239) = (Base.abs_float)(Core.SSAValue(238))::Float64
# meta: pop location
#= line 9 =#
# meta: location array.jl getindex 661
Core.SSAValue(240) = (Base.arrayref)(true, mn::Array{Float64,1}, Core.SSAValue(246))::Float64
# meta: pop location
# meta: location float.jl < 450
Core.SSAValue(241) = (Base.lt_float)(Core.SSAValue(239), Core.SSAValue(240))::Bool
# meta: pop location
unless Core.SSAValue(241) goto 189
#= line 10 =#
# meta: location array.jl setindex! 699
(Base.arrayset)(true, mn::Array{Float64,1}, Core.SSAValue(239), Core.SSAValue(246))::Array{Float64,1}
# meta: pop location
189:
goto 147
191:
goto 128
193:
return
end::Nothing
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With