This patch adds support for an attribute used to indicate that the function
in question will not loop indefinitely. This is a counter-part to the LLVM
patch
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20100705/103672.htmlwhich
must be applied first.
The idea is that we can't currently delete the dead code:
void foo(set<int> *s) { s->find(10); }
because the compiler is afraid that set<>::find may have the side-effect of
infinite looping. With a halting attribute manually applied in key places,
such as the declaration of find(), we can unstick dead code elimination and
ultimately reduce code size.
Please review!
Nick
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td (revision 107626)
+++ include/clang/Basic/Attr.td (working copy)
@@ -207,6 +207,10 @@
let Spellings = ["gnu_inline"];
}
+def Halting : Attr {
+ let Spellings = ["halting"];
+}
+
def Hiding : Attr {
let Spellings = ["hiding"];
let Subjects = [Field, CXXMethod];
Index: include/clang/AST/Attr.h
===================================================================
--- include/clang/AST/Attr.h (revision 107626)
+++ include/clang/AST/Attr.h (working copy)
@@ -275,6 +275,8 @@
static bool classof(const DestructorAttr *A) { return true; }
};
+DEF_SIMPLE_ATTR(Halting);
+
class IBOutletAttr : public Attr {
public:
IBOutletAttr() : Attr(attr::IBOutlet) {}
Index: include/clang/Parse/AttributeList.h
===================================================================
--- include/clang/Parse/AttributeList.h (revision 107626)
+++ include/clang/Parse/AttributeList.h (working copy)
@@ -79,6 +79,7 @@
AT_format,
AT_format_arg,
AT_gnu_inline,
+ AT_halting,
AT_hiding,
AT_malloc,
AT_mode,
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp (revision 107626)
+++ lib/Sema/SemaDeclAttr.cpp (working copy)
@@ -1856,6 +1856,22 @@
d->addAttr(::new (S.Context) BaseCheckAttr());
}
+static void HandleHaltingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+ // check the attribute arguments.
+ if (Attr.getNumArgs() != 0) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ return;
+ }
+
+ if (!isa<FunctionDecl>(d)) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+ << Attr.getName() << 0 /*function*/;
+ return;
+ }
+
+ d->addAttr(::new (S.Context) HaltingAttr());
+}
+
static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (Attr.getNumArgs() != 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
@@ -2005,6 +2021,7 @@
case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break;
case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break;
+ case AttributeList::AT_halting: HandleHaltingAttr (D, Attr, S); break;
case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break;
case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break;
Index: lib/AST/AttrImpl.cpp
===================================================================
--- lib/AST/AttrImpl.cpp (revision 107626)
+++ lib/AST/AttrImpl.cpp (working copy)
@@ -87,6 +87,7 @@
DEF_SIMPLE_ATTR_CLONE(Deprecated)
DEF_SIMPLE_ATTR_CLONE(FastCall)
DEF_SIMPLE_ATTR_CLONE(Final)
+DEF_SIMPLE_ATTR_CLONE(Halting)
DEF_SIMPLE_ATTR_CLONE(Hiding)
DEF_SIMPLE_ATTR_CLONE(Malloc)
DEF_SIMPLE_ATTR_CLONE(NSReturnsNotRetained)
Index: lib/Lex/PPMacroExpansion.cpp
===================================================================
--- lib/Lex/PPMacroExpansion.cpp (revision 107626)
+++ lib/Lex/PPMacroExpansion.cpp (working copy)
@@ -492,6 +492,7 @@
.Case("attribute_cf_returns_not_retained", true)
.Case("attribute_cf_returns_retained", true)
.Case("attribute_ext_vector_type", true)
+ .Case("attribute_halting", true)
.Case("attribute_ns_returns_not_retained", true)
.Case("attribute_ns_returns_retained", true)
.Case("attribute_objc_ivar_unused", true)
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp (revision 107626)
+++ lib/CodeGen/CGCall.cpp (working copy)
@@ -690,6 +690,8 @@
FuncAttrs |= llvm::Attribute::ReadNone;
else if (TargetDecl->hasAttr<PureAttr>())
FuncAttrs |= llvm::Attribute::ReadOnly;
+ if (TargetDecl->hasAttr<HaltingAttr>())
+ FuncAttrs |= llvm::Attribute::Halting;
if (TargetDecl->hasAttr<MallocAttr>())
RetAttrs |= llvm::Attribute::NoAlias;
}
Index: lib/Parse/AttributeList.cpp
===================================================================
--- lib/Parse/AttributeList.cpp (revision 107626)
+++ lib/Parse/AttributeList.cpp (working copy)
@@ -73,6 +73,7 @@
.Case("unused", AT_unused)
.Case("aligned", AT_aligned)
.Case("cleanup", AT_cleanup)
+ .Case("halting", AT_halting)
.Case("nodebug", AT_nodebug)
.Case("nonnull", AT_nonnull)
.Case("nothrow", AT_nothrow)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits