Mercurial > hg > CbC > CbC_gcc
comparison gcc/value-prof.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Transformations based on profile information for values. | 1 /* Transformations based on profile information for values. |
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | 2 Copyright (C) 2003-2017 Free Software Foundation, Inc. |
3 Free Software Foundation, Inc. | |
4 | 3 |
5 This file is part of GCC. | 4 This file is part of GCC. |
6 | 5 |
7 GCC is free software; you can redistribute it and/or modify it under | 6 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 | 7 the terms of the GNU General Public License as published by the Free |
19 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
20 | 19 |
21 #include "config.h" | 20 #include "config.h" |
22 #include "system.h" | 21 #include "system.h" |
23 #include "coretypes.h" | 22 #include "coretypes.h" |
24 #include "tm.h" | 23 #include "backend.h" |
25 #include "rtl.h" | 24 #include "rtl.h" |
25 #include "tree.h" | |
26 #include "gimple.h" | |
27 #include "cfghooks.h" | |
28 #include "ssa.h" | |
29 #include "cgraph.h" | |
30 #include "coverage.h" | |
31 #include "data-streamer.h" | |
32 #include "diagnostic.h" | |
33 #include "fold-const.h" | |
34 #include "tree-nested.h" | |
35 #include "calls.h" | |
26 #include "expr.h" | 36 #include "expr.h" |
27 #include "hard-reg-set.h" | |
28 #include "basic-block.h" | |
29 #include "value-prof.h" | 37 #include "value-prof.h" |
30 #include "output.h" | 38 #include "tree-eh.h" |
31 #include "flags.h" | 39 #include "gimplify.h" |
32 #include "insn-config.h" | 40 #include "gimple-iterator.h" |
33 #include "recog.h" | 41 #include "tree-cfg.h" |
34 #include "optabs.h" | |
35 #include "regs.h" | |
36 #include "ggc.h" | |
37 #include "tree-flow.h" | |
38 #include "tree-flow-inline.h" | |
39 #include "diagnostic.h" | |
40 #include "tree-pretty-print.h" | |
41 #include "gimple-pretty-print.h" | 42 #include "gimple-pretty-print.h" |
42 #include "coverage.h" | 43 #include "dumpfile.h" |
43 #include "tree.h" | 44 #include "builtins.h" |
44 #include "gcov-io.h" | 45 #include "params.h" |
45 #include "cgraph.h" | 46 #include "tree-chkp.h" |
46 #include "timevar.h" | |
47 #include "tree-pass.h" | |
48 #include "pointer-set.h" | |
49 | 47 |
50 /* In this file value profile based optimizations are placed. Currently the | 48 /* In this file value profile based optimizations are placed. Currently the |
51 following optimizations are implemented (for more detailed descriptions | 49 following optimizations are implemented (for more detailed descriptions |
52 see comments at value_profile_transformations): | 50 see comments at value_profile_transformations): |
53 | 51 |
54 1) Division/modulo specialization. Provided that we can determine that the | 52 1) Division/modulo specialization. Provided that we can determine that the |
55 operands of the division have some special properties, we may use it to | 53 operands of the division have some special properties, we may use it to |
56 produce more effective code. | 54 produce more effective code. |
57 2) Speculative prefetching. If we are able to determine that the difference | 55 |
56 2) Indirect/virtual call specialization. If we can determine most | |
57 common function callee in indirect/virtual call. We can use this | |
58 information to improve code effectiveness (especially info for | |
59 the inliner). | |
60 | |
61 3) Speculative prefetching. If we are able to determine that the difference | |
58 between addresses accessed by a memory reference is usually constant, we | 62 between addresses accessed by a memory reference is usually constant, we |
59 may add the prefetch instructions. | 63 may add the prefetch instructions. |
60 FIXME: This transformation was removed together with RTL based value | 64 FIXME: This transformation was removed together with RTL based value |
61 profiling. | 65 profiling. |
62 | 66 |
63 3) Indirect/virtual call specialization. If we can determine most | 67 |
64 common function callee in indirect/virtual call. We can use this | 68 Value profiling internals |
65 information to improve code effectiveness (especially info for | 69 ========================== |
66 inliner). | 70 |
67 | 71 Every value profiling transformation starts with defining what values |
68 Every such optimization should add its requirements for profiled values to | 72 to profile. There are different histogram types (see HIST_TYPE_* in |
69 insn_values_to_profile function. This function is called from branch_prob | 73 value-prof.h) and each transformation can request one or more histogram |
70 in profile.c and the requested values are instrumented by it in the first | 74 types per GIMPLE statement. The function gimple_find_values_to_profile() |
71 compilation with -fprofile-arcs. The optimization may then read the | 75 collects the values to profile in a vec, and adds the number of counters |
72 gathered data in the second compilation with -fbranch-probabilities. | 76 required for the different histogram types. |
73 | 77 |
74 The measured data is pointed to from the histograms | 78 For a -fprofile-generate run, the statements for which values should be |
75 field of the statement annotation of the instrumented insns. It is | 79 recorded, are instrumented in instrument_values(). The instrumentation |
76 kept as a linked list of struct histogram_value_t's, which contain the | 80 is done by helper functions that can be found in tree-profile.c, where |
77 same information as above. */ | 81 new types of histograms can be added if necessary. |
78 | 82 |
79 | 83 After a -fprofile-use, the value profiling data is read back in by |
80 static tree gimple_divmod_fixed_value (gimple, tree, int, gcov_type, gcov_type); | 84 compute_value_histograms() that translates the collected data to |
81 static tree gimple_mod_pow2 (gimple, int, gcov_type, gcov_type); | 85 histograms and attaches them to the profiled statements via |
82 static tree gimple_mod_subtract (gimple, int, int, int, gcov_type, gcov_type, | 86 gimple_add_histogram_value(). Histograms are stored in a hash table |
83 gcov_type); | 87 that is attached to every intrumented function, see VALUE_HISTOGRAMS |
88 in function.h. | |
89 | |
90 The value-profile transformations driver is the function | |
91 gimple_value_profile_transformations(). It traverses all statements in | |
92 the to-be-transformed function, and looks for statements with one or | |
93 more histograms attached to it. If a statement has histograms, the | |
94 transformation functions are called on the statement. | |
95 | |
96 Limitations / FIXME / TODO: | |
97 * Only one histogram of each type can be associated with a statement. | |
98 * Some value profile transformations are done in builtins.c (?!) | |
99 * Updating of histograms needs some TLC. | |
100 * The value profiling code could be used to record analysis results | |
101 from non-profiling (e.g. VRP). | |
102 * Adding new profilers should be simplified, starting with a cleanup | |
103 of what-happens-where and with making gimple_find_values_to_profile | |
104 and gimple_value_profile_transformations table-driven, perhaps... | |
105 */ | |
106 | |
84 static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *); | 107 static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *); |
85 static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *); | 108 static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *); |
86 static bool gimple_mod_subtract_transform (gimple_stmt_iterator *); | 109 static bool gimple_mod_subtract_transform (gimple_stmt_iterator *); |
87 static bool gimple_stringops_transform (gimple_stmt_iterator *); | 110 static bool gimple_stringops_transform (gimple_stmt_iterator *); |
88 static bool gimple_ic_transform (gimple); | 111 static bool gimple_ic_transform (gimple_stmt_iterator *); |
89 | 112 |
90 /* Allocate histogram value. */ | 113 /* Allocate histogram value. */ |
91 | 114 |
92 static histogram_value | 115 histogram_value |
93 gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED, | 116 gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED, |
94 enum hist_type type, gimple stmt, tree value) | 117 enum hist_type type, gimple *stmt, tree value) |
95 { | 118 { |
96 histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist)); | 119 histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist)); |
97 hist->hvalue.value = value; | 120 hist->hvalue.value = value; |
98 hist->hvalue.stmt = stmt; | 121 hist->hvalue.stmt = stmt; |
99 hist->type = type; | 122 hist->type = type; |
106 histogram_hash (const void *x) | 129 histogram_hash (const void *x) |
107 { | 130 { |
108 return htab_hash_pointer (((const_histogram_value)x)->hvalue.stmt); | 131 return htab_hash_pointer (((const_histogram_value)x)->hvalue.stmt); |
109 } | 132 } |
110 | 133 |
111 /* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */ | 134 /* Return nonzero if statement for histogram_value X is Y. */ |
112 | 135 |
113 static int | 136 static int |
114 histogram_eq (const void *x, const void *y) | 137 histogram_eq (const void *x, const void *y) |
115 { | 138 { |
116 return ((const_histogram_value) x)->hvalue.stmt == (const_gimple) y; | 139 return ((const_histogram_value) x)->hvalue.stmt == (const gimple *) y; |
117 } | 140 } |
118 | 141 |
119 /* Set histogram for STMT. */ | 142 /* Set histogram for STMT. */ |
120 | 143 |
121 static void | 144 static void |
122 set_histogram_value (struct function *fun, gimple stmt, histogram_value hist) | 145 set_histogram_value (struct function *fun, gimple *stmt, histogram_value hist) |
123 { | 146 { |
124 void **loc; | 147 void **loc; |
125 if (!hist && !VALUE_HISTOGRAMS (fun)) | 148 if (!hist && !VALUE_HISTOGRAMS (fun)) |
126 return; | 149 return; |
127 if (!VALUE_HISTOGRAMS (fun)) | 150 if (!VALUE_HISTOGRAMS (fun)) |
140 } | 163 } |
141 | 164 |
142 /* Get histogram list for STMT. */ | 165 /* Get histogram list for STMT. */ |
143 | 166 |
144 histogram_value | 167 histogram_value |
145 gimple_histogram_value (struct function *fun, gimple stmt) | 168 gimple_histogram_value (struct function *fun, gimple *stmt) |
146 { | 169 { |
147 if (!VALUE_HISTOGRAMS (fun)) | 170 if (!VALUE_HISTOGRAMS (fun)) |
148 return NULL; | 171 return NULL; |
149 return (histogram_value) htab_find_with_hash (VALUE_HISTOGRAMS (fun), stmt, | 172 return (histogram_value) htab_find_with_hash (VALUE_HISTOGRAMS (fun), stmt, |
150 htab_hash_pointer (stmt)); | 173 htab_hash_pointer (stmt)); |
151 } | 174 } |
152 | 175 |
153 /* Add histogram for STMT. */ | 176 /* Add histogram for STMT. */ |
154 | 177 |
155 void | 178 void |
156 gimple_add_histogram_value (struct function *fun, gimple stmt, | 179 gimple_add_histogram_value (struct function *fun, gimple *stmt, |
157 histogram_value hist) | 180 histogram_value hist) |
158 { | 181 { |
159 hist->hvalue.next = gimple_histogram_value (fun, stmt); | 182 hist->hvalue.next = gimple_histogram_value (fun, stmt); |
160 set_histogram_value (fun, stmt, hist); | 183 set_histogram_value (fun, stmt, hist); |
161 } | 184 hist->fun = fun; |
162 | 185 } |
163 | 186 |
164 /* Remove histogram HIST from STMT's histogram list. */ | 187 /* Remove histogram HIST from STMT's histogram list. */ |
165 | 188 |
166 void | 189 void |
167 gimple_remove_histogram_value (struct function *fun, gimple stmt, | 190 gimple_remove_histogram_value (struct function *fun, gimple *stmt, |
168 histogram_value hist) | 191 histogram_value hist) |
169 { | 192 { |
170 histogram_value hist2 = gimple_histogram_value (fun, stmt); | 193 histogram_value hist2 = gimple_histogram_value (fun, stmt); |
171 if (hist == hist2) | 194 if (hist == hist2) |
172 { | 195 { |
177 while (hist2->hvalue.next != hist) | 200 while (hist2->hvalue.next != hist) |
178 hist2 = hist2->hvalue.next; | 201 hist2 = hist2->hvalue.next; |
179 hist2->hvalue.next = hist->hvalue.next; | 202 hist2->hvalue.next = hist->hvalue.next; |
180 } | 203 } |
181 free (hist->hvalue.counters); | 204 free (hist->hvalue.counters); |
182 #ifdef ENABLE_CHECKING | 205 if (flag_checking) |
183 memset (hist, 0xab, sizeof (*hist)); | 206 memset (hist, 0xab, sizeof (*hist)); |
184 #endif | |
185 free (hist); | 207 free (hist); |
186 } | 208 } |
187 | 209 |
188 | |
189 /* Lookup histogram of type TYPE in the STMT. */ | 210 /* Lookup histogram of type TYPE in the STMT. */ |
190 | 211 |
191 histogram_value | 212 histogram_value |
192 gimple_histogram_value_of_type (struct function *fun, gimple stmt, | 213 gimple_histogram_value_of_type (struct function *fun, gimple *stmt, |
193 enum hist_type type) | 214 enum hist_type type) |
194 { | 215 { |
195 histogram_value hist; | 216 histogram_value hist; |
196 for (hist = gimple_histogram_value (fun, stmt); hist; | 217 for (hist = gimple_histogram_value (fun, stmt); hist; |
197 hist = hist->hvalue.next) | 218 hist = hist->hvalue.next) |
213 (hist->hdata.intvl.int_start | 234 (hist->hdata.intvl.int_start |
214 + hist->hdata.intvl.steps - 1)); | 235 + hist->hdata.intvl.steps - 1)); |
215 if (hist->hvalue.counters) | 236 if (hist->hvalue.counters) |
216 { | 237 { |
217 unsigned int i; | 238 unsigned int i; |
218 fprintf(dump_file, " ["); | 239 fprintf (dump_file, " ["); |
219 for (i = 0; i < hist->hdata.intvl.steps; i++) | 240 for (i = 0; i < hist->hdata.intvl.steps; i++) |
220 fprintf (dump_file, " %d:"HOST_WIDEST_INT_PRINT_DEC, | 241 fprintf (dump_file, " %d:%" PRId64, |
221 hist->hdata.intvl.int_start + i, | 242 hist->hdata.intvl.int_start + i, |
222 (HOST_WIDEST_INT) hist->hvalue.counters[i]); | 243 (int64_t) hist->hvalue.counters[i]); |
223 fprintf (dump_file, " ] outside range:"HOST_WIDEST_INT_PRINT_DEC, | 244 fprintf (dump_file, " ] outside range:%" PRId64, |
224 (HOST_WIDEST_INT) hist->hvalue.counters[i]); | 245 (int64_t) hist->hvalue.counters[i]); |
225 } | 246 } |
226 fprintf (dump_file, ".\n"); | 247 fprintf (dump_file, ".\n"); |
227 break; | 248 break; |
228 | 249 |
229 case HIST_TYPE_POW2: | 250 case HIST_TYPE_POW2: |
230 fprintf (dump_file, "Pow2 counter "); | 251 fprintf (dump_file, "Pow2 counter "); |
231 if (hist->hvalue.counters) | 252 if (hist->hvalue.counters) |
232 { | 253 { |
233 fprintf (dump_file, "pow2:"HOST_WIDEST_INT_PRINT_DEC | 254 fprintf (dump_file, "pow2:%" PRId64 |
234 " nonpow2:"HOST_WIDEST_INT_PRINT_DEC, | 255 " nonpow2:%" PRId64, |
235 (HOST_WIDEST_INT) hist->hvalue.counters[0], | 256 (int64_t) hist->hvalue.counters[1], |
236 (HOST_WIDEST_INT) hist->hvalue.counters[1]); | 257 (int64_t) hist->hvalue.counters[0]); |
237 } | 258 } |
238 fprintf (dump_file, ".\n"); | 259 fprintf (dump_file, ".\n"); |
239 break; | 260 break; |
240 | 261 |
241 case HIST_TYPE_SINGLE_VALUE: | 262 case HIST_TYPE_SINGLE_VALUE: |
242 fprintf (dump_file, "Single value "); | 263 fprintf (dump_file, "Single value "); |
243 if (hist->hvalue.counters) | 264 if (hist->hvalue.counters) |
244 { | 265 { |
245 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC | 266 fprintf (dump_file, "value:%" PRId64 |
246 " match:"HOST_WIDEST_INT_PRINT_DEC | 267 " match:%" PRId64 |
247 " wrong:"HOST_WIDEST_INT_PRINT_DEC, | 268 " wrong:%" PRId64, |
248 (HOST_WIDEST_INT) hist->hvalue.counters[0], | 269 (int64_t) hist->hvalue.counters[0], |
249 (HOST_WIDEST_INT) hist->hvalue.counters[1], | 270 (int64_t) hist->hvalue.counters[1], |
250 (HOST_WIDEST_INT) hist->hvalue.counters[2]); | 271 (int64_t) hist->hvalue.counters[2]); |
251 } | 272 } |
252 fprintf (dump_file, ".\n"); | 273 fprintf (dump_file, ".\n"); |
253 break; | 274 break; |
254 | 275 |
255 case HIST_TYPE_AVERAGE: | 276 case HIST_TYPE_AVERAGE: |
256 fprintf (dump_file, "Average value "); | 277 fprintf (dump_file, "Average value "); |
257 if (hist->hvalue.counters) | 278 if (hist->hvalue.counters) |
258 { | 279 { |
259 fprintf (dump_file, "sum:"HOST_WIDEST_INT_PRINT_DEC | 280 fprintf (dump_file, "sum:%" PRId64 |
260 " times:"HOST_WIDEST_INT_PRINT_DEC, | 281 " times:%" PRId64, |
261 (HOST_WIDEST_INT) hist->hvalue.counters[0], | 282 (int64_t) hist->hvalue.counters[0], |
262 (HOST_WIDEST_INT) hist->hvalue.counters[1]); | 283 (int64_t) hist->hvalue.counters[1]); |
263 } | 284 } |
264 fprintf (dump_file, ".\n"); | 285 fprintf (dump_file, ".\n"); |
265 break; | 286 break; |
266 | 287 |
267 case HIST_TYPE_IOR: | 288 case HIST_TYPE_IOR: |
268 fprintf (dump_file, "IOR value "); | 289 fprintf (dump_file, "IOR value "); |
269 if (hist->hvalue.counters) | 290 if (hist->hvalue.counters) |
270 { | 291 { |
271 fprintf (dump_file, "ior:"HOST_WIDEST_INT_PRINT_DEC, | 292 fprintf (dump_file, "ior:%" PRId64, |
272 (HOST_WIDEST_INT) hist->hvalue.counters[0]); | 293 (int64_t) hist->hvalue.counters[0]); |
273 } | 294 } |
274 fprintf (dump_file, ".\n"); | 295 fprintf (dump_file, ".\n"); |
275 break; | 296 break; |
276 | 297 |
277 case HIST_TYPE_CONST_DELTA: | |
278 fprintf (dump_file, "Constant delta "); | |
279 if (hist->hvalue.counters) | |
280 { | |
281 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC | |
282 " match:"HOST_WIDEST_INT_PRINT_DEC | |
283 " wrong:"HOST_WIDEST_INT_PRINT_DEC, | |
284 (HOST_WIDEST_INT) hist->hvalue.counters[0], | |
285 (HOST_WIDEST_INT) hist->hvalue.counters[1], | |
286 (HOST_WIDEST_INT) hist->hvalue.counters[2]); | |
287 } | |
288 fprintf (dump_file, ".\n"); | |
289 break; | |
290 case HIST_TYPE_INDIR_CALL: | 298 case HIST_TYPE_INDIR_CALL: |
291 fprintf (dump_file, "Indirect call "); | 299 fprintf (dump_file, "Indirect call "); |
292 if (hist->hvalue.counters) | 300 if (hist->hvalue.counters) |
293 { | 301 { |
294 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC | 302 fprintf (dump_file, "value:%" PRId64 |
295 " match:"HOST_WIDEST_INT_PRINT_DEC | 303 " match:%" PRId64 |
296 " all:"HOST_WIDEST_INT_PRINT_DEC, | 304 " all:%" PRId64, |
297 (HOST_WIDEST_INT) hist->hvalue.counters[0], | 305 (int64_t) hist->hvalue.counters[0], |
298 (HOST_WIDEST_INT) hist->hvalue.counters[1], | 306 (int64_t) hist->hvalue.counters[1], |
299 (HOST_WIDEST_INT) hist->hvalue.counters[2]); | 307 (int64_t) hist->hvalue.counters[2]); |
300 } | 308 } |
301 fprintf (dump_file, ".\n"); | 309 fprintf (dump_file, ".\n"); |
302 break; | 310 break; |
311 case HIST_TYPE_TIME_PROFILE: | |
312 fprintf (dump_file, "Time profile "); | |
313 if (hist->hvalue.counters) | |
314 { | |
315 fprintf (dump_file, "time:%" PRId64, | |
316 (int64_t) hist->hvalue.counters[0]); | |
317 } | |
318 fprintf (dump_file, ".\n"); | |
319 break; | |
320 case HIST_TYPE_INDIR_CALL_TOPN: | |
321 fprintf (dump_file, "Indirect call topn "); | |
322 if (hist->hvalue.counters) | |
323 { | |
324 int i; | |
325 | |
326 fprintf (dump_file, "accu:%" PRId64, hist->hvalue.counters[0]); | |
327 for (i = 1; i < (GCOV_ICALL_TOPN_VAL << 2); i += 2) | |
328 { | |
329 fprintf (dump_file, " target:%" PRId64 " value:%" PRId64, | |
330 (int64_t) hist->hvalue.counters[i], | |
331 (int64_t) hist->hvalue.counters[i+1]); | |
332 } | |
333 } | |
334 fprintf (dump_file, ".\n"); | |
335 break; | |
336 case HIST_TYPE_MAX: | |
337 gcc_unreachable (); | |
303 } | 338 } |
304 } | 339 } |
305 | 340 |
341 /* Dump information about HIST to DUMP_FILE. */ | |
342 | |
343 void | |
344 stream_out_histogram_value (struct output_block *ob, histogram_value hist) | |
345 { | |
346 struct bitpack_d bp; | |
347 unsigned int i; | |
348 | |
349 bp = bitpack_create (ob->main_stream); | |
350 bp_pack_enum (&bp, hist_type, HIST_TYPE_MAX, hist->type); | |
351 bp_pack_value (&bp, hist->hvalue.next != NULL, 1); | |
352 streamer_write_bitpack (&bp); | |
353 switch (hist->type) | |
354 { | |
355 case HIST_TYPE_INTERVAL: | |
356 streamer_write_hwi (ob, hist->hdata.intvl.int_start); | |
357 streamer_write_uhwi (ob, hist->hdata.intvl.steps); | |
358 break; | |
359 default: | |
360 break; | |
361 } | |
362 for (i = 0; i < hist->n_counters; i++) | |
363 { | |
364 /* When user uses an unsigned type with a big value, constant converted | |
365 to gcov_type (a signed type) can be negative. */ | |
366 gcov_type value = hist->hvalue.counters[i]; | |
367 if (hist->type == HIST_TYPE_SINGLE_VALUE && i == 0) | |
368 ; | |
369 else | |
370 gcc_assert (value >= 0); | |
371 | |
372 streamer_write_gcov_count (ob, value); | |
373 } | |
374 if (hist->hvalue.next) | |
375 stream_out_histogram_value (ob, hist->hvalue.next); | |
376 } | |
377 | |
378 /* Dump information about HIST to DUMP_FILE. */ | |
379 | |
380 void | |
381 stream_in_histogram_value (struct lto_input_block *ib, gimple *stmt) | |
382 { | |
383 enum hist_type type; | |
384 unsigned int ncounters = 0; | |
385 struct bitpack_d bp; | |
386 unsigned int i; | |
387 histogram_value new_val; | |
388 bool next; | |
389 histogram_value *next_p = NULL; | |
390 | |
391 do | |
392 { | |
393 bp = streamer_read_bitpack (ib); | |
394 type = bp_unpack_enum (&bp, hist_type, HIST_TYPE_MAX); | |
395 next = bp_unpack_value (&bp, 1); | |
396 new_val = gimple_alloc_histogram_value (cfun, type, stmt, NULL); | |
397 switch (type) | |
398 { | |
399 case HIST_TYPE_INTERVAL: | |
400 new_val->hdata.intvl.int_start = streamer_read_hwi (ib); | |
401 new_val->hdata.intvl.steps = streamer_read_uhwi (ib); | |
402 ncounters = new_val->hdata.intvl.steps + 2; | |
403 break; | |
404 | |
405 case HIST_TYPE_POW2: | |
406 case HIST_TYPE_AVERAGE: | |
407 ncounters = 2; | |
408 break; | |
409 | |
410 case HIST_TYPE_SINGLE_VALUE: | |
411 case HIST_TYPE_INDIR_CALL: | |
412 ncounters = 3; | |
413 break; | |
414 | |
415 case HIST_TYPE_IOR: | |
416 case HIST_TYPE_TIME_PROFILE: | |
417 ncounters = 1; | |
418 break; | |
419 | |
420 case HIST_TYPE_INDIR_CALL_TOPN: | |
421 ncounters = (GCOV_ICALL_TOPN_VAL << 2) + 1; | |
422 break; | |
423 | |
424 case HIST_TYPE_MAX: | |
425 gcc_unreachable (); | |
426 } | |
427 new_val->hvalue.counters = XNEWVAR (gcov_type, sizeof (*new_val->hvalue.counters) * ncounters); | |
428 new_val->n_counters = ncounters; | |
429 for (i = 0; i < ncounters; i++) | |
430 new_val->hvalue.counters[i] = streamer_read_gcov_count (ib); | |
431 if (!next_p) | |
432 gimple_add_histogram_value (cfun, stmt, new_val); | |
433 else | |
434 *next_p = new_val; | |
435 next_p = &new_val->hvalue.next; | |
436 } | |
437 while (next); | |
438 } | |
439 | |
306 /* Dump all histograms attached to STMT to DUMP_FILE. */ | 440 /* Dump all histograms attached to STMT to DUMP_FILE. */ |
307 | 441 |
308 void | 442 void |
309 dump_histograms_for_stmt (struct function *fun, FILE *dump_file, gimple stmt) | 443 dump_histograms_for_stmt (struct function *fun, FILE *dump_file, gimple *stmt) |
310 { | 444 { |
311 histogram_value hist; | 445 histogram_value hist; |
312 for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next) | 446 for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next) |
313 dump_histogram_value (dump_file, hist); | 447 dump_histogram_value (dump_file, hist); |
314 } | 448 } |
315 | 449 |
316 /* Remove all histograms associated with STMT. */ | 450 /* Remove all histograms associated with STMT. */ |
317 | 451 |
318 void | 452 void |
319 gimple_remove_stmt_histograms (struct function *fun, gimple stmt) | 453 gimple_remove_stmt_histograms (struct function *fun, gimple *stmt) |
320 { | 454 { |
321 histogram_value val; | 455 histogram_value val; |
322 while ((val = gimple_histogram_value (fun, stmt)) != NULL) | 456 while ((val = gimple_histogram_value (fun, stmt)) != NULL) |
323 gimple_remove_histogram_value (fun, stmt, val); | 457 gimple_remove_histogram_value (fun, stmt, val); |
324 } | 458 } |
325 | 459 |
326 /* Duplicate all histograms associates with OSTMT to STMT. */ | 460 /* Duplicate all histograms associates with OSTMT to STMT. */ |
327 | 461 |
328 void | 462 void |
329 gimple_duplicate_stmt_histograms (struct function *fun, gimple stmt, | 463 gimple_duplicate_stmt_histograms (struct function *fun, gimple *stmt, |
330 struct function *ofun, gimple ostmt) | 464 struct function *ofun, gimple *ostmt) |
331 { | 465 { |
332 histogram_value val; | 466 histogram_value val; |
333 for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next) | 467 for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next) |
334 { | 468 { |
335 histogram_value new_val = gimple_alloc_histogram_value (fun, val->type, NULL, NULL); | 469 histogram_value new_val = gimple_alloc_histogram_value (fun, val->type, NULL, NULL); |
339 memcpy (new_val->hvalue.counters, val->hvalue.counters, sizeof (*new_val->hvalue.counters) * new_val->n_counters); | 473 memcpy (new_val->hvalue.counters, val->hvalue.counters, sizeof (*new_val->hvalue.counters) * new_val->n_counters); |
340 gimple_add_histogram_value (fun, stmt, new_val); | 474 gimple_add_histogram_value (fun, stmt, new_val); |
341 } | 475 } |
342 } | 476 } |
343 | 477 |
344 | |
345 /* Move all histograms associated with OSTMT to STMT. */ | 478 /* Move all histograms associated with OSTMT to STMT. */ |
346 | 479 |
347 void | 480 void |
348 gimple_move_stmt_histograms (struct function *fun, gimple stmt, gimple ostmt) | 481 gimple_move_stmt_histograms (struct function *fun, gimple *stmt, gimple *ostmt) |
349 { | 482 { |
350 histogram_value val = gimple_histogram_value (fun, ostmt); | 483 histogram_value val = gimple_histogram_value (fun, ostmt); |
351 if (val) | 484 if (val) |
352 { | 485 { |
353 /* The following three statements can't be reordered, | 486 /* The following three statements can't be reordered, |
366 walk verify that it was reached via statement walk. */ | 499 walk verify that it was reached via statement walk. */ |
367 | 500 |
368 static int | 501 static int |
369 visit_hist (void **slot, void *data) | 502 visit_hist (void **slot, void *data) |
370 { | 503 { |
371 struct pointer_set_t *visited = (struct pointer_set_t *) data; | 504 hash_set<histogram_value> *visited = (hash_set<histogram_value> *) data; |
372 histogram_value hist = *(histogram_value *) slot; | 505 histogram_value hist = *(histogram_value *) slot; |
373 if (!pointer_set_contains (visited, hist)) | 506 |
507 if (!visited->contains (hist) | |
508 && hist->type != HIST_TYPE_TIME_PROFILE) | |
374 { | 509 { |
375 error ("dead histogram"); | 510 error ("dead histogram"); |
376 dump_histogram_value (stderr, hist); | 511 dump_histogram_value (stderr, hist); |
377 debug_gimple_stmt (hist->hvalue.stmt); | 512 debug_gimple_stmt (hist->hvalue.stmt); |
378 error_found = true; | 513 error_found = true; |
379 } | 514 } |
380 return 1; | 515 return 1; |
381 } | 516 } |
382 | 517 |
383 | |
384 /* Verify sanity of the histograms. */ | 518 /* Verify sanity of the histograms. */ |
385 | 519 |
386 DEBUG_FUNCTION void | 520 DEBUG_FUNCTION void |
387 verify_histograms (void) | 521 verify_histograms (void) |
388 { | 522 { |
389 basic_block bb; | 523 basic_block bb; |
390 gimple_stmt_iterator gsi; | 524 gimple_stmt_iterator gsi; |
391 histogram_value hist; | 525 histogram_value hist; |
392 struct pointer_set_t *visited_hists; | |
393 | 526 |
394 error_found = false; | 527 error_found = false; |
395 visited_hists = pointer_set_create (); | 528 hash_set<histogram_value> visited_hists; |
396 FOR_EACH_BB (bb) | 529 FOR_EACH_BB_FN (bb, cfun) |
397 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | 530 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
398 { | 531 { |
399 gimple stmt = gsi_stmt (gsi); | 532 gimple *stmt = gsi_stmt (gsi); |
400 | 533 |
401 for (hist = gimple_histogram_value (cfun, stmt); hist; | 534 for (hist = gimple_histogram_value (cfun, stmt); hist; |
402 hist = hist->hvalue.next) | 535 hist = hist->hvalue.next) |
403 { | 536 { |
404 if (hist->hvalue.stmt != stmt) | 537 if (hist->hvalue.stmt != stmt) |
407 "the statement it is associated with"); | 540 "the statement it is associated with"); |
408 debug_gimple_stmt (stmt); | 541 debug_gimple_stmt (stmt); |
409 dump_histogram_value (stderr, hist); | 542 dump_histogram_value (stderr, hist); |
410 error_found = true; | 543 error_found = true; |
411 } | 544 } |
412 pointer_set_insert (visited_hists, hist); | 545 visited_hists.add (hist); |
413 } | 546 } |
414 } | 547 } |
415 if (VALUE_HISTOGRAMS (cfun)) | 548 if (VALUE_HISTOGRAMS (cfun)) |
416 htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, visited_hists); | 549 htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, &visited_hists); |
417 pointer_set_destroy (visited_hists); | |
418 if (error_found) | 550 if (error_found) |
419 internal_error ("verify_histograms failed"); | 551 internal_error ("verify_histograms failed"); |
420 } | 552 } |
421 | 553 |
422 /* Helper function for verify_histograms. For each histogram reachable via htab | 554 /* Helper function for verify_histograms. For each histogram reachable via htab |
425 static int | 557 static int |
426 free_hist (void **slot, void *data ATTRIBUTE_UNUSED) | 558 free_hist (void **slot, void *data ATTRIBUTE_UNUSED) |
427 { | 559 { |
428 histogram_value hist = *(histogram_value *) slot; | 560 histogram_value hist = *(histogram_value *) slot; |
429 free (hist->hvalue.counters); | 561 free (hist->hvalue.counters); |
430 #ifdef ENABLE_CHECKING | |
431 memset (hist, 0xab, sizeof (*hist)); | |
432 #endif | |
433 free (hist); | 562 free (hist); |
434 return 1; | 563 return 1; |
435 } | 564 } |
436 | 565 |
437 void | 566 void |
438 free_histograms (void) | 567 free_histograms (struct function *fn) |
439 { | 568 { |
440 if (VALUE_HISTOGRAMS (cfun)) | 569 if (VALUE_HISTOGRAMS (fn)) |
441 { | 570 { |
442 htab_traverse (VALUE_HISTOGRAMS (cfun), free_hist, NULL); | 571 htab_traverse (VALUE_HISTOGRAMS (fn), free_hist, NULL); |
443 htab_delete (VALUE_HISTOGRAMS (cfun)); | 572 htab_delete (VALUE_HISTOGRAMS (fn)); |
444 VALUE_HISTOGRAMS (cfun) = NULL; | 573 VALUE_HISTOGRAMS (fn) = NULL; |
445 } | 574 } |
446 } | 575 } |
447 | |
448 | 576 |
449 /* The overall number of invocations of the counter should match | 577 /* The overall number of invocations of the counter should match |
450 execution count of basic block. Report it as error rather than | 578 execution count of basic block. Report it as error rather than |
451 internal error as it might mean that user has misused the profile | 579 internal error as it might mean that user has misused the profile |
452 somehow. */ | 580 somehow. */ |
453 | 581 |
454 static bool | 582 static bool |
455 check_counter (gimple stmt, const char * name, | 583 check_counter (gimple *stmt, const char * name, |
456 gcov_type *count, gcov_type *all, gcov_type bb_count) | 584 gcov_type *count, gcov_type *all, profile_count bb_count_d) |
457 { | 585 { |
586 gcov_type bb_count = bb_count_d.to_gcov_type (); | |
458 if (*all != bb_count || *count > *all) | 587 if (*all != bb_count || *count > *all) |
459 { | 588 { |
460 location_t locus; | 589 location_t locus; |
461 locus = (stmt != NULL) | 590 locus = (stmt != NULL) |
462 ? gimple_location (stmt) | 591 ? gimple_location (stmt) |
463 : DECL_SOURCE_LOCATION (current_function_decl); | 592 : DECL_SOURCE_LOCATION (current_function_decl); |
464 if (flag_profile_correction) | 593 if (flag_profile_correction) |
465 { | 594 { |
466 inform (locus, "correcting inconsistent value profile: " | 595 if (dump_enabled_p ()) |
467 "%s profiler overall count (%d) does not match BB count " | 596 dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus, |
468 "(%d)", name, (int)*all, (int)bb_count); | 597 "correcting inconsistent value profile: %s " |
598 "profiler overall count (%d) does not match BB " | |
599 "count (%d)\n", name, (int)*all, (int)bb_count); | |
469 *all = bb_count; | 600 *all = bb_count; |
470 if (*count > *all) | 601 if (*count > *all) |
471 *count = *all; | 602 *count = *all; |
472 return false; | 603 return false; |
473 } | 604 } |
485 } | 616 } |
486 | 617 |
487 return false; | 618 return false; |
488 } | 619 } |
489 | 620 |
490 | |
491 /* GIMPLE based transformations. */ | 621 /* GIMPLE based transformations. */ |
492 | 622 |
493 bool | 623 bool |
494 gimple_value_profile_transformations (void) | 624 gimple_value_profile_transformations (void) |
495 { | 625 { |
496 basic_block bb; | 626 basic_block bb; |
497 gimple_stmt_iterator gsi; | 627 gimple_stmt_iterator gsi; |
498 bool changed = false; | 628 bool changed = false; |
499 | 629 |
500 FOR_EACH_BB (bb) | 630 /* Autofdo does its own transformations for indirect calls, |
631 and otherwise does not support value profiling. */ | |
632 if (flag_auto_profile) | |
633 return false; | |
634 | |
635 FOR_EACH_BB_FN (bb, cfun) | |
501 { | 636 { |
502 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | 637 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
503 { | 638 { |
504 gimple stmt = gsi_stmt (gsi); | 639 gimple *stmt = gsi_stmt (gsi); |
505 histogram_value th = gimple_histogram_value (cfun, stmt); | 640 histogram_value th = gimple_histogram_value (cfun, stmt); |
506 if (!th) | 641 if (!th) |
507 continue; | 642 continue; |
508 | 643 |
509 if (dump_file) | 644 if (dump_file) |
518 transformation is used when more than one is applicable. */ | 653 transformation is used when more than one is applicable. */ |
519 /* It is expected that any code added by the transformations | 654 /* It is expected that any code added by the transformations |
520 will be added before the current statement, and that the | 655 will be added before the current statement, and that the |
521 current statement remain valid (although possibly | 656 current statement remain valid (although possibly |
522 modified) upon return. */ | 657 modified) upon return. */ |
523 if (flag_value_profile_transformations | 658 if (gimple_mod_subtract_transform (&gsi) |
524 && (gimple_mod_subtract_transform (&gsi) | 659 || gimple_divmod_fixed_value_transform (&gsi) |
525 || gimple_divmod_fixed_value_transform (&gsi) | 660 || gimple_mod_pow2_value_transform (&gsi) |
526 || gimple_mod_pow2_value_transform (&gsi) | 661 || gimple_stringops_transform (&gsi) |
527 || gimple_stringops_transform (&gsi) | 662 || gimple_ic_transform (&gsi)) |
528 || gimple_ic_transform (stmt))) | |
529 { | 663 { |
530 stmt = gsi_stmt (gsi); | 664 stmt = gsi_stmt (gsi); |
531 changed = true; | 665 changed = true; |
532 /* Original statement may no longer be in the same block. */ | 666 /* Original statement may no longer be in the same block. */ |
533 if (bb != gimple_bb (stmt)) | 667 if (bb != gimple_bb (stmt)) |
545 } | 679 } |
546 | 680 |
547 return changed; | 681 return changed; |
548 } | 682 } |
549 | 683 |
550 | |
551 /* Generate code for transformation 1 (with parent gimple assignment | 684 /* Generate code for transformation 1 (with parent gimple assignment |
552 STMT and probability of taking the optimal path PROB, which is | 685 STMT and probability of taking the optimal path PROB, which is |
553 equivalent to COUNT/ALL within roundoff error). This generates the | 686 equivalent to COUNT/ALL within roundoff error). This generates the |
554 result into a temp and returns the temp; it does not replace or | 687 result into a temp and returns the temp; it does not replace or |
555 alter the original STMT. */ | 688 alter the original STMT. */ |
556 | 689 |
557 static tree | 690 static tree |
558 gimple_divmod_fixed_value (gimple stmt, tree value, int prob, gcov_type count, | 691 gimple_divmod_fixed_value (gassign *stmt, tree value, profile_probability prob, |
559 gcov_type all) | 692 gcov_type count, gcov_type all) |
560 { | 693 { |
561 gimple stmt1, stmt2, stmt3; | 694 gassign *stmt1, *stmt2; |
562 tree tmp0, tmp1, tmp2, tmpv; | 695 gcond *stmt3; |
563 gimple bb1end, bb2end, bb3end; | 696 tree tmp0, tmp1, tmp2; |
697 gimple *bb1end, *bb2end, *bb3end; | |
564 basic_block bb, bb2, bb3, bb4; | 698 basic_block bb, bb2, bb3, bb4; |
565 tree optype, op1, op2; | 699 tree optype, op1, op2; |
566 edge e12, e13, e23, e24, e34; | 700 edge e12, e13, e23, e24, e34; |
567 gimple_stmt_iterator gsi; | 701 gimple_stmt_iterator gsi; |
568 | 702 |
575 op2 = gimple_assign_rhs2 (stmt); | 709 op2 = gimple_assign_rhs2 (stmt); |
576 | 710 |
577 bb = gimple_bb (stmt); | 711 bb = gimple_bb (stmt); |
578 gsi = gsi_for_stmt (stmt); | 712 gsi = gsi_for_stmt (stmt); |
579 | 713 |
580 tmpv = create_tmp_reg (optype, "PROF"); | 714 tmp0 = make_temp_ssa_name (optype, NULL, "PROF"); |
581 tmp0 = make_ssa_name (tmpv, NULL); | 715 tmp1 = make_temp_ssa_name (optype, NULL, "PROF"); |
582 tmp1 = make_ssa_name (tmpv, NULL); | |
583 stmt1 = gimple_build_assign (tmp0, fold_convert (optype, value)); | 716 stmt1 = gimple_build_assign (tmp0, fold_convert (optype, value)); |
584 SSA_NAME_DEF_STMT (tmp0) = stmt1; | |
585 stmt2 = gimple_build_assign (tmp1, op2); | 717 stmt2 = gimple_build_assign (tmp1, op2); |
586 SSA_NAME_DEF_STMT (tmp1) = stmt2; | |
587 stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE); | 718 stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE); |
588 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); | 719 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); |
589 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); | 720 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); |
590 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); | 721 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); |
591 bb1end = stmt3; | 722 bb1end = stmt3; |
592 | 723 |
593 tmp2 = make_rename_temp (optype, "PROF"); | 724 tmp2 = create_tmp_reg (optype, "PROF"); |
594 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2, | 725 stmt1 = gimple_build_assign (tmp2, gimple_assign_rhs_code (stmt), op1, tmp0); |
595 op1, tmp0); | |
596 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); | 726 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); |
597 bb2end = stmt1; | 727 bb2end = stmt1; |
598 | 728 |
599 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2, | 729 stmt1 = gimple_build_assign (tmp2, gimple_assign_rhs_code (stmt), op1, op2); |
600 op1, op2); | |
601 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); | 730 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); |
602 bb3end = stmt1; | 731 bb3end = stmt1; |
603 | 732 |
604 /* Fix CFG. */ | 733 /* Fix CFG. */ |
605 /* Edge e23 connects bb2 to bb3, etc. */ | 734 /* Edge e23 connects bb2 to bb3, etc. */ |
606 e12 = split_block (bb, bb1end); | 735 e12 = split_block (bb, bb1end); |
607 bb2 = e12->dest; | 736 bb2 = e12->dest; |
608 bb2->count = count; | 737 bb2->count = profile_count::from_gcov_type (count); |
609 e23 = split_block (bb2, bb2end); | 738 e23 = split_block (bb2, bb2end); |
610 bb3 = e23->dest; | 739 bb3 = e23->dest; |
611 bb3->count = all - count; | 740 bb3->count = profile_count::from_gcov_type (all - count); |
612 e34 = split_block (bb3, bb3end); | 741 e34 = split_block (bb3, bb3end); |
613 bb4 = e34->dest; | 742 bb4 = e34->dest; |
614 bb4->count = all; | 743 bb4->count = profile_count::from_gcov_type (all); |
615 | 744 |
616 e12->flags &= ~EDGE_FALLTHRU; | 745 e12->flags &= ~EDGE_FALLTHRU; |
617 e12->flags |= EDGE_FALSE_VALUE; | 746 e12->flags |= EDGE_FALSE_VALUE; |
618 e12->probability = prob; | 747 e12->probability = prob; |
619 e12->count = count; | |
620 | 748 |
621 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE); | 749 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE); |
622 e13->probability = REG_BR_PROB_BASE - prob; | 750 e13->probability = prob.invert (); |
623 e13->count = all - count; | |
624 | 751 |
625 remove_edge (e23); | 752 remove_edge (e23); |
626 | 753 |
627 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU); | 754 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU); |
628 e24->probability = REG_BR_PROB_BASE; | 755 e24->probability = profile_probability::always (); |
629 e24->count = count; | 756 |
630 | 757 e34->probability = profile_probability::always (); |
631 e34->probability = REG_BR_PROB_BASE; | |
632 e34->count = all - count; | |
633 | 758 |
634 return tmp2; | 759 return tmp2; |
635 } | 760 } |
636 | |
637 | 761 |
638 /* Do transform 1) on INSN if applicable. */ | 762 /* Do transform 1) on INSN if applicable. */ |
639 | 763 |
640 static bool | 764 static bool |
641 gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si) | 765 gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si) |
642 { | 766 { |
643 histogram_value histogram; | 767 histogram_value histogram; |
644 enum tree_code code; | 768 enum tree_code code; |
645 gcov_type val, count, all; | 769 gcov_type val, count, all; |
646 tree result, value, tree_val; | 770 tree result, value, tree_val; |
647 gcov_type prob; | 771 profile_probability prob; |
648 gimple stmt; | 772 gassign *stmt; |
649 | 773 |
650 stmt = gsi_stmt (*si); | 774 stmt = dyn_cast <gassign *> (gsi_stmt (*si)); |
651 if (gimple_code (stmt) != GIMPLE_ASSIGN) | 775 if (!stmt) |
652 return false; | 776 return false; |
653 | 777 |
654 if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))) | 778 if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))) |
655 return false; | 779 return false; |
656 | 780 |
681 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count)) | 805 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count)) |
682 return false; | 806 return false; |
683 | 807 |
684 /* Compute probability of taking the optimal path. */ | 808 /* Compute probability of taking the optimal path. */ |
685 if (all > 0) | 809 if (all > 0) |
686 prob = (count * REG_BR_PROB_BASE + all / 2) / all; | 810 prob = profile_probability::probability_in_gcov_type (count, all); |
687 else | 811 else |
688 prob = 0; | 812 prob = profile_probability::never (); |
689 | 813 |
690 tree_val = build_int_cst_wide (get_gcov_type (), | 814 if (sizeof (gcov_type) == sizeof (HOST_WIDE_INT)) |
691 (unsigned HOST_WIDE_INT) val, | 815 tree_val = build_int_cst (get_gcov_type (), val); |
692 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1); | 816 else |
817 { | |
818 HOST_WIDE_INT a[2]; | |
819 a[0] = (unsigned HOST_WIDE_INT) val; | |
820 a[1] = val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1; | |
821 | |
822 tree_val = wide_int_to_tree (get_gcov_type (), wide_int::from_array (a, 2, | |
823 TYPE_PRECISION (get_gcov_type ()), false)); | |
824 } | |
693 result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all); | 825 result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all); |
694 | 826 |
695 if (dump_file) | 827 if (dump_file) |
696 { | 828 { |
697 fprintf (dump_file, "Div/mod by constant "); | 829 fprintf (dump_file, "Div/mod by constant "); |
710 | 842 |
711 /* Generate code for transformation 2 (with parent gimple assign STMT and | 843 /* Generate code for transformation 2 (with parent gimple assign STMT and |
712 probability of taking the optimal path PROB, which is equivalent to COUNT/ALL | 844 probability of taking the optimal path PROB, which is equivalent to COUNT/ALL |
713 within roundoff error). This generates the result into a temp and returns | 845 within roundoff error). This generates the result into a temp and returns |
714 the temp; it does not replace or alter the original STMT. */ | 846 the temp; it does not replace or alter the original STMT. */ |
847 | |
715 static tree | 848 static tree |
716 gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all) | 849 gimple_mod_pow2 (gassign *stmt, profile_probability prob, gcov_type count, gcov_type all) |
717 { | 850 { |
718 gimple stmt1, stmt2, stmt3, stmt4; | 851 gassign *stmt1, *stmt2, *stmt3; |
719 tree tmp2, tmp3, tmpv; | 852 gcond *stmt4; |
720 gimple bb1end, bb2end, bb3end; | 853 tree tmp2, tmp3; |
854 gimple *bb1end, *bb2end, *bb3end; | |
721 basic_block bb, bb2, bb3, bb4; | 855 basic_block bb, bb2, bb3, bb4; |
722 tree optype, op1, op2; | 856 tree optype, op1, op2; |
723 edge e12, e13, e23, e24, e34; | 857 edge e12, e13, e23, e24, e34; |
724 gimple_stmt_iterator gsi; | 858 gimple_stmt_iterator gsi; |
725 tree result; | 859 tree result; |
732 op2 = gimple_assign_rhs2 (stmt); | 866 op2 = gimple_assign_rhs2 (stmt); |
733 | 867 |
734 bb = gimple_bb (stmt); | 868 bb = gimple_bb (stmt); |
735 gsi = gsi_for_stmt (stmt); | 869 gsi = gsi_for_stmt (stmt); |
736 | 870 |
737 result = make_rename_temp (optype, "PROF"); | 871 result = create_tmp_reg (optype, "PROF"); |
738 tmpv = create_tmp_var (optype, "PROF"); | 872 tmp2 = make_temp_ssa_name (optype, NULL, "PROF"); |
739 tmp2 = make_ssa_name (tmpv, NULL); | 873 tmp3 = make_temp_ssa_name (optype, NULL, "PROF"); |
740 tmp3 = make_ssa_name (tmpv, NULL); | 874 stmt2 = gimple_build_assign (tmp2, PLUS_EXPR, op2, |
741 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2, | 875 build_int_cst (optype, -1)); |
742 build_int_cst (optype, -1)); | 876 stmt3 = gimple_build_assign (tmp3, BIT_AND_EXPR, tmp2, op2); |
743 SSA_NAME_DEF_STMT (tmp2) = stmt2; | |
744 stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2); | |
745 SSA_NAME_DEF_STMT (tmp3) = stmt3; | |
746 stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0), | 877 stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0), |
747 NULL_TREE, NULL_TREE); | 878 NULL_TREE, NULL_TREE); |
748 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); | 879 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); |
749 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); | 880 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); |
750 gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT); | 881 gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT); |
751 bb1end = stmt4; | 882 bb1end = stmt4; |
752 | 883 |
753 /* tmp2 == op2-1 inherited from previous block. */ | 884 /* tmp2 == op2-1 inherited from previous block. */ |
754 stmt1 = gimple_build_assign_with_ops (BIT_AND_EXPR, result, op1, tmp2); | 885 stmt1 = gimple_build_assign (result, BIT_AND_EXPR, op1, tmp2); |
755 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); | 886 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); |
756 bb2end = stmt1; | 887 bb2end = stmt1; |
757 | 888 |
758 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result, | 889 stmt1 = gimple_build_assign (result, gimple_assign_rhs_code (stmt), |
759 op1, op2); | 890 op1, op2); |
760 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); | 891 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); |
761 bb3end = stmt1; | 892 bb3end = stmt1; |
762 | 893 |
763 /* Fix CFG. */ | 894 /* Fix CFG. */ |
764 /* Edge e23 connects bb2 to bb3, etc. */ | 895 /* Edge e23 connects bb2 to bb3, etc. */ |
765 e12 = split_block (bb, bb1end); | 896 e12 = split_block (bb, bb1end); |
766 bb2 = e12->dest; | 897 bb2 = e12->dest; |
767 bb2->count = count; | 898 bb2->count = profile_count::from_gcov_type (count); |
768 e23 = split_block (bb2, bb2end); | 899 e23 = split_block (bb2, bb2end); |
769 bb3 = e23->dest; | 900 bb3 = e23->dest; |
770 bb3->count = all - count; | 901 bb3->count = profile_count::from_gcov_type (all - count); |
771 e34 = split_block (bb3, bb3end); | 902 e34 = split_block (bb3, bb3end); |
772 bb4 = e34->dest; | 903 bb4 = e34->dest; |
773 bb4->count = all; | 904 bb4->count = profile_count::from_gcov_type (all); |
774 | 905 |
775 e12->flags &= ~EDGE_FALLTHRU; | 906 e12->flags &= ~EDGE_FALLTHRU; |
776 e12->flags |= EDGE_FALSE_VALUE; | 907 e12->flags |= EDGE_FALSE_VALUE; |
777 e12->probability = prob; | 908 e12->probability = prob; |
778 e12->count = count; | |
779 | 909 |
780 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE); | 910 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE); |
781 e13->probability = REG_BR_PROB_BASE - prob; | 911 e13->probability = prob.invert (); |
782 e13->count = all - count; | |
783 | 912 |
784 remove_edge (e23); | 913 remove_edge (e23); |
785 | 914 |
786 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU); | 915 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU); |
787 e24->probability = REG_BR_PROB_BASE; | 916 e24->probability = profile_probability::always (); |
788 e24->count = count; | 917 |
789 | 918 e34->probability = profile_probability::always (); |
790 e34->probability = REG_BR_PROB_BASE; | |
791 e34->count = all - count; | |
792 | 919 |
793 return result; | 920 return result; |
794 } | 921 } |
795 | 922 |
796 /* Do transform 2) on INSN if applicable. */ | 923 /* Do transform 2) on INSN if applicable. */ |
924 | |
797 static bool | 925 static bool |
798 gimple_mod_pow2_value_transform (gimple_stmt_iterator *si) | 926 gimple_mod_pow2_value_transform (gimple_stmt_iterator *si) |
799 { | 927 { |
800 histogram_value histogram; | 928 histogram_value histogram; |
801 enum tree_code code; | 929 enum tree_code code; |
802 gcov_type count, wrong_values, all; | 930 gcov_type count, wrong_values, all; |
803 tree lhs_type, result, value; | 931 tree lhs_type, result, value; |
804 gcov_type prob; | 932 profile_probability prob; |
805 gimple stmt; | 933 gassign *stmt; |
806 | 934 |
807 stmt = gsi_stmt (*si); | 935 stmt = dyn_cast <gassign *> (gsi_stmt (*si)); |
808 if (gimple_code (stmt) != GIMPLE_ASSIGN) | 936 if (!stmt) |
809 return false; | 937 return false; |
810 | 938 |
811 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt)); | 939 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt)); |
812 if (!INTEGRAL_TYPE_P (lhs_type)) | 940 if (!INTEGRAL_TYPE_P (lhs_type)) |
813 return false; | 941 return false; |
844 | 972 |
845 if (check_counter (stmt, "pow2", &count, &all, gimple_bb (stmt)->count)) | 973 if (check_counter (stmt, "pow2", &count, &all, gimple_bb (stmt)->count)) |
846 return false; | 974 return false; |
847 | 975 |
848 if (all > 0) | 976 if (all > 0) |
849 prob = (count * REG_BR_PROB_BASE + all / 2) / all; | 977 prob = profile_probability::probability_in_gcov_type (count, all); |
850 else | 978 else |
851 prob = 0; | 979 prob = profile_probability::never (); |
852 | 980 |
853 result = gimple_mod_pow2 (stmt, prob, count, all); | 981 result = gimple_mod_pow2 (stmt, prob, count, all); |
854 | 982 |
855 gimple_assign_set_rhs_from_tree (si, result); | 983 gimple_assign_set_rhs_from_tree (si, result); |
856 update_stmt (gsi_stmt (*si)); | 984 update_stmt (gsi_stmt (*si)); |
866 result into a temp and returns the temp; it does not replace or alter | 994 result into a temp and returns the temp; it does not replace or alter |
867 the original STMT. */ | 995 the original STMT. */ |
868 /* FIXME: Generalize the interface to handle NCOUNTS > 1. */ | 996 /* FIXME: Generalize the interface to handle NCOUNTS > 1. */ |
869 | 997 |
870 static tree | 998 static tree |
871 gimple_mod_subtract (gimple stmt, int prob1, int prob2, int ncounts, | 999 gimple_mod_subtract (gassign *stmt, profile_probability prob1, |
1000 profile_probability prob2, int ncounts, | |
872 gcov_type count1, gcov_type count2, gcov_type all) | 1001 gcov_type count1, gcov_type count2, gcov_type all) |
873 { | 1002 { |
874 gimple stmt1, stmt2, stmt3; | 1003 gassign *stmt1; |
1004 gimple *stmt2; | |
1005 gcond *stmt3; | |
875 tree tmp1; | 1006 tree tmp1; |
876 gimple bb1end, bb2end = NULL, bb3end; | 1007 gimple *bb1end, *bb2end = NULL, *bb3end; |
877 basic_block bb, bb2, bb3, bb4; | 1008 basic_block bb, bb2, bb3, bb4; |
878 tree optype, op1, op2; | 1009 tree optype, op1, op2; |
879 edge e12, e23 = 0, e24, e34, e14; | 1010 edge e12, e23 = 0, e24, e34, e14; |
880 gimple_stmt_iterator gsi; | 1011 gimple_stmt_iterator gsi; |
881 tree result; | 1012 tree result; |
888 op2 = gimple_assign_rhs2 (stmt); | 1019 op2 = gimple_assign_rhs2 (stmt); |
889 | 1020 |
890 bb = gimple_bb (stmt); | 1021 bb = gimple_bb (stmt); |
891 gsi = gsi_for_stmt (stmt); | 1022 gsi = gsi_for_stmt (stmt); |
892 | 1023 |
893 result = make_rename_temp (optype, "PROF"); | 1024 result = create_tmp_reg (optype, "PROF"); |
894 tmp1 = make_ssa_name (create_tmp_var (optype, "PROF"), NULL); | 1025 tmp1 = make_temp_ssa_name (optype, NULL, "PROF"); |
895 stmt1 = gimple_build_assign (result, op1); | 1026 stmt1 = gimple_build_assign (result, op1); |
896 stmt2 = gimple_build_assign (tmp1, op2); | 1027 stmt2 = gimple_build_assign (tmp1, op2); |
897 SSA_NAME_DEF_STMT (tmp1) = stmt2; | |
898 stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE); | 1028 stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE); |
899 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); | 1029 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); |
900 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); | 1030 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); |
901 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); | 1031 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); |
902 bb1end = stmt3; | 1032 bb1end = stmt3; |
903 | 1033 |
904 if (ncounts) /* Assumed to be 0 or 1 */ | 1034 if (ncounts) /* Assumed to be 0 or 1 */ |
905 { | 1035 { |
906 stmt1 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, tmp1); | 1036 stmt1 = gimple_build_assign (result, MINUS_EXPR, result, tmp1); |
907 stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE); | 1037 stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE); |
908 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); | 1038 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); |
909 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); | 1039 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); |
910 bb2end = stmt2; | 1040 bb2end = stmt2; |
911 } | 1041 } |
912 | 1042 |
913 /* Fallback case. */ | 1043 /* Fallback case. */ |
914 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result, | 1044 stmt1 = gimple_build_assign (result, gimple_assign_rhs_code (stmt), |
915 result, tmp1); | 1045 result, tmp1); |
916 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); | 1046 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); |
917 bb3end = stmt1; | 1047 bb3end = stmt1; |
918 | 1048 |
919 /* Fix CFG. */ | 1049 /* Fix CFG. */ |
920 /* Edge e23 connects bb2 to bb3, etc. */ | 1050 /* Edge e23 connects bb2 to bb3, etc. */ |
921 /* However block 3 is optional; if it is not there, references | 1051 /* However block 3 is optional; if it is not there, references |
922 to 3 really refer to block 2. */ | 1052 to 3 really refer to block 2. */ |
923 e12 = split_block (bb, bb1end); | 1053 e12 = split_block (bb, bb1end); |
924 bb2 = e12->dest; | 1054 bb2 = e12->dest; |
925 bb2->count = all - count1; | 1055 bb2->count = profile_count::from_gcov_type (all - count1); |
926 | 1056 |
927 if (ncounts) /* Assumed to be 0 or 1. */ | 1057 if (ncounts) /* Assumed to be 0 or 1. */ |
928 { | 1058 { |
929 e23 = split_block (bb2, bb2end); | 1059 e23 = split_block (bb2, bb2end); |
930 bb3 = e23->dest; | 1060 bb3 = e23->dest; |
931 bb3->count = all - count1 - count2; | 1061 bb3->count = profile_count::from_gcov_type (all - count1 - count2); |
932 } | 1062 } |
933 | 1063 |
934 e34 = split_block (ncounts ? bb3 : bb2, bb3end); | 1064 e34 = split_block (ncounts ? bb3 : bb2, bb3end); |
935 bb4 = e34->dest; | 1065 bb4 = e34->dest; |
936 bb4->count = all; | 1066 bb4->count = profile_count::from_gcov_type (all); |
937 | 1067 |
938 e12->flags &= ~EDGE_FALLTHRU; | 1068 e12->flags &= ~EDGE_FALLTHRU; |
939 e12->flags |= EDGE_FALSE_VALUE; | 1069 e12->flags |= EDGE_FALSE_VALUE; |
940 e12->probability = REG_BR_PROB_BASE - prob1; | 1070 e12->probability = prob1.invert (); |
941 e12->count = all - count1; | |
942 | 1071 |
943 e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE); | 1072 e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE); |
944 e14->probability = prob1; | 1073 e14->probability = prob1; |
945 e14->count = count1; | |
946 | 1074 |
947 if (ncounts) /* Assumed to be 0 or 1. */ | 1075 if (ncounts) /* Assumed to be 0 or 1. */ |
948 { | 1076 { |
949 e23->flags &= ~EDGE_FALLTHRU; | 1077 e23->flags &= ~EDGE_FALLTHRU; |
950 e23->flags |= EDGE_FALSE_VALUE; | 1078 e23->flags |= EDGE_FALSE_VALUE; |
951 e23->count = all - count1 - count2; | 1079 e23->probability = prob2.invert (); |
952 e23->probability = REG_BR_PROB_BASE - prob2; | |
953 | 1080 |
954 e24 = make_edge (bb2, bb4, EDGE_TRUE_VALUE); | 1081 e24 = make_edge (bb2, bb4, EDGE_TRUE_VALUE); |
955 e24->probability = prob2; | 1082 e24->probability = prob2; |
956 e24->count = count2; | 1083 } |
957 } | 1084 |
958 | 1085 e34->probability = profile_probability::always (); |
959 e34->probability = REG_BR_PROB_BASE; | |
960 e34->count = all - count1 - count2; | |
961 | 1086 |
962 return result; | 1087 return result; |
963 } | 1088 } |
964 | |
965 | 1089 |
966 /* Do transforms 3) and 4) on the statement pointed-to by SI if applicable. */ | 1090 /* Do transforms 3) and 4) on the statement pointed-to by SI if applicable. */ |
967 | 1091 |
968 static bool | 1092 static bool |
969 gimple_mod_subtract_transform (gimple_stmt_iterator *si) | 1093 gimple_mod_subtract_transform (gimple_stmt_iterator *si) |
970 { | 1094 { |
971 histogram_value histogram; | 1095 histogram_value histogram; |
972 enum tree_code code; | 1096 enum tree_code code; |
973 gcov_type count, wrong_values, all; | 1097 gcov_type count, wrong_values, all; |
974 tree lhs_type, result; | 1098 tree lhs_type, result; |
975 gcov_type prob1, prob2; | 1099 profile_probability prob1, prob2; |
976 unsigned int i, steps; | 1100 unsigned int i, steps; |
977 gcov_type count1, count2; | 1101 gcov_type count1, count2; |
978 gimple stmt; | 1102 gassign *stmt; |
979 | 1103 stmt = dyn_cast <gassign *> (gsi_stmt (*si)); |
980 stmt = gsi_stmt (*si); | 1104 if (!stmt) |
981 if (gimple_code (stmt) != GIMPLE_ASSIGN) | |
982 return false; | 1105 return false; |
983 | 1106 |
984 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt)); | 1107 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt)); |
985 if (!INTEGRAL_TYPE_P (lhs_type)) | 1108 if (!INTEGRAL_TYPE_P (lhs_type)) |
986 return false; | 1109 return false; |
1039 } | 1162 } |
1040 | 1163 |
1041 /* Compute probability of taking the optimal path(s). */ | 1164 /* Compute probability of taking the optimal path(s). */ |
1042 if (all > 0) | 1165 if (all > 0) |
1043 { | 1166 { |
1044 prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all; | 1167 prob1 = profile_probability::probability_in_gcov_type (count1, all); |
1045 prob2 = (count2 * REG_BR_PROB_BASE + all / 2) / all; | 1168 prob2 = profile_probability::probability_in_gcov_type (count2, all); |
1046 } | 1169 } |
1047 else | 1170 else |
1048 { | 1171 { |
1049 prob1 = prob2 = 0; | 1172 prob1 = prob2 = profile_probability::never (); |
1050 } | 1173 } |
1051 | 1174 |
1052 /* In practice, "steps" is always 2. This interface reflects this, | 1175 /* In practice, "steps" is always 2. This interface reflects this, |
1053 and will need to be changed if "steps" can change. */ | 1176 and will need to be changed if "steps" can change. */ |
1054 result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all); | 1177 result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all); |
1057 update_stmt (gsi_stmt (*si)); | 1180 update_stmt (gsi_stmt (*si)); |
1058 | 1181 |
1059 return true; | 1182 return true; |
1060 } | 1183 } |
1061 | 1184 |
1062 static struct cgraph_node** pid_map = NULL; | 1185 typedef int_hash <unsigned int, 0, UINT_MAX> profile_id_hash; |
1063 | 1186 |
1064 /* Initialize map of pids (pid -> cgraph node) */ | 1187 static hash_map<profile_id_hash, cgraph_node *> *cgraph_node_map = 0; |
1065 | 1188 |
1066 static void | 1189 /* Returns true if node graph is initialized. This |
1067 init_pid_map (void) | 1190 is used to test if profile_id has been created |
1191 for cgraph_nodes. */ | |
1192 | |
1193 bool | |
1194 coverage_node_map_initialized_p (void) | |
1195 { | |
1196 return cgraph_node_map != 0; | |
1197 } | |
1198 | |
1199 /* Initialize map from PROFILE_ID to CGRAPH_NODE. | |
1200 When LOCAL is true, the PROFILE_IDs are computed. when it is false we assume | |
1201 that the PROFILE_IDs was already assigned. */ | |
1202 | |
1203 void | |
1204 init_node_map (bool local) | |
1068 { | 1205 { |
1069 struct cgraph_node *n; | 1206 struct cgraph_node *n; |
1070 | 1207 cgraph_node_map = new hash_map<profile_id_hash, cgraph_node *>; |
1071 if (pid_map != NULL) | 1208 |
1072 return; | 1209 FOR_EACH_DEFINED_FUNCTION (n) |
1073 | 1210 if (n->has_gimple_body_p ()) |
1074 pid_map = XCNEWVEC (struct cgraph_node*, cgraph_max_pid); | 1211 { |
1075 | 1212 cgraph_node **val; |
1076 for (n = cgraph_nodes; n; n = n->next) | 1213 if (local) |
1077 { | 1214 { |
1078 if (n->pid != -1) | 1215 n->profile_id = coverage_compute_profile_id (n); |
1079 pid_map [n->pid] = n; | 1216 while ((val = cgraph_node_map->get (n->profile_id)) |
1080 } | 1217 || !n->profile_id) |
1218 { | |
1219 if (dump_file) | |
1220 fprintf (dump_file, "Local profile-id %i conflict" | |
1221 " with nodes %s %s\n", | |
1222 n->profile_id, | |
1223 n->dump_name (), | |
1224 (*val)->dump_name ()); | |
1225 n->profile_id = (n->profile_id + 1) & 0x7fffffff; | |
1226 } | |
1227 } | |
1228 else if (!n->profile_id) | |
1229 { | |
1230 if (dump_file) | |
1231 fprintf (dump_file, | |
1232 "Node %s has no profile-id" | |
1233 " (profile feedback missing?)\n", | |
1234 n->dump_name ()); | |
1235 continue; | |
1236 } | |
1237 else if ((val = cgraph_node_map->get (n->profile_id))) | |
1238 { | |
1239 if (dump_file) | |
1240 fprintf (dump_file, | |
1241 "Node %s has IP profile-id %i conflict. " | |
1242 "Giving up.\n", | |
1243 n->dump_name (), n->profile_id); | |
1244 *val = NULL; | |
1245 continue; | |
1246 } | |
1247 cgraph_node_map->put (n->profile_id, n); | |
1248 } | |
1249 } | |
1250 | |
1251 /* Delete the CGRAPH_NODE_MAP. */ | |
1252 | |
1253 void | |
1254 del_node_map (void) | |
1255 { | |
1256 delete cgraph_node_map; | |
1081 } | 1257 } |
1082 | 1258 |
1083 /* Return cgraph node for function with pid */ | 1259 /* Return cgraph node for function with pid */ |
1084 | 1260 |
1085 static inline struct cgraph_node* | 1261 struct cgraph_node* |
1086 find_func_by_pid (int pid) | 1262 find_func_by_profile_id (int profile_id) |
1087 { | 1263 { |
1088 init_pid_map (); | 1264 cgraph_node **val = cgraph_node_map->get (profile_id); |
1089 | 1265 if (val) |
1090 return pid_map [pid]; | 1266 return *val; |
1267 else | |
1268 return NULL; | |
1269 } | |
1270 | |
1271 /* Perform sanity check on the indirect call target. Due to race conditions, | |
1272 false function target may be attributed to an indirect call site. If the | |
1273 call expression type mismatches with the target function's type, expand_call | |
1274 may ICE. Here we only do very minimal sanity check just to make compiler happy. | |
1275 Returns true if TARGET is considered ok for call CALL_STMT. */ | |
1276 | |
1277 bool | |
1278 check_ic_target (gcall *call_stmt, struct cgraph_node *target) | |
1279 { | |
1280 location_t locus; | |
1281 if (gimple_check_call_matching_types (call_stmt, target->decl, true)) | |
1282 return true; | |
1283 | |
1284 locus = gimple_location (call_stmt); | |
1285 if (dump_enabled_p ()) | |
1286 dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus, | |
1287 "Skipping target %s with mismatching types for icall\n", | |
1288 target->name ()); | |
1289 return false; | |
1091 } | 1290 } |
1092 | 1291 |
1093 /* Do transformation | 1292 /* Do transformation |
1094 | 1293 |
1095 if (actual_callee_address == address_of_most_common_function/method) | 1294 if (actual_callee_address == address_of_most_common_function/method) |
1096 do direct call | 1295 do direct call |
1097 else | 1296 else |
1098 old call | 1297 old call |
1099 */ | 1298 */ |
1100 | 1299 |
1101 static gimple | 1300 gcall * |
1102 gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call, | 1301 gimple_ic (gcall *icall_stmt, struct cgraph_node *direct_call, |
1103 int prob, gcov_type count, gcov_type all) | 1302 profile_probability prob, profile_count count, profile_count all) |
1104 { | 1303 { |
1105 gimple dcall_stmt, load_stmt, cond_stmt; | 1304 gcall *dcall_stmt; |
1106 tree tmp0, tmp1, tmpv, tmp; | 1305 gassign *load_stmt; |
1107 basic_block cond_bb, dcall_bb, icall_bb, join_bb; | 1306 gcond *cond_stmt; |
1307 gcall *iretbnd_stmt = NULL; | |
1308 tree tmp0, tmp1, tmp; | |
1309 basic_block cond_bb, dcall_bb, icall_bb, join_bb = NULL; | |
1108 tree optype = build_pointer_type (void_type_node); | 1310 tree optype = build_pointer_type (void_type_node); |
1109 edge e_cd, e_ci, e_di, e_dj, e_ij; | 1311 edge e_cd, e_ci, e_di, e_dj = NULL, e_ij; |
1110 gimple_stmt_iterator gsi; | 1312 gimple_stmt_iterator gsi; |
1111 int lp_nr; | 1313 int lp_nr, dflags; |
1314 edge e_eh, e; | |
1315 edge_iterator ei; | |
1316 gimple_stmt_iterator psi; | |
1112 | 1317 |
1113 cond_bb = gimple_bb (icall_stmt); | 1318 cond_bb = gimple_bb (icall_stmt); |
1114 gsi = gsi_for_stmt (icall_stmt); | 1319 gsi = gsi_for_stmt (icall_stmt); |
1115 | 1320 |
1116 tmpv = create_tmp_reg (optype, "PROF"); | 1321 if (gimple_call_with_bounds_p (icall_stmt) && gimple_call_lhs (icall_stmt)) |
1117 tmp0 = make_ssa_name (tmpv, NULL); | 1322 iretbnd_stmt = chkp_retbnd_call_by_val (gimple_call_lhs (icall_stmt)); |
1118 tmp1 = make_ssa_name (tmpv, NULL); | 1323 |
1324 tmp0 = make_temp_ssa_name (optype, NULL, "PROF"); | |
1325 tmp1 = make_temp_ssa_name (optype, NULL, "PROF"); | |
1119 tmp = unshare_expr (gimple_call_fn (icall_stmt)); | 1326 tmp = unshare_expr (gimple_call_fn (icall_stmt)); |
1120 load_stmt = gimple_build_assign (tmp0, tmp); | 1327 load_stmt = gimple_build_assign (tmp0, tmp); |
1121 SSA_NAME_DEF_STMT (tmp0) = load_stmt; | |
1122 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT); | 1328 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT); |
1123 | 1329 |
1124 tmp = fold_convert (optype, build_addr (direct_call->decl, | 1330 tmp = fold_convert (optype, build_addr (direct_call->decl)); |
1125 current_function_decl)); | |
1126 load_stmt = gimple_build_assign (tmp1, tmp); | 1331 load_stmt = gimple_build_assign (tmp1, tmp); |
1127 SSA_NAME_DEF_STMT (tmp1) = load_stmt; | |
1128 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT); | 1332 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT); |
1129 | 1333 |
1130 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE); | 1334 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE); |
1131 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); | 1335 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); |
1132 | 1336 |
1337 if (TREE_CODE (gimple_vdef (icall_stmt)) == SSA_NAME) | |
1338 { | |
1339 unlink_stmt_vdef (icall_stmt); | |
1340 release_ssa_name (gimple_vdef (icall_stmt)); | |
1341 } | |
1133 gimple_set_vdef (icall_stmt, NULL_TREE); | 1342 gimple_set_vdef (icall_stmt, NULL_TREE); |
1134 gimple_set_vuse (icall_stmt, NULL_TREE); | 1343 gimple_set_vuse (icall_stmt, NULL_TREE); |
1135 update_stmt (icall_stmt); | 1344 update_stmt (icall_stmt); |
1136 dcall_stmt = gimple_copy (icall_stmt); | 1345 dcall_stmt = as_a <gcall *> (gimple_copy (icall_stmt)); |
1137 gimple_call_set_fndecl (dcall_stmt, direct_call->decl); | 1346 gimple_call_set_fndecl (dcall_stmt, direct_call->decl); |
1347 dflags = flags_from_decl_or_type (direct_call->decl); | |
1348 if ((dflags & ECF_NORETURN) != 0 | |
1349 && should_remove_lhs_p (gimple_call_lhs (dcall_stmt))) | |
1350 gimple_call_set_lhs (dcall_stmt, NULL_TREE); | |
1138 gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT); | 1351 gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT); |
1139 | 1352 |
1140 /* Fix CFG. */ | 1353 /* Fix CFG. */ |
1141 /* Edge e_cd connects cond_bb to dcall_bb, etc; note the first letters. */ | 1354 /* Edge e_cd connects cond_bb to dcall_bb, etc; note the first letters. */ |
1142 e_cd = split_block (cond_bb, cond_stmt); | 1355 e_cd = split_block (cond_bb, cond_stmt); |
1151 if (!stmt_ends_bb_p (icall_stmt)) | 1364 if (!stmt_ends_bb_p (icall_stmt)) |
1152 e_ij = split_block (icall_bb, icall_stmt); | 1365 e_ij = split_block (icall_bb, icall_stmt); |
1153 else | 1366 else |
1154 { | 1367 { |
1155 e_ij = find_fallthru_edge (icall_bb->succs); | 1368 e_ij = find_fallthru_edge (icall_bb->succs); |
1156 e_ij->probability = REG_BR_PROB_BASE; | 1369 /* The indirect call might be noreturn. */ |
1157 e_ij->count = all - count; | 1370 if (e_ij != NULL) |
1158 e_ij = single_pred_edge (split_edge (e_ij)); | 1371 { |
1159 } | 1372 e_ij->probability = profile_probability::always (); |
1160 join_bb = e_ij->dest; | 1373 e_ij = single_pred_edge (split_edge (e_ij)); |
1161 join_bb->count = all; | 1374 } |
1375 } | |
1376 if (e_ij != NULL) | |
1377 { | |
1378 join_bb = e_ij->dest; | |
1379 join_bb->count = all; | |
1380 } | |
1162 | 1381 |
1163 e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE; | 1382 e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE; |
1164 e_cd->probability = prob; | 1383 e_cd->probability = prob; |
1165 e_cd->count = count; | |
1166 | 1384 |
1167 e_ci = make_edge (cond_bb, icall_bb, EDGE_FALSE_VALUE); | 1385 e_ci = make_edge (cond_bb, icall_bb, EDGE_FALSE_VALUE); |
1168 e_ci->probability = REG_BR_PROB_BASE - prob; | 1386 e_ci->probability = prob.invert (); |
1169 e_ci->count = all - count; | |
1170 | 1387 |
1171 remove_edge (e_di); | 1388 remove_edge (e_di); |
1172 | 1389 |
1173 e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU); | 1390 if (e_ij != NULL) |
1174 e_dj->probability = REG_BR_PROB_BASE; | 1391 { |
1175 e_dj->count = count; | 1392 if ((dflags & ECF_NORETURN) == 0) |
1176 | 1393 { |
1177 e_ij->probability = REG_BR_PROB_BASE; | 1394 e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU); |
1178 e_ij->count = all - count; | 1395 e_dj->probability = profile_probability::always (); |
1396 } | |
1397 e_ij->probability = profile_probability::always (); | |
1398 } | |
1179 | 1399 |
1180 /* Insert PHI node for the call result if necessary. */ | 1400 /* Insert PHI node for the call result if necessary. */ |
1181 if (gimple_call_lhs (icall_stmt) | 1401 if (gimple_call_lhs (icall_stmt) |
1182 && TREE_CODE (gimple_call_lhs (icall_stmt)) == SSA_NAME) | 1402 && TREE_CODE (gimple_call_lhs (icall_stmt)) == SSA_NAME |
1403 && (dflags & ECF_NORETURN) == 0) | |
1183 { | 1404 { |
1184 tree result = gimple_call_lhs (icall_stmt); | 1405 tree result = gimple_call_lhs (icall_stmt); |
1185 gimple phi = create_phi_node (result, join_bb); | 1406 gphi *phi = create_phi_node (result, join_bb); |
1186 SSA_NAME_DEF_STMT (result) = phi; | |
1187 gimple_call_set_lhs (icall_stmt, | 1407 gimple_call_set_lhs (icall_stmt, |
1188 make_ssa_name (SSA_NAME_VAR (result), icall_stmt)); | 1408 duplicate_ssa_name (result, icall_stmt)); |
1189 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION); | 1409 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION); |
1190 gimple_call_set_lhs (dcall_stmt, | 1410 gimple_call_set_lhs (dcall_stmt, |
1191 make_ssa_name (SSA_NAME_VAR (result), dcall_stmt)); | 1411 duplicate_ssa_name (result, dcall_stmt)); |
1192 add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION); | 1412 add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION); |
1413 | |
1414 /* If indirect call has following BUILT_IN_CHKP_BNDRET | |
1415 call then we need to make it's copy for the direct | |
1416 call. */ | |
1417 if (iretbnd_stmt) | |
1418 { | |
1419 if (gimple_call_lhs (iretbnd_stmt)) | |
1420 { | |
1421 gimple *copy; | |
1422 | |
1423 if (TREE_CODE (gimple_vdef (iretbnd_stmt)) == SSA_NAME) | |
1424 { | |
1425 unlink_stmt_vdef (iretbnd_stmt); | |
1426 release_ssa_name (gimple_vdef (iretbnd_stmt)); | |
1427 } | |
1428 gimple_set_vdef (iretbnd_stmt, NULL_TREE); | |
1429 gimple_set_vuse (iretbnd_stmt, NULL_TREE); | |
1430 update_stmt (iretbnd_stmt); | |
1431 | |
1432 result = gimple_call_lhs (iretbnd_stmt); | |
1433 phi = create_phi_node (result, join_bb); | |
1434 | |
1435 copy = gimple_copy (iretbnd_stmt); | |
1436 gimple_call_set_arg (copy, 0, | |
1437 gimple_call_lhs (dcall_stmt)); | |
1438 gimple_call_set_lhs (copy, duplicate_ssa_name (result, copy)); | |
1439 gsi_insert_on_edge (e_dj, copy); | |
1440 add_phi_arg (phi, gimple_call_lhs (copy), | |
1441 e_dj, UNKNOWN_LOCATION); | |
1442 | |
1443 gimple_call_set_arg (iretbnd_stmt, 0, | |
1444 gimple_call_lhs (icall_stmt)); | |
1445 gimple_call_set_lhs (iretbnd_stmt, | |
1446 duplicate_ssa_name (result, iretbnd_stmt)); | |
1447 psi = gsi_for_stmt (iretbnd_stmt); | |
1448 gsi_remove (&psi, false); | |
1449 gsi_insert_on_edge (e_ij, iretbnd_stmt); | |
1450 add_phi_arg (phi, gimple_call_lhs (iretbnd_stmt), | |
1451 e_ij, UNKNOWN_LOCATION); | |
1452 | |
1453 gsi_commit_one_edge_insert (e_dj, NULL); | |
1454 gsi_commit_one_edge_insert (e_ij, NULL); | |
1455 } | |
1456 else | |
1457 { | |
1458 psi = gsi_for_stmt (iretbnd_stmt); | |
1459 gsi_remove (&psi, true); | |
1460 } | |
1461 } | |
1193 } | 1462 } |
1194 | 1463 |
1195 /* Build an EH edge for the direct call if necessary. */ | 1464 /* Build an EH edge for the direct call if necessary. */ |
1196 lp_nr = lookup_stmt_eh_lp (icall_stmt); | 1465 lp_nr = lookup_stmt_eh_lp (icall_stmt); |
1197 if (lp_nr != 0 | 1466 if (lp_nr > 0 && stmt_could_throw_p (dcall_stmt)) |
1198 && stmt_could_throw_p (dcall_stmt)) | 1467 { |
1199 { | |
1200 edge e_eh, e; | |
1201 edge_iterator ei; | |
1202 gimple_stmt_iterator psi; | |
1203 | |
1204 add_stmt_to_eh_lp (dcall_stmt, lp_nr); | 1468 add_stmt_to_eh_lp (dcall_stmt, lp_nr); |
1205 FOR_EACH_EDGE (e_eh, ei, icall_bb->succs) | 1469 } |
1206 if (e_eh->flags & EDGE_EH) | 1470 |
1207 break; | 1471 FOR_EACH_EDGE (e_eh, ei, icall_bb->succs) |
1208 e = make_edge (dcall_bb, e_eh->dest, EDGE_EH); | 1472 if (e_eh->flags & (EDGE_EH | EDGE_ABNORMAL)) |
1209 for (psi = gsi_start_phis (e_eh->dest); | 1473 { |
1210 !gsi_end_p (psi); gsi_next (&psi)) | 1474 e = make_edge (dcall_bb, e_eh->dest, e_eh->flags); |
1211 { | 1475 e->probability = e_eh->probability; |
1212 gimple phi = gsi_stmt (psi); | 1476 for (gphi_iterator psi = gsi_start_phis (e_eh->dest); |
1213 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), | 1477 !gsi_end_p (psi); gsi_next (&psi)) |
1214 PHI_ARG_DEF_FROM_EDGE (phi, e_eh)); | 1478 { |
1215 } | 1479 gphi *phi = psi.phi (); |
1216 } | 1480 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), |
1217 | 1481 PHI_ARG_DEF_FROM_EDGE (phi, e_eh)); |
1482 } | |
1483 } | |
1484 if (!stmt_could_throw_p (dcall_stmt)) | |
1485 gimple_purge_dead_eh_edges (dcall_bb); | |
1218 return dcall_stmt; | 1486 return dcall_stmt; |
1219 } | 1487 } |
1220 | 1488 |
1221 /* | 1489 /* |
1222 For every checked indirect/virtual call determine if most common pid of | 1490 For every checked indirect/virtual call determine if most common pid of |
1223 function/class method has probability more than 50%. If yes modify code of | 1491 function/class method has probability more than 50%. If yes modify code of |
1224 this call to: | 1492 this call to: |
1225 */ | 1493 */ |
1226 | 1494 |
1227 static bool | 1495 static bool |
1228 gimple_ic_transform (gimple stmt) | 1496 gimple_ic_transform (gimple_stmt_iterator *gsi) |
1229 { | 1497 { |
1498 gcall *stmt; | |
1230 histogram_value histogram; | 1499 histogram_value histogram; |
1231 gcov_type val, count, all, bb_all; | 1500 gcov_type val, count, all, bb_all; |
1232 gcov_type prob; | |
1233 tree callee; | |
1234 gimple modify; | |
1235 struct cgraph_node *direct_call; | 1501 struct cgraph_node *direct_call; |
1236 | 1502 |
1237 if (gimple_code (stmt) != GIMPLE_CALL) | 1503 stmt = dyn_cast <gcall *> (gsi_stmt (*gsi)); |
1238 return false; | 1504 if (!stmt) |
1239 | 1505 return false; |
1240 callee = gimple_call_fn (stmt); | 1506 |
1241 | 1507 if (gimple_call_fndecl (stmt) != NULL_TREE) |
1242 if (TREE_CODE (callee) == FUNCTION_DECL) | 1508 return false; |
1509 | |
1510 if (gimple_call_internal_p (stmt)) | |
1243 return false; | 1511 return false; |
1244 | 1512 |
1245 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL); | 1513 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL); |
1246 if (!histogram) | 1514 if (!histogram) |
1247 return false; | 1515 return false; |
1248 | 1516 |
1249 val = histogram->hvalue.counters [0]; | 1517 val = histogram->hvalue.counters [0]; |
1250 count = histogram->hvalue.counters [1]; | 1518 count = histogram->hvalue.counters [1]; |
1251 all = histogram->hvalue.counters [2]; | 1519 all = histogram->hvalue.counters [2]; |
1252 gimple_remove_histogram_value (cfun, stmt, histogram); | 1520 |
1253 | 1521 bb_all = gimple_bb (stmt)->count.to_gcov_type (); |
1254 if (4 * count <= 3 * all) | |
1255 return false; | |
1256 | |
1257 bb_all = gimple_bb (stmt)->count; | |
1258 /* The order of CHECK_COUNTER calls is important - | 1522 /* The order of CHECK_COUNTER calls is important - |
1259 since check_counter can correct the third parameter | 1523 since check_counter can correct the third parameter |
1260 and we want to make count <= all <= bb_all. */ | 1524 and we want to make count <= all <= bb_all. */ |
1261 if ( check_counter (stmt, "ic", &all, &bb_all, bb_all) | 1525 if (check_counter (stmt, "ic", &all, &bb_all, gimple_bb (stmt)->count) |
1262 || check_counter (stmt, "ic", &count, &all, all)) | 1526 || check_counter (stmt, "ic", &count, &all, |
1263 return false; | 1527 profile_count::from_gcov_type (all))) |
1264 | 1528 { |
1265 if (all > 0) | 1529 gimple_remove_histogram_value (cfun, stmt, histogram); |
1266 prob = (count * REG_BR_PROB_BASE + all / 2) / all; | 1530 return false; |
1267 else | 1531 } |
1268 prob = 0; | 1532 |
1269 direct_call = find_func_by_pid ((int)val); | 1533 if (4 * count <= 3 * all) |
1534 return false; | |
1535 | |
1536 direct_call = find_func_by_profile_id ((int)val); | |
1270 | 1537 |
1271 if (direct_call == NULL) | 1538 if (direct_call == NULL) |
1272 return false; | 1539 { |
1273 | 1540 if (val) |
1274 modify = gimple_ic (stmt, direct_call, prob, count, all); | 1541 { |
1542 if (dump_file) | |
1543 { | |
1544 fprintf (dump_file, "Indirect call -> direct call from other module"); | |
1545 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM); | |
1546 fprintf (dump_file, "=> %i (will resolve only with LTO)\n", (int)val); | |
1547 } | |
1548 } | |
1549 return false; | |
1550 } | |
1551 | |
1552 if (!check_ic_target (stmt, direct_call)) | |
1553 { | |
1554 if (dump_file) | |
1555 { | |
1556 fprintf (dump_file, "Indirect call -> direct call "); | |
1557 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM); | |
1558 fprintf (dump_file, "=> "); | |
1559 print_generic_expr (dump_file, direct_call->decl, TDF_SLIM); | |
1560 fprintf (dump_file, " transformation skipped because of type mismatch"); | |
1561 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | |
1562 } | |
1563 gimple_remove_histogram_value (cfun, stmt, histogram); | |
1564 return false; | |
1565 } | |
1275 | 1566 |
1276 if (dump_file) | 1567 if (dump_file) |
1277 { | 1568 { |
1278 fprintf (dump_file, "Indirect call -> direct call "); | 1569 fprintf (dump_file, "Indirect call -> direct call "); |
1279 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM); | 1570 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM); |
1280 fprintf (dump_file, "=> "); | 1571 fprintf (dump_file, "=> "); |
1281 print_generic_expr (dump_file, direct_call->decl, TDF_SLIM); | 1572 print_generic_expr (dump_file, direct_call->decl, TDF_SLIM); |
1282 fprintf (dump_file, " transformation on insn "); | 1573 fprintf (dump_file, " transformation on insn postponned to ipa-profile"); |
1283 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | 1574 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); |
1284 fprintf (dump_file, " to "); | 1575 fprintf (dump_file, "hist->count %" PRId64 |
1285 print_gimple_stmt (dump_file, modify, 0, TDF_SLIM); | 1576 " hist->all %" PRId64"\n", count, all); |
1286 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC | |
1287 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count, all); | |
1288 } | 1577 } |
1289 | 1578 |
1290 return true; | 1579 return true; |
1291 } | 1580 } |
1292 | 1581 |
1293 /* Return true if the stringop CALL with FNDECL shall be profiled. | 1582 /* Return true if the stringop CALL shall be profiled. SIZE_ARG be |
1294 SIZE_ARG be set to the argument index for the size of the string | 1583 set to the argument index for the size of the string operation. */ |
1295 operation. | 1584 |
1296 */ | |
1297 static bool | 1585 static bool |
1298 interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg) | 1586 interesting_stringop_to_profile_p (gcall *call, int *size_arg) |
1299 { | 1587 { |
1300 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); | 1588 enum built_in_function fcode; |
1301 | 1589 |
1590 fcode = DECL_FUNCTION_CODE (gimple_call_fndecl (call)); | |
1302 if (fcode != BUILT_IN_MEMCPY && fcode != BUILT_IN_MEMPCPY | 1591 if (fcode != BUILT_IN_MEMCPY && fcode != BUILT_IN_MEMPCPY |
1303 && fcode != BUILT_IN_MEMSET && fcode != BUILT_IN_BZERO) | 1592 && fcode != BUILT_IN_MEMSET && fcode != BUILT_IN_BZERO) |
1304 return false; | 1593 return false; |
1305 | 1594 |
1306 switch (fcode) | 1595 switch (fcode) |
1321 default: | 1610 default: |
1322 gcc_unreachable (); | 1611 gcc_unreachable (); |
1323 } | 1612 } |
1324 } | 1613 } |
1325 | 1614 |
1326 /* Convert stringop (..., vcall_size) | 1615 /* Convert stringop (..., vcall_size) |
1327 into | 1616 into |
1328 if (vcall_size == icall_size) | 1617 if (vcall_size == icall_size) |
1329 stringop (..., icall_size); | 1618 stringop (..., icall_size); |
1330 else | 1619 else |
1331 stringop (..., vcall_size); | 1620 stringop (..., vcall_size); |
1332 assuming we'll propagate a true constant into ICALL_SIZE later. */ | 1621 assuming we'll propagate a true constant into ICALL_SIZE later. */ |
1333 | 1622 |
1334 static void | 1623 static void |
1335 gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob, | 1624 gimple_stringop_fixed_value (gcall *vcall_stmt, tree icall_size, profile_probability prob, |
1336 gcov_type count, gcov_type all) | 1625 gcov_type count, gcov_type all) |
1337 { | 1626 { |
1338 gimple tmp_stmt, cond_stmt, icall_stmt; | 1627 gassign *tmp_stmt; |
1339 tree tmp0, tmp1, tmpv, vcall_size, optype; | 1628 gcond *cond_stmt; |
1629 gcall *icall_stmt; | |
1630 tree tmp0, tmp1, vcall_size, optype; | |
1340 basic_block cond_bb, icall_bb, vcall_bb, join_bb; | 1631 basic_block cond_bb, icall_bb, vcall_bb, join_bb; |
1341 edge e_ci, e_cv, e_iv, e_ij, e_vj; | 1632 edge e_ci, e_cv, e_iv, e_ij, e_vj; |
1342 gimple_stmt_iterator gsi; | 1633 gimple_stmt_iterator gsi; |
1343 tree fndecl; | |
1344 int size_arg; | 1634 int size_arg; |
1345 | 1635 |
1346 fndecl = gimple_call_fndecl (vcall_stmt); | 1636 if (!interesting_stringop_to_profile_p (vcall_stmt, &size_arg)) |
1347 if (!interesting_stringop_to_profile_p (fndecl, vcall_stmt, &size_arg)) | 1637 gcc_unreachable (); |
1348 gcc_unreachable(); | |
1349 | 1638 |
1350 cond_bb = gimple_bb (vcall_stmt); | 1639 cond_bb = gimple_bb (vcall_stmt); |
1351 gsi = gsi_for_stmt (vcall_stmt); | 1640 gsi = gsi_for_stmt (vcall_stmt); |
1352 | 1641 |
1353 vcall_size = gimple_call_arg (vcall_stmt, size_arg); | 1642 vcall_size = gimple_call_arg (vcall_stmt, size_arg); |
1354 optype = TREE_TYPE (vcall_size); | 1643 optype = TREE_TYPE (vcall_size); |
1355 | 1644 |
1356 tmpv = create_tmp_var (optype, "PROF"); | 1645 tmp0 = make_temp_ssa_name (optype, NULL, "PROF"); |
1357 tmp0 = make_ssa_name (tmpv, NULL); | 1646 tmp1 = make_temp_ssa_name (optype, NULL, "PROF"); |
1358 tmp1 = make_ssa_name (tmpv, NULL); | |
1359 tmp_stmt = gimple_build_assign (tmp0, fold_convert (optype, icall_size)); | 1647 tmp_stmt = gimple_build_assign (tmp0, fold_convert (optype, icall_size)); |
1360 SSA_NAME_DEF_STMT (tmp0) = tmp_stmt; | |
1361 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT); | 1648 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT); |
1362 | 1649 |
1363 tmp_stmt = gimple_build_assign (tmp1, vcall_size); | 1650 tmp_stmt = gimple_build_assign (tmp1, vcall_size); |
1364 SSA_NAME_DEF_STMT (tmp1) = tmp_stmt; | |
1365 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT); | 1651 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT); |
1366 | 1652 |
1367 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE); | 1653 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE); |
1368 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); | 1654 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); |
1369 | 1655 |
1656 if (TREE_CODE (gimple_vdef (vcall_stmt)) == SSA_NAME) | |
1657 { | |
1658 unlink_stmt_vdef (vcall_stmt); | |
1659 release_ssa_name (gimple_vdef (vcall_stmt)); | |
1660 } | |
1370 gimple_set_vdef (vcall_stmt, NULL); | 1661 gimple_set_vdef (vcall_stmt, NULL); |
1371 gimple_set_vuse (vcall_stmt, NULL); | 1662 gimple_set_vuse (vcall_stmt, NULL); |
1372 update_stmt (vcall_stmt); | 1663 update_stmt (vcall_stmt); |
1373 icall_stmt = gimple_copy (vcall_stmt); | 1664 icall_stmt = as_a <gcall *> (gimple_copy (vcall_stmt)); |
1374 gimple_call_set_arg (icall_stmt, size_arg, icall_size); | 1665 gimple_call_set_arg (icall_stmt, size_arg, |
1666 fold_convert (optype, icall_size)); | |
1375 gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT); | 1667 gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT); |
1376 | 1668 |
1377 /* Fix CFG. */ | 1669 /* Fix CFG. */ |
1378 /* Edge e_ci connects cond_bb to icall_bb, etc. */ | 1670 /* Edge e_ci connects cond_bb to icall_bb, etc. */ |
1379 e_ci = split_block (cond_bb, cond_stmt); | 1671 e_ci = split_block (cond_bb, cond_stmt); |
1380 icall_bb = e_ci->dest; | 1672 icall_bb = e_ci->dest; |
1381 icall_bb->count = count; | 1673 icall_bb->count = profile_count::from_gcov_type (count); |
1382 | 1674 |
1383 e_iv = split_block (icall_bb, icall_stmt); | 1675 e_iv = split_block (icall_bb, icall_stmt); |
1384 vcall_bb = e_iv->dest; | 1676 vcall_bb = e_iv->dest; |
1385 vcall_bb->count = all - count; | 1677 vcall_bb->count = profile_count::from_gcov_type (all - count); |
1386 | 1678 |
1387 e_vj = split_block (vcall_bb, vcall_stmt); | 1679 e_vj = split_block (vcall_bb, vcall_stmt); |
1388 join_bb = e_vj->dest; | 1680 join_bb = e_vj->dest; |
1389 join_bb->count = all; | 1681 join_bb->count = profile_count::from_gcov_type (all); |
1390 | 1682 |
1391 e_ci->flags = (e_ci->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE; | 1683 e_ci->flags = (e_ci->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE; |
1392 e_ci->probability = prob; | 1684 e_ci->probability = prob; |
1393 e_ci->count = count; | |
1394 | 1685 |
1395 e_cv = make_edge (cond_bb, vcall_bb, EDGE_FALSE_VALUE); | 1686 e_cv = make_edge (cond_bb, vcall_bb, EDGE_FALSE_VALUE); |
1396 e_cv->probability = REG_BR_PROB_BASE - prob; | 1687 e_cv->probability = prob.invert (); |
1397 e_cv->count = all - count; | |
1398 | 1688 |
1399 remove_edge (e_iv); | 1689 remove_edge (e_iv); |
1400 | 1690 |
1401 e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU); | 1691 e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU); |
1402 e_ij->probability = REG_BR_PROB_BASE; | 1692 e_ij->probability = profile_probability::always (); |
1403 e_ij->count = count; | 1693 |
1404 | 1694 e_vj->probability = profile_probability::always (); |
1405 e_vj->probability = REG_BR_PROB_BASE; | |
1406 e_vj->count = all - count; | |
1407 | 1695 |
1408 /* Insert PHI node for the call result if necessary. */ | 1696 /* Insert PHI node for the call result if necessary. */ |
1409 if (gimple_call_lhs (vcall_stmt) | 1697 if (gimple_call_lhs (vcall_stmt) |
1410 && TREE_CODE (gimple_call_lhs (vcall_stmt)) == SSA_NAME) | 1698 && TREE_CODE (gimple_call_lhs (vcall_stmt)) == SSA_NAME) |
1411 { | 1699 { |
1412 tree result = gimple_call_lhs (vcall_stmt); | 1700 tree result = gimple_call_lhs (vcall_stmt); |
1413 gimple phi = create_phi_node (result, join_bb); | 1701 gphi *phi = create_phi_node (result, join_bb); |
1414 SSA_NAME_DEF_STMT (result) = phi; | |
1415 gimple_call_set_lhs (vcall_stmt, | 1702 gimple_call_set_lhs (vcall_stmt, |
1416 make_ssa_name (SSA_NAME_VAR (result), vcall_stmt)); | 1703 duplicate_ssa_name (result, vcall_stmt)); |
1417 add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION); | 1704 add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION); |
1418 gimple_call_set_lhs (icall_stmt, | 1705 gimple_call_set_lhs (icall_stmt, |
1419 make_ssa_name (SSA_NAME_VAR (result), icall_stmt)); | 1706 duplicate_ssa_name (result, icall_stmt)); |
1420 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION); | 1707 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION); |
1421 } | 1708 } |
1422 | 1709 |
1423 /* Because these are all string op builtins, they're all nothrow. */ | 1710 /* Because these are all string op builtins, they're all nothrow. */ |
1424 gcc_assert (!stmt_could_throw_p (vcall_stmt)); | 1711 gcc_assert (!stmt_could_throw_p (vcall_stmt)); |
1425 gcc_assert (!stmt_could_throw_p (icall_stmt)); | 1712 gcc_assert (!stmt_could_throw_p (icall_stmt)); |
1426 } | 1713 } |
1427 | 1714 |
1428 /* Find values inside STMT for that we want to measure histograms for | 1715 /* Find values inside STMT for that we want to measure histograms for |
1429 division/modulo optimization. */ | 1716 division/modulo optimization. */ |
1717 | |
1430 static bool | 1718 static bool |
1431 gimple_stringops_transform (gimple_stmt_iterator *gsi) | 1719 gimple_stringops_transform (gimple_stmt_iterator *gsi) |
1432 { | 1720 { |
1433 gimple stmt = gsi_stmt (*gsi); | 1721 gcall *stmt; |
1434 tree fndecl; | |
1435 tree blck_size; | 1722 tree blck_size; |
1436 enum built_in_function fcode; | 1723 enum built_in_function fcode; |
1437 histogram_value histogram; | 1724 histogram_value histogram; |
1438 gcov_type count, all, val; | 1725 gcov_type count, all, val; |
1439 tree dest, src; | 1726 tree dest, src; |
1440 unsigned int dest_align, src_align; | 1727 unsigned int dest_align, src_align; |
1441 gcov_type prob; | 1728 profile_probability prob; |
1442 tree tree_val; | 1729 tree tree_val; |
1443 int size_arg; | 1730 int size_arg; |
1444 | 1731 |
1445 if (gimple_code (stmt) != GIMPLE_CALL) | 1732 stmt = dyn_cast <gcall *> (gsi_stmt (*gsi)); |
1446 return false; | 1733 if (!stmt) |
1447 fndecl = gimple_call_fndecl (stmt); | 1734 return false; |
1448 if (!fndecl) | 1735 |
1449 return false; | 1736 if (!gimple_call_builtin_p (gsi_stmt (*gsi), BUILT_IN_NORMAL)) |
1450 fcode = DECL_FUNCTION_CODE (fndecl); | 1737 return false; |
1451 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg)) | 1738 |
1739 if (!interesting_stringop_to_profile_p (stmt, &size_arg)) | |
1452 return false; | 1740 return false; |
1453 | 1741 |
1454 blck_size = gimple_call_arg (stmt, size_arg); | 1742 blck_size = gimple_call_arg (stmt, size_arg); |
1455 if (TREE_CODE (blck_size) == INTEGER_CST) | 1743 if (TREE_CODE (blck_size) == INTEGER_CST) |
1456 return false; | 1744 return false; |
1457 | 1745 |
1458 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE); | 1746 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE); |
1459 if (!histogram) | 1747 if (!histogram) |
1460 return false; | 1748 return false; |
1749 | |
1461 val = histogram->hvalue.counters[0]; | 1750 val = histogram->hvalue.counters[0]; |
1462 count = histogram->hvalue.counters[1]; | 1751 count = histogram->hvalue.counters[1]; |
1463 all = histogram->hvalue.counters[2]; | 1752 all = histogram->hvalue.counters[2]; |
1464 gimple_remove_histogram_value (cfun, stmt, histogram); | 1753 gimple_remove_histogram_value (cfun, stmt, histogram); |
1754 | |
1465 /* We require that count is at least half of all; this means | 1755 /* We require that count is at least half of all; this means |
1466 that for the transformation to fire the value must be constant | 1756 that for the transformation to fire the value must be constant |
1467 at least 80% of time. */ | 1757 at least 80% of time. */ |
1468 if ((6 * count / 5) < all || optimize_bb_for_size_p (gimple_bb (stmt))) | 1758 if ((6 * count / 5) < all || optimize_bb_for_size_p (gimple_bb (stmt))) |
1469 return false; | 1759 return false; |
1470 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count)) | 1760 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count)) |
1471 return false; | 1761 return false; |
1472 if (all > 0) | 1762 if (all > 0) |
1473 prob = (count * REG_BR_PROB_BASE + all / 2) / all; | 1763 prob = profile_probability::probability_in_gcov_type (count, all); |
1474 else | 1764 else |
1475 prob = 0; | 1765 prob = profile_probability::never (); |
1766 | |
1476 dest = gimple_call_arg (stmt, 0); | 1767 dest = gimple_call_arg (stmt, 0); |
1477 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT); | 1768 dest_align = get_pointer_alignment (dest); |
1769 fcode = DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)); | |
1478 switch (fcode) | 1770 switch (fcode) |
1479 { | 1771 { |
1480 case BUILT_IN_MEMCPY: | 1772 case BUILT_IN_MEMCPY: |
1481 case BUILT_IN_MEMPCPY: | 1773 case BUILT_IN_MEMPCPY: |
1482 src = gimple_call_arg (stmt, 1); | 1774 src = gimple_call_arg (stmt, 1); |
1483 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); | 1775 src_align = get_pointer_alignment (src); |
1484 if (!can_move_by_pieces (val, MIN (dest_align, src_align))) | 1776 if (!can_move_by_pieces (val, MIN (dest_align, src_align))) |
1485 return false; | 1777 return false; |
1486 break; | 1778 break; |
1487 case BUILT_IN_MEMSET: | 1779 case BUILT_IN_MEMSET: |
1488 if (!can_store_by_pieces (val, builtin_memset_read_str, | 1780 if (!can_store_by_pieces (val, builtin_memset_read_str, |
1497 return false; | 1789 return false; |
1498 break; | 1790 break; |
1499 default: | 1791 default: |
1500 gcc_unreachable (); | 1792 gcc_unreachable (); |
1501 } | 1793 } |
1502 tree_val = build_int_cst_wide (get_gcov_type (), | 1794 |
1503 (unsigned HOST_WIDE_INT) val, | 1795 if (sizeof (gcov_type) == sizeof (HOST_WIDE_INT)) |
1504 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1); | 1796 tree_val = build_int_cst (get_gcov_type (), val); |
1797 else | |
1798 { | |
1799 HOST_WIDE_INT a[2]; | |
1800 a[0] = (unsigned HOST_WIDE_INT) val; | |
1801 a[1] = val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1; | |
1802 | |
1803 tree_val = wide_int_to_tree (get_gcov_type (), wide_int::from_array (a, 2, | |
1804 TYPE_PRECISION (get_gcov_type ()), false)); | |
1805 } | |
1806 | |
1505 if (dump_file) | 1807 if (dump_file) |
1506 { | 1808 { |
1507 fprintf (dump_file, "Single value %i stringop transformation on ", | 1809 fprintf (dump_file, "Single value %i stringop transformation on ", |
1508 (int)val); | 1810 (int)val); |
1509 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); | 1811 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); |
1510 } | 1812 } |
1813 | |
1511 gimple_stringop_fixed_value (stmt, tree_val, prob, count, all); | 1814 gimple_stringop_fixed_value (stmt, tree_val, prob, count, all); |
1512 | 1815 |
1513 return true; | 1816 return true; |
1514 } | 1817 } |
1515 | 1818 |
1516 void | 1819 void |
1517 stringop_block_profile (gimple stmt, unsigned int *expected_align, | 1820 stringop_block_profile (gimple *stmt, unsigned int *expected_align, |
1518 HOST_WIDE_INT *expected_size) | 1821 HOST_WIDE_INT *expected_size) |
1519 { | 1822 { |
1520 histogram_value histogram; | 1823 histogram_value histogram; |
1521 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE); | 1824 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE); |
1825 | |
1522 if (!histogram) | 1826 if (!histogram) |
1523 *expected_size = -1; | 1827 *expected_size = -1; |
1524 else if (!histogram->hvalue.counters[1]) | 1828 else if (!histogram->hvalue.counters[1]) |
1525 { | 1829 { |
1526 *expected_size = -1; | 1830 *expected_size = -1; |
1537 if (size > INT_MAX) | 1841 if (size > INT_MAX) |
1538 size = INT_MAX; | 1842 size = INT_MAX; |
1539 *expected_size = size; | 1843 *expected_size = size; |
1540 gimple_remove_histogram_value (cfun, stmt, histogram); | 1844 gimple_remove_histogram_value (cfun, stmt, histogram); |
1541 } | 1845 } |
1846 | |
1542 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR); | 1847 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR); |
1848 | |
1543 if (!histogram) | 1849 if (!histogram) |
1544 *expected_align = 0; | 1850 *expected_align = 0; |
1545 else if (!histogram->hvalue.counters[0]) | 1851 else if (!histogram->hvalue.counters[0]) |
1546 { | 1852 { |
1547 gimple_remove_histogram_value (cfun, stmt, histogram); | 1853 gimple_remove_histogram_value (cfun, stmt, histogram); |
1548 *expected_align = 0; | 1854 *expected_align = 0; |
1549 } | 1855 } |
1550 else | 1856 else |
1551 { | 1857 { |
1552 gcov_type count; | 1858 gcov_type count; |
1553 int alignment; | 1859 unsigned int alignment; |
1554 | 1860 |
1555 count = histogram->hvalue.counters[0]; | 1861 count = histogram->hvalue.counters[0]; |
1556 alignment = 1; | 1862 alignment = 1; |
1557 while (!(count & alignment) | 1863 while (!(count & alignment) |
1558 && (alignment * 2 * BITS_PER_UNIT)) | 1864 && (alignment <= UINT_MAX / 2 / BITS_PER_UNIT)) |
1559 alignment <<= 1; | 1865 alignment <<= 1; |
1560 *expected_align = alignment * BITS_PER_UNIT; | 1866 *expected_align = alignment * BITS_PER_UNIT; |
1561 gimple_remove_histogram_value (cfun, stmt, histogram); | 1867 gimple_remove_histogram_value (cfun, stmt, histogram); |
1562 } | 1868 } |
1563 } | 1869 } |
1564 | 1870 |
1565 | 1871 |
1566 /* Find values inside STMT for that we want to measure histograms for | 1872 /* Find values inside STMT for that we want to measure histograms for |
1567 division/modulo optimization. */ | 1873 division/modulo optimization. */ |
1874 | |
1568 static void | 1875 static void |
1569 gimple_divmod_values_to_profile (gimple stmt, histogram_values *values) | 1876 gimple_divmod_values_to_profile (gimple *stmt, histogram_values *values) |
1570 { | 1877 { |
1571 tree lhs, divisor, op0, type; | 1878 tree lhs, divisor, op0, type; |
1572 histogram_value hist; | 1879 histogram_value hist; |
1573 | 1880 |
1574 if (gimple_code (stmt) != GIMPLE_ASSIGN) | 1881 if (gimple_code (stmt) != GIMPLE_ASSIGN) |
1584 case TRUNC_DIV_EXPR: | 1891 case TRUNC_DIV_EXPR: |
1585 case TRUNC_MOD_EXPR: | 1892 case TRUNC_MOD_EXPR: |
1586 divisor = gimple_assign_rhs2 (stmt); | 1893 divisor = gimple_assign_rhs2 (stmt); |
1587 op0 = gimple_assign_rhs1 (stmt); | 1894 op0 = gimple_assign_rhs1 (stmt); |
1588 | 1895 |
1589 VEC_reserve (histogram_value, heap, *values, 3); | 1896 values->reserve (3); |
1590 | 1897 |
1591 if (is_gimple_reg (divisor)) | 1898 if (TREE_CODE (divisor) == SSA_NAME) |
1592 /* Check for the case where the divisor is the same value most | 1899 /* Check for the case where the divisor is the same value most |
1593 of the time. */ | 1900 of the time. */ |
1594 VEC_quick_push (histogram_value, *values, | 1901 values->quick_push (gimple_alloc_histogram_value (cfun, |
1595 gimple_alloc_histogram_value (cfun, | |
1596 HIST_TYPE_SINGLE_VALUE, | 1902 HIST_TYPE_SINGLE_VALUE, |
1597 stmt, divisor)); | 1903 stmt, divisor)); |
1598 | 1904 |
1599 /* For mod, check whether it is not often a noop (or replaceable by | 1905 /* For mod, check whether it is not often a noop (or replaceable by |
1600 a few subtractions). */ | 1906 a few subtractions). */ |
1601 if (gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR | 1907 if (gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR |
1602 && TYPE_UNSIGNED (type)) | 1908 && TYPE_UNSIGNED (type) |
1909 && TREE_CODE (divisor) == SSA_NAME) | |
1603 { | 1910 { |
1604 tree val; | 1911 tree val; |
1605 /* Check for a special case where the divisor is power of 2. */ | 1912 /* Check for a special case where the divisor is power of 2. */ |
1606 VEC_quick_push (histogram_value, *values, | 1913 values->quick_push (gimple_alloc_histogram_value (cfun, |
1607 gimple_alloc_histogram_value (cfun, HIST_TYPE_POW2, | 1914 HIST_TYPE_POW2, |
1608 stmt, divisor)); | 1915 stmt, divisor)); |
1609 | 1916 |
1610 val = build2 (TRUNC_DIV_EXPR, type, op0, divisor); | 1917 val = build2 (TRUNC_DIV_EXPR, type, op0, divisor); |
1611 hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL, | 1918 hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL, |
1612 stmt, val); | 1919 stmt, val); |
1613 hist->hdata.intvl.int_start = 0; | 1920 hist->hdata.intvl.int_start = 0; |
1614 hist->hdata.intvl.steps = 2; | 1921 hist->hdata.intvl.steps = 2; |
1615 VEC_quick_push (histogram_value, *values, hist); | 1922 values->quick_push (hist); |
1616 } | 1923 } |
1617 return; | 1924 return; |
1618 | 1925 |
1619 default: | 1926 default: |
1620 return; | 1927 return; |
1623 | 1930 |
1624 /* Find calls inside STMT for that we want to measure histograms for | 1931 /* Find calls inside STMT for that we want to measure histograms for |
1625 indirect/virtual call optimization. */ | 1932 indirect/virtual call optimization. */ |
1626 | 1933 |
1627 static void | 1934 static void |
1628 gimple_indirect_call_to_profile (gimple stmt, histogram_values *values) | 1935 gimple_indirect_call_to_profile (gimple *stmt, histogram_values *values) |
1629 { | 1936 { |
1630 tree callee; | 1937 tree callee; |
1631 | 1938 |
1632 if (gimple_code (stmt) != GIMPLE_CALL | 1939 if (gimple_code (stmt) != GIMPLE_CALL |
1940 || gimple_call_internal_p (stmt) | |
1633 || gimple_call_fndecl (stmt) != NULL_TREE) | 1941 || gimple_call_fndecl (stmt) != NULL_TREE) |
1634 return; | 1942 return; |
1635 | 1943 |
1636 callee = gimple_call_fn (stmt); | 1944 callee = gimple_call_fn (stmt); |
1637 | 1945 |
1638 VEC_reserve (histogram_value, heap, *values, 3); | 1946 values->reserve (3); |
1639 | 1947 |
1640 VEC_quick_push (histogram_value, *values, | 1948 values->quick_push (gimple_alloc_histogram_value ( |
1641 gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL, | 1949 cfun, |
1642 stmt, callee)); | 1950 PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ? |
1951 HIST_TYPE_INDIR_CALL_TOPN : | |
1952 HIST_TYPE_INDIR_CALL, | |
1953 stmt, callee)); | |
1643 | 1954 |
1644 return; | 1955 return; |
1645 } | 1956 } |
1646 | 1957 |
1647 /* Find values inside STMT for that we want to measure histograms for | 1958 /* Find values inside STMT for that we want to measure histograms for |
1648 string operations. */ | 1959 string operations. */ |
1960 | |
1649 static void | 1961 static void |
1650 gimple_stringops_values_to_profile (gimple stmt, histogram_values *values) | 1962 gimple_stringops_values_to_profile (gimple *gs, histogram_values *values) |
1651 { | 1963 { |
1652 tree fndecl; | 1964 gcall *stmt; |
1653 tree blck_size; | 1965 tree blck_size; |
1654 tree dest; | 1966 tree dest; |
1655 int size_arg; | 1967 int size_arg; |
1656 | 1968 |
1657 if (gimple_code (stmt) != GIMPLE_CALL) | 1969 stmt = dyn_cast <gcall *> (gs); |
1970 if (!stmt) | |
1658 return; | 1971 return; |
1659 fndecl = gimple_call_fndecl (stmt); | 1972 |
1660 if (!fndecl) | 1973 if (!gimple_call_builtin_p (gs, BUILT_IN_NORMAL)) |
1661 return; | 1974 return; |
1662 | 1975 |
1663 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg)) | 1976 if (!interesting_stringop_to_profile_p (stmt, &size_arg)) |
1664 return; | 1977 return; |
1665 | 1978 |
1666 dest = gimple_call_arg (stmt, 0); | 1979 dest = gimple_call_arg (stmt, 0); |
1667 blck_size = gimple_call_arg (stmt, size_arg); | 1980 blck_size = gimple_call_arg (stmt, size_arg); |
1668 | 1981 |
1669 if (TREE_CODE (blck_size) != INTEGER_CST) | 1982 if (TREE_CODE (blck_size) != INTEGER_CST) |
1670 { | 1983 { |
1671 VEC_safe_push (histogram_value, heap, *values, | 1984 values->safe_push (gimple_alloc_histogram_value (cfun, |
1672 gimple_alloc_histogram_value (cfun, HIST_TYPE_SINGLE_VALUE, | 1985 HIST_TYPE_SINGLE_VALUE, |
1673 stmt, blck_size)); | 1986 stmt, blck_size)); |
1674 VEC_safe_push (histogram_value, heap, *values, | 1987 values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE, |
1675 gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE, | 1988 stmt, blck_size)); |
1676 stmt, blck_size)); | 1989 } |
1677 } | 1990 |
1678 if (TREE_CODE (blck_size) != INTEGER_CST) | 1991 if (TREE_CODE (blck_size) != INTEGER_CST) |
1679 VEC_safe_push (histogram_value, heap, *values, | 1992 values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR, |
1680 gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR, | 1993 stmt, dest)); |
1681 stmt, dest)); | |
1682 } | 1994 } |
1683 | 1995 |
1684 /* Find values inside STMT for that we want to measure histograms and adds | 1996 /* Find values inside STMT for that we want to measure histograms and adds |
1685 them to list VALUES. */ | 1997 them to list VALUES. */ |
1686 | 1998 |
1687 static void | 1999 static void |
1688 gimple_values_to_profile (gimple stmt, histogram_values *values) | 2000 gimple_values_to_profile (gimple *stmt, histogram_values *values) |
1689 { | 2001 { |
1690 if (flag_value_profile_transformations) | 2002 gimple_divmod_values_to_profile (stmt, values); |
1691 { | 2003 gimple_stringops_values_to_profile (stmt, values); |
1692 gimple_divmod_values_to_profile (stmt, values); | 2004 gimple_indirect_call_to_profile (stmt, values); |
1693 gimple_stringops_values_to_profile (stmt, values); | |
1694 gimple_indirect_call_to_profile (stmt, values); | |
1695 } | |
1696 } | 2005 } |
1697 | 2006 |
1698 void | 2007 void |
1699 gimple_find_values_to_profile (histogram_values *values) | 2008 gimple_find_values_to_profile (histogram_values *values) |
1700 { | 2009 { |
1701 basic_block bb; | 2010 basic_block bb; |
1702 gimple_stmt_iterator gsi; | 2011 gimple_stmt_iterator gsi; |
1703 unsigned i; | 2012 unsigned i; |
1704 histogram_value hist = NULL; | 2013 histogram_value hist = NULL; |
1705 | 2014 values->create (0); |
1706 *values = NULL; | 2015 |
1707 FOR_EACH_BB (bb) | 2016 FOR_EACH_BB_FN (bb, cfun) |
1708 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | 2017 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
1709 gimple_values_to_profile (gsi_stmt (gsi), values); | 2018 gimple_values_to_profile (gsi_stmt (gsi), values); |
1710 | 2019 |
1711 FOR_EACH_VEC_ELT (histogram_value, *values, i, hist) | 2020 values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_TIME_PROFILE, 0, 0)); |
2021 | |
2022 FOR_EACH_VEC_ELT (*values, i, hist) | |
1712 { | 2023 { |
1713 switch (hist->type) | 2024 switch (hist->type) |
1714 { | 2025 { |
1715 case HIST_TYPE_INTERVAL: | 2026 case HIST_TYPE_INTERVAL: |
1716 hist->n_counters = hist->hdata.intvl.steps + 2; | 2027 hist->n_counters = hist->hdata.intvl.steps + 2; |
1722 | 2033 |
1723 case HIST_TYPE_SINGLE_VALUE: | 2034 case HIST_TYPE_SINGLE_VALUE: |
1724 hist->n_counters = 3; | 2035 hist->n_counters = 3; |
1725 break; | 2036 break; |
1726 | 2037 |
1727 case HIST_TYPE_CONST_DELTA: | |
1728 hist->n_counters = 4; | |
1729 break; | |
1730 | |
1731 case HIST_TYPE_INDIR_CALL: | 2038 case HIST_TYPE_INDIR_CALL: |
1732 hist->n_counters = 3; | 2039 hist->n_counters = 3; |
1733 break; | 2040 break; |
1734 | 2041 |
2042 case HIST_TYPE_TIME_PROFILE: | |
2043 hist->n_counters = 1; | |
2044 break; | |
2045 | |
1735 case HIST_TYPE_AVERAGE: | 2046 case HIST_TYPE_AVERAGE: |
1736 hist->n_counters = 2; | 2047 hist->n_counters = 2; |
1737 break; | 2048 break; |
1738 | 2049 |
1739 case HIST_TYPE_IOR: | 2050 case HIST_TYPE_IOR: |
1740 hist->n_counters = 1; | 2051 hist->n_counters = 1; |
1741 break; | 2052 break; |
2053 | |
2054 case HIST_TYPE_INDIR_CALL_TOPN: | |
2055 hist->n_counters = GCOV_ICALL_TOPN_NCOUNTS; | |
2056 break; | |
1742 | 2057 |
1743 default: | 2058 default: |
1744 gcc_unreachable (); | 2059 gcc_unreachable (); |
1745 } | 2060 } |
1746 if (dump_file) | 2061 if (dump_file) |
1749 print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM); | 2064 print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM); |
1750 dump_histogram_value (dump_file, hist); | 2065 dump_histogram_value (dump_file, hist); |
1751 } | 2066 } |
1752 } | 2067 } |
1753 } | 2068 } |
1754 |