Patchwork [google] re-enable r185948

login
register
mail settings
Submitter Dehao Chen
Date May 3, 2012, 11:45 a.m.
Message ID <CAO2gOZXu1Pm76yW=kqvgxJkrpNeS2LFJJViHo6qpCDEgdmu8yA@mail.gmail.com>
Download mbox | patch
Permalink /patch/156670/
State New
Headers show

Comments

Dehao Chen - May 3, 2012, 11:45 a.m.
Hi,

This patch was reverted because of performance degradation. However,
it turns out to be an innocent performance loss. Thus we want to
reenable it in google branches.

Passed bootstrap and gcc regression tests and google performance tests.

OK for google branch?

Thanks,
Dehao

gcc/ChangeLog.google-4_6
2012-05-03  Dehao Chen  <dehao@google.com>

	* predict.c (predict_iv_comparison): Add the comparison of induction
	variable against its initial value. (Reenable r185948)

gcc/testsuite/ChangeLog.google-4_6
2012-05-03  Dehao Chen  <dehao@google.com>

	* gcc.dg/predict-1.c: Check if LOOP_IV_COMPARE static predict
	heuristic is working properly. Reenable r185948.
	* gcc.dg/predict-2.c: Likewise
	* gcc.dg/predict-3.c: Likewise
	* gcc.dg/predict-4.c: Likewise
	* gcc.dg/predict-5.c: Likewise
	* gcc.dg/predict-6.c: Likewise

Patch

Index: testsuite/gcc.dg/predict-3.c
===================================================================
--- testsuite/gcc.dg/predict-3.c	(revision 187013)
+++ testsuite/gcc.dg/predict-3.c	(working copy)
@@ -10,10 +10,16 @@ 
   int i, ret = 0;
   for (i = 0; i <= bound; i++)
     {
+      if (i < bound - 2)
+	global += bar (i);
+      if (i <= bound)
+	global += bar (i);
+      if (i + 1 < bound)
+	global += bar (i);
       if (i != bound)
 	global += bar (i);
     }
 }

-/* { dg-final { scan-tree-dump "loop iv compare heuristics"
"profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop iv compare heuristics:
100.0%" 4 "profile_estimate"} } */
 /* { dg-final { cleanup-tree-dump "profile_estimate" } } */
Index: testsuite/gcc.dg/predict-4.c
===================================================================
--- testsuite/gcc.dg/predict-4.c	(revision 187013)
+++ testsuite/gcc.dg/predict-4.c	(working copy)
@@ -15,5 +15,5 @@ 
     }
 }

-/* { dg-final { scan-tree-dump "loop iv compare heuristics"
"profile_estimate"} } */
+/* { dg-final { scan-tree-dump "loop iv compare heuristics: 50.0%"
"profile_estimate"} } */
 /* { dg-final { cleanup-tree-dump "profile_estimate" } } */
Index: testsuite/gcc.dg/predict-1.c
===================================================================
--- testsuite/gcc.dg/predict-1.c	(revision 187013)
+++ testsuite/gcc.dg/predict-1.c	(working copy)
@@ -10,10 +10,18 @@ 
   int i, ret = 0;
   for (i = 0; i < bound; i++)
     {
+      if (i > bound)
+	global += bar (i);
+      if (i >= bound + 2)
+	global += bar (i);
       if (i > bound - 2)
 	global += bar (i);
+      if (i + 2 > bound)
+	global += bar (i);
+      if (i == 10)
+	global += bar (i);
     }
 }

-/* { dg-final { scan-tree-dump "loop iv compare heuristics"
"profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "loop iv compare heuristics:
0.0%" 5 "profile_estimate"} } */
 /* { dg-final { cleanup-tree-dump "profile_estimate" } } */
Index: testsuite/gcc.dg/predict-2.c
===================================================================
--- testsuite/gcc.dg/predict-2.c	(revision 187013)
+++ testsuite/gcc.dg/predict-2.c	(working copy)
@@ -5,12 +5,20 @@ 

 int bar(int);

-void foo (int bound)
+void foo (int base, int bound)
 {
   int i, ret = 0;
-  for (i = 0; i < bound; i++)
+  for (i = base; i < bound; i++)
     {
-      if (i > bound * bound )
+      if (i > bound * bound)
+	global += bar (i);
+      if (i > bound + 10)
+	global += bar (i);
+      if (i <= bound + 10)
+	global += bar (i);
+      if (i > base + 10)
+	global += bar (i);
+      if (i < base - 10)
 	global += bar (i);
     }
 }
Index: predict.c
===================================================================
--- predict.c	(revision 187013)
+++ predict.c	(working copy)
@@ -1070,6 +1070,10 @@ 
     bound = get_base_value (bound);
   if (!bound)
     return false;
+  if (TREE_CODE (base) != INTEGER_CST)
+    base = get_base_value (base);
+  if (!base)
+    return false;

   *loop_invariant = bound;
   *compare_code = code;
@@ -1185,8 +1189,7 @@ 
       return;
     }

-  if (!expr_coherent_p (loop_bound_var, compare_var)
-      || loop_iv_base_var != compare_base)
+  if (!expr_coherent_p(loop_iv_base_var, compare_base))
     return;

   /* If loop bound, base and compare bound are all constents, we can
@@ -1230,34 +1233,52 @@ 
       return;
     }

-  if ((loop_bound_code == LT_EXPR || loop_bound_code == LE_EXPR)
-      && (compare_code == LT_EXPR || compare_code == LE_EXPR))
-    predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, TAKEN);
-  else if ((loop_bound_code == GT_EXPR || loop_bound_code == GE_EXPR)
-	   && (compare_code == GT_EXPR || compare_code == GE_EXPR))
-    predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, TAKEN);
-  else if (loop_bound_code == NE_EXPR)
-    {
-      /* If the loop backedge condition is "(i != bound)", we do
-	 the comparison based on the step of IV:
-	   * step < 0 : backedge condition is like (i > bound)
-	   * step > 0 : backedge condition is like (i < bound)  */
-      gcc_assert (loop_bound_step != 0);
+  if (expr_coherent_p (loop_bound_var, compare_var))
+    {
+      if ((loop_bound_code == LT_EXPR || loop_bound_code == LE_EXPR)
+	  && (compare_code == LT_EXPR || compare_code == LE_EXPR))
+	predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, TAKEN);
+      else if ((loop_bound_code == GT_EXPR || loop_bound_code == GE_EXPR)
+	       && (compare_code == GT_EXPR || compare_code == GE_EXPR))
+	predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, TAKEN);
+      else if (loop_bound_code == NE_EXPR)
+	{
+	  /* If the loop backedge condition is "(i != bound)", we do
+	     the comparison based on the step of IV:
+	     * step < 0 : backedge condition is like (i > bound)
+	     * step > 0 : backedge condition is like (i < bound)  */
+	  gcc_assert (loop_bound_step != 0);
+	  if (loop_bound_step > 0
+	      && (compare_code == LT_EXPR
+		  || compare_code == LE_EXPR))
+	    predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, TAKEN);
+	  else if (loop_bound_step < 0
+		   && (compare_code == GT_EXPR
+		       || compare_code == GE_EXPR))
+	    predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, TAKEN);
+	  else
+	    predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, NOT_TAKEN);
+	}
+      else
+	/* The branch is predicted not-taken if loop_bound_code is
+	   opposite with compare_code.  */
+	predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, NOT_TAKEN);
+    }
+  else if (expr_coherent_p (loop_iv_base_var, compare_var))
+    {
+      /* For cases like:
+	   for (i = s; i < h; i++)
+	     if (i > s + 2) ....
+	 The branch should be predicted taken.  */
       if (loop_bound_step > 0
-	  && (compare_code == LT_EXPR
-	      || compare_code == LE_EXPR))
+	  && (compare_code == GT_EXPR || compare_code == GE_EXPR))
 	predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, TAKEN);
       else if (loop_bound_step < 0
-	       && (compare_code == GT_EXPR
-		   || compare_code == GE_EXPR))
+	       && (compare_code == LT_EXPR || compare_code == LE_EXPR))
 	predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, TAKEN);
       else
 	predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, NOT_TAKEN);
     }
-  else
-    /* The branch is predicted not-taken if loop_bound_code is
-       opposite with compare_code.  */
-    predict_edge_def (then_edge, PRED_LOOP_IV_COMPARE, NOT_TAKEN);
 }

 /* Predict edge probabilities by exploiting loop structure.  */