This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]