diff options
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r-- | gcc/tree-cfg.c | 102 |
1 files changed, 18 insertions, 84 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 119d51f3194..8bdfe5ba9f6 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -790,7 +790,7 @@ main_block_label (tree label) return label_for_bb[bb->index]; } -/* Cleanup redundant labels. This is a three-steo process: +/* Cleanup redundant labels. This is a three-step process: 1) Find the leading label for each block. 2) Redirect all references to labels to the leading labels. 3) Cleanup all useless labels. */ @@ -1843,69 +1843,6 @@ remove_bb (basic_block bb) remove_phi_nodes_and_edges_for_unreachable_block (bb); } - -/* Examine BB to determine if it is a forwarding block (a block which only - transfers control to a new destination). If BB is a forwarding block, - then return the edge leading to the ultimate destination. */ - -edge -tree_block_forwards_to (basic_block bb) -{ - block_stmt_iterator bsi; - bb_ann_t ann = bb_ann (bb); - tree stmt; - - /* If this block is not forwardable, then avoid useless work. */ - if (! ann->forwardable) - return NULL; - - /* Set this block to not be forwardable. This prevents infinite loops since - any block currently under examination is considered non-forwardable. */ - ann->forwardable = 0; - - /* No forwarding is possible if this block is a special block (ENTRY/EXIT), - this block has more than one successor, this block's single successor is - reached via an abnormal edge, this block has phi nodes, or this block's - single successor has phi nodes. */ - if (bb == EXIT_BLOCK_PTR - || bb == ENTRY_BLOCK_PTR - || EDGE_COUNT (bb->succs) != 1 - || EDGE_SUCC (bb, 0)->dest == EXIT_BLOCK_PTR - || (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL) != 0 - || phi_nodes (bb) - || phi_nodes (EDGE_SUCC (bb, 0)->dest)) - return NULL; - - /* Walk past any labels at the start of this block. */ - for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) - { - stmt = bsi_stmt (bsi); - if (TREE_CODE (stmt) != LABEL_EXPR) - break; - } - - /* If we reached the end of this block we may be able to optimize this - case. */ - if (bsi_end_p (bsi)) - { - edge dest; - - /* Recursive call to pick up chains of forwarding blocks. */ - dest = tree_block_forwards_to (EDGE_SUCC (bb, 0)->dest); - - /* If none found, we forward to bb->succs[0] at minimum. */ - if (!dest) - dest = EDGE_SUCC (bb, 0); - - ann->forwardable = 1; - return dest; - } - - /* No forwarding possible. */ - return NULL; -} - - /* Try to remove superfluous control structures. */ static bool @@ -3757,7 +3694,10 @@ tree_make_forwarder_block (edge fallthru) /* Return true if basic block BB does nothing except pass control flow to another block and that we can safely insert a label at - the start of the successor block. */ + the start of the successor block. + + As a precondition, we require that BB be not equal to + ENTRY_BLOCK_PTR. */ static bool tree_forwarder_block_p (basic_block bb) @@ -3771,17 +3711,25 @@ tree_forwarder_block_p (basic_block bb) if (! bb_ann (bb)->forwardable) return false; - /* BB must have a single outgoing normal edge. Otherwise it can not be - a forwarder block. */ + /* BB must have a single outgoing edge. */ if (EDGE_COUNT (bb->succs) != 1 + /* BB can not have any PHI nodes. This could potentially be + relaxed early in compilation if we re-rewrote the variables + appearing in any PHI nodes in forwarder blocks. */ + || phi_nodes (bb) + /* BB may not be a predecessor of EXIT_BLOCK_PTR. */ || EDGE_SUCC (bb, 0)->dest == EXIT_BLOCK_PTR - || (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL) - || bb == ENTRY_BLOCK_PTR) + /* BB may not have an abnormal outgoing edge. */ + || (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL)) { bb_ann (bb)->forwardable = 0; return false; } +#if ENABLE_CHECKING + gcc_assert (bb != ENTRY_BLOCK_PTR); +#endif + /* Successors of the entry block are not forwarders. */ FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs) if (e->dest == bb) @@ -3790,15 +3738,6 @@ tree_forwarder_block_p (basic_block bb) return false; } - /* BB can not have any PHI nodes. This could potentially be relaxed - early in compilation if we re-rewrote the variables appearing in - any PHI nodes in forwarder blocks. */ - if (phi_nodes (bb)) - { - bb_ann (bb)->forwardable = 0; - return false; - } - /* Now walk through the statements. We can ignore labels, anything else means this is not a forwarder block. */ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) @@ -3884,12 +3823,7 @@ thread_jumps (void) tree_forwarder_block_p (dest); last = EDGE_SUCC (dest, 0), dest = EDGE_SUCC (dest, 0)->dest) - { - if (EDGE_SUCC (dest, 0)->dest == EXIT_BLOCK_PTR) - break; - - bb_ann (dest)->forwardable = 0; - } + bb_ann (dest)->forwardable = 0; /* Reset the forwardable marks to 1. */ for (tmp = e->dest; |