Merged revisions 208012,208018-208019,208021,208023-208030,208033,208037,208040-20804...
[official-gcc.git] / main / gcc / profile.c
blob43ff23714ed8aa582f41cbfb171b7b2ea1dd0168
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990-2014 Free Software Foundation, Inc.
3 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
4 based on some ideas from Dain Samples of UC Berkeley.
5 Further mangling by Bob Manson, Cygnus Support.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* Generate basic block profile instrumentation and auxiliary files.
24 Profile generation is optimized, so that not all arcs in the basic
25 block graph need instrumenting. First, the BB graph is closed with
26 one entry (function start), and one exit (function exit). Any
27 ABNORMAL_EDGE cannot be instrumented (because there is no control
28 path to place the code). We close the graph by inserting fake
29 EDGE_FAKE edges to the EXIT_BLOCK, from the sources of abnormal
30 edges that do not go to the exit_block. We ignore such abnormal
31 edges. Naturally these fake edges are never directly traversed,
32 and so *cannot* be directly instrumented. Some other graph
33 massaging is done. To optimize the instrumentation we generate the
34 BB minimal span tree, only edges that are not on the span tree
35 (plus the entry point) need instrumenting. From that information
36 all other edge counts can be deduced. By construction all fake
37 edges must be on the spanning tree. We also attempt to place
38 EDGE_CRITICAL edges on the spanning tree.
40 The auxiliary files generated are <dumpbase>.gcno (at compile time)
41 and <dumpbase>.gcda (at run time). The format is
42 described in full in gcov-io.h. */
44 /* ??? Register allocation should use basic block execution counts to
45 give preference to the most commonly executed blocks. */
47 /* ??? Should calculate branch probabilities before instrumenting code, since
48 then we can use arc counts to help decide which arcs to instrument. */
50 #include "config.h"
51 #include "system.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "rtl.h"
55 #include "flags.h"
56 #include "regs.h"
57 #include "expr.h"
58 #include "function.h"
59 #include "basic-block.h"
60 #include "diagnostic-core.h"
61 #include "coverage.h"
62 #include "value-prof.h"
63 #include "tree.h"
64 #include "tree-ssa-alias.h"
65 #include "internal-fn.h"
66 #include "gimple-expr.h"
67 #include "is-a.h"
68 #include "gimple.h"
69 #include "gimple-iterator.h"
70 #include "tree-cfg.h"
71 #include "cfgloop.h"
72 #include "dumpfile.h"
73 #include "params.h"
74 #include "cgraph.h"
76 #include "profile.h"
78 struct bb_info {
79 unsigned int count_valid : 1;
81 /* Number of successor and predecessor edges. */
82 gcov_type succ_count;
83 gcov_type pred_count;
86 #define BB_INFO(b) ((struct bb_info *) (b)->aux)
89 /* Counter summary from the last set of coverage counts read. */
91 const struct gcov_ctr_summary *profile_info;
93 /* Counter working set information computed from the current counter
94 summary. Not initialized unless profile_info summary is non-NULL. */
95 static gcov_working_set_t gcov_working_sets[NUM_GCOV_WORKING_SETS];
97 /* Collect statistics on the performance of this pass for the entire source
98 file. */
100 static int total_num_blocks;
101 static int total_num_edges;
102 static int total_num_edges_ignored;
103 static int total_num_edges_instrumented;
104 static int total_num_blocks_created;
105 static int total_num_passes;
106 static int total_num_times_called;
107 static int total_hist_br_prob[20];
108 static int total_num_branches;
110 /* Forward declarations. */
111 static void find_spanning_tree (struct edge_list *);
113 /* Add edge instrumentation code to the entire insn chain.
115 F is the first insn of the chain.
116 NUM_BLOCKS is the number of basic blocks found in F. */
118 static unsigned
119 instrument_edges (struct edge_list *el)
121 unsigned num_instr_edges = 0;
122 int num_edges = NUM_EDGES (el);
123 basic_block bb;
125 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
127 edge e;
128 edge_iterator ei;
130 FOR_EACH_EDGE (e, ei, bb->succs)
132 struct edge_info *inf = EDGE_INFO (e);
134 if (!inf->ignore && !inf->on_tree)
136 gcc_assert (!(e->flags & EDGE_ABNORMAL));
137 if (dump_file)
138 fprintf (dump_file, "Edge %d to %d instrumented%s\n",
139 e->src->index, e->dest->index,
140 EDGE_CRITICAL_P (e) ? " (and split)" : "");
141 gimple_gen_edge_profiler (num_instr_edges++, e);
146 total_num_blocks_created += num_edges;
147 if (dump_file)
148 fprintf (dump_file, "%d edges instrumented\n", num_instr_edges);
149 return num_instr_edges;
152 /* Add code to measure histograms for values in list VALUES. */
153 static void
154 instrument_values (histogram_values values)
156 unsigned i;
158 /* Emit code to generate the histograms before the insns. */
160 for (i = 0; i < values.length (); i++)
162 histogram_value hist = values[i];
163 unsigned t = COUNTER_FOR_HIST_TYPE (hist->type);
165 /* See condition in gimple_gen_ic_func_topn_profiler */
166 if (t == GCOV_COUNTER_ICALL_TOPNV
167 && (DECL_STATIC_CONSTRUCTOR (current_function_decl)
168 || DECL_STATIC_CONSTRUCTOR (current_function_decl)
169 || DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (
170 current_function_decl)))
171 continue;
173 if (!coverage_counter_alloc (t, hist->n_counters))
174 continue;
176 switch (hist->type)
178 case HIST_TYPE_INTERVAL:
179 gimple_gen_interval_profiler (hist, t, 0);
180 break;
182 case HIST_TYPE_POW2:
183 gimple_gen_pow2_profiler (hist, t, 0);
184 break;
186 case HIST_TYPE_SINGLE_VALUE:
187 gimple_gen_one_value_profiler (hist, t, 0);
188 break;
190 case HIST_TYPE_CONST_DELTA:
191 gimple_gen_const_delta_profiler (hist, t, 0);
192 break;
194 case HIST_TYPE_INDIR_CALL:
195 case HIST_TYPE_INDIR_CALL_TOPN:
196 gimple_gen_ic_profiler (hist, t, 0);
197 break;
199 case HIST_TYPE_AVERAGE:
200 gimple_gen_average_profiler (hist, t, 0);
201 break;
203 case HIST_TYPE_IOR:
204 gimple_gen_ior_profiler (hist, t, 0);
205 break;
207 case HIST_TYPE_TIME_PROFILE:
209 basic_block bb =
210 split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
211 gimple_stmt_iterator gsi = gsi_start_bb (bb);
213 gimple_gen_time_profiler (t, 0, gsi);
214 break;
217 default:
218 gcc_unreachable ();
224 /* Fill the working set information into the profile_info structure. */
226 void
227 get_working_sets (void)
229 unsigned ws_ix, pctinc, pct;
230 gcov_working_set_t *ws_info;
232 if (!profile_info)
233 return;
235 compute_working_sets (profile_info, gcov_working_sets);
237 if (dump_file)
239 fprintf (dump_file, "Counter working sets:\n");
240 /* Multiply the percentage by 100 to avoid float. */
241 pctinc = 100 * 100 / NUM_GCOV_WORKING_SETS;
242 for (ws_ix = 0, pct = pctinc; ws_ix < NUM_GCOV_WORKING_SETS;
243 ws_ix++, pct += pctinc)
245 if (ws_ix == NUM_GCOV_WORKING_SETS - 1)
246 pct = 9990;
247 ws_info = &gcov_working_sets[ws_ix];
248 /* Print out the percentage using int arithmatic to avoid float. */
249 fprintf (dump_file, "\t\t%u.%02u%%: num counts=%u, min counter="
250 HOST_WIDEST_INT_PRINT_DEC "\n",
251 pct / 100, pct - (pct / 100 * 100),
252 ws_info->num_counters,
253 (HOST_WIDEST_INT)ws_info->min_counter);
258 /* Given a the desired percentage of the full profile (sum_all from the
259 summary), multiplied by 10 to avoid float in PCT_TIMES_10, returns
260 the corresponding working set information. If an exact match for
261 the percentage isn't found, the closest value is used. */
263 gcov_working_set_t *
264 find_working_set (unsigned pct_times_10)
266 unsigned i;
267 if (!profile_info)
268 return NULL;
269 gcc_assert (pct_times_10 <= 1000);
270 if (pct_times_10 >= 999)
271 return &gcov_working_sets[NUM_GCOV_WORKING_SETS - 1];
272 i = pct_times_10 * NUM_GCOV_WORKING_SETS / 1000;
273 if (!i)
274 return &gcov_working_sets[0];
275 return &gcov_working_sets[i - 1];
278 /* Computes hybrid profile for all matching entries in da_file.
280 CFG_CHECKSUM is the precomputed checksum for the CFG. */
282 static gcov_type *
283 get_exec_counts (unsigned cfg_checksum, unsigned lineno_checksum)
285 unsigned num_edges = 0;
286 basic_block bb;
287 gcov_type *counts;
289 /* Count the edges to be (possibly) instrumented. */
290 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
292 edge e;
293 edge_iterator ei;
295 FOR_EACH_EDGE (e, ei, bb->succs)
296 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
297 num_edges++;
300 counts = get_coverage_counts (GCOV_COUNTER_ARCS, num_edges, cfg_checksum,
301 lineno_checksum, &profile_info);
302 if (!counts)
303 return NULL;
305 get_working_sets ();
307 if (dump_file && profile_info)
308 fprintf (dump_file, "Merged %u profiles with maximal count %u.\n",
309 profile_info->runs, (unsigned) profile_info->sum_max);
311 return counts;
315 static bool
316 is_edge_inconsistent (vec<edge, va_gc> *edges)
318 edge e;
319 edge_iterator ei;
320 FOR_EACH_EDGE (e, ei, edges)
322 if (!EDGE_INFO (e)->ignore)
324 if (e->count < 0
325 && (!(e->flags & EDGE_FAKE)
326 || e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun)
327 || !block_ends_with_call_p (e->src)))
329 if (dump_file)
331 fprintf (dump_file,
332 "Edge %i->%i is inconsistent, count"HOST_WIDEST_INT_PRINT_DEC,
333 e->src->index, e->dest->index, e->count);
334 dump_bb (dump_file, e->src, 0, TDF_DETAILS);
335 dump_bb (dump_file, e->dest, 0, TDF_DETAILS);
337 return true;
341 return false;
344 static void
345 correct_negative_edge_counts (void)
347 basic_block bb;
348 edge e;
349 edge_iterator ei;
351 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
353 FOR_EACH_EDGE (e, ei, bb->succs)
355 if (e->count < 0)
356 e->count = 0;
361 /* Check consistency.
362 Return true if inconsistency is found. */
363 static bool
364 is_inconsistent (void)
366 basic_block bb;
367 bool inconsistent = false;
368 FOR_EACH_BB_FN (bb, cfun)
370 inconsistent |= is_edge_inconsistent (bb->preds);
371 if (!dump_file && inconsistent)
372 return true;
373 inconsistent |= is_edge_inconsistent (bb->succs);
374 if (!dump_file && inconsistent)
375 return true;
376 if (bb->count < 0)
378 if (dump_file)
380 fprintf (dump_file, "BB %i count is negative "
381 HOST_WIDEST_INT_PRINT_DEC,
382 bb->index,
383 bb->count);
384 dump_bb (dump_file, bb, 0, TDF_DETAILS);
386 inconsistent = true;
388 if (bb->count != sum_edge_counts (bb->preds))
390 if (dump_file)
392 fprintf (dump_file, "BB %i count does not match sum of incoming edges "
393 HOST_WIDEST_INT_PRINT_DEC" should be " HOST_WIDEST_INT_PRINT_DEC,
394 bb->index,
395 bb->count,
396 sum_edge_counts (bb->preds));
397 dump_bb (dump_file, bb, 0, TDF_DETAILS);
399 inconsistent = true;
401 if (bb->count != sum_edge_counts (bb->succs) &&
402 ! (find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun)) != NULL
403 && block_ends_with_call_p (bb)))
405 if (dump_file)
407 fprintf (dump_file, "BB %i count does not match sum of outgoing edges "
408 HOST_WIDEST_INT_PRINT_DEC" should be " HOST_WIDEST_INT_PRINT_DEC,
409 bb->index,
410 bb->count,
411 sum_edge_counts (bb->succs));
412 dump_bb (dump_file, bb, 0, TDF_DETAILS);
414 inconsistent = true;
416 if (!dump_file && inconsistent)
417 return true;
420 return inconsistent;
423 /* Set each basic block count to the sum of its outgoing edge counts */
424 static void
425 set_bb_counts (void)
427 basic_block bb;
428 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
430 bb->count = sum_edge_counts (bb->succs);
431 gcc_assert (bb->count >= 0);
435 /* Reads profile data and returns total number of edge counts read */
436 static int
437 read_profile_edge_counts (gcov_type *exec_counts)
439 basic_block bb;
440 int num_edges = 0;
441 int exec_counts_pos = 0;
442 /* For each edge not on the spanning tree, set its execution count from
443 the .da file. */
444 /* The first count in the .da file is the number of times that the function
445 was entered. This is the exec_count for block zero. */
447 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
449 edge e;
450 edge_iterator ei;
452 FOR_EACH_EDGE (e, ei, bb->succs)
453 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
455 num_edges++;
456 if (exec_counts)
458 e->count = exec_counts[exec_counts_pos++];
459 if (e->count > profile_info->sum_max)
461 if (flag_profile_correction)
463 static bool informed = 0;
464 if (dump_enabled_p () && !informed)
465 dump_printf_loc (MSG_NOTE, input_location,
466 "corrupted profile info: edge count"
467 " exceeds maximal count\n");
468 informed = 1;
470 else
471 error ("corrupted profile info: edge from %i to %i exceeds maximal count",
472 bb->index, e->dest->index);
475 else
476 e->count = 0;
478 EDGE_INFO (e)->count_valid = 1;
479 BB_INFO (bb)->succ_count--;
480 BB_INFO (e->dest)->pred_count--;
481 if (dump_file)
483 fprintf (dump_file, "\nRead edge from %i to %i, count:",
484 bb->index, e->dest->index);
485 fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
486 (HOST_WIDEST_INT) e->count);
491 return num_edges;
494 #define OVERLAP_BASE 10000
496 /* Compare the static estimated profile to the actual profile, and
497 return the "degree of overlap" measure between them.
499 Degree of overlap is a number between 0 and OVERLAP_BASE. It is
500 the sum of each basic block's minimum relative weights between
501 two profiles. And overlap of OVERLAP_BASE means two profiles are
502 identical. */
504 static int
505 compute_frequency_overlap (void)
507 gcov_type count_total = 0, freq_total = 0;
508 int overlap = 0;
509 basic_block bb;
511 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
513 count_total += bb->count;
514 freq_total += bb->frequency;
517 if (count_total == 0 || freq_total == 0)
518 return 0;
520 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
521 overlap += MIN (bb->count * OVERLAP_BASE / count_total,
522 bb->frequency * OVERLAP_BASE / freq_total);
524 return overlap;
527 /* Compute the branch probabilities for the various branches.
528 Annotate them accordingly.
530 CFG_CHECKSUM is the precomputed checksum for the CFG. */
532 static void
533 compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
535 basic_block bb;
536 int i;
537 int num_edges = 0;
538 int changes;
539 int passes;
540 int hist_br_prob[20];
541 int num_branches;
542 gcov_type *exec_counts = get_exec_counts (cfg_checksum, lineno_checksum);
543 int inconsistent = 0;
545 /* Very simple sanity checks so we catch bugs in our profiling code. */
546 if (!profile_info)
547 return;
549 if (profile_info->sum_all < profile_info->sum_max)
551 error ("corrupted profile info: sum_all is smaller than sum_max");
552 exec_counts = NULL;
555 /* Attach extra info block to each bb. */
556 alloc_aux_for_blocks (sizeof (struct bb_info));
557 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
559 edge e;
560 edge_iterator ei;
562 FOR_EACH_EDGE (e, ei, bb->succs)
563 if (!EDGE_INFO (e)->ignore)
564 BB_INFO (bb)->succ_count++;
565 FOR_EACH_EDGE (e, ei, bb->preds)
566 if (!EDGE_INFO (e)->ignore)
567 BB_INFO (bb)->pred_count++;
570 /* Avoid predicting entry on exit nodes. */
571 BB_INFO (EXIT_BLOCK_PTR_FOR_FN (cfun))->succ_count = 2;
572 BB_INFO (ENTRY_BLOCK_PTR_FOR_FN (cfun))->pred_count = 2;
574 num_edges = read_profile_edge_counts (exec_counts);
576 if (dump_file)
577 fprintf (dump_file, "\n%d edge counts read\n", num_edges);
579 /* For every block in the file,
580 - if every exit/entrance edge has a known count, then set the block count
581 - if the block count is known, and every exit/entrance edge but one has
582 a known execution count, then set the count of the remaining edge
584 As edge counts are set, decrement the succ/pred count, but don't delete
585 the edge, that way we can easily tell when all edges are known, or only
586 one edge is unknown. */
588 /* The order that the basic blocks are iterated through is important.
589 Since the code that finds spanning trees starts with block 0, low numbered
590 edges are put on the spanning tree in preference to high numbered edges.
591 Hence, most instrumented edges are at the end. Graph solving works much
592 faster if we propagate numbers from the end to the start.
594 This takes an average of slightly more than 3 passes. */
596 changes = 1;
597 passes = 0;
598 while (changes)
600 passes++;
601 changes = 0;
602 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), NULL, prev_bb)
604 struct bb_info *bi = BB_INFO (bb);
605 if (! bi->count_valid)
607 if (bi->succ_count == 0)
609 edge e;
610 edge_iterator ei;
611 gcov_type total = 0;
613 FOR_EACH_EDGE (e, ei, bb->succs)
614 total += e->count;
615 bb->count = total;
616 bi->count_valid = 1;
617 changes = 1;
619 else if (bi->pred_count == 0)
621 edge e;
622 edge_iterator ei;
623 gcov_type total = 0;
625 FOR_EACH_EDGE (e, ei, bb->preds)
626 total += e->count;
627 bb->count = total;
628 bi->count_valid = 1;
629 changes = 1;
632 if (bi->count_valid)
634 if (bi->succ_count == 1)
636 edge e;
637 edge_iterator ei;
638 gcov_type total = 0;
640 /* One of the counts will be invalid, but it is zero,
641 so adding it in also doesn't hurt. */
642 FOR_EACH_EDGE (e, ei, bb->succs)
643 total += e->count;
645 /* Search for the invalid edge, and set its count. */
646 FOR_EACH_EDGE (e, ei, bb->succs)
647 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
648 break;
650 /* Calculate count for remaining edge by conservation. */
651 total = bb->count - total;
653 gcc_assert (e);
654 EDGE_INFO (e)->count_valid = 1;
655 e->count = total;
656 bi->succ_count--;
658 BB_INFO (e->dest)->pred_count--;
659 changes = 1;
661 if (bi->pred_count == 1)
663 edge e;
664 edge_iterator ei;
665 gcov_type total = 0;
667 /* One of the counts will be invalid, but it is zero,
668 so adding it in also doesn't hurt. */
669 FOR_EACH_EDGE (e, ei, bb->preds)
670 total += e->count;
672 /* Search for the invalid edge, and set its count. */
673 FOR_EACH_EDGE (e, ei, bb->preds)
674 if (!EDGE_INFO (e)->count_valid && !EDGE_INFO (e)->ignore)
675 break;
677 /* Calculate count for remaining edge by conservation. */
678 total = bb->count - total + e->count;
680 gcc_assert (e);
681 EDGE_INFO (e)->count_valid = 1;
682 e->count = total;
683 bi->pred_count--;
685 BB_INFO (e->src)->succ_count--;
686 changes = 1;
691 if (dump_file)
693 int overlap = compute_frequency_overlap ();
694 gimple_dump_cfg (dump_file, dump_flags);
695 fprintf (dump_file, "Static profile overlap: %d.%d%%\n",
696 overlap / (OVERLAP_BASE / 100),
697 overlap % (OVERLAP_BASE / 100));
700 total_num_passes += passes;
701 if (dump_file)
702 fprintf (dump_file, "Graph solving took %d passes.\n\n", passes);
704 /* If the graph has been correctly solved, every block will have a
705 succ and pred count of zero. */
706 FOR_EACH_BB_FN (bb, cfun)
708 gcc_assert (!BB_INFO (bb)->succ_count && !BB_INFO (bb)->pred_count);
711 /* Check for inconsistent basic block counts */
712 inconsistent = is_inconsistent ();
714 if (inconsistent)
716 if (flag_profile_correction)
718 /* Inconsistency detected. Make it flow-consistent. */
719 static int informed = 0;
720 if (dump_enabled_p () && informed == 0)
722 informed = 1;
723 dump_printf_loc (MSG_NOTE, input_location,
724 "correcting inconsistent profile data\n");
726 correct_negative_edge_counts ();
727 /* Set bb counts to the sum of the outgoing edge counts */
728 set_bb_counts ();
729 if (dump_file)
730 fprintf (dump_file, "\nCalling mcf_smooth_cfg\n");
731 mcf_smooth_cfg ();
733 else
734 error ("corrupted profile info: profile data is not flow-consistent");
737 /* For every edge, calculate its branch probability and add a reg_note
738 to the branch insn to indicate this. */
740 for (i = 0; i < 20; i++)
741 hist_br_prob[i] = 0;
742 num_branches = 0;
744 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
746 edge e;
747 edge_iterator ei;
749 if (bb->count < 0)
751 error ("corrupted profile info: number of iterations for basic block %d thought to be %i",
752 bb->index, (int)bb->count);
753 bb->count = 0;
755 FOR_EACH_EDGE (e, ei, bb->succs)
757 /* Function may return twice in the cased the called function is
758 setjmp or calls fork, but we can't represent this by extra
759 edge from the entry, since extra edge from the exit is
760 already present. We get negative frequency from the entry
761 point. */
762 if ((e->count < 0
763 && e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
764 || (e->count > bb->count
765 && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)))
767 if (block_ends_with_call_p (bb))
768 e->count = e->count < 0 ? 0 : bb->count;
770 if (e->count < 0 || e->count > bb->count)
772 error ("corrupted profile info: number of executions for edge %d-%d thought to be %i",
773 e->src->index, e->dest->index,
774 (int)e->count);
775 e->count = bb->count / 2;
778 if (bb->count)
780 FOR_EACH_EDGE (e, ei, bb->succs)
781 e->probability = GCOV_COMPUTE_SCALE (e->count, bb->count);
782 if (bb->index >= NUM_FIXED_BLOCKS
783 && block_ends_with_condjump_p (bb)
784 && EDGE_COUNT (bb->succs) >= 2)
786 int prob;
787 edge e;
788 int index;
790 /* Find the branch edge. It is possible that we do have fake
791 edges here. */
792 FOR_EACH_EDGE (e, ei, bb->succs)
793 if (!(e->flags & (EDGE_FAKE | EDGE_FALLTHRU)))
794 break;
796 prob = e->probability;
797 index = prob * 20 / REG_BR_PROB_BASE;
799 if (index == 20)
800 index = 19;
801 hist_br_prob[index]++;
803 num_branches++;
806 /* As a last resort, distribute the probabilities evenly.
807 Use simple heuristics that if there are normal edges,
808 give all abnormals frequency of 0, otherwise distribute the
809 frequency over abnormals (this is the case of noreturn
810 calls). */
811 else if (profile_status_for_fn (cfun) == PROFILE_ABSENT)
813 int total = 0;
815 FOR_EACH_EDGE (e, ei, bb->succs)
816 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
817 total ++;
818 if (total)
820 FOR_EACH_EDGE (e, ei, bb->succs)
821 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
822 e->probability = REG_BR_PROB_BASE / total;
823 else
824 e->probability = 0;
826 else
828 total += EDGE_COUNT (bb->succs);
829 FOR_EACH_EDGE (e, ei, bb->succs)
830 e->probability = REG_BR_PROB_BASE / total;
832 if (bb->index >= NUM_FIXED_BLOCKS
833 && block_ends_with_condjump_p (bb)
834 && EDGE_COUNT (bb->succs) >= 2)
835 num_branches++;
838 counts_to_freqs ();
839 profile_status_for_fn (cfun) = PROFILE_READ;
840 compute_function_frequency ();
842 if (dump_file)
844 fprintf (dump_file, "%d branches\n", num_branches);
845 if (num_branches)
846 for (i = 0; i < 10; i++)
847 fprintf (dump_file, "%d%% branches in range %d-%d%%\n",
848 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
849 5 * i, 5 * i + 5);
851 total_num_branches += num_branches;
852 for (i = 0; i < 20; i++)
853 total_hist_br_prob[i] += hist_br_prob[i];
855 fputc ('\n', dump_file);
856 fputc ('\n', dump_file);
859 free_aux_for_blocks ();
862 /* Load value histograms values whose description is stored in VALUES array
863 from .gcda file.
865 CFG_CHECKSUM is the precomputed checksum for the CFG. */
867 static void
868 compute_value_histograms (histogram_values values, unsigned cfg_checksum,
869 unsigned lineno_checksum)
871 unsigned i, j, t, any;
872 unsigned n_histogram_counters[GCOV_N_VALUE_COUNTERS];
873 gcov_type *histogram_counts[GCOV_N_VALUE_COUNTERS];
874 gcov_type *act_count[GCOV_N_VALUE_COUNTERS];
875 gcov_type *aact_count;
876 bool warned[GCOV_N_VALUE_COUNTERS];
877 static const char *const ctr_names[] = GCOV_COUNTER_NAMES;
878 struct cgraph_node *node;
880 for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
882 n_histogram_counters[t] = 0;
883 warned[t] = 0;
886 for (i = 0; i < values.length (); i++)
888 histogram_value hist = values[i];
889 n_histogram_counters[(int) hist->type] += hist->n_counters;
892 any = 0;
893 for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
895 if (!n_histogram_counters[t])
897 histogram_counts[t] = NULL;
898 continue;
901 histogram_counts[t] =
902 get_coverage_counts (COUNTER_FOR_HIST_TYPE (t),
903 n_histogram_counters[t], cfg_checksum,
904 lineno_checksum, NULL);
905 if (histogram_counts[t])
906 any = 1;
907 act_count[t] = histogram_counts[t];
909 if (!any)
910 return;
912 for (i = 0; i < values.length (); i++)
914 histogram_value hist = values[i];
915 gimple stmt = hist->hvalue.stmt;
917 t = (int) hist->type;
919 aact_count = act_count[t];
920 /* If the counter cannot be found in gcda file, skip this
921 histogram and give a warning. */
922 if (aact_count == 0)
924 if (!warned[t])
925 warning (0, "cannot find %s counters in function %s.",
926 ctr_names[COUNTER_FOR_HIST_TYPE(t)],
927 IDENTIFIER_POINTER (
928 DECL_ASSEMBLER_NAME (current_function_decl)));
929 hist->n_counters = 0;
930 warned[t] = true;
931 continue;
934 if (act_count[t])
935 act_count[t] += hist->n_counters;
937 gimple_add_histogram_value (cfun, stmt, hist);
938 hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters);
939 for (j = 0; j < hist->n_counters; j++)
940 if (aact_count)
941 hist->hvalue.counters[j] = aact_count[j];
942 else
943 hist->hvalue.counters[j] = 0;
945 /* Time profiler counter is not related to any statement,
946 so that we have to read the counter and set the value to
947 the corresponding call graph node. */
948 if (hist->type == HIST_TYPE_TIME_PROFILE)
950 node = cgraph_get_node (hist->fun->decl);
952 node->tp_first_run = hist->hvalue.counters[0];
954 if (dump_file)
955 fprintf (dump_file, "Read tp_first_run: %d\n", node->tp_first_run);
959 for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
960 free (histogram_counts[t]);
963 /* When passed NULL as file_name, initialize.
964 When passed something else, output the necessary commands to change
965 line to LINE and offset to FILE_NAME. */
966 static void
967 output_location (char const *file_name, int line,
968 gcov_position_t *offset, basic_block bb)
970 static char const *prev_file_name;
971 static int prev_line;
972 bool name_differs, line_differs;
974 if (!file_name)
976 prev_file_name = NULL;
977 prev_line = -1;
978 return;
981 name_differs = !prev_file_name || filename_cmp (file_name, prev_file_name);
982 line_differs = prev_line != line;
984 if (name_differs || line_differs)
986 if (!*offset)
988 *offset = gcov_write_tag (GCOV_TAG_LINES);
989 gcov_write_unsigned (bb->index);
990 name_differs = line_differs=true;
993 /* If this is a new source file, then output the
994 file's name to the .bb file. */
995 if (name_differs)
997 prev_file_name = file_name;
998 gcov_write_unsigned (0);
999 gcov_write_string (prev_file_name);
1001 if (line_differs)
1003 gcov_write_unsigned (line);
1004 prev_line = line;
1009 /* Instrument and/or analyze program behavior based on program the CFG.
1011 This function creates a representation of the control flow graph (of
1012 the function being compiled) that is suitable for the instrumentation
1013 of edges and/or converting measured edge counts to counts on the
1014 complete CFG.
1016 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
1017 the flow graph that are needed to reconstruct the dynamic behavior of the
1018 flow graph. This data is written to the gcno file for gcov.
1020 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
1021 information from the gcda file containing edge count information from
1022 previous executions of the function being compiled. In this case, the
1023 control flow graph is annotated with actual execution counts by
1024 compute_branch_probabilities().
1026 Main entry point of this file. */
1028 void
1029 branch_prob (void)
1031 basic_block bb;
1032 unsigned i;
1033 unsigned num_edges, ignored_edges;
1034 unsigned num_instrumented;
1035 struct edge_list *el;
1036 histogram_values values = histogram_values ();
1037 unsigned cfg_checksum, lineno_checksum;
1039 total_num_times_called++;
1041 flow_call_edges_add (NULL);
1042 add_noreturn_fake_exit_edges ();
1044 /* We can't handle cyclic regions constructed using abnormal edges.
1045 To avoid these we replace every source of abnormal edge by a fake
1046 edge from entry node and every destination by fake edge to exit.
1047 This keeps graph acyclic and our calculation exact for all normal
1048 edges except for exit and entrance ones.
1050 We also add fake exit edges for each call and asm statement in the
1051 basic, since it may not return. */
1053 FOR_EACH_BB_FN (bb, cfun)
1055 int need_exit_edge = 0, need_entry_edge = 0;
1056 int have_exit_edge = 0, have_entry_edge = 0;
1057 edge e;
1058 edge_iterator ei;
1060 /* Functions returning multiple times are not handled by extra edges.
1061 Instead we simply allow negative counts on edges from exit to the
1062 block past call and corresponding probabilities. We can't go
1063 with the extra edges because that would result in flowgraph that
1064 needs to have fake edges outside the spanning tree. */
1066 FOR_EACH_EDGE (e, ei, bb->succs)
1068 gimple_stmt_iterator gsi;
1069 gimple last = NULL;
1071 /* It may happen that there are compiler generated statements
1072 without a locus at all. Go through the basic block from the
1073 last to the first statement looking for a locus. */
1074 for (gsi = gsi_last_nondebug_bb (bb);
1075 !gsi_end_p (gsi);
1076 gsi_prev_nondebug (&gsi))
1078 last = gsi_stmt (gsi);
1079 if (gimple_has_location (last))
1080 break;
1083 /* Edge with goto locus might get wrong coverage info unless
1084 it is the only edge out of BB.
1085 Don't do that when the locuses match, so
1086 if (blah) goto something;
1087 is not computed twice. */
1088 if (last
1089 && gimple_has_location (last)
1090 && LOCATION_LOCUS (e->goto_locus) != UNKNOWN_LOCATION
1091 && !single_succ_p (bb)
1092 && (LOCATION_FILE (e->goto_locus)
1093 != LOCATION_FILE (gimple_location (last))
1094 || (LOCATION_LINE (e->goto_locus)
1095 != LOCATION_LINE (gimple_location (last)))))
1097 basic_block new_bb = split_edge (e);
1098 edge ne = single_succ_edge (new_bb);
1099 ne->goto_locus = e->goto_locus;
1101 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
1102 && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
1103 need_exit_edge = 1;
1104 if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
1105 have_exit_edge = 1;
1107 FOR_EACH_EDGE (e, ei, bb->preds)
1109 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
1110 && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
1111 need_entry_edge = 1;
1112 if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
1113 have_entry_edge = 1;
1116 if (need_exit_edge && !have_exit_edge)
1118 if (dump_file)
1119 fprintf (dump_file, "Adding fake exit edge to bb %i\n",
1120 bb->index);
1121 make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE);
1123 if (need_entry_edge && !have_entry_edge)
1125 if (dump_file)
1126 fprintf (dump_file, "Adding fake entry edge to bb %i\n",
1127 bb->index);
1128 make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FAKE);
1129 /* Avoid bbs that have both fake entry edge and also some
1130 exit edge. One of those edges wouldn't be added to the
1131 spanning tree, but we can't instrument any of them. */
1132 if (have_exit_edge || need_exit_edge)
1134 gimple_stmt_iterator gsi;
1135 gimple first;
1137 gsi = gsi_start_nondebug_after_labels_bb (bb);
1138 gcc_checking_assert (!gsi_end_p (gsi));
1139 first = gsi_stmt (gsi);
1140 /* Don't split the bbs containing __builtin_setjmp_receiver
1141 or ABNORMAL_DISPATCHER calls. These are very
1142 special and don't expect anything to be inserted before
1143 them. */
1144 if (is_gimple_call (first)
1145 && (gimple_call_builtin_p (first, BUILT_IN_SETJMP_RECEIVER)
1146 || (gimple_call_flags (first) & ECF_RETURNS_TWICE)
1147 || (gimple_call_internal_p (first)
1148 && (gimple_call_internal_fn (first)
1149 == IFN_ABNORMAL_DISPATCHER))))
1150 continue;
1152 if (dump_file)
1153 fprintf (dump_file, "Splitting bb %i after labels\n",
1154 bb->index);
1155 split_block_after_labels (bb);
1160 el = create_edge_list ();
1161 num_edges = NUM_EDGES (el);
1162 alloc_aux_for_edges (sizeof (struct edge_info));
1164 /* The basic blocks are expected to be numbered sequentially. */
1165 compact_blocks ();
1167 ignored_edges = 0;
1168 for (i = 0 ; i < num_edges ; i++)
1170 edge e = INDEX_EDGE (el, i);
1171 e->count = 0;
1173 /* Mark edges we've replaced by fake edges above as ignored. */
1174 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
1175 && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
1176 && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
1178 EDGE_INFO (e)->ignore = 1;
1179 ignored_edges++;
1183 /* Create spanning tree from basic block graph, mark each edge that is
1184 on the spanning tree. We insert as many abnormal and critical edges
1185 as possible to minimize number of edge splits necessary. */
1187 find_spanning_tree (el);
1189 /* Fake edges that are not on the tree will not be instrumented, so
1190 mark them ignored. */
1191 for (num_instrumented = i = 0; i < num_edges; i++)
1193 edge e = INDEX_EDGE (el, i);
1194 struct edge_info *inf = EDGE_INFO (e);
1196 if (inf->ignore || inf->on_tree)
1197 /*NOP*/;
1198 else if (e->flags & EDGE_FAKE)
1200 inf->ignore = 1;
1201 ignored_edges++;
1203 else
1204 num_instrumented++;
1207 total_num_blocks += n_basic_blocks_for_fn (cfun);
1208 if (dump_file)
1209 fprintf (dump_file, "%d basic blocks\n", n_basic_blocks_for_fn (cfun));
1211 total_num_edges += num_edges;
1212 if (dump_file)
1213 fprintf (dump_file, "%d edges\n", num_edges);
1215 total_num_edges_ignored += ignored_edges;
1216 if (dump_file)
1217 fprintf (dump_file, "%d ignored edges\n", ignored_edges);
1219 total_num_edges_instrumented += num_instrumented;
1220 if (dump_file)
1221 fprintf (dump_file, "%d instrumentation edges\n", num_instrumented);
1223 /* Compute two different checksums. Note that we want to compute
1224 the checksum in only once place, since it depends on the shape
1225 of the control flow which can change during
1226 various transformations. */
1227 cfg_checksum = coverage_compute_cfg_checksum ();
1228 lineno_checksum = coverage_compute_lineno_checksum ();
1230 /* Write the data from which gcov can reconstruct the basic block
1231 graph and function line numbers (the gcno file). */
1232 if (coverage_begin_function (lineno_checksum, cfg_checksum))
1234 gcov_position_t offset;
1236 /* Basic block flags */
1237 offset = gcov_write_tag (GCOV_TAG_BLOCKS);
1238 for (i = 0; i != (unsigned) (n_basic_blocks_for_fn (cfun)); i++)
1239 gcov_write_unsigned (0);
1240 gcov_write_length (offset);
1242 /* Arcs */
1243 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun),
1244 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
1246 edge e;
1247 edge_iterator ei;
1249 offset = gcov_write_tag (GCOV_TAG_ARCS);
1250 gcov_write_unsigned (bb->index);
1252 FOR_EACH_EDGE (e, ei, bb->succs)
1254 struct edge_info *i = EDGE_INFO (e);
1255 if (!i->ignore)
1257 unsigned flag_bits = 0;
1259 if (i->on_tree)
1260 flag_bits |= GCOV_ARC_ON_TREE;
1261 if (e->flags & EDGE_FAKE)
1262 flag_bits |= GCOV_ARC_FAKE;
1263 if (e->flags & EDGE_FALLTHRU)
1264 flag_bits |= GCOV_ARC_FALLTHROUGH;
1265 /* On trees we don't have fallthru flags, but we can
1266 recompute them from CFG shape. */
1267 if (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)
1268 && e->src->next_bb == e->dest)
1269 flag_bits |= GCOV_ARC_FALLTHROUGH;
1271 gcov_write_unsigned (e->dest->index);
1272 gcov_write_unsigned (flag_bits);
1276 gcov_write_length (offset);
1279 /* Line numbers. */
1280 /* Initialize the output. */
1281 output_location (NULL, 0, NULL, NULL);
1283 FOR_EACH_BB_FN (bb, cfun)
1285 gimple_stmt_iterator gsi;
1286 gcov_position_t offset = 0;
1288 if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb)
1290 expanded_location curr_location =
1291 expand_location (DECL_SOURCE_LOCATION (current_function_decl));
1292 output_location (curr_location.file, curr_location.line,
1293 &offset, bb);
1296 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1298 gimple stmt = gsi_stmt (gsi);
1299 if (gimple_has_location (stmt))
1300 output_location (gimple_filename (stmt), gimple_lineno (stmt),
1301 &offset, bb);
1304 /* Notice GOTO expressions eliminated while constructing the CFG. */
1305 if (single_succ_p (bb)
1306 && LOCATION_LOCUS (single_succ_edge (bb)->goto_locus)
1307 != UNKNOWN_LOCATION)
1309 expanded_location curr_location
1310 = expand_location (single_succ_edge (bb)->goto_locus);
1311 output_location (curr_location.file, curr_location.line,
1312 &offset, bb);
1315 if (offset)
1317 /* A file of NULL indicates the end of run. */
1318 gcov_write_unsigned (0);
1319 gcov_write_string (NULL);
1320 gcov_write_length (offset);
1325 if (flag_profile_values)
1326 gimple_find_values_to_profile (&values);
1328 if (flag_branch_probabilities)
1330 compute_branch_probabilities (cfg_checksum, lineno_checksum);
1331 if (flag_profile_values)
1332 compute_value_histograms (values, cfg_checksum, lineno_checksum);
1335 remove_fake_edges ();
1337 /* For each edge not on the spanning tree, add counting code. */
1338 if (profile_arc_flag
1339 && coverage_counter_alloc (GCOV_COUNTER_ARCS, num_instrumented))
1341 unsigned n_instrumented;
1343 gimple_init_edge_profiler ();
1345 n_instrumented = instrument_edges (el);
1347 gcc_assert (n_instrumented == num_instrumented);
1349 if (flag_profile_values)
1350 instrument_values (values);
1352 /* Commit changes done by instrumentation. */
1353 gsi_commit_edge_inserts ();
1355 if (flag_profile_generate_sampling
1356 || PARAM_VALUE (PARAM_COVERAGE_EXEC_ONCE))
1357 add_sampling_to_edge_counters ();
1360 free_aux_for_edges ();
1362 values.release ();
1363 free_edge_list (el);
1364 coverage_end_function (lineno_checksum, cfg_checksum);
1367 /* Union find algorithm implementation for the basic blocks using
1368 aux fields. */
1370 static basic_block
1371 find_group (basic_block bb)
1373 basic_block group = bb, bb1;
1375 while ((basic_block) group->aux != group)
1376 group = (basic_block) group->aux;
1378 /* Compress path. */
1379 while ((basic_block) bb->aux != group)
1381 bb1 = (basic_block) bb->aux;
1382 bb->aux = (void *) group;
1383 bb = bb1;
1385 return group;
1388 static void
1389 union_groups (basic_block bb1, basic_block bb2)
1391 basic_block bb1g = find_group (bb1);
1392 basic_block bb2g = find_group (bb2);
1394 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
1395 this code is unlikely going to be performance problem anyway. */
1396 gcc_assert (bb1g != bb2g);
1398 bb1g->aux = bb2g;
1401 /* This function searches all of the edges in the program flow graph, and puts
1402 as many bad edges as possible onto the spanning tree. Bad edges include
1403 abnormals edges, which can't be instrumented at the moment. Since it is
1404 possible for fake edges to form a cycle, we will have to develop some
1405 better way in the future. Also put critical edges to the tree, since they
1406 are more expensive to instrument. */
1408 static void
1409 find_spanning_tree (struct edge_list *el)
1411 int i;
1412 int num_edges = NUM_EDGES (el);
1413 basic_block bb;
1415 /* We use aux field for standard union-find algorithm. */
1416 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb)
1417 bb->aux = bb;
1419 /* Add fake edge exit to entry we can't instrument. */
1420 union_groups (EXIT_BLOCK_PTR_FOR_FN (cfun), ENTRY_BLOCK_PTR_FOR_FN (cfun));
1422 /* First add all abnormal edges to the tree unless they form a cycle. Also
1423 add all edges to the exit block to avoid inserting profiling code behind
1424 setting return value from function. */
1425 for (i = 0; i < num_edges; i++)
1427 edge e = INDEX_EDGE (el, i);
1428 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1429 || e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
1430 && !EDGE_INFO (e)->ignore
1431 && (find_group (e->src) != find_group (e->dest)))
1433 if (dump_file)
1434 fprintf (dump_file, "Abnormal edge %d to %d put to tree\n",
1435 e->src->index, e->dest->index);
1436 EDGE_INFO (e)->on_tree = 1;
1437 union_groups (e->src, e->dest);
1441 /* Now insert all critical edges to the tree unless they form a cycle. */
1442 for (i = 0; i < num_edges; i++)
1444 edge e = INDEX_EDGE (el, i);
1445 if (EDGE_CRITICAL_P (e) && !EDGE_INFO (e)->ignore
1446 && find_group (e->src) != find_group (e->dest))
1448 if (dump_file)
1449 fprintf (dump_file, "Critical edge %d to %d put to tree\n",
1450 e->src->index, e->dest->index);
1451 EDGE_INFO (e)->on_tree = 1;
1452 union_groups (e->src, e->dest);
1456 /* And now the rest. */
1457 for (i = 0; i < num_edges; i++)
1459 edge e = INDEX_EDGE (el, i);
1460 if (!EDGE_INFO (e)->ignore
1461 && find_group (e->src) != find_group (e->dest))
1463 if (dump_file)
1464 fprintf (dump_file, "Normal edge %d to %d put to tree\n",
1465 e->src->index, e->dest->index);
1466 EDGE_INFO (e)->on_tree = 1;
1467 union_groups (e->src, e->dest);
1471 clear_aux_for_blocks ();
1474 /* Perform file-level initialization for branch-prob processing. */
1476 void
1477 init_branch_prob (void)
1479 int i;
1481 total_num_blocks = 0;
1482 total_num_edges = 0;
1483 total_num_edges_ignored = 0;
1484 total_num_edges_instrumented = 0;
1485 total_num_blocks_created = 0;
1486 total_num_passes = 0;
1487 total_num_times_called = 0;
1488 total_num_branches = 0;
1489 for (i = 0; i < 20; i++)
1490 total_hist_br_prob[i] = 0;
1493 /* Performs file-level cleanup after branch-prob processing
1494 is completed. */
1496 void
1497 end_branch_prob (void)
1499 if (dump_file)
1501 fprintf (dump_file, "\n");
1502 fprintf (dump_file, "Total number of blocks: %d\n",
1503 total_num_blocks);
1504 fprintf (dump_file, "Total number of edges: %d\n", total_num_edges);
1505 fprintf (dump_file, "Total number of ignored edges: %d\n",
1506 total_num_edges_ignored);
1507 fprintf (dump_file, "Total number of instrumented edges: %d\n",
1508 total_num_edges_instrumented);
1509 fprintf (dump_file, "Total number of blocks created: %d\n",
1510 total_num_blocks_created);
1511 fprintf (dump_file, "Total number of graph solution passes: %d\n",
1512 total_num_passes);
1513 if (total_num_times_called != 0)
1514 fprintf (dump_file, "Average number of graph solution passes: %d\n",
1515 (total_num_passes + (total_num_times_called >> 1))
1516 / total_num_times_called);
1517 fprintf (dump_file, "Total number of branches: %d\n",
1518 total_num_branches);
1519 if (total_num_branches)
1521 int i;
1523 for (i = 0; i < 10; i++)
1524 fprintf (dump_file, "%d%% branches in range %d-%d%%\n",
1525 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1526 / total_num_branches, 5*i, 5*i+5);