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

Reply via email to