X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gprof%2Fbasic_blocks.c;h=a37ca0b2441e4cc6aa8b831b3b5aa9789aa3d6ac;hb=06846494cea461fe8d487d2f8611cd4dd6fc3d36;hp=7e42073e4a3e8a0e18abeadf1f80289c8fedd521;hpb=37503931d0e0114248e20c27c117f326a6e48963;p=deliverable%2Fbinutils-gdb.git diff --git a/gprof/basic_blocks.c b/gprof/basic_blocks.c index 7e42073e4a..a37ca0b244 100644 --- a/gprof/basic_blocks.c +++ b/gprof/basic_blocks.c @@ -2,7 +2,7 @@ of basic-block info to/from gmon.out; computing and formatting of basic-block related statistics. - Copyright 2000, 2001 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -21,21 +21,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include +#include "libiberty.h" +#include "gprof.h" #include "basic_blocks.h" #include "corefile.h" #include "gmon_io.h" #include "gmon_out.h" -#include "gprof.h" -#include "libiberty.h" +#include "search_list.h" #include "source.h" +#include "symtab.h" #include "sym_ids.h" -#ifdef HAVE_UNISTD_H -#include -#endif + +static int cmp_bb PARAMS ((const PTR, const PTR)); +static int cmp_ncalls PARAMS ((const PTR, const PTR)); +static void fskip_string PARAMS ((FILE *)); +static void annotate_with_count PARAMS ((char *, unsigned int, int, PTR)); /* Default option values: */ -bool bb_annotate_all_lines = FALSE; +bfd_boolean bb_annotate_all_lines = FALSE; unsigned long bb_min_calls = 1; int bb_table_length = 10; @@ -49,7 +52,9 @@ static long num_lines_executed; number, and address (in that order). */ static int -DEFUN (cmp_bb, (lp, rp), const void *lp AND const void *rp) +cmp_bb (lp, rp) + const PTR lp; + const PTR rp; { int r; const Sym *left = *(const Sym **) lp; @@ -58,7 +63,7 @@ DEFUN (cmp_bb, (lp, rp), const void *lp AND const void *rp) if (left->file && right->file) { r = strcmp (left->file->name, right->file->name); - + if (r) return r; @@ -78,7 +83,9 @@ DEFUN (cmp_bb, (lp, rp), const void *lp AND const void *rp) /* Helper for sorting. Order basic blocks in decreasing number of calls, ties are broken in increasing order of line numbers. */ static int -DEFUN (cmp_ncalls, (lp, rp), const void *lp AND const void *rp) +cmp_ncalls (lp, rp) + const PTR lp; + const PTR rp; { const Sym *left = *(const Sym **) lp; const Sym *right = *(const Sym **) rp; @@ -98,7 +105,8 @@ DEFUN (cmp_ncalls, (lp, rp), const void *lp AND const void *rp) /* Skip over variable length string. */ static void -DEFUN (fskip_string, (fp), FILE * fp) +fskip_string (fp) + FILE *fp; { int ch; @@ -113,21 +121,22 @@ DEFUN (fskip_string, (fp), FILE * fp) of file IFP and is provided for formatting error-messages only. */ void -DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename) +bb_read_rec (ifp, filename) + FILE *ifp; + const char *filename; { int nblocks, b; - bfd_vma addr; - unsigned long ncalls; + bfd_vma addr, ncalls; Sym *sym; - if (fread (&nblocks, sizeof (nblocks), 1, ifp) != 1) + if (gmon_io_read_32 (ifp, &nblocks)) { - fprintf (stderr, _("%s: %s: unexpected end of file\n"), whoami, filename); + fprintf (stderr, _("%s: %s: unexpected end of file\n"), + whoami, filename); done (1); } nblocks = bfd_get_32 (core_bfd, (bfd_byte *) & nblocks); - if (gmon_file_version == 0) fskip_string (ifp); @@ -136,7 +145,7 @@ DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename) if (gmon_file_version == 0) { int line_num; - + /* Version 0 had lots of extra stuff that we don't care about anymore. */ if ((fread (&ncalls, sizeof (ncalls), 1, ifp) != 1) @@ -149,24 +158,17 @@ DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename) done (1); } } - else + else if (gmon_io_read_vma (ifp, &addr) + || gmon_io_read_vma (ifp, &ncalls)) { - if (fread (&addr, sizeof (addr), 1, ifp) != 1 - || fread (&ncalls, sizeof (ncalls), 1, ifp) != 1) - { - perror (filename); - done (1); - } + perror (filename); + done (1); } /* Basic-block execution counts are meaningful only if we're - profiling at the line-by-line level: */ + profiling at the line-by-line level: */ if (line_granularity) { - /* Convert from target to host endianness: */ - addr = get_vma (core_bfd, (bfd_byte *) & addr); - ncalls = bfd_get_32 (core_bfd, (bfd_byte *) &ncalls); - sym = sym_lookup (&symtab, addr); if (sym) @@ -176,7 +178,7 @@ DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename) DBG (BBDEBUG, printf ("[bb_read_rec] 0x%lx->0x%lx (%s:%d) cnt=%lu\n", (unsigned long) addr, (unsigned long) sym->addr, - sym->name, sym->line_num, ncalls)); + sym->name, sym->line_num, (unsigned long) ncalls)); for (i = 0; i < NBBS; i++) { @@ -191,7 +193,7 @@ DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename) } else { - static bool user_warned = FALSE; + static bfd_boolean user_warned = FALSE; if (!user_warned) { @@ -209,12 +211,11 @@ DEFUN (bb_read_rec, (ifp, filename), FILE * ifp AND const char *filename) is the name of OFP and is provided for producing error-messages only. */ void -DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename) +bb_write_blocks (ofp, filename) + FILE *ofp; + const char *filename; { - const unsigned char tag = GMON_TAG_BB_COUNT; - int nblocks = 0; - bfd_vma addr; - unsigned long ncalls; + unsigned int nblocks = 0; Sym *sym; int i; @@ -227,9 +228,8 @@ DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename) } /* Write header: */ - bfd_put_32 (core_bfd, nblocks, (bfd_byte *) & nblocks); - if (fwrite (&tag, sizeof (tag), 1, ofp) != 1 - || fwrite (&nblocks, sizeof (nblocks), 1, ofp) != 1) + if (gmon_io_write_8 (ofp, GMON_TAG_BB_COUNT) + || gmon_io_write_32 (ofp, nblocks)) { perror (filename); done (1); @@ -240,11 +240,8 @@ DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename) { for (i = 0; i < NBBS && sym->bb_addr[i]; i++) { - put_vma (core_bfd, sym->bb_addr[i], (bfd_byte *) & addr); - bfd_put_32 (core_bfd, sym->bb_calls[i], (bfd_byte *) & ncalls); - - if (fwrite (&addr, sizeof (addr), 1, ofp) != 1 - || fwrite (&ncalls, sizeof (ncalls), 1, ofp) != 1) + if (gmon_io_write_vma (ofp, sym->bb_addr[i]) + || gmon_io_write_vma (ofp, (bfd_vma) sym->bb_calls[i])) { perror (filename); done (1); @@ -255,14 +252,14 @@ DEFUN (bb_write_blocks, (ofp, filename), FILE * ofp AND const char *filename) /* Output basic-block statistics in a format that is easily parseable. Current the format is: - - :: (: */ + + :: (: */ void -DEFUN_VOID (print_exec_counts) +print_exec_counts () { Sym **sorted_bbs, *sym; - int i, j, len; + unsigned int i, j, len; if (first_output) first_output = FALSE; @@ -272,12 +269,12 @@ DEFUN_VOID (print_exec_counts) /* Sort basic-blocks according to function name and line number: */ sorted_bbs = (Sym **) xmalloc (symtab.len * sizeof (sorted_bbs[0])); len = 0; - + 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 - and it does not appear in the EXCL_EXEC table. */ + or there is no INCL_EXEC table + and it does not appear in the EXCL_EXEC table. */ if (sym_lookup (&syms[INCL_EXEC], sym->addr) || (syms[INCL_EXEC].len == 0 && !sym_lookup (&syms[EXCL_EXEC], sym->addr))) @@ -285,7 +282,7 @@ DEFUN_VOID (print_exec_counts) sorted_bbs[len++] = sym; } } - + qsort (sorted_bbs, len, sizeof (sorted_bbs[0]), cmp_bb); /* Output basic-blocks: */ @@ -299,7 +296,7 @@ DEFUN_VOID (print_exec_counts) sym->file ? sym->file->name : _(""), sym->line_num, sym->name, (unsigned long) sym->addr, sym->ncalls); } - + for (j = 0; j < NBBS && sym->bb_addr[j]; j ++) { if (sym->bb_calls[j] > 0 || ! ignore_zeros) @@ -318,7 +315,7 @@ DEFUN_VOID (print_exec_counts) /* Helper for bb_annotated_source: format annotation containing number of line executions. Depends on being called on each line of a file in sequential order. - + Global variable bb_annotate_all_lines enables execution count compression (counts are supressed if identical to the last one) and prints counts on all executed lines. Otherwise, print @@ -326,17 +323,20 @@ DEFUN_VOID (print_exec_counts) that starts the basic-block. */ static void -DEFUN (annotate_with_count, (buf, width, line_num, arg), - char *buf AND int width AND int line_num AND void *arg) +annotate_with_count (buf, width, line_num, arg) + char *buf; + unsigned int width; + int line_num; + PTR arg; { Source_File *sf = arg; Sym *b; - int i; + unsigned int i; static unsigned long last_count; unsigned long last_print = (unsigned long) -1; b = NULL; - + if (line_num <= sf->num_lines) b = sf->line[line_num - 1]; @@ -352,7 +352,7 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg), char *p; unsigned long ncalls; int ncalls_set; - int len; + unsigned int len; ++num_executable_lines; @@ -363,11 +363,11 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg), ncalls_set = 0; /* If this is a function entry point, label the line no matter what. - Otherwise, we're in the middle of a function, so check to see - if the first basic-block address is larger than the starting - address of the line. If so, then this line begins with a - a portion of the previous basic-block, so print that prior - execution count (if bb_annotate_all_lines is set). */ + Otherwise, we're in the middle of a function, so check to see + if the first basic-block address is larger than the starting + address of the line. If so, then this line begins with a + a portion of the previous basic-block, so print that prior + execution count (if bb_annotate_all_lines is set). */ if (b->is_func) { sprintf (p, "%lu", b->ncalls); @@ -388,8 +388,8 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg), } /* Loop through all of this line's basic-blocks. For each one, - update last_count, then compress sequential identical counts - (if bb_annotate_all_lines) and print the execution count. */ + update last_count, then compress sequential identical counts + (if bb_annotate_all_lines) and print the execution count. */ for (i = 0; i < NBBS && b->bb_addr[i]; i++) { @@ -413,10 +413,10 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg), } /* We're done. If nothing has been printed on this line, - print the last execution count (bb_annotate_all_lines), - which could be from either a previous line (if there were - no BBs on this line), or from this line (if all our BB - counts were compressed out because they were identical). */ + print the last execution count (bb_annotate_all_lines), + which could be from either a previous line (if there were + no BBs on this line), or from this line (if all our BB + counts were compressed out because they were identical). */ if (bb_annotate_all_lines && p == tmpbuf) { @@ -428,7 +428,7 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg), if (! ncalls_set) { - int c; + unsigned int c; for (c = 0; c < width; c++) buf[c] = ' '; @@ -455,7 +455,7 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg), } else { - int c; + unsigned int c; strcpy (buf + width - len, tmpbuf); for (c = 0; c < width - len; ++c) @@ -469,7 +469,7 @@ DEFUN (annotate_with_count, (buf, width, line_num, arg), regarding that source file are printed. */ void -DEFUN_VOID (print_annotated_source) +print_annotated_source () { Sym *sym, *line_stats, *new_line; Source_File *sf; @@ -481,9 +481,9 @@ DEFUN_VOID (print_annotated_source) 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 - if it's in the INCL_ANNO table or there is no INCL_ANNO - table and it does not appear in the EXCL_ANNO table. */ + bigger than anything we have seen for that file so far and + if it's in the INCL_ANNO table or there is no INCL_ANNO + table and it does not appear in the EXCL_ANNO table. */ if (sym->file && sym->line_num > sym->file->num_lines && (sym_lookup (&syms[INCL_ANNO], sym->addr) || (syms[INCL_ANNO].len == 0 @@ -513,7 +513,7 @@ DEFUN_VOID (print_annotated_source) { sym->file->ncalls += sym->ncalls; line_stats = sym->file->line[sym->line_num - 1]; - + if (!line_stats) { /* Common case has at most one basic-block per source line: */ @@ -543,7 +543,7 @@ DEFUN_VOID (print_annotated_source) continue; num_executable_lines = num_lines_executed = 0; - + ofp = annotate_source (sf, 16, annotate_with_count, sf); if (!ofp) continue; @@ -556,14 +556,14 @@ DEFUN_VOID (print_annotated_source) /* Abuse line arrays---it's not needed anymore: */ qsort (sf->line, sf->num_lines, sizeof (sf->line[0]), cmp_ncalls); table_len = bb_table_length; - + if (table_len > sf->num_lines) table_len = sf->num_lines; - + for (i = 0; i < table_len; ++i) { sym = sf->line[i]; - + if (!sym || sym->ncalls == 0) break; @@ -588,7 +588,7 @@ DEFUN_VOID (print_annotated_source) num_executable_lines ? (double) sf->ncalls / (double) num_executable_lines : 0.0); - + if (ofp != stdout) fclose (ofp); }