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: Make gcov_type unsigned.


Hi,
this patch makes gcov_type an unsigned type. This will allow the gcov
files to only contain unsigned types (but not yet). This patch is backwards
compatible, provided no counter actually overflows into bit 63.

Also changes the function_checksum to be a crc32, rather than an ad hoc hash.

booted & tested on i686-pc-linux-gnu, ok for basic-improvements?

nathan
-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2002-09-02  Nathan Sidwell  <nathan@codesourcery.com>

	* basic-block.h (gcov_type): Make unsigned.
	* cfg.c (dump_flow_info): Make comparisons unsigned correct.
	* cfgcleanup.c (try_foreward_edges): Likewise.
	(try_crossjump_to_edge): Likewise.
	* cfglayout.c (cfg_layout_duplicate_bb): Likewise.
	* cfgloop.c (make_forwarder_block): Likewise.
	* cfgrtl.c (verify_flow_info): Likewise.
	* predict.c (counts_to_freqs): Use gcov_type.
	* profile.c (compute_checksum): Generate CRC32.
	* profile.h (struct profile_info): Adjust checksum type.
	* gcov-io.h (__store_gcov_type): Adjust.
	(__store_long): New function.

Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/basic-block.h,v
retrieving revision 1.158
diff -c -3 -p -r1.158 basic-block.h
*** basic-block.h	29 Jul 2002 18:40:45 -0000	1.158
--- basic-block.h	4 Sep 2002 09:48:08 -0000
*************** do {									\
*** 113,119 ****
  #define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
  
  /* Type we use to hold basic block counters.  Should be at least 64bit.  */
! typedef HOST_WIDEST_INT gcov_type;
  
  /* Control flow edge information.  */
  typedef struct edge_def {
--- 113,119 ----
  #define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
  
  /* Type we use to hold basic block counters.  Should be at least 64bit.  */
! typedef unsigned HOST_WIDEST_INT gcov_type;
  
  /* Control flow edge information.  */
  typedef struct edge_def {
Index: cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfg.c,v
retrieving revision 1.35
diff -c -3 -p -r1.35 cfg.c
*** cfg.c	10 Aug 2002 18:00:54 -0000	1.35
--- cfg.c	4 Sep 2002 09:48:20 -0000
*************** dump_flow_info (file)
*** 606,618 ****
        lsum = 0;
        for (e = bb->pred; e; e = e->pred_next)
  	lsum += e->count;
!       if (lsum - bb->count > 100 || lsum - bb->count < -100)
  	fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
  		 (int)lsum, (int)bb->count);
        lsum = 0;
        for (e = bb->succ; e; e = e->succ_next)
  	lsum += e->count;
!       if (bb->succ && (lsum - bb->count > 100 || lsum - bb->count < -100))
  	fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
  		 (int)lsum, (int)bb->count);
      }
--- 606,618 ----
        lsum = 0;
        for (e = bb->pred; e; e = e->pred_next)
  	lsum += e->count;
!       if (lsum > bb->count + 100 || lsum + 100 < bb->count)
  	fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
  		 (int)lsum, (int)bb->count);
        lsum = 0;
        for (e = bb->succ; e; e = e->succ_next)
  	lsum += e->count;
!       if (bb->succ && (lsum > bb->count + 100 || lsum +100 < bb->count))
  	fprintf (file, "Invalid sum of incomming counts %i, should be %i\n",
  		 (int)lsum, (int)bb->count);
      }
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.63
diff -c -3 -p -r1.63 cfgcleanup.c
*** cfgcleanup.c	5 Aug 2002 18:46:32 -0000	1.63
--- cfgcleanup.c	4 Sep 2002 09:48:24 -0000
*************** try_forward_edges (mode, b)
*** 568,578 ****
  	    {
  	      edge t;
  
! 	      first->count -= edge_count;
! 	      if (first->count < 0)
  		first->count = 0;
! 	      first->frequency -= edge_frequency;
! 	      if (first->frequency < 0)
  		first->frequency = 0;
  	      if (first->succ->succ_next)
  		{
--- 568,580 ----
  	    {
  	      edge t;
  
! 	      if (first->count >= edge_count)
! 		first->count -= edge_count;
! 	      else
  		first->count = 0;
! 	      if (first->frequency >= edge_frequency)
! 		first->frequency -= edge_frequency;
! 	      else
  		first->frequency = 0;
  	      if (first->succ->succ_next)
  		{
*************** try_forward_edges (mode, b)
*** 614,621 ****
  		  t = first->succ;
  		}
  
! 	      t->count -= edge_count;
! 	      if (t->count < 0)
  		t->count = 0;
  	      first = t->dest;
  	    }
--- 616,624 ----
  		  t = first->succ;
  		}
  
! 	      if (t->count >= edge_count)
! 		t->count -= edge_count;
! 	      else
  		t->count = 0;
  	      first = t->dest;
  	    }
