summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2015-11-13 00:42:21 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2015-11-13 00:42:21 +0000
commit7828b1e604f22e81815a3c2fc357e319f2807bb8 (patch)
tree0a15c5c8a42974829ad072a1e891cf4cb664ec6c /clang/lib
parentc9dd057e3ccdbe44dd2aa2fd0303ff9a26c45f15 (diff)
downloadbcm5719-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.cpp6
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp24
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;
OpenPOWER on IntegriCloud