mips.c (mips16_optimize_gp): Delete.
* config/mips/mips.c (mips16_optimize_gp): Delete. (mips_reorg): Don't call it. From-SVN: r76623
This commit is contained in:
parent
f210a0077b
commit
6865f4cd9f
|
@ -1,3 +1,8 @@
|
|||
2004-01-26 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
* config/mips/mips.c (mips16_optimize_gp): Delete.
|
||||
(mips_reorg): Don't call it.
|
||||
|
||||
2004-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
|
||||
|
||||
* config/c4x/c4x.md (addqi3_noclobber): Move up pecking order.
|
||||
|
|
|
@ -267,7 +267,6 @@ static rtx mips_return_fpr_pair (enum machine_mode mode,
|
|||
static rtx mips16_gp_pseudo_reg (void);
|
||||
static void mips16_fp_args (FILE *, int, int);
|
||||
static void build_mips16_function_stub (FILE *);
|
||||
static void mips16_optimize_gp (void);
|
||||
static rtx add_constant (struct constant **, rtx, enum machine_mode);
|
||||
static void dump_constants (struct constant *, rtx);
|
||||
static rtx mips_find_symbol (rtx);
|
||||
|
@ -8306,223 +8305,6 @@ build_mips16_call_stub (rtx retval, rtx fn, rtx arg_size, int fp_code)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* This function looks through the code for a function, and tries to
|
||||
optimize the usage of the $gp register. We arrange to copy $gp
|
||||
into a pseudo-register, and then let gcc's normal reload handling
|
||||
deal with the pseudo-register. Unfortunately, if reload choose to
|
||||
put the pseudo-register into a call-clobbered register, it will
|
||||
emit saves and restores for that register around any function
|
||||
calls. We don't need the saves, and it's faster to copy $gp than
|
||||
to do an actual restore. ??? This still means that we waste a
|
||||
stack slot.
|
||||
|
||||
This is an optimization, and the code which gcc has actually
|
||||
generated is correct, so we do not need to catch all cases. */
|
||||
|
||||
static void
|
||||
mips16_optimize_gp (void)
|
||||
{
|
||||
rtx gpcopy, slot, insn;
|
||||
|
||||
/* Look through the instructions. Set GPCOPY to the register which
|
||||
holds a copy of $gp. Set SLOT to the stack slot where it is
|
||||
saved. If we find an instruction which sets GPCOPY to anything
|
||||
other than $gp or SLOT, then we can't use it. If we find an
|
||||
instruction which sets SLOT to anything other than GPCOPY, we
|
||||
can't use it. */
|
||||
|
||||
gpcopy = NULL_RTX;
|
||||
slot = NULL_RTX;
|
||||
for (insn = get_insns (); insn != NULL_RTX; insn = next_active_insn (insn))
|
||||
{
|
||||
rtx set;
|
||||
|
||||
if (! INSN_P (insn))
|
||||
continue;
|
||||
|
||||
set = PATTERN (insn);
|
||||
|
||||
/* We know that all references to memory will be inside a SET,
|
||||
because there is no other way to access memory on the mips16.
|
||||
We don't have to worry about a PARALLEL here, because the
|
||||
mips.md file will never generate them for memory references. */
|
||||
if (GET_CODE (set) != SET)
|
||||
continue;
|
||||
|
||||
if (gpcopy == NULL_RTX
|
||||
&& GET_CODE (SET_SRC (set)) == CONST
|
||||
&& XEXP (SET_SRC (set), 0) == pic_offset_table_rtx
|
||||
&& GET_CODE (SET_DEST (set)) == REG)
|
||||
gpcopy = SET_DEST (set);
|
||||
else if (slot == NULL_RTX
|
||||
&& gpcopy != NULL_RTX
|
||||
&& GET_CODE (SET_DEST (set)) == MEM
|
||||
&& GET_CODE (SET_SRC (set)) == REG
|
||||
&& REGNO (SET_SRC (set)) == REGNO (gpcopy))
|
||||
{
|
||||
rtx base, offset;
|
||||
|
||||
offset = const0_rtx;
|
||||
base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
|
||||
if (GET_CODE (base) == REG
|
||||
&& (REGNO (base) == STACK_POINTER_REGNUM
|
||||
|| REGNO (base) == FRAME_POINTER_REGNUM))
|
||||
slot = SET_DEST (set);
|
||||
}
|
||||
else if (gpcopy != NULL_RTX
|
||||
&& (GET_CODE (SET_DEST (set)) == REG
|
||||
|| GET_CODE (SET_DEST (set)) == SUBREG)
|
||||
&& reg_overlap_mentioned_p (SET_DEST (set), gpcopy)
|
||||
&& (GET_CODE (SET_DEST (set)) != REG
|
||||
|| REGNO (SET_DEST (set)) != REGNO (gpcopy)
|
||||
|| ((GET_CODE (SET_SRC (set)) != CONST
|
||||
|| XEXP (SET_SRC (set), 0) != pic_offset_table_rtx)
|
||||
&& ! rtx_equal_p (SET_SRC (set), slot))))
|
||||
break;
|
||||
else if (slot != NULL_RTX
|
||||
&& GET_CODE (SET_DEST (set)) == MEM
|
||||
&& rtx_equal_p (SET_DEST (set), slot)
|
||||
&& (GET_CODE (SET_SRC (set)) != REG
|
||||
|| REGNO (SET_SRC (set)) != REGNO (gpcopy)))
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we couldn't find a unique value for GPCOPY or SLOT, then try a
|
||||
different optimization. Any time we find a copy of $28 into a
|
||||
register, followed by an add of a symbol_ref to that register, we
|
||||
convert it to load the value from the constant table instead.
|
||||
The copy and add will take six bytes, just as the load and
|
||||
constant table entry will take six bytes. However, it is
|
||||
possible that the constant table entry will be shared.
|
||||
|
||||
This could be a peephole optimization, but I don't know if the
|
||||
peephole code can call force_const_mem.
|
||||
|
||||
Using the same register for the copy of $28 and the add of the
|
||||
symbol_ref is actually pretty likely, since the add instruction
|
||||
requires the destination and the first addend to be the same
|
||||
register. */
|
||||
|
||||
if (insn != NULL_RTX || gpcopy == NULL_RTX || slot == NULL_RTX)
|
||||
{
|
||||
#if 0
|
||||
/* Used below in #if 0 area. */
|
||||
rtx next;
|
||||
#endif
|
||||
/* This optimization is only reasonable if the constant table
|
||||
entries are only 4 bytes. */
|
||||
if (Pmode != SImode)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
/* ??? FIXME. Rewrite for new UNSPEC_RELOC stuff. */
|
||||
for (insn = get_insns (); insn != NULL_RTX; insn = next)
|
||||
{
|
||||
rtx set1, set2;
|
||||
|
||||
next = insn;
|
||||
do
|
||||
{
|
||||
next = NEXT_INSN (next);
|
||||
}
|
||||
while (next != NULL_RTX
|
||||
&& (GET_CODE (next) == NOTE
|
||||
|| (GET_CODE (next) == INSN
|
||||
&& (GET_CODE (PATTERN (next)) == USE
|
||||
|| GET_CODE (PATTERN (next)) == CLOBBER))));
|
||||
|
||||
if (next == NULL_RTX)
|
||||
break;
|
||||
|
||||
if (! INSN_P (insn))
|
||||
continue;
|
||||
|
||||
if (! INSN_P (next))
|
||||
continue;
|
||||
|
||||
set1 = PATTERN (insn);
|
||||
if (GET_CODE (set1) != SET)
|
||||
continue;
|
||||
set2 = PATTERN (next);
|
||||
if (GET_CODE (set2) != SET)
|
||||
continue;
|
||||
|
||||
if (GET_CODE (SET_DEST (set1)) == REG
|
||||
&& GET_CODE (SET_SRC (set1)) == CONST
|
||||
&& XEXP (SET_SRC (set1), 0) == pic_offset_table_rtx
|
||||
&& rtx_equal_p (SET_DEST (set1), SET_DEST (set2))
|
||||
&& GET_CODE (SET_SRC (set2)) == PLUS
|
||||
&& rtx_equal_p (SET_DEST (set1), XEXP (SET_SRC (set2), 0))
|
||||
&& mips16_gp_offset_p (XEXP (SET_SRC (set2), 1))
|
||||
&& GET_CODE (XEXP (XEXP (SET_SRC (set2), 1), 0)) == MINUS)
|
||||
{
|
||||
rtx sym;
|
||||
|
||||
/* We've found a case we can change to load from the
|
||||
constant table. */
|
||||
|
||||
sym = XEXP (XEXP (XEXP (SET_SRC (set2), 1), 0), 0);
|
||||
if (GET_CODE (sym) != SYMBOL_REF)
|
||||
abort ();
|
||||
emit_insn_after (gen_rtx (SET, VOIDmode, SET_DEST (set1),
|
||||
force_const_mem (Pmode, sym)),
|
||||
next);
|
||||
|
||||
PUT_CODE (insn, NOTE);
|
||||
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
|
||||
NOTE_SOURCE_FILE (insn) = 0;
|
||||
|
||||
PUT_CODE (next, NOTE);
|
||||
NOTE_LINE_NUMBER (next) = NOTE_INSN_DELETED;
|
||||
NOTE_SOURCE_FILE (next) = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
/* We can safely remove all assignments to SLOT from GPCOPY, and
|
||||
replace all assignments from SLOT to GPCOPY with assignments from
|
||||
$28. */
|
||||
|
||||
for (insn = get_insns (); insn != NULL_RTX; insn = next_active_insn (insn))
|
||||
{
|
||||
rtx set;
|
||||
|
||||
if (! INSN_P (insn))
|
||||
continue;
|
||||
|
||||
set = PATTERN (insn);
|
||||
if (GET_CODE (set) != SET)
|
||||
continue;
|
||||
|
||||
if (GET_CODE (SET_DEST (set)) == MEM
|
||||
&& rtx_equal_p (SET_DEST (set), slot)
|
||||
&& GET_CODE (SET_SRC (set)) == REG
|
||||
&& REGNO (SET_SRC (set)) == REGNO (gpcopy))
|
||||
{
|
||||
PUT_CODE (insn, NOTE);
|
||||
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
|
||||
NOTE_SOURCE_FILE (insn) = 0;
|
||||
}
|
||||
else if (GET_CODE (SET_DEST (set)) == REG
|
||||
&& REGNO (SET_DEST (set)) == REGNO (gpcopy)
|
||||
&& GET_CODE (SET_SRC (set)) == MEM
|
||||
&& rtx_equal_p (SET_SRC (set), slot))
|
||||
{
|
||||
enum machine_mode mode;
|
||||
rtx src;
|
||||
|
||||
mode = GET_MODE (SET_DEST (set));
|
||||
src = gen_rtx_CONST (mode, pic_offset_table_rtx);
|
||||
emit_insn_after (gen_rtx_SET (VOIDmode, SET_DEST (set), src), insn);
|
||||
PUT_CODE (insn, NOTE);
|
||||
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
|
||||
NOTE_SOURCE_FILE (insn) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We keep a list of constants we which we have to add to internal
|
||||
constant tables in the middle of large functions. */
|
||||
|
||||
|
@ -8971,11 +8753,7 @@ static void
|
|||
mips_reorg (void)
|
||||
{
|
||||
if (TARGET_MIPS16)
|
||||
{
|
||||
if (optimize)
|
||||
mips16_optimize_gp ();
|
||||
mips16_lay_out_constants ();
|
||||
}
|
||||
mips16_lay_out_constants ();
|
||||
else if (TARGET_EXPLICIT_RELOCS)
|
||||
{
|
||||
if (mips_flag_delayed_branch)
|
||||
|
|
Loading…
Reference in New Issue