This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

mips: omit initialization of $gp and stack allocation when possible


This patch improves the code generated by GCC on mips for functions
that don't need $gp to be set.  It also documents a number of things
that formerly went unexplained about stack allocation and $gp slot
assignment, and cleans up some gunk that had piled up with the
confusion of ABIs in the mips back-end.  This was tested on
mips64-linux-gnu and mips-sgi-irix6.5.  Ok to install?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva at redhat dot com>

	* config/mips/mips-protos.h (mips_rtx_may_use_gp_p): Declare.
	* config/mips/mips.c (mips_rtx_may_use_gp_p,
	mips_cfun_may_need_gp_p): New functions.
	(struct machine_function): Added checked_gp.
	(struct mips_frame_info): Drop extra_size.
	(compute_frame_size): Likewise.  Compute initial args_size from
	STARTING_FRAME_OFFSET.  Don't add $gp space to gp_reg_size on O32
	or O64.  Try to recover the $gp stack slot reserved by
	STARTING_FRAME_OFFSET.  Move the forcing of args_size to non-zero
	down, after the final value is computed, and compute total_size
	after that.
	(save_restore_insns): Do not save $gp in O32 or O64, and do
	not skip its stack slot.
	(mips_output_function_prologue): Compute extra_size from args_size
	and outgoing_args_size.  Save $gp right after outgoing args area
	on O32 and O64 again.  Initialize gp only if needed.  Adjust
	computation of .cprestore stack slot.
	(mips_expand_prologue): Initialize gp only if needed.
	* config/mips/mips.md (movsi, movdi, movhi, movqi, movsf, movdf):
	Set current_function_uses_pic_offset_table if operands introduce
	use of gp.
	* config/mips/mips.h (STARTING_FRAME_OFFSET): Reserve stack slot
	for $gp only on O32 and O64.

Index: gcc/config/mips/mips-protos.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/mips/mips-protos.h,v
retrieving revision 1.33
diff -u -p -r1.33 mips-protos.h
--- gcc/config/mips/mips-protos.h 31 Jan 2003 23:34:15 -0000 1.33
+++ gcc/config/mips/mips-protos.h 24 Mar 2003 04:43:09 -0000
@@ -1,6 +1,6 @@
 /* Prototypes of target machine for GNU compiler.  MIPS version.
    Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2001, 2002 Free Software Foundation, Inc.
+   1999, 2001, 2002, 2003 Free Software Foundation, Inc.
    Contributed by A. Lichnewsky (lich at inria dot inria dot fr).
    Changed by Michael Meissner	(meissner at osf dot org).
    64 bit r4000 support by Ian Lance Taylor (ian at cygnus dot com) and
@@ -166,5 +166,7 @@ extern rtx		gen_int_relational PARAMS ((
 						    rtx,int *));
 extern void		gen_conditional_branch PARAMS ((rtx *, enum rtx_code));
 #endif
+
+extern bool		mips_rtx_may_use_gp_p PARAMS ((rtx, int));
 
 #endif /* ! GCC_MIPS_PROTOS_H */
Index: gcc/config/mips/mips.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/mips/mips.c,v
retrieving revision 1.252
diff -u -p -r1.252 mips.c
--- gcc/config/mips/mips.c 19 Feb 2003 18:03:09 -0000 1.252
+++ gcc/config/mips/mips.c 24 Mar 2003 04:43:16 -0000
@@ -106,6 +106,7 @@ static rtx mips_frame_set			PARAMS ((enu
 							 int, int));
 static void mips_emit_frame_related_store	PARAMS ((rtx, rtx,
 							 HOST_WIDE_INT));
+static bool mips_cfun_may_need_gp_p PARAMS ((void));
 static void save_restore_insns			PARAMS ((int, rtx, long));
 static void mips16_output_gp_offset		PARAMS ((FILE *, rtx));
 static void mips16_fp_args			PARAMS ((FILE *, int, int));
@@ -167,7 +168,6 @@ struct mips_frame_info GTY(())
   long total_size;		/* # bytes that the entire frame takes up */
   long var_size;		/* # bytes that variables take up */
   long args_size;		/* # bytes that outgoing arguments take up */
