PR optimization/2903
[official-gcc.git] / gcc / profile.c
blobfd1f4241ef8ee5e48700d56b751f61cfaf599399
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 /* Generate basic block profile instrumentation and auxiliary files.
26 Profile generation is optimized, so that not all arcs in the basic
27 block graph need instrumenting. First, the BB graph is closed with
28 one entry (function start), and one exit (function exit). Any
29 ABNORMAL_EDGE cannot be instrumented (because there is no control
30 path to place the code). We close the graph by inserting fake
31 EDGE_FAKE edges to the EXIT_BLOCK, from the sources of abnormal
32 edges that do not go to the exit_block. We ignore such abnormal
33 edges. Naturally these fake edges are never directly traversed,
34 and so *cannot* be directly instrumented. Some other graph
35 massaging is done. To optimize the instrumentation we generate the
36 BB minimal span tree, only edges that are not on the span tree
37 (plus the entry point) need instrumenting. From that information
38 all other edge counts can be deduced. By construction all fake
39 edges must be on the spanning tree. We also attempt to place
40 EDGE_CRITICAL edges on the spanning tree.
42 The two auxiliary files generated are <dumpbase>.bb and
43 <dumpbase>.bbg. The former contains the BB->linenumber
44 mappings, and the latter describes the BB graph.
46 The BB file contains line numbers for each block. For each basic
47 block, a zero count is output (to mark the start of a block), then
48 the line numbers of that block are listed. A zero ends the file
49 too.
51 The BBG file contains a count of the blocks, followed by edge
52 information, for every edge in the graph. The edge information
53 lists the source and target block numbers, and a bit mask
54 describing the type of edge.
56 The BB and BBG file formats are fully described in the gcov
57 documentation. */
59 /* ??? Register allocation should use basic block execution counts to
60 give preference to the most commonly executed blocks. */
62 /* ??? The .da files are not safe. Changing the program after creating .da
63 files or using different options when compiling with -fbranch-probabilities
64 can result the arc data not matching the program. Maybe add instrumented
65 arc count to .bbg file? Maybe check whether PFG matches the .bbg file? */
67 /* ??? Should calculate branch probabilities before instrumenting code, since
68 then we can use arc counts to help decide which arcs to instrument. */
70 #include "config.h"
71 #include "system.h"
72 #include "rtl.h"
73 #include "tree.h"
74 #include "flags.h"
75 #include "insn-config.h"
76 #include "output.h"
77 #include "regs.h"
78 #include "expr.h"
79 #include "function.h"
80 #include "toplev.h"
81 #include "ggc.h"
82 #include "hard-reg-set.h"
83 #include "basic-block.h"
84 #include "gcov-io.h"
85 #include "target.h"
86 #include "profile.h"
87 #include "libfuncs.h"
88 #include "langhooks.h"
90 /* Additional information about the edges we need. */
91 struct edge_info {
92 unsigned int count_valid : 1;
94 /* Is on the spanning tree. */
95 unsigned int on_tree : 1;
97 /* Pretend this edge does not exist (it is abnormal and we've
98 inserted a fake to compensate). */
99 unsigned int ignore : 1;
102 struct bb_info {
103 unsigned int count_valid : 1;
105 /* Number of successor and predecessor edges. */
106 gcov_type succ_count;
107 gcov_type pred_count;
110 #define EDGE_INFO(e) ((struct edge_info *) (e)->aux)
111 #define BB_INFO(b) ((struct bb_info *) (b)->aux)
113 /* Keep all basic block indexes nonnegative in the gcov output. Index 0
114 is used for entry block, last block exit block. */
115 #define BB_TO_GCOV_INDEX(bb) ((bb) == ENTRY_BLOCK_PTR ? 0 \
116 : ((bb) == EXIT_BLOCK_PTR \
117 ? last_basic_block + 1 : (bb)->index + 1))
119 /* Instantiate the profile info structure. */
121 struct profile_info profile_info;
123 /* Name and file pointer of the output file for the basic block graph. */
125 static FILE *bbg_file;
127 /* Name and file pointer of the input file for the arc count data. */
129 static FILE *da_file;
130 static char *da_file_name;
132 /* Pointer of the output file for the basic block/line number map. */
133 static FILE *bb_file;
135 /* Last source file name written to bb_file. */
137 static char *last_bb_file_name;
139 /* Collect statistics on the performance of this pass for the entire source
140 file. */
142 static int total_num_blocks;
143 static int total_num_edges;
144 static int total_num_edges_ignored;
145 static int total_num_edges_instrumented;
146 static int total_num_blocks_created;
147 static int total_num_passes;
148 static int total_num_times_called;
149 static int total_hist_br_prob[20];
150 static int total_num_never_executed;
151 static int total_num_branches;
153 /* Forward declarations. */
154 static void find_spanning_tree PARAMS ((struct edge_list *));
155 static void init_edge_profiler PARAMS ((void));
156 static rtx gen_edge_profiler PARAMS ((int));
157 static void instrument_edges PARAMS ((struct edge_list *));
158 static void output_gcov_string PARAMS ((const char *, long));
159 static void compute_branch_probabilities PARAMS ((void));
160 static gcov_type * get_exec_counts PARAMS ((void));
161 static long compute_checksum PARAMS ((void));
162 static basic_block find_group PARAMS ((basic_block));
163 static void union_groups PARAMS ((basic_block, basic_block));
165 /* If nonzero, we need to output a constructor to set up the
166 per-object-file data. */
167 static int need_func_profiler = 0;
169 /* Add edge instrumentation code to the entire insn chain.
171 F is the first insn of the chain.
172 NUM_BLOCKS is the number of basic blocks found in F. */
174 static void
175 instrument_edges (el)
176 struct edge_list *el;
178 int num_instr_edges = 0;
179 int num_edges = NUM_EDGES (el);
180 basic_block bb;
181 remove_fake_edges ();
183 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
185 edge e = bb->succ;
186 while (e)
188 struct edge_info *inf = EDGE_INFO (e);
189 if (!inf->ignore && !inf->on_tree)
191 if (e->flags & EDGE_ABNORMAL)
192 abort ();
193 if (rtl_dump_file)
194 fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
195 e->src->index, e->dest->index,
196 EDGE_CRITICAL_P (e) ? " (and split)" : "");
197 need_func_profiler = 1;
198 insert_insn_on_edge (
199 gen_edge_profiler (total_num_edges_instrumented
200 + num_instr_edges++), e);
202 e = e->succ_next;
206 profile_info.count_edges_instrumented_now = num_instr_edges;
207 total_num_edges_instrumented += num_instr_edges;
208 profile_info.count_instrumented_edges = total_num_edges_instrumented;
210 total_num_blocks_created += num_edges;
211 if (rtl_dump_file)
212 fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
214 commit_edge_insertions_watch_calls ();
217 /* Output STRING to bb_file, surrounded by DELIMITER. */
219 static void
220 output_gcov_string (string, delimiter)
221 const char *string;
222 long delimiter;
224 size_t temp;
226 /* Write a delimiter to indicate that a file name follows. */
227 __write_long (delimiter, bb_file, 4);
229 /* Write the string. */
230 temp = strlen (string) + 1;
231 fwrite (string, temp, 1, bb_file);
233 /* Append a few zeros, to align the output to a 4 byte boundary. */
234 temp = temp & 0x3;
235 if (temp)
237 char c[4];
239 c[0] = c[1] = c[2] = c[3] = 0;
240 fwrite (c, sizeof (char), 4 - temp, bb_file);
243 /* Store another delimiter in the .bb file, just to make it easy to find
244 the end of the file name. */
245 __write_long (delimiter, bb_file, 4);
249 /* Computes hybrid profile for all matching entries in da_file.
250 Sets max_counter_in_program as a side effect. */
252 static gcov_type *
253 get_exec_counts ()
255 int num_edges = 0;
256 basic_block bb;
257 int okay = 1, i;
258 int mismatch = 0;
259 gcov_type *profile;
260 char *function_name_buffer;
261 int function_name_buffer_len;
262 gcov_type max_counter_in_run;
263 const char *name = IDENTIFIER_POINTER
264 (DECL_ASSEMBLER_NAME (current_function_decl));
266 profile_info.max_counter_in_program = 0;
267 profile_info.count_profiles_merged = 0;
269 /* No .da file, no execution counts. */
270 if (!da_file)
271 return 0;
273 /* Count the edges to be (possibly) instrumented. */
275 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
277 edge e;
278 for (e = bb->succ; e; e = e->succ_next)
279 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
280 num_edges++;
283 /* now read and combine all matching profiles. */
285 profile = xmalloc (sizeof (gcov_type) * num_edges);
286 rewind (da_file);
287 function_name_buffer_len = strlen (name) + 1;
288 function_name_buffer = xmalloc (function_name_buffer_len + 1);
290 for (i = 0; i < num_edges; i++)
291 profile[i] = 0;
293 while (1)
295 long magic, extra_bytes;
296 long func_count;
297 int i;
299 if (__read_long (&magic, da_file, 4) != 0)
300 break;
302 if (magic != -123)
304 okay = 0;
305 break;
308 if (__read_long (&func_count, da_file, 4) != 0)
310 okay = 0;
311 break;
314 if (__read_long (&extra_bytes, da_file, 4) != 0)
316 okay = 0;
317 break;
320 fseek (da_file, 4 + 8, SEEK_CUR);
322 /* read the maximal counter. */
323 __read_gcov_type (&max_counter_in_run, da_file, 8);
325 /* skip the rest of "statistics" emited by __bb_exit_func. */
326 fseek (da_file, extra_bytes - (4 + 8 + 8), SEEK_CUR);
328 for (i = 0; i < func_count; i++)
330 long arc_count;
331 long chksum;
332 int j;
334 if (__read_gcov_string
335 (function_name_buffer, function_name_buffer_len, da_file,
336 -1) != 0)
338 okay = 0;
339 break;
342 if (__read_long (&chksum, da_file, 4) != 0)
344 okay = 0;
345 break;
348 if (__read_long (&arc_count, da_file, 4) != 0)
350 okay = 0;
351 break;
354 if (strcmp (function_name_buffer, name) != 0)
356 /* skip */
357 if (fseek (da_file, arc_count * 8, SEEK_CUR) < 0)
359 okay = 0;
360 break;
363 else if (arc_count != num_edges
364 || chksum != profile_info.current_function_cfg_checksum)
365 okay = 0, mismatch = 1;
366 else
368 gcov_type tmp;
370 profile_info.max_counter_in_program += max_counter_in_run;
371 profile_info.count_profiles_merged++;
373 for (j = 0; j < arc_count; j++)
374 if (__read_gcov_type (&tmp, da_file, 8) != 0)
376 okay = 0;
377 break;
379 else
381 profile[j] += tmp;
386 if (!okay)
387 break;
391 free (function_name_buffer);
393 if (!okay)
395 if (mismatch)
396 error
397 ("Profile does not match flowgraph of function %s (out of date?)",
398 current_function_name);
399 else
400 error (".da file corrupted");
401 free (profile);
402 return 0;
404 if (rtl_dump_file)
406 fprintf(rtl_dump_file, "Merged %i profiles with maximal count %i.\n",
407 profile_info.count_profiles_merged,
408 (int)profile_info.max_counter_in_program);
411 return profile;
415 /* Compute the branch probabilities for the various branches.
416 Annotate them accordingly. */
418 static void
419 compute_branch_probabilities ()
421 basic_block bb;
422 int i;
423 int num_edges = 0;
424 int changes;
425 int passes;
426 int hist_br_prob[20];
427 int num_never_executed;
428 int num_branches;
429 gcov_type *exec_counts = get_exec_counts ();
430 int exec_counts_pos = 0;
432 /* Attach extra info block to each bb. */
434 alloc_aux_for_blocks (sizeof (struct bb_info));
435 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
437 edge e;
439 for (e = bb->succ; e; e = e->succ_next)
440 if (!EDGE_INFO (e)->ignore)
441 BB_INFO (bb)->succ_count++;
442 for (e = bb->pred; e; e = e->pred_next)
443 if (!EDGE_INFO (e)->ignore)
444 BB_INFO (bb)->pred_count++;
447 /* Avoid predicting entry on exit nodes. */
448 BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
449 BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
451 /* For each edge not on the spanning tree, set its execution count from
452 the .da file. */
454 /* The first count in the .da file is the number of times that the function
455 was entered. This is the exec_count for block zero. */
457 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
459 edge e;
460 for (e = bb->succ; e; e = e->succ_next)
461 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
463 num_edges++;
464 if (exec_counts)
466 e->count = exec_counts[exec_counts_pos++];
468 else
469 e->count = 0;
471 EDGE_INFO (e)->count_valid = 1;
472 BB_INFO (bb)->succ_count--;
473 BB_INFO (e->dest)->pred_count--;
474 if (rtl_dump_file)
476 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
477 bb->index, e->dest->index);
478 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
479 (HOST_WIDEST_INT) e->count);
484 if (rtl_dump_file)
485 fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
487 /* For every block in the file,
488 - if every exit/entrance edge has a known count, then set the block count
489 - if the block count is known, and every exit/entrance edge but one has
490 a known execution count, then set the count of the remaining edge
492 As edge counts are set, decrement the succ/pred count, but don't delete
493 the edge, that way we can easily tell when all edges are known, or only
494 one edge is unknown. */
496 /* The order that the basic blocks are iterated through is important.
497 Since the code that finds spanning trees starts with block 0, low numbered
498 edges are put on the spanning tree in preference to high numbered edges.
499 Hence, most instrumented edges are at the end. Graph solving works much
500 faster if we propagate numbers from the end to the start.
502 This takes an average of slightly more than 3 passes. */
504 changes = 1;
505 passes = 0;
506 while (changes)
508 passes++;
509 changes = 0;
510 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
512 struct bb_info *bi = BB_INFO (bb);
513 if (! bi->count_valid)
515 if (bi->succ_count == 0)
517 edge e;
518 gcov_type total = 0;
520 for (e = bb->succ; e; e = e->succ_next)
521 total += e->count;
522 bb->count = total;
523 bi->count_valid = 1;
524 changes = 1;
526 else if (bi->pred_count == 0)
528 edge e;
529 gcov_type total = 0;
531 for (e = bb->pred; e; e = e->pred_next)
532 total += e->count;
533 bb->count = total;
534 bi->count_valid = 1;
535 changes = 1;
538 if (bi->count_valid)
540 if (bi->succ_count == 1)
542 edge e;
543 gcov_type total = 0;
545 /* One of the counts will be invalid, but it is zero,
546 so adding it in also doesn't hurt. */
547 for (e = bb->succ; e; e = e->succ_next)
548 total += e->count;
550 /* Seedgeh for the invalid edge, and set its count. */
551 for (e = bb->succ; e; e = e->succ_next)
552 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
553 break;
555 /* Calculate count for remaining edge by conservation. */
556 total = bb->count - total;
558 if (! e)
559 abort ();
560 EDGE_INFO (e)->count_valid = 1;
561 e->count = total;
562 bi->succ_count--;
564 BB_INFO (e->dest)->pred_count--;
565 changes = 1;
567 if (bi->pred_count == 1)
569 edge e;
570 gcov_type total = 0;
572 /* One of the counts will be invalid, but it is zero,
573 so adding it in also doesn't hurt. */
574 for (e = bb->pred; e; e = e->pred_next)
575 total += e->count;
577 /* Seedgeh for the invalid edge, and set its count. */
578 for (e = bb->pred; e; e = e->pred_next)
579 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
580 break;
582 /* Calculate count for remaining edge by conservation. */
583 total = bb->count - total + e->count;
585 if (! e)
586 abort ();
587 EDGE_INFO (e)->count_valid = 1;
588 e->count = total;
589 bi->pred_count--;
591 BB_INFO (e->src)->succ_count--;
592 changes = 1;
597 if (rtl_dump_file)
598 dump_flow_info (rtl_dump_file);
600 total_num_passes += passes;
601 if (rtl_dump_file)
602 fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
604 /* If the graph has been correctly solved, every block will have a
605 succ and pred count of zero. */
606 FOR_EACH_BB (bb)
608 if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
609 abort ();
612 /* For every edge, calculate its branch probability and add a reg_note
613 to the branch insn to indicate this. */
615 for (i = 0; i < 20; i++)
616 hist_br_prob[i] = 0;
617 num_never_executed = 0;
618 num_branches = 0;
620 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
622 edge e;
623 gcov_type total;
624 rtx note;
626 total = bb->count;
627 if (total)
629 for (e = bb->succ; e; e = e->succ_next)
631 e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
632 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
634 error ("corrupted profile info: prob for %d-%d thought to be %d",
635 e->src->index, e->dest->index, e->probability);
636 e->probability = REG_BR_PROB_BASE / 2;
639 if (bb->index >= 0
640 && any_condjump_p (bb->end)
641 && bb->succ->succ_next)
643 int prob;
644 edge e;
645 int index;
647 /* Find the branch edge. It is possible that we do have fake
648 edges here. */
649 for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
650 e = e->succ_next)
651 continue; /* Loop body has been intentionally left blank. */
653 prob = e->probability;
654 index = prob * 20 / REG_BR_PROB_BASE;
656 if (index == 20)
657 index = 19;
658 hist_br_prob[index]++;
660 note = find_reg_note (bb->end, REG_BR_PROB, 0);
661 /* There may be already note put by some other pass, such
662 as builtin_expect expander. */
663 if (note)
664 XEXP (note, 0) = GEN_INT (prob);
665 else
666 REG_NOTES (bb->end)
667 = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
668 REG_NOTES (bb->end));
669 num_branches++;
672 /* Otherwise distribute the probabilities evenly so we get sane sum.
673 Use simple heuristics that if there are normal edges, give all abnormals
674 frequency of 0, otherwise distribute the frequency over abnormals
675 (this is the case of noreturn calls). */
676 else
678 for (e = bb->succ; e; e = e->succ_next)
679 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
680 total ++;
681 if (total)
683 for (e = bb->succ; e; e = e->succ_next)
684 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
685 e->probability = REG_BR_PROB_BASE / total;
686 else
687 e->probability = 0;
689 else
691 for (e = bb->succ; e; e = e->succ_next)
692 total ++;
693 for (e = bb->succ; e; e = e->succ_next)
694 e->probability = REG_BR_PROB_BASE / total;
696 if (bb->index >= 0
697 && any_condjump_p (bb->end)
698 && bb->succ->succ_next)
699 num_branches++, num_never_executed;
703 if (rtl_dump_file)
705 fprintf (rtl_dump_file, "%d branches\n", num_branches);
706 fprintf (rtl_dump_file, "%d branches never executed\n",
707 num_never_executed);
708 if (num_branches)
709 for (i = 0; i < 10; i++)
710 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
711 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
712 5 * i, 5 * i + 5);
714 total_num_branches += num_branches;
715 total_num_never_executed += num_never_executed;
716 for (i = 0; i < 20; i++)
717 total_hist_br_prob[i] += hist_br_prob[i];
719 fputc ('\n', rtl_dump_file);
720 fputc ('\n', rtl_dump_file);
723 free_aux_for_blocks ();
724 if (exec_counts)
725 free (exec_counts);
728 /* Compute checksum for the current function. */
730 #define CHSUM_HASH 500000003
731 #define CHSUM_SHIFT 2
733 static long
734 compute_checksum ()
736 long chsum = 0;
737 basic_block bb;
739 FOR_EACH_BB (bb)
741 edge e;
743 for (e = bb->succ; e; e = e->succ_next)
745 chsum = ((chsum << CHSUM_SHIFT) + (BB_TO_GCOV_INDEX (e->dest) + 1)) % CHSUM_HASH;
748 chsum = (chsum << CHSUM_SHIFT) % CHSUM_HASH;
751 return chsum;
754 /* Instrument and/or analyze program behavior based on program flow graph.
755 In either case, this function builds a flow graph for the function being
756 compiled. The flow graph is stored in BB_GRAPH.
758 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
759 the flow graph that are needed to reconstruct the dynamic behavior of the
760 flow graph.
762 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
763 information from a data file containing edge count information from previous
764 executions of the function being compiled. In this case, the flow graph is
765 annotated with actual execution counts, which are later propagated into the
766 rtl for optimization purposes.
768 Main entry point of this file. */
770 void
771 branch_prob ()
773 basic_block bb;
774 int i;
775 int num_edges, ignored_edges;
776 struct edge_list *el;
777 const char *name = IDENTIFIER_POINTER
778 (DECL_ASSEMBLER_NAME (current_function_decl));
780 profile_info.current_function_cfg_checksum = compute_checksum ();
782 if (rtl_dump_file)
783 fprintf (rtl_dump_file, "CFG checksum is %ld\n",
784 profile_info.current_function_cfg_checksum);
786 /* Start of a function. */
787 if (flag_test_coverage)
788 output_gcov_string (name, (long) -2);
790 total_num_times_called++;
792 flow_call_edges_add (NULL);
793 add_noreturn_fake_exit_edges ();
795 /* We can't handle cyclic regions constructed using abnormal edges.
796 To avoid these we replace every source of abnormal edge by a fake
797 edge from entry node and every destination by fake edge to exit.
798 This keeps graph acyclic and our calculation exact for all normal
799 edges except for exit and entrance ones.
801 We also add fake exit edges for each call and asm statement in the
802 basic, since it may not return. */
804 FOR_EACH_BB (bb)
806 int need_exit_edge = 0, need_entry_edge = 0;
807 int have_exit_edge = 0, have_entry_edge = 0;
808 rtx insn;
809 edge e;
811 /* Add fake edges from entry block to the call insns that may return
812 twice. The CFG is not quite correct then, as call insn plays more
813 role of CODE_LABEL, but for our purposes, everything should be OK,
814 as we never insert code to the beggining of basic block. */
815 for (insn = bb->head; insn != NEXT_INSN (bb->end);
816 insn = NEXT_INSN (insn))
818 if (GET_CODE (insn) == CALL_INSN
819 && find_reg_note (insn, REG_SETJMP, NULL))
821 if (GET_CODE (bb->head) == CODE_LABEL
822 || insn != NEXT_INSN (bb->head))
824 e = split_block (bb, PREV_INSN (insn));
825 make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
826 break;
828 else
830 /* We should not get abort here, as call to setjmp should not
831 be the very first instruction of function. */
832 if (bb == ENTRY_BLOCK_PTR)
833 abort ();
834 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
839 for (e = bb->succ; e; e = e->succ_next)
841 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
842 && e->dest != EXIT_BLOCK_PTR)
843 need_exit_edge = 1;
844 if (e->dest == EXIT_BLOCK_PTR)
845 have_exit_edge = 1;
847 for (e = bb->pred; e; e = e->pred_next)
849 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
850 && e->src != ENTRY_BLOCK_PTR)
851 need_entry_edge = 1;
852 if (e->src == ENTRY_BLOCK_PTR)
853 have_entry_edge = 1;
856 if (need_exit_edge && !have_exit_edge)
858 if (rtl_dump_file)
859 fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
860 bb->index);
861 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
863 if (need_entry_edge && !have_entry_edge)
865 if (rtl_dump_file)
866 fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
867 bb->index);
868 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
872 el = create_edge_list ();
873 num_edges = NUM_EDGES (el);
874 alloc_aux_for_edges (sizeof (struct edge_info));
876 /* The basic blocks are expected to be numbered sequentially. */
877 compact_blocks ();
879 ignored_edges = 0;
880 for (i = 0 ; i < num_edges ; i++)
882 edge e = INDEX_EDGE (el, i);
883 e->count = 0;
885 /* Mark edges we've replaced by fake edges above as ignored. */
886 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
887 && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
889 EDGE_INFO (e)->ignore = 1;
890 ignored_edges++;
894 #ifdef ENABLE_CHECKING
895 verify_flow_info ();
896 #endif
898 /* Output line number information about each basic block for
899 GCOV utility. */
900 if (flag_test_coverage)
902 FOR_EACH_BB (bb)
904 rtx insn = bb->head;
905 static int ignore_next_note = 0;
907 /* We are looking for line number notes. Search backward before
908 basic block to find correct ones. */
909 insn = prev_nonnote_insn (insn);
910 if (!insn)
911 insn = get_insns ();
912 else
913 insn = NEXT_INSN (insn);
915 /* Output a zero to the .bb file to indicate that a new
916 block list is starting. */
917 __write_long (0, bb_file, 4);
919 while (insn != bb->end)
921 if (GET_CODE (insn) == NOTE)
923 /* Must ignore the line number notes that immediately
924 follow the end of an inline function to avoid counting
925 it twice. There is a note before the call, and one
926 after the call. */
927 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_REPEATED_LINE_NUMBER)
928 ignore_next_note = 1;
929 else if (NOTE_LINE_NUMBER (insn) > 0)
931 if (ignore_next_note)
932 ignore_next_note = 0;
933 else
935 /* If this is a new source file, then output the
936 file's name to the .bb file. */
937 if (! last_bb_file_name
938 || strcmp (NOTE_SOURCE_FILE (insn),
939 last_bb_file_name))
941 if (last_bb_file_name)
942 free (last_bb_file_name);
943 last_bb_file_name
944 = xstrdup (NOTE_SOURCE_FILE (insn));
945 output_gcov_string (NOTE_SOURCE_FILE (insn),
946 (long)-1);
948 /* Output the line number to the .bb file. Must be
949 done after the output_bb_profile_data() call, and
950 after the file name is written, to ensure that it
951 is correctly handled by gcov. */
952 __write_long (NOTE_LINE_NUMBER (insn), bb_file, 4);
956 insn = NEXT_INSN (insn);
959 __write_long (0, bb_file, 4);
962 /* Create spanning tree from basic block graph, mark each edge that is
963 on the spanning tree. We insert as many abnormal and critical edges
964 as possible to minimize number of edge splits necessary. */
966 find_spanning_tree (el);
968 /* Fake edges that are not on the tree will not be instrumented, so
969 mark them ignored. */
970 for (i = 0; i < num_edges; i++)
972 edge e = INDEX_EDGE (el, i);
973 struct edge_info *inf = EDGE_INFO (e);
974 if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
976 inf->ignore = 1;
977 ignored_edges++;
981 total_num_blocks += n_basic_blocks + 2;
982 if (rtl_dump_file)
983 fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
985 total_num_edges += num_edges;
986 if (rtl_dump_file)
987 fprintf (rtl_dump_file, "%d edges\n", num_edges);
989 total_num_edges_ignored += ignored_edges;
990 if (rtl_dump_file)
991 fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
993 /* Create a .bbg file from which gcov can reconstruct the basic block
994 graph. First output the number of basic blocks, and then for every
995 edge output the source and target basic block numbers.
996 NOTE: The format of this file must be compatible with gcov. */
998 if (flag_test_coverage)
1000 int flag_bits;
1002 __write_gcov_string (name, strlen (name), bbg_file, -1);
1004 /* write checksum. */
1005 __write_long (profile_info.current_function_cfg_checksum, bbg_file, 4);
1007 /* The plus 2 stands for entry and exit block. */
1008 __write_long (n_basic_blocks + 2, bbg_file, 4);
1009 __write_long (num_edges - ignored_edges + 1, bbg_file, 4);
1011 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
1013 edge e;
1014 long count = 0;
1016 for (e = bb->succ; e; e = e->succ_next)
1017 if (!EDGE_INFO (e)->ignore)
1018 count++;
1019 __write_long (count, bbg_file, 4);
1021 for (e = bb->succ; e; e = e->succ_next)
1023 struct edge_info *i = EDGE_INFO (e);
1024 if (!i->ignore)
1026 flag_bits = 0;
1027 if (i->on_tree)
1028 flag_bits |= 0x1;
1029 if (e->flags & EDGE_FAKE)
1030 flag_bits |= 0x2;
1031 if (e->flags & EDGE_FALLTHRU)
1032 flag_bits |= 0x4;
1034 __write_long (BB_TO_GCOV_INDEX (e->dest), bbg_file, 4);
1035 __write_long (flag_bits, bbg_file, 4);
1039 /* Emit fake loopback edge for EXIT block to maintain compatibility with
1040 old gcov format. */
1041 __write_long (1, bbg_file, 4);
1042 __write_long (0, bbg_file, 4);
1043 __write_long (0x1, bbg_file, 4);
1045 /* Emit a -1 to separate the list of all edges from the list of
1046 loop back edges that follows. */
1047 __write_long (-1, bbg_file, 4);
1050 if (flag_branch_probabilities)
1051 compute_branch_probabilities ();
1053 /* For each edge not on the spanning tree, add counting code as rtl. */
1055 if (profile_arc_flag)
1057 instrument_edges (el);
1058 allocate_reg_info (max_reg_num (), FALSE, FALSE);
1061 remove_fake_edges ();
1062 /* Re-merge split basic blocks and the mess introduced by
1063 insert_insn_on_edge. */
1064 cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
1065 if (rtl_dump_file)
1066 dump_flow_info (rtl_dump_file);
1068 free_aux_for_edges ();
1069 free_edge_list (el);
1072 /* Union find algorithm implementation for the basic blocks using
1073 aux fields. */
1075 static basic_block
1076 find_group (bb)
1077 basic_block bb;
1079 basic_block group = bb, bb1;
1081 while ((basic_block) group->aux != group)
1082 group = (basic_block) group->aux;
1084 /* Compress path. */
1085 while ((basic_block) bb->aux != group)
1087 bb1 = (basic_block) bb->aux;
1088 bb->aux = (void *) group;
1089 bb = bb1;
1091 return group;
1094 static void
1095 union_groups (bb1, bb2)
1096 basic_block bb1, bb2;
1098 basic_block bb1g = find_group (bb1);
1099 basic_block bb2g = find_group (bb2);
1101 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
1102 this code is unlikely going to be performance problem anyway. */
1103 if (bb1g == bb2g)
1104 abort ();
1106 bb1g->aux = bb2g;
1109 /* This function searches all of the edges in the program flow graph, and puts
1110 as many bad edges as possible onto the spanning tree. Bad edges include
1111 abnormals edges, which can't be instrumented at the moment. Since it is
1112 possible for fake edges to form an cycle, we will have to develop some
1113 better way in the future. Also put critical edges to the tree, since they
1114 are more expensive to instrument. */
1116 static void
1117 find_spanning_tree (el)
1118 struct edge_list *el;
1120 int i;
1121 int num_edges = NUM_EDGES (el);
1122 basic_block bb;
1124 /* We use aux field for standard union-find algorithm. */
1125 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1126 bb->aux = bb;
1128 /* Add fake edge exit to entry we can't instrument. */
1129 union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
1131 /* First add all abnormal edges to the tree unless they form an cycle. Also
1132 add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1133 setting return value from function. */
1134 for (i = 0; i < num_edges; i++)
1136 edge e = INDEX_EDGE (el, i);
1137 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1138 || e->dest == EXIT_BLOCK_PTR
1140 && !EDGE_INFO (e)->ignore
1141 && (find_group (e->src) != find_group (e->dest)))
1143 if (rtl_dump_file)
1144 fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
1145 e->src->index, e->dest->index);
1146 EDGE_INFO (e)->on_tree = 1;
1147 union_groups (e->src, e->dest);
1151 /* Now insert all critical edges to the tree unless they form an cycle. */
1152 for (i = 0; i < num_edges; i++)
1154 edge e = INDEX_EDGE (el, i);
1155 if ((EDGE_CRITICAL_P (e))
1156 && !EDGE_INFO (e)->ignore
1157 && (find_group (e->src) != find_group (e->dest)))
1159 if (rtl_dump_file)
1160 fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1161 e->src->index, e->dest->index);
1162 EDGE_INFO (e)->on_tree = 1;
1163 union_groups (e->src, e->dest);
1167 /* And now the rest. */
1168 for (i = 0; i < num_edges; i++)
1170 edge e = INDEX_EDGE (el, i);
1171 if (find_group (e->src) != find_group (e->dest)
1172 && !EDGE_INFO (e)->ignore)
1174 if (rtl_dump_file)
1175 fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1176 e->src->index, e->dest->index);
1177 EDGE_INFO (e)->on_tree = 1;
1178 union_groups (e->src, e->dest);
1182 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1183 bb->aux = NULL;
1186 /* Perform file-level initialization for branch-prob processing. */
1188 void
1189 init_branch_prob (filename)
1190 const char *filename;
1192 int len = strlen (filename);
1193 int i;
1195 if (flag_test_coverage)
1197 char *data_file, *bbg_file_name;
1199 /* Open an output file for the basic block/line number map. */
1200 data_file = (char *) alloca (len + 4);
1201 strcpy (data_file, filename);
1202 strcat (data_file, ".bb");
1203 if ((bb_file = fopen (data_file, "wb")) == 0)
1204 fatal_io_error ("can't open %s", data_file);
1206 /* Open an output file for the program flow graph. */
1207 bbg_file_name = (char *) alloca (len + 5);
1208 strcpy (bbg_file_name, filename);
1209 strcat (bbg_file_name, ".bbg");
1210 if ((bbg_file = fopen (bbg_file_name, "wb")) == 0)
1211 fatal_io_error ("can't open %s", bbg_file_name);
1213 /* Initialize to zero, to ensure that the first file name will be
1214 written to the .bb file. */
1215 last_bb_file_name = 0;
1218 da_file_name = (char *) xmalloc (len + 4);
1219 strcpy (da_file_name, filename);
1220 strcat (da_file_name, ".da");
1222 if (flag_branch_probabilities)
1224 da_file = fopen (da_file_name, "rb");
1225 if (!da_file)
1226 warning ("file %s not found, execution counts assumed to be zero",
1227 da_file_name);
1230 if (profile_arc_flag)
1231 init_edge_profiler ();
1233 total_num_blocks = 0;
1234 total_num_edges = 0;
1235 total_num_edges_ignored = 0;
1236 total_num_edges_instrumented = 0;
1237 total_num_blocks_created = 0;
1238 total_num_passes = 0;
1239 total_num_times_called = 0;
1240 total_num_branches = 0;
1241 total_num_never_executed = 0;
1242 for (i = 0; i < 20; i++)
1243 total_hist_br_prob[i] = 0;
1246 /* Performs file-level cleanup after branch-prob processing
1247 is completed. */
1249 void
1250 end_branch_prob ()
1252 if (flag_test_coverage)
1254 fclose (bb_file);
1255 fclose (bbg_file);
1256 unlink (da_file_name);
1259 if (flag_branch_probabilities && da_file)
1260 fclose (da_file);
1262 if (rtl_dump_file)
1264 fprintf (rtl_dump_file, "\n");
1265 fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1266 total_num_blocks);
1267 fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1268 fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1269 total_num_edges_ignored);
1270 fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1271 total_num_edges_instrumented);
1272 fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1273 total_num_blocks_created);
1274 fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1275 total_num_passes);
1276 if (total_num_times_called != 0)
1277 fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1278 (total_num_passes + (total_num_times_called >> 1))
1279 / total_num_times_called);
1280 fprintf (rtl_dump_file, "Total number of branches: %d\n",
1281 total_num_branches);
1282 fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1283 total_num_never_executed);
1284 if (total_num_branches)
1286 int i;
1288 for (i = 0; i < 10; i++)
1289 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1290 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1291 / total_num_branches, 5*i, 5*i+5);
1296 /* The label used by the edge profiling code. */
1298 static GTY(()) rtx profiler_label;
1300 /* Initialize the profiler_label. */
1302 static void
1303 init_edge_profiler ()
1305 /* Generate and save a copy of this so it can be shared. */
1306 char buf[20];
1307 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1308 profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1311 /* Output instructions as RTL to increment the edge execution count. */
1313 static rtx
1314 gen_edge_profiler (edgeno)
1315 int edgeno;
1317 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1318 rtx mem_ref, tmp;
1319 rtx sequence;
1321 start_sequence ();
1323 tmp = force_reg (Pmode, profiler_label);
1324 tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
1325 mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
1327 set_mem_alias_set (mem_ref, new_alias_set ());
1329 tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
1330 mem_ref, 0, OPTAB_WIDEN);
1332 if (tmp != mem_ref)
1333 emit_move_insn (copy_rtx (mem_ref), tmp);
1335 sequence = get_insns ();
1336 end_sequence ();
1337 return sequence;
1340 /* Output code for a constructor that will invoke __bb_init_func, if
1341 this has not already been done. */
1343 void
1344 output_func_start_profiler ()
1346 tree fnname, fndecl;
1347 char *name;
1348 char buf[20];
1349 const char *cfnname;
1350 rtx table_address;
1351 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1352 int save_flag_inline_functions = flag_inline_functions;
1354 /* It's either already been output, or we don't need it because we're
1355 not doing profile-edges. */
1356 if (! need_func_profiler)
1357 return;
1359 need_func_profiler = 0;
1361 /* Synthesize a constructor function to invoke __bb_init_func with a
1362 pointer to this object file's profile block. */
1364 /* Try and make a unique name given the "file function name".
1366 And no, I don't like this either. */
1368 fnname = get_file_function_name ('I');
1369 cfnname = IDENTIFIER_POINTER (fnname);
1370 name = concat (cfnname, "GCOV", NULL);
1371 fnname = get_identifier (name);
1372 free (name);
1374 fndecl = build_decl (FUNCTION_DECL, fnname,
1375 build_function_type (void_type_node, NULL_TREE));
1376 DECL_EXTERNAL (fndecl) = 0;
1378 /* It can be a static function as long as collect2 does not have
1379 to scan the object file to find its ctor/dtor routine. */
1380 TREE_PUBLIC (fndecl) = ! targetm.have_ctors_dtors;
1382 TREE_USED (fndecl) = 1;
1384 DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1386 fndecl = (*lang_hooks.decls.pushdecl) (fndecl);
1387 rest_of_decl_compilation (fndecl, 0, 1, 0);
1388 announce_function (fndecl);
1389 current_function_decl = fndecl;
1390 DECL_INITIAL (fndecl) = error_mark_node;
1391 make_decl_rtl (fndecl, NULL);
1392 init_function_start (fndecl, input_filename, lineno);
1393 (*lang_hooks.decls.pushlevel) (0);
1394 expand_function_start (fndecl, 0);
1395 cfun->arc_profile = 0;
1397 /* Actually generate the code to call __bb_init_func. */
1398 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 0);
1399 table_address = force_reg (Pmode,
1400 gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
1401 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__bb_init_func"), LCT_NORMAL,
1402 mode, 1, table_address, Pmode);
1404 expand_function_end (input_filename, lineno, 0);
1405 (*lang_hooks.decls.poplevel) (1, 0, 1);
1407 /* Since fndecl isn't in the list of globals, it would never be emitted
1408 when it's considered to be 'safe' for inlining, so turn off
1409 flag_inline_functions. */
1410 flag_inline_functions = 0;
1412 rest_of_compilation (fndecl);
1414 /* Reset flag_inline_functions to its original value. */
1415 flag_inline_functions = save_flag_inline_functions;
1417 if (! quiet_flag)
1418 fflush (asm_out_file);
1419 current_function_decl = NULL_TREE;
1421 if (targetm.have_ctors_dtors)
1422 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
1423 DEFAULT_INIT_PRIORITY);
1426 #include "gt-profile.h"