debug/dwarf: support 64-bit DWARF in byte order check
[official-gcc.git] / gcc / profile-count.c
blob44ceaed2d66140d32a4d1c7ccb7c2c961a21871a
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
10 version.
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
15 for more details.
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 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "profile-count.h"
25 #include "options.h"
26 #include "tree.h"
27 #include "basic-block.h"
28 #include "cfg.h"
29 #include "function.h"
30 #include "gimple.h"
31 #include "data-streamer.h"
32 #include "cgraph.h"
33 #include "wide-int.h"
35 /* Dump THIS to F. */
37 void
38 profile_count::dump (FILE *f) const
40 if (!initialized_p ())
41 fprintf (f, "uninitialized");
42 else
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. */
56 void
57 profile_count::debug () const
59 dump (stderr);
60 fprintf (stderr, "\n");
63 /* Return true if THIS differs from OTHER; tolerate small diferences. */
65 bool
66 profile_count::differs_from_p (profile_count other) const
68 if (!initialized_p () || !other.initialized_p ())
69 return false;
70 if ((uint64_t)m_val - (uint64_t)other.m_val < 100
71 || (uint64_t)other.m_val - (uint64_t)m_val < 100)
72 return false;
73 if (!other.m_val)
74 return true;
75 int64_t ratio = (int64_t)m_val * 100 / other.m_val;
76 return ratio < 99 || ratio > 101;
79 /* Stream THIS from IB. */
81 profile_count
82 profile_count::stream_in (struct lto_input_block *ib)
84 profile_count ret;
85 ret.m_val = streamer_read_gcov_count (ib);
86 ret.m_quality = (profile_quality) streamer_read_uhwi (ib);
87 return ret;
90 /* Stream THIS to OB. */
92 void
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. */
101 void
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. */
110 void
111 profile_probability::dump (FILE *f) const
113 if (!initialized_p ())
114 fprintf (f, "uninitialized");
115 else
117 /* Make difference between 0.00 as a roundoff error and actual 0.
118 Similarly for 1. */
119 if (m_val == 0)
120 fprintf (f, "never");
121 else if (m_val == max_probability)
122 fprintf (f, "always");
123 else
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. */
136 void
137 profile_probability::debug () const
139 dump (stderr);
140 fprintf (stderr, "\n");
143 /* Return true if THIS differs from OTHER; tolerate small diferences. */
145 bool
146 profile_probability::differs_from_p (profile_probability other) const
148 if (!initialized_p () || !other.initialized_p ())
149 return false;
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)
152 return false;
153 if (!other.m_val)
154 return true;
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. */
161 bool
162 profile_probability::differs_lot_from_p (profile_probability other) const
164 if (!initialized_p () || !other.initialized_p ())
165 return false;
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. */
172 profile_probability
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);
178 return ret;
181 /* Stream THIS to OB. */
183 void
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. */
192 void
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. */
201 bool
202 slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
204 FIXED_WIDE_INT (128) tmp = a;
205 bool overflow;
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 ();
211 return true;
213 *res = (uint64_t) -1;
214 return false;