1.5M  increase is not big concern. Ok with that.

David

On Tue, Sep 16, 2014 at 10:51 AM, Teresa Johnson <tejohn...@google.com> wrote:
> On Tue, Sep 16, 2014 at 8:07 AM, Xinliang David Li <davi...@google.com> wrote:
>>  The zero_counts array is passed to gcov_build_callgraph but not used
>> until the dyn-cgraph is initialized. We should avoid increasing
>> runtime memory overhead by not creating it if possible.
>
> We could delay creation a little bit, until the callgraph has been
> initialized. But I am not sure this gains us much as it doesn't avoid
> having the lifetime of the array overlap with the lifetime of the
> callgraph. And unless fixups have been explicitly disabled or there
> are no comdats we will need to allocate it (so likely in almost all
> cases).
>
> However, I can reduce the required overhead by using an array of chars
> instead of ints. I measured the number of bytes in the array for a big
> app and it was 5.6M with the int array and 1.5M with the char array.
> Does this seem reasonable? To reduce it further I could encode as a
> bitvector as we do in the gcda file.
>
> Teresa
>
>>
>> David
>>
>> On Tue, Sep 16, 2014 at 7:57 AM, Teresa Johnson <tejohn...@google.com> wrote:
>>> On Mon, Sep 15, 2014 at 9:29 PM, Xinliang David Li <davi...@google.com> 
>>> wrote:
>>>> Is it necessary to declare zero_counts array at all?  Can a flag field
>>>> be added to dyn_cgraph_node structure to indicate if it is fixed up?
>>>
>>> The zero_counts array is used to pass info back to the caller in
>>> libgcov-driver.cc (dyn_cgraph_node), which is where it is allocated.
>>> That routine does not have access to the dyn-ipa cgraph.
>>>
>>> Teresa
>>>
>>>>
>>>> David
>>>>
>>>> On Fri, Sep 12, 2014 at 4:31 PM, Teresa Johnson <tejohn...@google.com> 
>>>> wrote:
>>>>> This patch addresses issues when running gcov-tool after performing
>>>>> COMDAT fixup during dyn-ipa. Functions that were previously all zero
>>>>> counts are marked, and the counts are discarded when being read in
>>>>> by gcov-tool before recalculating module groups and summary info.
>>>>>
>>>>> While here, cleaned up the gcov-tool output (remove an overly-verbose 
>>>>> output,
>>>>> make all output consistently go to stderr).
>>>>>
>>>>> Passes regression tests and manual tests. Ok for google branches?
>>>>>
>>>>> 2014-09-12  Teresa Johnson  <tejohn...@google.com>
>>>>>
>>>>>         * gcc/coverage.c (read_counts_file): Handle new section.
>>>>>         * gcc/gcov.c (read_count_file): Ditto.
>>>>>         * gcc/gcov-dump.c (dump_gcov_file): Ditto.
>>>>>         (tag_function): Ditto.
>>>>>         (tag_zero_fixup): New function.
>>>>>         * gcc/gcov-io.c (gcov_read_comdat_zero_fixup): Ditto.
>>>>>         * gcc/gcov-io.h (gcov_read_comdat_zero_fixup): Ditto.
>>>>>         * libgcc/dyn-ipa.c (struct checksum_alias): Change flag to 
>>>>> pointer.
>>>>>         (new_checksum_alias): Ditto.
>>>>>         (cfg_checksum_insert): Ditto.
>>>>>         (checksum_set_insert): Ditto.
>>>>>         (gcov_build_callgraph): New parameter.
>>>>>         (gcov_collect_imported_modules): Add assert for duplicate gcda 
>>>>> reads.
>>>>>         (gcov_fixup_counters_checksum): Change flag to pointer to flag, 
>>>>> set it.
>>>>>         (__gcov_compute_module_groups): New parameter.
>>>>>         * libgcc/libgcov-driver.c (set_gcov_fn_fixed_up): New function.
>>>>>         (get_gcov_fn_fixed_up): Ditto.
>>>>>         (gcov_exit_merge_gcda): Handle new section.
>>>>>         (gcov_write_comdat_zero_fixup): Ditto.
>>>>>         (gcov_write_build_info): Ditto.
>>>>>         (gcov_write_comdat_zero_fixup): New function.
>>>>>         (gcov_write_func_counters): Fix indent.
>>>>>         (gcov_dump_module_info): Write new flag section.
>>>>>         * libgcc/libgcov.h (gcov_get_counter): Clear fixed-up counters.
>>>>>         (gcov_get_counter_target): Ditto.
>>>>>         * libgcc/libgcov-util.c (tag_function): Annotate fixed-up 
>>>>> functions,
>>>>>         remove overly verbose output.
>>>>>         (tag_counters): Clear fixed-up counters.
>>>>>         (lipo_process_substitute_string_1): Send all verbose output to 
>>>>> stderr.
>>>>>         (tag_zero_fixup): New function.
>>>>>         (read_gcda_file): Deallocate flag array.
>>>>>         (gcov_profile_scale): Send all verbose output to stderr.
>>>>>         (gcov_profile_normalize): Ditto.
>>>>>
>>>>> Index: gcc/coverage.c
>>>>> ===================================================================
>>>>> --- gcc/coverage.c      (revision 215230)
>>>>> +++ gcc/coverage.c      (working copy)
>>>>> @@ -820,6 +820,14 @@ read_counts_file (const char *da_file_name, unsign
>>>>>              free (build_info_strings[i]);
>>>>>            free (build_info_strings);
>>>>>          }
>>>>> +      else if (tag == GCOV_TAG_COMDAT_ZERO_FIXUP)
>>>>> +        {
>>>>> +          /* Zero-profile fixup flags are not used by the compiler, read 
>>>>> and
>>>>> +             ignore.  */
>>>>> +          gcov_unsigned_t num_fn;
>>>>> +          int *zero_fixup_flags = gcov_read_comdat_zero_fixup
>>>>> (length, &num_fn);
>>>>> +          free (zero_fixup_flags);
>>>>> +        }
>>>>>        else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
>>>>>         {
>>>>>           counts_entry_t **slot, *entry, elt;
>>>>> Index: gcc/gcov.c
>>>>> ===================================================================
>>>>> --- gcc/gcov.c  (revision 215230)
>>>>> +++ gcc/gcov.c  (working copy)
>>>>> @@ -1441,6 +1441,12 @@ read_count_file (function_t *fns)
>>>>>              free (build_info_strings[i]);
>>>>>            free (build_info_strings);
>>>>>          }
>>>>> +      else if (tag == GCOV_TAG_COMDAT_ZERO_FIXUP)
>>>>> +        {
>>>>> +          gcov_unsigned_t num_fn;
>>>>> +          int *zero_fixup_flags = gcov_read_comdat_zero_fixup
>>>>> (length, &num_fn);
>>>>> +          free (zero_fixup_flags);
>>>>> +        }
>>>>>        else if (tag == GCOV_TAG_FUNCTION && !length)
>>>>>         ; /* placeholder  */
>>>>>        else if (tag == GCOV_TAG_FUNCTION && length == 
>>>>> GCOV_TAG_FUNCTION_LENGTH)
>>>>> Index: gcc/gcov-dump.c
>>>>> ===================================================================
>>>>> --- gcc/gcov-dump.c     (revision 215230)
>>>>> +++ gcc/gcov-dump.c     (working copy)
>>>>> @@ -42,6 +42,7 @@ static void tag_summary (const char *, unsigned, u
>>>>>  static void tag_module_info (const char *, unsigned, unsigned);
>>>>>  static void dump_working_sets (const char *filename ATTRIBUTE_UNUSED,
>>>>>                                 const struct gcov_ctr_summary *summary);
>>>>> +static void tag_zero_fixup (const char *, unsigned, unsigned);
>>>>>  static void tag_build_info (const char *, unsigned, unsigned);
>>>>>  extern int main (int, char **);
>>>>>
>>>>> @@ -57,6 +58,9 @@ static int flag_dump_positions = 0;
>>>>>  static int flag_dump_aux_modules_only = 0;
>>>>>  static int flag_dump_working_sets = 0;
>>>>>
>>>>> +static unsigned num_fn_info;
>>>>> +static int *zero_fixup_flags = NULL;
>>>>> +
>>>>>  static const struct option options[] =
>>>>>  {
>>>>>    { "help",                 no_argument,       NULL, 'h' },
>>>>> @@ -79,6 +83,7 @@ static const tag_format_t tag_table[] =
>>>>>    {GCOV_TAG_OBJECT_SUMMARY, "OBJECT_SUMMARY", tag_summary},
>>>>>    {GCOV_TAG_PROGRAM_SUMMARY, "PROGRAM_SUMMARY", tag_summary},
>>>>>    {GCOV_TAG_MODULE_INFO, "MODULE INFO", tag_module_info},
>>>>> +  {GCOV_TAG_COMDAT_ZERO_FIXUP, "ZERO FIXUP", tag_zero_fixup},
>>>>>    {GCOV_TAG_BUILD_INFO, "BUILD INFO", tag_build_info},
>>>>>    {0, NULL, NULL}
>>>>>  };
>>>>> @@ -274,6 +279,8 @@ dump_gcov_file (const char *filename)
>>>>>      printf ("%s:stamp %lu\n", filename, (unsigned long)stamp);
>>>>>    }
>>>>>
>>>>> +  num_fn_info = 0;
>>>>> +
>>>>>    while (1)
>>>>>      {
>>>>>        gcov_position_t base, position = gcov_position ();
>>>>> @@ -341,6 +348,7 @@ dump_gcov_file (const char *filename)
>>>>>           break;
>>>>>         }
>>>>>      }
>>>>> +  free (zero_fixup_flags);
>>>>>    gcov_close ();
>>>>>  }
>>>>>
>>>>> @@ -354,7 +362,9 @@ tag_function (const char *filename ATTRIBUTE_UNUSE
>>>>>      printf (" placeholder");
>>>>>    else
>>>>>      {
>>>>> -      printf (" ident=%u", gcov_read_unsigned ());
>>>>> +      int had_fixup = zero_fixup_flags && zero_fixup_flags[num_fn_info];
>>>>> +      printf (" ident=%u%s", gcov_read_unsigned (),
>>>>> +              had_fixup ? " (Was 0-count COMDAT)" : "");
>>>>>        printf (", lineno_checksum=0x%08x", gcov_read_unsigned ());
>>>>>        printf (", cfg_checksum=0x%08x", gcov_read_unsigned ());
>>>>>
>>>>> @@ -369,6 +379,7 @@ tag_function (const char *filename ATTRIBUTE_UNUSE
>>>>>           printf (":%u", gcov_read_unsigned ());
>>>>>         }
>>>>>      }
>>>>> +  num_fn_info++;
>>>>>  }
>>>>>
>>>>>  static void
>>>>> @@ -600,6 +611,32 @@ tag_module_info (const char *filename ATTRIBUTE_UN
>>>>>  }
>>>>>
>>>>>  static void
>>>>> +tag_zero_fixup (const char *filename,
>>>>> +                unsigned tag ATTRIBUTE_UNUSED, unsigned length)
>>>>> +{
>>>>> +  gcov_unsigned_t num_fns = 0;
>>>>> +  zero_fixup_flags = gcov_read_comdat_zero_fixup (length, &num_fns);
>>>>> +  if (!zero_fixup_flags)
>>>>> +    {
>>>>> +      printf ("%s:error reading zero fixup flags\n", filename);
>>>>> +      return;
>>>>> +    }
>>>>> +  printf (" num_fns=%u", num_fns);
>>>>> +  for (unsigned i = 0; i < num_fns; i++)
>>>>> +    {
>>>>> +      if (!(i % 32))
>>>>> +        {
>>>>> +          printf ("\n");
>>>>> +          print_prefix (filename, 0, 0);
>>>>> +          printf ("\t\t");
>>>>> +        }
>>>>> +      if (!(i % 8))
>>>>> +        printf ("%s%4u:", (i%32)?" ":"", i);
>>>>> +      printf ("%u", zero_fixup_flags[i]);
>>>>> +    }
>>>>> +}
>>>>> +
>>>>> +static void
>>>>>  tag_build_info (const char *filename,
>>>>>                 unsigned tag ATTRIBUTE_UNUSED, unsigned length)
>>>>>  {
>>>>> Index: gcc/gcov-io.c
>>>>> ===================================================================
>>>>> --- gcc/gcov-io.c       (revision 215230)
>>>>> +++ gcc/gcov-io.c       (working copy)
>>>>> @@ -691,6 +691,36 @@ gcov_read_summary (struct gcov_summary *summary)
>>>>>      }
>>>>>  }
>>>>>
>>>>> +/* Read LENGTH words (unsigned type) from a zero profile fixup record 
>>>>> with the
>>>>> +   number of function flags saved in NUM_FNS.  Returns the int flag
>>>>> array, which
>>>>> +   should be deallocated by caller, or NULL on error.  */
>>>>> +
>>>>> +GCOV_LINKAGE int *
>>>>> +gcov_read_comdat_zero_fixup (gcov_unsigned_t length,
>>>>> +                             gcov_unsigned_t *num_fns)
>>>>> +{
>>>>> +  unsigned ix, f_ix;
>>>>> +  gcov_unsigned_t num = gcov_read_unsigned ();
>>>>> +  /* The length consists of 1 word to hold the number of functions,
>>>>> +     plus enough 32-bit words to hold 1 bit/function.  */
>>>>> +  gcc_assert ((num + 31) / 32 + 1 == length);
>>>>> +  int *zero_fixup_flags = (int *) xcalloc (num, sizeof (int));
>>>>> +  for (ix = 0; ix < length - 1; ix++)
>>>>> +    {
>>>>> +      gcov_unsigned_t bitvector = gcov_read_unsigned ();
>>>>> +      f_ix = ix * 32;
>>>>> +      while (bitvector)
>>>>> +        {
>>>>> +          if (bitvector & 0x1)
>>>>> +            zero_fixup_flags[f_ix] = 1;
>>>>> +          f_ix++;
>>>>> +          bitvector >>= 1;
>>>>> +        }
>>>>> +    }
>>>>> +  *num_fns = num;
>>>>> +  return zero_fixup_flags;
>>>>> +}
>>>>> +
>>>>>  /* Read NUM_STRINGS strings (as an unsigned array) in STRING_ARRAY, and 
>>>>> return
>>>>>     the number of words read.  */
>>>>>
>>>>> Index: gcc/gcov-io.h
>>>>> ===================================================================
>>>>> --- gcc/gcov-io.h       (revision 215230)
>>>>> +++ gcc/gcov-io.h       (working copy)
>>>>> @@ -129,7 +129,7 @@ see the files COPYING3 and COPYING.RUNTIME respect
>>>>>     blocks they are for.
>>>>>
>>>>>     The data file contains the following records.
>>>>> -        data: {unit summary:program* build_info function-data*}*
>>>>> +        data: {unit summary:program* build_info zero_fixup 
>>>>> function-data*}*
>>>>>         unit: header int32:checksum
>>>>>          function-data: announce_function present counts
>>>>>         announce_function: header int32:ident
>>>>> @@ -142,6 +142,7 @@ see the files COPYING3 and COPYING.RUNTIME respect
>>>>>          histogram: {int32:bitvector}8 histogram-buckets*
>>>>>          histogram-buckets: int32:num int64:min int64:sum
>>>>>          build_info: string:info*
>>>>> +        zero_fixup: int32:num int32:bitvector*
>>>>>
>>>>>     The ANNOUNCE_FUNCTION record is the same as that in the note file,
>>>>>     but without the source location.  The COUNTS gives the
>>>>> @@ -158,6 +159,12 @@ see the files COPYING3 and COPYING.RUNTIME respect
>>>>>     build.  For example, it can be used to include source revision
>>>>>     information that is useful in diagnosing profile mis-matches.
>>>>>
>>>>> +   ZERO_FIXUP record contains a count of functions in the gcda file
>>>>> +   and an array of bitvectors indexed by the function index's in the
>>>>> +   function-data section. Each bit flags whether the function was a
>>>>> +   COMDAT that had all-zero profiles that was fixed up by dyn-ipa
>>>>> +   using profiles from functions with matching checksums in other 
>>>>> modules.
>>>>> +
>>>>>     This file is included by both the compiler, gcov tools and the
>>>>>     runtime support library libgcov. IN_LIBGCOV and IN_GCOV are used to
>>>>>     distinguish which case is which.  If IN_LIBGCOV is nonzero,
>>>>> @@ -261,6 +268,9 @@ typedef unsigned HOST_WIDEST_INT gcov_type_unsigne
>>>>>  #define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2)
>>>>>  #define GCOV_TAG_OBJECT_SUMMARY  ((gcov_unsigned_t)0xa1000000) /* 
>>>>> Obsolete */
>>>>>  #define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000)
>>>>> +#define GCOV_TAG_COMDAT_ZERO_FIXUP ((gcov_unsigned_t)0xa9000000)
>>>>> +/* Ceiling divide by 32 bit word size, plus one word to hold NUM.  */
>>>>> +#define GCOV_TAG_COMDAT_ZERO_FIXUP_LENGTH(NUM) (1 + (NUM + 31) / 32)
>>>>>  #define GCOV_TAG_SUMMARY_LENGTH(NUM)  \
>>>>>          (1 + GCOV_COUNTERS_SUMMABLE * (10 + 3 * 2) + (NUM) * 5)
>>>>>  #define GCOV_TAG_BUILD_INFO ((gcov_unsigned_t)0xa7000000)
>>>>> @@ -441,6 +451,9 @@ GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDE
>>>>>  GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN;
>>>>>  GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN;
>>>>>  GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *) 
>>>>> ATTRIBUTE_HIDDEN;
>>>>> +GCOV_LINKAGE int *gcov_read_comdat_zero_fixup (gcov_unsigned_t,
>>>>> +                                               gcov_unsigned_t *)
>>>>> +    ATTRIBUTE_HIDDEN;
>>>>>  GCOV_LINKAGE char **gcov_read_build_info (gcov_unsigned_t, 
>>>>> gcov_unsigned_t *)
>>>>>    ATTRIBUTE_HIDDEN;
>>>>>  GCOV_LINKAGE const char *gcov_read_string (void);
>>>>> Index: libgcc/dyn-ipa.c
>>>>> ===================================================================
>>>>> --- libgcc/dyn-ipa.c    (revision 215230)
>>>>> +++ libgcc/dyn-ipa.c    (working copy)
>>>>> @@ -107,8 +107,9 @@ struct checksum_alias
>>>>>    struct checksum_alias *next_alias;
>>>>>    gcov_type guid;
>>>>>    const struct gcov_fn_info *fi_ptr;
>>>>> -  /* Does this function have all-zero arc counts?  */
>>>>> -  int zero_counts;
>>>>> +  /* Non-NULL pointer to flag if this function has all-zero arc counts, 
>>>>> to be
>>>>> +     set if we perform fixup.  */
>>>>> +  int *zero_count_fixup;
>>>>>  };
>>>>>
>>>>>  /* Module info is stored in dyn_caph->sup_modules
>>>>> @@ -178,10 +179,10 @@ extern gcov_unsigned_t __gcov_lipo_merge_modu_edge
>>>>>  extern gcov_unsigned_t __gcov_lipo_weak_inclusion;
>>>>>
>>>>>  #if defined(inhibit_libc)
>>>>> -void __gcov_build_callgraph (void) {}
>>>>> +void __gcov_build_callgraph (int **zero_counts) {}
>>>>>  #else
>>>>>
>>>>> -int __gcov_compute_module_groups (void) ATTRIBUTE_HIDDEN;
>>>>> +int __gcov_compute_module_groups (int **zero_counts) ATTRIBUTE_HIDDEN;
>>>>>  void __gcov_finalize_dyn_callgraph (void) ATTRIBUTE_HIDDEN;
>>>>>  static void gcov_dump_callgraph (gcov_type);
>>>>>  static void gcov_dump_cgraph_node_short (struct dyn_cgraph_node *node);
>>>>> @@ -378,18 +379,19 @@ lineno_checksum_get_key (const void *p)
>>>>>  }
>>>>>
>>>>>  /* Create a new checksum_alias struct for function with GUID, FI_PTR,
>>>>> -   and ZERO_COUNTS flag.  Prepends to list NEXT and returns new struct.  
>>>>> */
>>>>> +   and ZERO_COUNT_FIXUP flag pointer.  Prepends to list NEXT and returns
>>>>> +   new struct.  */
>>>>>
>>>>>  static struct checksum_alias *
>>>>>  new_checksum_alias (gcov_type guid, const struct gcov_fn_info *fi_ptr,
>>>>> -                    int zero_counts,
>>>>> +                    int *zero_count_fixup,
>>>>>                      struct checksum_alias *next)
>>>>>  {
>>>>>    struct checksum_alias *alias = XNEW (struct checksum_alias);
>>>>>    alias->next_alias = next;
>>>>>    alias->fi_ptr = fi_ptr;
>>>>>    alias->guid = guid;
>>>>> -  alias->zero_counts = zero_counts;
>>>>> +  alias->zero_count_fixup = zero_count_fixup;
>>>>>    return alias;
>>>>>  }
>>>>>
>>>>> @@ -407,11 +409,12 @@ find_cfg_checksum (struct checksum_alias_info *lis
>>>>>  }
>>>>>
>>>>>  /* Insert a new checksum_alias struct into LIST for function with
>>>>> -   CFG_CHECKSUM and associated GUID, FI_PTR, and ZERO_COUNTS flag.  */
>>>>> +   CFG_CHECKSUM and associated GUID, FI_PTR, and ZERO_COUNT_FIXUP
>>>>> +   flag pointer.  */
>>>>>
>>>>>  static struct checksum_alias_info *
>>>>>  cfg_checksum_insert (unsigned cfg_checksum, gcov_type guid,
>>>>> -                     const struct gcov_fn_info *fi_ptr, int zero_counts,
>>>>> +                     const struct gcov_fn_info *fi_ptr, int 
>>>>> *zero_count_fixup,
>>>>>                       struct checksum_alias_info *list)
>>>>>  {
>>>>>    struct checksum_alias_info *alias_info;
>>>>> @@ -419,7 +422,8 @@ cfg_checksum_insert (unsigned cfg_checksum, gcov_t
>>>>>    if (alias_info)
>>>>>      {
>>>>>        gcc_assert (alias_info->alias_list);
>>>>> -      alias_info->alias_list = new_checksum_alias (guid, fi_ptr, 
>>>>> zero_counts,
>>>>> +      alias_info->alias_list = new_checksum_alias (guid, fi_ptr,
>>>>> +                                                   zero_count_fixup,
>>>>>                                                     
>>>>> alias_info->alias_list);
>>>>>        return list;
>>>>>      }
>>>>> @@ -428,7 +432,8 @@ cfg_checksum_insert (unsigned cfg_checksum, gcov_t
>>>>>        alias_info = XNEW (struct checksum_alias_info);
>>>>>        alias_info->next_cfg_checksum = list;
>>>>>        alias_info->cfg_checksum = cfg_checksum;
>>>>> -      alias_info->alias_list = new_checksum_alias (guid, fi_ptr, 
>>>>> zero_counts,
>>>>> +      alias_info->alias_list = new_checksum_alias (guid, fi_ptr,
>>>>> +                                                   zero_count_fixup,
>>>>>                                                     NULL);
>>>>>        return alias_info;
>>>>>      }
>>>>> @@ -436,12 +441,12 @@ cfg_checksum_insert (unsigned cfg_checksum, gcov_t
>>>>>
>>>>>  /* Insert a new checksum_alias struct into lineno_pointer_sets for
>>>>> function with
>>>>>     LINENO_CHECKSUM and CFG_CHECKSUM with associated GUID, FI_PTR, and
>>>>> -   ZERO_COUNTS flag.  */
>>>>> +   ZERO_COUNT_FIXUP flag pointer.  */
>>>>>
>>>>>  static void
>>>>>  checksum_set_insert (unsigned lineno_checksum, unsigned cfg_checksum,
>>>>>                       gcov_type guid, const struct gcov_fn_info *fi_ptr,
>>>>> -                     int zero_counts)
>>>>> +                     int *zero_count_fixup)
>>>>>  {
>>>>>    struct dyn_pointer_set *p = the_dyn_call_graph.lineno_pointer_sets;
>>>>>    if (!p)
>>>>> @@ -452,7 +457,7 @@ checksum_set_insert (unsigned lineno_checksum, uns
>>>>>    if (*m)
>>>>>      {
>>>>>        (*m)->cfg_checksum_list = cfg_checksum_insert (cfg_checksum, guid,
>>>>> -                                                     fi_ptr, zero_counts,
>>>>> +                                                     fi_ptr, 
>>>>> zero_count_fixup,
>>>>>                                                       
>>>>> (*m)->cfg_checksum_list);
>>>>>      }
>>>>>    else
>>>>> @@ -460,7 +465,8 @@ checksum_set_insert (unsigned lineno_checksum, uns
>>>>>        *m = XNEW (struct lineno_checksum_alias);
>>>>>        (*m)->lineno_checksum = lineno_checksum;
>>>>>        (*m)->cfg_checksum_list = cfg_checksum_insert (cfg_checksum, guid,
>>>>> -                                                     fi_ptr,
>>>>> zero_counts, NULL);
>>>>> +                                                     fi_ptr, 
>>>>> zero_count_fixup,
>>>>> +                                                     NULL);
>>>>>        p->n_elements++;
>>>>>      }
>>>>>  }
>>>>> @@ -801,10 +807,10 @@ gcov_build_callgraph_ic_fn (struct dyn_cgraph_node
>>>>>      }
>>>>>  }
>>>>>
>>>>> -/* Build the dynamic call graph.  */
>>>>> +/* Build the dynamic call graph and update ZERO_COUNTS flags.  */
>>>>>
>>>>>  static void
>>>>> -gcov_build_callgraph (void)
>>>>> +gcov_build_callgraph (int **zero_counts)
>>>>>  {
>>>>>    struct gcov_info *gi_ptr;
>>>>>    unsigned m_ix;
>>>>> @@ -852,9 +858,19 @@ static void
>>>>>                    if (total_arc_count != 0)
>>>>>                      the_dyn_call_graph.num_nodes_executed++;
>>>>>                    if (fixup_type)
>>>>> -                    checksum_set_insert (fi_ptr->lineno_checksum,
>>>>> -                                         fi_ptr->cfg_checksum, 
>>>>> caller->guid,
>>>>> -                                         fi_ptr, total_arc_count == 0);
>>>>> +                    {
>>>>> +                      int *zero_count_fixup = NULL;
>>>>> +                      /* Passing in a non-NULL zero_count_fixup pointer
>>>>> +                         indicates that the counts were all zero for this
>>>>> +                         function, and the fixup routine will set the 
>>>>> flag
>>>>> +                         if the function's counters are updated to 
>>>>> non-zero
>>>>> +                         values.  */
>>>>> +                      if (total_arc_count == 0)
>>>>> +                        zero_count_fixup = &zero_counts[m_ix][f_ix];
>>>>> +                      checksum_set_insert (fi_ptr->lineno_checksum,
>>>>> +                                           fi_ptr->cfg_checksum, 
>>>>> caller->guid,
>>>>> +                                           fi_ptr, zero_count_fixup);
>>>>> +                    }
>>>>>                  }
>>>>>                ci_ptr++;
>>>>>              }
>>>>> @@ -1251,7 +1267,14 @@ gcov_collect_imported_modules (const void *value,
>>>>>    out_array = (struct gcov_import_mod_array *) data1;
>>>>>
>>>>>    if (m->imp_mod != out_array->importing_module)
>>>>> +  {
>>>>>      out_array->imported_modules[out_array->len++] = m;
>>>>> +    /* Sanity check that the importing (primary) module is not
>>>>> +       actually the same as the new aux module. This could happen if
>>>>> +       we accidentally read in the same gcda file twice.  */
>>>>> +    gcc_assert (m->imp_mod->mod_info->ident !=
>>>>> +                out_array->importing_module->mod_info->ident);
>>>>> +  }
>>>>>
>>>>>    return 1;
>>>>>  }
>>>>> @@ -2957,7 +2980,7 @@ gcov_fixup_counters_checksum (const struct checksu
>>>>>    for (alias = info->alias_list; alias;
>>>>>         alias = alias->next_alias)
>>>>>      {
>>>>> -      if (alias->zero_counts)
>>>>> +      if (alias->zero_count_fixup)
>>>>>          {
>>>>>            found = 1;
>>>>>            break;
>>>>> @@ -2972,7 +2995,7 @@ gcov_fixup_counters_checksum (const struct checksu
>>>>>    for (alias = info->alias_list; alias;
>>>>>         alias = alias->next_alias)
>>>>>      {
>>>>> -      if (alias->zero_counts)
>>>>> +      if (alias->zero_count_fixup)
>>>>>          continue;
>>>>>        merge_ctrs (merged_ctrs, alias->fi_ptr->ctrs, alias->guid);
>>>>>        found = 1;
>>>>> @@ -2990,9 +3013,10 @@ gcov_fixup_counters_checksum (const struct checksu
>>>>>    for (alias = info->alias_list; alias;
>>>>>         alias = alias->next_alias)
>>>>>      {
>>>>> -      if (!alias->zero_counts)
>>>>> +      if (!alias->zero_count_fixup)
>>>>>          continue;
>>>>>        copy_ctrs (alias->fi_ptr->ctrs, alias->guid, merged_ctrs);
>>>>> +      *alias->zero_count_fixup = 1;
>>>>>      }
>>>>>
>>>>>    return 1;
>>>>> @@ -3040,11 +3064,13 @@ gcov_fixup_zero_counters (void)
>>>>>    return changed;
>>>>>  }
>>>>>
>>>>> -/* Compute module groups needed for L-IPO compilation.  Returns 1 if any
>>>>> -   counter fixups were applied, requiring a profile rewrite, 0 
>>>>> otherwise.  */
>>>>> +/* Compute module groups needed for L-IPO compilation.  The ZERO_COUNTS
>>>>> +   flags are set for functions with zero count fixups applied. Returns 1
>>>>> +   if any counter fixups were applied, requiring a profile rewrite,
>>>>> +   0 otherwise.  */
>>>>>
>>>>>  int
>>>>> -__gcov_compute_module_groups (void)
>>>>> +__gcov_compute_module_groups (int **zero_counts)
>>>>>  {
>>>>>    gcov_type cut_off_count;
>>>>>    char *seed = getenv ("LIPO_RANDOM_GROUPING");
>>>>> @@ -3091,7 +3117,7 @@ int
>>>>>      fixup_type = atoi (do_fixup);
>>>>>
>>>>>    /* First compute dynamic call graph.  */
>>>>> -  gcov_build_callgraph ();
>>>>> +  gcov_build_callgraph (zero_counts);
>>>>>
>>>>>    cut_off_count = gcov_compute_cutoff_count ();
>>>>>
>>>>> Index: libgcc/libgcov-driver.c
>>>>> ===================================================================
>>>>> --- libgcc/libgcov-driver.c     (revision 215230)
>>>>> +++ libgcc/libgcov-driver.c     (working copy)
>>>>> @@ -55,7 +55,7 @@ static gcov_unsigned_t gcov_cur_module_id = 0;
>>>>>
>>>>>
>>>>>  /* Dynamic call graph build and form module groups.  */
>>>>> -int __gcov_compute_module_groups (void) ATTRIBUTE_HIDDEN;
>>>>> +int __gcov_compute_module_groups (int **zero_counts) ATTRIBUTE_HIDDEN;
>>>>>  void __gcov_finalize_dyn_callgraph (void) ATTRIBUTE_HIDDEN;
>>>>>
>>>>>  /* The following functions can be called from outside of this file.  */
>>>>> @@ -129,6 +129,24 @@ set_gcov_list (struct gcov_info *head)
>>>>>    __gcov_list = head;
>>>>>  }
>>>>>
>>>>> +/* Flag if the current function being read was marked as having fixed-up
>>>>> +   zero counters.  */
>>>>> +static int __gcov_curr_fn_fixed_up;
>>>>> +
>>>>> +/* Set function fixed up flag.  */
>>>>> +void
>>>>> +set_gcov_fn_fixed_up (int fixed_up)
>>>>> +{
>>>>> +  __gcov_curr_fn_fixed_up = fixed_up;
>>>>> +}
>>>>> +
>>>>> +/* Return function fixed up flag.  */
>>>>> +int
>>>>> +get_gcov_fn_fixed_up (void)
>>>>> +{
>>>>> +  return __gcov_curr_fn_fixed_up;
>>>>> +}
>>>>> +
>>>>>  /* Size of the longest file name. */
>>>>>  /* We need to expose this static variable when compiling for gcov-tool.  
>>>>> */
>>>>>  #ifndef IN_GCOV_TOOL
>>>>> @@ -564,6 +582,7 @@ gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
>>>>>    int error = 0;
>>>>>    struct gcov_fn_buffer **fn_tail = &fn_buffer;
>>>>>    struct gcov_summary_buffer **sum_tail = &sum_buffer;
>>>>> +  int *zero_fixup_flags = NULL;
>>>>>
>>>>>    length = gcov_read_unsigned ();
>>>>>    if (!gcov_version (gi_ptr, length, gi_filename))
>>>>> @@ -625,6 +644,21 @@ gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
>>>>>        tag = gcov_read_unsigned ();
>>>>>      }
>>>>>
>>>>> +  if (tag == GCOV_TAG_COMDAT_ZERO_FIXUP)
>>>>> +    {
>>>>> +      length = gcov_read_unsigned ();
>>>>> +      gcov_unsigned_t num_fns = 0;
>>>>> +      zero_fixup_flags = gcov_read_comdat_zero_fixup (length, &num_fns);
>>>>> +      if (!zero_fixup_flags)
>>>>> +        {
>>>>> +          gcov_error ("profiling:%s:Error reading zero fixup flags\n",
>>>>> +                      gi_filename);
>>>>> +          return -1;
>>>>> +        }
>>>>> +
>>>>> +      tag = gcov_read_unsigned ();
>>>>> +    }
>>>>> +
>>>>>    /* Merge execution counts for each function.  */
>>>>>    for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
>>>>>         f_ix++, tag = gcov_read_unsigned ())
>>>>> @@ -658,6 +692,9 @@ gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
>>>>>            continue;
>>>>>          }
>>>>>
>>>>> +      if (zero_fixup_flags)
>>>>> +        set_gcov_fn_fixed_up (zero_fixup_flags[f_ix]);
>>>>> +
>>>>>        length = gcov_read_unsigned ();
>>>>>        if (length != gfi_ptr->ident)
>>>>>          goto read_mismatch;
>>>>> @@ -689,6 +726,7 @@ gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
>>>>>        if ((error = gcov_is_error ()))
>>>>>          goto read_error;
>>>>>      }
>>>>> +  free (zero_fixup_flags);
>>>>>
>>>>>    if (tag && tag != GCOV_TAG_MODULE_INFO)
>>>>>      {
>>>>> @@ -706,6 +744,34 @@ read_error:
>>>>>    return -1;
>>>>>  }
>>>>>
>>>>> +
>>>>> +/* Write NUM_FNS ZERO_COUNTS fixup flags to a gcda file starting from its
>>>>> +   current location.  */
>>>>> +
>>>>> +static void
>>>>> +gcov_write_comdat_zero_fixup (int *zero_counts, unsigned num_fns)
>>>>> +{
>>>>> +  unsigned f_ix;
>>>>> +  gcov_unsigned_t len = GCOV_TAG_COMDAT_ZERO_FIXUP_LENGTH (num_fns);
>>>>> +  gcov_write_tag_length (GCOV_TAG_COMDAT_ZERO_FIXUP, len);
>>>>> +
>>>>> +  gcov_write_unsigned (num_fns);
>>>>> +  gcov_unsigned_t bitvector = 0, b_ix = 0;
>>>>> +  for (f_ix = 0; f_ix != num_fns; f_ix++)
>>>>> +    {
>>>>> +      if (zero_counts[f_ix])
>>>>> +        bitvector |= 1 << b_ix;
>>>>> +      if (++b_ix == 32)
>>>>> +        {
>>>>> +          gcov_write_unsigned (bitvector);
>>>>> +          b_ix = 0;
>>>>> +          bitvector = 0;
>>>>> +        }
>>>>> +    }
>>>>> +  if (b_ix > 0)
>>>>> +    gcov_write_unsigned (bitvector);
>>>>> +}
>>>>> +
>>>>>  /* Write build_info strings from GI_PTR to a gcda file starting from
>>>>> its current
>>>>>     location.  */
>>>>>
>>>>> @@ -758,7 +824,7 @@ gcov_write_func_counters (struct gcov_info *gi_ptr
>>>>>            if (gfi_ptr && gfi_ptr->key == gi_ptr)
>>>>>              length = GCOV_TAG_FUNCTION_LENGTH;
>>>>>            else
>>>>> -                length = 0;
>>>>> +            length = 0;
>>>>>          }
>>>>>
>>>>>        gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
>>>>> @@ -1104,9 +1170,24 @@ gcov_dump_module_info (struct gcov_filename_aux *g
>>>>>  {
>>>>>    struct gcov_info *gi_ptr;
>>>>>
>>>>> +  unsigned max_module_id = 0;
>>>>> +  for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
>>>>> +    {
>>>>> +      unsigned mod_id = gi_ptr->mod_info->ident;
>>>>> +      if (max_module_id < mod_id)
>>>>> +        max_module_id = mod_id;
>>>>> +    }
>>>>> +  int **zero_counts = (int **) xcalloc (max_module_id, sizeof (int *));
>>>>> +  for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
>>>>> +    {
>>>>> +      unsigned mod_id = gi_ptr->mod_info->ident;
>>>>> +      zero_counts[mod_id-1] = (int *) xcalloc (gi_ptr->n_functions,
>>>>> +                                               sizeof (int));
>>>>> +    }
>>>>> +
>>>>>    /* Compute the module groups and record whether there were any
>>>>>       counter fixups applied that require rewriting the counters.  */
>>>>> -  int changed = __gcov_compute_module_groups ();
>>>>> +  int changed = __gcov_compute_module_groups (zero_counts);
>>>>>
>>>>>    /* Now write out module group info.  */
>>>>>    for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
>>>>> @@ -1129,8 +1210,15 @@ gcov_dump_module_info (struct gcov_filename_aux *g
>>>>>                gcov_position_t eof_pos = gi_ptr->eof_pos;
>>>>>                gcov_rewrite ();
>>>>>                gcov_seek (summary_end_pos);
>>>>> +
>>>>> +              unsigned mod_id = gi_ptr->mod_info->ident;
>>>>> +              gcov_write_comdat_zero_fixup (zero_counts[mod_id-1],
>>>>> +                                            gi_ptr->n_functions);
>>>>> +              gcov_position_t zero_fixup_eof_pos = gcov_position ();
>>>>> +
>>>>>                gcov_write_func_counters (gi_ptr);
>>>>> -              gcc_assert (eof_pos == gi_ptr->eof_pos);
>>>>> +              gcc_assert (eof_pos + (zero_fixup_eof_pos - 
>>>>> summary_end_pos)
>>>>> +                          == gi_ptr->eof_pos);
>>>>>              }
>>>>>          }
>>>>>        else
>>>>> @@ -1149,7 +1237,11 @@ gcov_dump_module_info (struct gcov_filename_aux *g
>>>>>                                    "profiling:%s:Error writing\n",
>>>>>                                    gi_filename);
>>>>>        gcov_write_import_file (gi_filename, gi_ptr);
>>>>> +      free (zero_counts[gi_ptr->mod_info->ident-1]);
>>>>>      }
>>>>> +
>>>>> +  free (zero_counts);
>>>>> +
>>>>>    __gcov_finalize_dyn_callgraph ();
>>>>>  }
>>>>>
>>>>> Index: libgcc/libgcov.h
>>>>> ===================================================================
>>>>> --- libgcc/libgcov.h    (revision 215230)
>>>>> +++ libgcc/libgcov.h    (working copy)
>>>>> @@ -349,6 +349,9 @@ gcov_get_sorted_import_module_array (struct gcov_i
>>>>>      ATTRIBUTE_HIDDEN;
>>>>>  GCOV_LINKAGE inline void gcov_rewrite (void);
>>>>>
>>>>> +extern void set_gcov_fn_fixed_up (int fixed_up);
>>>>> +extern int get_gcov_fn_fixed_up (void);
>>>>> +
>>>>>  /* "Counts" stored in gcda files can be a real counter value, or
>>>>>     an target address. When differentiate these two types because
>>>>>     when manipulating counts, we should only change real counter values,
>>>>> @@ -361,7 +364,13 @@ gcov_get_counter (void)
>>>>>    /* This version is for reading count values in libgcov runtime:
>>>>>       we read from gcda files.  */
>>>>>
>>>>> -  return gcov_read_counter ();
>>>>> +  if (get_gcov_fn_fixed_up ())
>>>>> +    {
>>>>> +      gcov_read_counter ();
>>>>> +      return 0;
>>>>> +    }
>>>>> +  else
>>>>> +    return gcov_read_counter ();
>>>>>  #else
>>>>>    /* This version is for gcov-tool. We read the value from memory and
>>>>>       multiply it by the merge weight.  */
>>>>> @@ -380,7 +389,13 @@ gcov_get_counter_target (void)
>>>>>    /* This version is for reading count target values in libgcov runtime:
>>>>>       we read from gcda files.  */
>>>>>
>>>>> -  return gcov_read_counter ();
>>>>> +  if (get_gcov_fn_fixed_up ())
>>>>> +    {
>>>>> +      gcov_read_counter ();
>>>>> +      return 0;
>>>>> +    }
>>>>> +  else
>>>>> +    return gcov_read_counter ();
>>>>>  #else
>>>>>    /* This version is for gcov-tool.  We read the value from memory
>>>>> and we do NOT
>>>>>       multiply it by the merge weight.  */
>>>>> Index: libgcc/libgcov-util.c
>>>>> ===================================================================
>>>>> --- libgcc/libgcov-util.c       (revision 215230)
>>>>> +++ libgcc/libgcov-util.c       (working copy)
>>>>> @@ -66,6 +66,7 @@ static void tag_lines (unsigned, unsigned);
>>>>>  static void tag_counters (unsigned, unsigned);
>>>>>  static void tag_summary (unsigned, unsigned);
>>>>>  static void tag_module_info (unsigned, unsigned);
>>>>> +static void tag_zero_fixup (unsigned, unsigned);
>>>>>
>>>>>  /* The gcov_info for the first module.  */
>>>>>  static struct gcov_info *curr_gcov_info;
>>>>> @@ -88,6 +89,8 @@ static int k_ctrs_types;
>>>>>  /* The longest length of all the filenames.  */
>>>>>  static int max_filename_len;
>>>>>
>>>>> +static int *zero_fixup_flags = NULL;
>>>>> +
>>>>>  /* Merge functions for counters.  Similar to __gcov_dyn_ipa_merge_*
>>>>>     functions in dyn-ipa.c, which were derived from these, except
>>>>>     the versions in dyn-ipa are used when merging from another array.  */
>>>>> @@ -143,6 +146,7 @@ static const tag_format_t tag_table[] =
>>>>>    {GCOV_TAG_OBJECT_SUMMARY, "OBJECT_SUMMARY", tag_summary},
>>>>>    {GCOV_TAG_PROGRAM_SUMMARY, "PROGRAM_SUMMARY", tag_summary},
>>>>>    {GCOV_TAG_MODULE_INFO, "MODULE INFO", tag_module_info},
>>>>> +  {GCOV_TAG_COMDAT_ZERO_FIXUP, "ZERO FIXUP", tag_zero_fixup},
>>>>>    {0, NULL, NULL}
>>>>>  };
>>>>>
>>>>> @@ -169,14 +173,18 @@ tag_function (unsigned tag ATTRIBUTE_UNUSED, unsig
>>>>>       k_ctrs[i].num = 0;
>>>>>    k_ctrs_types = 0;
>>>>>
>>>>> +  if (zero_fixup_flags)
>>>>> +    {
>>>>> +      set_gcov_fn_fixed_up (zero_fixup_flags[num_fn_info]);
>>>>> +      if (get_gcov_fn_fixed_up () && verbose)
>>>>> +        fprintf (stderr, "Function id=%d fixed up\n", 
>>>>> curr_fn_info->ident);
>>>>> +    }
>>>>> +
>>>>>    curr_fn_info->key = curr_gcov_info;
>>>>>    curr_fn_info->ident = gcov_read_unsigned ();
>>>>>    curr_fn_info->lineno_checksum = gcov_read_unsigned ();
>>>>>    curr_fn_info->cfg_checksum = gcov_read_unsigned ();
>>>>>    num_fn_info++;
>>>>> -
>>>>> -  if (verbose)
>>>>> -    fnotice (stdout, "tag one function id=%d\n", curr_fn_info->ident);
>>>>>  }
>>>>>
>>>>>  /* Handler for reading block tag.  */
>>>>> @@ -226,7 +234,13 @@ tag_counters (unsigned tag, unsigned length)
>>>>>    gcc_assert (values);
>>>>>
>>>>>    for (ix = 0; ix != n_counts; ix++)
>>>>> -    values[ix] = gcov_read_counter ();
>>>>> +    {
>>>>> +      gcov_type val = gcov_read_counter ();
>>>>> +      if (!get_gcov_fn_fixed_up ())
>>>>> +        values[ix] = val;
>>>>> +      else
>>>>> +        values[ix] = 0;
>>>>> +    }
>>>>>  }
>>>>>
>>>>>  /* Handler for reading summary tag.  */
>>>>> @@ -323,7 +337,7 @@ lipo_process_substitute_string_1 (char *input_str,
>>>>>        char *t;
>>>>>
>>>>>        if (verbose)
>>>>> -        printf ("Substitute: %s \n", input_str);
>>>>> +        fprintf (stderr, "Substitute: %s \n", input_str);
>>>>>        t = (char*) xmalloc (strlen (input_str) + 1
>>>>>            + strlen (new_str) - strlen (cur_str));
>>>>>        *p = 0;
>>>>> @@ -332,7 +346,7 @@ lipo_process_substitute_string_1 (char *input_str,
>>>>>        strcat (t, new_str);
>>>>>        strcat (t, p + strlen (cur_str));
>>>>>        if (verbose)
>>>>> -        printf ("       -->  %s\n", t);
>>>>> +        fprintf (stderr, "       -->  %s\n", t);
>>>>>        return t;
>>>>>      }
>>>>>
>>>>> @@ -397,6 +411,16 @@ tag_module_info (unsigned tag ATTRIBUTE_UNUSED, un
>>>>>      free (mod_info);
>>>>>  }
>>>>>
>>>>> +/* Handler for reading the COMDAT zero-profile fixup section.  */
>>>>> +
>>>>> +static void
>>>>> +tag_zero_fixup (unsigned tag ATTRIBUTE_UNUSED, unsigned length)
>>>>> +{
>>>>> +  gcov_unsigned_t num_fns = 0;
>>>>> +  zero_fixup_flags = gcov_read_comdat_zero_fixup (length, &num_fns);
>>>>> +  gcc_assert (zero_fixup_flags);
>>>>> +}
>>>>> +
>>>>>  /* Read the content of a gcda file FILENAME, and return a gcov_info
>>>>> data structure.
>>>>>     Program level summary CURRENT_SUMMARY will also be updated.  */
>>>>>
>>>>> @@ -520,6 +544,7 @@ read_gcda_file (const char *filename)
>>>>>      }
>>>>>
>>>>>    read_gcda_finalize (obj_info);
>>>>> +  free (zero_fixup_flags);
>>>>>    gcov_close ();
>>>>>
>>>>>    return obj_info;
>>>>> @@ -1099,7 +1124,7 @@ gcov_profile_scale (struct gcov_info *profile, flo
>>>>>    unsigned f_ix;
>>>>>
>>>>>    if (verbose)
>>>>> -    fnotice (stdout, "scale_factor is %f or %d/%d\n", scale_factor, n, 
>>>>> d);
>>>>> +    fnotice (stderr, "scale_factor is %f or %d/%d\n", scale_factor, n, 
>>>>> d);
>>>>>
>>>>>    /* Scaling the counters.  */
>>>>>    for (gi_ptr = profile; gi_ptr; gi_ptr = gi_ptr->next)
>>>>> @@ -1167,7 +1192,7 @@ gcov_profile_normalize (struct gcov_info *profile,
>>>>>    scale_factor = (float)max_val / curr_max_val;
>>>>>  #if !defined (_WIN32)
>>>>>    if (verbose)
>>>>> -    fnotice (stdout, "max_val is %lld\n", (long long) curr_max_val);
>>>>> +    fnotice (stderr, "max_val is %lld\n", (long long) curr_max_val);
>>>>>  #endif
>>>>>
>>>>>    return gcov_profile_scale (profile, scale_factor, 0, 0);
>>>>>
>>>>> --
>>>>> Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413
>>>
>>>
>>>
>>> --
>>> Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413
>
>
>
> --
> Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413

Reply via email to