summaryrefslogtreecommitdiff
path: root/gcc/reg-stack.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-09-05 15:32:12 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-09-05 15:32:12 +0000
commitba126de4cf1f0bbc1e2718da90fc736e951c08d6 (patch)
tree341620536c3a3cfc629ac77fa76be2987cb80273 /gcc/reg-stack.c
parentd614575c1b88d9556b52e8a8a0821abb95f72a21 (diff)
downloadgcc-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.c40
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];