mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-23 07:19:12 +08:00
reg-stack.c (subst_stack_regs): Pop the stack register for a computed goto which sets the same stack register.
* reg-stack.c (subst_stack_regs): Pop the stack register for a computed goto which sets the same stack register. * reg-stack.c (compare_for_stack_reg): Swap only if the source and destination are both on the regstack. (subst_stack_regs_pat): Put the destination at the top of the regstack. Bring over regstack bugfixes from the FSF. From-SVN: r15096
This commit is contained in:
parent
d5d1738a3a
commit
914ec131d6
@ -1,3 +1,12 @@
|
||||
Thu Sep 4 23:14:27 1997 Stan Cox (coxs@dg-rtp.dg.com)
|
||||
|
||||
* reg-stack.c (subst_stack_regs): Pop the stack register for a
|
||||
computed goto which sets the same stack register.
|
||||
|
||||
* reg-stack.c (compare_for_stack_reg): Swap only if the source and
|
||||
destination are both on the regstack.
|
||||
(subst_stack_regs_pat): Put the destination at the top of the regstack.
|
||||
|
||||
Thu Sep 4 15:02:27 1997 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
* mips.md (nonlocal_goto_receiver): Define.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Register to Stack convert for GNU compiler.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -2018,6 +2018,7 @@ compare_for_stack_reg (insn, regstack, pat)
|
||||
rtx *src1, *src2;
|
||||
rtx src1_note, src2_note;
|
||||
rtx cc0_user;
|
||||
int have_cmove;
|
||||
|
||||
src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
|
||||
src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));
|
||||
@ -2032,11 +2033,16 @@ compare_for_stack_reg (insn, regstack, pat)
|
||||
rtx *dest, src_note;
|
||||
|
||||
dest = get_true_reg (&SET_DEST (PATTERN (cc0_user)));
|
||||
if (REGNO (*dest) != regstack->reg[regstack->top])
|
||||
|
||||
have_cmove = 1;
|
||||
if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG
|
||||
&& REGNO (*dest) != regstack->reg[regstack->top])
|
||||
{
|
||||
emit_swap_insn (insn, regstack, *dest);
|
||||
}
|
||||
}
|
||||
else
|
||||
have_cmove = 0;
|
||||
|
||||
/* ??? If fxch turns out to be cheaper than fstp, give priority to
|
||||
registers that die in this insn - move those to stack top first. */
|
||||
@ -2071,7 +2077,8 @@ compare_for_stack_reg (insn, regstack, pat)
|
||||
else
|
||||
src2_note = NULL_RTX;
|
||||
|
||||
emit_swap_insn (insn, regstack, *src1);
|
||||
if (! have_cmove)
|
||||
emit_swap_insn (insn, regstack, *src1);
|
||||
|
||||
replace_reg (src1, FIRST_STACK_REG);
|
||||
|
||||
@ -2378,8 +2385,6 @@ subst_stack_regs_pat (insn, regstack, pat)
|
||||
for (i = 1; i <= 2; i++)
|
||||
if (src_note [i])
|
||||
{
|
||||
int regno = get_hard_regnum (regstack, XEXP (src_note [i], 0));
|
||||
|
||||
/* If the register that dies is not at the top of stack, then
|
||||
move the top of stack to the dead reg */
|
||||
if (REGNO (XEXP (src_note[i], 0))
|
||||
@ -2397,13 +2402,15 @@ subst_stack_regs_pat (insn, regstack, pat)
|
||||
replace_reg (&XEXP (src_note[i], 0), FIRST_STACK_REG);
|
||||
regstack->top--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
|
||||
replace_reg (dest, FIRST_STACK_REG);
|
||||
}
|
||||
|
||||
/* Make dest the top of stack. Add dest to regstack if not present. */
|
||||
if (get_hard_regnum (regstack, *dest) < FIRST_STACK_REG)
|
||||
regstack->reg[++regstack->top] = REGNO (*dest);
|
||||
SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
|
||||
replace_reg (dest, FIRST_STACK_REG);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2719,6 +2726,7 @@ subst_stack_regs (insn, regstack)
|
||||
{
|
||||
register rtx *note_link, note;
|
||||
register int i;
|
||||
rtx head, jump, pat, cipat;
|
||||
int n_operands;
|
||||
|
||||
if (GET_CODE (insn) == CALL_INSN)
|
||||
@ -2790,6 +2798,39 @@ subst_stack_regs (insn, regstack)
|
||||
if (GET_CODE (insn) == NOTE)
|
||||
return;
|
||||
|
||||
/* If we are reached by a computed goto which sets this same stack register,
|
||||
then pop this stack register, but maintain regstack. */
|
||||
|
||||
pat = single_set (insn);
|
||||
if (pat != 0
|
||||
&& INSN_UID (insn) <= max_uid
|
||||
&& GET_CODE (block_begin[BLOCK_NUM(insn)]) == CODE_LABEL
|
||||
&& GET_CODE (pat) == SET && STACK_REG_P (SET_DEST (pat)))
|
||||
for (head = block_begin[BLOCK_NUM(insn)], jump = LABEL_REFS (head);
|
||||
jump != head;
|
||||
jump = LABEL_NEXTREF (jump))
|
||||
{
|
||||
cipat = single_set (CONTAINING_INSN (jump));
|
||||
if (cipat != 0
|
||||
&& GET_CODE (cipat) == SET
|
||||
&& SET_DEST (cipat) == pc_rtx
|
||||
&& uses_reg_or_mem (SET_SRC (cipat))
|
||||
&& INSN_UID (CONTAINING_INSN (jump)) <= max_uid)
|
||||
{
|
||||
int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
|
||||
if (TEST_HARD_REG_BIT (block_out_reg_set[from_block],
|
||||
REGNO (SET_DEST (pat))))
|
||||
{
|
||||
struct stack_def old;
|
||||
bcopy (regstack->reg, old.reg, sizeof (old.reg));
|
||||
emit_pop_insn (insn, regstack, SET_DEST (pat), emit_insn_before);
|
||||
regstack->top += 1;
|
||||
bcopy (old.reg, regstack->reg, sizeof (old.reg));
|
||||
SET_HARD_REG_BIT (regstack->reg_set, REGNO (SET_DEST (pat)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is a REG_UNUSED note on a stack register on this insn,
|
||||
the indicated reg must be popped. The REG_UNUSED note is removed,
|
||||
since the form of the newly emitted pop insn references the reg,
|
||||
|
Loading…
Reference in New Issue
Block a user