summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/basic-block.h2
-rw-r--r--gcc/cfg.c2
-rw-r--r--gcc/cfghooks.c28
-rw-r--r--gcc/cfghooks.h1
5 files changed, 28 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 51c3df30a5c..2955ab87a09 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2007-07-10 Zdenek Dvorak <dvorakz@suse.cz>
+
+ * cfghooks.c (remove_edge): New function.
+ (redirect_edge_and_branch, remove_branch, merge_blocks): Updated
+ loop exit rescans.
+ * cfghooks.h (remove_edge): Declare.
+ * cfg.c (remove_edge): Renamed to remove_edge_raw.
+ * basic-block.h (remove_edge): Declaration changed to remove_edge_raw.
+
2007-07-09 Wolfgang Gellerich <gellerich@de.ibm.com>
* optabs.h: Added declaration for signbit_optab.
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 71396605e43..6d5280eaf1c 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -490,7 +490,7 @@ extern edge unchecked_make_edge (basic_block, basic_block, int);
extern edge cached_make_edge (sbitmap, basic_block, basic_block, int);
extern edge make_edge (basic_block, basic_block, int);
extern edge make_single_succ_edge (basic_block, basic_block, int);
-extern void remove_edge (edge);
+extern void remove_edge_raw (edge);
extern void redirect_edge_succ (edge, basic_block);
extern edge redirect_edge_succ_nodup (edge, basic_block);
extern void redirect_edge_pred (edge, basic_block);
diff --git a/gcc/cfg.c b/gcc/cfg.c
index cf3b4403ef9..020be514ac9 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -352,7 +352,7 @@ make_single_succ_edge (basic_block src, basic_block dest, int flags)
/* This function will remove an edge from the flow graph. */
void
-remove_edge (edge e)
+remove_edge_raw (edge e)
{
remove_predictions_associated_with_edge (e);
execute_on_shrinking_pred (e);
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index 98b5e349e70..286625766e3 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -310,10 +310,10 @@ redirect_edge_and_branch (edge e, basic_block dest)
ret = cfg_hooks->redirect_edge_and_branch (e, dest);
- /* If RET != E, then the edge E was removed since RET already lead to the
- same destination. */
- if (ret != NULL && current_loops != NULL)
- rescan_loop_exit (e, false, ret != e);
+ /* If RET != E, then either the redirection failed, or the edge E
+ was removed since RET already lead to the same destination. */
+ if (current_loops != NULL && ret == e)
+ rescan_loop_exit (e, false, false);
return ret;
}
@@ -350,9 +350,6 @@ remove_branch (edge e)
other = EDGE_SUCC (src, EDGE_SUCC (src, 0) == e);
irr = other->flags & EDGE_IRREDUCIBLE_LOOP;
- if (current_loops != NULL)
- rescan_loop_exit (e, false, true);
-
e = redirect_edge_and_branch (e, other->dest);
gcc_assert (e != NULL);
@@ -360,6 +357,17 @@ remove_branch (edge e)
e->flags |= irr;
}
+/* Removes edge E from cfg. Unlike remove_branch, it does not update IL. */
+
+void
+remove_edge (edge e)
+{
+ if (current_loops != NULL)
+ rescan_loop_exit (e, false, true);
+
+ remove_edge_raw (e);
+}
+
/* Redirect the edge E to basic block DEST even if it requires creating
of a new basic block; then it returns the newly created basic block.
Aborts when redirection is impossible. */
@@ -657,11 +665,7 @@ merge_blocks (basic_block a, basic_block b)
whole lot of them and hope the caller knows what they're doing. */
while (EDGE_COUNT (a->succs) != 0)
- {
- if (current_loops != NULL)
- rescan_loop_exit (EDGE_SUCC (a, 0), false, true);
- remove_edge (EDGE_SUCC (a, 0));
- }
+ remove_edge (EDGE_SUCC (a, 0));
/* Adjust the edges out of B for the new owner. */
FOR_EACH_EDGE (e, ei, b->succs)
diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h
index 46a57fd9ea6..76bf238c5b4 100644
--- a/gcc/cfghooks.h
+++ b/gcc/cfghooks.h
@@ -144,6 +144,7 @@ extern edge redirect_edge_and_branch (edge, basic_block);
extern basic_block redirect_edge_and_branch_force (edge, basic_block);
extern bool can_remove_branch_p (edge);
extern void remove_branch (edge);
+extern void remove_edge (edge);
extern edge split_block (basic_block, void *);
extern edge split_block_after_labels (basic_block);
extern bool move_block_after (basic_block, basic_block);
OpenPOWER on IntegriCloud