LLVM tail call optimization

早过忘川 提交于 2019-12-05 10:58:22

There are two different things here:

  1. You can optimise self-recursive tail calls into a loop. LLVM provides an optimisation pass that does this. It does not require a specific calling convention.
  2. You can use a different calling convention to guarantee tail call optimisation of all calls in tail position (i.e. including calls to other functions). With LLVM, you need to specify the calling convention on the function, on the call instruction and mark the call as a tail call.

Sounds like you want the former.

Apparently the answer is yes. You have to change the definition of h to see this (because the optimizer is too good! It figures out that h is either the identity or returns 0).

Consider

int factorial (int x, int y){
  if (x==0)
    return y;
  else
    return factorial(x-1,y*x);
}

Compiled with clang -S -emit-llvm, so that no optimization is performed. One sees that no calling conventions are directly specified, which means that the default calling convention is enough to support tail recursion optimization (whether or not it supports tail calling in general is a different story -- it would be interesting to know, but I guess that is really a different question).

The file emitted by clang -S -emit-llvm is main.s (assuming the factorial definition is in main.c). If you run

opt -O3 main.s -S -o mainOpt.s

then you can see that the tail recursion is eliminated. There is an optimization called tailcallelim which may be turned on as -O3. It's hard to tell because the help file, opt --help, says only that -O3 is similar to gcc -O3.

The point is that we can see that the calling convention does not need to specified for this. Maybe fastcc is not needed, or maybe it is default? So (1) is partially answered; however, I still do not know (2) or (3).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!