Commit 00fc055e by Roger Sayle Committed by Roger Sayle

reg-stack.c (change_stack): Avoid placing the new top-of-stack in its correct…

reg-stack.c (change_stack): Avoid placing the new top-of-stack in its correct location during popping if...


	* reg-stack.c (change_stack): Avoid placing the new top-of-stack in
	its correct location during popping if we need to permute the stack
	afterwards.  Attempt to preserve the original stack ordering.

From-SVN: r92043
parent def6dcd7
2004-12-11 Roger Sayle <roger@eyesopen.com>
* reg-stack.c (change_stack): Avoid placing the new top-of-stack in
its correct location during popping if we need to permute the stack
afterwards. Attempt to preserve the original stack ordering.
2004-12-12 Kazu Hirata <kazu@cs.umass.edu> 2004-12-12 Kazu Hirata <kazu@cs.umass.edu>
* lcm.c (optimize_mode_switching): Free insert and delete in * lcm.c (optimize_mode_switching): Free insert and delete in
......
...@@ -2374,13 +2374,14 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where) ...@@ -2374,13 +2374,14 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
{ {
bool slots[REG_STACK_SIZE]; bool slots[REG_STACK_SIZE];
int pops[REG_STACK_SIZE]; int pops[REG_STACK_SIZE];
int next, dest; int next, dest, topsrc;
/* First pass to determine the free slots. */ /* First pass to determine the free slots. */
for (reg = 0; reg <= new->top; reg++) for (reg = 0; reg <= new->top; reg++)
slots[reg] = TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]); slots[reg] = TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]);
/* Second pass to allocate preferred slots. */ /* Second pass to allocate preferred slots. */
topsrc = -1;
for (reg = old->top; reg > new->top; reg--) for (reg = old->top; reg > new->top; reg--)
if (TEST_HARD_REG_BIT (new->reg_set, old->reg[reg])) if (TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
{ {
...@@ -2388,6 +2389,10 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where) ...@@ -2388,6 +2389,10 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
for (next = 0; next <= new->top; next++) for (next = 0; next <= new->top; next++)
if (!slots[next] && new->reg[next] == old->reg[reg]) if (!slots[next] && new->reg[next] == old->reg[reg])
{ {
/* If this is a preference for the new top of stack, record
the fact by remembering it's old->reg in topsrc. */
if (next == new->top)
topsrc = reg;
slots[next] = true; slots[next] = true;
dest = next; dest = next;
break; break;
...@@ -2397,8 +2402,23 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where) ...@@ -2397,8 +2402,23 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
else else
pops[reg] = reg; pops[reg] = reg;
/* Intentionally, avoid placing the top of stack in it's correct
location, if we still need to permute the stack below and we
can usefully place it somewhere else. This is the case if any
slot is still unallocated, in which case we should place the
top of stack there. */
if (topsrc != -1)
for (reg = 0; reg < new->top; reg++)
if (!slots[reg])
{
pops[topsrc] = reg;
slots[new->top] = false;
slots[reg] = true;
break;
}
/* Third pass allocates remaining slots and emits pop insns. */ /* Third pass allocates remaining slots and emits pop insns. */
next = 0; next = new->top;
for (reg = old->top; reg > new->top; reg--) for (reg = old->top; reg > new->top; reg--)
{ {
dest = pops[reg]; dest = pops[reg];
...@@ -2406,27 +2426,38 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where) ...@@ -2406,27 +2426,38 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
{ {
/* Find next free slot. */ /* Find next free slot. */
while (slots[next]) while (slots[next])
next++; next--;
dest = next++; dest = next--;
} }
emit_pop_insn (insn, old, FP_MODE_REG (old->reg[dest], DFmode), emit_pop_insn (insn, old, FP_MODE_REG (old->reg[dest], DFmode),
EMIT_BEFORE); EMIT_BEFORE);
} }
} }
else else
/* The following loop attempts to maximize the number of times we {
pop the top of the stack, as this permits the use of the faster /* The following loop attempts to maximize the number of times we
ffreep instruction on platforms that support it. */ pop the top of the stack, as this permits the use of the faster
for (reg = 0; reg <= old->top; reg++) ffreep instruction on platforms that support it. */
if (! TEST_HARD_REG_BIT (new->reg_set, old->reg[reg])) int live, next;
{
while (old->top > reg live = 0;
&& ! TEST_HARD_REG_BIT (new->reg_set, old->reg[old->top])) for (reg = 0; reg <= old->top; reg++)
emit_pop_insn (insn, old, FP_MODE_REG (old->reg[old->top], DFmode), if (TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
live++;
next = live;
while (old->top >= live)
if (TEST_HARD_REG_BIT (new->reg_set, old->reg[old->top]))
{
while (TEST_HARD_REG_BIT (new->reg_set, old->reg[next]))
next--;
emit_pop_insn (insn, old, FP_MODE_REG (old->reg[next], DFmode),
EMIT_BEFORE); EMIT_BEFORE);
emit_pop_insn (insn, old, FP_MODE_REG (old->reg[reg], DFmode), }
else
emit_pop_insn (insn, old, FP_MODE_REG (old->reg[old->top], DFmode),
EMIT_BEFORE); EMIT_BEFORE);
} }
if (new->top == -2) if (new->top == -2)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment