critical edges handling cleanup

Jan Hubicka jh@suse.cz
Tue Sep 11 07:14:00 GMT 2001


Hi,
this patch removes EDGE_CRITICAL flag and adds trivial EDGE_CRITICAL_P macro.
The mark_critical_edges is one of the top CPU hogs at Brand's testcase and
it is cheap enought to determine the information when needed and expensive
enought to keep it up-to-date to make this sollution superrior IMO.

Regtesting bootstrapping i686 together with previous patches.

Honza

Tue Sep 11 15:42:34 CEST 2001  Jan Hubicka  <jh@suse.cz>

	* basic-block.h (EDGE_CRITICAL): Remove; renumber other flags.
	(EDGE_CRITICAL_P): New predicate.
	* cfg.c (force_nonfallthru_and_redirect, split_edge): Kill EDGE_CRITICAL
	handling.
	(insert_insn_on_edge): Use EDGE_CRITICAL_P.
	(dump_edge_info): Remove "crit".
	* cfganal.c (mark_critical_edges): Kill.
	* cfgbuild.c (find_basic_blocks): Remove mark_critical_edges call.
	* cfgcleanup.c (cleanup_cfg): Likewise.
	* profile.c (instrument_edges): Use EDGE_CRITICAL_P.
	(find_spanning_tree): Likewise.
	* reg-stack.c (convert_regs_1): Likewise.
	* ssa.c (mark_regs_equivalent_over_bad_edges): Likewise.

*** basic-block.h.old	Tue Sep 11 15:34:21 2001
--- basic-block.h	Tue Sep 11 15:51:25 2001
*************** typedef struct edge_def {
*** 140,151 ****
  } *edge;
  
  #define EDGE_FALLTHRU		1
! #define EDGE_CRITICAL		2
! #define EDGE_ABNORMAL		4
! #define EDGE_ABNORMAL_CALL	8
! #define EDGE_EH			16
! #define EDGE_FAKE		32
! #define EDGE_DFS_BACK		64
  
  #define EDGE_COMPLEX	(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
  
--- 140,150 ----
  } *edge;
  
  #define EDGE_FALLTHRU		1
! #define EDGE_ABNORMAL		2
! #define EDGE_ABNORMAL_CALL	4
! #define EDGE_EH			8
! #define EDGE_FAKE		16
! #define EDGE_DFS_BACK		32
  
  #define EDGE_COMPLEX	(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
  
*************** struct edge_list
*** 536,541 ****
--- 535,544 ----
  					  * (e)->probability \
  					  + REG_BR_PROB_BASE / 2) \
  					 / REG_BR_PROB_BASE)
+ 
+ /* Return nonzero if edge is critical.  */
+ #define EDGE_CRITICAL_P(e)		((e)->src->succ->succ_next \
+ 					 && (e)->dest->pred->pred_next)
  
  struct edge_list * create_edge_list	PARAMS ((void));
  void free_edge_list			PARAMS ((struct edge_list *));
*** cfg.c.old	Tue Sep 11 15:36:34 2001
--- cfg.c	Tue Sep 11 16:10:25 2001
*************** force_nonfallthru_and_redirect (e, targe
*** 1278,1284 ****
      }
    else
      jump_block = e->src;
!   e->flags &= ~(EDGE_FALLTHRU | EDGE_CRITICAL);
    label = block_label (target);
    jump_block->end = emit_jump_insn_after (gen_jump (label), jump_block->end);
    JUMP_LABEL (jump_block->end) = label;
--- 1278,1284 ----
      }
    else
      jump_block = e->src;
!   e->flags &= ~EDGE_FALLTHRU;
    label = block_label (target);
    jump_block->end = emit_jump_insn_after (gen_jump (label), jump_block->end);
    JUMP_LABEL (jump_block->end) = label;
*************** split_edge (edge_in)
*** 1530,1536 ****
        COPY_REG_SET (bb->global_live_at_end, edge_in->dest->global_live_at_start);
      }
  
