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]

[google] Propagate profile information to RTL level during switch expansion


This patch propagates profile information to RTL level when expanding
switch statements using jump table or a binary tree of branches.

Ok for google/gcc-4_6 branch? I  would like the patch to be considered
for trunk when stage 1 opens again.

-Easwaran

2012-01-31  Easwaran Raman  <eraman@google.com>

	* expr.c (do_tablejump): Add default_probability as the
	sixth parameter and use it to generate REG_BR_PROB note.
	(try_tablejump): Add default_probability as a parameter.
	* cfgbuild.c (non_zero_profile_counts): New function.
	(compute_outgoing_frequencies): If edges have profile counts
	set, don't replace them with guessed values.
	* expr.h (try_tablejump): Add additional parameter to the
	declaration.
	* stmt.c (tree-flow.h): Include.
	(case_node): Add new fields count and subtree_count.
	(add_case_node): Pass count as a paramater and initialize
	count field of case_node.
	(case_probability): New macro.
	(expand_case): Propagate profile information from the tree
	level to RTL during switch case expansion.
	(balance_case_nodes): Compute subtree_count for case nodes.
	(emit_case_nodes): Set branch probabilities for generated
	branches.

testsuite/ChengeLog.google-4_6:

2012-01-31  Easwaran Raman  <eraman@google.com>

	* tree-prof/switch-case-1.c: New test.
	* tree-prof/switch-case-2.c: New test.
Index: gcc/testsuite/gcc.dg/tree-prof/switch-case-1.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-prof/switch-case-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-prof/switch-case-1.c	(revision 0)
@@ -0,0 +1,40 @@
+/* { dg-options "-O2 -fdump-rtl-expand-blocks -fdump-tree-optimized-blocks" } */
+int g;
+
+__attribute__((noinline)) void foo (int  n)
+{
+  switch (n)
+    {
+    case 1:
+      g++; break;
+    case 2:
+      g += 2; break;
+    case 3:
+      g += 1; break;
+    case 4:
+      g += 3; break;
+    case 5:
+      g += 4; break;
+    case 6:
+      g += 5; break;
+    case 7:
+      g += 6; break;
+    case 8:
+      g += 7; break;
+    case 9:
+      g += 8; break;
+    default:
+      g += 8; break;
+   }
+}
+
+int main ()
+{
+ int i;
+ for (i = 0; i < 10000; i++)
+   foo ((i * i) % 5);
+ return 0;
+}
+/* { dg-final-use { scan-rtl-dump-times "Succ edge\[^\\n\]*count:4000" 4 "expand"} } */
+/* { dg-final-use { scan-rtl-dump-times "Succ edge\[^\\n\]*count:2000" 1 "expand"} } */
+/* { dg-final-use { cleanup-rtl-dump "expand" } } */
Index: gcc/testsuite/gcc.dg/tree-prof/switch-case-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-prof/switch-case-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-prof/switch-case-2.c	(revision 0)
@@ -0,0 +1,40 @@
+/* { dg-options "-O2 -fdump-rtl-expand-blocks" } */
+int g;
+
+__attribute__((noinline)) void foo (int  n)
+{
+  switch (n)
+    {
+    case 99:
+      g += 2; break;
+    case 1:
+      g++; break;
+    case 100:
+      g += 1; break;
+    case 4:
+      g += 3; break;
+    case 5:
+      g += 4; break;
+    case 6:
+      g += 5; break;
+    case 7:
+      g += 6; break;
+    case 8:
+      g += 7; break;
+    case 9:
+      g += 8; break;
+    default:
+      g += 8; break;
+   }
+}
+
+int main ()
+{
+ int i;
+ for (i = 0; i < 10000; i++)
+   foo ((i * i) % 5);
+ return 0;
+}
+/* { dg-final-use { scan-rtl-dump-times "Succ edge\[^\\n\]*count:4000" 4 "expand"} } */
+/* { dg-final-use { scan-rtl-dump-times "Succ edge\[^\\n\]*count:2000" 1 "expand"} } */
+/* { dg-final-use { cleanup-rtl-dump "expand" } } */
Index: gcc/expr.c
===================================================================
--- gcc/expr.c	(revision 183262)
+++ gcc/expr.c	(working copy)
@@ -155,7 +155,7 @@ static rtx do_store_flag (sepops, rtx, enum machin
 #ifdef PUSH_ROUNDING
 static void emit_single_push_insn (enum machine_mode, rtx, tree);
 #endif
-static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx);
+static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx, int);
 static rtx const_vector_from_tree (tree);
 static void write_complex_part (rtx, rtx, bool);
 