*************** try_crossjump_to_edge (mode, e1, e2)
*** 1410,1424 ****
  
        if (FORWARDER_BLOCK_P (s2->dest))
  	{
! 	  s2->dest->succ->count -= s2->count;
! 	  if (s2->dest->succ->count < 0)
  	    s2->dest->succ->count = 0;
! 	  s2->dest->count -= s2->count;
! 	  s2->dest->frequency -= EDGE_FREQUENCY (s);
! 	  if (s2->dest->frequency < 0)
! 	    s2->dest->frequency = 0;
! 	  if (s2->dest->count < 0)
  	    s2->dest->count = 0;
  	}
  
        if (!redirect_to->frequency && !src1->frequency)
--- 1413,1432 ----
  
        if (FORWARDER_BLOCK_P (s2->dest))
  	{
! 	  if (s2->dest->succ->count >= s2->count)
! 	    s2->dest->succ->count -= s2->count;
! 	  else
  	    s2->dest->succ->count = 0;
! 	  
! 	  if (s2->dest->count >= s2->count)
! 	    s2->dest->count -= s2->count;
! 	  else
  	    s2->dest->count = 0;
+ 
+ 	  if (s2->dest->frequency >= EDGE_FREQUENCY (s))
+ 	    s2->dest->frequency -= EDGE_FREQUENCY (s);
+ 	  else
+ 	    s2->dest->frequency = 0;
  	}
  
        if (!redirect_to->frequency && !src1->frequency)
Index: cfglayout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfglayout.c,v
retrieving revision 1.21
diff -c -3 -p -r1.21 cfglayout.c
*** cfglayout.c	21 Jun 2002 19:05:00 -0000	1.21
--- cfglayout.c	4 Sep 2002 09:48:26 -0000
*************** cfg_layout_duplicate_bb (bb, e)
*** 932,951 ****
      }
  
    new_bb->count = new_count;
!   bb->count -= new_count;
  
    if (e)
      {
        new_bb->frequency = EDGE_FREQUENCY (e);
!       bb->frequency -= EDGE_FREQUENCY (e);
  
        cfg_layout_redirect_edge (e, new_bb);
      }
  
-   if (bb->count < 0)
-     bb->count = 0;
-   if (bb->frequency < 0)
-     bb->frequency = 0;
  
    RBI (new_bb)->original = bb;
    return new_bb;
--- 932,953 ----
      }
  
    new_bb->count = new_count;
!   if (bb->count >= new_count)
!     bb->count -= new_count;
!   else
!     bb->count = 0;
  
    if (e)
      {
        new_bb->frequency = EDGE_FREQUENCY (e);
!       if (bb->frequency >= EDGE_FREQUENCY (e))
! 	bb->frequency -= EDGE_FREQUENCY (e);
!       else
! 	bb->frequency = 0;
  
        cfg_layout_redirect_edge (e, new_bb);
      }
  
  
    RBI (new_bb)->original = bb;
    return new_bb;
Index: cfgloop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloop.c,v
retrieving revision 1.15
diff -c -3 -p -r1.15 cfgloop.c
*** cfgloop.c	20 Jun 2002 17:50:48 -0000	1.15
--- cfgloop.c	4 Sep 2002 09:48:27 -0000
*************** make_forwarder_block (bb, redirect_latch
*** 625,635 ****
  	  || !((redirect_latch && LATCH_EDGE (e))
  	       || (redirect_nonlatch && !LATCH_EDGE (e))))
  	{
! 	  dummy->frequency -= EDGE_FREQUENCY (e);
! 	  dummy->count -= e->count;
! 	  if (dummy->frequency < 0)
  	    dummy->frequency = 0;
! 	  if (dummy->count < 0)
  	    dummy->count = 0;
  	  redirect_edge_with_latch_update (e, bb);
  	}
