This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: mips: omit initialization of $gp and stack allocation when possible
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 07 May 2003 16:31:55 -0300
- Subject: Re: mips: omit initialization of $gp and stack allocation when possible
- Organization: GCC Team, Red Hat
- References: <orfzpdtlnp.fsf@free.redhat.lsd.ic.unicamp.br><orel4mnsuw.fsf@free.redhat.lsd.ic.unicamp.br>
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