@@ -10245,7 +10245,7 @@ try_casesi (tree index_type, tree index_expr, tree
 
 static void
 do_tablejump (rtx index, enum machine_mode mode, rtx range, rtx table_label,
-	      rtx default_label)
+	      rtx default_label, int default_probability)
 {
   rtx temp, vector;
 
@@ -10261,9 +10261,17 @@ do_tablejump (rtx index, enum machine_mode mode, r
      the maximum value of the range.  */
 
   if (default_label)
-    emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
-			     default_label);
+    {
+      emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
+			       default_label);
+      if (default_probability != -1)
+        {
+          rtx jump_insn = get_last_insn();
+          add_reg_note (jump_insn, REG_BR_PROB, GEN_INT (default_probability));
+        }
+    }
 
+
   /* If index is in range, it must fit in Pmode.
      Convert to Pmode so we can index with it.  */
   if (mode != Pmode)
@@ -10305,7 +10313,7 @@ do_tablejump (rtx index, enum machine_mode mode, r
 
 int
 try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
-	       rtx table_label, rtx default_label)
+	       rtx table_label, rtx default_label, int default_probability)
 {
   rtx index;
 
@@ -10323,7 +10331,7 @@ try_tablejump (tree index_type, tree index_expr, t
 			       TYPE_MODE (TREE_TYPE (range)),
 			       expand_normal (range),
 			       TYPE_UNSIGNED (TREE_TYPE (range))),
-		table_label, default_label);
+		table_label, default_label, default_probability);
   return 1;
 }
 
Index: gcc/cfgbuild.c
===================================================================
--- gcc/cfgbuild.c	(revision 183262)
+++ gcc/cfgbuild.c	(working copy)
@@ -522,6 +522,17 @@ find_bb_boundaries (basic_block bb)
     purge_dead_tablejump_edges (bb, table);
 }
 
+static bool non_zero_profile_counts ( VEC(edge,gc) *edges) {
+  edge e;
+  edge_iterator ei;
+  FOR_EACH_EDGE(e, ei, edges)
+    {
+      if (e->count > 0)
+        return true;
+    }
+  return false;
+}
+
 /*  Assume that frequency of basic block B is known.  Compute frequencies
     and probabilities of outgoing edges.  */
 
@@ -549,7 +560,6 @@ compute_outgoing_frequencies (basic_block b)
 	  return;
 	}
     }
-
   if (single_succ_p (b))
     {
       e = single_succ_edge (b);
@@ -557,6 +567,10 @@ compute_outgoing_frequencies (basic_block b)
       e->count = b->count;
       return;
     }
+  else if (non_zero_profile_counts (b->succs)){
+    /*Profile counts already set, but REG_NOTE missing. Retain the counts.  */
+    return;
+  }
   guess_outgoing_edge_probabilities (b);
   if (b->count)
     FOR_EACH_EDGE (e, ei, b->succs)
