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 magic, 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 (&magic) || magic != GCOV_DATA_MAGIC)
289 warning ("`%s' is not a gcov data file", name);
293 else if (gcov_read_unsigned (&version) || version != GCOV_VERSION)
296 magic = GCOV_VERSION;
298 for (ix = 4; ix--; magic >>= 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);
313 unsigned tag, length;
316 offset = gcov_save_position ();
317 if (gcov_read_unsigned (&tag) || gcov_read_unsigned (&length))
322 warning ("`%s' is corrupted", name);
324 htab_delete (counts_hash);
327 if (tag == GCOV_TAG_FUNCTION)
329 if (gcov_read_string (&function_name_buffer)
330 || gcov_read_unsigned (&checksum))
334 /* We have already seen a summary, this means that this
335 new function begins a new set of program runs. We
336 must unlink the summaried chain. */
337 counts_entry_t *entry, *chain;
339 for (entry = summaried; entry; entry = chain)
341 chain = entry->chain;
343 entry->max_counter_sum += entry->max_counter;
350 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
352 counts_entry_t *entry;
353 struct gcov_summary summary;
355 if (length != GCOV_SUMMARY_LENGTH
356 || gcov_read_summary (&summary))
360 for (entry = summaried; entry; entry = entry->chain)
362 entry->merged += summary.runs;
363 if (entry->max_counter < summary.arc_sum_max)
364 entry->max_counter = summary.arc_sum_max;
367 else if (GCOV_TAG_IS_SUBTAG (GCOV_TAG_FUNCTION, tag)
368 && function_name_buffer)
370 counts_entry_t **slot, *entry, elt;
371 unsigned n_counts = length / 8;
375 elt.function_name = function_name_buffer;
378 slot = (counts_entry_t **) htab_find_slot
379 (counts_hash, &elt, INSERT);
383 *slot = entry = xmalloc (sizeof (counts_entry_t));
384 entry->function_name = xstrdup (function_name_buffer);
385 entry->section = tag;
386 entry->checksum = checksum;
387 entry->n_counts = n_counts;
388 entry->counts = xcalloc (n_counts, sizeof (gcov_type));
390 else if (entry->checksum != checksum || entry->n_counts != n_counts)
392 warning ("profile mismatch for `%s'", function_name_buffer);
396 /* This should always be true for a just allocated entry,
397 and always false for an existing one. Check this way, in
398 case the gcov file is corrupt. */
399 if (!entry->chain || summaried != entry)
401 entry->chain = summaried;
404 for (ix = 0; ix != n_counts; ix++)
406 if (gcov_read_counter (&count))
408 entry->counts[ix] += count;
412 if (gcov_skip (length))
416 free (function_name_buffer);
420 /* Computes hybrid profile for all matching entries in da_file.
421 Sets max_counter_in_program as a side effect. */
426 unsigned num_edges = 0;
428 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
429 counts_entry_t *entry, elt;
431 profile_info.max_counter_in_program = 0;
432 profile_info.count_profiles_merged = 0;
434 /* No hash table, no counts. */
438 /* Count the edges to be (possibly) instrumented. */
439 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
442 for (e = bb->succ; e; e = e->succ_next)
443 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
447 elt.function_name = (char *) name;
448 elt.section = GCOV_TAG_ARC_COUNTS;
449 entry = htab_find (counts_hash, &elt);
452 warning ("No profile for function '%s' found.", name);
456 if (entry->checksum != profile_info.current_function_cfg_checksum
457 || num_edges != entry->n_counts)
459 warning ("profile mismatch for `%s'", current_function_name);
463 profile_info.count_profiles_merged = entry->merged;
464 profile_info.max_counter_in_program = entry->max_counter_sum;
468 fprintf(rtl_dump_file, "Merged %i profiles with maximal count %i.\n",
469 profile_info.count_profiles_merged,
470 (int)profile_info.max_counter_in_program);
473 return entry->counts;
477 /* Compute the branch probabilities for the various branches.
478 Annotate them accordingly. */
481 compute_branch_probabilities ()
488 int hist_br_prob[20];
489 int num_never_executed;
491 gcov_type *exec_counts = get_exec_counts ();
492 int exec_counts_pos = 0;
494 /* Attach extra info block to each bb. */
496 alloc_aux_for_blocks (sizeof (struct bb_info));
497 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
501 for (e = bb->succ; e; e = e->succ_next)
502 if (!EDGE_INFO (e)->ignore)
503 BB_INFO (bb)->succ_count++;
504 for (e = bb->pred; e; e = e->pred_next)
505 if (!EDGE_INFO (e)->ignore)
506 BB_INFO (bb)->pred_count++;
509 /* Avoid predicting entry on exit nodes. */
510 BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
511 BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
513 /* For each edge not on the spanning tree, set its execution count from
516 /* The first count in the .da file is the number of times that the function
517 was entered. This is the exec_count for block zero. */
519 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
522 for (e = bb->succ; e; e = e->succ_next)
523 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
528 e->count = exec_counts[exec_counts_pos++];
533 EDGE_INFO (e)->count_valid = 1;
534 BB_INFO (bb)->succ_count--;
535 BB_INFO (e->dest)->pred_count--;
538 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
539 bb->index, e->dest->index);
540 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
541 (HOST_WIDEST_INT) e->count);
547 fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
549 /* For every block in the file,
550 - if every exit/entrance edge has a known count, then set the block count
551 - if the block count is known, and every exit/entrance edge but one has
552 a known execution count, then set the count of the remaining edge
554 As edge counts are set, decrement the succ/pred count, but don't delete
555 the edge, that way we can easily tell when all edges are known, or only
556 one edge is unknown. */
558 /* The order that the basic blocks are iterated through is important.
559 Since the code that finds spanning trees starts with block 0, low numbered
560 edges are put on the spanning tree in preference to high numbered edges.
561 Hence, most instrumented edges are at the end. Graph solving works much
562 faster if we propagate numbers from the end to the start.
564 This takes an average of slightly more than 3 passes. */
572 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
574 struct bb_info *bi = BB_INFO (bb);
575 if (! bi->count_valid)
577 if (bi->succ_count == 0)
582 for (e = bb->succ; e; e = e->succ_next)
588 else if (bi->pred_count == 0)
593 for (e = bb->pred; e; e = e->pred_next)
602 if (bi->succ_count == 1)
607 /* One of the counts will be invalid, but it is zero,
608 so adding it in also doesn't hurt. */
609 for (e = bb->succ; e; e = e->succ_next)
612 /* Seedgeh for the invalid edge, and set its count. */
613 for (e = bb->succ; e; e = e->succ_next)
614 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
617 /* Calculate count for remaining edge by conservation. */
618 total = bb->count - total;
622 EDGE_INFO (e)->count_valid = 1;
626 BB_INFO (e->dest)->pred_count--;
629 if (bi->pred_count == 1)
634 /* One of the counts will be invalid, but it is zero,
635 so adding it in also doesn't hurt. */
636 for (e = bb->pred; e; e = e->pred_next)
639 /* Seedgeh for the invalid edge, and set its count. */
640 for (e = bb->pred; e; e = e->pred_next)
641 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
644 /* Calculate count for remaining edge by conservation. */
645 total = bb->count - total + e->count;
649 EDGE_INFO (e)->count_valid = 1;
653 BB_INFO (e->src)->succ_count--;
660 dump_flow_info (rtl_dump_file);
662 total_num_passes += passes;
664 fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
666 /* If the graph has been correctly solved, every block will have a
667 succ and pred count of zero. */
670 if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
674 /* For every edge, calculate its branch probability and add a reg_note
675 to the branch insn to indicate this. */
677 for (i = 0; i < 20; i++)
679 num_never_executed = 0;
682 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
691 for (e = bb->succ; e; e = e->succ_next)
693 e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
694 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
696 error ("corrupted profile info: prob for %d-%d thought to be %d",
697 e->src->index, e->dest->index, e->probability);
698 e->probability = REG_BR_PROB_BASE / 2;
702 && any_condjump_p (bb->end)
703 && bb->succ->succ_next)
709 /* Find the branch edge. It is possible that we do have fake
711 for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
713 continue; /* Loop body has been intentionally left blank. */
715 prob = e->probability;
716 index = prob * 20 / REG_BR_PROB_BASE;
720 hist_br_prob[index]++;
722 note = find_reg_note (bb->end, REG_BR_PROB, 0);
723 /* There may be already note put by some other pass, such
724 as builtin_expect expander. */
726 XEXP (note, 0) = GEN_INT (prob);
729 = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
730 REG_NOTES (bb->end));
734 /* Otherwise distribute the probabilities evenly so we get sane
735 sum. Use simple heuristics that if there are normal edges,
736 give all abnormals frequency of 0, otherwise distribute the
737 frequency over abnormals (this is the case of noreturn
741 for (e = bb->succ; e; e = e->succ_next)
742 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
746 for (e = bb->succ; e; e = e->succ_next)
747 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
748 e->probability = REG_BR_PROB_BASE / total;
754 for (e = bb->succ; e; e = e->succ_next)
756 for (e = bb->succ; e; e = e->succ_next)
757 e->probability = REG_BR_PROB_BASE / total;
760 && any_condjump_p (bb->end)
761 && bb->succ->succ_next)
762 num_branches++, num_never_executed;
768 fprintf (rtl_dump_file, "%d branches\n", num_branches);
769 fprintf (rtl_dump_file, "%d branches never executed\n",
772 for (i = 0; i < 10; i++)
773 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
774 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
777 total_num_branches += num_branches;
778 total_num_never_executed += num_never_executed;
779 for (i = 0; i < 20; i++)
780 total_hist_br_prob[i] += hist_br_prob[i];
782 fputc ('\n', rtl_dump_file);
783 fputc ('\n', rtl_dump_file);
786 free_aux_for_blocks ();
787 find_counters_section (GCOV_TAG_ARC_COUNTS)->present = 1;
790 /* Compute checksum for the current function. We generate a CRC32. */
804 unsigned value = BB_TO_GCOV_INDEX (e ? e->dest : bb);
807 /* No need to use all bits in value identically, nearly all
808 functions have less than 256 blocks. */
809 value ^= value << 16;
812 for (ix = 8; ix--; value <<= 1)
816 feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
821 e = e ? e->succ_next : bb->succ;
829 /* Instrument and/or analyze program behavior based on program flow graph.
830 In either case, this function builds a flow graph for the function being
831 compiled. The flow graph is stored in BB_GRAPH.
833 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
834 the flow graph that are needed to reconstruct the dynamic behavior of the
837 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
838 information from a data file containing edge count information from previous
839 executions of the function being compiled. In this case, the flow graph is
840 annotated with actual execution counts, which are later propagated into the
841 rtl for optimization purposes.
843 Main entry point of this file. */
850 unsigned num_edges, ignored_edges;
851 struct edge_list *el;
852 const char *name = IDENTIFIER_POINTER
853 (DECL_ASSEMBLER_NAME (current_function_decl));
855 profile_info.current_function_cfg_checksum = compute_checksum ();
856 for (i = 0; i < profile_info.n_sections; i++)
858 profile_info.section_info[i].n_counters_now = 0;
859 profile_info.section_info[i].present = 0;
863 fprintf (rtl_dump_file, "CFG checksum is %u\n",
864 profile_info.current_function_cfg_checksum);
866 total_num_times_called++;
868 flow_call_edges_add (NULL);
869 add_noreturn_fake_exit_edges ();
871 /* We can't handle cyclic regions constructed using abnormal edges.
872 To avoid these we replace every source of abnormal edge by a fake
873 edge from entry node and every destination by fake edge to exit.
874 This keeps graph acyclic and our calculation exact for all normal
875 edges except for exit and entrance ones.
877 We also add fake exit edges for each call and asm statement in the
878 basic, since it may not return. */
882 int need_exit_edge = 0, need_entry_edge = 0;
883 int have_exit_edge = 0, have_entry_edge = 0;
887 /* Add fake edges from entry block to the call insns that may return
888 twice. The CFG is not quite correct then, as call insn plays more
889 role of CODE_LABEL, but for our purposes, everything should be OK,
890 as we never insert code to the beginning of basic block. */
891 for (insn = bb->head; insn != NEXT_INSN (bb->end);
892 insn = NEXT_INSN (insn))
894 if (GET_CODE (insn) == CALL_INSN
895 && find_reg_note (insn, REG_SETJMP, NULL))
897 if (GET_CODE (bb->head) == CODE_LABEL
898 || insn != NEXT_INSN (bb->head))
900 e = split_block (bb, PREV_INSN (insn));
901 make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
906 /* We should not get abort here, as call to setjmp should not
907 be the very first instruction of function. */
908 if (bb == ENTRY_BLOCK_PTR)
910 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
915 for (e = bb->succ; e; e = e->succ_next)
917 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
918 && e->dest != EXIT_BLOCK_PTR)
920 if (e->dest == EXIT_BLOCK_PTR)
923 for (e = bb->pred; e; e = e->pred_next)
925 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
926 && e->src != ENTRY_BLOCK_PTR)
928 if (e->src == ENTRY_BLOCK_PTR)
932 if (need_exit_edge && !have_exit_edge)
935 fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
937 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
939 if (need_entry_edge && !have_entry_edge)
942 fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
944 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
948 el = create_edge_list ();
949 num_edges = NUM_EDGES (el);
950 alloc_aux_for_edges (sizeof (struct edge_info));
952 /* The basic blocks are expected to be numbered sequentially. */
956 for (i = 0 ; i < num_edges ; i++)
958 edge e = INDEX_EDGE (el, i);
961 /* Mark edges we've replaced by fake edges above as ignored. */
962 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
963 && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
965 EDGE_INFO (e)->ignore = 1;
970 #ifdef ENABLE_CHECKING
974 /* Create spanning tree from basic block graph, mark each edge that is
975 on the spanning tree. We insert as many abnormal and critical edges
976 as possible to minimize number of edge splits necessary. */
978 find_spanning_tree (el);
980 /* Fake edges that are not on the tree will not be instrumented, so
981 mark them ignored. */
982 for (i = 0; i < num_edges; i++)
984 edge e = INDEX_EDGE (el, i);
985 struct edge_info *inf = EDGE_INFO (e);
986 if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
993 total_num_blocks += n_basic_blocks + 2;
995 fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
997 total_num_edges += num_edges;
999 fprintf (rtl_dump_file, "%d edges\n", num_edges);
1001 total_num_edges_ignored += ignored_edges;
1003 fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
1005 /* Create a .bbg file from which gcov can reconstruct the basic block
1006 graph. First output the number of basic blocks, and then for every
1007 edge output the source and target basic block numbers.
1008 NOTE: The format of this file must be compatible with gcov. */
1013 const char *file = DECL_SOURCE_FILE (current_function_decl);
1014 unsigned line = DECL_SOURCE_LINE (current_function_decl);
1016 /* Announce function */
1017 if (gcov_write_unsigned (GCOV_TAG_FUNCTION)
1018 || !(offset = gcov_reserve_length ())
1019 || gcov_write_string (name)
1020 || gcov_write_unsigned (profile_info.current_function_cfg_checksum)
1021 || gcov_write_string (file)
1022 || gcov_write_unsigned (line)
1023 || gcov_write_length (offset))
1026 /* Basic block flags */
1027 if (gcov_write_unsigned (GCOV_TAG_BLOCKS)
1028 || !(offset = gcov_reserve_length ()))
1030 for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++)
1031 if (gcov_write_unsigned (0))
1033 if (gcov_write_length (offset))
1037 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
1041 if (gcov_write_unsigned (GCOV_TAG_ARCS)
1042 || !(offset = gcov_reserve_length ())
1043 || gcov_write_unsigned (BB_TO_GCOV_INDEX (bb)))
1046 for (e = bb->succ; e; e = e->succ_next)
1048 struct edge_info *i = EDGE_INFO (e);
1051 unsigned flag_bits = 0;
1054 flag_bits |= GCOV_ARC_ON_TREE;
1055 if (e->flags & EDGE_FAKE)
1056 flag_bits |= GCOV_ARC_FAKE;
1057 if (e->flags & EDGE_FALLTHRU)
1058 flag_bits |= GCOV_ARC_FALLTHROUGH;
1060 if (gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest))
1061 || gcov_write_unsigned (flag_bits))
1066 if (gcov_write_length (offset))
1070 /* Output line number information about each basic block for
1073 char const *prev_file_name = NULL;
1077 rtx insn = bb->head;
1078 int ignore_next_note = 0;
1082 /* We are looking for line number notes. Search backward
1083 before basic block to find correct ones. */
1084 insn = prev_nonnote_insn (insn);
1086 insn = get_insns ();
1088 insn = NEXT_INSN (insn);
1090 while (insn != bb->end)
1092 if (GET_CODE (insn) == NOTE)
1094 /* Must ignore the line number notes that immediately
1095 follow the end of an inline function to avoid counting
1096 it twice. There is a note before the call, and one
1098 if (NOTE_LINE_NUMBER (insn)
1099 == NOTE_INSN_REPEATED_LINE_NUMBER)
1100 ignore_next_note = 1;
1101 else if (NOTE_LINE_NUMBER (insn) <= 0)
1103 else if (ignore_next_note)
1104 ignore_next_note = 0;
1109 else if (gcov_write_unsigned (GCOV_TAG_LINES)
1110 || !(offset = gcov_reserve_length ())
1111 || (gcov_write_unsigned
1112 (BB_TO_GCOV_INDEX (bb))))
1114 /* If this is a new source file, then output
1115 the file's name to the .bb file. */
1117 || strcmp (NOTE_SOURCE_FILE (insn),
1120 prev_file_name = NOTE_SOURCE_FILE (insn);
1121 if (gcov_write_unsigned (0)
1122 || gcov_write_string (prev_file_name))
1125 if (gcov_write_unsigned (NOTE_LINE_NUMBER (insn)))
1129 insn = NEXT_INSN (insn);
1134 if (gcov_write_unsigned (0)
1135 || gcov_write_string (NULL)
1136 || gcov_write_length (offset))
1139 warning ("error writing `%s'", bbg_file_name);
1147 if (flag_branch_probabilities)
1148 compute_branch_probabilities ();
1150 /* For each edge not on the spanning tree, add counting code as rtl. */
1152 if (cfun->arc_profile && profile_arc_flag)
1154 struct function_list *item;
1156 instrument_edges (el);
1158 /* Commit changes done by instrumentation. */
1159 commit_edge_insertions_watch_calls ();
1160 allocate_reg_info (max_reg_num (), FALSE, FALSE);
1162 /* ??? Probably should re-use the existing struct function. */
1163 item = xmalloc (sizeof (struct function_list));
1165 *functions_tail = item;
1166 functions_tail = &item->next;
1169 item->name = xstrdup (name);
1170 item->cfg_checksum = profile_info.current_function_cfg_checksum;
1171 item->n_counter_sections = 0;
1172 for (i = 0; i < profile_info.n_sections; i++)
1173 if (profile_info.section_info[i].n_counters_now)
1175 item->counter_sections[item->n_counter_sections].tag =
1176 profile_info.section_info[i].tag;
1177 item->counter_sections[item->n_counter_sections].n_counters =
1178 profile_info.section_info[i].n_counters_now;
1179 item->n_counter_sections++;
1183 remove_fake_edges ();
1184 free_aux_for_edges ();
1185 /* Re-merge split basic blocks and the mess introduced by
1186 insert_insn_on_edge. */
1187 cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
1189 dump_flow_info (rtl_dump_file);
1191 free_edge_list (el);
1194 /* Union find algorithm implementation for the basic blocks using
1201 basic_block group = bb, bb1;
1203 while ((basic_block) group->aux != group)
1204 group = (basic_block) group->aux;
1206 /* Compress path. */
1207 while ((basic_block) bb->aux != group)
1209 bb1 = (basic_block) bb->aux;
1210 bb->aux = (void *) group;
1217 union_groups (bb1, bb2)
1218 basic_block bb1, bb2;
1220 basic_block bb1g = find_group (bb1);
1221 basic_block bb2g = find_group (bb2);
1223 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
1224 this code is unlikely going to be performance problem anyway. */
1231 /* This function searches all of the edges in the program flow graph, and puts
1232 as many bad edges as possible onto the spanning tree. Bad edges include
1233 abnormals edges, which can't be instrumented at the moment. Since it is
1234 possible for fake edges to form a cycle, we will have to develop some
1235 better way in the future. Also put critical edges to the tree, since they
1236 are more expensive to instrument. */
1239 find_spanning_tree (el)
1240 struct edge_list *el;
1243 int num_edges = NUM_EDGES (el);
1246 /* We use aux field for standard union-find algorithm. */
1247 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1250 /* Add fake edge exit to entry we can't instrument. */
1251 union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
1253 /* First add all abnormal edges to the tree unless they form a cycle. Also
1254 add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1255 setting return value from function. */
1256 for (i = 0; i < num_edges; i++)
1258 edge e = INDEX_EDGE (el, i);
1259 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1260 || e->dest == EXIT_BLOCK_PTR
1262 && !EDGE_INFO (e)->ignore
1263 && (find_group (e->src) != find_group (e->dest)))
1266 fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
1267 e->src->index, e->dest->index);
1268 EDGE_INFO (e)->on_tree = 1;
1269 union_groups (e->src, e->dest);
1273 /* Now insert all critical edges to the tree unless they form a cycle. */
1274 for (i = 0; i < num_edges; i++)
1276 edge e = INDEX_EDGE (el, i);
1277 if ((EDGE_CRITICAL_P (e))
1278 && !EDGE_INFO (e)->ignore
1279 && (find_group (e->src) != find_group (e->dest)))
1282 fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1283 e->src->index, e->dest->index);
1284 EDGE_INFO (e)->on_tree = 1;
1285 union_groups (e->src, e->dest);
1289 /* And now the rest. */
1290 for (i = 0; i < num_edges; i++)
1292 edge e = INDEX_EDGE (el, i);
1293 if (find_group (e->src) != find_group (e->dest)
1294 && !EDGE_INFO (e)->ignore)
1297 fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1298 e->src->index, e->dest->index);
1299 EDGE_INFO (e)->on_tree = 1;
1300 union_groups (e->src, e->dest);
1304 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1308 /* Perform file-level initialization for branch-prob processing. */
1311 init_branch_prob (filename)
1312 const char *filename;
1314 int len = strlen (filename);
1317 da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
1318 strcpy (da_file_name, filename);
1319 strcat (da_file_name, GCOV_DATA_SUFFIX);
1321 if (flag_branch_probabilities)
1322 read_counts_file (da_file_name);
1324 if (flag_test_coverage)
1326 /* Open the bbg output file. */
1327 bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1);
1328 strcpy (bbg_file_name, filename);
1329 strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
1330 if (!gcov_open (bbg_file_name, -1))
1332 error ("cannot open %s", bbg_file_name);
1335 else if (gcov_write_unsigned (GCOV_GRAPH_MAGIC)
1336 || gcov_write_unsigned (GCOV_VERSION))
1340 if (profile_arc_flag)
1342 /* Generate and save a copy of this so it can be shared. */
1345 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1346 profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1349 total_num_blocks = 0;
1350 total_num_edges = 0;
1351 total_num_edges_ignored = 0;
1352 total_num_edges_instrumented = 0;
1353 total_num_blocks_created = 0;
1354 total_num_passes = 0;
1355 total_num_times_called = 0;
1356 total_num_branches = 0;
1357 total_num_never_executed = 0;
1358 for (i = 0; i < 20; i++)
1359 total_hist_br_prob[i] = 0;
1362 /* Performs file-level cleanup after branch-prob processing
1368 if (flag_test_coverage)
1370 int error = gcov_close ();
1373 unlink (bbg_file_name);
1375 /* If the compiler is instrumented, we should not
1376 unconditionally remove the counts file, because we might be
1377 recompiling ourselves. The .da files are all removed during
1378 copying the stage1 files. */
1381 unlink (da_file_name);
1386 fprintf (rtl_dump_file, "\n");
1387 fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1389 fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1390 fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1391 total_num_edges_ignored);
1392 fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1393 total_num_edges_instrumented);
1394 fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1395 total_num_blocks_created);
1396 fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1398 if (total_num_times_called != 0)
1399 fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1400 (total_num_passes + (total_num_times_called >> 1))
1401 / total_num_times_called);
1402 fprintf (rtl_dump_file, "Total number of branches: %d\n",
1403 total_num_branches);
1404 fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1405 total_num_never_executed);
1406 if (total_num_branches)
1410 for (i = 0; i < 10; i++)
1411 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1412 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1413 / total_num_branches, 5*i, 5*i+5);
1418 /* Find (and create if not present) a section with TAG. */
1419 struct section_info *
1420 find_counters_section (tag)
1425 for (i = 0; i < profile_info.n_sections; i++)
1426 if (profile_info.section_info[i].tag == tag)
1427 return profile_info.section_info + i;
1429 if (i == MAX_COUNTER_SECTIONS)
1432 profile_info.section_info[i].tag = tag;
1433 profile_info.section_info[i].present = 0;
1434 profile_info.section_info[i].n_counters = 0;
1435 profile_info.section_info[i].n_counters_now = 0;
1436 profile_info.n_sections++;
1438 return profile_info.section_info + i;
1441 /* Set FIELDS as purpose to VALUE. */
1443 set_purpose (value, fields)
1447 tree act_field, act_value;
1449 for (act_field = fields, act_value = value;
1451 act_field = TREE_CHAIN (act_field), act_value = TREE_CHAIN (act_value))
1452 TREE_PURPOSE (act_value) = act_field;
1455 /* Returns label for base of counters inside TAG section. */
1462 case GCOV_TAG_ARC_COUNTS:
1463 return profiler_label;
1469 /* Creates fields of struct counter_section (in gcov-io.h). */
1471 build_counter_section_fields ()
1476 fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1479 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1480 TREE_CHAIN (field) = fields;
1486 /* Creates value of struct counter_section (in gcov-io.h). */
1488 build_counter_section_value (tag, n_counters)
1490 unsigned n_counters;
1492 tree value = NULL_TREE;
1495 value = tree_cons (NULL_TREE,
1496 convert (unsigned_type_node,
1497 build_int_2 (tag, 0)),
1501 value = tree_cons (NULL_TREE,
1502 convert (unsigned_type_node,
1503 build_int_2 (n_counters, 0)),
1509 /* Creates fields of struct counter_section_data (in gcov-io.h). */
1511 build_counter_section_data_fields ()
1513 tree field, fields, gcov_type, gcov_ptr_type;
1515 gcov_type = make_signed_type (GCOV_TYPE_SIZE);
1517 build_pointer_type (build_qualified_type (gcov_type,
1521 fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1524 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1525 TREE_CHAIN (field) = fields;
1529 field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
1530 TREE_CHAIN (field) = fields;
1536 /* Creates value of struct counter_section_data (in gcov-io.h). */
1538 build_counter_section_data_value (tag, n_counters)
1540 unsigned n_counters;
1542 tree value = NULL_TREE, counts_table, gcov_type, gcov_ptr_type;
1544 gcov_type = make_signed_type (GCOV_TYPE_SIZE);
1546 = build_pointer_type (build_qualified_type
1547 (gcov_type, TYPE_QUAL_CONST));
1550 value = tree_cons (NULL_TREE,
1551 convert (unsigned_type_node,
1552 build_int_2 (tag, 0)),
1556 value = tree_cons (NULL_TREE,
1557 convert (unsigned_type_node,
1558 build_int_2 (n_counters, 0)),
1564 tree gcov_type_array_type =
1565 build_array_type (gcov_type,
1566 build_index_type (build_int_2 (n_counters - 1,
1569 build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
1570 TREE_STATIC (counts_table) = 1;
1571 DECL_NAME (counts_table) = get_identifier (XSTR (label_for_tag (tag), 0));
1572 assemble_variable (counts_table, 0, 0, 0);
1573 counts_table = build1 (ADDR_EXPR, gcov_ptr_type, counts_table);
1576 counts_table = null_pointer_node;
1578 value = tree_cons (NULL_TREE, counts_table, value);
1583 /* Creates fields for struct function_info type (in gcov-io.h). */
1585 build_function_info_fields ()
1587 tree field, fields, counter_section_fields, counter_section_type;
1588 tree counter_sections_ptr_type;
1590 build_pointer_type (build_qualified_type (char_type_node,
1593 fields = build_decl (FIELD_DECL, NULL_TREE, string_type);
1596 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1597 TREE_CHAIN (field) = fields;
1600 /* n_counter_sections */
1601 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1602 TREE_CHAIN (field) = fields;
1605 /* counter_sections */
1606 counter_section_fields = build_counter_section_fields ();
1607 counter_section_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1608 finish_builtin_struct (counter_section_type, "__counter_section",
1609 counter_section_fields, NULL_TREE);
1610 counter_sections_ptr_type =
1612 (build_qualified_type (counter_section_type,
1614 field = build_decl (FIELD_DECL, NULL_TREE, counter_sections_ptr_type);
1615 TREE_CHAIN (field) = fields;
1621 /* Creates value for struct function_info (in gcov-io.h). */
1623 build_function_info_value (function)
1624 struct function_list *function;
1626 tree value = NULL_TREE;
1627 size_t name_len = strlen (function->name);
1628 tree fname = build_string (name_len + 1, function->name);
1630 build_pointer_type (build_qualified_type (char_type_node,
1632 tree counter_section_fields, counter_section_type, counter_sections_value;
1633 tree counter_sections_ptr_type, counter_sections_array_type;
1638 build_array_type (char_type_node,
1639 build_index_type (build_int_2 (name_len, 0)));
1640 value = tree_cons (NULL_TREE,
1647 value = tree_cons (NULL_TREE,
1648 convert (unsigned_type_node,
1649 build_int_2 (function->cfg_checksum, 0)),
1652 /* n_counter_sections */
1654 value = tree_cons (NULL_TREE,
1655 convert (unsigned_type_node,
1656 build_int_2 (function->n_counter_sections, 0)),
1659 /* counter_sections */
1660 counter_section_fields = build_counter_section_fields ();
1661 counter_section_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1662 counter_sections_ptr_type =
1664 (build_qualified_type (counter_section_type,
1666 counter_sections_array_type =
1667 build_array_type (counter_section_type,
1669 build_int_2 (function->n_counter_sections - 1,
1672 counter_sections_value = NULL_TREE;
1673 for (i = 0; i < function->n_counter_sections; i++)
1675 tree counter_section_value =
1676 build_counter_section_value (function->counter_sections[i].tag,
1677 function->counter_sections[i].n_counters);
1678 set_purpose (counter_section_value, counter_section_fields);
1679 counter_sections_value = tree_cons (NULL_TREE,
1681 counter_section_type,
1683 nreverse (counter_section_value)),
1684 counter_sections_value);
1686 finish_builtin_struct (counter_section_type, "__counter_section",
1687 counter_section_fields, NULL_TREE);
1689 if (function->n_counter_sections)
1691 counter_sections_value =
1693 counter_sections_array_type,
1695 nreverse (counter_sections_value)),
1696 counter_sections_value = build1 (ADDR_EXPR,
1697 counter_sections_ptr_type,
1698 counter_sections_value);
1701 counter_sections_value = null_pointer_node;
1703 value = tree_cons (NULL_TREE, counter_sections_value, value);
1708 /* Creates fields of struct gcov_info type (in gcov-io.h). */
1710 build_gcov_info_fields (gcov_info_type)
1711 tree gcov_info_type;
1717 build_pointer_type (build_qualified_type (char_type_node,
1719 tree function_info_fields, function_info_type, function_info_ptr_type;
1720 tree counter_section_data_fields, counter_section_data_type;
1721 tree counter_section_data_ptr_type;
1724 fields = build_decl (FIELD_DECL, NULL_TREE, long_unsigned_type_node);
1727 field = build_decl (FIELD_DECL, NULL_TREE,
1728 build_pointer_type (build_qualified_type (gcov_info_type,
1730 TREE_CHAIN (field) = fields;
1734 filename = getpwd ();
1735 filename = (filename && da_file_name[0] != '/'
1736 ? concat (filename, "/", da_file_name, NULL)
1738 filename_len = strlen (filename);
1739 if (filename != da_file_name)
1742 field = build_decl (FIELD_DECL, NULL_TREE, string_type);
1743 TREE_CHAIN (field) = fields;
1747 field = build_decl (FIELD_DECL, NULL_TREE, long_integer_type_node);
1748 TREE_CHAIN (field) = fields;
1751 /* number of functions */
1752 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1753 TREE_CHAIN (field) = fields;
1756 /* function_info table */
1757 function_info_fields = build_function_info_fields ();
1758 function_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1759 finish_builtin_struct (function_info_type, "__function_info",
1760 function_info_fields, NULL_TREE);
1761 function_info_ptr_type =
1763 (build_qualified_type (function_info_type,
1765 field = build_decl (FIELD_DECL, NULL_TREE, function_info_ptr_type);
1766 TREE_CHAIN (field) = fields;
1769 /* n_counter_sections */
1770 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1771 TREE_CHAIN (field) = fields;
1774 /* counter sections */
1775 counter_section_data_fields = build_counter_section_data_fields ();
1776 counter_section_data_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1777 finish_builtin_struct (counter_section_data_type, "__counter_section_data",
1778 counter_section_data_fields, NULL_TREE);
1779 counter_section_data_ptr_type =
1781 (build_qualified_type (counter_section_data_type,
1783 field = build_decl (FIELD_DECL, NULL_TREE, counter_section_data_ptr_type);
1784 TREE_CHAIN (field) = fields;
1790 /* Creates struct gcov_info value (in gcov-io.h). */
1792 build_gcov_info_value ()
1794 tree value = NULL_TREE;
1795 tree filename_string;
1798 unsigned n_functions, i;
1799 struct function_list *item;
1801 build_pointer_type (build_qualified_type (char_type_node,
1803 tree function_info_fields, function_info_type, function_info_ptr_type;
1805 tree counter_section_data_fields, counter_section_data_type;
1806 tree counter_section_data_ptr_type, counter_sections;
1809 value = tree_cons (NULL_TREE,
1810 convert (long_unsigned_type_node,
1811 build_int_2 (GCOV_VERSION, 0)),
1815 value = tree_cons (NULL_TREE, null_pointer_node, value);
1818 filename = getpwd ();
1819 filename = (filename && da_file_name[0] != '/'
1820 ? concat (filename, "/", da_file_name, NULL)
1822 filename_len = strlen (filename);
1823 filename_string = build_string (filename_len + 1, filename);
1824 if (filename != da_file_name)
1826 TREE_TYPE (filename_string) =
1827 build_array_type (char_type_node,
1828 build_index_type (build_int_2 (filename_len, 0)));
1829 value = tree_cons (NULL_TREE,
1836 value = tree_cons (NULL_TREE,
1837 convert (long_integer_type_node, integer_zero_node),
1840 /* number of functions */
1842 for (item = functions_head; item != 0; item = item->next, n_functions++)
1844 value = tree_cons (NULL_TREE,
1845 convert (unsigned_type_node,
1846 build_int_2 (n_functions, 0)),
1849 /* function_info table */
1850 function_info_fields = build_function_info_fields ();
1851 function_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1852 function_info_ptr_type =
1853 build_pointer_type (
1854 build_qualified_type (function_info_type,
1856 functions = NULL_TREE;
1857 for (item = functions_head; item != 0; item = item->next)
1859 tree function_info_value = build_function_info_value (item);
1860 set_purpose (function_info_value, function_info_fields);
1861 functions = tree_cons (NULL_TREE,
1865 nreverse (function_info_value)),
1868 finish_builtin_struct (function_info_type, "__function_info",
1869 function_info_fields, NULL_TREE);
1871 /* Create constructor for array. */
1876 array_type = build_array_type (
1878 build_index_type (build_int_2 (n_functions - 1, 0)));
1879 functions = build (CONSTRUCTOR,
1882 nreverse (functions));
1883 functions = build1 (ADDR_EXPR,
1884 function_info_ptr_type,
1888 functions = null_pointer_node;
1890 value = tree_cons (NULL_TREE, functions, value);
1892 /* n_counter_sections */
1893 value = tree_cons (NULL_TREE,
1894 convert (unsigned_type_node,
1895 build_int_2 (profile_info.n_sections, 0)),
1898 /* counter sections */
1899 counter_section_data_fields = build_counter_section_data_fields ();
1900 counter_section_data_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1901 counter_sections = NULL_TREE;
1902 for (i = 0; i < profile_info.n_sections; i++)
1904 tree counter_sections_value =
1905 build_counter_section_data_value (
1906 profile_info.section_info[i].tag,
1907 profile_info.section_info[i].n_counters);
1908 set_purpose (counter_sections_value, counter_section_data_fields);
1909 counter_sections = tree_cons (NULL_TREE,
1911 counter_section_data_type,
1913 nreverse (counter_sections_value)),
1916 finish_builtin_struct (counter_section_data_type, "__counter_section_data",
1917 counter_section_data_fields, NULL_TREE);
1918 counter_section_data_ptr_type =
1920 (build_qualified_type (counter_section_data_type,
1923 if (profile_info.n_sections)
1928 counter_section_data_type,
1929 build_index_type (build_int_2 (profile_info.n_sections - 1, 0))),
1931 nreverse (counter_sections));
1932 counter_sections = build1 (ADDR_EXPR,
1933 counter_section_data_ptr_type,
1937 counter_sections = null_pointer_node;
1938 value = tree_cons (NULL_TREE, counter_sections, value);
1943 /* Write out the structure which libgcc uses to locate all the arc
1944 counters. The structures used here must match those defined in
1945 gcov-io.h. Write out the constructor to call __gcov_init. */
1950 tree gcov_info_fields, gcov_info_type, gcov_info_value, gcov_info;
1954 rtx gcov_info_address;
1955 int save_flag_inline_functions = flag_inline_functions;
1958 for (i = 0; i < profile_info.n_sections; i++)
1959 if (profile_info.section_info[i].n_counters_now)
1961 if (i == profile_info.n_sections)
1964 gcov_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1965 gcov_info_fields = build_gcov_info_fields (gcov_info_type);
1966 gcov_info_value = build_gcov_info_value ();
1967 set_purpose (gcov_info_value, gcov_info_fields);
1968 finish_builtin_struct (gcov_info_type, "__gcov_info",
1969 gcov_info_fields, NULL_TREE);
1971 gcov_info = build (VAR_DECL, gcov_info_type, NULL_TREE, NULL_TREE);
1972 DECL_INITIAL (gcov_info) =
1973 build (CONSTRUCTOR, gcov_info_type, NULL_TREE,
1974 nreverse (gcov_info_value));
1976 TREE_STATIC (gcov_info) = 1;
1977 ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
1978 DECL_NAME (gcov_info) = get_identifier (name);
1980 /* Build structure. */
1981 assemble_variable (gcov_info, 0, 0, 0);
1983 /* Build the constructor function to invoke __gcov_init. */
1984 ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
1986 ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
1987 build_function_type (void_type_node, NULL_TREE));
1989 DECL_EXTERNAL (ctor) = 0;
1991 /* It can be a static function as long as collect2 does not have
1992 to scan the object file to find its ctor/dtor routine. */
1993 TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
1994 TREE_USED (ctor) = 1;
1995 DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1997 ctor = (*lang_hooks.decls.pushdecl) (ctor);
1998 rest_of_decl_compilation (ctor, 0, 1, 0);
1999 announce_function (ctor);
2000 current_function_decl = ctor;
2001 DECL_INITIAL (ctor) = error_mark_node;
2002 make_decl_rtl (ctor, NULL);
2003 init_function_start (ctor, input_filename, lineno);
2004 (*lang_hooks.decls.pushlevel) (0);
2005 expand_function_start (ctor, 0);
2006 cfun->arc_profile = 0;
2008 /* Actually generate the code to call __gcov_init. */
2009 gcov_info_address = force_reg (Pmode,
2010 gen_rtx_SYMBOL_REF (
2012 IDENTIFIER_POINTER (
2013 DECL_NAME (gcov_info))));
2014 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__gcov_init"),
2015 LCT_NORMAL, VOIDmode, 1,
2016 gcov_info_address, Pmode);
2018 expand_function_end (input_filename, lineno, 0);
2019 (*lang_hooks.decls.poplevel) (1, 0, 1);
2021 /* Since ctor isn't in the list of globals, it would never be emitted
2022 when it's considered to be 'safe' for inlining, so turn off
2023 flag_inline_functions. */
2024 flag_inline_functions = 0;
2026 rest_of_compilation (ctor);
2028 /* Reset flag_inline_functions to its original value. */
2029 flag_inline_functions = save_flag_inline_functions;
2032 fflush (asm_out_file);
2033 current_function_decl = NULL_TREE;
2035 if (targetm.have_ctors_dtors)
2036 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
2037 DEFAULT_INIT_PRIORITY);
2040 /* Output instructions as RTL to increment the edge execution count. */
2043 gen_edge_profiler (edgeno)
2046 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
2052 tmp = force_reg (Pmode, profiler_label);
2053 tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
2054 mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
2056 set_mem_alias_set (mem_ref, new_alias_set ());
2058 tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
2059 mem_ref, 0, OPTAB_WIDEN);
2062 emit_move_insn (copy_rtx (mem_ref), tmp);
2064 sequence = get_insns ();
2069 #include "gt-profile.h"