This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] cfg.c: Factor out common code.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 02 Mar 2005 08:36:35 -0500 (EST)
- Subject: [patch] cfg.c: Factor out common code.
Hi,
Attached is a patch to factor out common code in cfg.c.
Several edge manipulation functions have duplicate code to
connect/disconnect an edge to/from an edge vector.
The patch factors out the duplicate code by creating four new
functions:
connect_src,
connect_dest,
disconnect_src, and
disconnct_dest.
Note that my recent introduction of dest_idx made handling of pred
edge vector and succ edge vector asymmetric. This patch hides the
asymmetry from the users of the new functions.
Tested on i686-pc-linux-gnu. OK to apply?
Kazu Hirata
2005-03-02 Kazu Hirata <kazu@cs.umass.edu>
* cfg.c (connect_src, connect_dest, disconnect_src,
disconnct_dest): New.
(unchecked_make_edge, remove_edge, redirect_edge_succ,
redirect_edge_pred): Use the new functions.
Index: cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfg.c,v
retrieving revision 1.82
diff -c -d -p -r1.82 cfg.c
*** cfg.c 22 Feb 2005 15:42:25 -0000 1.82
--- cfg.c 28 Feb 2005 17:05:13 -0000
*************** expunge_block (basic_block b)
*** 243,248 ****
--- 243,305 ----
clear out BB pointer of dead statements consistently. */
}
+ /* Connect E to E->src. */
+
+ static inline void
+ connect_src (edge e)
+ {
+ VEC_safe_push (edge, e->src->succs, e);
+ }
+
+ /* Connect E to E->dest. */
+
+ static inline void
+ connect_dest (edge e)
+ {
+ basic_block dest = e->dest;
+ VEC_safe_push (edge, dest->preds, e);
+ e->dest_idx = EDGE_COUNT (dest->preds) - 1;
+ }
+
+ /* Disconnect edge E from E->src. */
+
+ static inline void
+ disconnect_src (edge e)
+ {
+ basic_block src = e->src;
+ edge_iterator ei;
+ edge tmp;
+
+ for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); )
+ {
+ if (tmp == e)
+ {
+ VEC_unordered_remove (edge, src->succs, ei.index);
+ return;
+ }
+ else
+ ei_next (&ei);
+ }
+
+ gcc_unreachable ();
+ }
+
+ /* Disconnect edge E from E->dest. */
+
+ static inline void
+ disconnect_dest (edge e)
+ {
+ basic_block dest = e->dest;
+ unsigned int dest_idx = e->dest_idx;
+
+ VEC_unordered_remove (edge, dest->preds, dest_idx);
+
+ /* If we removed an edge in the middle of the edge vector, we need
+ to update dest_idx of the edge that moved into the "hole". */
+ if (dest_idx < EDGE_COUNT (dest->preds))
+ EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
+ }
+
/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
created edge. Use this only if you are sure that this edge can't
possibly already exist. */
*************** unchecked_make_edge (basic_block src, ba
*** 254,266 ****
e = ggc_alloc_cleared (sizeof (*e));
n_edges++;
- VEC_safe_push (edge, src->succs, e);
- VEC_safe_push (edge, dst->preds, e);
-
e->src = src;
e->dest = dst;
e->flags = flags;
! e->dest_idx = EDGE_COUNT (dst->preds) - 1;
execute_on_growing_pred (e);
--- 311,322 ----
e = ggc_alloc_cleared (sizeof (*e));
n_edges++;
e->src = src;
e->dest = dst;
e->flags = flags;
!
! connect_src (e);
! connect_dest (e);
execute_on_growing_pred (e);
*************** make_single_succ_edge (basic_block src,
*** 334,371 ****
void
remove_edge (edge e)
{
- edge tmp;
- basic_block src, dest;
- unsigned int dest_idx;
- bool found = false;
- edge_iterator ei;
-
execute_on_shrinking_pred (e);
! src = e->src;
! dest = e->dest;
! dest_idx = e->dest_idx;
!
! for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); )
! {
! if (tmp == e)
! {
! VEC_unordered_remove (edge, src->succs, ei.index);
! found = true;
! break;
! }
! else
! ei_next (&ei);
! }
!
! gcc_assert (found);
!
! VEC_unordered_remove (edge, dest->preds, dest_idx);
!
! /* If we removed an edge in the middle of the edge vector, we need
! to update dest_idx of the edge that moved into the "hole". */
! if (dest_idx < EDGE_COUNT (dest->preds))
! EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
free_edge (e);
}
--- 390,399 ----
void
remove_edge (edge e)
{
execute_on_shrinking_pred (e);
! disconnect_src (e);
! disconnect_dest (e);
free_edge (e);
}
*************** remove_edge (edge e)
*** 375,396 ****
void
redirect_edge_succ (edge e, basic_block new_succ)
{
- basic_block dest = e->dest;
- unsigned int dest_idx = e->dest_idx;
-
execute_on_shrinking_pred (e);
! VEC_unordered_remove (edge, dest->preds, dest_idx);
! /* If we removed an edge in the middle of the edge vector, we need
! to update dest_idx of the edge that moved into the "hole". */
! if (dest_idx < EDGE_COUNT (dest->preds))
! EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
/* Reconnect the edge to the new successor block. */
! VEC_safe_push (edge, new_succ->preds, e);
! e->dest = new_succ;
! e->dest_idx = EDGE_COUNT (new_succ->preds) - 1;
execute_on_growing_pred (e);
}
--- 403,417 ----
void
redirect_edge_succ (edge e, basic_block new_succ)
{
execute_on_shrinking_pred (e);
! disconnect_dest (e);
! e->dest = new_succ;
/* Reconnect the edge to the new successor block. */
! connect_dest (e);
!
execute_on_growing_pred (e);
}
*************** redirect_edge_succ_nodup (edge e, basic_
*** 423,450 ****
void
redirect_edge_pred (edge e, basic_block new_pred)
{
! edge tmp;
! edge_iterator ei;
! bool found = false;
!
! /* Disconnect the edge from the old predecessor block. */
! for (ei = ei_start (e->src->succs); (tmp = ei_safe_edge (ei)); )
! {
! if (tmp == e)
! {
! VEC_unordered_remove (edge, e->src->succs, ei.index);
! found = true;
! break;
! }
! else
! ei_next (&ei);
! }
! gcc_assert (found);
/* Reconnect the edge to the new predecessor block. */
! VEC_safe_push (edge, new_pred->succs, e);
! e->src = new_pred;
}
/* Clear all basic block flags, with the exception of partitioning. */
--- 444,455 ----
void
redirect_edge_pred (edge e, basic_block new_pred)
{
! disconnect_src (e);
! e->src = new_pred;
/* Reconnect the edge to the new predecessor block. */
! connect_src (e);
}
/* Clear all basic block flags, with the exception of partitioning. */