OSDN Git Service

* ChangeLog.0, ChangeLog.1, ChangeLog.2, ChangeLog.3, ChangeLog.4,
[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 /* ??? Register allocation should use basic block execution counts to
26    give preference to the most commonly executed blocks.  */
27
28 /* ??? The .da files are not safe.  Changing the program after creating .da
29    files or using different options when compiling with -fbranch-probabilities
30    can result the arc data not matching the program.  Maybe add instrumented
31    arc count to .bbg file?  Maybe check whether PFG matches the .bbg file?  */
32
33 /* ??? Should calculate branch probabilities before instrumenting code, since
34    then we can use arc counts to help decide which arcs to instrument.  */
35
36 #include "config.h"
37 #include "system.h"
38 #include "rtl.h"
39 #include "tree.h"
40 #include "flags.h"
41 #include "insn-config.h"
42 #include "output.h"
43 #include "regs.h"
44 #include "expr.h"
45 #include "function.h"
46 #include "toplev.h"
47 #include "ggc.h"
48 #include "hard-reg-set.h"
49 #include "basic-block.h"
50 #include "gcov-io.h"
51 #include "target.h"
52
53 /* Additional information about the edges we need.  */
54 struct edge_info
55   {
56     unsigned int count_valid : 1;
57     unsigned int on_tree : 1;
58     unsigned int ignore : 1;
59   };
60 struct bb_info
61   {
62     unsigned int count_valid : 1;
63     gcov_type succ_count;
64     gcov_type pred_count;
65   };
66
67 #define EDGE_INFO(e)  ((struct edge_info *) (e)->aux)
68 #define BB_INFO(b)  ((struct bb_info *) (b)->aux)
69
70 /* Keep all basic block indexes nonnegative in the gcov output.  Index 0
71    is used for entry block, last block exit block.  */
72 #define GCOV_INDEX_TO_BB(i)  ((i) == 0 ? ENTRY_BLOCK_PTR                \
73                               : (((i) == n_basic_blocks + 1)            \
74                                  ? EXIT_BLOCK_PTR : BASIC_BLOCK ((i)-1)))
75 #define BB_TO_GCOV_INDEX(bb)  ((bb) == ENTRY_BLOCK_PTR ? 0              \
76                                : ((bb) == EXIT_BLOCK_PTR                \
77                                   ? n_basic_blocks + 1 : (bb)->index + 1))
78
79 /* Name and file pointer of the output file for the basic block graph.  */
80
81 static FILE *bbg_file;
82
83 /* Name and file pointer of the input file for the arc count data.  */
84
85 static FILE *da_file;
86
87 /* Pointer of the output file for the basic block/line number map.  */
88 static FILE *bb_file;
89
90 /* Last source file name written to bb_file.  */
91
92 static char *last_bb_file_name;
93
94 /* Used by final, for allocating the proper amount of storage for the
95    instrumented arc execution counts.  */
96
97 int count_instrumented_edges;
98
99 /* Collect statistics on the performance of this pass for the entire source
100    file.  */
101
102 static int total_num_blocks;
103 static int total_num_edges;
104 static int total_num_edges_ignored;
105 static int total_num_edges_instrumented;
106 static int total_num_blocks_created;
107 static int total_num_passes;
108 static int total_num_times_called;
109 static int total_hist_br_prob[20];
110 static int total_num_never_executed;
111 static int total_num_branches;
112
113 /* Forward declarations.  */
114 static void find_spanning_tree PARAMS ((struct edge_list *));
115 static void init_edge_profiler PARAMS ((void));
116 static rtx gen_edge_profiler PARAMS ((int));
117 static void instrument_edges PARAMS ((struct edge_list *));
118 static void output_gcov_string PARAMS ((const char *, long));
119 static void compute_branch_probabilities PARAMS ((void));
120 static basic_block find_group PARAMS ((basic_block));
121 static void union_groups PARAMS ((basic_block, basic_block));
122
123 /* If non-zero, we need to output a constructor to set up the
124    per-object-file data.  */
125 static int need_func_profiler = 0;
126 \f
127 /* Add edge instrumentation code to the entire insn chain.
128
129    F is the first insn of the chain.
130    NUM_BLOCKS is the number of basic blocks found in F.  */
131
132 static void
133 instrument_edges (el)
134      struct edge_list *el;
135 {
136   int i;
137   int num_instr_edges = 0;
138   int num_edges = NUM_EDGES (el);
139   remove_fake_edges ();
140
141   for (i = 0; i < n_basic_blocks + 2; i++)
142     {
143       basic_block bb = GCOV_INDEX_TO_BB (i);
144       edge e = bb->succ;
145       while (e)
146         {
147           struct edge_info *inf = EDGE_INFO (e);
148           if (!inf->ignore && !inf->on_tree)
149             {
150               if (e->flags & EDGE_ABNORMAL)
151                 abort ();
152               if (rtl_dump_file)
153                 fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
154                          e->src->index, e->dest->index,
155                          EDGE_CRITICAL_P (e) ? " (and split)" : "");
156               need_func_profiler = 1;
157               insert_insn_on_edge (
158                          gen_edge_profiler (total_num_edges_instrumented
159                                             + num_instr_edges++), e);
160             }
161           e = e->succ_next;
162         }
163     }
164
165   total_num_edges_instrumented += num_instr_edges;
166   count_instrumented_edges = total_num_edges_instrumented;
167
168   total_num_blocks_created += num_edges;
169   if (rtl_dump_file)
170     fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
171
172   commit_edge_insertions ();
173 }
174
175 /* Output STRING to bb_file, surrounded by DELIMITER.  */
176
177 static void
178 output_gcov_string (string, delimiter)
179      const char *string;
180      long delimiter;
181 {
182   long temp;
183
184   /* Write a delimiter to indicate that a file name follows.  */
185   __write_long (delimiter, bb_file, 4);
186
187   /* Write the string.  */
188   temp = strlen (string) + 1;
189   fwrite (string, temp, 1, bb_file);
190
191   /* Append a few zeros, to align the output to a 4 byte boundary.  */
192   temp = temp & 0x3;
193   if (temp)
194     {
195       char c[4];
196
197       c[0] = c[1] = c[2] = c[3] = 0;
198       fwrite (c, sizeof (char), 4 - temp, bb_file);
199     }
200
201   /* Store another delimiter in the .bb file, just to make it easy to find
202      the end of the file name.  */
203   __write_long (delimiter, bb_file, 4);
204 }
205 \f
206
207 /* Compute the branch probabilities for the various branches.
208    Annotate them accordingly.  */
209
210 static void
211 compute_branch_probabilities ()
212 {
213   int i;
214   int num_edges = 0;
215   int changes;
216   int passes;
217   int hist_br_prob[20];
218   int num_never_executed;
219   int num_branches;
220
221   /* Attach extra info block to each bb.  */
222
223   alloc_aux_for_blocks (sizeof (struct bb_info));
224   for (i = 0; i < n_basic_blocks + 2; i++)
225     {
226       basic_block bb = GCOV_INDEX_TO_BB (i);
227       edge e;
228
229       for (e = bb->succ; e; e = e->succ_next)
230         if (!EDGE_INFO (e)->ignore)
231           BB_INFO (bb)->succ_count++;
232       for (e = bb->pred; e; e = e->pred_next)
233         if (!EDGE_INFO (e)->ignore)
234           BB_INFO (bb)->pred_count++;
235     }
236
237   /* Avoid predicting entry on exit nodes.  */
238   BB_INFO (EXIT_BLOCK_PTR)->succ_count = 2;
239   BB_INFO (ENTRY_BLOCK_PTR)->pred_count = 2;
240
241   /* For each edge not on the spanning tree, set its execution count from
242      the .da file.  */
243
244   /* The first count in the .da file is the number of times that the function
245      was entered.  This is the exec_count for block zero.  */
246
247   for (i = 0; i < n_basic_blocks + 2; i++)
248     {
249       basic_block bb = GCOV_INDEX_TO_BB (i);
250       edge e;
251       for (e = bb->succ; e; e = e->succ_next)
252         if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
253           {
254             num_edges++;
255             if (da_file)
256               {
257                 gcov_type value;
258                 __read_gcov_type (&value, da_file, 8);
259                 e->count = value;
260               }
261             else
262               e->count = 0;
263             EDGE_INFO (e)->count_valid = 1;
264             BB_INFO (bb)->succ_count--;
265             BB_INFO (e->dest)->pred_count--;
266             if (rtl_dump_file)
267               {
268                 fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
269                          bb->index, e->dest->index);
270                 fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
271                          (HOST_WIDEST_INT) e->count);
272               }
273           }
274     }
275
276   if (rtl_dump_file)
277     fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
278
279   /* For every block in the file,
280      - if every exit/entrance edge has a known count, then set the block count
281      - if the block count is known, and every exit/entrance edge but one has
282      a known execution count, then set the count of the remaining edge
283
284      As edge counts are set, decrement the succ/pred count, but don't delete
285      the edge, that way we can easily tell when all edges are known, or only
286      one edge is unknown.  */
287
288   /* The order that the basic blocks are iterated through is important.
289      Since the code that finds spanning trees starts with block 0, low numbered
290      edges are put on the spanning tree in preference to high numbered edges.
291      Hence, most instrumented edges are at the end.  Graph solving works much
292      faster if we propagate numbers from the end to the start.
293
294      This takes an average of slightly more than 3 passes.  */
295
296   changes = 1;
297   passes = 0;
298   while (changes)
299     {
300       passes++;
301       changes = 0;
302       for (i = n_basic_blocks + 1; i >= 0; i--)
303         {
304           basic_block bb = GCOV_INDEX_TO_BB (i);
305           struct bb_info *bi = BB_INFO (bb);
306           if (! bi->count_valid)
307             {
308               if (bi->succ_count == 0)
309                 {
310                   edge e;
311                   gcov_type total = 0;
312
313                   for (e = bb->succ; e; e = e->succ_next)
314                     total += e->count;
315                   bb->count = total;
316                   bi->count_valid = 1;
317                   changes = 1;
318                 }
319               else if (bi->pred_count == 0)
320                 {
321                   edge e;
322                   gcov_type total = 0;
323
324                   for (e = bb->pred; e; e = e->pred_next)
325                     total += e->count;
326                   bb->count = total;
327                   bi->count_valid = 1;
328                   changes = 1;
329                 }
330             }
331           if (bi->count_valid)
332             {
333               if (bi->succ_count == 1)
334                 {
335                   edge e;
336                   gcov_type total = 0;
337
338                   /* One of the counts will be invalid, but it is zero,
339                      so adding it in also doesn't hurt.  */
340                   for (e = bb->succ; e; e = e->succ_next)
341                     total += e->count;
342
343                   /* Seedgeh for the invalid edge, and set its count.  */
344                   for (e = bb->succ; e; e = e->succ_next)
345                     if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
346                       break;
347
348                   /* Calculate count for remaining edge by conservation.  */
349                   total = bb->count - total;
350
351                   if (! e)
352                     abort ();
353                   EDGE_INFO (e)->count_valid = 1;
354                   e->count = total;
355                   bi->succ_count--;
356
357                   BB_INFO (e->dest)->pred_count--;
358                   changes = 1;
359                 }
360               if (bi->pred_count == 1)
361                 {
362                   edge e;
363                   gcov_type total = 0;
364
365                   /* One of the counts will be invalid, but it is zero,
366                      so adding it in also doesn't hurt.  */
367                   for (e = bb->pred; e; e = e->pred_next)
368                     total += e->count;
369
370                   /* Seedgeh for the invalid edge, and set its count.  */
371                   for (e = bb->pred; e; e = e->pred_next)
372                     if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
373                       break;
374
375                   /* Calculate count for remaining edge by conservation.  */
376                   total = bb->count - total + e->count;
377
378                   if (! e)
379                     abort ();
380                   EDGE_INFO (e)->count_valid = 1;
381                   e->count = total;
382                   bi->pred_count--;
383
384                   BB_INFO (e->src)->succ_count--;
385                   changes = 1;
386                 }
387             }
388         }
389     }
390   if (rtl_dump_file)
391     dump_flow_info (rtl_dump_file);
392
393   total_num_passes += passes;
394   if (rtl_dump_file)
395     fprintf (rtl_dump_file, "Graph solving took %d passes.\n\n", passes);
396
397   /* If the graph has been correctly solved, every block will have a
398      succ and pred count of zero.  */
399   for (i = 0; i < n_basic_blocks; i++)
400     {
401       basic_block bb = BASIC_BLOCK (i);
402       if (BB_INFO (bb)->succ_count || BB_INFO (bb)->pred_count)
403         abort ();
404     }
405
406   /* For every edge, calculate its branch probability and add a reg_note
407      to the branch insn to indicate this.  */
408
409   for (i = 0; i < 20; i++)
410     hist_br_prob[i] = 0;
411   num_never_executed = 0;
412   num_branches = 0;
413
414   for (i = 0; i < n_basic_blocks; i++)
415     {
416       basic_block bb = BASIC_BLOCK (i);
417       edge e;
418       gcov_type total;
419       rtx note;
420
421       total = bb->count;
422       if (total)
423         for (e = bb->succ; e; e = e->succ_next)
424           {
425               e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
426               if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
427                 {
428                   error ("Corrupted profile info: prob for %d-%d thought to be %d",
429                          e->src->index, e->dest->index, e->probability);
430                   e->probability = REG_BR_PROB_BASE / 2;
431                 }
432           }
433       if (any_condjump_p (bb->end)
434           && bb->succ->succ_next)
435         {
436           int prob;
437           edge e;
438
439           if (total == 0)
440             prob = -1;
441           else
442           if (total == -1)
443             num_never_executed++;
444           else
445             {
446               int index;
447
448               /* Find the branch edge.  It is possible that we do have fake
449                  edges here.  */
450               for (e = bb->succ; e->flags & (EDGE_FAKE | EDGE_FALLTHRU);
451                    e = e->succ_next)
452                 continue; /* Loop body has been intentionally left blank.  */
453
454               prob = e->probability;
455               index = prob * 20 / REG_BR_PROB_BASE;
456
457               if (index == 20)
458                 index = 19;
459               hist_br_prob[index]++;
460
461               note = find_reg_note (bb->end, REG_BR_PROB, 0);
462               /* There may be already note put by some other pass, such
463                  as builtin_expect expander.  */
464               if (note)
465                 XEXP (note, 0) = GEN_INT (prob);
466               else
467                 REG_NOTES (bb->end)
468                   = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
469                                        REG_NOTES (bb->end));
470             }
471           num_branches++;
472
473         }
474     }
475
476   if (rtl_dump_file)
477     {
478       fprintf (rtl_dump_file, "%d branches\n", num_branches);
479       fprintf (rtl_dump_file, "%d branches never executed\n",
480                num_never_executed);
481       if (num_branches)
482         for (i = 0; i < 10; i++)
483           fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
484                    (hist_br_prob[i] + hist_br_prob[19-i]) * 100 / num_branches,
485                    5 * i, 5 * i + 5);
486
487       total_num_branches += num_branches;
488       total_num_never_executed += num_never_executed;
489       for (i = 0; i < 20; i++)
490         total_hist_br_prob[i] += hist_br_prob[i];
491
492       fputc ('\n', rtl_dump_file);
493       fputc ('\n', rtl_dump_file);
494     }
495
496   free_aux_for_blocks ();
497 }
498
499 /* Instrument and/or analyze program behavior based on program flow graph.
500    In either case, this function builds a flow graph for the function being
501    compiled.  The flow graph is stored in BB_GRAPH.
502
503    When FLAG_PROFILE_ARCS is nonzero, this function instruments the edges in
504    the flow graph that are needed to reconstruct the dynamic behavior of the
505    flow graph.
506
507    When FLAG_BRANCH_PROBABILITIES is nonzero, this function reads auxiliary
508    information from a data file containing edge count information from previous
509    executions of the function being compiled.  In this case, the flow graph is
510    annotated with actual execution counts, which are later propagated into the
511    rtl for optimization purposes.
512
513    Main entry point of this file.  */
514
515 void
516 branch_prob ()
517 {
518   int i;
519   int num_edges, ignored_edges;
520   struct edge_list *el;
521
522   /* Start of a function.  */
523   if (flag_test_coverage)
524     output_gcov_string (current_function_name, (long) -2);
525
526   total_num_times_called++;
527
528   flow_call_edges_add (NULL);
529   add_noreturn_fake_exit_edges ();
530
531   /* We can't handle cyclic regions constructed using abnormal edges.
532      To avoid these we replace every source of abnormal edge by a fake
533      edge from entry node and every destination by fake edge to exit.
534      This keeps graph acyclic and our calculation exact for all normal
535      edges except for exit and entrance ones.
536
537      We also add fake exit edges for each call and asm statement in the
538      basic, since it may not return.  */
539
540   for (i = 0; i < n_basic_blocks ; i++)
541     {
542       int need_exit_edge = 0, need_entry_edge = 0;
543       int have_exit_edge = 0, have_entry_edge = 0;
544       basic_block bb = BASIC_BLOCK (i);
545       rtx insn;
546       edge e;
547
548       /* Add fake edges from entry block to the call insns that may return
549          twice.  The CFG is not quite correct then, as call insn plays more
550          role of CODE_LABEL, but for our purposes, everything should be OK,
551          as we never insert code to the beggining of basic block.  */
552       for (insn = bb->head; insn != NEXT_INSN (bb->end);
553            insn = NEXT_INSN (insn))
554         {
555           if (GET_CODE (insn) == CALL_INSN
556               && find_reg_note (insn, REG_SETJMP, NULL))
557             {
558               if (GET_CODE (bb->head) == CODE_LABEL
559                   || insn != NEXT_INSN (bb->head))
560                 {
561                   e = split_block (bb, PREV_INSN (insn));
562                   make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
563                   break;
564                 }
565               else
566                 {
567                   /* We should not get abort here, as call to setjmp should not
568                      be the very first instruction of function.  */
569                   if (!i)
570                     abort ();
571                   make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
572                 }
573             }
574         }
575
576       for (e = bb->succ; e; e = e->succ_next)
577         {
578           if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
579                && e->dest != EXIT_BLOCK_PTR)
580             need_exit_edge = 1;
581           if (e->dest == EXIT_BLOCK_PTR)
582             have_exit_edge = 1;
583         }
584       for (e = bb->pred; e; e = e->pred_next)
585         {
586           if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
587                && e->src != ENTRY_BLOCK_PTR)
588             need_entry_edge = 1;
589           if (e->src == ENTRY_BLOCK_PTR)
590             have_entry_edge = 1;
591         }
592
593       if (need_exit_edge && !have_exit_edge)
594         {
595           if (rtl_dump_file)
596             fprintf (rtl_dump_file, "Adding fake exit edge to bb %i\n",
597                      bb->index);
598           make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
599         }
600       if (need_entry_edge && !have_entry_edge)
601         {
602           if (rtl_dump_file)
603             fprintf (rtl_dump_file, "Adding fake entry edge to bb %i\n",
604                      bb->index);
605           make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
606         }
607     }
608
609   el = create_edge_list ();
610   num_edges = NUM_EDGES (el);
611   alloc_aux_for_edges (sizeof (struct edge_info));
612
613   ignored_edges = 0;
614   for (i = 0 ; i < num_edges ; i++)
615     {
616       edge e = INDEX_EDGE (el, i);
617       e->count = 0;
618
619       /* Mark edges we've replaced by fake edges above as ignored.  */
620       if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
621           && e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR)
622         {
623           EDGE_INFO (e)->ignore = 1;
624           ignored_edges++;
625         }
626     }
627
628 #ifdef ENABLE_CHECKING
629   verify_flow_info ();
630 #endif
631
632   /* Output line number information about each basic block for
633      GCOV utility.  */
634   if (flag_test_coverage)
635     {
636       int i = 0;
637       for (i = 0 ; i < n_basic_blocks; i++)
638         {
639           basic_block bb = BASIC_BLOCK (i);
640           rtx insn = bb->head;
641           static int ignore_next_note = 0;
642
643           /* We are looking for line number notes.  Search backward before
644              basic block to find correct ones.  */
645           insn = prev_nonnote_insn (insn);
646           if (!insn)
647             insn = get_insns ();
648           else
649             insn = NEXT_INSN (insn);
650
651           /* Output a zero to the .bb file to indicate that a new
652              block list is starting.  */
653           __write_long (0, bb_file, 4);
654
655           while (insn != bb->end)
656             {
657               if (GET_CODE (insn) == NOTE)
658                 {
659                   /* Must ignore the line number notes that immediately
660                      follow the end of an inline function to avoid counting
661                      it twice.  There is a note before the call, and one
662                      after the call.  */
663                   if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_REPEATED_LINE_NUMBER)
664                     ignore_next_note = 1;
665                   else if (NOTE_LINE_NUMBER (insn) > 0)
666                     {
667                       if (ignore_next_note)
668                         ignore_next_note = 0;
669                       else
670                         {
671                           /* If this is a new source file, then output the
672                              file's name to the .bb file.  */
673                           if (! last_bb_file_name
674                               || strcmp (NOTE_SOURCE_FILE (insn),
675                                          last_bb_file_name))
676                             {
677                               if (last_bb_file_name)
678                                 free (last_bb_file_name);
679                               last_bb_file_name
680                                 = xstrdup (NOTE_SOURCE_FILE (insn));
681                               output_gcov_string (NOTE_SOURCE_FILE (insn),
682                                                   (long)-1);
683                             }
684                           /* Output the line number to the .bb file.  Must be
685                              done after the output_bb_profile_data() call, and
686                              after the file name is written, to ensure that it
687                              is correctly handled by gcov.  */
688                           __write_long (NOTE_LINE_NUMBER (insn), bb_file, 4);
689                         }
690                     }
691                 }
692               insn = NEXT_INSN (insn);
693             }
694         }
695       __write_long (0, bb_file, 4);
696     }
697
698   /* Create spanning tree from basic block graph, mark each edge that is
699      on the spanning tree.  We insert as many abnormal and critical edges
700      as possible to minimize number of edge splits necessary.  */
701
702   find_spanning_tree (el);
703
704   /* Fake edges that are not on the tree will not be instrumented, so
705      mark them ignored.  */
706   for (i = 0; i < num_edges; i++)
707     {
708       edge e = INDEX_EDGE (el, i);
709       struct edge_info *inf = EDGE_INFO (e);
710       if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
711         {
712           inf->ignore = 1;
713           ignored_edges++;
714         }
715     }
716
717   total_num_blocks += n_basic_blocks + 2;
718   if (rtl_dump_file)
719     fprintf (rtl_dump_file, "%d basic blocks\n", n_basic_blocks);
720
721   total_num_edges += num_edges;
722   if (rtl_dump_file)
723     fprintf (rtl_dump_file, "%d edges\n", num_edges);
724
725   total_num_edges_ignored += ignored_edges;
726   if (rtl_dump_file)
727     fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
728
729   /* Create a .bbg file from which gcov can reconstruct the basic block
730      graph.  First output the number of basic blocks, and then for every
731      edge output the source and target basic block numbers.
732      NOTE: The format of this file must be compatible with gcov.  */
733
734   if (flag_test_coverage)
735     {
736       int flag_bits;
737
738       /* The plus 2 stands for entry and exit block.  */
739       __write_long (n_basic_blocks + 2, bbg_file, 4);
740       __write_long (num_edges - ignored_edges + 1, bbg_file, 4);
741
742       for (i = 0; i < n_basic_blocks + 1; i++)
743         {
744           basic_block bb = GCOV_INDEX_TO_BB (i);
745           edge e;
746           long count = 0;
747
748           for (e = bb->succ; e; e = e->succ_next)
749             if (!EDGE_INFO (e)->ignore)
750               count++;
751           __write_long (count, bbg_file, 4);
752
753           for (e = bb->succ; e; e = e->succ_next)
754             {
755               struct edge_info *i = EDGE_INFO (e);
756               if (!i->ignore)
757                 {
758                   flag_bits = 0;
759                   if (i->on_tree)
760                     flag_bits |= 0x1;
761                   if (e->flags & EDGE_FAKE)
762                     flag_bits |= 0x2;
763                   if (e->flags & EDGE_FALLTHRU)
764                     flag_bits |= 0x4;
765
766                   __write_long (BB_TO_GCOV_INDEX (e->dest), bbg_file, 4);
767                   __write_long (flag_bits, bbg_file, 4);
768                 }
769             }
770         }
771       /* Emit fake loopback edge for EXIT block to maitain compatibility with
772          old gcov format.  */
773       __write_long (1, bbg_file, 4);
774       __write_long (0, bbg_file, 4);
775       __write_long (0x1, bbg_file, 4);
776
777       /* Emit a -1 to separate the list of all edges from the list of
778          loop back edges that follows.  */
779       __write_long (-1, bbg_file, 4);
780     }
781
782   if (flag_branch_probabilities)
783     compute_branch_probabilities ();
784
785   /* For each edge not on the spanning tree, add counting code as rtl.  */
786
787   if (profile_arc_flag)
788     {
789       instrument_edges (el);
790       allocate_reg_info (max_reg_num (), FALSE, FALSE);
791     }
792
793   remove_fake_edges ();
794   /* Re-merge split basic blocks and the mess introduced by
795      insert_insn_on_edge.  */
796   cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
797   if (rtl_dump_file)
798     dump_flow_info (rtl_dump_file);
799
800   free_aux_for_edges ();
801   free_edge_list (el);
802 }
803 \f
804 /* Union find algorithm implementation for the basic blocks using
805    aux fields.  */
806
807 static basic_block
808 find_group (bb)
809      basic_block bb;
810 {
811   basic_block group = bb, bb1;
812
813   while ((basic_block) group->aux != group)
814     group = (basic_block) group->aux;
815
816   /* Compress path.  */
817   while ((basic_block) bb->aux != group)
818     {
819       bb1 = (basic_block) bb->aux;
820       bb->aux = (void *) group;
821       bb = bb1;
822     }
823   return group;
824 }
825
826 static void
827 union_groups (bb1, bb2)
828      basic_block bb1, bb2;
829 {
830   basic_block bb1g = find_group (bb1);
831   basic_block bb2g = find_group (bb2);
832
833   /* ??? I don't have a place for the rank field.  OK.  Lets go w/o it,
834      this code is unlikely going to be performance problem anyway.  */
835   if (bb1g == bb2g)
836     abort ();
837
838   bb1g->aux = bb2g;
839 }
840 \f
841 /* This function searches all of the edges in the program flow graph, and puts
842    as many bad edges as possible onto the spanning tree.  Bad edges include
843    abnormals edges, which can't be instrumented at the moment.  Since it is
844    possible for fake edges to form an cycle, we will have to develop some
845    better way in the future.  Also put critical edges to the tree, since they
846    are more expensive to instrument.  */
847
848 static void
849 find_spanning_tree (el)
850      struct edge_list *el;
851 {
852   int i;
853   int num_edges = NUM_EDGES (el);
854
855   /* We use aux field for standard union-find algorithm.  */
856   EXIT_BLOCK_PTR->aux = EXIT_BLOCK_PTR;
857   ENTRY_BLOCK_PTR->aux = ENTRY_BLOCK_PTR;
858   for (i = 0; i < n_basic_blocks; i++)
859     BASIC_BLOCK (i)->aux = BASIC_BLOCK (i);
860
861   /* Add fake edge exit to entry we can't instrument.  */
862   union_groups (EXIT_BLOCK_PTR, ENTRY_BLOCK_PTR);
863
864   /* First add all abnormal edges to the tree unless they form an cycle.  */
865   for (i = 0; i < num_edges; i++)
866     {
867       edge e = INDEX_EDGE (el, i);
868       if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
869           && !EDGE_INFO (e)->ignore
870           && (find_group (e->src) != find_group (e->dest)))
871         {
872           EDGE_INFO (e)->on_tree = 1;
873           union_groups (e->src, e->dest);
874         }
875     }
876
877   /* Now insert all critical edges to the tree unless they form an cycle.  */
878   for (i = 0; i < num_edges; i++)
879     {
880       edge e = INDEX_EDGE (el, i);
881       if ((EDGE_CRITICAL_P (e))
882           && !EDGE_INFO (e)->ignore
883           && (find_group (e->src) != find_group (e->dest)))
884         {
885           EDGE_INFO (e)->on_tree = 1;
886           union_groups (e->src, e->dest);
887         }
888     }
889
890   /* And now the rest.  */
891   for (i = 0; i < num_edges; i++)
892     {
893       edge e = INDEX_EDGE (el, i);
894       if (find_group (e->src) != find_group (e->dest)
895           && !EDGE_INFO (e)->ignore)
896         {
897           EDGE_INFO (e)->on_tree = 1;
898           union_groups (e->src, e->dest);
899         }
900     }
901
902   EXIT_BLOCK_PTR->aux = NULL;
903   ENTRY_BLOCK_PTR->aux = NULL;
904   for (i = 0; i < n_basic_blocks; i++)
905     BASIC_BLOCK (i)->aux = NULL;
906 }
907 \f
908 /* Perform file-level initialization for branch-prob processing.  */
909
910 void
911 init_branch_prob (filename)
912   const char *filename;
913 {
914   long len;
915   int i;
916
917   if (flag_test_coverage)
918     {
919       int len = strlen (filename);
920       char *data_file, *bbg_file_name;
921
922       /* Open an output file for the basic block/line number map.  */
923       data_file = (char *) alloca (len + 4);
924       strcpy (data_file, filename);
925       strip_off_ending (data_file, len);
926       strcat (data_file, ".bb");
927       if ((bb_file = fopen (data_file, "wb")) == 0)
928         fatal_io_error ("can't open %s", data_file);
929
930       /* Open an output file for the program flow graph.  */
931       bbg_file_name = (char *) alloca (len + 5);
932       strcpy (bbg_file_name, filename);
933       strip_off_ending (bbg_file_name, len);
934       strcat (bbg_file_name, ".bbg");
935       if ((bbg_file = fopen (bbg_file_name, "wb")) == 0)
936         fatal_io_error ("can't open %s", bbg_file_name);
937
938       /* Initialize to zero, to ensure that the first file name will be
939          written to the .bb file.  */
940       last_bb_file_name = 0;
941     }
942
943   if (flag_branch_probabilities)
944     {
945       char *da_file_name;
946
947       len = strlen (filename);
948       da_file_name = (char *) alloca (len + 4);
949       strcpy (da_file_name, filename);
950       strip_off_ending (da_file_name, len);
951       strcat (da_file_name, ".da");
952       if ((da_file = fopen (da_file_name, "rb")) == 0)
953         warning ("file %s not found, execution counts assumed to be zero.",
954                  da_file_name);
955
956       /* The first word in the .da file gives the number of instrumented
957          edges, which is not needed for our purposes.  */
958
959       if (da_file)
960         __read_long (&len, da_file, 8);
961     }
962
963   if (profile_arc_flag)
964     init_edge_profiler ();
965
966   total_num_blocks = 0;
967   total_num_edges = 0;
968   total_num_edges_ignored = 0;
969   total_num_edges_instrumented = 0;
970   total_num_blocks_created = 0;
971   total_num_passes = 0;
972   total_num_times_called = 0;
973   total_num_branches = 0;
974   total_num_never_executed = 0;
975   for (i = 0; i < 20; i++)
976     total_hist_br_prob[i] = 0;
977 }
978
979 /* Performs file-level cleanup after branch-prob processing
980    is completed.  */
981
982 void
983 end_branch_prob ()
984 {
985   if (flag_test_coverage)
986     {
987       fclose (bb_file);
988       fclose (bbg_file);
989     }
990
991   if (flag_branch_probabilities)
992     {
993       if (da_file)
994         {
995           long temp;
996           /* This seems slightly dangerous, as it presumes the EOF
997              flag will not be set until an attempt is made to read
998              past the end of the file.  */
999           if (feof (da_file))
1000             error (".da file contents exhausted too early");
1001           /* Should be at end of file now.  */
1002           if (__read_long (&temp, da_file, 8) == 0)
1003             error (".da file contents not exhausted");
1004           fclose (da_file);
1005         }
1006     }
1007
1008   if (rtl_dump_file)
1009     {
1010       fprintf (rtl_dump_file, "\n");
1011       fprintf (rtl_dump_file, "Total number of blocks: %d\n",
1012                total_num_blocks);
1013       fprintf (rtl_dump_file, "Total number of edges: %d\n", total_num_edges);
1014       fprintf (rtl_dump_file, "Total number of ignored edges: %d\n",
1015                total_num_edges_ignored);
1016       fprintf (rtl_dump_file, "Total number of instrumented edges: %d\n",
1017                total_num_edges_instrumented);
1018       fprintf (rtl_dump_file, "Total number of blocks created: %d\n",
1019                total_num_blocks_created);
1020       fprintf (rtl_dump_file, "Total number of graph solution passes: %d\n",
1021                total_num_passes);
1022       if (total_num_times_called != 0)
1023         fprintf (rtl_dump_file, "Average number of graph solution passes: %d\n",
1024                  (total_num_passes + (total_num_times_called  >> 1))
1025                  / total_num_times_called);
1026       fprintf (rtl_dump_file, "Total number of branches: %d\n",
1027                total_num_branches);
1028       fprintf (rtl_dump_file, "Total number of branches never executed: %d\n",
1029                total_num_never_executed);
1030       if (total_num_branches)
1031         {
1032           int i;
1033
1034           for (i = 0; i < 10; i++)
1035             fprintf (rtl_dump_file, "%d%% branches in range %d-%d%%\n",
1036                      (total_hist_br_prob[i] + total_hist_br_prob[19-i]) * 100
1037                      / total_num_branches, 5*i, 5*i+5);
1038         }
1039     }
1040 }
1041 \f
1042 /* The label used by the edge profiling code.  */
1043
1044 static rtx profiler_label;
1045
1046 /* Initialize the profiler_label.  */
1047
1048 static void
1049 init_edge_profiler ()
1050 {
1051   /* Generate and save a copy of this so it can be shared.  */
1052   char buf[20];
1053   ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
1054   profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1055   ggc_add_rtx_root (&profiler_label, 1);
1056 }
1057
1058 /* Output instructions as RTL to increment the edge execution count.  */
1059
1060 static rtx
1061 gen_edge_profiler (edgeno)
1062      int edgeno;
1063 {
1064   enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1065   rtx mem_ref, tmp;
1066   rtx sequence;
1067
1068   start_sequence ();
1069
1070   tmp = force_reg (Pmode, profiler_label);
1071   tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
1072   mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
1073
1074   tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
1075                              mem_ref, 0, OPTAB_WIDEN);
1076
1077   if (tmp != mem_ref)
1078     emit_move_insn (copy_rtx (mem_ref), tmp);
1079
1080   sequence = gen_sequence ();
1081   end_sequence ();
1082   return sequence;
1083 }
1084
1085 /* Output code for a constructor that will invoke __bb_init_func, if
1086    this has not already been done.  */
1087
1088 void
1089 output_func_start_profiler ()
1090 {
1091   tree fnname, fndecl;
1092   char *name;
1093   char buf[20];
1094   const char *cfnname;
1095   rtx table_address;
1096   enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
1097   int save_flag_inline_functions = flag_inline_functions;
1098   int save_flag_test_coverage = flag_test_coverage;
1099   int save_profile_arc_flag = profile_arc_flag;
1100   int save_flag_branch_probabilities = flag_branch_probabilities;
1101
1102   /* It's either already been output, or we don't need it because we're
1103      not doing profile-edges.  */
1104   if (! need_func_profiler)
1105     return;
1106
1107   need_func_profiler = 0;
1108
1109   /* Synthesize a constructor function to invoke __bb_init_func with a
1110      pointer to this object file's profile block.  */
1111
1112   /* Try and make a unique name given the "file function name".
1113
1114      And no, I don't like this either.  */
1115
1116   fnname = get_file_function_name ('I');
1117   cfnname = IDENTIFIER_POINTER (fnname);
1118   name = concat (cfnname, "GCOV", NULL);
1119   fnname = get_identifier (name);
1120   free (name);
1121
1122   fndecl = build_decl (FUNCTION_DECL, fnname,
1123                        build_function_type (void_type_node, NULL_TREE));
1124   DECL_EXTERNAL (fndecl) = 0;
1125
1126   /* It can be a static function as long as collect2 does not have
1127      to scan the object file to find its ctor/dtor routine.  */
1128   TREE_PUBLIC (fndecl) = ! targetm.have_ctors_dtors;
1129
1130   TREE_USED (fndecl) = 1;
1131
1132   DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1133
1134   fndecl = pushdecl (fndecl);
1135   rest_of_decl_compilation (fndecl, 0, 1, 0);
1136   announce_function (fndecl);
1137   current_function_decl = fndecl;
1138   DECL_INITIAL (fndecl) = error_mark_node;
1139   make_decl_rtl (fndecl, NULL);
1140   init_function_start (fndecl, input_filename, lineno);
1141   pushlevel (0);
1142   expand_function_start (fndecl, 0);
1143
1144   /* Actually generate the code to call __bb_init_func.  */
1145   ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 0);
1146   table_address = force_reg (Pmode,
1147                              gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
1148   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__bb_init_func"), 0,
1149                      mode, 1, table_address, Pmode);
1150
1151   expand_function_end (input_filename, lineno, 0);
1152   poplevel (1, 0, 1);
1153
1154   /* Since fndecl isn't in the list of globals, it would never be emitted
1155      when it's considered to be 'safe' for inlining, so turn off
1156      flag_inline_functions.  */
1157   flag_inline_functions = 0;
1158
1159   /* Don't instrument the function that turns on instrumentation.  Which
1160      is also handy since we'd get silly warnings about not consuming all
1161      of our da_file input.  */
1162   flag_test_coverage = 0;
1163   profile_arc_flag = 0;
1164   flag_branch_probabilities = 0;
1165
1166   rest_of_compilation (fndecl);
1167
1168   /* Reset flag_inline_functions to its original value.  */
1169   flag_inline_functions = save_flag_inline_functions;
1170   flag_test_coverage = save_flag_test_coverage;
1171   profile_arc_flag = save_profile_arc_flag;
1172   flag_branch_probabilities = save_flag_branch_probabilities;
1173
1174   if (! quiet_flag)
1175     fflush (asm_out_file);
1176   current_function_decl = NULL_TREE;
1177
1178   if (targetm.have_ctors_dtors)
1179     (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
1180                                      DEFAULT_INIT_PRIORITY);
1181 }