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