# Why the compiler can't optimize this simple code?

**URL:** <https://discourse.julialang.org/t/why-the-compiler-cant-optimize-this-simple-code/122504>\
**Category:** Performance\
**Created:** [November 11, 2024, 4:31pm UTC](https://discourse.julialang.org/t/why-the-compiler-cant-optimize-this-simple-code/122504 "2024-11-11T16:31:53Z")\
**Posts on this page:** 1\
**Page:** 2

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [November 14, 2024, 9:07am UTC](https://discourse.julialang.org/t/why-the-compiler-cant-optimize-this-simple-code/122504/21 "2024-11-14T09:07:33Z")

</div>

Indeed. If you look at `@code_llvm optimize=false`, which is what Julia provides as information to LLVM:

```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.

```llvm
  %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](https://github.com/JuliaLang/julia/blob/aa05c9899855e6f5dbd951fb90387d2016d913f7/src/codegen.cpp#L4952C16-L4952C30)
- Function handling `setfield` like things [julia/src/codegen.cpp at aa05c9899855e6f5dbd951fb90387d2016d913f7 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/blob/aa05c9899855e6f5dbd951fb90387d2016d913f7/src/codegen.cpp#L4074)
- Assumption that `fld` is constant [julia/src/codegen.cpp at aa05c9899855e6f5dbd951fb90387d2016d913f7 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/blob/aa05c9899855e6f5dbd951fb90387d2016d913f7/src/codegen.cpp#L4114C13-L4121)

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.

[Previous page](https://discourse.julialang.org/t/why-the-compiler-cant-optimize-this-simple-code/122504.md?page=1)
