* gcc.dg/vect/slp-perm-1.c (main): Make sure loops aren't vectorized.
[official-gcc.git] / gcc / value-prof.c
blob7b1e70a2de070ad9476a331281cc5acbbae25946
1 /* Transformations based on profile information for values.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
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"
35 #include "regs.h"
36 #include "ggc.h"
37 #include "tree-flow.h"
38 #include "tree-flow-inline.h"
39 #include "diagnostic.h"
40 #include "tree-pretty-print.h"
41 #include "gimple-pretty-print.h"
42 #include "coverage.h"
43 #include "tree.h"
44 #include "gcov-io.h"
45 #include "cgraph.h"
46 #include "timevar.h"
47 #include "tree-pass.h"
48 #include "toplev.h"
49 #include "pointer-set.h"
51 static struct value_prof_hooks *value_prof_hooks;
53 /* In this file value profile based optimizations are placed. Currently the
54 following optimizations are implemented (for more detailed descriptions
55 see comments at value_profile_transformations):
57 1) Division/modulo specialization. Provided that we can determine that the
58 operands of the division have some special properties, we may use it to
59 produce more effective code.
60 2) Speculative prefetching. If we are able to determine that the difference
61 between addresses accessed by a memory reference is usually constant, we
62 may add the prefetch instructions.
63 FIXME: This transformation was removed together with RTL based value
64 profiling.
66 3) Indirect/virtual call specialization. If we can determine most
67 common function callee in indirect/virtual call. We can use this
68 information to improve code effectiveness (especially info for
69 inliner).
71 Every such optimization should add its requirements for profiled values to
72 insn_values_to_profile function. This function is called from branch_prob
73 in profile.c and the requested values are instrumented by it in the first
74 compilation with -fprofile-arcs. The optimization may then read the
75 gathered data in the second compilation with -fbranch-probabilities.
77 The measured data is pointed to from the histograms
78 field of the statement annotation of the instrumented insns. It is
79 kept as a linked list of struct histogram_value_t's, which contain the
80 same information as above. */
83 static tree gimple_divmod_fixed_value (gimple, tree, int, gcov_type, gcov_type);
84 static tree gimple_mod_pow2 (gimple, int, gcov_type, gcov_type);
85 static tree gimple_mod_subtract (gimple, int, int, int, gcov_type, gcov_type,
86 gcov_type);
87 static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *);
88 static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *);
89 static bool gimple_mod_subtract_transform (gimple_stmt_iterator *);
90 static bool gimple_stringops_transform (gimple_stmt_iterator *);
91 static bool gimple_ic_transform (gimple);
93 /* Allocate histogram value. */
95 static histogram_value
96 gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED,
97 enum hist_type type, gimple stmt, tree value)
99 histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist));
100 hist->hvalue.value = value;
101 hist->hvalue.stmt = stmt;
102 hist->type = type;
103 return hist;
106 /* Hash value for histogram. */
108 static hashval_t
109 histogram_hash (const void *x)
111 return htab_hash_pointer (((const_histogram_value)x)->hvalue.stmt);
114 /* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */
116 static int
117 histogram_eq (const void *x, const void *y)
119 return ((const_histogram_value) x)->hvalue.stmt == (const_gimple) y;
122 /* Set histogram for STMT. */
124 static void
125 set_histogram_value (struct function *fun, gimple stmt, histogram_value hist)
127 void **loc;
128 if (!hist && !VALUE_HISTOGRAMS (fun))
129 return;
130 if (!VALUE_HISTOGRAMS (fun))
131 VALUE_HISTOGRAMS (fun) = htab_create (1, histogram_hash,
132 histogram_eq, NULL);
133 loc = htab_find_slot_with_hash (VALUE_HISTOGRAMS (fun), stmt,
134 htab_hash_pointer (stmt),
135 hist ? INSERT : NO_INSERT);
136 if (!hist)
138 if (loc)
139 htab_clear_slot (VALUE_HISTOGRAMS (fun), loc);
140 return;
142 *loc = hist;
145 /* Get histogram list for STMT. */
147 histogram_value
148 gimple_histogram_value (struct function *fun, gimple stmt)
150 if (!VALUE_HISTOGRAMS (fun))
151 return NULL;
152 return (histogram_value) htab_find_with_hash (VALUE_HISTOGRAMS (fun), stmt,
153 htab_hash_pointer (stmt));
156 /* Add histogram for STMT. */
158 void
159 gimple_add_histogram_value (struct function *fun, gimple stmt,
160 histogram_value hist)
162 hist->hvalue.next = gimple_histogram_value (fun, stmt);
163 set_histogram_value (fun, stmt, hist);
167 /* Remove histogram HIST from STMT's histogram list. */
169 void
170 gimple_remove_histogram_value (struct function *fun, gimple stmt,
171 histogram_value hist)
173 histogram_value hist2 = gimple_histogram_value (fun, stmt);
174 if (hist == hist2)
176 set_histogram_value (fun, stmt, hist->hvalue.next);
178 else
180 while (hist2->hvalue.next != hist)
181 hist2 = hist2->hvalue.next;
182 hist2->hvalue.next = hist->hvalue.next;
184 free (hist->hvalue.counters);
185 #ifdef ENABLE_CHECKING
186 memset (hist, 0xab, sizeof (*hist));
187 #endif
188 free (hist);
192 /* Lookup histogram of type TYPE in the STMT. */
194 histogram_value
195 gimple_histogram_value_of_type (struct function *fun, gimple stmt,
196 enum hist_type type)
198 histogram_value hist;
199 for (hist = gimple_histogram_value (fun, stmt); hist;
200 hist = hist->hvalue.next)
201 if (hist->type == type)
202 return hist;
203 return NULL;
206 /* Dump information about HIST to DUMP_FILE. */
208 static void
209 dump_histogram_value (FILE *dump_file, histogram_value hist)
211 switch (hist->type)
213 case HIST_TYPE_INTERVAL:
214 fprintf (dump_file, "Interval counter range %d -- %d",
215 hist->hdata.intvl.int_start,
216 (hist->hdata.intvl.int_start
217 + hist->hdata.intvl.steps - 1));
218 if (hist->hvalue.counters)
220 unsigned int i;
221 fprintf(dump_file, " [");
222 for (i = 0; i < hist->hdata.intvl.steps; i++)
223 fprintf (dump_file, " %d:"HOST_WIDEST_INT_PRINT_DEC,
224 hist->hdata.intvl.int_start + i,
225 (HOST_WIDEST_INT) hist->hvalue.counters[i]);
226 fprintf (dump_file, " ] outside range:"HOST_WIDEST_INT_PRINT_DEC,
227 (HOST_WIDEST_INT) hist->hvalue.counters[i]);
229 fprintf (dump_file, ".\n");
230 break;
232 case HIST_TYPE_POW2:
233 fprintf (dump_file, "Pow2 counter ");
234 if (hist->hvalue.counters)
236 fprintf (dump_file, "pow2:"HOST_WIDEST_INT_PRINT_DEC
237 " nonpow2:"HOST_WIDEST_INT_PRINT_DEC,
238 (HOST_WIDEST_INT) hist->hvalue.counters[0],
239 (HOST_WIDEST_INT) hist->hvalue.counters[1]);
241 fprintf (dump_file, ".\n");
242 break;
244 case HIST_TYPE_SINGLE_VALUE:
245 fprintf (dump_file, "Single value ");
246 if (hist->hvalue.counters)
248 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
249 " match:"HOST_WIDEST_INT_PRINT_DEC
250 " wrong:"HOST_WIDEST_INT_PRINT_DEC,
251 (HOST_WIDEST_INT) hist->hvalue.counters[0],
252 (HOST_WIDEST_INT) hist->hvalue.counters[1],
253 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
255 fprintf (dump_file, ".\n");
256 break;
258 case HIST_TYPE_AVERAGE:
259 fprintf (dump_file, "Average value ");
260 if (hist->hvalue.counters)
262 fprintf (dump_file, "sum:"HOST_WIDEST_INT_PRINT_DEC
263 " times:"HOST_WIDEST_INT_PRINT_DEC,
264 (HOST_WIDEST_INT) hist->hvalue.counters[0],
265 (HOST_WIDEST_INT) hist->hvalue.counters[1]);
267 fprintf (dump_file, ".\n");
268 break;
270 case HIST_TYPE_IOR:
271 fprintf (dump_file, "IOR value ");
272 if (hist->hvalue.counters)
274 fprintf (dump_file, "ior:"HOST_WIDEST_INT_PRINT_DEC,
275 (HOST_WIDEST_INT) hist->hvalue.counters[0]);
277 fprintf (dump_file, ".\n");
278 break;
280 case HIST_TYPE_CONST_DELTA:
281 fprintf (dump_file, "Constant delta ");
282 if (hist->hvalue.counters)
284 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
285 " match:"HOST_WIDEST_INT_PRINT_DEC
286 " wrong:"HOST_WIDEST_INT_PRINT_DEC,
287 (HOST_WIDEST_INT) hist->hvalue.counters[0],
288 (HOST_WIDEST_INT) hist->hvalue.counters[1],
289 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
291 fprintf (dump_file, ".\n");
292 break;
293 case HIST_TYPE_INDIR_CALL:
294 fprintf (dump_file, "Indirect call ");
295 if (hist->hvalue.counters)
297 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
298 " match:"HOST_WIDEST_INT_PRINT_DEC
299 " all:"HOST_WIDEST_INT_PRINT_DEC,
300 (HOST_WIDEST_INT) hist->hvalue.counters[0],
301 (HOST_WIDEST_INT) hist->hvalue.counters[1],
302 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
304 fprintf (dump_file, ".\n");
305 break;
309 /* Dump all histograms attached to STMT to DUMP_FILE. */
311 void
312 dump_histograms_for_stmt (struct function *fun, FILE *dump_file, gimple stmt)
314 histogram_value hist;
315 for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
316 dump_histogram_value (dump_file, hist);
319 /* Remove all histograms associated with STMT. */
321 void
322 gimple_remove_stmt_histograms (struct function *fun, gimple stmt)
324 histogram_value val;
325 while ((val = gimple_histogram_value (fun, stmt)) != NULL)
326 gimple_remove_histogram_value (fun, stmt, val);
329 /* Duplicate all histograms associates with OSTMT to STMT. */
331 void
332 gimple_duplicate_stmt_histograms (struct function *fun, gimple stmt,
333 struct function *ofun, gimple ostmt)
335 histogram_value val;
336 for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next)
338 histogram_value new_val = gimple_alloc_histogram_value (fun, val->type, NULL, NULL);
339 memcpy (new_val, val, sizeof (*val));
340 new_val->hvalue.stmt = stmt;
341 new_val->hvalue.counters = XNEWVAR (gcov_type, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
342 memcpy (new_val->hvalue.counters, val->hvalue.counters, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
343 gimple_add_histogram_value (fun, stmt, new_val);
348 /* Move all histograms associated with OSTMT to STMT. */
350 void
351 gimple_move_stmt_histograms (struct function *fun, gimple stmt, gimple ostmt)
353 histogram_value val = gimple_histogram_value (fun, ostmt);
354 if (val)
356 /* The following three statements can't be reordered,
357 because histogram hashtab relies on stmt field value
358 for finding the exact slot. */
359 set_histogram_value (fun, ostmt, NULL);
360 for (; val != NULL; val = val->hvalue.next)
361 val->hvalue.stmt = stmt;
362 set_histogram_value (fun, stmt, val);
366 static bool error_found = false;
368 /* Helper function for verify_histograms. For each histogram reachable via htab
369 walk verify that it was reached via statement walk. */
371 static int
372 visit_hist (void **slot, void *data)
374 struct pointer_set_t *visited = (struct pointer_set_t *) data;
375 histogram_value hist = *(histogram_value *) slot;
376 if (!pointer_set_contains (visited, hist))
378 error ("Dead histogram");
379 dump_histogram_value (stderr, hist);
380 debug_gimple_stmt (hist->hvalue.stmt);
381 error_found = true;
383 return 1;
387 /* Verify sanity of the histograms. */
389 DEBUG_FUNCTION void
390 verify_histograms (void)
392 basic_block bb;
393 gimple_stmt_iterator gsi;
394 histogram_value hist;
395 struct pointer_set_t *visited_hists;
397 error_found = false;
398 visited_hists = pointer_set_create ();
399 FOR_EACH_BB (bb)
400 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
402 gimple stmt = gsi_stmt (gsi);
404 for (hist = gimple_histogram_value (cfun, stmt); hist;
405 hist = hist->hvalue.next)
407 if (hist->hvalue.stmt != stmt)
409 error ("Histogram value statement does not correspond to "
410 "the statement it is associated with");
411 debug_gimple_stmt (stmt);
412 dump_histogram_value (stderr, hist);
413 error_found = true;
415 pointer_set_insert (visited_hists, hist);
418 if (VALUE_HISTOGRAMS (cfun))
419 htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, visited_hists);
420 pointer_set_destroy (visited_hists);
421 if (error_found)
422 internal_error ("verify_histograms failed");
425 /* Helper function for verify_histograms. For each histogram reachable via htab
426 walk verify that it was reached via statement walk. */
428 static int
429 free_hist (void **slot, void *data ATTRIBUTE_UNUSED)
431 histogram_value hist = *(histogram_value *) slot;
432 free (hist->hvalue.counters);
433 #ifdef ENABLE_CHECKING
434 memset (hist, 0xab, sizeof (*hist));
435 #endif
436 free (hist);
437 return 1;
440 void
441 free_histograms (void)
443 if (VALUE_HISTOGRAMS (cfun))
445 htab_traverse (VALUE_HISTOGRAMS (cfun), free_hist, NULL);
446 htab_delete (VALUE_HISTOGRAMS (cfun));
447 VALUE_HISTOGRAMS (cfun) = NULL;
452 /* The overall number of invocations of the counter should match
453 execution count of basic block. Report it as error rather than
454 internal error as it might mean that user has misused the profile
455 somehow. */
457 static bool
458 check_counter (gimple stmt, const char * name,
459 gcov_type *count, gcov_type *all, gcov_type bb_count)
461 if (*all != bb_count || *count > *all)
463 location_t locus;
464 locus = (stmt != NULL)
465 ? gimple_location (stmt)
466 : DECL_SOURCE_LOCATION (current_function_decl);
467 if (flag_profile_correction)
469 inform (locus, "Correcting inconsistent value profile: "
470 "%s profiler overall count (%d) does not match BB count "
471 "(%d)", name, (int)*all, (int)bb_count);
472 *all = bb_count;
473 if (*count > *all)
474 *count = *all;
475 return false;
477 else
479 error_at (locus, "Corrupted value profile: %s "
480 "profiler overall count (%d) does not match BB count (%d)",
481 name, (int)*all, (int)bb_count);
482 return true;
486 return false;
490 /* GIMPLE based transformations. */
492 static bool
493 gimple_value_profile_transformations (void)
495 basic_block bb;
496 gimple_stmt_iterator gsi;
497 bool changed = false;
499 FOR_EACH_BB (bb)
501 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
503 gimple stmt = gsi_stmt (gsi);
504 histogram_value th = gimple_histogram_value (cfun, stmt);
505 if (!th)
506 continue;
508 if (dump_file)
510 fprintf (dump_file, "Trying transformations on stmt ");
511 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
512 dump_histograms_for_stmt (cfun, dump_file, stmt);
515 /* Transformations: */
516 /* The order of things in this conditional controls which
517 transformation is used when more than one is applicable. */
518 /* It is expected that any code added by the transformations
519 will be added before the current statement, and that the
520 current statement remain valid (although possibly
521 modified) upon return. */
522 if (flag_value_profile_transformations
523 && (gimple_mod_subtract_transform (&gsi)
524 || gimple_divmod_fixed_value_transform (&gsi)
525 || gimple_mod_pow2_value_transform (&gsi)
526 || gimple_stringops_transform (&gsi)
527 || gimple_ic_transform (stmt)))
529 stmt = gsi_stmt (gsi);
530 changed = true;
531 /* Original statement may no longer be in the same block. */
532 if (bb != gimple_bb (stmt))
534 bb = gimple_bb (stmt);
535 gsi = gsi_for_stmt (stmt);
541 if (changed)
543 counts_to_freqs ();
546 return changed;
550 /* Generate code for transformation 1 (with parent gimple assignment
551 STMT and probability of taking the optimal path PROB, which is
552 equivalent to COUNT/ALL within roundoff error). This generates the
553 result into a temp and returns the temp; it does not replace or
554 alter the original STMT. */
556 static tree
557 gimple_divmod_fixed_value (gimple stmt, tree value, int prob, gcov_type count,
558 gcov_type all)
560 gimple stmt1, stmt2, stmt3;
561 tree tmp1, tmp2, tmpv;
562 gimple bb1end, bb2end, bb3end;
563 basic_block bb, bb2, bb3, bb4;
564 tree optype, op1, op2;
565 edge e12, e13, e23, e24, e34;
566 gimple_stmt_iterator gsi;
568 gcc_assert (is_gimple_assign (stmt)
569 && (gimple_assign_rhs_code (stmt) == TRUNC_DIV_EXPR
570 || gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR));
572 optype = TREE_TYPE (gimple_assign_lhs (stmt));
573 op1 = gimple_assign_rhs1 (stmt);
574 op2 = gimple_assign_rhs2 (stmt);
576 bb = gimple_bb (stmt);
577 gsi = gsi_for_stmt (stmt);
579 tmpv = create_tmp_var (optype, "PROF");
580 tmp1 = create_tmp_var (optype, "PROF");
581 stmt1 = gimple_build_assign (tmpv, fold_convert (optype, value));
582 stmt2 = gimple_build_assign (tmp1, op2);
583 stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
584 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
585 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
586 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
587 bb1end = stmt3;
589 tmp2 = create_tmp_var (optype, "PROF");
590 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
591 op1, tmpv);
592 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
593 bb2end = stmt1;
595 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
596 op1, op2);
597 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
598 bb3end = stmt1;
600 /* Fix CFG. */
601 /* Edge e23 connects bb2 to bb3, etc. */
602 e12 = split_block (bb, bb1end);
603 bb2 = e12->dest;
604 bb2->count = count;
605 e23 = split_block (bb2, bb2end);
606 bb3 = e23->dest;
607 bb3->count = all - count;
608 e34 = split_block (bb3, bb3end);
609 bb4 = e34->dest;
610 bb4->count = all;
612 e12->flags &= ~EDGE_FALLTHRU;
613 e12->flags |= EDGE_FALSE_VALUE;
614 e12->probability = prob;
615 e12->count = count;
617 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
618 e13->probability = REG_BR_PROB_BASE - prob;
619 e13->count = all - count;
621 remove_edge (e23);
623 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
624 e24->probability = REG_BR_PROB_BASE;
625 e24->count = count;
627 e34->probability = REG_BR_PROB_BASE;
628 e34->count = all - count;
630 return tmp2;
634 /* Do transform 1) on INSN if applicable. */
636 static bool
637 gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
639 histogram_value histogram;
640 enum tree_code code;
641 gcov_type val, count, all;
642 tree result, value, tree_val;
643 gcov_type prob;
644 gimple stmt;
646 stmt = gsi_stmt (*si);
647 if (gimple_code (stmt) != GIMPLE_ASSIGN)
648 return false;
650 if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))))
651 return false;
653 code = gimple_assign_rhs_code (stmt);
655 if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
656 return false;
658 histogram = gimple_histogram_value_of_type (cfun, stmt,
659 HIST_TYPE_SINGLE_VALUE);
660 if (!histogram)
661 return false;
663 value = histogram->hvalue.value;
664 val = histogram->hvalue.counters[0];
665 count = histogram->hvalue.counters[1];
666 all = histogram->hvalue.counters[2];
667 gimple_remove_histogram_value (cfun, stmt, histogram);
669 /* We require that count is at least half of all; this means
670 that for the transformation to fire the value must be constant
671 at least 50% of time (and 75% gives the guarantee of usage). */
672 if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
673 || 2 * count < all
674 || optimize_bb_for_size_p (gimple_bb (stmt)))
675 return false;
677 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
678 return false;
680 /* Compute probability of taking the optimal path. */
681 if (all > 0)
682 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
683 else
684 prob = 0;
686 tree_val = build_int_cst_wide (get_gcov_type (),
687 (unsigned HOST_WIDE_INT) val,
688 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
689 result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all);
691 if (dump_file)
693 fprintf (dump_file, "Div/mod by constant ");
694 print_generic_expr (dump_file, value, TDF_SLIM);
695 fprintf (dump_file, "=");
696 print_generic_expr (dump_file, tree_val, TDF_SLIM);
697 fprintf (dump_file, " transformation on insn ");
698 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
701 gimple_assign_set_rhs_from_tree (si, result);
703 return true;
706 /* Generate code for transformation 2 (with parent gimple assign STMT and
707 probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
708 within roundoff error). This generates the result into a temp and returns
709 the temp; it does not replace or alter the original STMT. */
710 static tree
711 gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
713 gimple stmt1, stmt2, stmt3, stmt4;
714 tree tmp2, tmp3;
715 gimple bb1end, bb2end, bb3end;
716 basic_block bb, bb2, bb3, bb4;
717 tree optype, op1, op2;
718 edge e12, e13, e23, e24, e34;
719 gimple_stmt_iterator gsi;
720 tree result;
722 gcc_assert (is_gimple_assign (stmt)
723 && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
725 optype = TREE_TYPE (gimple_assign_lhs (stmt));
726 op1 = gimple_assign_rhs1 (stmt);
727 op2 = gimple_assign_rhs2 (stmt);
729 bb = gimple_bb (stmt);
730 gsi = gsi_for_stmt (stmt);
732 result = create_tmp_var (optype, "PROF");
733 tmp2 = create_tmp_var (optype, "PROF");
734 tmp3 = create_tmp_var (optype, "PROF");
735 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2,
736 build_int_cst (optype, -1));
737 stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2);
738 stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0),
739 NULL_TREE, NULL_TREE);
740 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
741 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
742 gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
743 bb1end = stmt4;
745 /* tmp2 == op2-1 inherited from previous block. */
746 stmt1 = gimple_build_assign_with_ops (BIT_AND_EXPR, result, op1, tmp2);
747 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
748 bb2end = stmt1;
750 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
751 op1, op2);
752 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
753 bb3end = stmt1;
755 /* Fix CFG. */
756 /* Edge e23 connects bb2 to bb3, etc. */
757 e12 = split_block (bb, bb1end);
758 bb2 = e12->dest;
759 bb2->count = count;
760 e23 = split_block (bb2, bb2end);
761 bb3 = e23->dest;
762 bb3->count = all - count;
763 e34 = split_block (bb3, bb3end);
764 bb4 = e34->dest;
765 bb4->count = all;
767 e12->flags &= ~EDGE_FALLTHRU;
768 e12->flags |= EDGE_FALSE_VALUE;
769 e12->probability = prob;
770 e12->count = count;
772 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
773 e13->probability = REG_BR_PROB_BASE - prob;
774 e13->count = all - count;
776 remove_edge (e23);
778 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
779 e24->probability = REG_BR_PROB_BASE;
780 e24->count = count;
782 e34->probability = REG_BR_PROB_BASE;
783 e34->count = all - count;
785 return result;
788 /* Do transform 2) on INSN if applicable. */
789 static bool
790 gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
792 histogram_value histogram;
793 enum tree_code code;
794 gcov_type count, wrong_values, all;
795 tree lhs_type, result, value;
796 gcov_type prob;
797 gimple stmt;
799 stmt = gsi_stmt (*si);
800 if (gimple_code (stmt) != GIMPLE_ASSIGN)
801 return false;
803 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
804 if (!INTEGRAL_TYPE_P (lhs_type))
805 return false;
807 code = gimple_assign_rhs_code (stmt);
809 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
810 return false;
812 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_POW2);
813 if (!histogram)
814 return false;
816 value = histogram->hvalue.value;
817 wrong_values = histogram->hvalue.counters[0];
818 count = histogram->hvalue.counters[1];
820 gimple_remove_histogram_value (cfun, stmt, histogram);
822 /* We require that we hit a power of 2 at least half of all evaluations. */
823 if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
824 || count < wrong_values
825 || optimize_bb_for_size_p (gimple_bb (stmt)))
826 return false;
828 if (dump_file)
830 fprintf (dump_file, "Mod power of 2 transformation on insn ");
831 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
834 /* Compute probability of taking the optimal path. */
835 all = count + wrong_values;
837 if (check_counter (stmt, "pow2", &count, &all, gimple_bb (stmt)->count))
838 return false;
840 if (all > 0)
841 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
842 else
843 prob = 0;
845 result = gimple_mod_pow2 (stmt, prob, count, all);
847 gimple_assign_set_rhs_from_tree (si, result);
849 return true;
852 /* Generate code for transformations 3 and 4 (with parent gimple assign STMT, and
853 NCOUNTS the number of cases to support. Currently only NCOUNTS==0 or 1 is
854 supported and this is built into this interface. The probabilities of taking
855 the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
856 COUNT2/ALL respectively within roundoff error). This generates the
857 result into a temp and returns the temp; it does not replace or alter
858 the original STMT. */
859 /* FIXME: Generalize the interface to handle NCOUNTS > 1. */
861 static tree
862 gimple_mod_subtract (gimple stmt, int prob1, int prob2, int ncounts,
863 gcov_type count1, gcov_type count2, gcov_type all)
865 gimple stmt1, stmt2, stmt3;
866 tree tmp1;
867 gimple bb1end, bb2end = NULL, bb3end;
868 basic_block bb, bb2, bb3, bb4;
869 tree optype, op1, op2;
870 edge e12, e23 = 0, e24, e34, e14;
871 gimple_stmt_iterator gsi;
872 tree result;
874 gcc_assert (is_gimple_assign (stmt)
875 && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
877 optype = TREE_TYPE (gimple_assign_lhs (stmt));
878 op1 = gimple_assign_rhs1 (stmt);
879 op2 = gimple_assign_rhs2 (stmt);
881 bb = gimple_bb (stmt);
882 gsi = gsi_for_stmt (stmt);
884 result = create_tmp_var (optype, "PROF");
885 tmp1 = create_tmp_var (optype, "PROF");
886 stmt1 = gimple_build_assign (result, op1);
887 stmt2 = gimple_build_assign (tmp1, op2);
888 stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
889 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
890 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
891 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
892 bb1end = stmt3;
894 if (ncounts) /* Assumed to be 0 or 1 */
896 stmt1 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, tmp1);
897 stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
898 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
899 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
900 bb2end = stmt2;
903 /* Fallback case. */
904 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
905 result, tmp1);
906 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
907 bb3end = stmt1;
909 /* Fix CFG. */
910 /* Edge e23 connects bb2 to bb3, etc. */
911 /* However block 3 is optional; if it is not there, references
912 to 3 really refer to block 2. */
913 e12 = split_block (bb, bb1end);
914 bb2 = e12->dest;
915 bb2->count = all - count1;
917 if (ncounts) /* Assumed to be 0 or 1. */
919 e23 = split_block (bb2, bb2end);
920 bb3 = e23->dest;
921 bb3->count = all - count1 - count2;
924 e34 = split_block (ncounts ? bb3 : bb2, bb3end);
925 bb4 = e34->dest;
926 bb4->count = all;
928 e12->flags &= ~EDGE_FALLTHRU;
929 e12->flags |= EDGE_FALSE_VALUE;
930 e12->probability = REG_BR_PROB_BASE - prob1;
931 e12->count = all - count1;
933 e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE);
934 e14->probability = prob1;
935 e14->count = count1;
937 if (ncounts) /* Assumed to be 0 or 1. */
939 e23->flags &= ~EDGE_FALLTHRU;
940 e23->flags |= EDGE_FALSE_VALUE;
941 e23->count = all - count1 - count2;
942 e23->probability = REG_BR_PROB_BASE - prob2;
944 e24 = make_edge (bb2, bb4, EDGE_TRUE_VALUE);
945 e24->probability = prob2;
946 e24->count = count2;
949 e34->probability = REG_BR_PROB_BASE;
950 e34->count = all - count1 - count2;
952 return result;
956 /* Do transforms 3) and 4) on the statement pointed-to by SI if applicable. */
958 static bool
959 gimple_mod_subtract_transform (gimple_stmt_iterator *si)
961 histogram_value histogram;
962 enum tree_code code;
963 gcov_type count, wrong_values, all;
964 tree lhs_type, result;
965 gcov_type prob1, prob2;
966 unsigned int i, steps;
967 gcov_type count1, count2;
968 gimple stmt;
970 stmt = gsi_stmt (*si);
971 if (gimple_code (stmt) != GIMPLE_ASSIGN)
972 return false;
974 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
975 if (!INTEGRAL_TYPE_P (lhs_type))
976 return false;
978 code = gimple_assign_rhs_code (stmt);
980 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
981 return false;
983 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INTERVAL);
984 if (!histogram)
985 return false;
987 all = 0;
988 wrong_values = 0;
989 for (i = 0; i < histogram->hdata.intvl.steps; i++)
990 all += histogram->hvalue.counters[i];
992 wrong_values += histogram->hvalue.counters[i];
993 wrong_values += histogram->hvalue.counters[i+1];
994 steps = histogram->hdata.intvl.steps;
995 all += wrong_values;
996 count1 = histogram->hvalue.counters[0];
997 count2 = histogram->hvalue.counters[1];
999 /* Compute probability of taking the optimal path. */
1000 if (check_counter (stmt, "interval", &count1, &all, gimple_bb (stmt)->count))
1002 gimple_remove_histogram_value (cfun, stmt, histogram);
1003 return false;
1006 if (flag_profile_correction && count1 + count2 > all)
1007 all = count1 + count2;
1009 gcc_assert (count1 + count2 <= all);
1011 /* We require that we use just subtractions in at least 50% of all
1012 evaluations. */
1013 count = 0;
1014 for (i = 0; i < histogram->hdata.intvl.steps; i++)
1016 count += histogram->hvalue.counters[i];
1017 if (count * 2 >= all)
1018 break;
1020 if (i == steps
1021 || optimize_bb_for_size_p (gimple_bb (stmt)))
1022 return false;
1024 gimple_remove_histogram_value (cfun, stmt, histogram);
1025 if (dump_file)
1027 fprintf (dump_file, "Mod subtract transformation on insn ");
1028 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1031 /* Compute probability of taking the optimal path(s). */
1032 if (all > 0)
1034 prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all;
1035 prob2 = (count2 * REG_BR_PROB_BASE + all / 2) / all;
1037 else
1039 prob1 = prob2 = 0;
1042 /* In practice, "steps" is always 2. This interface reflects this,
1043 and will need to be changed if "steps" can change. */
1044 result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all);
1046 gimple_assign_set_rhs_from_tree (si, result);
1048 return true;
1051 static struct cgraph_node** pid_map = NULL;
1053 /* Initialize map of pids (pid -> cgraph node) */
1055 static void
1056 init_pid_map (void)
1058 struct cgraph_node *n;
1060 if (pid_map != NULL)
1061 return;
1063 pid_map = XCNEWVEC (struct cgraph_node*, cgraph_max_pid);
1065 for (n = cgraph_nodes; n; n = n->next)
1067 if (n->pid != -1)
1068 pid_map [n->pid] = n;
1072 /* Return cgraph node for function with pid */
1074 static inline struct cgraph_node*
1075 find_func_by_pid (int pid)
1077 init_pid_map ();
1079 return pid_map [pid];
1082 /* Do transformation
1084 if (actual_callee_address == address_of_most_common_function/method)
1085 do direct call
1086 else
1087 old call
1090 static gimple
1091 gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
1092 int prob, gcov_type count, gcov_type all)
1094 gimple dcall_stmt, load_stmt, cond_stmt;
1095 tree tmp1, tmpv, tmp;
1096 basic_block cond_bb, dcall_bb, icall_bb, join_bb;
1097 tree optype = build_pointer_type (void_type_node);
1098 edge e_cd, e_ci, e_di, e_dj, e_ij;
1099 gimple_stmt_iterator gsi;
1100 int lp_nr;
1102 cond_bb = gimple_bb (icall_stmt);
1103 gsi = gsi_for_stmt (icall_stmt);
1105 tmpv = create_tmp_var (optype, "PROF");
1106 tmp1 = create_tmp_var (optype, "PROF");
1107 tmp = unshare_expr (gimple_call_fn (icall_stmt));
1108 load_stmt = gimple_build_assign (tmpv, tmp);
1109 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
1111 tmp = fold_convert (optype, build_addr (direct_call->decl,
1112 current_function_decl));
1113 load_stmt = gimple_build_assign (tmp1, tmp);
1114 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
1116 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
1117 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
1119 dcall_stmt = gimple_copy (icall_stmt);
1120 gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
1121 gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
1123 /* Fix CFG. */
1124 /* Edge e_cd connects cond_bb to dcall_bb, etc; note the first letters. */
1125 e_cd = split_block (cond_bb, cond_stmt);
1126 dcall_bb = e_cd->dest;
1127 dcall_bb->count = count;
1129 e_di = split_block (dcall_bb, dcall_stmt);
1130 icall_bb = e_di->dest;
1131 icall_bb->count = all - count;
1133 e_ij = split_block (icall_bb, icall_stmt);
1134 join_bb = e_ij->dest;
1135 join_bb->count = all;
1137 e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
1138 e_cd->probability = prob;
1139 e_cd->count = count;
1141 e_ci = make_edge (cond_bb, icall_bb, EDGE_FALSE_VALUE);
1142 e_ci->probability = REG_BR_PROB_BASE - prob;
1143 e_ci->count = all - count;
1145 remove_edge (e_di);
1147 e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
1148 e_dj->probability = REG_BR_PROB_BASE;
1149 e_dj->count = count;
1151 e_ij->probability = REG_BR_PROB_BASE;
1152 e_ij->count = all - count;
1154 /* Fix eh edges */
1155 lp_nr = lookup_stmt_eh_lp (icall_stmt);
1156 if (lp_nr != 0)
1158 if (stmt_could_throw_p (dcall_stmt))
1160 add_stmt_to_eh_lp (dcall_stmt, lp_nr);
1161 make_eh_edges (dcall_stmt);
1164 gcc_assert (stmt_could_throw_p (icall_stmt));
1165 make_eh_edges (icall_stmt);
1167 /* The old EH edges are sill on the join BB, purge them. */
1168 gimple_purge_dead_eh_edges (join_bb);
1171 return dcall_stmt;
1175 For every checked indirect/virtual call determine if most common pid of
1176 function/class method has probability more than 50%. If yes modify code of
1177 this call to:
1180 static bool
1181 gimple_ic_transform (gimple stmt)
1183 histogram_value histogram;
1184 gcov_type val, count, all, bb_all;
1185 gcov_type prob;
1186 tree callee;
1187 gimple modify;
1188 struct cgraph_node *direct_call;
1190 if (gimple_code (stmt) != GIMPLE_CALL)
1191 return false;
1193 callee = gimple_call_fn (stmt);
1195 if (TREE_CODE (callee) == FUNCTION_DECL)
1196 return false;
1198 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);
1199 if (!histogram)
1200 return false;
1202 val = histogram->hvalue.counters [0];
1203 count = histogram->hvalue.counters [1];
1204 all = histogram->hvalue.counters [2];
1205 gimple_remove_histogram_value (cfun, stmt, histogram);
1207 if (4 * count <= 3 * all)
1208 return false;
1210 bb_all = gimple_bb (stmt)->count;
1211 /* The order of CHECK_COUNTER calls is important -
1212 since check_counter can correct the third parameter
1213 and we want to make count <= all <= bb_all. */
1214 if ( check_counter (stmt, "ic", &all, &bb_all, bb_all)
1215 || check_counter (stmt, "ic", &count, &all, all))
1216 return false;
1218 if (all > 0)
1219 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1220 else
1221 prob = 0;
1222 direct_call = find_func_by_pid ((int)val);
1224 if (direct_call == NULL)
1225 return false;
1227 modify = gimple_ic (stmt, direct_call, prob, count, all);
1229 if (dump_file)
1231 fprintf (dump_file, "Indirect call -> direct call ");
1232 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
1233 fprintf (dump_file, "=> ");
1234 print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
1235 fprintf (dump_file, " transformation on insn ");
1236 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1237 fprintf (dump_file, " to ");
1238 print_gimple_stmt (dump_file, modify, 0, TDF_SLIM);
1239 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC
1240 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count, all);
1243 return true;
1246 /* Return true if the stringop CALL with FNDECL shall be profiled.
1247 SIZE_ARG be set to the argument index for the size of the string
1248 operation.
1250 static bool
1251 interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg)
1253 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
1255 if (fcode != BUILT_IN_MEMCPY && fcode != BUILT_IN_MEMPCPY
1256 && fcode != BUILT_IN_MEMSET && fcode != BUILT_IN_BZERO)
1257 return false;
1259 switch (fcode)
1261 case BUILT_IN_MEMCPY:
1262 case BUILT_IN_MEMPCPY:
1263 *size_arg = 2;
1264 return validate_gimple_arglist (call, POINTER_TYPE, POINTER_TYPE,
1265 INTEGER_TYPE, VOID_TYPE);
1266 case BUILT_IN_MEMSET:
1267 *size_arg = 2;
1268 return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1269 INTEGER_TYPE, VOID_TYPE);
1270 case BUILT_IN_BZERO:
1271 *size_arg = 1;
1272 return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1273 VOID_TYPE);
1274 default:
1275 gcc_unreachable ();
1279 /* Convert stringop (..., vcall_size)
1280 into
1281 if (vcall_size == icall_size)
1282 stringop (..., icall_size);
1283 else
1284 stringop (..., vcall_size);
1285 assuming we'll propagate a true constant into ICALL_SIZE later. */
1287 static void
1288 gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
1289 gcov_type count, gcov_type all)
1291 gimple tmp_stmt, cond_stmt, icall_stmt;
1292 tree tmp1, tmpv, vcall_size, optype;
1293 basic_block cond_bb, icall_bb, vcall_bb, join_bb;
1294 edge e_ci, e_cv, e_iv, e_ij, e_vj;
1295 gimple_stmt_iterator gsi;
1296 tree fndecl;
1297 int size_arg;
1299 fndecl = gimple_call_fndecl (vcall_stmt);
1300 if (!interesting_stringop_to_profile_p (fndecl, vcall_stmt, &size_arg))
1301 gcc_unreachable();
1303 cond_bb = gimple_bb (vcall_stmt);
1304 gsi = gsi_for_stmt (vcall_stmt);
1306 vcall_size = gimple_call_arg (vcall_stmt, size_arg);
1307 optype = TREE_TYPE (vcall_size);
1309 tmpv = create_tmp_var (optype, "PROF");
1310 tmp1 = create_tmp_var (optype, "PROF");
1311 tmp_stmt = gimple_build_assign (tmpv, fold_convert (optype, icall_size));
1312 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
1314 tmp_stmt = gimple_build_assign (tmp1, vcall_size);
1315 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
1317 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
1318 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
1320 icall_stmt = gimple_copy (vcall_stmt);
1321 gimple_call_set_arg (icall_stmt, size_arg, icall_size);
1322 gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);
1324 /* Fix CFG. */
1325 /* Edge e_ci connects cond_bb to icall_bb, etc. */
1326 e_ci = split_block (cond_bb, cond_stmt);
1327 icall_bb = e_ci->dest;
1328 icall_bb->count = count;
1330 e_iv = split_block (icall_bb, icall_stmt);
1331 vcall_bb = e_iv->dest;
1332 vcall_bb->count = all - count;
1334 e_vj = split_block (vcall_bb, vcall_stmt);
1335 join_bb = e_vj->dest;
1336 join_bb->count = all;
1338 e_ci->flags = (e_ci->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
1339 e_ci->probability = prob;
1340 e_ci->count = count;
1342 e_cv = make_edge (cond_bb, vcall_bb, EDGE_FALSE_VALUE);
1343 e_cv->probability = REG_BR_PROB_BASE - prob;
1344 e_cv->count = all - count;
1346 remove_edge (e_iv);
1348 e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU);
1349 e_ij->probability = REG_BR_PROB_BASE;
1350 e_ij->count = count;
1352 e_vj->probability = REG_BR_PROB_BASE;
1353 e_vj->count = all - count;
1355 /* Because these are all string op builtins, they're all nothrow. */
1356 gcc_assert (!stmt_could_throw_p (vcall_stmt));
1357 gcc_assert (!stmt_could_throw_p (icall_stmt));
1360 /* Find values inside STMT for that we want to measure histograms for
1361 division/modulo optimization. */
1362 static bool
1363 gimple_stringops_transform (gimple_stmt_iterator *gsi)
1365 gimple stmt = gsi_stmt (*gsi);
1366 tree fndecl;
1367 tree blck_size;
1368 enum built_in_function fcode;
1369 histogram_value histogram;
1370 gcov_type count, all, val;
1371 tree dest, src;
1372 unsigned int dest_align, src_align;
1373 gcov_type prob;
1374 tree tree_val;
1375 int size_arg;
1377 if (gimple_code (stmt) != GIMPLE_CALL)
1378 return false;
1379 fndecl = gimple_call_fndecl (stmt);
1380 if (!fndecl)
1381 return false;
1382 fcode = DECL_FUNCTION_CODE (fndecl);
1383 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
1384 return false;
1386 blck_size = gimple_call_arg (stmt, size_arg);
1387 if (TREE_CODE (blck_size) == INTEGER_CST)
1388 return false;
1390 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
1391 if (!histogram)
1392 return false;
1393 val = histogram->hvalue.counters[0];
1394 count = histogram->hvalue.counters[1];
1395 all = histogram->hvalue.counters[2];
1396 gimple_remove_histogram_value (cfun, stmt, histogram);
1397 /* We require that count is at least half of all; this means
1398 that for the transformation to fire the value must be constant
1399 at least 80% of time. */
1400 if ((6 * count / 5) < all || optimize_bb_for_size_p (gimple_bb (stmt)))
1401 return false;
1402 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
1403 return false;
1404 if (all > 0)
1405 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1406 else
1407 prob = 0;
1408 dest = gimple_call_arg (stmt, 0);
1409 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1410 switch (fcode)
1412 case BUILT_IN_MEMCPY:
1413 case BUILT_IN_MEMPCPY:
1414 src = gimple_call_arg (stmt, 1);
1415 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1416 if (!can_move_by_pieces (val, MIN (dest_align, src_align)))
1417 return false;
1418 break;
1419 case BUILT_IN_MEMSET:
1420 if (!can_store_by_pieces (val, builtin_memset_read_str,
1421 gimple_call_arg (stmt, 1),
1422 dest_align, true))
1423 return false;
1424 break;
1425 case BUILT_IN_BZERO:
1426 if (!can_store_by_pieces (val, builtin_memset_read_str,
1427 integer_zero_node,
1428 dest_align, true))
1429 return false;
1430 break;
1431 default:
1432 gcc_unreachable ();
1434 tree_val = build_int_cst_wide (get_gcov_type (),
1435 (unsigned HOST_WIDE_INT) val,
1436 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
1437 if (dump_file)
1439 fprintf (dump_file, "Single value %i stringop transformation on ",
1440 (int)val);
1441 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1443 gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
1445 return true;
1448 void
1449 stringop_block_profile (gimple stmt, unsigned int *expected_align,
1450 HOST_WIDE_INT *expected_size)
1452 histogram_value histogram;
1453 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE);
1454 if (!histogram)
1455 *expected_size = -1;
1456 else if (!histogram->hvalue.counters[1])
1458 *expected_size = -1;
1459 gimple_remove_histogram_value (cfun, stmt, histogram);
1461 else
1463 gcov_type size;
1464 size = ((histogram->hvalue.counters[0]
1465 + histogram->hvalue.counters[1] / 2)
1466 / histogram->hvalue.counters[1]);
1467 /* Even if we can hold bigger value in SIZE, INT_MAX
1468 is safe "infinity" for code generation strategies. */
1469 if (size > INT_MAX)
1470 size = INT_MAX;
1471 *expected_size = size;
1472 gimple_remove_histogram_value (cfun, stmt, histogram);
1474 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR);
1475 if (!histogram)
1476 *expected_align = 0;
1477 else if (!histogram->hvalue.counters[0])
1479 gimple_remove_histogram_value (cfun, stmt, histogram);
1480 *expected_align = 0;
1482 else
1484 gcov_type count;
1485 int alignment;
1487 count = histogram->hvalue.counters[0];
1488 alignment = 1;
1489 while (!(count & alignment)
1490 && (alignment * 2 * BITS_PER_UNIT))
1491 alignment <<= 1;
1492 *expected_align = alignment * BITS_PER_UNIT;
1493 gimple_remove_histogram_value (cfun, stmt, histogram);
1497 struct value_prof_hooks {
1498 /* Find list of values for which we want to measure histograms. */
1499 void (*find_values_to_profile) (histogram_values *);
1501 /* Identify and exploit properties of values that are hard to analyze
1502 statically. See value-prof.c for more detail. */
1503 bool (*value_profile_transformations) (void);
1506 /* Find values inside STMT for that we want to measure histograms for
1507 division/modulo optimization. */
1508 static void
1509 gimple_divmod_values_to_profile (gimple stmt, histogram_values *values)
1511 tree lhs, divisor, op0, type;
1512 histogram_value hist;
1514 if (gimple_code (stmt) != GIMPLE_ASSIGN)
1515 return;
1517 lhs = gimple_assign_lhs (stmt);
1518 type = TREE_TYPE (lhs);
1519 if (!INTEGRAL_TYPE_P (type))
1520 return;
1522 switch (gimple_assign_rhs_code (stmt))
1524 case TRUNC_DIV_EXPR:
1525 case TRUNC_MOD_EXPR:
1526 divisor = gimple_assign_rhs2 (stmt);
1527 op0 = gimple_assign_rhs1 (stmt);
1529 VEC_reserve (histogram_value, heap, *values, 3);
1531 if (is_gimple_reg (divisor))
1532 /* Check for the case where the divisor is the same value most
1533 of the time. */
1534 VEC_quick_push (histogram_value, *values,
1535 gimple_alloc_histogram_value (cfun,
1536 HIST_TYPE_SINGLE_VALUE,
1537 stmt, divisor));
1539 /* For mod, check whether it is not often a noop (or replaceable by
1540 a few subtractions). */
1541 if (gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR
1542 && TYPE_UNSIGNED (type))
1544 tree val;
1545 /* Check for a special case where the divisor is power of 2. */
1546 VEC_quick_push (histogram_value, *values,
1547 gimple_alloc_histogram_value (cfun, HIST_TYPE_POW2,
1548 stmt, divisor));
1550 val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
1551 hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
1552 stmt, val);
1553 hist->hdata.intvl.int_start = 0;
1554 hist->hdata.intvl.steps = 2;
1555 VEC_quick_push (histogram_value, *values, hist);
1557 return;
1559 default:
1560 return;
1564 /* Find calls inside STMT for that we want to measure histograms for
1565 indirect/virtual call optimization. */
1567 static void
1568 gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
1570 tree callee;
1572 if (gimple_code (stmt) != GIMPLE_CALL
1573 || gimple_call_fndecl (stmt) != NULL_TREE)
1574 return;
1576 callee = gimple_call_fn (stmt);
1578 VEC_reserve (histogram_value, heap, *values, 3);
1580 VEC_quick_push (histogram_value, *values,
1581 gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
1582 stmt, callee));
1584 return;
1587 /* Find values inside STMT for that we want to measure histograms for
1588 string operations. */
1589 static void
1590 gimple_stringops_values_to_profile (gimple stmt, histogram_values *values)
1592 tree fndecl;
1593 tree blck_size;
1594 tree dest;
1595 int size_arg;
1597 if (gimple_code (stmt) != GIMPLE_CALL)
1598 return;
1599 fndecl = gimple_call_fndecl (stmt);
1600 if (!fndecl)
1601 return;
1603 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
1604 return;
1606 dest = gimple_call_arg (stmt, 0);
1607 blck_size = gimple_call_arg (stmt, size_arg);
1609 if (TREE_CODE (blck_size) != INTEGER_CST)
1611 VEC_safe_push (histogram_value, heap, *values,
1612 gimple_alloc_histogram_value (cfun, HIST_TYPE_SINGLE_VALUE,
1613 stmt, blck_size));
1614 VEC_safe_push (histogram_value, heap, *values,
1615 gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE,
1616 stmt, blck_size));
1618 if (TREE_CODE (blck_size) != INTEGER_CST)
1619 VEC_safe_push (histogram_value, heap, *values,
1620 gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR,
1621 stmt, dest));
1624 /* Find values inside STMT for that we want to measure histograms and adds
1625 them to list VALUES. */
1627 static void
1628 gimple_values_to_profile (gimple stmt, histogram_values *values)
1630 if (flag_value_profile_transformations)
1632 gimple_divmod_values_to_profile (stmt, values);
1633 gimple_stringops_values_to_profile (stmt, values);
1634 gimple_indirect_call_to_profile (stmt, values);
1638 static void
1639 gimple_find_values_to_profile (histogram_values *values)
1641 basic_block bb;
1642 gimple_stmt_iterator gsi;
1643 unsigned i;
1644 histogram_value hist = NULL;
1646 *values = NULL;
1647 FOR_EACH_BB (bb)
1648 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1649 gimple_values_to_profile (gsi_stmt (gsi), values);
1651 for (i = 0; VEC_iterate (histogram_value, *values, i, hist); i++)
1653 switch (hist->type)
1655 case HIST_TYPE_INTERVAL:
1656 hist->n_counters = hist->hdata.intvl.steps + 2;
1657 break;
1659 case HIST_TYPE_POW2:
1660 hist->n_counters = 2;
1661 break;
1663 case HIST_TYPE_SINGLE_VALUE:
1664 hist->n_counters = 3;
1665 break;
1667 case HIST_TYPE_CONST_DELTA:
1668 hist->n_counters = 4;
1669 break;
1671 case HIST_TYPE_INDIR_CALL:
1672 hist->n_counters = 3;
1673 break;
1675 case HIST_TYPE_AVERAGE:
1676 hist->n_counters = 2;
1677 break;
1679 case HIST_TYPE_IOR:
1680 hist->n_counters = 1;
1681 break;
1683 default:
1684 gcc_unreachable ();
1686 if (dump_file)
1688 fprintf (dump_file, "Stmt ");
1689 print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM);
1690 dump_histogram_value (dump_file, hist);
1695 static struct value_prof_hooks gimple_value_prof_hooks = {
1696 gimple_find_values_to_profile,
1697 gimple_value_profile_transformations
1700 void
1701 gimple_register_value_prof_hooks (void)
1703 gcc_assert (current_ir_type () == IR_GIMPLE);
1704 value_prof_hooks = &gimple_value_prof_hooks;
1707 /* IR-independent entry points. */
1708 void
1709 find_values_to_profile (histogram_values *values)
1711 (value_prof_hooks->find_values_to_profile) (values);
1714 bool
1715 value_profile_transformations (void)
1717 return (value_prof_hooks->value_profile_transformations) ();