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/>. */
23 #include "coretypes.h"
24 #include "profile-count.h"
27 #include "basic-block.h"
31 #include "data-streamer.h"
38 profile_count::dump (FILE *f
) const
40 if (!initialized_p ())
41 fprintf (f
, "uninitialized");
44 fprintf (f
, "%" PRId64
, m_val
);
45 if (m_quality
== profile_adjusted
)
46 fprintf (f
, " (adjusted)");
47 else if (m_quality
== profile_afdo
)
48 fprintf (f
, " (auto FDO)");
49 else if (m_quality
== profile_guessed
)
50 fprintf (f
, " (guessed)");
54 /* Dump THIS to stderr. */
57 profile_count::debug () const
60 fprintf (stderr
, "\n");
63 /* Return true if THIS differs from OTHER; tolerate small diferences. */
66 profile_count::differs_from_p (profile_count other
) const
68 if (!initialized_p () || !other
.initialized_p ())
70 if ((uint64_t)m_val
- (uint64_t)other
.m_val
< 100
71 || (uint64_t)other
.m_val
- (uint64_t)m_val
< 100)
75 int64_t ratio
= (int64_t)m_val
* 100 / other
.m_val
;
76 return ratio
< 99 || ratio
> 101;
79 /* Stream THIS from IB. */
82 profile_count::stream_in (struct lto_input_block
*ib
)
85 ret
.m_val
= streamer_read_gcov_count (ib
);
86 ret
.m_quality
= (profile_quality
) streamer_read_uhwi (ib
);
90 /* Stream THIS to OB. */
93 profile_count::stream_out (struct output_block
*ob
)
95 streamer_write_gcov_count (ob
, m_val
);
96 streamer_write_uhwi (ob
, m_quality
);
99 /* Stream THIS to OB. */
102 profile_count::stream_out (struct lto_output_stream
*ob
)
104 streamer_write_gcov_count_stream (ob
, m_val
);
105 streamer_write_uhwi_stream (ob
, m_quality
);
108 /* Dump THIS to F. */
111 profile_probability::dump (FILE *f
) const
113 if (!initialized_p ())
114 fprintf (f
, "uninitialized");
117 /* Make difference between 0.00 as a roundoff error and actual 0.
120 fprintf (f
, "never");
121 else if (m_val
== max_probability
)
122 fprintf (f
, "always");
124 fprintf (f
, "%3.1f%%", (double)m_val
* 100 / max_probability
);
125 if (m_quality
== profile_adjusted
)
126 fprintf (f
, " (adjusted)");
127 else if (m_quality
== profile_afdo
)
128 fprintf (f
, " (auto FDO)");
129 else if (m_quality
== profile_guessed
)
130 fprintf (f
, " (guessed)");
134 /* Dump THIS to stderr. */
137 profile_probability::debug () const
140 fprintf (stderr
, "\n");
143 /* Return true if THIS differs from OTHER; tolerate small diferences. */
146 profile_probability::differs_from_p (profile_probability other
) const
148 if (!initialized_p () || !other
.initialized_p ())
150 if ((uint64_t)m_val
- (uint64_t)other
.m_val
< max_probability
/ 1000
151 || (uint64_t)other
.m_val
- (uint64_t)max_probability
< 1000)
155 int64_t ratio
= (int64_t)m_val
* 100 / other
.m_val
;
156 return ratio
< 99 || ratio
> 101;
159 /* Return true if THIS differs significantly from OTHER. */
162 profile_probability::differs_lot_from_p (profile_probability other
) const
164 if (!initialized_p () || !other
.initialized_p ())
166 uint32_t d
= m_val
> other
.m_val
? m_val
- other
.m_val
: other
.m_val
- m_val
;
167 return d
> max_probability
/ 2;
170 /* Stream THIS from IB. */
173 profile_probability::stream_in (struct lto_input_block
*ib
)
175 profile_probability ret
;
176 ret
.m_val
= streamer_read_uhwi (ib
);
177 ret
.m_quality
= (profile_quality
) streamer_read_uhwi (ib
);
181 /* Stream THIS to OB. */
184 profile_probability::stream_out (struct output_block
*ob
)
186 streamer_write_uhwi (ob
, m_val
);
187 streamer_write_uhwi (ob
, m_quality
);
190 /* Stream THIS to OB. */
193 profile_probability::stream_out (struct lto_output_stream
*ob
)
195 streamer_write_uhwi_stream (ob
, m_val
);
196 streamer_write_uhwi_stream (ob
, m_quality
);
199 /* Compute RES=(a*b + c/2)/c capping and return false if overflow happened. */
202 slow_safe_scale_64bit (uint64_t a
, uint64_t b
, uint64_t c
, uint64_t *res
)
204 FIXED_WIDE_INT (128) tmp
= a
;
206 tmp
= wi::udiv_floor (wi::umul (tmp
, b
, &overflow
) + (c
/ 2), c
);
207 gcc_checking_assert (!overflow
);
208 if (wi::fits_uhwi_p (tmp
))
210 *res
= tmp
.to_uhwi ();
213 *res
= (uint64_t) -1;