* lcm.c (optimize_mode_switching): Revert previous change.
[official-gcc.git] / gcc / profile.c
blob73dbd0b79fe9f31244ece8202ff48bad6c26ae17
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
3 2000, 2001 Free Software Foundation, Inc.
4 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
5 based on some ideas from Dain Samples of UC Berkeley.
6 Further mangling by Bob Manson, Cygnus Support.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 2, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 02111-1307, USA. */
25 /* ??? Register allocation should use basic block execution counts to
26 give preference to the most commonly executed blocks. */
28 /* ??? The .da files are not safe. Changing the program after creating .da
29 files or using different options when compiling with -fbranch-probabilities
30 can result the arc data not matching the program. Maybe add instrumented
31 arc count to .bbg file? Maybe check whether PFG matches the .bbg file? */
33 /* ??? Should calculate branch probabilities before instrumenting code, since
34 then we can use arc counts to help decide which arcs to instrument. */
36 #include "config.h"
37 #include "system.h"
38 #include "rtl.h"
39 #include "tree.h"
40 #include "flags.h"
41 #include "insn-config.h"
42 #include "output.h"
43 #include "regs.h"
44 #include "expr.h"
45 #include "function.h"
46 #include "toplev.h"
47 #include "ggc.h"
48 #include "hard-reg-set.h"
49 #include "basic-block.h"
50 #include "gcov-io.h"
51 #include "target.h"
52 #include "profile.h"
53 #include "libfuncs.h"
54 #include "langhooks.h"
56 /* Additional information about the edges we need. */
57 struct edge_info
59 unsigned int count_valid : 1;
60 unsigned int on_tree : 1;
61 unsigned int ignore : 1;
63 struct bb_info
65 unsigned int count_valid : 1;
66 gcov_type succ_count;
67 gcov_type pred_count;
70 #define EDGE_INFO(e) ((struct edge_info *) (e)->aux)
71 #define BB_INFO(b) ((struct bb_info *) (b)->aux)
73 /* Keep all basic block indexes nonnegative in the gcov output. Index 0
74 is used for entry block, last block exit block. */
75 #define GCOV_INDEX_TO_BB(i) ((i) == 0 ? ENTRY_BLOCK_PTR \
76 : (((i) == last_basic_block + 1) \
77 ? EXIT_BLOCK_PTR : BASIC_BLOCK ((i)-1)))
78 #define BB_TO_GCOV_INDEX(bb) ((bb) == ENTRY_BLOCK_PTR ? 0 \
79 : ((bb) == EXIT_BLOCK_PTR \
80 ? last_basic_block + 1 : (bb)->sindex + 1))
82 /* Instantiate the profile info structure. */
84 struct profile_info profile_info;
86 /* Name and file pointer of the output file for the basic block graph. */
88 static FILE *bbg_file;
90 /* Name and file pointer of the input file for the arc count data. */
92 static FILE *da_file;
94 /* Pointer of the output file for the basic block/line number map. */
95 static FILE *bb_file;
97 /* Last source file name written to bb_file. */
99 static char *last_bb_file_name;
101 /* Collect statistics on the performance of this pass for the entire source
102 file. */
104 static int total_num_blocks;
105 static int total_num_edges;
106 static int total_num_edges_ignored;
107 static int total_num_edges_instrumented;
108 static int total_num_blocks_created;
109 static int total_num_passes;
110 static int total_num_times_called;
111 static int total_hist_br_prob[20];
112 static int total_num_never_executed;
113 static int total_num_branches;
115 /* Forward declarations. */
116 static void find_spanning_tree PARAMS ((struct edge_list *));
117 static void init_edge_profiler PARAMS ((void));
118 static rtx gen_edge_profiler PARAMS ((int));
119 static void instrument_edges PARAMS ((struct edge_list *));
120 static void output_gcov_string PARAMS ((const char *, long));
121 static void compute_branch_probabilities PARAMS ((void));
122 static gcov_type * get_exec_counts PARAMS ((void));
123 static long compute_checksum PARAMS ((void));
124 static basic_block find_group PARAMS ((basic_block));
125 static void union_groups PARAMS ((basic_block, basic_block));
127 /* If non-zero, we need to output a constructor to set up the
128 per-object-file data. */
129 static int need_func_profiler = 0;
131 /* Add edge instrumentation code to the entire insn chain.
133 F is the first insn of the chain.
134 NUM_BLOCKS is the number of basic blocks found in F. */
136 static void
137 instrument_edges (el)
138 struct edge_list *el;
140 int num_instr_edges = 0;
141 int num_edges = NUM_EDGES (el);
142 basic_block bb;
143 remove_fake_edges ();
145 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
147 edge e = bb->succ;
148 while (e)
150 struct edge_info *inf = EDGE_INFO (e);
151 if (!inf->ignore && !inf->on_tree)
153 if (e->flags & EDGE_ABNORMAL)
154 abort ();
155 if (rtl_dump_file)
156 fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
157 e->src->sindex, e->dest->sindex,
158 EDGE_CRITICAL_P (e) ? " (and split)" : "");
159 need_func_profiler = 1;
160 insert_insn_on_edge (
161 gen_edge_profiler (total_num_edges_instrumented
162 + num_instr_edges++), e);
164 e = e->succ_next;
168 profile_info.count_edges_instrumented_now = num_instr_edges;
169 total_num_edges_instrumented += num_instr_edges;
170 profile_info.count_instrumented_edges = total_num_edges_instrumented;
172 total_num_blocks_created += num_edges;
173 if (rtl_dump_file)
174 fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
176 commit_edge_insertions_watch_calls ();
179 /* Output STRING to bb_file, surrounded by DELIMITER. */
181 static void
182 output_gcov_string (string, delimiter)
183 const char *string;
184 long delimiter;
186 long temp;
188 /* Write a delimiter to indicate that a file name follows. */
189 __write_long (delimiter, bb_file, 4);
191 /* Write the string. */
192 temp = strlen (string) + 1;
193 fwrite (string, temp, 1, bb_file);
195 /* Append a few zeros, to align the output to a 4 byte boundary. */
196 temp = temp & 0x3;
197 if (temp)
199 char c[4];
201 c[0] = c[1] = c[2] = c[3] = 0;
202 fwrite (c, sizeof (char), 4 - temp, bb_file);
205 /* Store another delimiter in the .bb file, just to make it easy to find
206 the end of the file name. */
207 __write_long (delimiter, bb_file, 4);
211 /* Computes hybrid profile for all matching entries in da_file.
212 Sets max_counter_in_program as a side effect. */
214 static gcov_type *
215 get_exec_counts ()
217 int num_edges = 0;
218 basic_block bb;
219 int okay = 1, j;
220 int mismatch = 0;
221 gcov_type *profile;
222 char *function_name_buffer;
223 int function_name_buffer_len;
224 gcov_type max_counter_in_run;
226 profile_info.max_counter_in_program = 0;
227 profile_info.count_profiles_merged = 0;
229 /* No .da file, no execution counts. */
230 if (!da_file)
231 return 0;
233 /* Count the edges to be (possibly) instrumented. */
235 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
237 edge e;
238 for (e = bb->succ; e; e = e->succ_next)
239 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
240 num_edges++;
243 /* now read and combine all matching profiles. */
245 profile = xmalloc (sizeof (gcov_type) * num_edges);
246 rewind (da_file);
247 function_name_buffer_len = strlen (current_function_name) + 1;
248 function_name_buffer = xmalloc (function_name_buffer_len + 1);
250 for (j = 0; j < num_edges; j++)
251 profile[j] = 0;
253 while (1)
255 long magic, extra_bytes;
256 long func_count;
257 int i;
259 if (__read_long (&magic, da_file, 4) != 0)
260 break;
262 if (magic != -123)
264 okay = 0;
265 break;
268 if (__read_long (&func_count, da_file, 4) != 0)
270 okay = 0;
271 break;
274 if (__read_long (&extra_bytes, da_file, 4) != 0)
276 okay = 0;
277 break;
280 fseek (da_file, 4 + 8, SEEK_CUR);
282 /* read the maximal counter. */
283 __read_gcov_type (&max_counter_in_run, da_file, 8);
285 /* skip the rest of "statistics" emited by __bb_exit_func. */
286 fseek (da_file, extra_bytes - (4 + 8 + 8), SEEK_CUR);
288 for (i = 0; i < func_count; i++)
290 long arc_count;
291 long chksum;
292 int j;
294 if (__read_gcov_string
295 (function_name_buffer, function_name_buffer_len, da_file,
296 -1) != 0)
298 okay = 0;
299 break;
302 if (__read_long (&chksum, da_file, 4) != 0)
304 okay = 0;
305 break;
308 if (__read_long (&arc_count, da_file, 4) != 0)
310 okay = 0;
311 break;
314 if (strcmp (function_name_buffer, current_function_name) != 0)
316 /* skip */
317 if (fseek (da_file, arc_count * 8, SEEK_CUR) < 0)
319 okay = 0;
320 break;
323 else if (arc_count != num_edges
324 || chksum != profile_info.current_function_cfg_checksum)
325 okay = 0, mismatch = 1;
326 else
328 gcov_type tmp;
330 profile_info.max_counter_in_program += max_counter_in_run;
331 profile_info.count_profiles_merged++;
333 for (j = 0; j < arc_count; j++)
334 if (__read_gcov_type (&tmp, da_file, 8) != 0)
336 okay = 0;
337 break;
339 else
341 profile[j] += tmp;
346 if (!okay)
347 break;
351 free (function_name_buffer);
353 if (!okay)
355 if (mismatch)
356 error
357 ("Profile does not match flowgraph of function %s (out of date?)",
358 current_function_name);
359 else
360 error (".da file corrupted");
361 free (profile);
362 return 0;
365 return profile;
369 /* Compute the branch probabilities for the various branches.
370 Annotate them accordingly. */
372 static void
373 compute_branch_probabilities ()
375 basic_block bb;
376 int num_edges = 0, i;
377 int changes;
378 int passes;
379 int hist_br_prob[20];
380 int num_never_executed;
381 int num_branches;
382 gcov_type *exec_counts = get_exec_counts ();
383 int exec_counts_pos = 0;
385 /* Attach extra info block to each bb. */
387 alloc_aux_for_blocks (sizeof (struct bb_info));
388 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
390 edge e;
392 for (e = bb->succ; e; e = e->succ_next)
393 if (!EDGE_INFO (e)->ignore)
394 BB_INFO (bb)->succ_count++;
395 for (e = bb->pred; e; e = e->pred_next)
396 if (!EDGE_INFO (e)->ignore)
397 BB_INFO (bb)->pred_count++;
400 /* Avoid predicting entry on exit nodes. */
401 BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
402 BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
404 /* For each edge not on the spanning tree, set its execution count from
405 the .da file. */
407 /* The first count in the .da file is the number of times that the function
408 was entered. This is the exec_count for block zero. */
410 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
412 edge e;
413 for (e = bb->succ; e; e = e->succ_next)
414 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
416 num_edges++;
417 if (exec_counts)
419 e->count = exec_counts[exec_counts_pos++];
421 else
422 e->count = 0;
424 EDGE_INFO (e)->count_valid = 1;
425 BB_INFO (bb)->succ_count--;
426 BB_INFO (e->dest)->pred_count--;
427 if (rtl_dump_file)
429 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
430 bb->sindex, e->dest->sindex);
431 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
432 (HOST_WIDEST_INT) e->count);
437 if (rtl_dump_file)
438 fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
440 /* For every block in the file,
441 - if every exit/entrance edge has a known count, then set the block count
442 - if the block count is known, and every exit/entrance edge but one has
443 a known execution count, then set the count of the remaining edge
445 As edge counts are set, decrement the succ/pred count, but don't delete
446 the edge, that way we can easily tell when all edges are known, or only
447 one edge is unknown. */
449 /* The order that the basic blocks are iterated through is important.
450 Since the code that finds spanning trees starts with block 0, low numbered
451 edges are put on the spanning tree in preference to high numbered edges.
452 Hence, most instrumented edges are at the end. Graph solving works much
453 faster if we propagate numbers from the end to the start.
455 This takes an average of slightly more than 3 passes. */
457 changes = 1;
458 passes = 0;
459 while (changes)
461 passes++;
462 changes = 0;
463 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
465 struct bb_info *bi = BB_INFO (bb);
466 if (! bi->count_valid)
468 if (bi->succ_count == 0)
470 edge e;
471 gcov_type total = 0;
473 for (e = bb->succ; e; e = e->succ_next)
474 total += e->count;
475 bb->count = total;
476 bi->count_valid = 1;
477 changes = 1;
479 else if (bi->pred_count == 0)
481 edge e;
482 gcov_type total = 0;
484 for (e = bb->pred; e; e = e->pred_next)
485 total += e->count;
486 bb->count = total;
487 bi->count_valid = 1;
488 changes = 1;
491 if (bi->count_valid)
493 if (bi->succ_count == 1)
495 edge e;
496 gcov_type total = 0;
498 /* One of the counts will be invalid, but it is zero,
499 so adding it in also doesn't hurt. */
500 for (e = bb->succ; e; e = e->succ_next)
501 total += e->count;
503 /* Seedgeh for the invalid edge, and set its count. */
504 for (e = bb->succ; e; e = e->succ_next)
505 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
506 break;
508 /* Calculate count for remaining edge by conservation. */
509 total = bb->count - total;
511 if (! e)
512 abort ();
513 EDGE_INFO (e)->count_valid = 1;
514 e->count = total;
515 bi->succ_count--;
517 BB_INFO (e->dest)->pred_count--;
518 changes = 1;
520 if (bi->pred_count == 1)
522 edge e;
523 gcov_type total = 0;
525 /* One of the counts will be invalid, but it is zero,
526 so adding it in also doesn't hurt. */
527 for (e = bb->pred; e; e = e->pred_next)
528 total += e->count;
530 /* Seedgeh for the invalid edge, and set its count. */
531 for (e = bb->pred; e; e = e->pred_next)
532 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
533 break;
535 /* Calculate count for remaining edge by conservation. */
536 total = bb->count - total + e->count;
538 if (! e)
539 abort ();
540 EDGE_INFO (e)->count_valid = 1;
541 e->count = total;
542 bi->pred_count--;
544 BB_INFO (e->src)->succ_count--;
545 changes = 1;
550 if (rtl_dump_file)
551 dump_flow_info (rtl_dump_file);
553 total_num_passes += passes;
554 if (rtl_dump_file)
555 fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
557 /* If the graph has been correctly solved, every block will have a
558 succ and pred count of zero. */
559 FOR_ALL_BB (bb)
561 if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
562 abort ();
565 /* For every edge, calculate its branch probability and add a reg_note
566 to the branch insn to indicate this. */
568 for (i = 0; i < 20; i++)
569 hist_br_prob[i] = 0;
570 num_never_executed = 0;
571 num_branches = 0;
573 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
575 edge e;
576 gcov_type total;
577 rtx note;
579 total = bb->count;
580 if (total)
582 for (e = bb->succ; e; e = e->succ_next)
584 e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
585 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
587 error ("corrupted profile info: prob for %d-%d thought to be %d",
588 e->src->sindex, e->dest->sindex, e->probability);
589 e->probability = REG_BR_PROB_BASE / 2;
592 if (bb->sindex >= 0
593 && any_condjump_p (bb->end)
594 && bb->succ->succ_next)
596 int prob;
597 edge e;
598 int index;
600 /* Find the branch edge. It is possible that we do have fake
601 edges here. */
602 for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
603 e = e->succ_next)
604 continue; /* Loop body has been intentionally left blank. */
606 prob = e->probability;
607 index = prob * 20 / REG_BR_PROB_BASE;
609 if (index == 20)
610 index = 19;
611 hist_br_prob[index]++;
613 note = find_reg_note (bb->end, REG_BR_PROB, 0);
614 /* There may be already note put by some other pass, such
615 as builtin_expect expander. */
616 if (note)
617 XEXP (note, 0) = GEN_INT (prob);
618 else
619 REG_NOTES (bb->end)
620 = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
621 REG_NOTES (bb->end));
622 num_branches++;
625 /* Otherwise distribute the probabilities evenly so we get sane sum.
626 Use simple heuristics that if there are normal edges, give all abnormals
627 frequency of 0, otherwise distribute the frequency over abnormals
628 (this is the case of noreturn calls). */
629 else
631 for (e = bb->succ; e; e = e->succ_next)
632 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
633 total ++;
634 if (total)
636 for (e = bb->succ; e; e = e->succ_next)
637 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
638 e->probability = REG_BR_PROB_BASE / total;
639 else
640 e->probability = 0;
642 else
644 for (e = bb->succ; e; e = e->succ_next)
645 total ++;
646 for (e = bb->succ; e; e = e->succ_next)
647 e->probability = REG_BR_PROB_BASE / total;
649 if (bb->sindex >= 0
650 && any_condjump_p (bb->end)
651 && bb->succ->succ_next)
652 num_branches++, num_never_executed;
656 if (rtl_dump_file)
658 fprintf (rtl_dump_file, "%d branches\n", num_branches);
659 fprintf (rtl_dump_file, "%d branches never executed\n",
660 num_never_executed);
661 if (num_branches)
662 for (i = 0; i < 10; i++)
663 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
664 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
665 5 * i, 5 * i + 5);
667 total_num_branches += num_branches;
668 total_num_never_executed += num_never_executed;
669 for (i = 0; i < 20; i++)
670 total_hist_br_prob[i] += hist_br_prob[i];
672 fputc ('\n', rtl_dump_file);
673 fputc ('\n', rtl_dump_file);
676 free_aux_for_blocks ();
677 if (exec_counts)
678 free (exec_counts);
681 /* Compute checksum for the current function. */
683 #define CHSUM_HASH 500000003
684 #define CHSUM_SHIFT 2
686 static long
687 compute_checksum ()
689 long chsum = 0;
690 basic_block bb;
692 FOR_ALL_BB (bb)
694 edge e;
696 for (e = bb->succ; e; e = e->succ_next)
698 chsum = ((chsum << CHSUM_SHIFT) + (BB_TO_GCOV_INDEX (e->dest) + 1)) % CHSUM_HASH;
701 chsum = (chsum << CHSUM_SHIFT) % CHSUM_HASH;
704 return chsum;
707 /* Instrument and/or analyze program behavior based on program flow graph.
708 In either case, this function builds a flow graph for the function being
709 compiled. The flow graph is stored in BB_GRAPH.
711 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
712 the flow graph that are needed to reconstruct the dynamic behavior of the
713 flow graph.
715 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
716 information from a data file containing edge count information from previous
717 executions of the function being compiled. In this case, the flow graph is
718 annotated with actual execution counts, which are later propagated into the
719 rtl for optimization purposes.
721 Main entry point of this file. */
723 void
724 branch_prob ()
726 basic_block bb;
727 int i;
728 int num_edges, ignored_edges;
729 struct edge_list *el;
731 profile_info.current_function_cfg_checksum = compute_checksum ();
733 if (rtl_dump_file)
734 fprintf (rtl_dump_file, "CFG checksum is %ld\n",
735 profile_info.current_function_cfg_checksum);
737 /* Start of a function. */
738 if (flag_test_coverage)
739 output_gcov_string (current_function_name, (long) -2);
741 total_num_times_called++;
743 flow_call_edges_add (NULL);
744 add_noreturn_fake_exit_edges ();
746 /* We can't handle cyclic regions constructed using abnormal edges.
747 To avoid these we replace every source of abnormal edge by a fake
748 edge from entry node and every destination by fake edge to exit.
749 This keeps graph acyclic and our calculation exact for all normal
750 edges except for exit and entrance ones.
752 We also add fake exit edges for each call and asm statement in the
753 basic, since it may not return. */
755 FOR_ALL_BB (bb)
757 int need_exit_edge = 0, need_entry_edge = 0;
758 int have_exit_edge = 0, have_entry_edge = 0;
759 rtx insn;
760 edge e;
762 /* Add fake edges from entry block to the call insns that may return
763 twice. The CFG is not quite correct then, as call insn plays more
764 role of CODE_LABEL, but for our purposes, everything should be OK,
765 as we never insert code to the beggining of basic block. */
766 for (insn = bb->head; insn != NEXT_INSN (bb->end);
767 insn = NEXT_INSN (insn))
769 if (GET_CODE (insn) == CALL_INSN
770 && find_reg_note (insn, REG_SETJMP, NULL))
772 if (GET_CODE (bb->head) == CODE_LABEL
773 || insn != NEXT_INSN (bb->head))
775 e = split_block (bb, PREV_INSN (insn));
776 make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
777 break;
779 else
781 /* We should not get abort here, as call to setjmp should not
782 be the very first instruction of function. */
783 if (bb == ENTRY_BLOCK_PTR)
784 abort ();
785 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
790 for (e = bb->succ; e; e = e->succ_next)
792 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
793 && e->dest != EXIT_BLOCK_PTR)
794 need_exit_edge = 1;
795 if (e->dest == EXIT_BLOCK_PTR)
796 have_exit_edge = 1;
798 for (e = bb->pred; e; e = e->pred_next)
800 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
801 && e->src != ENTRY_BLOCK_PTR)
802 need_entry_edge = 1;
803 if (e->src == ENTRY_BLOCK_PTR)
804 have_entry_edge = 1;
807 if (need_exit_edge && !have_exit_edge)
809 if (rtl_dump_file)
810 fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
811 bb->sindex);
812 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
814 if (need_entry_edge && !have_entry_edge)
816 if (rtl_dump_file)
817 fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
818 bb->sindex);
819 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
823 el = create_edge_list ();
824 num_edges = NUM_EDGES (el);
825 alloc_aux_for_edges (sizeof (struct edge_info));
827 ignored_edges = 0;
828 for (i = 0 ; i < num_edges ; i++)
830 edge e = INDEX_EDGE (el, i);
831 e->count = 0;
833 /* Mark edges we've replaced by fake edges above as ignored. */
834 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
835 && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
837 EDGE_INFO (e)->ignore = 1;
838 ignored_edges++;
842 #ifdef ENABLE_CHECKING
843 verify_flow_info ();
844 #endif
846 /* Output line number information about each basic block for
847 GCOV utility. */
848 if (flag_test_coverage)
850 basic_block bb;
852 FOR_ALL_BB (bb)
854 rtx insn = bb->head;
855 static int ignore_next_note = 0;
857 /* We are looking for line number notes. Search backward before
858 basic block to find correct ones. */
859 insn = prev_nonnote_insn (insn);
860 if (!insn)
861 insn = get_insns ();
862 else
863 insn = NEXT_INSN (insn);
865 /* Output a zero to the .bb file to indicate that a new
866 block list is starting. */
867 __write_long (0, bb_file, 4);
869 while (insn != bb->end)
871 if (GET_CODE (insn) == NOTE)
873 /* Must ignore the line number notes that immediately
874 follow the end of an inline function to avoid counting
875 it twice. There is a note before the call, and one
876 after the call. */
877 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_REPEATED_LINE_NUMBER)
878 ignore_next_note = 1;
879 else if (NOTE_LINE_NUMBER (insn) > 0)
881 if (ignore_next_note)
882 ignore_next_note = 0;
883 else
885 /* If this is a new source file, then output the
886 file's name to the .bb file. */
887 if (! last_bb_file_name
888 || strcmp (NOTE_SOURCE_FILE (insn),
889 last_bb_file_name))
891 if (last_bb_file_name)
892 free (last_bb_file_name);
893 last_bb_file_name
894 = xstrdup (NOTE_SOURCE_FILE (insn));
895 output_gcov_string (NOTE_SOURCE_FILE (insn),
896 (long)-1);
898 /* Output the line number to the .bb file. Must be
899 done after the output_bb_profile_data() call, and
900 after the file name is written, to ensure that it
901 is correctly handled by gcov. */
902 __write_long (NOTE_LINE_NUMBER (insn), bb_file, 4);
906 insn = NEXT_INSN (insn);
909 __write_long (0, bb_file, 4);
912 /* Create spanning tree from basic block graph, mark each edge that is
913 on the spanning tree. We insert as many abnormal and critical edges
914 as possible to minimize number of edge splits necessary. */
916 find_spanning_tree (el);
918 /* Fake edges that are not on the tree will not be instrumented, so
919 mark them ignored. */
920 for (i = 0; i < num_edges; i++)
922 edge e = INDEX_EDGE (el, i);
923 struct edge_info *inf = EDGE_INFO (e);
924 if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
926 inf->ignore = 1;
927 ignored_edges++;
931 total_num_blocks += num_basic_blocks + 2;
932 if (rtl_dump_file)
933 fprintf (rtl_dump_file, "%d basic blocks\n", num_basic_blocks);
935 total_num_edges += num_edges;
936 if (rtl_dump_file)
937 fprintf (rtl_dump_file, "%d edges\n", num_edges);
939 total_num_edges_ignored += ignored_edges;
940 if (rtl_dump_file)
941 fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
943 /* Create a .bbg file from which gcov can reconstruct the basic block
944 graph. First output the number of basic blocks, and then for every
945 edge output the source and target basic block numbers.
946 NOTE: The format of this file must be compatible with gcov. */
948 if (flag_test_coverage)
950 int flag_bits;
952 __write_gcov_string (current_function_name,
953 strlen (current_function_name), bbg_file, -1);
955 /* write checksum. */
956 __write_long (profile_info.current_function_cfg_checksum, bbg_file, 4);
958 /* The plus 2 stands for entry and exit block. */
959 __write_long (num_basic_blocks + 2, bbg_file, 4);
960 __write_long (num_edges - ignored_edges + 1, bbg_file, 4);
962 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
964 edge e;
965 long count = 0;
967 for (e = bb->succ; e; e = e->succ_next)
968 if (!EDGE_INFO (e)->ignore)
969 count++;
970 __write_long (count, bbg_file, 4);
972 for (e = bb->succ; e; e = e->succ_next)
974 struct edge_info *i = EDGE_INFO (e);
975 if (!i->ignore)
977 flag_bits = 0;
978 if (i->on_tree)
979 flag_bits |= 0x1;
980 if (e->flags & EDGE_FAKE)
981 flag_bits |= 0x2;
982 if (e->flags & EDGE_FALLTHRU)
983 flag_bits |= 0x4;
985 __write_long (BB_TO_GCOV_INDEX (e->dest), bbg_file, 4);
986 __write_long (flag_bits, bbg_file, 4);
990 /* Emit fake loopback edge for EXIT block to maintain compatibility with
991 old gcov format. */
992 __write_long (1, bbg_file, 4);
993 __write_long (0, bbg_file, 4);
994 __write_long (0x1, bbg_file, 4);
996 /* Emit a -1 to separate the list of all edges from the list of
997 loop back edges that follows. */
998 __write_long (-1, bbg_file, 4);
1001 if (flag_branch_probabilities)
1002 compute_branch_probabilities ();
1004 /* For each edge not on the spanning tree, add counting code as rtl. */
1006 if (profile_arc_flag)
1008 instrument_edges (el);
1009 allocate_reg_info (max_reg_num (), FALSE, FALSE);
1012 remove_fake_edges ();
1013 /* Re-merge split basic blocks and the mess introduced by
1014 insert_insn_on_edge. */
1015 cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
1016 if (rtl_dump_file)
1017 dump_flow_info (rtl_dump_file);
1019 free_aux_for_edges ();
1020 free_edge_list (el);
1023 /* Union find algorithm implementation for the basic blocks using
1024 aux fields. */
1026 static basic_block
1027 find_group (bb)
1028 basic_block bb;
1030 basic_block group = bb, bb1;
1032 while ((basic_block) group->aux != group)
1033 group = (basic_block) group->aux;
1035 /* Compress path. */
1036 while ((basic_block) bb->aux != group)
1038 bb1 = (basic_block) bb->aux;
1039 bb->aux = (void *) group;
1040 bb = bb1;
1042 return group;
1045 static void
1046 union_groups (bb1, bb2)
1047 basic_block bb1, bb2;
1049 basic_block bb1g = find_group (bb1);
1050 basic_block bb2g = find_group (bb2);
1052 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
1053 this code is unlikely going to be performance problem anyway. */
1054 if (bb1g == bb2g)
1055 abort ();
1057 bb1g->aux = bb2g;
1060 /* This function searches all of the edges in the program flow graph, and puts
1061 as many bad edges as possible onto the spanning tree. Bad edges include
1062 abnormals edges, which can't be instrumented at the moment. Since it is
1063 possible for fake edges to form an cycle, we will have to develop some
1064 better way in the future. Also put critical edges to the tree, since they
1065 are more expensive to instrument. */
1067 static void
1068 find_spanning_tree (el)
1069 struct edge_list *el;
1071 int i;
1072 basic_block bb;
1073 int num_edges = NUM_EDGES (el);
1075 /* We use aux field for standard union-find algorithm. */
1076 EXIT_BLOCK_PTR->aux = EXIT_BLOCK_PTR;
1077 ENTRY_BLOCK_PTR->aux = ENTRY_BLOCK_PTR;
1078 FOR_ALL_BB (bb)
1079 bb->aux = bb;
1081 /* Add fake edge exit to entry we can't instrument. */
1082 union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
1084 /* First add all abnormal edges to the tree unless they form an cycle. Also
1085 add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1086 setting return value from function. */
1087 for (i = 0; i < num_edges; i++)
1089 edge e = INDEX_EDGE (el, i);
1090 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1091 || e->dest == EXIT_BLOCK_PTR
1093 && !EDGE_INFO (e)->ignore
1094 && (find_group (e->src) != find_group (e->dest)))
1096 if (rtl_dump_file)
1097 fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
1098 e->src->sindex, e->dest->sindex);
1099 EDGE_INFO (e)->on_tree = 1;
1100 union_groups (e->src, e->dest);
1104 /* Now insert all critical edges to the tree unless they form an cycle. */
1105 for (i = 0; i < num_edges; i++)
1107 edge e = INDEX_EDGE (el, i);
1108 if ((EDGE_CRITICAL_P (e))
1109 && !EDGE_INFO (e)->ignore
1110 && (find_group (e->src) != find_group (e->dest)))
1112 if (rtl_dump_file)
1113 fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1114 e->src->sindex, e->dest->sindex);
1115 EDGE_INFO (e)->on_tree = 1;
1116 union_groups (e->src, e->dest);
1120 /* And now the rest. */
1121 for (i = 0; i < num_edges; i++)
1123 edge e = INDEX_EDGE (el, i);
1124 if (find_group (e->src) != find_group (e->dest)
1125 && !EDGE_INFO (e)->ignore)
1127 if (rtl_dump_file)
1128 fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1129 e->src->sindex, e->dest->sindex);
1130 EDGE_INFO (e)->on_tree = 1;
1131 union_groups (e->src, e->dest);
1135 EXIT_BLOCK_PTR->aux = NULL;
1136 ENTRY_BLOCK_PTR->aux = NULL;
1137 FOR_ALL_BB (bb)
1138 bb->aux = NULL;
1141 /* Perform file-level initialization for branch-prob processing. */
1143 void
1144 init_branch_prob (filename)
1145 const char *filename;
1147 long len;
1148 int i;
1150 if (flag_test_coverage)
1152 int len = strlen (filename);
1153 char *data_file, *bbg_file_name;
1155 /* Open an output file for the basic block/line number map. */
1156 data_file = (char *) alloca (len + 4);
1157 strcpy (data_file, filename);
1158 strip_off_ending (data_file, len);
1159 strcat (data_file, ".bb");
1160 if ((bb_file = fopen (data_file, "wb")) == 0)
1161 fatal_io_error ("can't open %s", data_file);
1163 /* Open an output file for the program flow graph. */
1164 bbg_file_name = (char *) alloca (len + 5);
1165 strcpy (bbg_file_name, filename);
1166 strip_off_ending (bbg_file_name, len);
1167 strcat (bbg_file_name, ".bbg");
1168 if ((bbg_file = fopen (bbg_file_name, "wb")) == 0)
1169 fatal_io_error ("can't open %s", bbg_file_name);
1171 /* Initialize to zero, to ensure that the first file name will be
1172 written to the .bb file. */
1173 last_bb_file_name = 0;
1176 if (flag_branch_probabilities)
1178 char *da_file_name;
1180 len = strlen (filename);
1181 da_file_name = (char *) alloca (len + 4);
1182 strcpy (da_file_name, filename);
1183 strip_off_ending (da_file_name, len);
1184 strcat (da_file_name, ".da");
1185 if ((da_file = fopen (da_file_name, "rb")) == 0)
1186 warning ("file %s not found, execution counts assumed to be zero",
1187 da_file_name);
1190 if (profile_arc_flag)
1191 init_edge_profiler ();
1193 total_num_blocks = 0;
1194 total_num_edges = 0;
1195 total_num_edges_ignored = 0;
1196 total_num_edges_instrumented = 0;
1197 total_num_blocks_created = 0;
1198 total_num_passes = 0;
1199 total_num_times_called = 0;
1200 total_num_branches = 0;
1201 total_num_never_executed = 0;
1202 for (i = 0; i < 20; i++)
1203 total_hist_br_prob[i] = 0;
1206 /* Performs file-level cleanup after branch-prob processing
1207 is completed. */
1209 void
1210 end_branch_prob ()
1212 if (flag_test_coverage)
1214 fclose (bb_file);
1215 fclose (bbg_file);
1218 if (flag_branch_probabilities && da_file)
1219 fclose (da_file);
1221 if (rtl_dump_file)
1223 fprintf (rtl_dump_file, "\n");
1224 fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1225 total_num_blocks);
1226 fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1227 fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1228 total_num_edges_ignored);
1229 fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1230 total_num_edges_instrumented);
1231 fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1232 total_num_blocks_created);
1233 fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1234 total_num_passes);
1235 if (total_num_times_called != 0)
1236 fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1237 (total_num_passes + (total_num_times_called >> 1))
1238 / total_num_times_called);
1239 fprintf (rtl_dump_file, "Total number of branches: %d\n",
1240 total_num_branches);
1241 fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1242 total_num_never_executed);
1243 if (total_num_branches)
1245 int i;
1247 for (i = 0; i < 10; i++)
1248 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1249 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1250 / total_num_branches, 5*i, 5*i+5);
1255 /* The label used by the edge profiling code. */
1257 static rtx profiler_label;
1259 /* Initialize the profiler_label. */
1261 static void
1262 init_edge_profiler ()
1264 /* Generate and save a copy of this so it can be shared. */
1265 char buf[20];
1266 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1267 profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1268 ggc_add_rtx_root (&profiler_label, 1);
1271 /* Output instructions as RTL to increment the edge execution count. */
1273 static rtx
1274 gen_edge_profiler (edgeno)
1275 int edgeno;
1277 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1278 rtx mem_ref, tmp;
1279 rtx sequence;
1281 start_sequence ();
1283 tmp = force_reg (Pmode, profiler_label);
1284 tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
1285 mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
1287 tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
1288 mem_ref, 0, OPTAB_WIDEN);
1290 set_mem_alias_set (mem_ref, new_alias_set ());
1292 if (tmp != mem_ref)
1293 emit_move_insn (copy_rtx (mem_ref), tmp);
1295 sequence = gen_sequence ();
1296 end_sequence ();
1297 return sequence;
1300 /* Output code for a constructor that will invoke __bb_init_func, if
1301 this has not already been done. */
1303 void
1304 output_func_start_profiler ()
1306 tree fnname, fndecl;
1307 char *name;
1308 char buf[20];
1309 const char *cfnname;
1310 rtx table_address;
1311 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1312 int save_flag_inline_functions = flag_inline_functions;
1314 /* It's either already been output, or we don't need it because we're
1315 not doing profile-edges. */
1316 if (! need_func_profiler)
1317 return;
1319 need_func_profiler = 0;
1321 /* Synthesize a constructor function to invoke __bb_init_func with a
1322 pointer to this object file's profile block. */
1324 /* Try and make a unique name given the "file function name".
1326 And no, I don't like this either. */
1328 fnname = get_file_function_name ('I');
1329 cfnname = IDENTIFIER_POINTER (fnname);
1330 name = concat (cfnname, "GCOV", NULL);
1331 fnname = get_identifier (name);
1332 free (name);
1334 fndecl = build_decl (FUNCTION_DECL, fnname,
1335 build_function_type (void_type_node, NULL_TREE));
1336 DECL_EXTERNAL (fndecl) = 0;
1338 /* It can be a static function as long as collect2 does not have
1339 to scan the object file to find its ctor/dtor routine. */
1340 TREE_PUBLIC (fndecl) = ! targetm.have_ctors_dtors;
1342 TREE_USED (fndecl) = 1;
1344 DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1346 fndecl = (*lang_hooks.decls.pushdecl) (fndecl);
1347 rest_of_decl_compilation (fndecl, 0, 1, 0);
1348 announce_function (fndecl);
1349 current_function_decl = fndecl;
1350 DECL_INITIAL (fndecl) = error_mark_node;
1351 make_decl_rtl (fndecl, NULL);
1352 init_function_start (fndecl, input_filename, lineno);
1353 (*lang_hooks.decls.pushlevel) (0);
1354 expand_function_start (fndecl, 0);
1355 cfun->arc_profile = 0;
1357 /* Actually generate the code to call __bb_init_func. */
1358 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 0);
1359 table_address = force_reg (Pmode,
1360 gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
1361 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__bb_init_func"), LCT_NORMAL,
1362 mode, 1, table_address, Pmode);
1364 expand_function_end (input_filename, lineno, 0);
1365 (*lang_hooks.decls.poplevel) (1, 0, 1);
1367 /* Since fndecl isn't in the list of globals, it would never be emitted
1368 when it's considered to be 'safe' for inlining, so turn off
1369 flag_inline_functions. */
1370 flag_inline_functions = 0;
1372 rest_of_compilation (fndecl);
1374 /* Reset flag_inline_functions to its original value. */
1375 flag_inline_functions = save_flag_inline_functions;
1377 if (! quiet_flag)
1378 fflush (asm_out_file);
1379 current_function_decl = NULL_TREE;
1381 if (targetm.have_ctors_dtors)
1382 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
1383 DEFAULT_INIT_PRIORITY);