r201941 - Exposing the noduplicate attribute within Clang, which marks functions so that the optimizer does not duplicate code.

Aaron Ballman aaron at aaronballman.com
Sat Feb 22 08:59:25 PST 2014


Author: aaronballman
Date: Sat Feb 22 10:59:24 2014
New Revision: 201941

URL: http://llvm.org/viewvc/llvm-project?rev=201941&view=rev
Log:
Exposing the noduplicate attribute within Clang, which marks functions so that the optimizer does not duplicate code.

Patch thanks to Marcello Maggioni!

Added:
    cfe/trunk/test/CodeGen/noduplicate-cxx11-test.cpp
    cfe/trunk/test/Sema/attr-noduplicate.c
Modified:
    cfe/trunk/docs/AttributeReference.rst
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/AttrDocs.td
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Modified: cfe/trunk/docs/AttributeReference.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/AttributeReference.rst?rev=201941&r1=201940&r2=201941&view=diff
==============================================================================
--- cfe/trunk/docs/AttributeReference.rst (original)
+++ cfe/trunk/docs/AttributeReference.rst Sat Feb 22 10:59:24 2014
@@ -558,6 +558,50 @@ caveats to this use of name mangling:
 
 Query for this feature with ``__has_extension(attribute_overloadable)``.
 
+noduplicate
+-----------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+The ``noduplicate`` attribute can be placed on function declarations to control
+whether function calls to this function can be duplicated 
+or not as a result of optimizations. This is required for the implementation
+of functions with certain special requirements, like the OpenCL "barrier", 
+function that, depending on the hardware, might require to be run concurrently
+by all the threads that are currently executing in lockstep on the hardware.
+For example this attribute applied on the function "nodupfunc" 
+avoids that this code:
+
+.. code-block:: c
+
+  void nodupfunc() __attribute__((noduplicate));
+  // Setting it as a C++11 attribute is also valid
+  // void nodupfunc() [[clang::noduplicate]];
+  void foo();
+  void bar();
+
+  nodupfunc();
+  if (a > n) {
+    foo();
+  } else {
+    bar();
+  }
+
+gets possibly modified by some optimization into code similar to this:
+
+.. code-block:: c
+
+  if (a > n) {
+    nodupfunc();
+    foo();
+  } else {
+    nodupfunc();
+    bar();
+  }
+
+where the barrier call is duplicated and sunk into the two branches of the condition.
 
 Variable Attributes
 ===================

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=201941&r1=201940&r2=201941&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Sat Feb 22 10:59:24 2014
@@ -803,6 +803,12 @@ def NoDebug : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
+def NoDuplicate : InheritableAttr {
+  let Spellings = [GNU<"noduplicate">, CXX11<"clang", "noduplicate">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [NoDuplicateDocs];
+}
+
 def NoInline : InheritableAttr {
   let Spellings = [GCC<"noinline">, Declspec<"noinline">];
   let Subjects = SubjectList<[Function]>;

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=201941&r1=201940&r2=201941&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Sat Feb 22 10:59:24 2014
@@ -299,6 +299,49 @@ Query for this feature with ``__has_attr
   }];
 }
 
+def NoDuplicateDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``noduplicate`` attribute can be placed on function declarations to control
+whether function calls to this function can be duplicated 
+or not as a result of optimizations. This is required for the implementation
+of functions with certain special requirements, like the OpenCL "barrier", 
+function that, depending on the hardware, might require to be run concurrently
+by all the threads that are currently executing in lockstep on the hardware.
+For example this attribute applied on the function "nodupfunc" 
+avoids that this code:
+
+.. code-block:: c
+
+  void nodupfunc() __attribute__((noduplicate));
+  // Setting it as a C++11 attribute is also valid
+  // void nodupfunc() [[clang::noduplicate]];
+  void foo();
+  void bar();
+
+  nodupfunc();
+  if (a > n) {
+    foo();
+  } else {
+    bar();
+  }
+
+gets possibly modified by some optimization into code similar to this:
+
+.. code-block:: c
+
+  if (a > n) {
+    nodupfunc();
+    foo();
+  } else {
+    nodupfunc();
+    bar();
+  }
+
+where the barrier call is duplicated and sunk into the two branches of the condition.
+  }];
+}
+
 def ObjCRequiresSuperDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
