2014-11-18 Christophe Lyon <christophe.lyon@linaro.org>
[official-gcc.git] / gcc / value-prof.c
blob1b203e8aef17429c42be403ba16eca40831b86d2
1 /* Transformations based on profile information for values.
2 Copyright (C) 2003-2014 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "tree.h"
25 #include "tree-nested.h"
26 #include "calls.h"
27 #include "rtl.h"
28 #include "expr.h"
29 #include "hard-reg-set.h"
30 #include "predict.h"
31 #include "vec.h"
32 #include "hashtab.h"
33 #include "hash-set.h"
34 #include "machmode.h"
35 #include "input.h"
36 #include "function.h"
37 #include "dominance.h"
38 #include "cfg.h"
39 #include "basic-block.h"
40 #include "value-prof.h"
41 #include "flags.h"
42 #include "insn-config.h"
43 #include "recog.h"
44 #include "insn-codes.h"
45 #include "optabs.h"
46 #include "regs.h"
47 #include "tree-ssa-alias.h"
48 #include "internal-fn.h"
49 #include "tree-eh.h"
50 #include "gimple-expr.h"
51 #include "is-a.h"
52 #include "gimple.h"
53 #include "gimplify.h"
54 #include "gimple-iterator.h"
55 #include "gimple-ssa.h"
56 #include "tree-cfg.h"
57 #include "tree-phinodes.h"
58 #include "ssa-iterators.h"
59 #include "stringpool.h"
60 #include "tree-ssanames.h"
61 #include "diagnostic.h"
62 #include "gimple-pretty-print.h"
63 #include "coverage.h"
64 #include "tree.h"
65 #include "gcov-io.h"
66 #include "timevar.h"
67 #include "dumpfile.h"
68 #include "profile.h"
69 #include "hash-map.h"
70 #include "plugin-api.h"
71 #include "ipa-ref.h"
72 #include "cgraph.h"
73 #include "data-streamer.h"
74 #include "builtins.h"
75 #include "tree-nested.h"
76 #include "params.h"
77 #include "tree-chkp.h"
79 /* In this file value profile based optimizations are placed. Currently the
80 following optimizations are implemented (for more detailed descriptions
81 see comments at value_profile_transformations):
83 1) Division/modulo specialization. Provided that we can determine that the
84 operands of the division have some special properties, we may use it to
85 produce more effective code.
87 2) Indirect/virtual call specialization. If we can determine most
88 common function callee in indirect/virtual call. We can use this
89 information to improve code effectiveness (especially info for
90 the inliner).
92 3) Speculative prefetching. If we are able to determine that the difference
93 between addresses accessed by a memory reference is usually constant, we
94 may add the prefetch instructions.
95 FIXME: This transformation was removed together with RTL based value
96 profiling.
99 Value profiling internals
100 ==========================
102 Every value profiling transformation starts with defining what values
103 to profile. There are different histogram types (see HIST_TYPE_* in
104 value-prof.h) and each transformation can request one or more histogram
105 types per GIMPLE statement. The function gimple_find_values_to_profile()
106 collects the values to profile in a vec, and adds the number of counters
107 required for the different histogram types.
109 For a -fprofile-generate run, the statements for which values should be
110 recorded, are instrumented in instrument_values(). The instrumentation
111 is done by helper functions that can be found in tree-profile.c, where
112 new types of histograms can be added if necessary.
114 After a -fprofile-use, the value profiling data is read back in by
115 compute_value_histograms() that translates the collected data to
116 histograms and attaches them to the profiled statements via
117 gimple_add_histogram_value(). Histograms are stored in a hash table
118 that is attached to every intrumented function, see VALUE_HISTOGRAMS
119 in function.h.
121 The value-profile transformations driver is the function
122 gimple_value_profile_transformations(). It traverses all statements in
123 the to-be-transformed function, and looks for statements with one or
124 more histograms attached to it. If a statement has histograms, the
125 transformation functions are called on the statement.
127 Limitations / FIXME / TODO:
128 * Only one histogram of each type can be associated with a statement.
129 * Currently, HIST_TYPE_CONST_DELTA is not implemented.
130 (This type of histogram was originally used to implement a form of
131 stride profiling based speculative prefetching to improve SPEC2000
132 scores for memory-bound benchmarks, mcf and equake. However, this
133 was an RTL value-profiling transformation, and those have all been
134 removed.)
135 * Some value profile transformations are done in builtins.c (?!)
136 * Updating of histograms needs some TLC.
137 * The value profiling code could be used to record analysis results
138 from non-profiling (e.g. VRP).
139 * Adding new profilers should be simplified, starting with a cleanup
140 of what-happens-where andwith making gimple_find_values_to_profile
141 and gimple_value_profile_transformations table-driven, perhaps...
144 static tree gimple_divmod_fixed_value (gimple, tree, int, gcov_type, gcov_type);
145 static tree gimple_mod_pow2 (gimple, int, gcov_type, gcov_type);
146 static tree gimple_mod_subtract (gimple, int, int, int, gcov_type, gcov_type,
147 gcov_type);
148 static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *);
149 static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *);
150 static bool gimple_mod_subtract_transform (gimple_stmt_iterator *);
151 static bool gimple_stringops_transform (gimple_stmt_iterator *);
152 static bool gimple_ic_transform (gimple_stmt_iterator *);
154 /* Allocate histogram value. */
156 histogram_value
157 gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED,
158 enum hist_type type, gimple stmt, tree value)
160 histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist));
161 hist->hvalue.value = value;
162 hist->hvalue.stmt = stmt;
163 hist->type = type;
164 return hist;
167 /* Hash value for histogram. */
169 static hashval_t
170 histogram_hash (const void *x)
172 return htab_hash_pointer (((const_histogram_value)x)->hvalue.stmt);
175 /* Return nonzero if statement for histogram_value X is Y. */
177 static int
178 histogram_eq (const void *x, const void *y)
180 return ((const_histogram_value) x)->hvalue.stmt == (const_gimple) y;
183 /* Set histogram for STMT. */
185 static void
186 set_histogram_value (struct function *fun, gimple stmt, histogram_value hist)
188 void **loc;
189 if (!hist && !VALUE_HISTOGRAMS (fun))
190 return;
191 if (!VALUE_HISTOGRAMS (fun))
192 VALUE_HISTOGRAMS (fun) = htab_create (1, histogram_hash,
193 histogram_eq, NULL);
194 loc = htab_find_slot_with_hash (VALUE_HISTOGRAMS (fun), stmt,
195 htab_hash_pointer (stmt),
196 hist ? INSERT : NO_INSERT);
197 if (!hist)
199 if (loc)
200 htab_clear_slot (VALUE_HISTOGRAMS (fun), loc);
201 return;
203 *loc = hist;
206 /* Get histogram list for STMT. */
208 histogram_value
209 gimple_histogram_value (struct function *fun, gimple stmt)
211 if (!VALUE_HISTOGRAMS (fun))
212 return NULL;
213 return (histogram_value) htab_find_with_hash (VALUE_HISTOGRAMS (fun), stmt,
214 htab_hash_pointer (stmt));
217 /* Add histogram for STMT. */
219 void
220 gimple_add_histogram_value (struct function *fun, gimple stmt,
221 histogram_value hist)
223 hist->hvalue.next = gimple_histogram_value (fun, stmt);
224 set_histogram_value (fun, stmt, hist);
225 hist->fun = fun;
229 /* Remove histogram HIST from STMT's histogram list. */
231 void
232 gimple_remove_histogram_value (struct function *fun, gimple stmt,
233 histogram_value hist)
235 histogram_value hist2 = gimple_histogram_value (fun, stmt);
236 if (hist == hist2)
238 set_histogram_value (fun, stmt, hist->hvalue.next);
240 else
242 while (hist2->hvalue.next != hist)
243 hist2 = hist2->hvalue.next;
244 hist2->hvalue.next = hist->hvalue.next;
246 free (hist->hvalue.counters);
247 #ifdef ENABLE_CHECKING
248 memset (hist, 0xab, sizeof (*hist));
249 #endif
250 free (hist);
254 /* Lookup histogram of type TYPE in the STMT. */
256 histogram_value
257 gimple_histogram_value_of_type (struct function *fun, gimple stmt,
258 enum hist_type type)
260 histogram_value hist;
261 for (hist = gimple_histogram_value (fun, stmt); hist;
262 hist = hist->hvalue.next)
263 if (hist->type == type)
264 return hist;
265 return NULL;
268 /* Dump information about HIST to DUMP_FILE. */
270 static void
271 dump_histogram_value (FILE *dump_file, histogram_value hist)
273 switch (hist->type)
275 case HIST_TYPE_INTERVAL:
276 fprintf (dump_file, "Interval counter range %d -- %d",
277 hist->hdata.intvl.int_start,
278 (hist->hdata.intvl.int_start
279 + hist->hdata.intvl.steps - 1));
280 if (hist->hvalue.counters)
282 unsigned int i;
283 fprintf (dump_file, " [");
284 for (i = 0; i < hist->hdata.intvl.steps; i++)
285 fprintf (dump_file, " %d:%"PRId64,
286 hist->hdata.intvl.int_start + i,
287 (int64_t) hist->hvalue.counters[i]);
288 fprintf (dump_file, " ] outside range:%"PRId64,
289 (int64_t) hist->hvalue.counters[i]);
291 fprintf (dump_file, ".\n");
292 break;
294 case HIST_TYPE_POW2:
295 fprintf (dump_file, "Pow2 counter ");
296 if (hist->hvalue.counters)
298 fprintf (dump_file, "pow2:%"PRId64
299 " nonpow2:%"PRId64,
300 (int64_t) hist->hvalue.counters[0],
301 (int64_t) hist->hvalue.counters[1]);
303 fprintf (dump_file, ".\n");
304 break;
306 case HIST_TYPE_SINGLE_VALUE:
307 fprintf (dump_file, "Single value ");
308 if (hist->hvalue.counters)
310 fprintf (dump_file, "value:%"PRId64
311 " match:%"PRId64
312 " wrong:%"PRId64,
313 (int64_t) hist->hvalue.counters[0],
314 (int64_t) hist->hvalue.counters[1],
315 (int64_t) hist->hvalue.counters[2]);
317 fprintf (dump_file, ".\n");
318 break;
320 case HIST_TYPE_AVERAGE:
321 fprintf (dump_file, "Average value ");
322 if (hist->hvalue.counters)
324 fprintf (dump_file, "sum:%"PRId64
325 " times:%"PRId64,
326 (int64_t) hist->hvalue.counters[0],
327 (int64_t) hist->hvalue.counters[1]);
329 fprintf (dump_file, ".\n");
330 break;
332 case HIST_TYPE_IOR:
333 fprintf (dump_file, "IOR value ");
334 if (hist->hvalue.counters)
336 fprintf (dump_file, "ior:%"PRId64,
337 (int64_t) hist->hvalue.counters[0]);
339 fprintf (dump_file, ".\n");
340 break;
342 case HIST_TYPE_CONST_DELTA:
343 fprintf (dump_file, "Constant delta ");
344 if (hist->hvalue.counters)
346 fprintf (dump_file, "value:%"PRId64
347 " match:%"PRId64
348 " wrong:%"PRId64,
349 (int64_t) hist->hvalue.counters[0],
350 (int64_t) hist->hvalue.counters[1],
351 (int64_t) hist->hvalue.counters[2]);
353 fprintf (dump_file, ".\n");
354 break;
355 case HIST_TYPE_INDIR_CALL:
356 fprintf (dump_file, "Indirect call ");
357 if (hist->hvalue.counters)
359 fprintf (dump_file, "value:%"PRId64
360 " match:%"PRId64
361 " all:%"PRId64,
362 (int64_t) hist->hvalue.counters[0],
363 (int64_t) hist->hvalue.counters[1],
364 (int64_t) hist->hvalue.counters[2]);
366 fprintf (dump_file, ".\n");
367 break;
368 case HIST_TYPE_TIME_PROFILE:
369 fprintf (dump_file, "Time profile ");
370 if (hist->hvalue.counters)
372 fprintf (dump_file, "time:%"PRId64,
373 (int64_t) hist->hvalue.counters[0]);
375 fprintf (dump_file, ".\n");
376 break;
377 case HIST_TYPE_INDIR_CALL_TOPN:
378 fprintf (dump_file, "Indirect call topn ");
379 if (hist->hvalue.counters)
381 int i;
383 fprintf (dump_file, "accu:%"PRId64, hist->hvalue.counters[0]);
384 for (i = 1; i < (GCOV_ICALL_TOPN_VAL << 2); i += 2)
386 fprintf (dump_file, " target:%"PRId64 " value:%"PRId64,
387 (int64_t) hist->hvalue.counters[i],
388 (int64_t) hist->hvalue.counters[i+1]);
391 fprintf (dump_file, ".\n");
392 break;
393 case HIST_TYPE_MAX:
394 gcc_unreachable ();
398 /* Dump information about HIST to DUMP_FILE. */
400 void
401 stream_out_histogram_value (struct output_block *ob, histogram_value hist)
403 struct bitpack_d bp;
404 unsigned int i;
406 bp = bitpack_create (ob->main_stream);
407 bp_pack_enum (&bp, hist_type, HIST_TYPE_MAX, hist->type);
408 bp_pack_value (&bp, hist->hvalue.next != NULL, 1);
409 streamer_write_bitpack (&bp);
410 switch (hist->type)
412 case HIST_TYPE_INTERVAL:
413 streamer_write_hwi (ob, hist->hdata.intvl.int_start);
414 streamer_write_uhwi (ob, hist->hdata.intvl.steps);
415 break;
416 default:
417 break;
419 for (i = 0; i < hist->n_counters; i++)
420 streamer_write_gcov_count (ob, hist->hvalue.counters[i]);
421 if (hist->hvalue.next)
422 stream_out_histogram_value (ob, hist->hvalue.next);
424 /* Dump information about HIST to DUMP_FILE. */
426 void
427 stream_in_histogram_value (struct lto_input_block *ib, gimple stmt)
429 enum hist_type type;
430 unsigned int ncounters = 0;
431 struct bitpack_d bp;
432 unsigned int i;
433 histogram_value new_val;
434 bool next;
435 histogram_value *next_p = NULL;
439 bp = streamer_read_bitpack (ib);
440 type = bp_unpack_enum (&bp, hist_type, HIST_TYPE_MAX);
441 next = bp_unpack_value (&bp, 1);
442 new_val = gimple_alloc_histogram_value (cfun, type, stmt, NULL);
443 switch (type)
445 case HIST_TYPE_INTERVAL:
446 new_val->hdata.intvl.int_start = streamer_read_hwi (ib);
447 new_val->hdata.intvl.steps = streamer_read_uhwi (ib);
448 ncounters = new_val->hdata.intvl.steps + 2;
449 break;
451 case HIST_TYPE_POW2:
452 case HIST_TYPE_AVERAGE:
453 ncounters = 2;
454 break;
456 case HIST_TYPE_SINGLE_VALUE:
457 case HIST_TYPE_INDIR_CALL:
458 ncounters = 3;
459 break;
461 case HIST_TYPE_CONST_DELTA:
462 ncounters = 4;
463 break;
465 case HIST_TYPE_IOR:
466 case HIST_TYPE_TIME_PROFILE:
467 ncounters = 1;
468 break;
470 case HIST_TYPE_INDIR_CALL_TOPN:
471 ncounters = (GCOV_ICALL_TOPN_VAL << 2) + 1;
472 break;
474 case HIST_TYPE_MAX:
475 gcc_unreachable ();
477 new_val->hvalue.counters = XNEWVAR (gcov_type, sizeof (*new_val->hvalue.counters) * ncounters);
478 new_val->n_counters = ncounters;
479 for (i = 0; i < ncounters; i++)
480 new_val->hvalue.counters[i] = streamer_read_gcov_count (ib);
481 if (!next_p)
482 gimple_add_histogram_value (cfun, stmt, new_val);
483 else
484 *next_p = new_val;
485 next_p = &new_val->hvalue.next;
487 while (next);
490 /* Dump all histograms attached to STMT to DUMP_FILE. */
492 void
493 dump_histograms_for_stmt (struct function *fun, FILE *dump_file, gimple stmt)
495 histogram_value hist;
496 for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
497 dump_histogram_value (dump_file, hist);
500 /* Remove all histograms associated with STMT. */
502 void
503 gimple_remove_stmt_histograms (struct function *fun, gimple stmt)
505 histogram_value val;
506 while ((val = gimple_histogram_value (fun, stmt)) != NULL)
507 gimple_remove_histogram_value (fun, stmt, val);
510 /* Duplicate all histograms associates with OSTMT to STMT. */
512 void
513 gimple_duplicate_stmt_histograms (struct function *fun, gimple stmt,
514 struct function *ofun, gimple ostmt)
516 histogram_value val;
517 for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next)
519 histogram_value new_val = gimple_alloc_histogram_value (fun, val->type, NULL, NULL);
520 memcpy (new_val, val, sizeof (*val));
521 new_val->hvalue.stmt = stmt;
522 new_val->hvalue.counters = XNEWVAR (gcov_type, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
523 memcpy (new_val->hvalue.counters, val->hvalue.counters, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
524 gimple_add_histogram_value (fun, stmt, new_val);
529 /* Move all histograms associated with OSTMT to STMT. */
531 void
532 gimple_move_stmt_histograms (struct function *fun, gimple stmt, gimple ostmt)
534 histogram_value val = gimple_histogram_value (fun, ostmt);
535 if (val)
537 /* The following three statements can't be reordered,
538 because histogram hashtab relies on stmt field value
539 for finding the exact slot. */
540 set_histogram_value (fun, ostmt, NULL);
541 for (; val != NULL; val = val->hvalue.next)
542 val->hvalue.stmt = stmt;
543 set_histogram_value (fun, stmt, val);
547 static bool error_found = false;
549 /* Helper function for verify_histograms. For each histogram reachable via htab
550 walk verify that it was reached via statement walk. */
552 static int
553 visit_hist (void **slot, void *data)
555 hash_set<histogram_value> *visited = (hash_set<histogram_value> *) data;
556 histogram_value hist = *(histogram_value *) slot;
558 if (!visited->contains (hist)
559 && hist->type != HIST_TYPE_TIME_PROFILE)
561 error ("dead histogram");
562 dump_histogram_value (stderr, hist);
563 debug_gimple_stmt (hist->hvalue.stmt);
564 error_found = true;
566 return 1;
570 /* Verify sanity of the histograms. */
572 DEBUG_FUNCTION void
573 verify_histograms (void)
575 basic_block bb;
576 gimple_stmt_iterator gsi;
577 histogram_value hist;
579 error_found = false;
580 hash_set<histogram_value> visited_hists;
581 FOR_EACH_BB_FN (bb, cfun)
582 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
584 gimple stmt = gsi_stmt (gsi);
586 for (hist = gimple_histogram_value (cfun, stmt); hist;
587 hist = hist->hvalue.next)
589 if (hist->hvalue.stmt != stmt)
591 error ("Histogram value statement does not correspond to "
592 "the statement it is associated with");
593 debug_gimple_stmt (stmt);
594 dump_histogram_value (stderr, hist);
595 error_found = true;
597 visited_hists.add (hist);
600 if (VALUE_HISTOGRAMS (cfun))
601 htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, &visited_hists);
602 if (error_found)
603 internal_error ("verify_histograms failed");
606 /* Helper function for verify_histograms. For each histogram reachable via htab
607 walk verify that it was reached via statement walk. */
609 static int
610 free_hist (void **slot, void *data ATTRIBUTE_UNUSED)
612 histogram_value hist = *(histogram_value *) slot;
613 free (hist->hvalue.counters);
614 #ifdef ENABLE_CHECKING
615 memset (hist, 0xab, sizeof (*hist));
616 #endif
617 free (hist);
618 return 1;
621 void
622 free_histograms (void)
624 if (VALUE_HISTOGRAMS (cfun))
626 htab_traverse (VALUE_HISTOGRAMS (cfun), free_hist, NULL);
627 htab_delete (VALUE_HISTOGRAMS (cfun));
628 VALUE_HISTOGRAMS (cfun) = NULL;
633 /* The overall number of invocations of the counter should match
634 execution count of basic block. Report it as error rather than
635 internal error as it might mean that user has misused the profile
636 somehow. */
638 static bool
639 check_counter (gimple stmt, const char * name,
640 gcov_type *count, gcov_type *all, gcov_type bb_count)
642 if (*all != bb_count || *count > *all)
644 location_t locus;
645 locus = (stmt != NULL)
646 ? gimple_location (stmt)
647 : DECL_SOURCE_LOCATION (current_function_decl);
648 if (flag_profile_correction)
650 if (dump_enabled_p ())
651 dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
652 "correcting inconsistent value profile: %s "
653 "profiler overall count (%d) does not match BB "
654 "count (%d)\n", name, (int)*all, (int)bb_count);
655 *all = bb_count;
656 if (*count > *all)
657 *count = *all;
658 return false;
660 else
662 error_at (locus, "corrupted value profile: %s "
663 "profile counter (%d out of %d) inconsistent with "
664 "basic-block count (%d)",
665 name,
666 (int) *count,
667 (int) *all,
668 (int) bb_count);
669 return true;
673 return false;
677 /* GIMPLE based transformations. */
679 bool
680 gimple_value_profile_transformations (void)
682 basic_block bb;
683 gimple_stmt_iterator gsi;
684 bool changed = false;
686 FOR_EACH_BB_FN (bb, cfun)
688 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
690 gimple stmt = gsi_stmt (gsi);
691 histogram_value th = gimple_histogram_value (cfun, stmt);
692 if (!th)
693 continue;
695 if (dump_file)
697 fprintf (dump_file, "Trying transformations on stmt ");
698 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
699 dump_histograms_for_stmt (cfun, dump_file, stmt);
702 /* Transformations: */
703 /* The order of things in this conditional controls which
704 transformation is used when more than one is applicable. */
705 /* It is expected that any code added by the transformations
706 will be added before the current statement, and that the
707 current statement remain valid (although possibly
708 modified) upon return. */
709 if (gimple_mod_subtract_transform (&gsi)
710 || gimple_divmod_fixed_value_transform (&gsi)
711 || gimple_mod_pow2_value_transform (&gsi)
712 || gimple_stringops_transform (&gsi)
713 || gimple_ic_transform (&gsi))
715 stmt = gsi_stmt (gsi);
716 changed = true;
717 /* Original statement may no longer be in the same block. */
718 if (bb != gimple_bb (stmt))
720 bb = gimple_bb (stmt);
721 gsi = gsi_for_stmt (stmt);
727 if (changed)
729 counts_to_freqs ();
732 return changed;
736 /* Generate code for transformation 1 (with parent gimple assignment
737 STMT and probability of taking the optimal path PROB, which is
738 equivalent to COUNT/ALL within roundoff error). This generates the
739 result into a temp and returns the temp; it does not replace or
740 alter the original STMT. */
742 static tree
743 gimple_divmod_fixed_value (gimple stmt, tree value, int prob, gcov_type count,
744 gcov_type all)
746 gimple stmt1, stmt2, stmt3;
747 tree tmp0, tmp1, tmp2;
748 gimple bb1end, bb2end, bb3end;
749 basic_block bb, bb2, bb3, bb4;
750 tree optype, op1, op2;
751 edge e12, e13, e23, e24, e34;
752 gimple_stmt_iterator gsi;
754 gcc_assert (is_gimple_assign (stmt)
755 && (gimple_assign_rhs_code (stmt) == TRUNC_DIV_EXPR
756 || gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR));
758 optype = TREE_TYPE (gimple_assign_lhs (stmt));
759 op1 = gimple_assign_rhs1 (stmt);
760 op2 = gimple_assign_rhs2 (stmt);
762 bb = gimple_bb (stmt);
763 gsi = gsi_for_stmt (stmt);
765 tmp0 = make_temp_ssa_name (optype, NULL, "PROF");
766 tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
767 stmt1 = gimple_build_assign (tmp0, fold_convert (optype, value));
768 stmt2 = gimple_build_assign (tmp1, op2);
769 stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
770 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
771 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
772 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
773 bb1end = stmt3;
775 tmp2 = create_tmp_reg (optype, "PROF");
776 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
777 op1, tmp0);
778 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
779 bb2end = stmt1;
781 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
782 op1, op2);
783 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
784 bb3end = stmt1;
786 /* Fix CFG. */
787 /* Edge e23 connects bb2 to bb3, etc. */
788 e12 = split_block (bb, bb1end);
789 bb2 = e12->dest;
790 bb2->count = count;
791 e23 = split_block (bb2, bb2end);
792 bb3 = e23->dest;
793 bb3->count = all - count;
794 e34 = split_block (bb3, bb3end);
795 bb4 = e34->dest;
796 bb4->count = all;
798 e12->flags &= ~EDGE_FALLTHRU;
799 e12->flags |= EDGE_FALSE_VALUE;
800 e12->probability = prob;
801 e12->count = count;
803 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
804 e13->probability = REG_BR_PROB_BASE - prob;
805 e13->count = all - count;
807 remove_edge (e23);
809 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
810 e24->probability = REG_BR_PROB_BASE;
811 e24->count = count;
813 e34->probability = REG_BR_PROB_BASE;
814 e34->count = all - count;
816 return tmp2;
820 /* Do transform 1) on INSN if applicable. */
822 static bool
823 gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
825 histogram_value histogram;
826 enum tree_code code;
827 gcov_type val, count, all;
828 tree result, value, tree_val;
829 gcov_type prob;
830 gimple stmt;
832 stmt = gsi_stmt (*si);
833 if (gimple_code (stmt) != GIMPLE_ASSIGN)
834 return false;
836 if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))))
837 return false;
839 code = gimple_assign_rhs_code (stmt);
841 if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
842 return false;
844 histogram = gimple_histogram_value_of_type (cfun, stmt,
845 HIST_TYPE_SINGLE_VALUE);
846 if (!histogram)
847 return false;
849 value = histogram->hvalue.value;
850 val = histogram->hvalue.counters[0];
851 count = histogram->hvalue.counters[1];
852 all = histogram->hvalue.counters[2];
853 gimple_remove_histogram_value (cfun, stmt, histogram);
855 /* We require that count is at least half of all; this means
856 that for the transformation to fire the value must be constant
857 at least 50% of time (and 75% gives the guarantee of usage). */
858 if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
859 || 2 * count < all
860 || optimize_bb_for_size_p (gimple_bb (stmt)))
861 return false;
863 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
864 return false;
866 /* Compute probability of taking the optimal path. */
867 if (all > 0)
868 prob = GCOV_COMPUTE_SCALE (count, all);
869 else
870 prob = 0;
872 if (sizeof (gcov_type) == sizeof (HOST_WIDE_INT))
873 tree_val = build_int_cst (get_gcov_type (), val);
874 else
876 HOST_WIDE_INT a[2];
877 a[0] = (unsigned HOST_WIDE_INT) val;
878 a[1] = val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1;
880 tree_val = wide_int_to_tree (get_gcov_type (), wide_int::from_array (a, 2,
881 TYPE_PRECISION (get_gcov_type ()), false));
883 result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all);
885 if (dump_file)
887 fprintf (dump_file, "Div/mod by constant ");
888 print_generic_expr (dump_file, value, TDF_SLIM);
889 fprintf (dump_file, "=");
890 print_generic_expr (dump_file, tree_val, TDF_SLIM);
891 fprintf (dump_file, " transformation on insn ");
892 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
895 gimple_assign_set_rhs_from_tree (si, result);
896 update_stmt (gsi_stmt (*si));
898 return true;
901 /* Generate code for transformation 2 (with parent gimple assign STMT and
902 probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
903 within roundoff error). This generates the result into a temp and returns
904 the temp; it does not replace or alter the original STMT. */
905 static tree
906 gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
908 gimple stmt1, stmt2, stmt3, stmt4;
909 tree tmp2, tmp3;
910 gimple bb1end, bb2end, bb3end;
911 basic_block bb, bb2, bb3, bb4;
912 tree optype, op1, op2;
913 edge e12, e13, e23, e24, e34;
914 gimple_stmt_iterator gsi;
915 tree result;
917 gcc_assert (is_gimple_assign (stmt)
918 && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
920 optype = TREE_TYPE (gimple_assign_lhs (stmt));
921 op1 = gimple_assign_rhs1 (stmt);
922 op2 = gimple_assign_rhs2 (stmt);
924 bb = gimple_bb (stmt);
925 gsi = gsi_for_stmt (stmt);
927 result = create_tmp_reg (optype, "PROF");
928 tmp2 = make_temp_ssa_name (optype, NULL, "PROF");
929 tmp3 = make_temp_ssa_name (optype, NULL, "PROF");
930 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2,
931 build_int_cst (optype, -1));
932 stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2);
933 stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0),
934 NULL_TREE, NULL_TREE);
935 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
936 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
937 gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
938 bb1end = stmt4;
940 /* tmp2 == op2-1 inherited from previous block. */
941 stmt1 = gimple_build_assign_with_ops (BIT_AND_EXPR, result, op1, tmp2);
942 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
943 bb2end = stmt1;
945 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
946 op1, op2);
947 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
948 bb3end = stmt1;
950 /* Fix CFG. */
951 /* Edge e23 connects bb2 to bb3, etc. */
952 e12 = split_block (bb, bb1end);
953 bb2 = e12->dest;
954 bb2->count = count;
955 e23 = split_block (bb2, bb2end);
956 bb3 = e23->dest;
957 bb3->count = all - count;
958 e34 = split_block (bb3, bb3end);
959 bb4 = e34->dest;
960 bb4->count = all;
962 e12->flags &= ~EDGE_FALLTHRU;
963 e12->flags |= EDGE_FALSE_VALUE;
964 e12->probability = prob;
965 e12->count = count;
967 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
968 e13->probability = REG_BR_PROB_BASE - prob;
969 e13->count = all - count;
971 remove_edge (e23);
973 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
974 e24->probability = REG_BR_PROB_BASE;
975 e24->count = count;
977 e34->probability = REG_BR_PROB_BASE;
978 e34->count = all - count;
980 return result;
983 /* Do transform 2) on INSN if applicable. */
984 static bool
985 gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
987 histogram_value histogram;
988 enum tree_code code;
989 gcov_type count, wrong_values, all;
990 tree lhs_type, result, value;
991 gcov_type prob;
992 gimple stmt;
994 stmt = gsi_stmt (*si);
995 if (gimple_code (stmt) != GIMPLE_ASSIGN)
996 return false;
998 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
999 if (!INTEGRAL_TYPE_P (lhs_type))
1000 return false;
1002 code = gimple_assign_rhs_code (stmt);
1004 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
1005 return false;
1007 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_POW2);
1008 if (!histogram)
1009 return false;
1011 value = histogram->hvalue.value;
1012 wrong_values = histogram->hvalue.counters[0];
1013 count = histogram->hvalue.counters[1];
1015 gimple_remove_histogram_value (cfun, stmt, histogram);
1017 /* We require that we hit a power of 2 at least half of all evaluations. */
1018 if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
1019 || count < wrong_values
1020 || optimize_bb_for_size_p (gimple_bb (stmt)))
1021 return false;
1023 if (dump_file)
1025 fprintf (dump_file, "Mod power of 2 transformation on insn ");
1026 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1029 /* Compute probability of taking the optimal path. */
1030 all = count + wrong_values;
1032 if (check_counter (stmt, "pow2", &count, &all, gimple_bb (stmt)->count))
1033 return false;
1035 if (all > 0)
1036 prob = GCOV_COMPUTE_SCALE (count, all);
1037 else
1038 prob = 0;
1040 result = gimple_mod_pow2 (stmt, prob, count, all);
1042 gimple_assign_set_rhs_from_tree (si, result);
1043 update_stmt (gsi_stmt (*si));
1045 return true;
1048 /* Generate code for transformations 3 and 4 (with parent gimple assign STMT, and
1049 NCOUNTS the number of cases to support. Currently only NCOUNTS==0 or 1 is
1050 supported and this is built into this interface. The probabilities of taking
1051 the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
1052 COUNT2/ALL respectively within roundoff error). This generates the
1053 result into a temp and returns the temp; it does not replace or alter
1054 the original STMT. */
1055 /* FIXME: Generalize the interface to handle NCOUNTS > 1. */
1057 static tree
1058 gimple_mod_subtract (gimple stmt, int prob1, int prob2, int ncounts,
1059 gcov_type count1, gcov_type count2, gcov_type all)
1061 gimple stmt1, stmt2, stmt3;
1062 tree tmp1;
1063 gimple bb1end, bb2end = NULL, bb3end;
1064 basic_block bb, bb2, bb3, bb4;
1065 tree optype, op1, op2;
1066 edge e12, e23 = 0, e24, e34, e14;
1067 gimple_stmt_iterator gsi;
1068 tree result;
1070 gcc_assert (is_gimple_assign (stmt)
1071 && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
1073 optype = TREE_TYPE (gimple_assign_lhs (stmt));
1074 op1 = gimple_assign_rhs1 (stmt);
1075 op2 = gimple_assign_rhs2 (stmt);
1077 bb = gimple_bb (stmt);
1078 gsi = gsi_for_stmt (stmt);
1080 result = create_tmp_reg (optype, "PROF");
1081 tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
1082 stmt1 = gimple_build_assign (result, op1);
1083 stmt2 = gimple_build_assign (tmp1, op2);
1084 stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
1085 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
1086 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
1087 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
1088 bb1end = stmt3;
1090 if (ncounts) /* Assumed to be 0 or 1 */
1092 stmt1 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, tmp1);
1093 stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
1094 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
1095 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
1096 bb2end = stmt2;
1099 /* Fallback case. */
1100 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
1101 result, tmp1);
1102 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
1103 bb3end = stmt1;
1105 /* Fix CFG. */
1106 /* Edge e23 connects bb2 to bb3, etc. */
1107 /* However block 3 is optional; if it is not there, references
1108 to 3 really refer to block 2. */
1109 e12 = split_block (bb, bb1end);
1110 bb2 = e12->dest;
1111 bb2->count = all - count1;
1113 if (ncounts) /* Assumed to be 0 or 1. */
1115 e23 = split_block (bb2, bb2end);
1116 bb3 = e23->dest;
1117 bb3->count = all - count1 - count2;
1120 e34 = split_block (ncounts ? bb3 : bb2, bb3end);
1121 bb4 = e34->dest;
1122 bb4->count = all;
1124 e12->flags &= ~EDGE_FALLTHRU;
1125 e12->flags |= EDGE_FALSE_VALUE;
1126 e12->probability = REG_BR_PROB_BASE - prob1;
1127 e12->count = all - count1;
1129 e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE);
1130 e14->probability = prob1;
1131 e14->count = count1;
1133 if (ncounts) /* Assumed to be 0 or 1. */
1135 e23->flags &= ~EDGE_FALLTHRU;
1136 e23->flags |= EDGE_FALSE_VALUE;
1137 e23->count = all - count1 - count2;
1138 e23->probability = REG_BR_PROB_BASE - prob2;
1140 e24 = make_edge (bb2, bb4, EDGE_TRUE_VALUE);
1141 e24->probability = prob2;
1142 e24->count = count2;
1145 e34->probability = REG_BR_PROB_BASE;
1146 e34->count = all - count1 - count2;
1148 return result;
1152 /* Do transforms 3) and 4) on the statement pointed-to by SI if applicable. */
1154 static bool
1155 gimple_mod_subtract_transform (gimple_stmt_iterator *si)
1157 histogram_value histogram;
1158 enum tree_code code;
1159 gcov_type count, wrong_values, all;
1160 tree lhs_type, result;
1161 gcov_type prob1, prob2;
1162 unsigned int i, steps;
1163 gcov_type count1, count2;
1164 gimple stmt;
1166 stmt = gsi_stmt (*si);
1167 if (gimple_code (stmt) != GIMPLE_ASSIGN)
1168 return false;
1170 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
1171 if (!INTEGRAL_TYPE_P (lhs_type))
1172 return false;
1174 code = gimple_assign_rhs_code (stmt);
1176 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
1177 return false;
1179 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INTERVAL);
1180 if (!histogram)
1181 return false;
1183 all = 0;
1184 wrong_values = 0;
1185 for (i = 0; i < histogram->hdata.intvl.steps; i++)
1186 all += histogram->hvalue.counters[i];
1188 wrong_values += histogram->hvalue.counters[i];
1189 wrong_values += histogram->hvalue.counters[i+1];
1190 steps = histogram->hdata.intvl.steps;
1191 all += wrong_values;
1192 count1 = histogram->hvalue.counters[0];
1193 count2 = histogram->hvalue.counters[1];
1195 /* Compute probability of taking the optimal path. */
1196 if (check_counter (stmt, "interval", &count1, &all, gimple_bb (stmt)->count))
1198 gimple_remove_histogram_value (cfun, stmt, histogram);
1199 return false;
1202 if (flag_profile_correction && count1 + count2 > all)
1203 all = count1 + count2;
1205 gcc_assert (count1 + count2 <= all);
1207 /* We require that we use just subtractions in at least 50% of all
1208 evaluations. */
1209 count = 0;
1210 for (i = 0; i < histogram->hdata.intvl.steps; i++)
1212 count += histogram->hvalue.counters[i];
1213 if (count * 2 >= all)
1214 break;
1216 if (i == steps
1217 || optimize_bb_for_size_p (gimple_bb (stmt)))
1218 return false;
1220 gimple_remove_histogram_value (cfun, stmt, histogram);
1221 if (dump_file)
1223 fprintf (dump_file, "Mod subtract transformation on insn ");
1224 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1227 /* Compute probability of taking the optimal path(s). */
1228 if (all > 0)
1230 prob1 = GCOV_COMPUTE_SCALE (count1, all);
1231 prob2 = GCOV_COMPUTE_SCALE (count2, all);
1233 else
1235 prob1 = prob2 = 0;
1238 /* In practice, "steps" is always 2. This interface reflects this,
1239 and will need to be changed if "steps" can change. */
1240 result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all);
1242 gimple_assign_set_rhs_from_tree (si, result);
1243 update_stmt (gsi_stmt (*si));
1245 return true;
1248 struct profile_id_traits : default_hashmap_traits
1250 template<typename T>
1251 static bool
1252 is_deleted (T &e)
1254 return e.m_key == UINT_MAX;
1257 template<typename T> static bool is_empty (T &e) { return e.m_key == 0; }
1258 template<typename T> static void mark_deleted (T &e) { e.m_key = UINT_MAX; }
1259 template<typename T> static void mark_empty (T &e) { e.m_key = 0; }
1262 static hash_map<unsigned int, cgraph_node *, profile_id_traits> *
1263 cgraph_node_map = 0;
1265 /* Returns true if node graph is initialized. This
1266 is used to test if profile_id has been created
1267 for cgraph_nodes. */
1269 bool
1270 coverage_node_map_initialized_p (void)
1272 return cgraph_node_map != 0;
1275 /* Initialize map from PROFILE_ID to CGRAPH_NODE.
1276 When LOCAL is true, the PROFILE_IDs are computed. when it is false we assume
1277 that the PROFILE_IDs was already assigned. */
1279 void
1280 init_node_map (bool local)
1282 struct cgraph_node *n;
1283 cgraph_node_map
1284 = new hash_map<unsigned int, cgraph_node *, profile_id_traits>;
1286 FOR_EACH_DEFINED_FUNCTION (n)
1287 if (n->has_gimple_body_p ())
1289 cgraph_node **val;
1290 if (local)
1292 n->profile_id = coverage_compute_profile_id (n);
1293 while ((val = cgraph_node_map->get (n->profile_id))
1294 || !n->profile_id)
1296 if (dump_file)
1297 fprintf (dump_file, "Local profile-id %i conflict"
1298 " with nodes %s/%i %s/%i\n",
1299 n->profile_id,
1300 n->name (),
1301 n->order,
1302 (*val)->name (),
1303 (*val)->order);
1304 n->profile_id = (n->profile_id + 1) & 0x7fffffff;
1307 else if (!n->profile_id)
1309 if (dump_file)
1310 fprintf (dump_file,
1311 "Node %s/%i has no profile-id"
1312 " (profile feedback missing?)\n",
1313 n->name (),
1314 n->order);
1315 continue;
1317 else if ((val = cgraph_node_map->get (n->profile_id)))
1319 if (dump_file)
1320 fprintf (dump_file,
1321 "Node %s/%i has IP profile-id %i conflict. "
1322 "Giving up.\n",
1323 n->name (),
1324 n->order,
1325 n->profile_id);
1326 *val = NULL;
1327 continue;
1329 cgraph_node_map->put (n->profile_id, n);
1333 /* Delete the CGRAPH_NODE_MAP. */
1335 void
1336 del_node_map (void)
1338 delete cgraph_node_map;
1341 /* Return cgraph node for function with pid */
1343 struct cgraph_node*
1344 find_func_by_profile_id (int profile_id)
1346 cgraph_node **val = cgraph_node_map->get (profile_id);
1347 if (val)
1348 return *val;
1349 else
1350 return NULL;
1353 /* Perform sanity check on the indirect call target. Due to race conditions,
1354 false function target may be attributed to an indirect call site. If the
1355 call expression type mismatches with the target function's type, expand_call
1356 may ICE. Here we only do very minimal sanity check just to make compiler happy.
1357 Returns true if TARGET is considered ok for call CALL_STMT. */
1359 bool
1360 check_ic_target (gimple call_stmt, struct cgraph_node *target)
1362 location_t locus;
1363 if (gimple_check_call_matching_types (call_stmt, target->decl, true))
1364 return true;
1366 locus = gimple_location (call_stmt);
1367 if (dump_enabled_p ())
1368 dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
1369 "Skipping target %s with mismatching types for icall\n",
1370 target->name ());
1371 return false;
1374 /* Do transformation
1376 if (actual_callee_address == address_of_most_common_function/method)
1377 do direct call
1378 else
1379 old call
1382 gimple
1383 gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
1384 int prob, gcov_type count, gcov_type all)
1386 gimple dcall_stmt, load_stmt, cond_stmt, iretbnd_stmt = NULL;
1387 tree tmp0, tmp1, tmp;
1388 basic_block cond_bb, dcall_bb, icall_bb, join_bb = NULL;
1389 tree optype = build_pointer_type (void_type_node);
1390 edge e_cd, e_ci, e_di, e_dj = NULL, e_ij;
1391 gimple_stmt_iterator gsi;
1392 int lp_nr, dflags;
1393 edge e_eh, e;
1394 edge_iterator ei;
1395 gimple_stmt_iterator psi;
1397 cond_bb = gimple_bb (icall_stmt);
1398 gsi = gsi_for_stmt (icall_stmt);
1400 if (gimple_call_with_bounds_p (icall_stmt) && gimple_call_lhs (icall_stmt))
1401 iretbnd_stmt = chkp_retbnd_call_by_val (gimple_call_lhs (icall_stmt));
1403 tmp0 = make_temp_ssa_name (optype, NULL, "PROF");
1404 tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
1405 tmp = unshare_expr (gimple_call_fn (icall_stmt));
1406 load_stmt = gimple_build_assign (tmp0, tmp);
1407 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
1409 tmp = fold_convert (optype, build_addr (direct_call->decl,
1410 current_function_decl));
1411 load_stmt = gimple_build_assign (tmp1, tmp);
1412 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
1414 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
1415 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
1417 gimple_set_vdef (icall_stmt, NULL_TREE);
1418 gimple_set_vuse (icall_stmt, NULL_TREE);
1419 update_stmt (icall_stmt);
1420 dcall_stmt = gimple_copy (icall_stmt);
1421 gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
1422 dflags = flags_from_decl_or_type (direct_call->decl);
1423 if ((dflags & ECF_NORETURN) != 0)
1424 gimple_call_set_lhs (dcall_stmt, NULL_TREE);
1425 gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
1427 /* Fix CFG. */
1428 /* Edge e_cd connects cond_bb to dcall_bb, etc; note the first letters. */
1429 e_cd = split_block (cond_bb, cond_stmt);
1430 dcall_bb = e_cd->dest;
1431 dcall_bb->count = count;
1433 e_di = split_block (dcall_bb, dcall_stmt);
1434 icall_bb = e_di->dest;
1435 icall_bb->count = all - count;
1437 /* Do not disturb existing EH edges from the indirect call. */
1438 if (!stmt_ends_bb_p (icall_stmt))
1439 e_ij = split_block (icall_bb, icall_stmt);
1440 else
1442 e_ij = find_fallthru_edge (icall_bb->succs);
1443 /* The indirect call might be noreturn. */
1444 if (e_ij != NULL)
1446 e_ij->probability = REG_BR_PROB_BASE;
1447 e_ij->count = all - count;
1448 e_ij = single_pred_edge (split_edge (e_ij));
1451 if (e_ij != NULL)
1453 join_bb = e_ij->dest;
1454 join_bb->count = all;
1457 e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
1458 e_cd->probability = prob;
1459 e_cd->count = count;
1461 e_ci = make_edge (cond_bb, icall_bb, EDGE_FALSE_VALUE);
1462 e_ci->probability = REG_BR_PROB_BASE - prob;
1463 e_ci->count = all - count;
1465 remove_edge (e_di);
1467 if (e_ij != NULL)
1469 if ((dflags & ECF_NORETURN) != 0)
1470 e_ij->count = all;
1471 else
1473 e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
1474 e_dj->probability = REG_BR_PROB_BASE;
1475 e_dj->count = count;
1477 e_ij->count = all - count;
1479 e_ij->probability = REG_BR_PROB_BASE;
1482 /* Insert PHI node for the call result if necessary. */
1483 if (gimple_call_lhs (icall_stmt)
1484 && TREE_CODE (gimple_call_lhs (icall_stmt)) == SSA_NAME
1485 && (dflags & ECF_NORETURN) == 0)
1487 tree result = gimple_call_lhs (icall_stmt);
1488 gimple phi = create_phi_node (result, join_bb);
1489 gimple_call_set_lhs (icall_stmt,
1490 duplicate_ssa_name (result, icall_stmt));
1491 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
1492 gimple_call_set_lhs (dcall_stmt,
1493 duplicate_ssa_name (result, dcall_stmt));
1494 add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION);
1496 /* If indirect call has following BUILT_IN_CHKP_BNDRET
1497 call then we need to make it's copy for the direct
1498 call. */
1499 if (iretbnd_stmt)
1501 if (gimple_call_lhs (iretbnd_stmt))
1503 gimple copy;
1505 gimple_set_vdef (iretbnd_stmt, NULL_TREE);
1506 gimple_set_vuse (iretbnd_stmt, NULL_TREE);
1507 update_stmt (iretbnd_stmt);
1509 result = gimple_call_lhs (iretbnd_stmt);
1510 phi = create_phi_node (result, join_bb);
1512 copy = gimple_copy (iretbnd_stmt);
1513 gimple_call_set_arg (copy, 0,
1514 gimple_call_lhs (dcall_stmt));
1515 gimple_call_set_lhs (copy, duplicate_ssa_name (result, copy));
1516 gsi_insert_on_edge (e_dj, copy);
1517 add_phi_arg (phi, gimple_call_lhs (copy),
1518 e_dj, UNKNOWN_LOCATION);
1520 gimple_call_set_arg (iretbnd_stmt, 0,
1521 gimple_call_lhs (icall_stmt));
1522 gimple_call_set_lhs (iretbnd_stmt,
1523 duplicate_ssa_name (result, iretbnd_stmt));
1524 psi = gsi_for_stmt (iretbnd_stmt);
1525 gsi_remove (&psi, false);
1526 gsi_insert_on_edge (e_ij, iretbnd_stmt);
1527 add_phi_arg (phi, gimple_call_lhs (iretbnd_stmt),
1528 e_ij, UNKNOWN_LOCATION);
1530 gsi_commit_one_edge_insert (e_dj, NULL);
1531 gsi_commit_one_edge_insert (e_ij, NULL);
1533 else
1535 psi = gsi_for_stmt (iretbnd_stmt);
1536 gsi_remove (&psi, true);
1541 /* Build an EH edge for the direct call if necessary. */
1542 lp_nr = lookup_stmt_eh_lp (icall_stmt);
1543 if (lp_nr > 0 && stmt_could_throw_p (dcall_stmt))
1545 add_stmt_to_eh_lp (dcall_stmt, lp_nr);
1548 FOR_EACH_EDGE (e_eh, ei, icall_bb->succs)
1549 if (e_eh->flags & (EDGE_EH | EDGE_ABNORMAL))
1551 e = make_edge (dcall_bb, e_eh->dest, e_eh->flags);
1552 for (psi = gsi_start_phis (e_eh->dest);
1553 !gsi_end_p (psi); gsi_next (&psi))
1555 gimple phi = gsi_stmt (psi);
1556 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e),
1557 PHI_ARG_DEF_FROM_EDGE (phi, e_eh));
1560 return dcall_stmt;
1564 For every checked indirect/virtual call determine if most common pid of
1565 function/class method has probability more than 50%. If yes modify code of
1566 this call to:
1569 static bool
1570 gimple_ic_transform (gimple_stmt_iterator *gsi)
1572 gimple stmt = gsi_stmt (*gsi);
1573 histogram_value histogram;
1574 gcov_type val, count, all, bb_all;
1575 struct cgraph_node *direct_call;
1577 if (gimple_code (stmt) != GIMPLE_CALL)
1578 return false;
1580 if (gimple_call_fndecl (stmt) != NULL_TREE)
1581 return false;
1583 if (gimple_call_internal_p (stmt))
1584 return false;
1586 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);
1587 if (!histogram)
1588 return false;
1590 val = histogram->hvalue.counters [0];
1591 count = histogram->hvalue.counters [1];
1592 all = histogram->hvalue.counters [2];
1594 bb_all = gimple_bb (stmt)->count;
1595 /* The order of CHECK_COUNTER calls is important -
1596 since check_counter can correct the third parameter
1597 and we want to make count <= all <= bb_all. */
1598 if ( check_counter (stmt, "ic", &all, &bb_all, bb_all)
1599 || check_counter (stmt, "ic", &count, &all, all))
1601 gimple_remove_histogram_value (cfun, stmt, histogram);
1602 return false;
1605 if (4 * count <= 3 * all)
1606 return false;
1608 direct_call = find_func_by_profile_id ((int)val);
1610 if (direct_call == NULL)
1612 if (val)
1614 if (dump_file)
1616 fprintf (dump_file, "Indirect call -> direct call from other module");
1617 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
1618 fprintf (dump_file, "=> %i (will resolve only with LTO)\n", (int)val);
1621 return false;
1624 if (!check_ic_target (stmt, direct_call))
1626 if (dump_file)
1628 fprintf (dump_file, "Indirect call -> direct call ");
1629 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
1630 fprintf (dump_file, "=> ");
1631 print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
1632 fprintf (dump_file, " transformation skipped because of type mismatch");
1633 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1635 gimple_remove_histogram_value (cfun, stmt, histogram);
1636 return false;
1639 if (dump_file)
1641 fprintf (dump_file, "Indirect call -> direct call ");
1642 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
1643 fprintf (dump_file, "=> ");
1644 print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
1645 fprintf (dump_file, " transformation on insn postponned to ipa-profile");
1646 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1647 fprintf (dump_file, "hist->count %"PRId64
1648 " hist->all %"PRId64"\n", count, all);
1651 return true;
1654 /* Return true if the stringop CALL with FNDECL shall be profiled.
1655 SIZE_ARG be set to the argument index for the size of the string
1656 operation.
1658 static bool
1659 interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg)
1661 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
1663 if (fcode != BUILT_IN_MEMCPY && fcode != BUILT_IN_MEMPCPY
1664 && fcode != BUILT_IN_MEMSET && fcode != BUILT_IN_BZERO)
1665 return false;
1667 switch (fcode)
1669 case BUILT_IN_MEMCPY:
1670 case BUILT_IN_MEMPCPY:
1671 *size_arg = 2;
1672 return validate_gimple_arglist (call, POINTER_TYPE, POINTER_TYPE,
1673 INTEGER_TYPE, VOID_TYPE);
1674 case BUILT_IN_MEMSET:
1675 *size_arg = 2;
1676 return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1677 INTEGER_TYPE, VOID_TYPE);
1678 case BUILT_IN_BZERO:
1679 *size_arg = 1;
1680 return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1681 VOID_TYPE);
1682 default:
1683 gcc_unreachable ();
1687 /* Convert stringop (..., vcall_size)
1688 into
1689 if (vcall_size == icall_size)
1690 stringop (..., icall_size);
1691 else
1692 stringop (..., vcall_size);
1693 assuming we'll propagate a true constant into ICALL_SIZE later. */
1695 static void
1696 gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
1697 gcov_type count, gcov_type all)
1699 gimple tmp_stmt, cond_stmt, icall_stmt;
1700 tree tmp0, tmp1, vcall_size, optype;
1701 basic_block cond_bb, icall_bb, vcall_bb, join_bb;
1702 edge e_ci, e_cv, e_iv, e_ij, e_vj;
1703 gimple_stmt_iterator gsi;
1704 tree fndecl;
1705 int size_arg;
1707 fndecl = gimple_call_fndecl (vcall_stmt);
1708 if (!interesting_stringop_to_profile_p (fndecl, vcall_stmt, &size_arg))
1709 gcc_unreachable ();
1711 cond_bb = gimple_bb (vcall_stmt);
1712 gsi = gsi_for_stmt (vcall_stmt);
1714 vcall_size = gimple_call_arg (vcall_stmt, size_arg);
1715 optype = TREE_TYPE (vcall_size);
1717 tmp0 = make_temp_ssa_name (optype, NULL, "PROF");
1718 tmp1 = make_temp_ssa_name (optype, NULL, "PROF");
1719 tmp_stmt = gimple_build_assign (tmp0, fold_convert (optype, icall_size));
1720 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
1722 tmp_stmt = gimple_build_assign (tmp1, vcall_size);
1723 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
1725 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
1726 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
1728 gimple_set_vdef (vcall_stmt, NULL);
1729 gimple_set_vuse (vcall_stmt, NULL);
1730 update_stmt (vcall_stmt);
1731 icall_stmt = gimple_copy (vcall_stmt);
1732 gimple_call_set_arg (icall_stmt, size_arg, icall_size);
1733 gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);
1735 /* Fix CFG. */
1736 /* Edge e_ci connects cond_bb to icall_bb, etc. */
1737 e_ci = split_block (cond_bb, cond_stmt);
1738 icall_bb = e_ci->dest;
1739 icall_bb->count = count;
1741 e_iv = split_block (icall_bb, icall_stmt);
1742 vcall_bb = e_iv->dest;
1743 vcall_bb->count = all - count;
1745 e_vj = split_block (vcall_bb, vcall_stmt);
1746 join_bb = e_vj->dest;
1747 join_bb->count = all;
1749 e_ci->flags = (e_ci->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
1750 e_ci->probability = prob;
1751 e_ci->count = count;
1753 e_cv = make_edge (cond_bb, vcall_bb, EDGE_FALSE_VALUE);
1754 e_cv->probability = REG_BR_PROB_BASE - prob;
1755 e_cv->count = all - count;
1757 remove_edge (e_iv);
1759 e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU);
1760 e_ij->probability = REG_BR_PROB_BASE;
1761 e_ij->count = count;
1763 e_vj->probability = REG_BR_PROB_BASE;
1764 e_vj->count = all - count;
1766 /* Insert PHI node for the call result if necessary. */
1767 if (gimple_call_lhs (vcall_stmt)
1768 && TREE_CODE (gimple_call_lhs (vcall_stmt)) == SSA_NAME)
1770 tree result = gimple_call_lhs (vcall_stmt);
1771 gimple phi = create_phi_node (result, join_bb);
1772 gimple_call_set_lhs (vcall_stmt,
1773 duplicate_ssa_name (result, vcall_stmt));
1774 add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION);
1775 gimple_call_set_lhs (icall_stmt,
1776 duplicate_ssa_name (result, icall_stmt));
1777 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
1780 /* Because these are all string op builtins, they're all nothrow. */
1781 gcc_assert (!stmt_could_throw_p (vcall_stmt));
1782 gcc_assert (!stmt_could_throw_p (icall_stmt));
1785 /* Find values inside STMT for that we want to measure histograms for
1786 division/modulo optimization. */
1787 static bool
1788 gimple_stringops_transform (gimple_stmt_iterator *gsi)
1790 gimple stmt = gsi_stmt (*gsi);
1791 tree fndecl;
1792 tree blck_size;
1793 enum built_in_function fcode;
1794 histogram_value histogram;
1795 gcov_type count, all, val;
1796 tree dest, src;
1797 unsigned int dest_align, src_align;
1798 gcov_type prob;
1799 tree tree_val;
1800 int size_arg;
1802 if (gimple_code (stmt) != GIMPLE_CALL)
1803 return false;
1804 fndecl = gimple_call_fndecl (stmt);
1805 if (!fndecl)
1806 return false;
1807 fcode = DECL_FUNCTION_CODE (fndecl);
1808 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
1809 return false;
1811 blck_size = gimple_call_arg (stmt, size_arg);
1812 if (TREE_CODE (blck_size) == INTEGER_CST)
1813 return false;
1815 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
1816 if (!histogram)
1817 return false;
1818 val = histogram->hvalue.counters[0];
1819 count = histogram->hvalue.counters[1];
1820 all = histogram->hvalue.counters[2];
1821 gimple_remove_histogram_value (cfun, stmt, histogram);
1822 /* We require that count is at least half of all; this means
1823 that for the transformation to fire the value must be constant
1824 at least 80% of time. */
1825 if ((6 * count / 5) < all || optimize_bb_for_size_p (gimple_bb (stmt)))
1826 return false;
1827 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
1828 return false;
1829 if (all > 0)
1830 prob = GCOV_COMPUTE_SCALE (count, all);
1831 else
1832 prob = 0;
1833 dest = gimple_call_arg (stmt, 0);
1834 dest_align = get_pointer_alignment (dest);
1835 switch (fcode)
1837 case BUILT_IN_MEMCPY:
1838 case BUILT_IN_MEMPCPY:
1839 src = gimple_call_arg (stmt, 1);
1840 src_align = get_pointer_alignment (src);
1841 if (!can_move_by_pieces (val, MIN (dest_align, src_align)))
1842 return false;
1843 break;
1844 case BUILT_IN_MEMSET:
1845 if (!can_store_by_pieces (val, builtin_memset_read_str,
1846 gimple_call_arg (stmt, 1),
1847 dest_align, true))
1848 return false;
1849 break;
1850 case BUILT_IN_BZERO:
1851 if (!can_store_by_pieces (val, builtin_memset_read_str,
1852 integer_zero_node,
1853 dest_align, true))
1854 return false;
1855 break;
1856 default:
1857 gcc_unreachable ();
1859 if (sizeof (gcov_type) == sizeof (HOST_WIDE_INT))
1860 tree_val = build_int_cst (get_gcov_type (), val);
1861 else
1863 HOST_WIDE_INT a[2];
1864 a[0] = (unsigned HOST_WIDE_INT) val;
1865 a[1] = val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1;
1867 tree_val = wide_int_to_tree (get_gcov_type (), wide_int::from_array (a, 2,
1868 TYPE_PRECISION (get_gcov_type ()), false));
1871 if (dump_file)
1873 fprintf (dump_file, "Single value %i stringop transformation on ",
1874 (int)val);
1875 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1877 gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
1879 return true;
1882 void
1883 stringop_block_profile (gimple stmt, unsigned int *expected_align,
1884 HOST_WIDE_INT *expected_size)
1886 histogram_value histogram;
1887 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE);
1888 if (!histogram)
1889 *expected_size = -1;
1890 else if (!histogram->hvalue.counters[1])
1892 *expected_size = -1;
1893 gimple_remove_histogram_value (cfun, stmt, histogram);
1895 else
1897 gcov_type size;
1898 size = ((histogram->hvalue.counters[0]
1899 + histogram->hvalue.counters[1] / 2)
1900 / histogram->hvalue.counters[1]);
1901 /* Even if we can hold bigger value in SIZE, INT_MAX
1902 is safe "infinity" for code generation strategies. */
1903 if (size > INT_MAX)
1904 size = INT_MAX;
1905 *expected_size = size;
1906 gimple_remove_histogram_value (cfun, stmt, histogram);
1908 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR);
1909 if (!histogram)
1910 *expected_align = 0;
1911 else if (!histogram->hvalue.counters[0])
1913 gimple_remove_histogram_value (cfun, stmt, histogram);
1914 *expected_align = 0;
1916 else
1918 gcov_type count;
1919 int alignment;
1921 count = histogram->hvalue.counters[0];
1922 alignment = 1;
1923 while (!(count & alignment)
1924 && (alignment * 2 * BITS_PER_UNIT))
1925 alignment <<= 1;
1926 *expected_align = alignment * BITS_PER_UNIT;
1927 gimple_remove_histogram_value (cfun, stmt, histogram);
1932 /* Find values inside STMT for that we want to measure histograms for
1933 division/modulo optimization. */
1934 static void
1935 gimple_divmod_values_to_profile (gimple stmt, histogram_values *values)
1937 tree lhs, divisor, op0, type;
1938 histogram_value hist;
1940 if (gimple_code (stmt) != GIMPLE_ASSIGN)
1941 return;
1943 lhs = gimple_assign_lhs (stmt);
1944 type = TREE_TYPE (lhs);
1945 if (!INTEGRAL_TYPE_P (type))
1946 return;
1948 switch (gimple_assign_rhs_code (stmt))
1950 case TRUNC_DIV_EXPR:
1951 case TRUNC_MOD_EXPR:
1952 divisor = gimple_assign_rhs2 (stmt);
1953 op0 = gimple_assign_rhs1 (stmt);
1955 values->reserve (3);
1957 if (TREE_CODE (divisor) == SSA_NAME)
1958 /* Check for the case where the divisor is the same value most
1959 of the time. */
1960 values->quick_push (gimple_alloc_histogram_value (cfun,
1961 HIST_TYPE_SINGLE_VALUE,
1962 stmt, divisor));
1964 /* For mod, check whether it is not often a noop (or replaceable by
1965 a few subtractions). */
1966 if (gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR
1967 && TYPE_UNSIGNED (type))
1969 tree val;
1970 /* Check for a special case where the divisor is power of 2. */
1971 values->quick_push (gimple_alloc_histogram_value (cfun,
1972 HIST_TYPE_POW2,
1973 stmt, divisor));
1975 val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
1976 hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
1977 stmt, val);
1978 hist->hdata.intvl.int_start = 0;
1979 hist->hdata.intvl.steps = 2;
1980 values->quick_push (hist);
1982 return;
1984 default:
1985 return;
1989 /* Find calls inside STMT for that we want to measure histograms for
1990 indirect/virtual call optimization. */
1992 static void
1993 gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
1995 tree callee;
1997 if (gimple_code (stmt) != GIMPLE_CALL
1998 || gimple_call_internal_p (stmt)
1999 || gimple_call_fndecl (stmt) != NULL_TREE)
2000 return;
2002 callee = gimple_call_fn (stmt);
2004 values->reserve (3);
2006 values->quick_push (gimple_alloc_histogram_value (
2007 cfun,
2008 PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
2009 HIST_TYPE_INDIR_CALL_TOPN :
2010 HIST_TYPE_INDIR_CALL,
2011 stmt, callee));
2013 return;
2016 /* Find values inside STMT for that we want to measure histograms for
2017 string operations. */
2018 static void
2019 gimple_stringops_values_to_profile (gimple stmt, histogram_values *values)
2021 tree fndecl;
2022 tree blck_size;
2023 tree dest;
2024 int size_arg;
2026 if (gimple_code (stmt) != GIMPLE_CALL)
2027 return;
2028 fndecl = gimple_call_fndecl (stmt);
2029 if (!fndecl)
2030 return;
2032 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
2033 return;
2035 dest = gimple_call_arg (stmt, 0);
2036 blck_size = gimple_call_arg (stmt, size_arg);
2038 if (TREE_CODE (blck_size) != INTEGER_CST)
2040 values->safe_push (gimple_alloc_histogram_value (cfun,
2041 HIST_TYPE_SINGLE_VALUE,
2042 stmt, blck_size));
2043 values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE,
2044 stmt, blck_size));
2046 if (TREE_CODE (blck_size) != INTEGER_CST)
2047 values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR,
2048 stmt, dest));
2051 /* Find values inside STMT for that we want to measure histograms and adds
2052 them to list VALUES. */
2054 static void
2055 gimple_values_to_profile (gimple stmt, histogram_values *values)
2057 gimple_divmod_values_to_profile (stmt, values);
2058 gimple_stringops_values_to_profile (stmt, values);
2059 gimple_indirect_call_to_profile (stmt, values);
2062 void
2063 gimple_find_values_to_profile (histogram_values *values)
2065 basic_block bb;
2066 gimple_stmt_iterator gsi;
2067 unsigned i;
2068 histogram_value hist = NULL;
2069 values->create (0);
2071 FOR_EACH_BB_FN (bb, cfun)
2072 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2073 gimple_values_to_profile (gsi_stmt (gsi), values);
2075 values->safe_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_TIME_PROFILE, 0, 0));
2077 FOR_EACH_VEC_ELT (*values, i, hist)
2079 switch (hist->type)
2081 case HIST_TYPE_INTERVAL:
2082 hist->n_counters = hist->hdata.intvl.steps + 2;
2083 break;
2085 case HIST_TYPE_POW2:
2086 hist->n_counters = 2;
2087 break;
2089 case HIST_TYPE_SINGLE_VALUE:
2090 hist->n_counters = 3;
2091 break;
2093 case HIST_TYPE_CONST_DELTA:
2094 hist->n_counters = 4;
2095 break;
2097 case HIST_TYPE_INDIR_CALL:
2098 hist->n_counters = 3;
2099 break;
2101 case HIST_TYPE_TIME_PROFILE:
2102 hist->n_counters = 1;
2103 break;
2105 case HIST_TYPE_AVERAGE:
2106 hist->n_counters = 2;
2107 break;
2109 case HIST_TYPE_IOR:
2110 hist->n_counters = 1;
2111 break;
2113 case HIST_TYPE_INDIR_CALL_TOPN:
2114 hist->n_counters = GCOV_ICALL_TOPN_NCOUNTS;
2115 break;
2117 default:
2118 gcc_unreachable ();
2120 if (dump_file)
2122 fprintf (dump_file, "Stmt ");
2123 print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM);
2124 dump_histogram_value (dump_file, hist);