diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2015-11-13 00:42:21 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2015-11-13 00:42:21 +0000 |
commit | 7828b1e604f22e81815a3c2fc357e319f2807bb8 (patch) | |
tree | 0a15c5c8a42974829ad072a1e891cf4cb664ec6c /clang/lib | |
parent | c9dd057e3ccdbe44dd2aa2fd0303ff9a26c45f15 (diff) | |
download | bcm5719-llvm-7828b1e604f22e81815a3c2fc357e319f2807bb8.tar.gz bcm5719-llvm-7828b1e604f22e81815a3c2fc357e319f2807bb8.zip |
Add support for function attribute 'disable_tail_calls'.
The ``disable_tail_calls`` attribute instructs the backend to not
perform tail call optimization inside the marked function.
For example,
int callee(int);
int foo(int a) __attribute__((disable_tail_calls)) {
return callee(a); // This call is not tail-call optimized.
}
Note that this attribute is different from 'not_tail_called', which
prevents tail-call optimization to the marked function.
rdar://problem/8973573
Differential Revision: http://reviews.llvm.org/D12547
llvm-svn: 252986
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 24 |
2 files changed, 28 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 430184d4398..5dea876451f 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1481,8 +1481,12 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, FuncAttrs.addAttribute("no-frame-pointer-elim-non-leaf"); } + bool DisableTailCalls = + CodeGenOpts.DisableTailCalls || + (TargetDecl && TargetDecl->hasAttr<DisableTailCallsAttr>()); FuncAttrs.addAttribute("disable-tail-calls", - llvm::toStringRef(CodeGenOpts.DisableTailCalls)); + llvm::toStringRef(DisableTailCalls)); + FuncAttrs.addAttribute("less-precise-fpmad", llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD)); FuncAttrs.addAttribute("no-infs-fp-math", diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index a9473d2e119..abdab9a0692 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1583,6 +1583,15 @@ static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { D->addAttr(CA); } +static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) { + if (checkAttrMutualExclusion<DisableTailCallsAttr>(S, D, Attr.getRange(), + Attr.getName())) + return; + + D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context, + Attr.getAttributeSpellingListIndex())); +} + static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) { if (hasDeclarator(D)) return; @@ -1713,6 +1722,16 @@ static void handleNotTailCalledAttr(Sema &S, Decl *D, Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); } +static void handleDisableTailCallsAttr(Sema &S, Decl *D, + const AttributeList &Attr) { + if (checkAttrMutualExclusion<NakedAttr>(S, D, Attr.getRange(), + Attr.getName())) + return; + + D->addAttr(::new (S.Context) DisableTailCallsAttr( + Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); +} + static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { if (VD->hasLocalStorage()) { @@ -4933,7 +4952,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, handleHotAttr(S, D, Attr); break; case AttributeList::AT_Naked: - handleSimpleAttribute<NakedAttr>(S, D, Attr); + handleNakedAttr(S, D, Attr); break; case AttributeList::AT_NoReturn: handleNoReturnAttr(S, D, Attr); @@ -5056,6 +5075,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_NotTailCalled: handleNotTailCalledAttr(S, D, Attr); break; + case AttributeList::AT_DisableTailCalls: + handleDisableTailCallsAttr(S, D, Attr); + break; case AttributeList::AT_Used: handleUsedAttr(S, D, Attr); break; |