reg-stack.c (struct block_info_def): Correct grammar typo.
* reg-stack.c (struct block_info_def): Correct grammar typo. (compensate_edge): Clean-up. Perform as little work as possible when src and dest stacks match. Avoid modifying block_info. Reorder and simplify assertion checks. Avoid unnecessary copying of regstack structure. (convert_regs_1): Set the done flag here... (convert_regs_2): ... instead of here. From-SVN: r100602
This commit is contained in:
parent
6d0a809119
commit
579e4a82ec
2 changed files with 45 additions and 49 deletions
|
@ -1,3 +1,13 @@
|
|||
2005-06-04 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* reg-stack.c (struct block_info_def): Correct grammar typo.
|
||||
(compensate_edge): Clean-up. Perform as little work as possible
|
||||
when src and dest stacks match. Avoid modifying block_info.
|
||||
Reorder and simplify assertion checks. Avoid unnecessary copying
|
||||
of regstack structure.
|
||||
(convert_regs_1): Set the done flag here...
|
||||
(convert_regs_2): ... instead of here.
|
||||
|
||||
2005-06-04 Dale Johannesen <dalej@apple.com>
|
||||
|
||||
* config/rs6000/rs6000.c (no_global_regs_above): New.
|
||||
|
|
|
@ -208,7 +208,7 @@ typedef struct block_info_def
|
|||
struct stack_def stack_out; /* Output stack configuration. */
|
||||
HARD_REG_SET out_reg_set; /* Stack regs live on output. */
|
||||
int done; /* True if block already converted. */
|
||||
int predecessors; /* Number of predecessors that needs
|
||||
int predecessors; /* Number of predecessors that need
|
||||
to be visited. */
|
||||
} *block_info;
|
||||
|
||||
|
@ -2629,24 +2629,22 @@ propagate_stack (edge e)
|
|||
static bool
|
||||
compensate_edge (edge e, FILE *file)
|
||||
{
|
||||
basic_block block = e->src, target = e->dest;
|
||||
block_info bi = BLOCK_INFO (block);
|
||||
struct stack_def regstack, tmpstack;
|
||||
basic_block source = e->src, target = e->dest;
|
||||
stack target_stack = &BLOCK_INFO (target)->stack_in;
|
||||
stack source_stack = &BLOCK_INFO (source)->stack_out;
|
||||
struct stack_def regstack;
|
||||
int reg;
|
||||
|
||||
current_block = block;
|
||||
regstack = bi->stack_out;
|
||||
if (file)
|
||||
fprintf (file, "Edge %d->%d: ", block->index, target->index);
|
||||
fprintf (file, "Edge %d->%d: ", source->index, target->index);
|
||||
|
||||
gcc_assert (target_stack->top != -2);
|
||||
|
||||
/* Check whether stacks are identical. */
|
||||
if (target_stack->top == regstack.top)
|
||||
if (target_stack->top == source_stack->top)
|
||||
{
|
||||
for (reg = target_stack->top; reg >= 0; --reg)
|
||||
if (target_stack->reg[reg] != regstack.reg[reg])
|
||||
if (target_stack->reg[reg] != source_stack->reg[reg])
|
||||
break;
|
||||
|
||||
if (reg == -1)
|
||||
|
@ -2663,68 +2661,56 @@ compensate_edge (edge e, FILE *file)
|
|||
print_stack (file, target_stack);
|
||||
}
|
||||
|
||||
/* Care for non-call EH edges specially. The normal return path have
|
||||
values in registers. These will be popped en masse by the unwind
|
||||
library. */
|
||||
if ((e->flags & (EDGE_EH | EDGE_ABNORMAL_CALL)) == EDGE_EH)
|
||||
target_stack->top = -1;
|
||||
|
||||
/* Other calls may appear to have values live in st(0), but the
|
||||
/* Abnormal calls may appear to have values live in st(0), but the
|
||||
abnormal return path will not have actually loaded the values. */
|
||||
else if (e->flags & EDGE_ABNORMAL_CALL)
|
||||
if (e->flags & EDGE_ABNORMAL_CALL)
|
||||
{
|
||||
/* Assert that the lifetimes are as we expect -- one value
|
||||
live at st(0) on the end of the source block, and no
|
||||
values live at the beginning of the destination block. */
|
||||
HARD_REG_SET tmp;
|
||||
|
||||
CLEAR_HARD_REG_SET (tmp);
|
||||
GO_IF_HARD_REG_EQUAL (target_stack->reg_set, tmp, eh1);
|
||||
gcc_unreachable ();
|
||||
eh1:
|
||||
|
||||
/* We are sure that there is st(0) live, otherwise we won't compensate.
|
||||
For complex return values, we may have st(1) live as well. */
|
||||
SET_HARD_REG_BIT (tmp, FIRST_STACK_REG);
|
||||
if (TEST_HARD_REG_BIT (regstack.reg_set, FIRST_STACK_REG + 1))
|
||||
SET_HARD_REG_BIT (tmp, FIRST_STACK_REG + 1);
|
||||
GO_IF_HARD_REG_EQUAL (regstack.reg_set, tmp, eh2);
|
||||
gcc_unreachable ();
|
||||
eh2:
|
||||
|
||||
target_stack->top = -1;
|
||||
gcc_assert (source_stack->top == 0);
|
||||
gcc_assert (target_stack->top == -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Handle non-call EH edges specially. The normal return path have
|
||||
values in registers. These will be popped en masse by the unwind
|
||||
library. */
|
||||
if (e->flags & EDGE_EH)
|
||||
{
|
||||
gcc_assert (target_stack->top == -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We don't support abnormal edges. Global takes care to
|
||||
avoid any live register across them, so we should never
|
||||
have to insert instructions on such edges. */
|
||||
gcc_assert (! (e->flags & EDGE_ABNORMAL));
|
||||
|
||||
/* Make a copy of source_stack as change_stack is destructive. */
|
||||
regstack = *source_stack;
|
||||
|
||||
/* It is better to output directly to the end of the block
|
||||
instead of to the edge, because emit_swap can do minimal
|
||||
insn scheduling. We can do this when there is only one
|
||||
edge out, and it is not abnormal. */
|
||||
else if (EDGE_COUNT (block->succs) == 1 && !(e->flags & EDGE_ABNORMAL))
|
||||
if (EDGE_COUNT (source->succs) == 1)
|
||||
{
|
||||
/* change_stack kills values in regstack. */
|
||||
tmpstack = regstack;
|
||||
|
||||
change_stack (BB_END (block), &tmpstack, target_stack,
|
||||
(JUMP_P (BB_END (block))
|
||||
? EMIT_BEFORE : EMIT_AFTER));
|
||||
current_block = source;
|
||||
change_stack (BB_END (source), ®stack, target_stack,
|
||||
(JUMP_P (BB_END (source)) ? EMIT_BEFORE : EMIT_AFTER));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx seq, after;
|
||||
|
||||
/* We don't support abnormal edges. Global takes care to
|
||||
avoid any live register across them, so we should never
|
||||
have to insert instructions on such edges. */
|
||||
gcc_assert (!(e->flags & EDGE_ABNORMAL));
|
||||
|
||||
current_block = NULL;
|
||||
start_sequence ();
|
||||
|
||||
/* ??? change_stack needs some point to emit insns after. */
|
||||
after = emit_note (NOTE_INSN_DELETED);
|
||||
|
||||
tmpstack = regstack;
|
||||
change_stack (after, &tmpstack, target_stack, EMIT_BEFORE);
|
||||
change_stack (after, ®stack, target_stack, EMIT_BEFORE);
|
||||
|
||||
seq = get_insns ();
|
||||
end_sequence ();
|
||||
|
@ -2928,6 +2914,7 @@ convert_regs_1 (FILE *file, basic_block block)
|
|||
gcc_assert (any_malformed_asm);
|
||||
win:
|
||||
bi->stack_out = regstack;
|
||||
bi->done = true;
|
||||
}
|
||||
|
||||
/* Convert registers in all blocks reachable from BLOCK. */
|
||||
|
@ -2975,7 +2962,6 @@ convert_regs_2 (FILE *file, basic_block block)
|
|||
}
|
||||
|
||||
convert_regs_1 (file, block);
|
||||
BLOCK_INFO (block)->done = 1;
|
||||
}
|
||||
while (sp != stack);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue