ok. Is the change in google-47 branch? Please also submit this to trunk (there was also a previous one pending).
thanks, David On Thu, May 3, 2012 at 4:44 AM, Dehao Chen <de...@google.com> wrote: > 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 <de...@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 <de...@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 > > 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. */ >