FSF GCC merge 02/23/03
[official-gcc.git] / gcc / profile.c
blobde2d309b449ed634c8441cdb6e448171e2dbf824
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 /* No .da file, no data. */
293 if (!da_file)
294 return 0;
295 counts_file_index = htab_create (10, htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del);
297 /* Now index all profile sections. */
298 rewind (da_file);
300 summary = NULL;
302 if (gcov_read_unsigned (da_file, &magic) || magic != GCOV_DATA_MAGIC)
304 warning ("`%s' is not a gcov data file", da_file_name);
305 goto cleanup;
307 if (gcov_read_unsigned (da_file, &version) || version != GCOV_VERSION)
309 char v[4], e[4];
310 magic = GCOV_VERSION;
312 for (ix = 4; ix--; magic >>= 8, version >>= 8)
314 v[ix] = version;
315 e[ix] = magic;
317 warning ("`%s' is version `%.4s', expected version `%.4s'",
318 da_file_name, v, e);
319 goto cleanup;
322 while (1)
324 unsigned tag, length;
325 long offset;
327 offset = gcov_save_position (da_file);
328 if (gcov_read_unsigned (da_file, &tag)
329 || gcov_read_unsigned (da_file, &length))
331 if (feof (da_file))
332 break;
333 corrupt:;
334 warning ("`%s' is corrupted", da_file_name);
335 goto cleanup;
337 if (tag == GCOV_TAG_FUNCTION)
339 if (gcov_read_string (da_file, &function_name_buffer, NULL)
340 || gcov_read_unsigned (da_file, &checksum))
341 goto corrupt;
342 continue;
344 if (tag == GCOV_TAG_PROGRAM_SUMMARY)
346 if (length != GCOV_SUMMARY_LENGTH)
347 goto corrupt;
349 if (summary)
350 *summary = offset;
351 summary = NULL;
353 else
355 if (function_name_buffer)
357 struct da_index_entry **slot, elt;
358 elt.function_name = function_name_buffer;
359 elt.section = tag;
361 slot = (struct da_index_entry **)
362 htab_find_slot (counts_file_index, &elt, INSERT);
363 if (*slot)
365 if ((*slot)->checksum != checksum)
367 warning ("profile mismatch for `%s'", function_name_buffer);
368 goto cleanup;
370 (*slot)->n_offsets++;
371 (*slot)->offsets = xrealloc ((*slot)->offsets,
372 sizeof (struct section_reference) * (*slot)->n_offsets);
374 else
376 *slot = xmalloc (sizeof (struct da_index_entry));
377 (*slot)->function_name = xstrdup (function_name_buffer);
378 (*slot)->section = tag;
379 (*slot)->checksum = checksum;
380 (*slot)->n_offsets = 1;
381 (*slot)->offsets = xmalloc (sizeof (struct section_reference));
383 (*slot)->offsets[(*slot)->n_offsets - 1].offset = offset;
384 if (summary)
385 (*slot)->offsets[(*slot)->n_offsets - 1].owns_summary = 0;
386 else
388 summary = xmalloc (sizeof (long));
389 *summary = -1;
390 (*slot)->offsets[(*slot)->n_offsets - 1].owns_summary = 1;
392 (*slot)->offsets[(*slot)->n_offsets - 1].summary = summary;
395 if (gcov_skip (da_file, length))
396 goto corrupt;
399 free (function_name_buffer);
401 return 1;
403 cleanup:
404 cleanup_counts_index (1);
405 if (function_name_buffer)
406 free (function_name_buffer);
407 return 0;
410 /* Computes hybrid profile for all matching entries in da_file.
411 Sets max_counter_in_program as a side effect. */
413 static gcov_type *
414 get_exec_counts ()
416 unsigned num_edges = 0;
417 basic_block bb;
418 gcov_type *profile;
419 gcov_type max_count;
420 unsigned ix, i, tag, length, num;
421 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
422 struct da_index_entry *entry, what;
423 struct section_reference *act;
424 gcov_type count;
425 struct gcov_summary summ;
427 profile_info.max_counter_in_program = 0;
428 profile_info.count_profiles_merged = 0;
430 /* No .da file, no execution counts. */
431 if (!da_file)
432 return NULL;
433 if (!counts_file_index)
434 abort ();
436 /* Count the edges to be (possibly) instrumented. */
438 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
440 edge e;
441 for (e = bb->succ; e; e = e->succ_next)
442 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
443 num_edges++;
446 /* now read and combine all matching profiles. */
448 profile = xmalloc (sizeof (gcov_type) * num_edges);
450 for (ix = 0; ix < num_edges; ix++)
451 profile[ix] = 0;
453 what.function_name = (char *) name;
454 what.section = GCOV_TAG_ARC_COUNTS;
455 entry = htab_find (counts_file_index, &what);
456 if (!entry)
458 warning ("No profile for function '%s' found.", name);
459 goto cleanup;
462 if (entry->checksum != profile_info.current_function_cfg_checksum)
464 warning ("profile mismatch for `%s'", current_function_name);
465 goto cleanup;
468 for (i = 0; i < entry->n_offsets; i++)
470 act = entry->offsets + i;
472 /* Read arc counters. */
473 max_count = 0;
474 gcov_resync (da_file, act->offset, 0);
476 if (gcov_read_unsigned (da_file, &tag)
477 || gcov_read_unsigned (da_file, &length)
478 || tag != GCOV_TAG_ARC_COUNTS)
480 /* We have already passed through file, so any error means
481 something is rotten. */
482 abort ();
484 num = length / 8;
486 if (num != num_edges)
488 warning ("profile mismatch for `%s'", current_function_name);
489 goto cleanup;
492 for (ix = 0; ix != num; ix++)
494 if (gcov_read_counter (da_file, &count))
495 abort ();
496 if (count > max_count)
497 max_count = count;
498 profile[ix] += count;
501 /* Read program summary. */
502 if (*act->summary != -1)
504 gcov_resync (da_file, *act->summary, 0);
505 if (gcov_read_unsigned (da_file, &tag)
506 || gcov_read_unsigned (da_file, &length)
507 || tag != GCOV_TAG_PROGRAM_SUMMARY
508 || gcov_read_summary (da_file, &summ))
509 abort ();
510 profile_info.count_profiles_merged += summ.runs;
511 profile_info.max_counter_in_program += summ.arc_sum_max;
513 else
514 summ.runs = 0;
515 if (!summ.runs)
517 profile_info.count_profiles_merged++;
518 profile_info.max_counter_in_program += max_count;
522 if (rtl_dump_file)
524 fprintf(rtl_dump_file, "Merged %i profiles with maximal count %i.\n",
525 profile_info.count_profiles_merged,
526 (int)profile_info.max_counter_in_program);
529 return profile;
531 cleanup:;
532 free (profile);
533 cleanup_counts_index (1);
534 return NULL;
538 /* Compute the branch probabilities for the various branches.
539 Annotate them accordingly. */
541 static void
542 compute_branch_probabilities ()
544 basic_block bb;
545 int i;
546 int num_edges = 0;
547 int changes;
548 int passes;
549 int hist_br_prob[20];
550 int num_never_executed;
551 int num_branches;
552 gcov_type *exec_counts = get_exec_counts ();
553 int exec_counts_pos = 0;
555 /* Attach extra info block to each bb. */
557 alloc_aux_for_blocks (sizeof (struct bb_info));
558 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
560 edge e;
562 for (e = bb->succ; e; e = e->succ_next)
563 if (!EDGE_INFO (e)->ignore)
564 BB_INFO (bb)->succ_count++;
565 for (e = bb->pred; e; e = e->pred_next)
566 if (!EDGE_INFO (e)->ignore)
567 BB_INFO (bb)->pred_count++;
570 /* Avoid predicting entry on exit nodes. */
571 BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
572 BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
574 /* For each edge not on the spanning tree, set its execution count from
575 the .da file. */
577 /* The first count in the .da file is the number of times that the function
578 was entered. This is the exec_count for block zero. */
580 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
582 edge e;
583 for (e = bb->succ; e; e = e->succ_next)
584 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
586 num_edges++;
587 if (exec_counts)
589 e->count = exec_counts[exec_counts_pos++];
591 else
592 e->count = 0;
594 EDGE_INFO (e)->count_valid = 1;
595 BB_INFO (bb)->succ_count--;
596 BB_INFO (e->dest)->pred_count--;
597 if (rtl_dump_file)
599 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
600 bb->index, e->dest->index);
601 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
602 (HOST_WIDEST_INT) e->count);
607 if (rtl_dump_file)
608 fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
610 /* For every block in the file,
611 - if every exit/entrance edge has a known count, then set the block count
612 - if the block count is known, and every exit/entrance edge but one has
613 a known execution count, then set the count of the remaining edge
615 As edge counts are set, decrement the succ/pred count, but don't delete
616 the edge, that way we can easily tell when all edges are known, or only
617 one edge is unknown. */
619 /* The order that the basic blocks are iterated through is important.
620 Since the code that finds spanning trees starts with block 0, low numbered
621 edges are put on the spanning tree in preference to high numbered edges.
622 Hence, most instrumented edges are at the end. Graph solving works much
623 faster if we propagate numbers from the end to the start.
625 This takes an average of slightly more than 3 passes. */
627 changes = 1;
628 passes = 0;
629 while (changes)
631 passes++;
632 changes = 0;
633 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
635 struct bb_info *bi = BB_INFO (bb);
636 if (! bi->count_valid)
638 if (bi->succ_count == 0)
640 edge e;
641 gcov_type total = 0;
643 for (e = bb->succ; e; e = e->succ_next)
644 total += e->count;
645 bb->count = total;
646 bi->count_valid = 1;
647 changes = 1;
649 else if (bi->pred_count == 0)
651 edge e;
652 gcov_type total = 0;
654 for (e = bb->pred; e; e = e->pred_next)
655 total += e->count;
656 bb->count = total;
657 bi->count_valid = 1;
658 changes = 1;
661 if (bi->count_valid)
663 if (bi->succ_count == 1)
665 edge e;
666 gcov_type total = 0;
668 /* One of the counts will be invalid, but it is zero,
669 so adding it in also doesn't hurt. */
670 for (e = bb->succ; e; e = e->succ_next)
671 total += e->count;
673 /* Seedgeh for the invalid edge, and set its count. */
674 for (e = bb->succ; e; e = e->succ_next)
675 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
676 break;
678 /* Calculate count for remaining edge by conservation. */
679 total = bb->count - total;
681 if (! e)
682 abort ();
683 EDGE_INFO (e)->count_valid = 1;
684 e->count = total;
685 bi->succ_count--;
687 BB_INFO (e->dest)->pred_count--;
688 changes = 1;
690 if (bi->pred_count == 1)
692 edge e;
693 gcov_type total = 0;
695 /* One of the counts will be invalid, but it is zero,
696 so adding it in also doesn't hurt. */
697 for (e = bb->pred; e; e = e->pred_next)
698 total += e->count;
700 /* Seedgeh for the invalid edge, and set its count. */
701 for (e = bb->pred; e; e = e->pred_next)
702 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
703 break;
705 /* Calculate count for remaining edge by conservation. */
706 total = bb->count - total + e->count;
708 if (! e)
709 abort ();
710 EDGE_INFO (e)->count_valid = 1;
711 e->count = total;
712 bi->pred_count--;
714 BB_INFO (e->src)->succ_count--;
715 changes = 1;
720 if (rtl_dump_file)
721 dump_flow_info (rtl_dump_file);
723 total_num_passes += passes;
724 if (rtl_dump_file)
725 fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
727 /* If the graph has been correctly solved, every block will have a
728 succ and pred count of zero. */
729 FOR_EACH_BB (bb)
731 if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
732 abort ();
735 /* For every edge, calculate its branch probability and add a reg_note
736 to the branch insn to indicate this. */
738 for (i = 0; i < 20; i++)
739 hist_br_prob[i] = 0;
740 num_never_executed = 0;
741 num_branches = 0;
743 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
745 edge e;
746 gcov_type total;
747 rtx note;
749 total = bb->count;
750 if (total)
752 for (e = bb->succ; e; e = e->succ_next)
754 e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
755 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
757 error ("corrupted profile info: prob for %d-%d thought to be %d",
758 e->src->index, e->dest->index, e->probability);
759 e->probability = REG_BR_PROB_BASE / 2;
762 if (bb->index >= 0
763 && any_condjump_p (bb->end)
764 && bb->succ->succ_next)
766 int prob;
767 edge e;
768 int index;
770 /* Find the branch edge. It is possible that we do have fake
771 edges here. */
772 for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
773 e = e->succ_next)
774 continue; /* Loop body has been intentionally left blank. */
776 prob = e->probability;
777 index = prob * 20 / REG_BR_PROB_BASE;
779 if (index == 20)
780 index = 19;
781 hist_br_prob[index]++;
783 note = find_reg_note (bb->end, REG_BR_PROB, 0);
784 /* There may be already note put by some other pass, such
785 as builtin_expect expander. */
786 if (note)
787 XEXP (note, 0) = GEN_INT (prob);
788 else
789 REG_NOTES (bb->end)
790 = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
791 REG_NOTES (bb->end));
792 num_branches++;
795 /* Otherwise distribute the probabilities evenly so we get sane
796 sum. Use simple heuristics that if there are normal edges,
797 give all abnormals frequency of 0, otherwise distribute the
798 frequency over abnormals (this is the case of noreturn
799 calls). */
800 else
802 for (e = bb->succ; e; e = e->succ_next)
803 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
804 total ++;
805 if (total)
807 for (e = bb->succ; e; e = e->succ_next)
808 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
809 e->probability = REG_BR_PROB_BASE / total;
810 else
811 e->probability = 0;
813 else
815 for (e = bb->succ; e; e = e->succ_next)
816 total ++;
817 for (e = bb->succ; e; e = e->succ_next)
818 e->probability = REG_BR_PROB_BASE / total;
820 if (bb->index >= 0
821 && any_condjump_p (bb->end)
822 && bb->succ->succ_next)
823 num_branches++, num_never_executed;
827 if (rtl_dump_file)
829 fprintf (rtl_dump_file, "%d branches\n", num_branches);
830 fprintf (rtl_dump_file, "%d branches never executed\n",
831 num_never_executed);
832 if (num_branches)
833 for (i = 0; i < 10; i++)
834 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
835 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
836 5 * i, 5 * i + 5);
838 total_num_branches += num_branches;
839 total_num_never_executed += num_never_executed;
840 for (i = 0; i < 20; i++)
841 total_hist_br_prob[i] += hist_br_prob[i];
843 fputc ('\n', rtl_dump_file);
844 fputc ('\n', rtl_dump_file);
847 free_aux_for_blocks ();
848 if (exec_counts)
849 free (exec_counts);
852 /* Compute checksum for the current function. We generate a CRC32. */
854 static unsigned
855 compute_checksum ()
857 unsigned chksum = 0;
858 basic_block bb;
860 FOR_EACH_BB (bb)
862 edge e = NULL;
866 unsigned value = BB_TO_GCOV_INDEX (e ? e->dest : bb);
867 unsigned ix;
869 /* No need to use all bits in value identically, nearly all
870 functions have less than 256 blocks. */
871 value ^= value << 16;
872 value ^= value << 8;
874 for (ix = 8; ix--; value <<= 1)
876 unsigned feedback;
878 feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
879 chksum <<= 1;
880 chksum ^= feedback;
883 e = e ? e->succ_next : bb->succ;
885 while (e);
888 return chksum;
891 /* Instrument and/or analyze program behavior based on program flow graph.
892 In either case, this function builds a flow graph for the function being
893 compiled. The flow graph is stored in BB_GRAPH.
895 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
896 the flow graph that are needed to reconstruct the dynamic behavior of the
897 flow graph.
899 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
900 information from a data file containing edge count information from previous
901 executions of the function being compiled. In this case, the flow graph is
902 annotated with actual execution counts, which are later propagated into the
903 rtl for optimization purposes.
905 Main entry point of this file. */
907 void
908 branch_prob ()
910 basic_block bb;
911 int i;
912 int num_edges, ignored_edges;
913 struct edge_list *el;
914 const char *name = IDENTIFIER_POINTER
915 (DECL_ASSEMBLER_NAME (current_function_decl));
917 profile_info.current_function_cfg_checksum = compute_checksum ();
919 if (rtl_dump_file)
920 fprintf (rtl_dump_file, "CFG checksum is %u\n",
921 profile_info.current_function_cfg_checksum);
923 total_num_times_called++;
925 flow_call_edges_add (NULL);
926 add_noreturn_fake_exit_edges ();
928 /* We can't handle cyclic regions constructed using abnormal edges.
929 To avoid these we replace every source of abnormal edge by a fake
930 edge from entry node and every destination by fake edge to exit.
931 This keeps graph acyclic and our calculation exact for all normal
932 edges except for exit and entrance ones.
934 We also add fake exit edges for each call and asm statement in the
935 basic, since it may not return. */
937 FOR_EACH_BB (bb)
939 int need_exit_edge = 0, need_entry_edge = 0;
940 int have_exit_edge = 0, have_entry_edge = 0;
941 rtx insn;
942 edge e;
944 /* Add fake edges from entry block to the call insns that may return
945 twice. The CFG is not quite correct then, as call insn plays more
946 role of CODE_LABEL, but for our purposes, everything should be OK,
947 as we never insert code to the beginning of basic block. */
948 for (insn = bb->head; insn != NEXT_INSN (bb->end);
949 insn = NEXT_INSN (insn))
951 if (GET_CODE (insn) == CALL_INSN
952 && find_reg_note (insn, REG_SETJMP, NULL))
954 if (GET_CODE (bb->head) == CODE_LABEL
955 || insn != NEXT_INSN (bb->head))
957 e = split_block (bb, PREV_INSN (insn));
958 make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
959 break;
961 else
963 /* We should not get abort here, as call to setjmp should not
964 be the very first instruction of function. */
965 if (bb == ENTRY_BLOCK_PTR)
966 abort ();
967 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
972 for (e = bb->succ; e; e = e->succ_next)
974 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
975 && e->dest != EXIT_BLOCK_PTR)
976 need_exit_edge = 1;
977 if (e->dest == EXIT_BLOCK_PTR)
978 have_exit_edge = 1;
980 for (e = bb->pred; e; e = e->pred_next)
982 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
983 && e->src != ENTRY_BLOCK_PTR)
984 need_entry_edge = 1;
985 if (e->src == ENTRY_BLOCK_PTR)
986 have_entry_edge = 1;
989 if (need_exit_edge && !have_exit_edge)
991 if (rtl_dump_file)
992 fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
993 bb->index);
994 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
996 if (need_entry_edge && !have_entry_edge)
998 if (rtl_dump_file)
999 fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
1000 bb->index);
1001 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
1005 el = create_edge_list ();
1006 num_edges = NUM_EDGES (el);
1007 alloc_aux_for_edges (sizeof (struct edge_info));
1009 /* The basic blocks are expected to be numbered sequentially. */
1010 compact_blocks ();
1012 ignored_edges = 0;
1013 for (i = 0 ; i < num_edges ; i++)
1015 edge e = INDEX_EDGE (el, i);
1016 e->count = 0;
1018 /* Mark edges we've replaced by fake edges above as ignored. */
1019 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
1020 && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
1022 EDGE_INFO (e)->ignore = 1;
1023 ignored_edges++;
1027 #ifdef ENABLE_CHECKING
1028 verify_flow_info ();
1029 #endif
1031 /* Create spanning tree from basic block graph, mark each edge that is
1032 on the spanning tree. We insert as many abnormal and critical edges
1033 as possible to minimize number of edge splits necessary. */
1035 find_spanning_tree (el);
1037 /* Fake edges that are not on the tree will not be instrumented, so
1038 mark them ignored. */
1039 for (i = 0; i < num_edges; i++)
1041 edge e = INDEX_EDGE (el, i);
1042 struct edge_info *inf = EDGE_INFO (e);
1043 if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
1045 inf->ignore = 1;
1046 ignored_edges++;
1050 total_num_blocks += n_basic_blocks + 2;
1051 if (rtl_dump_file)
1052 fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
1054 total_num_edges += num_edges;
1055 if (rtl_dump_file)
1056 fprintf (rtl_dump_file, "%d edges\n", num_edges);
1058 total_num_edges_ignored += ignored_edges;
1059 if (rtl_dump_file)
1060 fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
1062 /* Create a .bbg file from which gcov can reconstruct the basic block
1063 graph. First output the number of basic blocks, and then for every
1064 edge output the source and target basic block numbers.
1065 NOTE: The format of this file must be compatible with gcov. */
1067 if (flag_test_coverage && bbg_file)
1069 long offset;
1071 /* Announce function */
1072 if (gcov_write_unsigned (bbg_file, GCOV_TAG_FUNCTION)
1073 || !(offset = gcov_reserve_length (bbg_file))
1074 || gcov_write_string (bbg_file, name,
1075 strlen (name))
1076 || gcov_write_unsigned (bbg_file,
1077 profile_info.current_function_cfg_checksum)
1078 || gcov_write_length (bbg_file, offset))
1079 goto bbg_error;
1081 /* Basic block flags */
1082 if (gcov_write_unsigned (bbg_file, GCOV_TAG_BLOCKS)
1083 || !(offset = gcov_reserve_length (bbg_file)))
1084 goto bbg_error;
1085 for (i = 0; i != n_basic_blocks + 2; i++)
1086 if (gcov_write_unsigned (bbg_file, 0))
1087 goto bbg_error;
1088 if (gcov_write_length (bbg_file, offset))
1089 goto bbg_error;
1091 /* Arcs */
1092 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
1094 edge e;
1096 if (gcov_write_unsigned (bbg_file, GCOV_TAG_ARCS)
1097 || !(offset = gcov_reserve_length (bbg_file))
1098 || gcov_write_unsigned (bbg_file, BB_TO_GCOV_INDEX (bb)))
1099 goto bbg_error;
1101 for (e = bb->succ; e; e = e->succ_next)
1103 struct edge_info *i = EDGE_INFO (e);
1104 if (!i->ignore)
1106 unsigned flag_bits = 0;
1108 if (i->on_tree)
1109 flag_bits |= GCOV_ARC_ON_TREE;
1110 if (e->flags & EDGE_FAKE)
1111 flag_bits |= GCOV_ARC_FAKE;
1112 if (e->flags & EDGE_FALLTHRU)
1113 flag_bits |= GCOV_ARC_FALLTHROUGH;
1115 if (gcov_write_unsigned (bbg_file,
1116 BB_TO_GCOV_INDEX (e->dest))
1117 || gcov_write_unsigned (bbg_file, flag_bits))
1118 goto bbg_error;
1121 if (gcov_write_length (bbg_file, offset))
1122 goto bbg_error;
1125 /* Output line number information about each basic block for
1126 GCOV utility. */
1128 char const *prev_file_name = NULL;
1130 FOR_EACH_BB (bb)
1132 rtx insn = bb->head;
1133 int ignore_next_note = 0;
1135 offset = 0;
1137 /* We are looking for line number notes. Search backward
1138 before basic block to find correct ones. */
1139 insn = prev_nonnote_insn (insn);
1140 if (!insn)
1141 insn = get_insns ();
1142 else
1143 insn = NEXT_INSN (insn);
1145 while (insn != bb->end)
1147 if (GET_CODE (insn) == NOTE)
1149 /* Must ignore the line number notes that immediately
1150 follow the end of an inline function to avoid counting
1151 it twice. There is a note before the call, and one
1152 after the call. */
1153 if (NOTE_LINE_NUMBER (insn)
1154 == NOTE_INSN_REPEATED_LINE_NUMBER)
1155 ignore_next_note = 1;
1156 else if (NOTE_LINE_NUMBER (insn) <= 0)
1157 /*NOP*/;
1158 else if (ignore_next_note)
1159 ignore_next_note = 0;
1160 else
1162 if (offset)
1163 /*NOP*/;
1164 else if (gcov_write_unsigned (bbg_file, GCOV_TAG_LINES)
1165 || !(offset = gcov_reserve_length (bbg_file))
1166 || gcov_write_unsigned (bbg_file,
1167 BB_TO_GCOV_INDEX (bb)))
1168 goto bbg_error;
1169 /* If this is a new source file, then output
1170 the file's name to the .bb file. */
1171 if (!prev_file_name
1172 || strcmp (NOTE_SOURCE_FILE (insn),
1173 prev_file_name))
1175 prev_file_name = NOTE_SOURCE_FILE (insn);
1176 if (gcov_write_unsigned (bbg_file, 0)
1177 || gcov_write_string (bbg_file, prev_file_name,
1178 strlen (prev_file_name)))
1179 goto bbg_error;
1181 if (gcov_write_unsigned (bbg_file, NOTE_LINE_NUMBER (insn)))
1182 goto bbg_error;
1185 insn = NEXT_INSN (insn);
1187 if (offset)
1189 if (gcov_write_unsigned (bbg_file, 0)
1190 || gcov_write_string (bbg_file, NULL, 0)
1191 || gcov_write_length (bbg_file, offset))
1193 bbg_error:;
1194 warning ("error writing `%s'", bbg_file_name);
1195 fclose (bbg_file);
1196 bbg_file = NULL;
1203 if (flag_branch_probabilities)
1204 compute_branch_probabilities ();
1206 /* For each edge not on the spanning tree, add counting code as rtl. */
1208 if (cfun->arc_profile && profile_arc_flag)
1210 struct function_list *item;
1212 instrument_edges (el);
1213 allocate_reg_info (max_reg_num (), FALSE, FALSE);
1215 /* ??? Probably should re-use the existing struct function. */
1216 item = xmalloc (sizeof (struct function_list));
1218 *functions_tail = item;
1219 functions_tail = &item->next;
1221 item->next = 0;
1222 item->name = xstrdup (name);
1223 item->cfg_checksum = profile_info.current_function_cfg_checksum;
1224 item->count_edges = profile_info.count_edges_instrumented_now;
1227 remove_fake_edges ();
1228 /* Re-merge split basic blocks and the mess introduced by
1229 insert_insn_on_edge. */
1230 cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
1231 if (rtl_dump_file)
1232 dump_flow_info (rtl_dump_file);
1234 free_aux_for_edges ();
1235 free_edge_list (el);
1238 /* Union find algorithm implementation for the basic blocks using
1239 aux fields. */
1241 static basic_block
1242 find_group (bb)
1243 basic_block bb;
1245 basic_block group = bb, bb1;
1247 while ((basic_block) group->aux != group)
1248 group = (basic_block) group->aux;
1250 /* Compress path. */
1251 while ((basic_block) bb->aux != group)
1253 bb1 = (basic_block) bb->aux;
1254 bb->aux = (void *) group;
1255 bb = bb1;
1257 return group;
1260 static void
1261 union_groups (bb1, bb2)
1262 basic_block bb1, bb2;
1264 basic_block bb1g = find_group (bb1);
1265 basic_block bb2g = find_group (bb2);
1267 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
1268 this code is unlikely going to be performance problem anyway. */
1269 if (bb1g == bb2g)
1270 abort ();
1272 bb1g->aux = bb2g;
1275 /* This function searches all of the edges in the program flow graph, and puts
1276 as many bad edges as possible onto the spanning tree. Bad edges include
1277 abnormals edges, which can't be instrumented at the moment. Since it is
1278 possible for fake edges to form a cycle, we will have to develop some
1279 better way in the future. Also put critical edges to the tree, since they
1280 are more expensive to instrument. */
1282 static void
1283 find_spanning_tree (el)
1284 struct edge_list *el;
1286 int i;
1287 int num_edges = NUM_EDGES (el);
1288 basic_block bb;
1290 /* We use aux field for standard union-find algorithm. */
1291 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1292 bb->aux = bb;
1294 /* Add fake edge exit to entry we can't instrument. */
1295 union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
1297 /* First add all abnormal edges to the tree unless they form a cycle. Also
1298 add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1299 setting return value from function. */
1300 for (i = 0; i < num_edges; i++)
1302 edge e = INDEX_EDGE (el, i);
1303 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1304 || e->dest == EXIT_BLOCK_PTR
1306 && !EDGE_INFO (e)->ignore
1307 && (find_group (e->src) != find_group (e->dest)))
1309 if (rtl_dump_file)
1310 fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
1311 e->src->index, e->dest->index);
1312 EDGE_INFO (e)->on_tree = 1;
1313 union_groups (e->src, e->dest);
1317 /* Now insert all critical edges to the tree unless they form a cycle. */
1318 for (i = 0; i < num_edges; i++)
1320 edge e = INDEX_EDGE (el, i);
1321 if ((EDGE_CRITICAL_P (e))
1322 && !EDGE_INFO (e)->ignore
1323 && (find_group (e->src) != find_group (e->dest)))
1325 if (rtl_dump_file)
1326 fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1327 e->src->index, e->dest->index);
1328 EDGE_INFO (e)->on_tree = 1;
1329 union_groups (e->src, e->dest);
1333 /* And now the rest. */
1334 for (i = 0; i < num_edges; i++)
1336 edge e = INDEX_EDGE (el, i);
1337 if (find_group (e->src) != find_group (e->dest)
1338 && !EDGE_INFO (e)->ignore)
1340 if (rtl_dump_file)
1341 fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1342 e->src->index, e->dest->index);
1343 EDGE_INFO (e)->on_tree = 1;
1344 union_groups (e->src, e->dest);
1348 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1349 bb->aux = NULL;
1352 /* Perform file-level initialization for branch-prob processing. */
1354 void
1355 init_branch_prob (filename)
1356 const char *filename;
1358 int len = strlen (filename);
1359 int i;
1361 if (flag_test_coverage)
1363 /* Open the bbg output file. */
1364 bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1);
1365 strcpy (bbg_file_name, filename);
1366 strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
1367 bbg_file = fopen (bbg_file_name, "wb");
1368 if (!bbg_file)
1369 fatal_io_error ("cannot open %s", bbg_file_name);
1371 if (gcov_write_unsigned (bbg_file, GCOV_GRAPH_MAGIC)
1372 || gcov_write_unsigned (bbg_file, GCOV_VERSION))
1374 fclose (bbg_file);
1375 fatal_io_error ("cannot write `%s'", bbg_file_name);
1379 da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
1380 strcpy (da_file_name, filename);
1381 strcat (da_file_name, GCOV_DATA_SUFFIX);
1383 if (flag_branch_probabilities)
1385 da_file = fopen (da_file_name, "rb");
1386 if (!da_file)
1387 warning ("file %s not found, execution counts assumed to be zero",
1388 da_file_name);
1389 if (counts_file_index && strcmp (da_file_name, counts_file_name))
1390 cleanup_counts_index (0);
1391 if (index_counts_file ())
1392 counts_file_name = xstrdup (da_file_name);
1395 if (profile_arc_flag)
1397 /* Generate and save a copy of this so it can be shared. */
1398 char buf[20];
1400 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1401 profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1404 total_num_blocks = 0;
1405 total_num_edges = 0;
1406 total_num_edges_ignored = 0;
1407 total_num_edges_instrumented = 0;
1408 total_num_blocks_created = 0;
1409 total_num_passes = 0;
1410 total_num_times_called = 0;
1411 total_num_branches = 0;
1412 total_num_never_executed = 0;
1413 for (i = 0; i < 20; i++)
1414 total_hist_br_prob[i] = 0;
1417 /* Performs file-level cleanup after branch-prob processing
1418 is completed. */
1420 void
1421 end_branch_prob ()
1423 if (flag_test_coverage)
1425 if (bbg_file)
1427 #if !SELF_COVERAGE
1428 /* If the compiler is instrumented, we should not remove the
1429 counts file, because we might be recompiling
1430 ourselves. The .da files are all removed during copying
1431 the stage1 files. */
1432 unlink (da_file_name);
1433 #endif
1434 fclose (bbg_file);
1436 else
1438 unlink (bbg_file_name);
1439 unlink (da_file_name);
1443 if (da_file)
1444 fclose (da_file);
1446 if (rtl_dump_file)
1448 fprintf (rtl_dump_file, "\n");
1449 fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1450 total_num_blocks);
1451 fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1452 fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1453 total_num_edges_ignored);
1454 fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1455 total_num_edges_instrumented);
1456 fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1457 total_num_blocks_created);
1458 fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1459 total_num_passes);
1460 if (total_num_times_called != 0)
1461 fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1462 (total_num_passes + (total_num_times_called >> 1))
1463 / total_num_times_called);
1464 fprintf (rtl_dump_file, "Total number of branches: %d\n",
1465 total_num_branches);
1466 fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1467 total_num_never_executed);
1468 if (total_num_branches)
1470 int i;
1472 for (i = 0; i < 10; i++)
1473 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1474 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1475 / total_num_branches, 5*i, 5*i+5);
1480 /* Write out the structure which libgcc uses to locate all the arc
1481 counters. The structures used here must match those defined in
1482 gcov-io.h. Write out the constructor to call __gcov_init. */
1484 void
1485 create_profiler ()
1487 tree fields, field, value = NULL_TREE;
1488 tree ginfo_type;
1489 tree string_type;
1490 tree gcov_type, gcov_ptr_type;
1491 char name[20];
1492 char *ctor_name;
1493 tree structure, ctor;
1494 rtx structure_address;
1495 int save_flag_inline_functions = flag_inline_functions;
1497 if (!profile_info.count_instrumented_edges)
1498 return;
1500 string_type = build_pointer_type
1501 (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
1502 gcov_type = make_signed_type (GCOV_TYPE_SIZE);
1503 gcov_ptr_type
1504 = build_pointer_type (build_qualified_type
1505 (gcov_type, TYPE_QUAL_CONST));
1507 ginfo_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1510 /* Version ident */
1511 fields = build_decl (FIELD_DECL, NULL_TREE, long_unsigned_type_node);
1512 value = tree_cons (fields, convert (long_unsigned_type_node, build_int_2
1513 (GCOV_VERSION, 0)), value);
1515 /* NULL */
1516 field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type
1517 (build_qualified_type
1518 (ginfo_type, TYPE_QUAL_CONST)));
1519 TREE_CHAIN (field) = fields;
1520 fields = field;
1521 value = tree_cons (fields, null_pointer_node, value);
1523 /* Filename */
1525 tree filename_string;
1526 char *filename;
1527 int filename_len;
1529 filename = getpwd ();
1530 filename = (filename && da_file_name[0] != '/'
1531 ? concat (filename, "/", da_file_name, NULL)
1532 : da_file_name);
1533 filename_len = strlen (filename);
1534 filename_string = build_string (filename_len + 1, filename);
1535 if (filename != da_file_name)
1536 free (filename);
1537 TREE_TYPE (filename_string) = build_array_type
1538 (char_type_node, build_index_type
1539 (build_int_2 (filename_len, 0)));
1541 field = build_decl (FIELD_DECL, NULL_TREE, string_type);
1542 TREE_CHAIN (field) = fields;
1543 fields = field;
1544 value = tree_cons (fields, build1 (ADDR_EXPR, string_type,
1545 filename_string), value);
1548 /* Workspace */
1549 field = build_decl (FIELD_DECL, NULL_TREE, long_integer_type_node);
1550 TREE_CHAIN (field) = fields;
1551 fields = field;
1552 value = tree_cons (fields,
1553 convert (long_integer_type_node, integer_zero_node),
1554 value);
1556 /* function_info table */
1558 struct function_list *item;
1559 int num_nodes = 0;
1560 tree array_value = NULL_TREE;
1561 tree finfo_type, finfo_ptr_type;
1562 tree name, checksum, arcs;
1564 finfo_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1565 name = build_decl (FIELD_DECL, NULL_TREE, string_type);
1566 checksum = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1567 TREE_CHAIN (checksum) = name;
1568 arcs = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1569 TREE_CHAIN (arcs) = checksum;
1570 finish_builtin_struct (finfo_type, "__function_info",
1571 arcs, NULL_TREE);
1572 finfo_ptr_type = build_pointer_type
1573 (build_qualified_type (finfo_type, TYPE_QUAL_CONST));
1575 for (item = functions_head; item != 0; item = item->next, num_nodes++)
1577 size_t name_len = strlen (item->name);
1578 tree finfo_value = NULL_TREE;
1579 tree fname = build_string (name_len + 1, item->name);
1581 TREE_TYPE (fname) = build_array_type
1582 (char_type_node, build_index_type (build_int_2 (name_len, 0)));
1583 finfo_value = tree_cons (name, build1
1584 (ADDR_EXPR, string_type,
1585 fname), finfo_value);
1586 finfo_value = tree_cons (checksum, convert
1587 (unsigned_type_node,
1588 build_int_2 (item->cfg_checksum, 0)),
1589 finfo_value);
1590 finfo_value = tree_cons (arcs, convert
1591 (unsigned_type_node,
1592 build_int_2 (item->count_edges, 0)),
1593 finfo_value);
1594 array_value = tree_cons (NULL_TREE, build
1595 (CONSTRUCTOR, finfo_type, NULL_TREE,
1596 nreverse (finfo_value)), array_value);
1599 /* Create constructor for array. */
1600 if (num_nodes)
1602 tree array_type;
1604 array_type = build_array_type (finfo_type, build_index_type
1605 (build_int_2 (num_nodes - 1, 0)));
1606 array_value = build (CONSTRUCTOR, array_type,
1607 NULL_TREE, nreverse (array_value));
1608 array_value = build1
1609 (ADDR_EXPR, finfo_ptr_type, array_value);
1611 else
1612 array_value = null_pointer_node;
1614 field = build_decl (FIELD_DECL, NULL_TREE, finfo_ptr_type);
1615 TREE_CHAIN (field) = fields;
1616 fields = field;
1617 value = tree_cons (fields, array_value, value);
1619 /* number of functions */
1620 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1621 TREE_CHAIN (field) = fields;
1622 fields = field;
1623 value = tree_cons (fields, convert (unsigned_type_node, build_int_2
1624 (num_nodes, 0)), value);
1627 /* arc count table */
1629 tree counts_table = null_pointer_node;
1631 if (profile_info.count_instrumented_edges)
1633 tree gcov_type_array_type
1634 = build_array_type (gcov_type, build_index_type
1635 (build_int_2 (profile_info.
1636 count_instrumented_edges - 1, 0)));
1637 /* No values. */
1638 counts_table
1639 = build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
1640 TREE_STATIC (counts_table) = 1;
1641 DECL_NAME (counts_table) = get_identifier (XSTR (profiler_label, 0));
1642 assemble_variable (counts_table, 0, 0, 0);
1643 counts_table = build1 (ADDR_EXPR, gcov_ptr_type, counts_table);
1646 field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
1647 TREE_CHAIN (field) = fields;
1648 fields = field;
1649 value = tree_cons (fields, counts_table, value);
1652 /* number of arc counts */
1653 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1654 TREE_CHAIN (field) = fields;
1655 fields = field;
1656 value = tree_cons (fields, convert
1657 (unsigned_type_node,
1658 build_int_2 (profile_info
1659 .count_instrumented_edges, 0)),
1660 value);
1662 finish_builtin_struct (ginfo_type, "__gcov_info", fields, NULL_TREE);
1663 structure = build (VAR_DECL, ginfo_type, NULL_TREE, NULL_TREE);
1664 DECL_INITIAL (structure)
1665 = build (CONSTRUCTOR, ginfo_type, NULL_TREE, nreverse (value));
1666 TREE_STATIC (structure) = 1;
1667 ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
1668 DECL_NAME (structure) = get_identifier (name);
1670 /* Build structure. */
1671 assemble_variable (structure, 0, 0, 0);
1673 /* Build the constructor function to invoke __gcov_init. */
1674 ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
1675 "_GCOV", NULL);
1676 ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
1677 build_function_type (void_type_node, NULL_TREE));
1678 free (ctor_name);
1679 DECL_EXTERNAL (ctor) = 0;
1681 /* It can be a static function as long as collect2 does not have
1682 to scan the object file to find its ctor/dtor routine. */
1683 TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
1684 TREE_USED (ctor) = 1;
1685 DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1687 ctor = (*lang_hooks.decls.pushdecl) (ctor);
1688 rest_of_decl_compilation (ctor, 0, 1, 0);
1689 announce_function (ctor);
1690 current_function_decl = ctor;
1691 DECL_INITIAL (ctor) = error_mark_node;
1692 make_decl_rtl (ctor, NULL);
1693 init_function_start (ctor, input_filename, lineno);
1694 (*lang_hooks.decls.pushlevel) (0);
1695 expand_function_start (ctor, 0);
1696 cfun->arc_profile = 0;
1698 /* Actually generate the code to call __gcov_init. */
1699 structure_address = force_reg (Pmode, gen_rtx_SYMBOL_REF
1700 (Pmode, IDENTIFIER_POINTER
1701 (DECL_NAME (structure))));
1702 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__gcov_init"),
1703 LCT_NORMAL, VOIDmode, 1,
1704 structure_address, Pmode);
1706 expand_function_end (input_filename, lineno, 0);
1707 (*lang_hooks.decls.poplevel) (1, 0, 1);
1709 /* Since ctor isn't in the list of globals, it would never be emitted
1710 when it's considered to be 'safe' for inlining, so turn off
1711 flag_inline_functions. */
1712 flag_inline_functions = 0;
1714 rest_of_compilation (ctor);
1716 /* Reset flag_inline_functions to its original value. */
1717 flag_inline_functions = save_flag_inline_functions;
1719 if (! quiet_flag)
1720 fflush (asm_out_file);
1721 current_function_decl = NULL_TREE;
1723 if (targetm.have_ctors_dtors)
1724 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
1725 DEFAULT_INIT_PRIORITY);
1728 /* Output instructions as RTL to increment the edge execution count. */
1730 static rtx
1731 gen_edge_profiler (edgeno)
1732 int edgeno;
1734 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1735 rtx mem_ref, tmp;
1736 rtx sequence;
1738 start_sequence ();
1740 tmp = force_reg (Pmode, profiler_label);
1741 tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
1742 mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
1744 set_mem_alias_set (mem_ref, new_alias_set ());
1746 tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
1747 mem_ref, 0, OPTAB_WIDEN);
1749 if (tmp != mem_ref)
1750 emit_move_insn (copy_rtx (mem_ref), tmp);
1752 sequence = get_insns ();
1753 end_sequence ();
1754 return sequence;
1757 #include "gt-profile.h"