Index: gcc/expr.h
===================================================================
--- gcc/expr.h	(revision 183262)
+++ gcc/expr.h	(working copy)
@@ -464,7 +464,7 @@ extern void do_compare_rtx_and_jump (rtx, rtx, enu
 
 /* Two different ways of generating switch statements.  */
 extern int try_casesi (tree, tree, tree, tree, rtx, rtx, rtx);
-extern int try_tablejump (tree, tree, tree, tree, rtx, rtx);
+extern int try_tablejump (tree, tree, tree, tree, rtx, rtx, int);
 
 /* Functions from alias.c */
 #include "alias.h"
Index: gcc/stmt.c
===================================================================
--- gcc/stmt.c	(revision 183262)
+++ gcc/stmt.c	(working copy)
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "pretty-print.h"
 #include "coverage.h"
 #include "bitmap.h"
+#include "tree-flow.h"
 
 
 /* Functions and data structures for expanding case statements.  */
@@ -93,6 +94,7 @@ struct case_node
   tree			low;	/* Lowest index value for this label */
   tree			high;	/* Highest index value for this label */
   tree			code_label; /* Label to jump to when node matches */
+  gcov_type             subtree_count, count; /* Execution counts */
 };
 
 typedef struct case_node case_node;
@@ -125,9 +127,10 @@ static void balance_case_nodes (case_node_ptr *, c
 static int node_has_low_bound (case_node_ptr, tree);
 static int node_has_high_bound (case_node_ptr, tree);
 static int node_is_bounded (case_node_ptr, tree);
-static void emit_case_nodes (rtx, case_node_ptr, rtx, tree);
+static void emit_case_nodes (rtx, case_node_ptr, rtx, int, tree);
 static struct case_node *add_case_node (struct case_node *, tree,
-                                        tree, tree, tree, alloc_pool);
+                                        tree, tree, tree, gcov_type,
+                                        alloc_pool);
 
 
 /* Return the rtx-label that corresponds to a LABEL_DECL,
@@ -2030,7 +2033,7 @@ expand_stack_restore (tree var)
 
 static struct case_node *
 add_case_node (struct case_node *head, tree type, tree low, tree high,
-               tree label, alloc_pool case_node_pool)
+               tree label, gcov_type count, alloc_pool case_node_pool)
 {
   tree min_value, max_value;
   struct case_node *r;
@@ -2089,6 +2092,8 @@ add_case_node (struct case_node *head, tree type,
 				TREE_INT_CST_HIGH (high));
   r->code_label = label;
   r->parent = r->left = NULL;
+  r->count = count;
+  r->subtree_count = 0;
   r->right = head;
   return r;
 }
@@ -2272,6 +2277,8 @@ expand_switch_using_bit_tests_p (tree index_expr,
 	      || (uniq == 3 && count >= 6)));
 }
 
+#define case_probability(x, y) ((y) ? ((x) * REG_BR_PROB_BASE  / (y))  : -1)
+
 /* Terminate a case (Pascal/Ada) or switch (C) statement
    in which ORIG_INDEX is the expression to be tested.
    If ORIG_TYPE is not NULL, it is the original ORIG_INDEX
@@ -2295,6 +2302,7 @@ expand_case (gimple stmt)
   tree index_expr = gimple_switch_index (stmt);
   tree index_type = TREE_TYPE (index_expr);
   int unsignedp = TYPE_UNSIGNED (index_type);
+  basic_block bb = gimple_bb (stmt);
 
   /* The insn after which the case dispatch should finally
      be emitted.  Zero for a dummy.  */
@@ -2307,6 +2315,8 @@ expand_case (gimple stmt)
   /* Label to jump to if no case matches.  */
   tree default_label_decl = NULL_TREE;
 
+  int default_count = 0;
+
   alloc_pool case_node_pool = create_alloc_pool ("struct case_node pool",
                                                  sizeof (struct case_node),
                                                  100);
