Hi,

the build of libgfortran and glibc for mips currently fails because we now 
evaluate
mips_compute_frame_info more often than before.  If any instruction uses
the predicate cprestore_save_slot_operand or cprestore_load_slot_operand
the function mips_cprestore_address_p calls mips_get_cprestore_base_and_offset
which needs valid data in frame->args_size and frame->hard_frame_pointer_offset,
but these are initialized after calling mips_global_pointer, which makes the 
function
get_attr_got raise an ICE.

This patch re-orders the frame structure initialization, to initialize the 
required data
before calling mips_global_pointer.

I built a cross-glibc and cross fortran and c++ compiler and verified that the 
ICE
is actually gone.

Is the patch ok for trunk?


Thanks
Bernd.
2015-12-27  Bernd Edlinger  <bernd.edlin...@hotmail.de>

        PR target/69012
        * config/mips/mips.c (mips_compute_frame_info): Move call to
        mips_global_pointer after initialization of args_size and
        hard_frame_pointer_offset.
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	(revision 231927)
+++ gcc/config/mips/mips.c	(working copy)
@@ -10347,8 +10347,6 @@ mips_compute_frame_info (void)
   memset (frame, 0, sizeof (*frame));
   size = get_frame_size ();
 
-  cfun->machine->global_pointer = mips_global_pointer ();
-
   /* The first two blocks contain the outgoing argument area and the $gp save
      slot.  This area isn't needed in leaf functions.  We can also skip it
      if we know that none of the called functions will use this space.
@@ -10377,6 +10375,17 @@ mips_compute_frame_info (void)
     }
   offset = frame->args_size + frame->cprestore_size;
 
+  /* MIPS16 code offsets the frame pointer by the size of the outgoing
+     arguments.  This tends to increase the chances of using unextended
+     instructions for local variables and incoming arguments.  */
+  if (TARGET_MIPS16)
+    frame->hard_frame_pointer_offset = frame->args_size;
+
+  /* The function mips_global_pointer walks all insns and some depend
+     on the predicate function mips_cprestore_address_p, which uses
+     frame->args_size and frame->hard_frame_pointer_offset.  */
+  cfun->machine->global_pointer = mips_global_pointer ();
+
   /* Move above the local variables.  */
   frame->var_size = MIPS_STACK_ALIGN (size);
   offset += frame->var_size;
@@ -10520,12 +10529,6 @@ mips_compute_frame_info (void)
     frame->acc_save_offset = frame->acc_sp_offset - offset;
   if (frame->num_cop0_regs > 0)
     frame->cop0_save_offset = frame->cop0_sp_offset - offset;
-
-  /* MIPS16 code offsets the frame pointer by the size of the outgoing
-     arguments.  This tends to increase the chances of using unextended
-     instructions for local variables and incoming arguments.  */
-  if (TARGET_MIPS16)
-    frame->hard_frame_pointer_offset = frame->args_size;
 }
 
 /* Return the style of GP load sequence that is being used for the

Reply via email to