mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
gprof: only process line numbers for intersection of vmas and histograms
Some programs like RTOS firmware may have a large number of symbols. The profile information in the profile data file includes histogram records, which capture low PC and high PC of program execution. If all histogram records come in the profile data file before any call-graph records and basic-block records, we can look up only the line numbers within low PC and high PC in histogram records, which reduces processing time for such a firmware from ~2 minutes to ~2 seconds. Add symbol table access function, get_symtab, get_symtab_direct and set_symtab to delay loading the symbol table until its first use. * aarch64.c (aarch64_find_call): Call get_symtab to get the symbol table pointer * alpha.c (alpha_find_call): Likewise. * basic_blocks.c (bb_read_rec): Likewise. (bb_write_blocks): Likewise. (print_exec_counts): Likewise. (print_annotated_source): Likewise. * call_graph.c (cg_tally): Likewise. (cg_write_arcs): Likewise. * cg_arcs.c (cycle_link): Likewise. (propagate_flags): Likewise. (cg_assemble): Likewise. * cg_print.c (cg_print): Likewise. (cg_print_index): Likewise. (cg_print_function_ordering): Likewise. * corefile.c: Include "gmon_io.h". (core_create_syms_from): Call get_symtab_direct to get the symbol table pointer. (core_create_function_syms): Likewise. (core_create_line_syms): Likewise. If all histogram records come in the profile data file before any call-graph records and basic-block records, we can look up only the line numbers within low PC and high PC in histogram records. * gmon_io.c (gmon_histograms_first): New. (gmon_out_read): Set gmon_histograms_first to true if all histogram records come first. (gmon_out_write): Call get_symtab to get the symbol table pointer. * hist.c (scale_and_align_entries): Likewise. (hist_assign_samples_1): Likewise. (hist_print): Likewise. * i386.c (i386_find_call): Likewise. * mips.c (mips_find_call): Likewise. * sparc.c (sparc_find_call): Likewise. * sym_ids.c (sym_id_parse): Likewise. * vax.c (vax_find_call): Likewise. * gmon_io.h (gmon_histograms_first): New. * gprof.c (man): Don't create profile info. (symtab_init): New. * gprof.h (symtab_init): New. * symtab.c (symtab): Changed to static. (get_symtab_direct): New. (get_symtab): Likewise. (set_symtab): Likewise. * symtab.h (symtab): Removed. (get_symtab_direct): New. (get_symtab): Likewise. (set_symtab): Likewise. Signed-off-by: Richard Allen <rsaxvc@gmail.com> Co-Authored-By: H.J. Lu <hjl.tools@gmail.com>
This commit is contained in:
@@ -122,6 +122,7 @@ bb_read_rec (FILE *ifp, const char *filename)
|
||||
unsigned int nblocks, b;
|
||||
bfd_vma addr, ncalls;
|
||||
Sym *sym;
|
||||
Sym_Table *symtab;
|
||||
|
||||
if (gmon_io_read_32 (ifp, &nblocks))
|
||||
{
|
||||
@@ -130,6 +131,8 @@ bb_read_rec (FILE *ifp, const char *filename)
|
||||
done (1);
|
||||
}
|
||||
|
||||
symtab = get_symtab ();
|
||||
|
||||
nblocks = bfd_get_32 (core_bfd, (bfd_byte *) & nblocks);
|
||||
if (gmon_file_version == 0)
|
||||
fskip_string (ifp);
|
||||
@@ -163,7 +166,7 @@ bb_read_rec (FILE *ifp, const char *filename)
|
||||
profiling at the line-by-line level: */
|
||||
if (line_granularity)
|
||||
{
|
||||
sym = sym_lookup (&symtab, addr);
|
||||
sym = sym_lookup (symtab, addr);
|
||||
|
||||
if (sym)
|
||||
{
|
||||
@@ -210,9 +213,10 @@ bb_write_blocks (FILE *ofp, const char *filename)
|
||||
unsigned int nblocks = 0;
|
||||
Sym *sym;
|
||||
int i;
|
||||
Sym_Table *symtab = get_symtab ();
|
||||
|
||||
/* Count how many non-zero blocks with have: */
|
||||
for (sym = symtab.base; sym < symtab.limit; ++sym)
|
||||
for (sym = symtab->base; sym < symtab->limit; ++sym)
|
||||
{
|
||||
for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
|
||||
;
|
||||
@@ -228,7 +232,7 @@ bb_write_blocks (FILE *ofp, const char *filename)
|
||||
}
|
||||
|
||||
/* Write counts: */
|
||||
for (sym = symtab.base; sym < symtab.limit; ++sym)
|
||||
for (sym = symtab->base; sym < symtab->limit; ++sym)
|
||||
{
|
||||
for (i = 0; i < NBBS && sym->bb_addr[i]; i++)
|
||||
{
|
||||
@@ -252,6 +256,7 @@ print_exec_counts (void)
|
||||
{
|
||||
Sym **sorted_bbs, *sym;
|
||||
unsigned int i, j, len;
|
||||
Sym_Table *symtab = get_symtab ();
|
||||
|
||||
if (first_output)
|
||||
first_output = false;
|
||||
@@ -259,10 +264,10 @@ print_exec_counts (void)
|
||||
printf ("\f\n");
|
||||
|
||||
/* Sort basic-blocks according to function name and line number: */
|
||||
sorted_bbs = (Sym **) xmalloc (symtab.len * sizeof (sorted_bbs[0]));
|
||||
sorted_bbs = (Sym **) xmalloc (symtab->len * sizeof (sorted_bbs[0]));
|
||||
len = 0;
|
||||
|
||||
for (sym = symtab.base; sym < symtab.limit; ++sym)
|
||||
for (sym = symtab->base; sym < symtab->limit; ++sym)
|
||||
{
|
||||
/* Accept symbol if it's in the INCL_EXEC table
|
||||
or there is no INCL_EXEC table
|
||||
@@ -461,10 +466,11 @@ print_annotated_source (void)
|
||||
Source_File *sf;
|
||||
int i, table_len;
|
||||
FILE *ofp;
|
||||
Sym_Table *symtab = get_symtab ();
|
||||
|
||||
/* Find maximum line number for each source file that user is
|
||||
interested in: */
|
||||
for (sym = symtab.base; sym < symtab.limit; ++sym)
|
||||
for (sym = symtab->base; sym < symtab->limit; ++sym)
|
||||
{
|
||||
/* Accept symbol if it's file is known, its line number is
|
||||
bigger than anything we have seen for that file so far and
|
||||
@@ -490,7 +496,7 @@ print_annotated_source (void)
|
||||
}
|
||||
|
||||
/* Count executions per line: */
|
||||
for (sym = symtab.base; sym < symtab.limit; ++sym)
|
||||
for (sym = symtab->base; sym < symtab->limit; ++sym)
|
||||
{
|
||||
if (sym->file && sym->file->num_lines
|
||||
&& (sym_lookup (&syms[INCL_ANNO], sym->addr)
|
||||
|
||||
Reference in New Issue
Block a user