Mercurial > hg > CbC > CbC_gcc
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 } |