@@ -2318,7 +2328,9 @@ expand_case (gimple stmt)
     {
       tree elt;
       bitmap label_bitmap;
+      edge case_edge = NULL, default_edge = NULL;
       int stopi = 0;
+      bool has_gaps = false;
 
       /* cleanup_tree_cfg removes all SWITCH_EXPR with their index
 	 expressions being INTEGER_CST.  */
@@ -2329,12 +2341,17 @@ expand_case (gimple stmt)
       if (!CASE_LOW (elt) && !CASE_HIGH (elt))
 	{
 	  default_label_decl = CASE_LABEL (elt);
+          case_edge = EDGE_SUCC(bb, 0);
+          default_edge = case_edge;
+          default_count = case_edge->count;
 	  stopi = 1;
 	}
 
       for (i = gimple_switch_num_labels (stmt) - 1; i >= stopi; --i)
 	{
 	  tree low, high;
+          basic_block case_bb;
+          edge case_edge;
 	  elt = gimple_switch_label (stmt, i);
 
 	  low = CASE_LOW (elt);
@@ -2344,9 +2361,11 @@ expand_case (gimple stmt)
 	  /* Discard empty ranges.  */
 	  if (high && tree_int_cst_lt (high, low))
 	    continue;
-
+          case_bb = label_to_block (CASE_LABEL(elt));
+          case_edge = find_edge (bb, case_bb);
 	  case_list = add_case_node (case_list, index_type, low, high,
-                                     CASE_LABEL (elt), case_node_pool);
+                                     CASE_LABEL (elt), case_edge->count,
+                                     case_node_pool);
 	}
 
 
@@ -2370,6 +2389,15 @@ expand_case (gimple stmt)
 	    }
 	  else
 	    {
+              tree min_minus_one = fold_build2 (MINUS_EXPR, index_type,
+                                                n->low,
+                                                build_int_cst (index_type, 1));
+              /* case_list is sorted in increasing order. If the minval - 1 of
+                 this node is greater than the previous maxval, then there is a
+                 gap. If jump table expansion is used, this gap will be filled
+                 with the default label.  */
+	      if (tree_int_cst_lt (maxval, min_minus_one))
+		has_gaps = true;
 	      if (tree_int_cst_lt (n->low, minval))
 		minval = n->low;
 	      if (tree_int_cst_lt (maxval, n->high))
@@ -2481,18 +2509,23 @@ expand_case (gimple stmt)
 
 	  use_cost_table = estimate_case_costs (case_list);
 	  balance_case_nodes (&case_list, NULL);
-	  emit_case_nodes (index, case_list, default_label, index_type);
+	  emit_case_nodes (index, case_list, default_label, default_count,
+                           index_type);
 	  if (default_label)
 	    emit_jump (default_label);
 	}
       else
 	{
 	  rtx fallback_label = label_rtx (case_list->code_label);
+          edge e;
+          edge_iterator ei;
+          int count = bb->count;
 	  table_label = gen_label_rtx ();
 	  if (! try_casesi (index_type, index_expr, minval, range,
 			    table_label, default_label, fallback_label))
 	    {
 	      bool ok;
+              int default_probability;
 
 	      /* Index jumptables from zero for suitable values of
                  minval to avoid a subtraction.  */
@@ -2502,12 +2535,37 @@ expand_case (gimple stmt)
 		{
 		  minval = build_int_cst (index_type, 0);
 		  range = maxval;
+                  has_gaps = true;
 		}
+              if (has_gaps)
+                {
+                  /* There is at least one entry in the jump table that jumps
+                     to default label. The default label can either be reached
+                     through the indirect jump or the direct conditional jump
+                     before that. Split the probability of reaching the
+                     default label among these two jumps.  */
+                  default_probability = case_probability (default_count/2,
+                                                          bb->count);
+                  default_count /= 2;
+                  count -= default_count;
+                }
+              else
+                {
+                  default_probability = case_probability (default_count,
+                                                          bb->count);
+                  count -= default_count;
+                  default_count = 0;
+                }
 
 	      ok = try_tablejump (index_type, index_expr, minval, range,
-				  table_label, default_label);
+				  table_label, default_label,
+                                  default_probability);
 	      gcc_assert (ok);
 	    }
