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