-  long extra_size;		/* # bytes of extra gunk */
   int  gp_reg_size;		/* # bytes needed to store gp regs */
   int  fp_reg_size;		/* # bytes needed to store fp regs */
   long mask;			/* mask of saved gp registers */
@@ -196,6 +196,13 @@ struct machine_function GTY(()) {
 
   /* Length of instructions in function; mips16 only.  */
   long insns_len;
+
+  /* Whether the function has been scanned for (possibly implicit)
+     uses of gp.  This is only set if no matches have initially been
+     found, and it serves as a negative cache as long as
+     current_function_uses_pic_offset_table (that may be set post-scan
+     by reload-generated mov patterns) is not set.  */
+  bool checked_gp;
 };
 
 /* Information about a single argument.  */
@@ -6917,6 +6924,132 @@ mips_declare_object (stream, name, init_
     }
 }
 
+
+/* Test whether X references $gp, explicitly or implicitly.  The
+   latter may be a bit too conservative.  BRANCH_TARGET should be 0,
+   unless this expression is a value being assigned to PC in a
+   branch.  */
+
+bool
+mips_rtx_may_use_gp_p (x, branch_target)
+     rtx x;
+     int branch_target;
+{
+  RTX_CODE code;
+  int i;
+  const char *fmt;
+
+  if (! x)
+    return false;
+
+  code = GET_CODE (x);
+  
+  switch (code)
+    {
+      /* Check branch targets especially.  */
+    case SET:
+      if (SET_DEST (x) != pc_rtx)
+	break;
+      return mips_rtx_may_use_gp_p (SET_SRC (x), 1);
+
+      /* Propagate branch_target to the THEN and ELSE parts of an
+	 IF_THEN_ELSE, but not to the conditional expression.  */
+    case IF_THEN_ELSE:
+      return mips_rtx_may_use_gp_p (XEXP (x, 0), 0)
+	|| mips_rtx_may_use_gp_p (XEXP (x, 1), branch_target)
+	|| mips_rtx_may_use_gp_p (XEXP (x, 2), branch_target);
+      
+    case PC:
+    case LABEL_REF:
+      if (branch_target)
+	return false;
+      /* Fall through.  */
+    case SYMBOL_REF:
+      return true;
+      /* This should be implied by regs_ever_live at function stream
+	 scanning time, but not when scanning reload-generated move
+	 operands.  */
+    case REG:
+      return (REGNO (x) == PIC_OFFSET_TABLE_REGNUM);
+      break;
+    default:
+      break;
+    }
+
+  fmt = GET_RTX_FORMAT (code);
+  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+    if (fmt[i] == 'e')
+      {
+	if (mips_rtx_may_use_gp_p (XEXP (x, i), 0))
+	  return true;
+      }
+    else if (fmt[i] == 'E')
+      {
+	int j;
+	for (j = 0; j < XVECLEN (x, i); j++)
+	  if (mips_rtx_may_use_gp_p (XVECEXP (x, i, j), 0))
+	    return true;
+      }
+
+  return false;
+}
+
+/* Determine whether the function currently being compiled needs $gp
+   to be initialized.  */
+
+static bool
+mips_cfun_may_need_gp_p ()
+{
+  rtx insn;
+  
+  /* We only have to save/restore $gp for PIC.  */
+  if (! TARGET_ABICALLS)
+    return false;
+
+  if (current_function_uses_pic_offset_table)
+    return true;
+
+  if (cfun->machine->checked_gp)
+    return false;
+
+  /* If we find explicit uses of $gp, we'd better preserve.  Constant
+     pools and profiling calls also need $gp to be initialized.
+
+     Being overly conservative, we also assume that non-leaf functions
+     need $gp to be set, even though they might be able to do without
+     it should they only call other functions through pointers
+     received in arguments.  */
+  if (regs_ever_live[PIC_OFFSET_TABLE_REGNUM]
+      || current_function_uses_const_pool
+      || current_function_profile
+      || ! optimize)
+    {
+      /* Cache result where we test first.  */
+    cache_positive:
+      current_function_uses_pic_offset_table = 1;
+      return true;
+    }
+
+  /* Scan the instruction stream looking for any explicit or implicit
+     references to $gp.  Since this function may be called *many*
+     times for every function, and negative results aren't (and
+     shouldn't) be cached, if the function is larger than a certain
+     threshold, just assume it is used.  Hopefully the scheduler will
+     be able to hide the latency of the instructions.  */
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    {
+      if (! INSN_P (insn))
+	continue;
+
+      if (mips_rtx_may_use_gp_p (PATTERN (insn), 0))
+	goto cache_positive;
+    }
+
+  cfun->machine->checked_gp = true;
+
+  return false;
+}
+
 /* Return the bytes needed to compute the frame pointer from the current
    stack pointer.
 
@@ -6978,7 +7111,6 @@ compute_frame_size (size)
   HOST_WIDE_INT total_size;	/* # bytes that the entire frame takes up */
   HOST_WIDE_INT var_size;	/* # bytes that variables take up */
   HOST_WIDE_INT args_size;	/* # bytes that outgoing arguments take up */
