~ubuntu-branches/ubuntu/raring/vc/raring-proposed

« back to all changes in this revision

Viewing changes to cmake/VcMacros.cmake

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-03-08 12:50:59 UTC
  • Revision ID: package-import@ubuntu.com-20130308125059-2vpu3hm02kgrqv96
Tags: upstream-0.7.0
ImportĀ upstreamĀ versionĀ 0.7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
18
cmake_minimum_required(VERSION 2.8.3)
 
19
 
 
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")
 
24
 
 
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}")
 
44
      elseif(MSVC)
 
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}")
 
51
 
 
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}")
 
58
         endif()
 
59
 
 
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)
 
64
         if(_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}")
 
71
               if(_tmp)
 
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}")
 
76
               endif()
 
77
            endif()
 
78
         endif()
 
79
      else()
 
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")
 
81
      endif()
 
82
   endif()
 
83
endmacro()
 
84
 
 
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)
 
101
   endif()
 
102
   mark_as_advanced(CMAKE_CXX_FLAGS_RELWITHDEBUG CMAKE_C_FLAGS_RELWITHDEBUG)
 
103
endmacro()
 
104
 
 
105
macro(vc_add_compiler_flag VAR _flag)
 
106
   AddCompilerFlag("${_flag}" CXX_FLAGS ${VAR})
 
107
endmacro()
 
108
 
 
109
macro(vc_check_assembler)
 
110
   if(APPLE)
 
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)
 
115
      endif()
 
116
   else(APPLE)
 
117
      if(${ARGC} EQUAL 1)
 
118
         set(_as "${ARGV1}")
 
119
      else()
 
120
         exec_program(${CMAKE_CXX_COMPILER} ARGS -print-prog-name=as OUTPUT_VARIABLE _as)
 
121
         mark_as_advanced(_as)
 
122
      endif()
 
123
      if(NOT _as)
 
124
         message(WARNING "Could not find 'as', the assembler used by GCC. Hoping everything will work out...")
 
125
      else()
 
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
 
132
         endif()
 
133
      endif()
 
134
   endif(APPLE)
 
135
endmacro()
 
136
 
 
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")
 
146
   endif()
 
147
endmacro()
 
148
 
 
149
macro(vc_set_preferred_compiler_flags)
 
150
   vc_determine_compiler()
 
151
 
 
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)
 
159
      endif()
 
160
   endforeach()
 
161
 
 
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)
 
166
 
 
167
   if(Vc_COMPILER_IS_OPEN64)
 
168
      ##################################################################################################
 
169
      #                                             Open64                                             #
 
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")
 
191
      endif()
 
192
      if(_add_buildtype_flags)
 
193
         vc_set_gnu_buildtype_flags()
 
194
      endif()
 
195
 
 
196
      vc_check_assembler()
 
197
 
 
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
      ##################################################################################################
 
202
      #                                              GCC                                               #
 
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")
 
207
         if(NOT WIN32)
 
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")
 
211
         endif()
 
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")
 
218
         endif()
 
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")
 
223
         endif()
 
224
      endif()
 
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.
 
227
 
 
228
      if(_add_buildtype_flags)
 
229
         vc_set_gnu_buildtype_flags()
 
230
      endif()
 
231
 
 
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")
 
237
      endif()
 
238
 
 
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)
 
250
         endif()
 
251
      endif()
 
252
 
 
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")
 
258
 
 
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")
 
261
 
 
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")
 
270
      endif()
 
271
 
 
272
      vc_check_fpmath()
 
273
      vc_check_assembler()
 
274
   elseif(Vc_COMPILER_IS_INTEL)
 
275
      ##################################################################################################
 
276
      #                                          Intel Compiler                                        #
 
277
      ##################################################################################################
 
278
 
 
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")
 
284
 
 
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)
 
292
         endif()
 
293
         set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   ${ALIAS_FLAGS}")
 
294
         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ALIAS_FLAGS}")
 
295
      endif()
 
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")
 
299
 
 
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")
 
304
      endif()
 
305
 
 
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)
 
319
      endif()
 
320
 
 
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")
 
325
 
 
326
      # get rid of the min/max macros
 
327
      set(Vc_DEFINITIONS "${Vc_DEFINITIONS} -DNOMINMAX")
 
328
 
 
329
      # MSVC doesn't implement the XOP or FMA4 intrinsics
 
