1 # atomic builtins are required for threading support. 2 3 INCLUDE(CheckCXXSourceCompiles) 4 5 # Sometimes linking against libatomic is required for atomic ops, if 6 # the platform doesn't support lock-free atomics. 7 8 function(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> 13 std::atomic<int> x; 14 int main() { 15 return x; 16 } 17 " ${varname}) 18 set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) 19 endfunction(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. 23 if (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() 39 endif() 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. 44 CHECK_CXX_SOURCE_COMPILES(" 45 #ifdef _MSC_VER 46 #include <Intrin.h> /* Workaround for PR19898. */ 47 #include <windows.h> 48 #endif 49 int 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 67 if( NOT LLVM_HAS_ATOMICS ) 68 message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing") 69 endif() 70