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] Move loop exit updating to remove_edge


Hello,

remove_edge is called on many places throughout the compiler, and in the
project to preserve loops, it would mean adding loop exit rescans on all
these places (I actually did that at first, but there are about 20 of
them, and I am fairly sure I missed some).  So it seems to me that it is
better to just add the rescan directly to remove_edge.

However, I would like to keep low-level cfg manipulation functions
(i.e., those changing just the cfg, not any other structures) separated;
thus, the patch below renames remove_edge to remove_edge_raw, and makes
remove_edge a separate wrapper over it, where the bits updating other
structures can be put.

Bootstrapped & regtested on i686.

Zdenek

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

Index: cfghooks.c
===================================================================
*** cfghooks.c	(revision 125822)
--- cfghooks.c	(working copy)
*************** redirect_edge_and_branch (edge e, basic_
*** 310,319 ****
  
    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);
  
    return ret;
  }
--- 310,319 ----
  
    ret = cfg_hooks->redirect_edge_and_branch (e, dest);
  
!   /* 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;
  }
*************** remove_branch (edge e)
*** 350,358 ****
    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);
  
--- 350,355 ----
*************** remove_branch (edge e)
*** 360,365 ****
--- 357,373 ----
    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.  */
*************** merge_blocks (basic_block a, basic_block
*** 657,667 ****
       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));
!     }
  
    /* Adjust the edges out of B for the new owner.  */
    FOR_EACH_EDGE (e, ei, b->succs)
--- 665,671 ----
       whole lot of them and hope the caller knows what they're doing.  */
  
    while (EDGE_COUNT (a->succs) != 0)
!     remove_edge (EDGE_SUCC (a, 0));
  
    /* Adjust the edges out of B for the new owner.  */
    FOR_EACH_EDGE (e, ei, b->succs)
Index: cfghooks.h
===================================================================
*** cfghooks.h	(revision 125822)
--- cfghooks.h	(working copy)
*************** extern edge redirect_edge_and_branch (ed
*** 144,149 ****
--- 144,150 ----
  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);
Index: cfg.c
===================================================================
*** cfg.c	(revision 125822)
--- cfg.c	(working copy)
*************** make_single_succ_edge (basic_block src, 
*** 352,358 ****
  /* This function will remove an edge from the flow graph.  */
  
  void
! remove_edge (edge e)
  {
    remove_predictions_associated_with_edge (e);
    execute_on_shrinking_pred (e);
--- 352,358 ----
  /* This function will remove an edge from the flow graph.  */
  
  void
! remove_edge_raw (edge e)
  {
    remove_predictions_associated_with_edge (e);
    execute_on_shrinking_pred (e);
Index: basic-block.h
===================================================================
*** basic-block.h	(revision 125822)
--- basic-block.h	(working copy)
*************** extern edge unchecked_make_edge (basic_b
*** 490,496 ****
  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 redirect_edge_succ (edge, basic_block);
  extern edge redirect_edge_succ_nodup (edge, basic_block);
  extern void redirect_edge_pred (edge, basic_block);
--- 490,496 ----
  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_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);


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