Import GCC-8 to a new vendor branch
[dragonfly.git] / contrib / gcc-8.0 / gcc / profile-count.c
1 /* Profile counter container type.
2    Copyright (C) 2017-2018 Free Software Foundation, Inc.
3    Contributed by Jan Hubicka
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>.  */
20
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"
34 #include "sreal.h"
35
36 /* Dump THIS to F.  */
37
38 void
39 profile_count::dump (FILE *f) const
40 {
41   if (!initialized_p ())
42     fprintf (f, "uninitialized");
43   else
44     {
45       fprintf (f, "%" PRId64, m_val);
46       if (m_quality == profile_guessed_local)
47         fprintf (f, " (estimated locally)");
48       else if (m_quality == profile_guessed_global0)
49         fprintf (f, " (estimated locally, globally 0)");
50       else if (m_quality == profile_guessed_global0adjusted)
51         fprintf (f, " (estimated locally, globally 0 adjusted)");
52       else if (m_quality == profile_adjusted)
53         fprintf (f, " (adjusted)");
54       else if (m_quality == profile_afdo)
55         fprintf (f, " (auto FDO)");
56       else if (m_quality == profile_guessed)
57         fprintf (f, " (guessed)");
58     }
59 }
60
61 /* Dump THIS to stderr.  */
62
63 void
64 profile_count::debug () const
65 {
66   dump (stderr);
67   fprintf (stderr, "\n");
68 }
69
70 /* Return true if THIS differs from OTHER; tolerate small diferences.  */
71
72 bool
73 profile_count::differs_from_p (profile_count other) const
74 {
75   gcc_checking_assert (compatible_p (other));
76   if (!initialized_p () || !other.initialized_p ())
77     return false;
78   if ((uint64_t)m_val - (uint64_t)other.m_val < 100
79       || (uint64_t)other.m_val - (uint64_t)m_val < 100)
80     return false;
81   if (!other.m_val)
82     return true;
83   int64_t ratio = (int64_t)m_val * 100 / other.m_val;
84   return ratio < 99 || ratio > 101;
85 }
86
87 /* Stream THIS from IB.  */
88
89 profile_count
90 profile_count::stream_in (struct lto_input_block *ib)
91 {
92   profile_count ret;
93   ret.m_val = streamer_read_gcov_count (ib);
94   ret.m_quality = (profile_quality) streamer_read_uhwi (ib);
95   return ret;
96 }
97
98 /* Stream THIS to OB.  */
99
100 void
101 profile_count::stream_out (struct output_block *ob)
102 {
103   streamer_write_gcov_count (ob, m_val);
104   streamer_write_uhwi (ob, m_quality);
105 }
106
107 /* Stream THIS to OB.  */
108
109 void
110 profile_count::stream_out (struct lto_output_stream *ob)
111 {
112   streamer_write_gcov_count_stream (ob, m_val);
113   streamer_write_uhwi_stream (ob, m_quality);
114 }
115
116 /* Dump THIS to F.  */
117
118 void
119 profile_probability::dump (FILE *f) const
120 {
121   if (!initialized_p ())
122     fprintf (f, "uninitialized");
123   else
124     {
125       /* Make difference between 0.00 as a roundoff error and actual 0.
126          Similarly for 1.  */
127       if (m_val == 0)
128         fprintf (f, "never");
129       else if (m_val == max_probability)
130         fprintf (f, "always");
131       else
132         fprintf (f, "%3.1f%%", (double)m_val * 100 / max_probability);
133       if (m_quality == profile_adjusted)
134         fprintf (f, " (adjusted)");
135       else if (m_quality == profile_afdo)
136         fprintf (f, " (auto FDO)");
137       else if (m_quality == profile_guessed)
138         fprintf (f, " (guessed)");
139     }
140 }
141
142 /* Dump THIS to stderr.  */
143
144 void
145 profile_probability::debug () const
146 {
147   dump (stderr);
148   fprintf (stderr, "\n");
149 }
150
151 /* Return true if THIS differs from OTHER; tolerate small diferences.  */
152
153 bool
154 profile_probability::differs_from_p (profile_probability other) const
155 {
156   if (!initialized_p () || !other.initialized_p ())
157     return false;
158   if ((uint64_t)m_val - (uint64_t)other.m_val < max_probability / 1000
159       || (uint64_t)other.m_val - (uint64_t)max_probability < 1000)
160     return false;
161   if (!other.m_val)
162     return true;
163   int64_t ratio = (int64_t)m_val * 100 / other.m_val;
164   return ratio < 99 || ratio > 101;
165 }
166
167 /* Return true if THIS differs significantly from OTHER.  */
168
169 bool
170 profile_probability::differs_lot_from_p (profile_probability other) const
171 {
172   if (!initialized_p () || !other.initialized_p ())
173     return false;
174   uint32_t d = m_val > other.m_val ? m_val - other.m_val : other.m_val - m_val;
175   return d > max_probability / 2;
176 }
177
178 /* Stream THIS from IB.  */
179
180 profile_probability
181 profile_probability::stream_in (struct lto_input_block *ib)
182 {
183   profile_probability ret;
184   ret.m_val = streamer_read_uhwi (ib);
185   ret.m_quality = (profile_quality) streamer_read_uhwi (ib);
186   return ret;
187 }
188
189 /* Stream THIS to OB.  */
190
191 void
192 profile_probability::stream_out (struct output_block *ob)
193 {
194   streamer_write_uhwi (ob, m_val);
195   streamer_write_uhwi (ob, m_quality);
196 }
197
198 /* Stream THIS to OB.  */
199
200 void
201 profile_probability::stream_out (struct lto_output_stream *ob)
202 {
203   streamer_write_uhwi_stream (ob, m_val);
204   streamer_write_uhwi_stream (ob, m_quality);
205 }
206
207 /* Compute RES=(a*b + c/2)/c capping and return false if overflow happened.  */
208
209 bool
210 slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
211 {
212   FIXED_WIDE_INT (128) tmp = a;
213   bool overflow;
214   tmp = wi::udiv_floor (wi::umul (tmp, b, &overflow) + (c / 2), c);
215   gcc_checking_assert (!overflow);
216   if (wi::fits_uhwi_p (tmp))
217     {
218       *res = tmp.to_uhwi ();
219       return true;
220     }
221   *res = (uint64_t) -1;
222   return false;
223 }
224
225 /* Return count as frequency within FUN scaled in range 0 to REG_FREQ_MAX
226    Used for legacy code and should not be used anymore.  */
227
228 int
229 profile_count::to_frequency (struct function *fun) const
230 {
231   if (!initialized_p ())
232     return BB_FREQ_MAX;
233   if (*this == profile_count::zero ())
234     return 0;
235   gcc_assert (REG_BR_PROB_BASE == BB_FREQ_MAX
236               && fun->cfg->count_max.initialized_p ());
237   profile_probability prob = probability_in (fun->cfg->count_max);
238   if (!prob.initialized_p ())
239     return REG_BR_PROB_BASE;
240   return prob.to_reg_br_prob_base ();
241 }
242
243 /* Return count as frequency within FUN scaled in range 0 to CGRAPH_FREQ_MAX
244    where CGRAPH_FREQ_BASE means that count equals to entry block count.
245    Used for legacy code and should not be used anymore.  */
246
247 int
248 profile_count::to_cgraph_frequency (profile_count entry_bb_count) const
249 {
250   if (!initialized_p () || !entry_bb_count.initialized_p ())
251     return CGRAPH_FREQ_BASE;
252   if (*this == profile_count::zero ())
253     return 0;
254   gcc_checking_assert (entry_bb_count.initialized_p ());
255   uint64_t scale;
256   if (!safe_scale_64bit (!entry_bb_count.m_val ? m_val + 1 : m_val,
257                          CGRAPH_FREQ_BASE, MAX (1, entry_bb_count.m_val), &scale))
258     return CGRAPH_FREQ_MAX;
259   return MIN (scale, CGRAPH_FREQ_MAX);
260 }
261
262 /* Return THIS/IN as sreal value.  */
263
264 sreal
265 profile_count::to_sreal_scale (profile_count in, bool *known) const
266 {
267   if (!initialized_p () || !in.initialized_p ())
268     {
269       if (known)
270         *known = false;
271       return 1;
272     }
273   if (known)
274     *known = true;
275   if (*this == profile_count::zero ())
276     return 0;
277
278   if (!in.m_val)
279     {
280       if (!m_val)
281         return 1;
282       return m_val * 4;
283     }
284   return (sreal)m_val / (sreal)in.m_val;
285 }
286
287 /* We want to scale profile across function boundary from NUM to DEN.
288    Take care of the side case when DEN is zeros.  We still want to behave
289    sanely here which means
290      - scale to profile_count::zero () if NUM is profile_count::zero
291      - do not affect anything if NUM == DEN
292      - preserve counter value but adjust quality in other cases.  */
293
294 void
295 profile_count::adjust_for_ipa_scaling (profile_count *num,
296                                        profile_count *den)
297 {
298   /* Scaling is no-op if NUM and DEN are the same.  */
299   if (*num == *den)
300     return;
301   /* Scaling to zero is always zero.  */
302   if (*num == profile_count::zero ())
303     return;
304   /* If den is non-zero we are safe.  */
305   if (den->force_nonzero () == *den)
306     return;
307   /* Force both to non-zero so we do not push profiles to 0 when
308      both num == 0 and den == 0.  */
309   *den = den->force_nonzero ();
310   *num = num->force_nonzero ();
311 }
312
313 /* THIS is a count of bb which is known to be executed IPA times.
314    Combine this information into bb counter.  This means returning IPA
315    if it is nonzero, not changing anything if IPA is uninitialized
316    and if IPA is zero, turning THIS into corresponding local profile with
317    global0.  */
318 profile_count
319 profile_count::combine_with_ipa_count (profile_count ipa)
320 {
321   ipa = ipa.ipa ();
322   if (ipa.nonzero_p ())
323     return ipa;
324   if (!ipa.initialized_p () || *this == profile_count::zero ())
325     return *this;
326   if (ipa == profile_count::zero ())
327     return this->global0 ();
328   return this->global0adjusted ();
329 }
330
331 /* The profiling runtime uses gcov_type, which is usually 64bit integer.
332    Conversions back and forth are used to read the coverage and get it
333    into internal representation.  */
334 profile_count
335 profile_count::from_gcov_type (gcov_type v)
336   {
337     profile_count ret;
338     gcc_checking_assert (v >= 0);
339     if (dump_file && v >= (gcov_type)max_count)
340       fprintf (dump_file,
341                "Capping gcov count %" PRId64 " to max_count %" PRId64 "\n",
342                (int64_t) v, (int64_t) max_count);
343     ret.m_val = MIN (v, (gcov_type)max_count);
344     ret.m_quality = profile_precise;
345     return ret;
346   }
347
348
349 /* COUNT1 times event happens with *THIS probability, COUNT2 times OTHER
350    happens with COUNT2 probablity. Return probablity that either *THIS or
351    OTHER happens.  */
352
353 profile_probability
354 profile_probability::combine_with_count (profile_count count1,
355                                          profile_probability other,
356                                          profile_count count2) const
357 {
358   /* If probabilities are same, we are done.
359      If counts are nonzero we can distribute accordingly. In remaining
360      cases just avreage the values and hope for the best.  */
361   if (*this == other || count1 == count2
362       || (count2 == profile_count::zero ()
363           && !(count1 == profile_count::zero ())))
364     return *this;
365   if (count1 == profile_count::zero () && !(count2 == profile_count::zero ()))
366     return other;
367   else if (count1.nonzero_p () || count2.nonzero_p ())
368     return *this * count1.probability_in (count1 + count2)
369            + other * count2.probability_in (count1 + count2);
370   else
371     return *this * profile_probability::even ()
372            + other * profile_probability::even ();
373 }