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 auxiliary file generated is <dumpbase>.bbg. The format is
43 described in full in gcov-io.h. */
45 /* ??? Register allocation should use basic block execution counts to
46 give preference to the most commonly executed blocks. */
48 /* ??? Should calculate branch probabilities before instrumenting code, since
49 then we can use arc counts to help decide which arcs to instrument. */
53 #include "coretypes.h"
58 #include "insn-config.h"
65 #include "hard-reg-set.h"
66 #include "basic-block.h"
71 #include "langhooks.h"
74 /* Additional information about the edges we need. */
76 unsigned int count_valid
: 1;
78 /* Is on the spanning tree. */
79 unsigned int on_tree
: 1;
81 /* Pretend this edge does not exist (it is abnormal and we've
82 inserted a fake to compensate). */
83 unsigned int ignore
: 1;
87 unsigned int count_valid
: 1;
89 /* Number of successor and predecessor edges. */
96 struct function_list
*next
; /* next function */
97 const char *name
; /* function name */
98 unsigned cfg_checksum
; /* function checksum */
99 unsigned n_counter_sections
; /* number of counter sections */
100 struct counter_section counter_sections
[MAX_COUNTER_SECTIONS
];
104 static struct function_list
*functions_head
= 0;
105 static struct function_list
**functions_tail
= &functions_head
;
107 #define EDGE_INFO(e) ((struct edge_info *) (e)->aux)
108 #define BB_INFO(b) ((struct bb_info *) (b)->aux)
110 /* Keep all basic block indexes nonnegative in the gcov output. Index 0
111 is used for entry block, last block exit block. */
112 #define BB_TO_GCOV_INDEX(bb) ((bb) == ENTRY_BLOCK_PTR ? 0 \
113 : ((bb) == EXIT_BLOCK_PTR \
114 ? last_basic_block + 1 : (bb)->index + 1))
116 /* Instantiate the profile info structure. */
118 struct profile_info profile_info
;
120 /* Name and file pointer of the output file for the basic block graph. */
122 static FILE *bbg_file
;
123 static char *bbg_file_name
;
125 /* Name and file pointer of the input file for the arc count data. */
127 static FILE *da_file
;
128 static char *da_file_name
;
130 /* The name of the count table. Used by the edge profiling code. */
131 static GTY(()) rtx profiler_label
;
133 /* Collect statistics on the performance of this pass for the entire source
136 static int total_num_blocks
;
137 static int total_num_edges
;
138 static int total_num_edges_ignored
;
139 static int total_num_edges_instrumented
;
140 static int total_num_blocks_created
;
141 static int total_num_passes
;
142 static int total_num_times_called
;
143 static int total_hist_br_prob
[20];
144 static int total_num_never_executed
;
145 static int total_num_branches
;
147 /* Forward declarations. */
148 static void find_spanning_tree
PARAMS ((struct edge_list
*));
149 static rtx gen_edge_profiler
PARAMS ((int));
150 static void instrument_edges
PARAMS ((struct edge_list
*));
151 static void compute_branch_probabilities
PARAMS ((void));
152 static hashval_t htab_counts_index_hash
PARAMS ((const void *));
153 static int htab_counts_index_eq
PARAMS ((const void *, const void *));
154 static void htab_counts_index_del
PARAMS ((void *));
155 static void cleanup_counts_index
PARAMS ((int));
156 static int index_counts_file
PARAMS ((void));
157 static gcov_type
* get_exec_counts
PARAMS ((void));
158 static unsigned compute_checksum
PARAMS ((void));
159 static basic_block find_group
PARAMS ((basic_block
));
160 static void union_groups
PARAMS ((basic_block
, basic_block
));
161 static void set_purpose
PARAMS ((tree
, tree
));
162 static rtx label_for_tag
PARAMS ((unsigned));
163 static tree build_counter_section_fields
PARAMS ((void));
164 static tree build_counter_section_value
PARAMS ((unsigned, unsigned));
165 static tree build_counter_section_data_fields
PARAMS ((void));
166 static tree build_counter_section_data_value
PARAMS ((unsigned, unsigned));
167 static tree build_function_info_fields
PARAMS ((void));
168 static tree build_function_info_value
PARAMS ((struct function_list
*));
169 static tree build_gcov_info_fields
PARAMS ((tree
));
170 static tree build_gcov_info_value
PARAMS ((void));
173 /* Add edge instrumentation code to the entire insn chain.
175 F is the first insn of the chain.
176 NUM_BLOCKS is the number of basic blocks found in F. */
179 instrument_edges (el
)
180 struct edge_list
*el
;
182 int num_instr_edges
= 0;
183 int num_edges
= NUM_EDGES (el
);
185 struct section_info
*section_info
;
186 remove_fake_edges ();
188 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_bb
)
193 struct edge_info
*inf
= EDGE_INFO (e
);
194 if (!inf
->ignore
&& !inf
->on_tree
)
196 if (e
->flags
& EDGE_ABNORMAL
)
199 fprintf (rtl_dump_file
, "Edge %d to %d instrumented%s\n",
200 e
->src
->index
, e
->dest
->index
,
201 EDGE_CRITICAL_P (e
) ? " (and split)" : "");
202 insert_insn_on_edge (
203 gen_edge_profiler (total_num_edges_instrumented
204 + num_instr_edges
++), e
);
210 section_info
= find_counters_section (GCOV_TAG_ARC_COUNTS
);
211 section_info
->n_counters_now
= num_instr_edges
;
212 total_num_edges_instrumented
+= num_instr_edges
;
213 section_info
->n_counters
= total_num_edges_instrumented
;
215 total_num_blocks_created
+= num_edges
;
217 fprintf (rtl_dump_file
, "%d edges instrumented\n", num_instr_edges
);
220 struct section_reference
227 struct da_index_entry
235 struct section_reference
*offsets
;
239 htab_counts_index_hash (of
)
242 const struct da_index_entry
*entry
= of
;
244 return htab_hash_string (entry
->function_name
) ^ entry
->section
;
248 htab_counts_index_eq (of1
, of2
)
252 const struct da_index_entry
*entry1
= of1
;
253 const struct da_index_entry
*entry2
= of2
;
255 return !strcmp (entry1
->function_name
, entry2
->function_name
)
256 && entry1
->section
== entry2
->section
;
260 htab_counts_index_del (what
)
263 struct da_index_entry
*entry
= what
;
266 for (i
= 0; i
< entry
->n_offsets
; i
++)
268 struct section_reference
*act
= entry
->offsets
+ i
;
269 if (act
->owns_summary
)
272 free (entry
->function_name
);
273 free (entry
->offsets
);
277 static char *counts_file_name
;
278 static htab_t counts_file_index
= NULL
;
281 cleanup_counts_index (close_file
)
284 if (da_file
&& close_file
)
289 if (counts_file_name
)
290 free (counts_file_name
);
291 counts_file_name
= NULL
;
292 if (counts_file_index
)
293 htab_delete (counts_file_index
);
294 counts_file_index
= NULL
;
300 char *function_name_buffer
= NULL
;
301 unsigned magic
, version
, ix
, checksum
;
304 /* No .da file, no data. */
307 counts_file_index
= htab_create (10, htab_counts_index_hash
, htab_counts_index_eq
, htab_counts_index_del
);
309 /* Now index all profile sections. */
314 if (gcov_read_unsigned (da_file
, &magic
) || magic
!= GCOV_DATA_MAGIC
)
316 warning ("`%s' is not a gcov data file", da_file_name
);
319 if (gcov_read_unsigned (da_file
, &version
) || version
!= GCOV_VERSION
)
322 magic
= GCOV_VERSION
;
324 for (ix
= 4; ix
--; magic
>>= 8, version
>>= 8)
329 warning ("`%s' is version `%.4s', expected version `%.4s'",
336 unsigned tag
, length
;
339 offset
= gcov_save_position (da_file
);
340 if (gcov_read_unsigned (da_file
, &tag
)
341 || gcov_read_unsigned (da_file
, &length
))
346 warning ("`%s' is corrupted", da_file_name
);
349 if (tag
== GCOV_TAG_FUNCTION
)
351 if (gcov_read_string (da_file
, &function_name_buffer
, NULL
)
352 || gcov_read_unsigned (da_file
, &checksum
))
356 if (tag
== GCOV_TAG_PROGRAM_SUMMARY
)
358 if (length
!= GCOV_SUMMARY_LENGTH
)
367 if (function_name_buffer
)
369 struct da_index_entry
**slot
, elt
;
370 elt
.function_name
= function_name_buffer
;
373 slot
= (struct da_index_entry
**)
374 htab_find_slot (counts_file_index
, &elt
, INSERT
);
377 if ((*slot
)->checksum
!= checksum
)
379 warning ("profile mismatch for `%s'", function_name_buffer
);
382 (*slot
)->n_offsets
++;
383 (*slot
)->offsets
= xrealloc ((*slot
)->offsets
,
384 sizeof (struct section_reference
) * (*slot
)->n_offsets
);
388 *slot
= xmalloc (sizeof (struct da_index_entry
));
389 (*slot
)->function_name
= xstrdup (function_name_buffer
);
390 (*slot
)->section
= tag
;
391 (*slot
)->checksum
= checksum
;
392 (*slot
)->n_offsets
= 1;
393 (*slot
)->offsets
= xmalloc (sizeof (struct section_reference
));
395 (*slot
)->offsets
[(*slot
)->n_offsets
- 1].offset
= offset
;
397 (*slot
)->offsets
[(*slot
)->n_offsets
- 1].owns_summary
= 0;
400 summary
= xmalloc (sizeof (long));
402 (*slot
)->offsets
[(*slot
)->n_offsets
- 1].owns_summary
= 1;
404 (*slot
)->offsets
[(*slot
)->n_offsets
- 1].summary
= summary
;
407 if (gcov_skip (da_file
, length
))
411 free (function_name_buffer
);
416 cleanup_counts_index (1);
417 if (function_name_buffer
)
418 free (function_name_buffer
);
422 /* Computes hybrid profile for all matching entries in da_file.
423 Sets max_counter_in_program as a side effect. */
428 unsigned num_edges
= 0;
432 unsigned ix
, i
, tag
, length
, num
;
433 const char *name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
));
434 struct da_index_entry
*entry
, what
;
435 struct section_reference
*act
;
437 struct gcov_summary summ
;
439 profile_info
.max_counter_in_program
= 0;
440 profile_info
.count_profiles_merged
= 0;
442 /* No .da file, no execution counts. */
445 if (!counts_file_index
)
448 /* Count the edges to be (possibly) instrumented. */
450 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_bb
)
453 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
454 if (!EDGE_INFO (e
)->ignore
&& !EDGE_INFO (e
)->on_tree
)
458 /* now read and combine all matching profiles. */
460 profile
= xmalloc (sizeof (gcov_type
) * num_edges
);
462 for (ix
= 0; ix
< num_edges
; ix
++)
465 what
.function_name
= (char *) name
;
466 what
.section
= GCOV_TAG_ARC_COUNTS
;
467 entry
= htab_find (counts_file_index
, &what
);
470 warning ("No profile for function '%s' found.", name
);
474 if (entry
->checksum
!= profile_info
.current_function_cfg_checksum
)
476 warning ("profile mismatch for `%s'", current_function_name
);
480 for (i
= 0; i
< entry
->n_offsets
; i
++)
482 act
= entry
->offsets
+ i
;
484 /* Read arc counters. */
486 gcov_resync (da_file
, act
->offset
, 0);
488 if (gcov_read_unsigned (da_file
, &tag
)
489 || gcov_read_unsigned (da_file
, &length
)
490 || tag
!= GCOV_TAG_ARC_COUNTS
)
492 /* We have already passed through file, so any error means
493 something is rotten. */
498 if (num
!= num_edges
)
500 warning ("profile mismatch for `%s'", current_function_name
);
504 for (ix
= 0; ix
!= num
; ix
++)
506 if (gcov_read_counter (da_file
, &count
))
508 if (count
> max_count
)
510 profile
[ix
] += count
;
513 /* Read program summary. */
514 if (*act
->summary
!= -1)
516 gcov_resync (da_file
, *act
->summary
, 0);
517 if (gcov_read_unsigned (da_file
, &tag
)
518 || gcov_read_unsigned (da_file
, &length
)
519 || tag
!= GCOV_TAG_PROGRAM_SUMMARY
520 || gcov_read_summary (da_file
, &summ
))
522 profile_info
.count_profiles_merged
+= summ
.runs
;
523 profile_info
.max_counter_in_program
+= summ
.arc_sum_max
;
529 profile_info
.count_profiles_merged
++;
530 profile_info
.max_counter_in_program
+= max_count
;
536 fprintf(rtl_dump_file
, "Merged %i profiles with maximal count %i.\n",
537 profile_info
.count_profiles_merged
,
538 (int)profile_info
.max_counter_in_program
);
545 cleanup_counts_index (1);
550 /* Compute the branch probabilities for the various branches.
551 Annotate them accordingly. */
554 compute_branch_probabilities ()
561 int hist_br_prob
[20];
562 int num_never_executed
;
564 gcov_type
*exec_counts
= get_exec_counts ();
565 int exec_counts_pos
= 0;
567 /* Attach extra info block to each bb. */
569 alloc_aux_for_blocks (sizeof (struct bb_info
));
570 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_bb
)
574 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
575 if (!EDGE_INFO (e
)->ignore
)
576 BB_INFO (bb
)->succ_count
++;
577 for (e
= bb
->pred
; e
; e
= e
->pred_next
)
578 if (!EDGE_INFO (e
)->ignore
)
579 BB_INFO (bb
)->pred_count
++;
582 /* Avoid predicting entry on exit nodes. */
583 BB_INFO (EXIT_BLOCK_PTR
)->succ_count
= 2;
584 BB_INFO (ENTRY_BLOCK_PTR
)->pred_count
= 2;
586 /* For each edge not on the spanning tree, set its execution count from
589 /* The first count in the .da file is the number of times that the function
590 was entered. This is the exec_count for block zero. */
592 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_bb
)
595 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
596 if (!EDGE_INFO (e
)->ignore
&& !EDGE_INFO (e
)->on_tree
)
601 e
->count
= exec_counts
[exec_counts_pos
++];
606 EDGE_INFO (e
)->count_valid
= 1;
607 BB_INFO (bb
)->succ_count
--;
608 BB_INFO (e
->dest
)->pred_count
--;
611 fprintf (rtl_dump_file
, "\nRead edge from %i to %i, count:",
612 bb
->index
, e
->dest
->index
);
613 fprintf (rtl_dump_file
, HOST_WIDEST_INT_PRINT_DEC
,
614 (HOST_WIDEST_INT
) e
->count
);
620 fprintf (rtl_dump_file
, "\n%d edge counts read\n", num_edges
);
622 /* For every block in the file,
623 - if every exit/entrance edge has a known count, then set the block count
624 - if the block count is known, and every exit/entrance edge but one has
625 a known execution count, then set the count of the remaining edge
627 As edge counts are set, decrement the succ/pred count, but don't delete
628 the edge, that way we can easily tell when all edges are known, or only
629 one edge is unknown. */
631 /* The order that the basic blocks are iterated through is important.
632 Since the code that finds spanning trees starts with block 0, low numbered
633 edges are put on the spanning tree in preference to high numbered edges.
634 Hence, most instrumented edges are at the end. Graph solving works much
635 faster if we propagate numbers from the end to the start.
637 This takes an average of slightly more than 3 passes. */
645 FOR_BB_BETWEEN (bb
, EXIT_BLOCK_PTR
, NULL
, prev_bb
)
647 struct bb_info
*bi
= BB_INFO (bb
);
648 if (! bi
->count_valid
)
650 if (bi
->succ_count
== 0)
655 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
661 else if (bi
->pred_count
== 0)
666 for (e
= bb
->pred
; e
; e
= e
->pred_next
)
675 if (bi
->succ_count
== 1)
680 /* One of the counts will be invalid, but it is zero,
681 so adding it in also doesn't hurt. */
682 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
685 /* Seedgeh for the invalid edge, and set its count. */
686 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
687 if (! EDGE_INFO (e
)->count_valid
&& ! EDGE_INFO (e
)->ignore
)
690 /* Calculate count for remaining edge by conservation. */
691 total
= bb
->count
- total
;
695 EDGE_INFO (e
)->count_valid
= 1;
699 BB_INFO (e
->dest
)->pred_count
--;
702 if (bi
->pred_count
== 1)
707 /* One of the counts will be invalid, but it is zero,
708 so adding it in also doesn't hurt. */
709 for (e
= bb
->pred
; e
; e
= e
->pred_next
)
712 /* Seedgeh for the invalid edge, and set its count. */
713 for (e
= bb
->pred
; e
; e
= e
->pred_next
)
714 if (! EDGE_INFO (e
)->count_valid
&& ! EDGE_INFO (e
)->ignore
)
717 /* Calculate count for remaining edge by conservation. */
718 total
= bb
->count
- total
+ e
->count
;
722 EDGE_INFO (e
)->count_valid
= 1;
726 BB_INFO (e
->src
)->succ_count
--;
733 dump_flow_info (rtl_dump_file
);
735 total_num_passes
+= passes
;
737 fprintf (rtl_dump_file
, "Graph solving took %d passes.\n\n", passes
);
739 /* If the graph has been correctly solved, every block will have a
740 succ and pred count of zero. */
743 if (BB_INFO (bb
)->succ_count
|| BB_INFO (bb
)->pred_count
)
747 /* For every edge, calculate its branch probability and add a reg_note
748 to the branch insn to indicate this. */
750 for (i
= 0; i
< 20; i
++)
752 num_never_executed
= 0;
755 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_bb
)
764 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
766 e
->probability
= (e
->count
* REG_BR_PROB_BASE
+ total
/ 2) / total
;
767 if (e
->probability
< 0 || e
->probability
> REG_BR_PROB_BASE
)
769 error ("corrupted profile info: prob for %d-%d thought to be %d",
770 e
->src
->index
, e
->dest
->index
, e
->probability
);
771 e
->probability
= REG_BR_PROB_BASE
/ 2;
775 && any_condjump_p (bb
->end
)
776 && bb
->succ
->succ_next
)
782 /* Find the branch edge. It is possible that we do have fake
784 for (e
= bb
->succ
; e
->flags
& (EDGE_FAKE
| EDGE_FALLTHRU
);
786 continue; /* Loop body has been intentionally left blank. */
788 prob
= e
->probability
;
789 index
= prob
* 20 / REG_BR_PROB_BASE
;
793 hist_br_prob
[index
]++;
795 note
= find_reg_note (bb
->end
, REG_BR_PROB
, 0);
796 /* There may be already note put by some other pass, such
797 as builtin_expect expander. */
799 XEXP (note
, 0) = GEN_INT (prob
);
802 = gen_rtx_EXPR_LIST (REG_BR_PROB
, GEN_INT (prob
),
803 REG_NOTES (bb
->end
));
807 /* Otherwise distribute the probabilities evenly so we get sane
808 sum. Use simple heuristics that if there are normal edges,
809 give all abnormals frequency of 0, otherwise distribute the
810 frequency over abnormals (this is the case of noreturn
814 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
815 if (!(e
->flags
& (EDGE_COMPLEX
| EDGE_FAKE
)))
819 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
820 if (!(e
->flags
& (EDGE_COMPLEX
| EDGE_FAKE
)))
821 e
->probability
= REG_BR_PROB_BASE
/ total
;
827 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
829 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
830 e
->probability
= REG_BR_PROB_BASE
/ total
;
833 && any_condjump_p (bb
->end
)
834 && bb
->succ
->succ_next
)
835 num_branches
++, num_never_executed
;
841 fprintf (rtl_dump_file
, "%d branches\n", num_branches
);
842 fprintf (rtl_dump_file
, "%d branches never executed\n",
845 for (i
= 0; i
< 10; i
++)
846 fprintf (rtl_dump_file
, "%d%% branches in range %d-%d%%\n",
847 (hist_br_prob
[i
] + hist_br_prob
[19-i
]) * 100 / num_branches
,
850 total_num_branches
+= num_branches
;
851 total_num_never_executed
+= num_never_executed
;
852 for (i
= 0; i
< 20; i
++)
853 total_hist_br_prob
[i
] += hist_br_prob
[i
];
855 fputc ('\n', rtl_dump_file
);
856 fputc ('\n', rtl_dump_file
);
859 free_aux_for_blocks ();
862 find_counters_section (GCOV_TAG_ARC_COUNTS
)->present
= 1;
865 /* Compute checksum for the current function. We generate a CRC32. */
879 unsigned value
= BB_TO_GCOV_INDEX (e
? e
->dest
: bb
);
882 /* No need to use all bits in value identically, nearly all
883 functions have less than 256 blocks. */
884 value
^= value
<< 16;
887 for (ix
= 8; ix
--; value
<<= 1)
891 feedback
= (value
^ chksum
) & 0x80000000 ? 0x04c11db7 : 0;
896 e
= e
? e
->succ_next
: bb
->succ
;
904 /* Instrument and/or analyze program behavior based on program flow graph.
905 In either case, this function builds a flow graph for the function being
906 compiled. The flow graph is stored in BB_GRAPH.
908 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
909 the flow graph that are needed to reconstruct the dynamic behavior of the
912 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
913 information from a data file containing edge count information from previous
914 executions of the function being compiled. In this case, the flow graph is
915 annotated with actual execution counts, which are later propagated into the
916 rtl for optimization purposes.
918 Main entry point of this file. */
925 unsigned num_edges
, ignored_edges
;
926 struct edge_list
*el
;
927 const char *name
= IDENTIFIER_POINTER
928 (DECL_ASSEMBLER_NAME (current_function_decl
));
930 profile_info
.current_function_cfg_checksum
= compute_checksum ();
931 for (i
= 0; i
< profile_info
.n_sections
; i
++)
933 profile_info
.section_info
[i
].n_counters_now
= 0;
934 profile_info
.section_info
[i
].present
= 0;
938 fprintf (rtl_dump_file
, "CFG checksum is %u\n",
939 profile_info
.current_function_cfg_checksum
);
941 total_num_times_called
++;
943 flow_call_edges_add (NULL
);
944 add_noreturn_fake_exit_edges ();
946 /* We can't handle cyclic regions constructed using abnormal edges.
947 To avoid these we replace every source of abnormal edge by a fake
948 edge from entry node and every destination by fake edge to exit.
949 This keeps graph acyclic and our calculation exact for all normal
950 edges except for exit and entrance ones.
952 We also add fake exit edges for each call and asm statement in the
953 basic, since it may not return. */
957 int need_exit_edge
= 0, need_entry_edge
= 0;
958 int have_exit_edge
= 0, have_entry_edge
= 0;
962 /* Add fake edges from entry block to the call insns that may return
963 twice. The CFG is not quite correct then, as call insn plays more
964 role of CODE_LABEL, but for our purposes, everything should be OK,
965 as we never insert code to the beginning of basic block. */
966 for (insn
= bb
->head
; insn
!= NEXT_INSN (bb
->end
);
967 insn
= NEXT_INSN (insn
))
969 if (GET_CODE (insn
) == CALL_INSN
970 && find_reg_note (insn
, REG_SETJMP
, NULL
))
972 if (GET_CODE (bb
->head
) == CODE_LABEL
973 || insn
!= NEXT_INSN (bb
->head
))
975 e
= split_block (bb
, PREV_INSN (insn
));
976 make_edge (ENTRY_BLOCK_PTR
, e
->dest
, EDGE_FAKE
);
981 /* We should not get abort here, as call to setjmp should not
982 be the very first instruction of function. */
983 if (bb
== ENTRY_BLOCK_PTR
)
985 make_edge (ENTRY_BLOCK_PTR
, bb
, EDGE_FAKE
);
990 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
992 if ((e
->flags
& (EDGE_ABNORMAL
| EDGE_ABNORMAL_CALL
))
993 && e
->dest
!= EXIT_BLOCK_PTR
)
995 if (e
->dest
== EXIT_BLOCK_PTR
)
998 for (e
= bb
->pred
; e
; e
= e
->pred_next
)
1000 if ((e
->flags
& (EDGE_ABNORMAL
| EDGE_ABNORMAL_CALL
))
1001 && e
->src
!= ENTRY_BLOCK_PTR
)
1002 need_entry_edge
= 1;
1003 if (e
->src
== ENTRY_BLOCK_PTR
)
1004 have_entry_edge
= 1;
1007 if (need_exit_edge
&& !have_exit_edge
)
1010 fprintf (rtl_dump_file
, "Adding fake exit edge to bb %i\n",
1012 make_edge (bb
, EXIT_BLOCK_PTR
, EDGE_FAKE
);
1014 if (need_entry_edge
&& !have_entry_edge
)
1017 fprintf (rtl_dump_file
, "Adding fake entry edge to bb %i\n",
1019 make_edge (ENTRY_BLOCK_PTR
, bb
, EDGE_FAKE
);
1023 el
= create_edge_list ();
1024 num_edges
= NUM_EDGES (el
);
1025 alloc_aux_for_edges (sizeof (struct edge_info
));
1027 /* The basic blocks are expected to be numbered sequentially. */
1031 for (i
= 0 ; i
< num_edges
; i
++)
1033 edge e
= INDEX_EDGE (el
, i
);
1036 /* Mark edges we've replaced by fake edges above as ignored. */
1037 if ((e
->flags
& (EDGE_ABNORMAL
| EDGE_ABNORMAL_CALL
))
1038 && e
->src
!= ENTRY_BLOCK_PTR
&& e
->dest
!= EXIT_BLOCK_PTR
)
1040 EDGE_INFO (e
)->ignore
= 1;
1045 #ifdef ENABLE_CHECKING
1046 verify_flow_info ();
1049 /* Create spanning tree from basic block graph, mark each edge that is
1050 on the spanning tree. We insert as many abnormal and critical edges
1051 as possible to minimize number of edge splits necessary. */
1053 find_spanning_tree (el
);
1055 /* Fake edges that are not on the tree will not be instrumented, so
1056 mark them ignored. */
1057 for (i
= 0; i
< num_edges
; i
++)
1059 edge e
= INDEX_EDGE (el
, i
);
1060 struct edge_info
*inf
= EDGE_INFO (e
);
1061 if ((e
->flags
& EDGE_FAKE
) && !inf
->ignore
&& !inf
->on_tree
)
1068 total_num_blocks
+= n_basic_blocks
+ 2;
1070 fprintf (rtl_dump_file
, "%d basic blocks\n", n_basic_blocks
);
1072 total_num_edges
+= num_edges
;
1074 fprintf (rtl_dump_file
, "%d edges\n", num_edges
);
1076 total_num_edges_ignored
+= ignored_edges
;
1078 fprintf (rtl_dump_file
, "%d ignored edges\n", ignored_edges
);
1080 /* Create a .bbg file from which gcov can reconstruct the basic block
1081 graph. First output the number of basic blocks, and then for every
1082 edge output the source and target basic block numbers.
1083 NOTE: The format of this file must be compatible with gcov. */
1085 if (flag_test_coverage
&& bbg_file
)
1089 /* Announce function */
1090 if (gcov_write_unsigned (bbg_file
, GCOV_TAG_FUNCTION
)
1091 || !(offset
= gcov_reserve_length (bbg_file
))
1092 || gcov_write_string (bbg_file
, name
,
1094 || gcov_write_unsigned (bbg_file
,
1095 profile_info
.current_function_cfg_checksum
)
1096 || gcov_write_length (bbg_file
, offset
))
1099 /* Basic block flags */
1100 if (gcov_write_unsigned (bbg_file
, GCOV_TAG_BLOCKS
)
1101 || !(offset
= gcov_reserve_length (bbg_file
)))
1103 for (i
= 0; i
!= (unsigned) (n_basic_blocks
+ 2); i
++)
1104 if (gcov_write_unsigned (bbg_file
, 0))
1106 if (gcov_write_length (bbg_file
, offset
))
1110 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, EXIT_BLOCK_PTR
, next_bb
)
1114 if (gcov_write_unsigned (bbg_file
, GCOV_TAG_ARCS
)
1115 || !(offset
= gcov_reserve_length (bbg_file
))
1116 || gcov_write_unsigned (bbg_file
, BB_TO_GCOV_INDEX (bb
)))
1119 for (e
= bb
->succ
; e
; e
= e
->succ_next
)
1121 struct edge_info
*i
= EDGE_INFO (e
);
1124 unsigned flag_bits
= 0;
1127 flag_bits
|= GCOV_ARC_ON_TREE
;
1128 if (e
->flags
& EDGE_FAKE
)
1129 flag_bits
|= GCOV_ARC_FAKE
;
1130 if (e
->flags
& EDGE_FALLTHRU
)
1131 flag_bits
|= GCOV_ARC_FALLTHROUGH
;
1133 if (gcov_write_unsigned (bbg_file
,
1134 BB_TO_GCOV_INDEX (e
->dest
))
1135 || gcov_write_unsigned (bbg_file
, flag_bits
))
1140 if (gcov_write_length (bbg_file
, offset
))
1144 /* Output line number information about each basic block for
1147 char const *prev_file_name
= NULL
;
1151 rtx insn
= bb
->head
;
1152 int ignore_next_note
= 0;
1156 /* We are looking for line number notes. Search backward
1157 before basic block to find correct ones. */
1158 insn
= prev_nonnote_insn (insn
);
1160 insn
= get_insns ();
1162 insn
= NEXT_INSN (insn
);
1164 while (insn
!= bb
->end
)
1166 if (GET_CODE (insn
) == NOTE
)
1168 /* Must ignore the line number notes that immediately
1169 follow the end of an inline function to avoid counting
1170 it twice. There is a note before the call, and one
1172 if (NOTE_LINE_NUMBER (insn
)
1173 == NOTE_INSN_REPEATED_LINE_NUMBER
)
1174 ignore_next_note
= 1;
1175 else if (NOTE_LINE_NUMBER (insn
) <= 0)
1177 else if (ignore_next_note
)
1178 ignore_next_note
= 0;
1183 else if (gcov_write_unsigned (bbg_file
, GCOV_TAG_LINES
)
1184 || !(offset
= gcov_reserve_length (bbg_file
))
1185 || gcov_write_unsigned (bbg_file
,
1186 BB_TO_GCOV_INDEX (bb
)))
1188 /* If this is a new source file, then output
1189 the file's name to the .bb file. */
1191 || strcmp (NOTE_SOURCE_FILE (insn
),
1194 prev_file_name
= NOTE_SOURCE_FILE (insn
);
1195 if (gcov_write_unsigned (bbg_file
, 0)
1196 || gcov_write_string (bbg_file
, prev_file_name
,
1197 strlen (prev_file_name
)))
1200 if (gcov_write_unsigned (bbg_file
, NOTE_LINE_NUMBER (insn
)))
1204 insn
= NEXT_INSN (insn
);
1209 if (gcov_write_unsigned (bbg_file
, 0)
1210 || gcov_write_string (bbg_file
, NULL
, 0)
1211 || gcov_write_length (bbg_file
, offset
))
1214 warning ("error writing `%s'", bbg_file_name
);
1223 if (flag_branch_probabilities
)
1224 compute_branch_probabilities ();
1226 /* For each edge not on the spanning tree, add counting code as rtl. */
1228 if (cfun
->arc_profile
&& profile_arc_flag
)
1230 struct function_list
*item
;
1232 instrument_edges (el
);
1234 /* Commit changes done by instrumentation. */
1235 commit_edge_insertions_watch_calls ();
1236 allocate_reg_info (max_reg_num (), FALSE
, FALSE
);
1238 /* ??? Probably should re-use the existing struct function. */
1239 item
= xmalloc (sizeof (struct function_list
));
1241 *functions_tail
= item
;
1242 functions_tail
= &item
->next
;
1245 item
->name
= xstrdup (name
);
1246 item
->cfg_checksum
= profile_info
.current_function_cfg_checksum
;
1247 item
->n_counter_sections
= 0;
1248 for (i
= 0; i
< profile_info
.n_sections
; i
++)
1249 if (profile_info
.section_info
[i
].n_counters_now
)
1251 item
->counter_sections
[item
->n_counter_sections
].tag
=
1252 profile_info
.section_info
[i
].tag
;
1253 item
->counter_sections
[item
->n_counter_sections
].n_counters
=
1254 profile_info
.section_info
[i
].n_counters_now
;
1255 item
->n_counter_sections
++;
1259 remove_fake_edges ();
1260 free_aux_for_edges ();
1261 /* Re-merge split basic blocks and the mess introduced by
1262 insert_insn_on_edge. */
1263 cleanup_cfg (profile_arc_flag
? CLEANUP_EXPENSIVE
: 0);
1265 dump_flow_info (rtl_dump_file
);
1267 free_edge_list (el
);
1270 /* Union find algorithm implementation for the basic blocks using
1277 basic_block group
= bb
, bb1
;
1279 while ((basic_block
) group
->aux
!= group
)
1280 group
= (basic_block
) group
->aux
;
1282 /* Compress path. */
1283 while ((basic_block
) bb
->aux
!= group
)
1285 bb1
= (basic_block
) bb
->aux
;
1286 bb
->aux
= (void *) group
;
1293 union_groups (bb1
, bb2
)
1294 basic_block bb1
, bb2
;
1296 basic_block bb1g
= find_group (bb1
);
1297 basic_block bb2g
= find_group (bb2
);
1299 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
1300 this code is unlikely going to be performance problem anyway. */
1307 /* This function searches all of the edges in the program flow graph, and puts
1308 as many bad edges as possible onto the spanning tree. Bad edges include
1309 abnormals edges, which can't be instrumented at the moment. Since it is
1310 possible for fake edges to form a cycle, we will have to develop some
1311 better way in the future. Also put critical edges to the tree, since they
1312 are more expensive to instrument. */
1315 find_spanning_tree (el
)
1316 struct edge_list
*el
;
1319 int num_edges
= NUM_EDGES (el
);
1322 /* We use aux field for standard union-find algorithm. */
1323 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_bb
)
1326 /* Add fake edge exit to entry we can't instrument. */
1327 union_groups (EXIT_BLOCK_PTR
, ENTRY_BLOCK_PTR
);
1329 /* First add all abnormal edges to the tree unless they form a cycle. Also
1330 add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1331 setting return value from function. */
1332 for (i
= 0; i
< num_edges
; i
++)
1334 edge e
= INDEX_EDGE (el
, i
);
1335 if (((e
->flags
& (EDGE_ABNORMAL
| EDGE_ABNORMAL_CALL
| EDGE_FAKE
))
1336 || e
->dest
== EXIT_BLOCK_PTR
1338 && !EDGE_INFO (e
)->ignore
1339 && (find_group (e
->src
) != find_group (e
->dest
)))
1342 fprintf (rtl_dump_file
, "Abnormal edge %d to %d put to tree\n",
1343 e
->src
->index
, e
->dest
->index
);
1344 EDGE_INFO (e
)->on_tree
= 1;
1345 union_groups (e
->src
, e
->dest
);
1349 /* Now insert all critical edges to the tree unless they form a cycle. */
1350 for (i
= 0; i
< num_edges
; i
++)
1352 edge e
= INDEX_EDGE (el
, i
);
1353 if ((EDGE_CRITICAL_P (e
))
1354 && !EDGE_INFO (e
)->ignore
1355 && (find_group (e
->src
) != find_group (e
->dest
)))
1358 fprintf (rtl_dump_file
, "Critical edge %d to %d put to tree\n",
1359 e
->src
->index
, e
->dest
->index
);
1360 EDGE_INFO (e
)->on_tree
= 1;
1361 union_groups (e
->src
, e
->dest
);
1365 /* And now the rest. */
1366 for (i
= 0; i
< num_edges
; i
++)
1368 edge e
= INDEX_EDGE (el
, i
);
1369 if (find_group (e
->src
) != find_group (e
->dest
)
1370 && !EDGE_INFO (e
)->ignore
)
1373 fprintf (rtl_dump_file
, "Normal edge %d to %d put to tree\n",
1374 e
->src
->index
, e
->dest
->index
);
1375 EDGE_INFO (e
)->on_tree
= 1;
1376 union_groups (e
->src
, e
->dest
);
1380 FOR_BB_BETWEEN (bb
, ENTRY_BLOCK_PTR
, NULL
, next_bb
)
1384 /* Perform file-level initialization for branch-prob processing. */
1387 init_branch_prob (filename
)
1388 const char *filename
;
1390 int len
= strlen (filename
);
1393 if (flag_test_coverage
)
1395 /* Open the bbg output file. */
1396 bbg_file_name
= (char *) xmalloc (len
+ strlen (GCOV_GRAPH_SUFFIX
) + 1);
1397 strcpy (bbg_file_name
, filename
);
1398 strcat (bbg_file_name
, GCOV_GRAPH_SUFFIX
);
1399 bbg_file
= fopen (bbg_file_name
, "wb");
1401 fatal_io_error ("cannot open %s", bbg_file_name
);
1403 if (gcov_write_unsigned (bbg_file
, GCOV_GRAPH_MAGIC
)
1404 || gcov_write_unsigned (bbg_file
, GCOV_VERSION
))
1407 fatal_io_error ("cannot write `%s'", bbg_file_name
);
1411 da_file_name
= (char *) xmalloc (len
+ strlen (GCOV_DATA_SUFFIX
) + 1);
1412 strcpy (da_file_name
, filename
);
1413 strcat (da_file_name
, GCOV_DATA_SUFFIX
);
1415 if (flag_branch_probabilities
)
1417 da_file
= fopen (da_file_name
, "rb");
1419 warning ("file %s not found, execution counts assumed to be zero",
1421 if (counts_file_index
&& strcmp (da_file_name
, counts_file_name
))
1422 cleanup_counts_index (0);
1423 if (index_counts_file ())
1424 counts_file_name
= xstrdup (da_file_name
);
1427 if (profile_arc_flag
)
1429 /* Generate and save a copy of this so it can be shared. */
1432 ASM_GENERATE_INTERNAL_LABEL (buf
, "LPBX", 2);
1433 profiler_label
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
1436 total_num_blocks
= 0;
1437 total_num_edges
= 0;
1438 total_num_edges_ignored
= 0;
1439 total_num_edges_instrumented
= 0;
1440 total_num_blocks_created
= 0;
1441 total_num_passes
= 0;
1442 total_num_times_called
= 0;
1443 total_num_branches
= 0;
1444 total_num_never_executed
= 0;
1445 for (i
= 0; i
< 20; i
++)
1446 total_hist_br_prob
[i
] = 0;
1449 /* Performs file-level cleanup after branch-prob processing
1455 if (flag_test_coverage
)
1460 /* If the compiler is instrumented, we should not remove the
1461 counts file, because we might be recompiling
1462 ourselves. The .da files are all removed during copying
1463 the stage1 files. */
1464 unlink (da_file_name
);
1470 unlink (bbg_file_name
);
1471 unlink (da_file_name
);
1480 fprintf (rtl_dump_file
, "\n");
1481 fprintf (rtl_dump_file
, "Total number of blocks: %d\n",
1483 fprintf (rtl_dump_file
, "Total number of edges: %d\n", total_num_edges
);
1484 fprintf (rtl_dump_file
, "Total number of ignored edges: %d\n",
1485 total_num_edges_ignored
);
1486 fprintf (rtl_dump_file
, "Total number of instrumented edges: %d\n",
1487 total_num_edges_instrumented
);
1488 fprintf (rtl_dump_file
, "Total number of blocks created: %d\n",
1489 total_num_blocks_created
);
1490 fprintf (rtl_dump_file
, "Total number of graph solution passes: %d\n",
1492 if (total_num_times_called
!= 0)
1493 fprintf (rtl_dump_file
, "Average number of graph solution passes: %d\n",
1494 (total_num_passes
+ (total_num_times_called
>> 1))
1495 / total_num_times_called
);
1496 fprintf (rtl_dump_file
, "Total number of branches: %d\n",
1497 total_num_branches
);
1498 fprintf (rtl_dump_file
, "Total number of branches never executed: %d\n",
1499 total_num_never_executed
);
1500 if (total_num_branches
)
1504 for (i
= 0; i
< 10; i
++)
1505 fprintf (rtl_dump_file
, "%d%% branches in range %d-%d%%\n",
1506 (total_hist_br_prob
[i
] + total_hist_br_prob
[19-i
]) * 100
1507 / total_num_branches
, 5*i
, 5*i
+5);
1512 /* Find (and create if not present) a section with TAG. */
1513 struct section_info
*
1514 find_counters_section (tag
)
1519 for (i
= 0; i
< profile_info
.n_sections
; i
++)
1520 if (profile_info
.section_info
[i
].tag
== tag
)
1521 return profile_info
.section_info
+ i
;
1523 if (i
== MAX_COUNTER_SECTIONS
)
1526 profile_info
.section_info
[i
].tag
= tag
;
1527 profile_info
.section_info
[i
].present
= 0;
1528 profile_info
.section_info
[i
].n_counters
= 0;
1529 profile_info
.section_info
[i
].n_counters_now
= 0;
1530 profile_info
.n_sections
++;
1532 return profile_info
.section_info
+ i
;
1535 /* Set FIELDS as purpose to VALUE. */
1537 set_purpose (value
, fields
)
1541 tree act_field
, act_value
;
1543 for (act_field
= fields
, act_value
= value
;
1545 act_field
= TREE_CHAIN (act_field
), act_value
= TREE_CHAIN (act_value
))
1546 TREE_PURPOSE (act_value
) = act_field
;
1549 /* Returns label for base of counters inside TAG section. */
1556 case GCOV_TAG_ARC_COUNTS
:
1557 return profiler_label
;
1563 /* Creates fields of struct counter_section (in gcov-io.h). */
1565 build_counter_section_fields ()
1570 fields
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
1573 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
1574 TREE_CHAIN (field
) = fields
;
1580 /* Creates value of struct counter_section (in gcov-io.h). */
1582 build_counter_section_value (tag
, n_counters
)
1584 unsigned n_counters
;
1586 tree value
= NULL_TREE
;
1589 value
= tree_cons (NULL_TREE
,
1590 convert (unsigned_type_node
,
1591 build_int_2 (tag
, 0)),
1595 value
= tree_cons (NULL_TREE
,
1596 convert (unsigned_type_node
,
1597 build_int_2 (n_counters
, 0)),
1603 /* Creates fields of struct counter_section_data (in gcov-io.h). */
1605 build_counter_section_data_fields ()
1607 tree field
, fields
, gcov_type
, gcov_ptr_type
;
1609 gcov_type
= make_signed_type (GCOV_TYPE_SIZE
);
1611 build_pointer_type (build_qualified_type (gcov_type
,
1615 fields
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
1618 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
1619 TREE_CHAIN (field
) = fields
;
1623 field
= build_decl (FIELD_DECL
, NULL_TREE
, gcov_ptr_type
);
1624 TREE_CHAIN (field
) = fields
;
1630 /* Creates value of struct counter_section_data (in gcov-io.h). */
1632 build_counter_section_data_value (tag
, n_counters
)
1634 unsigned n_counters
;
1636 tree value
= NULL_TREE
, counts_table
, gcov_type
, gcov_ptr_type
;
1638 gcov_type
= make_signed_type (GCOV_TYPE_SIZE
);
1640 = build_pointer_type (build_qualified_type
1641 (gcov_type
, TYPE_QUAL_CONST
));
1644 value
= tree_cons (NULL_TREE
,
1645 convert (unsigned_type_node
,
1646 build_int_2 (tag
, 0)),
1650 value
= tree_cons (NULL_TREE
,
1651 convert (unsigned_type_node
,
1652 build_int_2 (n_counters
, 0)),
1658 tree gcov_type_array_type
=
1659 build_array_type (gcov_type
,
1660 build_index_type (build_int_2 (n_counters
- 1,
1663 build (VAR_DECL
, gcov_type_array_type
, NULL_TREE
, NULL_TREE
);
1664 TREE_STATIC (counts_table
) = 1;
1665 DECL_NAME (counts_table
) = get_identifier (XSTR (label_for_tag (tag
), 0));
1666 assemble_variable (counts_table
, 0, 0, 0);
1667 counts_table
= build1 (ADDR_EXPR
, gcov_ptr_type
, counts_table
);
1670 counts_table
= null_pointer_node
;
1672 value
= tree_cons (NULL_TREE
, counts_table
, value
);
1677 /* Creates fields for struct function_info type (in gcov-io.h). */
1679 build_function_info_fields ()
1681 tree field
, fields
, counter_section_fields
, counter_section_type
;
1682 tree counter_sections_ptr_type
;
1684 build_pointer_type (build_qualified_type (char_type_node
,
1687 fields
= build_decl (FIELD_DECL
, NULL_TREE
, string_type
);
1690 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
1691 TREE_CHAIN (field
) = fields
;
1694 /* n_counter_sections */
1695 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
1696 TREE_CHAIN (field
) = fields
;
1699 /* counter_sections */
1700 counter_section_fields
= build_counter_section_fields ();
1701 counter_section_type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
1702 finish_builtin_struct (counter_section_type
, "__counter_section",
1703 counter_section_fields
, NULL_TREE
);
1704 counter_sections_ptr_type
=
1706 (build_qualified_type (counter_section_type
,
1708 field
= build_decl (FIELD_DECL
, NULL_TREE
, counter_sections_ptr_type
);
1709 TREE_CHAIN (field
) = fields
;
1715 /* Creates value for struct function_info (in gcov-io.h). */
1717 build_function_info_value (function
)
1718 struct function_list
*function
;
1720 tree value
= NULL_TREE
;
1721 size_t name_len
= strlen (function
->name
);
1722 tree fname
= build_string (name_len
+ 1, function
->name
);
1724 build_pointer_type (build_qualified_type (char_type_node
,
1726 tree counter_section_fields
, counter_section_type
, counter_sections_value
;
1727 tree counter_sections_ptr_type
, counter_sections_array_type
;
1732 build_array_type (char_type_node
,
1733 build_index_type (build_int_2 (name_len
, 0)));
1734 value
= tree_cons (NULL_TREE
,
1741 value
= tree_cons (NULL_TREE
,
1742 convert (unsigned_type_node
,
1743 build_int_2 (function
->cfg_checksum
, 0)),
1746 /* n_counter_sections */
1748 value
= tree_cons (NULL_TREE
,
1749 convert (unsigned_type_node
,
1750 build_int_2 (function
->n_counter_sections
, 0)),
1753 /* counter_sections */
1754 counter_section_fields
= build_counter_section_fields ();
1755 counter_section_type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
1756 counter_sections_ptr_type
=
1758 (build_qualified_type (counter_section_type
,
1760 counter_sections_array_type
=
1761 build_array_type (counter_section_type
,
1763 build_int_2 (function
->n_counter_sections
- 1,
1766 counter_sections_value
= NULL_TREE
;
1767 for (i
= 0; i
< function
->n_counter_sections
; i
++)
1769 tree counter_section_value
=
1770 build_counter_section_value (function
->counter_sections
[i
].tag
,
1771 function
->counter_sections
[i
].n_counters
);
1772 set_purpose (counter_section_value
, counter_section_fields
);
1773 counter_sections_value
= tree_cons (NULL_TREE
,
1775 counter_section_type
,
1777 nreverse (counter_section_value
)),
1778 counter_sections_value
);
1780 finish_builtin_struct (counter_section_type
, "__counter_section",
1781 counter_section_fields
, NULL_TREE
);
1783 if (function
->n_counter_sections
)
1785 counter_sections_value
=
1787 counter_sections_array_type
,
1789 nreverse (counter_sections_value
)),
1790 counter_sections_value
= build1 (ADDR_EXPR
,
1791 counter_sections_ptr_type
,
1792 counter_sections_value
);
1795 counter_sections_value
= null_pointer_node
;
1797 value
= tree_cons (NULL_TREE
, counter_sections_value
, value
);
1802 /* Creates fields of struct gcov_info type (in gcov-io.h). */
1804 build_gcov_info_fields (gcov_info_type
)
1805 tree gcov_info_type
;
1811 build_pointer_type (build_qualified_type (char_type_node
,
1813 tree function_info_fields
, function_info_type
, function_info_ptr_type
;
1814 tree counter_section_data_fields
, counter_section_data_type
;
1815 tree counter_section_data_ptr_type
;
1818 fields
= build_decl (FIELD_DECL
, NULL_TREE
, long_unsigned_type_node
);
1821 field
= build_decl (FIELD_DECL
, NULL_TREE
,
1822 build_pointer_type (build_qualified_type (gcov_info_type
,
1824 TREE_CHAIN (field
) = fields
;
1828 filename
= getpwd ();
1829 filename
= (filename
&& da_file_name
[0] != '/'
1830 ? concat (filename
, "/", da_file_name
, NULL
)
1832 filename_len
= strlen (filename
);
1833 if (filename
!= da_file_name
)
1836 field
= build_decl (FIELD_DECL
, NULL_TREE
, string_type
);
1837 TREE_CHAIN (field
) = fields
;
1841 field
= build_decl (FIELD_DECL
, NULL_TREE
, long_integer_type_node
);
1842 TREE_CHAIN (field
) = fields
;
1845 /* number of functions */
1846 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
1847 TREE_CHAIN (field
) = fields
;
1850 /* function_info table */
1851 function_info_fields
= build_function_info_fields ();
1852 function_info_type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
1853 finish_builtin_struct (function_info_type
, "__function_info",
1854 function_info_fields
, NULL_TREE
);
1855 function_info_ptr_type
=
1857 (build_qualified_type (function_info_type
,
1859 field
= build_decl (FIELD_DECL
, NULL_TREE
, function_info_ptr_type
);
1860 TREE_CHAIN (field
) = fields
;
1863 /* n_counter_sections */
1864 field
= build_decl (FIELD_DECL
, NULL_TREE
, unsigned_type_node
);
1865 TREE_CHAIN (field
) = fields
;
1868 /* counter sections */
1869 counter_section_data_fields
= build_counter_section_data_fields ();
1870 counter_section_data_type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
1871 finish_builtin_struct (counter_section_data_type
, "__counter_section_data",
1872 counter_section_data_fields
, NULL_TREE
);
1873 counter_section_data_ptr_type
=
1875 (build_qualified_type (counter_section_data_type
,
1877 field
= build_decl (FIELD_DECL
, NULL_TREE
, counter_section_data_ptr_type
);
1878 TREE_CHAIN (field
) = fields
;
1884 /* Creates struct gcov_info value (in gcov-io.h). */
1886 build_gcov_info_value ()
1888 tree value
= NULL_TREE
;
1889 tree filename_string
;
1892 unsigned n_functions
, i
;
1893 struct function_list
*item
;
1895 build_pointer_type (build_qualified_type (char_type_node
,
1897 tree function_info_fields
, function_info_type
, function_info_ptr_type
;
1899 tree counter_section_data_fields
, counter_section_data_type
;
1900 tree counter_section_data_ptr_type
, counter_sections
;
1903 value
= tree_cons (NULL_TREE
,
1904 convert (long_unsigned_type_node
,
1905 build_int_2 (GCOV_VERSION
, 0)),
1909 value
= tree_cons (NULL_TREE
, null_pointer_node
, value
);
1912 filename
= getpwd ();
1913 filename
= (filename
&& da_file_name
[0] != '/'
1914 ? concat (filename
, "/", da_file_name
, NULL
)
1916 filename_len
= strlen (filename
);
1917 filename_string
= build_string (filename_len
+ 1, filename
);
1918 if (filename
!= da_file_name
)
1920 TREE_TYPE (filename_string
) =
1921 build_array_type (char_type_node
,
1922 build_index_type (build_int_2 (filename_len
, 0)));
1923 value
= tree_cons (NULL_TREE
,
1930 value
= tree_cons (NULL_TREE
,
1931 convert (long_integer_type_node
, integer_zero_node
),
1934 /* number of functions */
1936 for (item
= functions_head
; item
!= 0; item
= item
->next
, n_functions
++)
1938 value
= tree_cons (NULL_TREE
,
1939 convert (unsigned_type_node
,
1940 build_int_2 (n_functions
, 0)),
1943 /* function_info table */
1944 function_info_fields
= build_function_info_fields ();
1945 function_info_type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
1946 function_info_ptr_type
=
1947 build_pointer_type (
1948 build_qualified_type (function_info_type
,
1950 functions
= NULL_TREE
;
1951 for (item
= functions_head
; item
!= 0; item
= item
->next
)
1953 tree function_info_value
= build_function_info_value (item
);
1954 set_purpose (function_info_value
, function_info_fields
);
1955 functions
= tree_cons (NULL_TREE
,
1959 nreverse (function_info_value
)),
1962 finish_builtin_struct (function_info_type
, "__function_info",
1963 function_info_fields
, NULL_TREE
);
1965 /* Create constructor for array. */
1970 array_type
= build_array_type (
1972 build_index_type (build_int_2 (n_functions
- 1, 0)));
1973 functions
= build (CONSTRUCTOR
,
1976 nreverse (functions
));
1977 functions
= build1 (ADDR_EXPR
,
1978 function_info_ptr_type
,
1982 functions
= null_pointer_node
;
1984 value
= tree_cons (NULL_TREE
, functions
, value
);
1986 /* n_counter_sections */
1987 value
= tree_cons (NULL_TREE
,
1988 convert (unsigned_type_node
,
1989 build_int_2 (profile_info
.n_sections
, 0)),
1992 /* counter sections */
1993 counter_section_data_fields
= build_counter_section_data_fields ();
1994 counter_section_data_type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
1995 counter_sections
= NULL_TREE
;
1996 for (i
= 0; i
< profile_info
.n_sections
; i
++)
1998 tree counter_sections_value
=
1999 build_counter_section_data_value (
2000 profile_info
.section_info
[i
].tag
,
2001 profile_info
.section_info
[i
].n_counters
);
2002 set_purpose (counter_sections_value
, counter_section_data_fields
);
2003 counter_sections
= tree_cons (NULL_TREE
,
2005 counter_section_data_type
,
2007 nreverse (counter_sections_value
)),
2010 finish_builtin_struct (counter_section_data_type
, "__counter_section_data",
2011 counter_section_data_fields
, NULL_TREE
);
2012 counter_section_data_ptr_type
=
2014 (build_qualified_type (counter_section_data_type
,
2017 if (profile_info
.n_sections
)
2022 counter_section_data_type
,
2023 build_index_type (build_int_2 (profile_info
.n_sections
- 1, 0))),
2025 nreverse (counter_sections
));
2026 counter_sections
= build1 (ADDR_EXPR
,
2027 counter_section_data_ptr_type
,
2031 counter_sections
= null_pointer_node
;
2032 value
= tree_cons (NULL_TREE
, counter_sections
, value
);
2037 /* Write out the structure which libgcc uses to locate all the arc
2038 counters. The structures used here must match those defined in
2039 gcov-io.h. Write out the constructor to call __gcov_init. */
2044 tree gcov_info_fields
, gcov_info_type
, gcov_info_value
, gcov_info
;
2048 rtx gcov_info_address
;
2049 int save_flag_inline_functions
= flag_inline_functions
;
2052 for (i
= 0; i
< profile_info
.n_sections
; i
++)
2053 if (profile_info
.section_info
[i
].n_counters_now
)
2055 if (i
== profile_info
.n_sections
)
2058 gcov_info_type
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
2059 gcov_info_fields
= build_gcov_info_fields (gcov_info_type
);
2060 gcov_info_value
= build_gcov_info_value ();
2061 set_purpose (gcov_info_value
, gcov_info_fields
);
2062 finish_builtin_struct (gcov_info_type
, "__gcov_info",
2063 gcov_info_fields
, NULL_TREE
);
2065 gcov_info
= build (VAR_DECL
, gcov_info_type
, NULL_TREE
, NULL_TREE
);
2066 DECL_INITIAL (gcov_info
) =
2067 build (CONSTRUCTOR
, gcov_info_type
, NULL_TREE
,
2068 nreverse (gcov_info_value
));
2070 TREE_STATIC (gcov_info
) = 1;
2071 ASM_GENERATE_INTERNAL_LABEL (name
, "LPBX", 0);
2072 DECL_NAME (gcov_info
) = get_identifier (name
);
2074 /* Build structure. */
2075 assemble_variable (gcov_info
, 0, 0, 0);
2077 /* Build the constructor function to invoke __gcov_init. */
2078 ctor_name
= concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
2080 ctor
= build_decl (FUNCTION_DECL
, get_identifier (ctor_name
),
2081 build_function_type (void_type_node
, NULL_TREE
));
2083 DECL_EXTERNAL (ctor
) = 0;
2085 /* It can be a static function as long as collect2 does not have
2086 to scan the object file to find its ctor/dtor routine. */
2087 TREE_PUBLIC (ctor
) = ! targetm
.have_ctors_dtors
;
2088 TREE_USED (ctor
) = 1;
2089 DECL_RESULT (ctor
) = build_decl (RESULT_DECL
, NULL_TREE
, void_type_node
);
2091 ctor
= (*lang_hooks
.decls
.pushdecl
) (ctor
);
2092 rest_of_decl_compilation (ctor
, 0, 1, 0);
2093 announce_function (ctor
);
2094 current_function_decl
= ctor
;
2095 DECL_INITIAL (ctor
) = error_mark_node
;
2096 make_decl_rtl (ctor
, NULL
);
2097 init_function_start (ctor
, input_filename
, lineno
);
2098 (*lang_hooks
.decls
.pushlevel
) (0);
2099 expand_function_start (ctor
, 0);
2100 cfun
->arc_profile
= 0;
2102 /* Actually generate the code to call __gcov_init. */
2103 gcov_info_address
= force_reg (Pmode
,
2104 gen_rtx_SYMBOL_REF (
2106 IDENTIFIER_POINTER (
2107 DECL_NAME (gcov_info
))));
2108 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__gcov_init"),
2109 LCT_NORMAL
, VOIDmode
, 1,
2110 gcov_info_address
, Pmode
);
2112 expand_function_end (input_filename
, lineno
, 0);
2113 (*lang_hooks
.decls
.poplevel
) (1, 0, 1);
2115 /* Since ctor isn't in the list of globals, it would never be emitted
2116 when it's considered to be 'safe' for inlining, so turn off
2117 flag_inline_functions. */
2118 flag_inline_functions
= 0;
2120 rest_of_compilation (ctor
);
2122 /* Reset flag_inline_functions to its original value. */
2123 flag_inline_functions
= save_flag_inline_functions
;
2126 fflush (asm_out_file
);
2127 current_function_decl
= NULL_TREE
;
2129 if (targetm
.have_ctors_dtors
)
2130 (* targetm
.asm_out
.constructor
) (XEXP (DECL_RTL (ctor
), 0),
2131 DEFAULT_INIT_PRIORITY
);
2134 /* Output instructions as RTL to increment the edge execution count. */
2137 gen_edge_profiler (edgeno
)
2140 enum machine_mode mode
= mode_for_size (GCOV_TYPE_SIZE
, MODE_INT
, 0);
2146 tmp
= force_reg (Pmode
, profiler_label
);
2147 tmp
= plus_constant (tmp
, GCOV_TYPE_SIZE
/ BITS_PER_UNIT
* edgeno
);
2148 mem_ref
= validize_mem (gen_rtx_MEM (mode
, tmp
));
2150 set_mem_alias_set (mem_ref
, new_alias_set ());
2152 tmp
= expand_simple_binop (mode
, PLUS
, mem_ref
, const1_rtx
,
2153 mem_ref
, 0, OPTAB_WIDEN
);
2156 emit_move_insn (copy_rtx (mem_ref
), tmp
);
2158 sequence
= get_insns ();
2163 #include "gt-profile.h"