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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits