sdardis created this revision.
sdardis added a subscriber: cfe-commits.
Herald added a reviewer: vkalintiris.
Herald added a subscriber: aemerson.

Targets typically support atomics that are word sized (e.g. 32 or 64 bit) or
half word sized (e.g. 32 bit on 64 bit systems). For larger sizes, some
targets can perform them directly (x86, ARM), other must expand them into
a library call. This patch adds the optional warning -Watomic-libcall which
warns when a atomic operation cannot be expanded inline and must use a
library call.

https://reviews.llvm.org/D24448

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaChecking.cpp
  test/Sema/atomic-libcall.c

Index: test/Sema/atomic-libcall.c
===================================================================
--- /dev/null
+++ test/Sema/atomic-libcall.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -triple=mips-mti-linux-gnu 
-Watomic-libcall
+
+// Test that larger than word size atomics are warned about.
+
+long long var;
+
+void foo(long long a) {
+  __sync_fetch_and_add(&var, 0, a); // expected-warning {{atomic builtin 
expands to library call}}
+}
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -3035,6 +3035,15 @@
 
   ASTContext& Context = this->getASTContext();
 
+  // Warn if the requested atomic will expand into a library call, as this can
+  // impact performance significantly if it requires kernel intervention or
+  // some other shared but hidden lock.
+  if (Context.getTypeSizeInChars(ValType) >
+      Context.toCharUnitsFromBits(
+          Context.getTargetInfo().getMaxAtomicInlineWidth())) {
+    Diag(DRE->getLocStart(), diag::warn_atomic_builtin_expands_to_libcall);
+  }
+
   // Create a new DeclRefExpr to refer to the new decl.
   DeclRefExpr* NewDRE = DeclRefExpr::Create(
       Context,
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5118,6 +5118,8 @@
   "_Atomic cannot be applied to "
   "%select{incomplete |array |function |reference |atomic |qualified |}0type "
   "%1 %select{||||||which is not trivially copyable}0">;
+def warn_atomic_builtin_expands_to_libcall : Warning<
+  "atomic builtin expands to library call">, InGroup<AtomicLibcall>, 
DefaultIgnore;
 
 // Expressions.
 def ext_sizeof_alignof_function_type : Extension<
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -859,6 +859,8 @@
 def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
 def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
 
+def AtomicLibcall : DiagGroup<"atomic-libcall">;
+
 // AddressSanitizer frontent instrumentation remarks.
 def SanitizeAddressRemarks : DiagGroup<"sanitize-address">;
 
@@ -880,4 +882,4 @@
 
 // A warning group for warnings about code that clang accepts when
 // compiling OpenCL C/C++ but which is not compatible with the SPIR spec.
-def SpirCompat : DiagGroup<"spir-compat">;
\ No newline at end of file
+def SpirCompat : DiagGroup<"spir-compat">;


Index: test/Sema/atomic-libcall.c
===================================================================
--- /dev/null
+++ test/Sema/atomic-libcall.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -triple=mips-mti-linux-gnu -Watomic-libcall
+
+// Test that larger than word size atomics are warned about.
+
+long long var;
+
+void foo(long long a) {
+  __sync_fetch_and_add(&var, 0, a); // expected-warning {{atomic builtin expands to library call}}
+}
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -3035,6 +3035,15 @@
 
   ASTContext& Context = this->getASTContext();
 
+  // Warn if the requested atomic will expand into a library call, as this can
+  // impact performance significantly if it requires kernel intervention or
+  // some other shared but hidden lock.
+  if (Context.getTypeSizeInChars(ValType) >
+      Context.toCharUnitsFromBits(
+          Context.getTargetInfo().getMaxAtomicInlineWidth())) {
+    Diag(DRE->getLocStart(), diag::warn_atomic_builtin_expands_to_libcall);
+  }
+
   // Create a new DeclRefExpr to refer to the new decl.
   DeclRefExpr* NewDRE = DeclRefExpr::Create(
       Context,
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5118,6 +5118,8 @@
   "_Atomic cannot be applied to "
   "%select{incomplete |array |function |reference |atomic |qualified |}0type "
   "%1 %select{||||||which is not trivially copyable}0">;
+def warn_atomic_builtin_expands_to_libcall : Warning<
+  "atomic builtin expands to library call">, InGroup<AtomicLibcall>, DefaultIgnore;
 
 // Expressions.
 def ext_sizeof_alignof_function_type : Extension<
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -859,6 +859,8 @@
 def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
 def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
 
+def AtomicLibcall : DiagGroup<"atomic-libcall">;
+
 // AddressSanitizer frontent instrumentation remarks.
 def SanitizeAddressRemarks : DiagGroup<"sanitize-address">;
 
@@ -880,4 +882,4 @@
 
 // A warning group for warnings about code that clang accepts when
 // compiling OpenCL C/C++ but which is not compatible with the SPIR spec.
-def SpirCompat : DiagGroup<"spir-compat">;
\ No newline at end of file
+def SpirCompat : DiagGroup<"spir-compat">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to