Fix frequency and probability updating

Jan Hubicka jh@suse.cz
Fri Jul 27 06:56:00 GMT 2001


Hi,
this patch fixes few remaining places, where the profile info wasn't
updated properly.

Honza

Thu Jul 26 15:58:57 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* basic-block.h (EDGE_FREQUENCY): New macro.
	* bb-reorder (fixup_reorder_chain): Set counts and frequencies
	for new BB/edges.
	* flow.c (find_sub_basic_blocks): Likewise.
	(try_crossjump_to_edge): Likewise; use EDGE_FREQUENCY
	(redirect_edge_and_branch): Use EDGE_FREQUENCY.
*** basic-block.h.nop	Thu Jul 26 02:44:35 2001
--- basic-block.h	Thu Jul 26 02:44:35 2001
*************** struct edge_list 
*** 511,516 ****
--- 511,522 ----
  #define BRANCH_EDGE(bb)			((bb)->succ->flags & EDGE_FALLTHRU \
  					 ? (bb)->succ->succ_next : (bb)->succ)
  
+ /* Return expected execution frequency of the edge E.  */
+ #define EDGE_FREQUENCY(e)		(((e)->src->frequency \
+ 					  * (e)->probability \
+ 					  + REG_BR_PROB_BASE / 2) \
+ 					 / REG_BR_PROB_BASE)
+ 
  struct edge_list * create_edge_list	PARAMS ((void));
  void free_edge_list			PARAMS ((struct edge_list *));
  void print_edge_list			PARAMS ((FILE *, struct edge_list *));
*** bb-reorder.c.nop	Thu Jul 26 02:44:35 2001
--- bb-reorder.c	Thu Jul 26 02:50:28 2001
*************** fixup_reorder_chain ()
*** 721,726 ****
--- 720,727 ----
        nb->global_live_at_start = OBSTACK_ALLOC_REG_SET (&flow_obstack);
        nb->global_live_at_end = OBSTACK_ALLOC_REG_SET (&flow_obstack);
        nb->local_set = 0;
+       nb->count = e_fall->count;
+       nb->frequency = EDGE_FREQUENCY (e_fall);
  
        COPY_REG_SET (nb->global_live_at_start, bb->global_live_at_start);
        COPY_REG_SET (nb->global_live_at_end, bb->global_live_at_start);
*************** fixup_reorder_chain ()
*** 737,742 ****
--- 738,745 ----
        /* Link to new block.  */
        make_edge (NULL, nb, e_fall->dest, 0);
        redirect_edge_succ (e_fall, nb);
+       nb->succ->count = e_fall->count;
+       nb->succ->probability = REG_BR_PROB_BASE;
  
        /* Don't process this new block.  */
        bb = nb;
*** flow.c.nop	Thu Jul 26 02:44:35 2001
--- flow.c	Thu Jul 26 15:23:25 2001
*************** find_sub_basic_blocks (bb)
*** 712,717 ****
--- 712,718 ----
    rtx jump_insn = NULL_RTX;
    edge falltru = 0;
    basic_block first_bb = bb;
+   int i;
  
    if (insn == bb->end)
      return;
*************** find_sub_basic_blocks (bb)
*** 784,789 ****
--- 785,832 ----
    /* Now re-scan and wire in all edges.  This expect simple (conditional)
       jumps at the end of each new basic blocks.  */
    make_edges (NULL, first_bb->index, bb->index, 1);
