From 89619f87697a0e0b54be4627f0f811f6c486ffe5 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 21 Jul 2023 08:52:00 +0200 Subject: Cleanup expected_loop_iterations this patch cleanups API for determining expected loop iteraitons from profile. We started with having expected_loop_iterations and only source was the integer represented BB counts. It did some work on guessing number of iteration if profile was absent or bogus. Later we introduced loop_info and added get_estimated_loop_iterations which made expected_loop_iterations useful mostly when doing profile updates and not for loop optimization heuristics. The naming is bit ambiguous so this difference is not clear. Even later we introduced precision tracking to profile and exended the API to return reliablity of result but did not update all uses to do reasonable stuff with it. There is also some cofusion about +-1s concering latch execution counts versus header execution counts. This patch aims to obsolette expected_loop_iterations and expected_loop_iterations_unbounded (and "suceeds" modulo 1 use of each of two). It adds expected_loop_iterations_by_profile which computes sreal and does correct precision/presence tracking. Unlike old code, it is based on CFG profile only and does not attempt to provide fake answer when info is missing and does not check sanity with loop_info. We now define iterations consistently as lath execution in loop_info so I use that here too. I converted almost all calls to new API: dumps, code produing loop_info from CFG profile and profile updating. Remaining uses are in loop unrolling and prefetching that needs more TLC I will do incrementally. There are some improvements possible which I can play with incrementally. - for simple loops with one exit dominating latch we can use exit probability for easier to preserve info in loop itraionts. THis is probably not too critical since all esitmates should be recorded in loop_info and would help mostly if new loop is constructed or old loop is lost and redicovered. - We may want to avoid trusting the profile if it is obviously inconsistent on header. gcc/ChangeLog: * cfgloop.cc: Include sreal.h. (flow_loop_dump): Dump sreal iteration exsitmate. (get_estimated_loop_iterations): Update. * cfgloop.h (expected_loop_iterations_by_profile): Declare. * cfgloopanal.cc (expected_loop_iterations_by_profile): New function. (expected_loop_iterations_unbounded): Use new API. * cfgloopmanip.cc (scale_loop_profile): Use expected_loop_iterations_by_profile * predict.cc (pass_profile::execute): Likewise. * profile.cc (branch_prob): Likewise. * tree-ssa-loop-niter.cc: Include sreal.h. (estimate_numbers_of_iterations): Likewise --- gcc/cfgloop.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'gcc/cfgloop.cc') diff --git a/gcc/cfgloop.cc b/gcc/cfgloop.cc index ccda741..020e573 100644 --- a/gcc/cfgloop.cc +++ b/gcc/cfgloop.cc @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "dumpfile.h" #include "tree-ssa.h" #include "tree-pretty-print.h" +#include "sreal.h" static void flow_loops_cfg_dump (FILE *); @@ -138,14 +139,11 @@ flow_loop_dump (const class loop *loop, FILE *file, loop_depth (loop), (long) (loop_outer (loop) ? loop_outer (loop)->num : -1)); - if (loop->latch) - { - bool read_profile_p; - gcov_type nit = expected_loop_iterations_unbounded (loop, &read_profile_p); - if (read_profile_p && !loop->any_estimate) - fprintf (file, ";; profile-based iteration count: %" PRIu64 "\n", - (uint64_t) nit); - } + bool reliable; + sreal iterations; + if (loop->num && expected_loop_iterations_by_profile (loop, &iterations, &reliable)) + fprintf (file, ";; profile-based iteration count: %f %s\n", + iterations.to_double (), reliable ? "(reliable)" : "(unreliable)"); fprintf (file, ";; nodes:"); bbs = get_loop_body (loop); @@ -2014,10 +2012,12 @@ get_estimated_loop_iterations (class loop *loop, widest_int *nit) profile. */ if (!loop->any_estimate) { - if (loop->header->count.reliable_p ()) + sreal snit; + bool reliable; + if (expected_loop_iterations_by_profile (loop, &snit, &reliable) + && reliable) { - *nit = gcov_type_to_wide_int - (expected_loop_iterations_unbounded (loop) + 1); + *nit = (snit + 0.5).to_int (); return true; } return false; -- cgit v1.1