diff options
author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-06-04 22:05:35 +0000 |
---|---|---|
committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-06-04 22:05:35 +0000 |
commit | d1b17fc8d96fa3dc7d4f266365204463c31fae8f (patch) | |
tree | 8335f5fc6555b2980dc3a9d65b5fd1347670edd4 /gcc/reg-stack.c | |
parent | e02c27124c59ee703e2f80bb85e4e3889bd344e7 (diff) | |
download | gcc-d1b17fc8d96fa3dc7d4f266365204463c31fae8f.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100602 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r-- | gcc/reg-stack.c | 82 |
1 files changed, 34 insertions, 48 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 5e5fcc74744..7007fcb2bd6 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -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: + gcc_assert (source_stack->top == 0); + gcc_assert (target_stack->top == -1); + return false; + } - 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 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); |