This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix support for multiple counters sections


Hello,

now that I was finally able to port vpt to mainline, several bugs in
support of additional counter sections showed up. The attached patch
fixes them.

During writing it, I was forced to convert gcov_exit function from
the "manual strength reduction" style it was written in in order
to understand what is going on.  Is there some good reason for
leaving it in that state?  It is somewhat nonstandard and also
pretty hard to read, especially to distinguish variables that
are really induction variables from those that only pretend to (c_ix
and some other).

Zdenek

Changelog:

	* libgcov.c (gcov_exit): Cleanup and fix.
	* profile.c (compute_value_histograms): Don't try to read profiles
	that are not present.

Index: libgcov.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/libgcov.c,v
retrieving revision 1.20
diff -c -3 -p -r1.20 libgcov.c
*** libgcov.c	10 Jul 2003 14:13:00 -0000	1.20
--- libgcov.c	31 Jul 2003 17:21:03 -0000
*************** gcov_exit (void)
*** 122,153 ****
    struct gcov_info *gi_ptr;
    struct gcov_summary this_program;
    struct gcov_summary all;
  
    memset (&all, 0, sizeof (all));
    /* Find the totals for this execution.  */
    memset (&this_program, 0, sizeof (this_program));
    for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
      {
!       const struct gcov_ctr_info *ci_ptr;
!       struct gcov_ctr_summary *cs_ptr;
!       unsigned t_ix;
!       
!       for (t_ix = 0, ci_ptr = gi_ptr->counts, cs_ptr = this_program.ctrs;
! 	   t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++, cs_ptr++)
! 	if ((1 << t_ix) & gi_ptr->ctr_mask)
! 	  {
! 	    const gcov_type *c_ptr;
! 	    gcov_unsigned_t c_num;
  
! 	    cs_ptr->num += ci_ptr->num;
! 	    for (c_num = ci_ptr->num, c_ptr = ci_ptr->values; c_num--; c_ptr++)
! 	      {
! 		cs_ptr->sum_all += *c_ptr;
! 		if (cs_ptr->run_max < *c_ptr)
! 		  cs_ptr->run_max = *c_ptr;
! 	      }
! 	    ci_ptr++;
! 	  }
      }
  
    /* Now merge each file.  */
--- 122,153 ----
    struct gcov_info *gi_ptr;
    struct gcov_summary this_program;
    struct gcov_summary all;
+   struct gcov_ctr_summary *cs_ptr;
+   const struct gcov_ctr_info *ci_ptr;
+   unsigned t_ix;
+   gcov_unsigned_t c_num;
  
    memset (&all, 0, sizeof (all));
    /* Find the totals for this execution.  */
    memset (&this_program, 0, sizeof (this_program));
    for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
      {
!       ci_ptr = gi_ptr->counts;
!       for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
! 	{
! 	  if (!((1 << t_ix) & gi_ptr->ctr_mask))
! 	    continue;
  
! 	  cs_ptr = &this_program.ctrs[t_ix];
! 	  cs_ptr->num += ci_ptr->num;
! 	  for (c_num = 0; c_num < ci_ptr->num; c_num++)
! 	    {
!       	      cs_ptr->sum_all += ci_ptr->values[c_num];
! 	      if (cs_ptr->run_max < ci_ptr->values[c_num])
! 		cs_ptr->run_max = ci_ptr->values[c_num];
! 	    }
! 	  ci_ptr++;
! 	}
      }
  
    /* Now merge each file.  */
*************** gcov_exit (void)
*** 158,193 ****
        gcov_type *values[GCOV_COUNTERS];
        const struct gcov_fn_info *fi_ptr;
        unsigned fi_stride;
!       unsigned c_ix, t_ix, f_ix;
!       const struct gcov_ctr_info *ci_ptr;
!       struct gcov_ctr_summary *cs_ptr;
        struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
        int error = 0;
        gcov_unsigned_t tag, length;
        gcov_position_t summary_pos = 0;
  
        memset (&this_object, 0, sizeof (this_object));
        memset (&object, 0, sizeof (object));
        
        /* Totals for this object file.  */
