diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2005-04-03 11:26:41 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2005-04-03 11:26:41 +0000 |
commit | 00b28cb030eded609070d66ad864d6ce09261504 (patch) | |
tree | 2307aea9266f2b95acc3d81d3a480cbbb28d87c8 /gcc/bb-reorder.c | |
parent | e16acfcd1431d5448b7e958ab72f783e1f0f1263 (diff) | |
download | gcc-00b28cb030eded609070d66ad864d6ce09261504.zip gcc-00b28cb030eded609070d66ad864d6ce09261504.tar.gz gcc-00b28cb030eded609070d66ad864d6ce09261504.tar.bz2 |
re PR middle-end/20648 (ICE in cfg_layout_redirect_edge_and_branch_force)
PR middle-end/20648
* bb-reorder.c (duplicate_computed_gotos): Do not unfactor
a computed goto if the edge to the computed goto block has
incoming abnormal edges. Clarify how the function works.
From-SVN: r97486
Diffstat (limited to 'gcc/bb-reorder.c')
-rw-r--r-- | gcc/bb-reorder.c | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index f540ab1..6925114 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -2013,33 +2013,49 @@ duplicate_computed_gotos (void) max_size = uncond_jump_length * PARAM_VALUE (PARAM_MAX_GOTO_DUPLICATION_INSNS); candidates = BITMAP_ALLOC (NULL); - /* Build the reorder chain for the original order of blocks. - Look for a computed jump while we are at it. */ + /* Look for blocks that end in a computed jump, and see if such blocks + are suitable for unfactoring. If a block is a candidate for unfactoring, + mark it in the candidates. */ FOR_EACH_BB (bb) { + rtx insn; + edge e; + edge_iterator ei; + int size, all_flags; + + /* Build the reorder chain for the original order of blocks. */ if (bb->next_bb != EXIT_BLOCK_PTR) bb->rbi->next = bb->next_bb; - /* If the block ends in a computed jump and it is small enough, - make it a candidate for duplication. */ - if (computed_jump_p (BB_END (bb)) - && !find_reg_note (BB_END (bb), REG_CROSSING_JUMP, NULL_RTX)) - { - rtx insn; - int size = 0; + /* Obviously the block has to end in a computed jump. */ + if (!computed_jump_p (BB_END (bb))) + continue; - FOR_BB_INSNS (bb, insn) - if (INSN_P (insn)) - { - size += get_attr_length (insn); - if (size > max_size) - break; - } + /* Only consider blocks that can be duplicated. */ + if (find_reg_note (BB_END (bb), REG_CROSSING_JUMP, NULL_RTX) + || !can_duplicate_block_p (bb)) + continue; - if (size <= max_size - && can_duplicate_block_p (bb)) - bitmap_set_bit (candidates, bb->index); - } + /* Make sure that the block is small enough. */ + size = 0; + FOR_BB_INSNS (bb, insn) + if (INSN_P (insn)) + { + size += get_attr_length (insn); + if (size > max_size) + break; + } + if (size > max_size) + continue; + + /* Final check: there must not be any incoming abnormal edges. */ + all_flags = 0; + FOR_EACH_EDGE (e, ei, bb->preds) + all_flags |= e->flags; + if (all_flags & EDGE_COMPLEX) + continue; + + bitmap_set_bit (candidates, bb->index); } /* Nothing to do if there is no computed jump here. */ |