1# atomic builtins are required for threading support. 2 3INCLUDE(CheckCXXSourceCompiles) 4 5# Sometimes linking against libatomic is required for atomic ops, if 6# the platform doesn't support lock-free atomics. 7 8function(check_working_cxx_atomics varname) 9 set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) 10 set(CMAKE_REQUIRED_FLAGS "-std=c++11") 11 CHECK_CXX_SOURCE_COMPILES(" 12#include <atomic> 13std::atomic<int> x; 14int main() { 15 return x; 16} 17" ${varname}) 18 set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) 19endfunction(check_working_cxx_atomics) 20 21# This isn't necessary on MSVC, so avoid command-line switch annoyance 22# by only running on GCC-like hosts. 23if (LLVM_COMPILER_IS_GCC_COMPATIBLE) 24 # First check if atomics work without the library. 25 check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB) 26 # If not, check if the library exists, and atomics work with it. 27 if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) 28 check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC) 29 if( HAVE_LIBATOMIC ) 30 list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") 31 check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB) 32 if (NOT HAVE_CXX_ATOMICS_WITH_LIB) 33 message(FATAL_ERROR "Host compiler must support std::atomic!") 34 endif() 35 else() 36 message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.") 37 endif() 38 endif() 39endif() 40 41## TODO: This define is only used for the legacy atomic operations in 42## llvm's Atomic.h, which should be replaced. Other code simply 43## assumes C++11 <atomic> works. 44CHECK_CXX_SOURCE_COMPILES(" 45#ifdef _MSC_VER 46#include <Intrin.h> /* Workaround for PR19898. */ 47#include <windows.h> 48#endif 49int main() { 50#ifdef _MSC_VER 51 volatile LONG val = 1; 52 MemoryBarrier(); 53 InterlockedCompareExchange(&val, 0, 1); 54 InterlockedIncrement(&val); 55 InterlockedDecrement(&val); 56#else 57 volatile unsigned long val = 1; 58 __sync_synchronize(); 59 __sync_val_compare_and_swap(&val, 1, 0); 60 __sync_add_and_fetch(&val, 1); 61 __sync_sub_and_fetch(&val, 1); 62#endif 63 return 0; 64 } 65" LLVM_HAS_ATOMICS) 66 67if( NOT LLVM_HAS_ATOMICS ) 68 message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing") 69endif() 70