annotate gcc/profile-count.c @ 16:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16
kono
parents:
diff changeset
1 /* Profile counter container type.
kono
parents:
diff changeset
2 Copyright (C) 2017 Free Software Foundation, Inc.
kono
parents:
diff changeset
3 Contributed by Jan Hubicka
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
8 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
9 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
10 version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
15 for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 #include "config.h"
kono
parents:
diff changeset
22 #include "system.h"
kono
parents:
diff changeset
23 #include "coretypes.h"
kono
parents:
diff changeset
24 #include "profile-count.h"
kono
parents:
diff changeset
25 #include "options.h"
kono
parents:
diff changeset
26 #include "tree.h"
kono
parents:
diff changeset
27 #include "basic-block.h"
kono
parents:
diff changeset
28 #include "cfg.h"
kono
parents:
diff changeset
29 #include "function.h"
kono
parents:
diff changeset
30 #include "gimple.h"
kono
parents:
diff changeset
31 #include "data-streamer.h"
kono
parents:
diff changeset
32 #include "cgraph.h"
kono
parents:
diff changeset
33 #include "wide-int.h"
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 /* Dump THIS to F. */
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 void
kono
parents:
diff changeset
38 profile_count::dump (FILE *f) const
kono
parents:
diff changeset
39 {
kono
parents:
diff changeset
40 if (!initialized_p ())
kono
parents:
diff changeset
41 fprintf (f, "uninitialized");
kono
parents:
diff changeset
42 else
kono
parents:
diff changeset
43 {
kono
parents:
diff changeset
44 fprintf (f, "%" PRId64, m_val);
kono
parents:
diff changeset
45 if (m_quality == profile_adjusted)
kono
parents:
diff changeset
46 fprintf (f, " (adjusted)");
kono
parents:
diff changeset
47 else if (m_quality == profile_afdo)
kono
parents:
diff changeset
48 fprintf (f, " (auto FDO)");
kono
parents:
diff changeset
49 else if (m_quality == profile_guessed)
kono
parents:
diff changeset
50 fprintf (f, " (guessed)");
kono
parents:
diff changeset
51 }
kono
parents:
diff changeset
52 }
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 /* Dump THIS to stderr. */
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 void
kono
parents:
diff changeset
57 profile_count::debug () const
kono
parents:
diff changeset
58 {
kono
parents:
diff changeset
59 dump (stderr);
kono
parents:
diff changeset
60 fprintf (stderr, "\n");
kono
parents:
diff changeset
61 }
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 /* Return true if THIS differs from OTHER; tolerate small diferences. */
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65 bool
kono
parents:
diff changeset
66 profile_count::differs_from_p (profile_count other) const
kono
parents:
diff changeset
67 {
kono
parents:
diff changeset
68 if (!initialized_p () || !other.initialized_p ())
kono
parents:
diff changeset
69 return false;
kono
parents:
diff changeset
70 if ((uint64_t)m_val - (uint64_t)other.m_val < 100
kono
parents:
diff changeset
71 || (uint64_t)other.m_val - (uint64_t)m_val < 100)
kono
parents:
diff changeset
72 return false;
kono
parents:
diff changeset
73 if (!other.m_val)
kono
parents:
diff changeset
74 return true;
kono
parents:
diff changeset
75 int64_t ratio = (int64_t)m_val * 100 / other.m_val;
kono
parents:
diff changeset
76 return ratio < 99 || ratio > 101;
kono
parents:
diff changeset
77 }
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 /* Stream THIS from IB. */
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 profile_count
kono
parents:
diff changeset
82 profile_count::stream_in (struct lto_input_block *ib)
kono
parents:
diff changeset
83 {
kono
parents:
diff changeset
84 profile_count ret;
kono
parents:
diff changeset
85 ret.m_val = streamer_read_gcov_count (ib);
kono
parents:
diff changeset
86 ret.m_quality = (profile_quality) streamer_read_uhwi (ib);
kono
parents:
diff changeset
87 return ret;
kono
parents:
diff changeset
88 }
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 /* Stream THIS to OB. */
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 void
kono
parents:
diff changeset
93 profile_count::stream_out (struct output_block *ob)
kono
parents:
diff changeset
94 {
kono
parents:
diff changeset
95 streamer_write_gcov_count (ob, m_val);
kono
parents:
diff changeset
96 streamer_write_uhwi (ob, m_quality);
kono
parents:
diff changeset
97 }
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 /* Stream THIS to OB. */
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 void
kono
parents:
diff changeset
102 profile_count::stream_out (struct lto_output_stream *ob)
kono
parents:
diff changeset
103 {
kono
parents:
diff changeset
104 streamer_write_gcov_count_stream (ob, m_val);
kono
parents:
diff changeset
105 streamer_write_uhwi_stream (ob, m_quality);
kono
parents:
diff changeset
106 }
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 /* Dump THIS to F. */
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 void
kono
parents:
diff changeset
111 profile_probability::dump (FILE *f) const
kono
parents:
diff changeset
112 {
kono
parents:
diff changeset
113 if (!initialized_p ())
kono
parents:
diff changeset
114 fprintf (f, "uninitialized");
kono
parents:
diff changeset
115 else
kono
parents:
diff changeset
116 {
kono
parents:
diff changeset
117 /* Make difference between 0.00 as a roundoff error and actual 0.
kono
parents:
diff changeset
118 Similarly for 1. */
kono
parents:
diff changeset
119 if (m_val == 0)
kono
parents:
diff changeset
120 fprintf (f, "never");
kono
parents:
diff changeset
121 else if (m_val == max_probability)
kono
parents:
diff changeset
122 fprintf (f, "always");
kono
parents:
diff changeset
123 else
kono
parents:
diff changeset
124 fprintf (f, "%3.1f%%", (double)m_val * 100 / max_probability);
kono
parents:
diff changeset
125 if (m_quality == profile_adjusted)
kono
parents:
diff changeset
126 fprintf (f, " (adjusted)");
kono
parents:
diff changeset
127 else if (m_quality == profile_afdo)
kono
parents:
diff changeset
128 fprintf (f, " (auto FDO)");
kono
parents:
diff changeset
129 else if (m_quality == profile_guessed)
kono
parents:
diff changeset
130 fprintf (f, " (guessed)");
kono
parents:
diff changeset
131 }
kono
parents:
diff changeset
132 }
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 /* Dump THIS to stderr. */
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 void
kono
parents:
diff changeset
137 profile_probability::debug () const
kono
parents:
diff changeset
138 {
kono
parents:
diff changeset
139 dump (stderr);
kono
parents:
diff changeset
140 fprintf (stderr, "\n");
kono
parents:
diff changeset
141 }
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 /* Return true if THIS differs from OTHER; tolerate small diferences. */
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 bool
kono
parents:
diff changeset
146 profile_probability::differs_from_p (profile_probability other) const
kono
parents:
diff changeset
147 {
kono
parents:
diff changeset
148 if (!initialized_p () || !other.initialized_p ())
kono
parents:
diff changeset
149 return false;
kono
parents:
diff changeset
150 if ((uint64_t)m_val - (uint64_t)other.m_val < max_probability / 1000
kono
parents:
diff changeset
151 || (uint64_t)other.m_val - (uint64_t)max_probability < 1000)
kono
parents:
diff changeset
152 return false;
kono
parents:
diff changeset
153 if (!other.m_val)
kono
parents:
diff changeset
154 return true;
kono
parents:
diff changeset
155 int64_t ratio = (int64_t)m_val * 100 / other.m_val;
kono
parents:
diff changeset
156 return ratio < 99 || ratio > 101;
kono
parents:
diff changeset
157 }
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 /* Return true if THIS differs significantly from OTHER. */
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 bool
kono
parents:
diff changeset
162 profile_probability::differs_lot_from_p (profile_probability other) const
kono
parents:
diff changeset
163 {
kono
parents:
diff changeset
164 if (!initialized_p () || !other.initialized_p ())
kono
parents:
diff changeset
165 return false;
kono
parents:
diff changeset
166 uint32_t d = m_val > other.m_val ? m_val - other.m_val : other.m_val - m_val;
kono
parents:
diff changeset
167 return d > max_probability / 2;
kono
parents:
diff changeset
168 }
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 /* Stream THIS from IB. */
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 profile_probability
kono
parents:
diff changeset
173 profile_probability::stream_in (struct lto_input_block *ib)
kono
parents:
diff changeset
174 {
kono
parents:
diff changeset
175 profile_probability ret;
kono
parents:
diff changeset
176 ret.m_val = streamer_read_uhwi (ib);
kono
parents:
diff changeset
177 ret.m_quality = (profile_quality) streamer_read_uhwi (ib);
kono
parents:
diff changeset
178 return ret;
kono
parents:
diff changeset
179 }
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 /* Stream THIS to OB. */
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 void
kono
parents:
diff changeset
184 profile_probability::stream_out (struct output_block *ob)
kono
parents:
diff changeset
185 {
kono
parents:
diff changeset
186 streamer_write_uhwi (ob, m_val);
kono
parents:
diff changeset
187 streamer_write_uhwi (ob, m_quality);
kono
parents:
diff changeset
188 }
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 /* Stream THIS to OB. */
kono
parents:
diff changeset
191
kono
parents:
diff changeset
192 void
kono
parents:
diff changeset
193 profile_probability::stream_out (struct lto_output_stream *ob)
kono
parents:
diff changeset
194 {
kono
parents:
diff changeset
195 streamer_write_uhwi_stream (ob, m_val);
kono
parents:
diff changeset
196 streamer_write_uhwi_stream (ob, m_quality);
kono
parents:
diff changeset
197 }
kono
parents:
diff changeset
198
kono
parents:
diff changeset
199 /* Compute RES=(a*b + c/2)/c capping and return false if overflow happened. */
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 bool
kono
parents:
diff changeset
202 slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
kono
parents:
diff changeset
203 {
kono
parents:
diff changeset
204 FIXED_WIDE_INT (128) tmp = a;
kono
parents:
diff changeset
205 bool overflow;
kono
parents:
diff changeset
206 tmp = wi::udiv_floor (wi::umul (tmp, b, &overflow) + (c / 2), c);
kono
parents:
diff changeset
207 gcc_checking_assert (!overflow);
kono
parents:
diff changeset
208 if (wi::fits_uhwi_p (tmp))
kono
parents:
diff changeset
209 {
kono
parents:
diff changeset
210 *res = tmp.to_uhwi ();
kono
parents:
diff changeset
211 return true;
kono
parents:
diff changeset
212 }
kono
parents:
diff changeset
213 *res = (uint64_t) -1;
kono
parents:
diff changeset
214 return false;
kono
parents:
diff changeset
215 }