# Constant propagation depth

**URL:** <https://discourse.julialang.org/t/constant-propagation-depth/73012>\
**Category:** Internals & Design\
**Created:** [December 13, 2021, 10:04am UTC](https://discourse.julialang.org/t/constant-propagation-depth/73012 "2021-12-13T10:04:39Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marco\_Lombardi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_lombardi/32/14608_2.png) [@Marco\_Lombardi](https://discourse.julialang.org/u/Marco_Lombardi)\
**Post date:** [December 13, 2021, 10:04am UTC](https://discourse.julialang.org/t/constant-propagation-depth/73012/1 "2021-12-13T10:04:39Z")

</div>

Is there a limit in the depth of a tree for constant propagation? I have seen that rather long expressions involving only constants are not completely replaced by their result:

```julia
julia> c() = log(log(log(log(2*π) + 2) + π) + tanh(3 + π))
c (generic function with 1 method)

julia> @code_llvm c()
; @ REPL[28]:1 within `c'
define double @julia_c_874() {
top:
  %0 = call double @j_log_876(double 0x400EB3F8E4325F5A)
; ┌ @ promotion.jl:321 within `+' @ float.jl:326
   %1 = fadd double %0, 0x400921FB54442D18
; └
  %2 = call double @j_log_877(double %1)
; ┌ @ float.jl:326 within `+'
   %3 = fadd double %2, 0x3FEFFFEC95BFEC1C
; └
  %4 = call double @j_log_878(double %3)
  ret double %4
}

```

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [December 13, 2021, 10:16am UTC](https://discourse.julialang.org/t/constant-propagation-depth/73012/2 "2021-12-13T10:16:52Z")

</div>

Not answering your question, but with Julia v1.7 I get

```julia
julia> c() = log(log(log(log(2*π) + 2) + π) + tanh(3 + π))
c (generic function with 1 method)

julia> @code_llvm c()
; @ REPL[1]:1 within `c`
define double @julia_c_181() #0 {
top:
  ret double 0x3FED55BF3C312E04
}

```

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [December 13, 2021, 10:18am UTC](https://discourse.julialang.org/t/constant-propagation-depth/73012/3 "2021-12-13T10:18:42Z")

</div>

Also not an answer, but with `@code_warntype` you can see nicely where i breaks down:

```julia
julia> c() = sin(sin(sin(sin(1)))); @code_warntype c()
MethodInstance for c()
  from c() in Main at REPL[21]:1
Arguments
  #self#::Core.Const(c)
Body::Float64
1 ─ %1 = Main.sin(1)::Core.Const(0.8414709848078965)
│ %2 = Main.sin(%1)::Core.Const(0.7456241416655579)
│ %3 = Main.sin(%2)::Float64
│ %4 = Main.sin(%3)::Float64
└── return %4

```

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [December 13, 2021, 10:21am UTC](https://discourse.julialang.org/t/constant-propagation-depth/73012/4 "2021-12-13T10:21:55Z")

</div>

That’s a good suggestion, compare v1.6 vs v1.7:

```julia
# v1.6
julia> @code_warntype c()
Variables
  #self#::Core.Const(c)

Body::Float64
1 ─ %1 = (2 * Main.π)::Core.Const(6.283185307179586)
│ %2 = Main.log(%1)::Float64
│ %3 = (%2 + 2)::Float64
│ %4 = Main.log(%3)::Float64
│ %5 = (%4 + Main.π)::Float64
│ %6 = Main.log(%5)::Float64
│ %7 = (3 + Main.π)::Core.Const(6.141592653589793)
│ %8 = Main.tanh(%7)::Core.Const(0.9999907421873817)
│ %9 = (%6 + %8)::Float64
│ %10 = Main.log(%9)::Float64
└── return %10

# v1.7
julia> @code_warntype c()
MethodInstance for c()
  from c() in Main at REPL[1]:1
Arguments
  #self#::Core.Const(c)
Body::Float64
1 ─ %1 = (2 * Main.π)::Core.Const(6.283185307179586)
│ %2 = Main.log(%1)::Core.Const(1.8378770664093453)
│ %3 = (%2 + 2)::Core.Const(3.8378770664093453)
│ %4 = Main.log(%3)::Core.Const(1.3449193664339925)
│ %5 = (%4 + Main.π)::Core.Const(4.486512020023786)
│ %6 = Main.log(%5)::Core.Const(1.5010755669062448)
│ %7 = (3 + Main.π)::Core.Const(6.141592653589793)
│ %8 = Main.tanh(%7)::Core.Const(0.9999907421873817)
│ %9 = (%6 + %8)::Core.Const(2.5010663090936265)
│ %10 = Main.log(%9)::Core.Const(0.9167171645762555)
└── return %10

```

---

<div class="post-metadata">

**Author:** ![Marco\_Lombardi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_lombardi/32/14608_2.png) [@Marco\_Lombardi](https://discourse.julialang.org/u/Marco_Lombardi)\
**Post date:** [December 13, 2021, 4:33pm UTC](https://discourse.julialang.org/t/constant-propagation-depth/73012/5 "2021-12-13T16:33:53Z")

</div>

So presumably this is something present in Julia 1.6 and solved already (at least up to this depth) in Julia 1.7. Another good reason to upgrade then…

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [December 13, 2021, 5:00pm UTC](https://discourse.julialang.org/t/constant-propagation-depth/73012/6 "2021-12-13T17:00:27Z")

</div>

Yes, details are given here: [Julia 1.7 Highlights](https://julialang.org/blog/2021/11/julia-1.7-highlights/#inference_improvements)

---

<div class="post-metadata">

**Author:** ![N5N3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/n5n3/32/17663_2.png) [@N5N3](https://discourse.julialang.org/u/N5N3)\
**Post date:** [December 21, 2021, 3:15am UTC](https://discourse.julialang.org/t/constant-propagation-depth/73012/7 "2021-12-21T03:15:35Z")

</div>

For this case const propgate was blocked by `sqrt`:

```julia
c() = sin(sin(sin(sin(1)))); @code_typed c()
CodeInfo(
1 ─ %1 = Base.Math.sqrt_llvm(2.220446049250313e-16)::Float64
│ %2 = Base.lt_float(0.7456241416655579, %1)::Bool
└── goto #3 if not %2
2 ─ goto #4
3 ─ goto #4
4 ┄ %6 = φ (#2 => 0.7456241416655579, #3 => 0.6784304773607402)::Float64
│ %7 = invoke Main.sin(%6::Float64)::Float64
└── return %7
) => Float64

```

And looks like we disable it for correctness, see ([https://github.com/JuliaLang/julia/blob/3a3cf028eb5e3138b0dfe5e31efce7f87f5cbfe3/base/compiler/optimize.jl#L547-L556](https://github.com/JuliaLang/julia/blob/3a3cf028eb5e3138b0dfe5e31efce7f87f5cbfe3/base/compiler/optimize.jl#L547-L556))
