1# 2# Copyright (C) Mellanox Technologies Ltd. 2001-2014. ALL RIGHTS RESERVED. 3# Copyright (c) UT-Battelle, LLC. 2017. ALL RIGHTS RESERVED. 4# Copyright (C) ARM Ltd. 2016-2020. ALL RIGHTS RESERVED. 5# See file LICENSE for terms. 6# 7 8 9# 10# Initialize CFLAGS 11# 12BASE_CFLAGS="-g -Wall -Werror" 13 14 15# 16# Check that C++ is functional. 17# 18# AC_PROG_CXX never fails but falls back on g++ as a default CXX compiler that 19# always present. If g++ isn't installed, the macro doesn't detect this and 20# compilation fails later on. CHECK_CXX_COMP compiles simple C++ code to 21# verify that compiler is present and functional. 22# 23AC_DEFUN([CHECK_CXX_COMP], 24 [AC_MSG_CHECKING(if $CXX works) 25 AC_LANG_PUSH([C++]) 26 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 27 #ifndef __cplusplus 28 #error "No C++ support, AC_PROG_CXX failed" 29 #endif 30 ]])], 31 [AC_MSG_RESULT([yes])], 32 [AC_MSG_ERROR([Cannot continue. Please install C++ compiler.])]) 33 AC_LANG_POP([C++]) 34 ]) 35 36 37# 38# Debug mode 39# 40AC_ARG_ENABLE(debug, 41 AC_HELP_STRING([--enable-debug], [Enable debug mode build]), 42 [], 43 [enable_debug=no]) 44AS_IF([test "x$enable_debug" = xyes], 45 [BASE_CFLAGS="-D_DEBUG $BASE_CFLAGS" 46 BASE_CXXFLAGS="-D_DEBUG" $BASE_CXXFLAGS], 47 []) 48 49 50# 51# Optimization level 52# 53AC_ARG_ENABLE(compiler-opt, 54 AC_HELP_STRING([--enable-compiler-opt], [Set optimization level [0-3]]), 55 [], 56 [enable_compiler_opt="none"]) 57AS_IF([test "x$enable_compiler_opt" = "xyes"], [BASE_CFLAGS="-O3 $BASE_CFLAGS"], 58 [test "x$enable_compiler_opt" = "xnone"], 59 [AS_IF([test "x$enable_debug" = xyes], 60 [BASE_CFLAGS="-O0 $BASE_CFLAGS" 61 BASE_CXXFLAGS="-O0 $BASE_CXXFLAGS"], 62 [BASE_CFLAGS="-O3 $BASE_CFLAGS" 63 BASE_CXXFLAGS="-O0 $BASE_CXXFLAGS"])], 64 [test "x$enable_compiler_opt" = "xno"], [], 65 [BASE_CFLAGS="-O$enable_compiler_opt $BASE_CFLAGS"]) 66 67 68# 69# CHECK_CROSS_COMP (program, true-action, false-action) 70# 71# The macro checks if it can run the program; it executes 72# true action if the program can be executed, otherwise 73# false action is executed. 74# For cross-platform compilation we only check 75# if we can compile and link the program. 76AC_DEFUN([CHECK_CROSS_COMP], [ 77 AC_RUN_IFELSE([$1], [$2], [$3], 78 [AC_LINK_IFELSE([$1], [$2], [$3])]) 79]) 80 81 82# 83# Check for one specific attribute by compiling with C 84# Usage: CHECK_SPECIFIC_ATTRIBUTE([name], [doc], [program]) 85# 86AC_DEFUN([CHECK_SPECIFIC_ATTRIBUTE], [ 87 AC_CACHE_VAL(ucx_cv_attribute_[$1], [ 88 SAVE_CFLAGS="$CFLAGS" 89 CFLAGS="$BASE_CFLAGS $CFLAGS" 90 # 91 # Try to compile using the C compiler 92 # 93 AC_TRY_COMPILE([$3],[], 94 [ucx_cv_attribute_[$1]=1], 95 [ucx_cv_attribute_[$1]=0]) 96 CFLAGS="$SAVE_CFLAGS" 97 ]) 98 AC_MSG_CHECKING([for __attribute__([$1])]) 99 AC_MSG_RESULT([$ucx_cv_attribute_[$1]]) 100 AC_DEFINE_UNQUOTED([HAVE_ATTRIBUTE_[$2]], [$ucx_cv_attribute_[$1]], [Check attribute [$1]]) 101]) 102 103 104# 105# Enable/disable turning on machine-specific optimizations 106# 107AC_ARG_ENABLE(optimizations, 108 AC_HELP_STRING([--enable-optimizations], 109 [Enable non-portable machine-specific CPU optimizations, default: NO]), 110 [], 111 [enable_optimizations=no]) 112 113 114# 115# Check if compiler supports a given CPU optimization flag, and if yes - add it 116# to BASE_CFLAGS substitution, and OPT_CFLAGS C define. 117# 118# Usage: COMPILER_CPU_OPTIMIZATION([name], [doc], [flag], [program]) 119# 120AC_DEFUN([COMPILER_CPU_OPTIMIZATION], 121[ 122 AC_ARG_WITH([$1], 123 [AC_HELP_STRING([--with-$1], [Use $2 compiler option.])], 124 [], 125 [with_$1=$enable_optimizations]) 126 127 AS_IF([test "x$with_$1" != "xno"], 128 [SAVE_CFLAGS="$CFLAGS" 129 CFLAGS="$BASE_CFLAGS $CFLAGS $3" 130 AC_MSG_CHECKING([$3]) 131 CHECK_CROSS_COMP([AC_LANG_SOURCE([$4])], 132 [AC_MSG_RESULT([yes]) 133 # TODO: Add CPU UARCH detector and validator in UCX init. 134 # As for now we will avoid passing this information to 135 # library. 136 BASE_CFLAGS="$BASE_CFLAGS $3" 137 AS_IF([test "x$1" != "xmcpu" -a "x$1" != "xmarch"], 138 [OPT_CFLAGS="$OPT_CFLAGS|$1"])], 139 [AC_MSG_RESULT([no])]) 140 CFLAGS="$SAVE_CFLAGS"]) 141]) 142 143 144# 145# Check platform uarch and apply micro-architecture specific optimizations 146# 147AC_DEFUN([DETECT_UARCH], 148[ 149 cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` 150 cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` 151 cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` 152 cpupart=`grep 'CPU part' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1` 153 154 ax_cpu="" 155 ax_arch="" 156 157 AC_MSG_NOTICE(Detected CPU implementation: ${cpuimpl}) 158 AC_MSG_NOTICE(Detected CPU architecture: ${cpuarch}) 159 AC_MSG_NOTICE(Detected CPU variant: ${cpuvar}) 160 AC_MSG_NOTICE(Detected CPU part: ${cpupart}) 161 162 case $cpuimpl in 163 0x42) case $cpupart in 164 0x516 | 0x0516) 165 AC_DEFINE([HAVE_AARCH64_THUNDERX2], 1, [Cavium ThunderX2]) 166 ax_cpu="thunderx2t99" 167 ax_arch="armv8.1-a+lse" ;; 168 0xaf | 0x0af) 169 AC_DEFINE([HAVE_AARCH64_THUNDERX2], 1, [Cavium ThunderX2]) 170 ax_cpu="thunderx2t99" 171 ax_arch="armv8.1-a+lse" ;; 172 esac 173 ;; 174 0x43) case $cpupart in 175 0x516 | 0x0516) 176 AC_DEFINE([HAVE_AARCH64_THUNDERX2], 1, [Cavium ThunderX2]) 177 ax_cpu="thunderx2t99" 178 ax_arch="armv8.1-a+lse" ;; 179 0xaf | 0x0af) 180 AC_DEFINE([HAVE_AARCH64_THUNDERX2], 1, [Cavium ThunderX2]) 181 ax_cpu="thunderx2t99" 182 ax_arch="armv8.1-a+lse" ;; 183 0xa1 | 0x0a1) 184 AC_DEFINE([HAVE_AARCH64_THUNDERX1], 1, [Cavium ThunderX1]) 185 ax_cpu="thunderxt88" ;; 186 esac 187 ;; 188 0x48) case $cpupart in 189 0xd01 | 0x0d01) 190 AC_DEFINE([HAVE_AARCH64_HI1620], 1, [Huawei Kunpeng 920]) 191 ax_cpu="tsv110" 192 ax_arch="armv8.2-a" ;; 193 esac 194 ;; 195 *) 196 ;; 197 esac 198 AM_CONDITIONAL([HAVE_AARCH64_THUNDERX2], [test x$ax_cpu = xthunderx2t99]) 199 AM_CONDITIONAL([HAVE_AARCH64_THUNDERX1], [test x$ax_cpu = xthunderxt88]) 200 AM_CONDITIONAL([HAVE_AARCH64_HI1620], [test x$ax_cpu = xtsv110]) 201]) 202 203 204# 205# CHECK_COMPILER_FLAG 206# Usage: CHECK_COMPILER_FLAG([name], [flag], [program], [if-true], [if-false]) 207# 208# The macro checks if program may be compiled using specified flag 209# 210AC_DEFUN([CHECK_COMPILER_FLAG], 211[ 212 AC_MSG_CHECKING([compiler flag $1]) 213 SAVE_CFLAGS="$CFLAGS" 214 SAVE_CXXFLAGS="$CFLAGS" 215 CFLAGS="$BASE_CFLAGS $CFLAGS $2" 216 CXXFLAGS="$BASE_CXXFLAGS $CXXFLAGS $2" 217 AC_COMPILE_IFELSE([$3], 218 [AC_MSG_RESULT([yes]) 219 CFLAGS="$SAVE_CFLAGS" 220 CXXFLAGS="$SAVE_CXXFLAGS" 221 $4], 222 [AC_MSG_RESULT([no]) 223 CFLAGS="$SAVE_CFLAGS" 224 CXXFLAGS="$SAVE_CXXFLAGS" 225 $5]) 226]) 227 228 229# 230# ADD_COMPILER_FLAG_IF_SUPPORTED 231# Usage: ADD_COMPILER_FLAG_IF_SUPPORTED([name], [flag], [program], [if-true], [if-false]) 232# 233# The macro checks if program may be compiled using specified flag and adds 234# this flag if it is supported 235# 236AC_DEFUN([ADD_COMPILER_FLAG_IF_SUPPORTED], 237[ 238 CHECK_COMPILER_FLAG([$1], [$2], [$3], 239 [BASE_CFLAGS="$BASE_CFLAGS $2" 240 $4], 241 [$5]) 242]) 243 244 245# 246# ADD_COMPILER_FLAGS_IF_SUPPORTED 247# Usage: ADD_COMPILER_FLAGS_IF_SUPPORTED([[flag1], [flag2], [flag3]], [program]) 248# 249# The macro checks multiple flags supported by compiler 250# 251AC_DEFUN([ADD_COMPILER_FLAGS_IF_SUPPORTED], 252[ 253 m4_foreach([_flag], [$1], 254 [ADD_COMPILER_FLAG_IF_SUPPORTED([_flag], [_flag], [$2], [], [])]) 255]) 256 257 258# 259# CHECK_DEPRECATED_DECL_FLAG (flag, variable) 260# 261# The macro checks if the given compiler flag enables usig deprecated declarations. 262# If yes, it appends the flags to "variable". 263# 264AC_DEFUN([CHECK_DEPRECATED_DECL_FLAG], 265[ 266 AC_MSG_CHECKING([whether $1 overrides deprecated declarations]) 267 SAVE_CFLAGS="$CFLAGS" 268 CFLAGS="$BASE_CFLAGS $CFLAGS $1" 269 AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ 270 int __attribute__ ((__deprecated__)) f() { return 0; } 271 int main(int argc, char** argv) { return f(); } 272 ]])], 273 [AC_MSG_RESULT([yes]) 274 $2="${$2} $1"], 275 [AC_MSG_RESULT([no])]) 276 CFLAGS="$SAVE_CFLAGS" 277]) 278 279 280# 281# Force ICC treat command line warnings as errors. 282# This evaluation should be called prior to all other compiler flags evals 283# 284CHECK_COMPILER_FLAG([-diag-error 10006], [-diag-error 10006], 285 [AC_LANG_SOURCE([[int main(int argc, char** argv){return 0;}]])], 286 [BASE_CFLAGS="$BASE_CFLAGS -diag-error 10006" 287 BASE_CXXFLAGS="$BASE_CXXFLAGS -diag-error 10006"], 288 []) 289 290 291CHECK_DEPRECATED_DECL_FLAG([-diag-disable 1478], CFLAGS_NO_DEPRECATED) # icc 292CHECK_DEPRECATED_DECL_FLAG([-Wno-deprecated-declarations], CFLAGS_NO_DEPRECATED) # gcc 293AC_SUBST([CFLAGS_NO_DEPRECATED], [$CFLAGS_NO_DEPRECATED]) 294 295 296# 297# Disable format-string warning on ICC 298# 299ADD_COMPILER_FLAG_IF_SUPPORTED([-diag-disable 269], 300 [-diag-disable 269], 301 [AC_LANG_SOURCE([[#include <stdlib.h> 302 #include <stdio.h> 303 int main(int argc, char** argv) { 304 char *p = NULL; 305 scanf("%m[^.]", &p); 306 free(p); 307 return 0; 308 }]])], 309 [], 310 []) 311 312 313# 314# Set default datatype alignment to 16 bytes. 315# Some compilers (LLVM based, clang) expects allocation of datatypes by 32 bytes 316# to optimize operations memset/memcpy/etc using vectorized processor instructions 317# which requires aligment of memory buffer by 32 or higer bytes. Default malloc method 318# guarantee alignment for 16 bytes only. Force using compiler 16-bytes alignment 319# by default if option is supported. 320# 321UCX_ALLOC_ALIGN=16 322ADD_COMPILER_FLAG_IF_SUPPORTED([-fmax-type-align=$UCX_ALLOC_ALIGN], 323 [-fmax-type-align=$UCX_ALLOC_ALIGN], 324 [AC_LANG_SOURCE([[int main(int argc, char** argv){return 0;}]])], 325 [AC_DEFINE_UNQUOTED([UCX_ALLOC_ALIGN], $UCX_ALLOC_ALIGN, [Set aligment assumption for compiler])], 326 []) 327 328 329# 330# SSE/AVX 331# 332COMPILER_CPU_OPTIMIZATION([avx], [AVX], [-mavx], 333 [#include <immintrin.h> 334 int main(int argc, char** argv) { 335 return _mm256_testz_si256(_mm256_set1_epi32(1), _mm256_set1_epi32(3)); 336 } 337 ]) 338AS_IF([test "x$with_avx" != xyes], 339 [COMPILER_CPU_OPTIMIZATION([sse41], [SSE 4.1], [-msse4.1], 340 [#include <smmintrin.h> 341 int main(int argc, char** argv) { 342 return _mm_testz_si128(_mm_set1_epi32(1), _mm_set1_epi32(3)); 343 } 344 ]) 345 COMPILER_CPU_OPTIMIZATION([sse42], [SSE 4.2], [-msse4.2], 346 [#include <popcntintrin.h> 347 int main(int argc, char** argv) { return _mm_popcnt_u32(0x101) - 2; 348 }]) 349 ]) 350 351 352DETECT_UARCH() 353 354 355# 356# CPU tuning 357# 358AS_IF([test "x$ax_cpu" != "x"], 359 [COMPILER_CPU_OPTIMIZATION([mcpu], [CPU Model], [-mcpu=$ax_cpu], 360 [int main(int argc, char** argv) { return 0;}]) 361 ]) 362 363 364# 365# Architecture tuning 366# 367AS_IF([test "x$ax_arch" != "x"], 368 [COMPILER_CPU_OPTIMIZATION([march], [architecture tuning], [-march=$ax_arch], 369 [int main(int argc, char** argv) { return 0;}]) 370 ]) 371 372 373# 374# Check for compiler attribute which disables optimizations per-function. 375# 376CHECK_SPECIFIC_ATTRIBUTE([optimize], [NOOPTIMIZE], 377 [int foo (int arg) __attribute__ ((optimize("O0")));]) 378 379 380# 381# Compile code with frame pointer. Optimizations usually omit the frame pointer, 382# but if we are profiling the code with callgraph we need it. 383# This option may affect perofrmance so it is off by default. 384# 385AC_ARG_ENABLE([frame-pointer], 386 AS_HELP_STRING([--enable-frame-pointer], 387 [Compile with frame pointer, useful for profiling, default: NO]), 388 [], 389 [enable_frame_pointer=no]) 390AS_IF([test "x$enable_frame_pointer" = xyes], 391 [ADD_COMPILER_FLAG_IF_SUPPORTED([-fno-omit-frame-pointer], 392 [-fno-omit-frame-pointer], 393 [AC_LANG_SOURCE([[int main(int argc, char** argv){return 0;}]])], 394 [AS_MESSAGE([compiling with frame pointer])], 395 [AS_MESSAGE([compiling with frame pointer is not supported])])], 396 [:]) 397 398ADD_COMPILER_FLAG_IF_SUPPORTED([-funwind-tables], 399 [-funwind-tables], 400 [AC_LANG_SOURCE([[int main(int argc, char** argv){return 0;}]])], 401 [AS_MESSAGE([compiling with unwind tables])], 402 [AS_MESSAGE([compiling without unwind tables])]) 403 404 405# 406# Check for C++ support 407# 408CHECK_CXX_COMP() 409 410 411# 412# Check for C++11 support 413# 414AC_MSG_CHECKING([c++11 support]) 415AC_LANG_PUSH([C++]) 416SAVE_CXXFLAGS="$CXXFLAGS" 417CXX11FLAGS="-std=c++11" 418CXXFLAGS="$CXXFLAGS $CXX11FLAGS" 419AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <iostream> 420 #include <string> 421 int main(int argc, char** argv) { 422 std::to_string(1); 423 return 0; 424 } ]])], 425 [AC_MSG_RESULT([yes]) 426 AC_SUBST([CXX11FLAGS]) 427 cxx11_happy=yes], 428 [AC_MSG_RESULT([no]) 429 cxx11_happy=no]) 430CXXFLAGS="$SAVE_CXXFLAGS" 431AC_LANG_POP 432AM_CONDITIONAL([HAVE_CXX11], [test "x$cxx11_happy" != xno]) 433 434 435# 436# Check for GNU++11 support 437# 438AC_MSG_CHECKING([gnu++11 support]) 439AC_LANG_PUSH([C++]) 440 441SAVE_CXXFLAGS="$CXXFLAGS" 442CXX11FLAGS="-std=gnu++11" 443CXXFLAGS="$CXXFLAGS $CXX11FLAGS" 444AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <iostream> 445 #include <string> 446 int main(int argc, char** argv) { 447 int a; 448 typeof(a) b = 0; 449 std::to_string(1); 450 return 0; 451 } ]])], 452 [AC_MSG_RESULT([yes]) 453 AC_SUBST([CXX11FLAGS]) 454 gnuxx11_happy=yes], 455 [AC_MSG_RESULT([no]) 456 gnuxx11_happy=no]) 457CXXFLAGS="$SAVE_CXXFLAGS" 458AM_CONDITIONAL([HAVE_GNUXX11], [test "x$gnuxx11_happy" != xno]) 459 460AC_CHECK_DECL(_GLIBCXX_NOTHROW, have_glibcxx_nothrow=yes, 461 have_glibcxx_nothrow=no, [[#include <exception>]]) 462AM_CONDITIONAL([HAVE_GLIBCXX_NOTHROW], [test "x$have_glibcxx_nothrow" = xyes]) 463 464AC_LANG_POP 465 466 467# 468# PGI specific switches 469# 470# --diag_suppress 181 - Suppress incorrect printf format for PGI18 compiler. TODO: remove it after compiler fix 471# --diag_suppress 1215 - Suppress deprecated API warning for PGI18 compiler 472# --diag_suppress 1901 - Use of a const variable in a constant expression is nonstandard in C 473ADD_COMPILER_FLAGS_IF_SUPPORTED([[--display_error_number], 474 [--diag_suppress 181], 475 [--diag_suppress 1215], 476 [--diag_suppress 1901]], 477 [AC_LANG_SOURCE([[int main(int argc, char **argv){return 0;}]])]) 478 479 480# 481# Check if "-pedantic" flag is supported 482# 483CHECK_COMPILER_FLAG([-pedantic], [-pedantic], 484 [AC_LANG_SOURCE([[int main(int argc, char** argv){return 0;}]])], 485 [CFLAGS_PEDANTIC="$CFLAGS_PEDANTIC -pedantic"], 486 []) 487 488 489# 490# Add strict compilation flags 491# 492ADD_COMPILER_FLAGS_IF_SUPPORTED([[-Wno-missing-field-initializers], 493 [-Wno-unused-parameter], 494 [-Wno-unused-label], 495 [-Wno-long-long], 496 [-Wno-endif-labels], 497 [-Wno-sign-compare], 498 [-Wno-multichar], 499 [-Wno-deprecated-declarations], 500 [-Winvalid-pch]], 501 [AC_LANG_SOURCE([[int main(int argc, char **argv){return 0;}]])]) 502 503 504# 505# Set C++ optimization/debug flags to be the same as for C 506# 507BASE_CXXFLAGS="$BASE_CFLAGS" 508 509 510# 511# Add strict flags supported by C compiler only 512# NOTE: This must be done after setting BASE_CXXFLAGS 513# 514ADD_COMPILER_FLAGS_IF_SUPPORTED([[-Wno-pointer-sign], 515 [-Werror-implicit-function-declaration], 516 [-Wno-format-zero-length], 517 [-Wnested-externs], 518 [-Wshadow]], 519 [AC_LANG_SOURCE([[int main(int argc, char **argv){return 0;}]])]) 520 521 522AC_SUBST([BASE_CFLAGS]) 523AC_SUBST([BASE_CXXFLAGS]) 524AC_SUBST([CFLAGS_PEDANTIC]) 525 526 527# 528# Set common C preprocessor flags 529# 530BASE_CPPFLAGS="-DCPU_FLAGS=\"$OPT_CFLAGS\"" 531BASE_CPPFLAGS="$BASE_CPPFLAGS -I\${abs_top_srcdir}/src" 532BASE_CPPFLAGS="$BASE_CPPFLAGS -I\${abs_top_builddir}" 533BASE_CPPFLAGS="$BASE_CPPFLAGS -I\${abs_top_builddir}/src" 534AC_SUBST([BASE_CPPFLAGS], [$BASE_CPPFLAGS]) 535