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
<[email protected]> wrote:
> On Tue, Jul 31, 2012 at 5:17 AM, Dehao Chen <[email protected]> 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 <[email protected]>
>>
>> * predict.c (predict_loops): Fix the prediction of LOOP_BRANCH.
>>
>> gcc/testsuite/ChangeLog
>>
>> 2012-07-31 Dehao Chen <[email protected]>
>>
>> * 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.