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