-   edge_in->flags &= ~EDGE_CRITICAL;
    edge_out = make_single_succ_edge (bb, edge_in->dest, EDGE_FALLTHRU);
  
    /* For non-fallthry edges, we must adjust the predecessor's
--- 1530,1535 ----
*************** insert_insn_on_edge (pattern, e)
*** 1557,1564 ****
  {
    /* We cannot insert instructions on an abnormal critical edge.
       It will be easier to find the culprit if we die now.  */
!   if ((e->flags & (EDGE_ABNORMAL|EDGE_CRITICAL))
!       == (EDGE_ABNORMAL|EDGE_CRITICAL))
      abort ();
  
    if (e->insns == NULL_RTX)
--- 1556,1562 ----
  {
    /* We cannot insert instructions on an abnormal critical edge.
       It will be easier to find the culprit if we die now.  */
!   if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e))
      abort ();
  
    if (e->insns == NULL_RTX)
*************** dump_edge_info (file, e, do_succ)
*** 1835,1841 ****
    if (e->flags)
      {
        static const char * const bitnames[] = {
! 	"fallthru", "crit", "ab", "abcall", "eh", "fake", "dfs_back"
        };
        int comma = 0;
        int i, flags = e->flags;
--- 1833,1839 ----
    if (e->flags)
      {
        static const char * const bitnames[] = {
! 	"fallthru", "ab", "abcall", "eh", "fake", "dfs_back"
        };
        int comma = 0;
        int i, flags = e->flags;
*** cfganal.c.old	Tue Sep 11 15:36:14 2001
--- cfganal.c	Tue Sep 11 15:36:30 2001
*************** can_fallthru (src, target)
*** 89,138 ****
    return next_active_insn (insn) == insn2;
  }
  
- /* Identify critical edges and set the bits appropriately.  */
- 
- void
- mark_critical_edges ()
- {
-   int i, n = n_basic_blocks;
-   basic_block bb;
- 
-   /* We begin with the entry block.  This is not terribly important now,
-      but could be if a front end (Fortran) implemented alternate entry
-      points.  */
-   bb = ENTRY_BLOCK_PTR;
-   i = -1;
- 
-   while (1)
-     {
-       edge e;
- 
-       /* (1) Critical edges must have a source with multiple successors.  */
-       if (bb->succ && bb->succ->succ_next)
- 	{
- 	  for (e = bb->succ; e; e = e->succ_next)
- 	    {
- 	      /* (2) Critical edges must have a destination with multiple
- 		 predecessors.  Note that we know there is at least one
- 		 predecessor -- the edge we followed to get here.  */
- 	      if (e->dest->pred->pred_next)
- 		e->flags |= EDGE_CRITICAL;
- 	      else
- 		e->flags &= ~EDGE_CRITICAL;
- 	    }
- 	}
-       else
- 	{
- 	  for (e = bb->succ; e; e = e->succ_next)
- 	    e->flags &= ~EDGE_CRITICAL;
- 	}
- 
-       if (++i >= n)
- 	break;
-       bb = BASIC_BLOCK (i);
-     }
- }
- 
  /* Mark the back edges in DFS traversal.
     Return non-zero if a loop (natural or otherwise) is present.
     Inspired by Depth_First_Search_PP described in:
--- 89,94 ----
*** cfgbuild.c.old	Tue Sep 11 15:39:53 2001
--- cfgbuild.c	Tue Sep 11 15:40:01 2001
*************** find_basic_blocks (f, nregs, file)
*** 659,666 ****
       here and cleanup_cfg, e.g. thread_prologue_and_epilogue_insns.  */
    tidy_fallthru_edges ();
  
-   mark_critical_edges ();
- 
  #ifdef ENABLE_CHECKING
    verify_flow_info ();
  #endif
--- 659,664 ----
*** cfgcleanup.c.old	Tue Sep 11 15:40:09 2001
--- cfgcleanup.c	Tue Sep 11 15:40:17 2001
*************** cleanup_cfg (mode)
*** 1208,1216 ****
    if (try_optimize_cfg (mode))
      delete_unreachable_blocks (), changed = true;
  
-   if (changed)
-     mark_critical_edges ();
- 
    /* Kill the data we won't maintain.  */
    free_EXPR_LIST_list (&label_value_list);
    free_EXPR_LIST_list (&tail_recursion_label_list);
--- 1208,1213 ----
*** profile.c.old	Tue Sep 11 15:37:25 2001
--- profile.c	Tue Sep 11 15:37:48 2001
*************** instrument_edges (el)
*** 152,158 ****
  	      if (rtl_dump_file)
  		fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
  			 e->src->index, e->dest->index,
! 			 e->flags & EDGE_CRITICAL ? " (and split)" : "");
  	      need_func_profiler = 1;
  	      insert_insn_on_edge (
  			 gen_edge_profiler (total_num_edges_instrumented
--- 152,158 ----
  	      if (rtl_dump_file)
  		fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
  			 e->src->index, e->dest->index,
! 			 EDGE_CRITICAL_P (e) ? " (and split)" : "");
  	      need_func_profiler = 1;
  	      insert_insn_on_edge (
  			 gen_edge_profiler (total_num_edges_instrumented
*************** find_spanning_tree (el)
*** 884,890 ****
    for (i = 0; i < num_edges; i++)
      {
        edge e = INDEX_EDGE (el, i);
!       if ((e->flags & EDGE_CRITICAL)
  	  && !EDGE_INFO (e)->ignore
  	  && (find_group (e->src) != find_group (e->dest)))
  	{
--- 884,890 ----
    for (i = 0; i < num_edges; i++)
      {
        edge e = INDEX_EDGE (el, i);
!       if ((EDGE_CRITICAL_P (e))
  	  && !EDGE_INFO (e)->ignore
  	  && (find_group (e->src) != find_group (e->dest)))
  	{
*** reg-stack.c.old	Tue Sep 11 15:37:57 2001
--- reg-stack.c	Tue Sep 11 15:39:00 2001
*************** convert_regs_1 (file, block)
*** 2660,2668 ****
  	beste = e;
        else if (beste->count > e->count)
  	;
!       else if ((e->flags & EDGE_CRITICAL) != (beste->flags & EDGE_CRITICAL))
  	{
! 	  if (e->flags & EDGE_CRITICAL)
  	    beste = e;
  	}
        else if (e->src->index < beste->src->index)
--- 2660,2669 ----
  	beste = e;
        else if (beste->count > e->count)
  	;
!       else if ((EDGE_CRITICAL_P (e) != 0)
! 	       != (EDGE_CRITICAL_P (beste) != 0))
  	{
! 	  if (EDGE_CRITICAL_P (e))
  	    beste = e;
  	}
        else if (e->src->index < beste->src->index)
*** ssa.c.old	Tue Sep 11 15:39:11 2001
--- ssa.c	Tue Sep 11 15:39:35 2001
*************** make_regs_equivalent_over_bad_edges (bb,
*** 1498,1505 ****
  
        /* Scan incoming abnormal critical edges.  */
        for (e = b->pred; e; e = e->pred_next)
! 	if ((e->flags & (EDGE_ABNORMAL | EDGE_CRITICAL)) 
! 		== (EDGE_ABNORMAL | EDGE_CRITICAL))
  	  {
  	    rtx *alt = phi_alternative (set, e->src->index);
  	    int alt_regno;
--- 1498,1504 ----
  
        /* Scan incoming abnormal critical edges.  */
        for (e = b->pred; e; e = e->pred_next)
! 	if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e))
  	  {
  	    rtx *alt = phi_alternative (set, e->src->index);
  	    int alt_regno;



More information about the Gcc-patches mailing list