aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>2004-07-17 20:08:10 +0200
committerZdenek Dvorak <rakdver@gcc.gnu.org>2004-07-17 18:08:10 +0000
commit8a807136e16752e8024f34967cf2071e4c1c284f (patch)
treef9b4d8d5ff8c3cf2b8b7d8b0817c4d09fca2073d
parent0e242c8215a01f83fd09116711e8ec13e5341d93 (diff)
downloadgcc-8a807136e16752e8024f34967cf2071e4c1c284f.zip
gcc-8a807136e16752e8024f34967cf2071e4c1c284f.tar.gz
gcc-8a807136e16752e8024f34967cf2071e4c1c284f.tar.bz2
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
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/loop-init.c2
-rw-r--r--gcc/passes.c2
-rw-r--r--gcc/tree-cfg.c51
-rw-r--r--gcc/tree-ssa-phiopt.c12
5 files changed, 68 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 50b998b..c86cd8e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2004-07-17 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * 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 <graham.stott@btinternet.com>
* 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 ff441e8..35fa12e 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 60b4c08..108d185 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 ac2d5da..c80dcf1 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 bc14dc4..50c845e 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);