diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-09-05 15:32:12 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-09-05 15:32:12 +0000 |
commit | ba126de4cf1f0bbc1e2718da90fc736e951c08d6 (patch) | |
tree | 341620536c3a3cfc629ac77fa76be2987cb80273 /gcc/reg-stack.c | |
parent | d614575c1b88d9556b52e8a8a0821abb95f72a21 (diff) | |
download | gcc-ba126de4cf1f0bbc1e2718da90fc736e951c08d6.tar.gz |
* i386.c (size_cost): New static variable.
(override_function): Use size_cost when -Os is specified.
* i386.c (ix86_expand_prologue): Set use_fast_prologue_epilogue
properly; Use current_function_calls_eh_return.
(ix86_expand_epilogue): Avoid dummy optimize_size tests;
use leave to avoid depdendancy chain.
* local-alloc.c (update_equiv_regs): Use CFG to iterate over INSN stream;
get BB loop_depth instead of computing it from LOOP notes.
* reg-stack.c (subst_stack_reg_pat): Handle reversal of conditional moves.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45415 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r-- | gcc/reg-stack.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 558735fc2fa..79aabfa95b7 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -1775,6 +1775,12 @@ subst_stack_regs_pat (insn, regstack, pat) case IF_THEN_ELSE: /* This insn requires the top of stack to be the destination. */ + src1 = get_true_reg (&XEXP (pat_src, 1)); + src2 = get_true_reg (&XEXP (pat_src, 2)); + + src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); + src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2)); + /* If the comparison operator is an FP comparison operator, it is handled correctly by compare_for_stack_reg () who will move the destination to the top of stack. But if the @@ -1782,13 +1788,35 @@ subst_stack_regs_pat (insn, regstack, pat) have to handle it here. */ if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG && REGNO (*dest) != regstack->reg[regstack->top]) - emit_swap_insn (insn, regstack, *dest); - - src1 = get_true_reg (&XEXP (pat_src, 1)); - src2 = get_true_reg (&XEXP (pat_src, 2)); + { + /* In case one of operands is the top of stack and the operands + dies, it is safe to make it the destination operand by reversing + the direction of cmove and avoid fxch. */ + if ((REGNO (*src1) == regstack->reg[regstack->top] + && src1_note) + || (REGNO (*src2) == regstack->reg[regstack->top] + && src2_note)) + { - src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1)); - src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2)); + /* We know that both sources "dies", as one dies and other + is overwriten by the destination. Claim both sources + to be dead, as the code bellow will properly pop the + non-top-of-stack note and replace top-of-stack by the + result by popping source first and then pushing result. */ + if (!src1_note) + src1_note = REG_NOTES (insn) + = gen_rtx_EXPR_LIST (REG_DEAD, *src1, REG_NOTES (insn)); + if (!src2_note) + src2_note = REG_NOTES (insn) + = gen_rtx_EXPR_LIST (REG_DEAD, *src2, REG_NOTES (insn)); + + /* i386 do have comparison always reversible. */ + PUT_CODE (XEXP (pat_src, 0), + reversed_comparison_code (XEXP (pat_src, 0), insn)); + } + else + emit_swap_insn (insn, regstack, *dest); + } { rtx src_note [3]; |