+          default_edge->count = default_count;
+          if (count)
+            FOR_EACH_EDGE (e, ei, bb->succs)
+              e->probability = e->count * REG_BR_PROB_BASE / count;
 
 	  /* Get table of labels to jump to, in order of case index.  */
 
@@ -2572,10 +2630,10 @@ expand_case (gimple stmt)
 
 static void
 do_jump_if_equal (enum machine_mode mode, rtx op0, rtx op1, rtx label,
-		  int unsignedp)
+		  int unsignedp, int prob)
 {
   do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode,
-			   NULL_RTX, NULL_RTX, label, -1);
+			   NULL_RTX, NULL_RTX, label, prob);
 }
 
 /* Not all case values are encountered equally.  This function
@@ -2679,6 +2737,7 @@ balance_case_nodes (case_node_ptr *head, case_node
       int cost = 0;
       int i = 0;
       int ranges = 0;
+      gcov_type count = 0;
       case_node_ptr *npp;
       case_node_ptr left;
 
@@ -2728,9 +2787,15 @@ balance_case_nodes (case_node_ptr *head, case_node
 		     side and fill in `parent' fields for right-hand side.  */
 		  np = *head;
 		  np->parent = parent;
+                  np->subtree_count = count;
 		  balance_case_nodes (&np->left, np);
-		  for (; np->right; np = np->right)
+                  if (np->left)
+                    np->subtree_count += np->left->subtree_count;
+
+		  for (; np->right; np = np->right) {
 		    np->right->parent = np;
+                    (*head)->subtree_count += np->right->count;
+                  }
 		  return;
 		}
 	    }
