I can not review tree.c changes.  I would probably suggest making crc_byte 
inline.

> +#if IN_LIBGCOV
> +
> +/* These functions are guarded by #if to avoid compile time warning.  */
> +
> +/* Return the number of words STRING would need including the length
> +   field in the output stream itself.  This should be identical to
> +   "alloc" calculation in gcov_write_string().  */

Hmm, probably better to make gcov_write_string to use gcov_string_length then.
> @@ -238,13 +265,15 @@ gcov_write_words (unsigned words)
>  
>    gcc_assert (gcov_var.mode < 0);
>  #if IN_LIBGCOV
> -  if (gcov_var.offset >= GCOV_BLOCK_SIZE)
> +  if (gcov_var.offset + words >= GCOV_BLOCK_SIZE)
>      {
> -      gcov_write_block (GCOV_BLOCK_SIZE);
> +      gcov_write_block (MIN (gcov_var.offset, GCOV_BLOCK_SIZE));
>        if (gcov_var.offset)
>       {
> -       gcc_assert (gcov_var.offset == 1);
> -       memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
> +       gcc_assert (gcov_var.offset < GCOV_BLOCK_SIZE);
> +       memcpy (gcov_var.buffer,
> +                  gcov_var.buffer + GCOV_BLOCK_SIZE,
> +                  gcov_var.offset << 2);

I don't really follow the logic here.  buffer is allocated to be size of
block+4 and it is expected that gcov_write_words is not executed on size
greater than 4.  Since gcov_write_string now seems to be expected to handle
strings of bigger size, I think you acually need to make write_string to write
in chunks when you reach block boundary?

As soon as you decide to not write out in the GCOV_BLOCK_SIZE chunks, the
MIN computation above seems unnecesary (and bogus, since we won't let
gcov_var.offset to grow past GCOV_BLOCK_SIZE.

What gets into libgcov is very problematic busyness for embedded targets, where 
you really want
libgcov to be small.  Why do you need to store strings now?
> Index: gcov-io.h
> ===================================================================
> --- gcov-io.h (revision 172693)
> +++ gcov-io.h (working copy)
> @@ -101,9 +101,10 @@ see the files COPYING3 and COPYING.RUNTI
>  
>     The basic block graph file contains the following records
>       note: unit function-graph*
> -     unit: header int32:checksum string:source
> +     unit: header int32:checksum int32: string:source
>       function-graph: announce_function basic_blocks {arcs | lines}*
> -     announce_function: header int32:ident int32:checksum
> +     announce_function: header int32:ident
> +             int32:lineno_checksum int32:cfg_checksum
>               string:name string:source int32:lineno
>       basic_block: header int32:flags*
>       arcs: header int32:block_no arc*
> @@ -132,7 +133,9 @@ see the files COPYING3 and COPYING.RUNTI
>          data: {unit function-data* summary:object summary:program*}*
>       unit: header int32:checksum
>          function-data:       announce_function arc_counts
> -     announce_function: header int32:ident int32:checksum
> +     announce_function: header int32:ident
> +             int32:lineno_checksum int32:cfg_checksum
> +             string:name
>       arc_counts: header int64:count*
>       summary: int32:checksum {count-summary}GCOV_COUNTERS
>       count-summary:  int32:num int32:runs int64:sum

We also need to bump gcov version, right?

> @@ -411,11 +417,20 @@ struct gcov_summary
>  /* Information about a single function.  This uses the trailing array
>     idiom. The number of counters is determined from the counter_mask
>     in gcov_info.  We hold an array of function info, so have to
> -   explicitly calculate the correct array stride.  */
> +   explicitly calculate the correct array stride.  
> +
> +   "ident" is no longer used in hash computation.  Additionally,
> +   "name" is used in hash computation.  This makes the profile data
> +   not compatible across function name changes.
> +   Also, the function pointer is stored for later use for indirect
> +   function call name resolution.

Hmm, your patch is not adding indirect function call name resolution,
so independent change?
> Index: profile.c
> ===================================================================
> --- profile.c (revision 172693)
> +++ profile.c (working copy)
> @@ -102,13 +102,6 @@ static int total_num_branches;
>  
>  /* Forward declarations.  */
>  static void find_spanning_tree (struct edge_list *);
> -static unsigned instrument_edges (struct edge_list *);
> -static void instrument_values (histogram_values);
> -static void compute_branch_probabilities (void);
> -static void compute_value_histograms (histogram_values);
> -static gcov_type * get_exec_counts (void);
> -static basic_block find_group (basic_block);
> -static void union_groups (basic_block, basic_block);

This is also independent and OK for mainline.
>  
>  /* Add edge instrumentation code to the entire insn chain.
>  
> @@ -233,10 +226,12 @@ instrument_values (histogram_values valu
>  }
>  
>  
> -/* Computes hybrid profile for all matching entries in da_file.  */
> +/* Computes hybrid profile for all matching entries in da_file.  
> +   
> +   CFG_CHECKSUM is the precomputed checksum for the CFG.  */
document LINENO_CHECKSUM, too.
>    struct function_list *next;         /* next function */
>    unsigned ident;             /* function ident */
> -  unsigned checksum;          /* function checksum */
> +  unsigned lineno_checksum;   /* function lineno checksum */
> +  unsigned cfg_checksum;      /* function cfg checksum */
> +  const char *name;              /* function name */
> +  tree decl;                     /* function decl */
>    unsigned n_ctrs[GCOV_COUNTERS];/* number of counters.  */
>  };
>  
> @@ -67,9 +71,11 @@ typedef struct counts_entry
>    /* We hash by  */
>    unsigned ident;
>    unsigned ctr;
> +  char *name;
also const, right?
> @@ -139,12 +144,21 @@ get_gcov_unsigned_t (void)
>    return lang_hooks.types.type_for_size (32, true);
>  }
>  
> +/* Return the type node for const char *.  */
> +
> +static tree
> +get_const_string_type (void)

This is not really coverage specific and already mudflap is doing the same. So 
probably it better
should go into tree.c.
> -       if (entry->checksum != checksum)
> -         inform (input_location, "checksum is %x instead of %x",
> -                 entry->checksum, checksum);
> +       if (entry->cfg_checksum != cfg_checksum)
> +         inform (input_location, "cfg_checksum is %x instead of %x",
> +                 entry->cfg_checksum, cfg_checksum);

Well, the message is already cryptic, perhaps just expanding cfg to be control 
flow graph
so users get some clue.
> @@ -641,13 +744,24 @@ build_fn_info_type (unsigned int counter
>    /* ident */
>    fields = build_decl (BUILTINS_LOCATION,
>                      FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
> -
> -  /* checksum */
> +  /* lineno_checksum */
>    field = build_decl (BUILTINS_LOCATION,
>                     FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
>    DECL_CHAIN (field) = fields;
>    fields = field;
>  
> +  /* cfg checksum */
> +  field = build_decl (BUILTINS_LOCATION,
> +                      FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
> +  DECL_CHAIN (field) = fields;
> +  fields = field;

Why do we need function names to end up there at runtime?

Honza

Reply via email to