Problem in propagating profiling information through loop unrolling

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Mon Apr 19 21:44:00 GMT 2004


Hello,

> The following line from "scale_bbs_frequencies" of cfgloopmanip.c
>       bbs[i]->count = (bbs[i]->count * num) / den;
> may cause a loop whose preheader has a count of 1 (and whose body has a
> very
> large count) to receive a zero preheader count after a precondition is
> inserted on the preheader edge.  This phenomena was observed after noticing
> that the doloop rewrite (of Zedenek Dvorak) produced less branch-on-counts
> than the original one when feedback is turned on.  The zero preheader count
> convinced the doloop optimization that it was not profitable to perform the
> doloop opt.
> 
> 
> IMHO, the result of the division should be rounded instead of truncated.
> When I used the below patch it fixed the problem - the unrolled loop was
> successfully "doloop'ed".
> I am not sure that this is the correct fix, please comment.

seems a good thing to do in anyway.

However the place where IMHO the real problem is is
expected_loop_iterations, which should not return 0 in this case;
i.e. I would suggest

Index: cfgloopanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloopanal.c,v
retrieving revision 1.2.4.9.2.6
diff -c -3 -p -r1.2.4.9.2.6 cfgloopanal.c
*** cfgloopanal.c	21 Mar 2004 03:19:43 -0000	1.2.4.9.2.6
--- cfgloopanal.c	19 Apr 2004 21:40:00 -0000
*************** expected_loop_iterations (const struct l
*** 431,439 ****
  	  count_in += e->count;
  
        if (count_in == 0)
! 	return 0;
! 
!       expected = (count_latch + count_in - 1) / count_in;
  
        /* Avoid overflows.  */
        return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected);
--- 431,439 ----
  	  count_in += e->count;
  
        if (count_in == 0)
! 	expected = count_latch;
!       else
! 	expected = (count_latch + count_in - 1) / count_in;
  
        /* Avoid overflows.  */
        return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected);

> Index: cfgloopmanip.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/cfgloopmanip.c,v
> retrieving revision 1.23
> diff -c -p -r1.23 cfgloopmanip.c
> *** cfgloopmanip.c      24 Feb 2004 23:39:54 -0000      1.23
> --- cfgloopmanip.c      19 Apr 2004 21:18:24 -0000
> *************** scale_bbs_frequencies (basic_block *bbs,
> *** 458,464 ****
>     for (i = 0; i < nbbs; i++)
>       {
>         bbs[i]->frequency = (bbs[i]->frequency * num) / den;
> !       bbs[i]->count = (bbs[i]->count * num) / den;

Perhaps you might use the RDIV macro (just for consistency)?

Zdenek

>         for (e = bbs[i]->succ; e; e = e->succ_next)
>         e->count = (e->count * num) /den;
>       }
> --- 458,464 ----
>     for (i = 0; i < nbbs; i++)
>       {
>         bbs[i]->frequency = (bbs[i]->frequency * num) / den;
> !       bbs[i]->count = (bbs[i]->count * num + (den/2)) / den;
>         for (e = bbs[i]->succ; e; e = e->succ_next)
>         e->count = (e->count * num) /den;
>       }



More information about the Gcc mailing list