* tree-ssa-loop-prefetch.c (determine_unroll_factor): Bound the unroll
[official-gcc.git] / gcc / value-prof.c
blob24a21717278572637c3a920ead285c05392c7ba5
1 /* Transformations based on profile information for values.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA. */
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 "coverage.h"
41 #include "tree.h"
42 #include "gcov-io.h"
43 #include "cgraph.h"
44 #include "timevar.h"
45 #include "tree-pass.h"
46 #include "toplev.h"
47 #include "pointer-set.h"
49 static struct value_prof_hooks *value_prof_hooks;
51 /* In this file value profile based optimizations are placed. Currently the
52 following optimizations are implemented (for more detailed descriptions
53 see comments at value_profile_transformations):
55 1) Division/modulo specialization. Provided that we can determine that the
56 operands of the division have some special properties, we may use it to
57 produce more effective code.
58 2) Speculative prefetching. If we are able to determine that the difference
59 between addresses accessed by a memory reference is usually constant, we
60 may add the prefetch instructions.
61 FIXME: This transformation was removed together with RTL based value
62 profiling.
64 3) Indirect/virtual call specialization. If we can determine most
65 common function callee in indirect/virtual call. We can use this
66 information to improve code effectiveness (especially info for
67 inliner).
69 Every such optimization should add its requirements for profiled values to
70 insn_values_to_profile function. This function is called from branch_prob
71 in profile.c and the requested values are instrumented by it in the first
72 compilation with -fprofile-arcs. The optimization may then read the
73 gathered data in the second compilation with -fbranch-probabilities.
75 The measured data is pointed to from the histograms
76 field of the statement annotation of the instrumented insns. It is
77 kept as a linked list of struct histogram_value_t's, which contain the
78 same information as above. */
81 static tree tree_divmod_fixed_value (tree, tree, tree, tree,
82 tree, int, gcov_type, gcov_type);
83 static tree tree_mod_pow2 (tree, tree, tree, tree, int, gcov_type, gcov_type);
84 static tree tree_mod_subtract (tree, tree, tree, tree, int, int, int,
85 gcov_type, gcov_type, gcov_type);
86 static bool tree_divmod_fixed_value_transform (tree);
87 static bool tree_mod_pow2_value_transform (tree);
88 static bool tree_mod_subtract_transform (tree);
89 static bool tree_stringops_transform (block_stmt_iterator *);
90 static bool tree_ic_transform (tree);
92 /* Allocate histogram value. */
94 static histogram_value
95 gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED,
96 enum hist_type type, tree stmt, tree value)
98 histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist));
99 hist->hvalue.value = value;
100 hist->hvalue.stmt = stmt;
101 hist->type = type;
102 return hist;
105 /* Hash value for histogram. */
107 static hashval_t
108 histogram_hash (const void *x)
110 return htab_hash_pointer (((histogram_value)x)->hvalue.stmt);
113 /* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y. */
115 static int
116 histogram_eq (const void *x, const void *y)
118 return ((histogram_value) x)->hvalue.stmt == (tree)y;
121 /* Set histogram for STMT. */
123 static void
124 set_histogram_value (struct function *fun, tree stmt, histogram_value hist)
126 void **loc;
127 if (!hist && !VALUE_HISTOGRAMS (fun))
128 return;
129 if (!VALUE_HISTOGRAMS (fun))
130 VALUE_HISTOGRAMS (fun) = htab_create (1, histogram_hash,
131 histogram_eq, NULL);
132 loc = htab_find_slot_with_hash (VALUE_HISTOGRAMS (fun), stmt,
133 htab_hash_pointer (stmt),
134 hist ? INSERT : NO_INSERT);
135 if (!hist)
137 if (loc)
138 htab_clear_slot (VALUE_HISTOGRAMS (fun), loc);
139 return;
141 *loc = hist;
144 /* Get histogram list for STMT. */
146 histogram_value
147 gimple_histogram_value (struct function *fun, tree stmt)
149 if (!VALUE_HISTOGRAMS (fun))
150 return NULL;
151 return htab_find_with_hash (VALUE_HISTOGRAMS (fun), stmt,
152 htab_hash_pointer (stmt));
155 /* Add histogram for STMT. */
157 void
158 gimple_add_histogram_value (struct function *fun, tree stmt, histogram_value hist)
160 hist->hvalue.next = gimple_histogram_value (fun, stmt);
161 set_histogram_value (fun, stmt, hist);
164 /* Remove histogram HIST from STMT's histogram list. */
166 void
167 gimple_remove_histogram_value (struct function *fun, tree stmt, histogram_value hist)
169 histogram_value hist2 = gimple_histogram_value (fun, stmt);
170 if (hist == hist2)
172 set_histogram_value (fun, stmt, hist->hvalue.next);
174 else
176 while (hist2->hvalue.next != hist)
177 hist2 = hist2->hvalue.next;
178 hist2->hvalue.next = hist->hvalue.next;
180 free (hist->hvalue.counters);
181 #ifdef ENABLE_CHECKING
182 memset (hist, 0xab, sizeof (*hist));
183 #endif
184 free (hist);
187 /* Lookup histogram of type TYPE in the STMT. */
189 histogram_value
190 gimple_histogram_value_of_type (struct function *fun, tree stmt, enum hist_type type)
192 histogram_value hist;
193 for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
194 if (hist->type == type)
195 return hist;
196 return NULL;
199 /* Dump information about HIST to DUMP_FILE. */
201 static void
202 dump_histogram_value (FILE *dump_file, histogram_value hist)
204 switch (hist->type)
206 case HIST_TYPE_INTERVAL:
207 fprintf (dump_file, "Interval counter range %d -- %d",
208 hist->hdata.intvl.int_start,
209 (hist->hdata.intvl.int_start
210 + hist->hdata.intvl.steps - 1));
211 if (hist->hvalue.counters)
213 unsigned int i;
214 fprintf(dump_file, " [");
215 for (i = 0; i < hist->hdata.intvl.steps; i++)
216 fprintf (dump_file, " %d:"HOST_WIDEST_INT_PRINT_DEC,
217 hist->hdata.intvl.int_start + i,
218 (HOST_WIDEST_INT) hist->hvalue.counters[i]);
219 fprintf (dump_file, " ] outside range:"HOST_WIDEST_INT_PRINT_DEC,
220 (HOST_WIDEST_INT) hist->hvalue.counters[i]);
222 fprintf (dump_file, ".\n");
223 break;
225 case HIST_TYPE_POW2:
226 fprintf (dump_file, "Pow2 counter ");
227 if (hist->hvalue.counters)
229 fprintf (dump_file, "pow2:"HOST_WIDEST_INT_PRINT_DEC
230 " nonpow2:"HOST_WIDEST_INT_PRINT_DEC,
231 (HOST_WIDEST_INT) hist->hvalue.counters[0],
232 (HOST_WIDEST_INT) hist->hvalue.counters[1]);
234 fprintf (dump_file, ".\n");
235 break;
237 case HIST_TYPE_SINGLE_VALUE:
238 fprintf (dump_file, "Single value ");
239 if (hist->hvalue.counters)
241 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
242 " match:"HOST_WIDEST_INT_PRINT_DEC
243 " wrong:"HOST_WIDEST_INT_PRINT_DEC,
244 (HOST_WIDEST_INT) hist->hvalue.counters[0],
245 (HOST_WIDEST_INT) hist->hvalue.counters[1],
246 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
248 fprintf (dump_file, ".\n");
249 break;
251 case HIST_TYPE_AVERAGE:
252 fprintf (dump_file, "Average value ");
253 if (hist->hvalue.counters)
255 fprintf (dump_file, "sum:"HOST_WIDEST_INT_PRINT_DEC
256 " times:"HOST_WIDEST_INT_PRINT_DEC,
257 (HOST_WIDEST_INT) hist->hvalue.counters[0],
258 (HOST_WIDEST_INT) hist->hvalue.counters[1]);
260 fprintf (dump_file, ".\n");
261 break;
263 case HIST_TYPE_IOR:
264 fprintf (dump_file, "IOR value ");
265 if (hist->hvalue.counters)
267 fprintf (dump_file, "ior:"HOST_WIDEST_INT_PRINT_DEC,
268 (HOST_WIDEST_INT) hist->hvalue.counters[0]);
270 fprintf (dump_file, ".\n");
271 break;
273 case HIST_TYPE_CONST_DELTA:
274 fprintf (dump_file, "Constant delta ");
275 if (hist->hvalue.counters)
277 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
278 " match:"HOST_WIDEST_INT_PRINT_DEC
279 " wrong:"HOST_WIDEST_INT_PRINT_DEC,
280 (HOST_WIDEST_INT) hist->hvalue.counters[0],
281 (HOST_WIDEST_INT) hist->hvalue.counters[1],
282 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
284 fprintf (dump_file, ".\n");
285 break;
286 case HIST_TYPE_INDIR_CALL:
287 fprintf (dump_file, "Indirect call ");
288 if (hist->hvalue.counters)
290 fprintf (dump_file, "value:"HOST_WIDEST_INT_PRINT_DEC
291 " match:"HOST_WIDEST_INT_PRINT_DEC
292 " all:"HOST_WIDEST_INT_PRINT_DEC,
293 (HOST_WIDEST_INT) hist->hvalue.counters[0],
294 (HOST_WIDEST_INT) hist->hvalue.counters[1],
295 (HOST_WIDEST_INT) hist->hvalue.counters[2]);
297 fprintf (dump_file, ".\n");
298 break;
302 /* Dump all histograms attached to STMT to DUMP_FILE. */
304 void
305 dump_histograms_for_stmt (struct function *fun, FILE *dump_file, tree stmt)
307 histogram_value hist;
308 for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
309 dump_histogram_value (dump_file, hist);
312 /* Remove all histograms associated with STMT. */
314 void
315 gimple_remove_stmt_histograms (struct function *fun, tree stmt)
317 histogram_value val;
318 while ((val = gimple_histogram_value (fun, stmt)) != NULL)
319 gimple_remove_histogram_value (fun, stmt, val);
322 /* Duplicate all histograms associates with OSTMT to STMT. */
324 void
325 gimple_duplicate_stmt_histograms (struct function *fun, tree stmt,
326 struct function *ofun, tree ostmt)
328 histogram_value val;
329 for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next)
331 histogram_value new = gimple_alloc_histogram_value (fun, val->type, NULL, NULL);
332 memcpy (new, val, sizeof (*val));
333 new->hvalue.stmt = stmt;
334 new->hvalue.counters = xmalloc (sizeof (*new->hvalue.counters) * new->n_counters);
335 memcpy (new->hvalue.counters, val->hvalue.counters, sizeof (*new->hvalue.counters) * new->n_counters);
336 gimple_add_histogram_value (fun, stmt, new);
340 static bool error_found = false;
342 /* Helper function for verify_histograms. For each histogram reachable via htab
343 walk verify that it was reached via statement walk. */
345 static int
346 visit_hist (void **slot, void *data)
348 struct pointer_set_t *visited = (struct pointer_set_t *) data;
349 histogram_value hist = *(histogram_value *) slot;
350 if (!pointer_set_contains (visited, hist))
352 error ("Dead histogram");
353 dump_histogram_value (stderr, hist);
354 debug_generic_stmt (hist->hvalue.stmt);
355 error_found = true;
357 return 1;
360 /* Verify sanity of the histograms. */
362 void
363 verify_histograms (void)
365 basic_block bb;
366 block_stmt_iterator bsi;
367 histogram_value hist;
368 struct pointer_set_t *visited_hists;
370 error_found = false;
371 visited_hists = pointer_set_create ();
372 FOR_EACH_BB (bb)
373 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
375 tree stmt = bsi_stmt (bsi);
377 for (hist = gimple_histogram_value (cfun, stmt); hist; hist = hist->hvalue.next)
379 if (hist->hvalue.stmt != stmt)
381 error ("Histogram value statement does not correspond to statement"
382 " it is associated with");
383 debug_generic_stmt (stmt);
384 dump_histogram_value (stderr, hist);
385 error_found = true;
387 pointer_set_insert (visited_hists, hist);
390 if (VALUE_HISTOGRAMS (cfun))
391 htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, visited_hists);
392 pointer_set_destroy (visited_hists);
393 if (error_found)
394 internal_error ("verify_histograms failed");
397 /* Helper function for verify_histograms. For each histogram reachable via htab
398 walk verify that it was reached via statement walk. */
400 static int
401 free_hist (void **slot, void *data ATTRIBUTE_UNUSED)
403 histogram_value hist = *(histogram_value *) slot;
404 free (hist->hvalue.counters);
405 #ifdef ENABLE_CHECKING
406 memset (hist, 0xab, sizeof (*hist));
407 #endif
408 free (hist);
409 return 1;
412 void
413 free_histograms (void)
415 if (VALUE_HISTOGRAMS (cfun))
417 htab_traverse (VALUE_HISTOGRAMS (cfun), free_hist, NULL);
418 htab_delete (VALUE_HISTOGRAMS (cfun));
419 VALUE_HISTOGRAMS (cfun) = NULL;
423 /* The overall number of invocations of the counter should match execution count
424 of basic block. Report it as error rather than internal error as it might
425 mean that user has misused the profile somehow. */
426 static bool
427 check_counter (tree stmt, const char * name, gcov_type all, gcov_type bb_count)
429 if (all != bb_count)
431 location_t * locus;
432 locus = (stmt != NULL && EXPR_HAS_LOCATION (stmt)
433 ? EXPR_LOCUS (stmt)
434 : &DECL_SOURCE_LOCATION (current_function_decl));
435 error ("%HCorrupted value profile: %s profiler overall count (%d) does not match BB count (%d)",
436 locus, name, (int)all, (int)bb_count);
437 return true;
439 return false;
442 /* Tree based transformations. */
443 static bool
444 tree_value_profile_transformations (void)
446 basic_block bb;
447 block_stmt_iterator bsi;
448 bool changed = false;
450 FOR_EACH_BB (bb)
452 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
454 tree stmt = bsi_stmt (bsi);
455 histogram_value th = gimple_histogram_value (cfun, stmt);
456 if (!th)
457 continue;
459 if (dump_file)
461 fprintf (dump_file, "Trying transformations on stmt ");
462 print_generic_stmt (dump_file, stmt, TDF_SLIM);
463 dump_histograms_for_stmt (cfun, dump_file, stmt);
466 /* Transformations: */
467 /* The order of things in this conditional controls which
468 transformation is used when more than one is applicable. */
469 /* It is expected that any code added by the transformations
470 will be added before the current statement, and that the
471 current statement remain valid (although possibly
472 modified) upon return. */
473 if (flag_value_profile_transformations
474 && (tree_mod_subtract_transform (stmt)
475 || tree_divmod_fixed_value_transform (stmt)
476 || tree_mod_pow2_value_transform (stmt)
477 || tree_stringops_transform (&bsi)
478 || tree_ic_transform (stmt)))
480 stmt = bsi_stmt (bsi);
481 changed = true;
482 /* Original statement may no longer be in the same block. */
483 if (bb != bb_for_stmt (stmt))
485 bb = bb_for_stmt (stmt);
486 bsi = bsi_for_stmt (stmt);
492 if (changed)
494 counts_to_freqs ();
497 return changed;
500 /* Generate code for transformation 1 (with OPERATION, operands OP1
501 and OP2, whose value is expected to be VALUE, parent modify-expr STMT and
502 probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
503 within roundoff error). This generates the result into a temp and returns
504 the temp; it does not replace or alter the original STMT. */
505 static tree
506 tree_divmod_fixed_value (tree stmt, tree operation,
507 tree op1, tree op2, tree value, int prob, gcov_type count,
508 gcov_type all)
510 tree stmt1, stmt2, stmt3;
511 tree tmp1, tmp2, tmpv;
512 tree label_decl1 = create_artificial_label ();
513 tree label_decl2 = create_artificial_label ();
514 tree label1, label2;
515 tree bb1end, bb2end, bb3end;
516 basic_block bb, bb2, bb3, bb4;
517 tree optype = TREE_TYPE (operation);
518 edge e12, e13, e23, e24, e34;
519 block_stmt_iterator bsi;
521 bb = bb_for_stmt (stmt);
522 bsi = bsi_for_stmt (stmt);
524 tmpv = create_tmp_var (optype, "PROF");
525 tmp1 = create_tmp_var (optype, "PROF");
526 stmt1 = build_gimple_modify_stmt (tmpv, fold_convert (optype, value));
527 stmt2 = build_gimple_modify_stmt (tmp1, op2);
528 stmt3 = build3 (COND_EXPR, void_type_node,
529 build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
530 build1 (GOTO_EXPR, void_type_node, label_decl2),
531 build1 (GOTO_EXPR, void_type_node, label_decl1));
532 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
533 bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
534 bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
535 bb1end = stmt3;
537 tmp2 = create_tmp_var (optype, "PROF");
538 label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
539 stmt1 = build_gimple_modify_stmt (tmp2,
540 build2 (TREE_CODE (operation), optype,
541 op1, tmpv));
542 bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
543 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
544 bb2end = stmt1;
546 label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
547 stmt1 = build_gimple_modify_stmt (tmp2,
548 build2 (TREE_CODE (operation), optype,
549 op1, op2));
550 bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
551 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
552 bb3end = stmt1;
554 /* Fix CFG. */
555 /* Edge e23 connects bb2 to bb3, etc. */
556 e12 = split_block (bb, bb1end);
557 bb2 = e12->dest;
558 bb2->count = count;
559 e23 = split_block (bb2, bb2end);
560 bb3 = e23->dest;
561 bb3->count = all - count;
562 e34 = split_block (bb3, bb3end);
563 bb4 = e34->dest;
564 bb4->count = all;
566 e12->flags &= ~EDGE_FALLTHRU;
567 e12->flags |= EDGE_FALSE_VALUE;
568 e12->probability = prob;
569 e12->count = count;
571 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
572 e13->probability = REG_BR_PROB_BASE - prob;
573 e13->count = all - count;
575 remove_edge (e23);
577 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
578 e24->probability = REG_BR_PROB_BASE;
579 e24->count = count;
581 e34->probability = REG_BR_PROB_BASE;
582 e34->count = all - count;
584 return tmp2;
587 /* Do transform 1) on INSN if applicable. */
588 static bool
589 tree_divmod_fixed_value_transform (tree stmt)
591 histogram_value histogram;
592 enum tree_code code;
593 gcov_type val, count, all;
594 tree modify, op, op1, op2, result, value, tree_val;
595 int prob;
597 modify = stmt;
598 if (TREE_CODE (stmt) == RETURN_EXPR
599 && TREE_OPERAND (stmt, 0)
600 && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
601 modify = TREE_OPERAND (stmt, 0);
602 if (TREE_CODE (modify) != GIMPLE_MODIFY_STMT)
603 return false;
604 op = GIMPLE_STMT_OPERAND (modify, 1);
605 if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
606 return false;
607 code = TREE_CODE (op);
609 if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
610 return false;
612 op1 = TREE_OPERAND (op, 0);
613 op2 = TREE_OPERAND (op, 1);
615 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
616 if (!histogram)
617 return false;
619 value = histogram->hvalue.value;
620 val = histogram->hvalue.counters[0];
621 count = histogram->hvalue.counters[1];
622 all = histogram->hvalue.counters[2];
623 gimple_remove_histogram_value (cfun, stmt, histogram);
625 /* We require that count is at least half of all; this means
626 that for the transformation to fire the value must be constant
627 at least 50% of time (and 75% gives the guarantee of usage). */
628 if (simple_cst_equal (op2, value) != 1 || 2 * count < all
629 || !maybe_hot_bb_p (bb_for_stmt (stmt)))
630 return false;
632 if (check_counter (stmt, "value", all, bb_for_stmt (stmt)->count))
633 return false;
635 /* Compute probability of taking the optimal path. */
636 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
638 tree_val = build_int_cst_wide (get_gcov_type (),
639 (unsigned HOST_WIDE_INT) val,
640 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
641 result = tree_divmod_fixed_value (stmt, op, op1, op2, tree_val, prob, count, all);
643 if (dump_file)
645 fprintf (dump_file, "Div/mod by constant ");
646 print_generic_expr (dump_file, value, TDF_SLIM);
647 fprintf (dump_file, "=");
648 print_generic_expr (dump_file, tree_val, TDF_SLIM);
649 fprintf (dump_file, " transformation on insn ");
650 print_generic_stmt (dump_file, stmt, TDF_SLIM);
653 GIMPLE_STMT_OPERAND (modify, 1) = result;
655 return true;
658 /* Generate code for transformation 2 (with OPERATION, operands OP1
659 and OP2, parent modify-expr STMT and probability of taking the optimal
660 path PROB, which is equivalent to COUNT/ALL within roundoff error).
661 This generates the result into a temp and returns
662 the temp; it does not replace or alter the original STMT. */
663 static tree
664 tree_mod_pow2 (tree stmt, tree operation, tree op1, tree op2, int prob,
665 gcov_type count, gcov_type all)
667 tree stmt1, stmt2, stmt3, stmt4;
668 tree tmp2, tmp3;
669 tree label_decl1 = create_artificial_label ();
670 tree label_decl2 = create_artificial_label ();
671 tree label1, label2;
672 tree bb1end, bb2end, bb3end;
673 basic_block bb, bb2, bb3, bb4;
674 tree optype = TREE_TYPE (operation);
675 edge e12, e13, e23, e24, e34;
676 block_stmt_iterator bsi;
677 tree result = create_tmp_var (optype, "PROF");
679 bb = bb_for_stmt (stmt);
680 bsi = bsi_for_stmt (stmt);
682 tmp2 = create_tmp_var (optype, "PROF");
683 tmp3 = create_tmp_var (optype, "PROF");
684 stmt2 = build_gimple_modify_stmt (tmp2,
685 build2 (PLUS_EXPR, optype, op2,
686 build_int_cst (optype, -1)));
687 stmt3 = build_gimple_modify_stmt (tmp3,
688 build2 (BIT_AND_EXPR, optype, tmp2, op2));
689 stmt4 = build3 (COND_EXPR, void_type_node,
690 build2 (NE_EXPR, boolean_type_node,
691 tmp3, build_int_cst (optype, 0)),
692 build1 (GOTO_EXPR, void_type_node, label_decl2),
693 build1 (GOTO_EXPR, void_type_node, label_decl1));
694 bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
695 bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
696 bsi_insert_before (&bsi, stmt4, BSI_SAME_STMT);
697 bb1end = stmt4;
699 /* tmp2 == op2-1 inherited from previous block */
700 label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
701 stmt1 = build_gimple_modify_stmt (result,
702 build2 (BIT_AND_EXPR, optype, op1, tmp2));
703 bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
704 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
705 bb2end = stmt1;
707 label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
708 stmt1 = build_gimple_modify_stmt (result,
709 build2 (TREE_CODE (operation), optype,
710 op1, op2));
711 bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
712 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
713 bb3end = stmt1;
715 /* Fix CFG. */
716 /* Edge e23 connects bb2 to bb3, etc. */
717 e12 = split_block (bb, bb1end);
718 bb2 = e12->dest;
719 bb2->count = count;
720 e23 = split_block (bb2, bb2end);
721 bb3 = e23->dest;
722 bb3->count = all - count;
723 e34 = split_block (bb3, bb3end);
724 bb4 = e34->dest;
725 bb4->count = all;
727 e12->flags &= ~EDGE_FALLTHRU;
728 e12->flags |= EDGE_FALSE_VALUE;
729 e12->probability = prob;
730 e12->count = count;
732 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
733 e13->probability = REG_BR_PROB_BASE - prob;
734 e13->count = all - count;
736 remove_edge (e23);
738 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
739 e24->probability = REG_BR_PROB_BASE;
740 e24->count = count;
742 e34->probability = REG_BR_PROB_BASE;
743 e34->count = all - count;
745 return result;
748 /* Do transform 2) on INSN if applicable. */
749 static bool
750 tree_mod_pow2_value_transform (tree stmt)
752 histogram_value histogram;
753 enum tree_code code;
754 gcov_type count, wrong_values, all;
755 tree modify, op, op1, op2, result, value;
756 int prob;
758 modify = stmt;
759 if (TREE_CODE (stmt) == RETURN_EXPR
760 && TREE_OPERAND (stmt, 0)
761 && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
762 modify = TREE_OPERAND (stmt, 0);
763 if (TREE_CODE (modify) != GIMPLE_MODIFY_STMT)
764 return false;
765 op = GIMPLE_STMT_OPERAND (modify, 1);
766 if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
767 return false;
768 code = TREE_CODE (op);
770 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (TREE_TYPE (op)))
771 return false;
773 op1 = TREE_OPERAND (op, 0);
774 op2 = TREE_OPERAND (op, 1);
776 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_POW2);
777 if (!histogram)
778 return false;
780 value = histogram->hvalue.value;
781 wrong_values = histogram->hvalue.counters[0];
782 count = histogram->hvalue.counters[1];
784 gimple_remove_histogram_value (cfun, stmt, histogram);
786 /* We require that we hit a power of 2 at least half of all evaluations. */
787 if (simple_cst_equal (op2, value) != 1 || count < wrong_values
788 || !maybe_hot_bb_p (bb_for_stmt (stmt)))
789 return false;
791 if (dump_file)
793 fprintf (dump_file, "Mod power of 2 transformation on insn ");
794 print_generic_stmt (dump_file, stmt, TDF_SLIM);
797 /* Compute probability of taking the optimal path. */
798 all = count + wrong_values;
800 if (check_counter (stmt, "pow2", all, bb_for_stmt (stmt)->count))
801 return false;
803 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
805 result = tree_mod_pow2 (stmt, op, op1, op2, prob, count, all);
807 GIMPLE_STMT_OPERAND (modify, 1) = result;
809 return true;
812 /* Generate code for transformations 3 and 4 (with OPERATION, operands OP1
813 and OP2, parent modify-expr STMT, and NCOUNTS the number of cases to
814 support. Currently only NCOUNTS==0 or 1 is supported and this is
815 built into this interface. The probabilities of taking the optimal
816 paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
817 COUNT2/ALL respectively within roundoff error). This generates the
818 result into a temp and returns the temp; it does not replace or alter
819 the original STMT. */
820 /* FIXME: Generalize the interface to handle NCOUNTS > 1. */
822 static tree
823 tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2,
824 int prob1, int prob2, int ncounts,
825 gcov_type count1, gcov_type count2, gcov_type all)
827 tree stmt1, stmt2, stmt3;
828 tree tmp1;
829 tree label_decl1 = create_artificial_label ();
830 tree label_decl2 = create_artificial_label ();
831 tree label_decl3 = create_artificial_label ();
832 tree label1, label2, label3;
833 tree bb1end, bb2end = NULL_TREE, bb3end;
834 basic_block bb, bb2, bb3, bb4;
835 tree optype = TREE_TYPE (operation);
836 edge e12, e23 = 0, e24, e34, e14;
837 block_stmt_iterator bsi;
838 tree result = create_tmp_var (optype, "PROF");
840 bb = bb_for_stmt (stmt);
841 bsi = bsi_for_stmt (stmt);
843 tmp1 = create_tmp_var (optype, "PROF");
844 stmt1 = build_gimple_modify_stmt (result, op1);
845 stmt2 = build_gimple_modify_stmt (tmp1, op2);
846 stmt3 = build3 (COND_EXPR, void_type_node,
847 build2 (LT_EXPR, boolean_type_node, result, tmp1),
848 build1 (GOTO_EXPR, void_type_node, label_decl3),
849 build1 (GOTO_EXPR, void_type_node,
850 ncounts ? label_decl1 : label_decl2));
851 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
852 bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
853 bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
854 bb1end = stmt3;
856 if (ncounts) /* Assumed to be 0 or 1 */
858 label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
859 stmt1 = build_gimple_modify_stmt (result,
860 build2 (MINUS_EXPR, optype,
861 result, tmp1));
862 stmt2 = build3 (COND_EXPR, void_type_node,
863 build2 (LT_EXPR, boolean_type_node, result, tmp1),
864 build1 (GOTO_EXPR, void_type_node, label_decl3),
865 build1 (GOTO_EXPR, void_type_node, label_decl2));
866 bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
867 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
868 bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
869 bb2end = stmt2;
872 /* Fallback case. */
873 label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
874 stmt1 = build_gimple_modify_stmt (result,
875 build2 (TREE_CODE (operation), optype,
876 result, tmp1));
877 bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
878 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
879 bb3end = stmt1;
881 label3 = build1 (LABEL_EXPR, void_type_node, label_decl3);
882 bsi_insert_before (&bsi, label3, BSI_SAME_STMT);
884 /* Fix CFG. */
885 /* Edge e23 connects bb2 to bb3, etc. */
886 /* However block 3 is optional; if it is not there, references
887 to 3 really refer to block 2. */
888 e12 = split_block (bb, bb1end);
889 bb2 = e12->dest;
890 bb2->count = all - count1;
892 if (ncounts) /* Assumed to be 0 or 1. */
894 e23 = split_block (bb2, bb2end);
895 bb3 = e23->dest;
896 bb3->count = all - count1 - count2;
899 e34 = split_block (ncounts ? bb3 : bb2, bb3end);
900 bb4 = e34->dest;
901 bb4->count = all;
903 e12->flags &= ~EDGE_FALLTHRU;
904 e12->flags |= EDGE_FALSE_VALUE;
905 e12->probability = REG_BR_PROB_BASE - prob1;
906 e12->count = all - count1;
908 e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE);
909 e14->probability = prob1;
910 e14->count = count1;
912 if (ncounts) /* Assumed to be 0 or 1. */
914 e23->flags &= ~EDGE_FALLTHRU;
915 e23->flags |= EDGE_FALSE_VALUE;
916 e23->count = all - count1 - count2;
917 e23->probability = REG_BR_PROB_BASE - prob2;
919 e24 = make_edge (bb2, bb4, EDGE_TRUE_VALUE);
920 e24->probability = prob2;
921 e24->count = count2;
924 e34->probability = REG_BR_PROB_BASE;
925 e34->count = all - count1 - count2;
927 return result;
930 /* Do transforms 3) and 4) on INSN if applicable. */
931 static bool
932 tree_mod_subtract_transform (tree stmt)
934 histogram_value histogram;
935 enum tree_code code;
936 gcov_type count, wrong_values, all;
937 tree modify, op, op1, op2, result, value;
938 int prob1, prob2;
939 unsigned int i, steps;
940 gcov_type count1, count2;
942 modify = stmt;
943 if (TREE_CODE (stmt) == RETURN_EXPR
944 && TREE_OPERAND (stmt, 0)
945 && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
946 modify = TREE_OPERAND (stmt, 0);
947 if (TREE_CODE (modify) != GIMPLE_MODIFY_STMT)
948 return false;
949 op = GIMPLE_STMT_OPERAND (modify, 1);
950 if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
951 return false;
952 code = TREE_CODE (op);
954 if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (TREE_TYPE (op)))
955 return false;
957 op1 = TREE_OPERAND (op, 0);
958 op2 = TREE_OPERAND (op, 1);
960 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INTERVAL);
961 if (!histogram)
962 return false;
964 value = histogram->hvalue.value;
965 all = 0;
966 wrong_values = 0;
967 for (i = 0; i < histogram->hdata.intvl.steps; i++)
968 all += histogram->hvalue.counters[i];
970 wrong_values += histogram->hvalue.counters[i];
971 wrong_values += histogram->hvalue.counters[i+1];
972 steps = histogram->hdata.intvl.steps;
973 all += wrong_values;
974 count1 = histogram->hvalue.counters[0];
975 count2 = histogram->hvalue.counters[1];
977 /* Compute probability of taking the optimal path. */
978 if (check_counter (stmt, "interval", all, bb_for_stmt (stmt)->count))
980 gimple_remove_histogram_value (cfun, stmt, histogram);
981 return false;
984 /* We require that we use just subtractions in at least 50% of all
985 evaluations. */
986 count = 0;
987 for (i = 0; i < histogram->hdata.intvl.steps; i++)
989 count += histogram->hvalue.counters[i];
990 if (count * 2 >= all)
991 break;
993 if (i == steps
994 || !maybe_hot_bb_p (bb_for_stmt (stmt)))
995 return false;
997 gimple_remove_histogram_value (cfun, stmt, histogram);
998 if (dump_file)
1000 fprintf (dump_file, "Mod subtract transformation on insn ");
1001 print_generic_stmt (dump_file, stmt, TDF_SLIM);
1004 /* Compute probability of taking the optimal path(s). */
1005 prob1 = (count1 * REG_BR_PROB_BASE + all / 2) / all;
1006 prob2 = (count2 * REG_BR_PROB_BASE + all / 2) / all;
1008 /* In practice, "steps" is always 2. This interface reflects this,
1009 and will need to be changed if "steps" can change. */
1010 result = tree_mod_subtract (stmt, op, op1, op2, prob1, prob2, i,
1011 count1, count2, all);
1013 GIMPLE_STMT_OPERAND (modify, 1) = result;
1015 return true;
1018 static struct cgraph_node** pid_map = NULL;
1020 /* Initialize map of pids (pid -> cgraph node) */
1022 static void
1023 init_pid_map (void)
1025 struct cgraph_node *n;
1027 if (pid_map != NULL)
1028 return;
1030 pid_map
1031 = (struct cgraph_node**) xmalloc (sizeof (struct cgraph_node*) * cgraph_max_pid);
1033 for (n = cgraph_nodes; n; n = n->next)
1035 if (n->pid != -1)
1036 pid_map [n->pid] = n;
1040 /* Return cgraph node for function with pid */
1042 static inline struct cgraph_node*
1043 find_func_by_pid (int pid)
1045 init_pid_map ();
1047 return pid_map [pid];
1050 /* Do transformation
1052 if (actual_callee_addres == addres_of_most_common_function/method)
1053 do direct call
1054 else
1055 old call
1058 static tree
1059 tree_ic (tree stmt, tree call, struct cgraph_node* direct_call,
1060 int prob, gcov_type count, gcov_type all)
1062 tree stmt1, stmt2, stmt3;
1063 tree tmp1, tmpv, tmp;
1064 tree label_decl1 = create_artificial_label ();
1065 tree label_decl2 = create_artificial_label ();
1066 tree label1, label2;
1067 tree bb1end, bb2end, bb3end;
1068 tree new_call;
1069 basic_block bb, bb2, bb3, bb4;
1070 tree optype = build_pointer_type (void_type_node);
1071 edge e12, e13, e23, e24, e34;
1072 block_stmt_iterator bsi;
1073 int region;
1075 bb = bb_for_stmt (stmt);
1076 bsi = bsi_for_stmt (stmt);
1078 tmpv = create_tmp_var (optype, "PROF");
1079 tmp1 = create_tmp_var (optype, "PROF");
1080 stmt1 = build_gimple_modify_stmt (tmpv,
1081 unshare_expr (CALL_EXPR_FN (call)));
1082 tmp = fold_convert (optype, build_addr (direct_call->decl,
1083 current_function_decl));
1084 stmt2 = build_gimple_modify_stmt (tmp1, tmp);
1085 stmt3 = build3 (COND_EXPR, void_type_node,
1086 build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
1087 build1 (GOTO_EXPR, void_type_node, label_decl2),
1088 build1 (GOTO_EXPR, void_type_node, label_decl1));
1089 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
1090 bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
1091 bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
1092 bb1end = stmt3;
1094 label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
1095 stmt1 = unshare_expr (stmt);
1096 new_call = get_call_expr_in (stmt1);
1097 CALL_EXPR_FN (new_call) = build_addr (direct_call->decl,
1098 current_function_decl);
1099 bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
1100 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
1101 bb2end = stmt1;
1103 label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
1104 bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
1105 bb3end = stmt;
1107 /* Fix CFG. */
1108 /* Edge e23 connects bb2 to bb3, etc. */
1109 e12 = split_block (bb, bb1end);
1110 bb2 = e12->dest;
1111 bb2->count = count;
1112 e23 = split_block (bb2, bb2end);
1113 bb3 = e23->dest;
1114 bb3->count = all - count;
1115 e34 = split_block (bb3, bb3end);
1116 bb4 = e34->dest;
1117 bb4->count = all;
1119 e12->flags &= ~EDGE_FALLTHRU;
1120 e12->flags |= EDGE_FALSE_VALUE;
1121 e12->probability = prob;
1122 e12->count = count;
1124 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
1125 e13->probability = REG_BR_PROB_BASE - prob;
1126 e13->count = all - count;
1128 remove_edge (e23);
1130 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
1131 e24->probability = REG_BR_PROB_BASE;
1132 e24->count = count;
1133 e34->probability = REG_BR_PROB_BASE;
1134 e34->count = all - count;
1136 /* Fix eh edges */
1137 region = lookup_stmt_eh_region (stmt);
1138 if (region >=0 && tree_could_throw_p (stmt1))
1140 add_stmt_to_eh_region (stmt1, region);
1141 make_eh_edges (stmt1);
1144 if (region >=0 && tree_could_throw_p (stmt))
1146 tree_purge_dead_eh_edges (bb4);
1147 make_eh_edges (stmt);
1150 return stmt1;
1154 For every checked indirect/virtual call determine if most common pid of
1155 function/class method has probability more than 50%. If yes modify code of
1156 this call to:
1159 static bool
1160 tree_ic_transform (tree stmt)
1162 histogram_value histogram;
1163 gcov_type val, count, all;
1164 int prob;
1165 tree call, callee, modify;
1166 struct cgraph_node *direct_call;
1168 call = get_call_expr_in (stmt);
1170 if (!call || TREE_CODE (call) != CALL_EXPR)
1171 return false;
1173 callee = CALL_EXPR_FN (call);
1175 if (TREE_CODE (callee) == ADDR_EXPR)
1176 return false;
1178 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);
1179 if (!histogram)
1180 return false;
1182 val = histogram->hvalue.counters [0];
1183 count = histogram->hvalue.counters [1];
1184 all = histogram->hvalue.counters [2];
1185 gimple_remove_histogram_value (cfun, stmt, histogram);
1187 if (4 * count <= 3 * all)
1188 return false;
1190 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1191 direct_call = find_func_by_pid ((int)val);
1193 if (direct_call == NULL)
1194 return false;
1196 modify = tree_ic (stmt, call, direct_call, prob, count, all);
1198 if (dump_file)
1200 fprintf (dump_file, "Indirect call -> direct call ");
1201 print_generic_expr (dump_file, call, TDF_SLIM);
1202 fprintf (dump_file, "=> ");
1203 print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
1204 fprintf (dump_file, " transformation on insn ");
1205 print_generic_stmt (dump_file, stmt, TDF_SLIM);
1206 fprintf (dump_file, " to ");
1207 print_generic_stmt (dump_file, modify, TDF_SLIM);
1210 return true;
1213 /* Return true if the stringop CALL with FNDECL shall be profiled. */
1214 static bool
1215 interesting_stringop_to_profile_p (tree fndecl, tree call)
1217 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
1219 if (fcode != BUILT_IN_MEMSET && fcode != BUILT_IN_MEMCPY
1220 && fcode != BUILT_IN_BZERO)
1221 return false;
1223 switch (fcode)
1225 case BUILT_IN_MEMCPY:
1226 case BUILT_IN_MEMPCPY:
1227 return validate_arglist (call,
1228 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
1229 VOID_TYPE);
1230 case BUILT_IN_MEMSET:
1231 return validate_arglist (call,
1232 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE,
1233 VOID_TYPE);
1234 case BUILT_IN_BZERO:
1235 return validate_arglist (call, POINTER_TYPE, INTEGER_TYPE,
1236 VOID_TYPE);
1237 default:
1238 gcc_unreachable ();
1242 /* Convert stringop (..., size)
1243 into
1244 if (size == VALUE)
1245 stringop (...., VALUE);
1246 else
1247 stringop (...., size);
1248 assuming constant propagation of VALUE will happen later.
1250 static void
1251 tree_stringop_fixed_value (tree stmt, tree value, int prob, gcov_type count,
1252 gcov_type all)
1254 tree stmt1, stmt2, stmt3;
1255 tree tmp1, tmpv;
1256 tree label_decl1 = create_artificial_label ();
1257 tree label_decl2 = create_artificial_label ();
1258 tree label1, label2;
1259 tree bb1end, bb2end;
1260 basic_block bb, bb2, bb3, bb4;
1261 edge e12, e13, e23, e24, e34;
1262 block_stmt_iterator bsi;
1263 tree call = get_call_expr_in (stmt);
1264 tree blck_size = CALL_EXPR_ARG (call, 2);
1265 tree optype = TREE_TYPE (blck_size);
1266 int region;
1268 bb = bb_for_stmt (stmt);
1269 bsi = bsi_for_stmt (stmt);
1271 if (bsi_end_p (bsi))
1273 edge_iterator ei;
1274 for (ei = ei_start (bb->succs); (e34 = ei_safe_edge (ei)); )
1275 if (!e34->flags & EDGE_ABNORMAL)
1276 break;
1278 else
1280 e34 = split_block (bb, stmt);
1281 bsi = bsi_for_stmt (stmt);
1283 bb4 = e34->dest;
1285 tmpv = create_tmp_var (optype, "PROF");
1286 tmp1 = create_tmp_var (optype, "PROF");
1287 stmt1 = build_gimple_modify_stmt (tmpv, fold_convert (optype, value));
1288 stmt2 = build_gimple_modify_stmt (tmp1, blck_size);
1289 stmt3 = build3 (COND_EXPR, void_type_node,
1290 build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
1291 build1 (GOTO_EXPR, void_type_node, label_decl2),
1292 build1 (GOTO_EXPR, void_type_node, label_decl1));
1293 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
1294 bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
1295 bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
1296 bb1end = stmt3;
1298 label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
1299 stmt1 = unshare_expr (stmt);
1300 call = get_call_expr_in (stmt1);
1301 CALL_EXPR_ARG (call, 2) = value;
1302 bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
1303 bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
1304 region = lookup_stmt_eh_region (stmt);
1305 if (region >= 0)
1306 add_stmt_to_eh_region (stmt1, region);
1307 bb2end = stmt1;
1308 label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
1309 bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
1311 /* Fix CFG. */
1312 /* Edge e23 connects bb2 to bb3, etc. */
1313 e12 = split_block (bb, bb1end);
1314 bb2 = e12->dest;
1315 bb2->count = count;
1316 e23 = split_block (bb2, bb2end);
1317 bb3 = e23->dest;
1318 bb3->count = all - count;
1320 e12->flags &= ~EDGE_FALLTHRU;
1321 e12->flags |= EDGE_FALSE_VALUE;
1322 e12->probability = prob;
1323 e12->count = count;
1325 e13 = make_edge (bb, bb3, EDGE_TRUE_VALUE);
1326 e13->probability = REG_BR_PROB_BASE - prob;
1327 e13->count = all - count;
1329 remove_edge (e23);
1331 e24 = make_edge (bb2, bb4, EDGE_FALLTHRU);
1332 e24->probability = REG_BR_PROB_BASE;
1333 e24->count = count;
1335 e34->probability = REG_BR_PROB_BASE;
1336 e34->count = all - count;
1339 /* Find values inside STMT for that we want to measure histograms for
1340 division/modulo optimization. */
1341 static bool
1342 tree_stringops_transform (block_stmt_iterator *bsi)
1344 tree stmt = bsi_stmt (*bsi);
1345 tree call = get_call_expr_in (stmt);
1346 tree fndecl;
1347 tree blck_size;
1348 enum built_in_function fcode;
1349 histogram_value histogram;
1350 gcov_type count, all, val;
1351 tree value;
1352 tree dest, src;
1353 unsigned int dest_align, src_align;
1354 int prob;
1355 tree tree_val;
1357 if (!call)
1358 return false;
1359 fndecl = get_callee_fndecl (call);
1360 if (!fndecl)
1361 return false;
1362 fcode = DECL_FUNCTION_CODE (fndecl);
1363 if (!interesting_stringop_to_profile_p (fndecl, call))
1364 return false;
1366 if (fcode == BUILT_IN_BZERO)
1367 blck_size = CALL_EXPR_ARG (call, 1);
1368 else
1369 blck_size = CALL_EXPR_ARG (call, 2);
1370 if (TREE_CODE (blck_size) == INTEGER_CST)
1371 return false;
1373 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
1374 if (!histogram)
1375 return false;
1376 value = histogram->hvalue.value;
1377 val = histogram->hvalue.counters[0];
1378 count = histogram->hvalue.counters[1];
1379 all = histogram->hvalue.counters[2];
1380 gimple_remove_histogram_value (cfun, stmt, histogram);
1381 /* We require that count is at least half of all; this means
1382 that for the transformation to fire the value must be constant
1383 at least 80% of time. */
1384 if ((6 * count / 5) < all || !maybe_hot_bb_p (bb_for_stmt (stmt)))
1385 return false;
1386 if (check_counter (stmt, "value", all, bb_for_stmt (stmt)->count))
1387 return false;
1388 prob = (count * REG_BR_PROB_BASE + all / 2) / all;
1389 dest = CALL_EXPR_ARG (call, 0);
1390 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
1391 switch (fcode)
1393 case BUILT_IN_MEMCPY:
1394 case BUILT_IN_MEMPCPY:
1395 src = CALL_EXPR_ARG (call, 1);
1396 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
1397 if (!can_move_by_pieces (val, MIN (dest_align, src_align)))
1398 return false;
1399 break;
1400 case BUILT_IN_MEMSET:
1401 if (!can_store_by_pieces (val, builtin_memset_read_str,
1402 CALL_EXPR_ARG (call, 1),
1403 dest_align))
1404 return false;
1405 break;
1406 case BUILT_IN_BZERO:
1407 if (!can_store_by_pieces (val, builtin_memset_read_str,
1408 integer_zero_node,
1409 dest_align))
1410 return false;
1411 break;
1412 default:
1413 gcc_unreachable ();
1415 tree_val = build_int_cst_wide (get_gcov_type (),
1416 (unsigned HOST_WIDE_INT) val,
1417 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
1418 if (dump_file)
1420 fprintf (dump_file, "Single value %i stringop transformation on ",
1421 (int)val);
1422 print_generic_stmt (dump_file, stmt, TDF_SLIM);
1424 tree_stringop_fixed_value (stmt, tree_val, prob, count, all);
1426 return true;
1429 void
1430 stringop_block_profile (tree stmt, unsigned int *expected_align,
1431 HOST_WIDE_INT *expected_size)
1433 histogram_value histogram;
1434 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_AVERAGE);
1435 if (!histogram)
1436 *expected_size = -1;
1437 else if (!histogram->hvalue.counters[1])
1439 *expected_size = -1;
1440 gimple_remove_histogram_value (cfun, stmt, histogram);
1442 else
1444 gcov_type size;
1445 size = ((histogram->hvalue.counters[0]
1446 + histogram->hvalue.counters[1] / 2)
1447 / histogram->hvalue.counters[1]);
1448 /* Even if we can hold bigger value in SIZE, INT_MAX
1449 is safe "infinity" for code generation strategies. */
1450 if (size > INT_MAX)
1451 size = INT_MAX;
1452 *expected_size = size;
1453 gimple_remove_histogram_value (cfun, stmt, histogram);
1455 histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_IOR);
1456 if (!histogram)
1457 *expected_align = 0;
1458 else if (!histogram->hvalue.counters[0])
1460 gimple_remove_histogram_value (cfun, stmt, histogram);
1461 *expected_align = 0;
1463 else
1465 gcov_type count;
1466 int alignment;
1468 count = histogram->hvalue.counters[0];
1469 alignment = 1;
1470 while (!(count & alignment)
1471 && (alignment * 2 * BITS_PER_UNIT))
1472 alignment <<= 1;
1473 *expected_align = alignment * BITS_PER_UNIT;
1474 gimple_remove_histogram_value (cfun, stmt, histogram);
1478 struct value_prof_hooks {
1479 /* Find list of values for which we want to measure histograms. */
1480 void (*find_values_to_profile) (histogram_values *);
1482 /* Identify and exploit properties of values that are hard to analyze
1483 statically. See value-prof.c for more detail. */
1484 bool (*value_profile_transformations) (void);
1487 /* Find values inside STMT for that we want to measure histograms for
1488 division/modulo optimization. */
1489 static void
1490 tree_divmod_values_to_profile (tree stmt, histogram_values *values)
1492 tree assign, lhs, rhs, divisor, op0, type;
1493 histogram_value hist;
1495 if (TREE_CODE (stmt) == RETURN_EXPR)
1496 assign = TREE_OPERAND (stmt, 0);
1497 else
1498 assign = stmt;
1500 if (!assign
1501 || TREE_CODE (assign) != GIMPLE_MODIFY_STMT)
1502 return;
1503 lhs = GIMPLE_STMT_OPERAND (assign, 0);
1504 type = TREE_TYPE (lhs);
1505 if (!INTEGRAL_TYPE_P (type))
1506 return;
1508 rhs = GIMPLE_STMT_OPERAND (assign, 1);
1509 switch (TREE_CODE (rhs))
1511 case TRUNC_DIV_EXPR:
1512 case TRUNC_MOD_EXPR:
1513 divisor = TREE_OPERAND (rhs, 1);
1514 op0 = TREE_OPERAND (rhs, 0);
1516 VEC_reserve (histogram_value, heap, *values, 3);
1518 if (is_gimple_reg (divisor))
1519 /* Check for the case where the divisor is the same value most
1520 of the time. */
1521 VEC_quick_push (histogram_value, *values,
1522 gimple_alloc_histogram_value (cfun, HIST_TYPE_SINGLE_VALUE,
1523 stmt, divisor));
1525 /* For mod, check whether it is not often a noop (or replaceable by
1526 a few subtractions). */
1527 if (TREE_CODE (rhs) == TRUNC_MOD_EXPR
1528 && TYPE_UNSIGNED (type))
1530 tree val;
1531 /* Check for a special case where the divisor is power of 2. */
1532 VEC_quick_push (histogram_value, *values,
1533 gimple_alloc_histogram_value (cfun, HIST_TYPE_POW2,
1534 stmt, divisor));
1536 val = build2 (TRUNC_DIV_EXPR, type, op0, divisor);
1537 hist = gimple_alloc_histogram_value (cfun, HIST_TYPE_INTERVAL,
1538 stmt, val);
1539 hist->hdata.intvl.int_start = 0;
1540 hist->hdata.intvl.steps = 2;
1541 VEC_quick_push (histogram_value, *values, hist);
1543 return;
1545 default:
1546 return;
1550 /* Find calls inside STMT for that we want to measure histograms for
1551 indirect/virtual call optimization. */
1553 static void
1554 tree_indirect_call_to_profile (tree stmt, histogram_values *values)
1556 tree call;
1557 tree callee;
1559 call = get_call_expr_in (stmt);
1561 if (!call || TREE_CODE (call) != CALL_EXPR)
1562 return;
1564 callee = CALL_EXPR_FN (call);
1566 if (TREE_CODE (callee) == ADDR_EXPR)
1567 return;
1569 VEC_reserve (histogram_value, heap, *values, 3);
1571 VEC_quick_push (histogram_value, *values,
1572 gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
1573 stmt, callee));
1575 return;
1578 /* Find values inside STMT for that we want to measure histograms for
1579 string operations. */
1580 static void
1581 tree_stringops_values_to_profile (tree stmt, histogram_values *values)
1583 tree call = get_call_expr_in (stmt);
1584 tree fndecl;
1585 tree blck_size;
1586 tree dest;
1587 enum built_in_function fcode;
1589 if (!call)
1590 return;
1591 fndecl = get_callee_fndecl (call);
1592 if (!fndecl)
1593 return;
1594 fcode = DECL_FUNCTION_CODE (fndecl);
1596 if (!interesting_stringop_to_profile_p (fndecl, call))
1597 return;
1599 dest = CALL_EXPR_ARG (call, 0);
1600 if (fcode == BUILT_IN_BZERO)
1601 blck_size = CALL_EXPR_ARG (call, 1);
1602 else
1603 blck_size = CALL_EXPR_ARG (call, 2);
1605 if (TREE_CODE (blck_size) != INTEGER_CST)
1607 VEC_safe_push (histogram_value, heap, *values,
1608 gimple_alloc_histogram_value (cfun, HIST_TYPE_SINGLE_VALUE,
1609 stmt, blck_size));
1610 VEC_safe_push (histogram_value, heap, *values,
1611 gimple_alloc_histogram_value (cfun, HIST_TYPE_AVERAGE,
1612 stmt, blck_size));
1614 if (TREE_CODE (blck_size) != INTEGER_CST)
1615 VEC_safe_push (histogram_value, heap, *values,
1616 gimple_alloc_histogram_value (cfun, HIST_TYPE_IOR,
1617 stmt, dest));
1620 /* Find values inside STMT for that we want to measure histograms and adds
1621 them to list VALUES. */
1623 static void
1624 tree_values_to_profile (tree stmt, histogram_values *values)
1626 if (flag_value_profile_transformations)
1628 tree_divmod_values_to_profile (stmt, values);
1629 tree_stringops_values_to_profile (stmt, values);
1630 tree_indirect_call_to_profile (stmt, values);
1634 static void
1635 tree_find_values_to_profile (histogram_values *values)
1637 basic_block bb;
1638 block_stmt_iterator bsi;
1639 unsigned i;
1640 histogram_value hist = NULL;
1642 *values = NULL;
1643 FOR_EACH_BB (bb)
1644 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1645 tree_values_to_profile (bsi_stmt (bsi), values);
1647 for (i = 0; VEC_iterate (histogram_value, *values, i, hist); i++)
1649 switch (hist->type)
1651 case HIST_TYPE_INTERVAL:
1652 hist->n_counters = hist->hdata.intvl.steps + 2;
1653 break;
1655 case HIST_TYPE_POW2:
1656 hist->n_counters = 2;
1657 break;
1659 case HIST_TYPE_SINGLE_VALUE:
1660 hist->n_counters = 3;
1661 break;
1663 case HIST_TYPE_CONST_DELTA:
1664 hist->n_counters = 4;
1665 break;
1667 case HIST_TYPE_INDIR_CALL:
1668 hist->n_counters = 3;
1669 break;
1671 case HIST_TYPE_AVERAGE:
1672 hist->n_counters = 2;
1673 break;
1675 case HIST_TYPE_IOR:
1676 hist->n_counters = 1;
1677 break;
1679 default:
1680 gcc_unreachable ();
1682 if (dump_file)
1684 fprintf (dump_file, "Stmt ");
1685 print_generic_expr (dump_file, hist->hvalue.stmt, TDF_SLIM);
1686 dump_histogram_value (dump_file, hist);
1691 static struct value_prof_hooks tree_value_prof_hooks = {
1692 tree_find_values_to_profile,
1693 tree_value_profile_transformations
1696 void
1697 tree_register_value_prof_hooks (void)
1699 gcc_assert (current_ir_type () == IR_GIMPLE);
1700 value_prof_hooks = &tree_value_prof_hooks;
1703 /* IR-independent entry points. */
1704 void
1705 find_values_to_profile (histogram_values *values)
1707 (value_prof_hooks->find_values_to_profile) (values);
1710 bool
1711 value_profile_transformations (void)
1713 return (value_prof_hooks->value_profile_transformations) ();