]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprof/hist.c
Fix some PID/TPID fallout for HP/UX.
[thirdparty/binutils-gdb.git] / gprof / hist.c
CommitLineData
ef368dac
NC
1/* hist.c - Histogram related operations.
2
0eee5820 3 Copyright 2000, 2001 Free Software Foundation, Inc.
ef368dac
NC
4
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21\f
252b5132
RH
22#include <stdio.h>
23#include "libiberty.h"
24#include "gprof.h"
25#include "corefile.h"
26#include "gmon_io.h"
27#include "gmon_out.h"
28#include "hist.h"
29#include "symtab.h"
30#include "sym_ids.h"
31#include "utils.h"
32
33#define UNITS_TO_CODE (offset_to_code / sizeof(UNIT))
34
35static void scale_and_align_entries PARAMS ((void));
36
ef368dac 37/* Declarations of automatically generated functions to output blurbs. */
252b5132
RH
38extern void flat_blurb PARAMS ((FILE * fp));
39
ef368dac
NC
40bfd_vma s_lowpc; /* Lowest address in .text. */
41bfd_vma s_highpc = 0; /* Highest address in .text. */
42bfd_vma lowpc, highpc; /* Same, but expressed in UNITs. */
43int hist_num_bins = 0; /* Number of histogram samples. */
44int *hist_sample = 0; /* Histogram samples (shorts in the file!). */
252b5132 45double hist_scale;
0eee5820 46char hist_dimension[16] = "seconds";
252b5132
RH
47char hist_dimension_abbrev = 's';
48
0eee5820 49static double accum_time; /* Accumulated time so far for print_line(). */
ef368dac
NC
50static double total_time; /* Total time for all routines. */
51
52/* Table of SI prefixes for powers of 10 (used to automatically
53 scale some of the values in the flat profile). */
252b5132
RH
54const struct
55 {
56 char prefix;
57 double scale;
58 }
59SItab[] =
60{
0eee5820
AM
61 { 'T', 1e-12 }, /* tera */
62 { 'G', 1e-09 }, /* giga */
63 { 'M', 1e-06 }, /* mega */
64 { 'K', 1e-03 }, /* kilo */
65 { ' ', 1e-00 },
66 { 'm', 1e+03 }, /* milli */
67 { 'u', 1e+06 }, /* micro */
68 { 'n', 1e+09 }, /* nano */
69 { 'p', 1e+12 }, /* pico */
70 { 'f', 1e+15 }, /* femto */
71 { 'a', 1e+18 } /* ato */
252b5132
RH
72};
73
ef368dac
NC
74
75/* Read the histogram from file IFP. FILENAME is the name of IFP and
76 is provided for formatting error messages only. */
77
252b5132
RH
78void
79DEFUN (hist_read_rec, (ifp, filename), FILE * ifp AND const char *filename)
80{
252b5132
RH
81 bfd_vma n_lowpc, n_highpc;
82 int i, ncnt, profrate;
83 UNIT count;
84
0eee5820
AM
85 if (gmon_io_read_vma (ifp, &n_lowpc)
86 || gmon_io_read_vma (ifp, &n_highpc)
87 || gmon_io_read_32 (ifp, &ncnt)
88 || gmon_io_read_32 (ifp, &profrate)
89 || gmon_io_read (ifp, hist_dimension, 15)
90 || gmon_io_read (ifp, &hist_dimension_abbrev, 1))
252b5132
RH
91 {
92 fprintf (stderr, _("%s: %s: unexpected end of file\n"),
93 whoami, filename);
0eee5820 94
252b5132
RH
95 done (1);
96 }
97
252b5132
RH
98 if (!s_highpc)
99 {
ef368dac 100 /* This is the first histogram record. */
252b5132
RH
101 s_lowpc = n_lowpc;
102 s_highpc = n_highpc;
103 lowpc = (bfd_vma) n_lowpc / sizeof (UNIT);
104 highpc = (bfd_vma) n_highpc / sizeof (UNIT);
105 hist_num_bins = ncnt;
106 hz = profrate;
107 }
108
109 DBG (SAMPLEDEBUG,
110 printf ("[hist_read_rec] n_lowpc 0x%lx n_highpc 0x%lx ncnt %d\n",
fdcf7d43 111 (unsigned long) n_lowpc, (unsigned long) n_highpc, ncnt);
252b5132 112 printf ("[hist_read_rec] s_lowpc 0x%lx s_highpc 0x%lx nsamples %d\n",
fdcf7d43
ILT
113 (unsigned long) s_lowpc, (unsigned long) s_highpc,
114 hist_num_bins);
252b5132 115 printf ("[hist_read_rec] lowpc 0x%lx highpc 0x%lx\n",
fdcf7d43 116 (unsigned long) lowpc, (unsigned long) highpc));
252b5132
RH
117
118 if (n_lowpc != s_lowpc || n_highpc != s_highpc
119 || ncnt != hist_num_bins || hz != profrate)
120 {
121 fprintf (stderr, _("%s: `%s' is incompatible with first gmon file\n"),
122 whoami, filename);
123 done (1);
124 }
125
126 if (!hist_sample)
127 {
128 hist_sample = (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0]));
129 memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0]));
130 }
131
132 for (i = 0; i < hist_num_bins; ++i)
133 {
134 if (fread (&count[0], sizeof (count), 1, ifp) != 1)
135 {
136 fprintf (stderr,
0eee5820 137 _("%s: %s: unexpected EOF after reading %d of %d samples\n"),
252b5132
RH
138 whoami, filename, i, hist_num_bins);
139 done (1);
140 }
141 hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]);
0eee5820
AM
142 DBG (SAMPLEDEBUG,
143 printf ("[hist_read_rec] 0x%lx: %u\n",
144 (unsigned long) (n_lowpc + i * (n_highpc - n_lowpc) / ncnt),
145 hist_sample[i]));
252b5132
RH
146 }
147}
148
149
ef368dac
NC
150/* Write execution histogram to file OFP. FILENAME is the name
151 of OFP and is provided for formatting error-messages only. */
152
252b5132
RH
153void
154DEFUN (hist_write_hist, (ofp, filename), FILE * ofp AND const char *filename)
155{
252b5132
RH
156 UNIT count;
157 int i;
158
ef368dac 159 /* Write header. */
252b5132 160
0eee5820
AM
161 if (gmon_io_write_8 (ofp, GMON_TAG_TIME_HIST)
162 || gmon_io_write_vma (ofp, s_lowpc)
163 || gmon_io_write_vma (ofp, s_highpc)
164 || gmon_io_write_32 (ofp, hist_num_bins)
165 || gmon_io_write_32 (ofp, hz)
166 || gmon_io_write (ofp, hist_dimension, 15)
167 || gmon_io_write (ofp, &hist_dimension_abbrev, 1))
252b5132
RH
168 {
169 perror (filename);
170 done (1);
171 }
172
173 for (i = 0; i < hist_num_bins; ++i)
174 {
175 bfd_put_16 (core_bfd, hist_sample[i], (bfd_byte *) & count[0]);
0eee5820 176
252b5132
RH
177 if (fwrite (&count[0], sizeof (count), 1, ofp) != 1)
178 {
179 perror (filename);
180 done (1);
181 }
182 }
183}
184
185
ef368dac
NC
186/* Calculate scaled entry point addresses (to save time in
187 hist_assign_samples), and, on architectures that have procedure
188 entry masks at the start of a function, possibly push the scaled
189 entry points over the procedure entry mask, if it turns out that
190 the entry point is in one bin and the code for a routine is in the
191 next bin. */
192
252b5132
RH
193static void
194scale_and_align_entries ()
195{
196 Sym *sym;
197 bfd_vma bin_of_entry;
198 bfd_vma bin_of_code;
199
200 for (sym = symtab.base; sym < symtab.limit; sym++)
201 {
202 sym->hist.scaled_addr = sym->addr / sizeof (UNIT);
203 bin_of_entry = (sym->hist.scaled_addr - lowpc) / hist_scale;
0eee5820
AM
204 bin_of_code = ((sym->hist.scaled_addr + UNITS_TO_CODE - lowpc)
205 / hist_scale);
252b5132
RH
206 if (bin_of_entry < bin_of_code)
207 {
208 DBG (SAMPLEDEBUG,
209 printf ("[scale_and_align_entries] pushing 0x%lx to 0x%lx\n",
fdcf7d43
ILT
210 (unsigned long) sym->hist.scaled_addr,
211 (unsigned long) (sym->hist.scaled_addr
212 + UNITS_TO_CODE)));
252b5132
RH
213 sym->hist.scaled_addr += UNITS_TO_CODE;
214 }
215 }
216}
217
218
ef368dac 219/* Assign samples to the symbol to which they belong.
0eee5820 220
ef368dac
NC
221 Histogram bin I covers some address range [BIN_LOWPC,BIN_HIGH_PC)
222 which may overlap one more symbol address ranges. If a symbol
223 overlaps with the bin's address range by O percent, then O percent
224 of the bin's count is credited to that symbol.
0eee5820 225
ef368dac
NC
226 There are three cases as to where BIN_LOW_PC and BIN_HIGH_PC can be
227 with respect to the symbol's address range [SYM_LOW_PC,
228 SYM_HIGH_PC) as shown in the following diagram. OVERLAP computes
229 the distance (in UNITs) between the arrows, the fraction of the
230 sample that is to be credited to the symbol which starts at
231 SYM_LOW_PC.
0eee5820
AM
232
233 sym_low_pc sym_high_pc
234 | |
235 v v
236
237 +-----------------------------------------------+
238 | |
239 | ->| |<- ->| |<- ->| |<- |
240 | | | | | |
241 +---------+ +---------+ +---------+
242
243 ^ ^ ^ ^ ^ ^
244 | | | | | |
ef368dac 245 bin_low_pc bin_high_pc bin_low_pc bin_high_pc bin_low_pc bin_high_pc
0eee5820 246
ef368dac
NC
247 For the VAX we assert that samples will never fall in the first two
248 bytes of any routine, since that is the entry mask, thus we call
249 scale_and_align_entries() to adjust the entry points if the entry
250 mask falls in one bin but the code for the routine doesn't start
251 until the next bin. In conjunction with the alignment of routine
252 addresses, this should allow us to have only one sample for every
253 four bytes of text space and never have any overlap (the two end
254 cases, above). */
255
252b5132
RH
256void
257DEFUN_VOID (hist_assign_samples)
258{
259 bfd_vma bin_low_pc, bin_high_pc;
260 bfd_vma sym_low_pc, sym_high_pc;
261 bfd_vma overlap, addr;
262 int bin_count, i;
263 unsigned int j;
264 double time, credit;
265
ef368dac 266 /* Read samples and assign to symbols. */
252b5132
RH
267 hist_scale = highpc - lowpc;
268 hist_scale /= hist_num_bins;
269 scale_and_align_entries ();
270
ef368dac 271 /* Iterate over all sample bins. */
252b5132
RH
272 for (i = 0, j = 1; i < hist_num_bins; ++i)
273 {
274 bin_count = hist_sample[i];
ef368dac
NC
275 if (! bin_count)
276 continue;
277
252b5132
RH
278 bin_low_pc = lowpc + (bfd_vma) (hist_scale * i);
279 bin_high_pc = lowpc + (bfd_vma) (hist_scale * (i + 1));
280 time = bin_count;
0eee5820 281
252b5132
RH
282 DBG (SAMPLEDEBUG,
283 printf (
284 "[assign_samples] bin_low_pc=0x%lx, bin_high_pc=0x%lx, bin_count=%d\n",
fdcf7d43
ILT
285 (unsigned long) (sizeof (UNIT) * bin_low_pc),
286 (unsigned long) (sizeof (UNIT) * bin_high_pc),
252b5132
RH
287 bin_count));
288 total_time += time;
289
ef368dac 290 /* Credit all symbols that are covered by bin I. */
252b5132
RH
291 for (j = j - 1; j < symtab.len; ++j)
292 {
293 sym_low_pc = symtab.base[j].hist.scaled_addr;
294 sym_high_pc = symtab.base[j + 1].hist.scaled_addr;
0eee5820 295
ef368dac
NC
296 /* If high end of bin is below entry address,
297 go for next bin. */
252b5132 298 if (bin_high_pc < sym_low_pc)
ef368dac
NC
299 break;
300
301 /* If low end of bin is above high end of symbol,
302 go for next symbol. */
252b5132 303 if (bin_low_pc >= sym_high_pc)
ef368dac
NC
304 continue;
305
252b5132
RH
306 overlap =
307 MIN (bin_high_pc, sym_high_pc) - MAX (bin_low_pc, sym_low_pc);
308 if (overlap > 0)
309 {
310 DBG (SAMPLEDEBUG,
311 printf (
0eee5820
AM
312 "[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n",
313 (unsigned long) symtab.base[j].addr,
314 (unsigned long) (sizeof (UNIT) * sym_high_pc),
315 symtab.base[j].name, overlap * time / hist_scale,
316 (long) overlap));
317
252b5132
RH
318 addr = symtab.base[j].addr;
319 credit = overlap * time / hist_scale;
0eee5820 320
ef368dac 321 /* Credit symbol if it appears in INCL_FLAT or that
0eee5820
AM
322 table is empty and it does not appear it in
323 EXCL_FLAT. */
252b5132
RH
324 if (sym_lookup (&syms[INCL_FLAT], addr)
325 || (syms[INCL_FLAT].len == 0
326 && !sym_lookup (&syms[EXCL_FLAT], addr)))
327 {
328 symtab.base[j].hist.time += credit;
329 }
330 else
331 {
332 total_time -= credit;
333 }
334 }
335 }
336 }
0eee5820 337
252b5132
RH
338 DBG (SAMPLEDEBUG, printf ("[assign_samples] total_time %f\n",
339 total_time));
340}
341
342
ef368dac
NC
343/* Print header for flag histogram profile. */
344
252b5132
RH
345static void
346DEFUN (print_header, (prefix), const char prefix)
347{
348 char unit[64];
349
350 sprintf (unit, _("%c%c/call"), prefix, hist_dimension_abbrev);
351
352 if (bsd_style_output)
353 {
354 printf (_("\ngranularity: each sample hit covers %ld byte(s)"),
355 (long) hist_scale * sizeof (UNIT));
356 if (total_time > 0.0)
357 {
358 printf (_(" for %.2f%% of %.2f %s\n\n"),
359 100.0 / total_time, total_time / hz, hist_dimension);
360 }
361 }
362 else
363 {
364 printf (_("\nEach sample counts as %g %s.\n"), 1.0 / hz, hist_dimension);
365 }
366
367 if (total_time <= 0.0)
368 {
369 printf (_(" no time accumulated\n\n"));
0eee5820 370
ef368dac 371 /* This doesn't hurt since all the numerators will be zero. */
252b5132
RH
372 total_time = 1.0;
373 }
374
375 printf ("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
0eee5820
AM
376 "% ", _("cumulative"), _("self "), "", _("self "), _("total "),
377 "");
252b5132
RH
378 printf ("%5.5s %9.9s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
379 _("time"), hist_dimension, hist_dimension, _("calls"), unit, unit,
380 _("name"));
381}
382
383
384static void
385DEFUN (print_line, (sym, scale), Sym * sym AND double scale)
386{
387 if (ignore_zeros && sym->ncalls == 0 && sym->hist.time == 0)
ef368dac 388 return;
252b5132
RH
389
390 accum_time += sym->hist.time;
0eee5820 391
252b5132 392 if (bsd_style_output)
ef368dac
NC
393 printf ("%5.1f %10.2f %8.2f",
394 total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0,
395 accum_time / hz, sym->hist.time / hz);
252b5132 396 else
ef368dac
NC
397 printf ("%6.2f %9.2f %8.2f",
398 total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0,
399 accum_time / hz, sym->hist.time / hz);
0eee5820 400
252b5132 401 if (sym->ncalls != 0)
ef368dac
NC
402 printf (" %8lu %8.2f %8.2f ",
403 sym->ncalls, scale * sym->hist.time / hz / sym->ncalls,
404 scale * (sym->hist.time + sym->cg.child_time) / hz / sym->ncalls);
252b5132 405 else
ef368dac 406 printf (" %8.8s %8.8s %8.8s ", "", "", "");
0eee5820 407
252b5132 408 if (bsd_style_output)
ef368dac 409 print_name (sym);
252b5132 410 else
ef368dac
NC
411 print_name_only (sym);
412
252b5132
RH
413 printf ("\n");
414}
415
416
ef368dac
NC
417/* Compare LP and RP. The primary comparison key is execution time,
418 the secondary is number of invocation, and the tertiary is the
419 lexicographic order of the function names. */
420
252b5132
RH
421static int
422DEFUN (cmp_time, (lp, rp), const PTR lp AND const PTR rp)
423{
424 const Sym *left = *(const Sym **) lp;
425 const Sym *right = *(const Sym **) rp;
426 double time_diff;
427
428 time_diff = right->hist.time - left->hist.time;
0eee5820 429
252b5132 430 if (time_diff > 0.0)
ef368dac 431 return 1;
0eee5820 432
252b5132 433 if (time_diff < 0.0)
ef368dac 434 return -1;
252b5132
RH
435
436 if (right->ncalls > left->ncalls)
ef368dac
NC
437 return 1;
438
252b5132 439 if (right->ncalls < left->ncalls)
ef368dac 440 return -1;
252b5132
RH
441
442 return strcmp (left->name, right->name);
443}
444
445
ef368dac
NC
446/* Print the flat histogram profile. */
447
252b5132
RH
448void
449DEFUN_VOID (hist_print)
450{
451 Sym **time_sorted_syms, *top_dog, *sym;
452 unsigned int index;
453 int log_scale;
454 double top_time, time;
455 bfd_vma addr;
456
457 if (first_output)
ef368dac 458 first_output = FALSE;
252b5132 459 else
ef368dac 460 printf ("\f\n");
252b5132
RH
461
462 accum_time = 0.0;
0eee5820 463
252b5132
RH
464 if (bsd_style_output)
465 {
466 if (print_descriptions)
467 {
468 printf (_("\n\n\nflat profile:\n"));
469 flat_blurb (stdout);
470 }
471 }
472 else
473 {
474 printf (_("Flat profile:\n"));
475 }
0eee5820 476
ef368dac
NC
477 /* Sort the symbol table by time (call-count and name as secondary
478 and tertiary keys). */
252b5132 479 time_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
0eee5820 480
252b5132 481 for (index = 0; index < symtab.len; ++index)
ef368dac
NC
482 time_sorted_syms[index] = &symtab.base[index];
483
252b5132
RH
484 qsort (time_sorted_syms, symtab.len, sizeof (Sym *), cmp_time);
485
486 if (bsd_style_output)
487 {
ef368dac 488 log_scale = 5; /* Milli-seconds is BSD-default. */
252b5132
RH
489 }
490 else
491 {
ef368dac
NC
492 /* Search for symbol with highest per-call
493 execution time and scale accordingly. */
252b5132
RH
494 log_scale = 0;
495 top_dog = 0;
496 top_time = 0.0;
0eee5820 497
252b5132
RH
498 for (index = 0; index < symtab.len; ++index)
499 {
500 sym = time_sorted_syms[index];
0eee5820 501
252b5132
RH
502 if (sym->ncalls != 0)
503 {
504 time = (sym->hist.time + sym->cg.child_time) / sym->ncalls;
0eee5820 505
252b5132
RH
506 if (time > top_time)
507 {
508 top_dog = sym;
509 top_time = time;
510 }
511 }
512 }
0eee5820 513
252b5132
RH
514 if (top_dog && top_dog->ncalls != 0 && top_time > 0.0)
515 {
516 top_time /= hz;
0eee5820 517
252b5132
RH
518 while (SItab[log_scale].scale * top_time < 1000.0
519 && ((size_t) log_scale
520 < sizeof (SItab) / sizeof (SItab[0]) - 1))
521 {
522 ++log_scale;
523 }
524 }
525 }
526
ef368dac
NC
527 /* For now, the dimension is always seconds. In the future, we
528 may also want to support other (pseudo-)dimensions (such as
529 I-cache misses etc.). */
252b5132 530 print_header (SItab[log_scale].prefix);
0eee5820 531
252b5132
RH
532 for (index = 0; index < symtab.len; ++index)
533 {
534 addr = time_sorted_syms[index]->addr;
0eee5820 535
ef368dac 536 /* Print symbol if its in INCL_FLAT table or that table
0eee5820 537 is empty and the symbol is not in EXCL_FLAT. */
252b5132
RH
538 if (sym_lookup (&syms[INCL_FLAT], addr)
539 || (syms[INCL_FLAT].len == 0
540 && !sym_lookup (&syms[EXCL_FLAT], addr)))
ef368dac 541 print_line (time_sorted_syms[index], SItab[log_scale].scale);
252b5132 542 }
0eee5820 543
252b5132
RH
544 free (time_sorted_syms);
545
546 if (print_descriptions && !bsd_style_output)
ef368dac 547 flat_blurb (stdout);
252b5132 548}