jfb created this revision.
jfb added reviewers: rnk, Bigcheese, __simt__.
Herald added subscribers: llvm-commits, lldb-commits, cfe-commits, kadircet, 
arphaman, dexonsmith, jkorous, hiraditya, mgorny.
Herald added projects: clang, LLDB, LLVM.

Some of the cmake checks are obsolete and make bootstrapping an LLVM build 
painful: we only need to check for libatomic which we can do in pure C, no need 
for C++ <atomic>. That leads us to Atomic.h which we can get rid of.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D65493

Files:
  clang-tools-extra/clangd/CMakeLists.txt
  lldb/source/Utility/CMakeLists.txt
  llvm/cmake/modules/CheckAtomic.cmake
  llvm/include/llvm/Support/Atomic.h
  llvm/include/llvm/Support/Threading.h
  llvm/lib/Support/Atomic.cpp
  llvm/lib/Support/Windows/Threading.inc

Index: llvm/lib/Support/Windows/Threading.inc
===================================================================
--- llvm/lib/Support/Windows/Threading.inc
+++ llvm/lib/Support/Windows/Threading.inc
@@ -16,11 +16,6 @@
 #include "WindowsSupport.h"
 #include <process.h>
 
-// Windows will at times define MemoryFence.
-#ifdef MemoryFence
-#undef MemoryFence
-#endif
-
 namespace {
   struct ThreadInfo {
     void(*func)(void*);
Index: llvm/lib/Support/Atomic.cpp
===================================================================
--- llvm/lib/Support/Atomic.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file implements atomic operations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/Atomic.h"
-#include "llvm/Config/llvm-config.h"
-
-using namespace llvm;
-
-#if defined(_MSC_VER)
-#include <intrin.h>
-
-// We must include windows.h after intrin.h.
-#include <windows.h>
-#undef MemoryFence
-#endif
-
-#if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210)
-#define GNU_ATOMICS
-#endif
-
-void sys::MemoryFence() {
-#if LLVM_HAS_ATOMICS == 0
-  return;
-#else
-#  if defined(GNU_ATOMICS)
-  __sync_synchronize();
-#  elif defined(_MSC_VER)
-  MemoryBarrier();
-#  else
-# error No memory fence implementation for your platform!
-#  endif
-#endif
-}
-
-sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
-                                  sys::cas_flag new_value,
-                                  sys::cas_flag old_value) {
-#if LLVM_HAS_ATOMICS == 0
-  sys::cas_flag result = *ptr;
-  if (result == old_value)
-    *ptr = new_value;
-  return result;
-#elif defined(GNU_ATOMICS)
-  return __sync_val_compare_and_swap(ptr, old_value, new_value);
-#elif defined(_MSC_VER)
-  return InterlockedCompareExchange(ptr, new_value, old_value);
-#else
-#  error No compare-and-swap implementation for your platform!
-#endif
-}
Index: llvm/include/llvm/Support/Threading.h
===================================================================
--- llvm/include/llvm/Support/Threading.h
+++ llvm/include/llvm/Support/Threading.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
 #include "llvm/Support/Compiler.h"
+#include <atomic>
 #include <ciso646> // So we can check the C++ standard lib macros.
 #include <functional>
 
@@ -41,8 +42,6 @@
 
 #if LLVM_THREADING_USE_STD_CALL_ONCE
 #include <mutex>
-#else
-#include "llvm/Support/Atomic.h"
 #endif
 
 namespace llvm {
@@ -69,7 +68,7 @@
 
 #if LLVM_THREADING_USE_STD_CALL_ONCE
 
-  typedef std::once_flag once_flag;
+  using once_flag = std::once_flag;
 
 #else
 
@@ -81,7 +80,7 @@
   /// This structure must be used as an opaque object. It is a struct to force
   /// autoinitialization and behave like std::once_flag.
   struct once_flag {
-    volatile sys::cas_flag status = Uninitialized;
+    std::atomic<int> status = ATOMIC_VAR_INIT(Uninitialized);
   };
 
 #endif
@@ -104,23 +103,22 @@
     std::call_once(flag, std::forward<Function>(F),
                    std::forward<Args>(ArgList)...);
 #else
-    // For other platforms we use a generic (if brittle) version based on our
-    // atomics.
-    sys::cas_flag old_val = sys::CompareAndSwap(&flag.status, Wait, Uninitialized);
-    if (old_val == Uninitialized) {
+    InitStatus Expect = Uninitialized;
+    bool Success = flag.status.compare_exchange_strong(Expect, Wait);
+    if (Success) {
       std::forward<Function>(F)(std::forward<Args>(ArgList)...);
-      sys::MemoryFence();
+      std::atomic_thread_fence(std::memory_order_seq_cst);
       TsanIgnoreWritesBegin();
       TsanHappensBefore(&flag.status);
       flag.status = Done;
       TsanIgnoreWritesEnd();
     } else {
       // Wait until any thread doing the call has finished.
-      sys::cas_flag tmp = flag.status;
-      sys::MemoryFence();
+      InitStatus tmp = flag.status;
+      std::atomic_thread_fence(std::memory_order_seq_cst);
       while (tmp != Done) {
         tmp = flag.status;
-        sys::MemoryFence();
+        std::atomic_thread_fence(std::memory_order_seq_cst);
       }
     }
     TsanHappensAfter(&flag.status);
Index: llvm/include/llvm/Support/Atomic.h
===================================================================
--- llvm/include/llvm/Support/Atomic.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===- llvm/Support/Atomic.h - Atomic Operations -----------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the llvm::sys atomic operations.
-//
-// DO NOT USE IN NEW CODE!
-//
-// New code should always rely on the std::atomic facilities in C++11.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_ATOMIC_H
-#define LLVM_SUPPORT_ATOMIC_H
-
-#include "llvm/Support/DataTypes.h"
-
-// Windows will at times define MemoryFence.
-#ifdef MemoryFence
-#undef MemoryFence
-#endif
-
-namespace llvm {
-  namespace sys {
-    void MemoryFence();
-
-#ifdef _MSC_VER
-    typedef long cas_flag;
-#else
-    typedef uint32_t cas_flag;
-#endif
-    cas_flag CompareAndSwap(volatile cas_flag* ptr,
-                            cas_flag new_value,
-                            cas_flag old_value);
-  }
-}
-
-#endif
Index: llvm/cmake/modules/CheckAtomic.cmake
===================================================================
--- llvm/cmake/modules/CheckAtomic.cmake
+++ llvm/cmake/modules/CheckAtomic.cmake
@@ -6,48 +6,44 @@
 # Sometimes linking against libatomic is required for atomic ops, if
 # the platform doesn't support lock-free atomics.
 
-function(check_working_cxx_atomics varname)
+function(check_working_atomics varname)
   set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
-  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
-  CHECK_CXX_SOURCE_COMPILES("
-#include <atomic>
-std::atomic<int> x;
+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c11")
+  CHECK_C_SOURCE_COMPILES("
+_Atomic int x;
 int main() {
   return x;
 }
 " ${varname})
   set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
-endfunction(check_working_cxx_atomics)
+endfunction(check_working_atomics)
 
-function(check_working_cxx_atomics64 varname)
+function(check_working_atomics64 varname)
   set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
-  set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
-  CHECK_CXX_SOURCE_COMPILES("
-#include <atomic>
-#include <cstdint>
-std::atomic<uint64_t> x (0);
+  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c11")
+  CHECK_C_SOURCE_COMPILES("
+_Atomic long long x;
 int main() {
-  uint64_t i = x.load(std::memory_order_relaxed);
-  return 0;
+  return x;
 }
 " ${varname})
   set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
-endfunction(check_working_cxx_atomics64)
+endfunction(check_working_atomics64)
 
 
 # This isn't necessary on MSVC, so avoid command-line switch annoyance
 # by only running on GCC-like hosts.
 if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
   # First check if atomics work without the library.
-  check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
+  check_working_atomics(HAVE_ATOMICS_WITHOUT_LIB)
   # If not, check if the library exists, and atomics work with it.
-  if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
+  if(NOT HAVE_ATOMICS_WITHOUT_LIB)
     check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
     if( HAVE_LIBATOMIC )
       list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
-      check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
-      if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
-	message(FATAL_ERROR "Host compiler must support std::atomic!")
+      check_working_atomics(HAVE_ATOMICS_WITH_LIB)
+      if (NOT HAVE_ATOMICS_WITH_LIB)
+	message(FATAL_ERROR "Host compiler must support atomic!")
       endif()
     else()
       message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
@@ -57,50 +53,25 @@
 
 # Check for 64 bit atomic operations.
 if(MSVC)
-  set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
+  set(HAVE_ATOMICS64_WITHOUT_LIB True)
 else()
-  check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+  check_working_atomics64(HAVE_ATOMICS64_WITHOUT_LIB)
 endif()
 
 # If not, check if the library exists, and atomics work with it.
-if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+if(NOT HAVE_ATOMICS64_WITHOUT_LIB)
   check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
   if(HAVE_CXX_LIBATOMICS64)
     list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
-    check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
-    if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
-      message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
+    check_working_atomics64(HAVE_ATOMICS64_WITH_LIB)
+    if (NOT HAVE_ATOMICS64_WITH_LIB)
+      message(FATAL_ERROR "Host compiler must support 64-bit atomic!")
     endif()
   else()
     message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
   endif()
 endif()
 
-## TODO: This define is only used for the legacy atomic operations in
-## llvm's Atomic.h, which should be replaced.  Other code simply
-## assumes C++11 <atomic> works.
-CHECK_CXX_SOURCE_COMPILES("
-#ifdef _MSC_VER
-#include <windows.h>
-#endif
-int main() {
-#ifdef _MSC_VER
-        volatile LONG val = 1;
-        MemoryBarrier();
-        InterlockedCompareExchange(&val, 0, 1);
-        InterlockedIncrement(&val);
-        InterlockedDecrement(&val);
-#else
-        volatile unsigned long val = 1;
-        __sync_synchronize();
-        __sync_val_compare_and_swap(&val, 1, 0);
-        __sync_add_and_fetch(&val, 1);
-        __sync_sub_and_fetch(&val, 1);
-#endif
-        return 0;
-      }
-" LLVM_HAS_ATOMICS)
-
 if( NOT LLVM_HAS_ATOMICS )
   message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")
 endif()
Index: lldb/source/Utility/CMakeLists.txt
===================================================================
--- lldb/source/Utility/CMakeLists.txt
+++ lldb/source/Utility/CMakeLists.txt
@@ -6,7 +6,7 @@
   list(APPEND LLDB_SYSTEM_LIBS ws2_32 rpcrt4)
 endif ()
 
-if (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB )
+if (NOT HAVE_ATOMICS64_WITHOUT_LIB)
     list(APPEND LLDB_SYSTEM_LIBS atomic)
 endif()
 
Index: clang-tools-extra/clangd/CMakeLists.txt
===================================================================
--- clang-tools-extra/clangd/CMakeLists.txt
+++ clang-tools-extra/clangd/CMakeLists.txt
@@ -25,12 +25,12 @@
   )
 
 if(CLANG_BUILT_STANDALONE)
-  # needed to get HAVE_CXX_ATOMICS64_WITHOUT_LIB defined
+  # needed to get HAVE_ATOMICS64_WITHOUT_LIB defined
   include(CheckAtomic)
 endif()
 
 set(CLANGD_ATOMIC_LIB "")
-if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
+if(NOT HAVE_ATOMICS64_WITHOUT_LIB)
   list(APPEND CLANGD_ATOMIC_LIB "atomic")
 endif()
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to