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