tk3369
September 23, 2019, 5:18pm
1
I’m trying to understand the result of @code_lowered
macro. Consider this simple example:
julia> mutable struct Foo
value
end
julia> foo = Foo(1)
Foo(1)
julia> @code_lowered(foo.value = 2)
CodeInfo(
1 ─ %1 = (Base.typeof)(x)
│ %2 = (Base.fieldtype)(%1, f)
│ %3 = (Base.convert)(%2, v)
│ %4 = (Base.setfield!)(x, f, %3)
└── return %4
)
I can largely follow the logic but got really confused with x
, f
, and v
. If I match to the original code, I can derive that:
x = foo
so %1 = Foo
f = :value
so %2 = Any
v = 2
so %3 = 2
%4 = 2
Is there any reason why these values are not just displayed as-is? Ideally something like this:
CodeInfo(
1 ─ %1 = (Base.typeof)(foo)
│ %2 = (Base.fieldtype)(%1, :value)
│ %3 = (Base.convert)(%2, Int64(2))
│ %4 = (Base.setfield!)(foo, :value, %3)
└── return %4
)
Also, is there a naming convention for these variables?
1 Like
Keno
September 23, 2019, 5:37pm
2
The various @code_
macros operate on function calls NOT expressions. In particular, everything, but the outermost call is evaluated. Now, in your example, there’s an extra bit of confusion, because a.b = c
is syntactic sugar for setproperty!(a, :b, c)
. As a result, the what you’re asking for is
julia> @code_lowered setproperty!(a, :b, c)
which then does faithfully show you the lowered code of the setproperty! function: https://github.com/JuliaLang/julia/blob/4f17558e4c71908e8ba40d24e37bdacd5e2f2e5e/base/Base.jl#L34 . If you want to see the lowering of an expression, an easy way to do so is to put it in an anonymous function:
julia> @code_lowered((()->foo.value = 2)())
CodeInfo(
1 ─ Base.setproperty!(Main.foo, :value, 2)
└── return 2
)
or by asking the lowering code directly (if you happen to care about scoping differences):
Meta.lower(Main, :(foo.value = 2))
:($(Expr(:thunk, CodeInfo(
@ none within `top-level scope'
1 ─ Base.setproperty!(foo, :value, 2)
└── return 2
))))
6 Likes