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 {
452 gcc_checking_assert (other.m_val);
453 ret.m_val = RDIV ((uint64_t)m_val * max_probability, other.m_val);
454 }
455 ret.set_quality (MIN (MIN (quality (), other.quality ()), ADJUSTED));
456 return ret;
457 }
458
460 {
461 if (*this == never ())
462 return *this = never ();
463 if (!initialized_p () || !other.initialized_p ())
464 return *this = uninitialized ();
465 else
466 {
467 /* If we get probability above 1, mark it as unreliable
468 and return 1. */
469 if (m_val > other.m_val)
470 {
472 set_quality (MIN (MIN (quality (), other.quality ()),
473 GUESSED));
474 return *this;
475 }
476 else if (!m_val)
477 ;
478 else
479 {
480 gcc_checking_assert (other.m_val);
481 m_val = RDIV ((uint64_t)m_val * max_probability, other.m_val);
482 }
483 set_quality (MIN (MIN (quality (), other.quality ()), ADJUSTED));
484 }
485 return *this;
486 }
487
488 /* Split *THIS (ORIG) probability into 2 probabilities, such that
489 the returned one (FIRST) is *THIS * CPROB and *THIS is
490 adjusted (SECOND) so that FIRST + FIRST.invert () * SECOND
491 == ORIG. This is useful e.g. when splitting a conditional
492 branch like:
493 if (cond)
494 goto lab; // ORIG probability
495 into
496 if (cond1)
497 goto lab; // FIRST = ORIG * CPROB probability
498 if (cond2)
499 goto lab; // SECOND probability
500 such that the overall probability of jumping to lab remains
501 the same. CPROB gives the relative probability between the
502 branches. */
504 {
505 profile_probability ret = *this * cprob;
506 /* The following is equivalent to:
507 *this = cprob.invert () * *this / ret.invert ();
508 Avoid scaling when overall outcome is supposed to be always.
509 Without knowing that one is inverse of other, the result would be
510 conservative. */
511 if (!(*this == always ()))
512 *this = (*this - ret) / ret.invert ();
513 return ret;
514 }
515
517 {
518 if (*this == uninitialized ())
519 return val / 2;
520 return RDIV (val * m_val, max_probability);
521 }
522
523 /* Return 1-*THIS. */
525 {
526 return always() - *this;
527 }
528
529 /* Return THIS with quality dropped to GUESSED. */
531 {
532 profile_probability ret = *this;
533 ret.set_quality (GUESSED);
534 return ret;
535 }
536
537 /* Return THIS with quality dropped to AFDO. */
539 {
540 profile_probability ret = *this;
541 ret.set_quality (AFDO);
542 return ret;
543 }
544
545 /* Return *THIS * NUM / DEN. */
546 profile_probability apply_scale (int64_t num, int64_t den) const
547 {
548 if (*this == never ())
549 return *this;
550 if (!initialized_p ())
551 return uninitialized ();
553 uint64_t tmp;
554 safe_scale_64bit (m_val, num, den, &tmp);
555 ret.m_val = MIN (tmp, max_probability);
556 ret.set_quality (MIN (quality (), ADJUSTED));
557 return ret;
558 }
559
560 /* Return *THIS * NUM / DEN. */
562 profile_probability den) const
563 {
564 if (*this == never ())
565 return *this;
566 if (num == never ())
567 return num;
568 if (!initialized_p () || !num.initialized_p () || !den.initialized_p ())
569 return uninitialized ();
570 if (num == den)
571 return *this;
573
575 ret.m_val = MIN (RDIV ((uint64_t)m_val * num.m_val, den.m_val),
577 ret.set_quality (MIN (MIN (MIN (quality (), ADJUSTED),
578 num.quality ()), den.quality ()));
579 return ret;
580 }
581
582 /* Return true when the probability of edge is reliable.
583
584 The profile guessing code is good at predicting branch outcome (i.e.
585 taken/not taken), that is predicted right slightly over 75% of time.
586 It is however notoriously poor on predicting the probability itself.
587 In general the profile appear a lot flatter (with probabilities closer
588 to 50%) than the reality so it is bad idea to use it to drive optimization
589 such as those disabling dynamic branch prediction for well predictable
590 branches.
591
592 There are two exceptions - edges leading to noreturn edges and edges
593 predicted by number of iterations heuristics are predicted well. This macro
594 should be able to distinguish those, but at the moment it simply check for
595 noreturn heuristic that is only one giving probability over 99% or below
596 1%. In future we might want to propagate reliability information across the
597 CFG if we find this information useful on multiple places. */
599 {
600 if (quality () >= ADJUSTED)
601 return true;
602 if (!initialized_p ())
603 return false;
604 return m_val < max_probability / 100
606 }
607
608 /* Return false if profile_probability is bogus. */
609 bool verify () const
610 {
613 return quality () == GUESSED;
614 else if (quality () < GUESSED)
615 return false;
616 return m_val <= max_probability;
617 }
618
619 /* Comparisons are three-state and conservative. False is returned if
620 the inequality cannot be decided. */
621 bool operator< (const profile_probability &other) const
622 {
623 return initialized_p () && other.initialized_p () && m_val < other.m_val;
624 }
625
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 profile_probability operator* (int64_t num) const
642 {
643 return apply_scale (num, 1);
644 }
645
647 {
648 *this = apply_scale (num, 1);
649 return *this;
650 }
651
652 profile_probability operator/ (int64_t den) const
653 {
654 return apply_scale (1, den);
655 }
656
658 {
659 *this = apply_scale (1, den);
660 return *this;
661 }
662
663 /* Compute n-th power. */
664 profile_probability pow (int) const;
665
666 /* Compute sware root. */
667 profile_probability sqrt () const;
668
669 /* Get the value of the probability. */
670 uint32_t value () const { return m_val; }
671
672 /* Get the quality of the probability. */
679
680 /* Output THIS to F. */
681 void dump (FILE *f) const;
682
683 /* Output THIS to BUFFER. */
684 void dump (char *buffer) const;
685
686 /* Print THIS to stderr. */
687 void debug () const;
688
689 /* Return true if THIS is known to differ significantly from OTHER. */
690 bool differs_from_p (profile_probability other) const;
691
692 /* Return if difference is greater than 50%. */
693 bool differs_lot_from_p (profile_probability other) const;
694
695 /* COUNT1 times event happens with *THIS probability, COUNT2 times OTHER
696 happens with COUNT2 probability. Return probability that either *THIS or
697 OTHER happens. */
698 profile_probability combine_with_count (profile_count count1,
700 profile_count count2) const;
701
702 /* Return probability as sreal. */
703 sreal to_sreal () const;
704 /* LTO streaming support. */
705 static profile_probability stream_in (class lto_input_block *);
706 void stream_out (struct output_block *);
707 void stream_out (struct lto_output_stream *);
708};
709
710/* Main data type to hold profile counters in GCC. Profile counts originate
711 either from profile feedback, static profile estimation or both. We do not
712 perform whole program profile propagation and thus profile estimation
713 counters are often local to function, while counters from profile feedback
714 (or special cases of profile estimation) can be used inter-procedurally.
715
716 There are 3 basic types
717 1) local counters which are result of intra-procedural static profile
718 estimation.
719 2) ipa counters which are result of profile feedback or special case
720 of static profile estimation (such as in function main).
721 3) counters which counts as 0 inter-procedurally (because given function
722 was never run in train feedback) but they hold local static profile
723 estimate.
724
725 Counters of type 1 and 3 cannot be mixed with counters of different type
726 within operation (because whole function should use one type of counter)
727 with exception that global zero mix in most operations where outcome is
728 well defined.
729
730 To take local counter and use it inter-procedurally use ipa member function
731 which strips information irrelevant at the inter-procedural level.
732
733 Counters are 61bit integers representing number of executions during the
734 train run or normalized frequency within the function.
735
736 As the profile is maintained during the compilation, many adjustments are
737 made. Not all transformations can be made precisely, most importantly
738 when code is being duplicated. It also may happen that part of CFG has
739 profile counts known while other do not - for example when LTO optimizing
740 partly profiled program or when profile was lost due to COMDAT merging.
741
742 For this reason profile_count tracks more information than
743 just unsigned integer and it is also ready for profile mismatches.
744 The API of this data type represent operations that are natural
745 on profile counts - sum, difference and operation with scales and
746 probabilities. All operations are safe by never getting negative counts
747 and they do end up in uninitialized scale if any of the parameters is
748 uninitialized.
749
750 All comparisons that are three state and handling of probabilities. Thus
751 a < b is not equal to !(a >= b).
752
753 The following pre-defined counts are available:
754
755 profile_count::zero () for code that is known to execute zero times at
756 runtime (this can be detected statically i.e. for paths leading to
757 abort ();
758 profile_count::one () for code that is known to execute once (such as
759 main () function
760 profile_count::uninitialized () for unknown execution count.
761
762 */
763
765{
766public:
767 /* Use 60bit to hold basic block counters. Should be at least
768 64bit. Although a counter cannot be negative, we use a signed
769 type to hold various extra stages. */
770
771 static const int n_bits = 60;
772 static const uint64_t max_count = ((uint64_t) 1 << n_bits) - 2;
773private:
774 static const uint64_t uninitialized_count = ((uint64_t) 1 << n_bits) - 1;
775
776#if defined (__arm__) && (__GNUC__ >= 6 && __GNUC__ <= 8)
777 /* Work-around for PR88469. A bug in the gcc-6/7/8 PCS layout code
778 incorrectly detects the alignment of a structure where the only
779 64-bit aligned object is a bit-field. We force the alignment of
780 the entire field to mitigate this. */
781#define UINT64_BIT_FIELD_ALIGN __attribute__ ((aligned(8)))
782#else
783#define UINT64_BIT_FIELD_ALIGN
784#endif
786#undef UINT64_BIT_FIELD_ALIGN
788public:
789
790 /* Return true if both values can meaningfully appear in single function
791 body. We have either all counters in function local or global, otherwise
792 operations between them are not really defined well. */
793 bool compatible_p (const profile_count other) const
794 {
795 if (!initialized_p () || !other.initialized_p ())
796 return true;
797 if (*this == zero ()
798 || other == zero ())
799 return true;
800 /* Do not allow nonzero global profile together with local guesses
801 that are globally0. */
802 if (ipa ().nonzero_p ()
803 && !(other.ipa () == other))
804 return false;
805 if (other.ipa ().nonzero_p ()
806 && !(ipa () == *this))
807 return false;
808
809 return ipa_p () == other.ipa_p ();
810 }
811
812 /* Used for counters which are expected to be never executed. */
814 {
815 return from_gcov_type (0);
816 }
817
819 {
821 c.m_val = 0;
822 c.m_quality = ADJUSTED;
823 return c;
824 }
825
827 {
829 c.m_val = 0;
830 c.m_quality = AFDO;
831 return c;
832 }
833
835 {
837 c.m_val = 0;
838 c.m_quality = GUESSED;
839 return c;
840 }
841
843 {
844 return from_gcov_type (1);
845 }
846
847 /* Value of counters which has not been initialized. Either because
848 initialization did not happen yet or because profile is unknown. */
850 {
852 c.m_val = uninitialized_count;
853 c.m_quality = GUESSED_LOCAL;
854 return c;
855 }
856
857 /* Conversion to gcov_type is lossy. */
859 {
861 return m_val;
862 }
863
864 /* Return true if value has been initialized. */
865 bool initialized_p () const
866 {
867 return m_val != uninitialized_count;
868 }
869
870 /* Return true if value can be trusted. */
871 bool reliable_p () const
872 {
873 return m_quality >= ADJUSTED;
874 }
875
876 /* Return true if value can be operated inter-procedurally. */
877 bool ipa_p () const
878 {
880 }
881
882 /* Return true if quality of profile is precise. */
883 bool precise_p () const
884 {
885 return m_quality == PRECISE;
886 }
887
888 /* Get the value of the count. */
889 uint64_t value () const { return m_val; }
890
891 /* Get the quality of the count. */
892 enum profile_quality quality () const { return m_quality; }
893
894 /* When merging basic blocks, the two different profile counts are unified.
895 Return true if this can be done without losing info about profile.
896 The only case we care about here is when first BB contains something
897 that makes it terminate in a way not visible in CFG. */
898 bool ok_for_merging (profile_count other) const
899 {
900 if (m_quality < ADJUSTED
901 || other.m_quality < ADJUSTED)
902 return true;
903 return !(other < *this);
904 }
905
906 /* When merging two BBs with different counts, pick common count that looks
907 most representative. */
909 {
910 if (*this == other || !other.initialized_p ()
911 || m_quality > other.m_quality)
912 return *this;
913 if (other.m_quality > m_quality
914 || other > *this)
915 return other;
916 return *this;
917 }
918
919 /* Basic operations. */
920 bool operator== (const profile_count &other) const
921 {
922 return m_val == other.m_val && m_quality == other.m_quality;
923 }
924
926 {
927 if (other == zero ())
928 return *this;
929 if (*this == zero ())
930 return other;
931 if (!initialized_p () || !other.initialized_p ())
932 return uninitialized ();
933
934 profile_count ret;
936 uint64_t ret_val = m_val + other.m_val;
937 ret.m_val = MIN (ret_val, max_count);
938 ret.m_quality = MIN (m_quality, other.m_quality);
939 return ret;
940 }
941
943 {
944 if (other == zero ())
945 return *this;
946 if (*this == zero ())
947 {
948 *this = other;
949 return *this;
950 }
951 if (!initialized_p () || !other.initialized_p ())
952 return *this = uninitialized ();
953 else
954 {
956 uint64_t ret_val = m_val + other.m_val;
957 m_val = MIN (ret_val, max_count);
958 m_quality = MIN (m_quality, other.m_quality);
959 }
960 return *this;
961 }
962
964 {
965 if (*this == zero () || other == zero ())
966 return *this;
967 if (!initialized_p () || !other.initialized_p ())
968 return uninitialized ();
970 profile_count ret;
971 ret.m_val = m_val >= other.m_val ? m_val - other.m_val : 0;
972 ret.m_quality = MIN (m_quality, other.m_quality);
973 return ret;
974 }
975
977 {
978 if (*this == zero () || other == zero ())
979 return *this;
980 if (!initialized_p () || !other.initialized_p ())
981 return *this = uninitialized ();
982 else
983 {
985 m_val = m_val >= other.m_val ? m_val - other.m_val : 0;
986 m_quality = MIN (m_quality, other.m_quality);
987 }
988 return *this;
989 }
990
991 /* Return false if profile_count is bogus. */
997
998 /* Comparisons are three-state and conservative. False is returned if
999 the inequality cannot be decided. */
1000 bool operator< (const profile_count &other) const
1001 {
1002 if (!initialized_p () || !other.initialized_p ())
1003 return false;
1004 if (*this == zero ())
1005 return !(other == zero ());
1006 if (other == zero ())
1007 return false;
1009 return m_val < other.m_val;
1010 }
1011
1012 bool operator> (const profile_count &other) const
1013 {
1014 if (!initialized_p () || !other.initialized_p ())
1015 return false;
1016 if (*this == zero ())
1017 return false;
1018 if (other == zero ())
1019 return !(*this == zero ());
1021 return initialized_p () && other.initialized_p () && m_val > other.m_val;
1022 }
1023
1024 bool operator< (const gcov_type other) const
1025 {
1027 gcc_checking_assert (other >= 0);
1028 return ipa ().initialized_p () && ipa ().m_val < (uint64_t) other;
1029 }
1030
1031 bool operator> (const gcov_type other) const
1032 {
1034 gcc_checking_assert (other >= 0);
1035 return ipa ().initialized_p () && ipa ().m_val > (uint64_t) other;
1036 }
1037
1038 bool operator<= (const profile_count &other) const
1039 {
1040 if (!initialized_p () || !other.initialized_p ())
1041 return false;
1042 if (*this == zero ())
1043 return true;
1044 if (other == zero ())
1045 return (*this == zero ());
1047 return m_val <= other.m_val;
1048 }
1049
1050 bool operator>= (const profile_count &other) const
1051 {
1052 if (!initialized_p () || !other.initialized_p ())
1053 return false;
1054 if (other == zero ())
1055 return true;
1056 if (*this == zero ())
1057 return (other == zero ());
1059 return m_val >= other.m_val;
1060 }
1061
1062 bool operator<= (const gcov_type other) const
1063 {
1065 gcc_checking_assert (other >= 0);
1066 return ipa ().initialized_p () && ipa ().m_val <= (uint64_t) other;
1067 }
1068
1069 bool operator>= (const gcov_type other) const
1070 {
1072 gcc_checking_assert (other >= 0);
1073 return ipa ().initialized_p () && ipa ().m_val >= (uint64_t) other;
1074 }
1075
1076 profile_count operator* (int64_t num) const
1077 {
1078 return apply_scale (num, 1);
1079 }
1080
1082 {
1083 *this = apply_scale (num, 1);
1084 return *this;
1085 }
1086
1087 profile_count operator* (const sreal &num) const;
1088 profile_count operator*= (const sreal &num);
1089
1090 profile_count operator/ (int64_t den) const
1091 {
1092 return apply_scale (1, den);
1093 }
1094
1096 {
1097 *this = apply_scale (1, den);
1098 return *this;
1099 }
1100
1101 /* Return true when value is not zero and can be used for scaling.
1102 This is different from *this > 0 because that requires counter to
1103 be IPA. */
1104 bool nonzero_p () const
1105 {
1106 return initialized_p () && m_val != 0;
1107 }
1108
1109 /* Make counter forcibly nonzero. */
1110 profile_count force_nonzero () const;
1111
1113 {
1114 profile_count val = *this;
1115
1116 /* Always prefer nonzero IPA counts over local counts. */
1117 if (ipa ().nonzero_p () || other.ipa ().nonzero_p ())
1118 {
1119 val = ipa ();
1120 other = other.ipa ();
1121 }
1122 if (!initialized_p ())
1123 return other;
1124 if (!other.initialized_p ())
1125 return *this;
1126 if (*this == zero ())
1127 return other;
1128 if (other == zero ())
1129 return *this;
1131 if (val.m_val < other.m_val || (m_val == other.m_val
1132 && val.m_quality < other.m_quality))
1133 return other;
1134 return *this;
1135 }
1136
1137 /* PROB is a probability in scale 0...REG_BR_PROB_BASE. Scale counter
1138 accordingly. */
1140 {
1141 gcc_checking_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
1142 if (m_val == 0)
1143 return *this;
1144 if (!initialized_p ())
1145 return uninitialized ();
1146 profile_count ret;
1147 uint64_t tmp;
1149 ret.m_val = tmp;
1151 return ret;
1152 }
1153
1154 /* Scale counter according to PROB. */
1156 {
1157 if (*this == zero () || prob == profile_probability::always ())
1158 return *this;
1159 if (prob == profile_probability::never ())
1160 return zero ();
1161 if (!initialized_p () || !prob.initialized_p ())
1162 return uninitialized ();
1163 profile_count ret;
1164 uint64_t tmp;
1166 &tmp);
1167 ret.m_val = tmp;
1168 ret.m_quality = MIN (m_quality, prob.quality ());
1169 return ret;
1170 }
1171
1172 /* Return *THIS * NUM / DEN. */
1173 profile_count apply_scale (int64_t num, int64_t den) const
1174 {
1175 if (m_val == 0)
1176 return *this;
1177 if (!initialized_p ())
1178 return uninitialized ();
1179 profile_count ret;
1180 uint64_t tmp;
1181
1182 gcc_checking_assert (num >= 0 && den > 0);
1183 safe_scale_64bit (m_val, num, den, &tmp);
1184 ret.m_val = MIN (tmp, max_count);
1186 return ret;
1187 }
1188
1190 {
1191 if (*this == zero ())
1192 return *this;
1193 if (num == zero ())
1194 return num;
1195 if (!initialized_p () || !num.initialized_p () || !den.initialized_p ())
1196 return uninitialized ();
1197 if (num == den)
1198 return *this;
1200
1201 profile_count ret;
1202 uint64_t val;
1203 safe_scale_64bit (m_val, num.m_val, den.m_val, &val);
1204 ret.m_val = MIN (val, max_count);
1206 num.m_quality), den.m_quality);
1207 /* Be sure that ret is not local if num is global.
1208 Also ensure that ret is not global0 when num is global. */
1209 if (num.ipa_p ())
1210 {
1211 /* This is common case of AFDO scaling when we upgrade
1212 GLOBAL0_AFDO function to AFDO. Be sure that result
1213 is AFDO and not GUESSED (which is unnecesarily low). */
1214 if (num.m_quality == AFDO
1215 && (ret.m_quality != GUESSED
1216 && ret.m_quality != GUESSED_LOCAL))
1217 ret.m_quality = AFDO;
1218 else
1219 ret.m_quality = MAX (ret.m_quality,
1220 num == num.ipa () ? GUESSED : num.m_quality);
1221 }
1222 return ret;
1223 }
1224
1225 /* Return THIS with quality dropped to GUESSED_LOCAL. */
1227 {
1228 profile_count ret = *this;
1229 if (!initialized_p ())
1230 return *this;
1232 return ret;
1233 }
1234
1235 /* We know that profile is globally 0 but keep local profile if present. */
1237 {
1238 profile_count ret = *this;
1239 if (!initialized_p ())
1240 return *this;
1242 return ret;
1243 }
1244
1245 /* We know that profile is globally afdo 0 but keep local profile
1246 if present. */
1248 {
1249 profile_count ret = *this;
1250 if (!initialized_p ())
1251 return *this;
1253 return ret;
1254 }
1255
1256 /* We know that profile is globally adjusted 0 but keep local profile
1257 if present. */
1259 {
1260 profile_count ret = *this;
1261 if (!initialized_p ())
1262 return *this;
1264 return ret;
1265 }
1266
1267 /* Return THIS with quality dropped to GUESSED. */
1269 {
1270 profile_count ret = *this;
1271 ret.m_quality = MIN (ret.m_quality, GUESSED);
1272 return ret;
1273 }
1274
1275 /* Return THIS with quality GUESSED. */
1277 {
1278 profile_count ret = *this;
1280 ret.m_quality = GUESSED;
1281 return ret;
1282 }
1283
1284 /* Return variant of profile count which is always safe to compare
1285 across functions. */
1287 {
1289 return *this;
1291 return zero ();
1293 return adjusted_zero ();
1295 return afdo_zero ();
1296 return uninitialized ();
1297 }
1298
1299 /* Return THIS with quality dropped to AFDO. */
1301 {
1302 profile_count ret = *this;
1303 ret.m_quality = AFDO;
1304 return ret;
1305 }
1306
1307 /* Return probability of event with counter THIS within event with counter
1308 OVERALL. */
1310 {
1311 if (*this == zero ()
1312 && !(overall == zero ()))
1314 if (!initialized_p () || !overall.initialized_p ()
1315 || !overall.m_val)
1317 if (*this == overall && m_quality == PRECISE)
1321
1322 if (overall.m_val < m_val)
1323 {
1325 ret.set_quality (GUESSED);
1326 return ret;
1327 }
1328 else
1329 {
1330 gcc_checking_assert (overall.m_val);
1331 uint64_t tmp;
1333 overall.m_val, &tmp);
1335 ret.m_val = tmp;
1336 }
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:573
Definition lto-streamer.h:338
Definition profile-count.h:149
enum profile_quality quality() const
Definition profile-count.h:673
profile_probability sqrt() const
Definition profile-count.cc:498
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:626
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:546
profile_probability split(const profile_probability &cprob)
Definition profile-count.h:503
static const uint32_t max_probability
Definition profile-count.h:153
profile_probability & operator/=(const profile_probability &other)
Definition profile-count.h:459
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:516
profile_probability apply_scale(profile_probability num, profile_probability den) const
Definition profile-count.h:561
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:466
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:212
void dump(FILE *f) const
Definition profile-count.cc:202
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:524
sreal to_sreal() const
Definition profile-count.cc:489
static const uint32_t uninitialized_probability
Definition profile-count.h:155
uint32_t value() const
Definition profile-count.h:670
bool probably_reliable_p() const
Definition profile-count.h:598
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:221
bool operator<(const profile_probability &other) const
Definition profile-count.h:621
bool operator<=(const profile_probability &other) const
Definition profile-count.h:631
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:248
profile_probability afdo() const
Definition profile-count.h:538
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:528
profile_probability & operator*=(const profile_probability &other)
Definition profile-count.h:418
profile_probability guessed() const
Definition profile-count.h:530
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:609
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:259
bool operator>=(const profile_probability &other) const
Definition profile-count.h:636
bool differs_lot_from_p(profile_probability other) const
Definition profile-count.cc:237
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
static bool operator==(cfa_reg &cfa, rtx reg)
Definition dwarf2cfi.cc:1164
double pow(double, double)
double sqrt(double)
bool operator<(const pattern_pos &e1, const pattern_pos &e2)
Definition genrecog.cc:3893
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:63
#define UINT64_BIT_FIELD_ALIGN
Definition profile-count.h:783
bool slow_safe_scale_64bit(uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
Definition profile-count.cc:277
const char * profile_quality_as_string(enum profile_quality)
Definition profile-count.cc:55
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:765
profile_count combine_with_ipa_count(profile_count ipa)
Definition profile-count.cc:401
profile_count apply_probability(profile_probability prob) const
Definition profile-count.h:1155
uint64_t value() const
Definition profile-count.h:889
sreal to_sreal_scale(profile_count in, bool *known=NULL) const
Definition profile-count.cc:333
static const uint64_t uninitialized_count
Definition profile-count.h:774
profile_count force_nonzero() const
Definition profile-count.cc:577
gcov_type to_gcov_type() const
Definition profile-count.h:858
bool operator<(const profile_count &other) const
Definition profile-count.h:1000
profile_count global0adjusted() const
Definition profile-count.h:1258
static const int n_bits
Definition profile-count.h:771
profile_count max(profile_count other) const
Definition profile-count.h:1112
uint64_t UINT64_BIT_FIELD_ALIGN m_val
Definition profile-count.h:785
bool operator<=(const profile_count &other) const
Definition profile-count.h:1038
static profile_count stream_in(class lto_input_block *)
Definition profile-count.cc:145
static const uint64_t max_count
Definition profile-count.h:772
profile_count operator/(int64_t den) const
Definition profile-count.h:1090
profile_count force_guessed() const
Definition profile-count.h:1276
profile_count combine_with_ipa_count_within(profile_count ipa, profile_count ipa2)
Definition profile-count.cc:420
profile_count operator+(const profile_count &other) const
Definition profile-count.h:925
bool initialized_p() const
Definition profile-count.h:865
enum profile_quality quality() const
Definition profile-count.h:892
void dump(FILE *f, struct function *fun=NULL) const
Definition profile-count.cc:93
int to_cgraph_frequency(profile_count entry_bb_count) const
Definition profile-count.cc:315
static profile_count uninitialized()
Definition profile-count.h:849
static profile_count afdo_zero()
Definition profile-count.h:826
bool very_large_p()
Definition profile-count.h:1345
bool precise_p() const
Definition profile-count.h:883
static profile_count one()
Definition profile-count.h:842
enum profile_quality m_quality
Definition profile-count.h:787
static void adjust_for_ipa_scaling(profile_count *num, profile_count *den)
Definition profile-count.cc:372
static profile_count zero()
Definition profile-count.h:813
profile_count & operator+=(const profile_count &other)
Definition profile-count.h:942
bool reliable_p() const
Definition profile-count.h:871
profile_count guessed_local() const
Definition profile-count.h:1226
bool operator>(const profile_count &other) const
Definition profile-count.h:1012
profile_count operator*=(int64_t num)
Definition profile-count.h:1081
profile_count apply_scale(profile_count num, profile_count den) const
Definition profile-count.h:1189
profile_count global0afdo() const
Definition profile-count.h:1247
profile_count operator*(int64_t num) const
Definition profile-count.h:1076
bool ok_for_merging(profile_count other) const
Definition profile-count.h:898
profile_count merge(profile_count other) const
Definition profile-count.h:908
static profile_count guessed_zero()
Definition profile-count.h:834
profile_count ipa() const
Definition profile-count.h:1286
static profile_count from_gcov_type(gcov_type v, profile_quality quality=PRECISE)
Definition profile-count.cc:448
bool nonzero_p() const
Definition profile-count.h:1104
bool compatible_p(const profile_count other) const
Definition profile-count.h:793
bool differs_from_p(profile_count other) const
Definition profile-count.cc:127
bool operator==(const profile_count &other) const
Definition profile-count.h:920
bool operator>=(const profile_count &other) const
Definition profile-count.h:1050
profile_probability probability_in(const profile_count overall) const
Definition profile-count.h:1309
static profile_count adjusted_zero()
Definition profile-count.h:818
void stream_out(struct output_block *)
Definition profile-count.cc:156
profile_count global0() const
Definition profile-count.h:1236
profile_count apply_scale(int64_t num, int64_t den) const
Definition profile-count.h:1173
profile_count operator-(const profile_count &other) const
Definition profile-count.h:963
profile_count afdo() const
Definition profile-count.h:1300
profile_count & operator-=(const profile_count &other)
Definition profile-count.h:976
void debug() const
Definition profile-count.cc:118
int to_frequency(struct function *fun) const
Definition profile-count.cc:296
bool ipa_p() const
Definition profile-count.h:877
profile_count guessed() const
Definition profile-count.h:1268
bool verify() const
Definition profile-count.h:992
profile_count operator/=(int64_t den)
Definition profile-count.h:1095
profile_count apply_probability(int prob) const
Definition profile-count.h:1139
#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:270
comp_cost operator-(comp_cost cost1, comp_cost cost2)
Definition tree-ssa-loop-ivopts.cc:283