from Ante Bilandzic:
[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#=============================================================================
8# Copyright 2009-2012 Matthias Kretz <kretz@kde.org>
9#
10# Distributed under the OSI-approved BSD License (the "License");
11# see accompanying file CmakeCopyright.txt for details.
12#
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#=============================================================================
17
18get_filename_component(_currentDir "${CMAKE_CURRENT_LIST_FILE}" PATH)
19include ("${_currentDir}/UserWarning.cmake")
20include ("${_currentDir}/AddCompilerFlag.cmake")
21include ("${_currentDir}/OptimizeForArchitecture.cmake")
22
23macro(vc_determine_compiler)
24 if(NOT DEFINED Vc_COMPILER_IS_INTEL)
25 set(Vc_COMPILER_IS_INTEL false)
26 set(Vc_COMPILER_IS_OPEN64 false)
27 set(Vc_COMPILER_IS_CLANG false)
28 set(Vc_COMPILER_IS_MSVC false)
29 set(Vc_COMPILER_IS_GCC false)
30 if(CMAKE_CXX_COMPILER MATCHES "/(icpc|icc)$")
31 set(Vc_COMPILER_IS_INTEL true)
32 exec_program(${CMAKE_C_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE Vc_ICC_VERSION)
33 message(STATUS "Detected Compiler: Intel ${Vc_ICC_VERSION}")
23a11150 34 elseif(CMAKE_CXX_COMPILER MATCHES "(opencc|openCC)$")
f22341db 35 set(Vc_COMPILER_IS_OPEN64 true)
36 message(STATUS "Detected Compiler: Open64")
23a11150 37 elseif(CMAKE_CXX_COMPILER MATCHES "clang\\+\\+$")
f22341db 38 set(Vc_COMPILER_IS_CLANG true)
39 message(STATUS "Detected Compiler: Clang")
40 elseif(MSVC)
41 set(Vc_COMPILER_IS_MSVC true)
42 message(STATUS "Detected Compiler: MSVC")
43 elseif(CMAKE_COMPILER_IS_GNUCXX)
44 set(Vc_COMPILER_IS_GCC true)
45 exec_program(${CMAKE_C_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE Vc_GCC_VERSION)
46 message(STATUS "Detected Compiler: GCC ${Vc_GCC_VERSION}")
47
48 # some distributions patch their GCC to return nothing or only major and minor version on -dumpversion.
49 # In that case we must extract the version number from --version.
50 if(NOT Vc_GCC_VERSION OR Vc_GCC_VERSION MATCHES "^[0-9]\\.[0-9]+$")
51 exec_program(${CMAKE_C_COMPILER} ARGS --version OUTPUT_VARIABLE Vc_GCC_VERSION)
52 string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" Vc_GCC_VERSION "${Vc_GCC_VERSION}")
53 message(STATUS "GCC Version from --version: ${Vc_GCC_VERSION}")
54 endif()
55
56 # some distributions patch their GCC to be API incompatible to what the FSF released. In
57 # those cases we require a macro to identify the distribution version
58 find_program(_lsb_release lsb_release)
59 mark_as_advanced(_lsb_release)
60 if(_lsb_release)
61 execute_process(COMMAND ${_lsb_release} -is OUTPUT_VARIABLE _distributor_id OUTPUT_STRIP_TRAILING_WHITESPACE)
62 execute_process(COMMAND ${_lsb_release} -rs OUTPUT_VARIABLE _distributor_release OUTPUT_STRIP_TRAILING_WHITESPACE)
63 string(TOUPPER "${_distributor_id}" _distributor_id)
64 if(_distributor_id STREQUAL "UBUNTU")
65 execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE _gcc_version)
66 string(REGEX MATCH "\\(.* ${Vc_GCC_VERSION}-([0-9]+).*\\)" _tmp "${_gcc_version}")
67 if(_tmp)
68 set(_patch ${CMAKE_MATCH_1})
69 string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _tmp "${_distributor_release}")
70 execute_process(COMMAND printf 0x%x%02x%02x ${CMAKE_MATCH_1} ${CMAKE_MATCH_2} ${_patch} OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE _tmp)
71 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -D__GNUC_UBUNTU_VERSION__=${_tmp}")
72 endif()
73 endif()
74 endif()
75 else()
76 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")
77 endif()
78 endif()
79endmacro()
80
81macro(vc_set_gnu_buildtype_flags)
82 set(CMAKE_CXX_FLAGS_DEBUG "-g3" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
83 set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG" CACHE STRING "Flags used by the compiler during release minsize builds." FORCE)
84 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)
85 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -g" CACHE STRING "Flags used by the compiler during Release with Debug Info builds." FORCE)
86 set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
87 set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}" CACHE STRING "Flags used by the compiler during release minsize builds." FORCE)
88 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)
89 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" CACHE STRING "Flags used by the compiler during Release with Debug Info builds." FORCE)
90 if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
91 set(ENABLE_STRICT_ALIASING true CACHE BOOL "Enables strict aliasing rules for more aggressive optimizations")
92 if(NOT ENABLE_STRICT_ALIASING)
93 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-strict-aliasing ")
94 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-strict-aliasing ")
95 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fno-strict-aliasing ")
96 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fno-strict-aliasing ")
97 endif(NOT ENABLE_STRICT_ALIASING)
98 endif()
99endmacro()
100
101macro(vc_add_compiler_flag VAR _flag)
102 AddCompilerFlag("${_flag}" CXX_FLAGS ${VAR})
103endmacro()
104
105macro(vc_check_assembler)
106 if(APPLE)
107 if(NOT Vc_COMPILER_IS_CLANG)
3ea24db6 108 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.")
109 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_NO_XGETBV")
110 set(Vc_AVX_INTRINSICS_BROKEN true)
f22341db 111 endif()
112 else(APPLE)
113 if(${ARGC} EQUAL 1)
114 set(_as "${ARGV1}")
115 else()
116 exec_program(${CMAKE_CXX_COMPILER} ARGS -print-prog-name=as OUTPUT_VARIABLE _as)
117 mark_as_advanced(_as)
118 endif()
119 if(NOT _as)
120 message(WARNING "Could not find 'as', the assembler used by GCC. Hoping everything will work out...")
121 else()
122 exec_program(${_as} ARGS --version OUTPUT_VARIABLE _as_version)
123 string(REGEX REPLACE "\\([^\\)]*\\)" "" _as_version "${_as_version}")
124 string(REGEX MATCH "[1-9]\\.[0-9]+(\\.[0-9]+)?" _as_version "${_as_version}")
125 if(_as_version VERSION_LESS "2.18.93")
6936ae04 126 UserWarning("Your binutils is too old (${_as_version}). Some optimizations of Vc will be disabled.")
f22341db 127 add_definitions(-DVC_NO_XGETBV) # old assembler doesn't know the xgetbv instruction
128 endif()
129 endif()
130 endif(APPLE)
131endmacro()
132
133macro(vc_check_fpmath)
134 # if compiling for 32 bit x86 we need to use the -mfpmath=sse since the x87 is broken by design
135 include (CheckCXXSourceRuns)
136 check_cxx_source_runs("int main() { return sizeof(void*) != 8; }" Vc_VOID_PTR_IS_64BIT)
137 if(NOT Vc_VOID_PTR_IS_64BIT)
138 exec_program(${CMAKE_C_COMPILER} ARGS -dumpmachine OUTPUT_VARIABLE _gcc_machine)
139 if(_gcc_machine MATCHES "[x34567]86")
140 vc_add_compiler_flag(Vc_DEFINITIONS "-mfpmath=sse")
141 endif(_gcc_machine MATCHES "[x34567]86")
142 endif()
143endmacro()
144
145macro(vc_set_preferred_compiler_flags)
146 vc_determine_compiler()
147
148 set(_add_warning_flags false)
149 set(_add_buildtype_flags false)
150 foreach(_arg ${ARGN})
151 if(_arg STREQUAL "WARNING_FLAGS")
152 set(_add_warning_flags true)
153 elseif(_arg STREQUAL "BUILDTYPE_FLAGS")
154 set(_add_buildtype_flags true)
155 endif()
156 endforeach()
157
158 set(Vc_SSE_INTRINSICS_BROKEN false)
159 set(Vc_AVX_INTRINSICS_BROKEN false)
6936ae04 160 set(Vc_XOP_INTRINSICS_BROKEN false)
f22341db 161
162 if(Vc_COMPILER_IS_OPEN64)
163 ##################################################################################################
164 # Open64 #
165 ##################################################################################################
166 if(_add_warning_flags)
167 AddCompilerFlag("-W")
168 AddCompilerFlag("-Wall")
169 AddCompilerFlag("-Wimplicit")
170 AddCompilerFlag("-Wswitch")
171 AddCompilerFlag("-Wformat")
172 AddCompilerFlag("-Wchar-subscripts")
173 AddCompilerFlag("-Wparentheses")
174 AddCompilerFlag("-Wmultichar")
175 AddCompilerFlag("-Wtrigraphs")
176 AddCompilerFlag("-Wpointer-arith")
177 AddCompilerFlag("-Wcast-align")
178 AddCompilerFlag("-Wreturn-type")
179 AddCompilerFlag("-Wno-unused-function")
180 AddCompilerFlag("-ansi")
181 AddCompilerFlag("-pedantic")
182 AddCompilerFlag("-Wno-long-long")
183 AddCompilerFlag("-Wshadow")
184 AddCompilerFlag("-Wold-style-cast")
185 AddCompilerFlag("-Wno-variadic-macros")
186 endif()
187 if(_add_buildtype_flags)
188 vc_set_gnu_buildtype_flags()
189 endif()
190
191 vc_check_assembler()
192 elseif(Vc_COMPILER_IS_GCC)
193 ##################################################################################################
194 # GCC #
195 ##################################################################################################
196 if(_add_warning_flags)
197 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 -ansi -pedantic -Wno-long-long -Wshadow")
198 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 -ansi -pedantic -Wno-long-long -Wshadow")
199 AddCompilerFlag("-Wimplicit")
200 AddCompilerFlag("-Wold-style-cast")
201 AddCompilerFlag("-Wno-variadic-macros")
202 if(Vc_GCC_VERSION VERSION_GREATER "4.5.2" AND Vc_GCC_VERSION VERSION_LESS "4.6.4")
203 # GCC gives bogus "array subscript is above array bounds" warnings in math.cpp
204 AddCompilerFlag("-Wno-array-bounds")
205 endif()
6936ae04 206 if(Vc_GCC_VERSION VERSION_GREATER "4.7.99")
207 # GCC 4.8 warns about stuff we don't care about
208 # Some older GCC versions have problems to note that they don't support the flag
209 AddCompilerFlag("-Wno-unused-local-typedefs")
210 endif()
f22341db 211 endif()
212 vc_add_compiler_flag(Vc_DEFINITIONS "-Wabi")
213 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.
214
215 if(_add_buildtype_flags)
216 vc_set_gnu_buildtype_flags()
217 endif()
218
219 # GCC 4.5.[01] fail at inlining some functions, creating functions with a single instructions,
220 # thus creating a large overhead.
221 if(Vc_GCC_VERSION VERSION_LESS "4.5.2" AND NOT Vc_GCC_VERSION VERSION_LESS "4.5.0")
222 UserWarning("GCC 4.5.0 and 4.5.1 have problems with inlining correctly. Setting early-inlining-insns=12 as workaround.")
223 AddCompilerFlag("--param early-inlining-insns=12")
224 endif()
225
6936ae04 226 if(Vc_GCC_VERSION VERSION_LESS "4.1.99")
227 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")
228 vc_add_compiler_flag(Vc_DEFINITIONS "-fno-strict-aliasing")
229 set(Vc_AVX_INTRINSICS_BROKEN true)
230 set(Vc_SSE_INTRINSICS_BROKEN true)
231 elseif(Vc_GCC_VERSION VERSION_LESS "4.4.6")
f22341db 232 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.")
233 set(Vc_AVX_INTRINSICS_BROKEN true)
234 if(Vc_GCC_VERSION VERSION_LESS "4.3.0")
235 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.")
236 set(Vc_SSE_INTRINSICS_BROKEN true)
237 endif()
238 endif()
239
240 if(Vc_GCC_VERSION VERSION_LESS 4.5.0)
241 UserWarning("GCC 4.4.x shows false positives for -Wparentheses, thus we rather disable the warning.")
242 string(REPLACE " -Wparentheses " " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
243 string(REPLACE " -Wparentheses " " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
244 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -Wno-parentheses")
245 elseif(Vc_GCC_VERSION VERSION_EQUAL 4.7.0)
246 UserWarning("GCC 4.7.0 miscompiles at -O3, adding -fno-predictive-commoning to the compiler flags as workaround")
247 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -fno-predictive-commoning")
248 endif()
249
250 vc_check_fpmath()
251 vc_check_assembler()
252 elseif(Vc_COMPILER_IS_INTEL)
253 ##################################################################################################
254 # Intel Compiler #
255 ##################################################################################################
256
257 if(_add_buildtype_flags)
258 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
259 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
260 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
261 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
262
263 set(ALIAS_FLAGS "-no-ansi-alias")
264 if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
265 # default ICC to -no-ansi-alias because otherwise tests/utils_sse fails. So far I suspect a miscompilation...
266 set(ENABLE_STRICT_ALIASING false CACHE BOOL "Enables strict aliasing rules for more aggressive optimizations")
267 if(ENABLE_STRICT_ALIASING)
268 set(ALIAS_FLAGS "-ansi-alias")
269 endif(ENABLE_STRICT_ALIASING)
270 endif()
271 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ALIAS_FLAGS}")
272 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ALIAS_FLAGS}")
273 endif()
274 vc_add_compiler_flag(Vc_DEFINITIONS "-diag-disable 913")
275 elseif(Vc_COMPILER_IS_MSVC)
276 if(_add_warning_flags)
277 AddCompilerFlag("/wd4800") # Disable warning "forcing value to bool"
278 AddCompilerFlag("/wd4996") # Disable warning about strdup vs. _strdup
279 AddCompilerFlag("/wd4244") # Disable warning "conversion from 'unsigned int' to 'float', possible loss of data"
280 AddCompilerFlag("/wd4146") # Disable warning "unary minus operator applied to unsigned type, result still unsigned"
281 AddCompilerFlag("/wd4227") # Disable warning "anachronism used : qualifiers on reference are ignored" (this is about 'restrict' usage on references, stupid MSVC)
282 AddCompilerFlag("/wd4722") # Disable warning "destructor never returns, potential memory leak" (warns about ~_UnitTest_Global_Object which we don't care about)
283 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)
284 add_definitions(-D_CRT_SECURE_NO_WARNINGS)
285 endif()
286
287 # MSVC does not support inline assembly on 64 bit! :(
288 # searching the help for xgetbv doesn't turn up anything. So just fall back to not supporting AVX on Windows :(
289 # TODO: apparently MSVC 2010 SP1 added _xgetbv
290 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_NO_XGETBV")
291
292 # get rid of the min/max macros
293 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DNOMINMAX")
6936ae04 294
295 # MSVC doesn't implement the XOP intrinsics
296 set(Vc_XOP_INTRINSICS_BROKEN true)
f22341db 297 elseif(Vc_COMPILER_IS_CLANG)
298 # for now I don't know of any arguments I want to pass. -march and stuff is tried by OptimizeForArchitecture...
299
300 # disable these warnings because clang shows them for function overloads that were discarded via SFINAE
301 vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-local-type-template-args")
302 vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-unnamed-type-template-args")
303 endif()
304
305 OptimizeForArchitecture()
306 set(Vc_DEFINITIONS "${Vc_ARCHITECTURE_FLAGS} ${Vc_DEFINITIONS}")
307
308 set(VC_IMPL "auto" CACHE STRING "Force the Vc implementation globally to the selected instruction set. \"auto\" lets Vc use the best available instructions.")
309 if(NOT VC_IMPL STREQUAL "auto")
310 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_IMPL=${VC_IMPL}")
311 if(NOT VC_IMPL STREQUAL "Scalar")
312 set(_use_var "USE_${VC_IMPL}")
313 if(VC_IMPL STREQUAL "SSE")
314 set(_use_var "USE_SSE2")
315 endif()
316 if(NOT ${_use_var})
317 message(WARNING "The selected value for VC_IMPL (${VC_IMPL}) will not work because the relevant instructions are not enabled via compiler flags.")
318 endif()
319 endif()
320 endif()
321endmacro()