ARM64 only supports sibling call, and it doesn't really support aggressive tail call optimization as AArch64 is able to do right now. This patch is to support aggressive tail call optimization for ARM64. There is a tracker at http://llvm.org/bugs/show_bug.cgi?id=19426 describing the issue, and this is blocking the merge from AArch64 to ARM64.
Originally ARM64 is using IsTailCall to represent sibling call. With this patch, IsTailCall is changed to be the original tail call eligibility meaning, and IsSibCall is added to describe the real sibling call.
Both sibling call and tail call optimizations use branch instruction to replace the call, and remove the return instruction after calling the callee, but the difference is sibling call doesn't break traditional ABI, i.e. not pop argument stack, while tail call does.
IsTailCall, TailCallOpt and IsSibCall have the following relationships,
- IsTailCall and TailCallOpt are orthogonal.
- IsTailCall means a callee isEligibleForTailCallOptimization().
- TailCallOpt means command line option switch Options.GuaranteedTailCallOpt only.
- IsSibCall = (!TailCallOpt && IsTailCall)
For Darwin, I'm not sure if we still need to guarantee 16-byte alignment, so the tests don't really cover arm64-darwin yet.
Thanks,
-Jiangning
It looks like ARM64's emitFrameOffset can handle larger immediates (up to 24 bits easily, beyond that inefficiently). Same thing later.