Commit ba26e3bb authored by Anthony Chan's avatar Anthony Chan
Browse files

[svn-r7063]

added a new test PAC_F2C_ATTR_ALIGNED_SIZE to replace PAC_C_ATTR_ALIGNED to determine the alignment of Fortran common block as seen in C.  Also added a switch, --enable-multi-aliases, to disable the feature just in case something goes wrong.
parent b6c2deca
......@@ -74,10 +74,12 @@ AC_PATH_PROGS_FEATURE_CHECK(NM_G, nm, [
AC_LANG_POP(C)
]) dnl Endof AC_DEFUN([PAC_PATH_NM_G]
dnl
dnl PAC_C_MULTI_ATTR_ALIAS()
dnl
dnl The checks if multiple __attribute__((alias)) is available
dnl If the multiple __attribute((alias)) support is found,
dnl pac_c_multi_attr_alias=yes is set.
dnl
dnl The checks if Multiple __attribute__((alias)) is available
dnl If the multiple __attribute((alias)) support is there,
dnl define(HAVE_C_MULTI_ATTR_ALIAS) and pac_c_multi_attr_alias=yes.
dnl The default is to do a runtime test. When cross_compiling=yes,
dnl pac_path_NM_G will be used to determine the test result.
dnl If CFLAGS(or CPPFLAGS) contains ATTR_ALIAS_DEBUG, the runtime will print
......@@ -241,8 +243,6 @@ if test "$pac_c_attr_alias_main" = "yes" ; then
if test "$diff_addrs" != "yes" ; then
dnl echo "Same addresses. Multiple aliases support"
AC_MSG_RESULT([${NM_G} says yes])
AC_DEFINE(HAVE_C_MULTI_ATTR_ALIAS, 1,
[Define if multiple __attribute__((alias)) are supported])
pac_c_multi_attr_alias=yes
else
dnl echo "Different addresses. No multiple aliases support."
......@@ -260,8 +260,6 @@ if test "$pac_c_attr_alias_main" = "yes" ; then
fi
if test "$pac_c_attr_alias_val" -eq 1 ; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_C_MULTI_ATTR_ALIAS, 1,
[Define if multiple __attribute__((alias)) are supported])
pac_c_multi_attr_alias=yes
else
AC_MSG_RESULT(no)
......@@ -281,8 +279,10 @@ AC_LANG_POP(C)
]) dnl Endof AC_DEFUN([PAC_C_MULTI_ATTR_ALIAS]
dnl
dnl Check if __attribute__((aligned)) is supported.
dnl If so, define HAVE_C_ATTR_ALIGNED and set pac_c_attr_aligned=yes.
dnl PAC_C_ATTR_ALIGNED()
dnl
dnl Check if __attribute__((aligned)) support is there.
dnl If so, set pac_c_attr_aligned=yes.
dnl
dnl Do a link test instead of compile test to check if the linker
dnl would emit an error.
......@@ -298,12 +298,207 @@ typedef struct mpif_cmblk_t_ mpif_cmblk_t;
mpif_cmblk_t mpifcmbr __attribute__((aligned)) = {0};
],[])
],[pac_c_attr_aligned=yes], [pac_c_attr_aligned=no])
if test "$pac_c_attr_aligned" = "yes" ; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_C_ATTR_ALIGNED,1,
[Define if __attribute__((aligned)) is supported.])
AC_MSG_RESULT([$pac_c_attr_aligned])
AC_LANG_POP(C)
])
dnl
dnl PAC_F2C_ATTR_ALIGNED_SIZE(ARRAY_SIZE, [OUTPUT_VAR], [MIN_ALIGNMENT])
dnl
dnl ARRAY_SIZE : Size of the integer array within the fortran commmon block.
dnl OUTPUT_VAR : Optional variable to be set.
dnl if test succeeds, set OUTPUT_VAR=$pac_f2c_attr_aligned_str.
dnl if test fails, set OUTPUT_VAR="unknown".
dnl MIN_ALIGNMENT : Optional value.
dnl Minimum alignment size to be used in OUTPUT_VAR.
dnl pac_f2c_attr_aligned_str won't be modified.
dnl
dnl "pac_f2c_attr_aligned_str" will be set with
dnl 1) __attribute__((aligned(ALIGNMENT_SIZE))),
dnl 2) __attribute__((aligned)).
dnl 3) "", i.e. empty string.
dnl
dnl 2) means the test can't find a good alignment value, but both the Fortran
dnl and C compilers are OK with "aligned" which in principle means the C
dnl compiler will pick the maximum useful alignment supported by the
dnl architecture.
dnl 3) means that the test has failed to find the alignment.
dnl
AC_DEFUN([PAC_F2C_ATTR_ALIGNED_SIZE],[
cmblksize=$1
AC_MSG_CHECKING([the minimum alignment of Fortran common block of $cmblksize integers])
dnl To find the minmium alignment of Fortran common block (of integer array)
dnl as seen by C object file, C object files of various (typical) alignments
dnl are linked to the Fortran code using the common block of integer array.
#
dnl Since the incorrect alignment results only a warning messages from the
dnl fortran compiler(or linker), so we use "diff" to compare the fortran
dnl compiler/linker output. We cannot use AC_LANG_WERROR,
dnl i.e. ac_fc_werror_flag=yes, because compiler like pgf77 at version 10.x)
dnl has non-zero stderr output if a fortran program is used in the linking.
dnl The stderr contains the name of fortran program even if the linking is
dnl successful. We could avoid the non-zero stderr output in pgf77 by
dnl compiling everthing into object files and linking all the object files
dnl with pgf77. Doing that would need us to use AC_TRY_EVAL instead of
dnl AC_LINK_IFELSE, so "diff" approach is used instead.
#
dnl Using diff of compiler(linker) output requires a reference output file
dnl as the base of diff. The process of creating this reference output file
dnl has to be exactly the same as the testing process, because pgf77 has
dnl the following weird behavour
dnl pgf77 -o ftest ftest.f => when $?=0 with zero stderr output
dnl pgf77 -o ftest ftest.f dummy.o => when $?=0 with non-zero stderr output.
dnl stderr has "ftest.f:".
dnl
# First create a fortran CONFTEST which will be used repeatedly.
AC_LANG_PUSH([Fortran]) dnl AC_LANG_PUSH([Fortran 77])
AC_LANG_CONFTEST([
AC_LANG_SOURCE([
program fconftest
integer isize
parameter (isize=$cmblksize)
integer status_array(isize)
common /mpifcmb/ status_array
save /mpifcmb/
end
])
])
AC_LANG_POP([Fortran]) dnl AC_LANG_POP([Fortran 77])
dnl
dnl
dnl
# Compile a C dummy.$OBJEXT and link with Fortran test program to create
# a reference linker output file, pac_align0.log, as the base of "diff".
AC_LANG_PUSH([C])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],[
cp conftest.$ac_ext pac_conftest.c
PAC_RUNLOG([mv conftest.$OBJEXT pac_conftest.$OBJEXT])
saved_LIBS="$LIBS"
LIBS="pac_conftest.$OBJEXT $LIBS"
AC_LANG_PUSH([Fortran]) dnl AC_LANG_PUSH([Fortran 77])
saved_ac_link="$ac_link"
ac_link="`echo $saved_ac_link | sed -e 's|>.*$|> $pac_logfile 2>\&1|g'`"
pac_logfile="pac_align0.log"
rm -f $pac_logfile
AC_LINK_IFELSE([],[
pac_f2c_alignedn_diffbase=yes
],[
pac_f2c_alignedn_diffbase=no
])
# Be sure NOT to remove the conftest.f which is still needed for later use.
# rm -f conftest.$ac_ext
# Restore everything in autoconf that has been overwritten
ac_link="$saved_ac_link"
# restore previously saved LIBS
LIBS="$saved_LIBS"
AC_LANG_POP([Fortran]) dnl AC_LANG_POP([Fortran 77])
],[
pac_f2c_alignedn_diffbase=no
])
AC_LANG_POP([C])
dnl
dnl
if test "$pac_f2c_alignedn_diffbase" = "yes" ; then
# Initialize pac_result_str to empty string since part of the test
# depends on pac_result_str is empty or non-empty string.
pac_result_str=""
# Initialize pac_f2c_attr_aligned_str to empty string and
# it will remain as empty string if the following test fails.
pac_f2c_attr_aligned_str=""
for asize in 4 8 16 32 64 128 max ; do
if test "$asize" != "max" ; then
pac_attr_aligned_str="__attribute__((aligned($asize)))"
else
pac_attr_aligned_str="__attribute__((aligned))"
fi
AC_LANG_PUSH([C])
#Compile the __attribute__ object file.
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([
changequote(,)
struct mpif_cmblk_t_ { int imembers[$cmblksize]; };
changequote([,])
typedef struct mpif_cmblk_t_ mpif_cmblk_t;
mpif_cmblk_t mpifcmbr $pac_attr_aligned_str = {0};
extern mpif_cmblk_t _CMPIFCMB __attribute__ ((alias("mpifcmbr")));
extern mpif_cmblk_t MPIFCMB __attribute__ ((alias("mpifcmbr")));
extern mpif_cmblk_t MPIFCMB_ __attribute__ ((alias("mpifcmbr")));
extern mpif_cmblk_t _Cmpifcmb __attribute__ ((alias("mpifcmbr")));
extern mpif_cmblk_t mpifcmb __attribute__ ((alias("mpifcmbr")));
extern mpif_cmblk_t mpifcmb_ __attribute__ ((alias("mpifcmbr")));
])
],[
cp conftest.$ac_ext pac_conftest.c
PAC_RUNLOG([mv conftest.$OBJEXT pac_conftest.$OBJEXT])
saved_LIBS="$LIBS"
LIBS="pac_conftest.$OBJEXT $LIBS"
AC_LANG_PUSH([Fortran]) dnl AC_LANG_PUSH([Fortran 77])
saved_ac_link="$ac_link"
ac_link="`echo $saved_ac_link | sed -e 's|>.*$|> $pac_logfile 2>\&1|g'`"
pac_logfile="pac_align1.log"
rm -f $pac_logfile
# Use conftest.f created in CONFTEST.
AC_LINK_IFELSE([],[
PAC_RUNLOG_IFELSE([diff -b pac_align0.log pac_align1.log],[
pac_attr_alignedn=yes
],[
pac_attr_alignedn=no
cat $pac_logfile >&AS_MESSAGE_LOG_FD
echo "failed C program was:" >&AS_MESSAGE_LOG_FD
cat pac_conftest.c >&AS_MESSAGE_LOG_FD
echo "failed Fortran program was:" >&AS_MESSAGE_LOG_FD
cat conftest.$ac_ext >&AS_MESSAGE_LOG_FD
])
],[
pac_attr_alignedn=no
])
# Restore everything in autoconf that has been overwritten
ac_link="$saved_ac_link"
# restore previously saved LIBS
LIBS="$saved_LIBS"
AC_LANG_POP([Fortran]) dnl AC_LANG_POP([Fortran 77])
# remove previously generated object file and C file.
rm -f pac_conftest.$OBJEXT pac_conftest.c
rm -f $pac_logfile
if test "$pac_attr_alignedn" = yes ; then
ifelse([$3],[],[
pac_result_str="$asize"
pac_f2c_attr_aligned_str="$pac_attr_aligned_str"
break
],[
if test "$asize" != "max" -a "$asize" -lt "$3" ; then
if test "X$pac_result_str" = "X" ; then
pac_result_str="$asize"
pac_f2c_attr_aligned_str="$pac_attr_aligned_str"
fi
continue
else
pac_f2c_attr_aligned_str="$pac_attr_aligned_str"
if test "X$pac_result_str" != "X" ; then
pac_result_str="$pac_result_str, too small! reset to $asize"
else
pac_result_str="$asize"
fi
break
fi
])
fi
], [
pac_attr_alignedn=no
])
AC_LANG_POP([C])
done
ifelse([$2],[],[],[$2="$pac_f2c_attr_aligned_str"])
else
AC_MSG_RESULT(no)
pac_result_str=""
# Since the test fails, set pac_f2c_attr_aligned_str to empty string.
pac_f2c_attr_aligned_str=""
fi
AC_LANG_POP(C)
if test "X$pac_result_str" != "X" ; then
AC_MSG_RESULT([$pac_result_str])
else
AC_MSG_RESULT([unknown])
fi
rm -f pac_align0.log
])
dnl
......@@ -533,6 +533,12 @@ enable_weak_symbols=yes)
dnl
dnl
dnl
AC_ARG_ENABLE(multi-aliases,
[--enable-multi-aliases - Multiple aliasing to support multiple fortran compilers (default)],,
enable_multi_aliases=yes)
dnl
dnl
dnl
AC_ARG_WITH(cross,
[--with-cross=file - Specify the values of variables that configure cannot
determine in a cross-compilation environment]
......@@ -1858,12 +1864,6 @@ EOF
fi
fi
# Check if multiple __attribute__((alias)) is available
if test "$enable_f77" = yes ; then
PAC_C_ATTR_ALIGNED
PAC_C_MULTI_ATTR_ALIAS
fi
# FC requires F77 as well. If the user disabled f77, do not run the
# next test; instead, drop into the warning message
# Set a default value for fc works with f77. This value is
......@@ -4441,6 +4441,23 @@ EOF
# rest of the bits were ignored. For now, we'll assume that there are
# unique true and false values.
# Check if multiple __attribute__((alias)) is available
if test "$enable_multi_aliases" = "yes" ; then
PAC_C_MULTI_ATTR_ALIAS
if test "$pac_c_multi_attr_alias" = "yes" ; then
PAC_F2C_ATTR_ALIGNED_SIZE([1],[CMB_1INT_ALIGNMENT])
AC_SUBST(CMB_1INT_ALIGNMENT)
PAC_F2C_ATTR_ALIGNED_SIZE([$MPI_STATUS_SIZE],[CMB_STATUS_ALIGNMENT],
[32])
AC_SUBST(CMB_STATUS_ALIGNMENT)
if test "X$CMB_1INT_ALIGNMENT" != "X" \
-a "X$CMB_STATUS_ALIGNMENT" != "X" ; then
AC_DEFINE(HAVE_C_MULTI_ATTR_ALIAS, 1,
[Define if multiple __attribute__((alias)) are supported])
fi
fi
fi
# Get the ADDRESS_KIND and OFFSET_KIND if possible
#
# For Fortran 90, we'll also need MPI_ADDRESS_KIND and MPI_OFFSET_KIND
......
......@@ -308,6 +308,8 @@ else
libtoolize=${LIBTOOLIZE:-libtoolize}
fi
# FIXME: "which xxx" determines xxx in user's PATH
# but not necessarily what is being used here in this script
autoconfdir=`which autoconf | sed -e 's_/[^/]*$__g'`
automakedir=`which automake | sed -e 's_/[^/]*$__g'`
libtooldir=`which libtool | sed -e 's_/[^/]*$__g'`
......
......@@ -98,11 +98,7 @@ struct mpif_cmblk1_t_ {
MPI_Fint MPIF_STATUS_IGNORE[MPIF_STATUS_SIZE];
};
typedef struct mpif_cmblk1_t_ mpif_cmblk1_t;
#if defined(HAVE_C_ATTR_ALIGNED)
mpif_cmblk1_t mpifcmb1r __attribute__((aligned)) = {0};
#else
mpif_cmblk1_t mpifcmb1r = {0};
#endif
mpif_cmblk1_t mpifcmb1r @CMB_STATUS_ALIGNMENT@ = {0};
extern mpif_cmblk1_t _CMPIFCMB1 __attribute__ ((alias("mpifcmb1r")));
extern mpif_cmblk1_t MPIFCMB1 __attribute__ ((alias("mpifcmb1r")));
extern mpif_cmblk1_t MPIFCMB1_ __attribute__ ((alias("mpifcmb1r")));
......@@ -114,11 +110,7 @@ struct mpif_cmblk2_t_ {
MPI_Fint MPIF_STATUSES_IGNORE[1][MPIF_STATUS_SIZE];
};
typedef struct mpif_cmblk2_t_ mpif_cmblk2_t;
#if defined(HAVE_C_ATTR_ALIGNED)
mpif_cmblk2_t mpifcmb2r __attribute__((aligned)) = {0};
#else
mpif_cmblk2_t mpifcmb2r = {0};
#endif
mpif_cmblk2_t mpifcmb2r @CMB_STATUS_ALIGNMENT@ = {0};
extern mpif_cmblk2_t _CMPIFCMB2 __attribute__ ((alias("mpifcmb2r")));
extern mpif_cmblk2_t MPIFCMB2 __attribute__ ((alias("mpifcmb2r")));
extern mpif_cmblk2_t MPIFCMB2_ __attribute__ ((alias("mpifcmb2r")));
......@@ -130,11 +122,7 @@ struct mpif_cmblk3_t_ {
MPI_Fint MPIF_BOTTOM;
};
typedef struct mpif_cmblk3_t_ mpif_cmblk3_t;
#if defined(HAVE_C_ATTR_ALIGNED)
mpif_cmblk3_t mpifcmb3r __attribute__((aligned)) = {0};
#else
mpif_cmblk3_t mpifcmb3r = {0};
#endif
mpif_cmblk3_t mpifcmb3r @CMB_1INT_ALIGNMENT@ = {0};
extern mpif_cmblk3_t _CMPIFCMB3 __attribute__ ((alias("mpifcmb3r")));
extern mpif_cmblk3_t MPIFCMB3 __attribute__ ((alias("mpifcmb3r")));
extern mpif_cmblk3_t MPIFCMB3_ __attribute__ ((alias("mpifcmb3r")));
......@@ -146,11 +134,7 @@ struct mpif_cmblk4_t_ {
MPI_Fint MPIF_IN_PLACE;
};
typedef struct mpif_cmblk4_t_ mpif_cmblk4_t;
#if defined(HAVE_C_ATTR_ALIGNED)
mpif_cmblk4_t mpifcmb4r __attribute__((aligned)) = {0};
#else
mpif_cmblk4_t mpifcmb4r = {0};
#endif
mpif_cmblk4_t mpifcmb4r @CMB_1INT_ALIGNMENT@ = {0};
extern mpif_cmblk4_t _CMPIFCMB4 __attribute__ ((alias("mpifcmb4r")));
extern mpif_cmblk4_t MPIFCMB4 __attribute__ ((alias("mpifcmb4r")));
extern mpif_cmblk4_t MPIFCMB4_ __attribute__ ((alias("mpifcmb4r")));
......@@ -162,11 +146,7 @@ struct mpif_cmblk5_t_ {
MPI_Fint MPIF_ERRCODES_IGNORE[1];
};
typedef struct mpif_cmblk5_t_ mpif_cmblk5_t;
#if defined(HAVE_C_ATTR_ALIGNED)
mpif_cmblk5_t mpifcmb5r __attribute__((aligned)) = {0};
#else
mpif_cmblk5_t mpifcmb5r = {0};
#endif
mpif_cmblk5_t mpifcmb5r @CMB_1INT_ALIGNMENT@ = {0};
extern mpif_cmblk5_t _CMPIFCMB5 __attribute__ ((alias("mpifcmb5r")));
extern mpif_cmblk5_t MPIFCMB5 __attribute__ ((alias("mpifcmb5r")));
extern mpif_cmblk5_t MPIFCMB5_ __attribute__ ((alias("mpifcmb5r")));
......@@ -179,11 +159,7 @@ struct mpif_cmblk7_t_ {
char pads[3];
};
typedef struct mpif_cmblk7_t_ mpif_cmblk7_t;
#if defined(HAVE_C_ATTR_ALIGNED)
mpif_cmblk7_t mpifcmb7r __attribute__((aligned)) = {0};
#else
mpif_cmblk7_t mpifcmb7r = {0};
#endif
mpif_cmblk7_t mpifcmb7r @CMB_1INT_ALIGNMENT@ = {0};
extern mpif_cmblk7_t _CMPIFCMB7 __attribute__ ((alias("mpifcmb7r")));
extern mpif_cmblk7_t MPIFCMB7 __attribute__ ((alias("mpifcmb7r")));
extern mpif_cmblk7_t MPIFCMB7_ __attribute__ ((alias("mpifcmb7r")));
......@@ -196,11 +172,7 @@ struct mpif_cmblk8_t_ {
char pads[3];
};
typedef struct mpif_cmblk8_t_ mpif_cmblk8_t;
#if defined(HAVE_C_ATTR_ALIGNED)
mpif_cmblk8_t mpifcmb8r __attribute__((aligned)) = {0};
#else
mpif_cmblk8_t mpifcmb8r = {0};
#endif
mpif_cmblk8_t mpifcmb8r @CMB_1INT_ALIGNMENT@ = {0};
extern mpif_cmblk8_t _CMPIFCMB8 __attribute__ ((alias("mpifcmb8r")));
extern mpif_cmblk8_t MPIFCMB8 __attribute__ ((alias("mpifcmb8r")));
extern mpif_cmblk8_t MPIFCMB8_ __attribute__ ((alias("mpifcmb8r")));
......
......@@ -74,10 +74,12 @@ AC_PATH_PROGS_FEATURE_CHECK(NM_G, nm, [
AC_LANG_POP(C)
]) dnl Endof AC_DEFUN([PAC_PATH_NM_G]
dnl
dnl PAC_C_MULTI_ATTR_ALIAS()
dnl
dnl The checks if multiple __attribute__((alias)) is available
dnl If the multiple __attribute((alias)) support is found,
dnl pac_c_multi_attr_alias=yes is set.
dnl
dnl The checks if Multiple __attribute__((alias)) is available
dnl If the multiple __attribute((alias)) support is there,
dnl define(HAVE_C_MULTI_ATTR_ALIAS) and pac_c_multi_attr_alias=yes.
dnl The default is to do a runtime test. When cross_compiling=yes,
dnl pac_path_NM_G will be used to determine the test result.
dnl If CFLAGS(or CPPFLAGS) contains ATTR_ALIAS_DEBUG, the runtime will print
......@@ -241,8 +243,6 @@ if test "$pac_c_attr_alias_main" = "yes" ; then
if test "$diff_addrs" != "yes" ; then
dnl echo "Same addresses. Multiple aliases support"
AC_MSG_RESULT([${NM_G} says yes])
AC_DEFINE(HAVE_C_MULTI_ATTR_ALIAS, 1,
[Define if multiple __attribute__((alias)) are supported])
pac_c_multi_attr_alias=yes
else
dnl echo "Different addresses. No multiple aliases support."
......@@ -260,8 +260,6 @@ if test "$pac_c_attr_alias_main" = "yes" ; then
fi
if test "$pac_c_attr_alias_val" -eq 1 ; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_C_MULTI_ATTR_ALIAS, 1,
[Define if multiple __attribute__((alias)) are supported])
pac_c_multi_attr_alias=yes
else
AC_MSG_RESULT(no)
......@@ -281,8 +279,10 @@ AC_LANG_POP(C)
]) dnl Endof AC_DEFUN([PAC_C_MULTI_ATTR_ALIAS]
dnl
dnl Check if __attribute__((aligned)) is supported.
dnl If so, define HAVE_C_ATTR_ALIGNED and set pac_c_attr_aligned=yes.
dnl PAC_C_ATTR_ALIGNED()
dnl
dnl Check if __attribute__((aligned)) support is there.
dnl If so, set pac_c_attr_aligned=yes.
dnl
dnl Do a link test instead of compile test to check if the linker
dnl would emit an error.
......@@ -298,12 +298,207 @@ typedef struct mpif_cmblk_t_ mpif_cmblk_t;
mpif_cmblk_t mpifcmbr __attribute__((aligned)) = {0};
],[])
],[pac_c_attr_aligned=yes], [pac_c_attr_aligned=no])
if test "$pac_c_attr_aligned" = "yes" ; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_C_ATTR_ALIGNED,1,
[Define if __attribute__((aligned)) is supported.])
AC_MSG_RESULT([$pac_c_attr_aligned])
AC_LANG_POP(C)
])
dnl
dnl PAC_F2C_ATTR_ALIGNED_SIZE(ARRAY_SIZE, [OUTPUT_VAR], [MIN_ALIGNMENT])
dnl
dnl ARRAY_SIZE : Size of the integer array within the fortran commmon block.
dnl OUTPUT_VAR : Optional variable to be set.
dnl if test succeeds, set OUTPUT_VAR=$pac_f2c_attr_aligned_str.
dnl if test fails, set OUTPUT_VAR="unknown".
dnl MIN_ALIGNMENT : Optional value.
dnl Minimum alignment size to be used in OUTPUT_VAR.
dnl pac_f2c_attr_aligned_str won't be modified.
dnl
dnl "pac_f2c_attr_aligned_str" will be set with
dnl 1) __attribute__((aligned(ALIGNMENT_SIZE))),
dnl 2) __attribute__((aligned)).
dnl 3) "", i.e. empty string.
dnl
dnl 2) means the test can't find a good alignment value, but both the Fortran
dnl and C compilers are OK with "aligned" which in principle means the C
dnl compiler will pick the maximum useful alignment supported by the
dnl architecture.
dnl 3) means that the test has failed to find the alignment.
dnl
AC_DEFUN([PAC_F2C_ATTR_ALIGNED_SIZE],[
cmblksize=$1
AC_MSG_CHECKING([the minimum alignment of Fortran common block of $cmblksize integers])
dnl To find the minmium alignment of Fortran common block (of integer array)
dnl as seen by C object file, C object files of various (typical) alignments
dnl are linked to the Fortran code using the common block of integer array.
#
dnl Since the incorrect alignment results only a warning messages from the
dnl fortran compiler(or linker), so we use "diff" to compare the fortran
dnl compiler/linker output. We cannot use AC_LANG_WERROR,
dnl i.e. ac_fc_werror_flag=yes, because compiler like pgf77 at version 10.x)
dnl has non-zero stderr output if a fortran program is used in the linking.
dnl The stderr contains the name of fortran program even if the linking is
dnl successful. We could avoid the non-zero stderr output in pgf77 by
dnl compiling everthing into object files and linking all the object files
dnl with pgf77. Doing that would need us to use AC_TRY_EVAL instead of
dnl AC_LINK_IFELSE, so "diff" approach is used instead.
#
dnl Using diff of compiler(linker) output requires a reference output file
dnl as the base of diff. The process of creating this reference output file
dnl has to be exactly the same as the testing process, because pgf77 has
dnl the following weird behavour
dnl pgf77 -o ftest ftest.f => when $?=0 with zero stderr output
dnl pgf77 -o ftest ftest.f dummy.o => when $?=0 with non-zero stderr output.
dnl stderr has "ftest.f:".
dnl
# First create a fortran CONFTEST which will be used repeatedly.
AC_LANG_PUSH([Fortran]) dnl AC_LANG_PUSH([Fortran 77])
AC_LANG_CONFTEST([
AC_LANG_SOURCE([
program fconftest
integer isize
parameter (isize=$cmblksize)
integer status_array(isize)
common /mpifcmb/ status_array
save /mpifcmb/
end
])
])
AC_LANG_POP([Fortran]) dnl AC_LANG_POP([Fortran 77])
dnl
dnl
dnl
# Compile a C dummy.$OBJEXT and link with Fortran test program to create
# a reference linker output file, pac_align0.log, as the base of "diff".
AC_LANG_PUSH([C])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],[
cp conftest.$ac_ext pac_conftest.c
PAC_RUNLOG([mv conftest.$OBJEXT pac_conftest.$OBJEXT])
saved_LIBS="$LIBS"
LIBS="pac_conftest.$OBJEXT $LIBS"
AC_LANG_PUSH([Fortran]) dnl AC_LANG_PUSH([Fortran 77])
saved_ac_link="$ac_link"
ac_link="`echo $saved_ac_link | sed -e 's|>.*$|> $pac_logfile 2>\&1|g'`"
pac_logfile="pac_align0.log"
rm -f $pac_logfile
AC_LINK_IFELSE([],[
pac_f2c_alignedn_diffbase=yes
],[
pac_f2c_alignedn_diffbase=no
])
# Be sure NOT to remove the conftest.f which is still needed for later use.
# rm -f conftest.$ac_ext
# Restore everything in autoconf that has been overwritten
ac_link="$saved_ac_link"
# restore previously saved LIBS
LIBS="$saved_LIBS"
AC_LANG_POP([Fortran]) dnl AC_LANG_POP([Fortran 77])
],[
pac_f2c_alignedn_diffbase=no
])
AC_LANG_POP([C])
dnl
dnl
if test "$pac_f2c_alignedn_diffbase" = "yes" ; then
# Initialize pac_result_str to empty string since part of the test
# depends on pac_result_str is empty or non-empty string.
pac_result_str=""
# Initialize pac_f2c_attr_aligned_str to empty string and
# it will remain as empty string if the following test fails.
pac_f2c_attr_aligned_str=""
for asize in 4 8 16 32 64 128 max ; do
if test "$asize" != "max" ; then
pac_attr_aligned_str="__attribute__((aligned($asize)))"
else
pac_attr_aligned_str="__attribute__((aligned))"
fi
AC_LANG_PUSH([C])
#Compile the __attribute__ object file.
AC_COMPILE_IFELSE([
AC_LANG_SOURCE([
changequote(,)
struct mpif_cmblk_t_ { int imembers[$cmblksize]; };
changequote([,])
typedef struct mpif_cmblk_t_ mpif_cmblk_t;
mpif_cmblk_t mpifcmbr $pac_attr_aligned_str = {0};
extern mpif_cmblk_t _CMPIFCMB __attribute__ ((alias("mpifcmbr")));
extern mpif_cmblk_t MPIFCMB __attribute__ ((alias("mpifcmbr")));
extern mpif_cmblk_t MPIFCMB_ __attribute__ ((alias("mpifcmbr")));
extern mpif_cmblk_t _Cmpifcmb __attribute__ ((alias("mpifcmbr")));
extern mpif_cmblk_t mpifcmb __attribute__ ((alias("mpifcmbr")));
extern mpif_cmblk_t mpifcmb_ __attribute__ ((alias("mpifcmbr")));
])
],[
cp conftest.$ac_ext pac_conftest.c
PAC_RUNLOG([mv conftest.$OBJEXT pac_conftest.$OBJEXT])
saved_LIBS="$LIBS"
LIBS="pac_conftest.$OBJEXT $LIBS"
AC_LANG_PUSH([Fortran]) dnl AC_LANG_PUSH([Fortran 77])
saved_ac_link="$ac_link"
ac_link="`echo $saved_ac_link | sed -e 's|>.*$|> $pac_logfile 2>\&1|g'`"
pac_logfile="pac_align1.log"
rm -f $pac_logfile
# Use conftest.f created in CONFTEST.
AC_LINK_IFELSE([],[
PAC_RUNLOG_IFELSE([diff -b pac_align0.log pac_align1.log],[
pac_attr_alignedn=yes
],[
pac_attr_alignedn=no
cat $pac_logfile >&AS_MESSAGE_LOG_FD
echo "failed C program was:" >&AS_MESSAGE_LOG_FD
cat pac_conftest.c >&AS_MESSAGE_LOG_FD
echo "failed Fortran program was:" >&AS_MESSAGE_LOG_FD
cat conftest.$ac_ext >&AS_MESSAGE_LOG_FD
])
],[
pac_attr_alignedn=no
])
# Restore everything in autoconf that has been overwritten
ac_link="$saved_ac_link"
# restore previously saved LIBS
LIBS="$saved_LIBS"
AC_LANG_POP([Fortran]) dnl AC_LANG_POP([Fortran 77])
# remove previously generated object file and C file.
rm -f pac_conftest.$OBJEXT pac_conftest.c
rm -f $pac_logfile
if test "$pac_attr_alignedn" = yes ; then
ifelse([$3],[],[
pac_result_str="$asize"
pac_f2c_attr_aligned_str="$pac_attr_aligned_str"
break
],[
if test "$asize" != "max" -a "$asize" -lt "$3" ; then
if test "X$pac_result_str" = "X" ; then
pac_result_str="$asize"
pac_f2c_attr_aligned_str="$pac_attr_aligned_str"
fi
continue
else
pac_f2c_attr_aligned_str="$pac_attr_aligned_str"
if test "X$pac_result_str" != "X" ; then
pac_result_str="$pac_result_str, too small! reset to $asize"
else
pac_result_str="$asize"
fi
break
fi
])
fi
], [