basic-block.h (EDGE_CRITICAL): Remove; renumber other flags.
[gcc.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 }