--- 625,638 ----
  	  || !((redirect_latch && LATCH_EDGE (e))
  	       || (redirect_nonlatch && !LATCH_EDGE (e))))
  	{
! 	  if (dummy->frequency >= EDGE_FREQUENCY (e))
! 	    dummy->frequency -= EDGE_FREQUENCY (e);
! 	  else
  	    dummy->frequency = 0;
! 
! 	  if (dummy->count >= e->count)
! 	    dummy->count -= e->count;
! 	  else
  	    dummy->count = 0;
  	  redirect_edge_with_latch_update (e, bb);
  	}
Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v
retrieving revision 1.58
diff -c -3 -p -r1.58 cfgrtl.c
*** cfgrtl.c	21 Jun 2002 19:05:00 -0000	1.58
--- cfgrtl.c	4 Sep 2002 09:48:32 -0000
*************** verify_flow_info ()
*** 1764,1781 ****
  	      err = 1;
  	    }
  	}
-       if (bb->count < 0)
- 	{
- 	  error ("verify_flow_info: Wrong count of block %i %i",
- 	         bb->index, (int)bb->count);
- 	  err = 1;
- 	}
-       if (bb->frequency < 0)
- 	{
- 	  error ("verify_flow_info: Wrong frequency of block %i %i",
- 	         bb->index, bb->frequency);
- 	  err = 1;
- 	}
        for (e = bb->succ; e; e = e->succ_next)
  	{
  	  if (last_visited [e->dest->index + 2] == bb)
--- 1764,1769 ----
*************** verify_flow_info ()
*** 1788,1799 ****
  	    {
  	      error ("verify_flow_info: Wrong probability of edge %i->%i %i",
  		     e->src->index, e->dest->index, e->probability);
- 	      err = 1;
- 	    }
- 	  if (e->count < 0)
- 	    {
- 	      error ("verify_flow_info: Wrong count of edge %i->%i %i",
- 		     e->src->index, e->dest->index, (int)e->count);
  	      err = 1;
  	    }
  
--- 1776,1781 ----
Index: gcov-io.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcov-io.h,v
retrieving revision 1.16
diff -c -3 -p -r1.16 gcov-io.h
*** gcov-io.h	4 Jun 2002 11:30:28 -0000	1.16
--- gcov-io.h	4 Sep 2002 09:48:57 -0000
*************** Software Foundation, 59 Temple Place - S
*** 26,31 ****
--- 26,33 ----
  
  static int __fetch_long	PARAMS ((long *, char *, size_t))
  	ATTRIBUTE_UNUSED;
+ static int __store_long PARAMS ((long, char *, size_t))
+ 	ATTRIBUTE_UNUSED;
  static int __read_long  PARAMS ((long *, FILE *, size_t))
  	ATTRIBUTE_UNUSED;
  static int __write_long PARAMS ((long, FILE *, size_t))
*************** __store_gcov_type (value, dest, bytes)
*** 55,82 ****
       char *dest;
       size_t bytes;
  {
-   int upper_bit = (value < 0 ? 128 : 0);
    size_t i;
  
-   if (value < 0)
-     {
-       gcov_type oldvalue = value;
-       value = -value;
-       if (oldvalue != -value)
- 	return 1;
-     }
- 
    for(i = 0 ; i < (sizeof (value) < bytes ? sizeof (value) : bytes) ; i++) {
!     dest[i] = value & (i == (bytes - 1) ? 127 : 255);
      value = value / 256;
    }
  
!   if (value && value != -1)
      return 1;
  
    for(; i < bytes ; i++)
      dest[i] = 0;
-   dest[bytes - 1] |= upper_bit;
    return 0;
  }
  
--- 57,74 ----
       char *dest;
       size_t bytes;
  {
    size_t i;
  
    for(i = 0 ; i < (sizeof (value) < bytes ? sizeof (value) : bytes) ; i++) {
!     dest[i] = value & 255;
      value = value / 256;
    }
  
!   if (value)
      return 1;
  
    for(; i < bytes ; i++)
      dest[i] = 0;
    return 0;
  }
  
*************** __fetch_gcov_type (dest, source, bytes)
*** 94,113 ****
    int i;
  
    for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
!     if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
        return 1;
  
    for (; i >= 0; i--)
!     value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
! 
!   if ((source[bytes - 1] & 128) && (value > 0))
!     value = - value;
  
    *dest = value;
    return 0;
  }
  
  static int
  __fetch_long (dest, source, bytes)
       long *dest;
       char *source;
--- 86,133 ----
    int i;
  
    for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
