OSDN Git Service

* libfuncs.h (LTI_setbits, LTI_gcov_flush, LTI_gcov_init): New.
[pf3gnuchains/gcc-fork.git] / gcc / profile.c
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.
7
8 This file is part of GCC.
9
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.
14
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.
19
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.  */
24
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.
41
42    The auxiliary file generated is <dumpbase>.bbg. The format is
43    described in full in gcov-io.h.  */
44
45 /* ??? Register allocation should use basic block execution counts to
46    give preference to the most commonly executed blocks.  */
47
48 /* ??? Should calculate branch probabilities before instrumenting code, since
49    then we can use arc counts to help decide which arcs to instrument.  */
50
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"
73
74 /* Additional information about the edges we need.  */
75 struct edge_info {
76   unsigned int count_valid : 1;
77   
78   /* Is on the spanning tree.  */
79   unsigned int on_tree : 1;
80   
81   /* Pretend this edge does not exist (it is abnormal and we've
82      inserted a fake to compensate).  */
83   unsigned int ignore : 1;
84 };
85
86 struct bb_info {
87   unsigned int count_valid : 1;
88
89   /* Number of successor and predecessor edges.  */
90   gcov_type succ_count;
91   gcov_type pred_count;
92 };
93
94 struct function_list
95 {
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 */
102 };
103
104
105 /* Counts information for a function.  */
106 typedef struct counts_entry
107 {
108   /* We hash by  */
109   char *function_name;
110   unsigned section;
111   
112   /* Store  */
113   unsigned checksum;
114   unsigned n_counts;
115   gcov_type *counts;
116   unsigned merged;
117   gcov_type max_counter;
118   gcov_type max_counter_sum;
119
120   /* Workspace */
121   struct counts_entry *chain;
122   
123 } counts_entry_t;
124
125 static struct function_list *functions_head = 0;
126 static struct function_list **functions_tail = &functions_head;
127
128 #define EDGE_INFO(e)  ((struct edge_info *) (e)->aux)
129 #define BB_INFO(b)  ((struct bb_info *) (b)->aux)
130
131 /* Keep all basic block indexes nonnegative in the gcov output.  Index 0
132    is used for entry block, last block exit block.  */
133 #define BB_TO_GCOV_INDEX(bb)  ((bb) == ENTRY_BLOCK_PTR ? 0              \
134                                : ((bb) == EXIT_BLOCK_PTR                \
135                                   ? last_basic_block + 1 : (bb)->index + 1))
136
137 /* Instantiate the profile info structure.  */
138
139 struct profile_info profile_info;
140
141 /* Name and file pointer of the output file for the basic block graph.  */
142
143 static char *bbg_file_name;
144
145 /* Name and file pointer of the input file for the arc count data.  */
146
147 static char *da_file_name;
148
149 /* The name of the count table. Used by the edge profiling code.  */
150 static GTY(()) rtx profiler_label;
151
152 /* Collect statistics on the performance of this pass for the entire source
153    file.  */
154
155 static int total_num_blocks;
156 static int total_num_edges;
157 static int total_num_edges_ignored;
158 static int total_num_edges_instrumented;
159 static int total_num_blocks_created;
160 static int total_num_passes;
161 static int total_num_times_called;
162 static int total_hist_br_prob[20];
163 static int total_num_never_executed;
164 static int total_num_branches;
165
166 /* Forward declarations.  */
167 static void find_spanning_tree PARAMS ((struct edge_list *));
168 static rtx gen_edge_profiler PARAMS ((int));
169 static void instrument_edges PARAMS ((struct edge_list *));
170 static void compute_branch_probabilities PARAMS ((void));
171 static hashval_t htab_counts_entry_hash PARAMS ((const void *));
172 static int htab_counts_entry_eq PARAMS ((const void *, const void *));
173 static void htab_counts_entry_del PARAMS ((void *));
174 static void read_counts_file PARAMS ((const char *));
175 static gcov_type * get_exec_counts PARAMS ((void));
176 static unsigned compute_checksum PARAMS ((void));
177 static basic_block find_group PARAMS ((basic_block));
178 static void union_groups PARAMS ((basic_block, basic_block));
179 static void set_purpose PARAMS ((tree, tree));
180 static rtx label_for_tag PARAMS ((unsigned));
181 static tree build_counter_section_fields PARAMS ((void));
182 static tree build_counter_section_value PARAMS ((unsigned, unsigned));
183 static tree build_counter_section_data_fields PARAMS ((void));
184 static tree build_counter_section_data_value PARAMS ((unsigned, unsigned));
185 static tree build_function_info_fields PARAMS ((void));
186 static tree build_function_info_value PARAMS ((struct function_list *));
187 static tree build_gcov_info_fields PARAMS ((tree));
188 static tree build_gcov_info_value PARAMS ((void));
189
190 \f
191 /* Add edge instrumentation code to the entire insn chain.
192
193    F is the first insn of the chain.
194    NUM_BLOCKS is the number of basic blocks found in F.  */
195
196 static void
197 instrument_edges (el)
198      struct edge_list *el;
199 {
200   int num_instr_edges = 0;
201   int num_edges = NUM_EDGES (el);
202   basic_block bb;
203   struct section_info *section_info;
204   remove_fake_edges ();
205
206   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
207     {
208       edge e = bb->succ;
209       while (e)
210         {
211           struct edge_info *inf = EDGE_INFO (e);
212           if (!inf->ignore && !inf->on_tree)
213             {
214               if (e->flags & EDGE_ABNORMAL)
215                 abort ();
216               if (rtl_dump_file)
217                 fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
218                          e->src->index, e->dest->index,
219                          EDGE_CRITICAL_P (e) ? " (and split)" : "");
220               insert_insn_on_edge (
221                          gen_edge_profiler (total_num_edges_instrumented
222                                             + num_instr_edges++), e);
223               rebuild_jump_labels (e->insns);
224             }
225           e = e->succ_next;
226         }
227     }
228
229   section_info = find_counters_section (GCOV_TAG_ARC_COUNTS);
230   section_info->n_counters_now = num_instr_edges;
231   total_num_edges_instrumented += num_instr_edges;
232   section_info->n_counters = total_num_edges_instrumented;
233
234   total_num_blocks_created += num_edges;
235   if (rtl_dump_file)
236     fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
237 }
238 \f
239 static hashval_t
240 htab_counts_entry_hash (of)
241      const void *of;
242 {
243   const counts_entry_t *entry = of;
244
245   return htab_hash_string (entry->function_name) ^ entry->section;
246 }
247
248 static int
249 htab_counts_entry_eq (of1, of2)
250      const void *of1;
251      const void *of2;
252 {
253   const counts_entry_t *entry1 = of1;
254   const counts_entry_t *entry2 = of2;
255
256   return !strcmp (entry1->function_name, entry2->function_name)
257     && entry1->section == entry2->section;
258 }
259
260 static void
261 htab_counts_entry_del (of)
262      void *of;
263 {
264   counts_entry_t *entry = of;
265
266   free (entry->function_name);
267   free (entry->counts);
268   free (entry);
269 }
270
271 static htab_t counts_hash = NULL;
272
273 static void
274 read_counts_file (const char *name)
275 {
276   char *function_name_buffer = NULL;
277   unsigned version, ix, checksum;
278   counts_entry_t *summaried = NULL;
279   unsigned seen_summary = 0;
280   
281   if (!gcov_open (name, 1))
282     {
283       warning ("file %s not found, execution counts assumed to be zero", name);
284       return;
285     }
286   
287   if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
288     {
289       warning ("`%s' is not a gcov data file", name);
290       gcov_close ();
291       return;
292     }
293   else if ((version = gcov_read_unsigned ()) != GCOV_VERSION)
294     {
295       char v[4], e[4];
296       unsigned required = GCOV_VERSION;
297       
298       for (ix = 4; ix--; required >>= 8, version >>= 8)
299         {
300           v[ix] = version;
301           e[ix] = required;
302         }
303       warning ("`%s' is version `%.4s', expected version `%.4s'", name, v, e);
304       gcov_close ();
305       return;
306     }
307   
308   counts_hash = htab_create (10,
309                              htab_counts_entry_hash, htab_counts_entry_eq,
310                              htab_counts_entry_del);
311   while (!gcov_is_eof ())
312     {
313       unsigned tag, length;
314       unsigned long offset;
315       int error;
316       
317       tag = gcov_read_unsigned ();
318       length = gcov_read_unsigned ();
319       offset = gcov_position ();
320       if (tag == GCOV_TAG_FUNCTION)
321         {
322           const char *string = gcov_read_string ();
323           free (function_name_buffer);
324           function_name_buffer = string ? xstrdup (string) : NULL;
325           checksum = gcov_read_unsigned ();
326           if (seen_summary)
327             {
328               /* We have already seen a summary, this means that this
329                  new function begins a new set of program runs. We
330                  must unlink the summaried chain.  */
331               counts_entry_t *entry, *chain;
332               
333               for (entry = summaried; entry; entry = chain)
334                 {
335                   chain = entry->chain;
336                   
337                   entry->max_counter_sum += entry->max_counter;
338                   entry->chain = NULL;
339                 }
340               summaried = NULL;
341               seen_summary = 0;
342             }
343         }
344       else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
345         {
346           counts_entry_t *entry;
347           struct gcov_summary summary;
348           
349           gcov_read_summary (&summary);
350           seen_summary = 1;
351           for (entry = summaried; entry; entry = entry->chain)
352             {
353               entry->merged += summary.runs;
354               if (entry->max_counter < summary.arc_sum_max)
355                 entry->max_counter = summary.arc_sum_max;
356             }
357         }
358       else if (GCOV_TAG_IS_SUBTAG (GCOV_TAG_FUNCTION, tag)
359                && function_name_buffer)
360         {
361           counts_entry_t **slot, *entry, elt;
362           unsigned n_counts = length / 8;
363           unsigned ix;
364
365           elt.function_name = function_name_buffer;
366           elt.section = tag;
367
368           slot = (counts_entry_t **) htab_find_slot
369             (counts_hash, &elt, INSERT);
370           entry = *slot;
371           if (!entry)
372             {
373               *slot = entry = xmalloc (sizeof (counts_entry_t));
374               entry->function_name = xstrdup (function_name_buffer);
375               entry->section = tag;
376               entry->checksum = checksum;
377               entry->n_counts = n_counts;
378               entry->counts = xcalloc (n_counts, sizeof (gcov_type));
379             }
380           else if (entry->checksum != checksum || entry->n_counts != n_counts)
381             {
382               warning ("profile mismatch for `%s'", function_name_buffer);
383               htab_delete (counts_hash);
384               break;
385             }
386           
387           /* This should always be true for a just allocated entry,
388              and always false for an existing one. Check this way, in
389              case the gcov file is corrupt.  */
390           if (!entry->chain || summaried != entry)
391             {
392               entry->chain = summaried;
393               summaried = entry;
394             }
395           for (ix = 0; ix != n_counts; ix++)
396             entry->counts[ix] += gcov_read_counter ();
397         }
398       gcov_seek (offset, length);
399       if ((error = gcov_is_error ()))
400         {
401           warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
402                    name);
403           htab_delete (counts_hash);
404           break;
405         }
406     }
407
408   free (function_name_buffer);
409   gcov_close ();
410 }
411
412 /* Computes hybrid profile for all matching entries in da_file.
413    Sets max_counter_in_program as a side effect.  */
414
415 static gcov_type *
416 get_exec_counts ()
417 {
418   unsigned num_edges = 0;
419   basic_block bb;
420   const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
421   counts_entry_t *entry, elt;
422
423   profile_info.max_counter_in_program = 0;
424   profile_info.count_profiles_merged = 0;
425
426   /* No hash table, no counts. */
427   if (!counts_hash)
428     return NULL;
429
430   /* Count the edges to be (possibly) instrumented.  */
431   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
432     {
433       edge e;
434       for (e = bb->succ; e; e = e->succ_next)
435         if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
436           num_edges++;
437     }
438
439   elt.function_name = (char *) name;
440   elt.section = GCOV_TAG_ARC_COUNTS;
441   entry = htab_find (counts_hash, &elt);
442   if (!entry)
443     {
444       warning ("No profile for function '%s' found.", name);
445       return NULL;
446     }
447   
448   if (entry->checksum != profile_info.current_function_cfg_checksum
449       || num_edges != entry->n_counts)
450     {
451       warning ("profile mismatch for `%s'", current_function_name);
452       return NULL;
453     }
454
455   profile_info.count_profiles_merged = entry->merged;
456   profile_info.max_counter_in_program = entry->max_counter_sum;
457
458   if (rtl_dump_file)
459     {
460       fprintf(rtl_dump_file, "Merged %i profiles with maximal count %i.\n",
461               profile_info.count_profiles_merged,
462               (int)profile_info.max_counter_in_program);
463     }
464
465   return entry->counts;
466 }
467 \f
468
469 /* Compute the branch probabilities for the various branches.
470    Annotate them accordingly.  */
471
472 static void
473 compute_branch_probabilities ()
474 {
475   basic_block bb;
476   int i;
477   int num_edges = 0;
478   int changes;
479   int passes;
480   int hist_br_prob[20];
481   int num_never_executed;
482   int num_branches;
483   gcov_type *exec_counts = get_exec_counts ();
484   int exec_counts_pos = 0;
485
486   /* Attach extra info block to each bb.  */
487
488   alloc_aux_for_blocks (sizeof (struct bb_info));
489   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
490     {
491       edge e;
492
493       for (e = bb->succ; e; e = e->succ_next)
494         if (!EDGE_INFO (e)->ignore)
495           BB_INFO (bb)->succ_count++;
496       for (e = bb->pred; e; e = e->pred_next)
497         if (!EDGE_INFO (e)->ignore)
498           BB_INFO (bb)->pred_count++;
499     }
500
501   /* Avoid predicting entry on exit nodes.  */
502   BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
503   BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
504
505   /* For each edge not on the spanning tree, set its execution count from
506      the .da file.  */
507
508   /* The first count in the .da file is the number of times that the function
509      was entered.  This is the exec_count for block zero.  */
510
511   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
512     {
513       edge e;
514       for (e = bb->succ; e; e = e->succ_next)
515         if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
516           {
517             num_edges++;
518             if (exec_counts)
519               {
520                 e->count = exec_counts[exec_counts_pos++];
521               }
522             else
523               e->count = 0;
524
525             EDGE_INFO (e)->count_valid = 1;
526             BB_INFO (bb)->succ_count--;
527             BB_INFO (e->dest)->pred_count--;
528             if (rtl_dump_file)
529               {
530                 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
531                          bb->index, e->dest->index);
532                 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
533                          (HOST_WIDEST_INT) e->count);
534               }
535           }
536     }
537
538   if (rtl_dump_file)
539     fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
540
541   /* For every block in the file,
542      - if every exit/entrance edge has a known count, then set the block count
543      - if the block count is known, and every exit/entrance edge but one has
544      a known execution count, then set the count of the remaining edge
545
546      As edge counts are set, decrement the succ/pred count, but don't delete
547      the edge, that way we can easily tell when all edges are known, or only
548      one edge is unknown.  */
549
550   /* The order that the basic blocks are iterated through is important.
551      Since the code that finds spanning trees starts with block 0, low numbered
552      edges are put on the spanning tree in preference to high numbered edges.
553      Hence, most instrumented edges are at the end.  Graph solving works much
554      faster if we propagate numbers from the end to the start.
555
556      This takes an average of slightly more than 3 passes.  */
557
558   changes = 1;
559   passes = 0;
560   while (changes)
561     {
562       passes++;
563       changes = 0;
564       FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
565         {
566           struct bb_info *bi = BB_INFO (bb);
567           if (! bi->count_valid)
568             {
569               if (bi->succ_count == 0)
570                 {
571                   edge e;
572                   gcov_type total = 0;
573
574                   for (e = bb->succ; e; e = e->succ_next)
575                     total += e->count;
576                   bb->count = total;
577                   bi->count_valid = 1;
578                   changes = 1;
579                 }
580               else if (bi->pred_count == 0)
581                 {
582                   edge e;
583                   gcov_type total = 0;
584
585                   for (e = bb->pred; e; e = e->pred_next)
586                     total += e->count;
587                   bb->count = total;
588                   bi->count_valid = 1;
589                   changes = 1;
590                 }
591             }
592           if (bi->count_valid)
593             {
594               if (bi->succ_count == 1)
595                 {
596                   edge e;
597                   gcov_type total = 0;
598
599                   /* One of the counts will be invalid, but it is zero,
600                      so adding it in also doesn't hurt.  */
601                   for (e = bb->succ; e; e = e->succ_next)
602                     total += e->count;
603
604                   /* Seedgeh for the invalid edge, and set its count.  */
605                   for (e = bb->succ; e; e = e->succ_next)
606                     if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
607                       break;
608
609                   /* Calculate count for remaining edge by conservation.  */
610                   total = bb->count - total;
611
612                   if (! e)
613                     abort ();
614                   EDGE_INFO (e)->count_valid = 1;
615                   e->count = total;
616                   bi->succ_count--;
617
618                   BB_INFO (e->dest)->pred_count--;
619                   changes = 1;
620                 }
621               if (bi->pred_count == 1)
622                 {
623                   edge e;
624                   gcov_type total = 0;
625
626                   /* One of the counts will be invalid, but it is zero,
627                      so adding it in also doesn't hurt.  */
628                   for (e = bb->pred; e; e = e->pred_next)
629                     total += e->count;
630
631                   /* Seedgeh for the invalid edge, and set its count.  */
632                   for (e = bb->pred; e; e = e->pred_next)
633                     if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
634                       break;
635
636                   /* Calculate count for remaining edge by conservation.  */
637                   total = bb->count - total + e->count;
638
639                   if (! e)
640                     abort ();
641                   EDGE_INFO (e)->count_valid = 1;
642                   e->count = total;
643                   bi->pred_count--;
644
645                   BB_INFO (e->src)->succ_count--;
646                   changes = 1;
647                 }
648             }
649         }
650     }
651   if (rtl_dump_file)
652     dump_flow_info (rtl_dump_file);
653
654   total_num_passes += passes;
655   if (rtl_dump_file)
656     fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
657
658   /* If the graph has been correctly solved, every block will have a
659      succ and pred count of zero.  */
660   FOR_EACH_BB (bb)
661     {
662       if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
663         abort ();
664     }
665
666   /* For every edge, calculate its branch probability and add a reg_note
667      to the branch insn to indicate this.  */
668
669   for (i = 0; i < 20; i++)
670     hist_br_prob[i] = 0;
671   num_never_executed = 0;
672   num_branches = 0;
673
674   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
675     {
676       edge e;
677       gcov_type total;
678       rtx note;
679
680       total = bb->count;
681       if (total)
682         {
683           for (e = bb->succ; e; e = e->succ_next)
684             {
685                 e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
686                 if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
687                   {
688                     error ("corrupted profile info: prob for %d-%d thought to be %d",
689                            e->src->index, e->dest->index, e->probability);
690                     e->probability = REG_BR_PROB_BASE / 2;
691                   }
692             }
693           if (bb->index >= 0
694               && any_condjump_p (bb->end)
695               && bb->succ->succ_next)
696             {
697               int prob;
698               edge e;
699               int index;
700
701               /* Find the branch edge.  It is possible that we do have fake
702                  edges here.  */
703               for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
704                    e = e->succ_next)
705                 continue; /* Loop body has been intentionally left blank.  */
706
707               prob = e->probability;
708               index = prob * 20 / REG_BR_PROB_BASE;
709
710               if (index == 20)
711                 index = 19;
712               hist_br_prob[index]++;
713
714               note = find_reg_note (bb->end, REG_BR_PROB, 0);
715               /* There may be already note put by some other pass, such
716                  as builtin_expect expander.  */
717               if (note)
718                 XEXP (note, 0) = GEN_INT (prob);
719               else
720                 REG_NOTES (bb->end)
721                   = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
722                                        REG_NOTES (bb->end));
723               num_branches++;
724             }
725         }
726       /* Otherwise distribute the probabilities evenly so we get sane
727          sum.  Use simple heuristics that if there are normal edges,
728          give all abnormals frequency of 0, otherwise distribute the
729          frequency over abnormals (this is the case of noreturn
730          calls).  */
731       else
732         {
733           for (e = bb->succ; e; e = e->succ_next)
734             if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
735               total ++;
736           if (total)
737             {
738               for (e = bb->succ; e; e = e->succ_next)
739                 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
740                   e->probability = REG_BR_PROB_BASE / total;
741                 else
742                   e->probability = 0;
743             }
744           else
745             {
746               for (e = bb->succ; e; e = e->succ_next)
747                 total ++;
748               for (e = bb->succ; e; e = e->succ_next)
749                 e->probability = REG_BR_PROB_BASE / total;
750             }
751           if (bb->index >= 0
752               && any_condjump_p (bb->end)
753               && bb->succ->succ_next)
754             num_branches++, num_never_executed;
755         }
756     }
757
758   if (rtl_dump_file)
759     {
760       fprintf (rtl_dump_file, "%d branches\n", num_branches);
761       fprintf (rtl_dump_file, "%d branches never executed\n",
762                num_never_executed);
763       if (num_branches)
764         for (i = 0; i < 10; i++)
765           fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
766                    (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
767                    5 * i, 5 * i + 5);
768
769       total_num_branches += num_branches;
770       total_num_never_executed += num_never_executed;
771       for (i = 0; i < 20; i++)
772         total_hist_br_prob[i] += hist_br_prob[i];
773
774       fputc ('\n', rtl_dump_file);
775       fputc ('\n', rtl_dump_file);
776     }
777
778   free_aux_for_blocks ();
779   find_counters_section (GCOV_TAG_ARC_COUNTS)->present = 1;
780 }
781
782 /* Compute checksum for the current function.  We generate a CRC32.  */
783
784 static unsigned
785 compute_checksum ()
786 {
787   unsigned chksum = 0;
788   basic_block bb;
789   
790   FOR_EACH_BB (bb)
791     {
792       edge e = NULL;
793       
794       do
795         {
796           unsigned value = BB_TO_GCOV_INDEX (e ? e->dest : bb);
797           unsigned ix;
798
799           /* No need to use all bits in value identically, nearly all
800              functions have less than 256 blocks.  */
801           value ^= value << 16;
802           value ^= value << 8;
803           
804           for (ix = 8; ix--; value <<= 1)
805             {
806               unsigned feedback;
807
808               feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
809               chksum <<= 1;
810               chksum ^= feedback;
811             }
812           
813           e = e ? e->succ_next : bb->succ;
814         }
815       while (e);
816     }
817
818   return chksum;
819 }
820
821 /* Instrument and/or analyze program behavior based on program flow graph.
822    In either case, this function builds a flow graph for the function being
823    compiled.  The flow graph is stored in BB_GRAPH.
824
825    When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
826    the flow graph that are needed to reconstruct the dynamic behavior of the
827    flow graph.
828
829    When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
830    information from a data file containing edge count information from previous
831    executions of the function being compiled.  In this case, the flow graph is
832    annotated with actual execution counts, which are later propagated into the
833    rtl for optimization purposes.
834
835    Main entry point of this file.  */
836
837 void
838 branch_prob ()
839 {
840   basic_block bb;
841   unsigned i;
842   unsigned num_edges, ignored_edges;
843   struct edge_list *el;
844   const char *name = IDENTIFIER_POINTER
845     (DECL_ASSEMBLER_NAME (current_function_decl));
846
847   profile_info.current_function_cfg_checksum = compute_checksum ();
848   for (i = 0; i < profile_info.n_sections; i++)
849     {
850       profile_info.section_info[i].n_counters_now = 0;
851       profile_info.section_info[i].present = 0;
852     }
853
854   if (rtl_dump_file)
855     fprintf (rtl_dump_file, "CFG checksum is %u\n",
856         profile_info.current_function_cfg_checksum);
857
858   total_num_times_called++;
859
860   flow_call_edges_add (NULL);
861   add_noreturn_fake_exit_edges ();
862
863   /* We can't handle cyclic regions constructed using abnormal edges.
864      To avoid these we replace every source of abnormal edge by a fake
865      edge from entry node and every destination by fake edge to exit.
866      This keeps graph acyclic and our calculation exact for all normal
867      edges except for exit and entrance ones.
868
869      We also add fake exit edges for each call and asm statement in the
870      basic, since it may not return.  */
871
872   FOR_EACH_BB (bb)
873     {
874       int need_exit_edge = 0, need_entry_edge = 0;
875       int have_exit_edge = 0, have_entry_edge = 0;
876       rtx insn;
877       edge e;
878
879       /* Add fake edges from entry block to the call insns that may return
880          twice.  The CFG is not quite correct then, as call insn plays more
881          role of CODE_LABEL, but for our purposes, everything should be OK,
882          as we never insert code to the beginning of basic block.  */
883       for (insn = bb->head; insn != NEXT_INSN (bb->end);
884            insn = NEXT_INSN (insn))
885         {
886           if (GET_CODE (insn) == CALL_INSN
887               && find_reg_note (insn, REG_SETJMP, NULL))
888             {
889               if (GET_CODE (bb->head) == CODE_LABEL
890                   || insn != NEXT_INSN (bb->head))
891                 {
892                   e = split_block (bb, PREV_INSN (insn));
893                   make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
894                   break;
895                 }
896               else
897                 {
898                   /* We should not get abort here, as call to setjmp should not
899                      be the very first instruction of function.  */
900                   if (bb == ENTRY_BLOCK_PTR)
901                     abort ();
902                   make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
903                 }
904             }
905         }
906
907       for (e = bb->succ; e; e = e->succ_next)
908         {
909           if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
910                && e->dest != EXIT_BLOCK_PTR)
911             need_exit_edge = 1;
912           if (e->dest == EXIT_BLOCK_PTR)
913             have_exit_edge = 1;
914         }
915       for (e = bb->pred; e; e = e->pred_next)
916         {
917           if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
918                && e->src != ENTRY_BLOCK_PTR)
919             need_entry_edge = 1;
920           if (e->src == ENTRY_BLOCK_PTR)
921             have_entry_edge = 1;
922         }
923
924       if (need_exit_edge && !have_exit_edge)
925         {
926           if (rtl_dump_file)
927             fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
928                      bb->index);
929           make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
930         }
931       if (need_entry_edge && !have_entry_edge)
932         {
933           if (rtl_dump_file)
934             fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
935                      bb->index);
936           make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
937         }
938     }
939
940   el = create_edge_list ();
941   num_edges = NUM_EDGES (el);
942   alloc_aux_for_edges (sizeof (struct edge_info));
943
944   /* The basic blocks are expected to be numbered sequentially.  */
945   compact_blocks ();
946
947   ignored_edges = 0;
948   for (i = 0 ; i < num_edges ; i++)
949     {
950       edge e = INDEX_EDGE (el, i);
951       e->count = 0;
952
953       /* Mark edges we've replaced by fake edges above as ignored.  */
954       if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
955           && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
956         {
957           EDGE_INFO (e)->ignore = 1;
958           ignored_edges++;
959         }
960     }
961
962 #ifdef ENABLE_CHECKING
963   verify_flow_info ();
964 #endif
965
966   /* Create spanning tree from basic block graph, mark each edge that is
967      on the spanning tree.  We insert as many abnormal and critical edges
968      as possible to minimize number of edge splits necessary.  */
969
970   find_spanning_tree (el);
971
972   /* Fake edges that are not on the tree will not be instrumented, so
973      mark them ignored.  */
974   for (i = 0; i < num_edges; i++)
975     {
976       edge e = INDEX_EDGE (el, i);
977       struct edge_info *inf = EDGE_INFO (e);
978       if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
979         {
980           inf->ignore = 1;
981           ignored_edges++;
982         }
983     }
984
985   total_num_blocks += n_basic_blocks + 2;
986   if (rtl_dump_file)
987     fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
988
989   total_num_edges += num_edges;
990   if (rtl_dump_file)
991     fprintf (rtl_dump_file, "%d edges\n", num_edges);
992
993   total_num_edges_ignored += ignored_edges;
994   if (rtl_dump_file)
995     fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
996
997   /* Create a .bbg file from which gcov can reconstruct the basic block
998      graph.  First output the number of basic blocks, and then for every
999      edge output the source and target basic block numbers.
1000      NOTE: The format of this file must be compatible with gcov.  */
1001
1002   if (!gcov_is_error ())
1003     {
1004       long offset;
1005       const char *file = DECL_SOURCE_FILE (current_function_decl);
1006       unsigned line = DECL_SOURCE_LINE (current_function_decl);
1007       
1008       /* Announce function */
1009       offset = gcov_write_tag (GCOV_TAG_FUNCTION);
1010       gcov_write_string (name);
1011       gcov_write_unsigned (profile_info.current_function_cfg_checksum);
1012       gcov_write_string (file);
1013       gcov_write_unsigned (line);
1014       gcov_write_length (offset);
1015
1016       /* Basic block flags */
1017       offset = gcov_write_tag (GCOV_TAG_BLOCKS);
1018       for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++)
1019         gcov_write_unsigned (0);
1020       gcov_write_length (offset);
1021       
1022       /* Arcs */
1023       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
1024         {
1025           edge e;
1026
1027           offset = gcov_write_tag (GCOV_TAG_ARCS);
1028           gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
1029           
1030           for (e = bb->succ; e; e = e->succ_next)
1031             {
1032               struct edge_info *i = EDGE_INFO (e);
1033               if (!i->ignore)
1034                 {
1035                   unsigned flag_bits = 0;
1036                   
1037                   if (i->on_tree)
1038                     flag_bits |= GCOV_ARC_ON_TREE;
1039                   if (e->flags & EDGE_FAKE)
1040                     flag_bits |= GCOV_ARC_FAKE;
1041                   if (e->flags & EDGE_FALLTHRU)
1042                     flag_bits |= GCOV_ARC_FALLTHROUGH;
1043
1044                   gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest));
1045                   gcov_write_unsigned (flag_bits);
1046                 }
1047             }
1048
1049           gcov_write_length (offset);
1050         }
1051
1052       /* Output line number information about each basic block for
1053          GCOV utility.  */
1054       {
1055         char const *prev_file_name = NULL;
1056         
1057         FOR_EACH_BB (bb)
1058           {
1059             rtx insn = bb->head;
1060             int ignore_next_note = 0;
1061             
1062             offset = 0;
1063             
1064             /* We are looking for line number notes.  Search backward
1065                before basic block to find correct ones.  */
1066             insn = prev_nonnote_insn (insn);
1067             if (!insn)
1068               insn = get_insns ();
1069             else
1070               insn = NEXT_INSN (insn);
1071
1072             while (insn != bb->end)
1073               {
1074                 if (GET_CODE (insn) == NOTE)
1075                   {
1076                      /* Must ignore the line number notes that immediately
1077                         follow the end of an inline function to avoid counting
1078                         it twice.  There is a note before the call, and one
1079                         after the call.  */
1080                     if (NOTE_LINE_NUMBER (insn)
1081                         == NOTE_INSN_REPEATED_LINE_NUMBER)
1082                       ignore_next_note = 1;
1083                     else if (NOTE_LINE_NUMBER (insn) <= 0)
1084                       /*NOP*/;
1085                     else if (ignore_next_note)
1086                       ignore_next_note = 0;
1087                     else
1088                       {
1089                         if (!offset)
1090                           {
1091                             offset = gcov_write_tag (GCOV_TAG_LINES);
1092                             gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
1093                           }
1094
1095                         /* If this is a new source file, then output
1096                            the file's name to the .bb file.  */
1097                         if (!prev_file_name
1098                             || strcmp (NOTE_SOURCE_FILE (insn),
1099                                        prev_file_name))
1100                           {
1101                             prev_file_name = NOTE_SOURCE_FILE (insn);
1102                             gcov_write_unsigned (0);
1103                             gcov_write_string (prev_file_name);
1104                           }
1105                         gcov_write_unsigned (NOTE_LINE_NUMBER (insn));
1106                       }
1107                   }
1108                 insn = NEXT_INSN (insn);
1109               }
1110
1111             if (offset)
1112               {
1113                 /* A file of NULL indicates the end of run.  */
1114                 gcov_write_unsigned (0);
1115                 gcov_write_string (NULL);
1116                 gcov_write_length (offset);
1117               }
1118             if (gcov_is_error ())
1119               warning ("error writing `%s'", bbg_file_name);
1120           }
1121       }
1122     }
1123
1124   if (flag_branch_probabilities)
1125     compute_branch_probabilities ();
1126
1127   /* For each edge not on the spanning tree, add counting code as rtl.  */
1128
1129   if (cfun->arc_profile && profile_arc_flag)
1130     {
1131       struct function_list *item;
1132       
1133       instrument_edges (el);
1134
1135       /* Commit changes done by instrumentation.  */
1136       commit_edge_insertions_watch_calls ();
1137       allocate_reg_info (max_reg_num (), FALSE, FALSE);
1138
1139       /* ??? Probably should re-use the existing struct function.  */
1140       item = xmalloc (sizeof (struct function_list));
1141       
1142       *functions_tail = item;
1143       functions_tail = &item->next;
1144       
1145       item->next = 0;
1146       item->name = xstrdup (name);
1147       item->cfg_checksum = profile_info.current_function_cfg_checksum;
1148       item->n_counter_sections = 0;
1149       for (i = 0; i < profile_info.n_sections; i++)
1150         if (profile_info.section_info[i].n_counters_now)
1151           {
1152             item->counter_sections[item->n_counter_sections].tag = 
1153                     profile_info.section_info[i].tag;
1154             item->counter_sections[item->n_counter_sections].n_counters =
1155                     profile_info.section_info[i].n_counters_now;
1156             item->n_counter_sections++;
1157           }
1158     }
1159
1160   remove_fake_edges ();
1161   free_aux_for_edges ();
1162   /* Re-merge split basic blocks and the mess introduced by
1163      insert_insn_on_edge.  */
1164   cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
1165   if (rtl_dump_file)
1166     dump_flow_info (rtl_dump_file);
1167
1168   free_edge_list (el);
1169 }
1170 \f
1171 /* Union find algorithm implementation for the basic blocks using
1172    aux fields.  */
1173
1174 static basic_block
1175 find_group (bb)
1176      basic_block bb;
1177 {
1178   basic_block group = bb, bb1;
1179
1180   while ((basic_block) group->aux != group)
1181     group = (basic_block) group->aux;
1182
1183   /* Compress path.  */
1184   while ((basic_block) bb->aux != group)
1185     {
1186       bb1 = (basic_block) bb->aux;
1187       bb->aux = (void *) group;
1188       bb = bb1;
1189     }
1190   return group;
1191 }
1192
1193 static void
1194 union_groups (bb1, bb2)
1195      basic_block bb1, bb2;
1196 {
1197   basic_block bb1g = find_group (bb1);
1198   basic_block bb2g = find_group (bb2);
1199
1200   /* ??? I don't have a place for the rank field.  OK.  Lets go w/o it,
1201      this code is unlikely going to be performance problem anyway.  */
1202   if (bb1g == bb2g)
1203     abort ();
1204
1205   bb1g->aux = bb2g;
1206 }
1207 \f
1208 /* This function searches all of the edges in the program flow graph, and puts
1209    as many bad edges as possible onto the spanning tree.  Bad edges include
1210    abnormals edges, which can't be instrumented at the moment.  Since it is
1211    possible for fake edges to form a cycle, we will have to develop some
1212    better way in the future.  Also put critical edges to the tree, since they
1213    are more expensive to instrument.  */
1214
1215 static void
1216 find_spanning_tree (el)
1217      struct edge_list *el;
1218 {
1219   int i;
1220   int num_edges = NUM_EDGES (el);
1221   basic_block bb;
1222
1223   /* We use aux field for standard union-find algorithm.  */
1224   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1225     bb->aux = bb;
1226
1227   /* Add fake edge exit to entry we can't instrument.  */
1228   union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
1229
1230   /* First add all abnormal edges to the tree unless they form a cycle. Also
1231      add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
1232      setting return value from function.  */
1233   for (i = 0; i < num_edges; i++)
1234     {
1235       edge e = INDEX_EDGE (el, i);
1236       if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
1237            || e->dest == EXIT_BLOCK_PTR
1238            )
1239           && !EDGE_INFO (e)->ignore
1240           && (find_group (e->src) != find_group (e->dest)))
1241         {
1242           if (rtl_dump_file)
1243             fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
1244                      e->src->index, e->dest->index);
1245           EDGE_INFO (e)->on_tree = 1;
1246           union_groups (e->src, e->dest);
1247         }
1248     }
1249
1250   /* Now insert all critical edges to the tree unless they form a cycle.  */
1251   for (i = 0; i < num_edges; i++)
1252     {
1253       edge e = INDEX_EDGE (el, i);
1254       if ((EDGE_CRITICAL_P (e))
1255           && !EDGE_INFO (e)->ignore
1256           && (find_group (e->src) != find_group (e->dest)))
1257         {
1258           if (rtl_dump_file)
1259             fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
1260                      e->src->index, e->dest->index);
1261           EDGE_INFO (e)->on_tree = 1;
1262           union_groups (e->src, e->dest);
1263         }
1264     }
1265
1266   /* And now the rest.  */
1267   for (i = 0; i < num_edges; i++)
1268     {
1269       edge e = INDEX_EDGE (el, i);
1270       if (find_group (e->src) != find_group (e->dest)
1271           && !EDGE_INFO (e)->ignore)
1272         {
1273           if (rtl_dump_file)
1274             fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
1275                      e->src->index, e->dest->index);
1276           EDGE_INFO (e)->on_tree = 1;
1277           union_groups (e->src, e->dest);
1278         }
1279     }
1280
1281   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
1282     bb->aux = NULL;
1283 }
1284 \f
1285 /* Perform file-level initialization for branch-prob processing.  */
1286
1287 void
1288 init_branch_prob (filename)
1289   const char *filename;
1290 {
1291   int len = strlen (filename);
1292   int i;
1293
1294   da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
1295   strcpy (da_file_name, filename);
1296   strcat (da_file_name, GCOV_DATA_SUFFIX);
1297   
1298   if (flag_branch_probabilities)
1299     read_counts_file (da_file_name);
1300
1301   if (flag_test_coverage)
1302     {
1303       /* Open the bbg output file.  */
1304       bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1);
1305       strcpy (bbg_file_name, filename);
1306       strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
1307       if (!gcov_open (bbg_file_name, -1))
1308         error ("cannot open %s", bbg_file_name);
1309       gcov_write_unsigned (GCOV_GRAPH_MAGIC);
1310       gcov_write_unsigned (GCOV_VERSION);
1311     }
1312
1313   if (profile_arc_flag)
1314     {
1315       /* Generate and save a copy of this so it can be shared.  */
1316       char buf[20];
1317       
1318       ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1319       profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1320     }
1321   
1322   total_num_blocks = 0;
1323   total_num_edges = 0;
1324   total_num_edges_ignored = 0;
1325   total_num_edges_instrumented = 0;
1326   total_num_blocks_created = 0;
1327   total_num_passes = 0;
1328   total_num_times_called = 0;
1329   total_num_branches = 0;
1330   total_num_never_executed = 0;
1331   for (i = 0; i < 20; i++)
1332     total_hist_br_prob[i] = 0;
1333 }
1334
1335 /* Performs file-level cleanup after branch-prob processing
1336    is completed.  */
1337
1338 void
1339 end_branch_prob ()
1340 {
1341   if (flag_test_coverage)
1342     {
1343       int error = gcov_close ();
1344       
1345       if (error)
1346         unlink (bbg_file_name);
1347 #if SELF_COVERAGE
1348       /* If the compiler is instrumented, we should not
1349          unconditionally remove the counts file, because we might be
1350          recompiling ourselves. The .da files are all removed during
1351          copying the stage1 files.  */
1352       if (error)
1353 #endif
1354         unlink (da_file_name);
1355     }
1356
1357   if (rtl_dump_file)
1358     {
1359       fprintf (rtl_dump_file, "\n");
1360       fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1361                total_num_blocks);
1362       fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1363       fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1364                total_num_edges_ignored);
1365       fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1366                total_num_edges_instrumented);
1367       fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1368                total_num_blocks_created);
1369       fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1370                total_num_passes);
1371       if (total_num_times_called != 0)
1372         fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1373                  (total_num_passes + (total_num_times_called  >> 1))
1374                  / total_num_times_called);
1375       fprintf (rtl_dump_file, "Total number of branches: %d\n",
1376                total_num_branches);
1377       fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1378                total_num_never_executed);
1379       if (total_num_branches)
1380         {
1381           int i;
1382
1383           for (i = 0; i < 10; i++)
1384             fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1385                      (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1386                      / total_num_branches, 5*i, 5*i+5);
1387         }
1388     }
1389 }
1390
1391 /* Find (and create if not present) a section with TAG.  */
1392 struct section_info *
1393 find_counters_section (tag)
1394      unsigned tag;
1395 {
1396   unsigned i;
1397
1398   for (i = 0; i < profile_info.n_sections; i++)
1399     if (profile_info.section_info[i].tag == tag)
1400       return profile_info.section_info + i;
1401
1402   if (i == MAX_COUNTER_SECTIONS)
1403     abort ();
1404
1405   profile_info.section_info[i].tag = tag;
1406   profile_info.section_info[i].present = 0;
1407   profile_info.section_info[i].n_counters = 0;
1408   profile_info.section_info[i].n_counters_now = 0;
1409   profile_info.n_sections++;
1410
1411   return profile_info.section_info + i;
1412 }
1413
1414 /* Set FIELDS as purpose to VALUE.  */
1415 static void
1416 set_purpose (value, fields)
1417      tree value;
1418      tree fields;
1419 {
1420   tree act_field, act_value;
1421   
1422   for (act_field = fields, act_value = value;
1423        act_field;
1424        act_field = TREE_CHAIN (act_field), act_value = TREE_CHAIN (act_value))
1425     TREE_PURPOSE (act_value) = act_field;
1426 }
1427
1428 /* Returns label for base of counters inside TAG section.  */
1429 static rtx
1430 label_for_tag (tag)
1431      unsigned tag;
1432 {
1433   switch (tag)
1434     {
1435     case GCOV_TAG_ARC_COUNTS:
1436       return profiler_label;
1437     default:
1438       abort ();
1439     }
1440 }
1441
1442 /* Creates fields of struct counter_section (in gcov-io.h).  */
1443 static tree
1444 build_counter_section_fields ()
1445 {
1446   tree field, fields;
1447
1448   /* tag */
1449   fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1450
1451   /* n_counters */
1452   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1453   TREE_CHAIN (field) = fields;
1454   fields = field;
1455
1456   return fields;
1457 }
1458
1459 /* Creates value of struct counter_section (in gcov-io.h).  */
1460 static tree
1461 build_counter_section_value (tag, n_counters)
1462      unsigned tag;
1463      unsigned n_counters;
1464 {
1465   tree value = NULL_TREE;
1466
1467   /* tag */
1468   value = tree_cons (NULL_TREE,
1469                      convert (unsigned_type_node,
1470                               build_int_2 (tag, 0)),
1471                      value);
1472   
1473   /* n_counters */
1474   value = tree_cons (NULL_TREE,
1475                      convert (unsigned_type_node,
1476                               build_int_2 (n_counters, 0)),
1477                      value);
1478
1479   return value;
1480 }
1481
1482 /* Creates fields of struct counter_section_data (in gcov-io.h).  */
1483 static tree
1484 build_counter_section_data_fields ()
1485 {
1486   tree field, fields, gcov_type, gcov_ptr_type;
1487
1488   gcov_type = make_signed_type (GCOV_TYPE_SIZE);
1489   gcov_ptr_type =
1490           build_pointer_type (build_qualified_type (gcov_type,
1491                                                     TYPE_QUAL_CONST));
1492
1493   /* tag */
1494   fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1495
1496   /* n_counters */
1497   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1498   TREE_CHAIN (field) = fields;
1499   fields = field;
1500
1501   /* counters */
1502   field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
1503   TREE_CHAIN (field) = fields;
1504   fields = field;
1505
1506   return fields;
1507 }
1508
1509 /* Creates value of struct counter_section_data (in gcov-io.h).  */
1510 static tree
1511 build_counter_section_data_value (tag, n_counters)
1512      unsigned tag;
1513      unsigned n_counters;
1514 {
1515   tree value = NULL_TREE, counts_table, gcov_type, gcov_ptr_type;
1516
1517   gcov_type = make_signed_type (GCOV_TYPE_SIZE);
1518   gcov_ptr_type
1519     = build_pointer_type (build_qualified_type
1520                           (gcov_type, TYPE_QUAL_CONST));
1521
1522   /* tag */
1523   value = tree_cons (NULL_TREE,
1524                      convert (unsigned_type_node,
1525                               build_int_2 (tag, 0)),
1526                      value);
1527   
1528   /* n_counters */
1529   value = tree_cons (NULL_TREE,
1530                      convert (unsigned_type_node,
1531                               build_int_2 (n_counters, 0)),
1532                      value);
1533
1534   /* counters */
1535   if (n_counters)
1536     {
1537       tree gcov_type_array_type =
1538               build_array_type (gcov_type,
1539                                 build_index_type (build_int_2 (n_counters - 1,
1540                                                                0)));
1541       counts_table =
1542               build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
1543       TREE_STATIC (counts_table) = 1;
1544       DECL_NAME (counts_table) = get_identifier (XSTR (label_for_tag (tag), 0));
1545       assemble_variable (counts_table, 0, 0, 0);
1546       counts_table = build1 (ADDR_EXPR, gcov_ptr_type, counts_table);
1547     }
1548   else
1549     counts_table = null_pointer_node;
1550
1551   value = tree_cons (NULL_TREE, counts_table, value);
1552
1553   return value;
1554 }
1555
1556 /* Creates fields for struct function_info type (in gcov-io.h).  */
1557 static tree
1558 build_function_info_fields ()
1559 {
1560   tree field, fields, counter_section_fields, counter_section_type;
1561   tree counter_sections_ptr_type;
1562   tree string_type =
1563           build_pointer_type (build_qualified_type (char_type_node,
1564                                                     TYPE_QUAL_CONST));
1565   /* name */
1566   fields = build_decl (FIELD_DECL, NULL_TREE, string_type);
1567
1568   /* checksum */
1569   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1570   TREE_CHAIN (field) = fields;
1571   fields = field;
1572
1573   /* n_counter_sections */
1574   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1575   TREE_CHAIN (field) = fields;
1576   fields = field;
1577
1578   /* counter_sections */
1579   counter_section_fields = build_counter_section_fields ();
1580   counter_section_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1581   finish_builtin_struct (counter_section_type, "__counter_section",
1582                          counter_section_fields, NULL_TREE);
1583   counter_sections_ptr_type =
1584           build_pointer_type
1585                 (build_qualified_type (counter_section_type,
1586                                        TYPE_QUAL_CONST));
1587   field = build_decl (FIELD_DECL, NULL_TREE, counter_sections_ptr_type);
1588   TREE_CHAIN (field) = fields;
1589   fields = field;
1590
1591   return fields;
1592 }
1593
1594 /* Creates value for struct function_info (in gcov-io.h).  */
1595 static tree
1596 build_function_info_value (function)
1597      struct function_list *function;
1598 {
1599   tree value = NULL_TREE;
1600   size_t name_len = strlen (function->name);
1601   tree fname = build_string (name_len + 1, function->name);
1602   tree string_type =
1603           build_pointer_type (build_qualified_type (char_type_node,
1604                                                     TYPE_QUAL_CONST));
1605   tree counter_section_fields, counter_section_type, counter_sections_value;
1606   tree counter_sections_ptr_type, counter_sections_array_type;
1607   unsigned i;
1608
1609   /* name */
1610   TREE_TYPE (fname) =
1611           build_array_type (char_type_node,
1612                             build_index_type (build_int_2 (name_len, 0)));
1613   value = tree_cons (NULL_TREE,
1614                      build1 (ADDR_EXPR,
1615                              string_type,
1616                              fname),
1617                      value);
1618
1619   /* checksum */
1620   value = tree_cons (NULL_TREE,
1621                      convert (unsigned_type_node,
1622                               build_int_2 (function->cfg_checksum, 0)),
1623                      value);
1624
1625   /* n_counter_sections */
1626
1627   value = tree_cons (NULL_TREE,
1628                      convert (unsigned_type_node,
1629                               build_int_2 (function->n_counter_sections, 0)),
1630                     value);
1631
1632   /* counter_sections */
1633   counter_section_fields = build_counter_section_fields ();
1634   counter_section_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1635   counter_sections_ptr_type =
1636           build_pointer_type
1637                 (build_qualified_type (counter_section_type,
1638                                        TYPE_QUAL_CONST));
1639   counter_sections_array_type =
1640           build_array_type (counter_section_type,
1641                             build_index_type (
1642                                 build_int_2 (function->n_counter_sections - 1,
1643                                              0)));
1644
1645   counter_sections_value = NULL_TREE;
1646   for (i = 0; i < function->n_counter_sections; i++)
1647     {
1648       tree counter_section_value =
1649               build_counter_section_value (function->counter_sections[i].tag,
1650                                            function->counter_sections[i].n_counters);
1651       set_purpose (counter_section_value, counter_section_fields);
1652       counter_sections_value = tree_cons (NULL_TREE,
1653                                           build (CONSTRUCTOR,
1654                                                  counter_section_type,
1655                                                  NULL_TREE,
1656                                                  nreverse (counter_section_value)),
1657                                           counter_sections_value);
1658     }
1659   finish_builtin_struct (counter_section_type, "__counter_section",
1660                          counter_section_fields, NULL_TREE);
1661
1662   if (function->n_counter_sections)
1663     {
1664       counter_sections_value = 
1665               build (CONSTRUCTOR,
1666                      counter_sections_array_type,
1667                      NULL_TREE,
1668                      nreverse (counter_sections_value)),
1669       counter_sections_value = build1 (ADDR_EXPR,
1670                                        counter_sections_ptr_type,
1671                                        counter_sections_value);
1672     }
1673   else
1674     counter_sections_value = null_pointer_node;
1675
1676   value = tree_cons (NULL_TREE, counter_sections_value, value);
1677
1678   return value;
1679 }
1680
1681 /* Creates fields of struct gcov_info type (in gcov-io.h).  */
1682 static tree
1683 build_gcov_info_fields (gcov_info_type)
1684      tree gcov_info_type;
1685 {
1686   tree field, fields;
1687   char *filename;
1688   int filename_len;
1689   tree string_type =
1690           build_pointer_type (build_qualified_type (char_type_node,
1691                                                     TYPE_QUAL_CONST));
1692   tree function_info_fields, function_info_type, function_info_ptr_type;
1693   tree counter_section_data_fields, counter_section_data_type;
1694   tree counter_section_data_ptr_type;
1695
1696   /* Version ident */
1697   fields = build_decl (FIELD_DECL, NULL_TREE, long_unsigned_type_node);
1698
1699   /* next -- NULL */
1700   field = build_decl (FIELD_DECL, NULL_TREE,
1701                       build_pointer_type (build_qualified_type (gcov_info_type,
1702                                                                 TYPE_QUAL_CONST)));
1703   TREE_CHAIN (field) = fields;
1704   fields = field;
1705   
1706   /* Filename */
1707   filename = getpwd ();
1708   filename = (filename && da_file_name[0] != '/'
1709               ? concat (filename, "/", da_file_name, NULL)
1710               : da_file_name);
1711   filename_len = strlen (filename);
1712   if (filename != da_file_name)
1713     free (filename);
1714
1715   field = build_decl (FIELD_DECL, NULL_TREE, string_type);
1716   TREE_CHAIN (field) = fields;
1717   fields = field;
1718   
1719   /* Workspace */
1720   field = build_decl (FIELD_DECL, NULL_TREE, long_integer_type_node);
1721   TREE_CHAIN (field) = fields;
1722   fields = field;
1723
1724   /* number of functions */
1725   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1726   TREE_CHAIN (field) = fields;
1727   fields = field;
1728       
1729   /* function_info table */
1730   function_info_fields = build_function_info_fields ();
1731   function_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1732   finish_builtin_struct (function_info_type, "__function_info",
1733                          function_info_fields, NULL_TREE);
1734   function_info_ptr_type =
1735           build_pointer_type
1736                 (build_qualified_type (function_info_type,
1737                                        TYPE_QUAL_CONST));
1738   field = build_decl (FIELD_DECL, NULL_TREE, function_info_ptr_type);
1739   TREE_CHAIN (field) = fields;
1740   fields = field;
1741     
1742   /* n_counter_sections  */
1743   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1744   TREE_CHAIN (field) = fields;
1745   fields = field;
1746   
1747   /* counter sections */
1748   counter_section_data_fields = build_counter_section_data_fields ();
1749   counter_section_data_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1750   finish_builtin_struct (counter_section_data_type, "__counter_section_data",
1751                          counter_section_data_fields, NULL_TREE);
1752   counter_section_data_ptr_type =
1753           build_pointer_type
1754                 (build_qualified_type (counter_section_data_type,
1755                                        TYPE_QUAL_CONST));
1756   field = build_decl (FIELD_DECL, NULL_TREE, counter_section_data_ptr_type);
1757   TREE_CHAIN (field) = fields;
1758   fields = field;
1759
1760   return fields;
1761 }
1762
1763 /* Creates struct gcov_info value (in gcov-io.h).  */
1764 static tree
1765 build_gcov_info_value ()
1766 {
1767   tree value = NULL_TREE;
1768   tree filename_string;
1769   char *filename;
1770   int filename_len;
1771   unsigned n_functions, i;
1772   struct function_list *item;
1773   tree string_type =
1774           build_pointer_type (build_qualified_type (char_type_node,
1775                                                     TYPE_QUAL_CONST));
1776   tree function_info_fields, function_info_type, function_info_ptr_type;
1777   tree functions;
1778   tree counter_section_data_fields, counter_section_data_type;
1779   tree counter_section_data_ptr_type, counter_sections;
1780
1781   /* Version ident */
1782   value = tree_cons (NULL_TREE,
1783                      convert (long_unsigned_type_node,
1784                               build_int_2 (GCOV_VERSION, 0)),
1785                      value);
1786
1787   /* next -- NULL */
1788   value = tree_cons (NULL_TREE, null_pointer_node, value);
1789   
1790   /* Filename */
1791   filename = getpwd ();
1792   filename = (filename && da_file_name[0] != '/'
1793               ? concat (filename, "/", da_file_name, NULL)
1794               : da_file_name);
1795   filename_len = strlen (filename);
1796   filename_string = build_string (filename_len + 1, filename);
1797   if (filename != da_file_name)
1798     free (filename);
1799   TREE_TYPE (filename_string) =
1800           build_array_type (char_type_node,
1801                             build_index_type (build_int_2 (filename_len, 0)));
1802   value = tree_cons (NULL_TREE,
1803                      build1 (ADDR_EXPR,
1804                              string_type,
1805                              filename_string),
1806                      value);
1807   
1808   /* Workspace */
1809   value = tree_cons (NULL_TREE,
1810                      convert (long_integer_type_node, integer_zero_node),
1811                      value);
1812       
1813   /* number of functions */
1814   n_functions = 0;
1815   for (item = functions_head; item != 0; item = item->next, n_functions++)
1816     continue;
1817   value = tree_cons (NULL_TREE,
1818                      convert (unsigned_type_node,
1819                               build_int_2 (n_functions, 0)),
1820                      value);
1821
1822   /* function_info table */
1823   function_info_fields = build_function_info_fields ();
1824   function_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1825   function_info_ptr_type =
1826           build_pointer_type (
1827                 build_qualified_type (function_info_type,
1828                                       TYPE_QUAL_CONST));
1829   functions = NULL_TREE;
1830   for (item = functions_head; item != 0; item = item->next)
1831     {
1832       tree function_info_value = build_function_info_value (item);
1833       set_purpose (function_info_value, function_info_fields);
1834       functions = tree_cons (NULL_TREE,
1835                              build (CONSTRUCTOR,
1836                                     function_info_type,
1837                                     NULL_TREE,
1838                                     nreverse (function_info_value)),
1839                              functions);
1840     }
1841   finish_builtin_struct (function_info_type, "__function_info",
1842                          function_info_fields, NULL_TREE);
1843
1844   /* Create constructor for array.  */
1845   if (n_functions)
1846     {
1847       tree array_type;
1848
1849       array_type = build_array_type (
1850                         function_info_type,
1851                         build_index_type (build_int_2 (n_functions - 1, 0)));
1852       functions = build (CONSTRUCTOR,
1853                          array_type,
1854                          NULL_TREE,
1855                          nreverse (functions));
1856       functions = build1 (ADDR_EXPR,
1857                           function_info_ptr_type,
1858                           functions);
1859     }
1860   else
1861     functions = null_pointer_node;
1862
1863   value = tree_cons (NULL_TREE, functions, value);
1864
1865   /* n_counter_sections  */
1866   value = tree_cons (NULL_TREE,
1867                      convert (unsigned_type_node,
1868                               build_int_2 (profile_info.n_sections, 0)),
1869                      value);
1870   
1871   /* counter sections */
1872   counter_section_data_fields = build_counter_section_data_fields ();
1873   counter_section_data_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1874   counter_sections = NULL_TREE;
1875   for (i = 0; i < profile_info.n_sections; i++)
1876     {
1877       tree counter_sections_value =
1878               build_counter_section_data_value (
1879                 profile_info.section_info[i].tag,
1880                 profile_info.section_info[i].n_counters);
1881       set_purpose (counter_sections_value, counter_section_data_fields);
1882       counter_sections = tree_cons (NULL_TREE,
1883                                     build (CONSTRUCTOR,
1884                                            counter_section_data_type,
1885                                            NULL_TREE,
1886                                            nreverse (counter_sections_value)),
1887                                     counter_sections);
1888     }
1889   finish_builtin_struct (counter_section_data_type, "__counter_section_data",
1890                          counter_section_data_fields, NULL_TREE);
1891   counter_section_data_ptr_type =
1892           build_pointer_type
1893                 (build_qualified_type (counter_section_data_type,
1894                                        TYPE_QUAL_CONST));
1895
1896   if (profile_info.n_sections)
1897     {
1898       counter_sections =
1899               build (CONSTRUCTOR,
1900                      build_array_type (
1901                                        counter_section_data_type,
1902                                        build_index_type (build_int_2 (profile_info.n_sections - 1, 0))),
1903                      NULL_TREE,
1904                      nreverse (counter_sections));
1905       counter_sections = build1 (ADDR_EXPR,
1906                                  counter_section_data_ptr_type,
1907                                  counter_sections);
1908     }
1909   else
1910     counter_sections = null_pointer_node;
1911   value = tree_cons (NULL_TREE, counter_sections, value);
1912
1913   return value;
1914 }
1915
1916 /* Write out the structure which libgcc uses to locate all the arc
1917    counters.  The structures used here must match those defined in
1918    gcov-io.h.  Write out the constructor to call __gcov_init.  */
1919
1920 void
1921 create_profiler ()
1922 {
1923   tree gcov_info_fields, gcov_info_type, gcov_info_value, gcov_info;
1924   char name[20];
1925   char *ctor_name;
1926   tree ctor;
1927   rtx gcov_info_address;
1928   int save_flag_inline_functions = flag_inline_functions;
1929   unsigned i;
1930
1931   for (i = 0; i < profile_info.n_sections; i++)
1932     if (profile_info.section_info[i].n_counters_now)
1933       break;
1934   if (i == profile_info.n_sections)
1935     return;
1936   
1937   gcov_info_type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1938   gcov_info_fields = build_gcov_info_fields (gcov_info_type);
1939   gcov_info_value = build_gcov_info_value ();
1940   set_purpose (gcov_info_value, gcov_info_fields);
1941   finish_builtin_struct (gcov_info_type, "__gcov_info",
1942                          gcov_info_fields, NULL_TREE);
1943
1944   gcov_info = build (VAR_DECL, gcov_info_type, NULL_TREE, NULL_TREE);
1945   DECL_INITIAL (gcov_info) =
1946           build (CONSTRUCTOR, gcov_info_type, NULL_TREE,
1947                  nreverse (gcov_info_value));
1948
1949   TREE_STATIC (gcov_info) = 1;
1950   ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
1951   DECL_NAME (gcov_info) = get_identifier (name);
1952   
1953   /* Build structure.  */
1954   assemble_variable (gcov_info, 0, 0, 0);
1955
1956   /* Build the constructor function to invoke __gcov_init.  */
1957   ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
1958                       "_GCOV", NULL);
1959   ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
1960                      build_function_type (void_type_node, NULL_TREE));
1961   free (ctor_name);
1962   DECL_EXTERNAL (ctor) = 0;
1963
1964   /* It can be a static function as long as collect2 does not have
1965      to scan the object file to find its ctor/dtor routine.  */
1966   TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
1967   TREE_USED (ctor) = 1;
1968   DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1969
1970   ctor = (*lang_hooks.decls.pushdecl) (ctor);
1971   rest_of_decl_compilation (ctor, 0, 1, 0);
1972   announce_function (ctor);
1973   current_function_decl = ctor;
1974   DECL_INITIAL (ctor) = error_mark_node;
1975   make_decl_rtl (ctor, NULL);
1976   init_function_start (ctor, input_filename, lineno);
1977   (*lang_hooks.decls.pushlevel) (0);
1978   expand_function_start (ctor, 0);
1979   cfun->arc_profile = 0;
1980
1981   /* Actually generate the code to call __gcov_init.  */
1982   gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0));
1983   emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1,
1984                      gcov_info_address, Pmode);
1985
1986   expand_function_end (input_filename, lineno, 0);
1987   (*lang_hooks.decls.poplevel) (1, 0, 1);
1988
1989   /* Since ctor isn't in the list of globals, it would never be emitted
1990      when it's considered to be 'safe' for inlining, so turn off
1991      flag_inline_functions.  */
1992   flag_inline_functions = 0;
1993
1994   rest_of_compilation (ctor);
1995
1996   /* Reset flag_inline_functions to its original value.  */
1997   flag_inline_functions = save_flag_inline_functions;
1998
1999   if (! quiet_flag)
2000     fflush (asm_out_file);
2001   current_function_decl = NULL_TREE;
2002
2003   if (targetm.have_ctors_dtors)
2004     (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
2005                                      DEFAULT_INIT_PRIORITY);
2006 }
2007 \f
2008 /* Output instructions as RTL to increment the edge execution count.  */
2009
2010 static rtx
2011 gen_edge_profiler (edgeno)
2012      int edgeno;
2013 {
2014   enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
2015   rtx mem_ref, tmp;
2016   rtx sequence;
2017
2018   start_sequence ();
2019
2020   tmp = force_reg (Pmode, profiler_label);
2021   tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
2022   mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
2023
2024   set_mem_alias_set (mem_ref, new_alias_set ());
2025
2026   tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
2027                              mem_ref, 0, OPTAB_WIDEN);
2028
2029   if (tmp != mem_ref)
2030     emit_move_insn (copy_rtx (mem_ref), tmp);
2031
2032   sequence = get_insns ();
2033   end_sequence ();
2034   return sequence;
2035 }
2036
2037 #include "gt-profile.h"