# How does constant propagation work?

**URL:** <https://discourse.julialang.org/t/how-does-constant-propagation-work/22735>\
**Category:** General Usage\
**Created:** [April 4, 2019, 7:27am UTC](https://discourse.julialang.org/t/how-does-constant-propagation-work/22735 "2019-04-04T07:27:34Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 4, 2019, 7:27am UTC](https://discourse.julialang.org/t/how-does-constant-propagation-work/22735/1 "2019-04-04T07:27:34Z")

</div>

Let’s say I start with the following:

```julia
julia> function f(x, y) 
         if y > 10
           x + 1
         else
           x * 2
         end
       end
f (generic function with 1 method)

julia> @code_warntype f(2, 20)
Body::Int64
1 ─ %1 = (Base.slt_int)(10, y)::Bool
└── goto #3 if not %1
2 ─ %3 = (Base.add_int)(x, 1)::Int64
└── return %3
3 ─ %5 = (Base.mul_int)(x, 2)::Int64
└── return %5

```

Then, I realize that the compiler can optimize away a branch if it knows that it always choose the other branch:

```julia
julia> g() = f(2,3)
g (generic function with 2 methods)

julia> @code_warntype g()
Body::Int64
1 ─ return 4

```

That’s great, but if I define a global constant then why wouldn’t it optimize in this case?

```julia
julia> const cy = 3
3

julia> g(y) = f(2, y)
g (generic function with 2 methods)

julia> @code_warntype g(cy)
Body::Int64
1 ─ %1 = (Base.slt_int)(10, y)::Bool
└── goto #3 if not %1
2 ─ goto #4
3 ─ goto #4
4 ┄ %5 = φ (#2 => 3, #3 => 4)::Int64
└── return %5

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 4, 2019, 7:38am UTC](https://discourse.julialang.org/t/how-does-constant-propagation-work/22735/2 "2019-04-04T07:38:22Z")

</div>

You are not using the macro in a way that allows constant propagation, cf:

```julia
julia> h() = g(cy)
h (generic function with 1 method)

julia> @code_warntype h()
Body::Int64
1 ─ return 4

```

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 5, 2019, 3:28pm UTC](https://discourse.julialang.org/t/how-does-constant-propagation-work/22735/3 "2019-04-05T15:28:23Z")

</div>

Thanks, but my question is why the compiler cannot figure it out and optimize it away? Am I missing something?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 5, 2019, 3:42pm UTC](https://discourse.julialang.org/t/how-does-constant-propagation-work/22735/4 "2019-04-05T15:42:33Z")

</div>

It has to do with how `@code_warntype` (and all the `@code_*` introspection functionality) works — it doesn’t care what the values of the arguments are that you pass in. It simply takes their types, looks up the relevant method, and then gets the code for that method.

Thus, you need a helper function like Kristoffer’s `h()` above to actually put the constant values in a place where Julia can see them.

---

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [April 5, 2019, 3:52pm UTC](https://discourse.julialang.org/t/how-does-constant-propagation-work/22735/5 "2019-04-05T15:52:53Z")

</div>

Thanks for the explanation. Does that mean the optimization would actually kick in when I pass constants, and I just can’t see it properly because of the way that I use `@code_warntype`?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 5, 2019, 8:46pm UTC](https://discourse.julialang.org/t/how-does-constant-propagation-work/22735/6 "2019-04-05T20:46:56Z")

</div>

Yes. Maybe not if the constants comes from global scope, not sure.
