Merge from trunk: 215733-215743
[official-gcc.git] / gcc-4_6_3-mobile / gcc / value-prof.c
blobc5a693964cfd867bf8d3347c4f5ff88edde5b460
1 /* Transformations based on profile information for values.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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 "pointer-set.h"
49 #include "langhooks.h"
50 #include "params.h"
51 #include "l-ipo.h"
52 #include "profile.h"
54 /* In this file value profile based optimizations are placed. Currently the
55 following optimizations are implemented (for more detailed descriptions
56 see comments at value_profile_transformations):
58 1) Division/modulo specialization. Provided that we can determine that the
59 operands of the division have some special properties, we may use it to
60 produce more effective code.
61 2) Speculative prefetching. If we are able to determine that the difference
62 between addresses accessed by a memory reference is usually constant, we
63 may add the prefetch instructions.
64 FIXME: This transformation was removed together with RTL based value
65 profiling.
67 3) Indirect/virtual call specialization. If we can determine most
68 common function callee in indirect/virtual call. We can use this
69 information to improve code effectiveness (especially info for
70 inliner).
72 Every such optimization should add its requirements for profiled values to
73 insn_values_to_profile function. This function is called from branch_prob
74 in profile.c and the requested values are instrumented by it in the first
75 compilation with -fprofile-arcs. The optimization may then read the
76 gathered data in the second compilation with -fbranch-probabilities.
78 The measured data is pointed to from the histograms
79 field of the statement annotation of the instrumented insns. It is
80 kept as a linked list of struct histogram_value_t's, which contain the
81 same information as above. */
84 static tree gimple_divmod_fixed_value (gimple, tree, int, gcov_type, gcov_type);
85 static tree gimple_mod_pow2 (gimple, int, gcov_type, gcov_type);
86 static tree gimple_mod_subtract (gimple, int, int, int, gcov_type, gcov_type,
87 gcov_type);
88 static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *);
89 static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *);
90 static bool gimple_mod_subtract_transform (gimple_stmt_iterator *);
91 static bool gimple_stringops_transform (gimple_stmt_iterator *);
92 static bool gimple_ic_transform (gimple);
94 /* Allocate histogram value. */
96 static histogram_value
97 gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED,
98 enum hist_type type, gimple stmt, tree value)
100 histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist));
101 hist->hvalue.value = value;
102 hist->hvalue.stmt = stmt;
103 hist->type = type;
104 return hist;
107 /* Hash value for histogram. */
109 static hashval_t
110 histogram_hash (const void *x)
112 return htab_hash_pointer (((const_histogram_value)x)->hvalue.stmt);
115 /* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */
117 static int
118 histogram_eq (const void *x, const void *y)
120 return ((const_histogram_value) x)->hvalue.stmt == (const_gimple) y;
123 /* Set histogram for STMT. */
125 static void
126 set_histogram_value (struct function *fun, gimple stmt, histogram_value hist)
128 void **loc;
129 if (!hist && !VALUE_HISTOGRAMS (fun))
130 return;
131 if (!VALUE_HISTOGRAMS (fun))
132 VALUE_HISTOGRAMS (fun) = htab_create (1, histogram_hash,
133 histogram_eq, NULL);
134 loc = htab_find_slot_with_hash (VALUE_HISTOGRAMS (fun), stmt,
135 htab_hash_pointer (stmt),
136 hist ? INSERT : NO_INSERT);
137 if (!hist)
139 if (loc)
140 htab_clear_slot (VALUE_HISTOGRAMS (fun), loc);
141 return;
143 *loc = hist;
146 /* Get histogram list for STMT. */
148 histogram_value
149 gimple_histogram_value (struct function *fun, gimple stmt)
151 if (!VALUE_HISTOGRAMS (fun))
152 return NULL;
153 return (histogram_value) htab_find_with_hash (VALUE_HISTOGRAMS (fun), stmt,
154 htab_hash_pointer (stmt));
157 /* Add histogram for STMT. */
159 void
160 gimple_add_histogram_value (struct function *fun, gimple stmt,
161 histogram_value hist)
163 hist->hvalue.next = gimple_histogram_value (fun, stmt);
164 set_histogram_value (fun, stmt, hist);
168 /* Remove histogram HIST from STMT's histogram list. */
170 void
171 gimple_remove_histogram_value (struct function *fun, gimple stmt,
172 histogram_value hist)
174 histogram_value hist2 = gimple_histogram_value (fun, stmt);
175 if (hist == hist2)
177 set_histogram_value (fun, stmt, hist->hvalue.next);
179 else
181 while (hist2->hvalue.next != hist)
182 hist2 = hist2->hvalue.next;
183 hist2->hvalue.next = hist->hvalue.next;
185 free (hist->hvalue.counters);
186 #ifdef ENABLE_CHECKING
187 memset (hist, 0xab, sizeof (*hist));
188 #endif
189 free (hist);
193 /* Lookup histogram of type TYPE in the STMT. */
195 histogram_value
196 gimple_histogram_value_of_type (struct function *fun, gimple stmt,
197 enum hist_type type)
199 histogram_value hist;
200 for (hist = gimple_histogram_value (fun, stmt); hist;
201 hist = hist->hvalue.next)
202 if (hist->type == type)
203 return hist;
204 return NULL;
207 /* Dump information about HIST to DUMP_FILE. */
209 static void
210 dump_histogram_value (FILE *dump_file, histogram_value hist)
212 switch (hist->type)
214 case HIST_TYPE_INTERVAL:
215 fprintf (dump_file, "Interval counter range %d -- %d",
216 hist->hdata.intvl.int_start,
217 (hist->hdata.intvl.int_start
218 + hist->hdata.intvl.steps - 1));
219 if (hist->hvalue.counters)
221 unsigned int i;
222 fprintf(dump_file, " [");
223 for (i = 0; i < hist->hdata.intvl.steps; i++)
224 fprintf (dump_file, " %d:"HOST_WIDEST_INT_PRINT_DEC,
225 hist->hdata.intvl.int_start + i,
226 (HOST_WIDEST_INT) hist->hvalue.counters[i]);
227 fprintf (dump_file, " ] outside range:"HOST_WIDEST_INT_PRINT_DEC,
228 (HOST_WIDEST_INT) hist->hvalue.counters[i]);
230 fprintf (dump_file, ".\n");
231 break;
233 case HIST_TYPE_POW2:
234 fprintf (dump_file, "Pow2 counter ");
235 if (hist->hvalue.counters)
237 fprintf (dump_file, "pow2:"HOST_WIDEST_INT_PRINT_DEC
238 " nonpow2:"HOST_WIDEST_INT_PRINT_DEC,
239 (HOST_WIDEST_INT) hist->hvalue.counters[0],
240 (HOST_WIDEST_INT) hist->hvalue.counters[1]);
242 fprintf (dump_file, ".\n");
243 break;
245 case HIST_TYPE_SINGLE_VALUE:
246 fprintf (dump_file, "Single value ");
247 if (hist->hvalue.counters)
249 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
250 " match:"HOST_WIDEST_INT_PRINT_DEC
251 " wrong:"HOST_WIDEST_INT_PRINT_DEC,
252 (HOST_WIDEST_INT) hist->hvalue.counters[0],
253 (HOST_WIDEST_INT) hist->hvalue.counters[1],
254 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
256 fprintf (dump_file, ".\n");
257 break;
259 case HIST_TYPE_AVERAGE:
260 fprintf (dump_file, "Average value ");
261 if (hist->hvalue.counters)
263 fprintf (dump_file, "sum:"HOST_WIDEST_INT_PRINT_DEC
264 " times:"HOST_WIDEST_INT_PRINT_DEC,
265 (HOST_WIDEST_INT) hist->hvalue.counters[0],
266 (HOST_WIDEST_INT) hist->hvalue.counters[1]);
268 fprintf (dump_file, ".\n");
269 break;
271 case HIST_TYPE_IOR:
272 fprintf (dump_file, "IOR value ");
273 if (hist->hvalue.counters)
275 fprintf (dump_file, "ior:"HOST_WIDEST_INT_PRINT_DEC,
276 (HOST_WIDEST_INT) hist->hvalue.counters[0]);
278 fprintf (dump_file, ".\n");
279 break;
281 case HIST_TYPE_CONST_DELTA:
282 fprintf (dump_file, "Constant delta ");
283 if (hist->hvalue.counters)
285 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
286 " match:"HOST_WIDEST_INT_PRINT_DEC
287 " wrong:"HOST_WIDEST_INT_PRINT_DEC,
288 (HOST_WIDEST_INT) hist->hvalue.counters[0],
289 (HOST_WIDEST_INT) hist->hvalue.counters[1],
290 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
292 fprintf (dump_file, ".\n");
293 break;
294 case HIST_TYPE_INDIR_CALL:
295 fprintf (dump_file, "Indirect call ");
296 if (hist->hvalue.counters)
298 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
299 " match:"HOST_WIDEST_INT_PRINT_DEC
300 " all:"HOST_WIDEST_INT_PRINT_DEC,
301 (HOST_WIDEST_INT) hist->hvalue.counters[0],
302 (HOST_WIDEST_INT) hist->hvalue.counters[1],
303 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
305 fprintf (dump_file, ".\n");
306 break;
307 case HIST_TYPE_INDIR_CALL_TOPN:
308 fprintf (dump_file, "Indirect call -- top N\n");
309 /* TODO add more elaborate dumping code. */
310 break;
314 /* Dump all histograms attached to STMT to DUMP_FILE. */
316 void
317 dump_histograms_for_stmt (struct function *fun, FILE *dump_file, gimple stmt)
319 histogram_value hist;
320 for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
321 dump_histogram_value (dump_file, hist);
324 /* Remove all histograms associated with STMT. */
326 void
327 gimple_remove_stmt_histograms (struct function *fun, gimple stmt)
329 histogram_value val;
330 while ((val = gimple_histogram_value (fun, stmt)) != NULL)
331 gimple_remove_histogram_value (fun, stmt, val);
334 /* Duplicate all histograms associates with OSTMT to STMT. */
336 void
337 gimple_duplicate_stmt_histograms (struct function *fun, gimple stmt,
338 struct function *ofun, gimple ostmt)
340 histogram_value val;
341 for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next)
343 histogram_value new_val = gimple_alloc_histogram_value (fun, val->type, NULL, NULL);
344 memcpy (new_val, val, sizeof (*val));
345 new_val->hvalue.stmt = stmt;
346 new_val->hvalue.counters = XNEWVAR (gcov_type, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
347 memcpy (new_val->hvalue.counters, val->hvalue.counters, sizeof (*new_val->hvalue.counters) * new_val->n_counters);
348 gimple_add_histogram_value (fun, stmt, new_val);
353 /* Move all histograms associated with OSTMT to STMT. */
355 void
356 gimple_move_stmt_histograms (struct function *fun, gimple stmt, gimple ostmt)
358 histogram_value val = gimple_histogram_value (fun, ostmt);
359 if (val)
361 /* The following three statements can't be reordered,
362 because histogram hashtab relies on stmt field value
363 for finding the exact slot. */
364 set_histogram_value (fun, ostmt, NULL);
365 for (; val != NULL; val = val->hvalue.next)
366 val->hvalue.stmt = stmt;
367 set_histogram_value (fun, stmt, val);
371 static bool error_found = false;
373 /* Helper function for verify_histograms. For each histogram reachable via htab
374 walk verify that it was reached via statement walk. */
376 static int
377 visit_hist (void **slot, void *data)
379 struct pointer_set_t *visited = (struct pointer_set_t *) data;
380 histogram_value hist = *(histogram_value *) slot;
381 if (!pointer_set_contains (visited, hist))
383 error ("dead histogram");
384 dump_histogram_value (stderr, hist);
385 debug_gimple_stmt (hist->hvalue.stmt);
386 error_found = true;
388 return 1;
392 /* Verify sanity of the histograms. */
394 DEBUG_FUNCTION void
395 verify_histograms (void)
397 basic_block bb;
398 gimple_stmt_iterator gsi;
399 histogram_value hist;
400 struct pointer_set_t *visited_hists;
402 error_found = false;
403 visited_hists = pointer_set_create ();
404 FOR_EACH_BB (bb)
405 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
407 gimple stmt = gsi_stmt (gsi);
409 for (hist = gimple_histogram_value (cfun, stmt); hist;
410 hist = hist->hvalue.next)
412 if (hist->hvalue.stmt != stmt)
414 error ("Histogram value statement does not correspond to "
415 "the statement it is associated with");
416 debug_gimple_stmt (stmt);
417 dump_histogram_value (stderr, hist);
418 error_found = true;
420 pointer_set_insert (visited_hists, hist);
423 if (VALUE_HISTOGRAMS (cfun))
424 htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, visited_hists);
425 pointer_set_destroy (visited_hists);
426 if (error_found)
427 internal_error ("verify_histograms failed");
430 /* Helper function for verify_histograms. For each histogram reachable via htab
431 walk verify that it was reached via statement walk. */
433 static int
434 free_hist (void **slot, void *data ATTRIBUTE_UNUSED)
436 histogram_value hist = *(histogram_value *) slot;
437 free (hist->hvalue.counters);
438 #ifdef ENABLE_CHECKING
439 memset (hist, 0xab, sizeof (*hist));
440 #endif
441 free (hist);
442 return 1;
445 void
446 free_histograms (void)
448 if (VALUE_HISTOGRAMS (cfun))
450 htab_traverse (VALUE_HISTOGRAMS (cfun), free_hist, NULL);
451 htab_delete (VALUE_HISTOGRAMS (cfun));
452 VALUE_HISTOGRAMS (cfun) = NULL;
457 /* The overall number of invocations of the counter should match
458 execution count of basic block. Report it as error rather than
459 internal error as it might mean that user has misused the profile
460 somehow. */
462 static bool
463 check_counter (gimple stmt, const char * name,
464 gcov_type *count, gcov_type *all, gcov_type bb_count)
466 if (*all != bb_count || *count > *all)
468 location_t locus;
469 locus = (stmt != NULL)
470 ? gimple_location (stmt)
471 : DECL_SOURCE_LOCATION (current_function_decl);
472 if (flag_profile_correction)
474 if (flag_opt_info >= OPT_INFO_MAX)
475 inform (locus, "correcting inconsistent value profile: %s "
476 "profiler overall count (%d) does not match BB count "
477 "(%d)", name, (int)*all, (int)bb_count);
478 *all = bb_count;
479 if (*count > *all)
480 *count = *all;
481 return false;
483 else
485 error_at (locus, "corrupted value profile: %s "
486 "profile counter (%d out of %d) inconsistent with "
487 "basic-block count (%d)",
488 name,
489 (int) *count,
490 (int) *all,
491 (int) bb_count);
492 return true;
496 return false;
499 /* The overall number of invocations of the counter should match
500 execution count of basic block. Report it as error rather than
501 internal error as it might mean that user has misused the profile
502 somehow. STMT is the indiret call, COUNT1 and COUNT2 are counts
503 of two top targets, and ALL is the enclosing basic block execution
504 count. */
506 static bool
507 check_ic_counter (gimple stmt, gcov_type *count1, gcov_type *count2,
508 gcov_type all)
510 location_t locus;
511 if (*count1 > all && flag_profile_correction)
513 if (flag_opt_info >= OPT_INFO_MAX)
515 locus = (stmt != NULL)
516 ? gimple_location (stmt)
517 : DECL_SOURCE_LOCATION (current_function_decl);
518 inform (locus, "Correcting inconsistent value profile: "
519 "ic (topn) profiler top target count (%ld) exceeds "
520 "BB count (%ld)", (long)*count1, (long)all);
522 *count1 = all;
524 if (*count2 > all && flag_profile_correction)
526 if (flag_opt_info >= OPT_INFO_MAX)
528 locus = (stmt != NULL)
529 ? gimple_location (stmt)
530 : DECL_SOURCE_LOCATION (current_function_decl);
531 inform (locus, "Correcting inconsistent value profile: "
532 "ic (topn) profiler second target count (%ld) exceeds "
533 "BB count (%ld)", (long)*count2, (long)all);
535 *count2 = all;
538 if (*count2 > *count1)
540 if (flag_opt_info >= OPT_INFO_MAX)
542 locus = (stmt != NULL)
543 ? gimple_location (stmt)
544 : DECL_SOURCE_LOCATION (current_function_decl);
545 inform (locus, "Corrupted topn ic value profile: "
546 "first target count (%ld) is less than the second "
547 "target count (%ld)", (long)*count1, (long)*count2);
549 return true;
552 if (*count1 + *count2 > all)
554 /* If (COUNT1 + COUNT2) is greater than ALL by less than around 10% then
555 just fix COUNT2 up so that (COUNT1 + COUNT2) equals ALL. */
556 if ((*count1 + *count2 - all) < (all >> 3))
557 *count2 = all - *count1;
558 else
560 if (flag_opt_info >= OPT_INFO_MAX)
562 locus = (stmt != NULL)
563 ? gimple_location (stmt)
564 : DECL_SOURCE_LOCATION (current_function_decl);
565 inform (locus,
566 "Corrupted topn ic value profile: top two targets's"
567 " total count (%ld) exceeds bb count (%ld)",
568 (long)(*count1 + *count2), (long)all);
570 return true;
573 return false;
577 /* GIMPLE based transformations. */
579 bool
580 gimple_value_profile_transformations (void)
582 basic_block bb;
583 gimple_stmt_iterator gsi;
584 bool changed = false;
586 FOR_EACH_BB (bb)
588 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
590 gimple stmt = gsi_stmt (gsi);
591 histogram_value th = gimple_histogram_value (cfun, stmt);
592 if (!th)
593 continue;
595 if (dump_file)
597 fprintf (dump_file, "Trying transformations on stmt ");
598 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
599 dump_histograms_for_stmt (cfun, dump_file, stmt);
602 /* Transformations: */
603 /* The order of things in this conditional controls which
604 transformation is used when more than one is applicable. */
605 /* It is expected that any code added by the transformations
606 will be added before the current statement, and that the
607 current statement remain valid (although possibly
608 modified) upon return. */
609 if (flag_value_profile_transformations
610 && (gimple_mod_subtract_transform (&gsi)
611 || gimple_divmod_fixed_value_transform (&gsi)
612 || gimple_mod_pow2_value_transform (&gsi)
613 || gimple_stringops_transform (&gsi)
614 || gimple_ic_transform (stmt)))
616 stmt = gsi_stmt (gsi);
617 changed = true;
618 /* Original statement may no longer be in the same block. */
619 if (bb != gimple_bb (stmt))
621 bb = gimple_bb (stmt);
622 gsi = gsi_for_stmt (stmt);
628 if (changed)
630 counts_to_freqs ();
631 /* Value profile transformations may change inline parameters
632 a lot (e.g., indirect call promotion introduces new direct calls).
633 The update is also needed to avoid compiler ICE -- when MULTI
634 target icall promotion happens, the caller's size may become
635 negative when the promoted direct calls get promoted. */
636 /* Guard this for LIPO for now. */
637 if (L_IPO_COMP_MODE || flag_ripa_stream)
638 compute_inline_parameters (cgraph_node (current_function_decl));
641 return changed;
645 /* Generate code for transformation 1 (with parent gimple assignment
646 STMT and probability of taking the optimal path PROB, which is
647 equivalent to COUNT/ALL within roundoff error). This generates the
648 result into a temp and returns the temp; it does not replace or
649 alter the original STMT. */
651 static tree
652 gimple_divmod_fixed_value (gimple stmt, tree value, int prob, gcov_type count,
653 gcov_type all)
655 gimple stmt1, stmt2, stmt3;
656 tree tmp0, tmp1, tmp2, tmpv;
657 gimple bb1end, bb2end, bb3end;
658 basic_block bb, bb2, bb3, bb4;
659 tree optype, op1, op2;
660 edge e12, e13, e23, e24, e34;
661 gimple_stmt_iterator gsi;
663 gcc_assert (is_gimple_assign (stmt)
664 && (gimple_assign_rhs_code (stmt) == TRUNC_DIV_EXPR
665 || gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR));
667 optype = TREE_TYPE (gimple_assign_lhs (stmt));
668 op1 = gimple_assign_rhs1 (stmt);
669 op2 = gimple_assign_rhs2 (stmt);
671 bb = gimple_bb (stmt);
672 gsi = gsi_for_stmt (stmt);
674 tmpv = create_tmp_reg (optype, "PROF");
675 tmp0 = make_ssa_name (tmpv, NULL);
676 tmp1 = make_ssa_name (tmpv, NULL);
677 stmt1 = gimple_build_assign (tmp0, fold_convert (optype, value));
678 SSA_NAME_DEF_STMT (tmp0) = stmt1;
679 stmt2 = gimple_build_assign (tmp1, op2);
680 SSA_NAME_DEF_STMT (tmp1) = stmt2;
681 stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
682 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
683 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
684 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
685 bb1end = stmt3;
687 tmp2 = make_rename_temp (optype, "PROF");
688 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
689 op1, tmp0);
690 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
691 bb2end = stmt1;
693 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
694 op1, op2);
695 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
696 bb3end = stmt1;
698 /* Fix CFG. */
699 /* Edge e23 connects bb2 to bb3, etc. */
700 e12 = split_block (bb, bb1end);
701 bb2 = e12->dest;
702 bb2->count = count;
703 e23 = split_block (bb2, bb2end);
704 bb3 = e23->dest;
705 bb3->count = all - count;
706 e34 = split_block (bb3, bb3end);
707 bb4 = e34->dest;
708 bb4->count = all;
710 e12->flags &= ~EDGE_FALLTHRU;
711 e12->flags |= EDGE_FALSE_VALUE;
712 e12->probability = prob;
713 e12->count = count;
715 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
716 e13->probability = REG_BR_PROB_BASE - prob;
717 e13->count = all - count;
719 remove_edge (e23);
721 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
722 e24->probability = REG_BR_PROB_BASE;
723 e24->count = count;
725 e34->probability = REG_BR_PROB_BASE;
726 e34->count = all - count;
728 return tmp2;
732 /* Do transform 1) on INSN if applicable. */
734 static bool
735 gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
737 histogram_value histogram;
738 enum tree_code code;
739 gcov_type val, count, all;
740 tree result, value, tree_val;
741 gcov_type prob;
742 gimple stmt;
744 stmt = gsi_stmt (*si);
745 if (gimple_code (stmt) != GIMPLE_ASSIGN)
746 return false;
748 if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))))
749 return false;
751 code = gimple_assign_rhs_code (stmt);
753 if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
754 return false;
756 histogram = gimple_histogram_value_of_type (cfun, stmt,
757 HIST_TYPE_SINGLE_VALUE);
758 if (!histogram)
759 return false;
761 value = histogram->hvalue.value;
762 val = histogram->hvalue.counters[0];
763 count = histogram->hvalue.counters[1];
764 all = histogram->hvalue.counters[2];
765 gimple_remove_histogram_value (cfun, stmt, histogram);
767 /* We require that count is at least half of all; this means
768 that for the transformation to fire the value must be constant
769 at least 50% of time (and 75% gives the guarantee of usage). */
770 if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
771 || 2 * count < all
772 || optimize_bb_for_size_p (gimple_bb (stmt)))
773 return false;
775 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
776 return false;
778 /* Compute probability of taking the optimal path. */
779 if (all > 0)
780 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
781 else
782 prob = 0;
784 tree_val = build_int_cst_wide (get_gcov_type (),
785 (unsigned HOST_WIDE_INT) val,
786 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
787 result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all);
789 if (dump_file)
791 fprintf (dump_file, "Div/mod by constant ");
792 print_generic_expr (dump_file, value, TDF_SLIM);
793 fprintf (dump_file, "=");
794 print_generic_expr (dump_file, tree_val, TDF_SLIM);
795 fprintf (dump_file, " transformation on insn ");
796 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
799 gimple_assign_set_rhs_from_tree (si, result);
800 update_stmt (gsi_stmt (*si));
802 return true;
805 /* Generate code for transformation 2 (with parent gimple assign STMT and
806 probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
807 within roundoff error). This generates the result into a temp and returns
808 the temp; it does not replace or alter the original STMT. */
809 static tree
810 gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
812 gimple stmt1, stmt2, stmt3, stmt4;
813 tree tmp2, tmp3, tmpv;
814 gimple bb1end, bb2end, bb3end;
815 basic_block bb, bb2, bb3, bb4;
816 tree optype, op1, op2;
817 edge e12, e13, e23, e24, e34;
818 gimple_stmt_iterator gsi;
819 tree result;
821 gcc_assert (is_gimple_assign (stmt)
822 && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
824 optype = TREE_TYPE (gimple_assign_lhs (stmt));
825 op1 = gimple_assign_rhs1 (stmt);
826 op2 = gimple_assign_rhs2 (stmt);
828 bb = gimple_bb (stmt);
829 gsi = gsi_for_stmt (stmt);
831 result = make_rename_temp (optype, "PROF");
832 tmpv = create_tmp_var (optype, "PROF");
833 tmp2 = make_ssa_name (tmpv, NULL);
834 tmp3 = make_ssa_name (tmpv, NULL);
835 stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2,
836 build_int_cst (optype, -1));
837 SSA_NAME_DEF_STMT (tmp2) = stmt2;
838 stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2);
839 SSA_NAME_DEF_STMT (tmp3) = stmt3;
840 stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0),
841 NULL_TREE, NULL_TREE);
842 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
843 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
844 gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
845 bb1end = stmt4;
847 /* tmp2 == op2-1 inherited from previous block. */
848 stmt1 = gimple_build_assign_with_ops (BIT_AND_EXPR, result, op1, tmp2);
849 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
850 bb2end = stmt1;
852 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
853 op1, op2);
854 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
855 bb3end = stmt1;
857 /* Fix CFG. */
858 /* Edge e23 connects bb2 to bb3, etc. */
859 e12 = split_block (bb, bb1end);
860 bb2 = e12->dest;
861 bb2->count = count;
862 e23 = split_block (bb2, bb2end);
863 bb3 = e23->dest;
864 bb3->count = all - count;
865 e34 = split_block (bb3, bb3end);
866 bb4 = e34->dest;
867 bb4->count = all;
869 e12->flags &= ~EDGE_FALLTHRU;
870 e12->flags |= EDGE_FALSE_VALUE;
871 e12->probability = prob;
872 e12->count = count;
874 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
875 e13->probability = REG_BR_PROB_BASE - prob;
876 e13->count = all - count;
878 remove_edge (e23);
880 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
881 e24->probability = REG_BR_PROB_BASE;
882 e24->count = count;
884 e34->probability = REG_BR_PROB_BASE;
885 e34->count = all - count;
887 return result;
890 /* Do transform 2) on INSN if applicable. */
891 static bool
892 gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
894 histogram_value histogram;
895 enum tree_code code;
896 gcov_type count, wrong_values, all;
897 tree lhs_type, result, value;
898 gcov_type prob;
899 gimple stmt;
901 stmt = gsi_stmt (*si);
902 if (gimple_code (stmt) != GIMPLE_ASSIGN)
903 return false;
905 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
906 if (!INTEGRAL_TYPE_P (lhs_type))
907 return false;
909 code = gimple_assign_rhs_code (stmt);
911 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
912 return false;
914 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_POW2);
915 if (!histogram)
916 return false;
918 value = histogram->hvalue.value;
919 wrong_values = histogram->hvalue.counters[0];
920 count = histogram->hvalue.counters[1];
922 gimple_remove_histogram_value (cfun, stmt, histogram);
924 /* We require that we hit a power of 2 at least half of all evaluations. */
925 if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
926 || count < wrong_values
927 || optimize_bb_for_size_p (gimple_bb (stmt)))
928 return false;
930 if (dump_file)
932 fprintf (dump_file, "Mod power of 2 transformation on insn ");
933 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
936 /* Compute probability of taking the optimal path. */
937 all = count + wrong_values;
939 if (check_counter (stmt, "pow2", &count, &all, gimple_bb (stmt)->count))
940 return false;
942 if (all > 0)
943 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
944 else
945 prob = 0;
947 result = gimple_mod_pow2 (stmt, prob, count, all);
949 gimple_assign_set_rhs_from_tree (si, result);
950 update_stmt (gsi_stmt (*si));
952 return true;
955 /* Generate code for transformations 3 and 4 (with parent gimple assign STMT, and
956 NCOUNTS the number of cases to support. Currently only NCOUNTS==0 or 1 is
957 supported and this is built into this interface. The probabilities of taking
958 the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
959 COUNT2/ALL respectively within roundoff error). This generates the
960 result into a temp and returns the temp; it does not replace or alter
961 the original STMT. */
962 /* FIXME: Generalize the interface to handle NCOUNTS > 1. */
964 static tree
965 gimple_mod_subtract (gimple stmt, int prob1, int prob2, int ncounts,
966 gcov_type count1, gcov_type count2, gcov_type all)
968 gimple stmt1, stmt2, stmt3;
969 tree tmp1;
970 gimple bb1end, bb2end = NULL, bb3end;
971 basic_block bb, bb2, bb3, bb4;
972 tree optype, op1, op2;
973 edge e12, e23 = 0, e24, e34, e14;
974 gimple_stmt_iterator gsi;
975 tree result;
977 gcc_assert (is_gimple_assign (stmt)
978 && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
980 optype = TREE_TYPE (gimple_assign_lhs (stmt));
981 op1 = gimple_assign_rhs1 (stmt);
982 op2 = gimple_assign_rhs2 (stmt);
984 bb = gimple_bb (stmt);
985 gsi = gsi_for_stmt (stmt);
987 result = make_rename_temp (optype, "PROF");
988 tmp1 = make_ssa_name (create_tmp_var (optype, "PROF"), NULL);
989 stmt1 = gimple_build_assign (result, op1);
990 stmt2 = gimple_build_assign (tmp1, op2);
991 SSA_NAME_DEF_STMT (tmp1) = stmt2;
992 stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
993 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
994 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
995 gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
996 bb1end = stmt3;
998 if (ncounts) /* Assumed to be 0 or 1 */
1000 stmt1 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, tmp1);
1001 stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
1002 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
1003 gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
1004 bb2end = stmt2;
1007 /* Fallback case. */
1008 stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
1009 result, tmp1);
1010 gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
1011 bb3end = stmt1;
1013 /* Fix CFG. */
1014 /* Edge e23 connects bb2 to bb3, etc. */
1015 /* However block 3 is optional; if it is not there, references
1016 to 3 really refer to block 2. */
1017 e12 = split_block (bb, bb1end);
1018 bb2 = e12->dest;
1019 bb2->count = all - count1;
1021 if (ncounts) /* Assumed to be 0 or 1. */
1023 e23 = split_block (bb2, bb2end);
1024 bb3 = e23->dest;
1025 bb3->count = all - count1 - count2;
1028 e34 = split_block (ncounts ? bb3 : bb2, bb3end);
1029 bb4 = e34->dest;
1030 bb4->count = all;
1032 e12->flags &= ~EDGE_FALLTHRU;
1033 e12->flags |= EDGE_FALSE_VALUE;
1034 e12->probability = REG_BR_PROB_BASE - prob1;
1035 e12->count = all - count1;
1037 e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE);
1038 e14->probability = prob1;
1039 e14->count = count1;
1041 if (ncounts) /* Assumed to be 0 or 1. */
1043 e23->flags &= ~EDGE_FALLTHRU;
1044 e23->flags |= EDGE_FALSE_VALUE;
1045 e23->count = all - count1 - count2;
1046 e23->probability = REG_BR_PROB_BASE - prob2;
1048 e24 = make_edge (bb2, bb4, EDGE_TRUE_VALUE);
1049 e24->probability = prob2;
1050 e24->count = count2;
1053 e34->probability = REG_BR_PROB_BASE;
1054 e34->count = all - count1 - count2;
1056 return result;
1060 /* Do transforms 3) and 4) on the statement pointed-to by SI if applicable. */
1062 static bool
1063 gimple_mod_subtract_transform (gimple_stmt_iterator *si)
1065 histogram_value histogram;
1066 enum tree_code code;
1067 gcov_type count, wrong_values, all;
1068 tree lhs_type, result;
1069 gcov_type prob1, prob2;
1070 unsigned int i, steps;
1071 gcov_type count1, count2;
1072 gimple stmt;
1074 stmt = gsi_stmt (*si);
1075 if (gimple_code (stmt) != GIMPLE_ASSIGN)
1076 return false;
1078 lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
1079 if (!INTEGRAL_TYPE_P (lhs_type))
1080 return false;
1082 code = gimple_assign_rhs_code (stmt);
1084 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
1085 return false;
1087 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INTERVAL);
1088 if (!histogram)
1089 return false;
1091 all = 0;
1092 wrong_values = 0;
1093 for (i = 0; i < histogram->hdata.intvl.steps; i++)
1094 all += histogram->hvalue.counters[i];
1096 wrong_values += histogram->hvalue.counters[i];
1097 wrong_values += histogram->hvalue.counters[i+1];
1098 steps = histogram->hdata.intvl.steps;
1099 all += wrong_values;
1100 count1 = histogram->hvalue.counters[0];
1101 count2 = histogram->hvalue.counters[1];
1103 /* Compute probability of taking the optimal path. */
1104 if (check_counter (stmt, "interval", &count1, &all, gimple_bb (stmt)->count))
1106 gimple_remove_histogram_value (cfun, stmt, histogram);
1107 return false;
1110 if (flag_profile_correction && count1 + count2 > all)
1111 all = count1 + count2;
1113 gcc_assert (count1 + count2 <= all);
1115 /* We require that we use just subtractions in at least 50% of all
1116 evaluations. */
1117 count = 0;
1118 for (i = 0; i < histogram->hdata.intvl.steps; i++)
1120 count += histogram->hvalue.counters[i];
1121 if (count * 2 >= all)
1122 break;
1124 if (i == steps
1125 || optimize_bb_for_size_p (gimple_bb (stmt)))
1126 return false;
1128 gimple_remove_histogram_value (cfun, stmt, histogram);
1129 if (dump_file)
1131 fprintf (dump_file, "Mod subtract transformation on insn ");
1132 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1135 /* Compute probability of taking the optimal path(s). */
1136 if (all > 0)
1138 prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all;
1139 prob2 = (count2 * REG_BR_PROB_BASE + all / 2) / all;
1141 else
1143 prob1 = prob2 = 0;
1146 /* In practice, "steps" is always 2. This interface reflects this,
1147 and will need to be changed if "steps" can change. */
1148 result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all);
1150 gimple_assign_set_rhs_from_tree (si, result);
1151 update_stmt (gsi_stmt (*si));
1153 return true;
1156 static VEC(cgraph_node_ptr, heap) *cgraph_node_map = NULL;
1158 /* Initialize map from FUNCDEF_NO to CGRAPH_NODE. */
1160 void
1161 init_node_map (void)
1163 struct cgraph_node *n;
1165 if (L_IPO_COMP_MODE || flag_ripa_stream)
1166 return;
1168 if (get_last_funcdef_no ())
1169 VEC_safe_grow_cleared (cgraph_node_ptr, heap,
1170 cgraph_node_map, get_last_funcdef_no ());
1172 for (n = cgraph_nodes; n; n = n->next)
1174 if (DECL_STRUCT_FUNCTION (n->decl))
1175 VEC_replace (cgraph_node_ptr, cgraph_node_map,
1176 DECL_STRUCT_FUNCTION (n->decl)->funcdef_no, n);
1180 /* Delete the CGRAPH_NODE_MAP. */
1182 void
1183 del_node_map (void)
1185 if (L_IPO_COMP_MODE || flag_ripa_stream)
1186 return;
1188 VEC_free (cgraph_node_ptr, heap, cgraph_node_map);
1189 cgraph_node_map = NULL;
1192 /* Return cgraph node for function with pid */
1194 static inline struct cgraph_node*
1195 find_func_by_funcdef_no (int func_id)
1197 int max_id = get_last_funcdef_no ();
1198 if (func_id >= max_id || VEC_index (cgraph_node_ptr,
1199 cgraph_node_map,
1200 func_id) == NULL)
1202 if (flag_profile_correction)
1204 if (flag_opt_info >= OPT_INFO_MED)
1205 inform (DECL_SOURCE_LOCATION (current_function_decl),
1206 "Inconsistent profile: indirect call target (%d) does not exist", func_id);
1208 else
1209 error ("Inconsistent profile: indirect call target (%d) does not exist", func_id);
1211 return NULL;
1214 return VEC_index (cgraph_node_ptr, cgraph_node_map, func_id);
1217 /* Initialize map of gids (gid -> cgraph node) */
1219 static htab_t gid_map = NULL;
1221 typedef struct func_gid_entry
1223 struct cgraph_node *node;
1224 unsigned HOST_WIDEST_INT gid;
1225 } func_gid_entry_t;
1227 /* Hash function for function global unique ids. */
1229 static hashval_t
1230 htab_gid_hash (const void * ent)
1232 const func_gid_entry_t *const entry = (const func_gid_entry_t *) ent;
1233 return entry->gid;
1236 /* Hash table equality function for function global unique ids. */
1238 static int
1239 htab_gid_eq (const void *ent1, const void * ent2)
1241 const func_gid_entry_t *const entry1 = (const func_gid_entry_t *) ent1;
1242 const func_gid_entry_t *const entry2 = (const func_gid_entry_t *) ent2;
1243 return entry1->gid == entry2->gid;
1246 static void
1247 htab_gid_del (void *ent)
1249 func_gid_entry_t *const entry = (func_gid_entry_t *) ent;
1250 free (entry);
1253 /* Initialize the global unique id map for functions. */
1255 static void
1256 init_gid_map (void)
1258 struct cgraph_node *n;
1260 gcc_assert (!gid_map);
1262 gid_map
1263 = htab_create (10, htab_gid_hash, htab_gid_eq, htab_gid_del);
1265 for (n = cgraph_nodes; n; n = n->next)
1267 func_gid_entry_t ent, *entp;
1268 func_gid_entry_t **slot;
1269 struct function *f;
1270 ent.node = n;
1271 f = DECL_STRUCT_FUNCTION (n->decl);
1272 /* Do not care to indirect call promote a function with id. */
1273 if (!f || DECL_ABSTRACT (n->decl))
1274 continue;
1275 /* The global function id computed at profile-use time
1276 is slightly different from the one computed in
1277 instrumentation runtime -- for the latter, the intra-
1278 module function ident is 1 based while in profile-use
1279 phase, it is zero based. See get_next_funcdef_no in
1280 function.c. */
1281 ent.gid = FUNC_DECL_GLOBAL_ID (DECL_STRUCT_FUNCTION (n->decl));
1282 slot = (func_gid_entry_t **) htab_find_slot (gid_map, &ent, INSERT);
1284 gcc_assert (!*slot || ((*slot)->gid == ent.gid && (*slot)->node == n));
1285 if (!*slot)
1287 *slot = entp = XCNEW (func_gid_entry_t);
1288 entp->node = n;
1289 entp->gid = ent.gid;
1294 /* Initialize the global unique id map for functions. */
1296 void
1297 cgraph_init_gid_map (void)
1299 if (!(L_IPO_COMP_MODE || flag_ripa_stream))
1300 return;
1302 init_gid_map ();
1305 /* Return cgraph node for function with global id. */
1307 struct cgraph_node *
1308 find_func_by_global_id (unsigned HOST_WIDE_INT gid)
1310 func_gid_entry_t ent, *entp;
1312 gcc_assert (gid_map);
1314 ent.node = NULL;
1315 ent.gid = gid;
1316 entp = (func_gid_entry_t *)htab_find (gid_map, &ent);
1317 if (entp)
1318 return entp->node;
1319 return NULL;
1322 /* Perform sanity check on the indirect call target. Due to race conditions,
1323 false function target may be attributed to an indirect call site. If the
1324 call expression type mismatches with the target function's type, expand_call
1325 may ICE. Here we only do very minimal sanity check just to make compiler happy.
1326 Returns true if TARGET is considered ok for call CALL_STMT. */
1328 static bool
1329 check_ic_target (gimple call_stmt, struct cgraph_node *target)
1331 location_t locus;
1332 if (gimple_check_call_matching_types (call_stmt, target->decl))
1333 return true;
1335 locus = gimple_location (call_stmt);
1336 if (flag_opt_info >= OPT_INFO_MAX)
1337 inform (locus, "Skipping target %s with mismatching types for icall ",
1338 cgraph_node_name (target));
1339 return false;
1342 /* Do transformation
1344 if (actual_callee_address == address_of_most_common_function/method)
1345 do direct call
1346 else
1347 old call
1350 static gimple
1351 gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
1352 int prob, gcov_type count, gcov_type all)
1354 gimple dcall_stmt, load_stmt, cond_stmt;
1355 tree tmp0, tmp1, tmpv, tmp;
1356 basic_block cond_bb, dcall_bb, icall_bb, join_bb = NULL;
1357 tree optype = build_pointer_type (void_type_node);
1358 edge e_cd, e_ci, e_di, e_dj = NULL, e_ij;
1359 gimple_stmt_iterator gsi;
1360 int lp_nr;
1362 cond_bb = gimple_bb (icall_stmt);
1363 gsi = gsi_for_stmt (icall_stmt);
1365 tmpv = create_tmp_reg (optype, "PROF");
1366 tmp0 = make_ssa_name (tmpv, NULL);
1367 tmp1 = make_ssa_name (tmpv, NULL);
1368 tmp = unshare_expr (gimple_call_fn (icall_stmt));
1369 load_stmt = gimple_build_assign (tmp0, tmp);
1370 SSA_NAME_DEF_STMT (tmp0) = load_stmt;
1371 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
1373 tmp = fold_convert (optype, build_addr (direct_call->decl,
1374 current_function_decl));
1375 load_stmt = gimple_build_assign (tmp1, tmp);
1376 SSA_NAME_DEF_STMT (tmp1) = load_stmt;
1377 gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
1379 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
1380 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
1382 gimple_set_vdef (icall_stmt, NULL_TREE);
1383 gimple_set_vuse (icall_stmt, NULL_TREE);
1384 update_stmt (icall_stmt);
1385 dcall_stmt = gimple_copy (icall_stmt);
1386 gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
1387 gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
1389 /* Fix CFG. */
1390 /* Edge e_cd connects cond_bb to dcall_bb, etc; note the first letters. */
1391 e_cd = split_block (cond_bb, cond_stmt);
1392 dcall_bb = e_cd->dest;
1393 dcall_bb->count = count;
1395 e_di = split_block (dcall_bb, dcall_stmt);
1396 icall_bb = e_di->dest;
1397 icall_bb->count = all - count;
1399 /* Do not disturb existing EH edges from the indirect call. */
1400 if (!stmt_ends_bb_p (icall_stmt))
1401 e_ij = split_block (icall_bb, icall_stmt);
1402 else
1404 e_ij = find_fallthru_edge (icall_bb->succs);
1405 /* The indirect call might be noreturn. */
1406 if (e_ij != NULL)
1408 e_ij->probability = REG_BR_PROB_BASE;
1409 e_ij->count = all - count;
1410 e_ij = single_pred_edge (split_edge (e_ij));
1413 if (e_ij != NULL)
1415 join_bb = e_ij->dest;
1416 join_bb->count = all;
1419 e_cd->flags = (e_cd->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
1420 e_cd->probability = prob;
1421 e_cd->count = count;
1423 e_ci = make_edge (cond_bb, icall_bb, EDGE_FALSE_VALUE);
1424 e_ci->probability = REG_BR_PROB_BASE - prob;
1425 e_ci->count = all - count;
1427 remove_edge (e_di);
1429 if (e_ij != NULL)
1431 e_dj = make_edge (dcall_bb, join_bb, EDGE_FALLTHRU);
1432 e_dj->probability = REG_BR_PROB_BASE;
1433 e_dj->count = count;
1435 e_ij->probability = REG_BR_PROB_BASE;
1436 e_ij->count = all - count;
1439 /* Insert PHI node for the call result if necessary. */
1440 if (gimple_call_lhs (icall_stmt)
1441 && TREE_CODE (gimple_call_lhs (icall_stmt)) == SSA_NAME)
1443 tree result = gimple_call_lhs (icall_stmt);
1444 gimple phi = create_phi_node (result, join_bb);
1445 SSA_NAME_DEF_STMT (result) = phi;
1446 gimple_call_set_lhs (icall_stmt,
1447 make_ssa_name (SSA_NAME_VAR (result), icall_stmt));
1448 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
1449 gimple_call_set_lhs (dcall_stmt,
1450 make_ssa_name (SSA_NAME_VAR (result), dcall_stmt));
1451 add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION);
1454 /* Build an EH edge for the direct call if necessary. */
1455 lp_nr = lookup_stmt_eh_lp (icall_stmt);
1456 if (lp_nr != 0
1457 && stmt_could_throw_p (dcall_stmt))
1459 edge e_eh, e;
1460 edge_iterator ei;
1461 gimple_stmt_iterator psi;
1463 add_stmt_to_eh_lp (dcall_stmt, lp_nr);
1464 FOR_EACH_EDGE (e_eh, ei, icall_bb->succs)
1465 if (e_eh->flags & EDGE_EH)
1466 break;
1467 e = make_edge (dcall_bb, e_eh->dest, EDGE_EH);
1468 for (psi = gsi_start_phis (e_eh->dest);
1469 !gsi_end_p (psi); gsi_next (&psi))
1471 gimple phi = gsi_stmt (psi);
1472 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e),
1473 PHI_ARG_DEF_FROM_EDGE (phi, e_eh));
1477 return dcall_stmt;
1481 For every checked indirect/virtual call determine if most common pid of
1482 function/class method has probability more than 50%. If yes modify code of
1483 this call to:
1486 static bool
1487 gimple_ic_transform_single_targ (gimple stmt, histogram_value histogram)
1489 gcov_type val, count, all, bb_all;
1490 gcov_type prob;
1491 gimple modify;
1492 struct cgraph_node *direct_call;
1494 val = histogram->hvalue.counters [0];
1495 count = histogram->hvalue.counters [1];
1496 all = histogram->hvalue.counters [2];
1497 gimple_remove_histogram_value (cfun, stmt, histogram);
1499 if (4 * count <= 3 * all)
1500 return false;
1502 bb_all = gimple_bb (stmt)->count;
1503 /* The order of CHECK_COUNTER calls is important -
1504 since check_counter can correct the third parameter
1505 and we want to make count <= all <= bb_all. */
1506 if ( check_counter (stmt, "ic", &all, &bb_all, bb_all)
1507 || check_counter (stmt, "ic", &count, &all, all))
1508 return false;
1510 if (all > 0)
1511 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1512 else
1513 prob = 0;
1514 direct_call = find_func_by_funcdef_no ((int)val);
1516 if (direct_call == NULL)
1517 return false;
1519 if (!check_ic_target (stmt, direct_call))
1520 return false;
1522 modify = gimple_ic (stmt, direct_call, prob, count, all);
1524 if (dump_file)
1526 fprintf (dump_file, "Indirect call -> direct call ");
1527 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
1528 fprintf (dump_file, "=> ");
1529 print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
1530 fprintf (dump_file, " transformation on insn ");
1531 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1532 fprintf (dump_file, " to ");
1533 print_gimple_stmt (dump_file, modify, 0, TDF_SLIM);
1534 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC
1535 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count, all);
1538 return true;
1541 /* Convert indirect function call STMT into guarded direct function
1542 calls. Multiple indirect call targets are supported. HISTOGRAM
1543 is the target distribution for the callsite. */
1545 static bool
1546 gimple_ic_transform_mult_targ (gimple stmt, histogram_value histogram)
1548 gcov_type val1, val2, count1, count2, all, bb_all;
1549 gcov_type prob1, prob2;
1550 gimple modify1, modify2;
1551 struct cgraph_node *direct_call1 = 0, *direct_call2 = 0;
1552 int perc_threshold, count_threshold, always_inline;
1553 location_t locus;
1555 val1 = histogram->hvalue.counters [1];
1556 count1 = histogram->hvalue.counters [2];
1557 val2 = histogram->hvalue.counters [3];
1558 count2 = histogram->hvalue.counters [4];
1559 bb_all = gimple_bb (stmt)->count;
1560 all = bb_all;
1562 gimple_remove_histogram_value (cfun, stmt, histogram);
1564 if (count1 == 0)
1565 return false;
1567 perc_threshold = PARAM_VALUE (PARAM_ICALL_PROMOTE_PERCENT_THRESHOLD);
1568 count_threshold = PARAM_VALUE (PARAM_ICALL_PROMOTE_COUNT_THRESHOLD);
1569 always_inline = PARAM_VALUE (PARAM_ALWAYS_INLINE_ICALL_TARGET);
1571 if (100 * count1 < all * perc_threshold || count1 < count_threshold)
1572 return false;
1574 if (check_ic_counter (stmt, &count1, &count2, all))
1575 return false;
1577 if (all > 0)
1579 prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all;
1580 if (all - count1 > 0)
1581 prob2 = (count2 * REG_BR_PROB_BASE
1582 + (all - count1) / 2) / (all - count1);
1583 else
1584 prob2 = 0;
1586 else
1587 prob1 = prob2 = 0;
1589 direct_call1 = find_func_by_global_id (val1);
1591 if (val2 && (100 * count2 >= all * perc_threshold)
1592 && count2 > count_threshold)
1593 direct_call2 = find_func_by_global_id (val2);
1595 locus = (stmt != NULL) ? gimple_location (stmt)
1596 : DECL_SOURCE_LOCATION (current_function_decl);
1597 if (direct_call1 == NULL
1598 || !check_ic_target (stmt, direct_call1))
1600 if (flag_opt_info >= OPT_INFO_MAX)
1602 if (!direct_call1)
1603 inform (locus, "Can not find indirect call target decl "
1604 "(%d:%d)[cnt:%u] in current module",
1605 EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1),
1606 EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1), (unsigned) count1);
1607 else
1608 inform (locus,
1609 "Can not find promote indirect call target decl -- type mismatch "
1610 "(%d:%d)[cnt:%u] in current module",
1611 EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1),
1612 EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1), (unsigned) count1);
1614 return false;
1617 /* Don't indirect-call promote if the target is in auxiliary module and
1618 DECL_ARTIFICIAL and not TREE_PUBLIC, because we don't static-promote
1619 DECL_ARTIFICIALs yet. */
1620 if (cgraph_is_auxiliary (direct_call1->decl)
1621 && DECL_ARTIFICIAL (direct_call1->decl)
1622 && ! TREE_PUBLIC (direct_call1->decl))
1623 return false;
1625 modify1 = gimple_ic (stmt, direct_call1, prob1, count1, all);
1626 if (flag_opt_info >= OPT_INFO_MIN)
1627 inform (locus, "Promote indirect call to target (call count:%u) %s",
1628 (unsigned) count1,
1629 lang_hooks.decl_printable_name (direct_call1->decl, 3));
1631 if (always_inline && count1 >= always_inline)
1633 /* TODO: should mark the call edge. */
1634 DECL_DISREGARD_INLINE_LIMITS (direct_call1->decl) = 1;
1635 direct_call1->local.disregard_inline_limits = 1;
1637 if (dump_file)
1639 fprintf (dump_file, "Indirect call -> direct call ");
1640 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
1641 fprintf (dump_file, "=> ");
1642 print_generic_expr (dump_file, direct_call1->decl, TDF_SLIM);
1643 fprintf (dump_file, " (module_id:%d, func_id:%d)\n",
1644 EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val1),
1645 EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val1));
1646 fprintf (dump_file, "Transformation on insn:\n");
1647 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1648 fprintf (dump_file, "==>\n");
1649 print_gimple_stmt (dump_file, modify1, 0, TDF_SLIM);
1650 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC
1651 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count1, all);
1654 if (direct_call2 && check_ic_target (stmt, direct_call2)
1655 /* Don't indirect-call promote if the target is in auxiliary module and
1656 DECL_ARTIFICIAL and not TREE_PUBLIC, because we don't static-promote
1657 DECL_ARTIFICIALs yet. */
1658 && ! (cgraph_is_auxiliary (direct_call2->decl)
1659 && DECL_ARTIFICIAL (direct_call2->decl)
1660 && ! TREE_PUBLIC (direct_call2->decl)))
1662 modify2 = gimple_ic (stmt, direct_call2,
1663 prob2, count2, all - count1);
1665 if (flag_opt_info >= OPT_INFO_MIN)
1666 inform (locus, "Promote indirect call to target (call count:%u) %s",
1667 (unsigned) count2,
1668 lang_hooks.decl_printable_name (direct_call2->decl, 3));
1670 if (always_inline && count2 >= always_inline)
1672 /* TODO: should mark the call edge. */
1673 DECL_DISREGARD_INLINE_LIMITS (direct_call2->decl) = 1;
1674 direct_call2->local.disregard_inline_limits = 1;
1676 if (dump_file)
1678 fprintf (dump_file, "Indirect call -> direct call ");
1679 print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
1680 fprintf (dump_file, "=> ");
1681 print_generic_expr (dump_file, direct_call2->decl, TDF_SLIM);
1682 fprintf (dump_file, " (module_id:%d, func_id:%d)\n",
1683 EXTRACT_MODULE_ID_FROM_GLOBAL_ID (val2),
1684 EXTRACT_FUNC_ID_FROM_GLOBAL_ID (val2));
1685 fprintf (dump_file, "Transformation on insn\n");
1686 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1687 fprintf (dump_file, "=>\n");
1688 print_gimple_stmt (dump_file, modify2, 0, TDF_SLIM);
1689 fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC
1690 " hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count2,
1691 all - count1);
1695 return true;
1698 /* Perform indirect call (STMT) to guarded direct function call
1699 transformation using value profile data. */
1701 static bool
1702 gimple_ic_transform (gimple stmt)
1704 histogram_value histogram;
1705 tree callee;
1707 if (gimple_code (stmt) != GIMPLE_CALL)
1708 return false;
1710 callee = gimple_call_fn (stmt);
1712 if (TREE_CODE (callee) == FUNCTION_DECL)
1713 return false;
1715 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);
1716 if (!histogram)
1718 histogram = gimple_histogram_value_of_type (cfun, stmt,
1719 HIST_TYPE_INDIR_CALL_TOPN);
1720 if (!histogram)
1721 return false;
1724 if (histogram->type == HIST_TYPE_INDIR_CALL)
1725 return gimple_ic_transform_single_targ (stmt, histogram);
1726 else
1727 return gimple_ic_transform_mult_targ (stmt, histogram);
1730 /* Return true if the stringop CALL with FNDECL shall be profiled.
1731 SIZE_ARG be set to the argument index for the size of the string
1732 operation.
1734 static bool
1735 interesting_stringop_to_profile_p (tree fndecl, gimple call, int *size_arg)
1737 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
1739 /* Disable stringop collection with reuse distance instrumentation
1740 or optimization. Otherwise we end up with hard to correct profile
1741 mismatches for functions where reuse distance-based transformation are
1742 made. We see a number of "memcpy" at instrumentation time and a different
1743 number of "memcpy" at profile use time. */
1744 if (flag_profile_reusedist || flag_optimize_locality)
1745 return false;
1747 if (fcode != BUILT_IN_MEMCPY && fcode != BUILT_IN_MEMPCPY
1748 && fcode != BUILT_IN_MEMSET && fcode != BUILT_IN_BZERO)
1749 return false;
1751 switch (fcode)
1753 case BUILT_IN_MEMCPY:
1754 case BUILT_IN_MEMPCPY:
1755 *size_arg = 2;
1756 return validate_gimple_arglist (call, POINTER_TYPE, POINTER_TYPE,
1757 INTEGER_TYPE, VOID_TYPE);
1758 case BUILT_IN_MEMSET:
1759 *size_arg = 2;
1760 return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1761 INTEGER_TYPE, VOID_TYPE);
1762 case BUILT_IN_BZERO:
1763 *size_arg = 1;
1764 return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1765 VOID_TYPE);
1766 default:
1767 gcc_unreachable ();
1771 /* Convert stringop (..., vcall_size)
1772 into
1773 if (vcall_size == icall_size)
1774 stringop (..., icall_size);
1775 else
1776 stringop (..., vcall_size);
1777 assuming we'll propagate a true constant into ICALL_SIZE later. */
1779 static void
1780 gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
1781 gcov_type count, gcov_type all)
1783 gimple tmp_stmt, cond_stmt, icall_stmt;
1784 tree tmp0, tmp1, tmpv, vcall_size, optype;
1785 basic_block cond_bb, icall_bb, vcall_bb, join_bb;
1786 edge e_ci, e_cv, e_iv, e_ij, e_vj;
1787 gimple_stmt_iterator gsi;
1788 tree fndecl;
1789 int size_arg;
1791 fndecl = gimple_call_fndecl (vcall_stmt);
1792 if (!interesting_stringop_to_profile_p (fndecl, vcall_stmt, &size_arg))
1793 gcc_unreachable();
1795 cond_bb = gimple_bb (vcall_stmt);
1796 gsi = gsi_for_stmt (vcall_stmt);
1798 vcall_size = gimple_call_arg (vcall_stmt, size_arg);
1799 optype = TREE_TYPE (vcall_size);
1801 tmpv = create_tmp_var (optype, "PROF");
1802 tmp0 = make_ssa_name (tmpv, NULL);
1803 tmp1 = make_ssa_name (tmpv, NULL);
1804 tmp_stmt = gimple_build_assign (tmp0, fold_convert (optype, icall_size));
1805 SSA_NAME_DEF_STMT (tmp0) = tmp_stmt;
1806 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
1808 tmp_stmt = gimple_build_assign (tmp1, vcall_size);
1809 SSA_NAME_DEF_STMT (tmp1) = tmp_stmt;
1810 gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
1812 cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE);
1813 gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
1815 gimple_set_vdef (vcall_stmt, NULL);
1816 gimple_set_vuse (vcall_stmt, NULL);
1817 update_stmt (vcall_stmt);
1818 icall_stmt = gimple_copy (vcall_stmt);
1819 gimple_call_set_arg (icall_stmt, size_arg, icall_size);
1820 gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);
1822 /* Fix CFG. */
1823 /* Edge e_ci connects cond_bb to icall_bb, etc. */
1824 e_ci = split_block (cond_bb, cond_stmt);
1825 icall_bb = e_ci->dest;
1826 icall_bb->count = count;
1828 e_iv = split_block (icall_bb, icall_stmt);
1829 vcall_bb = e_iv->dest;
1830 vcall_bb->count = all - count;
1832 e_vj = split_block (vcall_bb, vcall_stmt);
1833 join_bb = e_vj->dest;
1834 join_bb->count = all;
1836 e_ci->flags = (e_ci->flags & ~EDGE_FALLTHRU) | EDGE_TRUE_VALUE;
1837 e_ci->probability = prob;
1838 e_ci->count = count;
1840 e_cv = make_edge (cond_bb, vcall_bb, EDGE_FALSE_VALUE);
1841 e_cv->probability = REG_BR_PROB_BASE - prob;
1842 e_cv->count = all - count;
1844 remove_edge (e_iv);
1846 e_ij = make_edge (icall_bb, join_bb, EDGE_FALLTHRU);
1847 e_ij->probability = REG_BR_PROB_BASE;
1848 e_ij->count = count;
1850 e_vj->probability = REG_BR_PROB_BASE;
1851 e_vj->count = all - count;
1853 /* Insert PHI node for the call result if necessary. */
1854 if (gimple_call_lhs (vcall_stmt)
1855 && TREE_CODE (gimple_call_lhs (vcall_stmt)) == SSA_NAME)
1857 tree result = gimple_call_lhs (vcall_stmt);
1858 gimple phi = create_phi_node (result, join_bb);
1859 SSA_NAME_DEF_STMT (result) = phi;
1860 gimple_call_set_lhs (vcall_stmt,
1861 make_ssa_name (SSA_NAME_VAR (result), vcall_stmt));
1862 add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION);
1863 gimple_call_set_lhs (icall_stmt,
1864 make_ssa_name (SSA_NAME_VAR (result), icall_stmt));
1865 add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
1868 /* Because these are all string op builtins, they're all nothrow. */
1869 gcc_assert (!stmt_could_throw_p (vcall_stmt));
1870 gcc_assert (!stmt_could_throw_p (icall_stmt));
1873 /* Find values inside STMT for that we want to measure histograms for
1874 division/modulo optimization. */
1875 static bool
1876 gimple_stringops_transform (gimple_stmt_iterator *gsi)
1878 gimple stmt = gsi_stmt (*gsi);
1879 tree fndecl;
1880 tree blck_size;
1881 enum built_in_function fcode;
1882 histogram_value histogram;
1883 gcov_type count, all, val;
1884 tree dest, src;
1885 unsigned int dest_align, src_align;
1886 gcov_type prob;
1887 tree tree_val;
1888 int size_arg;
1890 if (gimple_code (stmt) != GIMPLE_CALL)
1891 return false;
1892 fndecl = gimple_call_fndecl (stmt);
1893 if (!fndecl)
1894 return false;
1895 fcode = DECL_FUNCTION_CODE (fndecl);
1896 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
1897 return false;
1899 blck_size = gimple_call_arg (stmt, size_arg);
1900 if (TREE_CODE (blck_size) == INTEGER_CST)
1901 return false;
1903 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
1904 if (!histogram)
1905 return false;
1906 val = histogram->hvalue.counters[0];
1907 count = histogram->hvalue.counters[1];
1908 all = histogram->hvalue.counters[2];
1909 gimple_remove_histogram_value (cfun, stmt, histogram);
1910 /* We require that count is at least half of all; this means
1911 that for the transformation to fire the value must be constant
1912 at least 80% of time. */
1913 if ((6 * count / 5) < all || optimize_bb_for_size_p (gimple_bb (stmt)))
1914 return false;
1915 if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count))
1916 return false;
1917 if (all > 0)
1918 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1919 else
1920 prob = 0;
1921 dest = gimple_call_arg (stmt, 0);
1922 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1923 switch (fcode)
1925 case BUILT_IN_MEMCPY:
1926 case BUILT_IN_MEMPCPY:
1927 src = gimple_call_arg (stmt, 1);
1928 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1929 if (!can_move_by_pieces (val, MIN (dest_align, src_align)))
1930 return false;
1931 break;
1932 case BUILT_IN_MEMSET:
1933 if (!can_store_by_pieces (val, builtin_memset_read_str,
1934 gimple_call_arg (stmt, 1),
1935 dest_align, true))
1936 return false;
1937 break;
1938 case BUILT_IN_BZERO:
1939 if (!can_store_by_pieces (val, builtin_memset_read_str,
1940 integer_zero_node,
1941 dest_align, true))
1942 return false;
1943 break;
1944 default:
1945 gcc_unreachable ();
1947 tree_val = build_int_cst_wide (get_gcov_type (),
1948 (unsigned HOST_WIDE_INT) val,
1949 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
1950 if (dump_file)
1952 fprintf (dump_file, "Single value %i stringop transformation on ",
1953 (int)val);
1954 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1956 gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
1958 return true;
1961 void
1962 stringop_block_profile (gimple stmt, unsigned int *expected_align,
1963 HOST_WIDE_INT *expected_size)
1965 histogram_value histogram;
1966 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE);
1967 if (!histogram)
1968 *expected_size = -1;
1969 else if (!histogram->hvalue.counters[1])
1971 *expected_size = -1;
1972 gimple_remove_histogram_value (cfun, stmt, histogram);
1974 else
1976 gcov_type size;
1977 size = ((histogram->hvalue.counters[0]
1978 + histogram->hvalue.counters[1] / 2)
1979 / histogram->hvalue.counters[1]);
1980 /* Even if we can hold bigger value in SIZE, INT_MAX
1981 is safe "infinity" for code generation strategies. */
1982 if (size > INT_MAX)
1983 size = INT_MAX;
1984 *expected_size = size;
1985 gimple_remove_histogram_value (cfun, stmt, histogram);
1987 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR);
1988 if (!histogram)
1989 *expected_align = 0;
1990 else if (!histogram->hvalue.counters[0])
1992 gimple_remove_histogram_value (cfun, stmt, histogram);
1993 *expected_align = 0;
1995 else
1997 gcov_type count;
1998 int alignment;
2000 count = histogram->hvalue.counters[0];
2001 alignment = 1;
2002 while (!(count & alignment)
2003 && (alignment * 2 * BITS_PER_UNIT))
2004 alignment <<= 1;
2005 *expected_align = alignment * BITS_PER_UNIT;
2006 gimple_remove_histogram_value (cfun, stmt, histogram);
2011 /* Find values inside STMT for that we want to measure histograms for
2012 division/modulo optimization. */
2013 static void
2014 gimple_divmod_values_to_profile (gimple stmt, histogram_values *values)
2016 tree lhs, divisor, op0, type;
2017 histogram_value hist;
2019 if (gimple_code (stmt) != GIMPLE_ASSIGN)
2020 return;
2022 lhs = gimple_assign_lhs (stmt);
2023 type = TREE_TYPE (lhs);
2024 if (!INTEGRAL_TYPE_P (type))
2025 return;
2027 switch (gimple_assign_rhs_code (stmt))
2029 case TRUNC_DIV_EXPR:
2030 case TRUNC_MOD_EXPR:
2031 divisor = gimple_assign_rhs2 (stmt);
2032 op0 = gimple_assign_rhs1 (stmt);
2034 VEC_reserve (histogram_value, heap, *values, 3);
2036 if (is_gimple_reg (divisor))
2037 /* Check for the case where the divisor is the same value most
2038 of the time. */
2039 VEC_quick_push (histogram_value, *values,
2040 gimple_alloc_histogram_value (cfun,
2041 HIST_TYPE_SINGLE_VALUE,
2042 stmt, divisor));
2044 /* For mod, check whether it is not often a noop (or replaceable by
2045 a few subtractions). */
2046 if (gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR
2047 && TYPE_UNSIGNED (type))
2049 tree val;
2050 /* Check for a special case where the divisor is power of 2. */
2051 VEC_quick_push (histogram_value, *values,
2052 gimple_alloc_histogram_value (cfun, HIST_TYPE_POW2,
2053 stmt, divisor));
2055 val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
2056 hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
2057 stmt, val);
2058 hist->hdata.intvl.int_start = 0;
2059 hist->hdata.intvl.steps = 2;
2060 VEC_quick_push (histogram_value, *values, hist);
2062 return;
2064 default:
2065 return;
2069 /* Find calls inside STMT for that we want to measure histograms for
2070 indirect/virtual call optimization. */
2072 static void
2073 gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
2075 tree callee;
2077 if (gimple_code (stmt) != GIMPLE_CALL
2078 || gimple_call_fndecl (stmt) != NULL_TREE)
2079 return;
2081 callee = gimple_call_fn (stmt);
2083 VEC_reserve (histogram_value, heap, *values, 3);
2085 if (flag_dyn_ipa || flag_ripa_stream)
2086 VEC_quick_push (histogram_value, *values,
2087 gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL_TOPN,
2088 stmt, callee));
2089 else
2090 VEC_quick_push (histogram_value, *values,
2091 gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
2092 stmt, callee));
2094 return;
2097 /* Find values inside STMT for that we want to measure histograms for
2098 string operations. */
2099 static void
2100 gimple_stringops_values_to_profile (gimple stmt, histogram_values *values)
2102 tree fndecl;
2103 tree blck_size;
2104 tree dest;
2105 int size_arg;
2107 if (gimple_code (stmt) != GIMPLE_CALL)
2108 return;
2109 fndecl = gimple_call_fndecl (stmt);
2110 if (!fndecl)
2111 return;
2113 if (!interesting_stringop_to_profile_p (fndecl, stmt, &size_arg))
2114 return;
2116 dest = gimple_call_arg (stmt, 0);
2117 blck_size = gimple_call_arg (stmt, size_arg);
2119 if (TREE_CODE (blck_size) != INTEGER_CST)
2121 VEC_safe_push (histogram_value, heap, *values,
2122 gimple_alloc_histogram_value (cfun, HIST_TYPE_SINGLE_VALUE,
2123 stmt, blck_size));
2124 VEC_safe_push (histogram_value, heap, *values,
2125 gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE,
2126 stmt, blck_size));
2128 if (TREE_CODE (blck_size) != INTEGER_CST)
2129 VEC_safe_push (histogram_value, heap, *values,
2130 gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR,
2131 stmt, dest));
2134 /* Find values inside STMT for that we want to measure histograms and adds
2135 them to list VALUES. */
2137 static void
2138 gimple_values_to_profile (gimple stmt, histogram_values *values)
2140 if (flag_value_profile_transformations)
2142 gimple_divmod_values_to_profile (stmt, values);
2143 gimple_stringops_values_to_profile (stmt, values);
2144 gimple_indirect_call_to_profile (stmt, values);
2148 void
2149 gimple_find_values_to_profile (histogram_values *values)
2151 basic_block bb;
2152 gimple_stmt_iterator gsi;
2153 unsigned i;
2154 histogram_value hist = NULL;
2156 *values = NULL;
2157 FOR_EACH_BB (bb)
2158 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2159 gimple_values_to_profile (gsi_stmt (gsi), values);
2161 FOR_EACH_VEC_ELT (histogram_value, *values, i, hist)
2163 switch (hist->type)
2165 case HIST_TYPE_INTERVAL:
2166 hist->n_counters = hist->hdata.intvl.steps + 2;
2167 break;
2169 case HIST_TYPE_POW2:
2170 hist->n_counters = 2;
2171 break;
2173 case HIST_TYPE_SINGLE_VALUE:
2174 hist->n_counters = 3;
2175 break;
2177 case HIST_TYPE_CONST_DELTA:
2178 hist->n_counters = 4;
2179 break;
2181 case HIST_TYPE_INDIR_CALL:
2182 hist->n_counters = 3;
2183 break;
2185 case HIST_TYPE_AVERAGE:
2186 hist->n_counters = 2;
2187 break;
2189 case HIST_TYPE_IOR:
2190 hist->n_counters = 1;
2191 break;
2193 case HIST_TYPE_INDIR_CALL_TOPN:
2194 hist->n_counters = (GCOV_ICALL_TOPN_VAL << 2) + 1;
2195 break;
2197 default:
2198 gcc_unreachable ();
2200 if (dump_file)
2202 fprintf (dump_file, "Stmt ");
2203 print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM);
2204 dump_histogram_value (dump_file, hist);