!       for (t_ix = c_ix = 0,
! 	     ci_ptr = gi_ptr->counts, cs_ptr = this_object.ctrs;
! 	   t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++, cs_ptr++)
  	if ((1 << t_ix) & gi_ptr->ctr_mask)
  	  {
! 	    const gcov_type *c_ptr;
! 	    gcov_unsigned_t c_num;
! 
! 	    cs_ptr->num += ci_ptr->num;
! 	    values[c_ix] = ci_ptr->values;
! 	    for (c_num = ci_ptr->num, c_ptr = ci_ptr->values; c_num--; c_ptr++)
! 	      {
! 		cs_ptr->sum_all += *c_ptr;
! 		if (cs_ptr->run_max < *c_ptr)
! 		  cs_ptr->run_max = *c_ptr;
! 	      }
  	    c_ix++;
- 	    ci_ptr++;
  	  }
  
        /* Calculate the function_info stride. This depends on the
--- 158,199 ----
        gcov_type *values[GCOV_COUNTERS];
        const struct gcov_fn_info *fi_ptr;
        unsigned fi_stride;
!       unsigned c_ix, f_ix, n_counts;
        struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
        int error = 0;
        gcov_unsigned_t tag, length;
        gcov_position_t summary_pos = 0;
+       gcov_type *c_ptr;
+       gcov_merge_fn merge;
  
        memset (&this_object, 0, sizeof (this_object));
        memset (&object, 0, sizeof (object));
        
        /* Totals for this object file.  */
!       ci_ptr = gi_ptr->counts;
!       for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
! 	{
! 	  if (!((1 << t_ix) & gi_ptr->ctr_mask))
! 	    continue;
! 
! 	  cs_ptr = &this_program.ctrs[t_ix];
! 	  cs_ptr->num += ci_ptr->num;
! 	  for (c_num = 0; c_num < ci_ptr->num; c_num++)
! 	    {
! 	      cs_ptr->sum_all += ci_ptr->values[c_num];
! 	      if (cs_ptr->run_max < ci_ptr->values[c_num])
! 		cs_ptr->run_max = ci_ptr->values[c_num];
! 	    }
! 
! 	  ci_ptr++;
! 	}
! 
!       c_ix = 0;
!       for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
  	if ((1 << t_ix) & gi_ptr->ctr_mask)
  	  {
! 	    values[c_ix] = gi_ptr->counts[c_ix].values;
  	    c_ix++;
  	  }
  
        /* Calculate the function_info stride. This depends on the
*************** gcov_exit (void)
*** 231,241 ****
  	    }
  	  
  	  /* Merge execution counts for each function.  */
! 	  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))
  	    {
  	      tag = gcov_read_unsigned ();
  	      length = gcov_read_unsigned ();
  
--- 237,246 ----
  	    }
  	  
  	  /* Merge execution counts for each function.  */
! 	  for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
  	    {
+ 	      fi_ptr = (const struct gcov_fn_info *)
+ 		      ((const char *) gi_ptr->functions + f_ix * fi_stride);
  	      tag = gcov_read_unsigned ();
  	      length = gcov_read_unsigned ();
  
*************** gcov_exit (void)
*** 252,276 ****
  		  goto read_fatal;
  		}
  
! 	      for (c_ix = t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
! 		if ((1 << t_ix) & gi_ptr->ctr_mask)
! 		  {
! 		    unsigned n_counts = fi_ptr->n_ctrs[c_ix];
! 		    gcov_merge_fn merge = gi_ptr->counts[c_ix].merge;
  		    
! 		    tag = gcov_read_unsigned ();
! 		    length = gcov_read_unsigned ();
! 		    if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
! 			|| length != GCOV_TAG_COUNTER_LENGTH (n_counts))
! 		      goto read_mismatch;
! 		    (*merge) (values[c_ix], n_counts);
! 		    values[c_ix] += n_counts;
! 		    c_ix++;
  		}
  	      if ((error = gcov_is_error ()))
  		goto read_error;
  	    }
  
  	  /* Check program & object summary */
  	  while (1)
  	    {
--- 257,285 ----
  		  goto read_fatal;
  		}
  
! 	      c_ix = 0;
! 	      for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
! 		{
! 		  if (!((1 << t_ix) & gi_ptr->ctr_mask))
! 		    continue;
! 		  
! 		  n_counts = fi_ptr->n_ctrs[c_ix];
! 		  merge = gi_ptr->counts[c_ix].merge;
  		    
! 		  tag = gcov_read_unsigned ();
! 		  length = gcov_read_unsigned ();
! 		  if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
! 		      || length != GCOV_TAG_COUNTER_LENGTH (n_counts))
! 		    goto read_mismatch;
! 		  (*merge) (values[c_ix], n_counts);
! 		  values[c_ix] += n_counts;
! 		  c_ix++;
  		}
  	      if ((error = gcov_is_error ()))
  		goto read_error;
  	    }
  