-  HOST_WIDE_INT extra_size;	/* # extra bytes */
   HOST_WIDE_INT gp_reg_rounded;	/* # bytes needed to store gp after rounding */
   HOST_WIDE_INT gp_reg_size;	/* # bytes needed to store gp regs */
   HOST_WIDE_INT fp_reg_size;	/* # bytes needed to store fp regs */
@@ -6990,19 +7122,9 @@ compute_frame_size (size)
   fp_reg_size = 0;
   mask = 0;
   fmask	= 0;
-  extra_size = MIPS_STACK_ALIGN (((TARGET_ABICALLS) ? UNITS_PER_WORD : 0));
   var_size = MIPS_STACK_ALIGN (size);
-  args_size = MIPS_STACK_ALIGN (current_function_outgoing_args_size);
+  args_size = STARTING_FRAME_OFFSET;
 
-  /* The MIPS 3.0 linker does not like functions that dynamically
-     allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
-     looks like we are trying to create a second frame pointer to the
-     function, so allocate some stack space to make it happy.  */
-
-  if (args_size == 0 && current_function_calls_alloca)
-    args_size = 4 * UNITS_PER_WORD;
-
-  total_size = var_size + args_size + extra_size;
   return_type = DECL_RESULT (current_function_decl);
 
   /* Calculate space needed for gp registers.  */
@@ -7055,6 +7177,37 @@ compute_frame_size (size)
 	}
     }
 
+  if ((mask & (1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))) == 0
+      && mips_cfun_may_need_gp_p ())
+    {
+      /* Add the context-pointer to the saved registers.  */
+      mask |= 1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST);
+      /* In o32 and o64, since gp is call-clobbered, we keep its value
+	 right after the outgoing-arguments area, rather than in the
+	 register save area, such that the code to restore it after
+	 function calls (implicitly generated by .cprestore) is small
+	 even in functions with large frames.  We've already accounted
+	 for this space in STARTING_FRAME_OFFSET.  */
+      if (mips_abi != ABI_32 && mips_abi != ABI_O64)
+	gp_reg_size += UNITS_PER_WORD;
+    }
+
+  /* If there are no local variables, we may optimize away the space
+     reserved by STARTING_FRAME_OFFSET for $gp before we could tell we
+     wouldn't need it.  */
+  if ((mask & (1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))) == 0
+      && var_size == 0
+      && (mips_abi == ABI_32 || mips_abi == ABI_O64))
+    args_size -= MIPS_STACK_ALIGN (UNITS_PER_WORD);
+
+  /* The MIPS 3.0 linker does not like functions that dynamically
+     allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
+     looks like we are trying to create a second frame pointer to the
+     function, so allocate some stack space to make it happy.  */
+
+  if (args_size == 0 && current_function_calls_alloca)
+    args_size += MIPS_STACK_ALIGN (UNITS_PER_WORD);
+
   /* This loop must iterate over the same space as its companion in
      save_restore_insns.  */
   for (regno = (FP_REG_LAST - FP_INC + 1);
@@ -7069,26 +7222,8 @@ compute_frame_size (size)
     }
 
   gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
