zoecarver created this revision.
Herald added a reviewer: jfb.
Herald added subscribers: cfe-commits, kbarton, aheejin, javed.absar, nemanjai.
Herald added a project: clang.

Creates the `__builtin_hardware_destructive_interference_size` and 
`__builtin_hardware_constructive_interference_size` builtins proposed by @jfb 
[[ here | http://lists.llvm.org/pipermail/cfe-dev/2018-May/058073.html ]]. 
These builtins can be used to implement [[ P0154 | http://wg21.link/P0154 ]] in 
libc++ and other standard libraries. My implementation switches on the target 
triple to get the max cache line size for that target. I am not sure if this is 
the best way to implement these builtins, but it will ensure that there is not 
an ABI break.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D66822

Files:
  clang/include/clang/Basic/Builtins.def
  clang/lib/AST/ExprConstant.cpp
  clang/test/Sema/builtins.c
  clang/test/SemaCXX/builtin-hardware-interference-size-aarch.cpp
  clang/test/SemaCXX/builtin-hardware-interference-size-amd.cpp
  clang/test/SemaCXX/builtin-hardware-interference-size-arm.cpp
  clang/test/SemaCXX/builtin-hardware-interference-size-nvptx.cpp
  clang/test/SemaCXX/builtin-hardware-interference-size-ppc.cpp
  clang/test/SemaCXX/builtin-hardware-interference-size-unknown.cpp
  clang/test/SemaCXX/builtin-hardware-interference-size-x86.cpp

Index: clang/test/SemaCXX/builtin-hardware-interference-size-x86.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/builtin-hardware-interference-size-x86.cpp
@@ -0,0 +1,7 @@
+// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-unknown-unknown
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-apple-darwin16.0.0
+
+static_assert(__builtin_hardware_constructive_interference_size() == 64);
+static_assert(__builtin_hardware_destructive_interference_size() == 64);
Index: clang/test/SemaCXX/builtin-hardware-interference-size-unknown.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/builtin-hardware-interference-size-unknown.cpp
@@ -0,0 +1,9 @@
+// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=systemz-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=wasm32-unknown-unknown
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=wasm64-unknown-unknown
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=hexagon-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=systemz-apple-darwin16.0.0
+
+static_assert(__builtin_hardware_constructive_interference_size() == 0);
+static_assert(__builtin_hardware_destructive_interference_size() == 0);
Index: clang/test/SemaCXX/builtin-hardware-interference-size-ppc.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/builtin-hardware-interference-size-ppc.cpp
@@ -0,0 +1,8 @@
+// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=ppc-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=ppc64-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=ppc64le-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=ppc-apple-darwin16.0.0
+
+static_assert(__builtin_hardware_constructive_interference_size() == 128);
+static_assert(__builtin_hardware_destructive_interference_size() == 128);
Index: clang/test/SemaCXX/builtin-hardware-interference-size-nvptx.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/builtin-hardware-interference-size-nvptx.cpp
@@ -0,0 +1,7 @@
+// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=nvptx-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=nvptx64-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=nvptx-apple-darwin16.0.0
+
+static_assert(__builtin_hardware_constructive_interference_size() == 64);
+static_assert(__builtin_hardware_destructive_interference_size() == 64);
Index: clang/test/SemaCXX/builtin-hardware-interference-size-arm.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/builtin-hardware-interference-size-arm.cpp
@@ -0,0 +1,9 @@
+// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=arm-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=armeb-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=thumb-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=thumbeb-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=arm-apple-darwin16.0.0
+
+static_assert(__builtin_hardware_constructive_interference_size() == 64);
+static_assert(__builtin_hardware_destructive_interference_size() == 64);
Index: clang/test/SemaCXX/builtin-hardware-interference-size-amd.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/builtin-hardware-interference-size-amd.cpp
@@ -0,0 +1,7 @@
+// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=r600-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=amdgcn-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=amdgcn-apple-darwin16.0.0
+
+static_assert(__builtin_hardware_constructive_interference_size() == 64);
+static_assert(__builtin_hardware_destructive_interference_size() == 64);
Index: clang/test/SemaCXX/builtin-hardware-interference-size-aarch.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/builtin-hardware-interference-size-aarch.cpp
@@ -0,0 +1,7 @@
+// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=aarch64-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=aarch64_be-linux-gnu
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=aarch64-apple-darwin16.0.0
+
+static_assert(__builtin_hardware_constructive_interference_size() == 128);
+static_assert(__builtin_hardware_destructive_interference_size() == 128);
Index: clang/test/Sema/builtins.c
===================================================================
--- clang/test/Sema/builtins.c
+++ clang/test/Sema/builtins.c
@@ -234,7 +234,7 @@
 
         strlcat(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcat' call appears to be size of the source; expected the size of the destination}} \
                                     // expected-note {{change size argument to be the size of the destination}}
-				    
+
         __builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call appears to be size of the source; expected the size of the destination}} \
                                                                                    // expected-note {{change size argument to be the size of the destination}} \
 				                                                   // expected-warning {{'strlcat' will always overflow; destination buffer has size 20, but size argument is 40}}
@@ -315,8 +315,16 @@
   my_memcpy(buf, src, 11); // expected-warning{{'memcpy' will always overflow; destination buffer has size 10, but size argument is 11}}
 }
 
-// Test that __builtin_is_constant_evaluated() is not allowed in C
-int test_cxx_builtin() {
+// Test that C++ builtins are not allowed in C
+void test_cxx_builtin() {
   // expected-error@+1 {{use of unknown builtin '__builtin_is_constant_evaluated'}}
-  return __builtin_is_constant_evaluated();
+  (void)__builtin_is_constant_evaluated();
+
+  // expected-error@+2 {{use of unknown builtin '__builtin_hardware_destructive_interference_size'}}
+  // expected-note@+1 {{'__builtin_hardware_destructive_interference_size' declared here}}
+  (void)__builtin_hardware_destructive_interference_size();
+
+  // expected-error@+2 {{use of unknown builtin '__builtin_hardware_constructive_interference_size'}}
+  // expected-note@+1 {{did you mean '__builtin_hardware_destructive_interference_size'?}}
+  (void)__builtin_hardware_constructive_interference_size();
 }
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -9478,6 +9478,40 @@
   return ExprEvaluatorBaseTy::VisitCallExpr(E);
 }
 
+static unsigned getCacheLineSize(llvm::Triple::ArchType Arch) {
+    switch (Arch) {
+    case llvm::Triple::arm:
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumb:
+    case llvm::Triple::thumbeb:
+        // This value is between 8 and 64. We are using the upper bound to be safe.
+        return 64;
+    case llvm::Triple::aarch64:
+    case llvm::Triple::aarch64_be:
+        // Sometimes bit.LITTLE will have cores with both a 64 and 128 line sizes.
+        return 128;
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
+        return 64;
+    case llvm::Triple::ppc:
+    case llvm::Triple::ppc64:
+    case llvm::Triple::ppc64le:
+        return 128;
+    case llvm::Triple::r600:
+    case llvm::Triple::amdgcn:
+        return 64;
+    case llvm::Triple::nvptx:
+    case llvm::Triple::nvptx64:
+        return 64;
+    case llvm::Triple::systemz:
+    case llvm::Triple::wasm32:
+    case llvm::Triple::wasm64:
+    case llvm::Triple::hexagon:
+    default:
+        return 0;
+    }
+}
+
 bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
                                             unsigned BuiltinOp) {
   switch (unsigned BuiltinOp = E->getBuiltinCallee()) {
@@ -9575,6 +9609,12 @@
 
   case Builtin::BI__builtin_is_constant_evaluated:
     return Success(Info.InConstantContext, E);
+  case Builtin::BI__builtin_hardware_destructive_interference_size:
+  case Builtin::BI__builtin_hardware_constructive_interference_size: {
+    unsigned cacheLineSize
+        = getCacheLineSize(Info.Ctx.getTargetInfo().getTriple().getArch());
+    return Success(cacheLineSize, E);
+  }
 
   case Builtin::BI__builtin_ctz:
   case Builtin::BI__builtin_ctzl:
Index: clang/include/clang/Basic/Builtins.def
===================================================================
--- clang/include/clang/Basic/Builtins.def
+++ clang/include/clang/Basic/Builtins.def
@@ -525,6 +525,8 @@
 BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
 BUILTIN(__builtin_thread_pointer, "v*", "nc")
 BUILTIN(__builtin_launder, "v*v*", "nt")
+LANGBUILTIN(__builtin_hardware_destructive_interference_size, "i", "n", CXX_LANG)
+LANGBUILTIN(__builtin_hardware_constructive_interference_size, "i", "n", CXX_LANG)
 LANGBUILTIN(__builtin_is_constant_evaluated, "b", "n", CXX_LANG)
 
 // GCC exception builtins
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to