# Why superfluous function call is not eliminated?

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

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

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, but I thought it was a separate question.

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

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

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

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,

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

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

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

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.
3 Likes

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

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

2 Likes