]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/value-prof.c
* diagnostic-core.h: Include bversion.h.
[thirdparty/gcc.git] / gcc / value-prof.c
CommitLineData
d81602c4 1/* Transformations based on profile information for values.
ce084dfc 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
d81602c4 4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
8c4c00c1 9Software Foundation; either version 3, or (at your option) any later
d81602c4 10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
8c4c00c1 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
d81602c4 20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tm.h"
25#include "rtl.h"
26#include "expr.h"
27#include "hard-reg-set.h"
28#include "basic-block.h"
29#include "value-prof.h"
30#include "output.h"
31#include "flags.h"
32#include "insn-config.h"
33#include "recog.h"
34#include "optabs.h"
1c6a7b8c 35#include "regs.h"
8a5df2ce 36#include "ggc.h"
d2971487 37#include "tree-flow.h"
38#include "tree-flow-inline.h"
39#include "diagnostic.h"
ce084dfc 40#include "tree-pretty-print.h"
41#include "gimple-pretty-print.h"
b1b07349 42#include "coverage.h"
d2971487 43#include "tree.h"
44#include "gcov-io.h"
167b550b 45#include "cgraph.h"
77fce4cd 46#include "timevar.h"
47#include "tree-pass.h"
4992f399 48#include "pointer-set.h"
d81602c4 49
4ee9c684 50static struct value_prof_hooks *value_prof_hooks;
51
8a5df2ce 52/* In this file value profile based optimizations are placed. Currently the
53 following optimizations are implemented (for more detailed descriptions
54 see comments at value_profile_transformations):
55
597ff315 56 1) Division/modulo specialization. Provided that we can determine that the
8a5df2ce 57 operands of the division have some special properties, we may use it to
58 produce more effective code.
59 2) Speculative prefetching. If we are able to determine that the difference
60 between addresses accessed by a memory reference is usually constant, we
61 may add the prefetch instructions.
ed4294da 62 FIXME: This transformation was removed together with RTL based value
63 profiling.
d81602c4 64
167b550b 65 3) Indirect/virtual call specialization. If we can determine most
66 common function callee in indirect/virtual call. We can use this
0d424440 67 information to improve code effectiveness (especially info for
167b550b 68 inliner).
69
d81602c4 70 Every such optimization should add its requirements for profiled values to
71 insn_values_to_profile function. This function is called from branch_prob
72 in profile.c and the requested values are instrumented by it in the first
73 compilation with -fprofile-arcs. The optimization may then read the
91c82c20 74 gathered data in the second compilation with -fbranch-probabilities.
d2971487 75
ed4294da 76 The measured data is pointed to from the histograms
d2971487 77 field of the statement annotation of the instrumented insns. It is
78 kept as a linked list of struct histogram_value_t's, which contain the
79 same information as above. */
d81602c4 80
ed4294da 81
75a70cf9 82static tree gimple_divmod_fixed_value (gimple, tree, int, gcov_type, gcov_type);
83static tree gimple_mod_pow2 (gimple, int, gcov_type, gcov_type);
84static tree gimple_mod_subtract (gimple, int, int, int, gcov_type, gcov_type,
85 gcov_type);
86static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *);
87static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *);
88static bool gimple_mod_subtract_transform (gimple_stmt_iterator *);
89static bool gimple_stringops_transform (gimple_stmt_iterator *);
90static bool gimple_ic_transform (gimple);
d2971487 91
4992f399 92/* Allocate histogram value. */
93
94static histogram_value
95gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED,
75a70cf9 96 enum hist_type type, gimple stmt, tree value)
4992f399 97{
98 histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist));
99 hist->hvalue.value = value;
100 hist->hvalue.stmt = stmt;
101 hist->type = type;
102 return hist;
103}
104
105/* Hash value for histogram. */
106
107static hashval_t
108histogram_hash (const void *x)
109{
c1fdef8e 110 return htab_hash_pointer (((const_histogram_value)x)->hvalue.stmt);
4992f399 111}
112
113/* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */
114
115static int
116histogram_eq (const void *x, const void *y)
117{
75a70cf9 118 return ((const_histogram_value) x)->hvalue.stmt == (const_gimple) y;
4992f399 119}
120
121/* Set histogram for STMT. */
122
123static void
75a70cf9 124set_histogram_value (struct function *fun, gimple stmt, histogram_value hist)
4992f399 125{
126 void **loc;
127 if (!hist && !VALUE_HISTOGRAMS (fun))
128 return;
129 if (!VALUE_HISTOGRAMS (fun))
130 VALUE_HISTOGRAMS (fun) = htab_create (1, histogram_hash,
131 histogram_eq, NULL);
132 loc = htab_find_slot_with_hash (VALUE_HISTOGRAMS (fun), stmt,
133 htab_hash_pointer (stmt),
134 hist ? INSERT : NO_INSERT);
135 if (!hist)
136 {
137 if (loc)
138 htab_clear_slot (VALUE_HISTOGRAMS (fun), loc);
139 return;
140 }
141 *loc = hist;
142}
143
144/* Get histogram list for STMT. */
145
146histogram_value
75a70cf9 147gimple_histogram_value (struct function *fun, gimple stmt)
4992f399 148{
149 if (!VALUE_HISTOGRAMS (fun))
150 return NULL;
45ba1503 151 return (histogram_value) htab_find_with_hash (VALUE_HISTOGRAMS (fun), stmt,
152 htab_hash_pointer (stmt));
4992f399 153}
154
155/* Add histogram for STMT. */
156
157void
75a70cf9 158gimple_add_histogram_value (struct function *fun, gimple stmt,
159 histogram_value hist)
4992f399 160{
161 hist->hvalue.next = gimple_histogram_value (fun, stmt);
162 set_histogram_value (fun, stmt, hist);
163}
164
75a70cf9 165
4992f399 166/* Remove histogram HIST from STMT's histogram list. */
167
168void
75a70cf9 169gimple_remove_histogram_value (struct function *fun, gimple stmt,
170 histogram_value hist)
4992f399 171{
172 histogram_value hist2 = gimple_histogram_value (fun, stmt);
173 if (hist == hist2)
174 {
175 set_histogram_value (fun, stmt, hist->hvalue.next);
176 }
177 else
178 {
179 while (hist2->hvalue.next != hist)
180 hist2 = hist2->hvalue.next;
181 hist2->hvalue.next = hist->hvalue.next;
182 }
183 free (hist->hvalue.counters);
184#ifdef ENABLE_CHECKING
185 memset (hist, 0xab, sizeof (*hist));
186#endif
187 free (hist);
188}
189
75a70cf9 190
4992f399 191/* Lookup histogram of type TYPE in the STMT. */
192
193histogram_value
75a70cf9 194gimple_histogram_value_of_type (struct function *fun, gimple stmt,
195 enum hist_type type)
4992f399 196{
197 histogram_value hist;
75a70cf9 198 for (hist = gimple_histogram_value (fun, stmt); hist;
199 hist = hist->hvalue.next)
4992f399 200 if (hist->type == type)
201 return hist;
202 return NULL;
203}
204
205/* Dump information about HIST to DUMP_FILE. */
206
207static void
208dump_histogram_value (FILE *dump_file, histogram_value hist)
209{
210 switch (hist->type)
211 {
212 case HIST_TYPE_INTERVAL:
213 fprintf (dump_file, "Interval counter range %d -- %d",
214 hist->hdata.intvl.int_start,
215 (hist->hdata.intvl.int_start
216 + hist->hdata.intvl.steps - 1));
217 if (hist->hvalue.counters)
218 {
219 unsigned int i;
220 fprintf(dump_file, " [");
221 for (i = 0; i < hist->hdata.intvl.steps; i++)
222 fprintf (dump_file, " %d:"HOST_WIDEST_INT_PRINT_DEC,
223 hist->hdata.intvl.int_start + i,
224 (HOST_WIDEST_INT) hist->hvalue.counters[i]);
225 fprintf (dump_file, " ] outside range:"HOST_WIDEST_INT_PRINT_DEC,
226 (HOST_WIDEST_INT) hist->hvalue.counters[i]);
227 }
228 fprintf (dump_file, ".\n");
229 break;
230
231 case HIST_TYPE_POW2:
232 fprintf (dump_file, "Pow2 counter ");
233 if (hist->hvalue.counters)
234 {
235 fprintf (dump_file, "pow2:"HOST_WIDEST_INT_PRINT_DEC
236 " nonpow2:"HOST_WIDEST_INT_PRINT_DEC,
237 (HOST_WIDEST_INT) hist->hvalue.counters[0],
238 (HOST_WIDEST_INT) hist->hvalue.counters[1]);
239 }
240 fprintf (dump_file, ".\n");
241 break;
242
243 case HIST_TYPE_SINGLE_VALUE:
244 fprintf (dump_file, "Single value ");
245 if (hist->hvalue.counters)
246 {
247 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
248 " match:"HOST_WIDEST_INT_PRINT_DEC
249 " wrong:"HOST_WIDEST_INT_PRINT_DEC,
250 (HOST_WIDEST_INT) hist->hvalue.counters[0],
251 (HOST_WIDEST_INT) hist->hvalue.counters[1],
252 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
253 }
254 fprintf (dump_file, ".\n");
255 break;
256
162719b3 257 case HIST_TYPE_AVERAGE:
258 fprintf (dump_file, "Average value ");
259 if (hist->hvalue.counters)
260 {
261 fprintf (dump_file, "sum:"HOST_WIDEST_INT_PRINT_DEC
262 " times:"HOST_WIDEST_INT_PRINT_DEC,
263 (HOST_WIDEST_INT) hist->hvalue.counters[0],
264 (HOST_WIDEST_INT) hist->hvalue.counters[1]);
265 }
266 fprintf (dump_file, ".\n");
267 break;
268
269 case HIST_TYPE_IOR:
270 fprintf (dump_file, "IOR value ");
271 if (hist->hvalue.counters)
272 {
273 fprintf (dump_file, "ior:"HOST_WIDEST_INT_PRINT_DEC,
274 (HOST_WIDEST_INT) hist->hvalue.counters[0]);
275 }
276 fprintf (dump_file, ".\n");
277 break;
278
4992f399 279 case HIST_TYPE_CONST_DELTA:
280 fprintf (dump_file, "Constant delta ");
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;
167b550b 292 case HIST_TYPE_INDIR_CALL:
293 fprintf (dump_file, "Indirect call ");
294 if (hist->hvalue.counters)
295 {
296 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
297 " match:"HOST_WIDEST_INT_PRINT_DEC
298 " all:"HOST_WIDEST_INT_PRINT_DEC,
299 (HOST_WIDEST_INT) hist->hvalue.counters[0],
300 (HOST_WIDEST_INT) hist->hvalue.counters[1],
301 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
302 }
303 fprintf (dump_file, ".\n");
304 break;
4992f399 305 }
306}
307
308/* Dump all histograms attached to STMT to DUMP_FILE. */
309
310void
75a70cf9 311dump_histograms_for_stmt (struct function *fun, FILE *dump_file, gimple stmt)
4992f399 312{
313 histogram_value hist;
314 for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
315 dump_histogram_value (dump_file, hist);
316}
317
318/* Remove all histograms associated with STMT. */
319
320void
75a70cf9 321gimple_remove_stmt_histograms (struct function *fun, gimple stmt)
4992f399 322{
323 histogram_value val;
324 while ((val = gimple_histogram_value (fun, stmt)) != NULL)
325 gimple_remove_histogram_value (fun, stmt, val);
326}
327
328/* Duplicate all histograms associates with OSTMT to STMT. */
329
330void
75a70cf9 331gimple_duplicate_stmt_histograms (struct function *fun, gimple stmt,
332 struct function *ofun, gimple ostmt)
4992f399 333{
334 histogram_value val;
335 for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next)
336 {
f4e36c33 337 histogram_value new_val = gimple_alloc_histogram_value (fun, val->type, NULL, NULL);
338 memcpy (new_val, val, sizeof (*val));
339 new_val->hvalue.stmt = stmt;
340 new_val->hvalue.counters = XNEWVAR (gcov_type, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
341 memcpy (new_val->hvalue.counters, val->hvalue.counters, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
342 gimple_add_histogram_value (fun, stmt, new_val);
4992f399 343 }
344}
345
69eee21d 346
347/* Move all histograms associated with OSTMT to STMT. */
348
349void
75a70cf9 350gimple_move_stmt_histograms (struct function *fun, gimple stmt, gimple ostmt)
69eee21d 351{
352 histogram_value val = gimple_histogram_value (fun, ostmt);
353 if (val)
354 {
355 /* The following three statements can't be reordered,
356 because histogram hashtab relies on stmt field value
357 for finding the exact slot. */
358 set_histogram_value (fun, ostmt, NULL);
359 for (; val != NULL; val = val->hvalue.next)
360 val->hvalue.stmt = stmt;
361 set_histogram_value (fun, stmt, val);
362 }
363}
364
4992f399 365static bool error_found = false;
366
367/* Helper function for verify_histograms. For each histogram reachable via htab
368 walk verify that it was reached via statement walk. */
369
370static int
371visit_hist (void **slot, void *data)
372{
373 struct pointer_set_t *visited = (struct pointer_set_t *) data;
374 histogram_value hist = *(histogram_value *) slot;
375 if (!pointer_set_contains (visited, hist))
376 {
bf776685 377 error ("dead histogram");
4992f399 378 dump_histogram_value (stderr, hist);
75a70cf9 379 debug_gimple_stmt (hist->hvalue.stmt);
4992f399 380 error_found = true;
381 }
a63f3f1d 382 return 1;
4992f399 383}
384
75a70cf9 385
4992f399 386/* Verify sanity of the histograms. */
387
4b987fac 388DEBUG_FUNCTION void
4992f399 389verify_histograms (void)
390{
391 basic_block bb;
75a70cf9 392 gimple_stmt_iterator gsi;
4992f399 393 histogram_value hist;
394 struct pointer_set_t *visited_hists;
395
396 error_found = false;
397 visited_hists = pointer_set_create ();
398 FOR_EACH_BB (bb)
75a70cf9 399 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4992f399 400 {
75a70cf9 401 gimple stmt = gsi_stmt (gsi);
4992f399 402
75a70cf9 403 for (hist = gimple_histogram_value (cfun, stmt); hist;
404 hist = hist->hvalue.next)
4992f399 405 {
406 if (hist->hvalue.stmt != stmt)
407 {
75a70cf9 408 error ("Histogram value statement does not correspond to "
409 "the statement it is associated with");
410 debug_gimple_stmt (stmt);
4992f399 411 dump_histogram_value (stderr, hist);
412 error_found = true;
413 }
414 pointer_set_insert (visited_hists, hist);
415 }
416 }
417 if (VALUE_HISTOGRAMS (cfun))
418 htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, visited_hists);
419 pointer_set_destroy (visited_hists);
420 if (error_found)
421 internal_error ("verify_histograms failed");
422}
423
424/* Helper function for verify_histograms. For each histogram reachable via htab
425 walk verify that it was reached via statement walk. */
426
427static int
428free_hist (void **slot, void *data ATTRIBUTE_UNUSED)
429{
430 histogram_value hist = *(histogram_value *) slot;
431 free (hist->hvalue.counters);
432#ifdef ENABLE_CHECKING
433 memset (hist, 0xab, sizeof (*hist));
434#endif
435 free (hist);
a63f3f1d 436 return 1;
4992f399 437}
438
439void
440free_histograms (void)
441{
442 if (VALUE_HISTOGRAMS (cfun))
443 {
444 htab_traverse (VALUE_HISTOGRAMS (cfun), free_hist, NULL);
445 htab_delete (VALUE_HISTOGRAMS (cfun));
446 VALUE_HISTOGRAMS (cfun) = NULL;
447 }
448}
449
75a70cf9 450
451/* The overall number of invocations of the counter should match
452 execution count of basic block. Report it as error rather than
453 internal error as it might mean that user has misused the profile
454 somehow. */
455
2ca9602a 456static bool
e0dc6f2b 457check_counter (gimple stmt, const char * name,
458 gcov_type *count, gcov_type *all, gcov_type bb_count)
2ca9602a 459{
e0dc6f2b 460 if (*all != bb_count || *count > *all)
2ca9602a 461 {
75a70cf9 462 location_t locus;
463 locus = (stmt != NULL)
e0dc6f2b 464 ? gimple_location (stmt)
465 : DECL_SOURCE_LOCATION (current_function_decl);
466 if (flag_profile_correction)
467 {
bf776685 468 inform (locus, "correcting inconsistent value profile: "
e0dc6f2b 469 "%s profiler overall count (%d) does not match BB count "
32fc3782 470 "(%d)", name, (int)*all, (int)bb_count);
e0dc6f2b 471 *all = bb_count;
472 if (*count > *all)
473 *count = *all;
474 return false;
475 }
476 else
477 {
bf776685 478 error_at (locus, "corrupted value profile: %s "
5fb6a912 479 "profiler overall count (%d) does not match BB count (%d)",
480 name, (int)*all, (int)bb_count);
e0dc6f2b 481 return true;
482 }
2ca9602a 483 }
75a70cf9 484
2ca9602a 485 return false;
486}
487
75a70cf9 488
489/* GIMPLE based transformations. */
490
d2971487 491static bool
75a70cf9 492gimple_value_profile_transformations (void)
d2971487 493{
494 basic_block bb;
75a70cf9 495 gimple_stmt_iterator gsi;
d2971487 496 bool changed = false;
497
498 FOR_EACH_BB (bb)
499 {
75a70cf9 500 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
d2971487 501 {
75a70cf9 502 gimple stmt = gsi_stmt (gsi);
4992f399 503 histogram_value th = gimple_histogram_value (cfun, stmt);
d2971487 504 if (!th)
505 continue;
506
507 if (dump_file)
508 {
4992f399 509 fprintf (dump_file, "Trying transformations on stmt ");
75a70cf9 510 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
4992f399 511 dump_histograms_for_stmt (cfun, dump_file, stmt);
d2971487 512 }
513
514 /* Transformations: */
515 /* The order of things in this conditional controls which
516 transformation is used when more than one is applicable. */
517 /* It is expected that any code added by the transformations
518 will be added before the current statement, and that the
519 current statement remain valid (although possibly
520 modified) upon return. */
521 if (flag_value_profile_transformations
75a70cf9 522 && (gimple_mod_subtract_transform (&gsi)
523 || gimple_divmod_fixed_value_transform (&gsi)
524 || gimple_mod_pow2_value_transform (&gsi)
525 || gimple_stringops_transform (&gsi)
526 || gimple_ic_transform (stmt)))
d2971487 527 {
75a70cf9 528 stmt = gsi_stmt (gsi);
d2971487 529 changed = true;
530 /* Original statement may no longer be in the same block. */
75a70cf9 531 if (bb != gimple_bb (stmt))
e3a1de9d 532 {
75a70cf9 533 bb = gimple_bb (stmt);
534 gsi = gsi_for_stmt (stmt);
e3a1de9d 535 }
d2971487 536 }
d2971487 537 }
538 }
539
540 if (changed)
541 {
542 counts_to_freqs ();
543 }
544
545 return changed;
546}
547
75a70cf9 548
549/* Generate code for transformation 1 (with parent gimple assignment
550 STMT and probability of taking the optimal path PROB, which is
551 equivalent to COUNT/ALL within roundoff error). This generates the
552 result into a temp and returns the temp; it does not replace or
553 alter the original STMT. */
554
d2971487 555static tree
75a70cf9 556gimple_divmod_fixed_value (gimple stmt, tree value, int prob, gcov_type count,
557 gcov_type all)
d2971487 558{
0acacf9e 559 gimple stmt1, stmt2, stmt3;
85344eeb 560 tree tmp0, tmp1, tmp2, tmpv;
75a70cf9 561 gimple bb1end, bb2end, bb3end;
d2971487 562 basic_block bb, bb2, bb3, bb4;
75a70cf9 563 tree optype, op1, op2;
d2971487 564 edge e12, e13, e23, e24, e34;
75a70cf9 565 gimple_stmt_iterator gsi;
566
567 gcc_assert (is_gimple_assign (stmt)
568 && (gimple_assign_rhs_code (stmt) == TRUNC_DIV_EXPR
569 || gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR));
570
571 optype = TREE_TYPE (gimple_assign_lhs (stmt));
572 op1 = gimple_assign_rhs1 (stmt);
573 op2 = gimple_assign_rhs2 (stmt);
d2971487 574
75a70cf9 575 bb = gimple_bb (stmt);
576 gsi = gsi_for_stmt (stmt);
d2971487 577
85344eeb 578 tmpv = create_tmp_reg (optype, "PROF");
579 tmp0 = make_ssa_name (tmpv, NULL);
580 tmp1 = make_ssa_name (tmpv, NULL);
581 stmt1 = gimple_build_assign (tmp0, fold_convert (optype, value));
582 SSA_NAME_DEF_STMT (tmp0) = stmt1;
75a70cf9 583 stmt2 = gimple_build_assign (tmp1, op2);
85344eeb 584 SSA_NAME_DEF_STMT (tmp1) = stmt2;
585 stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
75a70cf9 586 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
587 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
588 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
d2971487 589 bb1end = stmt3;
590
85344eeb 591 tmp2 = make_rename_temp (optype, "PROF");
75a70cf9 592 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
85344eeb 593 op1, tmp0);
75a70cf9 594 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
d2971487 595 bb2end = stmt1;
596
75a70cf9 597 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
598 op1, op2);
75a70cf9 599 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
d2971487 600 bb3end = stmt1;
601
d2971487 602 /* Fix CFG. */
603 /* Edge e23 connects bb2 to bb3, etc. */
604 e12 = split_block (bb, bb1end);
605 bb2 = e12->dest;
606 bb2->count = count;
607 e23 = split_block (bb2, bb2end);
608 bb3 = e23->dest;
609 bb3->count = all - count;
610 e34 = split_block (bb3, bb3end);
611 bb4 = e34->dest;
612 bb4->count = all;
613
614 e12->flags &= ~EDGE_FALLTHRU;
615 e12->flags |= EDGE_FALSE_VALUE;
616 e12->probability = prob;
617 e12->count = count;
618
619 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
620 e13->probability = REG_BR_PROB_BASE - prob;
621 e13->count = all - count;
622
623 remove_edge (e23);
48e1416a 624
d2971487 625 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
626 e24->probability = REG_BR_PROB_BASE;
627 e24->count = count;
628
629 e34->probability = REG_BR_PROB_BASE;
630 e34->count = all - count;
631
632 return tmp2;
633}
634
75a70cf9 635
d2971487 636/* Do transform 1) on INSN if applicable. */
75a70cf9 637
d2971487 638static bool
75a70cf9 639gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
d2971487 640{
d2971487 641 histogram_value histogram;
642 enum tree_code code;
643 gcov_type val, count, all;
75a70cf9 644 tree result, value, tree_val;
5b17b7ae 645 gcov_type prob;
75a70cf9 646 gimple stmt;
d2971487 647
75a70cf9 648 stmt = gsi_stmt (*si);
649 if (gimple_code (stmt) != GIMPLE_ASSIGN)
d2971487 650 return false;
75a70cf9 651
652 if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))))
d2971487 653 return false;
75a70cf9 654
655 code = gimple_assign_rhs_code (stmt);
48e1416a 656
d2971487 657 if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
658 return false;
659
75a70cf9 660 histogram = gimple_histogram_value_of_type (cfun, stmt,
661 HIST_TYPE_SINGLE_VALUE);
d2971487 662 if (!histogram)
663 return false;
664
ed4294da 665 value = histogram->hvalue.value;
666 val = histogram->hvalue.counters[0];
667 count = histogram->hvalue.counters[1];
668 all = histogram->hvalue.counters[2];
4992f399 669 gimple_remove_histogram_value (cfun, stmt, histogram);
d2971487 670
671 /* We require that count is at least half of all; this means
672 that for the transformation to fire the value must be constant
673 at least 50% of time (and 75% gives the guarantee of usage). */
75a70cf9 674 if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
675 || 2 * count < all
0bfd8d5c 676 || optimize_bb_for_size_p (gimple_bb (stmt)))
d2971487 677 return false;
678
e0dc6f2b 679 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
2ca9602a 680 return false;
681
d2971487 682 /* Compute probability of taking the optimal path. */
5b17b7ae 683 if (all > 0)
684 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
685 else
686 prob = 0;
d2971487 687
8aa35772 688 tree_val = build_int_cst_wide (get_gcov_type (),
0346372d 689 (unsigned HOST_WIDE_INT) val,
690 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
75a70cf9 691 result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all);
d2971487 692
421e19dd 693 if (dump_file)
694 {
695 fprintf (dump_file, "Div/mod by constant ");
696 print_generic_expr (dump_file, value, TDF_SLIM);
697 fprintf (dump_file, "=");
698 print_generic_expr (dump_file, tree_val, TDF_SLIM);
699 fprintf (dump_file, " transformation on insn ");
75a70cf9 700 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
421e19dd 701 }
702
75a70cf9 703 gimple_assign_set_rhs_from_tree (si, result);
4b7a4b97 704 update_stmt (gsi_stmt (*si));
d2971487 705
706 return true;
707}
708
75a70cf9 709/* Generate code for transformation 2 (with parent gimple assign STMT and
710 probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
48e1416a 711 within roundoff error). This generates the result into a temp and returns
d2971487 712 the temp; it does not replace or alter the original STMT. */
713static tree
75a70cf9 714gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
d2971487 715{
75a70cf9 716 gimple stmt1, stmt2, stmt3, stmt4;
85344eeb 717 tree tmp2, tmp3, tmpv;
75a70cf9 718 gimple bb1end, bb2end, bb3end;
d2971487 719 basic_block bb, bb2, bb3, bb4;
75a70cf9 720 tree optype, op1, op2;
d2971487 721 edge e12, e13, e23, e24, e34;
75a70cf9 722 gimple_stmt_iterator gsi;
723 tree result;
d2971487 724
75a70cf9 725 gcc_assert (is_gimple_assign (stmt)
726 && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
d2971487 727
75a70cf9 728 optype = TREE_TYPE (gimple_assign_lhs (stmt));
729 op1 = gimple_assign_rhs1 (stmt);
730 op2 = gimple_assign_rhs2 (stmt);
731
732 bb = gimple_bb (stmt);
733 gsi = gsi_for_stmt (stmt);
734
85344eeb 735 result = make_rename_temp (optype, "PROF");
736 tmpv = create_tmp_var (optype, "PROF");
737 tmp2 = make_ssa_name (tmpv, NULL);
738 tmp3 = make_ssa_name (tmpv, NULL);
75a70cf9 739 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2,
740 build_int_cst (optype, -1));
85344eeb 741 SSA_NAME_DEF_STMT (tmp2) = stmt2;
75a70cf9 742 stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2);
85344eeb 743 SSA_NAME_DEF_STMT (tmp3) = stmt3;
75a70cf9 744 stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0),
745 NULL_TREE, NULL_TREE);
746 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
747 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
748 gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
d2971487 749 bb1end = stmt4;
750
75a70cf9 751 /* tmp2 == op2-1 inherited from previous block. */
75a70cf9 752 stmt1 = gimple_build_assign_with_ops (BIT_AND_EXPR, result, op1, tmp2);
75a70cf9 753 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
d2971487 754 bb2end = stmt1;
755
75a70cf9 756 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
757 op1, op2);
75a70cf9 758 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
d2971487 759 bb3end = stmt1;
760
d2971487 761 /* Fix CFG. */
762 /* Edge e23 connects bb2 to bb3, etc. */
763 e12 = split_block (bb, bb1end);
764 bb2 = e12->dest;
765 bb2->count = count;
766 e23 = split_block (bb2, bb2end);
767 bb3 = e23->dest;
768 bb3->count = all - count;
769 e34 = split_block (bb3, bb3end);
770 bb4 = e34->dest;
771 bb4->count = all;
772
773 e12->flags &= ~EDGE_FALLTHRU;
774 e12->flags |= EDGE_FALSE_VALUE;
775 e12->probability = prob;
776 e12->count = count;
777
778 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
779 e13->probability = REG_BR_PROB_BASE - prob;
780 e13->count = all - count;
781
782 remove_edge (e23);
48e1416a 783
d2971487 784 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
785 e24->probability = REG_BR_PROB_BASE;
786 e24->count = count;
787
788 e34->probability = REG_BR_PROB_BASE;
789 e34->count = all - count;
790
791 return result;
792}
793
794/* Do transform 2) on INSN if applicable. */
795static bool
75a70cf9 796gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
d2971487 797{
d2971487 798 histogram_value histogram;
799 enum tree_code code;
800 gcov_type count, wrong_values, all;
75a70cf9 801 tree lhs_type, result, value;
5b17b7ae 802 gcov_type prob;
75a70cf9 803 gimple stmt;
d2971487 804
75a70cf9 805 stmt = gsi_stmt (*si);
806 if (gimple_code (stmt) != GIMPLE_ASSIGN)
d2971487 807 return false;
75a70cf9 808
809 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
810 if (!INTEGRAL_TYPE_P (lhs_type))
d2971487 811 return false;
75a70cf9 812
813 code = gimple_assign_rhs_code (stmt);
48e1416a 814
75a70cf9 815 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
d2971487 816 return false;
817
4992f399 818 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_POW2);
d2971487 819 if (!histogram)
820 return false;
821
ed4294da 822 value = histogram->hvalue.value;
823 wrong_values = histogram->hvalue.counters[0];
824 count = histogram->hvalue.counters[1];
d2971487 825
4992f399 826 gimple_remove_histogram_value (cfun, stmt, histogram);
827
d2971487 828 /* We require that we hit a power of 2 at least half of all evaluations. */
75a70cf9 829 if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
830 || count < wrong_values
0bfd8d5c 831 || optimize_bb_for_size_p (gimple_bb (stmt)))
d2971487 832 return false;
833
834 if (dump_file)
835 {
836 fprintf (dump_file, "Mod power of 2 transformation on insn ");
75a70cf9 837 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
d2971487 838 }
839
840 /* Compute probability of taking the optimal path. */
841 all = count + wrong_values;
4992f399 842
e0dc6f2b 843 if (check_counter (stmt, "pow2", &count, &all, gimple_bb (stmt)->count))
2ca9602a 844 return false;
845
5b17b7ae 846 if (all > 0)
847 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
848 else
849 prob = 0;
d2971487 850
75a70cf9 851 result = gimple_mod_pow2 (stmt, prob, count, all);
d2971487 852
75a70cf9 853 gimple_assign_set_rhs_from_tree (si, result);
4b7a4b97 854 update_stmt (gsi_stmt (*si));
d2971487 855
856 return true;
857}
858
75a70cf9 859/* Generate code for transformations 3 and 4 (with parent gimple assign STMT, and
860 NCOUNTS the number of cases to support. Currently only NCOUNTS==0 or 1 is
861 supported and this is built into this interface. The probabilities of taking
862 the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
48e1416a 863 COUNT2/ALL respectively within roundoff error). This generates the
864 result into a temp and returns the temp; it does not replace or alter
d2971487 865 the original STMT. */
866/* FIXME: Generalize the interface to handle NCOUNTS > 1. */
867
868static tree
75a70cf9 869gimple_mod_subtract (gimple stmt, int prob1, int prob2, int ncounts,
870 gcov_type count1, gcov_type count2, gcov_type all)
d2971487 871{
75a70cf9 872 gimple stmt1, stmt2, stmt3;
d2971487 873 tree tmp1;
75a70cf9 874 gimple bb1end, bb2end = NULL, bb3end;
d2971487 875 basic_block bb, bb2, bb3, bb4;
75a70cf9 876 tree optype, op1, op2;
d2971487 877 edge e12, e23 = 0, e24, e34, e14;
75a70cf9 878 gimple_stmt_iterator gsi;
879 tree result;
880
881 gcc_assert (is_gimple_assign (stmt)
882 && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
d2971487 883
75a70cf9 884 optype = TREE_TYPE (gimple_assign_lhs (stmt));
885 op1 = gimple_assign_rhs1 (stmt);
886 op2 = gimple_assign_rhs2 (stmt);
d2971487 887
75a70cf9 888 bb = gimple_bb (stmt);
889 gsi = gsi_for_stmt (stmt);
890
85344eeb 891 result = make_rename_temp (optype, "PROF");
892 tmp1 = make_ssa_name (create_tmp_var (optype, "PROF"), NULL);
75a70cf9 893 stmt1 = gimple_build_assign (result, op1);
894 stmt2 = gimple_build_assign (tmp1, op2);
85344eeb 895 SSA_NAME_DEF_STMT (tmp1) = stmt2;
75a70cf9 896 stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
897 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
898 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
899 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
d2971487 900 bb1end = stmt3;
901
902 if (ncounts) /* Assumed to be 0 or 1 */
903 {
75a70cf9 904 stmt1 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, tmp1);
905 stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
75a70cf9 906 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
907 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
d2971487 908 bb2end = stmt2;
909 }
910
911 /* Fallback case. */
75a70cf9 912 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
913 result, tmp1);
75a70cf9 914 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
d2971487 915 bb3end = stmt1;
916
d2971487 917 /* Fix CFG. */
918 /* Edge e23 connects bb2 to bb3, etc. */
919 /* However block 3 is optional; if it is not there, references
920 to 3 really refer to block 2. */
921 e12 = split_block (bb, bb1end);
922 bb2 = e12->dest;
923 bb2->count = all - count1;
48e1416a 924
d2971487 925 if (ncounts) /* Assumed to be 0 or 1. */
926 {
927 e23 = split_block (bb2, bb2end);
928 bb3 = e23->dest;
929 bb3->count = all - count1 - count2;
930 }
931
932 e34 = split_block (ncounts ? bb3 : bb2, bb3end);
933 bb4 = e34->dest;
934 bb4->count = all;
935
936 e12->flags &= ~EDGE_FALLTHRU;
937 e12->flags |= EDGE_FALSE_VALUE;
938 e12->probability = REG_BR_PROB_BASE - prob1;
421e19dd 939 e12->count = all - count1;
d2971487 940
941 e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE);
942 e14->probability = prob1;
421e19dd 943 e14->count = count1;
d2971487 944
945 if (ncounts) /* Assumed to be 0 or 1. */
946 {
947 e23->flags &= ~EDGE_FALLTHRU;
948 e23->flags |= EDGE_FALSE_VALUE;
949 e23->count = all - count1 - count2;
950 e23->probability = REG_BR_PROB_BASE - prob2;
951
952 e24 = make_edge (bb2, bb4, EDGE_TRUE_VALUE);
953 e24->probability = prob2;
954 e24->count = count2;
955 }
956
957 e34->probability = REG_BR_PROB_BASE;
958 e34->count = all - count1 - count2;
959
960 return result;
961}
962
75a70cf9 963
964/* Do transforms 3) and 4) on the statement pointed-to by SI if applicable. */
965
d2971487 966static bool
75a70cf9 967gimple_mod_subtract_transform (gimple_stmt_iterator *si)
d2971487 968{
d2971487 969 histogram_value histogram;
970 enum tree_code code;
971 gcov_type count, wrong_values, all;
f018d957 972 tree lhs_type, result;
5b17b7ae 973 gcov_type prob1, prob2;
4992f399 974 unsigned int i, steps;
975 gcov_type count1, count2;
75a70cf9 976 gimple stmt;
d2971487 977
75a70cf9 978 stmt = gsi_stmt (*si);
979 if (gimple_code (stmt) != GIMPLE_ASSIGN)
d2971487 980 return false;
75a70cf9 981
982 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
983 if (!INTEGRAL_TYPE_P (lhs_type))
d2971487 984 return false;
75a70cf9 985
986 code = gimple_assign_rhs_code (stmt);
48e1416a 987
75a70cf9 988 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
d2971487 989 return false;
990
4992f399 991 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INTERVAL);
d2971487 992 if (!histogram)
993 return false;
994
d2971487 995 all = 0;
996 wrong_values = 0;
997 for (i = 0; i < histogram->hdata.intvl.steps; i++)
ed4294da 998 all += histogram->hvalue.counters[i];
d2971487 999
ed4294da 1000 wrong_values += histogram->hvalue.counters[i];
1001 wrong_values += histogram->hvalue.counters[i+1];
4992f399 1002 steps = histogram->hdata.intvl.steps;
d2971487 1003 all += wrong_values;
4992f399 1004 count1 = histogram->hvalue.counters[0];
1005 count2 = histogram->hvalue.counters[1];
d2971487 1006
2ca9602a 1007 /* Compute probability of taking the optimal path. */
e0dc6f2b 1008 if (check_counter (stmt, "interval", &count1, &all, gimple_bb (stmt)->count))
4992f399 1009 {
1010 gimple_remove_histogram_value (cfun, stmt, histogram);
1011 return false;
1012 }
2ca9602a 1013
e0dc6f2b 1014 if (flag_profile_correction && count1 + count2 > all)
1015 all = count1 + count2;
1016
1017 gcc_assert (count1 + count2 <= all);
1018
d2971487 1019 /* We require that we use just subtractions in at least 50% of all
1020 evaluations. */
1021 count = 0;
1022 for (i = 0; i < histogram->hdata.intvl.steps; i++)
1023 {
ed4294da 1024 count += histogram->hvalue.counters[i];
d2971487 1025 if (count * 2 >= all)
1026 break;
1027 }
4992f399 1028 if (i == steps
0bfd8d5c 1029 || optimize_bb_for_size_p (gimple_bb (stmt)))
d2971487 1030 return false;
1031
4992f399 1032 gimple_remove_histogram_value (cfun, stmt, histogram);
d2971487 1033 if (dump_file)
1034 {
1035 fprintf (dump_file, "Mod subtract transformation on insn ");
75a70cf9 1036 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
d2971487 1037 }
1038
1039 /* Compute probability of taking the optimal path(s). */
5b17b7ae 1040 if (all > 0)
1041 {
1042 prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all;
1043 prob2 = (count2 * REG_BR_PROB_BASE + all / 2) / all;
1044 }
1045 else
1046 {
1047 prob1 = prob2 = 0;
1048 }
d2971487 1049
1050 /* In practice, "steps" is always 2. This interface reflects this,
1051 and will need to be changed if "steps" can change. */
75a70cf9 1052 result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all);
d2971487 1053
75a70cf9 1054 gimple_assign_set_rhs_from_tree (si, result);
4b7a4b97 1055 update_stmt (gsi_stmt (*si));
d2971487 1056
1057 return true;
1058}
ed4294da 1059
167b550b 1060static struct cgraph_node** pid_map = NULL;
1061
1062/* Initialize map of pids (pid -> cgraph node) */
1063
48e1416a 1064static void
167b550b 1065init_pid_map (void)
1066{
1067 struct cgraph_node *n;
1068
1069 if (pid_map != NULL)
1070 return;
1071
4b49a15a 1072 pid_map = XCNEWVEC (struct cgraph_node*, cgraph_max_pid);
167b550b 1073
1074 for (n = cgraph_nodes; n; n = n->next)
1075 {
1076 if (n->pid != -1)
1077 pid_map [n->pid] = n;
1078 }
1079}
1080
1081/* Return cgraph node for function with pid */
1082
1083static inline struct cgraph_node*
1084find_func_by_pid (int pid)
1085{
1086 init_pid_map ();
1087
1088 return pid_map [pid];
1089}
1090
1091/* Do transformation
1092
f0b5f617 1093 if (actual_callee_address == address_of_most_common_function/method)
167b550b 1094 do direct call
1095 else
1096 old call
1097 */
1098
75a70cf9 1099static gimple
48e1416a 1100gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
75a70cf9 1101 int prob, gcov_type count, gcov_type all)
167b550b 1102{
e38def9c 1103 gimple dcall_stmt, load_stmt, cond_stmt;
85344eeb 1104 tree tmp0, tmp1, tmpv, tmp;
e38def9c 1105 basic_block cond_bb, dcall_bb, icall_bb, join_bb;
167b550b 1106 tree optype = build_pointer_type (void_type_node);
e38def9c 1107 edge e_cd, e_ci, e_di, e_dj, e_ij;
75a70cf9 1108 gimple_stmt_iterator gsi;
e38def9c 1109 int lp_nr;
167b550b 1110
e38def9c 1111 cond_bb = gimple_bb (icall_stmt);
1112 gsi = gsi_for_stmt (icall_stmt);
167b550b 1113
85344eeb 1114 tmpv = create_tmp_reg (optype, "PROF");
1115 tmp0 = make_ssa_name (tmpv, NULL);
1116 tmp1 = make_ssa_name (tmpv, NULL);
e38def9c 1117 tmp = unshare_expr (gimple_call_fn (icall_stmt));
85344eeb 1118 load_stmt = gimple_build_assign (tmp0, tmp);
1119 SSA_NAME_DEF_STMT (tmp0) = load_stmt;
e38def9c 1120 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
75a70cf9 1121
48e1416a 1122 tmp = fold_convert (optype, build_addr (direct_call->decl,
a0147880 1123 current_function_decl));
e38def9c 1124 load_stmt = gimple_build_assign (tmp1, tmp);
85344eeb 1125 SSA_NAME_DEF_STMT (tmp1) = load_stmt;
e38def9c 1126 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
167b550b 1127
85344eeb 1128 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
e38def9c 1129 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
1130
85344eeb 1131 gimple_set_vdef (icall_stmt, NULL_TREE);
1132 gimple_set_vuse (icall_stmt, NULL_TREE);
1133 update_stmt (icall_stmt);
e38def9c 1134 dcall_stmt = gimple_copy (icall_stmt);
1135 gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
1136 gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
167b550b 1137
1138 /* Fix CFG. */
e38def9c 1139 /* Edge e_cd connects cond_bb to dcall_bb, etc; note the first letters. */
1140 e_cd = split_block (cond_bb, cond_stmt);
1141 dcall_bb = e_cd->dest;
1142 dcall_bb->count = count;
167b550b 1143
e38def9c 1144 e_di = split_block (dcall_bb, dcall_stmt);
1145 icall_bb = e_di->dest;
1146 icall_bb->count = all - count;
167b550b 1147
e38def9c 1148 e_ij = split_block (icall_bb, icall_stmt);
1149 join_bb = e_ij->dest;
1150 join_bb->count = all;
167b550b 1151
e38def9c 1152 e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
1153 e_cd->probability = prob;
1154 e_cd->count = count;
1155
1156 e_ci = make_edge (cond_bb, icall_bb, EDGE_FALSE_VALUE);
1157 e_ci->probability = REG_BR_PROB_BASE - prob;
1158 e_ci->count = all - count;
1159
1160 remove_edge (e_di);
48e1416a 1161
e38def9c 1162 e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
1163 e_dj->probability = REG_BR_PROB_BASE;
1164 e_dj->count = count;
1165
1166 e_ij->probability = REG_BR_PROB_BASE;
1167 e_ij->count = all - count;
167b550b 1168
85344eeb 1169 /* Insert PHI node for the call result if necessary. */
1170 if (gimple_call_lhs (icall_stmt)
1171 && TREE_CODE (gimple_call_lhs (icall_stmt)) == SSA_NAME)
1172 {
1173 tree result = gimple_call_lhs (icall_stmt);
1174 gimple phi = create_phi_node (result, join_bb);
1175 SSA_NAME_DEF_STMT (result) = phi;
1176 gimple_call_set_lhs (icall_stmt,
1177 make_ssa_name (SSA_NAME_VAR (result), icall_stmt));
1178 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
1179 gimple_call_set_lhs (dcall_stmt,
1180 make_ssa_name (SSA_NAME_VAR (result), dcall_stmt));
1181 add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION);
1182 }
1183
167b550b 1184 /* Fix eh edges */
e38def9c 1185 lp_nr = lookup_stmt_eh_lp (icall_stmt);
1186 if (lp_nr != 0)
167b550b 1187 {
e38def9c 1188 if (stmt_could_throw_p (dcall_stmt))
1189 {
1190 add_stmt_to_eh_lp (dcall_stmt, lp_nr);
1191 make_eh_edges (dcall_stmt);
1192 }
1193
1194 gcc_assert (stmt_could_throw_p (icall_stmt));
1195 make_eh_edges (icall_stmt);
b89175b1 1196
1197 /* The old EH edges are sill on the join BB, purge them. */
1198 gimple_purge_dead_eh_edges (join_bb);
167b550b 1199 }
1200
e38def9c 1201 return dcall_stmt;
167b550b 1202}
1203
1204/*
1205 For every checked indirect/virtual call determine if most common pid of
1206 function/class method has probability more than 50%. If yes modify code of
1207 this call to:
1208 */
1209
1210static bool
75a70cf9 1211gimple_ic_transform (gimple stmt)
167b550b 1212{
1213 histogram_value histogram;
e0dc6f2b 1214 gcov_type val, count, all, bb_all;
5b17b7ae 1215 gcov_type prob;
75a70cf9 1216 tree callee;
1217 gimple modify;
167b550b 1218 struct cgraph_node *direct_call;
48e1416a 1219
75a70cf9 1220 if (gimple_code (stmt) != GIMPLE_CALL)
167b550b 1221 return false;
1222
75a70cf9 1223 callee = gimple_call_fn (stmt);
167b550b 1224
75a70cf9 1225 if (TREE_CODE (callee) == FUNCTION_DECL)
167b550b 1226 return false;
1227
1228 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);
1229 if (!histogram)
1230 return false;
1231
1232 val = histogram->hvalue.counters [0];
1233 count = histogram->hvalue.counters [1];
1234 all = histogram->hvalue.counters [2];
1235 gimple_remove_histogram_value (cfun, stmt, histogram);
1236
1237 if (4 * count <= 3 * all)
1238 return false;
1239
e0dc6f2b 1240 bb_all = gimple_bb (stmt)->count;
48e1416a 1241 /* The order of CHECK_COUNTER calls is important -
e0dc6f2b 1242 since check_counter can correct the third parameter
1243 and we want to make count <= all <= bb_all. */
1244 if ( check_counter (stmt, "ic", &all, &bb_all, bb_all)
1245 || check_counter (stmt, "ic", &count, &all, all))
1246 return false;
1247
5b17b7ae 1248 if (all > 0)
1249 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1250 else
1251 prob = 0;
167b550b 1252 direct_call = find_func_by_pid ((int)val);
1253
1254 if (direct_call == NULL)
1255 return false;
1256
e38def9c 1257 modify = gimple_ic (stmt, direct_call, prob, count, all);
167b550b 1258
1259 if (dump_file)
1260 {
1261 fprintf (dump_file, "Indirect call -> direct call ");
75a70cf9 1262 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
167b550b 1263 fprintf (dump_file, "=> ");
1264 print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
1265 fprintf (dump_file, " transformation on insn ");
75a70cf9 1266 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
167b550b 1267 fprintf (dump_file, " to ");
75a70cf9 1268 print_gimple_stmt (dump_file, modify, 0, TDF_SLIM);
6525819b 1269 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC
1270 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count, all);
167b550b 1271 }
1272
1273 return true;
1274}
1275
e0b41cd1 1276/* Return true if the stringop CALL with FNDECL shall be profiled.
1277 SIZE_ARG be set to the argument index for the size of the string
1278 operation.
1279*/
f656b751 1280static bool
e0b41cd1 1281interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg)
f656b751 1282{
1283 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
1284
058d05d5 1285 if (fcode != BUILT_IN_MEMCPY && fcode != BUILT_IN_MEMPCPY
1286 && fcode != BUILT_IN_MEMSET && fcode != BUILT_IN_BZERO)
f656b751 1287 return false;
1288
1289 switch (fcode)
1290 {
1291 case BUILT_IN_MEMCPY:
1292 case BUILT_IN_MEMPCPY:
e0b41cd1 1293 *size_arg = 2;
75a70cf9 1294 return validate_gimple_arglist (call, POINTER_TYPE, POINTER_TYPE,
1295 INTEGER_TYPE, VOID_TYPE);
f656b751 1296 case BUILT_IN_MEMSET:
e0b41cd1 1297 *size_arg = 2;
75a70cf9 1298 return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1299 INTEGER_TYPE, VOID_TYPE);
f656b751 1300 case BUILT_IN_BZERO:
e0b41cd1 1301 *size_arg = 1;
75a70cf9 1302 return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1303 VOID_TYPE);
f656b751 1304 default:
c2f47e15 1305 gcc_unreachable ();
f656b751 1306 }
1307}
1308
e38def9c 1309/* Convert stringop (..., vcall_size)
48e1416a 1310 into
e38def9c 1311 if (vcall_size == icall_size)
1312 stringop (..., icall_size);
f656b751 1313 else
e38def9c 1314 stringop (..., vcall_size);
1315 assuming we'll propagate a true constant into ICALL_SIZE later. */
1316
f656b751 1317static void
e38def9c 1318gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
1319 gcov_type count, gcov_type all)
f656b751 1320{
e38def9c 1321 gimple tmp_stmt, cond_stmt, icall_stmt;
85344eeb 1322 tree tmp0, tmp1, tmpv, vcall_size, optype;
e38def9c 1323 basic_block cond_bb, icall_bb, vcall_bb, join_bb;
1324 edge e_ci, e_cv, e_iv, e_ij, e_vj;
75a70cf9 1325 gimple_stmt_iterator gsi;
e0b41cd1 1326 tree fndecl;
1327 int size_arg;
1328
1329 fndecl = gimple_call_fndecl (vcall_stmt);
1330 if (!interesting_stringop_to_profile_p (fndecl, vcall_stmt, &size_arg))
1331 gcc_unreachable();
f656b751 1332
e38def9c 1333 cond_bb = gimple_bb (vcall_stmt);
1334 gsi = gsi_for_stmt (vcall_stmt);
f656b751 1335
e0b41cd1 1336 vcall_size = gimple_call_arg (vcall_stmt, size_arg);
e38def9c 1337 optype = TREE_TYPE (vcall_size);
f656b751 1338
1339 tmpv = create_tmp_var (optype, "PROF");
85344eeb 1340 tmp0 = make_ssa_name (tmpv, NULL);
1341 tmp1 = make_ssa_name (tmpv, NULL);
1342 tmp_stmt = gimple_build_assign (tmp0, fold_convert (optype, icall_size));
1343 SSA_NAME_DEF_STMT (tmp0) = tmp_stmt;
e38def9c 1344 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
f656b751 1345
e38def9c 1346 tmp_stmt = gimple_build_assign (tmp1, vcall_size);
85344eeb 1347 SSA_NAME_DEF_STMT (tmp1) = tmp_stmt;
e38def9c 1348 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
1349
85344eeb 1350 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
e38def9c 1351 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
1352
85344eeb 1353 gimple_set_vdef (vcall_stmt, NULL);
1354 gimple_set_vuse (vcall_stmt, NULL);
1355 update_stmt (vcall_stmt);
e38def9c 1356 icall_stmt = gimple_copy (vcall_stmt);
e0b41cd1 1357 gimple_call_set_arg (icall_stmt, size_arg, icall_size);
e38def9c 1358 gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);
f656b751 1359
1360 /* Fix CFG. */
e38def9c 1361 /* Edge e_ci connects cond_bb to icall_bb, etc. */
1362 e_ci = split_block (cond_bb, cond_stmt);
1363 icall_bb = e_ci->dest;
1364 icall_bb->count = count;
f656b751 1365
e38def9c 1366 e_iv = split_block (icall_bb, icall_stmt);
1367 vcall_bb = e_iv->dest;
1368 vcall_bb->count = all - count;
f656b751 1369
e38def9c 1370 e_vj = split_block (vcall_bb, vcall_stmt);
1371 join_bb = e_vj->dest;
1372 join_bb->count = all;
f656b751 1373
e38def9c 1374 e_ci->flags = (e_ci->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
1375 e_ci->probability = prob;
1376 e_ci->count = count;
1377
1378 e_cv = make_edge (cond_bb, vcall_bb, EDGE_FALSE_VALUE);
1379 e_cv->probability = REG_BR_PROB_BASE - prob;
1380 e_cv->count = all - count;
1381
1382 remove_edge (e_iv);
48e1416a 1383
e38def9c 1384 e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU);
1385 e_ij->probability = REG_BR_PROB_BASE;
1386 e_ij->count = count;
f656b751 1387
e38def9c 1388 e_vj->probability = REG_BR_PROB_BASE;
1389 e_vj->count = all - count;
1390
1391 /* Because these are all string op builtins, they're all nothrow. */
1392 gcc_assert (!stmt_could_throw_p (vcall_stmt));
1393 gcc_assert (!stmt_could_throw_p (icall_stmt));
f656b751 1394}
1395
1396/* Find values inside STMT for that we want to measure histograms for
1397 division/modulo optimization. */
1398static bool
75a70cf9 1399gimple_stringops_transform (gimple_stmt_iterator *gsi)
f656b751 1400{
75a70cf9 1401 gimple stmt = gsi_stmt (*gsi);
f656b751 1402 tree fndecl;
f656b751 1403 tree blck_size;
1404 enum built_in_function fcode;
f656b751 1405 histogram_value histogram;
1406 gcov_type count, all, val;
f656b751 1407 tree dest, src;
1408 unsigned int dest_align, src_align;
5b17b7ae 1409 gcov_type prob;
f656b751 1410 tree tree_val;
e0b41cd1 1411 int size_arg;
f656b751 1412
75a70cf9 1413 if (gimple_code (stmt) != GIMPLE_CALL)
f656b751 1414 return false;
75a70cf9 1415 fndecl = gimple_call_fndecl (stmt);
f656b751 1416 if (!fndecl)
1417 return false;
1418 fcode = DECL_FUNCTION_CODE (fndecl);
e0b41cd1 1419 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
f656b751 1420 return false;
1421
e0b41cd1 1422 blck_size = gimple_call_arg (stmt, size_arg);
f656b751 1423 if (TREE_CODE (blck_size) == INTEGER_CST)
1424 return false;
1425
4992f399 1426 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
f656b751 1427 if (!histogram)
1428 return false;
f656b751 1429 val = histogram->hvalue.counters[0];
1430 count = histogram->hvalue.counters[1];
1431 all = histogram->hvalue.counters[2];
4992f399 1432 gimple_remove_histogram_value (cfun, stmt, histogram);
f656b751 1433 /* We require that count is at least half of all; this means
1434 that for the transformation to fire the value must be constant
1435 at least 80% of time. */
0bfd8d5c 1436 if ((6 * count / 5) < all || optimize_bb_for_size_p (gimple_bb (stmt)))
f656b751 1437 return false;
e0dc6f2b 1438 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
f656b751 1439 return false;
5b17b7ae 1440 if (all > 0)
1441 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1442 else
1443 prob = 0;
75a70cf9 1444 dest = gimple_call_arg (stmt, 0);
f656b751 1445 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1446 switch (fcode)
1447 {
1448 case BUILT_IN_MEMCPY:
1449 case BUILT_IN_MEMPCPY:
75a70cf9 1450 src = gimple_call_arg (stmt, 1);
f656b751 1451 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1452 if (!can_move_by_pieces (val, MIN (dest_align, src_align)))
1453 return false;
1454 break;
1455 case BUILT_IN_MEMSET:
1456 if (!can_store_by_pieces (val, builtin_memset_read_str,
75a70cf9 1457 gimple_call_arg (stmt, 1),
4b297e2e 1458 dest_align, true))
f656b751 1459 return false;
1460 break;
1461 case BUILT_IN_BZERO:
1462 if (!can_store_by_pieces (val, builtin_memset_read_str,
1463 integer_zero_node,
4b297e2e 1464 dest_align, true))
f656b751 1465 return false;
1466 break;
1467 default:
1468 gcc_unreachable ();
1469 }
1470 tree_val = build_int_cst_wide (get_gcov_type (),
1471 (unsigned HOST_WIDE_INT) val,
1472 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
1473 if (dump_file)
1474 {
1475 fprintf (dump_file, "Single value %i stringop transformation on ",
1476 (int)val);
75a70cf9 1477 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
f656b751 1478 }
75a70cf9 1479 gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
48e1416a 1480
f656b751 1481 return true;
1482}
1483
162719b3 1484void
75a70cf9 1485stringop_block_profile (gimple stmt, unsigned int *expected_align,
162719b3 1486 HOST_WIDE_INT *expected_size)
1487{
1488 histogram_value histogram;
1489 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE);
1490 if (!histogram)
1491 *expected_size = -1;
553eb299 1492 else if (!histogram->hvalue.counters[1])
1493 {
1494 *expected_size = -1;
1495 gimple_remove_histogram_value (cfun, stmt, histogram);
1496 }
162719b3 1497 else
1498 {
1499 gcov_type size;
1500 size = ((histogram->hvalue.counters[0]
553eb299 1501 + histogram->hvalue.counters[1] / 2)
1502 / histogram->hvalue.counters[1]);
162719b3 1503 /* Even if we can hold bigger value in SIZE, INT_MAX
1504 is safe "infinity" for code generation strategies. */
1505 if (size > INT_MAX)
1506 size = INT_MAX;
1507 *expected_size = size;
1508 gimple_remove_histogram_value (cfun, stmt, histogram);
1509 }
1510 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR);
1511 if (!histogram)
f8eabf22 1512 *expected_align = 0;
553eb299 1513 else if (!histogram->hvalue.counters[0])
1514 {
1515 gimple_remove_histogram_value (cfun, stmt, histogram);
1516 *expected_align = 0;
1517 }
162719b3 1518 else
1519 {
1520 gcov_type count;
1521 int alignment;
1522
1523 count = histogram->hvalue.counters[0];
1524 alignment = 1;
1525 while (!(count & alignment)
1526 && (alignment * 2 * BITS_PER_UNIT))
1527 alignment <<= 1;
1528 *expected_align = alignment * BITS_PER_UNIT;
1529 gimple_remove_histogram_value (cfun, stmt, histogram);
1530 }
1531}
1532
4ee9c684 1533struct value_prof_hooks {
1534 /* Find list of values for which we want to measure histograms. */
8a5df2ce 1535 void (*find_values_to_profile) (histogram_values *);
4ee9c684 1536
1537 /* Identify and exploit properties of values that are hard to analyze
1538 statically. See value-prof.c for more detail. */
48e1416a 1539 bool (*value_profile_transformations) (void);
4ee9c684 1540};
4ee9c684 1541\f
d7683f13 1542/* Find values inside STMT for that we want to measure histograms for
d2971487 1543 division/modulo optimization. */
1544static void
75a70cf9 1545gimple_divmod_values_to_profile (gimple stmt, histogram_values *values)
d2971487 1546{
75a70cf9 1547 tree lhs, divisor, op0, type;
d2971487 1548 histogram_value hist;
1549
75a70cf9 1550 if (gimple_code (stmt) != GIMPLE_ASSIGN)
d2971487 1551 return;
75a70cf9 1552
1553 lhs = gimple_assign_lhs (stmt);
d7683f13 1554 type = TREE_TYPE (lhs);
1555 if (!INTEGRAL_TYPE_P (type))
d2971487 1556 return;
d7683f13 1557
75a70cf9 1558 switch (gimple_assign_rhs_code (stmt))
d2971487 1559 {
1560 case TRUNC_DIV_EXPR:
1561 case TRUNC_MOD_EXPR:
75a70cf9 1562 divisor = gimple_assign_rhs2 (stmt);
1563 op0 = gimple_assign_rhs1 (stmt);
d2971487 1564
046bfc77 1565 VEC_reserve (histogram_value, heap, *values, 3);
d7683f13 1566
1567 if (is_gimple_reg (divisor))
4992f399 1568 /* Check for the case where the divisor is the same value most
1569 of the time. */
1570 VEC_quick_push (histogram_value, *values,
75a70cf9 1571 gimple_alloc_histogram_value (cfun,
1572 HIST_TYPE_SINGLE_VALUE,
4992f399 1573 stmt, divisor));
d2971487 1574
1575 /* For mod, check whether it is not often a noop (or replaceable by
1576 a few subtractions). */
75a70cf9 1577 if (gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR
d7683f13 1578 && TYPE_UNSIGNED (type))
d2971487 1579 {
4992f399 1580 tree val;
421e19dd 1581 /* Check for a special case where the divisor is power of 2. */
4992f399 1582 VEC_quick_push (histogram_value, *values,
1583 gimple_alloc_histogram_value (cfun, HIST_TYPE_POW2,
1584 stmt, divisor));
421e19dd 1585
4992f399 1586 val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
1587 hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
1588 stmt, val);
d2971487 1589 hist->hdata.intvl.int_start = 0;
1590 hist->hdata.intvl.steps = 2;
046bfc77 1591 VEC_quick_push (histogram_value, *values, hist);
d2971487 1592 }
1593 return;
1594
1595 default:
1596 return;
1597 }
1598}
1599
48e1416a 1600/* Find calls inside STMT for that we want to measure histograms for
1601 indirect/virtual call optimization. */
167b550b 1602
1603static void
75a70cf9 1604gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
167b550b 1605{
75a70cf9 1606 tree callee;
167b550b 1607
0acacf9e 1608 if (gimple_code (stmt) != GIMPLE_CALL
1609 || gimple_call_fndecl (stmt) != NULL_TREE)
167b550b 1610 return;
1611
75a70cf9 1612 callee = gimple_call_fn (stmt);
167b550b 1613
1614 VEC_reserve (histogram_value, heap, *values, 3);
1615
48e1416a 1616 VEC_quick_push (histogram_value, *values,
167b550b 1617 gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
1618 stmt, callee));
1619
1620 return;
1621}
1622
f656b751 1623/* Find values inside STMT for that we want to measure histograms for
4992f399 1624 string operations. */
f656b751 1625static void
75a70cf9 1626gimple_stringops_values_to_profile (gimple stmt, histogram_values *values)
f656b751 1627{
f656b751 1628 tree fndecl;
f656b751 1629 tree blck_size;
162719b3 1630 tree dest;
e0b41cd1 1631 int size_arg;
f656b751 1632
75a70cf9 1633 if (gimple_code (stmt) != GIMPLE_CALL)
f656b751 1634 return;
75a70cf9 1635 fndecl = gimple_call_fndecl (stmt);
f656b751 1636 if (!fndecl)
1637 return;
f656b751 1638
e0b41cd1 1639 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
f656b751 1640 return;
1641
75a70cf9 1642 dest = gimple_call_arg (stmt, 0);
e0b41cd1 1643 blck_size = gimple_call_arg (stmt, size_arg);
f656b751 1644
162719b3 1645 if (TREE_CODE (blck_size) != INTEGER_CST)
1646 {
1647 VEC_safe_push (histogram_value, heap, *values,
1648 gimple_alloc_histogram_value (cfun, HIST_TYPE_SINGLE_VALUE,
1649 stmt, blck_size));
1650 VEC_safe_push (histogram_value, heap, *values,
1651 gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE,
1652 stmt, blck_size));
1653 }
f656b751 1654 if (TREE_CODE (blck_size) != INTEGER_CST)
4992f399 1655 VEC_safe_push (histogram_value, heap, *values,
162719b3 1656 gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR,
1657 stmt, dest));
f656b751 1658}
1659
d7683f13 1660/* Find values inside STMT for that we want to measure histograms and adds
1661 them to list VALUES. */
1662
4ee9c684 1663static void
75a70cf9 1664gimple_values_to_profile (gimple stmt, histogram_values *values)
4ee9c684 1665{
d2971487 1666 if (flag_value_profile_transformations)
f656b751 1667 {
75a70cf9 1668 gimple_divmod_values_to_profile (stmt, values);
1669 gimple_stringops_values_to_profile (stmt, values);
1670 gimple_indirect_call_to_profile (stmt, values);
f656b751 1671 }
4ee9c684 1672}
1673
d2971487 1674static void
75a70cf9 1675gimple_find_values_to_profile (histogram_values *values)
4ee9c684 1676{
d2971487 1677 basic_block bb;
75a70cf9 1678 gimple_stmt_iterator gsi;
d7683f13 1679 unsigned i;
4992f399 1680 histogram_value hist = NULL;
d7683f13 1681
046bfc77 1682 *values = NULL;
d2971487 1683 FOR_EACH_BB (bb)
75a70cf9 1684 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1685 gimple_values_to_profile (gsi_stmt (gsi), values);
48e1416a 1686
48148244 1687 FOR_EACH_VEC_ELT (histogram_value, *values, i, hist)
d2971487 1688 {
d2971487 1689 switch (hist->type)
1690 {
1691 case HIST_TYPE_INTERVAL:
d2971487 1692 hist->n_counters = hist->hdata.intvl.steps + 2;
1693 break;
1694
1695 case HIST_TYPE_POW2:
d7683f13 1696 hist->n_counters = 2;
d2971487 1697 break;
1698
1699 case HIST_TYPE_SINGLE_VALUE:
d2971487 1700 hist->n_counters = 3;
1701 break;
1702
1703 case HIST_TYPE_CONST_DELTA:
d2971487 1704 hist->n_counters = 4;
1705 break;
1706
167b550b 1707 case HIST_TYPE_INDIR_CALL:
1708 hist->n_counters = 3;
1709 break;
1710
162719b3 1711 case HIST_TYPE_AVERAGE:
553eb299 1712 hist->n_counters = 2;
162719b3 1713 break;
1714
1715 case HIST_TYPE_IOR:
553eb299 1716 hist->n_counters = 1;
162719b3 1717 break;
1718
d2971487 1719 default:
a53ff4c1 1720 gcc_unreachable ();
d2971487 1721 }
4992f399 1722 if (dump_file)
1723 {
1724 fprintf (dump_file, "Stmt ");
75a70cf9 1725 print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM);
4992f399 1726 dump_histogram_value (dump_file, hist);
1727 }
d2971487 1728 }
4ee9c684 1729}
1730
75a70cf9 1731static struct value_prof_hooks gimple_value_prof_hooks = {
1732 gimple_find_values_to_profile,
1733 gimple_value_profile_transformations
4ee9c684 1734};
1735
1736void
75a70cf9 1737gimple_register_value_prof_hooks (void)
4ee9c684 1738{
15b8fe07 1739 gcc_assert (current_ir_type () == IR_GIMPLE);
75a70cf9 1740 value_prof_hooks = &gimple_value_prof_hooks;
4ee9c684 1741}
1742\f
1743/* IR-independent entry points. */
1744void
8a5df2ce 1745find_values_to_profile (histogram_values *values)
4ee9c684 1746{
8a5df2ce 1747 (value_prof_hooks->find_values_to_profile) (values);
4ee9c684 1748}
1749
1750bool
1751value_profile_transformations (void)
1752{
102a5b98 1753 return (value_prof_hooks->value_profile_transformations) ();
4ee9c684 1754}
77fce4cd 1755\f