diff options
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r-- | gcc/tree-cfg.c | 128 |
1 files changed, 41 insertions, 87 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 119d51f3194..6bba74b0142 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 @@ -2713,6 +2650,24 @@ stmt_for_bsi (tree stmt) gcc_unreachable (); } +/* Mark statement T as modified, and update it. */ +static inline void +update_modified_stmts (tree t) +{ + if (TREE_CODE (t) == STATEMENT_LIST) + { + tree_stmt_iterator i; + tree stmt; + for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i)) + { + stmt = tsi_stmt (i); + update_stmt_if_modified (stmt); + } + } + else + update_stmt_if_modified (t); +} + /* Insert statement (or statement list) T before the statement pointed-to by iterator I. M specifies how to update iterator I after insertion (see enum bsi_iterator_update). */ @@ -2721,8 +2676,8 @@ void bsi_insert_before (block_stmt_iterator *i, tree t, enum bsi_iterator_update m) { set_bb_for_stmt (t, i->bb); + update_modified_stmts (t); tsi_link_before (&i->tsi, t, m); - modify_stmt (t); } @@ -2734,8 +2689,8 @@ void bsi_insert_after (block_stmt_iterator *i, tree t, enum bsi_iterator_update m) { set_bb_for_stmt (t, i->bb); + update_modified_stmts (t); tsi_link_after (&i->tsi, t, m); - modify_stmt (t); } @@ -2747,7 +2702,9 @@ bsi_remove (block_stmt_iterator *i) { tree t = bsi_stmt (*i); set_bb_for_stmt (t, NULL); + delink_stmt_imm_use (t); tsi_delink (&i->tsi); + mark_stmt_modified (t); } @@ -2811,7 +2768,7 @@ bsi_replace (const block_stmt_iterator *bsi, tree stmt, bool preserve_eh_info) } *bsi_stmt_ptr (*bsi) = stmt; - modify_stmt (stmt); + update_modified_stmts (stmt); } @@ -3757,7 +3714,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 +3731,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 +3758,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 +3843,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; |