Commit 579e4a82 by Roger Sayle Committed by Roger Sayle

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
parent 6d0a8091
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> 2005-06-04 Dale Johannesen <dalej@apple.com>
* config/rs6000/rs6000.c (no_global_regs_above): New. * config/rs6000/rs6000.c (no_global_regs_above): New.
......
...@@ -208,7 +208,7 @@ typedef struct block_info_def ...@@ -208,7 +208,7 @@ typedef struct block_info_def
struct stack_def stack_out; /* Output stack configuration. */ struct stack_def stack_out; /* Output stack configuration. */
HARD_REG_SET out_reg_set; /* Stack regs live on output. */ HARD_REG_SET out_reg_set; /* Stack regs live on output. */
int done; /* True if block already converted. */ int done; /* True if block already converted. */
int predecessors; /* Number of predecessors that needs int predecessors; /* Number of predecessors that need
to be visited. */ to be visited. */
} *block_info; } *block_info;
...@@ -2629,24 +2629,22 @@ propagate_stack (edge e) ...@@ -2629,24 +2629,22 @@ propagate_stack (edge e)
static bool static bool
compensate_edge (edge e, FILE *file) compensate_edge (edge e, FILE *file)
{ {
basic_block block = e->src, target = e->dest; basic_block source = e->src, target = e->dest;
block_info bi = BLOCK_INFO (block);
struct stack_def regstack, tmpstack;
stack target_stack = &BLOCK_INFO (target)->stack_in; stack target_stack = &BLOCK_INFO (target)->stack_in;
stack source_stack = &BLOCK_INFO (source)->stack_out;
struct stack_def regstack;
int reg; int reg;
current_block = block;
regstack = bi->stack_out;
if (file) 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); gcc_assert (target_stack->top != -2);
/* Check whether stacks are identical. */ /* 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) 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; break;
if (reg == -1) if (reg == -1)
...@@ -2663,68 +2661,56 @@ compensate_edge (edge e, FILE *file) ...@@ -2663,68 +2661,56 @@ compensate_edge (edge e, FILE *file)
print_stack (file, target_stack); print_stack (file, target_stack);
} }
/* Care for non-call EH edges specially. The normal return path have /* Abnormal calls may appear to have values live in st(0), but the
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 return path will not have actually loaded the values. */ 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 /* Assert that the lifetimes are as we expect -- one value
live at st(0) on the end of the source block, and no live at st(0) on the end of the source block, and no
values live at the beginning of the destination block. */ values live at the beginning of the destination block. */
HARD_REG_SET tmp; gcc_assert (source_stack->top == 0);
gcc_assert (target_stack->top == -1);
CLEAR_HARD_REG_SET (tmp); return false;
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; /* 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 /* It is better to output directly to the end of the block
instead of to the edge, because emit_swap can do minimal instead of to the edge, because emit_swap can do minimal
insn scheduling. We can do this when there is only one insn scheduling. We can do this when there is only one
edge out, and it is not abnormal. */ 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. */ current_block = source;
tmpstack = regstack; change_stack (BB_END (source), &regstack, target_stack,
(JUMP_P (BB_END (source)) ? EMIT_BEFORE : EMIT_AFTER));
change_stack (BB_END (block), &tmpstack, target_stack,
(JUMP_P (BB_END (block))
? EMIT_BEFORE : EMIT_AFTER));
} }
else else
{ {
rtx seq, after; 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; current_block = NULL;
start_sequence (); start_sequence ();
/* ??? change_stack needs some point to emit insns after. */ /* ??? change_stack needs some point to emit insns after. */
after = emit_note (NOTE_INSN_DELETED); after = emit_note (NOTE_INSN_DELETED);
tmpstack = regstack; change_stack (after, &regstack, target_stack, EMIT_BEFORE);
change_stack (after, &tmpstack, target_stack, EMIT_BEFORE);
seq = get_insns (); seq = get_insns ();
end_sequence (); end_sequence ();
...@@ -2928,6 +2914,7 @@ convert_regs_1 (FILE *file, basic_block block) ...@@ -2928,6 +2914,7 @@ convert_regs_1 (FILE *file, basic_block block)
gcc_assert (any_malformed_asm); gcc_assert (any_malformed_asm);
win: win:
bi->stack_out = regstack; bi->stack_out = regstack;
bi->done = true;
} }
/* Convert registers in all blocks reachable from BLOCK. */ /* Convert registers in all blocks reachable from BLOCK. */
...@@ -2975,7 +2962,6 @@ convert_regs_2 (FILE *file, basic_block block) ...@@ -2975,7 +2962,6 @@ convert_regs_2 (FILE *file, basic_block block)
} }
convert_regs_1 (file, block); convert_regs_1 (file, block);
BLOCK_INFO (block)->done = 1;
} }
while (sp != stack); while (sp != stack);
......
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