[m-rev.] for review: workaround bug #307
Julien Fischer
jfischer at opturion.com
Thu Jan 9 03:15:42 AEDT 2014
For review by anyone.
Branches: master, 14.01
(This diff could also be applied to the 13.05 branch if required.)
---------------------
Add a workaround for bug #307.
We encounter internal errors in GCC 4.8.2 on i686 Linux when compiling
runtime/mercury_ho_call.c in grades that use global registers when -fpic is
enabled. This change adds a test to configure to check whether GCC 4.8.X is
broken in this way and, if so, forces the use of `none' as the LLDS base grade.
I've looked for combination of GCC options that avoid the above problem, but
the only one that seems to have any affect is -fomit-frame-pointer, which is
one that we are required to disable on i686 anyway. (Compiling at -O0 also
avoids the problem -- I'll look into compiling just runtime/mercury_ho_call.c
with that separately.)
configure.ac:
As above.
Julien.
diff --git a/configure.ac b/configure.ac
index 07c5a18..8bdc7af 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2760,6 +2760,84 @@ CC="$save_CC"
#-----------------------------------------------------------------------------#
+# Compiling runtime/mercury_ho_call.c with -fpic enabled causes an internal
+# error in GCC 4.8.2 on i*86 Linux when global registers are enabled.
+# The following test checks if GCC is broken in this way -- if it is then
+# we disable the use of all GCC extensions. Doing so is the best means of
+# ensuring that the installation succeeds.
+
+case "$host" in i*86-*linux*)
+
+ case "$C_COMPILER_TYPE" in
+ gcc_4_8*)
+ AC_MSG_CHECKING([whether we can use global registers with -fpic])
+
+cat > conftest.c << EOF
+
+ typedef struct {
+ void *MR_closure_code;
+ unsigned int MR_closure_num_hidden_args_rf;
+ unsigned int MR_closure_hidden_args_0[0];
+ } MR_Closure;
+
+ typedef struct MR_mercury_engine_struct {
+ unsigned int MR_eng_fake_reg[1044];
+ } MercuryEngine;
+
+ register unsigned int MR_mr0 __asm__("esi");
+ register unsigned int MR_mr1 __asm__("edi");
+
+ extern unsigned int MR_real_r_reg_map[32];
+ extern MercuryEngine MR_engine_base;
+
+ void *mercury__do_call_closure_compact(void);
+
+ void* mercury__do_call_closure_compact(void)
+ {
+ MR_Closure *closure;
+ int num_hidden_r_args;
+
+ int i;
+
+ closure = (MR_Closure *) MR_engine_base.MR_eng_fake_reg[2];
+ num_hidden_r_args = closure->MR_closure_num_hidden_args_rf & 0xffff;
+
+ for (i = 1; i <= num_hidden_r_args; i++) {
+ if (i > 32) {
+ MR_engine_base.MR_eng_fake_reg[i + 19] =
+ closure->MR_closure_hidden_args_0[i - 1];
+
+ } else {
+ MR_engine_base.MR_eng_fake_reg[MR_real_r_reg_map[i - 1]] =
+ closure->MR_closure_hidden_args_0[i - 1];
+ }
+ }
+ return closure->MR_closure_code;
+ }
+
+EOF
+ if $CC -c -O1 -fno-omit-frame-pointer -fpic conftest.c \
+ >&AC_FD_CC 2>&1
+ then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ # If the above test failed the force the use of `none' as the
+ # LLDS base grade.
+ mercury_cv_asm_labels=no
+ mercury_cv_gcc_labels=no
+ mercury_cv_gcc_model_fast=no
+ mercury_cv_gcc_model_reg=no
+ mercury_cv_gcc_model_labels=no
+ fi
+ rm -f conftest*
+ ;;
+ esac
+ ;;
+esac
+
+#-----------------------------------------------------------------------------#
+
AC_MSG_CHECKING(whether we can support profiling on this system)
AC_CACHE_VAL(mercury_cv_profiling,
AC_TRY_CPP([
More information about the reviews
mailing list