# Why superfluous function call is not eliminated?

**URL:** <https://discourse.julialang.org/t/why-superfluous-function-call-is-not-eliminated/16071>\
**Category:** General Usage\
**Created:** [October 9, 2018, 1:22pm UTC](https://discourse.julialang.org/t/why-superfluous-function-call-is-not-eliminated/16071 "2018-10-09T13:22:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 1:22pm UTC](https://discourse.julialang.org/t/why-superfluous-function-call-is-not-eliminated/16071/1 "2018-10-09T13:22:13Z")

</div>

```julia
function f(x)
       T = typeof(sin(x))
       convert(T, x)
end

```

It seems that the call `sin(x)` can be ellided most of the time, because `sin` is type-stable. However,

```julia
@code_llvm f(1.)
define double @julia_f_35182(double) {
top:
  %1 = call double @julia_sin_35097(double %0)
  ret double %0
}

```

(I deleted the comments).

This contains the call to `sin`. Why there is no “constant propagation” here (not sure if this is the correct term here)? The compiler can infer the type of `sin(x)` when `x` is `Float64`, hence the `sin` call is not necessary.

This is probably related to [Getting the type of `f(x)` at compile time (without evaluating `f(x)`), for type-stable functions](https://discourse.julialang.org/t/getting-the-type-of-f-x-at-compile-time-without-evaluating-f-x-for-type-stable-functions/16069), but I thought it was a separate question.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [October 9, 2018, 1:30pm UTC](https://discourse.julialang.org/t/why-superfluous-function-call-is-not-eliminated/16071/2 "2018-10-09T13:30:37Z")

</div>

What kind of constant propagation were you hoping for? Do you just want LLVM code for returning the constant value of `f(1.)`?

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 1:32pm UTC](https://discourse.julialang.org/t/why-superfluous-function-call-is-not-eliminated/16071/3 "2018-10-09T13:32:45Z")

</div>

I was expecting `sin` not to be called to be called and `T` to be inferred at compile-time.

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [October 9, 2018, 1:37pm UTC](https://discourse.julialang.org/t/why-superfluous-function-call-is-not-eliminated/16071/4 "2018-10-09T13:37:23Z")

</div>

I think `T` is inferred because it returns `%0` directly but LLVM thinks `sin` has side-effects maybe.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 1:45pm UTC](https://discourse.julialang.org/t/why-superfluous-function-call-is-not-eliminated/16071/5 "2018-10-09T13:45:21Z")

</div>

I remember a comment by yuyichao that might apply here. A possible side-effect is that `sin` can throw an exception if `x == Inf`.

However,

```julia
function f(x)
  T = typeof(exp(x))
  convert(T, x)
end

```

still calls `exp` (which I don’t think throws any exceptions)

```julia
@code_llvm f(1.)
define double @julia_f_35146(double) {
top:
  %1 = call double @julia_exp_35147(double %0)
  ret double %0
}

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 9, 2018, 1:55pm UTC](https://discourse.julialang.org/t/why-superfluous-function-call-is-not-eliminated/16071/6 "2018-10-09T13:55:53Z")

</div>

Because there’s no constant to be propagated here.

If your question is instead why pure function isn’t being eliminated, then,

1. `sin` isn’t a pure function.
2. We currently don’t do that optimization.

---

<div class="post-metadata">

**Author:** ![e3c6](https://avatars.discourse-cdn.com/v4/letter/e/e79b87/32.png) [@e3c6](https://discourse.julialang.org/u/e3c6)\
**Post date:** [October 9, 2018, 1:57pm UTC](https://discourse.julialang.org/t/why-superfluous-function-call-is-not-eliminated/16071/7 "2018-10-09T13:57:51Z")

</div>

Is `exp` a pure function? In that case it could be eliminated (say in future Julia)?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 9, 2018, 2:00pm UTC](https://discourse.julialang.org/t/why-superfluous-function-call-is-not-eliminated/16071/8 "2018-10-09T14:00:58Z")

</div>

I mean, any optimization could be implemented but none of them will be guaranteed to be implemented…

Ref [POC/WIP: leverage LLVM function attributes for better CSE by jrevels · Pull Request #29566 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/29566) though.
