1 /* Profile counter container type.
2 Copyright (C) 2017 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #ifndef GCC_PROFILE_COUNT_H
22 #define GCC_PROFILE_COUNT_H
24 /* Quality of the profile count. Because gengtype does not support enums
25 inside of classes, this is in global namespace. */
26 enum profile_quality
{
27 /* Profile is based on static branch prediction heuristics. It may or may
28 not reflect the reality. */
30 /* Profile was determined by autofdo. */
32 /* Profile was originally based on feedback but it was adjusted
33 by code duplicating optimization. It may not precisely reflect the
34 particular code path. */
36 /* Profile was read from profile feedback or determined by accurate static
41 /* The base value for branch probability notes and edge probabilities. */
42 #define REG_BR_PROB_BASE 10000
44 #define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
46 bool slow_safe_scale_64bit (uint64_t a
, uint64_t b
, uint64_t c
, uint64_t *res
);
48 /* Compute RES=(a*b + c/2)/c capping and return false if overflow happened. */
51 safe_scale_64bit (uint64_t a
, uint64_t b
, uint64_t c
, uint64_t *res
)
53 #if (GCC_VERSION >= 5000)
55 if (!__builtin_mul_overflow (a
, b
, &tmp
)
56 && !__builtin_add_overflow (tmp
, c
/2, &tmp
))
67 if (a
< ((uint64_t)1 << 31)
68 && b
< ((uint64_t)1 << 31)
69 && c
< ((uint64_t)1 << 31))
71 *res
= (a
* b
+ (c
/ 2)) / c
;
75 return slow_safe_scale_64bit (a
, b
, c
, res
);
78 /* Data type to hold probabilities. It implements fixed point arithmetics
79 with capping so probability is always in range [0,1] and scaling requiring
80 values greater than 1 needs to be represented otherwise.
82 In addition to actual value the quality of profile is tracked and propagated
83 through all operations. Special value UNINITIALIZED is used for probabilities
84 that has not been determined yet (for example bacause of
85 -fno-guess-branch-probability)
87 Typically probabilities are derived from profile feedback (via
88 probability_in_gcov_type), autoFDO or guessed statically and then propagated
89 thorough the compilation.
91 Named probabilities are available:
92 - never (0 probability)
94 - very_unlikely (1/2000 probability)
95 - unlikely (1/5 probablity)
96 - even (1/2 probability)
97 - likely (4/5 probability)
98 - very_likely (1999/2000 probability)
102 Named probabilities except for never/always are assumed to be statically
103 guessed and thus not necessarily accurate. The difference between never
104 and guessed_never is that the first one should be used only in case that
105 well behaving program will very likely not execute the "never" path.
106 For example if the path is going to abort () call or it exception handling.
108 Always and guessed_always probabilities are symmetric.
110 For legacy code we support conversion to/from REG_BR_PROB_BASE based fixpoint
111 integer arithmetics. Once the code is converted to branch probabilities,
112 these conversions will probably go away because they are lossy.
115 class GTY((user
)) profile_probability
117 static const int n_bits
= 30;
118 /* We can technically use ((uint32_t) 1 << (n_bits - 1)) - 2 but that
119 will lead to harder multiplication sequences. */
120 static const uint32_t max_probability
= (uint32_t) 1 << (n_bits
- 2);
121 static const uint32_t uninitialized_probability
122 = ((uint32_t) 1 << (n_bits
- 1)) - 1;
125 enum profile_quality m_quality
: 2;
127 friend class profile_count
;
130 /* Named probabilities. */
131 static profile_probability
never ()
133 profile_probability ret
;
135 ret
.m_quality
= profile_precise
;
138 static profile_probability
guessed_never ()
140 profile_probability ret
;
142 ret
.m_quality
= profile_guessed
;
145 static profile_probability
very_unlikely ()
147 /* Be consistent with PROB_VERY_UNLIKELY in predict.h. */
148 profile_probability r
149 = profile_probability::always ().apply_scale (1, 2000);
153 static profile_probability
unlikely ()
155 /* Be consistent with PROB_VERY_LIKELY in predict.h. */
156 profile_probability r
157 = profile_probability::always ().apply_scale (1, 5);
161 static profile_probability
even ()
163 return profile_probability::always ().apply_scale (1, 2);
165 static profile_probability
very_likely ()
167 return profile_probability::always () - very_unlikely ();
169 static profile_probability
likely ()
171 return profile_probability::always () - unlikely ();
173 static profile_probability
guessed_always ()
175 profile_probability ret
;
176 ret
.m_val
= max_probability
;
177 ret
.m_quality
= profile_guessed
;
180 static profile_probability
always ()
182 profile_probability ret
;
183 ret
.m_val
= max_probability
;
184 ret
.m_quality
= profile_precise
;
187 /* Probabilities which has not been initialized. Either because
188 initialization did not happen yet or because profile is unknown. */
189 static profile_probability
uninitialized ()
191 profile_probability c
;
192 c
.m_val
= uninitialized_probability
;
193 c
.m_quality
= profile_guessed
;
198 /* Return true if value has been initialized. */
199 bool initialized_p () const
201 return m_val
!= uninitialized_probability
;
203 /* Return true if value can be trusted. */
204 bool reliable_p () const
206 return m_quality
>= profile_adjusted
;
209 /* Conversion from and to REG_BR_PROB_BASE integer fixpoint arithmetics.
210 this is mostly to support legacy code and should go away. */
211 static profile_probability
from_reg_br_prob_base (int v
)
213 profile_probability ret
;
214 gcc_checking_assert (v
>= 0 && v
<= REG_BR_PROB_BASE
);
215 ret
.m_val
= RDIV (v
* (uint64_t) max_probability
, REG_BR_PROB_BASE
);
216 ret
.m_quality
= profile_guessed
;
219 int to_reg_br_prob_base () const
221 gcc_checking_assert (initialized_p ());
222 return RDIV (m_val
* (uint64_t) REG_BR_PROB_BASE
, max_probability
);
225 /* Conversion to and from RTL representation of profile probabilities. */
226 static profile_probability
from_reg_br_prob_note (int v
)
228 profile_probability ret
;
229 ret
.m_val
= ((unsigned int)v
) / 4;
230 ret
.m_quality
= (enum profile_quality
)(v
& 3);
233 int to_reg_br_prob_note () const
235 gcc_checking_assert (initialized_p ());
236 int ret
= m_val
* 4 + m_quality
;
237 gcc_checking_assert (profile_probability::from_reg_br_prob_note (ret
)
242 /* Return VAL1/VAL2. */
243 static profile_probability probability_in_gcov_type
244 (gcov_type val1
, gcov_type val2
)
246 profile_probability ret
;
247 gcc_checking_assert (val1
>= 0 && val2
> 0);
249 ret
.m_val
= max_probability
;
253 safe_scale_64bit (val1
, max_probability
, val2
, &tmp
);
254 gcc_checking_assert (tmp
<= max_probability
);
257 ret
.m_quality
= profile_precise
;
261 /* Basic operations. */
262 bool operator== (const profile_probability
&other
) const
264 return m_val
== other
.m_val
&& m_quality
== other
.m_quality
;
266 profile_probability
operator+ (const profile_probability
&other
) const
268 if (other
== profile_probability::never ())
270 if (*this == profile_probability::never ())
272 if (!initialized_p () || !other
.initialized_p ())
273 return profile_probability::uninitialized ();
275 profile_probability ret
;
276 ret
.m_val
= MIN ((uint32_t)(m_val
+ other
.m_val
), max_probability
);
277 ret
.m_quality
= MIN (m_quality
, other
.m_quality
);
280 profile_probability
&operator+= (const profile_probability
&other
)
282 if (other
== profile_probability::never ())
284 if (*this == profile_probability::never ())
289 if (!initialized_p () || !other
.initialized_p ())
290 return *this = profile_probability::uninitialized ();
293 m_val
= MIN ((uint32_t)(m_val
+ other
.m_val
), max_probability
);
294 m_quality
= MIN (m_quality
, other
.m_quality
);
298 profile_probability
operator- (const profile_probability
&other
) const
300 if (*this == profile_probability::never ()
301 || other
== profile_probability::never ())
303 if (!initialized_p () || !other
.initialized_p ())
304 return profile_probability::uninitialized ();
305 profile_probability ret
;
306 ret
.m_val
= m_val
>= other
.m_val
? m_val
- other
.m_val
: 0;
307 ret
.m_quality
= MIN (m_quality
, other
.m_quality
);
310 profile_probability
&operator-= (const profile_probability
&other
)
312 if (*this == profile_probability::never ()
313 || other
== profile_probability::never ())
315 if (!initialized_p () || !other
.initialized_p ())
316 return *this = profile_probability::uninitialized ();
319 m_val
= m_val
>= other
.m_val
? m_val
- other
.m_val
: 0;
320 m_quality
= MIN (m_quality
, other
.m_quality
);
324 profile_probability
operator* (const profile_probability
&other
) const
326 if (*this == profile_probability::never ()
327 || other
== profile_probability::never ())
328 return profile_probability::never ();
329 if (!initialized_p () || !other
.initialized_p ())
330 return profile_probability::uninitialized ();
331 profile_probability ret
;
332 ret
.m_val
= RDIV ((uint64_t)m_val
* other
.m_val
, max_probability
);
333 ret
.m_quality
= MIN (m_quality
, other
.m_quality
);
336 profile_probability
&operator*= (const profile_probability
&other
)
338 if (*this == profile_probability::never ()
339 || other
== profile_probability::never ())
340 return *this = profile_probability::never ();
341 if (!initialized_p () || !other
.initialized_p ())
342 return *this = profile_probability::uninitialized ();
345 m_val
= RDIV ((uint64_t)m_val
* other
.m_val
, max_probability
);
346 m_quality
= MIN (m_quality
, other
.m_quality
);
350 profile_probability
operator/ (const profile_probability
&other
) const
352 if (*this == profile_probability::never ())
353 return profile_probability::never ();
354 if (!initialized_p () || !other
.initialized_p ())
355 return profile_probability::uninitialized ();
356 profile_probability ret
;
357 if (m_val
>= other
.m_val
)
358 ret
.m_val
= max_probability
;
363 gcc_checking_assert (other
.m_val
);
364 ret
.m_val
= MIN (RDIV ((uint64_t)m_val
* max_probability
,
368 ret
.m_quality
= MIN (m_quality
, other
.m_quality
);
371 profile_probability
&operator/= (const profile_probability
&other
)
373 if (*this == profile_probability::never ())
374 return *this = profile_probability::never ();
375 if (!initialized_p () || !other
.initialized_p ())
376 return *this = profile_probability::uninitialized ();
379 if (m_val
> other
.m_val
)
380 m_val
= max_probability
;
385 gcc_checking_assert (other
.m_val
);
386 m_val
= MIN (RDIV ((uint64_t)m_val
* max_probability
,
390 m_quality
= MIN (m_quality
, other
.m_quality
);
395 gcov_type
apply (gcov_type val
) const
397 if (*this == profile_probability::uninitialized ())
399 return RDIV (val
* m_val
, max_probability
);
402 /* Return 1-*THIS. */
403 profile_probability
invert () const
405 return profile_probability::always() - *this;
408 /* Return THIS with quality dropped to GUESSED. */
409 profile_probability
guessed () const
411 profile_probability ret
= *this;
412 ret
.m_quality
= profile_guessed
;
416 /* Return THIS with quality dropped to AFDO. */
417 profile_probability
afdo () const
419 profile_probability ret
= *this;
420 ret
.m_quality
= profile_afdo
;
424 profile_probability
combine_with_freq (int freq1
, profile_probability other
,
427 profile_probability ret
;
429 if (*this == profile_probability::uninitialized ()
430 || other
== profile_probability::uninitialized ())
431 return profile_probability::uninitialized ();
433 gcc_checking_assert (freq1
>= 0 && freq2
>= 0);
434 if (!freq1
&& !freq2
)
436 ret
.m_val
= (m_val
+ other
.m_val
) / 2;
439 ret
.m_val
= RDIV (m_val
* (uint64_t) freq1
440 + other
.m_val
* (uint64_t) freq2
, freq1
+ freq2
);
441 ret
.m_quality
= MIN (m_quality
, other
.m_quality
);
445 /* Return *THIS * NUM / DEN. */
446 profile_probability
apply_scale (int64_t num
, int64_t den
) const
448 if (*this == profile_probability::never ())
450 if (!initialized_p ())
451 return profile_probability::uninitialized ();
452 profile_probability ret
;
454 safe_scale_64bit (m_val
, num
, den
, &tmp
);
455 ret
.m_val
= MIN (tmp
, max_probability
);
456 ret
.m_quality
= MIN (m_quality
, profile_adjusted
);
460 /* Return true when the probability of edge is reliable.
462 The profile guessing code is good at predicting branch outcome (ie.
463 taken/not taken), that is predicted right slightly over 75% of time.
464 It is however notoriously poor on predicting the probability itself.
465 In general the profile appear a lot flatter (with probabilities closer
466 to 50%) than the reality so it is bad idea to use it to drive optimization
467 such as those disabling dynamic branch prediction for well predictable
470 There are two exceptions - edges leading to noreturn edges and edges
471 predicted by number of iterations heuristics are predicted well. This macro
472 should be able to distinguish those, but at the moment it simply check for
473 noreturn heuristic that is only one giving probability over 99% or bellow
474 1%. In future we might want to propagate reliability information across the
475 CFG if we find this information useful on multiple places. */
477 bool probably_reliable_p () const
479 if (m_quality
>= profile_adjusted
)
481 if (!initialized_p ())
483 return m_val
< max_probability
/ 100
484 || m_val
> max_probability
- max_probability
/ 100;
487 /* Return false if profile_probability is bogus. */
490 if (m_val
== uninitialized_probability
)
491 return m_quality
== profile_guessed
;
493 return m_val
<= max_probability
;
496 /* Comparsions are three-state and conservative. False is returned if
497 the inequality can not be decided. */
498 bool operator< (const profile_probability
&other
) const
500 return initialized_p () && other
.initialized_p () && m_val
< other
.m_val
;
502 bool operator> (const profile_probability
&other
) const
504 return initialized_p () && other
.initialized_p () && m_val
> other
.m_val
;
507 bool operator<= (const profile_probability
&other
) const
509 return initialized_p () && other
.initialized_p () && m_val
<= other
.m_val
;
511 bool operator>= (const profile_probability
&other
) const
513 return initialized_p () && other
.initialized_p () && m_val
>= other
.m_val
;
516 /* Output THIS to F. */
517 void dump (FILE *f
) const;
519 /* Print THIS to stderr. */
522 /* Return true if THIS is known to differ significantly from OTHER. */
523 bool differs_from_p (profile_probability other
) const;
524 /* Return if difference is greater than 50%. */
525 bool differs_lot_from_p (profile_probability other
) const;
527 /* LTO streaming support. */
528 static profile_probability
stream_in (struct lto_input_block
*);
529 void stream_out (struct output_block
*);
530 void stream_out (struct lto_output_stream
*);
533 /* Main data type to hold profile counters in GCC. In most cases profile
534 counts originate from profile feedback. They are 64bit integers
535 representing number of executions during the train run.
536 As the profile is maintained during the compilation, many adjustments are
537 made. Not all transformations can be made precisely, most importantly
538 when code is being duplicated. It also may happen that part of CFG has
539 profile counts known while other do not - for example when LTO optimizing
540 partly profiled program or when profile was lost due to COMDAT merging.
542 For this reason profile_count tracks more information than
543 just unsigned integer and it is also ready for profile mismatches.
544 The API of this data type represent operations that are natural
545 on profile counts - sum, difference and operation with scales and
546 probabilities. All operations are safe by never getting negative counts
547 and they do end up in uninitialized scale if any of the parameters is
550 All comparsions that are three state and handling of probabilities. Thus
551 a < b is not equal to !(a >= b).
553 The following pre-defined counts are available:
555 profile_count::zero () for code that is known to execute zero times at
556 runtime (this can be detected statically i.e. for paths leading to
558 profile_count::one () for code that is known to execute once (such as
560 profile_count::uninitialized () for unknown execution count.
564 class GTY(()) profile_count
566 /* Use 62bit to hold basic block counters. Should be at least
567 64bit. Although a counter cannot be negative, we use a signed
568 type to hold various extra stages. */
570 static const int n_bits
= 62;
571 static const uint64_t max_count
= ((uint64_t) 1 << n_bits
) - 2;
572 static const uint64_t uninitialized_count
= ((uint64_t) 1 << n_bits
) - 1;
574 uint64_t m_val
: n_bits
;
575 enum profile_quality m_quality
: 2;
578 /* Used for counters which are expected to be never executed. */
579 static profile_count
zero ()
581 return from_gcov_type (0);
583 static profile_count
guessed_zero ()
587 c
.m_quality
= profile_guessed
;
590 static profile_count
one ()
592 return from_gcov_type (1);
594 /* Value of counters which has not been initialized. Either because
595 initialization did not happen yet or because profile is unknown. */
596 static profile_count
uninitialized ()
599 c
.m_val
= uninitialized_count
;
600 c
.m_quality
= profile_guessed
;
604 /* The profiling runtime uses gcov_type, which is usually 64bit integer.
605 Conversions back and forth are used to read the coverage and get it
606 into internal representation. */
607 static profile_count
from_gcov_type (gcov_type v
)
610 gcc_checking_assert (v
>= 0 && (uint64_t) v
<= max_count
);
612 ret
.m_quality
= profile_precise
;
616 /* Conversion to gcov_type is lossy. */
617 gcov_type
to_gcov_type () const
619 gcc_checking_assert (initialized_p ());
623 /* Return true if value has been initialized. */
624 bool initialized_p () const
626 return m_val
!= uninitialized_count
;
628 /* Return true if value can be trusted. */
629 bool reliable_p () const
631 return m_quality
>= profile_adjusted
;
634 /* When merging basic blocks, the two different profile counts are unified.
635 Return true if this can be done without losing info about profile.
636 The only case we care about here is when first BB contains something
637 that makes it terminate in a way not visible in CFG. */
638 bool ok_for_merging (profile_count other
) const
640 if (m_quality
< profile_adjusted
641 || other
.m_quality
< profile_adjusted
)
643 return !(other
< *this);
646 /* When merging two BBs with different counts, pick common count that looks
647 most representative. */
648 profile_count
merge (profile_count other
) const
650 if (*this == other
|| !other
.initialized_p ()
651 || m_quality
> other
.m_quality
)
653 if (other
.m_quality
> m_quality
659 /* Basic operations. */
660 bool operator== (const profile_count
&other
) const
662 return m_val
== other
.m_val
&& m_quality
== other
.m_quality
;
664 profile_count
operator+ (const profile_count
&other
) const
666 if (other
== profile_count::zero ())
668 if (*this == profile_count::zero ())
670 if (!initialized_p () || !other
.initialized_p ())
671 return profile_count::uninitialized ();
674 ret
.m_val
= m_val
+ other
.m_val
;
675 ret
.m_quality
= MIN (m_quality
, other
.m_quality
);
678 profile_count
&operator+= (const profile_count
&other
)
680 if (other
== profile_count::zero ())
682 if (*this == profile_count::zero ())
687 if (!initialized_p () || !other
.initialized_p ())
688 return *this = profile_count::uninitialized ();
691 m_val
+= other
.m_val
;
692 m_quality
= MIN (m_quality
, other
.m_quality
);
696 profile_count
operator- (const profile_count
&other
) const
698 if (*this == profile_count::zero () || other
== profile_count::zero ())
700 if (!initialized_p () || !other
.initialized_p ())
701 return profile_count::uninitialized ();
703 ret
.m_val
= m_val
>= other
.m_val
? m_val
- other
.m_val
: 0;
704 ret
.m_quality
= MIN (m_quality
, other
.m_quality
);
707 profile_count
&operator-= (const profile_count
&other
)
709 if (*this == profile_count::zero () || other
== profile_count::zero ())
711 if (!initialized_p () || !other
.initialized_p ())
712 return *this = profile_count::uninitialized ();
715 m_val
= m_val
>= other
.m_val
? m_val
- other
.m_val
: 0;
716 m_quality
= MIN (m_quality
, other
.m_quality
);
721 /* Return false if profile_count is bogus. */
724 return m_val
!= uninitialized_count
|| m_quality
== profile_guessed
;
727 /* Comparsions are three-state and conservative. False is returned if
728 the inequality can not be decided. */
729 bool operator< (const profile_count
&other
) const
731 return initialized_p () && other
.initialized_p () && m_val
< other
.m_val
;
733 bool operator> (const profile_count
&other
) const
735 return initialized_p () && other
.initialized_p () && m_val
> other
.m_val
;
737 bool operator< (const gcov_type other
) const
739 gcc_checking_assert (other
>= 0);
740 return initialized_p () && m_val
< (uint64_t) other
;
742 bool operator> (const gcov_type other
) const
744 gcc_checking_assert (other
>= 0);
745 return initialized_p () && m_val
> (uint64_t) other
;
748 bool operator<= (const profile_count
&other
) const
750 return initialized_p () && other
.initialized_p () && m_val
<= other
.m_val
;
752 bool operator>= (const profile_count
&other
) const
754 return initialized_p () && other
.initialized_p () && m_val
>= other
.m_val
;
756 bool operator<= (const gcov_type other
) const
758 gcc_checking_assert (other
>= 0);
759 return initialized_p () && m_val
<= (uint64_t) other
;
761 bool operator>= (const gcov_type other
) const
763 gcc_checking_assert (other
>= 0);
764 return initialized_p () && m_val
>= (uint64_t) other
;
767 /* PROB is a probability in scale 0...REG_BR_PROB_BASE. Scale counter
769 profile_count
apply_probability (int prob
) const
771 gcc_checking_assert (prob
>= 0 && prob
<= REG_BR_PROB_BASE
);
774 if (!initialized_p ())
775 return profile_count::uninitialized ();
777 ret
.m_val
= RDIV (m_val
* prob
, REG_BR_PROB_BASE
);
778 ret
.m_quality
= MIN (m_quality
, profile_adjusted
);
782 /* Scale counter according to PROB. */
783 profile_count
apply_probability (profile_probability prob
) const
785 if (*this == profile_count::zero ())
787 if (prob
== profile_probability::never ())
788 return profile_count::zero ();
789 if (!initialized_p ())
790 return profile_count::uninitialized ();
793 safe_scale_64bit (m_val
, prob
.m_val
, profile_probability::max_probability
,
796 ret
.m_quality
= MIN (m_quality
, prob
.m_quality
);
799 /* Return *THIS * NUM / DEN. */
800 profile_count
apply_scale (int64_t num
, int64_t den
) const
804 if (!initialized_p ())
805 return profile_count::uninitialized ();
809 gcc_checking_assert (num
>= 0 && den
> 0);
810 safe_scale_64bit (m_val
, num
, den
, &tmp
);
811 ret
.m_val
= MIN (tmp
, max_count
);
812 ret
.m_quality
= MIN (m_quality
, profile_adjusted
);
815 profile_count
apply_scale (profile_count num
, profile_count den
) const
821 if (!initialized_p () || !num
.initialized_p () || !den
.initialized_p ())
822 return profile_count::uninitialized ();
823 gcc_checking_assert (den
> 0);
829 safe_scale_64bit (m_val
, num
.m_val
, den
.m_val
, &val
);
830 ret
.m_val
= MIN (val
, max_count
);
831 ret
.m_quality
= MIN (m_quality
, profile_adjusted
);
835 /* Return THIS with quality dropped to GUESSED. */
836 profile_count
guessed () const
838 profile_count ret
= *this;
839 ret
.m_quality
= profile_guessed
;
843 /* Return THIS with quality dropped to AFDO. */
844 profile_count
afdo () const
846 profile_count ret
= *this;
847 ret
.m_quality
= profile_afdo
;
851 /* Return probability of event with counter THIS within event with counter
853 profile_probability
probability_in (const profile_count overall
) const
856 return profile_probability::never ();
857 if (!initialized_p () || !overall
.initialized_p ()
859 return profile_probability::uninitialized ();
860 profile_probability ret
;
862 ret
.m_val
= profile_probability::max_probability
;
864 ret
.m_val
= RDIV (m_val
* profile_probability::max_probability
,
866 ret
.m_quality
= MIN (m_quality
, overall
.m_quality
);
870 /* Output THIS to F. */
871 void dump (FILE *f
) const;
873 /* Print THIS to stderr. */
876 /* Return true if THIS is known to differ significantly from OTHER. */
877 bool differs_from_p (profile_count other
) const;
879 /* LTO streaming support. */
880 static profile_count
stream_in (struct lto_input_block
*);
881 void stream_out (struct output_block
*);
882 void stream_out (struct lto_output_stream
*);