From: Zdenek Dvorak Date: Sat, 17 Jul 2004 18:08:10 +0000 (+0200) Subject: loop-init.c (loop_optimizer_init, [...]): Do not destroy dominance information. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8a807136e16752e8024f34967cf2071e4c1c284f;p=gcc.git loop-init.c (loop_optimizer_init, [...]): Do not destroy dominance information. * loop-init.c (loop_optimizer_init, loop_optimizer_finalize): Do not destroy dominance information. * passes.c (rest_of_handle_loop2): Free dominance information. * tree-cfg.c (cleanup_tree_cfg): Remove unreachable blocks before jump threading. (thread_jumps): Update dominance information and remove unreachable blocks. * tree-ssa-phiopt.c (replace_phi_with_stmt): Update dominance information and remove the unreachable block. From-SVN: r84873 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 50b998b1da2..c86cd8e7a5e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2004-07-17 Zdenek Dvorak + + * loop-init.c (loop_optimizer_init, loop_optimizer_finalize): Do not + destroy dominance information. + * passes.c (rest_of_handle_loop2): Free dominance information. + * tree-cfg.c (cleanup_tree_cfg): Remove unreachable blocks before + jump threading. + (thread_jumps): Update dominance information and remove unreachable + blocks. + * tree-ssa-phiopt.c (replace_phi_with_stmt): Update dominance + information and remove the unreachable block. + 2004-07-17 Graham Stott * emit-rtl.c (reorder_insns): Don't set BB for a BARRIER insn. diff --git a/gcc/loop-init.c b/gcc/loop-init.c index ff441e8c56d..35fa12ea3e6 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -55,7 +55,6 @@ loop_optimizer_init (FILE *dumpfile) { /* No loops. */ flow_loops_free (loops); - free_dominance_info (CDI_DOMINATORS); free (loops); return NULL; @@ -105,7 +104,6 @@ loop_optimizer_finalize (struct loops *loops, FILE *dumpfile) /* Clean up. */ flow_loops_free (loops); - free_dominance_info (CDI_DOMINATORS); free (loops); /* Checking. */ diff --git a/gcc/passes.c b/gcc/passes.c index 60b4c08d202..108d18583ad 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -1380,6 +1380,8 @@ rest_of_handle_loop2 (void) loop_optimizer_finalize (loops, dump_file); } + free_dominance_info (CDI_DOMINATORS); + /* Finalize layout changes. */ FOR_EACH_BB (bb) if (bb->next_bb != EXIT_BLOCK_PTR) diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index ac2d5da3c8d..c80dcf1d086 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -733,8 +733,8 @@ cleanup_tree_cfg (void) while (something_changed) { something_changed = cleanup_control_flow (); - something_changed |= thread_jumps (); something_changed |= delete_unreachable_blocks (); + something_changed |= thread_jumps (); } /* Merging the blocks creates no new opportunities for the other @@ -3904,7 +3904,7 @@ static bool thread_jumps (void) { edge e, next, last, old; - basic_block bb, dest, tmp; + basic_block bb, dest, tmp, old_dest, dom; tree phi; int arg; bool retval = false; @@ -3991,11 +3991,9 @@ thread_jumps (void) /* Perform the redirection. */ retval = true; + old_dest = e->dest; e = redirect_edge_and_branch (e, dest); - /* TODO -- updating dominators in this case is simple. */ - free_dominance_info (CDI_DOMINATORS); - if (!old) { /* Update PHI nodes. We know that the new argument should @@ -4009,6 +4007,49 @@ thread_jumps (void) add_phi_arg (&phi, PHI_ARG_DEF (phi, arg), e); } } + + /* Update the dominators. */ + if (dom_computed[CDI_DOMINATORS] >= DOM_CONS_OK) + { + /* Remove the unreachable blocks (observe that if all blocks + were reachable before, only those in the path we threaded + over and did not have any predecessor outside of the path + become unreachable). */ + for (; old_dest != dest; old_dest = tmp) + { + tmp = old_dest->succ->dest; + + if (old_dest->pred) + break; + + delete_basic_block (old_dest); + } + /* If the dominator of the destination was in the path, set its + dominator to the start of the redirected edge. */ + if (get_immediate_dominator (CDI_DOMINATORS, old_dest) == NULL) + set_immediate_dominator (CDI_DOMINATORS, old_dest, bb); + + /* Now proceed like if we forwarded just over one edge at a time. + Algorithm for forwarding over edge A --> B then is + + if (idom (B) == A) + idom (B) = idom (A); + recount_idom (A); */ + + for (; old_dest != dest; old_dest = tmp) + { + tmp = old_dest->succ->dest; + + if (get_immediate_dominator (CDI_DOMINATORS, tmp) == old_dest) + { + dom = get_immediate_dominator (CDI_DOMINATORS, old_dest); + set_immediate_dominator (CDI_DOMINATORS, tmp, dom); + } + + dom = recount_dominator (CDI_DOMINATORS, old_dest); + set_immediate_dominator (CDI_DOMINATORS, old_dest, dom); + } + } } /* Reset the forwardable bit on our block since it's no longer in diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index bc14dc48d80..50c845e7637 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -236,6 +236,8 @@ static void replace_phi_with_stmt (block_stmt_iterator bsi, basic_block bb, basic_block cond_block, tree phi, tree new) { + basic_block block_to_remove; + /* Insert our new statement at the head of our block. */ bsi_insert_after (&bsi, new, BSI_NEW_STMT); @@ -250,21 +252,23 @@ replace_phi_with_stmt (block_stmt_iterator bsi, basic_block bb, release_phi_node (phi); bb_ann (bb)->phi_nodes = NULL; - /* Disconnect the edge leading into the empty block. That will - make the empty block unreachable and it will be removed later. */ + /* Remove the empty basic block. */ if (cond_block->succ->dest == bb) { cond_block->succ->flags |= EDGE_FALLTHRU; cond_block->succ->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE); - ssa_remove_edge (cond_block->succ->succ_next); + + block_to_remove = cond_block->succ->succ_next->dest; } else { cond_block->succ->succ_next->flags |= EDGE_FALLTHRU; cond_block->succ->succ_next->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE); - ssa_remove_edge (cond_block->succ); + + block_to_remove = cond_block->succ->dest; } + delete_basic_block (block_to_remove); /* Eliminate the COND_EXPR at the end of COND_BLOCK. */ bsi = bsi_last (cond_block);