Vc package added (version 0.6.79-dev)
[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}")
34 elseif(CMAKE_CXX_COMPILER MATCHES "/(opencc|openCC)$")
35 set(Vc_COMPILER_IS_OPEN64 true)
36 message(STATUS "Detected Compiler: Open64")
37 elseif(CMAKE_CXX_COMPILER MATCHES "/clang\\+\\+$")
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)
108 message(WARNING "Apple does not provide an assembler with AVX support. Please use Clang instead of GCC.")
109 endif()
110 else(APPLE)
111 if(${ARGC} EQUAL 1)
112 set(_as "${ARGV1}")
113 else()
114 exec_program(${CMAKE_CXX_COMPILER} ARGS -print-prog-name=as OUTPUT_VARIABLE _as)
115 mark_as_advanced(_as)
116 endif()
117 if(NOT _as)
118 message(WARNING "Could not find 'as', the assembler used by GCC. Hoping everything will work out...")
119 else()
120 exec_program(${_as} ARGS --version OUTPUT_VARIABLE _as_version)
121 string(REGEX REPLACE "\\([^\\)]*\\)" "" _as_version "${_as_version}")
122 string(REGEX MATCH "[1-9]\\.[0-9]+(\\.[0-9]+)?" _as_version "${_as_version}")
123 if(_as_version VERSION_LESS "2.18.93")
124 message(WARNING "Your binutils is too old (${_as_version}). Some optimizations of Vc will be disabled.")
125 add_definitions(-DVC_NO_XGETBV) # old assembler doesn't know the xgetbv instruction
126 endif()
127 endif()
128 endif(APPLE)
129endmacro()
130
131macro(vc_check_fpmath)
132 # if compiling for 32 bit x86 we need to use the -mfpmath=sse since the x87 is broken by design
133 include (CheckCXXSourceRuns)
134 check_cxx_source_runs("int main() { return sizeof(void*) != 8; }" Vc_VOID_PTR_IS_64BIT)
135 if(NOT Vc_VOID_PTR_IS_64BIT)
136 exec_program(${CMAKE_C_COMPILER} ARGS -dumpmachine OUTPUT_VARIABLE _gcc_machine)
137 if(_gcc_machine MATCHES "[x34567]86")
138 vc_add_compiler_flag(Vc_DEFINITIONS "-mfpmath=sse")
139 endif(_gcc_machine MATCHES "[x34567]86")
140 endif()
141endmacro()
142
143macro(vc_set_preferred_compiler_flags)
144 vc_determine_compiler()
145
146 set(_add_warning_flags false)
147 set(_add_buildtype_flags false)
148 foreach(_arg ${ARGN})
149 if(_arg STREQUAL "WARNING_FLAGS")
150 set(_add_warning_flags true)
151 elseif(_arg STREQUAL "BUILDTYPE_FLAGS")
152 set(_add_buildtype_flags true)
153 endif()
154 endforeach()
155
156 set(Vc_SSE_INTRINSICS_BROKEN false)
157 set(Vc_AVX_INTRINSICS_BROKEN false)
158
159 if(Vc_COMPILER_IS_OPEN64)
160 ##################################################################################################
161 # Open64 #
162 ##################################################################################################
163 if(_add_warning_flags)
164 AddCompilerFlag("-W")
165 AddCompilerFlag("-Wall")
166 AddCompilerFlag("-Wimplicit")
167 AddCompilerFlag("-Wswitch")
168 AddCompilerFlag("-Wformat")
169 AddCompilerFlag("-Wchar-subscripts")
170 AddCompilerFlag("-Wparentheses")
171 AddCompilerFlag("-Wmultichar")
172 AddCompilerFlag("-Wtrigraphs")
173 AddCompilerFlag("-Wpointer-arith")
174 AddCompilerFlag("-Wcast-align")
175 AddCompilerFlag("-Wreturn-type")
176 AddCompilerFlag("-Wno-unused-function")
177 AddCompilerFlag("-ansi")
178 AddCompilerFlag("-pedantic")
179 AddCompilerFlag("-Wno-long-long")
180 AddCompilerFlag("-Wshadow")
181 AddCompilerFlag("-Wold-style-cast")
182 AddCompilerFlag("-Wno-variadic-macros")
183 endif()
184 if(_add_buildtype_flags)
185 vc_set_gnu_buildtype_flags()
186 endif()
187
188 vc_check_assembler()
189 elseif(Vc_COMPILER_IS_GCC)
190 ##################################################################################################
191 # GCC #
192 ##################################################################################################
193 if(_add_warning_flags)
194 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")
195 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")
196 AddCompilerFlag("-Wimplicit")
197 AddCompilerFlag("-Wold-style-cast")
198 AddCompilerFlag("-Wno-variadic-macros")
199 if(Vc_GCC_VERSION VERSION_GREATER "4.5.2" AND Vc_GCC_VERSION VERSION_LESS "4.6.4")
200 # GCC gives bogus "array subscript is above array bounds" warnings in math.cpp
201 AddCompilerFlag("-Wno-array-bounds")
202 endif()
203 endif()
204 vc_add_compiler_flag(Vc_DEFINITIONS "-Wabi")
205 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.
206
207 if(_add_buildtype_flags)
208 vc_set_gnu_buildtype_flags()
209 endif()
210
211 # GCC 4.5.[01] fail at inlining some functions, creating functions with a single instructions,
212 # thus creating a large overhead.
213 if(Vc_GCC_VERSION VERSION_LESS "4.5.2" AND NOT Vc_GCC_VERSION VERSION_LESS "4.5.0")
214 UserWarning("GCC 4.5.0 and 4.5.1 have problems with inlining correctly. Setting early-inlining-insns=12 as workaround.")
215 AddCompilerFlag("--param early-inlining-insns=12")
216 endif()
217
218 if(Vc_GCC_VERSION VERSION_LESS "4.4.6")
219 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.")
220 set(Vc_AVX_INTRINSICS_BROKEN true)
221 if(Vc_GCC_VERSION VERSION_LESS "4.3.0")
222 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.")
223 set(Vc_SSE_INTRINSICS_BROKEN true)
224 endif()
225 endif()
226
227 if(Vc_GCC_VERSION VERSION_LESS 4.5.0)
228 UserWarning("GCC 4.4.x shows false positives for -Wparentheses, thus we rather disable the warning.")
229 string(REPLACE " -Wparentheses " " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
230 string(REPLACE " -Wparentheses " " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
231 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -Wno-parentheses")
232 elseif(Vc_GCC_VERSION VERSION_EQUAL 4.7.0)
233 UserWarning("GCC 4.7.0 miscompiles at -O3, adding -fno-predictive-commoning to the compiler flags as workaround")
234 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -fno-predictive-commoning")
235 endif()
236
237 vc_check_fpmath()
238 vc_check_assembler()
239 elseif(Vc_COMPILER_IS_INTEL)
240 ##################################################################################################
241 # Intel Compiler #
242 ##################################################################################################
243
244 if(_add_buildtype_flags)
245 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
246 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
247 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
248 set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DNDEBUG -O3")
249
250 set(ALIAS_FLAGS "-no-ansi-alias")
251 if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
252 # default ICC to -no-ansi-alias because otherwise tests/utils_sse fails. So far I suspect a miscompilation...
253 set(ENABLE_STRICT_ALIASING false CACHE BOOL "Enables strict aliasing rules for more aggressive optimizations")
254 if(ENABLE_STRICT_ALIASING)
255 set(ALIAS_FLAGS "-ansi-alias")
256 endif(ENABLE_STRICT_ALIASING)
257 endif()
258 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ALIAS_FLAGS}")
259 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ALIAS_FLAGS}")
260 endif()
261 vc_add_compiler_flag(Vc_DEFINITIONS "-diag-disable 913")
262 elseif(Vc_COMPILER_IS_MSVC)
263 if(_add_warning_flags)
264 AddCompilerFlag("/wd4800") # Disable warning "forcing value to bool"
265 AddCompilerFlag("/wd4996") # Disable warning about strdup vs. _strdup
266 AddCompilerFlag("/wd4244") # Disable warning "conversion from 'unsigned int' to 'float', possible loss of data"
267 AddCompilerFlag("/wd4146") # Disable warning "unary minus operator applied to unsigned type, result still unsigned"
268 AddCompilerFlag("/wd4227") # Disable warning "anachronism used : qualifiers on reference are ignored" (this is about 'restrict' usage on references, stupid MSVC)
269 AddCompilerFlag("/wd4722") # Disable warning "destructor never returns, potential memory leak" (warns about ~_UnitTest_Global_Object which we don't care about)
270 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)
271 add_definitions(-D_CRT_SECURE_NO_WARNINGS)
272 endif()
273
274 # MSVC does not support inline assembly on 64 bit! :(
275 # searching the help for xgetbv doesn't turn up anything. So just fall back to not supporting AVX on Windows :(
276 # TODO: apparently MSVC 2010 SP1 added _xgetbv
277 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_NO_XGETBV")
278
279 # get rid of the min/max macros
280 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DNOMINMAX")
281 elseif(Vc_COMPILER_IS_CLANG)
282 # for now I don't know of any arguments I want to pass. -march and stuff is tried by OptimizeForArchitecture...
283
284 # disable these warnings because clang shows them for function overloads that were discarded via SFINAE
285 vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-local-type-template-args")
286 vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-unnamed-type-template-args")
287 endif()
288
289 OptimizeForArchitecture()
290 set(Vc_DEFINITIONS "${Vc_ARCHITECTURE_FLAGS} ${Vc_DEFINITIONS}")
291
292 set(VC_IMPL "auto" CACHE STRING "Force the Vc implementation globally to the selected instruction set. \"auto\" lets Vc use the best available instructions.")
293 if(NOT VC_IMPL STREQUAL "auto")
294 set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DVC_IMPL=${VC_IMPL}")
295 if(NOT VC_IMPL STREQUAL "Scalar")
296 set(_use_var "USE_${VC_IMPL}")
297 if(VC_IMPL STREQUAL "SSE")
298 set(_use_var "USE_SSE2")
299 endif()
300 if(NOT ${_use_var})
301 message(WARNING "The selected value for VC_IMPL (${VC_IMPL}) will not work because the relevant instructions are not enabled via compiler flags.")
302 endif()
303 endif()
304 endif()
305endmacro()