GCC Middle and Back End API Reference
profile-count.h
Go to the documentation of this file.
1/* Profile counter container type.
2 Copyright (C) 2017-2025 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_PROFILE_COUNT_H
22#define GCC_PROFILE_COUNT_H
23
24struct function;
25struct profile_count;
26class sreal;
27
28/* Quality of the profile count. Because gengtype does not support enums
29 inside of classes, this is in global namespace. */
31 /* Uninitialized value. */
33
34 /* Profile is based on static branch prediction heuristics and may
35 or may not match reality. It is local to function and cannot be compared
36 inter-procedurally. Never used by probabilities (they are always local).
37 */
39
40 /* Same as GUESSED_GLOBAL0 but global count is afdo 0. */
42
43 /* Same as GUESSED_GLOBAL0 but global count is adjusted 0. */
45
46 /* Profile was read by feedback and was 0, we used local heuristics to guess
47 better. This is the case of functions not run in profile feedback.
48 Never used by probabilities. */
50
51 /* Profile is based on static branch prediction heuristics. It may or may
52 not reflect the reality but it can be compared interprocedurally
53 (for example, we inlined function w/o profile feedback into function
54 with feedback and propagated from that). */
56
57 /* Profile was determined by autofdo. */
59
60 /* Profile was originally based on feedback but it was adjusted
61 by code duplicating optimization. It may not precisely reflect the
62 particular code path. */
64
65 /* Profile was read from profile feedback or determined by accurate static
66 method. */
68};
69
70extern const char *profile_quality_as_string (enum profile_quality);
71extern bool parse_profile_quality (const char *value,
72 profile_quality *quality);
73
74/* The base value for branch probability notes and edge probabilities. */
75#define REG_BR_PROB_BASE 10000
76
77#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
78
79bool slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res);
80
81/* Compute RES=(a*b + c/2)/c capping and return false if overflow happened. */
82
83inline bool
84safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
85{
86#if (GCC_VERSION >= 5000)
87 uint64_t tmp;
88 if (!__builtin_mul_overflow (a, b, &tmp)
89 && !__builtin_add_overflow (tmp, c/2, &tmp))
90 {
91 *res = tmp / c;
92 return true;
93 }
94 if (c == 1)
95 {
96 *res = (uint64_t) -1;
97 return false;
98 }
99#else
100 if (a < ((uint64_t)1 << 31)
101 && b < ((uint64_t)1 << 31)
102 && c < ((uint64_t)1 << 31))
103 {
104 *res = (a * b + (c / 2)) / c;
105 return true;
106 }
107#endif
108 return slow_safe_scale_64bit (a, b, c, res);
109}
110
111/* Data type to hold probabilities. It implements fixed point arithmetics
112 with capping so probability is always in range [0,1] and scaling requiring
113 values greater than 1 needs to be represented otherwise.
114
115 In addition to actual value the quality of profile is tracked and propagated
116 through all operations. Special value UNINITIALIZED_PROFILE is used for probabilities
117 that has not been determined yet (for example because of
118 -fno-guess-branch-probability)
119
120 Typically probabilities are derived from profile feedback (via
121 probability_in_gcov_type), autoFDO or guessed statically and then propagated
122 thorough the compilation.
123
124 Named probabilities are available:
125 - never (0 probability)
126 - guessed_never
127 - very_unlikely (1/2000 probability)
128 - unlikely (1/5 probability)
129 - even (1/2 probability)
130 - likely (4/5 probability)
131 - very_likely (1999/2000 probability)
132 - guessed_always
133 - always
134
135 Named probabilities except for never/always are assumed to be statically
136 guessed and thus not necessarily accurate. The difference between never
137 and guessed_never is that the first one should be used only in case that
138 well behaving program will very likely not execute the "never" path.
139 For example if the path is going to abort () call or it exception handling.
140
141 Always and guessed_always probabilities are symmetric.
142
143 For legacy code we support conversion to/from REG_BR_PROB_BASE based fixpoint
144 integer arithmetics. Once the code is converted to branch probabilities,
145 these conversions will probably go away because they are lossy.
146*/
147
149{
150 static const int n_bits = 29;
151 /* We can technically use ((uint32_t) 1 << (n_bits - 1)) - 2 but that
152 will lead to harder multiplication sequences. */
153 static const uint32_t max_probability = (uint32_t) 1 << (n_bits - 2);
154 static const uint32_t uninitialized_probability
155 = ((uint32_t) 1 << (n_bits - 1)) - 1;
156 /* For probibilityes quality is either UNINITIALIZED (0)
157 or greated then GUESSED. To save bits we store it in
158 adjusted form which skips the invalid values. */
159 static const int min_quality = GUESSED;
160
161 uint32_t m_val : 29;
162 unsigned m_adjusted_quality : 3;
163
164 friend struct profile_count;
165
166 /* Set the quality of the probability. */
167 void
174
175public:
178
182
183 /* Named probabilities. */
185 {
187 ret.m_val = 0;
188 ret.set_quality (PRECISE);
189 return ret;
190 }
191
193 {
195 ret.m_val = 0;
196 ret.set_quality (GUESSED);
197 return ret;
198 }
199
201 {
202 /* Be consistent with PROB_VERY_UNLIKELY in predict.h. */
204 r.m_val--;
205 return r;
206 }
207
209 {
210 /* Be consistent with PROB_VERY_LIKELY in predict.h. */
212 r.m_val--;
213 return r;
214 }
215
217 {
218 return guessed_always () / 2;
219 }
220
222 {
223 return always () - very_unlikely ();
224 }
225
227 {
228 return always () - unlikely ();
229 }
230 /* Return true when value is not zero and can be used for scaling. */
231 bool nonzero_p () const
232 {
233 return initialized_p () && m_val != 0;
234 }
235
237 {
240 ret.set_quality (GUESSED);
241 return ret;
242 }
243
245 {
248 ret.set_quality (PRECISE);
249 return ret;
250 }
251
252 /* Probabilities which has not been initialized. Either because
253 initialization did not happen yet or because profile is unknown. */
255 {
258 c.set_quality (GUESSED);
259 return c;
260 }
261
262 /* Return true if value has been initialized. */
263 bool initialized_p () const
264 {
266 }
267
268 /* Return true if value can be trusted. */
269 bool reliable_p () const
270 {
271 return quality () >= ADJUSTED;
272 }
273
274 /* Conversion from and to REG_BR_PROB_BASE integer fixpoint arithmetics.
275 this is mostly to support legacy code and should go away. */
277 {
279 gcc_checking_assert (v >= 0 && v <= REG_BR_PROB_BASE);
280 ret.m_val = RDIV (v * (uint64_t) max_probability, REG_BR_PROB_BASE);
281 ret.set_quality (GUESSED);
282 return ret;
283 }
284
285 /* Return THIS with quality set to ADJUSTED. */
287 {
288 profile_probability ret = *this;
289 if (!initialized_p ())
290 return *this;
291 ret.set_quality (ADJUSTED);
292 return ret;
293 }
294
296 {
298 return RDIV (m_val * (uint64_t) REG_BR_PROB_BASE, max_probability);
299 }
300
301 /* Conversion to and from RTL representation of profile probabilities. */
303 {
305 ret.m_val = ((unsigned int)v) / 8;
306 ret.m_adjusted_quality = ((unsigned int)v) & 7;
307 return ret;
308 }
309
311 {
313 int ret = m_val * 8 + m_adjusted_quality;
315 return ret;
316 }
317
318 /* Return VAL1/VAL2. */
320 (gcov_type val1, gcov_type val2)
321 {
323 gcc_checking_assert (val1 >= 0 && val2 > 0);
324 if (val1 > val2)
326 else
327 {
328 uint64_t tmp;
329 safe_scale_64bit (val1, max_probability, val2, &tmp);
331 ret.m_val = tmp;
332 }
333 ret.set_quality (PRECISE);
334 return ret;
335 }
336
337 /* Basic operations. */
338 bool operator== (const profile_probability &other) const
339 {
340 return m_val == other.m_val && quality () == other.quality ();
341 }
342
344 {
345 if (other == never ())
346 return *this;
347 if (*this == never ())
348 return other;
349 if (!initialized_p () || !other.initialized_p ())
350 return uninitialized ();
351
353 ret.m_val = MIN ((uint32_t)(m_val + other.m_val), max_probability);
354 ret.set_quality (MIN (quality (), other.quality ()));
355 return ret;
356 }
357
359 {
360 if (other == never ())
361 return *this;
362 if (*this == never ())
363 {
364 *this = other;
365 return *this;
366 }
367 if (!initialized_p () || !other.initialized_p ())
368 return *this = uninitialized ();
369 else
370 {
371 m_val = MIN ((uint32_t)(m_val + other.m_val), max_probability);
372 set_quality (MIN (quality (), other.quality ()));
373 }
374 return *this;
375 }
376
378 {
379 if (*this == never ()
380 || other == never ())
381 return *this;
382 if (!initialized_p () || !other.initialized_p ())
383 return uninitialized ();
385 ret.m_val = m_val >= other.m_val ? m_val - other.m_val : 0;
386 ret.set_quality (MIN (quality (), other.quality ()));
387 return ret;
388 }
389
391 {
392 if (*this == never ()
393 || other == never ())
394 return *this;
395 if (!initialized_p () || !other.initialized_p ())
396 return *this = uninitialized ();
397 else
398 {
399 m_val = m_val >= other.m_val ? m_val - other.m_val : 0;
400 set_quality (MIN (quality (), other.quality ()));
401 }
402 return *this;
403 }
404
405 profile_probability operator* (const profile_probability &other) const
406 {
407 if (*this == never ()
408 || other == never ())
409 return never ();
410 if (!initialized_p () || !other.initialized_p ())
411 return uninitialized ();
413 ret.m_val = RDIV ((uint64_t)m_val * other.m_val, max_probability);
414 ret.set_quality (MIN (quality (), other.quality ()));
415 return ret;
416 }
417
419 {
420 if (*this == never ()
421 || other == never ())
422 return *this = never ();
423 if (!initialized_p () || !other.initialized_p ())
424 return *this = uninitialized ();
425 else
426 {
427 m_val = RDIV ((uint64_t)m_val * other.m_val, max_probability);
428 set_quality (MIN (MIN (quality (), other.quality ()), ADJUSTED));
429 }
430 return *this;
431 }
432
433 profile_probability operator/ (const profile_probability &other) const
434 {
435 if (*this == never ())
436 return never ();
437 if (!initialized_p () || !other.initialized_p ())
438 return uninitialized ();
440 /* If we get probability above 1, mark it as unreliable and return 1. */
441 if (m_val >= other.m_val)
442 {
444 ret.set_quality (MIN (MIN (quality (), other.quality ()),
445 GUESSED));
446 return ret;
447 }
448 else if (!m_val)
449 ret.m_val = 0;
450 else
451 {
453 ret.m_val = MIN (RDIV ((uint64_t)m_val * max_probability,
454 other.m_val),
456 }
457 ret.set_quality (MIN (MIN (quality (), other.quality ()), ADJUSTED));
458 return ret;
459 }
460
462 {
463 if (*this == never ())
464 return *this = never ();
465 if (!initialized_p () || !other.initialized_p ())
466 return *this = uninitialized ();
467 else
468 {
469 /* If we get probability above 1, mark it as unreliable
470 and return 1. */
471 if (m_val > other.m_val)
472 {
474 set_quality (MIN (MIN (quality (), other.quality ()),
475 GUESSED));
476 return *this;
477 }
478 else if (!m_val)
479 ;
480 else
481 {
483 m_val = MIN (RDIV ((uint64_t)m_val * max_probability,
484 other.m_val),
486 }
487 set_quality (MIN (MIN (quality (), other.quality ()), ADJUSTED));
488 }
489 return *this;
490 }
491
492 /* Split *THIS (ORIG) probability into 2 probabilities, such that
493 the returned one (FIRST) is *THIS * CPROB and *THIS is
494 adjusted (SECOND) so that FIRST + FIRST.invert () * SECOND
495 == ORIG. This is useful e.g. when splitting a conditional
496 branch like:
497 if (cond)
498 goto lab; // ORIG probability
499 into
500 if (cond1)
501 goto lab; // FIRST = ORIG * CPROB probability
502 if (cond2)
503 goto lab; // SECOND probability
504 such that the overall probability of jumping to lab remains
505 the same. CPROB gives the relative probability between the
506 branches. */
508 {
509 profile_probability ret = *this * cprob;
510 /* The following is equivalent to:
511 *this = cprob.invert () * *this / ret.invert ();
512 Avoid scaling when overall outcome is supposed to be always.
513 Without knowing that one is inverse of other, the result would be
514 conservative. */
515 if (!(*this == always ()))
516 *this = (*this - ret) / ret.invert ();
517 return ret;
518 }
519
521 {
522 if (*this == uninitialized ())
523 return val / 2;
524 return RDIV (val * m_val, max_probability);
525 }
526
527 /* Return 1-*THIS. */
529 {
530 return always() - *this;
531 }
532
533 /* Return THIS with quality dropped to GUESSED. */
535 {
536 profile_probability ret = *this;
537 ret.set_quality (GUESSED);
538 return ret;
539 }
540
541 /* Return THIS with quality dropped to AFDO. */
543 {
544 profile_probability ret = *this;
545 ret.set_quality (AFDO);
546 return ret;
547 }
548
549 /* Return *THIS * NUM / DEN. */
550 profile_probability apply_scale (int64_t num, int64_t den) const
551 {
552 if (*this == never ())
553 return *this;
554 if (!initialized_p ())
555 return uninitialized ();
557 uint64_t tmp;
558 safe_scale_64bit (m_val, num, den, &tmp);
559 ret.m_val = MIN (tmp, max_probability);
560 ret.set_quality (MIN (quality (), ADJUSTED));
561 return ret;
562 }
563
564 /* Return *THIS * NUM / DEN. */
566 profile_probability den) const
567 {
568 if (*this == never ())
569 return *this;
570 if (num == never ())
571 return num;
572 if (!initialized_p () || !num.initialized_p () || !den.initialized_p ())
573 return uninitialized ();
574 if (num == den)
575 return *this;
577
579 uint64_t val;
580 safe_scale_64bit (m_val, num.m_val, den.m_val, &val);
581 ret.m_val = MIN (val, max_probability);
582 ret.set_quality (MIN (MIN (MIN (quality (), ADJUSTED),
583 num.quality ()), den.quality ()));
584 return ret;
585 }
586
587 /* Return true when the probability of edge is reliable.
588
589 The profile guessing code is good at predicting branch outcome (i.e.
590 taken/not taken), that is predicted right slightly over 75% of time.
591 It is however notoriously poor on predicting the probability itself.
592 In general the profile appear a lot flatter (with probabilities closer
593 to 50%) than the reality so it is bad idea to use it to drive optimization
594 such as those disabling dynamic branch prediction for well predictable
595 branches.
596
597 There are two exceptions - edges leading to noreturn edges and edges
598 predicted by number of iterations heuristics are predicted well. This macro
599 should be able to distinguish those, but at the moment it simply check for
600 noreturn heuristic that is only one giving probability over 99% or bellow
601 1%. In future we might want to propagate reliability information across the
602 CFG if we find this information useful on multiple places. */
604 {
605 if (quality () >= ADJUSTED)
606 return true;
607 if (!initialized_p ())
608 return false;
609 return m_val < max_probability / 100
611 }
612
613 /* Return false if profile_probability is bogus. */
614 bool verify () const
615 {
618 return quality () == GUESSED;
619 else if (quality () < GUESSED)
620 return false;
621 return m_val <= max_probability;
622 }
623
624 /* Comparisons are three-state and conservative. False is returned if
625 the inequality cannot be decided. */
626 bool operator< (const profile_probability &other) const
627 {
628 return initialized_p () && other.initialized_p () && m_val < other.m_val;
629 }
630
631 bool operator> (const profile_probability &other) const
632 {
633 return initialized_p () && other.initialized_p () && m_val > other.m_val;
634 }
635
636 bool operator<= (const profile_probability &other) const
637 {
638 return initialized_p () && other.initialized_p () && m_val <= other.m_val;
639 }
640
641 bool operator>= (const profile_probability &other) const
642 {
643 return initialized_p () && other.initialized_p () && m_val >= other.m_val;
644 }
645
646 profile_probability operator* (int64_t num) const
647 {
648 return apply_scale (num, 1);
649 }
650
652 {
653 *this = apply_scale (num, 1);
654 return *this;
655 }
656
657 profile_probability operator/ (int64_t den) const
658 {
659 return apply_scale (1, den);
660 }
661
663 {
664 *this = apply_scale (1, den);
665 return *this;
666 }
667
668 /* Compute n-th power. */
669 profile_probability pow (int) const;
670
671 /* Compute sware root. */
672 profile_probability sqrt () const;
673
674 /* Get the value of the probability. */
675 uint32_t value () const { return m_val; }
676
677 /* Get the quality of the probability. */
684
685 /* Output THIS to F. */
686 void dump (FILE *f) const;
687
688 /* Output THIS to BUFFER. */
689 void dump (char *buffer) const;
690
691 /* Print THIS to stderr. */
692 void debug () const;
693
694 /* Return true if THIS is known to differ significantly from OTHER. */
695 bool differs_from_p (profile_probability other) const;
696
697 /* Return if difference is greater than 50%. */
698 bool differs_lot_from_p (profile_probability other) const;
699
700 /* COUNT1 times event happens with *THIS probability, COUNT2 times OTHER
701 happens with COUNT2 probability. Return probability that either *THIS or
702 OTHER happens. */
703 profile_probability combine_with_count (profile_count count1,
705 profile_count count2) const;
706
707 /* Return probability as sreal. */
708 sreal to_sreal () const;
709 /* LTO streaming support. */
710 static profile_probability stream_in (class lto_input_block *);
711 void stream_out (struct output_block *);
712 void stream_out (struct lto_output_stream *);
713};
714
715/* Main data type to hold profile counters in GCC. Profile counts originate
716 either from profile feedback, static profile estimation or both. We do not
717 perform whole program profile propagation and thus profile estimation
718 counters are often local to function, while counters from profile feedback
719 (or special cases of profile estimation) can be used inter-procedurally.
720
721 There are 3 basic types
722 1) local counters which are result of intra-procedural static profile
723 estimation.
724 2) ipa counters which are result of profile feedback or special case
725 of static profile estimation (such as in function main).
726 3) counters which counts as 0 inter-procedurally (because given function
727 was never run in train feedback) but they hold local static profile
728 estimate.
729
730 Counters of type 1 and 3 cannot be mixed with counters of different type
731 within operation (because whole function should use one type of counter)
732 with exception that global zero mix in most operations where outcome is
733 well defined.
734
735 To take local counter and use it inter-procedurally use ipa member function
736 which strips information irrelevant at the inter-procedural level.
737
738 Counters are 61bit integers representing number of executions during the
739 train run or normalized frequency within the function.
740
741 As the profile is maintained during the compilation, many adjustments are
742 made. Not all transformations can be made precisely, most importantly
743 when code is being duplicated. It also may happen that part of CFG has
744 profile counts known while other do not - for example when LTO optimizing
745 partly profiled program or when profile was lost due to COMDAT merging.
746
747 For this reason profile_count tracks more information than
748 just unsigned integer and it is also ready for profile mismatches.
749 The API of this data type represent operations that are natural
750 on profile counts - sum, difference and operation with scales and
751 probabilities. All operations are safe by never getting negative counts
752 and they do end up in uninitialized scale if any of the parameters is
753 uninitialized.
754
755 All comparisons that are three state and handling of probabilities. Thus
756 a < b is not equal to !(a >= b).
757
758 The following pre-defined counts are available:
759
760 profile_count::zero () for code that is known to execute zero times at
761 runtime (this can be detected statically i.e. for paths leading to
762 abort ();
763 profile_count::one () for code that is known to execute once (such as
764 main () function
765 profile_count::uninitialized () for unknown execution count.
766
767 */
768
770{
771public:
772 /* Use 60bit to hold basic block counters. Should be at least
773 64bit. Although a counter cannot be negative, we use a signed
774 type to hold various extra stages. */
775
776 static const int n_bits = 60;
777 static const uint64_t max_count = ((uint64_t) 1 << n_bits) - 2;
778private:
779 static const uint64_t uninitialized_count = ((uint64_t) 1 << n_bits) - 1;
780
781#if defined (__arm__) && (__GNUC__ >= 6 && __GNUC__ <= 8)
782 /* Work-around for PR88469. A bug in the gcc-6/7/8 PCS layout code
783 incorrectly detects the alignment of a structure where the only
784 64-bit aligned object is a bit-field. We force the alignment of
785 the entire field to mitigate this. */
786#define UINT64_BIT_FIELD_ALIGN __attribute__ ((aligned(8)))
787#else
788#define UINT64_BIT_FIELD_ALIGN
789#endif
791#undef UINT64_BIT_FIELD_ALIGN
793public:
794
795 /* Return true if both values can meaningfully appear in single function
796 body. We have either all counters in function local or global, otherwise
797 operations between them are not really defined well. */
798 bool compatible_p (const profile_count other) const
799 {
800 if (!initialized_p () || !other.initialized_p ())
801 return true;
802 if (*this == zero ()
803 || other == zero ())
804 return true;
805 /* Do not allow nonzero global profile together with local guesses
806 that are globally0. */
807 if (ipa ().nonzero_p ()
808 && !(other.ipa () == other))
809 return false;
810 if (other.ipa ().nonzero_p ()
811 && !(ipa () == *this))
812 return false;
813
814 return ipa_p () == other.ipa_p ();
815 }
816
817 /* Used for counters which are expected to be never executed. */
819 {
820 return from_gcov_type (0);
821 }
822
824 {
826 c.m_val = 0;
827 c.m_quality = ADJUSTED;
828 return c;
829 }
830
832 {
834 c.m_val = 0;
835 c.m_quality = AFDO;
836 return c;
837 }
838
840 {
842 c.m_val = 0;
843 c.m_quality = GUESSED;
844 return c;
845 }
846
848 {
849 return from_gcov_type (1);
850 }
851
852 /* Value of counters which has not been initialized. Either because
853 initialization did not happen yet or because profile is unknown. */
855 {
857 c.m_val = uninitialized_count;
858 c.m_quality = GUESSED_LOCAL;
859 return c;
860 }
861
862 /* Conversion to gcov_type is lossy. */
864 {
866 return m_val;
867 }
868
869 /* Return true if value has been initialized. */
870 bool initialized_p () const
871 {
872 return m_val != uninitialized_count;
873 }
874
875 /* Return true if value can be trusted. */
876 bool reliable_p () const
877 {
878 return m_quality >= ADJUSTED;
879 }
880
881 /* Return true if value can be operated inter-procedurally. */
882 bool ipa_p () const
883 {
885 }
886
887 /* Return true if quality of profile is precise. */
888 bool precise_p () const
889 {
890 return m_quality == PRECISE;
891 }
892
893 /* Get the value of the count. */
894 uint64_t value () const { return m_val; }
895
896 /* Get the quality of the count. */
897 enum profile_quality quality () const { return m_quality; }
898
899 /* When merging basic blocks, the two different profile counts are unified.
900 Return true if this can be done without losing info about profile.
901 The only case we care about here is when first BB contains something
902 that makes it terminate in a way not visible in CFG. */
903 bool ok_for_merging (profile_count other) const
904 {
905 if (m_quality < ADJUSTED
906 || other.m_quality < ADJUSTED)
907 return true;
908 return !(other < *this);
909 }
910
911 /* When merging two BBs with different counts, pick common count that looks
912 most representative. */
914 {
915 if (*this == other || !other.initialized_p ()
916 || m_quality > other.m_quality)
917 return *this;
918 if (other.m_quality > m_quality
919 || other > *this)
920 return other;
921 return *this;
922 }
923
924 /* Basic operations. */
925 bool operator== (const profile_count &other) const
926 {
927 return m_val == other.m_val && m_quality == other.m_quality;
928 }
929
931 {
932 if (other == zero ())
933 return *this;
934 if (*this == zero ())
935 return other;
936 if (!initialized_p () || !other.initialized_p ())
937 return uninitialized ();
938
939 profile_count ret;
941 uint64_t ret_val = m_val + other.m_val;
942 ret.m_val = MIN (ret_val, max_count);
943 ret.m_quality = MIN (m_quality, other.m_quality);
944 return ret;
945 }
946
948 {
949 if (other == zero ())
950 return *this;
951 if (*this == zero ())
952 {
953 *this = other;
954 return *this;
955 }
956 if (!initialized_p () || !other.initialized_p ())
957 return *this = uninitialized ();
958 else
959 {
961 uint64_t ret_val = m_val + other.m_val;
962 m_val = MIN (ret_val, max_count);
963 m_quality = MIN (m_quality, other.m_quality);
964 }
965 return *this;
966 }
967
969 {
970 if (*this == zero () || other == zero ())
971 return *this;
972 if (!initialized_p () || !other.initialized_p ())
973 return uninitialized ();
975 profile_count ret;
976 ret.m_val = m_val >= other.m_val ? m_val - other.m_val : 0;
977 ret.m_quality = MIN (m_quality, other.m_quality);
978 return ret;
979 }
980
982 {
983 if (*this == zero () || other == zero ())
984 return *this;
985 if (!initialized_p () || !other.initialized_p ())
986 return *this = uninitialized ();
987 else
988 {
990 m_val = m_val >= other.m_val ? m_val - other.m_val : 0;
991 m_quality = MIN (m_quality, other.m_quality);
992 }
993 return *this;
994 }
995
996 /* Return false if profile_count is bogus. */
1002
1003 /* Comparisons are three-state and conservative. False is returned if
1004 the inequality cannot be decided. */
1005 bool operator< (const profile_count &other) const
1006 {
1007 if (!initialized_p () || !other.initialized_p ())
1008 return false;
1009 if (*this == zero ())
1010 return !(other == zero ());
1011 if (other == zero ())
1012 return false;
1014 return m_val < other.m_val;
1015 }
1016
1017 bool operator> (const profile_count &other) const
1018 {
1019 if (!initialized_p () || !other.initialized_p ())
1020 return false;
1021 if (*this == zero ())
1022 return false;
1023 if (other == zero ())
1024 return !(*this == zero ());
1026 return initialized_p () && other.initialized_p () && m_val > other.m_val;
1027 }
1028
1029 bool operator< (const gcov_type other) const
1030 {
1032 gcc_checking_assert (other >= 0);
1033 return ipa ().initialized_p () && ipa ().m_val < (uint64_t) other;
1034 }
1035
1036 bool operator> (const gcov_type other) const
1037 {
1039 gcc_checking_assert (other >= 0);
1040 return ipa ().initialized_p () && ipa ().m_val > (uint64_t) other;
1041 }
1042
1043 bool operator<= (const profile_count &other) const
1044 {
1045 if (!initialized_p () || !other.initialized_p ())
1046 return false;
1047 if (*this == zero ())
1048 return true;
1049 if (other == zero ())
1050 return (*this == zero ());
1052 return m_val <= other.m_val;
1053 }
1054
1055 bool operator>= (const profile_count &other) const
1056 {
1057 if (!initialized_p () || !other.initialized_p ())
1058 return false;
1059 if (other == zero ())
1060 return true;
1061 if (*this == zero ())
1062 return (other == zero ());
1064 return m_val >= other.m_val;
1065 }
1066
1067 bool operator<= (const gcov_type other) const
1068 {
1070 gcc_checking_assert (other >= 0);
1071 return ipa ().initialized_p () && ipa ().m_val <= (uint64_t) other;
1072 }
1073
1074 bool operator>= (const gcov_type other) const
1075 {
1077 gcc_checking_assert (other >= 0);
1078 return ipa ().initialized_p () && ipa ().m_val >= (uint64_t) other;
1079 }
1080
1081 profile_count operator* (int64_t num) const
1082 {
1083 return apply_scale (num, 1);
1084 }
1085
1087 {
1088 *this = apply_scale (num, 1);
1089 return *this;
1090 }
1091
1092 profile_count operator* (const sreal &num) const;
1093 profile_count operator*= (const sreal &num);
1094
1095 profile_count operator/ (int64_t den) const
1096 {
1097 return apply_scale (1, den);
1098 }
1099
1101 {
1102 *this = apply_scale (1, den);
1103 return *this;
1104 }
1105
1106 /* Return true when value is not zero and can be used for scaling.
1107 This is different from *this > 0 because that requires counter to
1108 be IPA. */
1109 bool nonzero_p () const
1110 {
1111 return initialized_p () && m_val != 0;
1112 }
1113
1114 /* Make counter forcibly nonzero. */
1116 {
1117 if (!initialized_p ())
1118 return *this;
1119 profile_count ret = *this;
1120 if (ret.m_val == 0)
1121 {
1122 ret.m_val = 1;
1124 }
1125 return ret;
1126 }
1127
1129 {
1130 profile_count val = *this;
1131
1132 /* Always prefer nonzero IPA counts over local counts. */
1133 if (ipa ().nonzero_p () || other.ipa ().nonzero_p ())
1134 {
1135 val = ipa ();
1136 other = other.ipa ();
1137 }
1138 if (!initialized_p ())
1139 return other;
1140 if (!other.initialized_p ())
1141 return *this;
1142 if (*this == zero ())
1143 return other;
1144 if (other == zero ())
1145 return *this;
1147 if (val.m_val < other.m_val || (m_val == other.m_val
1148 && val.m_quality < other.m_quality))
1149 return other;
1150 return *this;
1151 }
1152
1153 /* PROB is a probability in scale 0...REG_BR_PROB_BASE. Scale counter
1154 accordingly. */
1156 {
1157 gcc_checking_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
1158 if (m_val == 0)
1159 return *this;
1160 if (!initialized_p ())
1161 return uninitialized ();
1162 profile_count ret;
1163 uint64_t tmp;
1165 ret.m_val = tmp;
1167 return ret;
1168 }
1169
1170 /* Scale counter according to PROB. */
1172 {
1173 if (*this == zero () || prob == profile_probability::always ())
1174 return *this;
1175 if (prob == profile_probability::never ())
1176 return zero ();
1177 if (!initialized_p () || !prob.initialized_p ())
1178 return uninitialized ();
1179 profile_count ret;
1180 uint64_t tmp;
1182 &tmp);
1183 ret.m_val = tmp;
1184 ret.m_quality = MIN (m_quality, prob.quality ());
1185 return ret;
1186 }
1187
1188 /* Return *THIS * NUM / DEN. */
1189 profile_count apply_scale (int64_t num, int64_t den) const
1190 {
1191 if (m_val == 0)
1192 return *this;
1193 if (!initialized_p ())
1194 return uninitialized ();
1195 profile_count ret;
1196 uint64_t tmp;
1197
1198 gcc_checking_assert (num >= 0 && den > 0);
1199 safe_scale_64bit (m_val, num, den, &tmp);
1200 ret.m_val = MIN (tmp, max_count);
1202 return ret;
1203 }
1204
1206 {
1207 if (*this == zero ())
1208 return *this;
1209 if (num == zero ())
1210 return num;
1211 if (!initialized_p () || !num.initialized_p () || !den.initialized_p ())
1212 return uninitialized ();
1213 if (num == den)
1214 return *this;
1216
1217 profile_count ret;
1218 uint64_t val;
1219 safe_scale_64bit (m_val, num.m_val, den.m_val, &val);
1220 ret.m_val = MIN (val, max_count);
1222 num.m_quality), den.m_quality);
1223 /* Be sure that ret is not local if num is global.
1224 Also ensure that ret is not global0 when num is global. */
1225 if (num.ipa_p ())
1226 ret.m_quality = MAX (ret.m_quality,
1227 num == num.ipa () ? GUESSED : num.m_quality);
1228 return ret;
1229 }
1230
1231 /* Return THIS with quality dropped to GUESSED_LOCAL. */
1233 {
1234 profile_count ret = *this;
1235 if (!initialized_p ())
1236 return *this;
1238 return ret;
1239 }
1240
1241 /* We know that profile is globally 0 but keep local profile if present. */
1243 {
1244 profile_count ret = *this;
1245 if (!initialized_p ())
1246 return *this;
1248 return ret;
1249 }
1250
1251 /* We know that profile is globally afdo 0 but keep local profile
1252 if present. */
1254 {
1255 profile_count ret = *this;
1256 if (!initialized_p ())
1257 return *this;
1259 return ret;
1260 }
1261
1262 /* We know that profile is globally adjusted 0 but keep local profile
1263 if present. */
1265 {
1266 profile_count ret = *this;
1267 if (!initialized_p ())
1268 return *this;
1270 return ret;
1271 }
1272
1273 /* Return THIS with quality dropped to GUESSED. */
1275 {
1276 profile_count ret = *this;
1277 ret.m_quality = MIN (ret.m_quality, GUESSED);
1278 return ret;
1279 }
1280
1281 /* Return THIS with quality GUESSED. */
1283 {
1284 profile_count ret = *this;
1286 ret.m_quality = GUESSED;
1287 return ret;
1288 }
1289
1290 /* Return variant of profile count which is always safe to compare
1291 across functions. */
1293 {
1295 return *this;
1297 return zero ();
1299 return adjusted_zero ();
1301 return afdo_zero ();
1302 return uninitialized ();
1303 }
1304
1305 /* Return THIS with quality dropped to AFDO. */
1307 {
1308 profile_count ret = *this;
1309 ret.m_quality = AFDO;
1310 return ret;
1311 }
1312
1313 /* Return probability of event with counter THIS within event with counter
1314 OVERALL. */
1316 {
1317 if (*this == zero ()
1318 && !(overall == zero ()))
1320 if (!initialized_p () || !overall.initialized_p ()
1321 || !overall.m_val)
1323 if (*this == overall && m_quality == PRECISE)
1327
1328 if (overall.m_val < m_val)
1329 {
1331 ret.set_quality (GUESSED);
1332 return ret;
1333 }
1334 else
1336 overall.m_val);
1337 ret.set_quality (MIN (MAX (MIN (m_quality, overall.m_quality),
1338 GUESSED), ADJUSTED));
1339 return ret;
1340 }
1341
1342 /* Return true if profile count is very large, so we risk overflows
1343 with loop transformations. */
1344 bool
1346 {
1347 if (!initialized_p ())
1348 return false;
1349 return m_val > max_count / 65536;
1350 }
1351
1352 int to_frequency (struct function *fun) const;
1353 int to_cgraph_frequency (profile_count entry_bb_count) const;
1354 sreal to_sreal_scale (profile_count in, bool *known = NULL) const;
1355
1356 /* Output THIS to F. */
1357 void dump (FILE *f, struct function *fun = NULL) const;
1358
1359 /* Print THIS to stderr. */
1360 void debug () const;
1361
1362 /* Return true if THIS is known to differ significantly from OTHER. */
1363 bool differs_from_p (profile_count other) const;
1364
1365 /* We want to scale profile across function boundary from NUM to DEN.
1366 Take care of the side case when NUM and DEN are zeros of incompatible
1367 kinds. */
1368 static void adjust_for_ipa_scaling (profile_count *num, profile_count *den);
1369
1370 /* THIS is a count of bb which is known to be executed IPA times.
1371 Combine this information into bb counter. This means returning IPA
1372 if it is nonzero, not changing anything if IPA is uninitialized
1373 and if IPA is zero, turning THIS into corresponding local profile with
1374 global0. */
1375 profile_count combine_with_ipa_count (profile_count ipa);
1376
1377 /* Same as combine_with_ipa_count but inside function with count IPA2. */
1378 profile_count combine_with_ipa_count_within
1379 (profile_count ipa, profile_count ipa2);
1380
1381 /* The profiling runtime uses gcov_type, which is usually 64bit integer.
1382 Conversions back and forth are used to read the coverage and get it
1383 into internal representation. */
1384 static profile_count from_gcov_type (gcov_type v,
1385 profile_quality quality = PRECISE);
1386
1387 /* LTO streaming support. */
1388 static profile_count stream_in (class lto_input_block *);
1389 void stream_out (struct output_block *);
1390 void stream_out (struct lto_output_stream *);
1391};
1392#endif
gcov_type apply_scale(gcov_type freq, gcov_type scale)
Definition basic-block.h:578
Definition lto-streamer.h:338
Definition profile-count.h:149
enum profile_quality quality() const
Definition profile-count.h:678
profile_probability sqrt() const
Definition profile-count.cc:497
profile_probability()
Definition profile-count.h:176
static const int n_bits
Definition profile-count.h:150
static profile_probability unlikely()
Definition profile-count.h:208
bool operator>(const profile_probability &other) const
Definition profile-count.h:631
static const int min_quality
Definition profile-count.h:159
profile_probability operator+(const profile_probability &other) const
Definition profile-count.h:343
bool reliable_p() const
Definition profile-count.h:269
friend struct profile_count
Definition profile-count.h:164
profile_probability apply_scale(int64_t num, int64_t den) const
Definition profile-count.h:550
profile_probability split(const profile_probability &cprob)
Definition profile-count.h:507
static const uint32_t max_probability
Definition profile-count.h:153
profile_probability & operator/=(const profile_probability &other)
Definition profile-count.h:461
profile_probability operator*(const profile_probability &other) const
Definition profile-count.h:405
void set_quality(profile_quality quality)
Definition profile-count.h:168
gcov_type apply(gcov_type val) const
Definition profile-count.h:520
profile_probability apply_scale(profile_probability num, profile_probability den) const
Definition profile-count.h:565
static profile_probability uninitialized()
Definition profile-count.h:254
static profile_probability very_unlikely()
Definition profile-count.h:200
profile_probability combine_with_count(profile_count count1, profile_probability other, profile_count count2) const
Definition profile-count.cc:465
uint32_t m_val
Definition profile-count.h:161
int to_reg_br_prob_base() const
Definition profile-count.h:295
static profile_probability guessed_never()
Definition profile-count.h:192
void debug() const
Definition profile-count.cc:211
void dump(FILE *f) const
Definition profile-count.cc:201
bool operator==(const profile_probability &other) const
Definition profile-count.h:338
bool initialized_p() const
Definition profile-count.h:263
profile_probability operator/(const profile_probability &other) const
Definition profile-count.h:433
profile_probability(uint32_t val, profile_quality quality)
Definition profile-count.h:179
profile_probability invert() const
Definition profile-count.h:528
sreal to_sreal() const
Definition profile-count.cc:488
static const uint32_t uninitialized_probability
Definition profile-count.h:155
uint32_t value() const
Definition profile-count.h:675
bool probably_reliable_p() const
Definition profile-count.h:603
static profile_probability from_reg_br_prob_base(int v)
Definition profile-count.h:276
bool differs_from_p(profile_probability other) const
Definition profile-count.cc:220
bool operator<(const profile_probability &other) const
Definition profile-count.h:626
bool operator<=(const profile_probability &other) const
Definition profile-count.h:636
int to_reg_br_prob_note() const
Definition profile-count.h:310
static profile_probability stream_in(class lto_input_block *)
Definition profile-count.cc:247
profile_probability afdo() const
Definition profile-count.h:542
profile_probability & operator+=(const profile_probability &other)
Definition profile-count.h:358
profile_probability adjusted() const
Definition profile-count.h:286
profile_probability operator-(const profile_probability &other) const
Definition profile-count.h:377
profile_probability pow(int) const
Definition profile-count.cc:527
profile_probability & operator*=(const profile_probability &other)
Definition profile-count.h:418
profile_probability guessed() const
Definition profile-count.h:534
profile_probability & operator-=(const profile_probability &other)
Definition profile-count.h:390
static profile_probability from_reg_br_prob_note(int v)
Definition profile-count.h:302
static profile_probability very_likely()
Definition profile-count.h:221
bool verify() const
Definition profile-count.h:614
static profile_probability probability_in_gcov_type(gcov_type val1, gcov_type val2)
Definition profile-count.h:320
static profile_probability likely()
Definition profile-count.h:226
static profile_probability guessed_always()
Definition profile-count.h:236
static profile_probability always()
Definition profile-count.h:244
unsigned m_adjusted_quality
Definition profile-count.h:162
bool nonzero_p() const
Definition profile-count.h:231
static profile_probability never()
Definition profile-count.h:184
static profile_probability even()
Definition profile-count.h:216
void stream_out(struct output_block *)
Definition profile-count.cc:258
bool operator>=(const profile_probability &other) const
Definition profile-count.h:641
bool differs_lot_from_p(profile_probability other) const
Definition profile-count.cc:236
Definition sreal.h:41
bool debug
Definition collect-utils.cc:34
#define GTY(x)
Definition coretypes.h:41
int64_t gcov_type
Definition coretypes.h:46
bool operator==(const nowarn_spec_t &lhs, const nowarn_spec_t &rhs)
Definition diagnostic-spec.h:131
double pow(double, double)
double sqrt(double)
bool operator<(const pattern_pos &e1, const pattern_pos &e2)
Definition genrecog.cc:3893
@ value
Definition logical-location.h:59
poly_int< N, C > r
Definition poly-int.h:774
Ca const poly_int< N, Cb > & b
Definition poly-int.h:771
Ca & a
Definition poly-int.h:770
profile_quality
Definition profile-count.h:30
@ ADJUSTED
Definition profile-count.h:63
@ GUESSED_LOCAL
Definition profile-count.h:38
@ UNINITIALIZED_PROFILE
Definition profile-count.h:32
@ GUESSED_GLOBAL0_AFDO
Definition profile-count.h:41
@ GUESSED_GLOBAL0_ADJUSTED
Definition profile-count.h:44
@ GUESSED_GLOBAL0
Definition profile-count.h:49
@ AFDO
Definition profile-count.h:58
@ PRECISE
Definition profile-count.h:67
@ GUESSED
Definition profile-count.h:55
#define RDIV(X, Y)
Definition profile-count.h:77
#define REG_BR_PROB_BASE
Definition profile-count.h:75
bool parse_profile_quality(const char *value, profile_quality *quality)
Definition profile-count.cc:62
#define UINT64_BIT_FIELD_ALIGN
Definition profile-count.h:788
bool slow_safe_scale_64bit(uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
Definition profile-count.cc:276
const char * profile_quality_as_string(enum profile_quality)
Definition profile-count.cc:54
bool safe_scale_64bit(uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
Definition profile-count.h:84
sreal & operator/=(sreal &a, const sreal &b)
Definition sreal.h:157
bool operator<=(const sreal &a, const sreal &b)
Definition sreal.h:177
sreal & operator*=(sreal &a, const sreal &b)
Definition sreal.h:162
bool operator>(const sreal &a, const sreal &b)
Definition sreal.h:172
sreal & operator-=(sreal &a, const sreal &b)
Definition sreal.h:152
sreal & operator+=(sreal &a, const sreal &b)
Definition sreal.h:147
bool operator>=(const sreal &a, const sreal &b)
Definition sreal.h:182
Definition function.h:249
Definition lto-streamer.h:633
Definition lto-streamer.h:709
Definition profile-count.h:770
profile_count combine_with_ipa_count(profile_count ipa)
Definition profile-count.cc:400
profile_count apply_probability(profile_probability prob) const
Definition profile-count.h:1171
uint64_t value() const
Definition profile-count.h:894
sreal to_sreal_scale(profile_count in, bool *known=NULL) const
Definition profile-count.cc:332
static const uint64_t uninitialized_count
Definition profile-count.h:779
profile_count force_nonzero() const
Definition profile-count.h:1115
gcov_type to_gcov_type() const
Definition profile-count.h:863
bool operator<(const profile_count &other) const
Definition profile-count.h:1005
profile_count global0adjusted() const
Definition profile-count.h:1264
static const int n_bits
Definition profile-count.h:776
profile_count max(profile_count other) const
Definition profile-count.h:1128
uint64_t UINT64_BIT_FIELD_ALIGN m_val
Definition profile-count.h:790
bool operator<=(const profile_count &other) const
Definition profile-count.h:1043
static profile_count stream_in(class lto_input_block *)
Definition profile-count.cc:144
static const uint64_t max_count
Definition profile-count.h:777
profile_count operator/(int64_t den) const
Definition profile-count.h:1095
profile_count force_guessed() const
Definition profile-count.h:1282
profile_count combine_with_ipa_count_within(profile_count ipa, profile_count ipa2)
Definition profile-count.cc:419
profile_count operator+(const profile_count &other) const
Definition profile-count.h:930
bool initialized_p() const
Definition profile-count.h:870
enum profile_quality quality() const
Definition profile-count.h:897
void dump(FILE *f, struct function *fun=NULL) const
Definition profile-count.cc:92
int to_cgraph_frequency(profile_count entry_bb_count) const
Definition profile-count.cc:314
static profile_count uninitialized()
Definition profile-count.h:854
static profile_count afdo_zero()
Definition profile-count.h:831
bool very_large_p()
Definition profile-count.h:1345
bool precise_p() const
Definition profile-count.h:888
static profile_count one()
Definition profile-count.h:847
enum profile_quality m_quality
Definition profile-count.h:792
static void adjust_for_ipa_scaling(profile_count *num, profile_count *den)
Definition profile-count.cc:371
static profile_count zero()
Definition profile-count.h:818
profile_count & operator+=(const profile_count &other)
Definition profile-count.h:947
bool reliable_p() const
Definition profile-count.h:876
profile_count guessed_local() const
Definition profile-count.h:1232
bool operator>(const profile_count &other) const
Definition profile-count.h:1017
profile_count operator*=(int64_t num)
Definition profile-count.h:1086
profile_count apply_scale(profile_count num, profile_count den) const
Definition profile-count.h:1205
profile_count global0afdo() const
Definition profile-count.h:1253
profile_count operator*(int64_t num) const
Definition profile-count.h:1081
bool ok_for_merging(profile_count other) const
Definition profile-count.h:903
profile_count merge(profile_count other) const
Definition profile-count.h:913
static profile_count guessed_zero()
Definition profile-count.h:839
profile_count ipa() const
Definition profile-count.h:1292
static profile_count from_gcov_type(gcov_type v, profile_quality quality=PRECISE)
Definition profile-count.cc:447
bool nonzero_p() const
Definition profile-count.h:1109
bool compatible_p(const profile_count other) const
Definition profile-count.h:798
bool differs_from_p(profile_count other) const
Definition profile-count.cc:126
bool operator==(const profile_count &other) const
Definition profile-count.h:925
bool operator>=(const profile_count &other) const
Definition profile-count.h:1055
profile_probability probability_in(const profile_count overall) const
Definition profile-count.h:1315
static profile_count adjusted_zero()
Definition profile-count.h:823
void stream_out(struct output_block *)
Definition profile-count.cc:155
profile_count global0() const
Definition profile-count.h:1242
profile_count apply_scale(int64_t num, int64_t den) const
Definition profile-count.h:1189
profile_count operator-(const profile_count &other) const
Definition profile-count.h:968
profile_count afdo() const
Definition profile-count.h:1306
profile_count & operator-=(const profile_count &other)
Definition profile-count.h:981
void debug() const
Definition profile-count.cc:117
int to_frequency(struct function *fun) const
Definition profile-count.cc:295
bool ipa_p() const
Definition profile-count.h:882
profile_count guessed() const
Definition profile-count.h:1274
bool verify() const
Definition profile-count.h:997
profile_count operator/=(int64_t den)
Definition profile-count.h:1100
profile_count apply_probability(int prob) const
Definition profile-count.h:1155
#define NULL
Definition system.h:50
#define MIN(X, Y)
Definition system.h:396
#define gcc_checking_assert(EXPR)
Definition system.h:821
#define MAX(X, Y)
Definition system.h:397
comp_cost operator+(comp_cost cost1, comp_cost cost2)
Definition tree-ssa-loop-ivopts.cc:269
comp_cost operator-(comp_cost cost1, comp_cost cost2)
Definition tree-ssa-loop-ivopts.cc:282