comparison gcc/profile-count.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Profile counter container type. 1 /* Profile counter container type.
2 Copyright (C) 2017 Free Software Foundation, Inc. 2 Copyright (C) 2017-2018 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka 3 Contributed by Jan Hubicka
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it under 7 GCC is free software; you can redistribute it and/or modify it under
23 #include "coretypes.h" 23 #include "coretypes.h"
24 #include "profile-count.h" 24 #include "profile-count.h"
25 #include "options.h" 25 #include "options.h"
26 #include "tree.h" 26 #include "tree.h"
27 #include "basic-block.h" 27 #include "basic-block.h"
28 #include "function.h"
28 #include "cfg.h" 29 #include "cfg.h"
29 #include "function.h"
30 #include "gimple.h" 30 #include "gimple.h"
31 #include "data-streamer.h" 31 #include "data-streamer.h"
32 #include "cgraph.h" 32 #include "cgraph.h"
33 #include "wide-int.h" 33 #include "wide-int.h"
34 #include "sreal.h"
35
36 /* Get a string describing QUALITY. */
37
38 const char *
39 profile_quality_as_string (enum profile_quality quality)
40 {
41 switch (quality)
42 {
43 default:
44 gcc_unreachable ();
45 case profile_uninitialized:
46 return "uninitialized";
47 case profile_guessed_local:
48 return "guessed_local";
49 case profile_guessed_global0:
50 return "guessed_global0";
51 case profile_guessed_global0adjusted:
52 return "guessed_global0adjusted";
53 case profile_guessed:
54 return "guessed";
55 case profile_afdo:
56 return "afdo";
57 case profile_adjusted:
58 return "adjusted";
59 case profile_precise:
60 return "precise";
61 }
62 }
34 63
35 /* Dump THIS to F. */ 64 /* Dump THIS to F. */
36 65
37 void 66 void
38 profile_count::dump (FILE *f) const 67 profile_count::dump (FILE *f) const
40 if (!initialized_p ()) 69 if (!initialized_p ())
41 fprintf (f, "uninitialized"); 70 fprintf (f, "uninitialized");
42 else 71 else
43 { 72 {
44 fprintf (f, "%" PRId64, m_val); 73 fprintf (f, "%" PRId64, m_val);
45 if (m_quality == profile_adjusted) 74 if (m_quality == profile_guessed_local)
75 fprintf (f, " (estimated locally)");
76 else if (m_quality == profile_guessed_global0)
77 fprintf (f, " (estimated locally, globally 0)");
78 else if (m_quality == profile_guessed_global0adjusted)
79 fprintf (f, " (estimated locally, globally 0 adjusted)");
80 else if (m_quality == profile_adjusted)
46 fprintf (f, " (adjusted)"); 81 fprintf (f, " (adjusted)");
47 else if (m_quality == profile_afdo) 82 else if (m_quality == profile_afdo)
48 fprintf (f, " (auto FDO)"); 83 fprintf (f, " (auto FDO)");
49 else if (m_quality == profile_guessed) 84 else if (m_quality == profile_guessed)
50 fprintf (f, " (guessed)"); 85 fprintf (f, " (guessed)");
63 /* Return true if THIS differs from OTHER; tolerate small diferences. */ 98 /* Return true if THIS differs from OTHER; tolerate small diferences. */
64 99
65 bool 100 bool
66 profile_count::differs_from_p (profile_count other) const 101 profile_count::differs_from_p (profile_count other) const
67 { 102 {
103 gcc_checking_assert (compatible_p (other));
68 if (!initialized_p () || !other.initialized_p ()) 104 if (!initialized_p () || !other.initialized_p ())
69 return false; 105 return false;
70 if ((uint64_t)m_val - (uint64_t)other.m_val < 100 106 if ((uint64_t)m_val - (uint64_t)other.m_val < 100
71 || (uint64_t)other.m_val - (uint64_t)m_val < 100) 107 || (uint64_t)other.m_val - (uint64_t)m_val < 100)
72 return false; 108 return false;
200 236
201 bool 237 bool
202 slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res) 238 slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
203 { 239 {
204 FIXED_WIDE_INT (128) tmp = a; 240 FIXED_WIDE_INT (128) tmp = a;
205 bool overflow; 241 wi::overflow_type overflow;
206 tmp = wi::udiv_floor (wi::umul (tmp, b, &overflow) + (c / 2), c); 242 tmp = wi::udiv_floor (wi::umul (tmp, b, &overflow) + (c / 2), c);
207 gcc_checking_assert (!overflow); 243 gcc_checking_assert (!overflow);
208 if (wi::fits_uhwi_p (tmp)) 244 if (wi::fits_uhwi_p (tmp))
209 { 245 {
210 *res = tmp.to_uhwi (); 246 *res = tmp.to_uhwi ();
211 return true; 247 return true;
212 } 248 }
213 *res = (uint64_t) -1; 249 *res = (uint64_t) -1;
214 return false; 250 return false;
215 } 251 }
252
253 /* Return count as frequency within FUN scaled in range 0 to REG_FREQ_MAX
254 Used for legacy code and should not be used anymore. */
255
256 int
257 profile_count::to_frequency (struct function *fun) const
258 {
259 if (!initialized_p ())
260 return BB_FREQ_MAX;
261 if (*this == profile_count::zero ())
262 return 0;
263 gcc_assert (REG_BR_PROB_BASE == BB_FREQ_MAX
264 && fun->cfg->count_max.initialized_p ());
265 profile_probability prob = probability_in (fun->cfg->count_max);
266 if (!prob.initialized_p ())
267 return REG_BR_PROB_BASE;
268 return prob.to_reg_br_prob_base ();
269 }
270
271 /* Return count as frequency within FUN scaled in range 0 to CGRAPH_FREQ_MAX
272 where CGRAPH_FREQ_BASE means that count equals to entry block count.
273 Used for legacy code and should not be used anymore. */
274
275 int
276 profile_count::to_cgraph_frequency (profile_count entry_bb_count) const
277 {
278 if (!initialized_p () || !entry_bb_count.initialized_p ())
279 return CGRAPH_FREQ_BASE;
280 if (*this == profile_count::zero ())
281 return 0;
282 gcc_checking_assert (entry_bb_count.initialized_p ());
283 uint64_t scale;
284 if (!safe_scale_64bit (!entry_bb_count.m_val ? m_val + 1 : m_val,
285 CGRAPH_FREQ_BASE, MAX (1, entry_bb_count.m_val), &scale))
286 return CGRAPH_FREQ_MAX;
287 return MIN (scale, CGRAPH_FREQ_MAX);
288 }
289
290 /* Return THIS/IN as sreal value. */
291
292 sreal
293 profile_count::to_sreal_scale (profile_count in, bool *known) const
294 {
295 if (!initialized_p () || !in.initialized_p ())
296 {
297 if (known)
298 *known = false;
299 return 1;
300 }
301 if (known)
302 *known = true;
303 if (*this == profile_count::zero ())
304 return 0;
305
306 if (!in.m_val)
307 {
308 if (!m_val)
309 return 1;
310 return m_val * 4;
311 }
312 return (sreal)m_val / (sreal)in.m_val;
313 }
314
315 /* We want to scale profile across function boundary from NUM to DEN.
316 Take care of the side case when DEN is zeros. We still want to behave
317 sanely here which means
318 - scale to profile_count::zero () if NUM is profile_count::zero
319 - do not affect anything if NUM == DEN
320 - preserve counter value but adjust quality in other cases. */
321
322 void
323 profile_count::adjust_for_ipa_scaling (profile_count *num,
324 profile_count *den)
325 {
326 /* Scaling is no-op if NUM and DEN are the same. */
327 if (*num == *den)
328 return;
329 /* Scaling to zero is always zero. */
330 if (*num == profile_count::zero ())
331 return;
332 /* If den is non-zero we are safe. */
333 if (den->force_nonzero () == *den)
334 return;
335 /* Force both to non-zero so we do not push profiles to 0 when
336 both num == 0 and den == 0. */
337 *den = den->force_nonzero ();
338 *num = num->force_nonzero ();
339 }
340
341 /* THIS is a count of bb which is known to be executed IPA times.
342 Combine this information into bb counter. This means returning IPA
343 if it is nonzero, not changing anything if IPA is uninitialized
344 and if IPA is zero, turning THIS into corresponding local profile with
345 global0. */
346 profile_count
347 profile_count::combine_with_ipa_count (profile_count ipa)
348 {
349 ipa = ipa.ipa ();
350 if (ipa.nonzero_p ())
351 return ipa;
352 if (!ipa.initialized_p () || *this == profile_count::zero ())
353 return *this;
354 if (ipa == profile_count::zero ())
355 return this->global0 ();
356 return this->global0adjusted ();
357 }
358
359 /* The profiling runtime uses gcov_type, which is usually 64bit integer.
360 Conversions back and forth are used to read the coverage and get it
361 into internal representation. */
362 profile_count
363 profile_count::from_gcov_type (gcov_type v)
364 {
365 profile_count ret;
366 gcc_checking_assert (v >= 0);
367 if (dump_file && v >= (gcov_type)max_count)
368 fprintf (dump_file,
369 "Capping gcov count %" PRId64 " to max_count %" PRId64 "\n",
370 (int64_t) v, (int64_t) max_count);
371 ret.m_val = MIN (v, (gcov_type)max_count);
372 ret.m_quality = profile_precise;
373 return ret;
374 }
375
376
377 /* COUNT1 times event happens with *THIS probability, COUNT2 times OTHER
378 happens with COUNT2 probablity. Return probablity that either *THIS or
379 OTHER happens. */
380
381 profile_probability
382 profile_probability::combine_with_count (profile_count count1,
383 profile_probability other,
384 profile_count count2) const
385 {
386 /* If probabilities are same, we are done.
387 If counts are nonzero we can distribute accordingly. In remaining
388 cases just avreage the values and hope for the best. */
389 if (*this == other || count1 == count2
390 || (count2 == profile_count::zero ()
391 && !(count1 == profile_count::zero ())))
392 return *this;
393 if (count1 == profile_count::zero () && !(count2 == profile_count::zero ()))
394 return other;
395 else if (count1.nonzero_p () || count2.nonzero_p ())
396 return *this * count1.probability_in (count1 + count2)
397 + other * count2.probability_in (count1 + count2);
398 else
399 return *this * profile_probability::even ()
400 + other * profile_probability::even ();
401 }