1
# Macros for use with the Vc library. Vc can be found at http://code.compeng.uni-frankfurt.de/projects/vc
3
# The following macros are provided:
4
# vc_determine_compiler
5
# vc_set_preferred_compiler_flags
7
#=============================================================================
8
# Copyright 2009-2012 Matthias Kretz <kretz@kde.org>
10
# Distributed under the OSI-approved BSD License (the "License");
11
# see accompanying file CmakeCopyright.txt for details.
13
# This software is distributed WITHOUT ANY WARRANTY; without even the
14
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
# See the License for more information.
16
#=============================================================================
18
cmake_minimum_required(VERSION 2.8.3)
20
get_filename_component(_currentDir "${CMAKE_CURRENT_LIST_FILE}" PATH)
21
include ("${_currentDir}/UserWarning.cmake")
22
include ("${_currentDir}/AddCompilerFlag.cmake")
23
include ("${_currentDir}/OptimizeForArchitecture.cmake")
25
macro(vc_determine_compiler)
26
if(NOT DEFINED Vc_COMPILER_IS_INTEL)
27
set(Vc_COMPILER_IS_INTEL false)
28
set(Vc_COMPILER_IS_OPEN64 false)
29
set(Vc_COMPILER_IS_CLANG false)
30
set(Vc_COMPILER_IS_MSVC false)
31
set(Vc_COMPILER_IS_GCC false)
32
if(CMAKE_CXX_COMPILER MATCHES "/(icpc|icc)$")
33
set(Vc_COMPILER_IS_INTEL true)
34
exec_program(${CMAKE_C_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE Vc_ICC_VERSION)
35
message(STATUS "Detected Compiler: Intel ${Vc_ICC_VERSION}")
36
elseif(CMAKE_CXX_COMPILER MATCHES "(opencc|openCC)$")
37
set(Vc_COMPILER_IS_OPEN64 true)
38
message(STATUS "Detected Compiler: Open64")
39
elseif(CMAKE_CXX_COMPILER MATCHES "clang\\+\\+$")
40
set(Vc_COMPILER_IS_CLANG true)
41
exec_program(${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE Vc_CLANG_VERSION)
42
string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" Vc_CLANG_VERSION "${Vc_CLANG_VERSION}")
43
message(STATUS "Detected Compiler: Clang ${Vc_CLANG_VERSION}")
45
set(Vc_COMPILER_IS_MSVC true)
46
message(STATUS "Detected Compiler: MSVC ${MSVC_VERSION}")
47
elseif(CMAKE_COMPILER_IS_GNUCXX)
48
set(Vc_COMPILER_IS_GCC true)
49
exec_program(${CMAKE_C_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE Vc_GCC_VERSION)
50
message(STATUS "Detected Compiler: GCC ${Vc_GCC_VERSION}")
52
# some distributions patch their GCC to return nothing or only major and minor version on -dumpversion.
53
# In that case we must extract the version number from --version.
54
if(NOT Vc_GCC_VERSION OR Vc_GCC_VERSION MATCHES "^[0-9]\\.[0-9]+$")
55
exec_program(${CMAKE_C_COMPILER} ARGS --version OUTPUT_VARIABLE Vc_GCC_VERSION)
56
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" Vc_GCC_VERSION "${Vc_GCC_VERSION}")
57
message(STATUS "GCC Version from --version: ${Vc_GCC_VERSION}")
60
# some distributions patch their GCC to be API incompatible to what the FSF released. In
61
# those cases we require a macro to identify the distribution version
62
find_program(_lsb_release lsb_release)
63
mark_as_advanced(_lsb_release)
65
execute_process(COMMAND ${_lsb_release} -is OUTPUT_VARIABLE _distributor_id OUTPUT_STRIP_TRAILING_WHITESPACE)
66
execute_process(COMMAND ${_lsb_release} -rs OUTPUT_VARIABLE _distributor_release OUTPUT_STRIP_TRAILING_WHITESPACE)
67
string(TOUPPER "${_distributor_id}" _distributor_id)
68
if(_distributor_id STREQUAL "UBUNTU")
69
execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE _gcc_version)
70
string(REGEX MATCH "\\(.* ${Vc_GCC_VERSION}-([0-9]+).*\\)" _tmp "${_gcc_version}")
72
set(_patch ${CMAKE_MATCH_1})
73
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _tmp "${_distributor_release}")
74
execute_process(COMMAND printf 0x%x%02x%02x ${CMAKE_MATCH_1} ${CMAKE_MATCH_2} ${_patch} OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE _tmp)
75
set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -D__GNUC_UBUNTU_VERSION__=${_tmp}")
80
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")
85
macro(vc_set_gnu_buildtype_flags)
86
set(CMAKE_CXX_FLAGS_DEBUG "-g3" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
87
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG" CACHE STRING "Flags used by the compiler during release minsize builds." FORCE)
88
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)
89
set(CMAKE_CXX_FLAGS_RELWITHDEBUG "-O3" CACHE STRING "Flags used by the compiler during release builds containing runtime checks." FORCE)
90
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBUG} -g" CACHE STRING "Flags used by the compiler during Release with Debug Info builds." FORCE)
91
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
92
set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}" CACHE STRING "Flags used by the compiler during release minsize builds." FORCE)
93
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)
94
set(CMAKE_C_FLAGS_RELWITHDEBUG "${CMAKE_CXX_FLAGS_RELWITHDEBUG}" CACHE STRING "Flags used by the compiler during release builds containing runtime checks." FORCE)
95
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" CACHE STRING "Flags used by the compiler during Release with Debug Info builds." FORCE)
96
if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebug")
97
set(ENABLE_STRICT_ALIASING true CACHE BOOL "Enables strict aliasing rules for more aggressive optimizations")
98
if(NOT ENABLE_STRICT_ALIASING)
99
AddCompilerFlag(-fno-strict-aliasing)
100
endif(NOT ENABLE_STRICT_ALIASING)
102
mark_as_advanced(CMAKE_CXX_FLAGS_RELWITHDEBUG CMAKE_C_FLAGS_RELWITHDEBUG)
105
macro(vc_add_compiler_flag VAR _flag)
106
AddCompilerFlag("${_flag}" CXX_FLAGS ${VAR})
109
macro(vc_check_assembler)
111
if(NOT Vc_COMPILER_IS_CLANG)
112
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.")
113
set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_NO_XGETBV")
114
set(Vc_AVX_INTRINSICS_BROKEN true)
120
exec_program(${CMAKE_CXX_COMPILER} ARGS -print-prog-name=as OUTPUT_VARIABLE _as)
121
mark_as_advanced(_as)
124
message(WARNING "Could not find 'as', the assembler used by GCC. Hoping everything will work out...")
126
exec_program(${_as} ARGS --version OUTPUT_VARIABLE _as_version)
127
string(REGEX REPLACE "\\([^\\)]*\\)" "" _as_version "${_as_version}")
128
string(REGEX MATCH "[1-9]\\.[0-9]+(\\.[0-9]+)?" _as_version "${_as_version}")
129
if(_as_version VERSION_LESS "2.18.93")
130
UserWarning("Your binutils is too old (${_as_version}). Some optimizations of Vc will be disabled.")
131
add_definitions(-DVC_NO_XGETBV) # old assembler doesn't know the xgetbv instruction
137
macro(vc_check_fpmath)
138
# if compiling for 32 bit x86 we need to use the -mfpmath=sse since the x87 is broken by design
139
include (CheckCXXSourceRuns)
140
check_cxx_source_runs("int main() { return sizeof(void*) != 8; }" Vc_VOID_PTR_IS_64BIT)
141
if(NOT Vc_VOID_PTR_IS_64BIT)
142
exec_program(${CMAKE_C_COMPILER} ARGS -dumpmachine OUTPUT_VARIABLE _gcc_machine)
143
if(_gcc_machine MATCHES "[x34567]86")
144
vc_add_compiler_flag(Vc_DEFINITIONS "-mfpmath=sse")
145
endif(_gcc_machine MATCHES "[x34567]86")
149
macro(vc_set_preferred_compiler_flags)
150
vc_determine_compiler()
152
set(_add_warning_flags false)
153
set(_add_buildtype_flags false)
154
foreach(_arg ${ARGN})
155
if(_arg STREQUAL "WARNING_FLAGS")
156
set(_add_warning_flags true)
157
elseif(_arg STREQUAL "BUILDTYPE_FLAGS")
158
set(_add_buildtype_flags true)
162
set(Vc_SSE_INTRINSICS_BROKEN false)
163
set(Vc_AVX_INTRINSICS_BROKEN false)
164
set(Vc_XOP_INTRINSICS_BROKEN false)
165
set(Vc_FMA4_INTRINSICS_BROKEN false)
167
if(Vc_COMPILER_IS_OPEN64)
168
##################################################################################################
170
##################################################################################################
171
if(_add_warning_flags)
172
AddCompilerFlag("-W")
173
AddCompilerFlag("-Wall")
174
AddCompilerFlag("-Wimplicit")
175
AddCompilerFlag("-Wswitch")
176
AddCompilerFlag("-Wformat")
177
AddCompilerFlag("-Wchar-subscripts")
178
AddCompilerFlag("-Wparentheses")
179
AddCompilerFlag("-Wmultichar")
180
AddCompilerFlag("-Wtrigraphs")
181
AddCompilerFlag("-Wpointer-arith")
182
AddCompilerFlag("-Wcast-align")
183
AddCompilerFlag("-Wreturn-type")
184
AddCompilerFlag("-Wno-unused-function")
185
AddCompilerFlag("-ansi")
186
AddCompilerFlag("-pedantic")
187
AddCompilerFlag("-Wno-long-long")
188
AddCompilerFlag("-Wshadow")
189
AddCompilerFlag("-Wold-style-cast")
190
AddCompilerFlag("-Wno-variadic-macros")
192
if(_add_buildtype_flags)
193
vc_set_gnu_buildtype_flags()
198
# Open64 4.5.1 still doesn't ship immintrin.h
199
set(Vc_AVX_INTRINSICS_BROKEN true)
200
elseif(Vc_COMPILER_IS_GCC)
201
##################################################################################################
203
##################################################################################################
204
if(_add_warning_flags)
205
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")
206
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")
208
# the -ansi flag makes MinGW unusable, so maybe it's better to omit it
209
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ansi")
210
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ansi")
212
AddCompilerFlag("-Wundef")
213
AddCompilerFlag("-Wold-style-cast")
214
AddCompilerFlag("-Wno-variadic-macros")
215
if(Vc_GCC_VERSION VERSION_GREATER "4.5.2" AND Vc_GCC_VERSION VERSION_LESS "4.6.4")
216
# GCC gives bogus "array subscript is above array bounds" warnings in math.cpp
217
AddCompilerFlag("-Wno-array-bounds")
219
if(Vc_GCC_VERSION VERSION_GREATER "4.7.99")
220
# GCC 4.8 warns about stuff we don't care about
221
# Some older GCC versions have problems to note that they don't support the flag
222
AddCompilerFlag("-Wno-unused-local-typedefs")
225
vc_add_compiler_flag(Vc_DEFINITIONS "-Wabi")
226
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.
228
if(_add_buildtype_flags)
229
vc_set_gnu_buildtype_flags()
232
# GCC 4.5.[01] fail at inlining some functions, creating functions with a single instructions,
233
# thus creating a large overhead.
234
if(Vc_GCC_VERSION VERSION_LESS "4.5.2" AND NOT Vc_GCC_VERSION VERSION_LESS "4.5.0")
235
UserWarning("GCC 4.5.0 and 4.5.1 have problems with inlining correctly. Setting early-inlining-insns=12 as workaround.")
236
AddCompilerFlag("--param early-inlining-insns=12")
239
if(Vc_GCC_VERSION VERSION_LESS "4.1.99")
240
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")
241
vc_add_compiler_flag(Vc_DEFINITIONS "-fno-strict-aliasing")
242
set(Vc_AVX_INTRINSICS_BROKEN true)
243
set(Vc_SSE_INTRINSICS_BROKEN true)
244
elseif(Vc_GCC_VERSION VERSION_LESS "4.4.6")
245
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.")
246
set(Vc_AVX_INTRINSICS_BROKEN true)
247
if(Vc_GCC_VERSION VERSION_LESS "4.3.0")
248
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.")
249
set(Vc_SSE_INTRINSICS_BROKEN true)
253
if(Vc_GCC_VERSION VERSION_LESS 4.5.0)
254
UserWarning("GCC 4.4.x shows false positives for -Wparentheses, thus we rather disable the warning.")
255
string(REPLACE " -Wparentheses " " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
256
string(REPLACE " -Wparentheses " " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
257
set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -Wno-parentheses")
259
UserWarning("GCC 4.4.x shows false positives for -Wstrict-aliasing, thus we rather disable the warning. Use a newer GCC for better warnings.")
260
AddCompilerFlag("-Wno-strict-aliasing")
262
UserWarning("GCC 4.4.x shows false positives for -Wuninitialized, thus we rather disable the warning. Use a newer GCC for better warnings.")
263
AddCompilerFlag("-Wno-uninitialized")
264
elseif(Vc_GCC_VERSION VERSION_EQUAL 4.6.0)
265
UserWarning("GCC 4.6.0 miscompiles AVX loads/stores, leading to spurious segfaults. Disabling AVX per default.")
266
set(Vc_AVX_INTRINSICS_BROKEN true)
267
elseif(Vc_GCC_VERSION VERSION_EQUAL 4.7.0)
268
UserWarning("GCC 4.7.0 miscompiles at -O3, adding -fno-predictive-commoning to the compiler flags as workaround")
269
set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -fno-predictive-commoning")
274
elseif(Vc_COMPILER_IS_INTEL)
275
##################################################################################################
277
##################################################################################################
279
if(_add_buildtype_flags)
280
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
281
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
282
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
283
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
285
set(ALIAS_FLAGS "-no-ansi-alias")
286
if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
287
# default ICC to -no-ansi-alias because otherwise tests/utils_sse fails. So far I suspect a miscompilation...
288
set(ENABLE_STRICT_ALIASING false CACHE BOOL "Enables strict aliasing rules for more aggressive optimizations")
289
if(ENABLE_STRICT_ALIASING)
290
set(ALIAS_FLAGS "-ansi-alias")
291
endif(ENABLE_STRICT_ALIASING)
293
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ALIAS_FLAGS}")
294
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ALIAS_FLAGS}")
296
vc_add_compiler_flag(Vc_DEFINITIONS "-diag-disable 913")
297
# Disable warning #13211 "Immediate parameter to intrinsic call too large". (sse/vector.tcc rotated(int))
298
vc_add_compiler_flag(Vc_DEFINITIONS "-diag-disable 13211")
300
if(NOT "$ENV{DASHBOARD_TEST_FROM_CTEST}" STREQUAL "")
301
# disable warning #2928: the __GXX_EXPERIMENTAL_CXX0X__ macro is disabled when using GNU version 4.6 with the c++0x option
302
# this warning just adds noise about problems in the compiler - but I'm only interested in seeing problems in Vc
303
vc_add_compiler_flag(Vc_DEFINITIONS "-diag-disable 2928")
306
# Intel doesn't implement the XOP or FMA4 intrinsics
307
set(Vc_XOP_INTRINSICS_BROKEN true)
308
set(Vc_FMA4_INTRINSICS_BROKEN true)
309
elseif(Vc_COMPILER_IS_MSVC)
310
if(_add_warning_flags)
311
AddCompilerFlag("/wd4800") # Disable warning "forcing value to bool"
312
AddCompilerFlag("/wd4996") # Disable warning about strdup vs. _strdup
313
AddCompilerFlag("/wd4244") # Disable warning "conversion from 'unsigned int' to 'float', possible loss of data"
314
AddCompilerFlag("/wd4146") # Disable warning "unary minus operator applied to unsigned type, result still unsigned"
315
AddCompilerFlag("/wd4227") # Disable warning "anachronism used : qualifiers on reference are ignored" (this is about 'restrict' usage on references, stupid MSVC)
316
AddCompilerFlag("/wd4722") # Disable warning "destructor never returns, potential memory leak" (warns about ~_UnitTest_Global_Object which we don't care about)
317
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)
318
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
321
# MSVC does not support inline assembly on 64 bit! :(
322
# searching the help for xgetbv doesn't turn up anything. So just fall back to not supporting AVX on Windows :(
323
# TODO: apparently MSVC 2010 SP1 added _xgetbv
324
set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_NO_XGETBV")
326
# get rid of the min/max macros
327
set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DNOMINMAX")
329
# MSVC doesn't implement the XOP or FMA4 intrinsics
330
set(Vc_XOP_INTRINSICS_BROKEN true)
331
set(Vc_FMA4_INTRINSICS_BROKEN true)
333
if(MSVC_VERSION LESS 1700)
334
UserWarning("MSVC before 2012 has a broken std::vector::resize implementation. STL + Vc code will probably not compile.")
336
elseif(Vc_COMPILER_IS_CLANG)
337
# for now I don't know of any arguments I want to pass. -march and stuff is tried by OptimizeForArchitecture...
338
if(Vc_CLANG_VERSION VERSION_EQUAL "3.0")
339
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.")
340
elseif(Vc_CLANG_VERSION VERSION_LESS "3.3")
341
# the LLVM assembler gets FMAs wrong (bug 15040)
342
vc_add_compiler_flag(Vc_DEFINITIONS "-no-integrated-as")
345
# disable these warnings because clang shows them for function overloads that were discarded via SFINAE
346
vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-local-type-template-args")
347
vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-unnamed-type-template-args")
350
if(NOT Vc_COMPILER_IS_MSVC)
351
vc_add_compiler_flag(Vc_DEFINITIONS "-ffp-contract=fast")
354
OptimizeForArchitecture()
355
set(Vc_DEFINITIONS "${Vc_ARCHITECTURE_FLAGS} ${Vc_DEFINITIONS}")
357
set(VC_IMPL "auto" CACHE STRING "Force the Vc implementation globally to the selected instruction set. \"auto\" lets Vc use the best available instructions.")
358
if(NOT VC_IMPL STREQUAL "auto")
359
set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_IMPL=${VC_IMPL}")
360
if(NOT VC_IMPL STREQUAL "Scalar")
361
set(_use_var "USE_${VC_IMPL}")
362
if(VC_IMPL STREQUAL "SSE")
363
set(_use_var "USE_SSE2")
366
message(WARNING "The selected value for VC_IMPL (${VC_IMPL}) will not work because the relevant instructions are not enabled via compiler flags.")
372
# helper macro for vc_compile_for_all_implementations
373
macro(_vc_compile_one_implementation _objs _impl)
374
list(FIND _disabled_targets "${_impl}" _disabled_index)
375
list(FIND _only_targets "${_impl}" _only_index)
376
if(${_disabled_index} EQUAL -1 AND (NOT _only_targets OR ${_only_index} GREATER -1))
379
foreach(_flag ${ARGN})
380
if(_flag STREQUAL "NO_FLAG")
384
string(REPLACE " " ";" _flag_list "${_flag}")
385
foreach(_flag ${_flag_list})
386
AddCompilerFlag(${_flag} CXX_RESULT _ok)
392
set(_extra_flags ${_flag_list})
397
set(_outfile_flag -c -o)
398
if(Vc_COMPILER_IS_MSVC)
399
# MSVC for 64bit does not recognize /arch:SSE2 anymore. Therefore we set override _ok if _impl
401
if("${_impl}" MATCHES "SSE")
404
set(_outfile_flag /c /Fo)
408
get_filename_component(_out "${_vc_compile_src}" NAME_WE)
409
get_filename_component(_ext "${_vc_compile_src}" EXT)
410
if(Vc_COMPILER_IS_MSVC)
411
set(_out "${_out}_${_impl}${_ext}.obj")
413
set(_out "${_out}_${_impl}${_ext}.o")
415
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_out}
416
COMMAND ${CMAKE_CXX_COMPILER} ${_flags} ${_extra_flags}
418
${_outfile_flag}${_out} ${CMAKE_CURRENT_SOURCE_DIR}/${_vc_compile_src}
419
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${_vc_compile_src}
420
IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/${_vc_compile_src}
421
COMMENT "Building CXX object ${_out}"
422
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
425
list(APPEND ${_objs} "${CMAKE_CURRENT_BINARY_DIR}/${_out}")
430
# Generate compile rules for the given C++ source file for all available implementations and return
431
# the resulting list of object files in _obj
432
# all remaining arguments are additional flags
434
# vc_compile_for_all_implementations(_objs src/trigonometric.cpp FLAGS -DCOMPILE_BLAH EXCLUDE Scalar)
435
# add_executable(executable main.cpp ${_objs})
436
macro(vc_compile_for_all_implementations _objs _src)
439
# remove all -march, -msse, etc. flags from the flags we want to pass
440
string(REPLACE "${Vc_ARCHITECTURE_FLAGS}" "" _flags "${Vc_DEFINITIONS}")
441
string(REPLACE "-DVC_IMPL=[^ ]*" "" _flags "${_flags}")
443
# capture the -march= switch as -mtune; if there is none skip it
444
if(Vc_ARCHITECTURE_FLAGS MATCHES "-march=")
445
string(REGEX REPLACE "^.*-march=([^ ]*).*$" "-mtune=\\1" _tmp "${Vc_ARCHITECTURE_FLAGS}")
446
set(_flags "${_flags} ${_tmp}")
449
unset(_disabled_targets)
452
foreach(_arg ${ARGN})
453
if(_arg STREQUAL "FLAGS")
455
elseif(_arg STREQUAL "EXCLUDE")
457
elseif(_arg STREQUAL "ONLY")
459
elseif(_state EQUAL 1)
460
set(_flags "${_flags} ${_arg}")
461
elseif(_state EQUAL 2)
462
list(APPEND _disabled_targets "${_arg}")
463
elseif(_state EQUAL 3)
464
list(APPEND _only_targets "${_arg}")
466
message(FATAL_ERROR "incorrect argument to vc_compile_for_all_implementations")
470
# make a semicolon separated list of all flags
471
string(TOUPPER "${CMAKE_BUILD_TYPE}" _tmp)
472
set(_tmp "CMAKE_CXX_FLAGS_${_tmp}")
473
string(REPLACE " " ";" _flags "${CMAKE_CXX_FLAGS} ${${_tmp}} ${_flags}")
474
get_directory_property(_inc INCLUDE_DIRECTORIES)
476
list(APPEND _flags "-I${_i}")
479
set(_vc_compile_src "${_src}")
481
_vc_compile_one_implementation(${_objs} Scalar NO_FLAG)
482
if(NOT Vc_SSE_INTRINSICS_BROKEN)
483
_vc_compile_one_implementation(${_objs} SSE2 "-msse2" "-xSSE2" "/arch:SSE2")
484
_vc_compile_one_implementation(${_objs} SSE3 "-msse3" "-xSSE3" "/arch:SSE2")
485
_vc_compile_one_implementation(${_objs} SSSE3 "-mssse3" "-xSSSE3" "/arch:SSE2")
486
_vc_compile_one_implementation(${_objs} SSE4_1 "-msse4.1" "-xSSE4.1" "/arch:SSE2")
487
_vc_compile_one_implementation(${_objs} SSE4_2 "-msse4.2" "-xSSE4.2" "/arch:SSE2")
488
_vc_compile_one_implementation(${_objs} SSE3+SSE4a "-msse4a")
490
if(NOT Vc_AVX_INTRINSICS_BROKEN)
491
_vc_compile_one_implementation(${_objs} AVX "-mavx" "-xAVX" "/arch:AVX")
492
if(NOT Vc_XOP_INTRINSICS_BROKEN)
493
if(NOT Vc_FMA4_INTRINSICS_BROKEN)
494
_vc_compile_one_implementation(${_objs} SSE+XOP+FMA4 "-mxop -mfma4" "" "")
495
_vc_compile_one_implementation(${_objs} AVX+XOP+FMA4 "-mavx -mxop -mfma4" "" "")
497
_vc_compile_one_implementation(${_objs} SSE+XOP+FMA "-mxop -mfma" "" "")
498
_vc_compile_one_implementation(${_objs} AVX+XOP+FMA "-mavx -mxop -mfma" "" "")
500
_vc_compile_one_implementation(${_objs} AVX+FMA "-mavx -mfma" "" "")