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];
105 /* Counts information for a function. */
106 typedef struct counts_entry
117 gcov_type max_counter;
118 gcov_type max_counter_sum;
121 struct counts_entry *chain;
125 static struct function_list *functions_head = 0;
126 static struct function_list **functions_tail = &functions_head;
128 #define EDGE_INFO(e) ((struct edge_info *) (e)->aux)
129 #define BB_INFO(b) ((struct bb_info *) (b)->aux)
131 /* Keep all basic block indexes nonnegative in the gcov output. Index 0
132 is used for entry block, last block exit block. */
133 #define BB_TO_GCOV_INDEX(bb) ((bb) == ENTRY_BLOCK_PTR ? 0 \
134 : ((bb) == EXIT_BLOCK_PTR \
135 ? last_basic_block + 1 : (bb)->index + 1))
137 /* Instantiate the profile info structure. */
139 struct profile_info profile_info;
141 /* Name and file pointer of the output file for the basic block graph. */
143 static char *bbg_file_name;
145 /* Name and file pointer of the input file for the arc count data. */
147 static char *da_file_name;
149 /* The name of the count table. Used by the edge profiling code. */
150 static GTY(()) rtx profiler_label;
152 /* Collect statistics on the performance of this pass for the entire source
155 static int total_num_blocks;
156 static int total_num_edges;
157 static int total_num_edges_ignored;
158 static int total_num_edges_instrumented;
159 static int total_num_blocks_created;
160 static int total_num_passes;
161 static int total_num_times_called;
162 static int total_hist_br_prob[20];
163 static int total_num_never_executed;
164 static int total_num_branches;
166 /* Forward declarations. */
167 static void find_spanning_tree PARAMS ((struct edge_list *));
168 static rtx gen_edge_profiler PARAMS ((int));
169 static void instrument_edges PARAMS ((struct edge_list *));
170 static void compute_branch_probabilities PARAMS ((void));
171 static hashval_t htab_counts_entry_hash PARAMS ((const void *));
172 static int htab_counts_entry_eq PARAMS ((const void *, const void *));
173 static void htab_counts_entry_del PARAMS ((void *));
174 static void read_counts_file PARAMS ((const char *));
175 static gcov_type * get_exec_counts PARAMS ((void));
176 static unsigned compute_checksum PARAMS ((void));
177 static basic_block find_group PARAMS ((basic_block));
178 static void union_groups PARAMS ((basic_block, basic_block));
179 static void set_purpose PARAMS ((tree, tree));
180 static rtx label_for_tag PARAMS ((unsigned));
181 static tree build_counter_section_fields PARAMS ((void));
182 static tree build_counter_section_value PARAMS ((unsigned, unsigned));
183 static tree build_counter_section_data_fields PARAMS ((void));
184 static tree build_counter_section_data_value PARAMS ((unsigned, unsigned));
185 static tree build_function_info_fields PARAMS ((void));
186 static tree build_function_info_value PARAMS ((struct function_list *));
187 static tree build_gcov_info_fields PARAMS ((tree));
188 static tree build_gcov_info_value PARAMS ((void));
191 /* Add edge instrumentation code to the entire insn chain.
193 F is the first insn of the chain.
194 NUM_BLOCKS is the number of basic blocks found in F. */
197 instrument_edges (el)
198 struct edge_list *el;
200 int num_instr_edges = 0;
201 int num_edges = NUM_EDGES (el);
203 struct section_info *section_info;
204 remove_fake_edges ();
206 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
211 struct edge_info *inf = EDGE_INFO (e);
212 if (!inf->ignore && !inf->on_tree)
214 if (e->flags & EDGE_ABNORMAL)
217 fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
218 e->src->index, e->dest->index,
219 EDGE_CRITICAL_P (e) ? " (and split)" : "");
220 insert_insn_on_edge (
221 gen_edge_profiler (total_num_edges_instrumented
222 + num_instr_edges++), e);
223 rebuild_jump_labels (e->insns);
229 section_info = find_counters_section (GCOV_TAG_ARC_COUNTS);
230 section_info->n_counters_now = num_instr_edges;
231 total_num_edges_instrumented += num_instr_edges;
232 section_info->n_counters = total_num_edges_instrumented;
234 total_num_blocks_created += num_edges;
236 fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
240 htab_counts_entry_hash (of)
243 const counts_entry_t *entry = of;
245 return htab_hash_string (entry->function_name) ^ entry->section;
249 htab_counts_entry_eq (of1, of2)
253 const counts_entry_t *entry1 = of1;
254 const counts_entry_t *entry2 = of2;
256 return !strcmp (entry1->function_name, entry2->function_name)
257 && entry1->section == entry2->section;
261 htab_counts_entry_del (of)
264 counts_entry_t *entry = of;
266 free (entry->function_name);
267 free (entry->counts);
271 static htab_t counts_hash = NULL;
274 read_counts_file (const char *name)
276 char *function_name_buffer = NULL;
277 unsigned version, ix, checksum;
278 counts_entry_t *summaried = NULL;
279 unsigned seen_summary = 0;
281 if (!gcov_open (name, 1))
283 warning ("file %s not found, execution counts assumed to be zero", name);
287 if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
289 warning ("`%s' is not a gcov data file", name);
293 else if ((version = gcov_read_unsigned ()) != GCOV_VERSION)
296 unsigned required = GCOV_VERSION;
298 for (ix = 4; ix--; required >>= 8, version >>= 8)
303 warning ("`%s' is version `%.4s', expected version `%.4s'", name, v, e);
308 counts_hash = htab_create (10,
309 htab_counts_entry_hash, htab_counts_entry_eq,
310 htab_counts_entry_del);
311 while (!gcov_is_eof ())
313 unsigned tag, length;
314 unsigned long offset;
317 tag = gcov_read_unsigned ();
318 length = gcov_read_unsigned ();
319 offset = gcov_position ();
320 if (tag == GCOV_TAG_FUNCTION)
322 const char *string = gcov_read_string ();
323 free (function_name_buffer);
324 function_name_buffer = string ? xstrdup (string) : NULL;
325 checksum = gcov_read_unsigned ();
328 /* We have already seen a summary, this means that this
329 new function begins a new set of program runs. We
330 must unlink the summaried chain. */
331 counts_entry_t *entry, *chain;
333 for (entry = summaried; entry; entry = chain)
335 chain = entry->chain;
337 entry->max_counter_sum += entry->max_counter;
344 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
346 counts_entry_t *entry;
347 struct gcov_summary summary;
349 gcov_read_summary (&summary);
351 for (entry = summaried; entry; entry = entry->chain)
353 entry->merged += summary.runs;
354 if (entry->max_counter < summary.arc_sum_max)
355 entry->max_counter = summary.arc_sum_max;
358 else if (GCOV_TAG_IS_SUBTAG (GCOV_TAG_FUNCTION, tag)
359 && function_name_buffer)
361 counts_entry_t **slot, *entry, elt;
362 unsigned n_counts = length / 8;
365 elt.function_name = function_name_buffer;
368 slot = (counts_entry_t **) htab_find_slot
369 (counts_hash, &elt, INSERT);
373 *slot = entry = xmalloc (sizeof (counts_entry_t));
374 entry->function_name = xstrdup (function_name_buffer);
375 entry->section = tag;
376 entry->checksum = checksum;
377 entry->n_counts = n_counts;
378 entry->counts = xcalloc (n_counts, sizeof (gcov_type));
380 else if (entry->checksum != checksum || entry->n_counts != n_counts)
382 warning ("profile mismatch for `%s'", function_name_buffer);
383 htab_delete (counts_hash);
387 /* This should always be true for a just allocated entry,
388 and always false for an existing one. Check this way, in
389 case the gcov file is corrupt. */
390 if (!entry->chain || summaried != entry)
392 entry->chain = summaried;
395 for (ix = 0; ix != n_counts; ix++)
396 entry->counts[ix] += gcov_read_counter ();
398 gcov_seek (offset, length);
399 if ((error = gcov_is_error ()))
401 warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
403 htab_delete (counts_hash);
408 free (function_name_buffer);
412 /* Computes hybrid profile for all matching entries in da_file.
413 Sets max_counter_in_program as a side effect. */
418 unsigned num_edges = 0;
420 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
421 counts_entry_t *entry, elt;
423 profile_info.max_counter_in_program = 0;
424 profile_info.count_profiles_merged = 0;
426 /* No hash table, no counts. */
430 /* Count the edges to be (possibly) instrumented. */
431 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
434 for (e = bb->succ; e; e = e->succ_next)
435 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
439 elt.function_name = (char *) name;
440 elt.section = GCOV_TAG_ARC_COUNTS;
441 entry = htab_find (counts_hash, &elt);
444 warning ("No profile for function '%s' found.", name);
448 if (entry->checksum != profile_info.current_function_cfg_checksum
449 || num_edges != entry->n_counts)
451 warning ("profile mismatch for `%s'", current_function_name);
455 profile_info.count_profiles_merged = entry->merged;
456 profile_info.max_counter_in_program = entry->max_counter_sum;
460 fprintf(rtl_dump_file, "Merged %i profiles with maximal count %i.\n",
461 profile_info.count_profiles_merged,
462 (int)profile_info.max_counter_in_program);
465 return entry->counts;
469 /* Compute the branch probabilities for the various branches.
470 Annotate them accordingly. */
473 compute_branch_probabilities ()
480 int hist_br_prob[20];
481 int num_never_executed;
483 gcov_type *exec_counts = get_exec_counts ();
484 int exec_counts_pos = 0;
486 /* Attach extra info block to each bb. */
488 alloc_aux_for_blocks (sizeof (struct bb_info));
489 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
493 for (e = bb->succ; e; e = e->succ_next)
494 if (!EDGE_INFO (e)->ignore)
495 BB_INFO (bb)->succ_count++;
496 for (e = bb->pred; e; e = e->pred_next)
497 if (!EDGE_INFO (e)->ignore)
498 BB_INFO (bb)->pred_count++;
501 /* Avoid predicting entry on exit nodes. */
502 BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
503 BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
505 /* For each edge not on the spanning tree, set its execution count from
508 /* The first count in the .da file is the number of times that the function
509 was entered. This is the exec_count for block zero. */
511 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
514 for (e = bb->succ; e; e = e->succ_next)
515 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
520 e->count = exec_counts[exec_counts_pos++];
525 EDGE_INFO (e)->count_valid = 1;
526 BB_INFO (bb)->succ_count--;
527 BB_INFO (e->dest)->pred_count--;
530 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
531 bb->index, e->dest->index);
532 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
533 (HOST_WIDEST_INT) e->count);
539 fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
541 /* For every block in the file,
542 - if every exit/entrance edge has a known count, then set the block count
543 - if the block count is known, and every exit/entrance edge but one has
544 a known execution count, then set the count of the remaining edge
546 As edge counts are set, decrement the succ/pred count, but don't delete
547 the edge, that way we can easily tell when all edges are known, or only
548 one edge is unknown. */
550 /* The order that the basic blocks are iterated through is important.
551 Since the code that finds spanning trees starts with block 0, low numbered
552 edges are put on the spanning tree in preference to high numbered edges.
553 Hence, most instrumented edges are at the end. Graph solving works much
554 faster if we propagate numbers from the end to the start.
556 This takes an average of slightly more than 3 passes. */
564 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
566 struct bb_info *bi = BB_INFO (bb);
567 if (! bi->count_valid)
569 if (bi->succ_count == 0)
574 for (e = bb->succ; e; e = e->succ_next)
580 else if (bi->pred_count == 0)
585 for (e = bb->pred; e; e = e->pred_next)
594 if (bi->succ_count == 1)
599 /* One of the counts will be invalid, but it is zero,
600 so adding it in also doesn't hurt. */
601 for (e = bb->succ; e; e = e->succ_next)
604 /* Seedgeh for the invalid edge, and set its count. */
605 for (e = bb->succ; e; e = e->succ_next)
606 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
609 /* Calculate count for remaining edge by conservation. */
610 total = bb->count - total;
614 EDGE_INFO (e)->count_valid = 1;
618 BB_INFO (e->dest)->pred_count--;
621 if (bi->pred_count == 1)
626 /* One of the counts will be invalid, but it is zero,
627 so adding it in also doesn't hurt. */
628 for (e = bb->pred; e; e = e->pred_next)
631 /* Seedgeh for the invalid edge, and set its count. */
632 for (e = bb->pred; e; e = e->pred_next)
633 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
636 /* Calculate count for remaining edge by conservation. */
637 total = bb->count - total + e->count;
641 EDGE_INFO (e)->count_valid = 1;
645 BB_INFO (e->src)->succ_count--;
652 dump_flow_info (rtl_dump_file);
654 total_num_passes += passes;
656 fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
658 /* If the graph has been correctly solved, every block will have a
659 succ and pred count of zero. */
662 if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
666 /* For every edge, calculate its branch probability and add a reg_note
667 to the branch insn to indicate this. */
669 for (i = 0; i < 20; i++)
671 num_never_executed = 0;
674 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
683 for (e = bb->succ; e; e = e->succ_next)
685 e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
686 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
688 error ("corrupted profile info: prob for %d-%d thought to be %d",
689 e->src->index, e->dest->index, e->probability);
690 e->probability = REG_BR_PROB_BASE / 2;
694 && any_condjump_p (bb->end)
695 && bb->succ->succ_next)
701 /* Find the branch edge. It is possible that we do have fake
703 for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
705 continue; /* Loop body has been intentionally left blank. */
707 prob = e->probability;
708 index = prob * 20 / REG_BR_PROB_BASE;
712 hist_br_prob[index]++;
714 note = find_reg_note (bb->end, REG_BR_PROB, 0);
715 /* There may be already note put by some other pass, such
716 as builtin_expect expander. */
718 XEXP (note, 0) = GEN_INT (prob);
721 = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
722 REG_NOTES (bb->end));
726 /* Otherwise distribute the probabilities evenly so we get sane
727 sum. Use simple heuristics that if there are normal edges,
728 give all abnormals frequency of 0, otherwise distribute the
729 frequency over abnormals (this is the case of noreturn
733 for (e = bb->succ; e; e = e->succ_next)
734 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
738 for (e = bb->succ; e; e = e->succ_next)
739 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
740 e->probability = REG_BR_PROB_BASE / total;
746 for (e = bb->succ; e; e = e->succ_next)
748 for (e = bb->succ; e; e = e->succ_next)
749 e->probability = REG_BR_PROB_BASE / total;
752 && any_condjump_p (bb->end)
753 && bb->succ->succ_next)
754 num_branches++, num_never_executed;
760 fprintf (rtl_dump_file, "%d branches\n", num_branches);
761 fprintf (rtl_dump_file, "%d branches never executed\n",
764 for (i = 0; i < 10; i++)
765 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
766 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
769 total_num_branches += num_branches;
770 total_num_never_executed += num_never_executed;
771 for (i = 0; i < 20; i++)
772 total_hist_br_prob[i] += hist_br_prob[i];
774 fputc ('\n', rtl_dump_file);
775 fputc ('\n', rtl_dump_file);
778 free_aux_for_blocks ();
779 find_counters_section (GCOV_TAG_ARC_COUNTS)->present = 1;
782 /* Compute checksum for the current function. We generate a CRC32. */
796 unsigned value = BB_TO_GCOV_INDEX (e ? e->dest : bb);
799 /* No need to use all bits in value identically, nearly all
800 functions have less than 256 blocks. */
801 value ^= value << 16;
804 for (ix = 8; ix--; value <<= 1)
808 feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
813 e = e ? e->succ_next : bb->succ;
821 /* Instrument and/or analyze program behavior based on program flow graph.
822 In either case, this function builds a flow graph for the function being
823 compiled. The flow graph is stored in BB_GRAPH.
825 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
826 the flow graph that are needed to reconstruct the dynamic behavior of the
829 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
830 information from a data file containing edge count information from previous
831 executions of the function being compiled. In this case, the flow graph is
832 annotated with actual execution counts, which are later propagated into the
833 rtl for optimization purposes.
835 Main entry point of this file. */
842 unsigned num_edges, ignored_edges;
843 struct edge_list *el;
844 const char *name = IDENTIFIER_POINTER
845 (DECL_ASSEMBLER_NAME (current_function_decl));
847 profile_info.current_function_cfg_checksum = compute_checksum ();
848 for (i = 0; i < profile_info.n_sections; i++)
850 profile_info.section_info[i].n_counters_now = 0;
851 profile_info.section_info[i].present = 0;
855 fprintf (rtl_dump_file, "CFG checksum is %u\n",
856 profile_info.current_function_cfg_checksum);
858 total_num_times_called++;
860 flow_call_edges_add (NULL);
861 add_noreturn_fake_exit_edges ();
863 /* We can't handle cyclic regions constructed using abnormal edges.
864 To avoid these we replace every source of abnormal edge by a fake
865 edge from entry node and every destination by fake edge to exit.
866 This keeps graph acyclic and our calculation exact for all normal
867 edges except for exit and entrance ones.
869 We also add fake exit edges for each call and asm statement in the
870 basic, since it may not return. */
874 int need_exit_edge = 0, need_entry_edge = 0;
875 int have_exit_edge = 0, have_entry_edge = 0;
879 /* Add fake edges from entry block to the call insns that may return
880 twice. The CFG is not quite correct then, as call insn plays more
881 role of CODE_LABEL, but for our purposes, everything should be OK,
882 as we never insert code to the beginning of basic block. */
883 for (insn = bb->head; insn != NEXT_INSN (bb->end);
884 insn = NEXT_INSN (insn))
886 if (GET_CODE (insn) == CALL_INSN
887 && find_reg_note (insn, REG_SETJMP, NULL))
889 if (GET_CODE (bb->head) == CODE_LABEL
890 || insn != NEXT_INSN (bb->head))
892 e = split_block (bb, PREV_INSN (insn));
893 make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
898 /* We should not get abort here, as call to setjmp should not
899 be the very first instruction of function. */
900 if (bb == ENTRY_BLOCK_PTR)
902 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
907 for (e = bb->succ; e; e = e->succ_next)
909 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
910 && e->dest != EXIT_BLOCK_PTR)
912 if (e->dest == EXIT_BLOCK_PTR)
915 for (e = bb->pred; e; e = e->pred_next)
917 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
918 && e->src != ENTRY_BLOCK_PTR)
920 if (e->src == ENTRY_BLOCK_PTR)
924 if (need_exit_edge && !have_exit_edge)
927 fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
929 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
931 if (need_entry_edge && !have_entry_edge)
934 fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
936 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
940 el = create_edge_list ();
941 num_edges = NUM_EDGES (el);
942 alloc_aux_for_edges (sizeof (struct edge_info));
944 /* The basic blocks are expected to be numbered sequentially. */
948 for (i = 0 ; i < num_edges ; i++)
950 edge e = INDEX_EDGE (el, i);
953 /* Mark edges we've replaced by fake edges above as ignored. */
954 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
955 && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
957 EDGE_INFO (e)->ignore = 1;
962 #ifdef ENABLE_CHECKING
966 /* Create spanning tree from basic block graph, mark each edge that is
967 on the spanning tree. We insert as many abnormal and critical edges
968 as possible to minimize number of edge splits necessary. */
970 find_spanning_tree (el);
972 /* Fake edges that are not on the tree will not be instrumented, so
973 mark them ignored. */
974 for (i = 0; i < num_edges; i++)
976 edge e = INDEX_EDGE (el, i);
977 struct edge_info *inf = EDGE_INFO (e);
978 if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
985 total_num_blocks += n_basic_blocks + 2;
987 fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
989 total_num_edges += num_edges;
991 fprintf (rtl_dump_file, "%d edges\n", num_edges);
993 total_num_edges_ignored += ignored_edges;
995 fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
997 /* Create a .bbg file from which gcov can reconstruct the basic block
998 graph. First output the number of basic blocks, and then for every
999 edge output the source and target basic block numbers.
1000 NOTE: The format of this file must be compatible with gcov. */
1002 if (!gcov_is_error ())
1005 const char *file = DECL_SOURCE_FILE (current_function_decl);
1006 unsigned line = DECL_SOURCE_LINE (current_function_decl);
1008 /* Announce function */
1009 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
1010 gcov_write_string (name);
1011 gcov_write_unsigned (profile_info.current_function_cfg_checksum);
1012 gcov_write_string (file);
1013 gcov_write_unsigned (line);
1014 gcov_write_length (offset);
1016 /* Basic block flags */
1017 offset = gcov_write_tag (GCOV_TAG_BLOCKS);
1018 for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++)
1019 gcov_write_unsigned (0);
1020 gcov_write_length (offset);
1023 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
1027 offset = gcov_write_tag (GCOV_TAG_ARCS);
1028 gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
1030 for (e = bb->succ; e; e = e->succ_next)
1032 struct edge_info *i = EDGE_INFO (e);
1035 unsigned flag_bits = 0;
1038 flag_bits |= GCOV_ARC_ON_TREE;
1039 if (e->flags & EDGE_FAKE)
1040 flag_bits |= GCOV_ARC_FAKE;
1041 if (e->flags & EDGE_FALLTHRU)
1042 flag_bits |= GCOV_ARC_FALLTHROUGH;
1044 gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest));
1045 gcov_write_unsigned (flag_bits);
1049 gcov_write_length (offset);
1052 /* Output line number information about each basic block for
1055 char const *prev_file_name = NULL;
1059 rtx insn = bb->head;
1060 int ignore_next_note = 0;
1064 /* We are looking for line number notes. Search backward
1065 before basic block to find correct ones. */
1066 insn = prev_nonnote_insn (insn);
1068 insn = get_insns ();
1070 insn = NEXT_INSN (insn);
1072 while (insn != bb->end)
1074 if (GET_CODE (insn) == NOTE)
1076 /* Must ignore the line number notes that immediately
1077 follow the end of an inline function to avoid counting
1078 it twice. There is a note before the call, and one
1080 if (NOTE_LINE_NUMBER (insn)
1081 == NOTE_INSN_REPEATED_LINE_NUMBER)
1082 ignore_next_note = 1;
1083 else if (NOTE_LINE_NUMBER (insn) <= 0)
1085 else if (ignore_next_note)
1086 ignore_next_note = 0;
1091 offset = gcov_write_tag (GCOV_TAG_LINES);
1092 gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
1095 /* If this is a new source file, then output
1096 the file's name to the .bb file. */
1098 || strcmp (NOTE_SOURCE_FILE (insn),
1101 prev_file_name = NOTE_SOURCE_FILE (insn);
1102 gcov_write_unsigned (0);
1103 gcov_write_string (prev_file_name);
1105 gcov_write_unsigned (NOTE_LINE_NUMBER (insn));
1108 insn = NEXT_INSN (insn);
1113 /* A file of NULL indicates the end of run. */
1114 gcov_write_unsigned (0);
1115 gcov_write_string (NULL);
1116 gcov_write_length (offset);
1118 if (gcov_is_error ())
1119 warning ("error writing `%s'", bbg_file_name);
1124 if (flag_branch_probabilities)
1125 compute_branch_probabilities ();
1127 /* For each edge not on the spanning tree, add counting code as rtl. */
1129 if (cfun->arc_profile && profile_arc_flag)
1131 struct function_list *item;
1133 instrument_edges (el);
1135 /* Commit changes done by instrumentation. */
1136 commit_edge_insertions_watch_calls ();
1137 allocate_reg_info (max_reg_num (), FALSE, FALSE);
1139 /* ??? Probably should re-use the existing struct function. */
1140 item = xmalloc (sizeof (struct function_list));
1142 *functions_tail = item;
1143 functions_tail = &item->next;
1146 item->name = xstrdup (name);
1147 item->cfg_checksum = profile_info.current_function_cfg_checksum;
1148 item->n_counter_sections = 0;
1149 for (i = 0; i < profile_info.n_sections; i++)
1150 if (profile_info.section_info[i].n_counters_now)
1152 item->counter_sections[item->n_counter_sections].tag =
1153 profile_info.section_info[i].tag;
1154 item->counter_sections[item->n_counter_sections].n_counters =
1155 profile_info.section_info[i].n_counters_now;
1156 item->n_counter_sections++;
1160 remove_fake_edges ();
1161 free_aux_for_edges ();
1162 /* Re-merge split basic blocks and the mess introduced by
1163 insert_insn_on_edge. */
1164 cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
1166 dump_flow_info (rtl_dump_file);
1168 free_edge_list (el);
1171 /* Union find algorithm implementation for the basic blocks using
1178 basic_block group = bb, bb1;
1180 while ((basic_block) group->aux != group)
1181 group = (basic_block) group->aux;
1183 /* Compress path. */
1184 while ((basic_block) bb->aux != group)
1186 bb1 = (basic_block) bb->aux;
1187 bb->aux = (void *) group;
1194 union_groups (bb1, bb2)
1195 basic_block bb1, bb2;
1197 basic_block bb1g = find_group (bb1);
1198 basic_block bb2g = find_group (bb2);
1200 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
1201 this code is unlikely going to be performance problem anyway. */
1208 /* This function searches all of the edges in the program flow graph, and puts
1209 as many bad edges as possible onto the spanning tree. Bad edges include
1210 abnormals edges, which can't be instrumented at the moment. Since it is
1211 possible for fake edges to form a cycle, we will have to develop some
1212 better way in the future. Also put critical edges to the tree, since they
1213 are more expensive to instrument. */
1216 find_spanning_tree (el)
1217 struct edge_list *el;
1220 int num_edges = NUM_EDGES (el);
1223 /* We use aux field for standard union-find algorithm. */
1224 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1227 /* Add fake edge exit to entry we can't instrument. */
1228 union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
1230 /* First add all abnormal edges to the tree unless they form a cycle. Also
1231 add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1232 setting return value from function. */
1233 for (i = 0; i < num_edges; i++)
1235 edge e = INDEX_EDGE (el, i);
1236 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1237 || e->dest == EXIT_BLOCK_PTR
1239 && !EDGE_INFO (e)->ignore
1240 && (find_group (e->src) != find_group (e->dest)))
1243 fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
1244 e->src->index, e->dest->index);
1245 EDGE_INFO (e)->on_tree = 1;
1246 union_groups (e->src, e->dest);
1250 /* Now insert all critical edges to the tree unless they form a cycle. */
1251 for (i = 0; i < num_edges; i++)
1253 edge e = INDEX_EDGE (el, i);
1254 if ((EDGE_CRITICAL_P (e))
1255 && !EDGE_INFO (e)->ignore
1256 && (find_group (e->src) != find_group (e->dest)))
1259 fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1260 e->src->index, e->dest->index);
1261 EDGE_INFO (e)->on_tree = 1;
1262 union_groups (e->src, e->dest);
1266 /* And now the rest. */
1267 for (i = 0; i < num_edges; i++)
1269 edge e = INDEX_EDGE (el, i);
1270 if (find_group (e->src) != find_group (e->dest)
1271 && !EDGE_INFO (e)->ignore)
1274 fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1275 e->src->index, e->dest->index);
1276 EDGE_INFO (e)->on_tree = 1;
1277 union_groups (e->src, e->dest);
1281 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1285 /* Perform file-level initialization for branch-prob processing. */
1288 init_branch_prob (filename)
1289 const char *filename;
1291 int len = strlen (filename);
1294 da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
1295 strcpy (da_file_name, filename);
1296 strcat (da_file_name, GCOV_DATA_SUFFIX);
1298 if (flag_branch_probabilities)
1299 read_counts_file (da_file_name);
1301 if (flag_test_coverage)
1303 /* Open the bbg output file. */
1304 bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1);
1305 strcpy (bbg_file_name, filename);
1306 strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
1307 if (!gcov_open (bbg_file_name, -1))
1308 error ("cannot open %s", bbg_file_name);
1309 gcov_write_unsigned (GCOV_GRAPH_MAGIC);
1310 gcov_write_unsigned (GCOV_VERSION);
1313 if (profile_arc_flag)
1315 /* Generate and save a copy of this so it can be shared. */
1318 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1319 profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1322 total_num_blocks = 0;
1323 total_num_edges = 0;
1324 total_num_edges_ignored = 0;
1325 total_num_edges_instrumented = 0;
1326 total_num_blocks_created = 0;
1327 total_num_passes = 0;
1328 total_num_times_called = 0;
1329 total_num_branches = 0;
1330 total_num_never_executed = 0;
1331 for (i = 0; i < 20; i++)
1332 total_hist_br_prob[i] = 0;
1335 /* Performs file-level cleanup after branch-prob processing
1341 if (flag_test_coverage)
1343 int error = gcov_close ();
1346 unlink (bbg_file_name);
1348 /* If the compiler is instrumented, we should not
1349 unconditionally remove the counts file, because we might be
1350 recompiling ourselves. The .da files are all removed during
1351 copying the stage1 files. */
1354 unlink (da_file_name);
1359 fprintf (rtl_dump_file, "\n");
1360 fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1362 fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1363 fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1364 total_num_edges_ignored);
1365 fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1366 total_num_edges_instrumented);
1367 fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1368 total_num_blocks_created);
1369 fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1371 if (total_num_times_called != 0)
1372 fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1373 (total_num_passes + (total_num_times_called >> 1))
1374 / total_num_times_called);
1375 fprintf (rtl_dump_file, "Total number of branches: %d\n",
1376 total_num_branches);
1377 fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1378 total_num_never_executed);
1379 if (total_num_branches)
1383 for (i = 0; i < 10; i++)
1384 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1385 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1386 / total_num_branches, 5*i, 5*i+5);
1391 /* Find (and create if not present) a section with TAG. */
1392 struct section_info *
1393 find_counters_section (tag)
1398 for (i = 0; i < profile_info.n_sections; i++)
1399 if (profile_info.section_info[i].tag == tag)
1400 return profile_info.section_info + i;
1402 if (i == MAX_COUNTER_SECTIONS)
1405 profile_info.section_info[i].tag = tag;
1406 profile_info.section_info[i].present = 0;
1407 profile_info.section_info[i].n_counters = 0;
1408 profile_info.section_info[i].n_counters_now = 0;
1409 profile_info.n_sections++;
1411 return profile_info.section_info + i;
1414 /* Set FIELDS as purpose to VALUE. */
1416 set_purpose (value, fields)
1420 tree act_field, act_value;
1422 for (act_field = fields, act_value = value;
1424 act_field = TREE_CHAIN (act_field), act_value = TREE_CHAIN (act_value))
1425 TREE_PURPOSE (act_value) = act_field;
1428 /* Returns label for base of counters inside TAG section. */
1435 case GCOV_TAG_ARC_COUNTS:
1436 return profiler_label;
1442 /* Creates fields of struct counter_section (in gcov-io.h). */
1444 build_counter_section_fields ()
1449 fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1452 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1453 TREE_CHAIN (field) = fields;
1459 /* Creates value of struct counter_section (in gcov-io.h). */
1461 build_counter_section_value (tag, n_counters)
1463 unsigned n_counters;
1465 tree value = NULL_TREE;
1468 value = tree_cons (NULL_TREE,
1469 convert (unsigned_type_node,
1470 build_int_2 (tag, 0)),
1474 value = tree_cons (NULL_TREE,
1475 convert (unsigned_type_node,
1476 build_int_2 (n_counters, 0)),
1482 /* Creates fields of struct counter_section_data (in gcov-io.h). */
1484 build_counter_section_data_fields ()
1486 tree field, fields, gcov_type, gcov_ptr_type;
1488 gcov_type = make_signed_type (GCOV_TYPE_SIZE);
1490 build_pointer_type (build_qualified_type (gcov_type,
1494 fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1497 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1498 TREE_CHAIN (field) = fields;
1502 field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
1503 TREE_CHAIN (field) = fields;
1509 /* Creates value of struct counter_section_data (in gcov-io.h). */
1511 build_counter_section_data_value (tag, n_counters)
1513 unsigned n_counters;
1515 tree value = NULL_TREE, counts_table, gcov_type, gcov_ptr_type;
1517 gcov_type = make_signed_type (GCOV_TYPE_SIZE);
1519 = build_pointer_type (build_qualified_type
1520 (gcov_type, TYPE_QUAL_CONST));
1523 value = tree_cons (NULL_TREE,
1524 convert (unsigned_type_node,
1525 build_int_2 (tag, 0)),
1529 value = tree_cons (NULL_TREE,
1530 convert (unsigned_type_node,
1531 build_int_2 (n_counters, 0)),
1537 tree gcov_type_array_type =
1538 build_array_type (gcov_type,
1539 build_index_type (build_int_2 (n_counters - 1,
1542 build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
1543 TREE_STATIC (counts_table) = 1;
1544 DECL_NAME (counts_table) = get_identifier (XSTR (label_for_tag (tag), 0));
1545 assemble_variable (counts_table, 0, 0, 0);
1546 counts_table = build1 (ADDR_EXPR, gcov_ptr_type, counts_table);
1549 counts_table = null_pointer_node;
1551 value = tree_cons (NULL_TREE, counts_table, value);
1556 /* Creates fields for struct function_info type (in gcov-io.h). */
1558 build_function_info_fields ()
1560 tree field, fields, counter_section_fields, counter_section_type;
1561 tree counter_sections_ptr_type;
1563 build_pointer_type (build_qualified_type (char_type_node,
1566 fields = build_decl (FIELD_DECL, NULL_TREE, string_type);
1569 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1570 TREE_CHAIN (field) = fields;
1573 /* n_counter_sections */
1574 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1575 TREE_CHAIN (field) = fields;
1578 /* counter_sections */
1579 counter_section_fields = build_counter_section_fields ();
1580 counter_section_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1581 finish_builtin_struct (counter_section_type, "__counter_section",
1582 counter_section_fields, NULL_TREE);
1583 counter_sections_ptr_type =
1585 (build_qualified_type (counter_section_type,
1587 field = build_decl (FIELD_DECL, NULL_TREE, counter_sections_ptr_type);
1588 TREE_CHAIN (field) = fields;
1594 /* Creates value for struct function_info (in gcov-io.h). */
1596 build_function_info_value (function)
1597 struct function_list *function;
1599 tree value = NULL_TREE;
1600 size_t name_len = strlen (function->name);
1601 tree fname = build_string (name_len + 1, function->name);
1603 build_pointer_type (build_qualified_type (char_type_node,
1605 tree counter_section_fields, counter_section_type, counter_sections_value;
1606 tree counter_sections_ptr_type, counter_sections_array_type;
1611 build_array_type (char_type_node,
1612 build_index_type (build_int_2 (name_len, 0)));
1613 value = tree_cons (NULL_TREE,
1620 value = tree_cons (NULL_TREE,
1621 convert (unsigned_type_node,
1622 build_int_2 (function->cfg_checksum, 0)),
1625 /* n_counter_sections */
1627 value = tree_cons (NULL_TREE,
1628 convert (unsigned_type_node,
1629 build_int_2 (function->n_counter_sections, 0)),
1632 /* counter_sections */
1633 counter_section_fields = build_counter_section_fields ();
1634 counter_section_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1635 counter_sections_ptr_type =
1637 (build_qualified_type (counter_section_type,
1639 counter_sections_array_type =
1640 build_array_type (counter_section_type,
1642 build_int_2 (function->n_counter_sections - 1,
1645 counter_sections_value = NULL_TREE;
1646 for (i = 0; i < function->n_counter_sections; i++)
1648 tree counter_section_value =
1649 build_counter_section_value (function->counter_sections[i].tag,
1650 function->counter_sections[i].n_counters);
1651 set_purpose (counter_section_value, counter_section_fields);
1652 counter_sections_value = tree_cons (NULL_TREE,
1654 counter_section_type,
1656 nreverse (counter_section_value)),
1657 counter_sections_value);
1659 finish_builtin_struct (counter_section_type, "__counter_section",
1660 counter_section_fields, NULL_TREE);
1662 if (function->n_counter_sections)
1664 counter_sections_value =
1666 counter_sections_array_type,
1668 nreverse (counter_sections_value)),
1669 counter_sections_value = build1 (ADDR_EXPR,
1670 counter_sections_ptr_type,
1671 counter_sections_value);
1674 counter_sections_value = null_pointer_node;
1676 value = tree_cons (NULL_TREE, counter_sections_value, value);
1681 /* Creates fields of struct gcov_info type (in gcov-io.h). */
1683 build_gcov_info_fields (gcov_info_type)
1684 tree gcov_info_type;
1690 build_pointer_type (build_qualified_type (char_type_node,
1692 tree function_info_fields, function_info_type, function_info_ptr_type;
1693 tree counter_section_data_fields, counter_section_data_type;
1694 tree counter_section_data_ptr_type;
1697 fields = build_decl (FIELD_DECL, NULL_TREE, long_unsigned_type_node);
1700 field = build_decl (FIELD_DECL, NULL_TREE,
1701 build_pointer_type (build_qualified_type (gcov_info_type,
1703 TREE_CHAIN (field) = fields;
1707 filename = getpwd ();
1708 filename = (filename && da_file_name[0] != '/'
1709 ? concat (filename, "/", da_file_name, NULL)
1711 filename_len = strlen (filename);
1712 if (filename != da_file_name)
1715 field = build_decl (FIELD_DECL, NULL_TREE, string_type);
1716 TREE_CHAIN (field) = fields;
1720 field = build_decl (FIELD_DECL, NULL_TREE, long_integer_type_node);
1721 TREE_CHAIN (field) = fields;
1724 /* number of functions */
1725 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1726 TREE_CHAIN (field) = fields;
1729 /* function_info table */
1730 function_info_fields = build_function_info_fields ();
1731 function_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1732 finish_builtin_struct (function_info_type, "__function_info",
1733 function_info_fields, NULL_TREE);
1734 function_info_ptr_type =
1736 (build_qualified_type (function_info_type,
1738 field = build_decl (FIELD_DECL, NULL_TREE, function_info_ptr_type);
1739 TREE_CHAIN (field) = fields;
1742 /* n_counter_sections */
1743 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1744 TREE_CHAIN (field) = fields;
1747 /* counter sections */
1748 counter_section_data_fields = build_counter_section_data_fields ();
1749 counter_section_data_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1750 finish_builtin_struct (counter_section_data_type, "__counter_section_data",
1751 counter_section_data_fields, NULL_TREE);
1752 counter_section_data_ptr_type =
1754 (build_qualified_type (counter_section_data_type,
1756 field = build_decl (FIELD_DECL, NULL_TREE, counter_section_data_ptr_type);
1757 TREE_CHAIN (field) = fields;
1763 /* Creates struct gcov_info value (in gcov-io.h). */
1765 build_gcov_info_value ()
1767 tree value = NULL_TREE;
1768 tree filename_string;
1771 unsigned n_functions, i;
1772 struct function_list *item;
1774 build_pointer_type (build_qualified_type (char_type_node,
1776 tree function_info_fields, function_info_type, function_info_ptr_type;
1778 tree counter_section_data_fields, counter_section_data_type;
1779 tree counter_section_data_ptr_type, counter_sections;
1782 value = tree_cons (NULL_TREE,
1783 convert (long_unsigned_type_node,
1784 build_int_2 (GCOV_VERSION, 0)),
1788 value = tree_cons (NULL_TREE, null_pointer_node, value);
1791 filename = getpwd ();
1792 filename = (filename && da_file_name[0] != '/'
1793 ? concat (filename, "/", da_file_name, NULL)
1795 filename_len = strlen (filename);
1796 filename_string = build_string (filename_len + 1, filename);
1797 if (filename != da_file_name)
1799 TREE_TYPE (filename_string) =
1800 build_array_type (char_type_node,
1801 build_index_type (build_int_2 (filename_len, 0)));
1802 value = tree_cons (NULL_TREE,
1809 value = tree_cons (NULL_TREE,
1810 convert (long_integer_type_node, integer_zero_node),
1813 /* number of functions */
1815 for (item = functions_head; item != 0; item = item->next, n_functions++)
1817 value = tree_cons (NULL_TREE,
1818 convert (unsigned_type_node,
1819 build_int_2 (n_functions, 0)),
1822 /* function_info table */
1823 function_info_fields = build_function_info_fields ();
1824 function_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1825 function_info_ptr_type =
1826 build_pointer_type (
1827 build_qualified_type (function_info_type,
1829 functions = NULL_TREE;
1830 for (item = functions_head; item != 0; item = item->next)
1832 tree function_info_value = build_function_info_value (item);
1833 set_purpose (function_info_value, function_info_fields);
1834 functions = tree_cons (NULL_TREE,
1838 nreverse (function_info_value)),
1841 finish_builtin_struct (function_info_type, "__function_info",
1842 function_info_fields, NULL_TREE);
1844 /* Create constructor for array. */
1849 array_type = build_array_type (
1851 build_index_type (build_int_2 (n_functions - 1, 0)));
1852 functions = build (CONSTRUCTOR,
1855 nreverse (functions));
1856 functions = build1 (ADDR_EXPR,
1857 function_info_ptr_type,
1861 functions = null_pointer_node;
1863 value = tree_cons (NULL_TREE, functions, value);
1865 /* n_counter_sections */
1866 value = tree_cons (NULL_TREE,
1867 convert (unsigned_type_node,
1868 build_int_2 (profile_info.n_sections, 0)),
1871 /* counter sections */
1872 counter_section_data_fields = build_counter_section_data_fields ();
1873 counter_section_data_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1874 counter_sections = NULL_TREE;
1875 for (i = 0; i < profile_info.n_sections; i++)
1877 tree counter_sections_value =
1878 build_counter_section_data_value (
1879 profile_info.section_info[i].tag,
1880 profile_info.section_info[i].n_counters);
1881 set_purpose (counter_sections_value, counter_section_data_fields);
1882 counter_sections = tree_cons (NULL_TREE,
1884 counter_section_data_type,
1886 nreverse (counter_sections_value)),
1889 finish_builtin_struct (counter_section_data_type, "__counter_section_data",
1890 counter_section_data_fields, NULL_TREE);
1891 counter_section_data_ptr_type =
1893 (build_qualified_type (counter_section_data_type,
1896 if (profile_info.n_sections)
1901 counter_section_data_type,
1902 build_index_type (build_int_2 (profile_info.n_sections - 1, 0))),
1904 nreverse (counter_sections));
1905 counter_sections = build1 (ADDR_EXPR,
1906 counter_section_data_ptr_type,
1910 counter_sections = null_pointer_node;
1911 value = tree_cons (NULL_TREE, counter_sections, value);
1916 /* Write out the structure which libgcc uses to locate all the arc
1917 counters. The structures used here must match those defined in
1918 gcov-io.h. Write out the constructor to call __gcov_init. */
1923 tree gcov_info_fields, gcov_info_type, gcov_info_value, gcov_info;
1927 rtx gcov_info_address;
1928 int save_flag_inline_functions = flag_inline_functions;
1931 for (i = 0; i < profile_info.n_sections; i++)
1932 if (profile_info.section_info[i].n_counters_now)
1934 if (i == profile_info.n_sections)
1937 gcov_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1938 gcov_info_fields = build_gcov_info_fields (gcov_info_type);
1939 gcov_info_value = build_gcov_info_value ();
1940 set_purpose (gcov_info_value, gcov_info_fields);
1941 finish_builtin_struct (gcov_info_type, "__gcov_info",
1942 gcov_info_fields, NULL_TREE);
1944 gcov_info = build (VAR_DECL, gcov_info_type, NULL_TREE, NULL_TREE);
1945 DECL_INITIAL (gcov_info) =
1946 build (CONSTRUCTOR, gcov_info_type, NULL_TREE,
1947 nreverse (gcov_info_value));
1949 TREE_STATIC (gcov_info) = 1;
1950 ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
1951 DECL_NAME (gcov_info) = get_identifier (name);
1953 /* Build structure. */
1954 assemble_variable (gcov_info, 0, 0, 0);
1956 /* Build the constructor function to invoke __gcov_init. */
1957 ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
1959 ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
1960 build_function_type (void_type_node, NULL_TREE));
1962 DECL_EXTERNAL (ctor) = 0;
1964 /* It can be a static function as long as collect2 does not have
1965 to scan the object file to find its ctor/dtor routine. */
1966 TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
1967 TREE_USED (ctor) = 1;
1968 DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1970 ctor = (*lang_hooks.decls.pushdecl) (ctor);
1971 rest_of_decl_compilation (ctor, 0, 1, 0);
1972 announce_function (ctor);
1973 current_function_decl = ctor;
1974 DECL_INITIAL (ctor) = error_mark_node;
1975 make_decl_rtl (ctor, NULL);
1976 init_function_start (ctor, input_filename, lineno);
1977 (*lang_hooks.decls.pushlevel) (0);
1978 expand_function_start (ctor, 0);
1979 cfun->arc_profile = 0;
1981 /* Actually generate the code to call __gcov_init. */
1982 gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0));
1983 emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1,
1984 gcov_info_address, Pmode);
1986 expand_function_end (input_filename, lineno, 0);
1987 (*lang_hooks.decls.poplevel) (1, 0, 1);
1989 /* Since ctor isn't in the list of globals, it would never be emitted
1990 when it's considered to be 'safe' for inlining, so turn off
1991 flag_inline_functions. */
1992 flag_inline_functions = 0;
1994 rest_of_compilation (ctor);
1996 /* Reset flag_inline_functions to its original value. */
1997 flag_inline_functions = save_flag_inline_functions;
2000 fflush (asm_out_file);
2001 current_function_decl = NULL_TREE;
2003 if (targetm.have_ctors_dtors)
2004 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
2005 DEFAULT_INIT_PRIORITY);
2008 /* Output instructions as RTL to increment the edge execution count. */
2011 gen_edge_profiler (edgeno)
2014 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
2020 tmp = force_reg (Pmode, profiler_label);
2021 tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
2022 mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
2024 set_mem_alias_set (mem_ref, new_alias_set ());
2026 tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
2027 mem_ref, 0, OPTAB_WIDEN);
2030 emit_move_insn (copy_rtx (mem_ref), tmp);
2032 sequence = get_insns ();
2037 #include "gt-profile.h"