diff options
author | Joshua Haberman <jhaberman@gmail.com> | 2021-04-15 16:49:19 -0700 |
---|---|---|
committer | Richard Smith <richard@metafoo.co.uk> | 2021-04-15 17:12:21 -0700 |
commit | 8344675908424ee532d4ae30e5043c5a5834e02c (patch) | |
tree | dd25b2df07b856bb22f4610b6ad734f0425cd088 /clang/lib/CodeGen/CodeGenFunction.h | |
parent | f280505aa08432f5d4c4296122c6ff728b753398 (diff) | |
download | llvm-8344675908424ee532d4ae30e5043c5a5834e02c.zip llvm-8344675908424ee532d4ae30e5043c5a5834e02c.tar.gz llvm-8344675908424ee532d4ae30e5043c5a5834e02c.tar.bz2 |
Implemented [[clang::musttail]] attribute for guaranteed tail calls.
This is a Clang-only change and depends on the existing "musttail"
support already implemented in LLVM.
The [[clang::musttail]] attribute goes on a return statement, not
a function definition. There are several constraints that the user
must follow when using [[clang::musttail]], and these constraints
are verified by Sema.
Tail calls are supported on regular function calls, calls through a
function pointer, member function calls, and even pointer to member.
Future work would be to throw a warning if a users tries to pass
a pointer or reference to a local variable through a musttail call.
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D99517
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 0b3da9e..7723382 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -520,6 +520,10 @@ public: /// True if the current statement has nomerge attribute. bool InNoMergeAttributedStmt = false; + // The CallExpr within the current statement that the musttail attribute + // applies to. nullptr if there is no 'musttail' on the current statement. + const CallExpr *MustTailCall = nullptr; + /// True if the current function should be marked mustprogress. bool FnIsMustProgress = false; @@ -568,6 +572,8 @@ public: llvm::Instruction *CurrentFuncletPad = nullptr; class CallLifetimeEnd final : public EHScopeStack::Cleanup { + bool isRedundantBeforeReturn() override { return true; } + llvm::Value *Addr; llvm::Value *Size; @@ -3913,12 +3919,14 @@ public: /// LLVM arguments and the types they were derived from. RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, - llvm::CallBase **callOrInvoke, SourceLocation Loc); + llvm::CallBase **callOrInvoke, bool IsMustTail, + SourceLocation Loc); RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, - llvm::CallBase **callOrInvoke = nullptr) { + llvm::CallBase **callOrInvoke = nullptr, + bool IsMustTail = false) { return EmitCall(CallInfo, Callee, ReturnValue, Args, callOrInvoke, - SourceLocation()); + IsMustTail, SourceLocation()); } RValue EmitCall(QualType FnType, const CGCallee &Callee, const CallExpr *E, ReturnValueSlot ReturnValue, llvm::Value *Chain = nullptr); |