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