Are you suggesting a patch like this:

Index: gcc/predict.c
===================================================================
--- gcc/predict.c       (revision 189835)
+++ gcc/predict.c       (working copy)
@@ -1319,6 +1319,7 @@
       tree loop_bound_var = NULL;
       tree loop_iv_base = NULL;
       gimple stmt = NULL;
+      int header_found = 0;

       exits = get_loop_exit_edges (loop);
       n_exits = VEC_length (edge, exits);
@@ -1387,9 +1388,20 @@

       bbs = get_loop_body (loop);

+      /* Loop branch heuristics - predict an edge back to a
+        loop's head as taken.  */
+      if (loop->latch && loop->latch->loop_father == loop)
+       {
+         edge e = find_edge (loop->latch, loop->header);
+         if (e)
+           {
+             header_found = 1;
+             predict_edge_def (e, PRED_LOOP_BRANCH, TAKEN);
+           }
+       }
+
       for (j = 0; j < loop->num_nodes; j++)
        {
-         int header_found = 0;
          edge e;
          edge_iterator ei;

@@ -1402,21 +1414,9 @@
          if (predicted_by_p (bb, PRED_CONTINUE))
            continue;

-         /* Loop branch heuristics - predict an edge back to a
-            loop's head as taken.  */
-         if (bb == loop->latch)
-           {
-             e = find_edge (loop->latch, loop->header);
-             if (e)
-               {
-                 header_found = 1;
-                 predict_edge_def (e, PRED_LOOP_BRANCH, TAKEN);
-               }
-           }
-
          /* Loop exit heuristics - predict an edge exiting the loop if the
             conditional has no loop header successors as not taken.  */
-         if (!header_found
+         if (!(header_found && bb == loop->latch)
              /* If we already used more reliable loop exit predictors, do not
                 bother with PRED_LOOP_EXIT.  */
              && !predicted_by_p (bb, PRED_LOOP_ITERATIONS_GUESSED)

On Tue, Jul 31, 2012 at 5:18 PM, Richard Guenther
<richard.guent...@gmail.com> wrote:
> On Tue, Jul 31, 2012 at 5:17 AM, Dehao Chen <de...@google.com> wrote:
>> Hi,
>>
>> This patch fixed the problem when a LOOP_EXIT edge for the inner loop
>> happened to target at the LOOP_LATCH of the outer loop. As the outer
>> loop is processed first, the LOOP_BRANCH heuristic is honored
>> (first_match), thus the inner loop's trip count is 0. (The attached
>> unittest demonstrates this).
>>
>> Bootstrapped and passed gcc regression test.
>>
>> Is it ok for trunk?
>>
>> Thanks,
>> Dehao
>>
>> gcc/ChangeLog
>>
>> 2012-07-30  Dehao Chen  <de...@google.com>
>>
>>         * predict.c (predict_loops): Fix the prediction of LOOP_BRANCH.
>>
>> gcc/testsuite/ChangeLog
>>
>> 2012-07-31  Dehao Chen  <de...@google.com>
>>
>>         * gcc.dg/predict-7.c: New test.
>>
>> Index: gcc/testsuite/gcc.dg/predict-7.c
>> ===================================================================
>> --- gcc/testsuite/gcc.dg/predict-7.c    (revision 0)
>> +++ gcc/testsuite/gcc.dg/predict-7.c    (revision 0)
>> @@ -0,0 +1,17 @@
>> +/* { dg-do compile } */
>> +/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
>> +
>> +extern int global;
>> +
>> +int bar (int);
>> +
>> +void foo (int base)
>> +{
>> +  int i;
>> +  while (global < 10)
>> +    for (i = base; i < 10; i++)
>> +      bar (i);
>> +}
>> +
>> +/* { dg-final { scan-tree-dump-times "loop branch heuristics" 0
>> "profile_estimate"} } */
>> +/* { dg-final { cleanup-tree-dump "profile_estimate" } } */
>> Index: gcc/predict.c
>> ===================================================================
>> --- gcc/predict.c       (revision 189835)
>> +++ gcc/predict.c       (working copy)
>> @@ -1404,7 +1404,7 @@
>>
>>           /* Loop branch heuristics - predict an edge back to a
>>              loop's head as taken.  */
>> -         if (bb == loop->latch)
>> +         if (bb == loop->latch && bb->loop_father == loop)
>>             {
>>               e = find_edge (loop->latch, loop->header);
>>               if (e)
>
> I think this heuristic should instead move out of the loop iterating over loop
> nodes and be done before like
>
>   if (loop->latch)
>     {
>        e = find_edge (loop->latch, loop->header);
>        ...
>     }
>
> which also makes header_found initialized before we visit loop blocks.
>
> Instead the code
>
>           /* Loop exit heuristics - predict an edge exiting the loop if the
>              conditional has no loop header successors as not taken.  */
>           if (!header_found
>               /* If we already used more reliable loop exit predictors, do not
>                  bother with PRED_LOOP_EXIT.  */
> ...
>               FOR_EACH_EDGE (e, ei, bb->succs)
>                 if (e->dest->index < NUM_FIXED_BLOCKS
>                     || !flow_bb_inside_loop_p (loop, e->dest))
>                   predict_edge (e, PRED_LOOP_EXIT, probability);
>
> looks wrong for bb's that are parts of an inner loop of loop - assuming we
> only want to predicate exits from loop and not exits from an inner loop
> that also happen to exit loop (we will do that when predicating the inner 
> loop).

You are right. And if we want to change this, we'd also need to modify
get_loop_exit_edges to only count edges whose src is in the same loop
level. However, this is relatively minor issue because it only
predicts inaccurate bias ratio, while in the testcase I gave,
LOOP_BRANCH is predicting in the wrong direction.

Thanks,
Dehao


>
> Is that what you experienced?
>
> Thanks,
> Richard.

Reply via email to