Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / openmp / runtime / cmake / config-ix.cmake
blob9869aeab03546350c7b09576111e6dd5d94965e5
2 #//===----------------------------------------------------------------------===//
3 #//
4 #// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 #// See https://llvm.org/LICENSE.txt for license information.
6 #// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 #//
8 #//===----------------------------------------------------------------------===//
11 include(CheckCCompilerFlag)
12 include(CheckCSourceCompiles)
13 include(CheckCXXSourceCompiles)
14 include(CheckCXXCompilerFlag)
15 include(CheckIncludeFile)
16 include(CheckLibraryExists)
17 include(CheckIncludeFiles)
18 include(CheckSymbolExists)
19 include(LibompCheckFortranFlag)
20 include(LLVMCheckCompilerLinkerFlag)
22 # Check for versioned symbols
23 function(libomp_check_version_symbols retval)
24   set(source_code
25     "#include <stdio.h>
26     void func1() { printf(\"Hello\"); }
27     void func2() { printf(\"World\"); }
28     __asm__(\".symver func1, func@VER1\");
29     __asm__(\".symver func2, func@VER2\");
30     int main(void) {
31       func1();
32       func2();
33       return 0;
34     }")
35   set(version_script_source "VER1 { }; VER2 { } VER1;")
36   file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/__version_script.txt "${version_script_source}")
37   set(CMAKE_REQUIRED_FLAGS -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/__version_script.txt)
38   check_c_source_compiles("${source_code}" ${retval})
39   set(${retval} ${${retval}} PARENT_SCOPE)
40   file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/__version_script.txt)
41 endfunction()
43 # Includes the architecture flag in both compile and link phase
44 function(libomp_check_architecture_flag flag retval)
45   set(CMAKE_REQUIRED_FLAGS "${flag}")
46   check_c_compiler_flag("${flag}" ${retval})
47   set(${retval} ${${retval}} PARENT_SCOPE)
48 endfunction()
50 # Checking CXX, Linker Flags
52 # GCC silently accepts any -Wno-<foo> option, but warns about those options
53 # being unrecognized only if the compilation triggers other warnings to be
54 # printed. Therefore, check for whether the compiler supports options in the
55 # form -W<foo>, and if supported, add the corresponding -Wno-<foo> option.
57 check_cxx_compiler_flag(-fno-exceptions LIBOMP_HAVE_FNO_EXCEPTIONS_FLAG)
58 check_cxx_compiler_flag(-fno-rtti LIBOMP_HAVE_FNO_RTTI_FLAG)
59 check_cxx_compiler_flag(-Wclass-memaccess LIBOMP_HAVE_WCLASS_MEMACCESS_FLAG)
60 check_cxx_compiler_flag(-Wcovered-switch-default LIBOMP_HAVE_WCOVERED_SWITCH_DEFAULT_FLAG)
61 check_cxx_compiler_flag(-Wframe-address LIBOMP_HAVE_WFRAME_ADDRESS_FLAG)
62 check_cxx_compiler_flag(-Wstrict-aliasing LIBOMP_HAVE_WSTRICT_ALIASING_FLAG)
63 check_cxx_compiler_flag(-Wstringop-overflow=0 LIBOMP_HAVE_WSTRINGOP_OVERFLOW_FLAG)
64 check_cxx_compiler_flag(-Wstringop-truncation LIBOMP_HAVE_WSTRINGOP_TRUNCATION_FLAG)
65 check_cxx_compiler_flag(-Wswitch LIBOMP_HAVE_WSWITCH_FLAG)
66 check_cxx_compiler_flag(-Wuninitialized LIBOMP_HAVE_WUNINITIALIZED_FLAG)
67 check_cxx_compiler_flag(-Wreturn-type-c-linkage LIBOMP_HAVE_WRETURN_TYPE_C_LINKAGE_FLAG)
68 check_cxx_compiler_flag(-Wcast-qual LIBOMP_HAVE_WCAST_QUAL_FLAG)
69 check_cxx_compiler_flag(-Wint-to-void-pointer-cast LIBOMP_HAVE_WINT_TO_VOID_POINTER_CAST_FLAG)
70 # check_cxx_compiler_flag(-Wconversion LIBOMP_HAVE_WCONVERSION_FLAG)
71 check_cxx_compiler_flag(-msse2 LIBOMP_HAVE_MSSE2_FLAG)
72 check_cxx_compiler_flag(-ftls-model=initial-exec LIBOMP_HAVE_FTLS_MODEL_FLAG)
73 libomp_check_architecture_flag(-mmic LIBOMP_HAVE_MMIC_FLAG)
74 libomp_check_architecture_flag(-m32 LIBOMP_HAVE_M32_FLAG)
75 if(WIN32)
76   if(MSVC)
77     # Check Windows MSVC style flags.
78     check_cxx_compiler_flag(/EHsc LIBOMP_HAVE_EHSC_FLAG)
79     check_cxx_compiler_flag(/GS LIBOMP_HAVE_GS_FLAG)
80     check_cxx_compiler_flag(/Oy- LIBOMP_HAVE_Oy__FLAG)
81     check_cxx_compiler_flag(/arch:SSE2 LIBOMP_HAVE_ARCH_SSE2_FLAG)
82     check_cxx_compiler_flag(/Qsafeseh LIBOMP_HAVE_QSAFESEH_FLAG)
83   endif()
84   check_cxx_compiler_flag(-mrtm LIBOMP_HAVE_MRTM_FLAG)
85   # It is difficult to create a dummy masm assembly file
86   # and then check the MASM assembler to see if these flags exist and work,
87   # so we assume they do for Windows.
88   set(LIBOMP_HAVE_SAFESEH_MASM_FLAG TRUE)
89   set(LIBOMP_HAVE_COFF_MASM_FLAG TRUE)
90   # Change Windows flags /MDx to /MTx
91   foreach(libomp_lang IN ITEMS C CXX)
92     foreach(libomp_btype IN ITEMS DEBUG RELWITHDEBINFO RELEASE MINSIZEREL)
93       string(REPLACE "/MD" "/MT"
94         CMAKE_${libomp_lang}_FLAGS_${libomp_btype}
95         "${CMAKE_${libomp_lang}_FLAGS_${libomp_btype}}"
96       )
97     endforeach()
98   endforeach()
99 endif()
100 if(${LIBOMP_FORTRAN_MODULES})
101   libomp_check_fortran_flag(-m32 LIBOMP_HAVE_M32_FORTRAN_FLAG)
102 endif()
104 # Check for Unix shared memory
105 check_symbol_exists(shm_open "sys/mman.h" LIBOMP_HAVE_SHM_OPEN_NO_LRT)
106 if (NOT LIBOMP_HAVE_SHM_OPEN_NO_LRT)
107   set(CMAKE_REQUIRED_LIBRARIES -lrt)
108   check_symbol_exists(shm_open "sys/mman.h" LIBOMP_HAVE_SHM_OPEN_WITH_LRT)
109   set(CMAKE_REQUIRED_LIBRARIES)
110 endif()
112 # Check for aligned memory allocator function
113 check_include_file(xmmintrin.h LIBOMP_HAVE_XMMINTRIN_H)
114 set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
115 if (LIBOMP_HAVE_XMMINTRIN_H)
116   set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -DLIBOMP_HAVE_XMMINTRIN_H")
117 endif()
118 set(source_code "// check for _mm_malloc
119     #ifdef LIBOMP_HAVE_XMMINTRIN_H
120     #include <xmmintrin.h>
121     #endif
122     int main() { void *ptr = _mm_malloc(sizeof(int) * 1000, 64); _mm_free(ptr); return 0; }")
123 check_cxx_source_compiles("${source_code}" LIBOMP_HAVE__MM_MALLOC)
124 set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
125 check_symbol_exists(aligned_alloc "stdlib.h" LIBOMP_HAVE_ALIGNED_ALLOC)
126 check_symbol_exists(posix_memalign "stdlib.h" LIBOMP_HAVE_POSIX_MEMALIGN)
127 check_symbol_exists(_aligned_malloc "malloc.h" LIBOMP_HAVE__ALIGNED_MALLOC)
129 # Check linker flags
130 if(WIN32)
131   llvm_check_compiler_linker_flag(C /SAFESEH LIBOMP_HAVE_SAFESEH_FLAG)
132 elseif(NOT APPLE)
133   llvm_check_compiler_linker_flag(C -Wl,-x LIBOMP_HAVE_X_FLAG)
134   llvm_check_compiler_linker_flag(C -Wl,--as-needed LIBOMP_HAVE_AS_NEEDED_FLAG)
135   llvm_check_compiler_linker_flag(C "-Wl,--version-script=${LIBOMP_SRC_DIR}/exports_test_so.txt" LIBOMP_HAVE_VERSION_SCRIPT_FLAG)
136   llvm_check_compiler_linker_flag(C -static-libgcc LIBOMP_HAVE_STATIC_LIBGCC_FLAG)
137   llvm_check_compiler_linker_flag(C -Wl,-z,noexecstack LIBOMP_HAVE_Z_NOEXECSTACK_FLAG)
138 endif()
140 # Check Intel(R) C Compiler specific flags
141 if(CMAKE_C_COMPILER_ID STREQUAL "Intel" OR CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM")
142   check_cxx_compiler_flag(/Qlong_double LIBOMP_HAVE_LONG_DOUBLE_FLAG)
143   check_cxx_compiler_flag(/Qdiag-disable:177 LIBOMP_HAVE_DIAG_DISABLE_177_FLAG)
144   check_cxx_compiler_flag(/Qinline-min-size=1 LIBOMP_HAVE_INLINE_MIN_SIZE_FLAG)
145   check_cxx_compiler_flag(-Qoption,cpp,--extended_float_types LIBOMP_HAVE_EXTENDED_FLOAT_TYPES_FLAG)
146   check_cxx_compiler_flag(-falign-stack=maintain-16-byte LIBOMP_HAVE_FALIGN_STACK_FLAG)
147   check_cxx_compiler_flag("-opt-streaming-stores never" LIBOMP_HAVE_OPT_STREAMING_STORES_FLAG)
148   llvm_check_compiler_linker_flag(C -static-intel LIBOMP_HAVE_STATIC_INTEL_FLAG)
149   llvm_check_compiler_linker_flag(C -no-intel-extensions LIBOMP_HAVE_NO_INTEL_EXTENSIONS_FLAG)
150   check_library_exists(irc_pic _intel_fast_memcpy "" LIBOMP_HAVE_IRC_PIC_LIBRARY)
151 endif()
153 # Checking Threading requirements
154 find_package(Threads REQUIRED)
155 if(WIN32)
156   if(NOT CMAKE_USE_WIN32_THREADS_INIT)
157     libomp_error_say("Need Win32 thread interface on Windows.")
158   endif()
159 else()
160   if(NOT CMAKE_USE_PTHREADS_INIT)
161     libomp_error_say("Need pthread interface on Unix-like systems.")
162   endif()
163 endif()
165 # Checking for x86-specific waitpkg and rtm attribute and intrinsics
166 if (IA32 OR INTEL64)
167   check_include_file(immintrin.h LIBOMP_HAVE_IMMINTRIN_H)
168   if (NOT LIBOMP_HAVE_IMMINTRIN_H)
169     check_include_file(intrin.h LIBOMP_HAVE_INTRIN_H)
170   endif()
171   check_cxx_source_compiles("__attribute__((target(\"rtm\")))
172                              int main() {return 0;}" LIBOMP_HAVE_ATTRIBUTE_RTM)
173   check_cxx_source_compiles("__attribute__((target(\"waitpkg\")))
174                             int main() {return 0;}" LIBOMP_HAVE_ATTRIBUTE_WAITPKG)
175   libomp_append(CMAKE_REQUIRED_DEFINITIONS -DIMMINTRIN_H LIBOMP_HAVE_IMMINTRIN_H)
176   libomp_append(CMAKE_REQUIRED_DEFINITIONS -DINTRIN_H LIBOMP_HAVE_INTRIN_H)
177   libomp_append(CMAKE_REQUIRED_DEFINITIONS -DATTRIBUTE_WAITPKG LIBOMP_HAVE_ATTRIBUTE_WAITPKG)
178   libomp_append(CMAKE_REQUIRED_DEFINITIONS -DATTRIBUTE_RTM LIBOMP_HAVE_ATTRIBUTE_RTM)
179   set(source_code "// check for attribute and wait pkg intrinsics
180       #ifdef IMMINTRIN_H
181       #include <immintrin.h>
182       #endif
183       #ifdef INTRIN_H
184       #include <intrin.h>
185       #endif
186       #ifdef ATTRIBUTE_WAITPKG
187       __attribute__((target(\"waitpkg\")))
188       #endif
189       static inline int __kmp_umwait(unsigned hint, unsigned long long counter) {
190         return _umwait(hint, counter);
191       }
192       int main() { int a = __kmp_umwait(0, 1000); return a; }")
193   check_cxx_source_compiles("${source_code}" LIBOMP_HAVE_WAITPKG_INTRINSICS)
194   set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
195   if (LIBOMP_HAVE_MRTM_FLAG)
196     set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -mrtm")
197   endif()
198   set(source_code "// check for attribute rtm and rtm intrinsics
199       #ifdef IMMINTRIN_H
200       #include <immintrin.h>
201       #endif
202       #ifdef INTRIN_H
203       #include <intrin.h>
204       #endif
205       #ifdef ATTRIBUTE_RTM
206       __attribute__((target(\"rtm\")))
207       #endif
208       static inline int __kmp_xbegin() {
209         return _xbegin();
210       }
211       int main() { int a = __kmp_xbegin(); return a; }")
212   check_cxx_source_compiles("${source_code}" LIBOMP_HAVE_RTM_INTRINSICS)
213   set(CMAKE_REQUIRED_DEFINITIONS)
214   set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
215 endif()
217 # Find perl executable
218 # Perl is used to create omp.h (and other headers) along with kmp_i18n_id.inc and kmp_i18n_default.inc
219 find_package(Perl REQUIRED)
220 # The perl scripts take the --os=/--arch= flags which expect a certain format for operating systems and arch's.
221 # Until the perl scripts are removed, the most portable way to handle this is to have all operating systems that
222 # are neither Windows nor Mac (Most Unix flavors) be considered lin to the perl scripts.  This is rooted
223 # in that all the Perl scripts check the operating system and will fail if it isn't "valid".  This
224 # temporary solution lets us avoid trying to enumerate all the possible OS values inside the Perl modules.
225 if(WIN32)
226   set(LIBOMP_PERL_SCRIPT_OS win)
227 elseif(APPLE)
228   set(LIBOMP_PERL_SCRIPT_OS mac)
229 else()
230   set(LIBOMP_PERL_SCRIPT_OS lin)
231 endif()
232 if(IA32)
233   set(LIBOMP_PERL_SCRIPT_ARCH 32)
234 elseif(MIC)
235   set(LIBOMP_PERL_SCRIPT_ARCH mic)
236 elseif(INTEL64)
237   set(LIBOMP_PERL_SCRIPT_ARCH 32e)
238 else()
239   set(LIBOMP_PERL_SCRIPT_ARCH ${LIBOMP_ARCH})
240 endif()
242 # Checking features
243 # Check if version symbol assembler directives are supported
244 if (LIBOMP_HAVE_VERSION_SCRIPT_FLAG)
245   libomp_check_version_symbols(LIBOMP_HAVE_VERSION_SYMBOLS)
246 else()
247   set(LIBOMP_HAVE_VERSION_SYMBOLS FALSE)
248 endif()
250 # Check if quad precision types are available
251 if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
252   set(LIBOMP_HAVE_QUAD_PRECISION TRUE)
253 elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel" OR CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM")
254   if(LIBOMP_HAVE_EXTENDED_FLOAT_TYPES_FLAG)
255     set(LIBOMP_HAVE_QUAD_PRECISION TRUE)
256   else()
257     set(LIBOMP_HAVE_QUAD_PRECISION TRUE)
258   endif()
259 else()
260   set(LIBOMP_HAVE_QUAD_PRECISION FALSE)
261 endif()
263 # Check if adaptive locks are available
264 if((${IA32} OR ${INTEL64}) AND NOT MSVC)
265   set(LIBOMP_HAVE_ADAPTIVE_LOCKS TRUE)
266 else()
267   set(LIBOMP_HAVE_ADAPTIVE_LOCKS FALSE)
268 endif()
270 # Check if stats-gathering is available
271 if(${LIBOMP_STATS})
272   check_c_source_compiles(
273      "__thread int x;
274      int main(int argc, char** argv)
275      { x = argc; return x; }"
276      LIBOMP_HAVE___THREAD)
277   check_c_source_compiles(
278      "int main(int argc, char** argv)
279      { unsigned long long t = __builtin_readcyclecounter(); return 0; }"
280      LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER)
281   if(NOT LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER)
282     if(${IA32} OR ${INTEL64} OR ${MIC})
283       check_include_file(x86intrin.h LIBOMP_HAVE_X86INTRIN_H)
284       libomp_append(CMAKE_REQUIRED_DEFINITIONS -DLIBOMP_HAVE_X86INTRIN_H LIBOMP_HAVE_X86INTRIN_H)
285       check_c_source_compiles(
286         "#ifdef LIBOMP_HAVE_X86INTRIN_H
287          # include <x86intrin.h>
288          #endif
289          int main(int argc, char** argv) { unsigned long long t = __rdtsc(); return 0; }" LIBOMP_HAVE___RDTSC)
290       set(CMAKE_REQUIRED_DEFINITIONS)
291     endif()
292   endif()
293   if(LIBOMP_HAVE___THREAD AND (LIBOMP_HAVE___RDTSC OR LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER))
294     set(LIBOMP_HAVE_STATS TRUE)
295   else()
296     set(LIBOMP_HAVE_STATS FALSE)
297   endif()
298 endif()
300 # Check if OMPT support is available
301 # Currently, __builtin_frame_address() is required for OMPT
302 # Weak attribute is required for Unices (except Darwin), LIBPSAPI is used for Windows
303 check_c_source_compiles("int main(int argc, char** argv) {
304   void* p = __builtin_frame_address(0);
305   return 0;}" LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS)
306 check_c_source_compiles("__attribute__ ((weak)) int foo(int a) { return a*a; }
307   int main(int argc, char** argv) {
308   return foo(argc);}" LIBOMP_HAVE_WEAK_ATTRIBUTE)
309 set(CMAKE_REQUIRED_LIBRARIES psapi)
310 check_c_source_compiles("#include <windows.h>
311   #include <psapi.h>
312   int main(int artc, char** argv) {
313     return EnumProcessModules(NULL, NULL, 0, NULL);
314   }" LIBOMP_HAVE_PSAPI)
315 set(CMAKE_REQUIRED_LIBRARIES)
316 if(NOT LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS)
317   set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)
318 else()
319   if( # hardware architecture supported?
320      ((LIBOMP_ARCH STREQUAL x86_64) OR
321       (LIBOMP_ARCH STREQUAL i386) OR
322 #      (LIBOMP_ARCH STREQUAL arm) OR
323       (LIBOMP_ARCH STREQUAL aarch64) OR
324       (LIBOMP_ARCH STREQUAL aarch64_a64fx) OR
325       (LIBOMP_ARCH STREQUAL ppc64le) OR
326       (LIBOMP_ARCH STREQUAL ppc64) OR
327       (LIBOMP_ARCH STREQUAL riscv64) OR
328       (LIBOMP_ARCH STREQUAL loongarch64))
329      AND # OS supported?
330      ((WIN32 AND LIBOMP_HAVE_PSAPI) OR APPLE OR (NOT WIN32 AND LIBOMP_HAVE_WEAK_ATTRIBUTE)))
331     set(LIBOMP_HAVE_OMPT_SUPPORT TRUE)
332   else()
333     set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)
334   endif()
335 endif()
337 set(LIBOMP_HAVE_OMPT_SUPPORT ${LIBOMP_HAVE_OMPT_SUPPORT} PARENT_SCOPE)
339 # Check if HWLOC support is available
340 if(${LIBOMP_USE_HWLOC})
341   find_path(LIBOMP_HWLOC_INCLUDE_DIR NAMES hwloc.h HINTS ${LIBOMP_HWLOC_INSTALL_DIR} PATH_SUFFIXES include)
342   set(CMAKE_REQUIRED_INCLUDES ${LIBOMP_HWLOC_INCLUDE_DIR})
343   check_include_file(hwloc.h LIBOMP_HAVE_HWLOC_H)
344   set(CMAKE_REQUIRED_INCLUDES)
345   find_library(LIBOMP_HWLOC_LIBRARY
346     NAMES hwloc libhwloc
347     HINTS ${LIBOMP_HWLOC_INSTALL_DIR}/lib)
348   if(LIBOMP_HWLOC_LIBRARY)
349     check_library_exists(${LIBOMP_HWLOC_LIBRARY} hwloc_topology_init
350       ${LIBOMP_HWLOC_INSTALL_DIR}/lib LIBOMP_HAVE_LIBHWLOC)
351     get_filename_component(LIBOMP_HWLOC_LIBRARY_DIR ${LIBOMP_HWLOC_LIBRARY} PATH)
352   endif()
353   if(LIBOMP_HAVE_HWLOC_H AND LIBOMP_HAVE_LIBHWLOC AND LIBOMP_HWLOC_LIBRARY)
354     set(LIBOMP_HAVE_HWLOC TRUE)
355   else()
356     set(LIBOMP_HAVE_HWLOC FALSE)
357     libomp_say("Could not find hwloc")
358   endif()
359 endif()
361 # Check if ThreadSanitizer support is available
362 if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux" AND ${INTEL64})
363   set(LIBOMP_HAVE_TSAN_SUPPORT TRUE)
364 else()
365   set(LIBOMP_HAVE_TSAN_SUPPORT FALSE)
366 endif()