+ 
+   /* Update branch probabilities.  Expect only (un)conditional jumps
+      to be created with only the forward edges.  */
+   for (i = first_bb->index; i <= bb->index; i++)
+     {
+       edge e,f;
+       basic_block b = BASIC_BLOCK (i);
+       if (b != first_bb)
+ 	{
+ 	  b->count = 0;
+ 	  b->frequency = 0;
+ 	  for (e = b->pred; e; e=e->pred_next)
+ 	    {
+ 	      b->count += e->count;
+ 	      b->frequency += EDGE_FREQUENCY (e);
+ 	    }
+ 	}
+       if (b->succ && b->succ->succ_next && !b->succ->succ_next->succ_next)
+ 	{
+ 	  rtx note = find_reg_note (b->end, REG_BR_PROB, NULL);
+ 	  int probability;
+ 
+ 	  if (!note)
+ 	    continue;
+ 	  probability = INTVAL (XEXP (find_reg_note (b->end,
+ 						     REG_BR_PROB,
+ 						     NULL), 0));
+ 	  e = BRANCH_EDGE (b);
+ 	  e->probability = probability;
+ 	  e->count = ((b->count * probability + REG_BR_PROB_BASE / 2)
+ 		      / REG_BR_PROB_BASE);
+ 	  f = FALLTHRU_EDGE (b);
+ 	  f->probability = REG_BR_PROB_BASE - probability;
+ 	  f->count = b->count - e->count;
+ 	}
+       if (b->succ && !b->succ->succ_next)
+ 	{
+ 	  e = b->succ;
+ 	  e->probability = REG_BR_PROB_BASE;
+ 	  e->count = b->count;
+ 	}
+     }
  }
  
  /* Find all basic blocks of the function whose first insn is F.
*************** redirect_edge_and_branch_force (e, targe
*** 1909,1915 ****
    new_bb->succ = NULL;
    new_bb->pred = NULL;
    new_bb->count = e->count;
!   new_bb->frequency = e->probability * e->src->frequency / REG_BR_PROB_BASE;
    new_bb->loop_depth = e->dest->loop_depth;
  
    new_edge = make_edge (NULL, e->src, new_bb, EDGE_FALLTHRU);
--- 1952,1958 ----
    new_bb->succ = NULL;
    new_bb->pred = NULL;
    new_bb->count = e->count;
!   new_bb->frequency = EDGE_FREQUENCY (e);
    new_bb->loop_depth = e->dest->loop_depth;
  
    new_edge = make_edge (NULL, e->src, new_bb, EDGE_FALLTHRU);
*************** split_edge (edge_in)
*** 2000,2007 ****
  
    /* Wire them up.  */
    bb->count = edge_in->count;
!   bb->frequency = (edge_in->probability * edge_in->src->frequency
! 		   / REG_BR_PROB_BASE);
  
    edge_in->flags &= ~EDGE_CRITICAL;
  
--- 2043,2049 ----
  
    /* Wire them up.  */
    bb->count = edge_in->count;
!   bb->frequency = EDGE_FREQUENCY (edge_in);
  
    edge_in->flags &= ~EDGE_CRITICAL;
  
*************** try_crossjump_to_edge (mode, e1, e2)
*** 3458,3463 ****
--- 3498,3504 ----
    edge s;
    rtx last;
    rtx label;
+   rtx note;
  
    /* Search backward through forwarder blocks.  We don't need to worry
       about multiple entry or chained forwarders, as they will be optimized
*************** try_crossjump_to_edge (mode, e1, e2)
*** 3556,3570 ****
  	{
  	  s->dest->succ->count += s2->count;
  	  s->dest->count += s2->count;
! 	  s->dest->frequency += ((s->probability * s->src->frequency)
! 				 / REG_BR_PROB_BASE);
  	}
        if (forwarder_block_p (s2->dest))
  	{
  	  s2->dest->succ->count -= s2->count;
  	  s2->dest->count -= s2->count;
! 	  s2->dest->frequency -= ((s->probability * s->src->frequency)
! 				  / REG_BR_PROB_BASE);
  	}
        if (!redirect_to->frequency && !src1->frequency)
  	s->probability = (s->probability + s2->probability) / 2;
--- 3597,3609 ----
  	{
  	  s->dest->succ->count += s2->count;
  	  s->dest->count += s2->count;
! 	  s->dest->frequency += EDGE_FREQUENCY (s);
  	}
        if (forwarder_block_p (s2->dest))
  	{
  	  s2->dest->succ->count -= s2->count;
  	  s2->dest->count -= s2->count;
! 	  s2->dest->frequency -= EDGE_FREQUENCY (s);
  	}
        if (!redirect_to->frequency && !src1->frequency)
  	s->probability = (s->probability + s2->probability) / 2;
*************** try_crossjump_to_edge (mode, e1, e2)
*** 3575,3586 ****
  	   / (redirect_to->frequency + src1->frequency));
      }
  
-   /* FIXME: enable once probabilities are fetched properly at CFG build.  */
- #if 0
    note = find_reg_note (redirect_to->end, REG_BR_PROB, 0);
    if (note)
      XEXP (note, 0) = GEN_INT (BRANCH_EDGE (redirect_to)->probability);
- #endif
  
    /* Edit SRC1 to go to REDIRECT_TO at NEWPOS1.  */
  
--- 3614,3622 ----
*************** try_crossjump_to_edge (mode, e1, e2)
*** 3611,3616 ****
--- 3647,3654 ----
    while (src1->succ)
      remove_edge (src1->succ);
    make_edge (NULL, src1, redirect_to, 0);
+   src1->succ->probability = REG_BR_PROB_BASE;
+   src1->succ->count = src1->count;
  
    return true;
  }



More information about the Gcc-patches mailing list