1*9880d681SAndroid Build Coastguard Worker# atomic builtins are required for threading support. 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard WorkerINCLUDE(CheckCXXSourceCompiles) 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker# Sometimes linking against libatomic is required for atomic ops, if 6*9880d681SAndroid Build Coastguard Worker# the platform doesn't support lock-free atomics. 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerfunction(check_working_cxx_atomics varname) 9*9880d681SAndroid Build Coastguard Worker set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) 10*9880d681SAndroid Build Coastguard Worker set(CMAKE_REQUIRED_FLAGS "-std=c++11") 11*9880d681SAndroid Build Coastguard Worker CHECK_CXX_SOURCE_COMPILES(" 12*9880d681SAndroid Build Coastguard Worker#include <atomic> 13*9880d681SAndroid Build Coastguard Workerstd::atomic<int> x; 14*9880d681SAndroid Build Coastguard Workerint main() { 15*9880d681SAndroid Build Coastguard Worker return x; 16*9880d681SAndroid Build Coastguard Worker} 17*9880d681SAndroid Build Coastguard Worker" ${varname}) 18*9880d681SAndroid Build Coastguard Worker set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) 19*9880d681SAndroid Build Coastguard Workerendfunction(check_working_cxx_atomics) 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Workerfunction(check_working_cxx_atomics64 varname) 22*9880d681SAndroid Build Coastguard Worker set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) 23*9880d681SAndroid Build Coastguard Worker set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}") 24*9880d681SAndroid Build Coastguard Worker CHECK_CXX_SOURCE_COMPILES(" 25*9880d681SAndroid Build Coastguard Worker#include <atomic> 26*9880d681SAndroid Build Coastguard Worker#include <cstdint> 27*9880d681SAndroid Build Coastguard Workerstd::atomic<uint64_t> x (0); 28*9880d681SAndroid Build Coastguard Workerint main() { 29*9880d681SAndroid Build Coastguard Worker uint64_t i = x.load(std::memory_order_relaxed); 30*9880d681SAndroid Build Coastguard Worker return 0; 31*9880d681SAndroid Build Coastguard Worker} 32*9880d681SAndroid Build Coastguard Worker" ${varname}) 33*9880d681SAndroid Build Coastguard Worker set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) 34*9880d681SAndroid Build Coastguard Workerendfunction(check_working_cxx_atomics64) 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker# This isn't necessary on MSVC, so avoid command-line switch annoyance 38*9880d681SAndroid Build Coastguard Worker# by only running on GCC-like hosts. 39*9880d681SAndroid Build Coastguard Workerif (LLVM_COMPILER_IS_GCC_COMPATIBLE) 40*9880d681SAndroid Build Coastguard Worker # First check if atomics work without the library. 41*9880d681SAndroid Build Coastguard Worker check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB) 42*9880d681SAndroid Build Coastguard Worker # If not, check if the library exists, and atomics work with it. 43*9880d681SAndroid Build Coastguard Worker if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) 44*9880d681SAndroid Build Coastguard Worker check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC) 45*9880d681SAndroid Build Coastguard Worker if( HAVE_LIBATOMIC ) 46*9880d681SAndroid Build Coastguard Worker list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") 47*9880d681SAndroid Build Coastguard Worker check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB) 48*9880d681SAndroid Build Coastguard Worker if (NOT HAVE_CXX_ATOMICS_WITH_LIB) 49*9880d681SAndroid Build Coastguard Worker message(FATAL_ERROR "Host compiler must support std::atomic!") 50*9880d681SAndroid Build Coastguard Worker endif() 51*9880d681SAndroid Build Coastguard Worker else() 52*9880d681SAndroid Build Coastguard Worker message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.") 53*9880d681SAndroid Build Coastguard Worker endif() 54*9880d681SAndroid Build Coastguard Worker endif() 55*9880d681SAndroid Build Coastguard Workerendif() 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker# Check for 64 bit atomic operations. 58*9880d681SAndroid Build Coastguard Workerif(MSVC) 59*9880d681SAndroid Build Coastguard Worker set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True) 60*9880d681SAndroid Build Coastguard Workerelse() 61*9880d681SAndroid Build Coastguard Worker check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB) 62*9880d681SAndroid Build Coastguard Workerendif() 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker# If not, check if the library exists, and atomics work with it. 65*9880d681SAndroid Build Coastguard Workerif(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB) 66*9880d681SAndroid Build Coastguard Worker check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64) 67*9880d681SAndroid Build Coastguard Worker if(HAVE_CXX_LIBATOMICS64) 68*9880d681SAndroid Build Coastguard Worker list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") 69*9880d681SAndroid Build Coastguard Worker check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB) 70*9880d681SAndroid Build Coastguard Worker if (NOT HAVE_CXX_ATOMICS64_WITH_LIB) 71*9880d681SAndroid Build Coastguard Worker message(FATAL_ERROR "Host compiler must support std::atomic!") 72*9880d681SAndroid Build Coastguard Worker endif() 73*9880d681SAndroid Build Coastguard Worker else() 74*9880d681SAndroid Build Coastguard Worker message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.") 75*9880d681SAndroid Build Coastguard Worker endif() 76*9880d681SAndroid Build Coastguard Workerendif() 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker## TODO: This define is only used for the legacy atomic operations in 79*9880d681SAndroid Build Coastguard Worker## llvm's Atomic.h, which should be replaced. Other code simply 80*9880d681SAndroid Build Coastguard Worker## assumes C++11 <atomic> works. 81*9880d681SAndroid Build Coastguard WorkerCHECK_CXX_SOURCE_COMPILES(" 82*9880d681SAndroid Build Coastguard Worker#ifdef _MSC_VER 83*9880d681SAndroid Build Coastguard Worker#include <Intrin.h> /* Workaround for PR19898. */ 84*9880d681SAndroid Build Coastguard Worker#include <windows.h> 85*9880d681SAndroid Build Coastguard Worker#endif 86*9880d681SAndroid Build Coastguard Workerint main() { 87*9880d681SAndroid Build Coastguard Worker#ifdef _MSC_VER 88*9880d681SAndroid Build Coastguard Worker volatile LONG val = 1; 89*9880d681SAndroid Build Coastguard Worker MemoryBarrier(); 90*9880d681SAndroid Build Coastguard Worker InterlockedCompareExchange(&val, 0, 1); 91*9880d681SAndroid Build Coastguard Worker InterlockedIncrement(&val); 92*9880d681SAndroid Build Coastguard Worker InterlockedDecrement(&val); 93*9880d681SAndroid Build Coastguard Worker#else 94*9880d681SAndroid Build Coastguard Worker volatile unsigned long val = 1; 95*9880d681SAndroid Build Coastguard Worker __sync_synchronize(); 96*9880d681SAndroid Build Coastguard Worker __sync_val_compare_and_swap(&val, 1, 0); 97*9880d681SAndroid Build Coastguard Worker __sync_add_and_fetch(&val, 1); 98*9880d681SAndroid Build Coastguard Worker __sync_sub_and_fetch(&val, 1); 99*9880d681SAndroid Build Coastguard Worker#endif 100*9880d681SAndroid Build Coastguard Worker return 0; 101*9880d681SAndroid Build Coastguard Worker } 102*9880d681SAndroid Build Coastguard Worker" LLVM_HAS_ATOMICS) 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Workerif( NOT LLVM_HAS_ATOMICS ) 105*9880d681SAndroid Build Coastguard Worker message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing") 106*9880d681SAndroid Build Coastguard Workerendif() 107