-  total_size += gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
-
-  /* The gp reg is caller saved in the 32 bit ABI, so there is no need
-     for leaf routines (total_size == extra_size) to save the gp reg.
-     The gp reg is callee saved in the 64 bit ABI, so all routines must
-     save the gp reg.  This is not a leaf routine if -p, because of the
-     call to mcount.  */
-  if (total_size == extra_size
-      && (mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI)
-      && ! current_function_profile)
-    total_size = extra_size = 0;
-  else if (TARGET_ABICALLS)
-    {
-      /* Add the context-pointer to the saved registers.  */
-      gp_reg_size += UNITS_PER_WORD;
-      mask |= 1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST);
-      total_size -= gp_reg_rounded;
-      gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
-      total_size += gp_reg_rounded;
-    }
+  total_size = var_size + args_size
+    + gp_reg_rounded + MIPS_STACK_ALIGN (fp_reg_size);
 
   /* Add in space reserved on the stack by the callee for storing arguments
      passed in registers.  */
@@ -7103,7 +7238,6 @@ compute_frame_size (size)
   cfun->machine->frame.total_size = total_size;
   cfun->machine->frame.var_size = var_size;
   cfun->machine->frame.args_size = args_size;
-  cfun->machine->frame.extra_size = extra_size;
   cfun->machine->frame.gp_reg_size = gp_reg_size;
   cfun->machine->frame.fp_reg_size = fp_reg_size;
   cfun->machine->frame.mask = mask;
@@ -7119,7 +7253,7 @@ compute_frame_size (size)
       /* When using mips_entry, the registers are always saved at the
          top of the stack.  */
       if (! mips_entry)
