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