[PATCH] D99517: Implemented [[clang::musttail]] attribute for guaranteed tail calls.

John McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 2 16:17:40 PDT 2021


rjmccall added a comment.

In D99517#2667088 <https://reviews.llvm.org/D99517#2667088>, @rsmith wrote:

> In D99517#2667025 <https://reviews.llvm.org/D99517#2667025>, @rjmccall wrote:
>
>> You should structure this code so it's easy to add exceptions for certain calling conventions that can support tail calls with weaker restrictions (principally, callee-pop conventions).  Mostly that probably means checking the calling convention first, or extracting the type restriction checks into a different function that you can skip.  For example, I believe x86's `fastcall` convention can logically support any combination of prototypes as `musttail` as long as the return types are vaguely compatible.
>
> The LLVM `musttail` flag doesn't seem to allow for any target-specific loosening of the rules at the moment, so I don't think we can get any benefit from such restructuring right now; do you think it's OK to defer this restructuring and use the stricter rules across all targets for now?

Right, I wasn't suggesting that we needed to implement weaker rules right now, just that it'd be nice if the code didn't have to be totally restructured just to do it.  Right now it's one big function that does all the checks.

> I think there is also value in having a target-independent set of restrictions, even if we could actually guarantee tail calls in more circumstances on some (or maybe most!) targets, in order to allow people to make portable use of the attribute and as data towards something that we might be able to standardize. (For example, the people working on coroutines in C++ wanted something like this, but wanted feedback from implementers on what set of restrictions would be necessary in order to portably guarantee a tail call.) In order to strike a balance between portability and usefulness here, maybe we could plan to eventually accept any musttail call we know the target can support, but warn on musttail calls that don't satisfy the stricter rules and therefore may be non-portable?

I agree that we should not start loosening restrictions based on the vagaries of the platform CC, e.g. recognizing that a particular set of arguments happens to be passed solely in registers.  I was thinking about callee-pop CCs, like `fastcall` and `swiftasynccall`, which are generally designed from the start to support almost unrestricted tail calls; e.g. the only restriction on tail calls between `fastcall` functions is that the return types are compatible.  (IIRC — it's possible that highly-aligned arguments would change that.)  Since tail calls are part of the designed feature set of these conventions, it seems appropriate to think about them when adding a tail-call feature.

Standard C conventions generally don't support unrestricted tail calls (because of variadics, unprototyped calls, easier assembly-writing, and history), so this would only apply as a target-specific extension when used in conjunction with a non-standard CC, which meshes well with your goals for standardization.  I just want you to write the code so that maintainers can more easily skip some of the restrictions to cover a non-standard CC.

I'm not surprised that the C++ coroutine people want unrestricted tail calls; this is all pretty predictable, and it's essentially the point I made about generic coroutine lowering several years ago at LLVM dev.  Really, they need to be asking for a standard calling convention that guarantees unrestricted tail calls.  Of course, that would require the standard to admit the existence of calling conventions (other than language linkage :)).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D99517/new/

https://reviews.llvm.org/D99517



More information about the cfe-commits mailing list