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]

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


On Apr  1, 2003, Alexandre Oliva <aoliva@redhat.com> wrote:

> On Mar 24, 2003, Alexandre Oliva <aoliva@redhat.com> wrote:
>> 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.

> There was a bug in the patch, that might cause it to recover the stack
> space reserved for $gp even when no such space was allocated, causing
> the frame size to potentially go negative.  Oops.  Thanks to Richard
> Sandiford for spotting it.  This revised patch fixes it.  It was
> tested on mips64-linux-gnu (also building a 32-bit kernel, which
> happened to trigger the bug) and mips-sgi-irix6.5.  Ok to install?

This is an updated version of the patch, such that it applies cleanly
after the merged from mips-rewrite-branch.  No changes other than
patch context.  Tested by bootstrapping on mips-sgi-irix6.5 with
native as and ld, and mips-sgi-irix6.5o32 with GNU as (for some reason
the native as didn't seem to like some %got expressions introduced
with the rewrite when assembling for -32).

Ok to install?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.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.37
diff -u -p -r1.37 mips-protos.h
--- gcc/config/mips/mips-protos.h 6 May 2003 11:23:41 -0000 1.37
+++ gcc/config/mips/mips-protos.h 7 May 2003 07:55:52 -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@inria.inria.fr).
    Changed by Michael Meissner	(meissner@osf.org).
    64 bit r4000 support by Ian Lance Taylor (ian@cygnus.com) and
@@ -175,5 +175,7 @@ extern rtx		gen_int_relational PARAMS ((
 extern void		gen_conditional_branch PARAMS ((rtx *, enum rtx_code));
 #endif
 extern rtx              mips_return_addr PARAMS ((int, rtx));
+
+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.260
diff -u -p -r1.260 mips.c
--- gcc/config/mips/mips.c 6 May 2003 11:23:42 -0000 1.260
+++ gcc/config/mips/mips.c 7 May 2003 07:55:58 -0000
@@ -237,6 +237,7 @@ static void mips_set_frame_expr			PARAMS
 static rtx mips_frame_set			PARAMS ((rtx, 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_fp_args			PARAMS ((FILE *, int, int));
 static void build_mips16_function_stub		PARAMS ((FILE *));
@@ -297,7 +298,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 */
@@ -326,6 +326,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.  */
@@ -6906,6 +6913,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.
 
@@ -6967,7 +7100,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 */
@@ -6979,19 +7111,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);
-
-  /* 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;
+  args_size = STARTING_FRAME_OFFSET;
 
-  total_size = var_size + args_size + extra_size;
   return_type = DECL_RESULT (current_function_decl);
 
   /* Calculate space needed for gp registers.  */
@@ -7044,6 +7166,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 && TARGET_ABICALLS
+      && (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);
@@ -7058,26 +7211,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.  */
@@ -7092,7 +7227,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;
@@ -7108,7 +7242,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);
@@ -7124,7 +7258,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;
@@ -7286,7 +7420,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;
@@ -7298,9 +7431,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));
 
@@ -7415,11 +7548,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
@@ -7543,7 +7674,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)
@@ -7554,7 +7685,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",
@@ -7686,15 +7818,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",
 		   (ptr_mode == 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 ())
@@ -8052,7 +8192,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.247
diff -u -p -r1.247 mips.h
--- gcc/config/mips/mips.h 6 May 2003 11:23:42 -0000 1.247
+++ gcc/config/mips/mips.h 7 May 2003 07:56:02 -0000
@@ -2471,12 +2471,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.166
diff -u -p -r1.166 mips.md
--- gcc/config/mips/mips.md 6 May 2003 11:23:42 -0000 1.166
+++ gcc/config/mips/mips.md 7 May 2003 07:56:05 -0000
@@ -5051,6 +5051,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_legitimize_move (DImode, operands[0], operands[1]))
     DONE;
 
@@ -5364,6 +5370,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_legitimize_move (SImode, operands[0], operands[1]))
     DONE;
 
@@ -5837,6 +5849,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)
@@ -5962,6 +5980,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)
@@ -6057,6 +6081,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))
@@ -6105,6 +6135,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@{redhat.com, gcc.gnu.org}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.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]