@@ -842,4 +885,4 @@ Clang implements two kinds of checks wit
    the corresponding arguments are annotated.  If the arguments are
    incorrect, the caller of ``foo`` will receive a warning.
   }];
-}
\ No newline at end of file
+}

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=201941&r1=201940&r2=201941&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Sat Feb 22 10:59:24 2014
@@ -1052,6 +1052,8 @@ void CodeGenModule::ConstructAttributeLi
       FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
     if (TargetDecl->hasAttr<NoReturnAttr>())
       FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
+    if (TargetDecl->hasAttr<NoDuplicateAttr>())
+      FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
 
     if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
       const FunctionProtoType *FPT = Fn->getType()->getAs<FunctionProtoType>();

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=201941&r1=201940&r2=201941&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sat Feb 22 10:59:24 2014
@@ -631,6 +631,8 @@ void CodeGenModule::SetLLVMFunctionAttri
     // Naked implies noinline: we should not be inlining such functions.
     B.addAttribute(llvm::Attribute::Naked);
     B.addAttribute(llvm::Attribute::NoInline);
+  } else if (D->hasAttr<NoDuplicateAttr>()) {
+    B.addAttribute(llvm::Attribute::NoDuplicate);
   } else if (D->hasAttr<NoInlineAttr>()) {
     B.addAttribute(llvm::Attribute::NoInline);
   } else if ((D->hasAttr<AlwaysInlineAttr>() ||

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=201941&r1=201940&r2=201941&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sat Feb 22 10:59:24 2014
@@ -4237,6 +4237,8 @@ static void ProcessDeclAttribute(Sema &S
     handleSimpleAttribute<PureAttr>(S, D, Attr); break;
   case AttributeList::AT_Cleanup:     handleCleanupAttr     (S, D, Attr); break;
   case AttributeList::AT_NoDebug:     handleNoDebugAttr     (S, D, Attr); break;
+  case AttributeList::AT_NoDuplicate:
+    handleSimpleAttribute<NoDuplicateAttr>(S, D, Attr); break;
   case AttributeList::AT_NoInline:
     handleSimpleAttribute<NoInlineAttr>(S, D, Attr); break;
   case AttributeList::AT_NoInstrumentFunction:  // Interacts with -pg.

Added: cfe/trunk/test/CodeGen/noduplicate-cxx11-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/noduplicate-cxx11-test.cpp?rev=201941&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/noduplicate-cxx11-test.cpp (added)
+++ cfe/trunk/test/CodeGen/noduplicate-cxx11-test.cpp Sat Feb 22 10:59:24 2014
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple=i686-pc-unknown -std=c++11 %s  -emit-llvm -o - | FileCheck %s
+
+// This was a problem in Sema, but only shows up as noinline missing
+// in CodeGen.
+
+// CHECK: define i32 @_Z15noduplicatedfuni(i32 %a) [[NI:#[0-9]+]]
+
+int noduplicatedfun [[clang::noduplicate]] (int a) {
+
+  return a+1;
+
+}
+
+int main() {
+
+  return noduplicatedfun(5);
+
+}
+
+// CHECK: attributes [[NI]] = { noduplicate nounwind{{.*}} }

Added: cfe/trunk/test/Sema/attr-noduplicate.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-noduplicate.c?rev=201941&view=auto
==============================================================================
--- cfe/trunk/test/Sema/attr-noduplicate.c (added)
+++ cfe/trunk/test/Sema/attr-noduplicate.c Sat Feb 22 10:59:24 2014
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int a __attribute__((noduplicate)); // expected-warning {{'noduplicate' attribute only applies to functions}}
+
+void t1() __attribute__((noduplicate));
+
+void t2() __attribute__((noduplicate(2))); // expected-error {{'noduplicate' attribute takes no arguments}}
+





More information about the cfe-commits mailing list