brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · f11cadf Raw
126 lines · plain
1# atomic builtins are required for threading support.2 3INCLUDE(CheckCXXSourceCompiles)4INCLUDE(CheckLibraryExists)5 6# Sometimes linking against libatomic is required for atomic ops, if7# the platform doesn't support lock-free atomics.8 9function(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>14std::atomic<int> x;15std::atomic<short> y;16std::atomic<char> z;17int main() {18  ++z;19  ++y;20  return ++x;21}22" ${varname})23  set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})24endfunction(check_working_cxx_atomics)25 26function(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>32std::atomic<uint64_t> x (0);33int 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})40endfunction(check_working_cxx_atomics64)41 42 43# Check for (non-64-bit) atomic operations.44if(MSVC)45  set(HAVE_CXX_ATOMICS_WITHOUT_LIB True)46elseif(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()62endif()63 64# Check for 64 bit atomic operations.65if(MSVC)66  set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True)67elseif(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()83endif()84 85# Set variable LLVM_ATOMIC_LIB specifying flags for linking against libatomic.86if(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()94else()95  set(LLVM_ATOMIC_LIB)96endif()97 98## TODO: This define is only used for the legacy atomic operations in99## llvm's Atomic.h, which should be replaced.  Other code simply100## assumes C++11 <atomic> works.101CHECK_CXX_SOURCE_COMPILES("102#ifdef _MSC_VER103#include <windows.h>104#endif105int main() {106#ifdef _MSC_VER107        volatile LONG val = 1;108        MemoryBarrier();109        InterlockedCompareExchange(&val, 0, 1);110        InterlockedIncrement(&val);111        InterlockedDecrement(&val);112#else113        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#endif119        return 0;120      }121" LLVM_HAS_ATOMICS)122 123if( NOT LLVM_HAS_ATOMICS )124  message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")125endif()126