fix bb-reorder wrt call fallthru

Richard Henderson rth@redhat.com
Tue Feb 15 15:41:00 GMT 2005


This problem showed up as an Ada stage2 build failure on Alpha.
The symptom is that we managed to separate a call from the gp
reload that's supposed to immedately follow the call.

This happened because, without feedback information, we assign
equal propability to all of the non-eh edges of blocks that are
not terminated by jumps.  So edges from call sites due to
non-local goto are equal probability with fallthru.  This is
surely not correct, but adjusting it will merely hide the base
problem.

The correct solution is to recognize that rearranging edges from
a call site do no good.  We should *always* prefer the fallthru
edge.  All other edges can only be reached by abnormal means anyway.

Bootstrapped and tested on alpha-linux.


r~


        * bb-reorder.c (find_traces_1_round): Force fallthru edge from a
        call to be best_edge.

Index: bb-reorder.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/bb-reorder.c,v
retrieving revision 1.89
diff -u -p -d -r1.89 bb-reorder.c
--- bb-reorder.c	1 Feb 2005 10:03:04 -0000	1.89
+++ bb-reorder.c	15 Feb 2005 09:25:17 -0000
@@ -488,6 +488,7 @@ find_traces_1_round (int branch_th, int 
       do
 	{
 	  int prob, freq;
+	  bool ends_in_call;
 
 	  /* The probability and frequency of the best edge.  */
 	  int best_prob = INT_MIN / 2;
@@ -501,6 +502,8 @@ find_traces_1_round (int branch_th, int 
 	    fprintf (dump_file, "Basic block %d was visited in trace %d\n",
 		     bb->index, *n_traces - 1);
 
+          ends_in_call = block_ends_with_call_p (bb);
+
 	  /* Select the successor that will be placed after BB.  */
 	  FOR_EACH_EDGE (e, ei, bb->succs)
 	    {
@@ -520,6 +523,19 @@ find_traces_1_round (int branch_th, int 
 	      prob = e->probability;
 	      freq = EDGE_FREQUENCY (e);
 
+	      /* The only sensible preference for a call instruction is the
+		 fallthru edge.  Don't bother selecting anything else.  */
+	      if (ends_in_call)
+		{
+		  if (e->flags & EDGE_CAN_FALLTHRU)
+		    {
+		      best_edge = e;
+		      best_prob = prob;
+		      best_freq = freq;
+		    }
+		  continue;
+		}
+
 	      /* Edge that cannot be fallthru or improbable or infrequent
 		 successor (i.e. it is unsuitable successor).  */
 	      if (!(e->flags & EDGE_CAN_FALLTHRU) || (e->flags & EDGE_COMPLEX)



More information about the Gcc-patches mailing list