1dnl 2dnl Check for BSD or POSIZ style global symbol lister, nm. 3dnl If found, pac_path_NM_G contains the absolute athname of nm + options 4dnl pac_path_NM_G_type will be either POSIX or BSD. NM_G will be 5dnl pac_path_NM_G without the absolute path. Preference is BSD style. 6dnl 7dnl The test checks if nm accepts the known options and also if nm produces 8dnl the expected BSD or POSIX output format. 9dnl 10AC_DEFUN([PAC_PATH_NM_G],[ 11AC_MSG_CHECKING([for BSD/POSIX style global symbol lister]) 12AC_LANG_PUSH(C) 13AC_PATH_PROGS_FEATURE_CHECK(NM_G, nm, [ 14 # Check if nm accepts -g and BSD or POSIX compatible flag. 15 # Use the `sed 1q' to avoid HP-UX's unknown option message: 16 # nm: unknown option "B" ignored 17 # Tru64's nm complains that /dev/null is an invalid object file 18 # 19 # AIX's sed does not accept \+, 1) instead of doing 's|a\+||', do 's|aa*||' 20 # or 2) instead of 's|A \+B|AB|g', do 's|A *B|AB|g' 21 22 # Check if nm accepts -g 23 case `${ac_path_NM_G} -g /dev/null 2>&1 | sed '1q'` in 24 */dev/null* | *'Invalid file or object type'*) 25 ac_path_NM_G="${ac_path_NM_G} -g" 26 # Check if nm accepts -B 27 case `${ac_path_NM_G} -B /dev/null 2>&1 | sed '1q'` in 28 */dev/null* | *'Invalid file or object type'*) 29 AC_COMPILE_IFELSE([ 30 AC_LANG_SOURCE([int iglobal;]) 31 ],[ 32 changequote(,) 33 case `${ac_path_NM_G} -B conftest.$OBJEXT | sed -e 's|[0-9][0-9]* *[A-Z] *iglobal|XXXX|g'` in 34 *XXXX*) 35 pac_path_NM_G="${ac_path_NM_G} -B" 36 pac_path_NM_G_type="BSD" 37 ;; 38 esac 39 changequote([,]) 40 ]) 41 ;; 42 *) 43 # Check if nm accepts -P 44 case `${ac_path_NM_G} -P /dev/null 2>&1 | sed '1q'` in 45 */dev/null* | *'Invalid file or object type'*) 46 AC_COMPILE_IFELSE([ 47 AC_LANG_SOURCE([int iglobal;]) 48 ],[ 49 changequote(,) 50 case `${ac_path_NM_G} -P conftest.$OBJEXT | sed -e 's|iglobal *[A-Z] *[0-9][0-9]*|XXXX|g'` in 51 *XXXX*) 52 pac_path_NM_G="${ac_path_NM_G} -P" 53 pac_path_NM_G_type="POSIX" 54 ;; 55 esac 56 changequote([,]) 57 ]) 58 ;; 59 esac # Endof case `${ac_path_NM_G} -P 60 ;; 61 esac # Endof case `${ac_path_NM_G} -B 62 ;; 63 esac # Endof case `${ac_path_NM_G} -g 64 if test "X$pac_path_NM_G" != "X" ; then 65 AC_MSG_RESULT([$pac_path_NM_G_type style,$pac_path_NM_G]) 66 NM_G="`echo $pac_path_NM_G | sed -e 's|^.*nm |nm |g'`" 67 else 68 AC_MSG_RESULT(no) 69 fi 70 ac_cv_path_NM_G=${ac_path_NM_G} 71 ac_path_NM_G_found=: 72], [AC_MSG_RESULT(no)], 73[$PATH$PATH_SEPARATOR/usr/ccs/bin/elf$PATH_SEPARATOR/usr/ccs/bin$PATH_SEPARATOR/usr/ucb$PATH_SEPARATOR/bin]) 74AC_LANG_POP(C) 75]) dnl Endof AC_DEFUN([PAC_PATH_NM_G] 76dnl 77dnl PAC_C_MULTI_ATTR_ALIAS() 78dnl 79dnl The checks if multiple __attribute__((alias)) is available 80dnl If the multiple __attribute((alias)) support is found, 81dnl pac_c_multi_attr_alias=yes is set. 82dnl 83dnl The default is to do a runtime test. When cross_compiling=yes, 84dnl pac_path_NM_G will be used to determine the test result. 85dnl If CFLAGS(or CPPFLAGS) contains ATTR_ALIAS_DEBUG, the runtime will print 86dnl out addresses of struct(s) for debugging purpose. 87dnl 88dnl 89AC_DEFUN([PAC_C_MULTI_ATTR_ALIAS],[ 90AC_REQUIRE([PAC_PATH_NM_G]) 91AC_LANG_PUSH(C) 92AC_CHECK_HEADERS([stdio.h]) 93AC_MSG_CHECKING([for multiple __attribute__((alias)) support]) 94 95#Compile the "other" __attribute__ object file. 96AC_COMPILE_IFELSE([ 97 AC_LANG_SOURCE([ 98#if defined(HAVE_STDIO_H) || defined(STDC_HEADERS) 99#include <stdio.h> 100#endif 101 102struct mpif_cmblk_t_ { int imember; }; 103typedef struct mpif_cmblk_t_ mpif_cmblk_t; 104 105/* NOT initialize these structure so it appears in BSS or as COMMON symbols */ 106mpif_cmblk_t mpifcmb; 107mpif_cmblk_t MPIFCMB; 108 109/* 110 Do the test in this file instead in the file 111 where __attribute__((alias)) is used. 112 This is needed for pgcc since pgcc seems to 113 define aliased symbols if they are in the same file. 114*/ 115/* 116 We can't do the following comparision in one test: 117 118 ilogical = (( &mpifcmb == ptr && &MPIFCMB == ptr ) ? TRUE : FALSE) ; 119 120 because some compiler, like gcc 4.4.2's -O* optimizes the code 121 such that the ilogical expression is FALSE. The likely reason is that 122 mpifcmb and MPIFCMB are defined in the same scope in which C optimizer 123 may have treated them as different objects (with different addresses), 124 &mpifcmb != &MPIFCMB, before actually running the test and hence the 125 illogical expression is assumed to be always FALSE. The solution taken 126 here is to prevent the optimizer the opportunity to equate &mpifcmb and 127 &MPIFCMB (in same scope), e.g. using 2 separate tests and combine the 128 test results in a different scope. 129*/ 130int same_addrs1( void *ptr ); 131int same_addrs1( void *ptr ) 132{ 133#if defined(ATTR_ALIAS_DEBUG) 134 printf( "others: addr(mpifcmb)=%p, addr(input ptr)=%p\n", &mpifcmb, ptr ); 135#endif 136 return ( &mpifcmb == ptr ? 1 : 0 ); 137} 138 139int same_addrs2( void *ptr ); 140int same_addrs2( void *ptr ) 141{ 142#if defined(ATTR_ALIAS_DEBUG) 143 printf( "others: addr(MPIFCMB)=%p, addr(input ptr)=%p\n", &MPIFCMB, ptr ); 144#endif 145 return ( &MPIFCMB == ptr ? 1 : 0 ); 146} 147 148 ]) 149],[ 150 rm -f pac_conftest_other.$OBJEXT 151 PAC_RUNLOG([cp conftest.$OBJEXT pac_conftest_other.$OBJEXT]) 152 test -s pac_conftest_other.$OBJEXT && pac_c_attr_alias_other=yes 153dnl cp conftest.$ac_ext pac_conftest_other.$ac_ext 154dnl echo 155dnl echo "pac_conftest_other.$OBJEXT" 156dnl nm -P -g pac_conftest_other.$OBJEXT | grep -i "mpifcmb" 157],[ 158 pac_c_attr_alias_other=no 159]) dnl Endof AC_COMPILE_IFELSE 160 161pac_c_attr_alias_main=no 162if test "$pac_c_attr_alias_other" = "yes" ; then 163 164# Push LIBS for later restoration. 165 PAC_PUSH_FLAG([LIBS]) 166 LIBS="pac_conftest_other.$OBJEXT $LIBS" 167 168# Link the "other" __attribute__ object file. 169 AC_LINK_IFELSE([ 170 AC_LANG_PROGRAM([ 171#if defined(HAVE_STDIO_H) || defined(STDC_HEADERS) 172#include <stdio.h> 173#endif 174 175struct mpif_cmblk_t_ { int imember; }; 176typedef struct mpif_cmblk_t_ mpif_cmblk_t; 177 178mpif_cmblk_t mpifcmbr = {0}; 179extern mpif_cmblk_t MPIFCMB __attribute__ ((alias("mpifcmbr"))); 180extern mpif_cmblk_t mpifcmb __attribute__ ((alias("mpifcmbr"))); 181 182extern int same_addrs1( void *ptr ); 183extern int same_addrs2( void *ptr ); 184 185 ],[ 186 int iaddr = 0; 187#if defined(ATTR_ALIAS_DEBUG) 188 printf( "main: addr(mpifcmbr) = %p\n", &mpifcmbr ); 189 printf( "main: addr(mpifcmb) = %p\n", &mpifcmb ); 190 printf( "main: addr(MPIFCMB) = %p\n", &MPIFCMB ); 191#endif 192 iaddr = same_addrs1( &mpifcmbr ) && same_addrs2( &mpifcmbr ); 193 FILE *file = fopen( "pac_conftestval", "w" ); 194 if (!file) return 1; 195 fprintf( file, "%d\n", iaddr ); 196 ]) 197 ],[ 198 rm -f pac_conftest_main$EXEEXT 199 PAC_RUNLOG([cp conftest$EXEEXT pac_conftest_main$EXEEXT]) 200 test -x pac_conftest_main$EXEEXT && pac_c_attr_alias_main=yes 201dnl cp conftest.$ac_ext pac_conftest_main.$ac_ext 202dnl echo 203dnl echo "pac_conftest_main$EXEEXT" 204dnl nm -P -g pac_conftest_main$EXEEXT | grep -i "mpifcmb" 205 ],[ 206 pac_c_attr_alias_main=no 207dnl cp conftest.$ac_ext pac_conftest_main.$ac_ext 208 ]) dnl Endof AC_LINK_IFELSE 209 210# Restore the previously pushed LIBS 211 PAC_POP_FLAG([LIBS]) 212 rm -f pac_conftest_other.$OBJEXT 213fi dnl Endof if test "$pac_c_attr_alias_other" = "yes" 214 215if test "$pac_c_attr_alias_main" = "yes" ; then 216 if test "$cross_compiling" = "yes" ; then 217 changequote(,) 218 # echo "PAC CROSS-COMPILING" dnl 219 # POSIX NM = nm -P format dnl 220 if test "$pac_path_NM_G_type" = "POSIX" ; then 221 addrs=`${pac_path_NM_G} ./pac_conftest_main$EXEEXT | grep -i mpifcmb | sed -e 's% *[a-zA-Z][a-zA-Z]* *[a-zA-Z] *\([0-9abcdef][0-9abcdef]*\).*%\1%g'` 222 fi 223 224 # BSD NM = nm -B format dnl 225 if test "$pac_path_NM_G_type" = "BSD" ; then 226 addrs=`${pac_path_NM_G} -g ./pac_conftest_main$EXEEXT | grep -i mpifcmb | sed -e "s% *\([0-9abcdef][0-9abcdef]*\) *[a-zA-Z] *[a-zA-Z][a-zA-A]*.*%\1%g"` 227 fi 228 changequote([,]) 229 230 cmp_addr="" 231 diff_addrs=no 232 for addr in ${addrs} ; do 233 if test "X${cmp_addr}" != "X" ; then 234 if test "${cmp_addr}" != "${addr}" ; then 235 diff_addrs=yes 236 break 237 fi 238 else 239 cmp_addr=${addr} 240 fi 241 done 242 243 if test "$diff_addrs" != "yes" ; then 244 dnl echo "Same addresses. Multiple aliases support" 245 AC_MSG_RESULT([${NM_G} says yes]) 246 pac_c_multi_attr_alias=yes 247 else 248 dnl echo "Different addresses. No multiple aliases support." 249 AC_MSG_RESULT([${NM_G} says no]) 250 pac_c_multi_attr_alias=no 251 fi 252 253 else # if test "$cross_compiling" != "yes" 254 rm -f pac_conftestval 255 ac_try="./pac_conftest_main$EXEEXT" 256 if AC_TRY_EVAL(ac_try) ; then 257 pac_c_attr_alias_val=0 258 if test -s pac_conftestval ; then 259 eval pac_c_attr_alias_val=`cat pac_conftestval` 260 fi 261 if test "$pac_c_attr_alias_val" -eq 1 ; then 262 AC_MSG_RESULT(yes) 263 pac_c_multi_attr_alias=yes 264 else 265 AC_MSG_RESULT(no) 266 pac_c_multi_attr_alias=no 267 fi 268 rm -f pac_conftestval 269 fi 270 fi 271 dnl Endof if test "$cross_compiling" = "yes" 272 rm -f pac_conftest_main$EXEEXT 273else 274 AC_MSG_RESULT(no! link failure) 275 pac_c_multi_attr_alias=no 276fi dnl Endof if test "$pac_c_attr_alias_main" = "yes" 277 278AC_LANG_POP(C) 279 280]) dnl Endof AC_DEFUN([PAC_C_MULTI_ATTR_ALIAS] 281dnl 282dnl PAC_C_ATTR_ALIGNED() 283dnl 284dnl Check if __attribute__((aligned)) support is there. 285dnl If so, set pac_c_attr_aligned=yes. 286dnl 287dnl Do a link test instead of compile test to check if the linker 288dnl would emit an error. 289dnl 290AC_DEFUN([PAC_C_ATTR_ALIGNED],[ 291AC_LANG_PUSH(C) 292AC_MSG_CHECKING([for __attribute__((aligned)) support]) 293#Link the __attribute__ object file. 294AC_LINK_IFELSE([ 295 AC_LANG_PROGRAM([ 296struct mpif_cmblk_t_ { int imembers[5]; }; 297typedef struct mpif_cmblk_t_ mpif_cmblk_t; 298mpif_cmblk_t mpifcmbr __attribute__((aligned)) = {0}; 299 ],[]) 300],[pac_c_attr_aligned=yes], [pac_c_attr_aligned=no]) 301AC_MSG_RESULT([$pac_c_attr_aligned]) 302AC_LANG_POP(C) 303]) 304dnl 305dnl PAC_F2C_ATTR_ALIGNED_SIZE(ARRAY_SIZE, [OUTPUT_VAR], [MIN_ALIGNMENT]) 306dnl 307dnl ARRAY_SIZE : Size of the integer array within the fortran commmon block. 308dnl OUTPUT_VAR : Optional variable to be set. 309dnl if test succeeds, set OUTPUT_VAR=$pac_f2c_attr_aligned_str. 310dnl if test fails, set OUTPUT_VAR="unknown". 311dnl MIN_ALIGNMENT : Optional value. 312dnl Minimum alignment size to be used in OUTPUT_VAR. 313dnl pac_f2c_attr_aligned_str won't be modified. 314dnl 315dnl "pac_f2c_attr_aligned_str" will be set with 316dnl 1) __attribute__((aligned(ALIGNMENT_SIZE))), 317dnl 2) __attribute__((aligned)). 318dnl 3) "", i.e. empty string. 319dnl 320dnl 2) means the test can't find a good alignment value, but both the Fortran 321dnl and C compilers are OK with "aligned" which in principle means the C 322dnl compiler will pick the maximum useful alignment supported by the 323dnl architecture. 324dnl 3) means that the test has failed to find the alignment. 325dnl 326AC_DEFUN([PAC_F2C_ATTR_ALIGNED_SIZE],[ 327cmblksize=$1 328AC_MSG_CHECKING([the minimum alignment of Fortran common block of $cmblksize integers]) 329dnl To find the minmium alignment of Fortran common block (of integer array) 330dnl as seen by C object file, C object files of various (typical) alignments 331dnl are linked to the Fortran code using the common block of integer array. 332# 333dnl Since the incorrect alignment results only a warning messages from the 334dnl fortran compiler(or linker), so we use "diff" to compare the fortran 335dnl compiler/linker output. We cannot use AC_LANG_WERROR, 336dnl i.e. ac_fc_werror_flag=yes, because compiler like pgf77 at version 10.x) 337dnl has non-zero stderr output if a fortran program is used in the linking. 338dnl The stderr contains the name of fortran program even if the linking is 339dnl successful. We could avoid the non-zero stderr output in pgf77 by 340dnl compiling everthing into object files and linking all the object files 341dnl with pgf77. Doing that would need us to use AC_TRY_EVAL instead of 342dnl AC_LINK_IFELSE, so "diff" approach is used instead. 343# 344dnl Using diff of compiler(linker) output requires a reference output file 345dnl as the base of diff. The process of creating this reference output file 346dnl has to be exactly the same as the testing process, because pgf77 has 347dnl the following weird behavour 348dnl pgf77 -o ftest ftest.f => when $?=0 with zero stderr output 349dnl pgf77 -o ftest ftest.f dummy.o => when $?=0 with non-zero stderr output. 350dnl stderr has "ftest.f:". 351dnl 352# First create a fortran CONFTEST which will be used repeatedly. 353AC_LANG_PUSH([Fortran]) dnl AC_LANG_PUSH([Fortran 77]) 354AC_LANG_CONFTEST([ 355 AC_LANG_SOURCE([ 356 program fconftest 357 integer isize 358 parameter (isize=$cmblksize) 359 integer status_array(isize) 360 common /mpifcmb/ status_array 361 save /mpifcmb/ 362 end 363 ]) 364]) 365AC_LANG_POP([Fortran]) dnl AC_LANG_POP([Fortran 77]) 366dnl 367dnl 368dnl 369# Compile a C dummy.$OBJEXT and link with Fortran test program to create 370# a reference linker output file, pac_align0.log, as the base of "diff". 371AC_LANG_PUSH([C]) 372AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],[ 373 cp conftest.$ac_ext pac_conftest.c 374 PAC_RUNLOG([mv conftest.$OBJEXT pac_conftest.$OBJEXT]) 375 PAC_PUSH_FLAG([LIBS]) 376 LIBS="pac_conftest.$OBJEXT $LIBS" 377 AC_LANG_PUSH([Fortran]) dnl AC_LANG_PUSH([Fortran 77]) 378 PAC_PUSH_FLAG([ac_link]) 379 ac_link="`echo $ac_link | sed -e 's|>.*$|> $pac_logfile 2>\&1|g'`" 380 pac_logfile="pac_align0.log" 381 rm -f $pac_logfile 382 AC_LINK_IFELSE([],[ 383 pac_f2c_alignedn_diffbase=yes 384 ],[ 385 pac_f2c_alignedn_diffbase=no 386 ]) 387 # Be sure NOT to remove the conftest.f which is still needed for later use. 388 # rm -f conftest.$ac_ext 389 # Restore everything in autoconf that has been overwritten 390 PAC_POP_FLAG([ac_link]) 391 # restore previously pushed LIBS 392 PAC_POP_FLAG([LIBS]) 393 AC_LANG_POP([Fortran]) dnl AC_LANG_POP([Fortran 77]) 394],[ 395 pac_f2c_alignedn_diffbase=no 396]) 397AC_LANG_POP([C]) 398dnl 399dnl 400if test "$pac_f2c_alignedn_diffbase" = "yes" ; then 401 # Initialize pac_result_str to empty string since part of the test 402 # depends on pac_result_str is empty or non-empty string. 403 pac_result_str="" 404 # Initialize pac_f2c_attr_aligned_str to empty string and 405 # it will remain as empty string if the following test fails. 406 pac_f2c_attr_aligned_str="" 407 for asize in 4 8 16 32 64 128 max ; do 408 if test "$asize" != "max" ; then 409 pac_attr_aligned_str="__attribute__((aligned($asize)))" 410 else 411 pac_attr_aligned_str="__attribute__((aligned))" 412 fi 413 AC_LANG_PUSH([C]) 414 #Compile the __attribute__ object file. 415 AC_COMPILE_IFELSE([ 416 AC_LANG_SOURCE([ 417changequote(,) 418struct mpif_cmblk_t_ { $MPI_FINT imembers[$cmblksize]; }; 419changequote([,]) 420typedef struct mpif_cmblk_t_ mpif_cmblk_t; 421mpif_cmblk_t mpifcmbr $pac_attr_aligned_str = {0}; 422 423extern mpif_cmblk_t _CMPIFCMB __attribute__ ((alias("mpifcmbr"))); 424extern mpif_cmblk_t MPIFCMB __attribute__ ((alias("mpifcmbr"))); 425extern mpif_cmblk_t MPIFCMB_ __attribute__ ((alias("mpifcmbr"))); 426extern mpif_cmblk_t _Cmpifcmb __attribute__ ((alias("mpifcmbr"))); 427extern mpif_cmblk_t mpifcmb __attribute__ ((alias("mpifcmbr"))); 428extern mpif_cmblk_t mpifcmb_ __attribute__ ((alias("mpifcmbr"))); 429 ]) 430 ],[ 431 cp conftest.$ac_ext pac_conftest.c 432 PAC_RUNLOG([mv conftest.$OBJEXT pac_conftest.$OBJEXT]) 433 PAC_PUSH_FLAG([LIBS]) 434 LIBS="pac_conftest.$OBJEXT $LIBS" 435 AC_LANG_PUSH([Fortran]) dnl AC_LANG_PUSH([Fortran 77]) 436 PAC_PUSH_FLAG([ac_link]) 437 ac_link="`echo $ac_link | sed -e 's|>.*$|> $pac_logfile 2>\&1|g'`" 438 pac_logfile="pac_align1.log" 439 rm -f $pac_logfile 440 # Use conftest.f created in CONFTEST. 441 AC_LINK_IFELSE([],[ 442 PAC_RUNLOG_IFELSE([diff -b pac_align0.log pac_align1.log],[ 443 pac_attr_alignedn=yes 444 ],[ 445 pac_attr_alignedn=no 446 cat $pac_logfile >&AS_MESSAGE_LOG_FD 447 echo "failed C program was:" >&AS_MESSAGE_LOG_FD 448 cat pac_conftest.c >&AS_MESSAGE_LOG_FD 449 echo "failed Fortran program was:" >&AS_MESSAGE_LOG_FD 450 cat conftest.$ac_ext >&AS_MESSAGE_LOG_FD 451 ]) 452 ],[ 453 pac_attr_alignedn=no 454 ]) 455 # Restore everything in autoconf that has been overwritten 456 PAC_POP_FLAG([ac_link]) 457 # restore previously pushed LIBS 458 PAC_POP_FLAG([LIBS]) 459 AC_LANG_POP([Fortran]) dnl AC_LANG_POP([Fortran 77]) 460 # remove previously generated object file and C file. 461 rm -f pac_conftest.$OBJEXT pac_conftest.c 462 rm -f $pac_logfile 463 if test "$pac_attr_alignedn" = yes ; then 464 ifelse([$3],[],[ 465 pac_result_str="$asize" 466 pac_f2c_attr_aligned_str="$pac_attr_aligned_str" 467 break 468 ],[ 469 if test "$asize" != "max" -a "$asize" -lt "$3" ; then 470 if test "X$pac_result_str" = "X" ; then 471 pac_result_str="$asize" 472 pac_f2c_attr_aligned_str="$pac_attr_aligned_str" 473 fi 474 continue 475 else 476 pac_f2c_attr_aligned_str="$pac_attr_aligned_str" 477 if test "X$pac_result_str" != "X" ; then 478 pac_result_str="$pac_result_str, too small! reset to $asize" 479 else 480 pac_result_str="$asize" 481 fi 482 break 483 fi 484 ]) 485 fi 486 ], [ 487 pac_attr_alignedn=no 488 ]) 489 AC_LANG_POP([C]) 490 done 491 ifelse([$2],[],[],[$2="$pac_f2c_attr_aligned_str"]) 492else 493 pac_result_str="" 494 # Since the test fails, set pac_f2c_attr_aligned_str to empty string. 495 pac_f2c_attr_aligned_str="" 496fi 497if test "X$pac_result_str" != "X" ; then 498 AC_MSG_RESULT([$pac_result_str]) 499else 500 AC_MSG_RESULT([unknown]) 501fi 502rm -f pac_align0.log 503]) 504dnl 505