-	offset = (args_size + extra_size + var_size
+	offset = (args_size + var_size
 		  + gp_reg_size - GET_MODE_SIZE (gpr_mode));
       else
 	offset = total_size - GET_MODE_SIZE (gpr_mode);
@@ -7135,7 +7269,7 @@ compute_frame_size (size)
 
   if (fmask)
     {
-      unsigned long offset = (args_size + extra_size + var_size
+      unsigned long offset = (args_size + var_size
 			      + gp_reg_rounded + fp_reg_size
 			      - FP_INC * UNITS_PER_FPREG);
       cfun->machine->frame.fp_sp_offset = offset;
@@ -7290,7 +7424,6 @@ save_restore_insns (store_p, large_reg, 
 {
   long mask = cfun->machine->frame.mask;
   long fmask = cfun->machine->frame.fmask;
-  long real_mask = mask;
   int regno;
   rtx base_reg_rtx;
   HOST_WIDE_INT base_offset;
@@ -7302,9 +7435,9 @@ save_restore_insns (store_p, large_reg, 
       && ! BITSET_P (mask, HARD_FRAME_POINTER_REGNUM - GP_REG_FIRST))
     abort ();
 
-  /* Do not restore GP under certain conditions.  */
-  if (! store_p
-      && TARGET_ABICALLS
+  /* Do not save or restore GP in O32 or O64, since we use the area
+     just past the outgoing arguments for it.  */
+  if (TARGET_ABICALLS
       && (mips_abi == ABI_32 || mips_abi == ABI_O64))
     mask &= ~(1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST));
 
@@ -7419,11 +7552,9 @@ save_restore_insns (store_p, large_reg, 
 		    emit_move_insn (gen_rtx (REG, gpr_mode, regno),
 				    reg_rtx);
 		}
+
+	      gp_offset -= GET_MODE_SIZE (gpr_mode);
 	    }
-	  /* If the restore is being supressed, still take into account
-	     the offset at which it is stored.  */
-	  if (BITSET_P (real_mask, regno - GP_REG_FIRST))
-	    gp_offset -= GET_MODE_SIZE (gpr_mode);
 	}
     }
   else
@@ -7547,7 +7678,7 @@ mips_output_function_prologue (file, siz
     {
       /* .frame FRAMEREG, FRAMESIZE, RETREG */
       fprintf (file,
-	       "\t.frame\t%s,%ld,%s\t\t# vars= %ld, regs= %d/%d, args= %d, extra= %ld\n",
+	       "\t.frame\t%s,%ld,%s\t# vars= %ld, regs= %d/%d, args= %d, extra= %ld\n",
 	       (reg_names[(frame_pointer_needed)
 			  ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM]),
 	       ((frame_pointer_needed && TARGET_MIPS16)
@@ -7558,7 +7689,8 @@ mips_output_function_prologue (file, siz
 	       cfun->machine->frame.num_gp,
 	       cfun->machine->frame.num_fp,
 	       current_function_outgoing_args_size,
-	       cfun->machine->frame.extra_size);
+	       cfun->machine->frame.args_size
+	       - current_function_outgoing_args_size);
 
       /* .mask MASK, GPOFFSET; .fmask FPOFFSET */
       fprintf (file, "\t.mask\t0x%08lx,%ld\n\t.fmask\t0x%08lx,%ld\n",
@@ -7690,15 +7822,23 @@ mips_output_function_prologue (file, siz
   if (TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64))
     {
       const char *const sp_str = reg_names[STACK_POINTER_REGNUM];
+      bool set_gp = (cfun->machine->frame.mask
+		     & (1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))) != 0;
 
-      fprintf (file, "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n",
-	       reg_names[PIC_FUNCTION_ADDR_REGNUM]);
+      if (set_gp)
+	fprintf (file, "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n",
+		 reg_names[PIC_FUNCTION_ADDR_REGNUM]);
       if (tsize > 0)
 	{
 	  fprintf (file, "\t%s\t%s,%s,%ld\n",
 		   (Pmode == DImode ? "dsubu" : "subu"),
 		   sp_str, sp_str, (long) tsize);
-	  fprintf (file, "\t.cprestore %ld\n", cfun->machine->frame.args_size);
+	  if (set_gp)
+	    /* We reserve space for saving $gp right after the
+	       outgoing arguments area.  */
+	    fprintf (file, "\t.cprestore %ld\n",
+		     cfun->machine->frame.args_size
+		     - MIPS_STACK_ALIGN (UNITS_PER_WORD));
 	}
 
       if (dwarf2out_do_frame ())
@@ -8058,7 +8198,9 @@ mips_expand_prologue ()
 	    RTX_FRAME_RELATED_P (insn) = 1;
 	}
 
-      if (TARGET_ABICALLS && (mips_abi != ABI_32 && mips_abi != ABI_O64))
+      if (TARGET_ABICALLS && (mips_abi != ABI_32 && mips_abi != ABI_O64)
+	  && (cfun->machine->frame.mask
+	      & (1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))) != 0)
 	emit_insn (gen_loadgp (XEXP (DECL_RTL (current_function_decl), 0),
 			       gen_rtx_REG (DImode, 25)));
     }
Index: gcc/config/mips/mips.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/mips/mips.h,v
retrieving revision 1.241
diff -u -p -r1.241 mips.h
--- gcc/config/mips/mips.h 14 Mar 2003 15:53:48 -0000 1.241
+++ gcc/config/mips/mips.h 24 Mar 2003 04:43:20 -0000
@@ -2392,12 +2392,16 @@ extern enum reg_class mips_char_to_class
 /* #define FRAME_GROWS_DOWNWARD */
 
 /* Offset within stack frame to start allocating local variables at.
-   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
-   first local allocated.  Otherwise, it is the offset to the BEGINNING
-   of the first local allocated.  */
+   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the first
+   local allocated.  Otherwise, it is the offset to the BEGINNING of
+   the first local allocated.  Besides the space for outgoing
+   arguments, we reserve space to save $gp near the frame pointer in
+   o32 and o64.  We try to get that space back in compute_frame_size,
+   if there are no local variables.  */
 #define STARTING_FRAME_OFFSET						\
   (current_function_outgoing_args_size					\
-   + (TARGET_ABICALLS ? MIPS_STACK_ALIGN (UNITS_PER_WORD) : 0))
+   + (TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)	\
+      ? MIPS_STACK_ALIGN (UNITS_PER_WORD) : 0))
 
 /* Offset from the stack pointer register to an item dynamically
    allocated on the stack, e.g., by `alloca'.
Index: gcc/config/mips/mips.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/mips/mips.md,v
retrieving revision 1.163
diff -u -p -r1.163 mips.md
--- gcc/config/mips/mips.md 18 Feb 2003 23:24:23 -0000 1.163
+++ gcc/config/mips/mips.md 24 Mar 2003 04:43:23 -0000
@@ -5174,6 +5174,12 @@ move\\t%0,%z4\\n\\
   ""
   "
 {
+  if (reload_in_progress && TARGET_ABICALLS
+      && ! current_function_uses_pic_offset_table)
+    current_function_uses_pic_offset_table =
+      mips_rtx_may_use_gp_p (operands[0], 0)
+      || mips_rtx_may_use_gp_p (operands[1], 0);
+
   if (mips_split_addresses && mips_check_split (operands[1], DImode))
     {
       enum machine_mode mode = GET_MODE (operands[0]);
@@ -5625,6 +5631,12 @@ move\\t%0,%z4\\n\\
   ""
   "
 {
+  if (reload_in_progress && TARGET_ABICALLS
+      && ! current_function_uses_pic_offset_table)
+    current_function_uses_pic_offset_table =
+      mips_rtx_may_use_gp_p (operands[0], 0)
+      || mips_rtx_may_use_gp_p (operands[1], 0);
+
   if (mips_split_addresses && mips_check_split (operands[1], SImode))
     {
       enum machine_mode mode = GET_MODE (operands[0]);
@@ -6185,6 +6197,12 @@ move\\t%0,%z4\\n\\
   ""
   "
 {
+  if (reload_in_progress && TARGET_ABICALLS
+      && ! current_function_uses_pic_offset_table)
+    current_function_uses_pic_offset_table =
+      mips_rtx_may_use_gp_p (operands[0], 0)
+      || mips_rtx_may_use_gp_p (operands[1], 0);
+
   if ((reload_in_progress | reload_completed) == 0
       && !register_operand (operands[0], HImode)
       && !register_operand (operands[1], HImode)
@@ -6295,6 +6313,12 @@ move\\t%0,%z4\\n\\
   ""
   "
 {
+  if (reload_in_progress && TARGET_ABICALLS
+      && ! current_function_uses_pic_offset_table)
+    current_function_uses_pic_offset_table =
+      mips_rtx_may_use_gp_p (operands[0], 0)
+      || mips_rtx_may_use_gp_p (operands[1], 0);
+
   if ((reload_in_progress | reload_completed) == 0
       && !register_operand (operands[0], QImode)
       && !register_operand (operands[1], QImode)
@@ -6388,6 +6412,12 @@ move\\t%0,%z4\\n\\
   ""
   "
 {
+  if (reload_in_progress && TARGET_ABICALLS
+      && ! current_function_uses_pic_offset_table)
+    current_function_uses_pic_offset_table =
+      mips_rtx_may_use_gp_p (operands[0], 0)
+      || mips_rtx_may_use_gp_p (operands[1], 0);
+
   if ((reload_in_progress | reload_completed) == 0
       && !register_operand (operands[0], SFmode)
       && !nonmemory_operand (operands[1], SFmode))
@@ -6436,6 +6466,12 @@ move\\t%0,%z4\\n\\
   ""
   "
 {
+  if (reload_in_progress && TARGET_ABICALLS
+      && ! current_function_uses_pic_offset_table)
+    current_function_uses_pic_offset_table =
+      mips_rtx_may_use_gp_p (operands[0], 0)
+      || mips_rtx_may_use_gp_p (operands[1], 0);
+
   if ((reload_in_progress | reload_completed) == 0
       && !register_operand (operands[0], DFmode)
       && !nonmemory_operand (operands[1], DFmode))
-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                 aoliva at {redhat dot com, gcc.gnu.org}
CS PhD student at IC-Unicamp        oliva at {lsd dot ic dot unicamp dot br, gnu.org}
Free Software Evangelist                Professional serial bug killer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]