From 796621e8c274bfce5c7f3f1d23126267b91f102f Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 24 Apr 2003 09:46:17 +0000 Subject: [PATCH] New GCOV_TAG_FUNCTION layout New GCOV_TAG_FUNCTION layout * coverage.c (struct function_list): Replace name with ident. (struct counts_entry): Likewise. (fn_ident): New. (htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del): Adjust. (reads_count_file, get_coverage_counts, coverage_begin_output, coverage_end_function): Adjust. (build_fn_info_type, build_fn_info_value): Likewise. * gcov-dump.c (tag_function): Adjust. * gcov-io.c (gcov_write_string, gcov_read_string): Not in LIBGCOV. * gcov-io.h (gcov_write_string, gcov_read_string): Not in LIBGCOV. * gcov.c (struct function_info): Add ident. (read_graph_file, read_count_file): Adjust. * libgcov.c (gcov_exit): Adjust. From-SVN: r66035 --- gcc/ChangeLog | 18 ++++++++++++++ gcc/coverage.c | 74 ++++++++++++++++++++++++--------------------------------- gcc/gcov-dump.c | 10 ++++---- gcc/gcov-io.c | 4 ++++ gcc/gcov-io.h | 20 +++++++++------- gcc/gcov.c | 17 +++++++------ gcc/libgcov.c | 18 +++++++------- 7 files changed, 89 insertions(+), 72 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5745284..a4dd1da 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2003-04-24 Nathan Sidwell + + New GCOV_TAG_FUNCTION layout + * coverage.c (struct function_list): Replace name with ident. + (struct counts_entry): Likewise. + (fn_ident): New. + (htab_counts_entry_hash, htab_counts_entry_eq, + htab_counts_entry_del): Adjust. + (reads_count_file, get_coverage_counts, + coverage_begin_output, coverage_end_function): Adjust. + (build_fn_info_type, build_fn_info_value): Likewise. + * gcov-dump.c (tag_function): Adjust. + * gcov-io.c (gcov_write_string, gcov_read_string): Not in LIBGCOV. + * gcov-io.h (gcov_write_string, gcov_read_string): Not in LIBGCOV. + * gcov.c (struct function_info): Add ident. + (read_graph_file, read_count_file): Adjust. + * libgcov.c (gcov_exit): Adjust. + 2003-04-23 Richard Henderson PR opt/8300 diff --git a/gcc/coverage.c b/gcc/coverage.c index 421b3b1..9d7e089 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -50,7 +50,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA struct function_list { struct function_list *next; /* next function */ - const char *name; /* function name */ + unsigned ident; /* function ident */ unsigned checksum; /* function checksum */ unsigned n_ctrs[GCOV_COUNTERS];/* number of counters. */ }; @@ -59,7 +59,7 @@ struct function_list typedef struct counts_entry { /* We hash by */ - char *function_name; + unsigned ident; unsigned ctr; /* Store */ @@ -72,6 +72,7 @@ typedef struct counts_entry } counts_entry_t; +static unsigned fn_ident = 1; static struct function_list *functions_head = 0; static struct function_list **functions_tail = &functions_head; @@ -118,7 +119,7 @@ htab_counts_entry_hash (of) { const counts_entry_t *entry = of; - return htab_hash_string (entry->function_name) ^ entry->ctr; + return entry->ident * GCOV_COUNTERS + entry->ctr; } static int @@ -129,8 +130,7 @@ htab_counts_entry_eq (of1, of2) const counts_entry_t *entry1 = of1; const counts_entry_t *entry2 = of2; - return !strcmp (entry1->function_name, entry2->function_name) - && entry1->ctr == entry2->ctr; + return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr; } static void @@ -139,7 +139,6 @@ htab_counts_entry_del (of) { counts_entry_t *entry = of; - free (entry->function_name); free (entry->counts); free (entry); } @@ -149,7 +148,7 @@ htab_counts_entry_del (of) static void read_counts_file () { - char *function_name_buffer = NULL; + unsigned fn_ident = 0; unsigned version, ix, checksum = -1; counts_entry_t *summaried = NULL; unsigned seen_summary = 0; @@ -193,9 +192,7 @@ read_counts_file () offset = gcov_position (); if (tag == GCOV_TAG_FUNCTION) { - const char *string = gcov_read_string (); - free (function_name_buffer); - function_name_buffer = string ? xstrdup (string) : NULL; + fn_ident = gcov_read_unsigned (); checksum = gcov_read_unsigned (); if (seen_summary) { @@ -231,13 +228,13 @@ read_counts_file () entry->summary.sum_max += csum->sum_max; } } - else if (GCOV_TAG_IS_COUNTER (tag) && function_name_buffer) + else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident) { counts_entry_t **slot, *entry, elt; unsigned n_counts = length / 8; unsigned ix; - elt.function_name = function_name_buffer; + elt.ident = fn_ident; elt.ctr = GCOV_COUNTER_FOR_TAG (tag); slot = (counts_entry_t **) htab_find_slot @@ -246,7 +243,7 @@ read_counts_file () if (!entry) { *slot = entry = xcalloc (1, sizeof (counts_entry_t)); - entry->function_name = xstrdup (elt.function_name); + entry->ident = elt.ident; entry->ctr = elt.ctr; entry->checksum = checksum; entry->summary.num = n_counts; @@ -255,7 +252,7 @@ read_counts_file () else if (entry->checksum != checksum || entry->summary.num != n_counts) { - warning ("profile mismatch for `%s'", function_name_buffer); + warning ("coverage mismatch for function %u", fn_ident); htab_delete (counts_hash); break; } @@ -281,7 +278,6 @@ read_counts_file () } } - free (function_name_buffer); gcov_close (); } @@ -304,24 +300,24 @@ get_coverage_counts (unsigned counter, unsigned expected, return NULL; } - elt.function_name - = (char *) IDENTIFIER_POINTER - (DECL_ASSEMBLER_NAME (current_function_decl)); + elt.ident = fn_ident; elt.ctr = counter; entry = htab_find (counts_hash, &elt); if (!entry) { - warning ("No profile for function '%s' found.", elt.function_name); + warning ("no coverage for function '%s' found.", IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (current_function_decl))); return 0; } if (expected != entry->summary.num || compute_checksum () != entry->checksum) { - warning ("profile mismatch for `%s'", elt.function_name); + warning ("coverage mismatch for `%s'", IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (current_function_decl))); return NULL; } - + if (summary) *summary = &entry->summary; @@ -426,9 +422,10 @@ coverage_begin_output () /* Announce function */ offset = gcov_write_tag (GCOV_TAG_FUNCTION); + gcov_write_unsigned (fn_ident); + gcov_write_unsigned (compute_checksum ()); gcov_write_string (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); - gcov_write_unsigned (compute_checksum ()); gcov_write_string (file); gcov_write_unsigned (line); gcov_write_length (offset); @@ -456,15 +453,14 @@ coverage_end_function () { struct function_list *item; - /* ??? Probably should re-use the existing struct function. */ item = xmalloc (sizeof (struct function_list)); *functions_tail = item; functions_tail = &item->next; item->next = 0; - item->name = xstrdup (IDENTIFIER_POINTER - (DECL_ASSEMBLER_NAME (current_function_decl))); + /* It would be nice to use the unique source location. */ + item->ident = fn_ident; item->checksum = compute_checksum (); for (i = 0; i != GCOV_COUNTERS; i++) { @@ -476,6 +472,7 @@ coverage_end_function () fn_ctr_mask = 0; } bbg_function_announced = 0; + fn_ident++; } /* Creates the gcov_fn_info RECORD_TYPE. */ @@ -486,13 +483,10 @@ build_fn_info_type (counters) { tree type = (*lang_hooks.types.make_type) (RECORD_TYPE); tree field, fields; - tree string_type = - build_pointer_type (build_qualified_type (char_type_node, - TYPE_QUAL_CONST)); tree array_type; - /* name */ - fields = build_decl (FIELD_DECL, NULL_TREE, string_type); + /* ident */ + fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node); /* checksum */ field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node); @@ -523,20 +517,13 @@ build_fn_info_value (function, type) { tree value = NULL_TREE; tree fields = TYPE_FIELDS (type); - size_t name_len = strlen (function->name); - tree fname = build_string (name_len + 1, function->name); - tree string_type = - build_pointer_type (build_qualified_type (char_type_node, - TYPE_QUAL_CONST)); unsigned ix; tree array_value = NULL_TREE; - /* name */ - TREE_TYPE (fname) = - build_array_type (char_type_node, - build_index_type (build_int_2 (name_len, 0))); + /* ident */ value = tree_cons (fields, - build1 (ADDR_EXPR, string_type, fname), + convert (unsigned_type_node, + build_int_2 (function->ident, 0)), value); fields = TREE_CHAIN (fields); @@ -854,16 +841,17 @@ coverage_init (filename) { int len = strlen (filename); + /* Name of da file. */ da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1); strcpy (da_file_name, filename); strcat (da_file_name, GCOV_DATA_SUFFIX); - read_counts_file (); - - /* Open the bbg output file. */ + /* Name of bbg file. */ bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1); strcpy (bbg_file_name, filename); strcat (bbg_file_name, GCOV_GRAPH_SUFFIX); + + read_counts_file (); } /* Performs file-level cleanup. Close graph file, generate coverage diff --git a/gcc/gcov-dump.c b/gcc/gcov-dump.c index 5c0dd3a..818c6ef 100644 --- a/gcc/gcov-dump.c +++ b/gcc/gcov-dump.c @@ -254,15 +254,17 @@ tag_function (filename, tag, length) unsigned tag ATTRIBUTE_UNUSED; unsigned length ATTRIBUTE_UNUSED; { - const char *name; unsigned long pos = gcov_position (); - name = gcov_read_string (); - printf (" `%s'", name ? name : "NULL"); - printf (" checksum=0x%08x", gcov_read_unsigned ()); + printf (" ident=%u", gcov_read_unsigned ()); + printf (", checksum=0x%08x", gcov_read_unsigned ()); if (gcov_position () - pos < length) { + const char *name; + + name = gcov_read_string (); + printf (", `%s'", name ? name : "NULL"); name = gcov_read_string (); printf (" %s", name ? name : "NULL"); printf (":%u", gcov_read_unsigned ()); diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c index b595217..2f2a87f 100644 --- a/gcc/gcov-io.c +++ b/gcc/gcov-io.c @@ -222,6 +222,7 @@ gcov_write_counter (gcov_type value) } #endif /* IN_LIBGCOV */ +#if !IN_LIBGCOV /* Write STRING to coverage file. Sets error flag on file error, overflow flag on overflow */ @@ -254,6 +255,7 @@ gcov_write_string (const char *string) memcpy (buffer + 4 + length, &pad, rem); } } +#endif /* Write a tag TAG and reserve space for the record length. Return a value to be used for gcov_write_length. */ @@ -396,6 +398,7 @@ gcov_read_counter () buffer, or NULL on empty string. You must copy the string before calling another gcov function. */ +#if !IN_LIBGCOV GCOV_LINKAGE const char * gcov_read_string () { @@ -407,6 +410,7 @@ gcov_read_string () length += 4 - (length & 3); return (const char *) gcov_read_bytes (length); } +#endif GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *summary) diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h index 7f88199..df5fb97 100644 --- a/gcc/gcov-io.h +++ b/gcc/gcov-io.h @@ -95,10 +95,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA file and [a1..ff] for the counter file. The basic block graph file contains the following records - bbg: function-graph* + bbg: unit function-graph* + unit: header int32:checksum string:source function-graph: announce_function basic_blocks {arcs | lines}* - announce_function: header string:name int32:checksum - string:source int32:lineno + announce_function: header int32:ident int32:checksum + string:name string:source int32:lineno basic_block: header int32:flags* arcs: header int32:block_no arc* arc: int32:dest_block int32:flags @@ -123,9 +124,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA blocks they are for. The data file contains the following records. - da: {function-data* summary:object summary:program*}* + da: {unit function-data* summary:object summary:program*}* + unit: header int32:checksum function-data: announce_function arc_counts - announce_function: header string:name int32:checksum + announce_function: header int32:ident int32:checksum arc_counts: header int64:count* summary: int32:checksum {count-summary}GCOV_COUNTERS count-summary: int32:num int32:runs int64:sum @@ -279,7 +281,7 @@ struct gcov_summary explicitly calculate the correct array stride. */ struct gcov_fn_info { - const char *name; /* (mangled) name of function */ + unsigned ident; /* unique ident of function */ unsigned checksum; /* function checksum */ unsigned n_ctrs[0]; /* instrumented counters */ }; @@ -339,8 +341,9 @@ GCOV_LINKAGE unsigned char *gcov_write_bytes (unsigned); GCOV_LINKAGE void gcov_write_unsigned (unsigned); #if IN_LIBGCOV GCOV_LINKAGE void gcov_write_counter (gcov_type); -#endif +#else GCOV_LINKAGE void gcov_write_string (const char *); +#endif GCOV_LINKAGE unsigned long gcov_write_tag (unsigned); GCOV_LINKAGE void gcov_write_length (unsigned long /*position*/); #if IN_LIBGCOV @@ -350,9 +353,10 @@ GCOV_LINKAGE void gcov_write_summary (unsigned, const struct gcov_summary *); GCOV_LINKAGE const unsigned char *gcov_read_bytes (unsigned); GCOV_LINKAGE unsigned gcov_read_unsigned (void); GCOV_LINKAGE gcov_type gcov_read_counter (void); +#if !IN_LIBGCOV GCOV_LINKAGE const char *gcov_read_string (void); +#endif GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *); - static unsigned long gcov_position (void); static void gcov_seek (unsigned long /*base*/, unsigned /*length */); static unsigned long gcov_seek_end (void); diff --git a/gcc/gcov.c b/gcc/gcov.c index 5722923..40e16cf 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -168,6 +168,7 @@ typedef struct function_info { /* Name of function. */ char *name; + unsigned ident; unsigned checksum; /* Array of basic blocks. */ @@ -744,21 +745,23 @@ read_graph_file () unsigned tag = gcov_read_unsigned (); unsigned length = gcov_read_unsigned (); unsigned long base = gcov_position (); - + if (tag == GCOV_TAG_FUNCTION) { char *function_name; - unsigned checksum, lineno; + unsigned ident, checksum, lineno; source_t *src; function_t *probe, *prev; - function_name = xstrdup (gcov_read_string ()); + ident = gcov_read_unsigned (); checksum = gcov_read_unsigned (); + function_name = xstrdup (gcov_read_string ()); src = find_source (gcov_read_string ()); lineno = gcov_read_unsigned (); fn = (function_t *)xcalloc (1, sizeof (function_t)); fn->name = function_name; + fn->ident = ident; fn->checksum = checksum; fn->src = src; fn->line = lineno; @@ -1015,7 +1018,7 @@ read_count_file () program_count++; else if (tag == GCOV_TAG_FUNCTION) { - const char *function_name = gcov_read_string (); + unsigned ident = gcov_read_unsigned (); struct function_info *fn_n = functions; for (fn = fn ? fn->next : NULL; ; fn = fn->next) @@ -1026,11 +1029,11 @@ read_count_file () fn_n = NULL; else { - fnotice (stderr, "%s:unknown function `%s'\n", - da_file_name, function_name); + fnotice (stderr, "%s:unknown function `%u'\n", + da_file_name, ident); break; } - if (!strcmp (fn->name, function_name)) + if (fn->ident == ident) break; } diff --git a/gcc/libgcov.c b/gcc/libgcov.c index a2c831e..a406114 100644 --- a/gcc/libgcov.c +++ b/gcc/libgcov.c @@ -203,7 +203,8 @@ gcov_exit (void) } /* Merge execution counts for each function. */ - for (f_ix = gi_ptr->n_functions, fi_ptr = gi_ptr->functions; f_ix--; + for (f_ix = gi_ptr->n_functions, fi_ptr = gi_ptr->functions; + f_ix--; fi_ptr = (const struct gcov_fn_info *) ((const char *) fi_ptr + fi_stride)) { @@ -211,19 +212,17 @@ gcov_exit (void) length = gcov_read_unsigned (); /* Check function */ - if (tag != GCOV_TAG_FUNCTION) + if (tag != GCOV_TAG_FUNCTION + || gcov_read_unsigned () != fi_ptr->ident + || gcov_read_unsigned () != fi_ptr->checksum) { read_mismatch:; fprintf (stderr, "profiling:%s:Merge mismatch for %s\n", gi_ptr->filename, - fi_ptr ? fi_ptr->name : "summaries"); + f_ix + 1 ? "function" : "summaries"); goto read_fatal; } - if (strcmp (gcov_read_string (), fi_ptr->name) - || gcov_read_unsigned () != fi_ptr->checksum) - goto read_mismatch; - for (c_ix = t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++) if ((1 << t_ix) & gi_ptr->ctr_mask) { @@ -284,9 +283,8 @@ gcov_exit (void) if (!summary_pos) memset (&program, 0, sizeof (program)); - fi_ptr = 0; - /* Merge the summaries. */ + f_ix = ~0u; for (t_ix = c_ix = 0, cs_obj = object.ctrs, cs_tobj = this_object.ctrs, cs_prg = program.ctrs, cs_tprg = this_program.ctrs, @@ -346,7 +344,7 @@ gcov_exit (void) { /* Announce function. */ base = gcov_write_tag (GCOV_TAG_FUNCTION); - gcov_write_string (fi_ptr->name); + gcov_write_unsigned (fi_ptr->ident); gcov_write_unsigned (fi_ptr->checksum); gcov_write_length (base); -- 2.7.4