std_bitset.h: Better comments.
[official-gcc.git] / gcc / profile.c
blobd14b86244ae46a59298a6879b6e342092bb6203f
1 /* Calculate branch probabilities, and basic block execution counts.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
3 2000, 2001 Free Software Foundation, Inc.
4 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
5 based on some ideas from Dain Samples of UC Berkeley.
6 Further mangling by Bob Manson, Cygnus Support.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 2, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 02111-1307, USA. */
25 /* Generate basic block profile instrumentation and auxiliary files.
26 Profile generation is optimized, so that not all arcs in the basic
27 block graph need instrumenting. First, the BB graph is closed with
28 one entry (function start), and one exit (function exit). Any
29 ABNORMAL_EDGE cannot be instrumented (because there is no control
30 path to place the code). We close the graph by inserting fake
31 EDGE_FAKE edges to the EXIT_BLOCK, from the sources of abnormal
32 edges that do not go to the exit_block. We ignore such abnormal
33 edges. Naturally these fake edges are never directly traversed,
34 and so *cannot* be directly instrumented. Some other graph
35 massaging is done. To optimize the instrumentation we generate the
36 BB minimal span tree, only edges that are not on the span tree
37 (plus the entry point) need instrumenting. From that information
38 all other edge counts can be deduced. By construction all fake
39 edges must be on the spanning tree. We also attempt to place
40 EDGE_CRITICAL edges on the spanning tree.
42 The 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. */
51 #include "config.h"
52 #include "system.h"
53 #include "coretypes.h"
54 #include "tm.h"
55 #include "rtl.h"
56 #include "tree.h"
57 #include "flags.h"
58 #include "insn-config.h"
59 #include "output.h"
60 #include "regs.h"
61 #include "expr.h"
62 #include "function.h"
63 #include "toplev.h"
64 #include "ggc.h"
65 #include "hard-reg-set.h"
66 #include "basic-block.h"
67 #include "gcov-io.h"
68 #include "target.h"
69 #include "profile.h"
70 #include "libfuncs.h"
71 #include "langhooks.h"
72 #include "hashtab.h"
74 /* Additional information about the edges we need. */
75 struct edge_info {
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;
86 struct bb_info {
87 unsigned int count_valid : 1;
89 /* Number of successor and predecessor edges. */
90 gcov_type succ_count;
91 gcov_type pred_count;
94 struct function_list
96 struct function_list *next; /* next function */
97 const char *name; /* function name */
98 unsigned cfg_checksum; /* function checksum */
99 unsigned count_edges; /* number of intrumented edges */
102 static struct function_list *functions_head = 0;
103 static struct function_list **functions_tail = &functions_head;
105 #define EDGE_INFO(e) ((struct edge_info *) (e)->aux)
106 #define BB_INFO(b) ((struct bb_info *) (b)->aux)
108 /* Keep all basic block indexes nonnegative in the gcov output. Index 0
109 is used for entry block, last block exit block. */
110 #define BB_TO_GCOV_INDEX(bb) ((bb) == ENTRY_BLOCK_PTR ? 0 \
111 : ((bb) == EXIT_BLOCK_PTR \
112 ? last_basic_block + 1 : (bb)->index + 1))
114 /* Instantiate the profile info structure. */
116 struct profile_info profile_info;
118 /* Name and file pointer of the output file for the basic block graph. */
120 static FILE *bbg_file;
121 static char *bbg_file_name;
123 /* Name and file pointer of the input file for the arc count data. */
125 static FILE *da_file;
126 static char *da_file_name;
128 /* The name of the count table. Used by the edge profiling code. */
129 static GTY(()) rtx profiler_label;
131 /* Collect statistics on the performance of this pass for the entire source
132 file. */
134 static int total_num_blocks;
135 static int total_num_edges;
136 static int total_num_edges_ignored;
137 static int total_num_edges_instrumented;
138 static int total_num_blocks_created;
139 static int total_num_passes;
140 static int total_num_times_called;
141 static int total_hist_br_prob[20];
142 static int total_num_never_executed;
143 static int total_num_branches;
145 /* Forward declarations. */
146 static void find_spanning_tree PARAMS ((struct edge_list *));
147 static rtx gen_edge_profiler PARAMS ((int));
148 static void instrument_edges PARAMS ((struct edge_list *));
149 static void compute_branch_probabilities PARAMS ((void));
150 static hashval_t htab_counts_index_hash PARAMS ((const void *));
151 static int htab_counts_index_eq PARAMS ((const void *, const void *));
152 static void htab_counts_index_del PARAMS ((void *));
153 static void cleanup_counts_index PARAMS ((int));
154 static int index_counts_file PARAMS ((void));
155 static gcov_type * get_exec_counts PARAMS ((void));
156 static unsigned compute_checksum PARAMS ((void));
157 static basic_block find_group PARAMS ((basic_block));
158 static void union_groups PARAMS ((basic_block, basic_block));
161 /* Add edge instrumentation code to the entire insn chain.
163 F is the first insn of the chain.
164 NUM_BLOCKS is the number of basic blocks found in F. */
166 static void
167 instrument_edges (el)
168 struct edge_list *el;
170 int num_instr_edges = 0;
171 int num_edges = NUM_EDGES (el);
172 basic_block bb;
173 remove_fake_edges ();
175 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
177 edge e = bb->succ;
178 while (e)
180 struct edge_info *inf = EDGE_INFO (e);
181 if (!inf->ignore && !inf->on_tree)
183 if (e->flags & EDGE_ABNORMAL)
184 abort ();
185 if (rtl_dump_file)
186 fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
187 e->src->index, e->dest->index,
188 EDGE_CRITICAL_P (e) ? " (and split)" : "");
189 insert_insn_on_edge (
190 gen_edge_profiler (total_num_edges_instrumented
191 + num_instr_edges++), e);
193 e = e->succ_next;
197 profile_info.count_edges_instrumented_now = num_instr_edges;
198 total_num_edges_instrumented += num_instr_edges;
199 profile_info.count_instrumented_edges = total_num_edges_instrumented;
201 total_num_blocks_created += num_edges;
202 if (rtl_dump_file)
203 fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
205 commit_edge_insertions_watch_calls ();
208 struct section_reference
210 long offset;
211 int owns_summary;
212 long *summary;
215 struct da_index_entry
217 /* We hash by */
218 char *function_name;
219 unsigned section;
220 /* and store */
221 unsigned checksum;
222 unsigned n_offsets;
223 struct section_reference *offsets;
226 static hashval_t
227 htab_counts_index_hash (of)
228 const void *of;
230 const struct da_index_entry *entry = of;
232 return htab_hash_string (entry->function_name) ^ entry->section;
235 static int
236 htab_counts_index_eq (of1, of2)
237 const void *of1;
238 const void *of2;
240 const struct da_index_entry *entry1 = of1;
241 const struct da_index_entry *entry2 = of2;
243 return !strcmp (entry1->function_name, entry2->function_name)
244 && entry1->section == entry2->section;
247 static void
248 htab_counts_index_del (what)
249 void *what;
251 struct da_index_entry *entry = what;
252 unsigned i;
254 for (i = 0; i < entry->n_offsets; i++)
256 struct section_reference *act = entry->offsets + i;
257 if (act->owns_summary)
258 free (act->summary);
260 free (entry->function_name);
261 free (entry->offsets);
262 free (entry);
265 static char *counts_file_name;
266 static htab_t counts_file_index = NULL;
268 static void
269 cleanup_counts_index (close_file)
270 int close_file;
272 if (da_file && close_file)
274 fclose (da_file);
275 da_file = NULL;
277 if (counts_file_name)
278 free (counts_file_name);
279 counts_file_name = NULL;
280 if (counts_file_index)
281 htab_delete (counts_file_index);
282 counts_file_index = NULL;
285 static int
286 index_counts_file ()
288 char *function_name_buffer = NULL;
289 unsigned magic, version, ix, checksum;
290 long *summary;
292 if (!da_file)
293 return 0;
294 counts_file_index = htab_create (10, htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del);
296 /* No .da file, no data. */
297 if (!da_file)
298 return 0;
300 /* Now index all profile sections. */
302 rewind (da_file);
304 summary = NULL;
306 if (gcov_read_unsigned (da_file, &magic) || magic != GCOV_DATA_MAGIC)
308 warning ("`%s' is not a gcov data file", da_file_name);
309 goto cleanup;
311 if (gcov_read_unsigned (da_file, &version) || version != GCOV_VERSION)
313 char v[4], e[4];
314 magic = GCOV_VERSION;
316 for (ix = 4; ix--; magic >>= 8, version >>= 8)
318 v[ix] = version;
319 e[ix] = magic;
321 warning ("`%s' is version `%.4s', expected version `%.4s'",
322 da_file_name, v, e);
323 goto cleanup;
326 while (1)
328 unsigned tag, length;
329 long offset;
331 offset = gcov_save_position (da_file);
332 if (gcov_read_unsigned (da_file, &tag)
333 || gcov_read_unsigned (da_file, &length))
335 if (feof (da_file))
336 break;
337 corrupt:;
338 warning ("`%s' is corrupted", da_file_name);
339 goto cleanup;
341 if (tag == GCOV_TAG_FUNCTION)
343 if (gcov_read_string (da_file, &function_name_buffer, NULL)
344 || gcov_read_unsigned (da_file, &checksum))
345 goto corrupt;
346 continue;
348 if (tag == GCOV_TAG_PROGRAM_SUMMARY)
350 if (length != GCOV_SUMMARY_LENGTH)
351 goto corrupt;
353 if (summary)
354 *summary = offset;
355 summary = NULL;
357 else
359 if (function_name_buffer)
361 struct da_index_entry **slot, elt;
362 elt.function_name = function_name_buffer;
363 elt.section = tag;
365 slot = (struct da_index_entry **)
366 htab_find_slot (counts_file_index, &elt, INSERT);
367 if (*slot)
369 if ((*slot)->checksum != checksum)
371 warning ("profile mismatch for `%s'", function_name_buffer);
372 goto cleanup;
374 (*slot)->n_offsets++;
375 (*slot)->offsets = xrealloc ((*slot)->offsets,
376 sizeof (struct section_reference) * (*slot)->n_offsets);
378 else
380 *slot = xmalloc (sizeof (struct da_index_entry));
381 (*slot)->function_name = xstrdup (function_name_buffer);
382 (*slot)->section = tag;
383 (*slot)->checksum = checksum;
384 (*slot)->n_offsets = 1;
385 (*slot)->offsets = xmalloc (sizeof (struct section_reference));
387 (*slot)->offsets[(*slot)->n_offsets - 1].offset = offset;
388 if (summary)
389 (*slot)->offsets[(*slot)->n_offsets - 1].owns_summary = 0;
390 else
392 summary = xmalloc (sizeof (long));
393 *summary = -1;
394 (*slot)->offsets[(*slot)->n_offsets - 1].owns_summary = 1;
396 (*slot)->offsets[(*slot)->n_offsets - 1].summary = summary;
399 if (gcov_skip (da_file, length))
400 goto corrupt;
403 free (function_name_buffer);
405 return 1;
407 cleanup:
408 cleanup_counts_index (1);
409 if (function_name_buffer)
410 free (function_name_buffer);
411 return 0;
414 /* Computes hybrid profile for all matching entries in da_file.
415 Sets max_counter_in_program as a side effect. */
417 static gcov_type *
418 get_exec_counts ()
420 unsigned num_edges = 0;
421 basic_block bb;
422 gcov_type *profile;
423 gcov_type max_count;
424 unsigned ix, i, tag, length, num;
425 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
426 struct da_index_entry *entry, what;
427 struct section_reference *act;
428 gcov_type count;
429 struct gcov_summary summ;
431 profile_info.max_counter_in_program = 0;
432 profile_info.count_profiles_merged = 0;
434 /* No .da file, no execution counts. */
435 if (!da_file)
436 return NULL;
437 if (!counts_file_index)
438 abort ();
440 /* Count the edges to be (possibly) instrumented. */
442 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
444 edge e;
445 for (e = bb->succ; e; e = e->succ_next)
446 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
447 num_edges++;
450 /* now read and combine all matching profiles. */
452 profile = xmalloc (sizeof (gcov_type) * num_edges);
454 for (ix = 0; ix < num_edges; ix++)
455 profile[ix] = 0;
457 what.function_name = (char *) name;
458 what.section = GCOV_TAG_ARC_COUNTS;
459 entry = htab_find (counts_file_index, &what);
460 if (!entry)
462 warning ("No profile for function '%s' found.", name);
463 goto cleanup;
466 if (entry->checksum != profile_info.current_function_cfg_checksum)
468 warning ("profile mismatch for `%s'", current_function_name);
469 goto cleanup;
472 for (i = 0; i < entry->n_offsets; i++)
474 act = entry->offsets + i;
476 /* Read arc counters. */
477 max_count = 0;
478 gcov_resync (da_file, act->offset, 0);
480 if (gcov_read_unsigned (da_file, &tag)
481 || gcov_read_unsigned (da_file, &length)
482 || tag != GCOV_TAG_ARC_COUNTS)
484 /* We have already passed through file, so any error means
485 something is rotten. */
486 abort ();
488 num = length / 8;
490 if (num != num_edges)
492 warning ("profile mismatch for `%s'", current_function_name);
493 goto cleanup;
496 for (ix = 0; ix != num; ix++)
498 if (gcov_read_counter (da_file, &count))
499 abort ();
500 if (count > max_count)
501 max_count = count;
502 profile[ix] += count;
505 /* Read program summary. */
506 if (*act->summary != -1)
508 gcov_resync (da_file, *act->summary, 0);
509 if (gcov_read_unsigned (da_file, &tag)
510 || gcov_read_unsigned (da_file, &length)
511 || tag != GCOV_TAG_PROGRAM_SUMMARY
512 || gcov_read_summary (da_file, &summ))
513 abort ();
514 profile_info.count_profiles_merged += summ.runs;
515 profile_info.max_counter_in_program += summ.arc_sum_max;
517 else
518 summ.runs = 0;
519 if (!summ.runs)
521 profile_info.count_profiles_merged++;
522 profile_info.max_counter_in_program += max_count;
526 if (rtl_dump_file)
528 fprintf(rtl_dump_file, "Merged %i profiles with maximal count %i.\n",
529 profile_info.count_profiles_merged,
530 (int)profile_info.max_counter_in_program);
533 return profile;
535 cleanup:;
536 free (profile);
537 cleanup_counts_index (1);
538 return NULL;
542 /* Compute the branch probabilities for the various branches.
543 Annotate them accordingly. */
545 static void
546 compute_branch_probabilities ()
548 basic_block bb;
549 int i;
550 int num_edges = 0;
551 int changes;
552 int passes;
553 int hist_br_prob[20];
554 int num_never_executed;
555 int num_branches;
556 gcov_type *exec_counts = get_exec_counts ();
557 int exec_counts_pos = 0;
559 /* Attach extra info block to each bb. */
561 alloc_aux_for_blocks (sizeof (struct bb_info));
562 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
564 edge e;
566 for (e = bb->succ; e; e = e->succ_next)
567 if (!EDGE_INFO (e)->ignore)
568 BB_INFO (bb)->succ_count++;
569 for (e = bb->pred; e; e = e->pred_next)
570 if (!EDGE_INFO (e)->ignore)
571 BB_INFO (bb)->pred_count++;
574 /* Avoid predicting entry on exit nodes. */
575 BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
576 BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
578 /* For each edge not on the spanning tree, set its execution count from
579 the .da file. */
581 /* The first count in the .da file is the number of times that the function
582 was entered. This is the exec_count for block zero. */
584 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
586 edge e;
587 for (e = bb->succ; e; e = e->succ_next)
588 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
590 num_edges++;
591 if (exec_counts)
593 e->count = exec_counts[exec_counts_pos++];
595 else
596 e->count = 0;
598 EDGE_INFO (e)->count_valid = 1;
599 BB_INFO (bb)->succ_count--;
600 BB_INFO (e->dest)->pred_count--;
601 if (rtl_dump_file)
603 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
604 bb->index, e->dest->index);
605 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
606 (HOST_WIDEST_INT) e->count);
611 if (rtl_dump_file)
612 fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
614 /* For every block in the file,
615 - if every exit/entrance edge has a known count, then set the block count
616 - if the block count is known, and every exit/entrance edge but one has
617 a known execution count, then set the count of the remaining edge
619 As edge counts are set, decrement the succ/pred count, but don't delete
620 the edge, that way we can easily tell when all edges are known, or only
621 one edge is unknown. */
623 /* The order that the basic blocks are iterated through is important.
624 Since the code that finds spanning trees starts with block 0, low numbered
625 edges are put on the spanning tree in preference to high numbered edges.
626 Hence, most instrumented edges are at the end. Graph solving works much
627 faster if we propagate numbers from the end to the start.
629 This takes an average of slightly more than 3 passes. */
631 changes = 1;
632 passes = 0;
633 while (changes)
635 passes++;
636 changes = 0;
637 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
639 struct bb_info *bi = BB_INFO (bb);
640 if (! bi->count_valid)
642 if (bi->succ_count == 0)
644 edge e;
645 gcov_type total = 0;
647 for (e = bb->succ; e; e = e->succ_next)
648 total += e->count;
649 bb->count = total;
650 bi->count_valid = 1;
651 changes = 1;
653 else if (bi->pred_count == 0)
655 edge e;
656 gcov_type total = 0;
658 for (e = bb->pred; e; e = e->pred_next)
659 total += e->count;
660 bb->count = total;
661 bi->count_valid = 1;
662 changes = 1;
665 if (bi->count_valid)
667 if (bi->succ_count == 1)
669 edge e;
670 gcov_type total = 0;
672 /* One of the counts will be invalid, but it is zero,
673 so adding it in also doesn't hurt. */
674 for (e = bb->succ; e; e = e->succ_next)
675 total += e->count;
677 /* Seedgeh for the invalid edge, and set its count. */
678 for (e = bb->succ; e; e = e->succ_next)
679 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
680 break;
682 /* Calculate count for remaining edge by conservation. */
683 total = bb->count - total;
685 if (! e)
686 abort ();
687 EDGE_INFO (e)->count_valid = 1;
688 e->count = total;
689 bi->succ_count--;
691 BB_INFO (e->dest)->pred_count--;
692 changes = 1;
694 if (bi->pred_count == 1)
696 edge e;
697 gcov_type total = 0;
699 /* One of the counts will be invalid, but it is zero,
700 so adding it in also doesn't hurt. */
701 for (e = bb->pred; e; e = e->pred_next)
702 total += e->count;
704 /* Seedgeh for the invalid edge, and set its count. */
705 for (e = bb->pred; e; e = e->pred_next)
706 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
707 break;
709 /* Calculate count for remaining edge by conservation. */
710 total = bb->count - total + e->count;
712 if (! e)
713 abort ();
714 EDGE_INFO (e)->count_valid = 1;
715 e->count = total;
716 bi->pred_count--;
718 BB_INFO (e->src)->succ_count--;
719 changes = 1;
724 if (rtl_dump_file)
725 dump_flow_info (rtl_dump_file);
727 total_num_passes += passes;
728 if (rtl_dump_file)
729 fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
731 /* If the graph has been correctly solved, every block will have a
732 succ and pred count of zero. */
733 FOR_EACH_BB (bb)
735 if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
736 abort ();
739 /* For every edge, calculate its branch probability and add a reg_note
740 to the branch insn to indicate this. */
742 for (i = 0; i < 20; i++)
743 hist_br_prob[i] = 0;
744 num_never_executed = 0;
745 num_branches = 0;
747 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
749 edge e;
750 gcov_type total;
751 rtx note;
753 total = bb->count;
754 if (total)
756 for (e = bb->succ; e; e = e->succ_next)
758 e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
759 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
761 error ("corrupted profile info: prob for %d-%d thought to be %d",
762 e->src->index, e->dest->index, e->probability);
763 e->probability = REG_BR_PROB_BASE / 2;
766 if (bb->index >= 0
767 && any_condjump_p (bb->end)
768 && bb->succ->succ_next)
770 int prob;
771 edge e;
772 int index;
774 /* Find the branch edge. It is possible that we do have fake
775 edges here. */
776 for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
777 e = e->succ_next)
778 continue; /* Loop body has been intentionally left blank. */
780 prob = e->probability;
781 index = prob * 20 / REG_BR_PROB_BASE;
783 if (index == 20)
784 index = 19;
785 hist_br_prob[index]++;
787 note = find_reg_note (bb->end, REG_BR_PROB, 0);
788 /* There may be already note put by some other pass, such
789 as builtin_expect expander. */
790 if (note)
791 XEXP (note, 0) = GEN_INT (prob);
792 else
793 REG_NOTES (bb->end)
794 = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
795 REG_NOTES (bb->end));
796 num_branches++;
799 /* Otherwise distribute the probabilities evenly so we get sane
800 sum. Use simple heuristics that if there are normal edges,
801 give all abnormals frequency of 0, otherwise distribute the
802 frequency over abnormals (this is the case of noreturn
803 calls). */
804 else
806 for (e = bb->succ; e; e = e->succ_next)
807 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
808 total ++;
809 if (total)
811 for (e = bb->succ; e; e = e->succ_next)
812 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
813 e->probability = REG_BR_PROB_BASE / total;
814 else
815 e->probability = 0;
817 else
819 for (e = bb->succ; e; e = e->succ_next)
820 total ++;
821 for (e = bb->succ; e; e = e->succ_next)
822 e->probability = REG_BR_PROB_BASE / total;
824 if (bb->index >= 0
825 && any_condjump_p (bb->end)
826 && bb->succ->succ_next)
827 num_branches++, num_never_executed;
831 if (rtl_dump_file)
833 fprintf (rtl_dump_file, "%d branches\n", num_branches);
834 fprintf (rtl_dump_file, "%d branches never executed\n",
835 num_never_executed);
836 if (num_branches)
837 for (i = 0; i < 10; i++)
838 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
839 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
840 5 * i, 5 * i + 5);
842 total_num_branches += num_branches;
843 total_num_never_executed += num_never_executed;
844 for (i = 0; i < 20; i++)
845 total_hist_br_prob[i] += hist_br_prob[i];
847 fputc ('\n', rtl_dump_file);
848 fputc ('\n', rtl_dump_file);
851 free_aux_for_blocks ();
852 if (exec_counts)
853 free (exec_counts);
856 /* Compute checksum for the current function. We generate a CRC32. */
858 static unsigned
859 compute_checksum ()
861 unsigned chksum = 0;
862 basic_block bb;
864 FOR_EACH_BB (bb)
866 edge e = NULL;
870 unsigned value = BB_TO_GCOV_INDEX (e ? e->dest : bb);
871 unsigned ix;
873 /* No need to use all bits in value identically, nearly all
874 functions have less than 256 blocks. */
875 value ^= value << 16;
876 value ^= value << 8;
878 for (ix = 8; ix--; value <<= 1)
880 unsigned feedback;
882 feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
883 chksum <<= 1;
884 chksum ^= feedback;
887 e = e ? e->succ_next : bb->succ;
889 while (e);
892 return chksum;
895 /* Instrument and/or analyze program behavior based on program flow graph.
896 In either case, this function builds a flow graph for the function being
897 compiled. The flow graph is stored in BB_GRAPH.
899 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
900 the flow graph that are needed to reconstruct the dynamic behavior of the
901 flow graph.
903 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
904 information from a data file containing edge count information from previous
905 executions of the function being compiled. In this case, the flow graph is
906 annotated with actual execution counts, which are later propagated into the
907 rtl for optimization purposes.
909 Main entry point of this file. */
911 void
912 branch_prob ()
914 basic_block bb;
915 int i;
916 int num_edges, ignored_edges;
917 struct edge_list *el;
918 const char *name = IDENTIFIER_POINTER
919 (DECL_ASSEMBLER_NAME (current_function_decl));
921 profile_info.current_function_cfg_checksum = compute_checksum ();
923 if (rtl_dump_file)
924 fprintf (rtl_dump_file, "CFG checksum is %u\n",
925 profile_info.current_function_cfg_checksum);
927 total_num_times_called++;
929 flow_call_edges_add (NULL);
930 add_noreturn_fake_exit_edges ();
932 /* We can't handle cyclic regions constructed using abnormal edges.
933 To avoid these we replace every source of abnormal edge by a fake
934 edge from entry node and every destination by fake edge to exit.
935 This keeps graph acyclic and our calculation exact for all normal
936 edges except for exit and entrance ones.
938 We also add fake exit edges for each call and asm statement in the
939 basic, since it may not return. */
941 FOR_EACH_BB (bb)
943 int need_exit_edge = 0, need_entry_edge = 0;
944 int have_exit_edge = 0, have_entry_edge = 0;
945 rtx insn;
946 edge e;
948 /* Add fake edges from entry block to the call insns that may return
949 twice. The CFG is not quite correct then, as call insn plays more
950 role of CODE_LABEL, but for our purposes, everything should be OK,
951 as we never insert code to the beginning of basic block. */
952 for (insn = bb->head; insn != NEXT_INSN (bb->end);
953 insn = NEXT_INSN (insn))
955 if (GET_CODE (insn) == CALL_INSN
956 && find_reg_note (insn, REG_SETJMP, NULL))
958 if (GET_CODE (bb->head) == CODE_LABEL
959 || insn != NEXT_INSN (bb->head))
961 e = split_block (bb, PREV_INSN (insn));
962 make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
963 break;
965 else
967 /* We should not get abort here, as call to setjmp should not
968 be the very first instruction of function. */
969 if (bb == ENTRY_BLOCK_PTR)
970 abort ();
971 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
976 for (e = bb->succ; e; e = e->succ_next)
978 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
979 && e->dest != EXIT_BLOCK_PTR)
980 need_exit_edge = 1;
981 if (e->dest == EXIT_BLOCK_PTR)
982 have_exit_edge = 1;
984 for (e = bb->pred; e; e = e->pred_next)
986 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
987 && e->src != ENTRY_BLOCK_PTR)
988 need_entry_edge = 1;
989 if (e->src == ENTRY_BLOCK_PTR)
990 have_entry_edge = 1;
993 if (need_exit_edge && !have_exit_edge)
995 if (rtl_dump_file)
996 fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
997 bb->index);
998 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
1000 if (need_entry_edge && !have_entry_edge)
1002 if (rtl_dump_file)
1003 fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
1004 bb->index);
1005 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
1009 el = create_edge_list ();
1010 num_edges = NUM_EDGES (el);
1011 alloc_aux_for_edges (sizeof (struct edge_info));
1013 /* The basic blocks are expected to be numbered sequentially. */
1014 compact_blocks ();
1016 ignored_edges = 0;
1017 for (i = 0 ; i < num_edges ; i++)
1019 edge e = INDEX_EDGE (el, i);
1020 e->count = 0;
1022 /* Mark edges we've replaced by fake edges above as ignored. */
1023 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
1024 && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
1026 EDGE_INFO (e)->ignore = 1;
1027 ignored_edges++;
1031 #ifdef ENABLE_CHECKING
1032 verify_flow_info ();
1033 #endif
1035 /* Create spanning tree from basic block graph, mark each edge that is
1036 on the spanning tree. We insert as many abnormal and critical edges
1037 as possible to minimize number of edge splits necessary. */
1039 find_spanning_tree (el);
1041 /* Fake edges that are not on the tree will not be instrumented, so
1042 mark them ignored. */
1043 for (i = 0; i < num_edges; i++)
1045 edge e = INDEX_EDGE (el, i);
1046 struct edge_info *inf = EDGE_INFO (e);
1047 if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
1049 inf->ignore = 1;
1050 ignored_edges++;
1054 total_num_blocks += n_basic_blocks + 2;
1055 if (rtl_dump_file)
1056 fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
1058 total_num_edges += num_edges;
1059 if (rtl_dump_file)
1060 fprintf (rtl_dump_file, "%d edges\n", num_edges);
1062 total_num_edges_ignored += ignored_edges;
1063 if (rtl_dump_file)
1064 fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
1066 /* Create a .bbg file from which gcov can reconstruct the basic block
1067 graph. First output the number of basic blocks, and then for every
1068 edge output the source and target basic block numbers.
1069 NOTE: The format of this file must be compatible with gcov. */
1071 if (flag_test_coverage && bbg_file)
1073 long offset;
1075 /* Announce function */
1076 if (gcov_write_unsigned (bbg_file, GCOV_TAG_FUNCTION)
1077 || !(offset = gcov_reserve_length (bbg_file))
1078 || gcov_write_string (bbg_file, name,
1079 strlen (name))
1080 || gcov_write_unsigned (bbg_file,
1081 profile_info.current_function_cfg_checksum)
1082 || gcov_write_length (bbg_file, offset))
1083 goto bbg_error;
1085 /* Basic block flags */
1086 if (gcov_write_unsigned (bbg_file, GCOV_TAG_BLOCKS)
1087 || !(offset = gcov_reserve_length (bbg_file)))
1088 goto bbg_error;
1089 for (i = 0; i != n_basic_blocks + 2; i++)
1090 if (gcov_write_unsigned (bbg_file, 0))
1091 goto bbg_error;
1092 if (gcov_write_length (bbg_file, offset))
1093 goto bbg_error;
1095 /* Arcs */
1096 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
1098 edge e;
1100 if (gcov_write_unsigned (bbg_file, GCOV_TAG_ARCS)
1101 || !(offset = gcov_reserve_length (bbg_file))
1102 || gcov_write_unsigned (bbg_file, BB_TO_GCOV_INDEX (bb)))
1103 goto bbg_error;
1105 for (e = bb->succ; e; e = e->succ_next)
1107 struct edge_info *i = EDGE_INFO (e);
1108 if (!i->ignore)
1110 unsigned flag_bits = 0;
1112 if (i->on_tree)
1113 flag_bits |= GCOV_ARC_ON_TREE;
1114 if (e->flags & EDGE_FAKE)
1115 flag_bits |= GCOV_ARC_FAKE;
1116 if (e->flags & EDGE_FALLTHRU)
1117 flag_bits |= GCOV_ARC_FALLTHROUGH;
1119 if (gcov_write_unsigned (bbg_file,
1120 BB_TO_GCOV_INDEX (e->dest))
1121 || gcov_write_unsigned (bbg_file, flag_bits))
1122 goto bbg_error;
1125 if (gcov_write_length (bbg_file, offset))
1126 goto bbg_error;
1129 /* Output line number information about each basic block for
1130 GCOV utility. */
1132 char const *prev_file_name = NULL;
1134 FOR_EACH_BB (bb)
1136 rtx insn = bb->head;
1137 int ignore_next_note = 0;
1139 offset = 0;
1141 /* We are looking for line number notes. Search backward
1142 before basic block to find correct ones. */
1143 insn = prev_nonnote_insn (insn);
1144 if (!insn)
1145 insn = get_insns ();
1146 else
1147 insn = NEXT_INSN (insn);
1149 while (insn != bb->end)
1151 if (GET_CODE (insn) == NOTE)
1153 /* Must ignore the line number notes that immediately
1154 follow the end of an inline function to avoid counting
1155 it twice. There is a note before the call, and one
1156 after the call. */
1157 if (NOTE_LINE_NUMBER (insn)
1158 == NOTE_INSN_REPEATED_LINE_NUMBER)
1159 ignore_next_note = 1;
1160 else if (NOTE_LINE_NUMBER (insn) <= 0)
1161 /*NOP*/;
1162 else if (ignore_next_note)
1163 ignore_next_note = 0;
1164 else
1166 if (offset)
1167 /*NOP*/;
1168 else if (gcov_write_unsigned (bbg_file, GCOV_TAG_LINES)
1169 || !(offset = gcov_reserve_length (bbg_file))
1170 || gcov_write_unsigned (bbg_file,
1171 BB_TO_GCOV_INDEX (bb)))
1172 goto bbg_error;
1173 /* If this is a new source file, then output
1174 the file's name to the .bb file. */
1175 if (!prev_file_name
1176 || strcmp (NOTE_SOURCE_FILE (insn),
1177 prev_file_name))
1179 prev_file_name = NOTE_SOURCE_FILE (insn);
1180 if (gcov_write_unsigned (bbg_file, 0)
1181 || gcov_write_string (bbg_file, prev_file_name,
1182 strlen (prev_file_name)))
1183 goto bbg_error;
1185 if (gcov_write_unsigned (bbg_file, NOTE_LINE_NUMBER (insn)))
1186 goto bbg_error;
1189 insn = NEXT_INSN (insn);
1191 if (offset)
1193 if (gcov_write_unsigned (bbg_file, 0)
1194 || gcov_write_string (bbg_file, NULL, 0)
1195 || gcov_write_length (bbg_file, offset))
1197 bbg_error:;
1198 warning ("error writing `%s'", bbg_file_name);
1199 fclose (bbg_file);
1200 bbg_file = NULL;
1207 if (flag_branch_probabilities)
1208 compute_branch_probabilities ();
1210 /* For each edge not on the spanning tree, add counting code as rtl. */
1212 if (cfun->arc_profile && profile_arc_flag)
1214 struct function_list *item;
1216 instrument_edges (el);
1217 allocate_reg_info (max_reg_num (), FALSE, FALSE);
1219 /* ??? Probably should re-use the existing struct function. */
1220 item = xmalloc (sizeof (struct function_list));
1222 *functions_tail = item;
1223 functions_tail = &item->next;
1225 item->next = 0;
1226 item->name = xstrdup (name);
1227 item->cfg_checksum = profile_info.current_function_cfg_checksum;
1228 item->count_edges = profile_info.count_edges_instrumented_now;
1231 remove_fake_edges ();
1232 /* Re-merge split basic blocks and the mess introduced by
1233 insert_insn_on_edge. */
1234 cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
1235 if (rtl_dump_file)
1236 dump_flow_info (rtl_dump_file);
1238 free_aux_for_edges ();
1239 free_edge_list (el);
1242 /* Union find algorithm implementation for the basic blocks using
1243 aux fields. */
1245 static basic_block
1246 find_group (bb)
1247 basic_block bb;
1249 basic_block group = bb, bb1;
1251 while ((basic_block) group->aux != group)
1252 group = (basic_block) group->aux;
1254 /* Compress path. */
1255 while ((basic_block) bb->aux != group)
1257 bb1 = (basic_block) bb->aux;
1258 bb->aux = (void *) group;
1259 bb = bb1;
1261 return group;
1264 static void
1265 union_groups (bb1, bb2)
1266 basic_block bb1, bb2;
1268 basic_block bb1g = find_group (bb1);
1269 basic_block bb2g = find_group (bb2);
1271 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
1272 this code is unlikely going to be performance problem anyway. */
1273 if (bb1g == bb2g)
1274 abort ();
1276 bb1g->aux = bb2g;
1279 /* This function searches all of the edges in the program flow graph, and puts
1280 as many bad edges as possible onto the spanning tree. Bad edges include
1281 abnormals edges, which can't be instrumented at the moment. Since it is
1282 possible for fake edges to form a cycle, we will have to develop some
1283 better way in the future. Also put critical edges to the tree, since they
1284 are more expensive to instrument. */
1286 static void
1287 find_spanning_tree (el)
1288 struct edge_list *el;
1290 int i;
1291 int num_edges = NUM_EDGES (el);
1292 basic_block bb;
1294 /* We use aux field for standard union-find algorithm. */
1295 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1296 bb->aux = bb;
1298 /* Add fake edge exit to entry we can't instrument. */
1299 union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
1301 /* First add all abnormal edges to the tree unless they form a cycle. Also
1302 add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1303 setting return value from function. */
1304 for (i = 0; i < num_edges; i++)
1306 edge e = INDEX_EDGE (el, i);
1307 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1308 || e->dest == EXIT_BLOCK_PTR
1310 && !EDGE_INFO (e)->ignore
1311 && (find_group (e->src) != find_group (e->dest)))
1313 if (rtl_dump_file)
1314 fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
1315 e->src->index, e->dest->index);
1316 EDGE_INFO (e)->on_tree = 1;
1317 union_groups (e->src, e->dest);
1321 /* Now insert all critical edges to the tree unless they form a cycle. */
1322 for (i = 0; i < num_edges; i++)
1324 edge e = INDEX_EDGE (el, i);
1325 if ((EDGE_CRITICAL_P (e))
1326 && !EDGE_INFO (e)->ignore
1327 && (find_group (e->src) != find_group (e->dest)))
1329 if (rtl_dump_file)
1330 fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1331 e->src->index, e->dest->index);
1332 EDGE_INFO (e)->on_tree = 1;
1333 union_groups (e->src, e->dest);
1337 /* And now the rest. */
1338 for (i = 0; i < num_edges; i++)
1340 edge e = INDEX_EDGE (el, i);
1341 if (find_group (e->src) != find_group (e->dest)
1342 && !EDGE_INFO (e)->ignore)
1344 if (rtl_dump_file)
1345 fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1346 e->src->index, e->dest->index);
1347 EDGE_INFO (e)->on_tree = 1;
1348 union_groups (e->src, e->dest);
1352 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1353 bb->aux = NULL;
1356 /* Perform file-level initialization for branch-prob processing. */
1358 void
1359 init_branch_prob (filename)
1360 const char *filename;
1362 int len = strlen (filename);
1363 int i;
1365 if (flag_test_coverage)
1367 /* Open the bbg output file. */
1368 bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1);
1369 strcpy (bbg_file_name, filename);
1370 strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
1371 bbg_file = fopen (bbg_file_name, "wb");
1372 if (!bbg_file)
1373 fatal_io_error ("cannot open %s", bbg_file_name);
1375 if (gcov_write_unsigned (bbg_file, GCOV_GRAPH_MAGIC)
1376 || gcov_write_unsigned (bbg_file, GCOV_VERSION))
1378 fclose (bbg_file);
1379 fatal_io_error ("cannot write `%s'", bbg_file_name);
1383 da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
1384 strcpy (da_file_name, filename);
1385 strcat (da_file_name, GCOV_DATA_SUFFIX);
1387 if (flag_branch_probabilities)
1389 da_file = fopen (da_file_name, "rb");
1390 if (!da_file)
1391 warning ("file %s not found, execution counts assumed to be zero",
1392 da_file_name);
1393 if (counts_file_index && strcmp (da_file_name, counts_file_name))
1394 cleanup_counts_index (0);
1395 if (index_counts_file ())
1396 counts_file_name = xstrdup (da_file_name);
1399 if (profile_arc_flag)
1401 /* Generate and save a copy of this so it can be shared. */
1402 char buf[20];
1404 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1405 profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1408 total_num_blocks = 0;
1409 total_num_edges = 0;
1410 total_num_edges_ignored = 0;
1411 total_num_edges_instrumented = 0;
1412 total_num_blocks_created = 0;
1413 total_num_passes = 0;
1414 total_num_times_called = 0;
1415 total_num_branches = 0;
1416 total_num_never_executed = 0;
1417 for (i = 0; i < 20; i++)
1418 total_hist_br_prob[i] = 0;
1421 /* Performs file-level cleanup after branch-prob processing
1422 is completed. */
1424 void
1425 end_branch_prob ()
1427 if (flag_test_coverage)
1429 if (bbg_file)
1431 #if !SELF_COVERAGE
1432 /* If the compiler is instrumented, we should not remove the
1433 counts file, because we might be recompiling
1434 ourselves. The .da files are all removed during copying
1435 the stage1 files. */
1436 unlink (da_file_name);
1437 #endif
1438 fclose (bbg_file);
1440 else
1442 unlink (bbg_file_name);
1443 unlink (da_file_name);
1447 if (da_file)
1448 fclose (da_file);
1450 if (rtl_dump_file)
1452 fprintf (rtl_dump_file, "\n");
1453 fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1454 total_num_blocks);
1455 fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1456 fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1457 total_num_edges_ignored);
1458 fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1459 total_num_edges_instrumented);
1460 fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1461 total_num_blocks_created);
1462 fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1463 total_num_passes);
1464 if (total_num_times_called != 0)
1465 fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1466 (total_num_passes + (total_num_times_called >> 1))
1467 / total_num_times_called);
1468 fprintf (rtl_dump_file, "Total number of branches: %d\n",
1469 total_num_branches);
1470 fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1471 total_num_never_executed);
1472 if (total_num_branches)
1474 int i;
1476 for (i = 0; i < 10; i++)
1477 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1478 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1479 / total_num_branches, 5*i, 5*i+5);
1484 /* Write out the structure which libgcc uses to locate all the arc
1485 counters. The structures used here must match those defined in
1486 gcov-io.h. Write out the constructor to call __gcov_init. */
1488 void
1489 create_profiler ()
1491 tree fields, field, value = NULL_TREE;
1492 tree ginfo_type;
1493 tree string_type;
1494 tree gcov_type, gcov_ptr_type;
1495 char name[20];
1496 char *ctor_name;
1497 tree structure, ctor;
1498 rtx structure_address;
1499 int save_flag_inline_functions = flag_inline_functions;
1501 if (!profile_info.count_instrumented_edges)
1502 return;
1504 string_type = build_pointer_type
1505 (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
1506 gcov_type = make_signed_type (GCOV_TYPE_SIZE);
1507 gcov_ptr_type
1508 = build_pointer_type (build_qualified_type
1509 (gcov_type, TYPE_QUAL_CONST));
1511 ginfo_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1514 /* Version ident */
1515 fields = build_decl (FIELD_DECL, NULL_TREE, long_unsigned_type_node);
1516 value = tree_cons (fields, convert (long_unsigned_type_node, build_int_2
1517 (GCOV_VERSION, 0)), value);
1519 /* NULL */
1520 field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type
1521 (build_qualified_type
1522 (ginfo_type, TYPE_QUAL_CONST)));
1523 TREE_CHAIN (field) = fields;
1524 fields = field;
1525 value = tree_cons (fields, null_pointer_node, value);
1527 /* Filename */
1529 tree filename_string;
1530 char *filename;
1531 int filename_len;
1533 filename = getpwd ();
1534 filename = (filename && da_file_name[0] != '/'
1535 ? concat (filename, "/", da_file_name, NULL)
1536 : da_file_name);
1537 filename_len = strlen (filename);
1538 filename_string = build_string (filename_len + 1, filename);
1539 if (filename != da_file_name)
1540 free (filename);
1541 TREE_TYPE (filename_string) = build_array_type
1542 (char_type_node, build_index_type
1543 (build_int_2 (filename_len, 0)));
1545 field = build_decl (FIELD_DECL, NULL_TREE, string_type);
1546 TREE_CHAIN (field) = fields;
1547 fields = field;
1548 value = tree_cons (fields, build1 (ADDR_EXPR, string_type,
1549 filename_string), value);
1552 /* Workspace */
1553 field = build_decl (FIELD_DECL, NULL_TREE, long_integer_type_node);
1554 TREE_CHAIN (field) = fields;
1555 fields = field;
1556 value = tree_cons (fields,
1557 convert (long_integer_type_node, integer_zero_node),
1558 value);
1560 /* function_info table */
1562 struct function_list *item;
1563 int num_nodes = 0;
1564 tree array_value = NULL_TREE;
1565 tree finfo_type, finfo_ptr_type;
1566 tree name, checksum, arcs;
1568 finfo_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1569 name = build_decl (FIELD_DECL, NULL_TREE, string_type);
1570 checksum = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1571 TREE_CHAIN (checksum) = name;
1572 arcs = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1573 TREE_CHAIN (arcs) = checksum;
1574 finish_builtin_struct (finfo_type, "__function_info",
1575 arcs, NULL_TREE);
1576 finfo_ptr_type = build_pointer_type
1577 (build_qualified_type (finfo_type, TYPE_QUAL_CONST));
1579 for (item = functions_head; item != 0; item = item->next, num_nodes++)
1581 size_t name_len = strlen (item->name);
1582 tree finfo_value = NULL_TREE;
1583 tree fname = build_string (name_len + 1, item->name);
1585 TREE_TYPE (fname) = build_array_type
1586 (char_type_node, build_index_type (build_int_2 (name_len, 0)));
1587 finfo_value = tree_cons (name, build1
1588 (ADDR_EXPR, string_type,
1589 fname), finfo_value);
1590 finfo_value = tree_cons (checksum, convert
1591 (unsigned_type_node,
1592 build_int_2 (item->cfg_checksum, 0)),
1593 finfo_value);
1594 finfo_value = tree_cons (arcs, convert
1595 (unsigned_type_node,
1596 build_int_2 (item->count_edges, 0)),
1597 finfo_value);
1598 array_value = tree_cons (NULL_TREE, build
1599 (CONSTRUCTOR, finfo_type, NULL_TREE,
1600 nreverse (finfo_value)), array_value);
1603 /* Create constructor for array. */
1604 if (num_nodes)
1606 tree array_type;
1608 array_type = build_array_type (finfo_type, build_index_type
1609 (build_int_2 (num_nodes - 1, 0)));
1610 array_value = build (CONSTRUCTOR, array_type,
1611 NULL_TREE, nreverse (array_value));
1612 array_value = build1
1613 (ADDR_EXPR, finfo_ptr_type, array_value);
1615 else
1616 array_value = null_pointer_node;
1618 field = build_decl (FIELD_DECL, NULL_TREE, finfo_ptr_type);
1619 TREE_CHAIN (field) = fields;
1620 fields = field;
1621 value = tree_cons (fields, array_value, value);
1623 /* number of functions */
1624 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1625 TREE_CHAIN (field) = fields;
1626 fields = field;
1627 value = tree_cons (fields, convert (unsigned_type_node, build_int_2
1628 (num_nodes, 0)), value);
1631 /* arc count table */
1633 tree counts_table = null_pointer_node;
1635 if (profile_info.count_instrumented_edges)
1637 tree gcov_type_array_type
1638 = build_array_type (gcov_type, build_index_type
1639 (build_int_2 (profile_info.
1640 count_instrumented_edges - 1, 0)));
1641 /* No values. */
1642 counts_table
1643 = build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
1644 TREE_STATIC (counts_table) = 1;
1645 DECL_NAME (counts_table) = get_identifier (XSTR (profiler_label, 0));
1646 assemble_variable (counts_table, 0, 0, 0);
1647 counts_table = build1 (ADDR_EXPR, gcov_ptr_type, counts_table);
1650 field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
1651 TREE_CHAIN (field) = fields;
1652 fields = field;
1653 value = tree_cons (fields, counts_table, value);
1656 /* number of arc counts */
1657 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1658 TREE_CHAIN (field) = fields;
1659 fields = field;
1660 value = tree_cons (fields, convert
1661 (unsigned_type_node,
1662 build_int_2 (profile_info
1663 .count_instrumented_edges, 0)),
1664 value);
1666 finish_builtin_struct (ginfo_type, "__gcov_info", fields, NULL_TREE);
1667 structure = build (VAR_DECL, ginfo_type, NULL_TREE, NULL_TREE);
1668 DECL_INITIAL (structure)
1669 = build (CONSTRUCTOR, ginfo_type, NULL_TREE, nreverse (value));
1670 TREE_STATIC (structure) = 1;
1671 ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
1672 DECL_NAME (structure) = get_identifier (name);
1674 /* Build structure. */
1675 assemble_variable (structure, 0, 0, 0);
1677 /* Build the constructor function to invoke __gcov_init. */
1678 ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
1679 "_GCOV", NULL);
1680 ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
1681 build_function_type (void_type_node, NULL_TREE));
1682 free (ctor_name);
1683 DECL_EXTERNAL (ctor) = 0;
1685 /* It can be a static function as long as collect2 does not have
1686 to scan the object file to find its ctor/dtor routine. */
1687 TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
1688 TREE_USED (ctor) = 1;
1689 DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1691 ctor = (*lang_hooks.decls.pushdecl) (ctor);
1692 rest_of_decl_compilation (ctor, 0, 1, 0);
1693 announce_function (ctor);
1694 current_function_decl = ctor;
1695 DECL_INITIAL (ctor) = error_mark_node;
1696 make_decl_rtl (ctor, NULL);
1697 init_function_start (ctor, input_filename, lineno);
1698 (*lang_hooks.decls.pushlevel) (0);
1699 expand_function_start (ctor, 0);
1700 cfun->arc_profile = 0;
1702 /* Actually generate the code to call __gcov_init. */
1703 structure_address = force_reg (Pmode, gen_rtx_SYMBOL_REF
1704 (Pmode, IDENTIFIER_POINTER
1705 (DECL_NAME (structure))));
1706 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__gcov_init"),
1707 LCT_NORMAL, VOIDmode, 1,
1708 structure_address, Pmode);
1710 expand_function_end (input_filename, lineno, 0);
1711 (*lang_hooks.decls.poplevel) (1, 0, 1);
1713 /* Since ctor isn't in the list of globals, it would never be emitted
1714 when it's considered to be 'safe' for inlining, so turn off
1715 flag_inline_functions. */
1716 flag_inline_functions = 0;
1718 rest_of_compilation (ctor);
1720 /* Reset flag_inline_functions to its original value. */
1721 flag_inline_functions = save_flag_inline_functions;
1723 if (! quiet_flag)
1724 fflush (asm_out_file);
1725 current_function_decl = NULL_TREE;
1727 if (targetm.have_ctors_dtors)
1728 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
1729 DEFAULT_INIT_PRIORITY);
1732 /* Output instructions as RTL to increment the edge execution count. */
1734 static rtx
1735 gen_edge_profiler (edgeno)
1736 int edgeno;
1738 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1739 rtx mem_ref, tmp;
1740 rtx sequence;
1742 start_sequence ();
1744 tmp = force_reg (Pmode, profiler_label);
1745 tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
1746 mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
1748 set_mem_alias_set (mem_ref, new_alias_set ());
1750 tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
1751 mem_ref, 0, OPTAB_WIDEN);
1753 if (tmp != mem_ref)
1754 emit_move_insn (copy_rtx (mem_ref), tmp);
1756 sequence = get_insns ();
1757 end_sequence ();
1758 return sequence;
1761 #include "gt-profile.h"