OSDN Git Service

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