Update of the TOF code, see the presentation at
[u/mrichter/AliRoot.git] / Vc / cmake / VcMacros.cmake
CommitLineData
f22341db 1# Macros for use with the Vc library. Vc can be found at http://code.compeng.uni-frankfurt.de/projects/vc
2#
3# The following macros are provided:
4# vc_determine_compiler
5# vc_set_preferred_compiler_flags
6#
7#=============================================================================
c017a39f 8# Copyright 2009-2013 Matthias Kretz <kretz@kde.org>
f22341db 9#
c017a39f 10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions are
12# met:
f22341db 13#
c017a39f 14# * Redistributions of source code must retain the above copyright notice,
15# this list of conditions and the following disclaimer.
16#
17# * Redistributions in binary form must reproduce the above copyright notice,
18# this list of conditions and the following disclaimer in the documentation
19# and/or other materials provided with the distribution.
20#
21# * The names of Kitware, Inc., the Insight Consortium, or the names of
22# any consortium members, or of any contributors, may not be used to
23# endorse or promote products derived from this software without
24# specific prior written permission.
25#
26# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
27# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
30# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
f22341db 36#=============================================================================
37
c017a39f 38cmake_minimum_required(VERSION 2.8.3)
39
f22341db 40get_filename_component(_currentDir "${CMAKE_CURRENT_LIST_FILE}" PATH)
41include ("${_currentDir}/UserWarning.cmake")
42include ("${_currentDir}/AddCompilerFlag.cmake")
43include ("${_currentDir}/OptimizeForArchitecture.cmake")
44
45macro(vc_determine_compiler)
46 if(NOT DEFINED Vc_COMPILER_IS_INTEL)
c017a39f 47 execute_process(COMMAND "${CMAKE_CXX_COMPILER}" "--version" OUTPUT_VARIABLE _cxx_compiler_version ERROR_VARIABLE _cxx_compiler_version)
f22341db 48 set(Vc_COMPILER_IS_INTEL false)
49 set(Vc_COMPILER_IS_OPEN64 false)
50 set(Vc_COMPILER_IS_CLANG false)
51 set(Vc_COMPILER_IS_MSVC false)
52 set(Vc_COMPILER_IS_GCC false)
53 if(CMAKE_CXX_COMPILER MATCHES "/(icpc|icc)$")
54 set(Vc_COMPILER_IS_INTEL true)
55 exec_program(${CMAKE_C_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE Vc_ICC_VERSION)
56 message(STATUS "Detected Compiler: Intel ${Vc_ICC_VERSION}")
23a11150 57 elseif(CMAKE_CXX_COMPILER MATCHES "(opencc|openCC)$")
f22341db 58 set(Vc_COMPILER_IS_OPEN64 true)
59 message(STATUS "Detected Compiler: Open64")
c017a39f 60 elseif(CMAKE_CXX_COMPILER MATCHES "clang\\+\\+$" OR "${_cxx_compiler_version}" MATCHES "clang")
f22341db 61 set(Vc_COMPILER_IS_CLANG true)
c017a39f 62 exec_program(${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE Vc_CLANG_VERSION)
63 string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" Vc_CLANG_VERSION "${Vc_CLANG_VERSION}")
64 message(STATUS "Detected Compiler: Clang ${Vc_CLANG_VERSION}")
f22341db 65 elseif(MSVC)
66 set(Vc_COMPILER_IS_MSVC true)
c017a39f 67 message(STATUS "Detected Compiler: MSVC ${MSVC_VERSION}")
f22341db 68 elseif(CMAKE_COMPILER_IS_GNUCXX)
69 set(Vc_COMPILER_IS_GCC true)
70 exec_program(${CMAKE_C_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE Vc_GCC_VERSION)
71 message(STATUS "Detected Compiler: GCC ${Vc_GCC_VERSION}")
72
73 # some distributions patch their GCC to return nothing or only major and minor version on -dumpversion.
74 # In that case we must extract the version number from --version.
75 if(NOT Vc_GCC_VERSION OR Vc_GCC_VERSION MATCHES "^[0-9]\\.[0-9]+$")
76 exec_program(${CMAKE_C_COMPILER} ARGS --version OUTPUT_VARIABLE Vc_GCC_VERSION)
77 string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" Vc_GCC_VERSION "${Vc_GCC_VERSION}")
78 message(STATUS "GCC Version from --version: ${Vc_GCC_VERSION}")
79 endif()
80
81 # some distributions patch their GCC to be API incompatible to what the FSF released. In
82 # those cases we require a macro to identify the distribution version
83 find_program(_lsb_release lsb_release)
84 mark_as_advanced(_lsb_release)
85 if(_lsb_release)
86 execute_process(COMMAND ${_lsb_release} -is OUTPUT_VARIABLE _distributor_id OUTPUT_STRIP_TRAILING_WHITESPACE)
87 execute_process(COMMAND ${_lsb_release} -rs OUTPUT_VARIABLE _distributor_release OUTPUT_STRIP_TRAILING_WHITESPACE)
88 string(TOUPPER "${_distributor_id}" _distributor_id)
89 if(_distributor_id STREQUAL "UBUNTU")
90 execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE _gcc_version)
91 string(REGEX MATCH "\\(.* ${Vc_GCC_VERSION}-([0-9]+).*\\)" _tmp "${_gcc_version}")
92 if(_tmp)
93 set(_patch ${CMAKE_MATCH_1})
94 string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _tmp "${_distributor_release}")
95 execute_process(COMMAND printf 0x%x%02x%02x ${CMAKE_MATCH_1} ${CMAKE_MATCH_2} ${_patch} OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE _tmp)
96 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -D__GNUC_UBUNTU_VERSION__=${_tmp}")
97 endif()
98 endif()
99 endif()
100 else()
101 message(WARNING "Untested/-supported Compiler for use with Vc.\nPlease fill out the missing parts in the CMake scripts and submit a patch to http://code.compeng.uni-frankfurt.de/projects/vc")
102 endif()
103 endif()
104endmacro()
105
106macro(vc_set_gnu_buildtype_flags)
107 set(CMAKE_CXX_FLAGS_DEBUG "-g3" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
108 set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG" CACHE STRING "Flags used by the compiler during release minsize builds." FORCE)
109 set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "Flags used by the compiler during release builds (/MD /Ob1 /Oi /Ot /Oy /Gs will produce slightly less optimized but smaller files)." FORCE)
c017a39f 110 set(CMAKE_CXX_FLAGS_RELWITHDEBUG "-O3" CACHE STRING "Flags used by the compiler during release builds containing runtime checks." FORCE)
111 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBUG} -g" CACHE STRING "Flags used by the compiler during Release with Debug Info builds." FORCE)
f22341db 112 set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
113 set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}" CACHE STRING "Flags used by the compiler during release minsize builds." FORCE)
114 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "Flags used by the compiler during release builds (/MD /Ob1 /Oi /Ot /Oy /Gs will produce slightly less optimized but smaller files)." FORCE)
c017a39f 115 set(CMAKE_C_FLAGS_RELWITHDEBUG "${CMAKE_CXX_FLAGS_RELWITHDEBUG}" CACHE STRING "Flags used by the compiler during release builds containing runtime checks." FORCE)
f22341db 116 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" CACHE STRING "Flags used by the compiler during Release with Debug Info builds." FORCE)
c017a39f 117 if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebug")
f22341db 118 set(ENABLE_STRICT_ALIASING true CACHE BOOL "Enables strict aliasing rules for more aggressive optimizations")
119 if(NOT ENABLE_STRICT_ALIASING)
c017a39f 120 AddCompilerFlag(-fno-strict-aliasing)
f22341db 121 endif(NOT ENABLE_STRICT_ALIASING)
122 endif()
c017a39f 123 mark_as_advanced(CMAKE_CXX_FLAGS_RELWITHDEBUG CMAKE_C_FLAGS_RELWITHDEBUG)
f22341db 124endmacro()
125
126macro(vc_add_compiler_flag VAR _flag)
127 AddCompilerFlag("${_flag}" CXX_FLAGS ${VAR})
128endmacro()
129
130macro(vc_check_assembler)
131 if(APPLE)
132 if(NOT Vc_COMPILER_IS_CLANG)
3ea24db6 133 message(WARNING "Apple does not provide an assembler with AVX support. AVX will not be available. Please use Clang if you want to use AVX.")
134 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_NO_XGETBV")
135 set(Vc_AVX_INTRINSICS_BROKEN true)
f22341db 136 endif()
137 else(APPLE)
138 if(${ARGC} EQUAL 1)
139 set(_as "${ARGV1}")
140 else()
141 exec_program(${CMAKE_CXX_COMPILER} ARGS -print-prog-name=as OUTPUT_VARIABLE _as)
142 mark_as_advanced(_as)
143 endif()
144 if(NOT _as)
145 message(WARNING "Could not find 'as', the assembler used by GCC. Hoping everything will work out...")
146 else()
147 exec_program(${_as} ARGS --version OUTPUT_VARIABLE _as_version)
148 string(REGEX REPLACE "\\([^\\)]*\\)" "" _as_version "${_as_version}")
149 string(REGEX MATCH "[1-9]\\.[0-9]+(\\.[0-9]+)?" _as_version "${_as_version}")
150 if(_as_version VERSION_LESS "2.18.93")
6936ae04 151 UserWarning("Your binutils is too old (${_as_version}). Some optimizations of Vc will be disabled.")
f22341db 152 add_definitions(-DVC_NO_XGETBV) # old assembler doesn't know the xgetbv instruction
c017a39f 153 set(Vc_AVX_INTRINSICS_BROKEN true)
154 set(Vc_XOP_INTRINSICS_BROKEN true)
155 set(Vc_FMA4_INTRINSICS_BROKEN true)
156 elseif(_as_version VERSION_LESS "2.21.0")
157 UserWarning("Your binutils is too old (${_as_version}) for XOP instructions. They will therefore not be provided in libVc.")
158 set(Vc_XOP_INTRINSICS_BROKEN true)
f22341db 159 endif()
160 endif()
161 endif(APPLE)
162endmacro()
163
164macro(vc_check_fpmath)
165 # if compiling for 32 bit x86 we need to use the -mfpmath=sse since the x87 is broken by design
166 include (CheckCXXSourceRuns)
167 check_cxx_source_runs("int main() { return sizeof(void*) != 8; }" Vc_VOID_PTR_IS_64BIT)
168 if(NOT Vc_VOID_PTR_IS_64BIT)
169 exec_program(${CMAKE_C_COMPILER} ARGS -dumpmachine OUTPUT_VARIABLE _gcc_machine)
c017a39f 170 if(_gcc_machine MATCHES "[x34567]86" OR _gcc_machine STREQUAL "mingw32")
f22341db 171 vc_add_compiler_flag(Vc_DEFINITIONS "-mfpmath=sse")
c017a39f 172 endif()
f22341db 173 endif()
174endmacro()
175
176macro(vc_set_preferred_compiler_flags)
177 vc_determine_compiler()
178
179 set(_add_warning_flags false)
180 set(_add_buildtype_flags false)
181 foreach(_arg ${ARGN})
182 if(_arg STREQUAL "WARNING_FLAGS")
183 set(_add_warning_flags true)
184 elseif(_arg STREQUAL "BUILDTYPE_FLAGS")
185 set(_add_buildtype_flags true)
186 endif()
187 endforeach()
188
189 set(Vc_SSE_INTRINSICS_BROKEN false)
190 set(Vc_AVX_INTRINSICS_BROKEN false)
6936ae04 191 set(Vc_XOP_INTRINSICS_BROKEN false)
c017a39f 192 set(Vc_FMA4_INTRINSICS_BROKEN false)
f22341db 193
194 if(Vc_COMPILER_IS_OPEN64)
195 ##################################################################################################
196 # Open64 #
197 ##################################################################################################
198 if(_add_warning_flags)
199 AddCompilerFlag("-W")
200 AddCompilerFlag("-Wall")
201 AddCompilerFlag("-Wimplicit")
202 AddCompilerFlag("-Wswitch")
203 AddCompilerFlag("-Wformat")
204 AddCompilerFlag("-Wchar-subscripts")
205 AddCompilerFlag("-Wparentheses")
206 AddCompilerFlag("-Wmultichar")
207 AddCompilerFlag("-Wtrigraphs")
208 AddCompilerFlag("-Wpointer-arith")
209 AddCompilerFlag("-Wcast-align")
210 AddCompilerFlag("-Wreturn-type")
211 AddCompilerFlag("-Wno-unused-function")
212 AddCompilerFlag("-ansi")
213 AddCompilerFlag("-pedantic")
214 AddCompilerFlag("-Wno-long-long")
215 AddCompilerFlag("-Wshadow")
216 AddCompilerFlag("-Wold-style-cast")
217 AddCompilerFlag("-Wno-variadic-macros")
218 endif()
219 if(_add_buildtype_flags)
220 vc_set_gnu_buildtype_flags()
221 endif()
222
223 vc_check_assembler()
c017a39f 224
225 # Open64 4.5.1 still doesn't ship immintrin.h
226 set(Vc_AVX_INTRINSICS_BROKEN true)
f22341db 227 elseif(Vc_COMPILER_IS_GCC)
228 ##################################################################################################
229 # GCC #
230 ##################################################################################################
231 if(_add_warning_flags)
c017a39f 232 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W -Wall -Wswitch -Wformat -Wchar-subscripts -Wparentheses -Wmultichar -Wtrigraphs -Wpointer-arith -Wcast-align -Wreturn-type -Wno-unused-function -pedantic -Wno-long-long -Wshadow")
233 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wall -Wswitch -Wformat -Wchar-subscripts -Wparentheses -Wmultichar -Wtrigraphs -Wpointer-arith -Wcast-align -Wreturn-type -Wno-unused-function -pedantic -Wno-long-long -Wshadow")
234 if(NOT WIN32)
235 # the -ansi flag makes MinGW unusable, so maybe it's better to omit it
236 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ansi")
237 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ansi")
238 endif()
239 AddCompilerFlag("-Wundef")
f22341db 240 AddCompilerFlag("-Wold-style-cast")
241 AddCompilerFlag("-Wno-variadic-macros")
242 if(Vc_GCC_VERSION VERSION_GREATER "4.5.2" AND Vc_GCC_VERSION VERSION_LESS "4.6.4")
243 # GCC gives bogus "array subscript is above array bounds" warnings in math.cpp
244 AddCompilerFlag("-Wno-array-bounds")
245 endif()
6936ae04 246 if(Vc_GCC_VERSION VERSION_GREATER "4.7.99")
247 # GCC 4.8 warns about stuff we don't care about
248 # Some older GCC versions have problems to note that they don't support the flag
249 AddCompilerFlag("-Wno-unused-local-typedefs")
250 endif()
f22341db 251 endif()
252 vc_add_compiler_flag(Vc_DEFINITIONS "-Wabi")
253 vc_add_compiler_flag(Vc_DEFINITIONS "-fabi-version=0") # ABI version 4 is required to make __m128 and __m256 appear as different types. 0 should give us the latest version.
254
255 if(_add_buildtype_flags)
256 vc_set_gnu_buildtype_flags()
257 endif()
258
259 # GCC 4.5.[01] fail at inlining some functions, creating functions with a single instructions,
260 # thus creating a large overhead.
261 if(Vc_GCC_VERSION VERSION_LESS "4.5.2" AND NOT Vc_GCC_VERSION VERSION_LESS "4.5.0")
262 UserWarning("GCC 4.5.0 and 4.5.1 have problems with inlining correctly. Setting early-inlining-insns=12 as workaround.")
263 AddCompilerFlag("--param early-inlining-insns=12")
264 endif()
265
6936ae04 266 if(Vc_GCC_VERSION VERSION_LESS "4.1.99")
267 UserWarning("Your GCC is ancient and crashes on some important optimizations. The full set of SSE2 intrinsics is not supported. Vc will fall back to the scalar implementation. Use of the may_alias and always_inline attributes will be disabled. In turn all code using Vc must be compiled with -fno-strict-aliasing")
268 vc_add_compiler_flag(Vc_DEFINITIONS "-fno-strict-aliasing")
269 set(Vc_AVX_INTRINSICS_BROKEN true)
270 set(Vc_SSE_INTRINSICS_BROKEN true)
271 elseif(Vc_GCC_VERSION VERSION_LESS "4.4.6")
f22341db 272 UserWarning("Your GCC is older than 4.4.6. This is known to cause problems/bugs. Please update to the latest GCC if you can.")
273 set(Vc_AVX_INTRINSICS_BROKEN true)
274 if(Vc_GCC_VERSION VERSION_LESS "4.3.0")
275 UserWarning("Your GCC is older than 4.3.0. It is unable to handle the full set of SSE2 intrinsics. All SSE code will be disabled. Please update to the latest GCC if you can.")
276 set(Vc_SSE_INTRINSICS_BROKEN true)
277 endif()
278 endif()
279
280 if(Vc_GCC_VERSION VERSION_LESS 4.5.0)
281 UserWarning("GCC 4.4.x shows false positives for -Wparentheses, thus we rather disable the warning.")
282 string(REPLACE " -Wparentheses " " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
283 string(REPLACE " -Wparentheses " " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
284 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -Wno-parentheses")
c017a39f 285
286 UserWarning("GCC 4.4.x shows false positives for -Wstrict-aliasing, thus we rather disable the warning. Use a newer GCC for better warnings.")
287 AddCompilerFlag("-Wno-strict-aliasing")
288
289 UserWarning("GCC 4.4.x shows false positives for -Wuninitialized, thus we rather disable the warning. Use a newer GCC for better warnings.")
290 AddCompilerFlag("-Wno-uninitialized")
291 elseif(Vc_GCC_VERSION VERSION_EQUAL 4.6.0)
292 UserWarning("GCC 4.6.0 miscompiles AVX loads/stores, leading to spurious segfaults. Disabling AVX per default.")
293 set(Vc_AVX_INTRINSICS_BROKEN true)
f22341db 294 elseif(Vc_GCC_VERSION VERSION_EQUAL 4.7.0)
295 UserWarning("GCC 4.7.0 miscompiles at -O3, adding -fno-predictive-commoning to the compiler flags as workaround")
296 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -fno-predictive-commoning")
c017a39f 297 elseif(Vc_GCC_VERSION VERSION_EQUAL 4.8.0)
298 UserWarning("GCC 4.8.0 miscompiles at -O3, adding -fno-tree-vectorize to the compiler flags as workaround")
299 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -fno-tree-vectorize")
f22341db 300 endif()
301
302 vc_check_fpmath()
303 vc_check_assembler()
304 elseif(Vc_COMPILER_IS_INTEL)
305 ##################################################################################################
306 # Intel Compiler #
307 ##################################################################################################
308
309 if(_add_buildtype_flags)
310 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
311 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
312 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
313 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
314
315 set(ALIAS_FLAGS "-no-ansi-alias")
316 if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
317 # default ICC to -no-ansi-alias because otherwise tests/utils_sse fails. So far I suspect a miscompilation...
318 set(ENABLE_STRICT_ALIASING false CACHE BOOL "Enables strict aliasing rules for more aggressive optimizations")
319 if(ENABLE_STRICT_ALIASING)
320 set(ALIAS_FLAGS "-ansi-alias")
321 endif(ENABLE_STRICT_ALIASING)
322 endif()
323 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ALIAS_FLAGS}")
324 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ALIAS_FLAGS}")
325 endif()
326 vc_add_compiler_flag(Vc_DEFINITIONS "-diag-disable 913")
c017a39f 327 # Disable warning #13211 "Immediate parameter to intrinsic call too large". (sse/vector.tcc rotated(int))
328 vc_add_compiler_flag(Vc_DEFINITIONS "-diag-disable 13211")
329
330 if(NOT "$ENV{DASHBOARD_TEST_FROM_CTEST}" STREQUAL "")
331 # disable warning #2928: the __GXX_EXPERIMENTAL_CXX0X__ macro is disabled when using GNU version 4.6 with the c++0x option
332 # this warning just adds noise about problems in the compiler - but I'm only interested in seeing problems in Vc
333 vc_add_compiler_flag(Vc_DEFINITIONS "-diag-disable 2928")
334 endif()
335
336 # Intel doesn't implement the XOP or FMA4 intrinsics
337 set(Vc_XOP_INTRINSICS_BROKEN true)
338 set(Vc_FMA4_INTRINSICS_BROKEN true)
f22341db 339 elseif(Vc_COMPILER_IS_MSVC)
340 if(_add_warning_flags)
341 AddCompilerFlag("/wd4800") # Disable warning "forcing value to bool"
342 AddCompilerFlag("/wd4996") # Disable warning about strdup vs. _strdup
343 AddCompilerFlag("/wd4244") # Disable warning "conversion from 'unsigned int' to 'float', possible loss of data"
344 AddCompilerFlag("/wd4146") # Disable warning "unary minus operator applied to unsigned type, result still unsigned"
345 AddCompilerFlag("/wd4227") # Disable warning "anachronism used : qualifiers on reference are ignored" (this is about 'restrict' usage on references, stupid MSVC)
346 AddCompilerFlag("/wd4722") # Disable warning "destructor never returns, potential memory leak" (warns about ~_UnitTest_Global_Object which we don't care about)
347 AddCompilerFlag("/wd4748") # Disable warning "/GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function" (I don't get it)
348 add_definitions(-D_CRT_SECURE_NO_WARNINGS)
349 endif()
350
351 # MSVC does not support inline assembly on 64 bit! :(
352 # searching the help for xgetbv doesn't turn up anything. So just fall back to not supporting AVX on Windows :(
353 # TODO: apparently MSVC 2010 SP1 added _xgetbv
354 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_NO_XGETBV")
355
356 # get rid of the min/max macros
357 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DNOMINMAX")
6936ae04 358
c017a39f 359 # MSVC doesn't implement the XOP or FMA4 intrinsics
6936ae04 360 set(Vc_XOP_INTRINSICS_BROKEN true)
c017a39f 361 set(Vc_FMA4_INTRINSICS_BROKEN true)
362
363 if(MSVC_VERSION LESS 1700)
364 UserWarning("MSVC before 2012 has a broken std::vector::resize implementation. STL + Vc code will probably not compile.")
365 endif()
f22341db 366 elseif(Vc_COMPILER_IS_CLANG)
367 # for now I don't know of any arguments I want to pass. -march and stuff is tried by OptimizeForArchitecture...
c017a39f 368 if(Vc_CLANG_VERSION VERSION_EQUAL "3.0")
369 UserWarning("Clang 3.0 has serious issues to compile Vc code and will most likely crash when trying to do so.\nPlease update to a recent clang version.")
370 elseif(Vc_CLANG_VERSION VERSION_LESS "3.3")
371 # the LLVM assembler gets FMAs wrong (bug 15040)
372 vc_add_compiler_flag(Vc_DEFINITIONS "-no-integrated-as")
373 endif()
f22341db 374
375 # disable these warnings because clang shows them for function overloads that were discarded via SFINAE
376 vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-local-type-template-args")
377 vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-unnamed-type-template-args")
c017a39f 378
379 AddCompilerFlag(-stdlib=libc++)
380 endif()
381
382 if(NOT Vc_COMPILER_IS_MSVC)
383 vc_add_compiler_flag(Vc_DEFINITIONS "-ffp-contract=fast")
f22341db 384 endif()
385
386 OptimizeForArchitecture()
387 set(Vc_DEFINITIONS "${Vc_ARCHITECTURE_FLAGS} ${Vc_DEFINITIONS}")
388
389 set(VC_IMPL "auto" CACHE STRING "Force the Vc implementation globally to the selected instruction set. \"auto\" lets Vc use the best available instructions.")
390 if(NOT VC_IMPL STREQUAL "auto")
391 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_IMPL=${VC_IMPL}")
392 if(NOT VC_IMPL STREQUAL "Scalar")
393 set(_use_var "USE_${VC_IMPL}")
394 if(VC_IMPL STREQUAL "SSE")
395 set(_use_var "USE_SSE2")
396 endif()
397 if(NOT ${_use_var})
398 message(WARNING "The selected value for VC_IMPL (${VC_IMPL}) will not work because the relevant instructions are not enabled via compiler flags.")
399 endif()
400 endif()
401 endif()
402endmacro()
c017a39f 403
404# helper macro for vc_compile_for_all_implementations
405macro(_vc_compile_one_implementation _objs _impl)
406 list(FIND _disabled_targets "${_impl}" _disabled_index)
407 list(FIND _only_targets "${_impl}" _only_index)
408 if(${_disabled_index} EQUAL -1 AND (NOT _only_targets OR ${_only_index} GREATER -1))
409 set(_extra_flags)
410 set(_ok FALSE)
411 foreach(_flag ${ARGN})
412 if(_flag STREQUAL "NO_FLAG")
413 set(_ok TRUE)
414 break()
415 endif()
416 string(REPLACE " " ";" _flag_list "${_flag}")
417 foreach(_flag ${_flag_list})
418 AddCompilerFlag(${_flag} CXX_RESULT _ok)
419 if(NOT _ok)
420 break()
421 endif()
422 endforeach()
423 if(_ok)
424 set(_extra_flags ${_flag_list})
425 break()
426 endif()
427 endforeach()
428
429 set(_outfile_flag -c -o)
430 if(Vc_COMPILER_IS_MSVC)
431 # MSVC for 64bit does not recognize /arch:SSE2 anymore. Therefore we set override _ok if _impl
432 # says SSE
433 if("${_impl}" MATCHES "SSE")
434 set(_ok TRUE)
435 endif()
436 set(_outfile_flag /c /Fo)
437 endif()
438
439 if(_ok)
440 get_filename_component(_out "${_vc_compile_src}" NAME_WE)
441 get_filename_component(_ext "${_vc_compile_src}" EXT)
442 if(Vc_COMPILER_IS_MSVC)
443 set(_out "${_out}_${_impl}${_ext}.obj")
444 else()
445 set(_out "${_out}_${_impl}${_ext}.o")
446 endif()
447 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_out}
448 COMMAND ${CMAKE_CXX_COMPILER} ${_flags} ${_extra_flags}
449 -DVC_IMPL=${_impl}
450 ${_outfile_flag}${_out} ${CMAKE_CURRENT_SOURCE_DIR}/${_vc_compile_src}
451 MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${_vc_compile_src}
452 IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/${_vc_compile_src}
453 COMMENT "Building CXX object ${_out}"
454 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
455 VERBATIM
456 )
457 list(APPEND ${_objs} "${CMAKE_CURRENT_BINARY_DIR}/${_out}")
458 endif()
459 endif()
460endmacro()
461
462# Generate compile rules for the given C++ source file for all available implementations and return
463# the resulting list of object files in _obj
464# all remaining arguments are additional flags
465# Example:
466# vc_compile_for_all_implementations(_objs src/trigonometric.cpp FLAGS -DCOMPILE_BLAH EXCLUDE Scalar)
467# add_executable(executable main.cpp ${_objs})
468macro(vc_compile_for_all_implementations _objs _src)
469 set(${_objs})
470
471 # remove all -march, -msse, etc. flags from the flags we want to pass
472 string(REPLACE "${Vc_ARCHITECTURE_FLAGS}" "" _flags "${Vc_DEFINITIONS}")
473 string(REPLACE "-DVC_IMPL=[^ ]*" "" _flags "${_flags}")
474
475 # capture the -march= switch as -mtune; if there is none skip it
476 if(Vc_ARCHITECTURE_FLAGS MATCHES "-march=")
477 string(REGEX REPLACE "^.*-march=([^ ]*).*$" "-mtune=\\1" _tmp "${Vc_ARCHITECTURE_FLAGS}")
478 set(_flags "${_flags} ${_tmp}")
479 endif()
480
481 unset(_disabled_targets)
482 unset(_only_targets)
483 set(_state 0)
484 foreach(_arg ${ARGN})
485 if(_arg STREQUAL "FLAGS")
486 set(_state 1)
487 elseif(_arg STREQUAL "EXCLUDE")
488 set(_state 2)
489 elseif(_arg STREQUAL "ONLY")
490 set(_state 3)
491 elseif(_state EQUAL 1)
492 set(_flags "${_flags} ${_arg}")
493 elseif(_state EQUAL 2)
494 list(APPEND _disabled_targets "${_arg}")
495 elseif(_state EQUAL 3)
496 list(APPEND _only_targets "${_arg}")
497 else()
498 message(FATAL_ERROR "incorrect argument to vc_compile_for_all_implementations")
499 endif()
500 endforeach()
501
502 # make a semicolon separated list of all flags
503 string(TOUPPER "${CMAKE_BUILD_TYPE}" _tmp)
504 set(_tmp "CMAKE_CXX_FLAGS_${_tmp}")
505 string(REPLACE " " ";" _tmp "${CMAKE_CXX_FLAGS} ${${_tmp}} ${_flags}")
506 set(_flags)
507 foreach(item ${_tmp})
508 if(item MATCHES "^[^']*'[^']*$")
509 if(_str)
510 list(APPEND _flags "${_str} ${item}")
511 unset(_str)
512 else()
513 set(_str "${item}")
514 endif()
515 else()
516 list(APPEND _flags "${item}")
517 endif()
518 endforeach()
519 get_directory_property(_inc INCLUDE_DIRECTORIES)
520 foreach(_i ${_inc})
521 list(APPEND _flags "-I${_i}")
522 endforeach()
523
524 set(_vc_compile_src "${_src}")
525
526 _vc_compile_one_implementation(${_objs} Scalar NO_FLAG)
527 if(NOT Vc_SSE_INTRINSICS_BROKEN)
528 _vc_compile_one_implementation(${_objs} SSE2 "-msse2" "-xSSE2" "/arch:SSE2")
529 _vc_compile_one_implementation(${_objs} SSE3 "-msse3" "-xSSE3" "/arch:SSE2")
530 _vc_compile_one_implementation(${_objs} SSSE3 "-mssse3" "-xSSSE3" "/arch:SSE2")
531 _vc_compile_one_implementation(${_objs} SSE4_1 "-msse4.1" "-xSSE4.1" "/arch:SSE2")
532 _vc_compile_one_implementation(${_objs} SSE4_2 "-msse4.2" "-xSSE4.2" "/arch:SSE2")
533 _vc_compile_one_implementation(${_objs} SSE3+SSE4a "-msse4a")
534 endif()
535 if(NOT Vc_AVX_INTRINSICS_BROKEN)
536 _vc_compile_one_implementation(${_objs} AVX "-mavx" "-xAVX" "/arch:AVX")
537 if(NOT Vc_XOP_INTRINSICS_BROKEN)
538 if(NOT Vc_FMA4_INTRINSICS_BROKEN)
539 _vc_compile_one_implementation(${_objs} SSE+XOP+FMA4 "-mxop -mfma4" "" "")
540 _vc_compile_one_implementation(${_objs} AVX+XOP+FMA4 "-mavx -mxop -mfma4" "" "")
541 endif()
542 _vc_compile_one_implementation(${_objs} SSE+XOP+FMA "-mxop -mfma" "" "")
543 _vc_compile_one_implementation(${_objs} AVX+XOP+FMA "-mavx -mxop -mfma" "" "")
544 endif()
545 _vc_compile_one_implementation(${_objs} AVX+FMA "-mavx -mfma" "" "")
546 endif()
547endmacro()