+ 	  f_ix = ~0u;
  	  /* Check program & object summary */
  	  while (1)
  	    {
*************** gcov_exit (void)
*** 310,322 ****
  
        /* 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,
! 	     cs_all = all.ctrs;
! 	   t_ix != GCOV_COUNTERS_SUMMABLE;
! 	   t_ix++, cs_obj++, cs_tobj++, cs_prg++, cs_tprg++, cs_all++)
  	{
  	  if ((1 << t_ix) & gi_ptr->ctr_mask)
  	    {
  	      if (!cs_obj->runs++)
--- 319,332 ----
  
        /* Merge the summaries.  */
        f_ix = ~0u;
!       for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
  	{
+ 	  cs_obj = &object.ctrs[t_ix];
+ 	  cs_tobj = &this_object.ctrs[t_ix];
+ 	  cs_prg = &program.ctrs[t_ix];
+ 	  cs_tprg = &program.ctrs[t_ix];
+ 	  cs_all = &all.ctrs[t_ix];
+ 
  	  if ((1 << t_ix) & gi_ptr->ctr_mask)
  	    {
  	      if (!cs_obj->runs++)
*************** gcov_exit (void)
*** 336,344 ****
  	      if (cs_prg->run_max < cs_tprg->run_max)
  		cs_prg->run_max = cs_tprg->run_max;
  	      cs_prg->sum_max += cs_tprg->run_max;
- 	      
- 	      values[c_ix] = gi_ptr->counts[c_ix].values;
- 	      c_ix++;
  	    }
  	  else if (cs_obj->num || cs_prg->num)
  	    goto read_mismatch;
--- 346,351 ----
*************** gcov_exit (void)
*** 356,361 ****
--- 363,376 ----
  	    }
  	}
        
+       c_ix = 0;
+       for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
+ 	if ((1 << t_ix) & gi_ptr->ctr_mask)
+ 	  {
+ 	    values[c_ix] = gi_ptr->counts[c_ix].values;
+ 	    c_ix++;
+ 	  }
+ 
        program.checksum = gcov_crc32;
        
        /* Write out the data.  */
*************** gcov_exit (void)
*** 363,391 ****
        gcov_write_unsigned (gi_ptr->stamp);
        
        /* Write execution counts for each function.  */
!       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))
  	{
  	  /* Announce function.  */
  	  gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
  	  gcov_write_unsigned (fi_ptr->ident);
  	  gcov_write_unsigned (fi_ptr->checksum);
  
! 	  for (c_ix = t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
! 	    if ((1 << t_ix) & gi_ptr->ctr_mask)
! 	      {
! 		unsigned n_counts = fi_ptr->n_ctrs[c_ix];
! 		gcov_type *c_ptr;
  		    
! 		gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
! 				       GCOV_TAG_COUNTER_LENGTH (n_counts));
! 		c_ptr = values[c_ix];
! 		while (n_counts--)
! 		  gcov_write_counter (*c_ptr++);
! 		values[c_ix] = c_ptr;
! 		c_ix++;
! 	      }
  	}
  
        /* Object file summary.  */
--- 378,410 ----
        gcov_write_unsigned (gi_ptr->stamp);
        
        /* Write execution counts for each function.  */
!       for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
  	{
+ 	  fi_ptr = (const struct gcov_fn_info *)
+ 		  ((const char *) gi_ptr->functions + f_ix * fi_stride);
+ 
  	  /* Announce function.  */
  	  gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
  	  gcov_write_unsigned (fi_ptr->ident);
  	  gcov_write_unsigned (fi_ptr->checksum);
  
! 	  c_ix = 0;
! 	  for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
! 	    {
! 	      if (!((1 << t_ix) & gi_ptr->ctr_mask))
! 		continue;
! 
! 	      n_counts = fi_ptr->n_ctrs[c_ix];
  		    
! 	      gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
! 				     GCOV_TAG_COUNTER_LENGTH (n_counts));
! 	      c_ptr = values[c_ix];
! 	      while (n_counts--)
! 		gcov_write_counter (*c_ptr++);
! 
! 	      values[c_ix] = c_ptr;
! 	      c_ix++;
! 	    }
  	}
  
        /* Object file summary.  */

Index: profile.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/profile.c,v
retrieving revision 1.124
diff -c -3 -p -r1.124 profile.c
*** profile.c	30 Jul 2003 19:23:30 -0000	1.124
--- profile.c	31 Jul 2003 17:21:06 -0000
*************** compute_value_histograms (unsigned n_val
*** 622,630 ****
    any = 0;
    for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
      {
        histogram_counts[t] =
  	get_coverage_counts (COUNTER_FOR_HIST_TYPE (t),
! 			     n_histogram_counters[t], &profile_info);
        if (histogram_counts[t])
  	any = 1;
        act_count[t] = histogram_counts[t];
--- 622,636 ----
    any = 0;
    for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
      {
+       if (!n_histogram_counters[t])
+ 	{
+ 	  histogram_counts[t] = NULL;
+ 	  continue;
+ 	}
+ 
        histogram_counts[t] =
  	get_coverage_counts (COUNTER_FOR_HIST_TYPE (t),
! 			     n_histogram_counters[t], NULL);
        if (histogram_counts[t])
  	any = 1;
        act_count[t] = histogram_counts[t];


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]