I learned about __attribute__((const)) that allows LLVM to emit only single call when same function called with identical arguments. But I noticed that it appears to work at the scope of the basic block rather than a function.
I.e. if calls are looking something like this:
int main()
{
var i = func(1);
do_something_with(i);
var y = func(1);
do_something_with(y);
}
LLVM will make only single call to func(1).
But if instead it will look something like this:
int main(int z, int w)
{
if (z == 1)
{
var i = func(1);
do_something_with(i);
}
if (w == 1)
{
var y = func(1);
do_something_with(y);
}
}
LLVM will emit two separate calls to func(1) in -Oz optimization mode.
Interestingly, if I add another call to func(1) right before if block, it will fallback to making a single call.
My goal is to get LLVM to generate code in the case #2 above with a single call to func(1). I.e. I want LLVM to move func(1) to the level above if blocks.
Here is interactive example of what I am talking about - https://godbolt.org/z/8Yovo8o6a - notice how two calls to fetch cnt() is made, while only one to fetch cnt2().
Is there some kind of instructions re-ordering optimization available that can accomplish that without inserting dummy call to the "top level scope" of the function?