OSDN Git Service

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