* aarch64-linux-nat.c: Replace PIDGET with ptid_get_pid.
[deliverable/binutils-gdb.git] / gprof / hist.c
CommitLineData
ef368dac
NC
1/* hist.c - Histogram related operations.
2
c34f4fc6 3 Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2009
d6a39701 4 Free Software Foundation, Inc.
ef368dac
NC
5
6 This file is part of GNU Binutils.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
651dbc76 10 the Free Software Foundation; either version 3 of the License, or
ef368dac
NC
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
44eb1801
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
ef368dac 22\f
252b5132 23#include "gprof.h"
ecba005f 24#include "libiberty.h"
6d9c411a
AM
25#include "search_list.h"
26#include "source.h"
27#include "symtab.h"
252b5132
RH
28#include "corefile.h"
29#include "gmon_io.h"
30#include "gmon_out.h"
31#include "hist.h"
252b5132
RH
32#include "sym_ids.h"
33#include "utils.h"
b3296dc5
VP
34#include "math.h"
35#include "stdio.h"
36#include "stdlib.h"
252b5132
RH
37
38#define UNITS_TO_CODE (offset_to_code / sizeof(UNIT))
39
3e8f6abf
BE
40static void scale_and_align_entries (void);
41static void print_header (int);
42static void print_line (Sym *, double);
43static int cmp_time (const PTR, const PTR);
252b5132 44
ef368dac 45/* Declarations of automatically generated functions to output blurbs. */
3e8f6abf 46extern void flat_blurb (FILE * fp);
252b5132 47
b3296dc5
VP
48static histogram *find_histogram (bfd_vma lowpc, bfd_vma highpc);
49static histogram *find_histogram_for_pc (bfd_vma pc);
50
c34f4fc6
NC
51histogram * histograms;
52unsigned num_histograms;
252b5132 53double hist_scale;
9e972ca0
BE
54static char hist_dimension[16] = "seconds";
55static char hist_dimension_abbrev = 's';
252b5132 56
0eee5820 57static double accum_time; /* Accumulated time so far for print_line(). */
ef368dac
NC
58static double total_time; /* Total time for all routines. */
59
60/* Table of SI prefixes for powers of 10 (used to automatically
61 scale some of the values in the flat profile). */
252b5132
RH
62const struct
63 {
64 char prefix;
65 double scale;
66 }
67SItab[] =
68{
0eee5820
AM
69 { 'T', 1e-12 }, /* tera */
70 { 'G', 1e-09 }, /* giga */
71 { 'M', 1e-06 }, /* mega */
72 { 'K', 1e-03 }, /* kilo */
73 { ' ', 1e-00 },
74 { 'm', 1e+03 }, /* milli */
75 { 'u', 1e+06 }, /* micro */
76 { 'n', 1e+09 }, /* nano */
77 { 'p', 1e+12 }, /* pico */
78 { 'f', 1e+15 }, /* femto */
79 { 'a', 1e+18 } /* ato */
252b5132
RH
80};
81
b3296dc5
VP
82/* Reads just the header part of histogram record into
83 *RECORD from IFP. FILENAME is the name of IFP and
84 is provided for formatting error messages only.
ef368dac 85
b3296dc5
VP
86 If FIRST is non-zero, sets global variables HZ, HIST_DIMENSION,
87 HIST_DIMENSION_ABBREV, HIST_SCALE. If FIRST is zero, checks
88 that the new histogram is compatible with already-set values
89 of those variables and emits an error if that's not so. */
90static void
91read_histogram_header (histogram *record,
92 FILE *ifp, const char *filename,
93 int first)
252b5132 94{
b3296dc5
VP
95 unsigned int profrate;
96 char n_hist_dimension[15];
97 char n_hist_dimension_abbrev;
98 double n_hist_scale;
99
100 if (gmon_io_read_vma (ifp, &record->lowpc)
101 || gmon_io_read_vma (ifp, &record->highpc)
102 || gmon_io_read_32 (ifp, &record->num_bins)
0eee5820 103 || gmon_io_read_32 (ifp, &profrate)
b3296dc5
VP
104 || gmon_io_read (ifp, n_hist_dimension, 15)
105 || gmon_io_read (ifp, &n_hist_dimension_abbrev, 1))
252b5132
RH
106 {
107 fprintf (stderr, _("%s: %s: unexpected end of file\n"),
108 whoami, filename);
0eee5820 109
252b5132
RH
110 done (1);
111 }
112
b3296dc5
VP
113 n_hist_scale = (double)((record->highpc - record->lowpc) / sizeof (UNIT))
114 / record->num_bins;
115
116 if (first)
252b5132 117 {
b3296dc5
VP
118 /* We don't try to veryfy profrate is the same for all histogram
119 records. If we have two histogram records for the same
120 address range and profiling samples is done as often
121 as possible as opposed on timer, then the actual profrate will
122 be slightly different. Most of the time the difference does not
123 matter and insisting that profiling rate is exactly the same
124 will only create inconvenient. */
252b5132 125 hz = profrate;
b3296dc5
VP
126 memcpy (hist_dimension, n_hist_dimension, 15);
127 hist_dimension_abbrev = n_hist_dimension_abbrev;
128 hist_scale = n_hist_scale;
252b5132 129 }
b3296dc5 130 else
252b5132 131 {
b3296dc5
VP
132 if (strncmp (n_hist_dimension, hist_dimension, 15) != 0)
133 {
134 fprintf (stderr,
135 _("%s: dimension unit changed between histogram records\n"
136 "%s: from '%s'\n"
137 "%s: to '%s'\n"),
138 whoami, whoami, hist_dimension, whoami, n_hist_dimension);
139 done (1);
140 }
141
142 if (n_hist_dimension_abbrev != hist_dimension_abbrev)
143 {
144 fprintf (stderr,
145 _("%s: dimension abbreviation changed between histogram records\n"
146 "%s: from '%c'\n"
147 "%s: to '%c'\n"),
148 whoami, whoami, hist_dimension_abbrev, whoami, n_hist_dimension_abbrev);
149 done (1);
150 }
151
152 /* The only reason we require the same scale for histograms is that
153 there's code (notably printing code), that prints units,
154 and it would be very confusing to have one unit mean different
155 things for different functions. */
156 if (fabs (hist_scale - n_hist_scale) > 0.000001)
157 {
158 fprintf (stderr,
159 _("%s: different scales in histogram records"),
160 whoami);
161 done (1);
162 }
252b5132 163 }
b3296dc5 164}
252b5132 165
b3296dc5
VP
166/* Read the histogram from file IFP. FILENAME is the name of IFP and
167 is provided for formatting error messages only. */
168
169void
170hist_read_rec (FILE * ifp, const char *filename)
171{
172 bfd_vma lowpc, highpc;
173 histogram n_record;
174 histogram *record, *existing_record;
175 unsigned i;
176
177 /* 1. Read the header and see if there's existing record for the
178 same address range and that there are no overlapping records. */
179 read_histogram_header (&n_record, ifp, filename, num_histograms == 0);
180
181 existing_record = find_histogram (n_record.lowpc, n_record.highpc);
182 if (existing_record)
252b5132 183 {
b3296dc5
VP
184 record = existing_record;
185 }
186 else
187 {
188 /* If this record overlaps, but does not completely match an existing
189 record, it's an error. */
190 lowpc = n_record.lowpc;
191 highpc = n_record.highpc;
192 hist_clip_symbol_address (&lowpc, &highpc);
193 if (lowpc != highpc)
194 {
195 fprintf (stderr,
196 _("%s: overlapping histogram records\n"),
197 whoami);
198 done (1);
199 }
200
201 /* This is new record. Add it to global array and allocate space for
202 the samples. */
1e9cc1c2
NC
203 histograms = (struct histogram *)
204 xrealloc (histograms, sizeof (histogram) * (num_histograms + 1));
b3296dc5
VP
205 memcpy (histograms + num_histograms,
206 &n_record, sizeof (histogram));
207 record = &histograms[num_histograms];
208 ++num_histograms;
209
210 record->sample = (int *) xmalloc (record->num_bins
211 * sizeof (record->sample[0]));
212 memset (record->sample, 0, record->num_bins * sizeof (record->sample[0]));
252b5132
RH
213 }
214
b3296dc5
VP
215 /* 2. We have either a new record (with zeroed histogram data), or an existing
216 record with some data in the histogram already. Read new data into the
217 record, adding hit counts. */
218
219 DBG (SAMPLEDEBUG,
220 printf ("[hist_read_rec] n_lowpc 0x%lx n_highpc 0x%lx ncnt %u\n",
221 (unsigned long) record->lowpc, (unsigned long) record->highpc,
222 record->num_bins));
223
224 for (i = 0; i < record->num_bins; ++i)
252b5132 225 {
b3296dc5 226 UNIT count;
252b5132
RH
227 if (fread (&count[0], sizeof (count), 1, ifp) != 1)
228 {
229 fprintf (stderr,
8c62e9e1 230 _("%s: %s: unexpected EOF after reading %u of %u samples\n"),
b3296dc5 231 whoami, filename, i, record->num_bins);
252b5132
RH
232 done (1);
233 }
b3296dc5 234 record->sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) & count[0]);
0eee5820
AM
235 DBG (SAMPLEDEBUG,
236 printf ("[hist_read_rec] 0x%lx: %u\n",
b3296dc5
VP
237 (unsigned long) (record->lowpc
238 + i * (record->highpc - record->lowpc)
239 / record->num_bins),
240 record->sample[i]));
252b5132
RH
241 }
242}
243
244
b3296dc5 245/* Write all execution histograms file OFP. FILENAME is the name
ef368dac
NC
246 of OFP and is provided for formatting error-messages only. */
247
252b5132 248void
3e8f6abf 249hist_write_hist (FILE * ofp, const char *filename)
252b5132 250{
252b5132 251 UNIT count;
b3296dc5 252 unsigned int i, r;
252b5132 253
b3296dc5 254 for (r = 0; r < num_histograms; ++r)
252b5132 255 {
b3296dc5
VP
256 histogram *record = &histograms[r];
257
258 /* Write header. */
259
260 if (gmon_io_write_8 (ofp, GMON_TAG_TIME_HIST)
261 || gmon_io_write_vma (ofp, record->lowpc)
262 || gmon_io_write_vma (ofp, record->highpc)
263 || gmon_io_write_32 (ofp, record->num_bins)
264 || gmon_io_write_32 (ofp, hz)
265 || gmon_io_write (ofp, hist_dimension, 15)
266 || gmon_io_write (ofp, &hist_dimension_abbrev, 1))
252b5132
RH
267 {
268 perror (filename);
269 done (1);
270 }
b3296dc5
VP
271
272 for (i = 0; i < record->num_bins; ++i)
273 {
274 bfd_put_16 (core_bfd, (bfd_vma) record->sample[i], (bfd_byte *) &count[0]);
275
276 if (fwrite (&count[0], sizeof (count), 1, ofp) != 1)
277 {
278 perror (filename);
279 done (1);
280 }
281 }
252b5132
RH
282 }
283}
284
ef368dac
NC
285/* Calculate scaled entry point addresses (to save time in
286 hist_assign_samples), and, on architectures that have procedure
287 entry masks at the start of a function, possibly push the scaled
288 entry points over the procedure entry mask, if it turns out that
289 the entry point is in one bin and the code for a routine is in the
290 next bin. */
291
252b5132
RH
292static void
293scale_and_align_entries ()
294{
295 Sym *sym;
296 bfd_vma bin_of_entry;
297 bfd_vma bin_of_code;
298
299 for (sym = symtab.base; sym < symtab.limit; sym++)
300 {
b3296dc5
VP
301 histogram *r = find_histogram_for_pc (sym->addr);
302
74bad5d4
L
303 sym->hist.scaled_addr = sym->addr / sizeof (UNIT);
304
b3296dc5 305 if (r)
252b5132 306 {
b3296dc5
VP
307 bin_of_entry = (sym->hist.scaled_addr - r->lowpc) / hist_scale;
308 bin_of_code = ((sym->hist.scaled_addr + UNITS_TO_CODE - r->lowpc)
309 / hist_scale);
310 if (bin_of_entry < bin_of_code)
311 {
312 DBG (SAMPLEDEBUG,
313 printf ("[scale_and_align_entries] pushing 0x%lx to 0x%lx\n",
314 (unsigned long) sym->hist.scaled_addr,
315 (unsigned long) (sym->hist.scaled_addr
316 + UNITS_TO_CODE)));
317 sym->hist.scaled_addr += UNITS_TO_CODE;
318 }
252b5132
RH
319 }
320 }
321}
322
323
ef368dac 324/* Assign samples to the symbol to which they belong.
0eee5820 325
ef368dac
NC
326 Histogram bin I covers some address range [BIN_LOWPC,BIN_HIGH_PC)
327 which may overlap one more symbol address ranges. If a symbol
328 overlaps with the bin's address range by O percent, then O percent
329 of the bin's count is credited to that symbol.
0eee5820 330
ef368dac
NC
331 There are three cases as to where BIN_LOW_PC and BIN_HIGH_PC can be
332 with respect to the symbol's address range [SYM_LOW_PC,
333 SYM_HIGH_PC) as shown in the following diagram. OVERLAP computes
334 the distance (in UNITs) between the arrows, the fraction of the
335 sample that is to be credited to the symbol which starts at
336 SYM_LOW_PC.
0eee5820
AM
337
338 sym_low_pc sym_high_pc
339 | |
340 v v
341
342 +-----------------------------------------------+
343 | |
344 | ->| |<- ->| |<- ->| |<- |
345 | | | | | |
346 +---------+ +---------+ +---------+
347
348 ^ ^ ^ ^ ^ ^
349 | | | | | |
ef368dac 350 bin_low_pc bin_high_pc bin_low_pc bin_high_pc bin_low_pc bin_high_pc
0eee5820 351
ef368dac
NC
352 For the VAX we assert that samples will never fall in the first two
353 bytes of any routine, since that is the entry mask, thus we call
354 scale_and_align_entries() to adjust the entry points if the entry
355 mask falls in one bin but the code for the routine doesn't start
356 until the next bin. In conjunction with the alignment of routine
357 addresses, this should allow us to have only one sample for every
358 four bytes of text space and never have any overlap (the two end
359 cases, above). */
360
b3296dc5
VP
361static void
362hist_assign_samples_1 (histogram *r)
252b5132
RH
363{
364 bfd_vma bin_low_pc, bin_high_pc;
365 bfd_vma sym_low_pc, sym_high_pc;
366 bfd_vma overlap, addr;
8c62e9e1 367 unsigned int bin_count;
db5d0b26 368 unsigned int i, j, k;
91d6fa6a 369 double count_time, credit;
252b5132 370
b3296dc5 371 bfd_vma lowpc = r->lowpc / sizeof (UNIT);
252b5132 372
ef368dac 373 /* Iterate over all sample bins. */
db5d0b26 374 for (i = 0, k = 1; i < r->num_bins; ++i)
252b5132 375 {
b3296dc5 376 bin_count = r->sample[i];
ef368dac
NC
377 if (! bin_count)
378 continue;
379
252b5132
RH
380 bin_low_pc = lowpc + (bfd_vma) (hist_scale * i);
381 bin_high_pc = lowpc + (bfd_vma) (hist_scale * (i + 1));
91d6fa6a 382 count_time = bin_count;
0eee5820 383
252b5132
RH
384 DBG (SAMPLEDEBUG,
385 printf (
8c62e9e1 386 "[assign_samples] bin_low_pc=0x%lx, bin_high_pc=0x%lx, bin_count=%u\n",
fdcf7d43
ILT
387 (unsigned long) (sizeof (UNIT) * bin_low_pc),
388 (unsigned long) (sizeof (UNIT) * bin_high_pc),
252b5132 389 bin_count));
91d6fa6a 390 total_time += count_time;
252b5132 391
cef976f5
NC
392 /* Credit all symbols that are covered by bin I.
393
394 PR gprof/13325: Make sure that K does not get decremented
395 and J will never be less than 0. */
db5d0b26 396 for (j = k - 1; j < symtab.len; k = ++j)
252b5132
RH
397 {
398 sym_low_pc = symtab.base[j].hist.scaled_addr;
399 sym_high_pc = symtab.base[j + 1].hist.scaled_addr;
0eee5820 400
ef368dac
NC
401 /* If high end of bin is below entry address,
402 go for next bin. */
252b5132 403 if (bin_high_pc < sym_low_pc)
db5d0b26 404 break;
ef368dac
NC
405
406 /* If low end of bin is above high end of symbol,
407 go for next symbol. */
252b5132 408 if (bin_low_pc >= sym_high_pc)
ef368dac
NC
409 continue;
410
252b5132
RH
411 overlap =
412 MIN (bin_high_pc, sym_high_pc) - MAX (bin_low_pc, sym_low_pc);
413 if (overlap > 0)
414 {
415 DBG (SAMPLEDEBUG,
416 printf (
0eee5820
AM
417 "[assign_samples] [0x%lx,0x%lx) %s gets %f ticks %ld overlap\n",
418 (unsigned long) symtab.base[j].addr,
419 (unsigned long) (sizeof (UNIT) * sym_high_pc),
91d6fa6a 420 symtab.base[j].name, overlap * count_time / hist_scale,
0eee5820
AM
421 (long) overlap));
422
252b5132 423 addr = symtab.base[j].addr;
91d6fa6a 424 credit = overlap * count_time / hist_scale;
0eee5820 425
ef368dac 426 /* Credit symbol if it appears in INCL_FLAT or that
0eee5820
AM
427 table is empty and it does not appear it in
428 EXCL_FLAT. */
252b5132
RH
429 if (sym_lookup (&syms[INCL_FLAT], addr)
430 || (syms[INCL_FLAT].len == 0
431 && !sym_lookup (&syms[EXCL_FLAT], addr)))
432 {
433 symtab.base[j].hist.time += credit;
434 }
435 else
436 {
437 total_time -= credit;
438 }
439 }
440 }
441 }
0eee5820 442
252b5132
RH
443 DBG (SAMPLEDEBUG, printf ("[assign_samples] total_time %f\n",
444 total_time));
445}
446
b3296dc5
VP
447/* Calls 'hist_assign_sampes_1' for all histogram records read so far. */
448void
449hist_assign_samples ()
450{
451 unsigned i;
452
453 scale_and_align_entries ();
454
455 for (i = 0; i < num_histograms; ++i)
456 hist_assign_samples_1 (&histograms[i]);
457
458}
252b5132 459
ef368dac
NC
460/* Print header for flag histogram profile. */
461
252b5132 462static void
3e8f6abf 463print_header (int prefix)
252b5132
RH
464{
465 char unit[64];
466
467 sprintf (unit, _("%c%c/call"), prefix, hist_dimension_abbrev);
468
469 if (bsd_style_output)
470 {
471 printf (_("\ngranularity: each sample hit covers %ld byte(s)"),
d2df793a 472 (long) hist_scale * (long) sizeof (UNIT));
252b5132
RH
473 if (total_time > 0.0)
474 {
475 printf (_(" for %.2f%% of %.2f %s\n\n"),
476 100.0 / total_time, total_time / hz, hist_dimension);
477 }
478 }
479 else
480 {
481 printf (_("\nEach sample counts as %g %s.\n"), 1.0 / hz, hist_dimension);
482 }
483
484 if (total_time <= 0.0)
485 {
486 printf (_(" no time accumulated\n\n"));
0eee5820 487
ef368dac 488 /* This doesn't hurt since all the numerators will be zero. */
252b5132
RH
489 total_time = 1.0;
490 }
491
492 printf ("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
0eee5820
AM
493 "% ", _("cumulative"), _("self "), "", _("self "), _("total "),
494 "");
252b5132
RH
495 printf ("%5.5s %9.9s %8.8s %8.8s %8.8s %8.8s %-8.8s\n",
496 _("time"), hist_dimension, hist_dimension, _("calls"), unit, unit,
497 _("name"));
498}
499
500
501static void
3e8f6abf 502print_line (Sym *sym, double scale)
252b5132
RH
503{
504 if (ignore_zeros && sym->ncalls == 0 && sym->hist.time == 0)
ef368dac 505 return;
252b5132
RH
506
507 accum_time += sym->hist.time;
0eee5820 508
252b5132 509 if (bsd_style_output)
ef368dac
NC
510 printf ("%5.1f %10.2f %8.2f",
511 total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0,
512 accum_time / hz, sym->hist.time / hz);
252b5132 513 else
ef368dac
NC
514 printf ("%6.2f %9.2f %8.2f",
515 total_time > 0.0 ? 100 * sym->hist.time / total_time : 0.0,
516 accum_time / hz, sym->hist.time / hz);
0eee5820 517
252b5132 518 if (sym->ncalls != 0)
ef368dac
NC
519 printf (" %8lu %8.2f %8.2f ",
520 sym->ncalls, scale * sym->hist.time / hz / sym->ncalls,
521 scale * (sym->hist.time + sym->cg.child_time) / hz / sym->ncalls);
252b5132 522 else
ef368dac 523 printf (" %8.8s %8.8s %8.8s ", "", "", "");
0eee5820 524
252b5132 525 if (bsd_style_output)
ef368dac 526 print_name (sym);
252b5132 527 else
ef368dac
NC
528 print_name_only (sym);
529
252b5132
RH
530 printf ("\n");
531}
532
533
ef368dac
NC
534/* Compare LP and RP. The primary comparison key is execution time,
535 the secondary is number of invocation, and the tertiary is the
536 lexicographic order of the function names. */
537
252b5132 538static int
3e8f6abf 539cmp_time (const PTR lp, const PTR rp)
252b5132
RH
540{
541 const Sym *left = *(const Sym **) lp;
542 const Sym *right = *(const Sym **) rp;
543 double time_diff;
544
545 time_diff = right->hist.time - left->hist.time;
0eee5820 546
252b5132 547 if (time_diff > 0.0)
ef368dac 548 return 1;
0eee5820 549
252b5132 550 if (time_diff < 0.0)
ef368dac 551 return -1;
252b5132
RH
552
553 if (right->ncalls > left->ncalls)
ef368dac
NC
554 return 1;
555
252b5132 556 if (right->ncalls < left->ncalls)
ef368dac 557 return -1;
252b5132
RH
558
559 return strcmp (left->name, right->name);
560}
561
562
ef368dac
NC
563/* Print the flat histogram profile. */
564
252b5132 565void
1355568a 566hist_print ()
252b5132
RH
567{
568 Sym **time_sorted_syms, *top_dog, *sym;
91d6fa6a 569 unsigned int sym_index;
be5523fb 570 unsigned log_scale;
91d6fa6a 571 double top_time;
252b5132
RH
572 bfd_vma addr;
573
574 if (first_output)
b34976b6 575 first_output = FALSE;
252b5132 576 else
ef368dac 577 printf ("\f\n");
252b5132
RH
578
579 accum_time = 0.0;
0eee5820 580
252b5132
RH
581 if (bsd_style_output)
582 {
583 if (print_descriptions)
584 {
585 printf (_("\n\n\nflat profile:\n"));
586 flat_blurb (stdout);
587 }
588 }
589 else
590 {
591 printf (_("Flat profile:\n"));
592 }
0eee5820 593
ef368dac
NC
594 /* Sort the symbol table by time (call-count and name as secondary
595 and tertiary keys). */
252b5132 596 time_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
0eee5820 597
91d6fa6a
NC
598 for (sym_index = 0; sym_index < symtab.len; ++sym_index)
599 time_sorted_syms[sym_index] = &symtab.base[sym_index];
ef368dac 600
252b5132
RH
601 qsort (time_sorted_syms, symtab.len, sizeof (Sym *), cmp_time);
602
603 if (bsd_style_output)
604 {
ef368dac 605 log_scale = 5; /* Milli-seconds is BSD-default. */
252b5132
RH
606 }
607 else
608 {
ef368dac
NC
609 /* Search for symbol with highest per-call
610 execution time and scale accordingly. */
252b5132
RH
611 log_scale = 0;
612 top_dog = 0;
613 top_time = 0.0;
0eee5820 614
91d6fa6a 615 for (sym_index = 0; sym_index < symtab.len; ++sym_index)
252b5132 616 {
91d6fa6a 617 sym = time_sorted_syms[sym_index];
0eee5820 618
252b5132
RH
619 if (sym->ncalls != 0)
620 {
91d6fa6a 621 double call_time;
0eee5820 622
91d6fa6a
NC
623 call_time = (sym->hist.time + sym->cg.child_time) / sym->ncalls;
624
625 if (call_time > top_time)
252b5132
RH
626 {
627 top_dog = sym;
91d6fa6a 628 top_time = call_time;
252b5132
RH
629 }
630 }
631 }
0eee5820 632
252b5132
RH
633 if (top_dog && top_dog->ncalls != 0 && top_time > 0.0)
634 {
635 top_time /= hz;
0eee5820 636
be5523fb 637 for (log_scale = 0; log_scale < ARRAY_SIZE (SItab); log_scale ++)
252b5132 638 {
be5523fb
FCE
639 double scaled_value = SItab[log_scale].scale * top_time;
640
641 if (scaled_value >= 1.0 && scaled_value < 1000.0)
642 break;
252b5132
RH
643 }
644 }
645 }
646
ef368dac
NC
647 /* For now, the dimension is always seconds. In the future, we
648 may also want to support other (pseudo-)dimensions (such as
649 I-cache misses etc.). */
252b5132 650 print_header (SItab[log_scale].prefix);
0eee5820 651
91d6fa6a 652 for (sym_index = 0; sym_index < symtab.len; ++sym_index)
252b5132 653 {
91d6fa6a 654 addr = time_sorted_syms[sym_index]->addr;
0eee5820 655
ef368dac 656 /* Print symbol if its in INCL_FLAT table or that table
0eee5820 657 is empty and the symbol is not in EXCL_FLAT. */
252b5132
RH
658 if (sym_lookup (&syms[INCL_FLAT], addr)
659 || (syms[INCL_FLAT].len == 0
660 && !sym_lookup (&syms[EXCL_FLAT], addr)))
91d6fa6a 661 print_line (time_sorted_syms[sym_index], SItab[log_scale].scale);
252b5132 662 }
0eee5820 663
252b5132
RH
664 free (time_sorted_syms);
665
666 if (print_descriptions && !bsd_style_output)
ef368dac 667 flat_blurb (stdout);
252b5132 668}
b3296dc5
VP
669
670int
671hist_check_address (unsigned address)
672{
673 unsigned i;
674
675 for (i = 0; i < num_histograms; ++i)
676 if (histograms[i].lowpc <= address && address < histograms[i].highpc)
677 return 1;
678
679 return 0;
680}
681
682#if ! defined(min)
683#define min(a,b) (((a)<(b)) ? (a) : (b))
684#endif
685#if ! defined(max)
686#define max(a,b) (((a)>(b)) ? (a) : (b))
687#endif
688
689void
690hist_clip_symbol_address (bfd_vma *p_lowpc, bfd_vma *p_highpc)
691{
692 unsigned i;
693 int found = 0;
694
695 if (num_histograms == 0)
696 {
697 *p_highpc = *p_lowpc;
698 return;
699 }
700
701 for (i = 0; i < num_histograms; ++i)
702 {
703 bfd_vma common_low, common_high;
704 common_low = max (histograms[i].lowpc, *p_lowpc);
705 common_high = min (histograms[i].highpc, *p_highpc);
706
707 if (common_low < common_high)
708 {
709 if (found)
710 {
711 fprintf (stderr,
712 _("%s: found a symbol that covers "
e701ca86 713 "several histogram records"),
b3296dc5
VP
714 whoami);
715 done (1);
716 }
717
718 found = 1;
719 *p_lowpc = common_low;
720 *p_highpc = common_high;
721 }
722 }
723
724 if (!found)
725 *p_highpc = *p_lowpc;
726}
727
728/* Find and return exising histogram record having the same lowpc and
729 highpc as passed via the parameters. Return NULL if nothing is found.
730 The return value is valid until any new histogram is read. */
731static histogram *
732find_histogram (bfd_vma lowpc, bfd_vma highpc)
733{
734 unsigned i;
735 for (i = 0; i < num_histograms; ++i)
736 {
737 if (histograms[i].lowpc == lowpc && histograms[i].highpc == highpc)
738 return &histograms[i];
739 }
740 return 0;
741}
742
743/* Given a PC, return histogram record which address range include this PC.
744 Return NULL if there's no such record. */
745static histogram *
746find_histogram_for_pc (bfd_vma pc)
747{
748 unsigned i;
749 for (i = 0; i < num_histograms; ++i)
750 {
751 if (histograms[i].lowpc <= pc && pc < histograms[i].highpc)
752 return &histograms[i];
753 }
754 return 0;
755}
This page took 0.605399 seconds and 4 git commands to generate.