2002-06-13 Akim Demaille <akim@epita.fr>
[official-gcc.git] / gcc / profile.c
blobc5b903f04614a7ac7d4370cef8f5da3c8c17580d
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)->index + 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->index, e->dest->index,
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, i;
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 (i = 0; i < num_edges; i++)
251 profile[i] = 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;
364 if (rtl_dump_file)
366 fprintf(rtl_dump_file, "Merged %i profiles with maximal count %i.\n",
367 profile_info.count_profiles_merged,
368 (int)profile_info.max_counter_in_program);
371 return profile;
375 /* Compute the branch probabilities for the various branches.
376 Annotate them accordingly. */
378 static void
379 compute_branch_probabilities ()
381 basic_block bb;
382 int i;
383 int num_edges = 0;
384 int changes;
385 int passes;
386 int hist_br_prob[20];
387 int num_never_executed;
388 int num_branches;
389 gcov_type *exec_counts = get_exec_counts ();
390 int exec_counts_pos = 0;
392 /* Attach extra info block to each bb. */
394 alloc_aux_for_blocks (sizeof (struct bb_info));
395 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
397 edge e;
399 for (e = bb->succ; e; e = e->succ_next)
400 if (!EDGE_INFO (e)->ignore)
401 BB_INFO (bb)->succ_count++;
402 for (e = bb->pred; e; e = e->pred_next)
403 if (!EDGE_INFO (e)->ignore)
404 BB_INFO (bb)->pred_count++;
407 /* Avoid predicting entry on exit nodes. */
408 BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
409 BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
411 /* For each edge not on the spanning tree, set its execution count from
412 the .da file. */
414 /* The first count in the .da file is the number of times that the function
415 was entered. This is the exec_count for block zero. */
417 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
419 edge e;
420 for (e = bb->succ; e; e = e->succ_next)
421 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
423 num_edges++;
424 if (exec_counts)
426 e->count = exec_counts[exec_counts_pos++];
428 else
429 e->count = 0;
431 EDGE_INFO (e)->count_valid = 1;
432 BB_INFO (bb)->succ_count--;
433 BB_INFO (e->dest)->pred_count--;
434 if (rtl_dump_file)
436 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
437 bb->index, e->dest->index);
438 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
439 (HOST_WIDEST_INT) e->count);
444 if (rtl_dump_file)
445 fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
447 /* For every block in the file,
448 - if every exit/entrance edge has a known count, then set the block count
449 - if the block count is known, and every exit/entrance edge but one has
450 a known execution count, then set the count of the remaining edge
452 As edge counts are set, decrement the succ/pred count, but don't delete
453 the edge, that way we can easily tell when all edges are known, or only
454 one edge is unknown. */
456 /* The order that the basic blocks are iterated through is important.
457 Since the code that finds spanning trees starts with block 0, low numbered
458 edges are put on the spanning tree in preference to high numbered edges.
459 Hence, most instrumented edges are at the end. Graph solving works much
460 faster if we propagate numbers from the end to the start.
462 This takes an average of slightly more than 3 passes. */
464 changes = 1;
465 passes = 0;
466 while (changes)
468 passes++;
469 changes = 0;
470 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
472 struct bb_info *bi = BB_INFO (bb);
473 if (! bi->count_valid)
475 if (bi->succ_count == 0)
477 edge e;
478 gcov_type total = 0;
480 for (e = bb->succ; e; e = e->succ_next)
481 total += e->count;
482 bb->count = total;
483 bi->count_valid = 1;
484 changes = 1;
486 else if (bi->pred_count == 0)
488 edge e;
489 gcov_type total = 0;
491 for (e = bb->pred; e; e = e->pred_next)
492 total += e->count;
493 bb->count = total;
494 bi->count_valid = 1;
495 changes = 1;
498 if (bi->count_valid)
500 if (bi->succ_count == 1)
502 edge e;
503 gcov_type total = 0;
505 /* One of the counts will be invalid, but it is zero,
506 so adding it in also doesn't hurt. */
507 for (e = bb->succ; e; e = e->succ_next)
508 total += e->count;
510 /* Seedgeh for the invalid edge, and set its count. */
511 for (e = bb->succ; e; e = e->succ_next)
512 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
513 break;
515 /* Calculate count for remaining edge by conservation. */
516 total = bb->count - total;
518 if (! e)
519 abort ();
520 EDGE_INFO (e)->count_valid = 1;
521 e->count = total;
522 bi->succ_count--;
524 BB_INFO (e->dest)->pred_count--;
525 changes = 1;
527 if (bi->pred_count == 1)
529 edge e;
530 gcov_type total = 0;
532 /* One of the counts will be invalid, but it is zero,
533 so adding it in also doesn't hurt. */
534 for (e = bb->pred; e; e = e->pred_next)
535 total += e->count;
537 /* Seedgeh for the invalid edge, and set its count. */
538 for (e = bb->pred; e; e = e->pred_next)
539 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
540 break;
542 /* Calculate count for remaining edge by conservation. */
543 total = bb->count - total + e->count;
545 if (! e)
546 abort ();
547 EDGE_INFO (e)->count_valid = 1;
548 e->count = total;
549 bi->pred_count--;
551 BB_INFO (e->src)->succ_count--;
552 changes = 1;
557 if (rtl_dump_file)
558 dump_flow_info (rtl_dump_file);
560 total_num_passes += passes;
561 if (rtl_dump_file)
562 fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
564 /* If the graph has been correctly solved, every block will have a
565 succ and pred count of zero. */
566 FOR_EACH_BB (bb)
568 if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
569 abort ();
572 /* For every edge, calculate its branch probability and add a reg_note
573 to the branch insn to indicate this. */
575 for (i = 0; i < 20; i++)
576 hist_br_prob[i] = 0;
577 num_never_executed = 0;
578 num_branches = 0;
580 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
582 edge e;
583 gcov_type total;
584 rtx note;
586 total = bb->count;
587 if (total)
589 for (e = bb->succ; e; e = e->succ_next)
591 e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
592 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
594 error ("corrupted profile info: prob for %d-%d thought to be %d",
595 e->src->index, e->dest->index, e->probability);
596 e->probability = REG_BR_PROB_BASE / 2;
599 if (bb->index >= 0
600 && any_condjump_p (bb->end)
601 && bb->succ->succ_next)
603 int prob;
604 edge e;
605 int index;
607 /* Find the branch edge. It is possible that we do have fake
608 edges here. */
609 for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
610 e = e->succ_next)
611 continue; /* Loop body has been intentionally left blank. */
613 prob = e->probability;
614 index = prob * 20 / REG_BR_PROB_BASE;
616 if (index == 20)
617 index = 19;
618 hist_br_prob[index]++;
620 note = find_reg_note (bb->end, REG_BR_PROB, 0);
621 /* There may be already note put by some other pass, such
622 as builtin_expect expander. */
623 if (note)
624 XEXP (note, 0) = GEN_INT (prob);
625 else
626 REG_NOTES (bb->end)
627 = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
628 REG_NOTES (bb->end));
629 num_branches++;
632 /* Otherwise distribute the probabilities evenly so we get sane sum.
633 Use simple heuristics that if there are normal edges, give all abnormals
634 frequency of 0, otherwise distribute the frequency over abnormals
635 (this is the case of noreturn calls). */
636 else
638 for (e = bb->succ; e; e = e->succ_next)
639 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
640 total ++;
641 if (total)
643 for (e = bb->succ; e; e = e->succ_next)
644 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
645 e->probability = REG_BR_PROB_BASE / total;
646 else
647 e->probability = 0;
649 else
651 for (e = bb->succ; e; e = e->succ_next)
652 total ++;
653 for (e = bb->succ; e; e = e->succ_next)
654 e->probability = REG_BR_PROB_BASE / total;
656 if (bb->index >= 0
657 && any_condjump_p (bb->end)
658 && bb->succ->succ_next)
659 num_branches++, num_never_executed;
663 if (rtl_dump_file)
665 fprintf (rtl_dump_file, "%d branches\n", num_branches);
666 fprintf (rtl_dump_file, "%d branches never executed\n",
667 num_never_executed);
668 if (num_branches)
669 for (i = 0; i < 10; i++)
670 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
671 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
672 5 * i, 5 * i + 5);
674 total_num_branches += num_branches;
675 total_num_never_executed += num_never_executed;
676 for (i = 0; i < 20; i++)
677 total_hist_br_prob[i] += hist_br_prob[i];
679 fputc ('\n', rtl_dump_file);
680 fputc ('\n', rtl_dump_file);
683 free_aux_for_blocks ();
684 if (exec_counts)
685 free (exec_counts);
688 /* Compute checksum for the current function. */
690 #define CHSUM_HASH 500000003
691 #define CHSUM_SHIFT 2
693 static long
694 compute_checksum ()
696 long chsum = 0;
697 basic_block bb;
699 FOR_EACH_BB (bb)
701 edge e;
703 for (e = bb->succ; e; e = e->succ_next)
705 chsum = ((chsum << CHSUM_SHIFT) + (BB_TO_GCOV_INDEX (e->dest) + 1)) % CHSUM_HASH;
708 chsum = (chsum << CHSUM_SHIFT) % CHSUM_HASH;
711 return chsum;
714 /* Instrument and/or analyze program behavior based on program flow graph.
715 In either case, this function builds a flow graph for the function being
716 compiled. The flow graph is stored in BB_GRAPH.
718 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
719 the flow graph that are needed to reconstruct the dynamic behavior of the
720 flow graph.
722 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
723 information from a data file containing edge count information from previous
724 executions of the function being compiled. In this case, the flow graph is
725 annotated with actual execution counts, which are later propagated into the
726 rtl for optimization purposes.
728 Main entry point of this file. */
730 void
731 branch_prob ()
733 basic_block bb;
734 int i;
735 int num_edges, ignored_edges;
736 struct edge_list *el;
738 profile_info.current_function_cfg_checksum = compute_checksum ();
740 if (rtl_dump_file)
741 fprintf (rtl_dump_file, "CFG checksum is %ld\n",
742 profile_info.current_function_cfg_checksum);
744 /* Start of a function. */
745 if (flag_test_coverage)
746 output_gcov_string (current_function_name, (long) -2);
748 total_num_times_called++;
750 flow_call_edges_add (NULL);
751 add_noreturn_fake_exit_edges ();
753 /* We can't handle cyclic regions constructed using abnormal edges.
754 To avoid these we replace every source of abnormal edge by a fake
755 edge from entry node and every destination by fake edge to exit.
756 This keeps graph acyclic and our calculation exact for all normal
757 edges except for exit and entrance ones.
759 We also add fake exit edges for each call and asm statement in the
760 basic, since it may not return. */
762 FOR_EACH_BB (bb)
764 int need_exit_edge = 0, need_entry_edge = 0;
765 int have_exit_edge = 0, have_entry_edge = 0;
766 rtx insn;
767 edge e;
769 /* Add fake edges from entry block to the call insns that may return
770 twice. The CFG is not quite correct then, as call insn plays more
771 role of CODE_LABEL, but for our purposes, everything should be OK,
772 as we never insert code to the beggining of basic block. */
773 for (insn = bb->head; insn != NEXT_INSN (bb->end);
774 insn = NEXT_INSN (insn))
776 if (GET_CODE (insn) == CALL_INSN
777 && find_reg_note (insn, REG_SETJMP, NULL))
779 if (GET_CODE (bb->head) == CODE_LABEL
780 || insn != NEXT_INSN (bb->head))
782 e = split_block (bb, PREV_INSN (insn));
783 make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
784 break;
786 else
788 /* We should not get abort here, as call to setjmp should not
789 be the very first instruction of function. */
790 if (bb == ENTRY_BLOCK_PTR)
791 abort ();
792 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
797 for (e = bb->succ; e; e = e->succ_next)
799 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
800 && e->dest != EXIT_BLOCK_PTR)
801 need_exit_edge = 1;
802 if (e->dest == EXIT_BLOCK_PTR)
803 have_exit_edge = 1;
805 for (e = bb->pred; e; e = e->pred_next)
807 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
808 && e->src != ENTRY_BLOCK_PTR)
809 need_entry_edge = 1;
810 if (e->src == ENTRY_BLOCK_PTR)
811 have_entry_edge = 1;
814 if (need_exit_edge && !have_exit_edge)
816 if (rtl_dump_file)
817 fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
818 bb->index);
819 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
821 if (need_entry_edge && !have_entry_edge)
823 if (rtl_dump_file)
824 fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
825 bb->index);
826 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
830 el = create_edge_list ();
831 num_edges = NUM_EDGES (el);
832 alloc_aux_for_edges (sizeof (struct edge_info));
834 /* The basic blocks are expected to be numbered sequentially. */
835 compact_blocks ();
837 ignored_edges = 0;
838 for (i = 0 ; i < num_edges ; i++)
840 edge e = INDEX_EDGE (el, i);
841 e->count = 0;
843 /* Mark edges we've replaced by fake edges above as ignored. */
844 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
845 && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
847 EDGE_INFO (e)->ignore = 1;
848 ignored_edges++;
852 #ifdef ENABLE_CHECKING
853 verify_flow_info ();
854 #endif
856 /* Output line number information about each basic block for
857 GCOV utility. */
858 if (flag_test_coverage)
860 FOR_EACH_BB (bb)
862 rtx insn = bb->head;
863 static int ignore_next_note = 0;
865 /* We are looking for line number notes. Search backward before
866 basic block to find correct ones. */
867 insn = prev_nonnote_insn (insn);
868 if (!insn)
869 insn = get_insns ();
870 else
871 insn = NEXT_INSN (insn);
873 /* Output a zero to the .bb file to indicate that a new
874 block list is starting. */
875 __write_long (0, bb_file, 4);
877 while (insn != bb->end)
879 if (GET_CODE (insn) == NOTE)
881 /* Must ignore the line number notes that immediately
882 follow the end of an inline function to avoid counting
883 it twice. There is a note before the call, and one
884 after the call. */
885 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_REPEATED_LINE_NUMBER)
886 ignore_next_note = 1;
887 else if (NOTE_LINE_NUMBER (insn) > 0)
889 if (ignore_next_note)
890 ignore_next_note = 0;
891 else
893 /* If this is a new source file, then output the
894 file's name to the .bb file. */
895 if (! last_bb_file_name
896 || strcmp (NOTE_SOURCE_FILE (insn),
897 last_bb_file_name))
899 if (last_bb_file_name)
900 free (last_bb_file_name);
901 last_bb_file_name
902 = xstrdup (NOTE_SOURCE_FILE (insn));
903 output_gcov_string (NOTE_SOURCE_FILE (insn),
904 (long)-1);
906 /* Output the line number to the .bb file. Must be
907 done after the output_bb_profile_data() call, and
908 after the file name is written, to ensure that it
909 is correctly handled by gcov. */
910 __write_long (NOTE_LINE_NUMBER (insn), bb_file, 4);
914 insn = NEXT_INSN (insn);
917 __write_long (0, bb_file, 4);
920 /* Create spanning tree from basic block graph, mark each edge that is
921 on the spanning tree. We insert as many abnormal and critical edges
922 as possible to minimize number of edge splits necessary. */
924 find_spanning_tree (el);
926 /* Fake edges that are not on the tree will not be instrumented, so
927 mark them ignored. */
928 for (i = 0; i < num_edges; i++)
930 edge e = INDEX_EDGE (el, i);
931 struct edge_info *inf = EDGE_INFO (e);
932 if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
934 inf->ignore = 1;
935 ignored_edges++;
939 total_num_blocks += n_basic_blocks + 2;
940 if (rtl_dump_file)
941 fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
943 total_num_edges += num_edges;
944 if (rtl_dump_file)
945 fprintf (rtl_dump_file, "%d edges\n", num_edges);
947 total_num_edges_ignored += ignored_edges;
948 if (rtl_dump_file)
949 fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
951 /* Create a .bbg file from which gcov can reconstruct the basic block
952 graph. First output the number of basic blocks, and then for every
953 edge output the source and target basic block numbers.
954 NOTE: The format of this file must be compatible with gcov. */
956 if (flag_test_coverage)
958 int flag_bits;
960 __write_gcov_string (current_function_name,
961 strlen (current_function_name), bbg_file, -1);
963 /* write checksum. */
964 __write_long (profile_info.current_function_cfg_checksum, bbg_file, 4);
966 /* The plus 2 stands for entry and exit block. */
967 __write_long (n_basic_blocks + 2, bbg_file, 4);
968 __write_long (num_edges - ignored_edges + 1, bbg_file, 4);
970 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
972 edge e;
973 long count = 0;
975 for (e = bb->succ; e; e = e->succ_next)
976 if (!EDGE_INFO (e)->ignore)
977 count++;
978 __write_long (count, bbg_file, 4);
980 for (e = bb->succ; e; e = e->succ_next)
982 struct edge_info *i = EDGE_INFO (e);
983 if (!i->ignore)
985 flag_bits = 0;
986 if (i->on_tree)
987 flag_bits |= 0x1;
988 if (e->flags & EDGE_FAKE)
989 flag_bits |= 0x2;
990 if (e->flags & EDGE_FALLTHRU)
991 flag_bits |= 0x4;
993 __write_long (BB_TO_GCOV_INDEX (e->dest), bbg_file, 4);
994 __write_long (flag_bits, bbg_file, 4);
998 /* Emit fake loopback edge for EXIT block to maintain compatibility with
999 old gcov format. */
1000 __write_long (1, bbg_file, 4);
1001 __write_long (0, bbg_file, 4);
1002 __write_long (0x1, bbg_file, 4);
1004 /* Emit a -1 to separate the list of all edges from the list of
1005 loop back edges that follows. */
1006 __write_long (-1, bbg_file, 4);
1009 if (flag_branch_probabilities)
1010 compute_branch_probabilities ();
1012 /* For each edge not on the spanning tree, add counting code as rtl. */
1014 if (profile_arc_flag)
1016 instrument_edges (el);
1017 allocate_reg_info (max_reg_num (), FALSE, FALSE);
1020 remove_fake_edges ();
1021 /* Re-merge split basic blocks and the mess introduced by
1022 insert_insn_on_edge. */
1023 cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
1024 if (rtl_dump_file)
1025 dump_flow_info (rtl_dump_file);
1027 free_aux_for_edges ();
1028 free_edge_list (el);
1031 /* Union find algorithm implementation for the basic blocks using
1032 aux fields. */
1034 static basic_block
1035 find_group (bb)
1036 basic_block bb;
1038 basic_block group = bb, bb1;
1040 while ((basic_block) group->aux != group)
1041 group = (basic_block) group->aux;
1043 /* Compress path. */
1044 while ((basic_block) bb->aux != group)
1046 bb1 = (basic_block) bb->aux;
1047 bb->aux = (void *) group;
1048 bb = bb1;
1050 return group;
1053 static void
1054 union_groups (bb1, bb2)
1055 basic_block bb1, bb2;
1057 basic_block bb1g = find_group (bb1);
1058 basic_block bb2g = find_group (bb2);
1060 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
1061 this code is unlikely going to be performance problem anyway. */
1062 if (bb1g == bb2g)
1063 abort ();
1065 bb1g->aux = bb2g;
1068 /* This function searches all of the edges in the program flow graph, and puts
1069 as many bad edges as possible onto the spanning tree. Bad edges include
1070 abnormals edges, which can't be instrumented at the moment. Since it is
1071 possible for fake edges to form an cycle, we will have to develop some
1072 better way in the future. Also put critical edges to the tree, since they
1073 are more expensive to instrument. */
1075 static void
1076 find_spanning_tree (el)
1077 struct edge_list *el;
1079 int i;
1080 int num_edges = NUM_EDGES (el);
1081 basic_block bb;
1083 /* We use aux field for standard union-find algorithm. */
1084 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1085 bb->aux = bb;
1087 /* Add fake edge exit to entry we can't instrument. */
1088 union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
1090 /* First add all abnormal edges to the tree unless they form an cycle. Also
1091 add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1092 setting return value from function. */
1093 for (i = 0; i < num_edges; i++)
1095 edge e = INDEX_EDGE (el, i);
1096 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1097 || e->dest == EXIT_BLOCK_PTR
1099 && !EDGE_INFO (e)->ignore
1100 && (find_group (e->src) != find_group (e->dest)))
1102 if (rtl_dump_file)
1103 fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
1104 e->src->index, e->dest->index);
1105 EDGE_INFO (e)->on_tree = 1;
1106 union_groups (e->src, e->dest);
1110 /* Now insert all critical edges to the tree unless they form an cycle. */
1111 for (i = 0; i < num_edges; i++)
1113 edge e = INDEX_EDGE (el, i);
1114 if ((EDGE_CRITICAL_P (e))
1115 && !EDGE_INFO (e)->ignore
1116 && (find_group (e->src) != find_group (e->dest)))
1118 if (rtl_dump_file)
1119 fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1120 e->src->index, e->dest->index);
1121 EDGE_INFO (e)->on_tree = 1;
1122 union_groups (e->src, e->dest);
1126 /* And now the rest. */
1127 for (i = 0; i < num_edges; i++)
1129 edge e = INDEX_EDGE (el, i);
1130 if (find_group (e->src) != find_group (e->dest)
1131 && !EDGE_INFO (e)->ignore)
1133 if (rtl_dump_file)
1134 fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1135 e->src->index, e->dest->index);
1136 EDGE_INFO (e)->on_tree = 1;
1137 union_groups (e->src, e->dest);
1141 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1142 bb->aux = NULL;
1145 /* Perform file-level initialization for branch-prob processing. */
1147 void
1148 init_branch_prob (filename)
1149 const char *filename;
1151 long len;
1152 int i;
1154 if (flag_test_coverage)
1156 int len = strlen (filename);
1157 char *data_file, *bbg_file_name;
1159 /* Open an output file for the basic block/line number map. */
1160 data_file = (char *) alloca (len + 4);
1161 strcpy (data_file, filename);
1162 strip_off_ending (data_file, len);
1163 strcat (data_file, ".bb");
1164 if ((bb_file = fopen (data_file, "wb")) == 0)
1165 fatal_io_error ("can't open %s", data_file);
1167 /* Open an output file for the program flow graph. */
1168 bbg_file_name = (char *) alloca (len + 5);
1169 strcpy (bbg_file_name, filename);
1170 strip_off_ending (bbg_file_name, len);
1171 strcat (bbg_file_name, ".bbg");
1172 if ((bbg_file = fopen (bbg_file_name, "wb")) == 0)
1173 fatal_io_error ("can't open %s", bbg_file_name);
1175 /* Initialize to zero, to ensure that the first file name will be
1176 written to the .bb file. */
1177 last_bb_file_name = 0;
1180 if (flag_branch_probabilities)
1182 char *da_file_name;
1184 len = strlen (filename);
1185 da_file_name = (char *) alloca (len + 4);
1186 strcpy (da_file_name, filename);
1187 strip_off_ending (da_file_name, len);
1188 strcat (da_file_name, ".da");
1189 if ((da_file = fopen (da_file_name, "rb")) == 0)
1190 warning ("file %s not found, execution counts assumed to be zero",
1191 da_file_name);
1194 if (profile_arc_flag)
1195 init_edge_profiler ();
1197 total_num_blocks = 0;
1198 total_num_edges = 0;
1199 total_num_edges_ignored = 0;
1200 total_num_edges_instrumented = 0;
1201 total_num_blocks_created = 0;
1202 total_num_passes = 0;
1203 total_num_times_called = 0;
1204 total_num_branches = 0;
1205 total_num_never_executed = 0;
1206 for (i = 0; i < 20; i++)
1207 total_hist_br_prob[i] = 0;
1210 /* Performs file-level cleanup after branch-prob processing
1211 is completed. */
1213 void
1214 end_branch_prob ()
1216 if (flag_test_coverage)
1218 fclose (bb_file);
1219 fclose (bbg_file);
1222 if (flag_branch_probabilities && da_file)
1223 fclose (da_file);
1225 if (rtl_dump_file)
1227 fprintf (rtl_dump_file, "\n");
1228 fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1229 total_num_blocks);
1230 fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1231 fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1232 total_num_edges_ignored);
1233 fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1234 total_num_edges_instrumented);
1235 fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1236 total_num_blocks_created);
1237 fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1238 total_num_passes);
1239 if (total_num_times_called != 0)
1240 fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1241 (total_num_passes + (total_num_times_called >> 1))
1242 / total_num_times_called);
1243 fprintf (rtl_dump_file, "Total number of branches: %d\n",
1244 total_num_branches);
1245 fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1246 total_num_never_executed);
1247 if (total_num_branches)
1249 int i;
1251 for (i = 0; i < 10; i++)
1252 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1253 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1254 / total_num_branches, 5*i, 5*i+5);
1259 /* The label used by the edge profiling code. */
1261 static GTY(()) rtx profiler_label;
1263 /* Initialize the profiler_label. */
1265 static void
1266 init_edge_profiler ()
1268 /* Generate and save a copy of this so it can be shared. */
1269 char buf[20];
1270 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1271 profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1274 /* Output instructions as RTL to increment the edge execution count. */
1276 static rtx
1277 gen_edge_profiler (edgeno)
1278 int edgeno;
1280 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1281 rtx mem_ref, tmp;
1282 rtx sequence;
1284 start_sequence ();
1286 tmp = force_reg (Pmode, profiler_label);
1287 tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
1288 mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
1290 set_mem_alias_set (mem_ref, new_alias_set ());
1292 tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
1293 mem_ref, 0, OPTAB_WIDEN);
1295 if (tmp != mem_ref)
1296 emit_move_insn (copy_rtx (mem_ref), tmp);
1298 sequence = get_insns ();
1299 end_sequence ();
1300 return sequence;
1303 /* Output code for a constructor that will invoke __bb_init_func, if
1304 this has not already been done. */
1306 void
1307 output_func_start_profiler ()
1309 tree fnname, fndecl;
1310 char *name;
1311 char buf[20];
1312 const char *cfnname;
1313 rtx table_address;
1314 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1315 int save_flag_inline_functions = flag_inline_functions;
1317 /* It's either already been output, or we don't need it because we're
1318 not doing profile-edges. */
1319 if (! need_func_profiler)
1320 return;
1322 need_func_profiler = 0;
1324 /* Synthesize a constructor function to invoke __bb_init_func with a
1325 pointer to this object file's profile block. */
1327 /* Try and make a unique name given the "file function name".
1329 And no, I don't like this either. */
1331 fnname = get_file_function_name ('I');
1332 cfnname = IDENTIFIER_POINTER (fnname);
1333 name = concat (cfnname, "GCOV", NULL);
1334 fnname = get_identifier (name);
1335 free (name);
1337 fndecl = build_decl (FUNCTION_DECL, fnname,
1338 build_function_type (void_type_node, NULL_TREE));
1339 DECL_EXTERNAL (fndecl) = 0;
1341 /* It can be a static function as long as collect2 does not have
1342 to scan the object file to find its ctor/dtor routine. */
1343 TREE_PUBLIC (fndecl) = ! targetm.have_ctors_dtors;
1345 TREE_USED (fndecl) = 1;
1347 DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1349 fndecl = (*lang_hooks.decls.pushdecl) (fndecl);
1350 rest_of_decl_compilation (fndecl, 0, 1, 0);
1351 announce_function (fndecl);
1352 current_function_decl = fndecl;
1353 DECL_INITIAL (fndecl) = error_mark_node;
1354 make_decl_rtl (fndecl, NULL);
1355 init_function_start (fndecl, input_filename, lineno);
1356 (*lang_hooks.decls.pushlevel) (0);
1357 expand_function_start (fndecl, 0);
1358 cfun->arc_profile = 0;
1360 /* Actually generate the code to call __bb_init_func. */
1361 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 0);
1362 table_address = force_reg (Pmode,
1363 gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
1364 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__bb_init_func"), LCT_NORMAL,
1365 mode, 1, table_address, Pmode);
1367 expand_function_end (input_filename, lineno, 0);
1368 (*lang_hooks.decls.poplevel) (1, 0, 1);
1370 /* Since fndecl isn't in the list of globals, it would never be emitted
1371 when it's considered to be 'safe' for inlining, so turn off
1372 flag_inline_functions. */
1373 flag_inline_functions = 0;
1375 rest_of_compilation (fndecl);
1377 /* Reset flag_inline_functions to its original value. */
1378 flag_inline_functions = save_flag_inline_functions;
1380 if (! quiet_flag)
1381 fflush (asm_out_file);
1382 current_function_decl = NULL_TREE;
1384 if (targetm.have_ctors_dtors)
1385 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
1386 DEFAULT_INIT_PRIORITY);
1389 #include "gt-profile.h"