comparison gcc/profile-count.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Profile counter container type.
2 Copyright (C) 2017 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
35 /* Dump THIS to F. */
36
37 void
38 profile_count::dump (FILE *f) const
39 {
40 if (!initialized_p ())
41 fprintf (f, "uninitialized");
42 else
43 {
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)");
51 }
52 }
53
54 /* Dump THIS to stderr. */
55
56 void
57 profile_count::debug () const
58 {
59 dump (stderr);
60 fprintf (stderr, "\n");
61 }
62
63 /* Return true if THIS differs from OTHER; tolerate small diferences. */
64
65 bool
66 profile_count::differs_from_p (profile_count other) const
67 {
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;
77 }
78
79 /* Stream THIS from IB. */
80
81 profile_count
82 profile_count::stream_in (struct lto_input_block *ib)
83 {
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;
88 }
89
90 /* Stream THIS to OB. */
91
92 void
93 profile_count::stream_out (struct output_block *ob)
94 {
95 streamer_write_gcov_count (ob, m_val);
96 streamer_write_uhwi (ob, m_quality);
97 }
98
99 /* Stream THIS to OB. */
100
101 void
102 profile_count::stream_out (struct lto_output_stream *ob)
103 {
104 streamer_write_gcov_count_stream (ob, m_val);
105 streamer_write_uhwi_stream (ob, m_quality);
106 }
107
108 /* Dump THIS to F. */
109
110 void
111 profile_probability::dump (FILE *f) const
112 {
113 if (!initialized_p ())
114 fprintf (f, "uninitialized");
115 else
116 {
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)");
131 }
132 }
133
134 /* Dump THIS to stderr. */
135
136 void
137 profile_probability::debug () const
138 {
139 dump (stderr);
140 fprintf (stderr, "\n");
141 }
142
143 /* Return true if THIS differs from OTHER; tolerate small diferences. */
144
145 bool
146 profile_probability::differs_from_p (profile_probability other) const
147 {
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;
157 }
158
159 /* Return true if THIS differs significantly from OTHER. */
160
161 bool
162 profile_probability::differs_lot_from_p (profile_probability other) const
163 {
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;
168 }
169
170 /* Stream THIS from IB. */
171
172 profile_probability
173 profile_probability::stream_in (struct lto_input_block *ib)
174 {
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;
179 }
180
181 /* Stream THIS to OB. */
182
183 void
184 profile_probability::stream_out (struct output_block *ob)
185 {
186 streamer_write_uhwi (ob, m_val);
187 streamer_write_uhwi (ob, m_quality);
188 }
189
190 /* Stream THIS to OB. */
191
192 void
193 profile_probability::stream_out (struct lto_output_stream *ob)
194 {
195 streamer_write_uhwi_stream (ob, m_val);
196 streamer_write_uhwi_stream (ob, m_quality);
197 }
198
199 /* Compute RES=(a*b + c/2)/c capping and return false if overflow happened. */
200
201 bool
202 slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
203 {
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))
209 {
210 *res = tmp.to_uhwi ();
211 return true;
212 }
213 *res = (uint64_t) -1;
214 return false;
215 }