Indeed. If you look at @code_llvm optimize=false
, which is what Julia provides as information to LLVM:
%box_Int64 = call nonnull align 8 dereferenceable(8) ptr @ijl_box_int64(i64 signext %"new::A.i") #2
%box_Int643 = call nonnull align 8 dereferenceable(8) ptr @ijl_box_int64(i64 signext %"v::Int64") #2
%jl_f_setfield_ret = call nonnull ptr (ptr, ptr, ...) @julia.call(ptr @jl_f_setfield, ptr null, ptr %"new::A", ptr %box_Int64, ptr %box_Int643)
After optimizations, LLVM does actually know that this is constant.
%box_Int64 = call nonnull align 8 dereferenceable(8) ptr @ijl_box_int64(i64 signext 1) #11
%box_Int643 = call nonnull align 8 dereferenceable(8) ptr @ijl_box_int64(i64 signext %"v::Int64") #11
; ...
%jl_f_setfield_ret = call nonnull ptr @jl_f_setfield(ptr null, ptr nonnull %jlcallframe1, i32 3)
But we haven’t written a pass and LLVM does not have nearly enough information to turn a setfield
with an eventually const element like that into the corresponding pointer store.
One way (at the expense of bloating the IR perhaps), would be for Julia to the inlined code for all possible variants in the hope that LLVM will be able to const-propagate. This is complicated by the fact that the setfield(v, ::Int)
version is probably less common than setfield(v, ::Symbol)
.
If anyone wants to try here are some crumbs:
- Builtin emission: julia/src/codegen.cpp at aa05c9899855e6f5dbd951fb90387d2016d913f7 · JuliaLang/julia · GitHub
- Function handling
setfield
like things julia/src/codegen.cpp at aa05c9899855e6f5dbd951fb90387d2016d913f7 · JuliaLang/julia · GitHub - Assumption that
fld
is constant julia/src/codegen.cpp at aa05c9899855e6f5dbd951fb90387d2016d913f7 · JuliaLang/julia · GitHub
So when fld
is not constant, but well-typed, one would need to loop over all possible fields and emit a select, the tricky things is to also get all the errors etc right, and handle symbols.
Then we would need to benchmark and study the impact on codesize, a similar change would also be necessary for getfield
since those ought to be symmetric.