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