Mercurial > hg > CbC > CbC_gcc
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 } |