From 914ec131d6bc1b87347a5a03de96bd69b942e4f7 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Fri, 5 Sep 1997 05:14:46 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 9 ++++++++ gcc/reg-stack.c | 59 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9bea4de7d7d..8c48d61f467 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 * mips.md (nonlocal_goto_receiver): Define. diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 5ef93561eba..881d94ffaa0 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -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, -- 2.30.2