OSDN Git Service

f5ee9f318254f3e1bfcd66a5d8fb43113e9bcf84
[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, 2002, 2003  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 "flags.h"
57 #include "output.h"
58 #include "regs.h"
59 #include "expr.h"
60 #include "function.h"
61 #include "toplev.h"
62 #include "coverage.h"
63
64 /* Additional information about the edges we need.  */
65 struct edge_info {
66   unsigned int count_valid : 1;
67   
68   /* Is on the spanning tree.  */
69   unsigned int on_tree : 1;
70   
71   /* Pretend this edge does not exist (it is abnormal and we've
72      inserted a fake to compensate).  */
73   unsigned int ignore : 1;
74 };
75
76 struct bb_info {
77   unsigned int count_valid : 1;
78
79   /* Number of successor and predecessor edges.  */
80   gcov_type succ_count;
81   gcov_type pred_count;
82 };
83
84 #define EDGE_INFO(e)  ((struct edge_info *) (e)->aux)
85 #define BB_INFO(b)  ((struct bb_info *) (b)->aux)
86
87 /* Keep all basic block indexes nonnegative in the gcov output.  Index 0
88    is used for entry block, last block exit block.  */
89 #define BB_TO_GCOV_INDEX(bb)  ((bb) == ENTRY_BLOCK_PTR ? 0              \
90                                : ((bb) == EXIT_BLOCK_PTR                \
91                                   ? last_basic_block + 1 : (bb)->index + 1))
92
93 /* Counter summary from the last set of coverage counts read. */
94
95 const struct gcov_ctr_summary *profile_info;
96
97 /* Collect statistics on the performance of this pass for the entire source
98    file.  */
99
100 static int total_num_blocks;
101 static int total_num_edges;
102 static int total_num_edges_ignored;
103 static int total_num_edges_instrumented;
104 static int total_num_blocks_created;
105 static int total_num_passes;
106 static int total_num_times_called;
107 static int total_hist_br_prob[20];
108 static int total_num_never_executed;
109 static int total_num_branches;
110
111 /* Forward declarations.  */
112 static void find_spanning_tree PARAMS ((struct edge_list *));
113 static rtx gen_edge_profiler PARAMS ((int));
114 static void instrument_edges PARAMS ((struct edge_list *));
115 static void compute_branch_probabilities PARAMS ((void));
116 static gcov_type * get_exec_counts PARAMS ((void));
117 static basic_block find_group PARAMS ((basic_block));
118 static void union_groups PARAMS ((basic_block, basic_block));
119
120 \f
121 /* Add edge instrumentation code to the entire insn chain.
122
123    F is the first insn of the chain.
124    NUM_BLOCKS is the number of basic blocks found in F.  */
125
126 static void
127 instrument_edges (el)
128      struct edge_list *el;
129 {
130   int num_instr_edges = 0;
131   int num_edges = NUM_EDGES (el);
132   basic_block bb;
133   remove_fake_edges ();
134
135   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
136     {
137       edge e = bb->succ;
138       while (e)
139         {
140           struct edge_info *inf = EDGE_INFO (e);
141           if (!inf->ignore && !inf->on_tree)
142             {
143               if (e->flags & EDGE_ABNORMAL)
144                 abort ();
145               if (rtl_dump_file)
146                 fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
147                          e->src->index, e->dest->index,
148                          EDGE_CRITICAL_P (e) ? " (and split)" : "");
149               insert_insn_on_edge (
150                          gen_edge_profiler (num_instr_edges++), e);
151               rebuild_jump_labels (e->insns);
152             }
153           e = e->succ_next;
154         }
155     }
156
157   total_num_blocks_created += num_edges;
158   if (rtl_dump_file)
159     fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
160 }
161 \f
162
163 /* Computes hybrid profile for all matching entries in da_file.
164    Sets max_counter_in_program as a side effect.  */
165
166 static gcov_type *
167 get_exec_counts ()
168 {
169   unsigned num_edges = 0;
170   basic_block bb;
171   gcov_type *counts;
172   
173   /* Count the edges to be (possibly) instrumented.  */
174   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
175     {
176       edge e;
177       for (e = bb->succ; e; e = e->succ_next)
178         if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
179           num_edges++;
180     }
181
182   counts = get_coverage_counts (GCOV_COUNTER_ARCS, num_edges, &profile_info);
183   if (!counts)
184     return NULL;
185
186   if (rtl_dump_file && profile_info)
187     fprintf(rtl_dump_file, "Merged %u profiles with maximal count %u.\n",
188             profile_info->runs, (unsigned) profile_info->sum_max);
189
190   return counts;
191 }
192 \f
193
194 /* Compute the branch probabilities for the various branches.
195    Annotate them accordingly.  */
196
197 static void
198 compute_branch_probabilities ()
199 {
200   basic_block bb;
201   int i;
202   int num_edges = 0;
203   int changes;
204   int passes;
205   int hist_br_prob[20];
206   int num_never_executed;
207   int num_branches;
208   gcov_type *exec_counts = get_exec_counts ();
209   int exec_counts_pos = 0;
210
211   /* Attach extra info block to each bb.  */
212
213   alloc_aux_for_blocks (sizeof (struct bb_info));
214   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
215     {
216       edge e;
217
218       for (e = bb->succ; e; e = e->succ_next)
219         if (!EDGE_INFO (e)->ignore)
220           BB_INFO (bb)->succ_count++;
221       for (e = bb->pred; e; e = e->pred_next)
222         if (!EDGE_INFO (e)->ignore)
223           BB_INFO (bb)->pred_count++;
224     }
225
226   /* Avoid predicting entry on exit nodes.  */
227   BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
228   BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
229
230   /* For each edge not on the spanning tree, set its execution count from
231      the .da file.  */
232
233   /* The first count in the .da file is the number of times that the function
234      was entered.  This is the exec_count for block zero.  */
235
236   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
237     {
238       edge e;
239       for (e = bb->succ; e; e = e->succ_next)
240         if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
241           {
242             num_edges++;
243             if (exec_counts)
244               {
245                 e->count = exec_counts[exec_counts_pos++];
246               }
247             else
248               e->count = 0;
249
250             EDGE_INFO (e)->count_valid = 1;
251             BB_INFO (bb)->succ_count--;
252             BB_INFO (e->dest)->pred_count--;
253             if (rtl_dump_file)
254               {
255                 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
256                          bb->index, e->dest->index);
257                 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
258                          (HOST_WIDEST_INT) e->count);
259               }
260           }
261     }
262
263   if (rtl_dump_file)
264     fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
265
266   /* For every block in the file,
267      - if every exit/entrance edge has a known count, then set the block count
268      - if the block count is known, and every exit/entrance edge but one has
269      a known execution count, then set the count of the remaining edge
270
271      As edge counts are set, decrement the succ/pred count, but don't delete
272      the edge, that way we can easily tell when all edges are known, or only
273      one edge is unknown.  */
274
275   /* The order that the basic blocks are iterated through is important.
276      Since the code that finds spanning trees starts with block 0, low numbered
277      edges are put on the spanning tree in preference to high numbered edges.
278      Hence, most instrumented edges are at the end.  Graph solving works much
279      faster if we propagate numbers from the end to the start.
280
281      This takes an average of slightly more than 3 passes.  */
282
283   changes = 1;
284   passes = 0;
285   while (changes)
286     {
287       passes++;
288       changes = 0;
289       FOR_BB_BETWEEN (bb, EXIT_BLOCK_PTR, NULL, prev_bb)
290         {
291           struct bb_info *bi = BB_INFO (bb);
292           if (! bi->count_valid)
293             {
294               if (bi->succ_count == 0)
295                 {
296                   edge e;
297                   gcov_type total = 0;
298
299                   for (e = bb->succ; e; e = e->succ_next)
300                     total += e->count;
301                   bb->count = total;
302                   bi->count_valid = 1;
303                   changes = 1;
304                 }
305               else if (bi->pred_count == 0)
306                 {
307                   edge e;
308                   gcov_type total = 0;
309
310                   for (e = bb->pred; e; e = e->pred_next)
311                     total += e->count;
312                   bb->count = total;
313                   bi->count_valid = 1;
314                   changes = 1;
315                 }
316             }
317           if (bi->count_valid)
318             {
319               if (bi->succ_count == 1)
320                 {
321                   edge e;
322                   gcov_type total = 0;
323
324                   /* One of the counts will be invalid, but it is zero,
325                      so adding it in also doesn't hurt.  */
326                   for (e = bb->succ; e; e = e->succ_next)
327                     total += e->count;
328
329                   /* Seedgeh for the invalid edge, and set its count.  */
330                   for (e = bb->succ; e; e = e->succ_next)
331                     if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
332                       break;
333
334                   /* Calculate count for remaining edge by conservation.  */
335                   total = bb->count - total;
336
337                   if (! e)
338                     abort ();
339                   EDGE_INFO (e)->count_valid = 1;
340                   e->count = total;
341                   bi->succ_count--;
342
343                   BB_INFO (e->dest)->pred_count--;
344                   changes = 1;
345                 }
346               if (bi->pred_count == 1)
347                 {
348                   edge e;
349                   gcov_type total = 0;
350
351                   /* One of the counts will be invalid, but it is zero,
352                      so adding it in also doesn't hurt.  */
353                   for (e = bb->pred; e; e = e->pred_next)
354                     total += e->count;
355
356                   /* Seedgeh for the invalid edge, and set its count.  */
357                   for (e = bb->pred; e; e = e->pred_next)
358                     if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
359                       break;
360
361                   /* Calculate count for remaining edge by conservation.  */
362                   total = bb->count - total + e->count;
363
364                   if (! e)
365                     abort ();
366                   EDGE_INFO (e)->count_valid = 1;
367                   e->count = total;
368                   bi->pred_count--;
369
370                   BB_INFO (e->src)->succ_count--;
371                   changes = 1;
372                 }
373             }
374         }
375     }
376   if (rtl_dump_file)
377     dump_flow_info (rtl_dump_file);
378
379   total_num_passes += passes;
380   if (rtl_dump_file)
381     fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
382
383   /* If the graph has been correctly solved, every block will have a
384      succ and pred count of zero.  */
385   FOR_EACH_BB (bb)
386     {
387       if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
388         abort ();
389     }
390
391   /* For every edge, calculate its branch probability and add a reg_note
392      to the branch insn to indicate this.  */
393
394   for (i = 0; i < 20; i++)
395     hist_br_prob[i] = 0;
396   num_never_executed = 0;
397   num_branches = 0;
398
399   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
400     {
401       edge e;
402       rtx note;
403
404       if (bb->count < 0)
405         {
406           error ("corrupted profile info: number of iterations for basic block %d thought to be %i",
407                  bb->index, (int)bb->count);
408           bb->count = 0;
409         }
410       for (e = bb->succ; e; e = e->succ_next)
411         {
412           /* Function may return twice in the cased the called fucntion is
413              setjmp or calls fork, but we can't represent this by extra
414              edge from the entry, since extra edge from the exit is
415              already present.  We get negative frequency from the entry
416              point.  */
417           if ((e->count < 0
418                && e->dest == EXIT_BLOCK_PTR)
419               || (e->count > bb->count
420                   && e->dest != EXIT_BLOCK_PTR))
421             {
422               rtx insn = bb->end;
423
424               while (GET_CODE (insn) != CALL_INSN
425                      && insn != bb->head
426                      && keep_with_call_p (insn))
427                 insn = PREV_INSN (insn);
428               if (GET_CODE (insn) == CALL_INSN)
429                 e->count = e->count < 0 ? 0 : bb->count;
430             }
431           if (e->count < 0 || e->count > bb->count)
432             {
433               error ("corrupted profile info: number of executions for edge %d-%d thought to be %i",
434                      e->src->index, e->dest->index,
435                      (int)e->count);
436               e->count = bb->count / 2;
437             }
438         }
439       if (bb->count)
440         {
441           for (e = bb->succ; e; e = e->succ_next)
442             e->probability = (e->count * REG_BR_PROB_BASE + bb->count / 2) / bb->count;
443           if (bb->index >= 0
444               && any_condjump_p (bb->end)
445               && bb->succ->succ_next)
446             {
447               int prob;
448               edge e;
449               int index;
450
451               /* Find the branch edge.  It is possible that we do have fake
452                  edges here.  */
453               for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
454                    e = e->succ_next)
455                 continue; /* Loop body has been intentionally left blank.  */
456
457               prob = e->probability;
458               index = prob * 20 / REG_BR_PROB_BASE;
459
460               if (index == 20)
461                 index = 19;
462               hist_br_prob[index]++;
463
464               note = find_reg_note (bb->end, REG_BR_PROB, 0);
465               /* There may be already note put by some other pass, such
466                  as builtin_expect expander.  */
467               if (note)
468                 XEXP (note, 0) = GEN_INT (prob);
469               else
470                 REG_NOTES (bb->end)
471                   = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
472                                        REG_NOTES (bb->end));
473               num_branches++;
474             }
475         }
476       /* Otherwise distribute the probabilities evenly so we get sane
477          sum.  Use simple heuristics that if there are normal edges,
478          give all abnormals frequency of 0, otherwise distribute the
479          frequency over abnormals (this is the case of noreturn
480          calls).  */
481       else
482         {
483           int total = 0;
484
485           for (e = bb->succ; e; e = e->succ_next)
486             if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
487               total ++;
488           if (total)
489             {
490               for (e = bb->succ; e; e = e->succ_next)
491                 if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
492                   e->probability = REG_BR_PROB_BASE / total;
493                 else
494                   e->probability = 0;
495             }
496           else
497             {
498               for (e = bb->succ; e; e = e->succ_next)
499                 total ++;
500               for (e = bb->succ; e; e = e->succ_next)
501                 e->probability = REG_BR_PROB_BASE / total;
502             }
503           if (bb->index >= 0
504               && any_condjump_p (bb->end)
505               && bb->succ->succ_next)
506             num_branches++, num_never_executed;
507         }
508     }
509
510   if (rtl_dump_file)
511     {
512       fprintf (rtl_dump_file, "%d branches\n", num_branches);
513       fprintf (rtl_dump_file, "%d branches never executed\n",
514                num_never_executed);
515       if (num_branches)
516         for (i = 0; i < 10; i++)
517           fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
518                    (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
519                    5 * i, 5 * i + 5);
520
521       total_num_branches += num_branches;
522       total_num_never_executed += num_never_executed;
523       for (i = 0; i < 20; i++)
524         total_hist_br_prob[i] += hist_br_prob[i];
525
526       fputc ('\n', rtl_dump_file);
527       fputc ('\n', rtl_dump_file);
528     }
529
530   free_aux_for_blocks ();
531 }
532
533 /* Instrument and/or analyze program behavior based on program flow graph.
534    In either case, this function builds a flow graph for the function being
535    compiled.  The flow graph is stored in BB_GRAPH.
536
537    When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
538    the flow graph that are needed to reconstruct the dynamic behavior of the
539    flow graph.
540
541    When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
542    information from a data file containing edge count information from previous
543    executions of the function being compiled.  In this case, the flow graph is
544    annotated with actual execution counts, which are later propagated into the
545    rtl for optimization purposes.
546
547    Main entry point of this file.  */
548
549 void
550 branch_prob ()
551 {
552   basic_block bb;
553   unsigned i;
554   unsigned num_edges, ignored_edges;
555   struct edge_list *el;
556
557   total_num_times_called++;
558
559   flow_call_edges_add (NULL);
560   add_noreturn_fake_exit_edges ();
561
562   /* We can't handle cyclic regions constructed using abnormal edges.
563      To avoid these we replace every source of abnormal edge by a fake
564      edge from entry node and every destination by fake edge to exit.
565      This keeps graph acyclic and our calculation exact for all normal
566      edges except for exit and entrance ones.
567
568      We also add fake exit edges for each call and asm statement in the
569      basic, since it may not return.  */
570
571   FOR_EACH_BB (bb)
572     {
573       int need_exit_edge = 0, need_entry_edge = 0;
574       int have_exit_edge = 0, have_entry_edge = 0;
575       edge e;
576
577       /* Functions returning multiple times are not handled by extra edges.
578          Instead we simply allow negative counts on edges from exit to the
579          block past call and corresponding probabilities.  We can't go
580          with the extra edges because that would result in flowgraph that
581          needs to have fake edges outside the spanning tree.  */
582
583       for (e = bb->succ; e; e = e->succ_next)
584         {
585           if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
586                && e->dest != EXIT_BLOCK_PTR)
587             need_exit_edge = 1;
588           if (e->dest == EXIT_BLOCK_PTR)
589             have_exit_edge = 1;
590         }
591       for (e = bb->pred; e; e = e->pred_next)
592         {
593           if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
594                && e->src != ENTRY_BLOCK_PTR)
595             need_entry_edge = 1;
596           if (e->src == ENTRY_BLOCK_PTR)
597             have_entry_edge = 1;
598         }
599
600       if (need_exit_edge && !have_exit_edge)
601         {
602           if (rtl_dump_file)
603             fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
604                      bb->index);
605           make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
606         }
607       if (need_entry_edge && !have_entry_edge)
608         {
609           if (rtl_dump_file)
610             fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
611                      bb->index);
612           make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
613         }
614     }
615
616   el = create_edge_list ();
617   num_edges = NUM_EDGES (el);
618   alloc_aux_for_edges (sizeof (struct edge_info));
619
620   /* The basic blocks are expected to be numbered sequentially.  */
621   compact_blocks ();
622
623   ignored_edges = 0;
624   for (i = 0 ; i < num_edges ; i++)
625     {
626       edge e = INDEX_EDGE (el, i);
627       e->count = 0;
628
629       /* Mark edges we've replaced by fake edges above as ignored.  */
630       if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
631           && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
632         {
633           EDGE_INFO (e)->ignore = 1;
634           ignored_edges++;
635         }
636     }
637
638 #ifdef ENABLE_CHECKING
639   verify_flow_info ();
640 #endif
641
642   /* Create spanning tree from basic block graph, mark each edge that is
643      on the spanning tree.  We insert as many abnormal and critical edges
644      as possible to minimize number of edge splits necessary.  */
645
646   find_spanning_tree (el);
647
648   /* Fake edges that are not on the tree will not be instrumented, so
649      mark them ignored.  */
650   for (i = 0; i < num_edges; i++)
651     {
652       edge e = INDEX_EDGE (el, i);
653       struct edge_info *inf = EDGE_INFO (e);
654       if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
655         {
656           inf->ignore = 1;
657           ignored_edges++;
658         }
659     }
660
661   total_num_blocks += n_basic_blocks + 2;
662   if (rtl_dump_file)
663     fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
664
665   total_num_edges += num_edges;
666   if (rtl_dump_file)
667     fprintf (rtl_dump_file, "%d edges\n", num_edges);
668
669   total_num_edges_ignored += ignored_edges;
670   if (rtl_dump_file)
671     fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
672
673   /* Write the data from which gcov can reconstruct the basic block
674      graph.  */
675
676   /* Basic block flags */
677   if (coverage_begin_output ())
678     {
679       gcov_position_t offset;
680       
681       offset = gcov_write_tag (GCOV_TAG_BLOCKS);
682       for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++)
683         gcov_write_unsigned (0);
684       gcov_write_length (offset);
685     }
686
687   /* Arcs */
688   if (coverage_begin_output ())
689     {
690       gcov_position_t offset;
691
692       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
693         {
694           edge e;
695
696           offset = gcov_write_tag (GCOV_TAG_ARCS);
697           gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
698           
699           for (e = bb->succ; e; e = e->succ_next)
700             {
701               struct edge_info *i = EDGE_INFO (e);
702               if (!i->ignore)
703                 {
704                   unsigned flag_bits = 0;
705                   
706                   if (i->on_tree)
707                     flag_bits |= GCOV_ARC_ON_TREE;
708                   if (e->flags & EDGE_FAKE)
709                     flag_bits |= GCOV_ARC_FAKE;
710                   if (e->flags & EDGE_FALLTHRU)
711                     flag_bits |= GCOV_ARC_FALLTHROUGH;
712
713                   gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest));
714                   gcov_write_unsigned (flag_bits);
715                 }
716             }
717
718           gcov_write_length (offset);
719         }
720     }
721   
722   /* Line numbers. */
723   if (coverage_begin_output ())
724     {
725       char const *prev_file_name = NULL;
726       gcov_position_t offset;
727       
728       FOR_EACH_BB (bb)
729         {
730           rtx insn = bb->head;
731           int ignore_next_note = 0;
732           
733           offset = 0;
734           
735           /* We are looking for line number notes.  Search backward
736              before basic block to find correct ones.  */
737           insn = prev_nonnote_insn (insn);
738           if (!insn)
739             insn = get_insns ();
740           else
741             insn = NEXT_INSN (insn);
742           
743           while (insn != bb->end)
744             {
745               if (GET_CODE (insn) == NOTE)
746                 {
747                   /* Must ignore the line number notes that
748                      immediately follow the end of an inline function
749                      to avoid counting it twice.  There is a note
750                      before the call, and one after the call.  */
751                   if (NOTE_LINE_NUMBER (insn)
752                       == NOTE_INSN_REPEATED_LINE_NUMBER)
753                     ignore_next_note = 1;
754                   else if (NOTE_LINE_NUMBER (insn) <= 0)
755                     /*NOP*/;
756                   else if (ignore_next_note)
757                     ignore_next_note = 0;
758                   else
759                     {
760                       if (!offset)
761                         {
762                           offset = gcov_write_tag (GCOV_TAG_LINES);
763                           gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
764                         }
765                       
766                       /* If this is a new source file, then output the
767                          file's name to the .bb file.  */
768                       if (!prev_file_name
769                           || strcmp (NOTE_SOURCE_FILE (insn),
770                                      prev_file_name))
771                         {
772                           prev_file_name = NOTE_SOURCE_FILE (insn);
773                           gcov_write_unsigned (0);
774                           gcov_write_string (prev_file_name);
775                         }
776                       gcov_write_unsigned (NOTE_LINE_NUMBER (insn));
777                     }
778                 }
779               insn = NEXT_INSN (insn);
780             }
781           
782           if (offset)
783             {
784               /* A file of NULL indicates the end of run.  */
785               gcov_write_unsigned (0);
786               gcov_write_string (NULL);
787               gcov_write_length (offset);
788             }
789         }
790     }
791
792   if (flag_branch_probabilities)
793     compute_branch_probabilities ();
794
795   /* For each edge not on the spanning tree, add counting code as rtl.  */
796
797   if (cfun->arc_profile && profile_arc_flag)
798     {
799       instrument_edges (el);
800
801       /* Commit changes done by instrumentation.  */
802       commit_edge_insertions_watch_calls ();
803       allocate_reg_info (max_reg_num (), FALSE, FALSE);
804     }
805
806   remove_fake_edges ();
807   free_aux_for_edges ();
808   /* Re-merge split basic blocks and the mess introduced by
809      insert_insn_on_edge.  */
810   cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
811   if (rtl_dump_file)
812     dump_flow_info (rtl_dump_file);
813
814   free_edge_list (el);
815 }
816 \f
817 /* Union find algorithm implementation for the basic blocks using
818    aux fields.  */
819
820 static basic_block
821 find_group (bb)
822      basic_block bb;
823 {
824   basic_block group = bb, bb1;
825
826   while ((basic_block) group->aux != group)
827     group = (basic_block) group->aux;
828
829   /* Compress path.  */
830   while ((basic_block) bb->aux != group)
831     {
832       bb1 = (basic_block) bb->aux;
833       bb->aux = (void *) group;
834       bb = bb1;
835     }
836   return group;
837 }
838
839 static void
840 union_groups (bb1, bb2)
841      basic_block bb1, bb2;
842 {
843   basic_block bb1g = find_group (bb1);
844   basic_block bb2g = find_group (bb2);
845
846   /* ??? I don't have a place for the rank field.  OK.  Lets go w/o it,
847      this code is unlikely going to be performance problem anyway.  */
848   if (bb1g == bb2g)
849     abort ();
850
851   bb1g->aux = bb2g;
852 }
853 \f
854 /* This function searches all of the edges in the program flow graph, and puts
855    as many bad edges as possible onto the spanning tree.  Bad edges include
856    abnormals edges, which can't be instrumented at the moment.  Since it is
857    possible for fake edges to form a cycle, we will have to develop some
858    better way in the future.  Also put critical edges to the tree, since they
859    are more expensive to instrument.  */
860
861 static void
862 find_spanning_tree (el)
863      struct edge_list *el;
864 {
865   int i;
866   int num_edges = NUM_EDGES (el);
867   basic_block bb;
868
869   /* We use aux field for standard union-find algorithm.  */
870   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
871     bb->aux = bb;
872
873   /* Add fake edge exit to entry we can't instrument.  */
874   union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
875
876   /* First add all abnormal edges to the tree unless they form a cycle. Also
877      add all edges to EXIT_BLOCK_PTR to avoid inserting profiling code behind
878      setting return value from function.  */
879   for (i = 0; i < num_edges; i++)
880     {
881       edge e = INDEX_EDGE (el, i);
882       if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
883            || e->dest == EXIT_BLOCK_PTR
884            )
885           && !EDGE_INFO (e)->ignore
886           && (find_group (e->src) != find_group (e->dest)))
887         {
888           if (rtl_dump_file)
889             fprintf (rtl_dump_file, "Abnormal edge %d to %d put to tree\n",
890                      e->src->index, e->dest->index);
891           EDGE_INFO (e)->on_tree = 1;
892           union_groups (e->src, e->dest);
893         }
894     }
895
896   /* Now insert all critical edges to the tree unless they form a cycle.  */
897   for (i = 0; i < num_edges; i++)
898     {
899       edge e = INDEX_EDGE (el, i);
900       if ((EDGE_CRITICAL_P (e))
901           && !EDGE_INFO (e)->ignore
902           && (find_group (e->src) != find_group (e->dest)))
903         {
904           if (rtl_dump_file)
905             fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
906                      e->src->index, e->dest->index);
907           EDGE_INFO (e)->on_tree = 1;
908           union_groups (e->src, e->dest);
909         }
910     }
911
912   /* And now the rest.  */
913   for (i = 0; i < num_edges; i++)
914     {
915       edge e = INDEX_EDGE (el, i);
916       if (find_group (e->src) != find_group (e->dest)
917           && !EDGE_INFO (e)->ignore)
918         {
919           if (rtl_dump_file)
920             fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
921                      e->src->index, e->dest->index);
922           EDGE_INFO (e)->on_tree = 1;
923           union_groups (e->src, e->dest);
924         }
925     }
926
927   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
928     bb->aux = NULL;
929 }
930 \f
931 /* Perform file-level initialization for branch-prob processing.  */
932
933 void
934 init_branch_prob ()
935 {
936   int i;
937
938   total_num_blocks = 0;
939   total_num_edges = 0;
940   total_num_edges_ignored = 0;
941   total_num_edges_instrumented = 0;
942   total_num_blocks_created = 0;
943   total_num_passes = 0;
944   total_num_times_called = 0;
945   total_num_branches = 0;
946   total_num_never_executed = 0;
947   for (i = 0; i < 20; i++)
948     total_hist_br_prob[i] = 0;
949 }
950
951 /* Performs file-level cleanup after branch-prob processing
952    is completed.  */
953
954 void
955 end_branch_prob ()
956 {
957   if (rtl_dump_file)
958     {
959       fprintf (rtl_dump_file, "\n");
960       fprintf (rtl_dump_file, "Total number of blocks: %d\n",
961                total_num_blocks);
962       fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
963       fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
964                total_num_edges_ignored);
965       fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
966                total_num_edges_instrumented);
967       fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
968                total_num_blocks_created);
969       fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
970                total_num_passes);
971       if (total_num_times_called != 0)
972         fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
973                  (total_num_passes + (total_num_times_called  >> 1))
974                  / total_num_times_called);
975       fprintf (rtl_dump_file, "Total number of branches: %d\n",
976                total_num_branches);
977       fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
978                total_num_never_executed);
979       if (total_num_branches)
980         {
981           int i;
982
983           for (i = 0; i < 10; i++)
984             fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
985                      (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
986                      / total_num_branches, 5*i, 5*i+5);
987         }
988     }
989 }
990
991 \f
992 /* Output instructions as RTL to increment the edge execution count.  */
993
994 static rtx
995 gen_edge_profiler (edgeno)
996      int edgeno;
997 {
998   rtx ref = coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
999   rtx tmp;
1000   enum machine_mode mode = GET_MODE (ref);
1001   rtx sequence;
1002
1003   start_sequence ();
1004   ref = validize_mem (ref);
1005
1006   tmp = expand_simple_binop (mode, PLUS, ref, const1_rtx,
1007                              ref, 0, OPTAB_WIDEN);
1008
1009   if (tmp != ref)
1010     emit_move_insn (copy_rtx (ref), tmp);
1011
1012   sequence = get_insns ();
1013   end_sequence ();
1014   return sequence;
1015 }