David Mosberger's fixes for cross compiling gprof.
[deliverable/binutils-gdb.git] / gprof / basic_blocks.c
CommitLineData
ef368dac
NC
1/* basic_blocks.c - Basic-block level related code: reading/writing
2 of basic-block info to/from gmon.out; computing and formatting of
3 basic-block related statistics.
4
37503931 5 Copyright 2000, 2001 Free Software Foundation, Inc.
ef368dac
NC
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA. */
23\f
252b5132 24#include <stdio.h>
252b5132
RH
25#include "basic_blocks.h"
26#include "corefile.h"
27#include "gmon_io.h"
28#include "gmon_out.h"
29#include "gprof.h"
30#include "libiberty.h"
31#include "source.h"
32#include "sym_ids.h"
b71c67ab
MS
33#ifdef HAVE_UNISTD_H
34#include <unistd.h>
35#endif
252b5132 36
ef368dac 37/* Default option values: */
252b5132
RH
38bool bb_annotate_all_lines = FALSE;
39unsigned long bb_min_calls = 1;
40int bb_table_length = 10;
41
ef368dac 42/* Variables used to compute annotated source listing stats: */
252b5132
RH
43static long num_executable_lines;
44static long num_lines_executed;
45
46
ef368dac
NC
47/* Helper for sorting. Compares two symbols and returns result
48 such that sorting will be increasing according to filename, line
49 number, and address (in that order). */
252b5132
RH
50
51static int
52DEFUN (cmp_bb, (lp, rp), const void *lp AND const void *rp)
53{
54 int r;
55 const Sym *left = *(const Sym **) lp;
56 const Sym *right = *(const Sym **) rp;
57
58 if (left->file && right->file)
59 {
60 r = strcmp (left->file->name, right->file->name);
0eee5820 61
252b5132 62 if (r)
ef368dac 63 return r;
252b5132
RH
64
65 if (left->line_num != right->line_num)
ef368dac 66 return left->line_num - right->line_num;
252b5132
RH
67 }
68
69 if (left->addr < right->addr)
ef368dac 70 return -1;
252b5132 71 else if (left->addr > right->addr)
ef368dac 72 return 1;
252b5132 73 else
ef368dac 74 return 0;
252b5132
RH
75}
76
77
ef368dac
NC
78/* Helper for sorting. Order basic blocks in decreasing number of
79 calls, ties are broken in increasing order of line numbers. */
252b5132
RH
80static int
81DEFUN (cmp_ncalls, (lp, rp), const void *lp AND const void *rp)
82{
83 const Sym *left = *(const Sym **) lp;
84 const Sym *right = *(const Sym **) rp;
85
86 if (!left)
ef368dac 87 return 1;
252b5132 88 else if (!right)
ef368dac 89 return -1;
252b5132
RH
90
91 if (left->ncalls < right->ncalls)
92 return 1;
93 else if (left->ncalls > right->ncalls)
94 return -1;
95
96 return left->line_num - right->line_num;
97}
98
ef368dac 99/* Skip over variable length string. */
252b5132
RH
100static void
101DEFUN (fskip_string, (fp), FILE * fp)
102{
103 int ch;
104
105 while ((ch = fgetc (fp)) != EOF)
106 {
107 if (ch == '\0')
ef368dac 108 break;
252b5132
RH
109 }
110}
111
ef368dac
NC
112/* Read a basic-block record from file IFP. FILENAME is the name
113 of file IFP and is provided for formatting error-messages only. */
252b5132 114
252b5132
RH
115void
116DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
117{
118 int nblocks, b;
0eee5820 119 bfd_vma addr, ncalls;
252b5132
RH
120 Sym *sym;
121
0eee5820 122 if (gmon_io_read_32 (ifp, &nblocks))
252b5132 123 {
0eee5820
AM
124 fprintf (stderr, _("%s: %s: unexpected end of file\n"),
125 whoami, filename);
252b5132
RH
126 done (1);
127 }
128
129 nblocks = bfd_get_32 (core_bfd, (bfd_byte *) & nblocks);
130 if (gmon_file_version == 0)
ef368dac 131 fskip_string (ifp);
252b5132
RH
132
133 for (b = 0; b < nblocks; ++b)
134 {
135 if (gmon_file_version == 0)
136 {
137 int line_num;
0eee5820 138
ef368dac
NC
139 /* Version 0 had lots of extra stuff that we don't
140 care about anymore. */
252b5132
RH
141 if ((fread (&ncalls, sizeof (ncalls), 1, ifp) != 1)
142 || (fread (&addr, sizeof (addr), 1, ifp) != 1)
143 || (fskip_string (ifp), FALSE)
144 || (fskip_string (ifp), FALSE)
145 || (fread (&line_num, sizeof (line_num), 1, ifp) != 1))
146 {
147 perror (filename);
148 done (1);
149 }
150 }
0eee5820
AM
151 else if (gmon_io_read_vma (ifp, &addr)
152 || gmon_io_read_vma (ifp, &ncalls))
252b5132 153 {
0eee5820
AM
154 perror (filename);
155 done (1);
252b5132
RH
156 }
157
ef368dac 158 /* Basic-block execution counts are meaningful only if we're
0eee5820 159 profiling at the line-by-line level: */
252b5132
RH
160 if (line_granularity)
161 {
252b5132
RH
162 sym = sym_lookup (&symtab, addr);
163
164 if (sym)
165 {
166 int i;
167
168 DBG (BBDEBUG,
169 printf ("[bb_read_rec] 0x%lx->0x%lx (%s:%d) cnt=%lu\n",
fdcf7d43 170 (unsigned long) addr, (unsigned long) sym->addr,
0eee5820 171 sym->name, sym->line_num, (unsigned long) ncalls));
252b5132
RH
172
173 for (i = 0; i < NBBS; i++)
174 {
175 if (! sym->bb_addr[i] || sym->bb_addr[i] == addr)
176 {
177 sym->bb_addr[i] = addr;
178 sym->bb_calls[i] += ncalls;
179 break;
180 }
181 }
182 }
183 }
184 else
185 {
186 static bool user_warned = FALSE;
187
188 if (!user_warned)
189 {
190 user_warned = TRUE;
191 fprintf (stderr,
ef368dac 192 _("%s: warning: ignoring basic-block exec counts (use -l or --line)\n"),
252b5132
RH
193 whoami);
194 }
195 }
196 }
197 return;
198}
199
ef368dac
NC
200/* Write all basic-blocks with non-zero counts to file OFP. FILENAME
201 is the name of OFP and is provided for producing error-messages
202 only. */
252b5132
RH
203void
204DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename)
205{
252b5132 206 int nblocks = 0;
252b5132
RH
207 Sym *sym;
208 int i;
209
ef368dac 210 /* Count how many non-zero blocks with have: */
252b5132
RH
211 for (sym = symtab.base; sym < symtab.limit; ++sym)
212 {
213 for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
214 ;
215 nblocks += i;
216 }
217
ef368dac 218 /* Write header: */
0eee5820
AM
219 if (gmon_io_write_8 (ofp, GMON_TAG_BB_COUNT)
220 || gmon_io_write_32 (ofp, nblocks))
252b5132
RH
221 {
222 perror (filename);
223 done (1);
224 }
225
ef368dac 226 /* Write counts: */
252b5132
RH
227 for (sym = symtab.base; sym < symtab.limit; ++sym)
228 {
229 for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
230 {
0eee5820
AM
231 if (gmon_io_write_vma (ofp, sym->bb_addr[i])
232 || gmon_io_write_vma (ofp, sym->bb_calls[i]))
252b5132
RH
233 {
234 perror (filename);
235 done (1);
236 }
237 }
238 }
239}
240
ef368dac
NC
241/* Output basic-block statistics in a format that is easily parseable.
242 Current the format is:
0eee5820
AM
243
244 <filename>:<line-number>: (<function-name>:<bb-addr): <ncalls> */
252b5132 245
252b5132
RH
246void
247DEFUN_VOID (print_exec_counts)
248{
249 Sym **sorted_bbs, *sym;
250 int i, j, len;
251
252 if (first_output)
ef368dac 253 first_output = FALSE;
252b5132 254 else
ef368dac 255 printf ("\f\n");
252b5132 256
ef368dac 257 /* Sort basic-blocks according to function name and line number: */
252b5132
RH
258 sorted_bbs = (Sym **) xmalloc (symtab.len * sizeof (sorted_bbs[0]));
259 len = 0;
0eee5820 260
252b5132
RH
261 for (sym = symtab.base; sym < symtab.limit; ++sym)
262 {
ef368dac 263 /* Accept symbol if it's in the INCL_EXEC table
0eee5820
AM
264 or there is no INCL_EXEC table
265 and it does not appear in the EXCL_EXEC table. */
252b5132
RH
266 if (sym_lookup (&syms[INCL_EXEC], sym->addr)
267 || (syms[INCL_EXEC].len == 0
268 && !sym_lookup (&syms[EXCL_EXEC], sym->addr)))
269 {
270 sorted_bbs[len++] = sym;
271 }
272 }
0eee5820 273
252b5132
RH
274 qsort (sorted_bbs, len, sizeof (sorted_bbs[0]), cmp_bb);
275
ef368dac 276 /* Output basic-blocks: */
252b5132
RH
277
278 for (i = 0; i < len; ++i)
279 {
280 if (sym->ncalls > 0 || ! ignore_zeros)
281 {
fdcf7d43 282 /* FIXME: This only works if bfd_vma is unsigned long. */
252b5132
RH
283 printf (_("%s:%d: (%s:0x%lx) %lu executions\n"),
284 sym->file ? sym->file->name : _("<unknown>"), sym->line_num,
fdcf7d43 285 sym->name, (unsigned long) sym->addr, sym->ncalls);
252b5132 286 }
0eee5820 287
252b5132
RH
288 for (j = 0; j < NBBS && sym->bb_addr[j]; j ++)
289 {
290 if (sym->bb_calls[j] > 0 || ! ignore_zeros)
291 {
fdcf7d43 292 /* FIXME: This only works if bfd_vma is unsigned long. */
252b5132
RH
293 printf (_("%s:%d: (%s:0x%lx) %lu executions\n"),
294 sym->file ? sym->file->name : _("<unknown>"), sym->line_num,
fdcf7d43
ILT
295 sym->name, (unsigned long) sym->bb_addr[j],
296 sym->bb_calls[j]);
252b5132
RH
297 }
298 }
299 }
300 free (sorted_bbs);
301}
302
ef368dac
NC
303/* Helper for bb_annotated_source: format annotation containing
304 number of line executions. Depends on being called on each
305 line of a file in sequential order.
0eee5820 306
ef368dac
NC
307 Global variable bb_annotate_all_lines enables execution count
308 compression (counts are supressed if identical to the last one)
309 and prints counts on all executed lines. Otherwise, print
310 all basic-block execution counts exactly once on the line
311 that starts the basic-block. */
252b5132
RH
312
313static void
314DEFUN (annotate_with_count, (buf, width, line_num, arg),
315 char *buf AND int width AND int line_num AND void *arg)
316{
317 Source_File *sf = arg;
318 Sym *b;
319 int i;
320 static unsigned long last_count;
321 unsigned long last_print = (unsigned long) -1;
322
323 b = NULL;
0eee5820 324
252b5132 325 if (line_num <= sf->num_lines)
ef368dac
NC
326 b = sf->line[line_num - 1];
327
252b5132
RH
328 if (!b)
329 {
330 for (i = 0; i < width; i++)
331 buf[i] = ' ';
332 buf[width] = '\0';
333 }
334 else
335 {
336 char tmpbuf[NBBS * 30];
337 char *p;
338 unsigned long ncalls;
339 int ncalls_set;
340 int len;
341
342 ++num_executable_lines;
343
344 p = tmpbuf;
345 *p = '\0';
346
347 ncalls = 0;
348 ncalls_set = 0;
349
350 /* If this is a function entry point, label the line no matter what.
0eee5820
AM
351 Otherwise, we're in the middle of a function, so check to see
352 if the first basic-block address is larger than the starting
353 address of the line. If so, then this line begins with a
354 a portion of the previous basic-block, so print that prior
355 execution count (if bb_annotate_all_lines is set). */
252b5132
RH
356 if (b->is_func)
357 {
358 sprintf (p, "%lu", b->ncalls);
359 p += strlen (p);
360 last_count = b->ncalls;
361 last_print = last_count;
362 ncalls = b->ncalls;
363 ncalls_set = 1;
364 }
365 else if (bb_annotate_all_lines
366 && b->bb_addr[0] && b->bb_addr[0] > b->addr)
367 {
368 sprintf (p, "%lu", last_count);
369 p += strlen (p);
370 last_print = last_count;
371 ncalls = last_count;
372 ncalls_set = 1;
373 }
374
375 /* Loop through all of this line's basic-blocks. For each one,
0eee5820
AM
376 update last_count, then compress sequential identical counts
377 (if bb_annotate_all_lines) and print the execution count. */
252b5132
RH
378
379 for (i = 0; i < NBBS && b->bb_addr[i]; i++)
380 {
381 last_count = b->bb_calls[i];
382 if (! ncalls_set)
383 {
384 ncalls = 0;
385 ncalls_set = 1;
386 }
387 ncalls += last_count;
388
389 if (bb_annotate_all_lines && last_count == last_print)
ef368dac 390 continue;
252b5132
RH
391
392 if (p > tmpbuf)
393 *p++ = ',';
394 sprintf (p, "%lu", last_count);
395 p += strlen (p);
396
397 last_print = last_count;
398 }
399
400 /* We're done. If nothing has been printed on this line,
0eee5820
AM
401 print the last execution count (bb_annotate_all_lines),
402 which could be from either a previous line (if there were
403 no BBs on this line), or from this line (if all our BB
404 counts were compressed out because they were identical). */
252b5132
RH
405
406 if (bb_annotate_all_lines && p == tmpbuf)
407 {
408 sprintf (p, "%lu", last_count);
409 p += strlen (p);
410 ncalls = last_count;
411 ncalls_set = 1;
412 }
413
414 if (! ncalls_set)
415 {
416 int c;
417
418 for (c = 0; c < width; c++)
419 buf[c] = ' ';
420 buf[width] = '\0';
421 return;
422 }
423
424 ++num_lines_executed;
425
426 if (ncalls < bb_min_calls)
427 {
428 strcpy (tmpbuf, "#####");
429 p = tmpbuf + 5;
430 }
431
432 strcpy (p, " -> ");
433 p += 4;
434
435 len = p - tmpbuf;
436 if (len >= width)
437 {
438 strncpy (buf, tmpbuf, width);
439 buf[width] = '\0';
440 }
441 else
442 {
443 int c;
444
445 strcpy (buf + width - len, tmpbuf);
446 for (c = 0; c < width - len; ++c)
447 buf[c] = ' ';
448 }
449 }
450}
451
ef368dac
NC
452/* Annotate the files named in SOURCE_FILES with basic-block statistics
453 (execution counts). After each source files, a few statistics
454 regarding that source file are printed. */
455
252b5132
RH
456void
457DEFUN_VOID (print_annotated_source)
458{
459 Sym *sym, *line_stats, *new_line;
460 Source_File *sf;
461 int i, table_len;
462 FILE *ofp;
463
ef368dac
NC
464 /* Find maximum line number for each source file that user is
465 interested in: */
252b5132
RH
466 for (sym = symtab.base; sym < symtab.limit; ++sym)
467 {
ef368dac 468 /* Accept symbol if it's file is known, its line number is
0eee5820
AM
469 bigger than anything we have seen for that file so far and
470 if it's in the INCL_ANNO table or there is no INCL_ANNO
471 table and it does not appear in the EXCL_ANNO table. */
252b5132
RH
472 if (sym->file && sym->line_num > sym->file->num_lines
473 && (sym_lookup (&syms[INCL_ANNO], sym->addr)
474 || (syms[INCL_ANNO].len == 0
475 && !sym_lookup (&syms[EXCL_ANNO], sym->addr))))
476 {
477 sym->file->num_lines = sym->line_num;
478 }
479 }
480
ef368dac 481 /* Allocate line descriptors: */
252b5132
RH
482 for (sf = first_src_file; sf; sf = sf->next)
483 {
484 if (sf->num_lines > 0)
485 {
486 sf->line = (void *) xmalloc (sf->num_lines * sizeof (sf->line[0]));
487 memset (sf->line, 0, sf->num_lines * sizeof (sf->line[0]));
488 }
489 }
490
ef368dac 491 /* Count executions per line: */
252b5132
RH
492 for (sym = symtab.base; sym < symtab.limit; ++sym)
493 {
494 if (sym->file && sym->file->num_lines
495 && (sym_lookup (&syms[INCL_ANNO], sym->addr)
496 || (syms[INCL_ANNO].len == 0
497 && !sym_lookup (&syms[EXCL_ANNO], sym->addr))))
498 {
499 sym->file->ncalls += sym->ncalls;
500 line_stats = sym->file->line[sym->line_num - 1];
0eee5820 501
252b5132
RH
502 if (!line_stats)
503 {
ef368dac 504 /* Common case has at most one basic-block per source line: */
252b5132
RH
505 sym->file->line[sym->line_num - 1] = sym;
506 }
507 else if (!line_stats->addr)
508 {
ef368dac 509 /* sym is the 3rd .. nth basic block for this line: */
252b5132
RH
510 line_stats->ncalls += sym->ncalls;
511 }
512 else
513 {
ef368dac 514 /* sym is the second basic block for this line. */
252b5132
RH
515 new_line = (Sym *) xmalloc (sizeof (*new_line));
516 *new_line = *line_stats;
517 new_line->addr = 0;
518 new_line->ncalls += sym->ncalls;
519 sym->file->line[sym->line_num - 1] = new_line;
520 }
521 }
522 }
523
ef368dac 524 /* Plod over source files, annotating them: */
252b5132
RH
525 for (sf = first_src_file; sf; sf = sf->next)
526 {
527 if (!sf->num_lines || (ignore_zeros && sf->ncalls == 0))
ef368dac 528 continue;
252b5132
RH
529
530 num_executable_lines = num_lines_executed = 0;
0eee5820 531
252b5132
RH
532 ofp = annotate_source (sf, 16, annotate_with_count, sf);
533 if (!ofp)
ef368dac 534 continue;
252b5132
RH
535
536 if (bb_table_length > 0)
537 {
538 fprintf (ofp, _("\n\nTop %d Lines:\n\n Line Count\n\n"),
539 bb_table_length);
540
ef368dac 541 /* Abuse line arrays---it's not needed anymore: */
252b5132
RH
542 qsort (sf->line, sf->num_lines, sizeof (sf->line[0]), cmp_ncalls);
543 table_len = bb_table_length;
0eee5820 544
252b5132 545 if (table_len > sf->num_lines)
ef368dac 546 table_len = sf->num_lines;
0eee5820 547
252b5132
RH
548 for (i = 0; i < table_len; ++i)
549 {
550 sym = sf->line[i];
0eee5820 551
252b5132 552 if (!sym || sym->ncalls == 0)
252b5132 553 break;
ef368dac 554
252b5132
RH
555 fprintf (ofp, "%9d %10lu\n", sym->line_num, sym->ncalls);
556 }
557 }
558
559 free (sf->line);
560 sf->line = 0;
561
562 fprintf (ofp, _("\nExecution Summary:\n\n"));
563 fprintf (ofp, _("%9ld Executable lines in this file\n"),
564 num_executable_lines);
565 fprintf (ofp, _("%9ld Lines executed\n"), num_lines_executed);
566 fprintf (ofp, _("%9.2f Percent of the file executed\n"),
567 num_executable_lines
568 ? 100.0 * num_lines_executed / (double) num_executable_lines
569 : 100.0);
570 fprintf (ofp, _("\n%9lu Total number of line executions\n"),
571 sf->ncalls);
572 fprintf (ofp, _("%9.2f Average executions per line\n"),
573 num_executable_lines
574 ? (double) sf->ncalls / (double) num_executable_lines
575 : 0.0);
0eee5820 576
252b5132 577 if (ofp != stdout)
ef368dac 578 fclose (ofp);
252b5132
RH
579 }
580}
This page took 0.089565 seconds and 4 git commands to generate.