330
      set(Vc_XOP_INTRINSICS_BROKEN true)
 
331
      set(Vc_FMA4_INTRINSICS_BROKEN true)
 
332
 
 
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.")
 
335
      endif()
 
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")
 
343
      endif()
 
344
 
 
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")
 
348
   endif()
 
349
 
 
350
   if(NOT Vc_COMPILER_IS_MSVC)
 
351
      vc_add_compiler_flag(Vc_DEFINITIONS "-ffp-contract=fast")
 
352
   endif()
 
353
 
 
354
   OptimizeForArchitecture()
 
355
   set(Vc_DEFINITIONS "${Vc_ARCHITECTURE_FLAGS} ${Vc_DEFINITIONS}")
 
356
 
 
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")
 
364
         endif()
 
365
         if(NOT ${_use_var})
 
366
            message(WARNING "The selected value for VC_IMPL (${VC_IMPL}) will not work because the relevant instructions are not enabled via compiler flags.")
 
367
         endif()
 
368
      endif()
 
369
   endif()
 
370
endmacro()
 
371
 
 
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))
 
377
      set(_extra_flags)
 
378
      set(_ok FALSE)
 
379
      foreach(_flag ${ARGN})
 
380
         if(_flag STREQUAL "NO_FLAG")
 
381
            set(_ok TRUE)
 
382
            break()
 
383
         endif()
 
384
         string(REPLACE " " ";" _flag_list "${_flag}")
 
385
         foreach(_flag ${_flag_list})
 
386
            AddCompilerFlag(${_flag} CXX_RESULT _ok)
 
387
            if(NOT _ok)
 
388
               break()
 
389
            endif()
 
390
         endforeach()
 
391
         if(_ok)
 
392
            set(_extra_flags ${_flag_list})
 
393
            break()
 
394
         endif()
 
395
      endforeach()
 
396
 
 
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
 
400
         # says SSE
 
401
         if("${_impl}" MATCHES "SSE")
 
402
            set(_ok TRUE)
 
403
         endif()
 
404
         set(_outfile_flag /c /Fo)
 
405
      endif()
 
406
 
 
407
      if(_ok)
 
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")
 
412
         else()
 
413
            set(_out "${_out}_${_impl}${_ext}.o")
 
414
         endif()
 
415
         add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_out}
 
416
            COMMAND ${CMAKE_CXX_COMPILER} ${_flags} ${_extra_flags}
 
417
            -DVC_IMPL=${_impl}
 
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}"
 
423
            VERBATIM
 
424
            )
 
425
         list(APPEND ${_objs} "${CMAKE_CURRENT_BINARY_DIR}/${_out}")
 
426
      endif()
 
427
   endif()
 
428
endmacro()
 
429
 
 
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
 
433
# Example:
 
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)
 
437
   set(${_objs})
 
438
 
 
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}")
 
442
 
 
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}")
 
447
   endif()
 
448
 
 
449
   unset(_disabled_targets)
 
450
   unset(_only_targets)
 
451
   set(_state 0)
 
452
   foreach(_arg ${ARGN})
 
453
      if(_arg STREQUAL "FLAGS")
 
454
         set(_state 1)
 
455
      elseif(_arg STREQUAL "EXCLUDE")
 
456
         set(_state 2)
 
457
      elseif(_arg STREQUAL "ONLY")
 
458
         set(_state 3)
 
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}")
 
465
      else()
 
466
         message(FATAL_ERROR "incorrect argument to vc_compile_for_all_implementations")
 
467
      endif()
 
468
   endforeach()
 
469
 
 
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)
 
475
   foreach(_i ${_inc})
 
476
      list(APPEND _flags "-I${_i}")
 
477
   endforeach()
 
478
 
 
479
   set(_vc_compile_src "${_src}")
 
480
 
 
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")
 
489
   endif()
 
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"  ""    "")
 
496
         endif()
 
497
         _vc_compile_one_implementation(${_objs} SSE+XOP+FMA "-mxop -mfma"        ""    "")
 
498
         _vc_compile_one_implementation(${_objs} AVX+XOP+FMA "-mavx -mxop -mfma"  ""    "")
 
499
      endif()
 
500
      _vc_compile_one_implementation(${_objs} AVX+FMA "-mavx -mfma"  ""    "")
 
501
   endif()
 
502
endmacro()