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
This commit is contained in:
Roger Sayle 2004-12-12 01:41:27 +00:00 committed by Roger Sayle
parent def6dcd75c
commit 00fc055e05
2 changed files with 52 additions and 15 deletions

View file

@ -1,3 +1,9 @@
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>
* lcm.c (optimize_mode_switching): Free insert and delete in

View file

@ -2374,13 +2374,14 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
{
bool slots[REG_STACK_SIZE];
int pops[REG_STACK_SIZE];
int next, dest;
int next, dest, topsrc;
/* First pass to determine the free slots. */
for (reg = 0; reg <= new->top; reg++)
slots[reg] = TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]);
/* Second pass to allocate preferred slots. */
topsrc = -1;
for (reg = old->top; reg > new->top; 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)
for (next = 0; next <= new->top; next++)
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;
dest = next;
break;
@ -2397,8 +2402,23 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
else
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. */
next = 0;
next = new->top;
for (reg = old->top; reg > new->top; reg--)
{
dest = pops[reg];
@ -2406,27 +2426,38 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
{
/* Find next free slot. */
while (slots[next])
next++;
dest = next++;
next--;
dest = next--;
}
emit_pop_insn (insn, old, FP_MODE_REG (old->reg[dest], DFmode),
EMIT_BEFORE);
}
}
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
ffreep instruction on platforms that support it. */
for (reg = 0; reg <= old->top; reg++)
if (! TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
{
while (old->top > reg
&& ! TEST_HARD_REG_BIT (new->reg_set, old->reg[old->top]))
emit_pop_insn (insn, old, FP_MODE_REG (old->reg[old->top], DFmode),
{
/* 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
ffreep instruction on platforms that support it. */
int live, next;
live = 0;
for (reg = 0; reg <= old->top; reg++)
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_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);
}
}
if (new->top == -2)
{