Currently afdo reads the profile and anotates basic blocks containing
statements which have samples in profile data. For basic blocks which has been
fully optimized out (for example, basic blocks controlling loops that has been
fully unrolled) it has no data which it then tries to determine in
afdo_propagate using Kirhoff law.
Problem is that often there is not enough info to solve the problem. In that
case few tricks are applied and then algorithm gives up.
In all cases where it gave up, the count is then set to AFDO 0 and consequently
we end up with basic blocks having 0 counts in hot regions of program and we
can not trust those 0s much when optimizing.
This patch attempts to preserve static profile in regions we have no info.
After the propagation connected regions are identified and existing profile is
scaled to fit profile data. For single-entry-single exit regions this is
correct answer. For other regions we can theoretically try to adjust static
profile, but no attempts is made to do it to keep things simple.
Static profile has quality GUESSED while AFDO data quality AFDO which makes
it possible to distinguish it later.
afdo_adjust_guessed_profile does the profile adjustment. Rest of changes are
preventing the code from tampering with counts of basic blocks that can not
be fully determined. The propagation has some tricks to compute lower bound
of some basic blocks on the boundary of annotated regions and i am not trying
to preserve that.
We can end up with connected components where we can not determine the count.
This happens in pracitce in hot code i.e. for SPEC2017 perl benchmark. I plan
to handle this incrementally. Current code will simply set profle as undefined
in those regions, which works worse than 0 and thus we get regression in perl.
With this changed to 0, I now get same SPEC2017 score as without profiling.
The patch also makes gcc to completely ignore info about basic blocks which
do have statements that have actual 0 AFDO profile info. Since the profile
generation tool cuts profile at 2%, I think we should keep low guessed profile
there insead of 0. This is another step I plan to work on incrementally
this week.
Bootstrapped/regtested x86-64, comitted.
gcc/ChangeLog:
* auto-profile.cc (edge_set): Remove unused typedef.
(is_bb_annotated): Sanity check that annotated BBs has
quality AFDO and non-anntoated non-AFDO. Exceptions are
zeros.
(set_bb_annotated): Verify that BB set annotated has
AFDO profile.
(afdo_set_bb_count): Do not return true for 0 counts.
(afdo_find_equiv_class): Fix formating;
do not combine profile of annoated and non-annotated BBs.
(afdo_propagate_edge): Fix variable names; dump info
about changes; do not change non-annoated BB profiles;
if all flow out of BB was decided on, annotate remaining
edges with 0.
(afdo_propagate): Dump info about copied BB counts
and number of iteraitons used.
(cmp): New function.
(afdo_adjust_guessed_profile): New function.
(afdo_calculate_branch_prob): Do not initialize loop
optimizer here; call afdo_adjust_guessed_profile.
(afdo_annotate_cfg): Initialize profile here;
anotate entry/exit blocks only of profile is non-0.
* profile-count.h: (profile_count::force_guessed): New.
* tree-cfg.cc (gimple_verify_flow_info): Fix typo.