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