!     if (source[i])
        return 1;
  
    for (; i >= 0; i--)
!     value = value * 256 + (source[i] & 255);
  
    *dest = value;
    return 0;
  }
  
  static int
+ __store_long (value, dest, bytes)
+      long value;
+      char *dest;
+      size_t bytes;
+ {
+   int upper_bit = (value < 0 ? 128 : 0);
+   size_t i;
+ 
+   if (value < 0)
+     {
+       long oldvalue = value;
+       value = -value;
+       if (oldvalue != -value)
+ 	return 1;
+     }
+ 
+   for(i = 0 ; i < (sizeof (value) < bytes ? sizeof (value) : bytes) ; i++) {
+     dest[i] = value & (i == (bytes - 1) ? 127 : 255);
+     value = value / 256;
+   }
+ 
+   if (value && value != -1)
+     return 1;
+ 
+   for(; i < bytes ; i++)
+     dest[i] = 0;
+   dest[bytes - 1] |= upper_bit;
+   return 0;
+ }
+ 
+ static int
  __fetch_long (dest, source, bytes)
       long *dest;
       char *source;
*************** __write_long (value, file, bytes)
*** 161,167 ****
  {
    char c[10];
  
!   if (bytes > 10 || __store_gcov_type ((gcov_type)value, c, bytes))
      return 1;
    else
      return fwrite(c, 1, bytes, file) != bytes;
--- 181,187 ----
  {
    char c[10];
  
!   if (bytes > 10 || __store_long (value, c, bytes))
      return 1;
    else
      return fwrite(c, 1, bytes, file) != bytes;
Index: gcov.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcov.c,v
retrieving revision 1.47
diff -c -3 -p -r1.47 gcov.c
*** gcov.c	10 Aug 2002 12:30:34 -0000	1.47
--- gcov.c	4 Sep 2002 09:49:00 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 51,57 ****
  
  #include <getopt.h>
  
! typedef HOST_WIDEST_INT gcov_type;
  #include "gcov-io.h"
  
  /* The .bb file format consists of several lists of 4-byte integers
--- 51,57 ----
  
  #include <getopt.h>
  
! typedef unsigned HOST_WIDEST_INT gcov_type;
  #include "gcov-io.h"
  
  /* The .bb file format consists of several lists of 4-byte integers
Index: predict.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/predict.c,v
retrieving revision 1.73
diff -c -3 -p -r1.73 predict.c
*** predict.c	21 Jul 2002 22:01:58 -0000	1.73
--- predict.c	4 Sep 2002 09:49:09 -0000
*************** estimate_loops_at_level (first_loop)
*** 1063,1069 ****
  static void
  counts_to_freqs ()
  {
!   HOST_WIDEST_INT count_max = 1;
    basic_block bb;
  
    FOR_EACH_BB (bb)
--- 1063,1069 ----
  static void
  counts_to_freqs ()
  {
!   gcov_type count_max = 1;
    basic_block bb;
  
    FOR_EACH_BB (bb)
Index: profile.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/profile.c,v
retrieving revision 1.97
diff -c -3 -p -r1.97 profile.c
*** profile.c	9 Aug 2002 08:51:27 -0000	1.97
--- profile.c	4 Sep 2002 09:49:12 -0000
*************** static void instrument_edges PARAMS ((st
*** 158,164 ****
  static void output_gcov_string PARAMS ((const char *, long));
  static void compute_branch_probabilities PARAMS ((void));
  static gcov_type * get_exec_counts PARAMS ((void));
! static long compute_checksum PARAMS ((void));
  static basic_block find_group PARAMS ((basic_block));
  static void union_groups PARAMS ((basic_block, basic_block));
  
--- 158,164 ----
  static void output_gcov_string PARAMS ((const char *, long));
  static void compute_branch_probabilities PARAMS ((void));
  static gcov_type * get_exec_counts PARAMS ((void));
! static unsigned compute_checksum PARAMS ((void));
  static basic_block find_group PARAMS ((basic_block));
  static void union_groups PARAMS ((basic_block, basic_block));
  
*************** get_exec_counts ()
*** 359,365 ****
  		}
  	    }
  	  else if (arc_count != num_edges
! 		   || chksum != profile_info.current_function_cfg_checksum)
  	    okay = 0, mismatch = 1;
  	  else
  	    {
--- 359,366 ----
  		}
  	    }
  	  else if (arc_count != num_edges
! 		   || ((unsigned) chksum
! 		       != profile_info.current_function_cfg_checksum))
  	    okay = 0, mismatch = 1;
  	  else
  	    {
*************** compute_branch_probabilities ()
*** 667,676 ****
  	      num_branches++;
  	    }
  	}
!       /* Otherwise distribute the probabilities evenly so we get sane sum.
! 	 Use simple heuristics that if there are normal edges, give all abnormals
! 	 frequency of 0, otherwise distribute the frequency over abnormals
! 	 (this is the case of noreturn calls).  */
        else
  	{
  	  for (e = bb->succ; e; e = e->succ_next)
--- 668,678 ----
  	      num_branches++;
  	    }
  	}
!       /* Otherwise distribute the probabilities evenly so we get sane
! 	 sum.  Use simple heuristics that if there are normal edges,
! 	 give all abnormals frequency of 0, otherwise distribute the
! 	 frequency over abnormals (this is the case of noreturn
! 	 calls).  */
        else
  	{
  	  for (e = bb->succ; e; e = e->succ_next)
*************** compute_branch_probabilities ()
*** 723,752 ****
      free (exec_counts);
  }
  
! /* Compute checksum for the current function.  */
  
! #define CHSUM_HASH	500000003
! #define CHSUM_SHIFT	2
! 
! static long
  compute_checksum ()
  {
!   long chsum = 0;
    basic_block bb;
! 
    FOR_EACH_BB (bb)
      {
!       edge e;
! 
!       for (e = bb->succ; e; e = e->succ_next)
  	{
! 	  chsum = ((chsum << CHSUM_SHIFT) + (BB_TO_GCOV_INDEX (e->dest) + 1)) % CHSUM_HASH;
! 	}
  
!       chsum = (chsum << CHSUM_SHIFT) % CHSUM_HASH;
      }
  
!   return chsum;
  }
  
  /* Instrument and/or analyze program behavior based on program flow graph.
--- 725,767 ----
      free (exec_counts);
  }
  
! /* Compute checksum for the current function.  We generate a CRC32.  */
  
! static unsigned
  compute_checksum ()
  {
!   unsigned chksum = 0;
    basic_block bb;
!   
    FOR_EACH_BB (bb)
      {
!       edge e = NULL;
!       
!       do
  	{
! 	  unsigned value = BB_TO_GCOV_INDEX (e ? e->dest : bb);
! 	  unsigned ix;
  
! 	  /* No need to use all bits in value identically, nearly all
! 	     functions have less than 256 blocks.  */
! 	  value ^= value << 16;
! 	  value ^= value << 8;
! 	  
! 	  for (ix = 8; ix--; value <<= 1)
! 	    {
! 	      unsigned feedback;
! 
! 	      feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
! 	      chksum <<= 1;
! 	      chksum ^= feedback;
! 	    }
! 	  
! 	  e = e ? e->succ_next : bb->succ;
! 	}
!       while (e);
      }
  
!   return chksum;
  }
  
  /* Instrument and/or analyze program behavior based on program flow graph.
*************** branch_prob ()
*** 776,782 ****
    profile_info.current_function_cfg_checksum = compute_checksum ();
  
    if (rtl_dump_file)
!     fprintf (rtl_dump_file, "CFG checksum is %ld\n",
  	profile_info.current_function_cfg_checksum);
  
    /* Start of a function.  */
--- 791,797 ----
    profile_info.current_function_cfg_checksum = compute_checksum ();
  
    if (rtl_dump_file)
!     fprintf (rtl_dump_file, "CFG checksum is %u\n",
  	profile_info.current_function_cfg_checksum);
  
    /* Start of a function.  */
Index: profile.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/profile.h,v
retrieving revision 1.3
diff -c -3 -p -r1.3 profile.h
*** profile.h	12 May 2002 17:03:35 -0000	1.3
--- profile.h	4 Sep 2002 09:49:12 -0000
*************** struct profile_info
*** 36,42 ****
      /* Checksum of the cfg. Used for 'identification' of code.
         Used by final.  */
  
!     long current_function_cfg_checksum;
  
      /* Max. value of counter in program corresponding to the profile data
         for the current function.  */
--- 36,42 ----
      /* Checksum of the cfg. Used for 'identification' of code.
         Used by final.  */
  
!     unsigned current_function_cfg_checksum;
  
      /* Max. value of counter in program corresponding to the profile data
         for the current function.  */

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