New GCOV_TAG_FUNCTION layout
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 24 Apr 2003 09:46:17 +0000 (09:46 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 24 Apr 2003 09:46:17 +0000 (09:46 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@66035 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/coverage.c
gcc/gcov-dump.c
gcc/gcov-io.c
gcc/gcov-io.h
gcc/gcov.c
gcc/libgcov.c

index 5745284..a4dd1da 100644 (file)
@@ -1,3 +1,21 @@
+2003-04-24  Nathan Sidwell  <nathan@codesourcery.com>
+
+       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  <rth@redhat.com>
 
        PR opt/8300
index 421b3b1..9d7e089 100644 (file)
@@ -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
index 5c0dd3a..818c6ef 100644 (file)
@@ -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 ());
index b595217..2f2a87f 100644 (file)
@@ -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)
index 7f88199..df5fb97 100644 (file)
@@ -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);
index 5722923..40e16cf 100644 (file)
@@ -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;
            }
 
index a2c831e..a406114 100644 (file)
@@ -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);