X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gprof%2Fcg_print.c;h=1722adfe22132d6652f8fdd9ef555b4090538f7b;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=ce8cbc417f6cfc87251e2f2c30625fa3f0704a22;hpb=651dbc76f217e10b4b03933f86fe9e5b39d382be;p=deliverable%2Fbinutils-gdb.git diff --git a/gprof/cg_print.c b/gprof/cg_print.c index ce8cbc417f..1722adfe22 100644 --- a/gprof/cg_print.c +++ b/gprof/cg_print.c @@ -1,6 +1,6 @@ /* cg_print.c - Print routines for displaying call graphs. - Copyright 2000, 2001, 2002, 2004, 2007 Free Software Foundation, Inc. + Copyright (C) 2000-2020 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -19,8 +19,9 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "libiberty.h" #include "gprof.h" +#include "libiberty.h" +#include "filenames.h" #include "search_list.h" #include "source.h" #include "symtab.h" @@ -60,7 +61,7 @@ double print_time = 0.0; static void -print_header () +print_header (void) { if (first_output) first_output = FALSE; @@ -76,7 +77,7 @@ print_header () } printf (_("\ngranularity: each sample hit covers %ld byte(s)"), - (long) hist_scale * sizeof (UNIT)); + (long) hist_scale * (long) sizeof (UNIT)); if (print_time > 0.0) printf (_(" for %.2f%% of %.2f seconds\n\n"), @@ -94,8 +95,11 @@ print_header () printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n", "", "", "", "", _("called"), _("total"), _("parents")); printf ("%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n", - _("index"), _("%time"), _("self"), _("descendants"), - _("called"), _("self"), _("name"), _("index")); + _("index"), + /* xgettext:no-c-format */ + _("%time"), + _("self"), _("descendants"), _("called"), _("self"), + _("name"), _("index")); printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n", "", "", "", "", _("called"), _("total"), _("children")); printf ("\n"); @@ -166,7 +170,7 @@ sort_members (Sym *cyc) todo = cyc->cg.cyc.next; cyc->cg.cyc.next = 0; - for (doing = todo; doing && doing->cg.cyc.next; doing = todo) + for (doing = todo; doing != NULL; doing = todo) { todo = doing->cg.cyc.next; @@ -498,7 +502,7 @@ print_line (Sym *np) void cg_print (Sym ** timesortsym) { - unsigned int index; + unsigned int sym_index; Sym *parent; if (print_descriptions && bsd_style_output) @@ -506,9 +510,9 @@ cg_print (Sym ** timesortsym) print_header (); - for (index = 0; index < symtab.len + num_cycles; ++index) + for (sym_index = 0; sym_index < symtab.len + num_cycles; ++sym_index) { - parent = timesortsym[index]; + parent = timesortsym[sym_index]; if ((ignore_zeros && parent->ncalls == 0 && parent->cg.self_calls == 0 && parent->cg.prop.self == 0 @@ -557,9 +561,9 @@ cmp_name (const PTR left, const PTR right) void -cg_print_index () +cg_print_index (void) { - unsigned int index; + unsigned int sym_index; unsigned int nnames, todo, i, j; int col, starting_col; Sym **name_sorted_syms, *sym; @@ -571,30 +575,30 @@ cg_print_index () alphabetically to create an index. */ name_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *)); - for (index = 0, nnames = 0; index < symtab.len; index++) + for (sym_index = 0, nnames = 0; sym_index < symtab.len; sym_index++) { - if (ignore_zeros && symtab.base[index].ncalls == 0 - && symtab.base[index].hist.time == 0) + if (ignore_zeros && symtab.base[sym_index].ncalls == 0 + && symtab.base[sym_index].hist.time == 0) continue; - name_sorted_syms[nnames++] = &symtab.base[index]; + name_sorted_syms[nnames++] = &symtab.base[sym_index]; } qsort (name_sorted_syms, nnames, sizeof (Sym *), cmp_name); - for (index = 1, todo = nnames; index <= num_cycles; index++) - name_sorted_syms[todo++] = &cycle_header[index]; + for (sym_index = 1, todo = nnames; sym_index <= num_cycles; sym_index++) + name_sorted_syms[todo++] = &cycle_header[sym_index]; printf ("\f\n"); printf (_("Index by function name\n\n")); - index = (todo + 2) / 3; + sym_index = (todo + 2) / 3; - for (i = 0; i < index; i++) + for (i = 0; i < sym_index; i++) { col = 0; starting_col = 0; - for (j = i; j < todo; j += index) + for (j = i; j < todo; j += sym_index) { sym = name_sorted_syms[j]; @@ -770,9 +774,11 @@ cmp_fun_nuses (const PTR left, const PTR right) of function ordering). */ void -cg_print_function_ordering () +cg_print_function_ordering (void) { - unsigned long index, used, unused, scratch_index; + unsigned long sym_index; + unsigned long arc_index; + unsigned long used, unused, scratch_index; unsigned long unplaced_arc_count, high_arc_count, scratch_arc_count; #ifdef __GNUC__ unsigned long long total_arcs, tmp_arcs_count; @@ -782,7 +788,7 @@ cg_print_function_ordering () Sym **unused_syms, **used_syms, **scratch_syms; Arc **unplaced_arcs, **high_arcs, **scratch_arcs; - index = 0; + sym_index = 0; used = 0; unused = 0; scratch_index = 0; @@ -800,25 +806,20 @@ cg_print_function_ordering () /* Walk through all the functions; mark those which are never called as placed (we'll emit them as a group later). */ - for (index = 0, used = 0, unused = 0; index < symtab.len; index++) + for (sym_index = 0, used = 0, unused = 0; sym_index < symtab.len; sym_index++) { - if (symtab.base[index].ncalls == 0) + if (symtab.base[sym_index].ncalls == 0) { - /* Filter out gprof generated names. */ - if (strcmp (symtab.base[index].name, "") - && strcmp (symtab.base[index].name, "")) - { - unused_syms[unused++] = &symtab.base[index]; - symtab.base[index].has_been_placed = 1; - } + unused_syms[unused++] = &symtab.base[sym_index]; + symtab.base[sym_index].has_been_placed = 1; } else { - used_syms[used++] = &symtab.base[index]; - symtab.base[index].has_been_placed = 0; - symtab.base[index].next = 0; - symtab.base[index].prev = 0; - symtab.base[index].nuses = 0; + used_syms[used++] = &symtab.base[sym_index]; + symtab.base[sym_index].has_been_placed = 0; + symtab.base[sym_index].next = 0; + symtab.base[sym_index].prev = 0; + symtab.base[sym_index].nuses = 0; } } @@ -831,26 +832,26 @@ cg_print_function_ordering () Overflow is much less likely when this file is compiled with GCC as it can double-wide integers via long long. */ total_arcs = 0; - for (index = 0; index < numarcs; index++) + for (arc_index = 0; arc_index < numarcs; arc_index++) { - total_arcs += arcs[index]->count; - arcs[index]->has_been_placed = 0; + total_arcs += arcs[arc_index]->count; + arcs[arc_index]->has_been_placed = 0; } /* We want to pull out those functions which are referenced by many highly used arcs and emit them as a group. This could probably use some tuning. */ tmp_arcs_count = 0; - for (index = 0; index < numarcs; index++) + for (arc_index = 0; arc_index < numarcs; arc_index++) { - tmp_arcs_count += arcs[index]->count; + tmp_arcs_count += arcs[arc_index]->count; /* Count how many times each parent and child are used up - to our threshhold of arcs (90%). */ + to our threshold of arcs (90%). */ if ((double)tmp_arcs_count / (double)total_arcs > 0.90) break; - arcs[index]->child->nuses++; + arcs[arc_index]->child->nuses++; } /* Now sort a temporary symbol table based on the number of @@ -860,9 +861,9 @@ cg_print_function_ordering () /* Now pick out those symbols we're going to emit as a group. We take up to 1.25% of the used symbols. */ - for (index = 0; index < used / 80; index++) + for (sym_index = 0; sym_index < used / 80; sym_index++) { - Sym *sym = scratch_syms[index]; + Sym *sym = scratch_syms[sym_index]; Arc *arc; /* If we hit symbols that aren't used from many call sites, @@ -901,7 +902,7 @@ cg_print_function_ordering () } /* Keep track of how many symbols we're going to place. */ - scratch_index = index; + scratch_index = sym_index; /* A lie, but it makes identifying these functions easier later. */ @@ -910,16 +911,16 @@ cg_print_function_ordering () /* Now walk through the temporary arcs and copy those we care about into the high arcs array. */ - for (index = 0; index < scratch_arc_count; index++) + for (arc_index = 0; arc_index < scratch_arc_count; arc_index++) { - Arc *arc = scratch_arcs[index]; + Arc *arc = scratch_arcs[arc_index]; /* If this arc refers to highly used functions, then then we want to keep it. */ if (arc->child->has_been_placed && arc->parent->has_been_placed) { - high_arcs[high_arc_count++] = scratch_arcs[index]; + high_arcs[high_arc_count++] = scratch_arcs[arc_index]; /* We need to turn of has_been_placed since we're going to use the main arc placement algorithm on these arcs. */ @@ -930,10 +931,10 @@ cg_print_function_ordering () /* Dump the multi-site high usage functions which are not going to be ordered by the main ordering algorithm. */ - for (index = 0; index < scratch_index; index++) + for (sym_index = 0; sym_index < scratch_index; sym_index++) { - if (scratch_syms[index]->has_been_placed) - printf ("%s\n", scratch_syms[index]->name); + if (scratch_syms[sym_index]->has_been_placed) + printf ("%s\n", scratch_syms[sym_index]->name); } /* Now we can order the multi-site high use @@ -952,13 +953,13 @@ cg_print_function_ordering () scratch_arcs, &scratch_arc_count); /* Output any functions not emitted by the order_and_dump calls. */ - for (index = 0; index < used; index++) - if (used_syms[index]->has_been_placed == 0) - printf("%s\n", used_syms[index]->name); + for (sym_index = 0; sym_index < used; sym_index++) + if (used_syms[sym_index]->has_been_placed == 0) + printf("%s\n", used_syms[sym_index]->name); /* Output the unused functions. */ - for (index = 0; index < unused; index++) - printf("%s\n", unused_syms[index]->name); + for (sym_index = 0; sym_index < unused; sym_index++) + printf("%s\n", unused_syms[sym_index]->name); unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *)); @@ -983,20 +984,16 @@ cg_print_function_ordering () #define MOST 0.99 static void -order_and_dump_functions_by_arcs (the_arcs, arc_count, all, - unplaced_arcs, unplaced_arc_count) - Arc **the_arcs; - unsigned long arc_count; - int all; - Arc **unplaced_arcs; - unsigned long *unplaced_arc_count; +order_and_dump_functions_by_arcs (Arc **the_arcs, unsigned long arc_count, + int all, Arc **unplaced_arcs, + unsigned long *unplaced_arc_count) { #ifdef __GNUC__ unsigned long long tmp_arcs, total_arcs; #else unsigned long tmp_arcs, total_arcs; #endif - unsigned int index; + unsigned int arc_index; /* If needed, compute the total arc count. @@ -1004,27 +1001,27 @@ order_and_dump_functions_by_arcs (the_arcs, arc_count, all, if (! all) { total_arcs = 0; - for (index = 0; index < arc_count; index++) - total_arcs += the_arcs[index]->count; + for (arc_index = 0; arc_index < arc_count; arc_index++) + total_arcs += the_arcs[arc_index]->count; } else total_arcs = 0; tmp_arcs = 0; - for (index = 0; index < arc_count; index++) + for (arc_index = 0; arc_index < arc_count; arc_index++) { Sym *sym1, *sym2; Sym *child, *parent; - tmp_arcs += the_arcs[index]->count; + tmp_arcs += the_arcs[arc_index]->count; /* Ignore this arc if it's already been placed. */ - if (the_arcs[index]->has_been_placed) + if (the_arcs[arc_index]->has_been_placed) continue; - child = the_arcs[index]->child; - parent = the_arcs[index]->parent; + child = the_arcs[arc_index]->child; + parent = the_arcs[arc_index]->parent; /* If we're not using all arcs, and this is a rarely used arc, then put it on the unplaced_arc list. Similarly @@ -1032,7 +1029,7 @@ order_and_dump_functions_by_arcs (the_arcs, arc_count, all, if ((! all && (double)tmp_arcs / (double)total_arcs > MOST) || child->has_been_placed || parent->has_been_placed) { - unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index]; + unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[arc_index]; continue; } @@ -1042,7 +1039,7 @@ order_and_dump_functions_by_arcs (the_arcs, arc_count, all, algorithm can use it to place function chains. */ if (parent->next && parent->prev && child->next && child->prev) { - unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index]; + unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[arc_index]; continue; } @@ -1097,7 +1094,7 @@ order_and_dump_functions_by_arcs (the_arcs, arc_count, all, { /* Couldn't find anywhere to attach the functions, put the arc on the unplaced arc list. */ - unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index]; + unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[arc_index]; continue; } @@ -1122,7 +1119,7 @@ order_and_dump_functions_by_arcs (the_arcs, arc_count, all, && sym2 == parent) { /* This would tie two ends together. */ - unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index]; + unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[arc_index]; continue; } @@ -1134,7 +1131,7 @@ order_and_dump_functions_by_arcs (the_arcs, arc_count, all, /* parent-prev and child-next */ parent->prev = child; child->next = parent; - the_arcs[index]->has_been_placed = 1; + the_arcs[arc_index]->has_been_placed = 1; } } else if (parent->prev) @@ -1145,7 +1142,7 @@ order_and_dump_functions_by_arcs (the_arcs, arc_count, all, /* parent-next and child-prev */ parent->next = child; child->prev = parent; - the_arcs[index]->has_been_placed = 1; + the_arcs[arc_index]->has_been_placed = 1; } } else @@ -1157,27 +1154,27 @@ order_and_dump_functions_by_arcs (the_arcs, arc_count, all, /* parent-prev and child-next. */ parent->prev = child; child->next = parent; - the_arcs[index]->has_been_placed = 1; + the_arcs[arc_index]->has_been_placed = 1; } else { /* parent-next and child-prev. */ parent->next = child; child->prev = parent; - the_arcs[index]->has_been_placed = 1; + the_arcs[arc_index]->has_been_placed = 1; } } } /* Dump the chains of functions we've made. */ - for (index = 0; index < arc_count; index++) + for (arc_index = 0; arc_index < arc_count; arc_index++) { Sym *sym; - if (the_arcs[index]->parent->has_been_placed - || the_arcs[index]->child->has_been_placed) + if (the_arcs[arc_index]->parent->has_been_placed + || the_arcs[arc_index]->child->has_been_placed) continue; - sym = the_arcs[index]->parent; + sym = the_arcs[arc_index]->parent; /* If this symbol isn't attached to any other symbols, then we've got a rarely used arc. @@ -1203,61 +1200,75 @@ order_and_dump_functions_by_arcs (the_arcs, arc_count, all, /* If we want to place all the arcs, then output those which weren't placed by the main algorithm. */ if (all) - for (index = 0; index < arc_count; index++) + for (arc_index = 0; arc_index < arc_count; arc_index++) { Sym *sym; - if (the_arcs[index]->parent->has_been_placed - || the_arcs[index]->child->has_been_placed) + if (the_arcs[arc_index]->parent->has_been_placed + || the_arcs[arc_index]->child->has_been_placed) continue; - sym = the_arcs[index]->parent; + sym = the_arcs[arc_index]->parent; sym->has_been_placed = 1; printf ("%s\n", sym->name); } } +/* Compare two function_map structs based on file name. + We want to sort in ascending order. */ + +static int +cmp_symbol_map (const void * l, const void * r) +{ + return filename_cmp (((struct function_map *) l)->file_name, + ((struct function_map *) r)->file_name); +} + /* Print a suggested .o ordering for files on a link line based on profiling information. This uses the function placement code for the bulk of its work. */ void -cg_print_file_ordering () +cg_print_file_ordering (void) { - unsigned long scratch_arc_count, index; + unsigned long scratch_arc_count; + unsigned long arc_index; + unsigned long sym_index; Arc **scratch_arcs; char *last; scratch_arc_count = 0; scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *)); - for (index = 0; index < numarcs; index++) + for (arc_index = 0; arc_index < numarcs; arc_index++) { - if (! arcs[index]->parent->mapped - || ! arcs[index]->child->mapped) - arcs[index]->has_been_placed = 1; + if (! arcs[arc_index]->parent->mapped + || ! arcs[arc_index]->child->mapped) + arcs[arc_index]->has_been_placed = 1; } order_and_dump_functions_by_arcs (arcs, numarcs, 0, scratch_arcs, &scratch_arc_count); /* Output .o's not handled by the main placement algorithm. */ - for (index = 0; index < symtab.len; index++) + for (sym_index = 0; sym_index < symtab.len; sym_index++) { - if (symtab.base[index].mapped - && ! symtab.base[index].has_been_placed) - printf ("%s\n", symtab.base[index].name); + if (symtab.base[sym_index].mapped + && ! symtab.base[sym_index].has_been_placed) + printf ("%s\n", symtab.base[sym_index].name); } + qsort (symbol_map, symbol_map_count, sizeof (struct function_map), cmp_symbol_map); + /* Now output any .o's that didn't have any text symbols. */ last = NULL; - for (index = 0; index < symbol_map_count; index++) + for (sym_index = 0; sym_index < symbol_map_count; sym_index++) { unsigned int index2; /* Don't bother searching if this symbol is the same as the previous one. */ - if (last && !strcmp (last, symbol_map[index].file_name)) + if (last && !filename_cmp (last, symbol_map[sym_index].file_name)) continue; for (index2 = 0; index2 < symtab.len; index2++) @@ -1265,14 +1276,15 @@ cg_print_file_ordering () if (! symtab.base[index2].mapped) continue; - if (!strcmp (symtab.base[index2].name, symbol_map[index].file_name)) + if (!filename_cmp (symtab.base[index2].name, + symbol_map[sym_index].file_name)) break; } /* If we didn't find it in the symbol table, then it must be a .o with no text symbols. Output it last. */ if (index2 == symtab.len) - printf ("%s\n", symbol_map[index].file_name); - last = symbol_map[index].file_name; + printf ("%s\n", symbol_map[sym_index].file_name); + last = symbol_map[sym_index].file_name; } }