Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. # atomic builtins are required for threading support.
  2.  
  3. INCLUDE(CheckCXXSourceCompiles)
  4. INCLUDE(CheckLibraryExists)
  5.  
  6. # Sometimes linking against libatomic is required for atomic ops, if
  7. # the platform doesn't support lock-free atomics.
  8.  
  9. function(check_working_cxx_atomics varname)
  10.   set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
  11.   set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11")
  12.   CHECK_CXX_SOURCE_COMPILES("
  13. #include <atomic>
  14. std::atomic<int> x;
  15. std::atomic<short> y;
  16. std::atomic<char> z;
  17. int main() {
  18.  ++z;
  19.  ++y;
  20.  return ++x;
  21. }
  22. " ${varname})
  23.   set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
  24. endfunction(check_working_cxx_atomics)
  25.  
  26. function(check_working_cxx_atomics64 varname)
  27.   set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
  28.   set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}")
  29.   CHECK_CXX_SOURCE_COMPILES("
  30. #include <atomic>
  31. #include <cstdint>
  32. std::atomic<uint64_t> x (0);
  33. int main() {
  34.  uint64_t i = x.load(std::memory_order_relaxed);
  35.  (void)i;
  36.  return 0;
  37. }
  38. " ${varname})
  39.   set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
  40. endfunction(check_working_cxx_atomics64)
  41.  
  42.  
  43. # Check for (non-64-bit) atomic operations.
  44. if(MSVC)
  45.   set(HAVE_CXX_ATOMICS_WITHOUT_LIB True)
  46. elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
  47.   # First check if atomics work without the library.
  48.   check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
  49.   # If not, check if the library exists, and atomics work with it.
  50.   if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
  51.     check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
  52.     if(HAVE_LIBATOMIC)
  53.       list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
  54.       check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
  55.       if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
  56.         message(FATAL_ERROR "Host compiler must support std::atomic!")
  57.       endif()
  58.     else()
  59.       message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
  60.     endif()
  61.   endif()
  62. endif()
  63.  
  64. # Check for 64 bit atomic operations.
  65. if(MSVC)
  66.   set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)
  67. elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
  68.   # First check if atomics work without the library.
  69.   check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB)
  70.   # If not, check if the library exists, and atomics work with it.
  71.   if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
  72.     check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64)
  73.     if(HAVE_CXX_LIBATOMICS64)
  74.       list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
  75.       check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB)
  76.       if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
  77.         message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
  78.       endif()
  79.     else()
  80.       message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
  81.     endif()
  82.   endif()
  83. endif()
  84.  
  85. # Set variable LLVM_ATOMIC_LIB specifying flags for linking against libatomic.
  86. if(HAVE_CXX_ATOMICS_WITH_LIB OR HAVE_CXX_ATOMICS64_WITH_LIB)
  87.   # Use options --push-state, --as-needed and --pop-state if linker is known to support them.
  88.   # Use single option -Wl of compiler driver to avoid incorrect re-ordering of options by CMake.
  89.   if(LLVM_LINKER_IS_GNULD OR LLVM_LINKER_IS_GOLD OR LLVM_LINKER_IS_LLD OR LLVM_LINKER_IS_MOLD)
  90.     set(LLVM_ATOMIC_LIB "-Wl,--push-state,--as-needed,-latomic,--pop-state")
  91.   else()
  92.     set(LLVM_ATOMIC_LIB "-latomic")
  93.   endif()
  94. else()
  95.   set(LLVM_ATOMIC_LIB)
  96. endif()
  97.  
  98. ## TODO: This define is only used for the legacy atomic operations in
  99. ## llvm's Atomic.h, which should be replaced.  Other code simply
  100. ## assumes C++11 <atomic> works.
  101. CHECK_CXX_SOURCE_COMPILES("
  102. #ifdef _MSC_VER
  103. #include <windows.h>
  104. #endif
  105. int main() {
  106. #ifdef _MSC_VER
  107.        volatile LONG val = 1;
  108.        MemoryBarrier();
  109.        InterlockedCompareExchange(&val, 0, 1);
  110.        InterlockedIncrement(&val);
  111.        InterlockedDecrement(&val);
  112. #else
  113.        volatile unsigned long val = 1;
  114.        __sync_synchronize();
  115.        __sync_val_compare_and_swap(&val, 1, 0);
  116.        __sync_add_and_fetch(&val, 1);
  117.        __sync_sub_and_fetch(&val, 1);
  118. #endif
  119.        return 0;
  120.      }
  121. " LLVM_HAS_ATOMICS)
  122.  
  123. if( NOT LLVM_HAS_ATOMICS )
  124.   message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")
  125. endif()
  126.