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
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
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
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
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
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. */
75 #include "insn-config.h"
82 #include "hard-reg-set.h"
83 #include "basic-block.h"
88 #include "langhooks.h"
90 /* Additional information about the edges we need. */
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;
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
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. */
175 instrument_edges (el
)
176 struct edge_list
*el
;
178 int num_instr_edges
= 0;
179 int num_edges
= NUM_EDGES (el
);
181 remove_fake_edges ();
183 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_bb
)
188 struct edge_info
*inf
= EDGE_INFO (e
);
189 if (!inf
->ignore
&& !inf
->on_tree
)
191 if (e
->flags
& EDGE_ABNORMAL
)
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
);
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
;
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. */
220 output_gcov_string (string
, delimiter
)
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. */
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. */
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. */
273 /* Count the edges to be (possibly) instrumented. */
275 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_bb
)
278 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
279 if (!EDGE_INFO (e
)->ignore
&& !EDGE_INFO (e
)->on_tree
)
283 /* now read and combine all matching profiles. */
285 profile
= xmalloc (sizeof (gcov_type
) * num_edges
);
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
++)
295 long magic
, extra_bytes
;
299 if (__read_long (&magic
, da_file
, 4) != 0)
308 if (__read_long (&func_count
, da_file
, 4) != 0)
314 if (__read_long (&extra_bytes
, da_file
, 4) != 0)
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
++)
334 if (__read_gcov_string
335 (function_name_buffer
, function_name_buffer_len
, da_file
,
342 if (__read_long (&chksum
, da_file
, 4) != 0)
348 if (__read_long (&arc_count
, da_file
, 4) != 0)
354 if (strcmp (function_name_buffer
, name
) != 0)
357 if (fseek (da_file
, arc_count
* 8, SEEK_CUR
) < 0)
363 else if (arc_count
!= num_edges
364 || chksum
!= profile_info
.current_function_cfg_checksum
)
365 okay
= 0, mismatch
= 1;
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)
391 free (function_name_buffer
);
397 ("Profile does not match flowgraph of function %s (out of date?)",
398 current_function_name
);
400 error (".da file corrupted");
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
);
415 /* Compute the branch probabilities for the various branches.
416 Annotate them accordingly. */
419 compute_branch_probabilities ()
426 int hist_br_prob
[20];
427 int num_never_executed
;
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
)
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
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
)
460 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
461 if (!EDGE_INFO (e
)->ignore
&& !EDGE_INFO (e
)->on_tree
)
466 e
->count
= exec_counts
[exec_counts_pos
++];
471 EDGE_INFO (e
)->count_valid
= 1;
472 BB_INFO (bb
)->succ_count
--;
473 BB_INFO (e
->dest
)->pred_count
--;
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
);
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. */
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)
520 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
526 else if (bi
->pred_count
== 0)
531 for (e
= bb
->pred
; e
; e
= e
->pred_next
)
540 if (bi
->succ_count
== 1)
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
)
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
)
555 /* Calculate count for remaining edge by conservation. */
556 total
= bb
->count
- total
;
560 EDGE_INFO (e
)->count_valid
= 1;
564 BB_INFO (e
->dest
)->pred_count
--;
567 if (bi
->pred_count
== 1)
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
)
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
)
582 /* Calculate count for remaining edge by conservation. */
583 total
= bb
->count
- total
+ e
->count
;
587 EDGE_INFO (e
)->count_valid
= 1;
591 BB_INFO (e
->src
)->succ_count
--;
598 dump_flow_info (rtl_dump_file
);
600 total_num_passes
+= passes
;
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. */
608 if (BB_INFO (bb
)->succ_count
|| BB_INFO (bb
)->pred_count
)
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
++)
617 num_never_executed
= 0;
620 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_bb
)
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;
640 && any_condjump_p (bb
->end
)
641 && bb
->succ
->succ_next
)
647 /* Find the branch edge. It is possible that we do have fake
649 for (e
= bb
->succ
; e
->flags
& (EDGE_FAKE
| EDGE_FALLTHRU
);
651 continue; /* Loop body has been intentionally left blank. */
653 prob
= e
->probability
;
654 index
= prob
* 20 / REG_BR_PROB_BASE
;
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. */
664 XEXP (note
, 0) = GEN_INT (prob
);
667 = gen_rtx_EXPR_LIST (REG_BR_PROB
, GEN_INT (prob
),
668 REG_NOTES (bb
->end
));
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). */
678 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
679 if (!(e
->flags
& (EDGE_COMPLEX
| EDGE_FAKE
)))
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
;
691 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
693 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
694 e
->probability
= REG_BR_PROB_BASE
/ total
;
697 && any_condjump_p (bb
->end
)
698 && bb
->succ
->succ_next
)
699 num_branches
++, num_never_executed
;
705 fprintf (rtl_dump_file
, "%d branches\n", num_branches
);
706 fprintf (rtl_dump_file
, "%d branches never executed\n",
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
,
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 ();
728 /* Compute checksum for the current function. */
730 #define CHSUM_HASH 500000003
731 #define CHSUM_SHIFT 2
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
;
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
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. */
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 ();
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. */
806 int need_exit_edge
= 0, need_entry_edge
= 0;
807 int have_exit_edge
= 0, have_entry_edge
= 0;
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
);
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
)
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
)
844 if (e
->dest
== EXIT_BLOCK_PTR
)
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
)
852 if (e
->src
== ENTRY_BLOCK_PTR
)
856 if (need_exit_edge
&& !have_exit_edge
)
859 fprintf (rtl_dump_file
, "Adding fake exit edge to bb %i\n",
861 make_edge (bb
, EXIT_BLOCK_PTR
, EDGE_FAKE
);
863 if (need_entry_edge
&& !have_entry_edge
)
866 fprintf (rtl_dump_file
, "Adding fake entry edge to bb %i\n",
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. */
880 for (i
= 0 ; i
< num_edges
; i
++)
882 edge e
= INDEX_EDGE (el
, i
);
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;
894 #ifdef ENABLE_CHECKING
898 /* Output line number information about each basic block for
900 if (flag_test_coverage
)
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
);
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
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;
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
),
941 if (last_bb_file_name
)
942 free (last_bb_file_name
);
944 = xstrdup (NOTE_SOURCE_FILE (insn
));
945 output_gcov_string (NOTE_SOURCE_FILE (insn
),
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
)
981 total_num_blocks
+= n_basic_blocks
+ 2;
983 fprintf (rtl_dump_file
, "%d basic blocks\n", n_basic_blocks
);
985 total_num_edges
+= num_edges
;
987 fprintf (rtl_dump_file
, "%d edges\n", num_edges
);
989 total_num_edges_ignored
+= ignored_edges
;
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
)
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
)
1016 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
1017 if (!EDGE_INFO (e
)->ignore
)
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
);
1029 if (e
->flags
& EDGE_FAKE
)
1031 if (e
->flags
& EDGE_FALLTHRU
)
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
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);
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
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
;
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. */
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. */
1117 find_spanning_tree (el
)
1118 struct edge_list
*el
;
1121 int num_edges
= NUM_EDGES (el
);
1124 /* We use aux field for standard union-find algorithm. */
1125 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_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
)))
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
)))
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
)
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
)
1186 /* Perform file-level initialization for branch-prob processing. */
1189 init_branch_prob (filename
)
1190 const char *filename
;
1192 int len
= strlen (filename
);
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");
1226 warning ("file %s not found, execution counts assumed to be zero",
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
1252 if (flag_test_coverage
)
1256 unlink (da_file_name
);
1259 if (flag_branch_probabilities
&& da_file
)
1264 fprintf (rtl_dump_file
, "\n");
1265 fprintf (rtl_dump_file
, "Total number of blocks: %d\n",
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",
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
)
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. */
1303 init_edge_profiler ()
1305 /* Generate and save a copy of this so it can be shared. */
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. */
1314 gen_edge_profiler (edgeno
)
1317 enum machine_mode mode
= mode_for_size (GCOV_TYPE_SIZE
, MODE_INT
, 0);
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
);
1333 emit_move_insn (copy_rtx (mem_ref
), tmp
);
1335 sequence
= get_insns ();
1340 /* Output code for a constructor that will invoke __bb_init_func, if
1341 this has not already been done. */
1344 output_func_start_profiler ()
1346 tree fnname
, fndecl
;
1349 const char *cfnname
;
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
)
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
);
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
;
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"