@@ -2762,6 +2827,11 @@ balance_case_nodes (case_node_ptr *head, case_node
 	  /* Optimize each of the two split parts.  */
 	  balance_case_nodes (&np->left, np);
 	  balance_case_nodes (&np->right, np);
+          np->subtree_count = np->count;
+          if (np->left)
+            np->subtree_count += np->left->subtree_count;
+          if (np->right)
+            np->subtree_count += np->right->subtree_count;
 	}
       else
 	{
@@ -2769,8 +2839,11 @@ balance_case_nodes (case_node_ptr *head, case_node
 	     but fill in `parent' fields.  */
 	  np = *head;
 	  np->parent = parent;
-	  for (; np->right; np = np->right)
+          np->subtree_count = np->count;
+	  for (; np->right; np = np->right) {
 	    np->right->parent = np;
+            (*head)->subtree_count += np->right->subtree_count;
+          }
 	}
     }
 }
@@ -2883,6 +2956,17 @@ node_is_bounded (case_node_ptr node, tree index_ty
 	  && node_has_high_bound (node, index_type));
 }
 
+
+static void
+add_prob_note_to_last_insn(int probability)
+{
+  if (probability != -1)
+    {
+      rtx jump_insn = get_last_insn();
+      add_reg_note (jump_insn, REG_BR_PROB, GEN_INT (probability));
+    }
+}
+
 /* Emit step-by-step code to select a case for the value of INDEX.
    The thus generated decision tree follows the form of the
    case-node binary tree NODE, whose nodes represent test conditions.
@@ -2911,10 +2995,12 @@ node_is_bounded (case_node_ptr node, tree index_ty
 
 static void
 emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
-		 tree index_type)
+		 int default_count, tree index_type)
 {
   /* If INDEX has an unsigned type, we must make unsigned branches.  */
   int unsignedp = TYPE_UNSIGNED (index_type);
+  int probability;
+  gcov_type count = node->count, subtree_count = node->subtree_count;
   enum machine_mode mode = GET_MODE (index);
   enum machine_mode imode = TYPE_MODE (index_type);
 
@@ -2929,15 +3015,17 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 
   else if (tree_int_cst_equal (node->low, node->high))
     {
+      probability = case_probability (count, subtree_count + default_count);
       /* Node is single valued.  First see if the index expression matches
 	 this node and then check our children, if any.  */
-
       do_jump_if_equal (mode, index,
 			convert_modes (mode, imode,
 				       expand_normal (node->low),
 				       unsignedp),
-			label_rtx (node->code_label), unsignedp);
-
+			label_rtx (node->code_label), unsignedp, probability);
+      /* Since this case is taken at this point, reduce its weight from
+         subtree_weight.  */
+      subtree_count -= count;
       if (node->right != 0 && node->left != 0)
 	{
 	  /* This node has children on both sides.
@@ -2955,7 +3043,11 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 					unsignedp),
 				       GT, NULL_RTX, mode, unsignedp,
 				       label_rtx (node->right->code_label));
-	      emit_case_nodes (index, node->left, default_label, index_type);
+              probability = case_probability (node->right->count,
+                                              subtree_count + default_count);
+              add_prob_note_to_last_insn (probability);
+	      emit_case_nodes (index, node->left, default_label, default_count,
+                               index_type);
 	    }
 
 	  else if (node_is_bounded (node->left, index_type))
@@ -2967,7 +3059,10 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 					unsignedp),
 				       LT, NULL_RTX, mode, unsignedp,
 				       label_rtx (node->left->code_label));
-	      emit_case_nodes (index, node->right, default_label, index_type);
+              probability = case_probability (node->left->count,
+                                              subtree_count + default_count);
+              add_prob_note_to_last_insn (probability);
+	      emit_case_nodes (index, node->right, default_label, default_count, index_type);
 	    }
 
 	  /* If both children are single-valued cases with no
@@ -2985,21 +3080,25 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 
 	      /* See if the value matches what the right hand side
 		 wants.  */
+              probability = case_probability (node->right->count,
+                                              subtree_count + default_count);
 	      do_jump_if_equal (mode, index,
 				convert_modes (mode, imode,
 					       expand_normal (node->right->low),
 					       unsignedp),
 				label_rtx (node->right->code_label),
-				unsignedp);
+				unsignedp, probability);
 
 	      /* See if the value matches what the left hand side
 		 wants.  */
+              probability = case_probability (node->left->count,
+                                              subtree_count + default_count);
 	      do_jump_if_equal (mode, index,
 				convert_modes (mode, imode,
 					       expand_normal (node->left->low),
 					       unsignedp),
 				label_rtx (node->left->code_label),
-				unsignedp);
+				unsignedp, probability);
 	    }
 
 	  else
@@ -3019,10 +3118,18 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 					unsignedp),
 				       GT, NULL_RTX, mode, unsignedp,
 				       label_rtx (test_label));
+              /* The default label could be reached either through the right
+                 subtree or the left subtree. Divide the probability
+                 equally.  */
+              probability = case_probability (
+                  node->right->subtree_count + default_count/2,
+                  subtree_count + default_count);
+              default_count /= 2;
+              add_prob_note_to_last_insn (probability);
 
 	      /* Value must be on the left.
 		 Handle the left-hand subtree.  */
-	      emit_case_nodes (index, node->left, default_label, index_type);
+	      emit_case_nodes (index, node->left, default_label, default_count, index_type);
 	      /* If left-hand subtree does nothing,
 		 go to default.  */
 	      if (default_label)
@@ -3030,7 +3137,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 
 	      /* Code branches here for the right-hand subtree.  */
 	      expand_label (test_label);
-	      emit_case_nodes (index, node->right, default_label, index_type);
+	      emit_case_nodes (index, node->right, default_label, default_count, index_type);
 	    }
 	}
 
@@ -3055,21 +3162,29 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 					    unsignedp),
 					   LT, NULL_RTX, mode, unsignedp,
 					   default_label);
+                  probability = case_probability (default_count/2,
+                                                  subtree_count + default_count);
+                  default_count /= 2;
+                  add_prob_note_to_last_insn (probability);
 		}
 
-	      emit_case_nodes (index, node->right, default_label, index_type);
+	      emit_case_nodes (index, node->right, default_label, default_count, index_type);
 	    }
 	  else
-	    /* We cannot process node->right normally
-	       since we haven't ruled out the numbers less than
-	       this node's value.  So handle node->right explicitly.  */
-	    do_jump_if_equal (mode, index,
-			      convert_modes
-			      (mode, imode,
-			       expand_normal (node->right->low),
-			       unsignedp),
-			      label_rtx (node->right->code_label), unsignedp);
-	}
+            {
+              probability = case_probability (node->right->subtree_count,
+                                              subtree_count + default_count);
+	      /* We cannot process node->right normally
+	         since we haven't ruled out the numbers less than
+	         this node's value.  So handle node->right explicitly.  */
+	      do_jump_if_equal (mode, index,
+			        convert_modes
+			        (mode, imode,
+			         expand_normal (node->right->low),
+			         unsignedp),
+			        label_rtx (node->right->code_label), unsignedp, probability);
+            }
+	  }
 
       else if (node->right == 0 && node->left != 0)
 	{
@@ -3086,20 +3201,29 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 					    unsignedp),
 					   GT, NULL_RTX, mode, unsignedp,
 					   default_label);
+                  probability = case_probability (
+                      default_count/2, subtree_count + default_count);
+                  default_count /= 2;
+                  add_prob_note_to_last_insn (probability);
 		}
 
-	      emit_case_nodes (index, node->left, default_label, index_type);
+	      emit_case_nodes (index, node->left, default_label,
+                               default_count, index_type);
 	    }
 	  else
-	    /* We cannot process node->left normally
-	       since we haven't ruled out the numbers less than
-	       this node's value.  So handle node->left explicitly.  */
-	    do_jump_if_equal (mode, index,
-			      convert_modes
-			      (mode, imode,
-			       expand_normal (node->left->low),
-			       unsignedp),
-			      label_rtx (node->left->code_label), unsignedp);
+            {
+              probability = case_probability (node->left->subtree_count,
+                                              subtree_count + default_count);
+	      /* We cannot process node->left normally
+	         since we haven't ruled out the numbers less than
+	         this node's value.  So handle node->left explicitly.  */
+	      do_jump_if_equal (mode, index,
+			        convert_modes
+			        (mode, imode,
+			         expand_normal (node->left->low),
+			         unsignedp),
+			        label_rtx (node->left->code_label), unsignedp, probability);
+            }
 	}
     }
   else
@@ -3118,15 +3242,20 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 	  tree test_label = 0;
 
 	  if (node_is_bounded (node->right, index_type))
-	    /* Right hand node is fully bounded so we can eliminate any
-	       testing and branch directly to the target code.  */
-	    emit_cmp_and_jump_insns (index,
-				     convert_modes
-				     (mode, imode,
-				      expand_normal (node->high),
-				      unsignedp),
-				     GT, NULL_RTX, mode, unsignedp,
-				     label_rtx (node->right->code_label));
+            {
+	      /* Right hand node is fully bounded so we can eliminate any
+	         testing and branch directly to the target code.  */
+	      emit_cmp_and_jump_insns (index,
+				       convert_modes
+				       (mode, imode,
+				        expand_normal (node->high),
+				        unsignedp),
+				       GT, NULL_RTX, mode, unsignedp,
+				       label_rtx (node->right->code_label));
+              probability = case_probability (node->right->subtree_count,
+                                              subtree_count + default_count);
+              add_prob_note_to_last_insn (probability);
+            }
 	  else
 	    {
 	      /* Right hand node requires testing.
@@ -3141,6 +3270,10 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 					unsignedp),
 				       GT, NULL_RTX, mode, unsignedp,
 				       label_rtx (test_label));
+              probability = case_probability (node->right->subtree_count + default_count/2,
+                                              subtree_count + default_count);
+              default_count /= 2;
+              add_prob_note_to_last_insn (probability);
 	    }
 
 	  /* Value belongs to this node or to the left-hand subtree.  */
@@ -3152,9 +3285,11 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 				    unsignedp),
 				   GE, NULL_RTX, mode, unsignedp,
 				   label_rtx (node->code_label));
+          probability = case_probability (count, subtree_count + default_count);
+          add_prob_note_to_last_insn (probability);
 
 	  /* Handle the left-hand subtree.  */
-	  emit_case_nodes (index, node->left, default_label, index_type);
+	  emit_case_nodes (index, node->left, default_label, default_count, index_type);
 
 	  /* If right node had to be handled later, do that now.  */
 
@@ -3166,7 +3301,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 		emit_jump (default_label);
 
 	      expand_label (test_label);
-	      emit_case_nodes (index, node->right, default_label, index_type);
+	      emit_case_nodes (index, node->right, default_label, default_count, index_type);
 	    }
 	}
 
@@ -3183,6 +3318,10 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 					unsignedp),
 				       LT, NULL_RTX, mode, unsignedp,
 				       default_label);
+              probability = case_probability (default_count/2,
+                                              subtree_count + default_count);
+              default_count /= 2;
+              add_prob_note_to_last_insn (probability);
 	    }
 
 	  /* Value belongs to this node or to the right-hand subtree.  */
@@ -3194,8 +3333,10 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 				    unsignedp),
 				   LE, NULL_RTX, mode, unsignedp,
 				   label_rtx (node->code_label));
+          probability = case_probability (count, subtree_count + default_count);
+          add_prob_note_to_last_insn (probability);
 
-	  emit_case_nodes (index, node->right, default_label, index_type);
+	  emit_case_nodes (index, node->right, default_label, default_count, index_type);
 	}
 
       else if (node->right == 0 && node->left != 0)
@@ -3211,6 +3352,10 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 					unsignedp),
 				       GT, NULL_RTX, mode, unsignedp,
 				       default_label);
+              probability = case_probability (default_count/2,
+                                              subtree_count + default_count);
+              default_count /= 2;
+              add_prob_note_to_last_insn (probability);
 	    }
 
 	  /* Value belongs to this node or to the left-hand subtree.  */
@@ -3222,8 +3367,10 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 				    unsignedp),
 				   GE, NULL_RTX, mode, unsignedp,
 				   label_rtx (node->code_label));
+          probability = case_probability (count, subtree_count + default_count);
+          add_prob_note_to_last_insn (probability);
 
-	  emit_case_nodes (index, node->left, default_label, index_type);
+	  emit_case_nodes (index, node->left, default_label, default_count, index_type);
 	}
 
       else
@@ -3243,6 +3390,9 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 					unsignedp),
 				       GT, NULL_RTX, mode, unsignedp,
 				       default_label);
+              probability = case_probability (default_count,
+                                              subtree_count + default_count);
+              add_prob_note_to_last_insn (probability);
 	    }
 
 	  else if (!low_bound && high_bound)
@@ -3254,6 +3404,9 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 					unsignedp),
 				       LT, NULL_RTX, mode, unsignedp,
 				       default_label);
+              probability = case_probability (default_count,
+                                              subtree_count + default_count);
+              add_prob_note_to_last_insn (probability);
 	    }
 	  else if (!low_bound && !high_bound)
 	    {
@@ -3275,6 +3428,9 @@ emit_case_nodes (rtx index, case_node_ptr node, rt
 
 	      emit_cmp_and_jump_insns (new_index, new_bound, GT, NULL_RTX,
 				       mode, 1, default_label);
+              probability = case_probability (default_count,
+                                              subtree_count + default_count);
+              add_prob_note_to_last_insn (probability);
 	    }
 
 	  emit_jump (label_rtx (node->code_label));

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