2003-03-11 Aldy Hernandez <aldyh@redhat.com>
[official-gcc.git] / gcc / profile.c
blob261bfd0d007fe195c9a74bc0901399c182830da1
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 n_counter_sections; /* number of counter sections */
100 struct counter_section counter_sections[MAX_COUNTER_SECTIONS];
101 /* the sections */
104 static struct function_list *functions_head = 0;
105 static struct function_list **functions_tail = &functions_head;
107 #define EDGE_INFO(e) ((struct edge_info *) (e)->aux)
108 #define BB_INFO(b) ((struct bb_info *) (b)->aux)
110 /* Keep all basic block indexes nonnegative in the gcov output. Index 0
111 is used for entry block, last block exit block. */
112 #define BB_TO_GCOV_INDEX(bb) ((bb) == ENTRY_BLOCK_PTR ? 0 \
113 : ((bb) == EXIT_BLOCK_PTR \
114 ? last_basic_block + 1 : (bb)->index + 1))
116 /* Instantiate the profile info structure. */
118 struct profile_info profile_info;
120 /* Name and file pointer of the output file for the basic block graph. */
122 static FILE *bbg_file;
123 static char *bbg_file_name;
125 /* Name and file pointer of the input file for the arc count data. */
127 static FILE *da_file;
128 static char *da_file_name;
130 /* The name of the count table. Used by the edge profiling code. */
131 static GTY(()) rtx profiler_label;
133 /* Collect statistics on the performance of this pass for the entire source
134 file. */
136 static int total_num_blocks;
137 static int total_num_edges;
138 static int total_num_edges_ignored;
139 static int total_num_edges_instrumented;
140 static int total_num_blocks_created;
141 static int total_num_passes;
142 static int total_num_times_called;
143 static int total_hist_br_prob[20];
144 static int total_num_never_executed;
145 static int total_num_branches;
147 /* Forward declarations. */
148 static void find_spanning_tree PARAMS ((struct edge_list *));
149 static rtx gen_edge_profiler PARAMS ((int));
150 static void instrument_edges PARAMS ((struct edge_list *));
151 static void compute_branch_probabilities PARAMS ((void));
152 static hashval_t htab_counts_index_hash PARAMS ((const void *));
153 static int htab_counts_index_eq PARAMS ((const void *, const void *));
154 static void htab_counts_index_del PARAMS ((void *));
155 static void cleanup_counts_index PARAMS ((int));
156 static int index_counts_file PARAMS ((void));
157 static gcov_type * get_exec_counts PARAMS ((void));
158 static unsigned compute_checksum PARAMS ((void));
159 static basic_block find_group PARAMS ((basic_block));
160 static void union_groups PARAMS ((basic_block, basic_block));
161 static void set_purpose PARAMS ((tree, tree));
162 static rtx label_for_tag PARAMS ((unsigned));
163 static tree build_counter_section_fields PARAMS ((void));
164 static tree build_counter_section_value PARAMS ((unsigned, unsigned));
165 static tree build_counter_section_data_fields PARAMS ((void));
166 static tree build_counter_section_data_value PARAMS ((unsigned, unsigned));
167 static tree build_function_info_fields PARAMS ((void));
168 static tree build_function_info_value PARAMS ((struct function_list *));
169 static tree build_gcov_info_fields PARAMS ((tree));
170 static tree build_gcov_info_value PARAMS ((void));
173 /* Add edge instrumentation code to the entire insn chain.
175 F is the first insn of the chain.
176 NUM_BLOCKS is the number of basic blocks found in F. */
178 static void
179 instrument_edges (el)
180 struct edge_list *el;
182 int num_instr_edges = 0;
183 int num_edges = NUM_EDGES (el);
184 basic_block bb;
185 struct section_info *section_info;
186 remove_fake_edges ();
188 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
190 edge e = bb->succ;
191 while (e)
193 struct edge_info *inf = EDGE_INFO (e);
194 if (!inf->ignore && !inf->on_tree)
196 if (e->flags & EDGE_ABNORMAL)
197 abort ();
198 if (rtl_dump_file)
199 fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
200 e->src->index, e->dest->index,
201 EDGE_CRITICAL_P (e) ? " (and split)" : "");
202 insert_insn_on_edge (
203 gen_edge_profiler (total_num_edges_instrumented
204 + num_instr_edges++), e);
206 e = e->succ_next;
210 section_info = find_counters_section (GCOV_TAG_ARC_COUNTS);
211 section_info->n_counters_now = num_instr_edges;
212 total_num_edges_instrumented += num_instr_edges;
213 section_info->n_counters = total_num_edges_instrumented;
215 total_num_blocks_created += num_edges;
216 if (rtl_dump_file)
217 fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
220 struct section_reference
222 long offset;
223 int owns_summary;
224 long *summary;
227 struct da_index_entry
229 /* We hash by */
230 char *function_name;
231 unsigned section;
232 /* and store */
233 unsigned checksum;
234 unsigned n_offsets;
235 struct section_reference *offsets;
238 static hashval_t
239 htab_counts_index_hash (of)
240 const void *of;
242 const struct da_index_entry *entry = of;
244 return htab_hash_string (entry->function_name) ^ entry->section;
247 static int
248 htab_counts_index_eq (of1, of2)
249 const void *of1;
250 const void *of2;
252 const struct da_index_entry *entry1 = of1;
253 const struct da_index_entry *entry2 = of2;
255 return !strcmp (entry1->function_name, entry2->function_name)
256 && entry1->section == entry2->section;
259 static void
260 htab_counts_index_del (what)
261 void *what;
263 struct da_index_entry *entry = what;
264 unsigned i;
266 for (i = 0; i < entry->n_offsets; i++)
268 struct section_reference *act = entry->offsets + i;
269 if (act->owns_summary)
270 free (act->summary);
272 free (entry->function_name);
273 free (entry->offsets);
274 free (entry);
277 static char *counts_file_name;
278 static htab_t counts_file_index = NULL;
280 static void
281 cleanup_counts_index (close_file)
282 int close_file;
284 if (da_file && close_file)
286 fclose (da_file);
287 da_file = NULL;
289 if (counts_file_name)
290 free (counts_file_name);
291 counts_file_name = NULL;
292 if (counts_file_index)
293 htab_delete (counts_file_index);
294 counts_file_index = NULL;
297 static int
298 index_counts_file ()
300 char *function_name_buffer = NULL;
301 unsigned magic, version, ix, checksum;
302 long *summary;
304 /* No .da file, no data. */
305 if (!da_file)
306 return 0;
307 counts_file_index = htab_create (10, htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del);
309 /* Now index all profile sections. */
310 rewind (da_file);
312 summary = NULL;
314 if (gcov_read_unsigned (da_file, &magic) || magic != GCOV_DATA_MAGIC)
316 warning ("`%s' is not a gcov data file", da_file_name);
317 goto cleanup;
319 if (gcov_read_unsigned (da_file, &version) || version != GCOV_VERSION)
321 char v[4], e[4];
322 magic = GCOV_VERSION;
324 for (ix = 4; ix--; magic >>= 8, version >>= 8)
326 v[ix] = version;
327 e[ix] = magic;
329 warning ("`%s' is version `%.4s', expected version `%.4s'",
330 da_file_name, v, e);
331 goto cleanup;
334 while (1)
336 unsigned tag, length;
337 long offset;
339 offset = gcov_save_position (da_file);
340 if (gcov_read_unsigned (da_file, &tag)
341 || gcov_read_unsigned (da_file, &length))
343 if (feof (da_file))
344 break;
345 corrupt:;
346 warning ("`%s' is corrupted", da_file_name);
347 goto cleanup;
349 if (tag == GCOV_TAG_FUNCTION)
351 if (gcov_read_string (da_file, &function_name_buffer, NULL)
352 || gcov_read_unsigned (da_file, &checksum))
353 goto corrupt;
354 continue;
356 if (tag == GCOV_TAG_PROGRAM_SUMMARY)
358 if (length != GCOV_SUMMARY_LENGTH)
359 goto corrupt;
361 if (summary)
362 *summary = offset;
363 summary = NULL;
365 else
367 if (function_name_buffer)
369 struct da_index_entry **slot, elt;
370 elt.function_name = function_name_buffer;
371 elt.section = tag;
373 slot = (struct da_index_entry **)
374 htab_find_slot (counts_file_index, &elt, INSERT);
375 if (*slot)
377 if ((*slot)->checksum != checksum)
379 warning ("profile mismatch for `%s'", function_name_buffer);
380 goto cleanup;
382 (*slot)->n_offsets++;
383 (*slot)->offsets = xrealloc ((*slot)->offsets,
384 sizeof (struct section_reference) * (*slot)->n_offsets);
386 else
388 *slot = xmalloc (sizeof (struct da_index_entry));
389 (*slot)->function_name = xstrdup (function_name_buffer);
390 (*slot)->section = tag;
391 (*slot)->checksum = checksum;
392 (*slot)->n_offsets = 1;
393 (*slot)->offsets = xmalloc (sizeof (struct section_reference));
395 (*slot)->offsets[(*slot)->n_offsets - 1].offset = offset;
396 if (summary)
397 (*slot)->offsets[(*slot)->n_offsets - 1].owns_summary = 0;
398 else
400 summary = xmalloc (sizeof (long));
401 *summary = -1;
402 (*slot)->offsets[(*slot)->n_offsets - 1].owns_summary = 1;
404 (*slot)->offsets[(*slot)->n_offsets - 1].summary = summary;
407 if (gcov_skip (da_file, length))
408 goto corrupt;
411 free (function_name_buffer);
413 return 1;
415 cleanup:
416 cleanup_counts_index (1);
417 if (function_name_buffer)
418 free (function_name_buffer);
419 return 0;
422 /* Computes hybrid profile for all matching entries in da_file.
423 Sets max_counter_in_program as a side effect. */
425 static gcov_type *
426 get_exec_counts ()
428 unsigned num_edges = 0;
429 basic_block bb;
430 gcov_type *profile;
431 gcov_type max_count;
432 unsigned ix, i, tag, length, num;
433 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
434 struct da_index_entry *entry, what;
435 struct section_reference *act;
436 gcov_type count;
437 struct gcov_summary summ;
439 profile_info.max_counter_in_program = 0;
440 profile_info.count_profiles_merged = 0;
442 /* No .da file, no execution counts. */
443 if (!da_file)
444 return NULL;
445 if (!counts_file_index)
446 abort ();
448 /* Count the edges to be (possibly) instrumented. */
450 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
452 edge e;
453 for (e = bb->succ; e; e = e->succ_next)
454 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
455 num_edges++;
458 /* now read and combine all matching profiles. */
460 profile = xmalloc (sizeof (gcov_type) * num_edges);
462 for (ix = 0; ix < num_edges; ix++)
463 profile[ix] = 0;
465 what.function_name = (char *) name;
466 what.section = GCOV_TAG_ARC_COUNTS;
467 entry = htab_find (counts_file_index, &what);
468 if (!entry)
470 warning ("No profile for function '%s' found.", name);
471 goto cleanup;
474 if (entry->checksum != profile_info.current_function_cfg_checksum)
476 warning ("profile mismatch for `%s'", current_function_name);
477 goto cleanup;
480 for (i = 0; i < entry->n_offsets; i++)
482 act = entry->offsets + i;
484 /* Read arc counters. */
485 max_count = 0;
486 gcov_resync (da_file, act->offset, 0);
488 if (gcov_read_unsigned (da_file, &tag)
489 || gcov_read_unsigned (da_file, &length)
490 || tag != GCOV_TAG_ARC_COUNTS)
492 /* We have already passed through file, so any error means
493 something is rotten. */
494 abort ();
496 num = length / 8;
498 if (num != num_edges)
500 warning ("profile mismatch for `%s'", current_function_name);
501 goto cleanup;
504 for (ix = 0; ix != num; ix++)
506 if (gcov_read_counter (da_file, &count))
507 abort ();
508 if (count > max_count)
509 max_count = count;
510 profile[ix] += count;
513 /* Read program summary. */
514 if (*act->summary != -1)
516 gcov_resync (da_file, *act->summary, 0);
517 if (gcov_read_unsigned (da_file, &tag)
518 || gcov_read_unsigned (da_file, &length)
519 || tag != GCOV_TAG_PROGRAM_SUMMARY
520 || gcov_read_summary (da_file, &summ))
521 abort ();
522 profile_info.count_profiles_merged += summ.runs;
523 profile_info.max_counter_in_program += summ.arc_sum_max;
525 else
526 summ.runs = 0;
527 if (!summ.runs)
529 profile_info.count_profiles_merged++;
530 profile_info.max_counter_in_program += max_count;
534 if (rtl_dump_file)
536 fprintf(rtl_dump_file, "Merged %i profiles with maximal count %i.\n",
537 profile_info.count_profiles_merged,
538 (int)profile_info.max_counter_in_program);
541 return profile;
543 cleanup:;
544 free (profile);
545 cleanup_counts_index (1);
546 return NULL;
550 /* Compute the branch probabilities for the various branches.
551 Annotate them accordingly. */
553 static void
554 compute_branch_probabilities ()
556 basic_block bb;
557 int i;
558 int num_edges = 0;
559 int changes;
560 int passes;
561 int hist_br_prob[20];
562 int num_never_executed;
563 int num_branches;
564 gcov_type *exec_counts = get_exec_counts ();
565 int exec_counts_pos = 0;
567 /* Attach extra info block to each bb. */
569 alloc_aux_for_blocks (sizeof (struct bb_info));
570 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
572 edge e;
574 for (e = bb->succ; e; e = e->succ_next)
575 if (!EDGE_INFO (e)->ignore)
576 BB_INFO (bb)->succ_count++;
577 for (e = bb->pred; e; e = e->pred_next)
578 if (!EDGE_INFO (e)->ignore)
579 BB_INFO (bb)->pred_count++;
582 /* Avoid predicting entry on exit nodes. */
583 BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
584 BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
586 /* For each edge not on the spanning tree, set its execution count from
587 the .da file. */
589 /* The first count in the .da file is the number of times that the function
590 was entered. This is the exec_count for block zero. */
592 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
594 edge e;
595 for (e = bb->succ; e; e = e->succ_next)
596 if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
598 num_edges++;
599 if (exec_counts)
601 e->count = exec_counts[exec_counts_pos++];
603 else
604 e->count = 0;
606 EDGE_INFO (e)->count_valid = 1;
607 BB_INFO (bb)->succ_count--;
608 BB_INFO (e->dest)->pred_count--;
609 if (rtl_dump_file)
611 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
612 bb->index, e->dest->index);
613 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
614 (HOST_WIDEST_INT) e->count);
619 if (rtl_dump_file)
620 fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
622 /* For every block in the file,
623 - if every exit/entrance edge has a known count, then set the block count
624 - if the block count is known, and every exit/entrance edge but one has
625 a known execution count, then set the count of the remaining edge
627 As edge counts are set, decrement the succ/pred count, but don't delete
628 the edge, that way we can easily tell when all edges are known, or only
629 one edge is unknown. */
631 /* The order that the basic blocks are iterated through is important.
632 Since the code that finds spanning trees starts with block 0, low numbered
633 edges are put on the spanning tree in preference to high numbered edges.
634 Hence, most instrumented edges are at the end. Graph solving works much
635 faster if we propagate numbers from the end to the start.
637 This takes an average of slightly more than 3 passes. */
639 changes = 1;
640 passes = 0;
641 while (changes)
643 passes++;
644 changes = 0;
645 FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
647 struct bb_info *bi = BB_INFO (bb);
648 if (! bi->count_valid)
650 if (bi->succ_count == 0)
652 edge e;
653 gcov_type total = 0;
655 for (e = bb->succ; e; e = e->succ_next)
656 total += e->count;
657 bb->count = total;
658 bi->count_valid = 1;
659 changes = 1;
661 else if (bi->pred_count == 0)
663 edge e;
664 gcov_type total = 0;
666 for (e = bb->pred; e; e = e->pred_next)
667 total += e->count;
668 bb->count = total;
669 bi->count_valid = 1;
670 changes = 1;
673 if (bi->count_valid)
675 if (bi->succ_count == 1)
677 edge e;
678 gcov_type total = 0;
680 /* One of the counts will be invalid, but it is zero,
681 so adding it in also doesn't hurt. */
682 for (e = bb->succ; e; e = e->succ_next)
683 total += e->count;
685 /* Seedgeh for the invalid edge, and set its count. */
686 for (e = bb->succ; e; e = e->succ_next)
687 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
688 break;
690 /* Calculate count for remaining edge by conservation. */
691 total = bb->count - total;
693 if (! e)
694 abort ();
695 EDGE_INFO (e)->count_valid = 1;
696 e->count = total;
697 bi->succ_count--;
699 BB_INFO (e->dest)->pred_count--;
700 changes = 1;
702 if (bi->pred_count == 1)
704 edge e;
705 gcov_type total = 0;
707 /* One of the counts will be invalid, but it is zero,
708 so adding it in also doesn't hurt. */
709 for (e = bb->pred; e; e = e->pred_next)
710 total += e->count;
712 /* Seedgeh for the invalid edge, and set its count. */
713 for (e = bb->pred; e; e = e->pred_next)
714 if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
715 break;
717 /* Calculate count for remaining edge by conservation. */
718 total = bb->count - total + e->count;
720 if (! e)
721 abort ();
722 EDGE_INFO (e)->count_valid = 1;
723 e->count = total;
724 bi->pred_count--;
726 BB_INFO (e->src)->succ_count--;
727 changes = 1;
732 if (rtl_dump_file)
733 dump_flow_info (rtl_dump_file);
735 total_num_passes += passes;
736 if (rtl_dump_file)
737 fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
739 /* If the graph has been correctly solved, every block will have a
740 succ and pred count of zero. */
741 FOR_EACH_BB (bb)
743 if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
744 abort ();
747 /* For every edge, calculate its branch probability and add a reg_note
748 to the branch insn to indicate this. */
750 for (i = 0; i < 20; i++)
751 hist_br_prob[i] = 0;
752 num_never_executed = 0;
753 num_branches = 0;
755 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
757 edge e;
758 gcov_type total;
759 rtx note;
761 total = bb->count;
762 if (total)
764 for (e = bb->succ; e; e = e->succ_next)
766 e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
767 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
769 error ("corrupted profile info: prob for %d-%d thought to be %d",
770 e->src->index, e->dest->index, e->probability);
771 e->probability = REG_BR_PROB_BASE / 2;
774 if (bb->index >= 0
775 && any_condjump_p (bb->end)
776 && bb->succ->succ_next)
778 int prob;
779 edge e;
780 int index;
782 /* Find the branch edge. It is possible that we do have fake
783 edges here. */
784 for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
785 e = e->succ_next)
786 continue; /* Loop body has been intentionally left blank. */
788 prob = e->probability;
789 index = prob * 20 / REG_BR_PROB_BASE;
791 if (index == 20)
792 index = 19;
793 hist_br_prob[index]++;
795 note = find_reg_note (bb->end, REG_BR_PROB, 0);
796 /* There may be already note put by some other pass, such
797 as builtin_expect expander. */
798 if (note)
799 XEXP (note, 0) = GEN_INT (prob);
800 else
801 REG_NOTES (bb->end)
802 = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
803 REG_NOTES (bb->end));
804 num_branches++;
807 /* Otherwise distribute the probabilities evenly so we get sane
808 sum. Use simple heuristics that if there are normal edges,
809 give all abnormals frequency of 0, otherwise distribute the
810 frequency over abnormals (this is the case of noreturn
811 calls). */
812 else
814 for (e = bb->succ; e; e = e->succ_next)
815 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
816 total ++;
817 if (total)
819 for (e = bb->succ; e; e = e->succ_next)
820 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
821 e->probability = REG_BR_PROB_BASE / total;
822 else
823 e->probability = 0;
825 else
827 for (e = bb->succ; e; e = e->succ_next)
828 total ++;
829 for (e = bb->succ; e; e = e->succ_next)
830 e->probability = REG_BR_PROB_BASE / total;
832 if (bb->index >= 0
833 && any_condjump_p (bb->end)
834 && bb->succ->succ_next)
835 num_branches++, num_never_executed;
839 if (rtl_dump_file)
841 fprintf (rtl_dump_file, "%d branches\n", num_branches);
842 fprintf (rtl_dump_file, "%d branches never executed\n",
843 num_never_executed);
844 if (num_branches)
845 for (i = 0; i < 10; i++)
846 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
847 (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
848 5 * i, 5 * i + 5);
850 total_num_branches += num_branches;
851 total_num_never_executed += num_never_executed;
852 for (i = 0; i < 20; i++)
853 total_hist_br_prob[i] += hist_br_prob[i];
855 fputc ('\n', rtl_dump_file);
856 fputc ('\n', rtl_dump_file);
859 free_aux_for_blocks ();
860 if (exec_counts)
861 free (exec_counts);
862 find_counters_section (GCOV_TAG_ARC_COUNTS)->present = 1;
865 /* Compute checksum for the current function. We generate a CRC32. */
867 static unsigned
868 compute_checksum ()
870 unsigned chksum = 0;
871 basic_block bb;
873 FOR_EACH_BB (bb)
875 edge e = NULL;
879 unsigned value = BB_TO_GCOV_INDEX (e ? e->dest : bb);
880 unsigned ix;
882 /* No need to use all bits in value identically, nearly all
883 functions have less than 256 blocks. */
884 value ^= value << 16;
885 value ^= value << 8;
887 for (ix = 8; ix--; value <<= 1)
889 unsigned feedback;
891 feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
892 chksum <<= 1;
893 chksum ^= feedback;
896 e = e ? e->succ_next : bb->succ;
898 while (e);
901 return chksum;
904 /* Instrument and/or analyze program behavior based on program flow graph.
905 In either case, this function builds a flow graph for the function being
906 compiled. The flow graph is stored in BB_GRAPH.
908 When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
909 the flow graph that are needed to reconstruct the dynamic behavior of the
910 flow graph.
912 When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
913 information from a data file containing edge count information from previous
914 executions of the function being compiled. In this case, the flow graph is
915 annotated with actual execution counts, which are later propagated into the
916 rtl for optimization purposes.
918 Main entry point of this file. */
920 void
921 branch_prob ()
923 basic_block bb;
924 unsigned i;
925 unsigned num_edges, ignored_edges;
926 struct edge_list *el;
927 const char *name = IDENTIFIER_POINTER
928 (DECL_ASSEMBLER_NAME (current_function_decl));
930 profile_info.current_function_cfg_checksum = compute_checksum ();
931 for (i = 0; i < profile_info.n_sections; i++)
933 profile_info.section_info[i].n_counters_now = 0;
934 profile_info.section_info[i].present = 0;
937 if (rtl_dump_file)
938 fprintf (rtl_dump_file, "CFG checksum is %u\n",
939 profile_info.current_function_cfg_checksum);
941 total_num_times_called++;
943 flow_call_edges_add (NULL);
944 add_noreturn_fake_exit_edges ();
946 /* We can't handle cyclic regions constructed using abnormal edges.
947 To avoid these we replace every source of abnormal edge by a fake
948 edge from entry node and every destination by fake edge to exit.
949 This keeps graph acyclic and our calculation exact for all normal
950 edges except for exit and entrance ones.
952 We also add fake exit edges for each call and asm statement in the
953 basic, since it may not return. */
955 FOR_EACH_BB (bb)
957 int need_exit_edge = 0, need_entry_edge = 0;
958 int have_exit_edge = 0, have_entry_edge = 0;
959 rtx insn;
960 edge e;
962 /* Add fake edges from entry block to the call insns that may return
963 twice. The CFG is not quite correct then, as call insn plays more
964 role of CODE_LABEL, but for our purposes, everything should be OK,
965 as we never insert code to the beginning of basic block. */
966 for (insn = bb->head; insn != NEXT_INSN (bb->end);
967 insn = NEXT_INSN (insn))
969 if (GET_CODE (insn) == CALL_INSN
970 && find_reg_note (insn, REG_SETJMP, NULL))
972 if (GET_CODE (bb->head) == CODE_LABEL
973 || insn != NEXT_INSN (bb->head))
975 e = split_block (bb, PREV_INSN (insn));
976 make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
977 break;
979 else
981 /* We should not get abort here, as call to setjmp should not
982 be the very first instruction of function. */
983 if (bb == ENTRY_BLOCK_PTR)
984 abort ();
985 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
990 for (e = bb->succ; e; e = e->succ_next)
992 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
993 && e->dest != EXIT_BLOCK_PTR)
994 need_exit_edge = 1;
995 if (e->dest == EXIT_BLOCK_PTR)
996 have_exit_edge = 1;
998 for (e = bb->pred; e; e = e->pred_next)
1000 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
1001 && e->src != ENTRY_BLOCK_PTR)
1002 need_entry_edge = 1;
1003 if (e->src == ENTRY_BLOCK_PTR)
1004 have_entry_edge = 1;
1007 if (need_exit_edge && !have_exit_edge)
1009 if (rtl_dump_file)
1010 fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
1011 bb->index);
1012 make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
1014 if (need_entry_edge && !have_entry_edge)
1016 if (rtl_dump_file)
1017 fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
1018 bb->index);
1019 make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
1023 el = create_edge_list ();
1024 num_edges = NUM_EDGES (el);
1025 alloc_aux_for_edges (sizeof (struct edge_info));
1027 /* The basic blocks are expected to be numbered sequentially. */
1028 compact_blocks ();
1030 ignored_edges = 0;
1031 for (i = 0 ; i < num_edges ; i++)
1033 edge e = INDEX_EDGE (el, i);
1034 e->count = 0;
1036 /* Mark edges we've replaced by fake edges above as ignored. */
1037 if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
1038 && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
1040 EDGE_INFO (e)->ignore = 1;
1041 ignored_edges++;
1045 #ifdef ENABLE_CHECKING
1046 verify_flow_info ();
1047 #endif
1049 /* Create spanning tree from basic block graph, mark each edge that is
1050 on the spanning tree. We insert as many abnormal and critical edges
1051 as possible to minimize number of edge splits necessary. */
1053 find_spanning_tree (el);
1055 /* Fake edges that are not on the tree will not be instrumented, so
1056 mark them ignored. */
1057 for (i = 0; i < num_edges; i++)
1059 edge e = INDEX_EDGE (el, i);
1060 struct edge_info *inf = EDGE_INFO (e);
1061 if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
1063 inf->ignore = 1;
1064 ignored_edges++;
1068 total_num_blocks += n_basic_blocks + 2;
1069 if (rtl_dump_file)
1070 fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
1072 total_num_edges += num_edges;
1073 if (rtl_dump_file)
1074 fprintf (rtl_dump_file, "%d edges\n", num_edges);
1076 total_num_edges_ignored += ignored_edges;
1077 if (rtl_dump_file)
1078 fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
1080 /* Create a .bbg file from which gcov can reconstruct the basic block
1081 graph. First output the number of basic blocks, and then for every
1082 edge output the source and target basic block numbers.
1083 NOTE: The format of this file must be compatible with gcov. */
1085 if (flag_test_coverage && bbg_file)
1087 long offset;
1089 /* Announce function */
1090 if (gcov_write_unsigned (bbg_file, GCOV_TAG_FUNCTION)
1091 || !(offset = gcov_reserve_length (bbg_file))
1092 || gcov_write_string (bbg_file, name,
1093 strlen (name))
1094 || gcov_write_unsigned (bbg_file,
1095 profile_info.current_function_cfg_checksum)
1096 || gcov_write_length (bbg_file, offset))
1097 goto bbg_error;
1099 /* Basic block flags */
1100 if (gcov_write_unsigned (bbg_file, GCOV_TAG_BLOCKS)
1101 || !(offset = gcov_reserve_length (bbg_file)))
1102 goto bbg_error;
1103 for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++)
1104 if (gcov_write_unsigned (bbg_file, 0))
1105 goto bbg_error;
1106 if (gcov_write_length (bbg_file, offset))
1107 goto bbg_error;
1109 /* Arcs */
1110 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
1112 edge e;
1114 if (gcov_write_unsigned (bbg_file, GCOV_TAG_ARCS)
1115 || !(offset = gcov_reserve_length (bbg_file))
1116 || gcov_write_unsigned (bbg_file, BB_TO_GCOV_INDEX (bb)))
1117 goto bbg_error;
1119 for (e = bb->succ; e; e = e->succ_next)
1121 struct edge_info *i = EDGE_INFO (e);
1122 if (!i->ignore)
1124 unsigned flag_bits = 0;
1126 if (i->on_tree)
1127 flag_bits |= GCOV_ARC_ON_TREE;
1128 if (e->flags & EDGE_FAKE)
1129 flag_bits |= GCOV_ARC_FAKE;
1130 if (e->flags & EDGE_FALLTHRU)
1131 flag_bits |= GCOV_ARC_FALLTHROUGH;
1133 if (gcov_write_unsigned (bbg_file,
1134 BB_TO_GCOV_INDEX (e->dest))
1135 || gcov_write_unsigned (bbg_file, flag_bits))
1136 goto bbg_error;
1140 if (gcov_write_length (bbg_file, offset))
1141 goto bbg_error;
1144 /* Output line number information about each basic block for
1145 GCOV utility. */
1147 char const *prev_file_name = NULL;
1149 FOR_EACH_BB (bb)
1151 rtx insn = bb->head;
1152 int ignore_next_note = 0;
1154 offset = 0;
1156 /* We are looking for line number notes. Search backward
1157 before basic block to find correct ones. */
1158 insn = prev_nonnote_insn (insn);
1159 if (!insn)
1160 insn = get_insns ();
1161 else
1162 insn = NEXT_INSN (insn);
1164 while (insn != bb->end)
1166 if (GET_CODE (insn) == NOTE)
1168 /* Must ignore the line number notes that immediately
1169 follow the end of an inline function to avoid counting
1170 it twice. There is a note before the call, and one
1171 after the call. */
1172 if (NOTE_LINE_NUMBER (insn)
1173 == NOTE_INSN_REPEATED_LINE_NUMBER)
1174 ignore_next_note = 1;
1175 else if (NOTE_LINE_NUMBER (insn) <= 0)
1176 /*NOP*/;
1177 else if (ignore_next_note)
1178 ignore_next_note = 0;
1179 else
1181 if (offset)
1182 /*NOP*/;
1183 else if (gcov_write_unsigned (bbg_file, GCOV_TAG_LINES)
1184 || !(offset = gcov_reserve_length (bbg_file))
1185 || gcov_write_unsigned (bbg_file,
1186 BB_TO_GCOV_INDEX (bb)))
1187 goto bbg_error;
1188 /* If this is a new source file, then output
1189 the file's name to the .bb file. */
1190 if (!prev_file_name
1191 || strcmp (NOTE_SOURCE_FILE (insn),
1192 prev_file_name))
1194 prev_file_name = NOTE_SOURCE_FILE (insn);
1195 if (gcov_write_unsigned (bbg_file, 0)
1196 || gcov_write_string (bbg_file, prev_file_name,
1197 strlen (prev_file_name)))
1198 goto bbg_error;
1200 if (gcov_write_unsigned (bbg_file, NOTE_LINE_NUMBER (insn)))
1201 goto bbg_error;
1204 insn = NEXT_INSN (insn);
1207 if (offset)
1209 if (gcov_write_unsigned (bbg_file, 0)
1210 || gcov_write_string (bbg_file, NULL, 0)
1211 || gcov_write_length (bbg_file, offset))
1213 bbg_error:;
1214 warning ("error writing `%s'", bbg_file_name);
1215 fclose (bbg_file);
1216 bbg_file = NULL;
1223 if (flag_branch_probabilities)
1224 compute_branch_probabilities ();
1226 /* For each edge not on the spanning tree, add counting code as rtl. */
1228 if (cfun->arc_profile && profile_arc_flag)
1230 struct function_list *item;
1232 instrument_edges (el);
1234 /* Commit changes done by instrumentation. */
1235 commit_edge_insertions_watch_calls ();
1236 allocate_reg_info (max_reg_num (), FALSE, FALSE);
1238 /* ??? Probably should re-use the existing struct function. */
1239 item = xmalloc (sizeof (struct function_list));
1241 *functions_tail = item;
1242 functions_tail = &item->next;
1244 item->next = 0;
1245 item->name = xstrdup (name);
1246 item->cfg_checksum = profile_info.current_function_cfg_checksum;
1247 item->n_counter_sections = 0;
1248 for (i = 0; i < profile_info.n_sections; i++)
1249 if (profile_info.section_info[i].n_counters_now)
1251 item->counter_sections[item->n_counter_sections].tag =
1252 profile_info.section_info[i].tag;
1253 item->counter_sections[item->n_counter_sections].n_counters =
1254 profile_info.section_info[i].n_counters_now;
1255 item->n_counter_sections++;
1259 remove_fake_edges ();
1260 free_aux_for_edges ();
1261 /* Re-merge split basic blocks and the mess introduced by
1262 insert_insn_on_edge. */
1263 cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
1264 if (rtl_dump_file)
1265 dump_flow_info (rtl_dump_file);
1267 free_edge_list (el);
1270 /* Union find algorithm implementation for the basic blocks using
1271 aux fields. */
1273 static basic_block
1274 find_group (bb)
1275 basic_block bb;
1277 basic_block group = bb, bb1;
1279 while ((basic_block) group->aux != group)
1280 group = (basic_block) group->aux;
1282 /* Compress path. */
1283 while ((basic_block) bb->aux != group)
1285 bb1 = (basic_block) bb->aux;
1286 bb->aux = (void *) group;
1287 bb = bb1;
1289 return group;
1292 static void
1293 union_groups (bb1, bb2)
1294 basic_block bb1, bb2;
1296 basic_block bb1g = find_group (bb1);
1297 basic_block bb2g = find_group (bb2);
1299 /* ??? I don't have a place for the rank field. OK. Lets go w/o it,
1300 this code is unlikely going to be performance problem anyway. */
1301 if (bb1g == bb2g)
1302 abort ();
1304 bb1g->aux = bb2g;
1307 /* This function searches all of the edges in the program flow graph, and puts
1308 as many bad edges as possible onto the spanning tree. Bad edges include
1309 abnormals edges, which can't be instrumented at the moment. Since it is
1310 possible for fake edges to form a cycle, we will have to develop some
1311 better way in the future. Also put critical edges to the tree, since they
1312 are more expensive to instrument. */
1314 static void
1315 find_spanning_tree (el)
1316 struct edge_list *el;
1318 int i;
1319 int num_edges = NUM_EDGES (el);
1320 basic_block bb;
1322 /* We use aux field for standard union-find algorithm. */
1323 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1324 bb->aux = bb;
1326 /* Add fake edge exit to entry we can't instrument. */
1327 union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
1329 /* First add all abnormal edges to the tree unless they form a cycle. Also
1330 add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1331 setting return value from function. */
1332 for (i = 0; i < num_edges; i++)
1334 edge e = INDEX_EDGE (el, i);
1335 if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1336 || e->dest == EXIT_BLOCK_PTR
1338 && !EDGE_INFO (e)->ignore
1339 && (find_group (e->src) != find_group (e->dest)))
1341 if (rtl_dump_file)
1342 fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
1343 e->src->index, e->dest->index);
1344 EDGE_INFO (e)->on_tree = 1;
1345 union_groups (e->src, e->dest);
1349 /* Now insert all critical edges to the tree unless they form a cycle. */
1350 for (i = 0; i < num_edges; i++)
1352 edge e = INDEX_EDGE (el, i);
1353 if ((EDGE_CRITICAL_P (e))
1354 && !EDGE_INFO (e)->ignore
1355 && (find_group (e->src) != find_group (e->dest)))
1357 if (rtl_dump_file)
1358 fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1359 e->src->index, e->dest->index);
1360 EDGE_INFO (e)->on_tree = 1;
1361 union_groups (e->src, e->dest);
1365 /* And now the rest. */
1366 for (i = 0; i < num_edges; i++)
1368 edge e = INDEX_EDGE (el, i);
1369 if (find_group (e->src) != find_group (e->dest)
1370 && !EDGE_INFO (e)->ignore)
1372 if (rtl_dump_file)
1373 fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1374 e->src->index, e->dest->index);
1375 EDGE_INFO (e)->on_tree = 1;
1376 union_groups (e->src, e->dest);
1380 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1381 bb->aux = NULL;
1384 /* Perform file-level initialization for branch-prob processing. */
1386 void
1387 init_branch_prob (filename)
1388 const char *filename;
1390 int len = strlen (filename);
1391 int i;
1393 if (flag_test_coverage)
1395 /* Open the bbg output file. */
1396 bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1);
1397 strcpy (bbg_file_name, filename);
1398 strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
1399 bbg_file = fopen (bbg_file_name, "wb");
1400 if (!bbg_file)
1401 fatal_io_error ("cannot open %s", bbg_file_name);
1403 if (gcov_write_unsigned (bbg_file, GCOV_GRAPH_MAGIC)
1404 || gcov_write_unsigned (bbg_file, GCOV_VERSION))
1406 fclose (bbg_file);
1407 fatal_io_error ("cannot write `%s'", bbg_file_name);
1411 da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
1412 strcpy (da_file_name, filename);
1413 strcat (da_file_name, GCOV_DATA_SUFFIX);
1415 if (flag_branch_probabilities)
1417 da_file = fopen (da_file_name, "rb");
1418 if (!da_file)
1419 warning ("file %s not found, execution counts assumed to be zero",
1420 da_file_name);
1421 if (counts_file_index && strcmp (da_file_name, counts_file_name))
1422 cleanup_counts_index (0);
1423 if (index_counts_file ())
1424 counts_file_name = xstrdup (da_file_name);
1427 if (profile_arc_flag)
1429 /* Generate and save a copy of this so it can be shared. */
1430 char buf[20];
1432 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1433 profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1436 total_num_blocks = 0;
1437 total_num_edges = 0;
1438 total_num_edges_ignored = 0;
1439 total_num_edges_instrumented = 0;
1440 total_num_blocks_created = 0;
1441 total_num_passes = 0;
1442 total_num_times_called = 0;
1443 total_num_branches = 0;
1444 total_num_never_executed = 0;
1445 for (i = 0; i < 20; i++)
1446 total_hist_br_prob[i] = 0;
1449 /* Performs file-level cleanup after branch-prob processing
1450 is completed. */
1452 void
1453 end_branch_prob ()
1455 if (flag_test_coverage)
1457 if (bbg_file)
1459 #if !SELF_COVERAGE
1460 /* If the compiler is instrumented, we should not remove the
1461 counts file, because we might be recompiling
1462 ourselves. The .da files are all removed during copying
1463 the stage1 files. */
1464 unlink (da_file_name);
1465 #endif
1466 fclose (bbg_file);
1468 else
1470 unlink (bbg_file_name);
1471 unlink (da_file_name);
1475 if (da_file)
1476 fclose (da_file);
1478 if (rtl_dump_file)
1480 fprintf (rtl_dump_file, "\n");
1481 fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1482 total_num_blocks);
1483 fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1484 fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1485 total_num_edges_ignored);
1486 fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1487 total_num_edges_instrumented);
1488 fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1489 total_num_blocks_created);
1490 fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1491 total_num_passes);
1492 if (total_num_times_called != 0)
1493 fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1494 (total_num_passes + (total_num_times_called >> 1))
1495 / total_num_times_called);
1496 fprintf (rtl_dump_file, "Total number of branches: %d\n",
1497 total_num_branches);
1498 fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1499 total_num_never_executed);
1500 if (total_num_branches)
1502 int i;
1504 for (i = 0; i < 10; i++)
1505 fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1506 (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1507 / total_num_branches, 5*i, 5*i+5);
1512 /* Find (and create if not present) a section with TAG. */
1513 struct section_info *
1514 find_counters_section (tag)
1515 unsigned tag;
1517 unsigned i;
1519 for (i = 0; i < profile_info.n_sections; i++)
1520 if (profile_info.section_info[i].tag == tag)
1521 return profile_info.section_info + i;
1523 if (i == MAX_COUNTER_SECTIONS)
1524 abort ();
1526 profile_info.section_info[i].tag = tag;
1527 profile_info.section_info[i].present = 0;
1528 profile_info.section_info[i].n_counters = 0;
1529 profile_info.section_info[i].n_counters_now = 0;
1530 profile_info.n_sections++;
1532 return profile_info.section_info + i;
1535 /* Set FIELDS as purpose to VALUE. */
1536 static void
1537 set_purpose (value, fields)
1538 tree value;
1539 tree fields;
1541 tree act_field, act_value;
1543 for (act_field = fields, act_value = value;
1544 act_field;
1545 act_field = TREE_CHAIN (act_field), act_value = TREE_CHAIN (act_value))
1546 TREE_PURPOSE (act_value) = act_field;
1549 /* Returns label for base of counters inside TAG section. */
1550 static rtx
1551 label_for_tag (tag)
1552 unsigned tag;
1554 switch (tag)
1556 case GCOV_TAG_ARC_COUNTS:
1557 return profiler_label;
1558 default:
1559 abort ();
1563 /* Creates fields of struct counter_section (in gcov-io.h). */
1564 static tree
1565 build_counter_section_fields ()
1567 tree field, fields;
1569 /* tag */
1570 fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1572 /* n_counters */
1573 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1574 TREE_CHAIN (field) = fields;
1575 fields = field;
1577 return fields;
1580 /* Creates value of struct counter_section (in gcov-io.h). */
1581 static tree
1582 build_counter_section_value (tag, n_counters)
1583 unsigned tag;
1584 unsigned n_counters;
1586 tree value = NULL_TREE;
1588 /* tag */
1589 value = tree_cons (NULL_TREE,
1590 convert (unsigned_type_node,
1591 build_int_2 (tag, 0)),
1592 value);
1594 /* n_counters */
1595 value = tree_cons (NULL_TREE,
1596 convert (unsigned_type_node,
1597 build_int_2 (n_counters, 0)),
1598 value);
1600 return value;
1603 /* Creates fields of struct counter_section_data (in gcov-io.h). */
1604 static tree
1605 build_counter_section_data_fields ()
1607 tree field, fields, gcov_type, gcov_ptr_type;
1609 gcov_type = make_signed_type (GCOV_TYPE_SIZE);
1610 gcov_ptr_type =
1611 build_pointer_type (build_qualified_type (gcov_type,
1612 TYPE_QUAL_CONST));
1614 /* tag */
1615 fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1617 /* n_counters */
1618 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1619 TREE_CHAIN (field) = fields;
1620 fields = field;
1622 /* counters */
1623 field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
1624 TREE_CHAIN (field) = fields;
1625 fields = field;
1627 return fields;
1630 /* Creates value of struct counter_section_data (in gcov-io.h). */
1631 static tree
1632 build_counter_section_data_value (tag, n_counters)
1633 unsigned tag;
1634 unsigned n_counters;
1636 tree value = NULL_TREE, counts_table, gcov_type, gcov_ptr_type;
1638 gcov_type = make_signed_type (GCOV_TYPE_SIZE);
1639 gcov_ptr_type
1640 = build_pointer_type (build_qualified_type
1641 (gcov_type, TYPE_QUAL_CONST));
1643 /* tag */
1644 value = tree_cons (NULL_TREE,
1645 convert (unsigned_type_node,
1646 build_int_2 (tag, 0)),
1647 value);
1649 /* n_counters */
1650 value = tree_cons (NULL_TREE,
1651 convert (unsigned_type_node,
1652 build_int_2 (n_counters, 0)),
1653 value);
1655 /* counters */
1656 if (n_counters)
1658 tree gcov_type_array_type =
1659 build_array_type (gcov_type,
1660 build_index_type (build_int_2 (n_counters - 1,
1661 0)));
1662 counts_table =
1663 build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
1664 TREE_STATIC (counts_table) = 1;
1665 DECL_NAME (counts_table) = get_identifier (XSTR (label_for_tag (tag), 0));
1666 assemble_variable (counts_table, 0, 0, 0);
1667 counts_table = build1 (ADDR_EXPR, gcov_ptr_type, counts_table);
1669 else
1670 counts_table = null_pointer_node;
1672 value = tree_cons (NULL_TREE, counts_table, value);
1674 return value;
1677 /* Creates fields for struct function_info type (in gcov-io.h). */
1678 static tree
1679 build_function_info_fields ()
1681 tree field, fields, counter_section_fields, counter_section_type;
1682 tree counter_sections_ptr_type;
1683 tree string_type =
1684 build_pointer_type (build_qualified_type (char_type_node,
1685 TYPE_QUAL_CONST));
1686 /* name */
1687 fields = build_decl (FIELD_DECL, NULL_TREE, string_type);
1689 /* checksum */
1690 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1691 TREE_CHAIN (field) = fields;
1692 fields = field;
1694 /* n_counter_sections */
1695 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1696 TREE_CHAIN (field) = fields;
1697 fields = field;
1699 /* counter_sections */
1700 counter_section_fields = build_counter_section_fields ();
1701 counter_section_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1702 finish_builtin_struct (counter_section_type, "__counter_section",
1703 counter_section_fields, NULL_TREE);
1704 counter_sections_ptr_type =
1705 build_pointer_type
1706 (build_qualified_type (counter_section_type,
1707 TYPE_QUAL_CONST));
1708 field = build_decl (FIELD_DECL, NULL_TREE, counter_sections_ptr_type);
1709 TREE_CHAIN (field) = fields;
1710 fields = field;
1712 return fields;
1715 /* Creates value for struct function_info (in gcov-io.h). */
1716 static tree
1717 build_function_info_value (function)
1718 struct function_list *function;
1720 tree value = NULL_TREE;
1721 size_t name_len = strlen (function->name);
1722 tree fname = build_string (name_len + 1, function->name);
1723 tree string_type =
1724 build_pointer_type (build_qualified_type (char_type_node,
1725 TYPE_QUAL_CONST));
1726 tree counter_section_fields, counter_section_type, counter_sections_value;
1727 tree counter_sections_ptr_type, counter_sections_array_type;
1728 unsigned i;
1730 /* name */
1731 TREE_TYPE (fname) =
1732 build_array_type (char_type_node,
1733 build_index_type (build_int_2 (name_len, 0)));
1734 value = tree_cons (NULL_TREE,
1735 build1 (ADDR_EXPR,
1736 string_type,
1737 fname),
1738 value);
1740 /* checksum */
1741 value = tree_cons (NULL_TREE,
1742 convert (unsigned_type_node,
1743 build_int_2 (function->cfg_checksum, 0)),
1744 value);
1746 /* n_counter_sections */
1748 value = tree_cons (NULL_TREE,
1749 convert (unsigned_type_node,
1750 build_int_2 (function->n_counter_sections, 0)),
1751 value);
1753 /* counter_sections */
1754 counter_section_fields = build_counter_section_fields ();
1755 counter_section_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1756 counter_sections_ptr_type =
1757 build_pointer_type
1758 (build_qualified_type (counter_section_type,
1759 TYPE_QUAL_CONST));
1760 counter_sections_array_type =
1761 build_array_type (counter_section_type,
1762 build_index_type (
1763 build_int_2 (function->n_counter_sections - 1,
1764 0)));
1766 counter_sections_value = NULL_TREE;
1767 for (i = 0; i < function->n_counter_sections; i++)
1769 tree counter_section_value =
1770 build_counter_section_value (function->counter_sections[i].tag,
1771 function->counter_sections[i].n_counters);
1772 set_purpose (counter_section_value, counter_section_fields);
1773 counter_sections_value = tree_cons (NULL_TREE,
1774 build (CONSTRUCTOR,
1775 counter_section_type,
1776 NULL_TREE,
1777 nreverse (counter_section_value)),
1778 counter_sections_value);
1780 finish_builtin_struct (counter_section_type, "__counter_section",
1781 counter_section_fields, NULL_TREE);
1783 if (function->n_counter_sections)
1785 counter_sections_value =
1786 build (CONSTRUCTOR,
1787 counter_sections_array_type,
1788 NULL_TREE,
1789 nreverse (counter_sections_value)),
1790 counter_sections_value = build1 (ADDR_EXPR,
1791 counter_sections_ptr_type,
1792 counter_sections_value);
1794 else
1795 counter_sections_value = null_pointer_node;
1797 value = tree_cons (NULL_TREE, counter_sections_value, value);
1799 return value;
1802 /* Creates fields of struct gcov_info type (in gcov-io.h). */
1803 static tree
1804 build_gcov_info_fields (gcov_info_type)
1805 tree gcov_info_type;
1807 tree field, fields;
1808 char *filename;
1809 int filename_len;
1810 tree string_type =
1811 build_pointer_type (build_qualified_type (char_type_node,
1812 TYPE_QUAL_CONST));
1813 tree function_info_fields, function_info_type, function_info_ptr_type;
1814 tree counter_section_data_fields, counter_section_data_type;
1815 tree counter_section_data_ptr_type;
1817 /* Version ident */
1818 fields = build_decl (FIELD_DECL, NULL_TREE, long_unsigned_type_node);
1820 /* next -- NULL */
1821 field = build_decl (FIELD_DECL, NULL_TREE,
1822 build_pointer_type (build_qualified_type (gcov_info_type,
1823 TYPE_QUAL_CONST)));
1824 TREE_CHAIN (field) = fields;
1825 fields = field;
1827 /* Filename */
1828 filename = getpwd ();
1829 filename = (filename && da_file_name[0] != '/'
1830 ? concat (filename, "/", da_file_name, NULL)
1831 : da_file_name);
1832 filename_len = strlen (filename);
1833 if (filename != da_file_name)
1834 free (filename);
1836 field = build_decl (FIELD_DECL, NULL_TREE, string_type);
1837 TREE_CHAIN (field) = fields;
1838 fields = field;
1840 /* Workspace */
1841 field = build_decl (FIELD_DECL, NULL_TREE, long_integer_type_node);
1842 TREE_CHAIN (field) = fields;
1843 fields = field;
1845 /* number of functions */
1846 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1847 TREE_CHAIN (field) = fields;
1848 fields = field;
1850 /* function_info table */
1851 function_info_fields = build_function_info_fields ();
1852 function_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1853 finish_builtin_struct (function_info_type, "__function_info",
1854 function_info_fields, NULL_TREE);
1855 function_info_ptr_type =
1856 build_pointer_type
1857 (build_qualified_type (function_info_type,
1858 TYPE_QUAL_CONST));
1859 field = build_decl (FIELD_DECL, NULL_TREE, function_info_ptr_type);
1860 TREE_CHAIN (field) = fields;
1861 fields = field;
1863 /* n_counter_sections */
1864 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1865 TREE_CHAIN (field) = fields;
1866 fields = field;
1868 /* counter sections */
1869 counter_section_data_fields = build_counter_section_data_fields ();
1870 counter_section_data_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1871 finish_builtin_struct (counter_section_data_type, "__counter_section_data",
1872 counter_section_data_fields, NULL_TREE);
1873 counter_section_data_ptr_type =
1874 build_pointer_type
1875 (build_qualified_type (counter_section_data_type,
1876 TYPE_QUAL_CONST));
1877 field = build_decl (FIELD_DECL, NULL_TREE, counter_section_data_ptr_type);
1878 TREE_CHAIN (field) = fields;
1879 fields = field;
1881 return fields;
1884 /* Creates struct gcov_info value (in gcov-io.h). */
1885 static tree
1886 build_gcov_info_value ()
1888 tree value = NULL_TREE;
1889 tree filename_string;
1890 char *filename;
1891 int filename_len;
1892 unsigned n_functions, i;
1893 struct function_list *item;
1894 tree string_type =
1895 build_pointer_type (build_qualified_type (char_type_node,
1896 TYPE_QUAL_CONST));
1897 tree function_info_fields, function_info_type, function_info_ptr_type;
1898 tree functions;
1899 tree counter_section_data_fields, counter_section_data_type;
1900 tree counter_section_data_ptr_type, counter_sections;
1902 /* Version ident */
1903 value = tree_cons (NULL_TREE,
1904 convert (long_unsigned_type_node,
1905 build_int_2 (GCOV_VERSION, 0)),
1906 value);
1908 /* next -- NULL */
1909 value = tree_cons (NULL_TREE, null_pointer_node, value);
1911 /* Filename */
1912 filename = getpwd ();
1913 filename = (filename && da_file_name[0] != '/'
1914 ? concat (filename, "/", da_file_name, NULL)
1915 : da_file_name);
1916 filename_len = strlen (filename);
1917 filename_string = build_string (filename_len + 1, filename);
1918 if (filename != da_file_name)
1919 free (filename);
1920 TREE_TYPE (filename_string) =
1921 build_array_type (char_type_node,
1922 build_index_type (build_int_2 (filename_len, 0)));
1923 value = tree_cons (NULL_TREE,
1924 build1 (ADDR_EXPR,
1925 string_type,
1926 filename_string),
1927 value);
1929 /* Workspace */
1930 value = tree_cons (NULL_TREE,
1931 convert (long_integer_type_node, integer_zero_node),
1932 value);
1934 /* number of functions */
1935 n_functions = 0;
1936 for (item = functions_head; item != 0; item = item->next, n_functions++)
1937 continue;
1938 value = tree_cons (NULL_TREE,
1939 convert (unsigned_type_node,
1940 build_int_2 (n_functions, 0)),
1941 value);
1943 /* function_info table */
1944 function_info_fields = build_function_info_fields ();
1945 function_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1946 function_info_ptr_type =
1947 build_pointer_type (
1948 build_qualified_type (function_info_type,
1949 TYPE_QUAL_CONST));
1950 functions = NULL_TREE;
1951 for (item = functions_head; item != 0; item = item->next)
1953 tree function_info_value = build_function_info_value (item);
1954 set_purpose (function_info_value, function_info_fields);
1955 functions = tree_cons (NULL_TREE,
1956 build (CONSTRUCTOR,
1957 function_info_type,
1958 NULL_TREE,
1959 nreverse (function_info_value)),
1960 functions);
1962 finish_builtin_struct (function_info_type, "__function_info",
1963 function_info_fields, NULL_TREE);
1965 /* Create constructor for array. */
1966 if (n_functions)
1968 tree array_type;
1970 array_type = build_array_type (
1971 function_info_type,
1972 build_index_type (build_int_2 (n_functions - 1, 0)));
1973 functions = build (CONSTRUCTOR,
1974 array_type,
1975 NULL_TREE,
1976 nreverse (functions));
1977 functions = build1 (ADDR_EXPR,
1978 function_info_ptr_type,
1979 functions);
1981 else
1982 functions = null_pointer_node;
1984 value = tree_cons (NULL_TREE, functions, value);
1986 /* n_counter_sections */
1987 value = tree_cons (NULL_TREE,
1988 convert (unsigned_type_node,
1989 build_int_2 (profile_info.n_sections, 0)),
1990 value);
1992 /* counter sections */
1993 counter_section_data_fields = build_counter_section_data_fields ();
1994 counter_section_data_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1995 counter_sections = NULL_TREE;
1996 for (i = 0; i < profile_info.n_sections; i++)
1998 tree counter_sections_value =
1999 build_counter_section_data_value (
2000 profile_info.section_info[i].tag,
2001 profile_info.section_info[i].n_counters);
2002 set_purpose (counter_sections_value, counter_section_data_fields);
2003 counter_sections = tree_cons (NULL_TREE,
2004 build (CONSTRUCTOR,
2005 counter_section_data_type,
2006 NULL_TREE,
2007 nreverse (counter_sections_value)),
2008 counter_sections);
2010 finish_builtin_struct (counter_section_data_type, "__counter_section_data",
2011 counter_section_data_fields, NULL_TREE);
2012 counter_section_data_ptr_type =
2013 build_pointer_type
2014 (build_qualified_type (counter_section_data_type,
2015 TYPE_QUAL_CONST));
2017 if (profile_info.n_sections)
2019 counter_sections =
2020 build (CONSTRUCTOR,
2021 build_array_type (
2022 counter_section_data_type,
2023 build_index_type (build_int_2 (profile_info.n_sections - 1, 0))),
2024 NULL_TREE,
2025 nreverse (counter_sections));
2026 counter_sections = build1 (ADDR_EXPR,
2027 counter_section_data_ptr_type,
2028 counter_sections);
2030 else
2031 counter_sections = null_pointer_node;
2032 value = tree_cons (NULL_TREE, counter_sections, value);
2034 return value;
2037 /* Write out the structure which libgcc uses to locate all the arc
2038 counters. The structures used here must match those defined in
2039 gcov-io.h. Write out the constructor to call __gcov_init. */
2041 void
2042 create_profiler ()
2044 tree gcov_info_fields, gcov_info_type, gcov_info_value, gcov_info;
2045 char name[20];
2046 char *ctor_name;
2047 tree ctor;
2048 rtx gcov_info_address;
2049 int save_flag_inline_functions = flag_inline_functions;
2050 unsigned i;
2052 for (i = 0; i < profile_info.n_sections; i++)
2053 if (profile_info.section_info[i].n_counters_now)
2054 break;
2055 if (i == profile_info.n_sections)
2056 return;
2058 gcov_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
2059 gcov_info_fields = build_gcov_info_fields (gcov_info_type);
2060 gcov_info_value = build_gcov_info_value ();
2061 set_purpose (gcov_info_value, gcov_info_fields);
2062 finish_builtin_struct (gcov_info_type, "__gcov_info",
2063 gcov_info_fields, NULL_TREE);
2065 gcov_info = build (VAR_DECL, gcov_info_type, NULL_TREE, NULL_TREE);
2066 DECL_INITIAL (gcov_info) =
2067 build (CONSTRUCTOR, gcov_info_type, NULL_TREE,
2068 nreverse (gcov_info_value));
2070 TREE_STATIC (gcov_info) = 1;
2071 ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
2072 DECL_NAME (gcov_info) = get_identifier (name);
2074 /* Build structure. */
2075 assemble_variable (gcov_info, 0, 0, 0);
2077 /* Build the constructor function to invoke __gcov_init. */
2078 ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
2079 "_GCOV", NULL);
2080 ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
2081 build_function_type (void_type_node, NULL_TREE));
2082 free (ctor_name);
2083 DECL_EXTERNAL (ctor) = 0;
2085 /* It can be a static function as long as collect2 does not have
2086 to scan the object file to find its ctor/dtor routine. */
2087 TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
2088 TREE_USED (ctor) = 1;
2089 DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
2091 ctor = (*lang_hooks.decls.pushdecl) (ctor);
2092 rest_of_decl_compilation (ctor, 0, 1, 0);
2093 announce_function (ctor);
2094 current_function_decl = ctor;
2095 DECL_INITIAL (ctor) = error_mark_node;
2096 make_decl_rtl (ctor, NULL);
2097 init_function_start (ctor, input_filename, lineno);
2098 (*lang_hooks.decls.pushlevel) (0);
2099 expand_function_start (ctor, 0);
2100 cfun->arc_profile = 0;
2102 /* Actually generate the code to call __gcov_init. */
2103 gcov_info_address = force_reg (Pmode,
2104 gen_rtx_SYMBOL_REF (
2105 Pmode,
2106 IDENTIFIER_POINTER (
2107 DECL_NAME (gcov_info))));
2108 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__gcov_init"),
2109 LCT_NORMAL, VOIDmode, 1,
2110 gcov_info_address, Pmode);
2112 expand_function_end (input_filename, lineno, 0);
2113 (*lang_hooks.decls.poplevel) (1, 0, 1);
2115 /* Since ctor isn't in the list of globals, it would never be emitted
2116 when it's considered to be 'safe' for inlining, so turn off
2117 flag_inline_functions. */
2118 flag_inline_functions = 0;
2120 rest_of_compilation (ctor);
2122 /* Reset flag_inline_functions to its original value. */
2123 flag_inline_functions = save_flag_inline_functions;
2125 if (! quiet_flag)
2126 fflush (asm_out_file);
2127 current_function_decl = NULL_TREE;
2129 if (targetm.have_ctors_dtors)
2130 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
2131 DEFAULT_INIT_PRIORITY);
2134 /* Output instructions as RTL to increment the edge execution count. */
2136 static rtx
2137 gen_edge_profiler (edgeno)
2138 int edgeno;
2140 enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
2141 rtx mem_ref, tmp;
2142 rtx sequence;
2144 start_sequence ();
2146 tmp = force_reg (Pmode, profiler_label);
2147 tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
2148 mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
2150 set_mem_alias_set (mem_ref, new_alias_set ());
2152 tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
2153 mem_ref, 0, OPTAB_WIDEN);
2155 if (tmp != mem_ref)
2156 emit_move_insn (copy_rtx (mem_ref), tmp);
2158 sequence = get_insns ();
2159 end_sequence ();
2160 return sequence;
2163 #include "gt-profile.h"