Merge pull request #16122 from alalek:cmake_update_cpu_compiler_detection
[platform/upstream/opencv.git] / cmake / OpenCVCompilerOptimizations.cmake
1 # x86/x86-64 arch:
2 # SSE / SSE2 (always available on 64-bit CPUs)
3 # SSE3 / SSSE3
4 # SSE4_1 / SSE4_2 / POPCNT
5 # AVX / AVX2 / AVX_512F
6 # FMA3
7 #
8 # AVX512 details: https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512
9 #
10 # CPU features groups:
11 # AVX512_COMMON (Common instructions AVX-512F/CD for all CPUs that support AVX-512)
12 # AVX512_KNL (Knights Landing with AVX-512F/CD/ER/PF)
13 # AVX512_KNM (Knights Mill with AVX-512F/CD/ER/PF/4FMAPS/4VNNIW/VPOPCNTDQ)
14 # AVX512_SKX (Skylake-X with AVX-512F/CD/BW/DQ/VL)
15 # AVX512_CNL (Cannon Lake with AVX-512F/CD/BW/DQ/VL/IFMA/VBMI)
16 # AVX512_CLX (Cascade Lake with AVX-512F/CD/BW/DQ/VL/VNNI)
17 # AVX512_ICL (Ice Lake with AVX-512F/CD/BW/DQ/VL/IFMA/VBMI/VNNI/VBMI2/BITALG/VPOPCNTDQ/VPCLMULQDQ*/GFNI*/VAES*)
18
19 # ppc64le arch:
20 # VSX  (always available on Power8)
21 # VSX3 (always available on Power9)
22
23 # CPU_{opt}_SUPPORTED=ON/OFF - compiler support (possibly with additional flag)
24 # CPU_{opt}_IMPLIES=<list>
25 # CPU_{opt}_FORCE=<list> - subset of "implies" list
26 # CPU_{opt}_GROUP=<list> - similar to "implies" list, but additionally merges compiler flags
27 # CPU_{opt}_FLAGS_ON=""
28 # CPU_{opt}_FEATURE_ALIAS - mapping to CV_CPU_* HWFeature enum
29
30 # Input variables:
31 # CPU_BASELINE=<list> - preferred list of baseline optimizations
32 # CPU_DISPATCH=<list> - preferred list of dispatched optimizations
33
34 # Advanced input variables:
35 # CPU_BASELINE_REQUIRE=<list> - list of required baseline optimizations
36 # CPU_DISPATCH_REQUIRE=<list> - list of required dispatched optimizations
37 # CPU_BASELINE_DISABLE=<list> - list of disabled baseline optimizations
38
39 # Output variables:
40 # CPU_BASELINE_FINAL=<list> - final list of enabled compiler optimizations
41 # CPU_DISPATCH_FINAL=<list> - final list of dispatched optimizations
42 #
43 # CPU_DISPATCH_FLAGS_${opt} - flags for source files compiled separately (<name>.avx2.cpp)
44 #
45 # CPU_{opt}_ENABLED_DEFAULT=ON/OFF - has compiler support without additional flag (CPU_BASELINE_DETECT=ON only)
46
47 set(CPU_ALL_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;SSE4_2;POPCNT;AVX;FP16;AVX2;FMA3;AVX_512F")
48 list(APPEND CPU_ALL_OPTIMIZATIONS "AVX512_COMMON;AVX512_KNL;AVX512_KNM;AVX512_SKX;AVX512_CNL;AVX512_CLX;AVX512_ICL")
49 list(APPEND CPU_ALL_OPTIMIZATIONS NEON VFPV3 FP16)
50 list(APPEND CPU_ALL_OPTIMIZATIONS MSA)
51 list(APPEND CPU_ALL_OPTIMIZATIONS VSX VSX3)
52 list(REMOVE_DUPLICATES CPU_ALL_OPTIMIZATIONS)
53
54 ocv_update(CPU_VFPV3_FEATURE_ALIAS "")
55
56
57 set(HELP_CPU_BASELINE "Specify list of enabled baseline CPU optimizations")
58 set(HELP_CPU_BASELINE_REQUIRE "Specify list of required baseline CPU optimizations")
59 set(HELP_CPU_BASELINE_DISABLE "Specify list of forbidden baseline CPU optimizations")
60 set(HELP_CPU_DISPATCH "Specify list of dispatched CPU optimizations")
61 set(HELP_CPU_DISPATCH_REQUIRE "Specify list of required dispatched CPU optimizations")
62
63 foreach(var CPU_BASELINE CPU_BASELINE_REQUIRE CPU_BASELINE_DISABLE CPU_DISPATCH CPU_DISPATCH_REQUIRE)
64   if(DEFINED ${var})
65     string(REPLACE "," ";" _list "${${var}}")
66     set(${var} "${_list}" CACHE STRING "${HELP_${var}}" FORCE)
67   endif()
68 endforeach()
69
70 # process legacy flags
71 macro(ocv_optimization_process_obsolete_option legacy_flag OPT legacy_warn)
72   if(DEFINED "${legacy_flag}")
73     if("${legacy_warn}")
74       message(STATUS "WARNING: Option ${legacy_flag}='${${legacy_flag}}' is deprecated and should not be used anymore")
75       message(STATUS "         Behaviour of this option is not backward compatible")
76       message(STATUS "         Refer to 'CPU_BASELINE'/'CPU_DISPATCH' CMake options documentation")
77     endif()
78     if("${${legacy_flag}}")
79       if(NOT ";${CPU_BASELINE_REQUIRE};" MATCHES ";${OPT};")
80         set(CPU_BASELINE_REQUIRE "${CPU_BASELINE_REQUIRE};${OPT}" CACHE STRING "${HELP_CPU_BASELINE_REQUIRE}" FORCE)
81       endif()
82     else()
83       if(NOT ";${CPU_BASELINE_DISABLE};" MATCHES ";${OPT};")
84         set(CPU_BASELINE_DISABLE "${CPU_BASELINE_DISABLE};${OPT}" CACHE STRING "${HELP_CPU_BASELINE_DISABLE}" FORCE)
85       endif()
86     endif()
87   endif()
88 endmacro()
89 ocv_optimization_process_obsolete_option(ENABLE_SSE SSE ON)
90 ocv_optimization_process_obsolete_option(ENABLE_SSE2 SSE2 ON)
91 ocv_optimization_process_obsolete_option(ENABLE_SSE3 SSE3 ON)
92 ocv_optimization_process_obsolete_option(ENABLE_SSSE3 SSSE3 ON)
93 ocv_optimization_process_obsolete_option(ENABLE_SSE41 SSE4_1 ON)
94 ocv_optimization_process_obsolete_option(ENABLE_SSE42 SSE4_2 ON)
95 ocv_optimization_process_obsolete_option(ENABLE_POPCNT POPCNT ON)
96 ocv_optimization_process_obsolete_option(ENABLE_AVX AVX ON)
97 ocv_optimization_process_obsolete_option(ENABLE_AVX2 AVX2 ON)
98 ocv_optimization_process_obsolete_option(ENABLE_FMA3 FMA3 ON)
99
100 ocv_optimization_process_obsolete_option(ENABLE_VFPV3 VFPV3 OFF)
101 ocv_optimization_process_obsolete_option(ENABLE_NEON NEON OFF)
102
103 ocv_optimization_process_obsolete_option(ENABLE_VSX VSX ON)
104
105 macro(ocv_is_optimization_in_list resultvar check_opt)
106   set(__checked "")
107   set(__queue ${ARGN})
108   set(${resultvar} 0)
109   while(__queue AND NOT ${resultvar})
110     list(REMOVE_DUPLICATES __queue)
111     set(__queue_current ${__queue})
112     set(__queue "")
113     foreach(OPT ${__queue_current})
114       if("x${OPT}" STREQUAL "x${check_opt}")
115         set(${resultvar} 1)
116         break()
117       elseif(NOT ";${__checked};" MATCHES ";${OPT};")
118         list(APPEND __queue ${CPU_${OPT}_IMPLIES})
119       endif()
120       list(APPEND __checked ${OPT})
121     endforeach()
122   endwhile()
123 endmacro()
124
125 macro(ocv_is_optimization_in_force_list resultvar check_opt)
126   set(__checked "")
127   set(__queue ${ARGN})
128   set(${resultvar} 0)
129   while(__queue AND NOT ${resultvar})
130     list(REMOVE_DUPLICATES __queue)
131     set(__queue_current ${__queue})
132     set(__queue "")
133     foreach(OPT ${__queue_current})
134       if(OPT STREQUAL "${check_opt}")
135         set(${resultvar} 1)
136         break()
137       elseif(NOT ";${__checked};" MATCHES ";${OPT};")
138         list(APPEND __queue ${CPU_${OPT}_FORCE})
139       endif()
140       list(APPEND __checked ${OPT})
141     endforeach()
142   endwhile()
143 endmacro()
144
145 macro(ocv_append_optimization_flag var OPT)
146   if(CPU_${OPT}_FLAGS_CONFLICT)
147     string(REGEX REPLACE " ${CPU_${OPT}_FLAGS_CONFLICT}" "" ${var} " ${${var}} ")
148     string(REGEX REPLACE "^ +" "" ${var} "${${var}}")
149   endif()
150   set(${var} "${${var}} ${CPU_${OPT}_FLAGS_ON}")
151 endmacro()
152
153 # Support GCC -march=native or Intel Compiler -xHost flags
154 if(";${CPU_BASELINE};" MATCHES ";NATIVE;" OR ";${CPU_BASELINE};" MATCHES ";HOST;")
155   set(CPU_BASELINE_DETECT ON)
156   set(_add_native_flag ON)
157 elseif(";${CPU_BASELINE};" MATCHES ";DETECT;")
158   set(CPU_BASELINE_DETECT ON)
159 elseif(" ${CMAKE_CXX_FLAGS} " MATCHES " -march=native | -xHost | /QxHost ")
160   if(DEFINED CPU_BASELINE)
161     message(STATUS "CPU: Detected '-march=native' or '-xHost' compiler flag. Force CPU_BASELINE=DETECT.")
162   endif()
163   set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
164   set(CPU_BASELINE_DETECT ON)
165 endif()
166
167 if(X86 OR X86_64)
168   ocv_update(CPU_KNOWN_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;POPCNT;SSE4_2;FP16;FMA3;AVX;AVX2;AVX_512F;AVX512_COMMON;AVX512_KNL;AVX512_KNM;AVX512_SKX;AVX512_CNL;AVX512_CLX;AVX512_ICL")
169
170   ocv_update(CPU_AVX512_COMMON_GROUP "AVX_512F;AVX_512CD")
171   ocv_update(CPU_AVX512_KNL_GROUP "AVX512_COMMON;AVX512_KNL_EXTRA")
172   ocv_update(CPU_AVX512_KNM_GROUP "AVX512_KNL;AVX512_KNM_EXTRA;AVX_512VPOPCNTDQ")
173   ocv_update(CPU_AVX512_SKX_GROUP "AVX512_COMMON;AVX_512VL;AVX_512BW;AVX_512DQ")
174   ocv_update(CPU_AVX512_CNL_GROUP "AVX512_SKX;AVX_512IFMA;AVX_512VBMI")
175   ocv_update(CPU_AVX512_CLX_GROUP "AVX512_SKX;AVX_512VNNI")
176   ocv_update(CPU_AVX512_ICL_GROUP "AVX512_SKX;AVX_512IFMA;AVX_512VBMI;AVX_512VNNI;AVX_512VBMI2;AVX_512BITALG;AVX_512VPOPCNTDQ") # ? VPCLMULQDQ, GFNI, VAES
177
178   ocv_update(CPU_SSE_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse.cpp")
179   ocv_update(CPU_SSE2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse2.cpp")
180   ocv_update(CPU_SSE3_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse3.cpp")
181   ocv_update(CPU_SSSE3_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_ssse3.cpp")
182   ocv_update(CPU_SSE4_1_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse41.cpp")
183   ocv_update(CPU_SSE4_2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse42.cpp")
184   ocv_update(CPU_POPCNT_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_popcnt.cpp")
185   ocv_update(CPU_AVX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx.cpp")
186   ocv_update(CPU_AVX2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx2.cpp")
187   ocv_update(CPU_FP16_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_fp16.cpp")
188   ocv_update(CPU_AVX_512F_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512.cpp")
189   ocv_update(CPU_AVX512_COMMON_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512common.cpp")
190   ocv_update(CPU_AVX512_KNL_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512knl.cpp")
191   ocv_update(CPU_AVX512_KNM_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512knm.cpp")
192   ocv_update(CPU_AVX512_SKX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512skx.cpp")
193   ocv_update(CPU_AVX512_CNL_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512cnl.cpp")
194   ocv_update(CPU_AVX512_CLX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512clx.cpp")
195   ocv_update(CPU_AVX512_ICL_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512icl.cpp")
196
197   if(NOT OPENCV_CPU_OPT_IMPLIES_IGNORE)
198     ocv_update(CPU_AVX512_ICL_IMPLIES "AVX512_SKX")
199     ocv_update(CPU_AVX512_CLX_IMPLIES "AVX512_SKX")
200     ocv_update(CPU_AVX512_CNL_IMPLIES "AVX512_SKX")
201     ocv_update(CPU_AVX512_SKX_IMPLIES "AVX512_COMMON")
202     ocv_update(CPU_AVX512_KNM_IMPLIES "AVX512_KNL")
203     ocv_update(CPU_AVX512_KNL_IMPLIES "AVX512_COMMON")
204     ocv_update(CPU_AVX512_COMMON_IMPLIES "AVX_512F")
205     ocv_update(CPU_AVX_512F_IMPLIES "AVX2")
206     ocv_update(CPU_AVX_512F_FORCE "") # Don't force other optimizations
207     ocv_update(CPU_AVX2_IMPLIES "AVX;FMA3;FP16")
208     ocv_update(CPU_FMA3_IMPLIES "AVX2")
209     ocv_update(CPU_FMA3_FORCE "") # Don't force other optimizations
210     ocv_update(CPU_FP16_IMPLIES "AVX")
211     ocv_update(CPU_FP16_FORCE "") # Don't force other optimizations
212     ocv_update(CPU_AVX_IMPLIES "SSE4_2")
213     ocv_update(CPU_SSE4_2_IMPLIES "SSE4_1;POPCNT")
214     ocv_update(CPU_POPCNT_IMPLIES "SSE4_1")
215     ocv_update(CPU_POPCNT_FORCE "") # Don't force other optimizations
216     ocv_update(CPU_SSE4_1_IMPLIES "SSE3;SSSE3")
217     ocv_update(CPU_SSSE3_IMPLIES "SSE3")
218     ocv_update(CPU_SSE3_IMPLIES "SSE2")
219     ocv_update(CPU_SSE2_IMPLIES "SSE")
220   endif()
221
222   if(CV_ICC)
223     macro(ocv_intel_compiler_optimization_option name unix_flags msvc_flags)
224       ocv_update(CPU_${name}_FLAGS_NAME "${name}")
225       if(MSVC)
226         set(enable_flags "${msvc_flags}")
227         set(flags_conflict "/arch:[^ ]*|/Qx:[^ ]+")
228       else()
229         set(enable_flags "${unix_flags}")
230         set(flags_conflict "-msse[^ ]*|-mssse3|-mavx[^ ]*|-march[^ ]*|-x[^ ]+")
231       endif()
232       ocv_update(CPU_${name}_FLAGS_ON "${enable_flags}")
233       if(flags_conflict)
234         ocv_update(CPU_${name}_FLAGS_CONFLICT "${flags_conflict}")
235       endif()
236     endmacro()
237     ocv_intel_compiler_optimization_option(AVX2 "-march=core-avx2" "/arch:CORE-AVX2")
238     ocv_intel_compiler_optimization_option(FP16 "-mavx" "/arch:AVX")
239     ocv_intel_compiler_optimization_option(AVX "-mavx" "/arch:AVX")
240     ocv_intel_compiler_optimization_option(FMA3 "" "")
241     ocv_intel_compiler_optimization_option(POPCNT "" "")
242     ocv_intel_compiler_optimization_option(SSE4_2 "-msse4.2" "/arch:SSE4.2")
243     ocv_intel_compiler_optimization_option(SSE4_1 "-msse4.1" "/arch:SSE4.1")
244     ocv_intel_compiler_optimization_option(SSE3 "-msse3" "/arch:SSE3")
245     ocv_intel_compiler_optimization_option(SSSE3 "-mssse3" "/arch:SSSE3")
246     ocv_intel_compiler_optimization_option(SSE2 "-msse2" "/arch:SSE2")
247     if(NOT X86_64) # x64 compiler doesn't support /arch:sse
248       ocv_intel_compiler_optimization_option(SSE "-msse" "/arch:SSE")
249     endif()
250     ocv_intel_compiler_optimization_option(AVX_512F "-xCOMMON-AVX512" "/Qx:COMMON-AVX512")
251     ocv_intel_compiler_optimization_option(AVX512_COMMON "-xCOMMON-AVX512" "/Qx:COMMON-AVX512")
252     ocv_intel_compiler_optimization_option(AVX512_KNL "-xKNL" "/Qx:KNL")
253     ocv_intel_compiler_optimization_option(AVX512_KNM "-xKNM" "/Qx:KNM")
254     ocv_intel_compiler_optimization_option(AVX512_SKX "-xSKYLAKE-AVX512" "/Qx:SKYLAKE-AVX512")
255     ocv_intel_compiler_optimization_option(AVX512_CNL "-xCANNONLAKE" "/Qx:CANNONLAKE")
256     ocv_intel_compiler_optimization_option(AVX512_CLX "-xCASCADELAKE" "/Qx:CASCADELAKE")
257     ocv_intel_compiler_optimization_option(AVX512_ICL "-xICELAKE-CLIENT" "/Qx:ICELAKE-CLIENT")
258   elseif(CV_GCC OR CV_CLANG)
259     ocv_update(CPU_AVX2_FLAGS_ON "-mavx2")
260     ocv_update(CPU_FP16_FLAGS_ON "-mf16c")
261     ocv_update(CPU_AVX_FLAGS_ON "-mavx")
262     ocv_update(CPU_FMA3_FLAGS_ON "-mfma")
263     ocv_update(CPU_POPCNT_FLAGS_ON "-mpopcnt")
264     ocv_update(CPU_SSE4_2_FLAGS_ON "-msse4.2")
265     ocv_update(CPU_SSE4_1_FLAGS_ON "-msse4.1")
266     ocv_update(CPU_SSE3_FLAGS_ON "-msse3")
267     ocv_update(CPU_SSSE3_FLAGS_ON "-mssse3")
268     ocv_update(CPU_SSE2_FLAGS_ON "-msse2")
269     ocv_update(CPU_SSE_FLAGS_ON "-msse")
270     if(NOT (CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0"))  # GCC >= 5.0
271       ocv_update(CPU_AVX_512F_FLAGS_ON "-mavx512f")
272       ocv_update(CPU_AVX_512CD_FLAGS_ON "-mavx512cd")
273       ocv_update(CPU_AVX512_KNL_EXTRA_FLAGS_ON "-mavx512er -mavx512pf")
274       ocv_update(CPU_AVX512_KNM_EXTRA_FLAGS_ON "-mavx5124fmaps -mavx5124vnniw")
275       ocv_update(CPU_AVX_512BW_FLAGS_ON "-mavx512bw")
276       ocv_update(CPU_AVX_512DQ_FLAGS_ON "-mavx512dq")
277       ocv_update(CPU_AVX_512VL_FLAGS_ON "-mavx512vl")
278       ocv_update(CPU_AVX_512IFMA_FLAGS_ON "-mavx512ifma")
279       ocv_update(CPU_AVX_512VBMI_FLAGS_ON "-mavx512vbmi")
280       ocv_update(CPU_AVX_512VNNI_FLAGS_ON "-mavx512vnni")
281       ocv_update(CPU_AVX_512VBMI2_FLAGS_ON "-mavx512vbmi2")
282       ocv_update(CPU_AVX_512BITALG_FLAGS_ON "-mavx512bitalg")
283       ocv_update(CPU_AVX_512VPOPCNTDQ_FLAGS_ON "-mavx512vpopcntdq")
284     else()
285       ocv_update(CPU_AVX_512F_SUPPORTED OFF)
286     endif()
287   elseif(MSVC)
288     ocv_update(CPU_AVX2_FLAGS_ON "/arch:AVX2")
289     ocv_update(CPU_AVX_FLAGS_ON "/arch:AVX")
290     ocv_update(CPU_FP16_FLAGS_ON "/arch:AVX")
291     if(NOT X86_64)
292       # 64-bit MSVC compiler uses SSE/SSE2 by default
293       ocv_update(CPU_SSE_FLAGS_ON "/arch:SSE")
294       ocv_update(CPU_SSE_SUPPORTED ON)
295       ocv_update(CPU_SSE2_FLAGS_ON "/arch:SSE2")
296       ocv_update(CPU_SSE2_SUPPORTED ON)
297     else()
298       ocv_update(CPU_SSE_SUPPORTED ON)
299       ocv_update(CPU_SSE2_SUPPORTED ON)
300       ocv_update(CPU_AVX_512F_FLAGS_ON "/arch:AVX512")
301     endif()
302     # Other instruction sets are supported by default since MSVC 2008 at least
303   else()
304     message(WARNING "TODO: Unsupported compiler")
305   endif()
306
307   if(NOT DEFINED CPU_DISPATCH)
308     if(X86_64)
309       set(CPU_DISPATCH "SSE4_1;SSE4_2;AVX;FP16;AVX2;AVX512_SKX" CACHE STRING "${HELP_CPU_DISPATCH}")
310     else()
311       set(CPU_DISPATCH "SSE4_1;SSE4_2;AVX;FP16" CACHE STRING "${HELP_CPU_DISPATCH}")
312     endif()
313   endif()
314
315   if(NOT DEFINED CPU_BASELINE)
316     if(APPLE)
317       # MacOS X has limited set of possible supported H/W, so compiler is configured well
318       set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
319     elseif(X86_64)
320       set(CPU_BASELINE "SSE3" CACHE STRING "${HELP_CPU_BASELINE}")
321     else()
322       set(CPU_BASELINE "SSE2" CACHE STRING "${HELP_CPU_BASELINE}")
323     endif()
324   endif()
325
326 elseif(ARM OR AARCH64)
327   ocv_update(CPU_NEON_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_neon.cpp")
328   ocv_update(CPU_FP16_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_fp16.cpp")
329   if(NOT AARCH64)
330     ocv_update(CPU_KNOWN_OPTIMIZATIONS "VFPV3;NEON;FP16")
331     if(NOT MSVC)
332       ocv_update(CPU_VFPV3_FLAGS_ON "-mfpu=vfpv3")
333       ocv_update(CPU_NEON_FLAGS_ON "-mfpu=neon")
334       ocv_update(CPU_NEON_FLAGS_CONFLICT "-mfpu=[^ ]*")
335       ocv_update(CPU_FP16_FLAGS_ON "-mfpu=neon-fp16 -mfp16-format=ieee")
336       ocv_update(CPU_FP16_FLAGS_CONFLICT "-mfpu=[^ ]*")
337     endif()
338     ocv_update(CPU_FP16_IMPLIES "NEON")
339   else()
340     ocv_update(CPU_KNOWN_OPTIMIZATIONS "NEON;FP16")
341     ocv_update(CPU_NEON_FLAGS_ON "")
342     ocv_update(CPU_FP16_IMPLIES "NEON")
343     set(CPU_BASELINE "NEON;FP16" CACHE STRING "${HELP_CPU_BASELINE}")
344   endif()
345 elseif(MIPS)
346   ocv_update(CPU_MSA_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_msa.cpp")
347   ocv_update(CPU_KNOWN_OPTIMIZATIONS "MSA")
348   ocv_update(CPU_MSA_FLAGS_ON "-mmsa")
349   set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
350 elseif(PPC64LE)
351   ocv_update(CPU_KNOWN_OPTIMIZATIONS "VSX;VSX3")
352   ocv_update(CPU_VSX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_vsx.cpp")
353   ocv_update(CPU_VSX3_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_vsx3.cpp")
354
355   if(NOT OPENCV_CPU_OPT_IMPLIES_IGNORE)
356     ocv_update(CPU_VSX3_IMPLIES "VSX")
357   endif()
358
359   if(CV_CLANG AND (NOT ${CMAKE_CXX_COMPILER} MATCHES "xlc"))
360     ocv_update(CPU_VSX_FLAGS_ON "-mvsx -maltivec")
361     ocv_update(CPU_VSX3_FLAGS_ON "-mpower9-vector")
362   else()
363     ocv_update(CPU_VSX_FLAGS_ON "-mcpu=power8")
364     ocv_update(CPU_VSX3_FLAGS_ON "-mcpu=power9 -mtune=power9")
365   endif()
366
367   set(CPU_DISPATCH "VSX3" CACHE STRING "${HELP_CPU_DISPATCH}")
368   set(CPU_BASELINE "VSX" CACHE STRING "${HELP_CPU_BASELINE}")
369 endif()
370
371 # Helper values for cmake-gui
372 set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
373 set(CPU_DISPATCH "" CACHE STRING "${HELP_CPU_DISPATCH}")
374 set_property(CACHE CPU_BASELINE PROPERTY STRINGS "" ${CPU_KNOWN_OPTIMIZATIONS})
375 set_property(CACHE CPU_DISPATCH PROPERTY STRINGS "" ${CPU_KNOWN_OPTIMIZATIONS})
376
377 # Update CPU_BASELINE_DETECT flag
378 if(";${CPU_BASELINE};" MATCHES ";DETECT;")
379   set(CPU_BASELINE_DETECT ON)
380 endif()
381
382 set(CPU_BASELINE_FLAGS "")
383
384 set(CPU_BASELINE_FINAL "")
385 set(CPU_DISPATCH_FINAL "")
386
387 if(CV_DISABLE_OPTIMIZATION)
388   set(CPU_DISPATCH "")
389   set(CPU_DISPATCH_REQUIRE "")
390 endif()
391
392 if("x${CPU_DISPATCH}" STREQUAL "xALL")
393   set(CPU_DISPATCH "${CPU_KNOWN_OPTIMIZATIONS}")
394 endif()
395
396 macro(ocv_check_compiler_optimization OPT)
397   if(NOT DEFINED CPU_${OPT}_SUPPORTED)
398     if((DEFINED CPU_${OPT}_FLAGS_ON AND NOT "x${CPU_${OPT}_FLAGS_ON}" STREQUAL "x") OR CPU_${OPT}_TEST_FILE)
399       set(_varname "")
400       if(CPU_${OPT}_TEST_FILE)
401         set(__available 0)
402         if(CPU_BASELINE_DETECT)
403           set(_varname "HAVE_CPU_${OPT}_SUPPORT")
404           ocv_check_compiler_flag(CXX "${CPU_BASELINE_FLAGS}" "${_varname}" "${CPU_${OPT}_TEST_FILE}")
405           if(${_varname})
406             list(APPEND CPU_BASELINE_FINAL ${OPT})
407             set(CPU_${OPT}_ENABLED_DEFAULT ON)
408             set(__available 1)
409           endif()
410         endif()
411         if(NOT __available)
412           if(NOT "x${CPU_${OPT}_FLAGS_NAME}" STREQUAL "x")
413             set(_varname "HAVE_CPU_${CPU_${OPT}_FLAGS_NAME}")
414             set(_compile_flags "${CPU_BASELINE_FLAGS}")
415             ocv_append_optimization_flag(_compile_flags ${OPT})
416             ocv_check_compiler_flag(CXX "${_compile_flags}" "${_varname}" "${CPU_${OPT}_TEST_FILE}")
417           elseif(NOT "x${CPU_${OPT}_FLAGS_ON}" STREQUAL "x")
418             ocv_check_flag_support(CXX "${CPU_${OPT}_FLAGS_ON}" _varname "" "${CPU_${OPT}_TEST_FILE}")
419           else()
420             set(_varname "HAVE_CPU_${OPT}_SUPPORT")
421             set(_compile_flags "${CPU_BASELINE_FLAGS}")
422             ocv_append_optimization_flag(_compile_flags ${OPT})
423             ocv_check_compiler_flag(CXX "${_compile_flags}" "${_varname}" "${CPU_${OPT}_TEST_FILE}")
424           endif()
425         endif()
426       else()
427         ocv_check_flag_support(CXX "${CPU_${OPT}_FLAGS_ON}" _varname "")
428       endif()
429       if(_varname AND ${_varname})
430         set(CPU_${OPT}_SUPPORTED ON)
431       elseif(NOT CPU_${OPT}_SUPPORTED)
432         message(STATUS "${OPT} is not supported by C++ compiler")
433       endif()
434     else()
435       set(CPU_${OPT}_SUPPORTED ON)
436     endif()
437   endif()
438 endmacro()
439
440 foreach(OPT ${CPU_KNOWN_OPTIMIZATIONS})
441   set(CPU_${OPT}_USAGE_COUNT 0 CACHE INTERNAL "")
442   if("${CPU_${OPT}_FLAGS_ON}" STREQUAL "disabled")
443     set(CPU_${OPT}_SUPPORTED OFF)
444   elseif(DEFINED CPU_${OPT}_GROUP)
445     if(NOT DEFINED CPU_${OPT}_IMPLIES)
446       set(CPU_${OPT}_IMPLIES "${CPU_${OPT}_GROUP}")
447     endif()
448     set(__disabled 0)
449     set(__flags "")
450     foreach(OPT2 ${CPU_${OPT}_GROUP})
451       if("${CPU_${OPT2}_FLAGS_ON}" STREQUAL "disabled" OR (DEFINED CPU_${OPT2}_SUPPORTED AND NOT CPU_${OPT}_SUPPORTED))
452         set(__disabled 1)
453       endif()
454       set(__flags "${__flags} ${CPU_${OPT2}_FLAGS_ON}")
455       string(STRIP "${__flags}" __flags)
456     endforeach()
457     if(__disabled)
458       set(CPU_${OPT}_SUPPORTED OFF)
459     else()
460       if(NOT DEFINED CPU_${OPT}_FLAGS_ON)
461         set(CPU_${OPT}_FLAGS_ON "${__flags}")
462       endif()
463     endif()
464   endif()
465   if(NOT DEFINED CPU_${OPT}_FORCE)
466     set(CPU_${OPT}_FORCE "${CPU_${OPT}_IMPLIES}")
467   endif()
468   #message("${OPT}: CPU_${OPT}_FLAGS_ON=${CPU_${OPT}_FLAGS_ON}")
469 endforeach()
470
471 if(_add_native_flag)
472   set(_varname "HAVE_CPU_NATIVE_SUPPORT")
473   ocv_check_compiler_flag(CXX "-march=native" "${_varname}" "")
474   if(${_varname})
475     set(CPU_BASELINE_FLAGS "${CPU_BASELINE_FLAGS} -march=native")
476   else()
477     set(_varname "HAVE_CPU_HOST_SUPPORT")
478     if(MSVC)
479       set(_flag "/QxHost")
480     else()
481       set(_flag "-xHost")
482     endif()
483     ocv_check_compiler_flag(CXX "${_flag}" "${_varname}" "")
484     if(${_varname})
485       set(CPU_BASELINE_FLAGS "${CPU_BASELINE_FLAGS} ${_flag}")
486     endif()
487   endif()
488 endif()
489
490 foreach(OPT ${CPU_KNOWN_OPTIMIZATIONS})
491   set(__is_disabled 0)
492   foreach(OPT2 ${CPU_BASELINE_DISABLE})
493     ocv_is_optimization_in_list(__is_disabled ${OPT2} ${OPT})
494     if(__is_disabled)
495       break()
496     endif()
497   endforeach()
498   if(__is_disabled)
499     set(__is_from_baseline 0)
500   else()
501     if(CPU_${OPT}_SUPPORTED AND CPU_BASELINE_DETECT)
502       list(APPEND CPU_BASELINE_FINAL ${OPT})
503     endif()
504     ocv_is_optimization_in_list(__is_from_baseline ${OPT} ${CPU_BASELINE_REQUIRE})
505     if(NOT __is_from_baseline)
506       ocv_is_optimization_in_list(__is_from_baseline ${OPT} ${CPU_BASELINE})
507     endif()
508   endif()
509   ocv_is_optimization_in_list(__is_from_dispatch ${OPT} ${CPU_DISPATCH_REQUIRE})
510   if(NOT __is_from_dispatch)
511     ocv_is_optimization_in_list(__is_from_dispatch ${OPT} ${CPU_DISPATCH})
512   endif()
513   if(__is_from_dispatch OR __is_from_baseline OR CPU_BASELINE_DETECT)
514     ocv_check_compiler_optimization(${OPT})
515   endif()
516   if(CPU_BASELINE_DETECT AND NOT __is_from_baseline AND NOT __is_disabled)
517     ocv_is_optimization_in_list(__is_from_baseline ${OPT} ${CPU_BASELINE_FINAL})
518   endif()
519   if(CPU_${OPT}_SUPPORTED)
520     if(";${CPU_DISPATCH};" MATCHES ";${OPT};" AND NOT __is_from_baseline)
521       list(APPEND CPU_DISPATCH_FINAL ${OPT})
522     elseif(__is_from_baseline)
523       if(NOT ";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
524         list(APPEND CPU_BASELINE_FINAL ${OPT})
525       endif()
526       if(NOT CPU_${OPT}_ENABLED_DEFAULT)  # Don't change compiler flags in 'detection' mode
527         ocv_append_optimization_flag(CPU_BASELINE_FLAGS ${OPT})
528       endif()
529     endif()
530   endif()
531 endforeach()
532
533 foreach(OPT ${CPU_BASELINE_REQUIRE})
534   if(NOT ";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
535     message(SEND_ERROR "Required baseline optimization is not supported: ${OPT} (CPU_BASELINE_REQUIRE=${CPU_BASELINE_REQUIRE})")
536   endif()
537 endforeach()
538
539 foreach(OPT ${CPU_BASELINE})
540   if(OPT STREQUAL "DETECT" OR OPT STREQUAL "HOST" OR OPT STREQUAL "NATIVE")
541     # nothing
542   elseif(NOT ";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
543     message(STATUS "Optimization ${OPT} is not available, skipped")
544   endif()
545 endforeach()
546
547 foreach(OPT ${CPU_DISPATCH_REQUIRE})
548   if(";${CPU_DISPATCH_FINAL};" MATCHES ";${OPT};")
549     # OK
550   elseif(";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
551     message(SEND_ERROR "Dispatched optimization ${OPT} is in baseline list (CPU_DISPATCH_REQUIRE=${CPU_DISPATCH_REQUIRE})")
552   else()
553     message(SEND_ERROR "Required dispatch optimization is not supported: ${OPT} (CPU_DISPATCH_REQUIRE=${CPU_DISPATCH_REQUIRE})")
554   endif()
555 endforeach()
556
557 foreach(OPT ${CPU_DISPATCH})
558   if(";${CPU_DISPATCH_FINAL};" MATCHES ";${OPT};")
559     # OK
560   elseif(";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
561     # OK
562   else()
563     message(STATUS "Dispatch optimization ${OPT} is not available, skipped")
564   endif()
565 endforeach()
566
567 #message(STATUS "CPU_BASELINE_FINAL=${CPU_BASELINE_FINAL}")
568 #message(STATUS "CPU_DISPATCH_FINAL=${CPU_DISPATCH_FINAL}")
569
570 #if(CPU_DISPATCH_FINAL AND NOT PYTHON_DEFAULT_EXECUTABLE)
571 #  message(FATAL_ERROR "Python is required for CPU dispatched optimization support")
572 #endif()
573
574 macro(ocv_compiler_optimization_options)
575   set(__flags "${OPENCV_EXTRA_CXX_FLAGS} ${CPU_BASELINE_FLAGS}")
576   if(NOT __flags STREQUAL CACHED_CPU_BASELINE_FLAGS)
577     set(CACHED_CPU_BASELINE_FLAGS "${__flags}" CACHE INTERNAL "" FORCE)
578     ocv_clear_vars(HAVE_CPU_BASELINE_FLAGS)
579   endif()
580   ocv_check_compiler_flag(CXX "${__flags}" HAVE_CPU_BASELINE_FLAGS)
581   if(NOT HAVE_CPU_BASELINE_FLAGS)
582     message(FATAL_ERROR "Compiler doesn't support baseline optimization flags: ${CPU_BASELINE_FLAGS}")
583   endif()
584   add_extra_compiler_option_force("${CPU_BASELINE_FLAGS}")
585
586   foreach(OPT ${CPU_DISPATCH_FINAL})
587     set(__dispatch_flags "")
588     set(__dispatch_definitions "")
589     set(__dispatch_opts "")
590     set(__dispatch_opts_force "")
591     foreach(OPT2 ${CPU_KNOWN_OPTIMIZATIONS})
592       if(NOT CPU_${OPT2}_SUPPORTED)
593         #continue()
594       else()
595       ocv_is_optimization_in_list(__is_from_baseline ${OPT2} ${CPU_BASELINE_FINAL})
596       if(NOT __is_from_baseline)
597         ocv_is_optimization_in_list(__is_active ${OPT2} ${OPT})
598         if(__is_active)
599           ocv_append_optimization_flag(__dispatch_flags ${OPT2})
600           list(APPEND __dispatch_definitions "CV_CPU_COMPILE_${OPT2}=1")
601           list(APPEND __dispatch_opts "${OPT2}")
602         endif()
603         ocv_is_optimization_in_force_list(__is_force ${OPT2} ${OPT})
604         if(__is_force)
605           list(APPEND __dispatch_opts_force "${OPT2}")
606         endif()
607       endif()
608       endif()
609     endforeach()
610     set(__flags "${OPENCV_EXTRA_CXX_FLAGS} ${__dispatch_flags}")
611     if(NOT __flags STREQUAL CACHED_CPU_DISPATCH_${OPT}_FLAGS)
612       set(CACHED_CPU_DISPATCH_${OPT}_FLAGS "${__flags}" CACHE INTERNAL "" FORCE)
613       ocv_clear_vars(HAVE_CPU_DISPATCH_FLAGS_${OPT})
614     endif()
615     ocv_check_compiler_flag(CXX "${__flags}" HAVE_CPU_DISPATCH_FLAGS_${OPT})
616     if(NOT HAVE_CPU_DISPATCH_FLAGS_${OPT})
617       message(FATAL_ERROR "Compiler doesn't support optimization flags for ${OPT} dispatch mode: ${__dispatch_flags}")
618     endif()
619     set(CPU_DISPATCH_FLAGS_${OPT} "${__dispatch_flags}")
620     set(CPU_DISPATCH_DEFINITIONS_${OPT} "${__dispatch_definitions}")
621     set(CPU_DISPATCH_${OPT}_INCLUDED "${__dispatch_opts}")
622     set(CPU_DISPATCH_${OPT}_FORCED "${__dispatch_opts_force}")
623   endforeach()
624
625   if(ENABLE_POWERPC)
626     add_extra_compiler_option("-mcpu=G3 -mtune=G5")
627   endif()
628 endmacro()
629
630 macro(ocv_compiler_optimization_options_finalize)
631   if((CV_GCC OR CV_CLANG) AND (X86 OR X86_64))
632     if(NOT APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 4)
633       if(OPENCV_EXTRA_CXX_FLAGS MATCHES "-m(sse2|avx)")
634         add_extra_compiler_option(-mfpmath=sse) # !! important - be on the same wave with x64 compilers
635       else()
636         add_extra_compiler_option(-mfpmath=387)
637       endif()
638     endif()
639   endif()
640
641   if(MSVC)
642     # Generate Intrinsic Functions
643     set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /Oi")
644   endif(MSVC)
645 endmacro()
646
647 macro(ocv_compiler_optimization_process_sources SOURCES_VAR_NAME LIBS_VAR_NAME TARGET_BASE_NAME)
648   set(__result "")
649   set(__result_libs "")
650   foreach(OPT ${CPU_DISPATCH_FINAL})
651     set(__result_${OPT} "")
652   endforeach()
653   foreach(fname ${${SOURCES_VAR_NAME}})
654     string(TOLOWER "${fname}" fname_LOWER)
655     get_filename_component(fname_LOWER "${fname_LOWER}" NAME)
656     if(fname_LOWER MATCHES ".+\\.([^\\.]*)\\.cpp$")
657       string(TOUPPER "${CMAKE_MATCH_1}" OPT_)
658       if(OPT_ MATCHES "(CUDA.*|DISPATCH.*|OCL)") # don't touch files like filename.cuda.cpp
659         list(APPEND __result "${fname}")
660         #continue()
661       elseif(CV_DISABLE_OPTIMIZATION OR NOT CV_ENABLE_INTRINSICS)
662         ocv_get_smart_file_name(fname_ "${fname}")
663         message(STATUS "Excluding from source files list (optimization is disabled): ${fname_}")
664         #continue()
665       else()
666         get_source_file_property(__definitions "${fname}" COMPILE_DEFINITIONS)
667         if(__definitions)
668           list(APPEND __definitions "CV_CPU_DISPATCH_MODE=${OPT_}")
669         else()
670           set(__definitions "CV_CPU_DISPATCH_MODE=${OPT_}")
671         endif()
672         set_source_files_properties("${fname}" PROPERTIES COMPILE_DEFINITIONS "${__definitions}")
673
674         set(__opt_found 0)
675         foreach(OPT ${CPU_BASELINE_FINAL})
676           string(TOLOWER "${OPT}" OPT_LOWER)
677           if(fname_LOWER MATCHES "\\.${OPT_LOWER}\\.cpp$")
678 #message("${fname} BASELINE-${OPT}")
679             set(__opt_found 1)
680             list(APPEND __result "${fname}")
681             break()
682           endif()
683         endforeach()
684         foreach(OPT ${CPU_DISPATCH_FINAL})
685           foreach(OPT2 ${CPU_DISPATCH_${OPT}_FORCED})
686             string(TOLOWER "${OPT2}" OPT2_LOWER)
687             if(fname_LOWER MATCHES "\\.${OPT2_LOWER}\\.cpp$")
688               list(APPEND __result_${OPT} "${fname}")
689               math(EXPR CPU_${OPT}_USAGE_COUNT "${CPU_${OPT}_USAGE_COUNT}+1")
690               set(CPU_${OPT}_USAGE_COUNT "${CPU_${OPT}_USAGE_COUNT}" CACHE INTERNAL "" FORCE)
691 #message("(${CPU_${OPT}_USAGE_COUNT})${fname} ${OPT}")
692 #message("    ${CPU_DISPATCH_${OPT}_INCLUDED}")
693 #message("    ${CPU_DISPATCH_DEFINITIONS_${OPT}}")
694 #message("    ${CPU_DISPATCH_FLAGS_${OPT}}")
695               set(__opt_found 1)
696               break()
697             endif()
698           endforeach()
699           if(__opt_found)
700             set(__opt_found 1)
701             break()
702           endif()
703         endforeach()
704         if(NOT __opt_found)
705           ocv_get_smart_file_name(fname_ "${fname}")
706           message(STATUS "Excluding from source files list: ${fname_}")
707         endif()
708       endif()
709     else()
710       list(APPEND __result "${fname}")
711     endif()
712   endforeach()
713
714   foreach(OPT ${CPU_DISPATCH_FINAL})
715     if(__result_${OPT})
716 #message("${OPT}: ${__result_${OPT}}")
717       if(CMAKE_GENERATOR MATCHES "^Visual"
718           OR OPENCV_CMAKE_CPU_OPTIMIZATIONS_FORCE_TARGETS
719       )
720         # MSVS generator is not able to properly order compilation flags:
721         # extra flags are added before common flags, so switching between optimizations doesn't work correctly
722         # Also CMAKE_CXX_FLAGS doesn't work (it is directory-based, so add_subdirectory is required)
723         add_library(${TARGET_BASE_NAME}_${OPT} OBJECT ${__result_${OPT}})
724         ocv_append_dependant_targets(${TARGET_BASE_NAME} ${TARGET_BASE_NAME}_${OPT})
725         set_target_properties(${TARGET_BASE_NAME}_${OPT} PROPERTIES COMPILE_DEFINITIONS "${CPU_DISPATCH_DEFINITIONS_${OPT}}")
726         set_target_properties(${TARGET_BASE_NAME}_${OPT} PROPERTIES COMPILE_FLAGS "${CPU_DISPATCH_FLAGS_${OPT}}")
727         target_include_directories(${TARGET_BASE_NAME}_${OPT} PRIVATE $<TARGET_PROPERTY:${TARGET_BASE_NAME},INCLUDE_DIRECTORIES>)
728         #list(APPEND __result_libs ${TARGET_BASE_NAME}_${OPT})
729         list(APPEND __result "$<TARGET_OBJECTS:${TARGET_BASE_NAME}_${OPT}>")
730         if(ENABLE_SOLUTION_FOLDERS)
731           set_target_properties(${TARGET_BASE_NAME}_${OPT} PROPERTIES FOLDER "dispatched")
732         endif()
733       else()
734         foreach(fname ${__result_${OPT}})
735           get_source_file_property(__definitions "${fname}" COMPILE_DEFINITIONS)
736           if(__definitions)
737             list(APPEND __definitions "${CPU_DISPATCH_DEFINITIONS_${OPT}}")
738           else()
739             set(__definitions "${CPU_DISPATCH_DEFINITIONS_${OPT}}")
740           endif()
741           set_source_files_properties("${fname}" PROPERTIES COMPILE_DEFINITIONS "${__definitions}")
742           set_source_files_properties("${fname}" PROPERTIES COMPILE_FLAGS "${CPU_DISPATCH_FLAGS_${OPT}}")
743         endforeach()
744         list(APPEND __result ${__result_${OPT}})
745       endif()
746     endif()
747   endforeach()
748   set(${SOURCES_VAR_NAME} "${__result}")
749   list(APPEND ${LIBS_VAR_NAME} ${__result_libs})
750 endmacro()
751
752 macro(ocv_compiler_optimization_fill_cpu_config)
753   set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "")
754   foreach(OPT ${CPU_BASELINE_FINAL})
755     set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}
756 #define CV_CPU_COMPILE_${OPT} 1
757 #define CV_CPU_BASELINE_COMPILE_${OPT} 1
758 ")
759   endforeach()
760
761   set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}
762 #define CV_CPU_BASELINE_FEATURES 0 \\")
763   foreach(OPT ${CPU_BASELINE_FINAL})
764     if(NOT DEFINED CPU_${OPT}_FEATURE_ALIAS OR NOT "x${CPU_${OPT}_FEATURE_ALIAS}" STREQUAL "x")
765       set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}
766     , CV_CPU_${OPT} \\")
767     endif()
768   endforeach()
769   set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}\n")
770
771   set(__dispatch_modes "")
772   foreach(OPT ${CPU_DISPATCH_FINAL})
773     list(APPEND __dispatch_modes ${CPU_DISPATCH_${OPT}_FORCE} ${OPT})
774   endforeach()
775   list(REMOVE_DUPLICATES __dispatch_modes)
776   foreach(OPT ${__dispatch_modes})
777     set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}
778 #define CV_CPU_DISPATCH_COMPILE_${OPT} 1")
779   endforeach()
780
781   set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}
782 \n\n#define CV_CPU_DISPATCH_FEATURES 0 \\")
783   foreach(OPT ${__dispatch_modes})
784     if(NOT DEFINED CPU_${OPT}_FEATURE_ALIAS OR NOT "x${CPU_${OPT}_FEATURE_ALIAS}" STREQUAL "x")
785       set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}
786     , CV_CPU_${OPT} \\")
787     endif()
788   endforeach()
789   set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}\n")
790
791   set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "// AUTOGENERATED, DO NOT EDIT\n")
792   foreach(OPT ${CPU_ALL_OPTIMIZATIONS})
793     if(NOT DEFINED CPU_${OPT}_FEATURE_ALIAS OR NOT "x${CPU_${OPT}_FEATURE_ALIAS}" STREQUAL "x")
794       set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE}
795 #if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_${OPT}
796 #  define CV_TRY_${OPT} 1
797 #  define CV_CPU_FORCE_${OPT} 1
798 #  define CV_CPU_HAS_SUPPORT_${OPT} 1
799 #  define CV_CPU_CALL_${OPT}(fn, args) return (cpu_baseline::fn args)
800 #  define CV_CPU_CALL_${OPT}_(fn, args) return (opt_${OPT}::fn args)
801 #elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_${OPT}
802 #  define CV_TRY_${OPT} 1
803 #  define CV_CPU_FORCE_${OPT} 0
804 #  define CV_CPU_HAS_SUPPORT_${OPT} (cv::checkHardwareSupport(CV_CPU_${OPT}))
805 #  define CV_CPU_CALL_${OPT}(fn, args) if (CV_CPU_HAS_SUPPORT_${OPT}) return (opt_${OPT}::fn args)
806 #  define CV_CPU_CALL_${OPT}_(fn, args) if (CV_CPU_HAS_SUPPORT_${OPT}) return (opt_${OPT}::fn args)
807 #else
808 #  define CV_TRY_${OPT} 0
809 #  define CV_CPU_FORCE_${OPT} 0
810 #  define CV_CPU_HAS_SUPPORT_${OPT} 0
811 #  define CV_CPU_CALL_${OPT}(fn, args)
812 #  define CV_CPU_CALL_${OPT}_(fn, args)
813 #endif
814 #define __CV_CPU_DISPATCH_CHAIN_${OPT}(fn, args, mode, ...)  CV_CPU_CALL_${OPT}(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
815 ")
816     endif()
817   endforeach()
818
819   set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE}
820 #define CV_CPU_CALL_BASELINE(fn, args) return (cpu_baseline::fn args)
821 #define __CV_CPU_DISPATCH_CHAIN_BASELINE(fn, args, mode, ...)  CV_CPU_CALL_BASELINE(fn, args) /* last in sequence */
822 ")
823
824
825   set(__file "${OpenCV_SOURCE_DIR}/modules/core/include/opencv2/core/cv_cpu_helper.h")
826   if(EXISTS "${__file}")
827     file(READ "${__file}" __content)
828   endif()
829   if(__content STREQUAL OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE)
830     #message(STATUS "${__file} contains same content")
831   else()
832     file(WRITE "${__file}" "${OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE}")
833     message(WARNING "${__file} is updated")
834   endif()
835 endmacro()
836
837 macro(__ocv_add_dispatched_file filename target_src_var src_directory dst_directory precomp_hpp optimizations_var)
838   if(NOT OPENCV_INITIAL_PASS)
839     set(__codestr "
840 #include \"${src_directory}/${precomp_hpp}\"
841 #include \"${src_directory}/${filename}.simd.hpp\"
842 ")
843
844     set(__declarations_str "#define CV_CPU_SIMD_FILENAME \"${src_directory}/${filename}.simd.hpp\"")
845     set(__dispatch_modes "BASELINE")
846
847     set(__optimizations "${${optimizations_var}}")
848     if(CV_DISABLE_OPTIMIZATION OR NOT CV_ENABLE_INTRINSICS)
849       set(__optimizations "")
850     endif()
851
852     foreach(OPT ${__optimizations})
853       string(TOLOWER "${OPT}" OPT_LOWER)
854       set(__file "${CMAKE_CURRENT_BINARY_DIR}/${dst_directory}${filename}.${OPT_LOWER}.cpp")
855       if(EXISTS "${__file}")
856         file(READ "${__file}" __content)
857       else()
858         set(__content "")
859       endif()
860       if(__content STREQUAL __codestr)
861         #message(STATUS "${__file} contains up-to-date content")
862       else()
863         file(WRITE "${__file}" "${__codestr}")
864       endif()
865
866       if(";${CPU_DISPATCH_FINAL};" MATCHES "${OPT}" OR __CPU_DISPATCH_INCLUDE_ALL)
867         if(EXISTS "${src_directory}/${filename}.${OPT_LOWER}.cpp")
868           message(STATUS "Using overridden ${OPT} source: ${src_directory}/${filename}.${OPT_LOWER}.cpp")
869         else()
870           list(APPEND ${target_src_var} "${__file}")
871         endif()
872
873         set(__declarations_str "${__declarations_str}
874 #define CV_CPU_DISPATCH_MODE ${OPT}
875 #include \"opencv2/core/private/cv_cpu_include_simd_declarations.hpp\"
876 ")
877         set(__dispatch_modes "${OPT}, ${__dispatch_modes}")
878       endif()
879     endforeach()
880
881     set(__declarations_str "${__declarations_str}
882 #define CV_CPU_DISPATCH_MODES_ALL ${__dispatch_modes}
883
884 #undef CV_CPU_SIMD_FILENAME
885 ")
886
887     set(__file "${CMAKE_CURRENT_BINARY_DIR}/${dst_directory}${filename}.simd_declarations.hpp")
888     if(EXISTS "${__file}")
889       file(READ "${__file}" __content)
890     endif()
891     if(__content STREQUAL __declarations_str)
892       #message(STATUS "${__file} contains up-to-date content")
893     else()
894       file(WRITE "${__file}" "${__declarations_str}")
895     endif()
896   endif()
897 endmacro()
898
899 macro(ocv_add_dispatched_file filename)
900   set(__optimizations "${ARGN}")
901   if(" ${ARGV1}" STREQUAL " TEST")
902     list(REMOVE_AT __optimizations 0)
903     __ocv_add_dispatched_file("${filename}" "OPENCV_MODULE_${the_module}_TEST_SOURCES_DISPATCHED" "${CMAKE_CURRENT_LIST_DIR}/test" "test/" "test_precomp.hpp" __optimizations)
904   else()
905     __ocv_add_dispatched_file("${filename}" "OPENCV_MODULE_${the_module}_SOURCES_DISPATCHED" "${CMAKE_CURRENT_LIST_DIR}/src" "" "precomp.hpp" __optimizations)
906   endif()
907 endmacro()
908
909
910 # Workaround to support code which always require all code paths
911 macro(ocv_add_dispatched_file_force_all)
912   set(__CPU_DISPATCH_INCLUDE_ALL 1)
913   ocv_add_dispatched_file(${ARGN})
914   unset(__CPU_DISPATCH_INCLUDE_ALL)
915 endmacro()
916
917
918 if(CV_DISABLE_OPTIMIZATION OR CV_ICC)
919   ocv_update(CV_ENABLE_UNROLLED 0)
920 else()
921   ocv_update(CV_ENABLE_UNROLLED 1)
922 endif()