From 0e7d0eb9de3f1eafbba299c329a2e5abd4b3b19b Mon Sep 17 00:00:00 2001 From: James Van Artsdalen Date: Fri, 28 Aug 1992 01:24:42 +0000 Subject: [PATCH] (record_note_if_dead): Delete function. (record_reg_life_pat): Rewrite to handle any sort of pattern. (record_reg_life): Change interface to record_reg_life_pat. (stack_reg_life_analysis): Don't assume that MODE_FLOAT values are always returned in a float reg. (subst_stack_regs_pat): Add support for sin and cos insns. From-SVN: r1980 --- gcc/reg-stack.c | 222 +++++++++++++++++++++++++------------------------------- 1 file changed, 98 insertions(+), 124 deletions(-) diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 839a155..1b7fb1b 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -245,7 +245,7 @@ static void dump_stack_info (); int stack_regs_mentioned_p (pat) - register rtx pat; + rtx pat; { register char *fmt; register int i; @@ -446,36 +446,6 @@ get_true_reg (pat) return pat; } - -/* If REG is a stack register that is marked dead in REGSTACK, then - record that it is now live. If REG is not DEST, add a death note to - INSN if there isn't one already. If DEST is not a reg, it is safe to - assume that it does not mention a reg anywhere within. */ - -static void -record_note_if_dead (insn, regstack, reg, dest) - rtx insn; - stack regstack; - rtx reg, dest; -{ - reg = * get_true_reg (& reg); - - if (STACK_REG_P (reg)) - { - if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (reg))) - { - if ((! REG_P (dest) || REGNO (dest) != REGNO (reg)) - && ! find_regno_note (insn, REG_DEAD, REGNO (reg))) - REG_NOTES (insn) = gen_rtx (EXPR_LIST, - REG_DEAD, reg, REG_NOTES (insn)); - - SET_HARD_REG_BIT (regstack->reg_set, REGNO (reg)); - } - } - else - if (stack_regs_mentioned_p (reg)) - abort (); -} /* Scan the OPERANDS and OPERAND_CONSTRAINTS of an asm_operands. N_OPERANDS is the total number of operands. Return which alternative @@ -796,7 +766,7 @@ record_asm_reg_life (insn, regstack, operands, constraints, rtx *clobber_reg; - /* Find out what the constraints required. If no constraint + /* Find out what the constraints require. If no constraint alternative matches, that is a compiler bug: we should have caught such an insn during reload. */ i = constrain_asm_operands (n_operands, operands, constraints, @@ -981,103 +951,54 @@ record_asm_reg_life (insn, regstack, operands, constraints, } } -/* Scan PAT, which is part of INSN, and record the life & death of - stack registers in REGSTACK. If a register was dead, but is an input - operand in this insn, then mark the register live and record a death - note. - - If a register is dead after this insn, but is an output operand in - this insn, record a REG_UNUSED note. +/* Scan PAT, which is part of INSN, and record registers appearing in + a SET_DEST in DEST, and other registers in SRC. This function does not know about SET_DESTs that are both input and output (such as ZERO_EXTRACT) - this cannot happen on a 387. */ -static void -record_reg_life_pat (insn, regstack, pat) - rtx insn; - stack regstack; +void +record_reg_life_pat (pat, src, dest) rtx pat; + HARD_REG_SET *src, *dest; { - rtx src, dest; - - /* We should have already handled any asm. */ - if (GET_CODE (pat) == ASM_INPUT || GET_CODE (pat) == ASM_OPERANDS) - abort (); - - if (GET_CODE (pat) != SET) - return; - - dest = * get_true_reg (& SET_DEST (pat)); - - /* The destination is dead before this insn. If the destination is - not used after this insn, record this with REG_UNUSED. */ + register char *fmt; + register int i; - if (STACK_REG_P (dest)) + if (STACK_REG_P (pat)) { - /* ??? This check is unnecessary. */ + if (src) + SET_HARD_REG_BIT (*src, REGNO (pat)); - if (find_regno_note (insn, REG_UNUSED, REGNO (dest))) - abort (); + if (dest) + SET_HARD_REG_BIT (*dest, REGNO (pat)); - if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (dest))) - REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_UNUSED, dest, - REG_NOTES (insn)); - - CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (dest)); + return; } - else - if (dest != cc0_rtx && stack_regs_mentioned_p (dest)) - abort (); - - src = * get_true_reg (& SET_SRC (pat)); - switch (GET_CODE (src)) + if (GET_CODE (pat) == SET) { - /* ??? get_true_reg will make some of these cases redundant. */ - - case PLUS: - case MINUS: - case MULT: - case DIV: - case COMPARE: - record_note_if_dead (insn, regstack, XEXP (src, 0), dest); - record_note_if_dead (insn, regstack, XEXP (src, 1), dest); - break; - - case ABS: - case NEG: - case SQRT: - case FLOAT_EXTEND: - case FLOAT_TRUNCATE: - case FLOAT: - case UNSIGNED_FLOAT: - record_note_if_dead (insn, regstack, XEXP (src, 0), dest); - break; - - case UNSIGNED_FIX: - case FIX: - src = XEXP (src, 0); - if (GET_CODE (src) == FIX) - record_note_if_dead (insn, regstack, XEXP (src, 0), dest); - else - record_note_if_dead (insn, regstack, src, dest); - break; - - case ASM_OPERANDS: - case ASM_INPUT: - abort (); /* we should have caught this already. */ - break; + record_reg_life_pat (XEXP (pat, 0), NULL_PTR, dest); + record_reg_life_pat (XEXP (pat, 1), src, NULL_PTR); + return; + } - case REG: - record_note_if_dead (insn, regstack, src, dest); - break; + /* We don't need to consider either of these cases. */ + if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER) + return; - default: - /* If a stack register appears in the src RTL, it is a bug, and - code should be added above to handle it. */ + fmt = GET_RTX_FORMAT (GET_CODE (pat)); + for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--) + { + if (fmt[i] == 'E') + { + register int j; - if (stack_regs_mentioned_p (src)) - abort (); + for (j = XVECLEN (pat, i) - 1; j >= 0; j--) + record_reg_life_pat (XVECEXP (pat, i, j), src, dest); + } + else if (fmt[i] == 'e') + record_reg_life_pat (XEXP (pat, i), src, dest); } } @@ -1167,15 +1088,34 @@ record_reg_life (insn, block, regstack) return; } - if (GET_CODE (PATTERN (insn)) == PARALLEL) + /* An insn referencing a stack reg has a mode of QImode. */ + if (GET_MODE (insn) == QImode) { - register int i; + HARD_REG_SET src, dest; + int regno; + + CLEAR_HARD_REG_SET (src); + CLEAR_HARD_REG_SET (dest); + record_reg_life_pat (PATTERN (insn), &src, &dest); - for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++) - record_reg_life_pat (insn, regstack, XVECEXP (PATTERN (insn), 0, i)); + for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++) + if (! TEST_HARD_REG_BIT (regstack->reg_set, regno)) + { + if (TEST_HARD_REG_BIT (src, regno) + && ! TEST_HARD_REG_BIT (dest, regno)) + REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, + FP_mode_reg[regno][(int) DFmode], + REG_NOTES (insn)); + else if (TEST_HARD_REG_BIT (dest, regno) + && ! TEST_HARD_REG_BIT (src, regno)) + REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_UNUSED, + FP_mode_reg[regno][(int) DFmode], + REG_NOTES (insn)); + } + + AND_COMPL_HARD_REG_SET (regstack->reg_set, dest); + IOR_HARD_REG_SET (regstack->reg_set, src); } - else if (GET_MODE (insn) == QImode) - record_reg_life_pat (insn, regstack, PATTERN (insn)); /* There might be a reg that is live after a function call. Initialize it to zero so that the program does not crash. See comment @@ -1186,8 +1126,7 @@ record_reg_life (insn, block, regstack) int reg = FIRST_FLOAT_REG; /* If a stack reg is mentioned in a CALL_INSN, it must be as the - return value; conversely, if a float is returned, a stack reg - must be mentioned. */ + return value. */ if (stack_regs_mentioned_p (PATTERN (insn))) reg++; @@ -1317,21 +1256,24 @@ stack_reg_life_analysis (first) int reg, block; struct stack_def regstack; - if (current_function_returns_real) + if (current_function_returns_real + && STACK_REG_P (DECL_RTL (DECL_RESULT (current_function_decl)))) { /* Find all RETURN insns and mark them. */ + int value_regno = REGNO (DECL_RTL (DECL_RESULT (current_function_decl))); + for (block = blocks - 1; block >= 0; block--) if (GET_CODE (block_end[block]) == JUMP_INSN && GET_CODE (PATTERN (block_end[block])) == RETURN) - SET_HARD_REG_BIT (block_out_reg_set[block], FIRST_STACK_REG); + SET_HARD_REG_BIT (block_out_reg_set[block], value_regno); /* Mark of the end of last block if we "fall off" the end of the function into the epilogue. */ if (GET_CODE (block_end[blocks-1]) != JUMP_INSN || GET_CODE (PATTERN (block_end[blocks-1])) == RETURN) - SET_HARD_REG_BIT (block_out_reg_set[blocks-1], FIRST_STACK_REG); + SET_HARD_REG_BIT (block_out_reg_set[blocks-1], value_regno); } /* now scan all blocks backward for stack register use */ @@ -2035,6 +1977,38 @@ subst_stack_regs_pat (insn, regstack, pat) break; + case UNSPEC: + switch (XINT (SET_SRC (pat), 1)) + { + case 1: /* sin */ + case 2: /* cos */ + /* These insns only operate on the top of the stack. */ + + src1 = get_true_reg (&XVECEXP (SET_SRC (pat), 0, 0)); + + emit_swap_insn (insn, regstack, *src1, emit_insn_before); + + src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); + + if (STACK_REG_P (*dest)) + replace_reg (dest, FIRST_STACK_REG); + + if (src1_note) + { + replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG); + regstack->top--; + CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1)); + } + + replace_reg (src1, FIRST_STACK_REG); + + break; + + default: + abort (); + } + break; + default: abort (); } -- 2.7.4