mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-15 08:10:28 +08:00
reg-stack.c (change_stack): Improve algorithm used to pop regs off the stack to maximize ffreep usage and...
* reg-stack.c (change_stack): Improve algorithm used to pop regs off the stack to maximize ffreep usage and reduce fxch count. From-SVN: r91506
This commit is contained in:
parent
c54d30fae2
commit
0cc5dec18a
@ -1,3 +1,8 @@
|
||||
2004-11-29 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* reg-stack.c (change_stack): Improve algorithm used to pop regs
|
||||
off the stack to maximize ffreep usage and reduce fxch count.
|
||||
|
||||
2004-11-30 James A. Morrison <phython@gcc.gnu.org>
|
||||
|
||||
PR middle-end/18596
|
||||
|
@ -2367,10 +2367,66 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
|
||||
|
||||
/* Pop any registers that are not needed in the new block. */
|
||||
|
||||
for (reg = old->top; reg >= 0; reg--)
|
||||
if (! TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
|
||||
emit_pop_insn (insn, old, FP_MODE_REG (old->reg[reg], DFmode),
|
||||
EMIT_BEFORE);
|
||||
/* If the destination block's stack already has a specified layout
|
||||
and contains two or more registers, use a more intelligent algorithm
|
||||
to pop registers that minimizes the number number of fxchs below. */
|
||||
if (new->top > 0)
|
||||
{
|
||||
bool slots[REG_STACK_SIZE];
|
||||
int pops[REG_STACK_SIZE];
|
||||
int next, dest;
|
||||
|
||||
/* 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. */
|
||||
for (reg = old->top; reg > new->top; reg--)
|
||||
if (TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
|
||||
{
|
||||
dest = -1;
|
||||
for (next = 0; next <= new->top; next++)
|
||||
if (!slots[next] && new->reg[next] == old->reg[reg])
|
||||
{
|
||||
slots[next] = true;
|
||||
dest = next;
|
||||
break;
|
||||
}
|
||||
pops[reg] = dest;
|
||||
}
|
||||
else
|
||||
pops[reg] = reg;
|
||||
|
||||
/* Third pass allocates remaining slots and emits pop insns. */
|
||||
next = 0;
|
||||
for (reg = old->top; reg > new->top; reg--)
|
||||
{
|
||||
dest = pops[reg];
|
||||
if (dest == -1)
|
||||
{
|
||||
/* Find next free slot. */
|
||||
while (slots[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),
|
||||
EMIT_BEFORE);
|
||||
emit_pop_insn (insn, old, FP_MODE_REG (old->reg[reg], DFmode),
|
||||
EMIT_BEFORE);
|
||||
}
|
||||
|
||||
if (new->top == -2)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user