GCOV/profile 64bit patch.

Jan Hubicka jh@suse.cz
Thu Jun 29 09:05:00 GMT 2000


Hi
On machines with 32bit longs, it is quite easy to overflow the counters
in -fprofile-arces code.  This is quite anoying, since it makes a lot
of results meaningless.
This patch changes the code to use "gcov_type" that is defined to
long or long long, when it is 64bit and long othervise.

The file format remain the same, since it used 64 values already, so old
gcov reads new files and new gcov old ones, as long as the overflow didn't
happen.

Note that I am not quite happy with the solution gcov_type is choosed
(I can't define it in gcov-io.h, since it is included from both, the compiler
and the libgcc2), so I am open to all suggestions.


Thu Jun 29 14:48:32 CEST 2000  Jan Hubicka  <jh@suse.cz>

	* Makefile.in (reg-stack.o): Add missing dependency on basic_block.h
	* basic-block.h (gcov_type): Define.
	(struct edge_def): Use gcov_type for count field.
	(struct basic_block_def): Likewise.
	* final.c (LONG_TYPE_SIZE, LONG_TYPE_SIZE): Define default values.
	(GCOV_TYPE_SIZE): Define.
	(end_final): Use GCOV_TYPE_SIZE.
	* flow.c (dump_edge_info, dump_flow_info, dump_bb): Print count fields
	using HOST_WIDEST_INT_PRINT_DEC.
	* gcov-io.h (__fetch_gcov_type, __store_gcov_type, __read_gcov_type,
	__write_gcov_type): New.
	(store_long): Remove.
	* gcov.c (gcov_type): Set default.
	(struct adj_list): Use gcov_type for arc_count.
	(bb_info): Use gcov_type for succ_count, pred_count and exec_count.
	(create_program_flow_graph): Read arc_count properly.
	(solve_program_flow_graph): 'total' is gcov_type.
	(output_data): Line_counts is gcov_type, print it properly.
	* libgcc2.c (struct bb): Counts is gcov_type.
	(LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE): Set default.
	(__bb_exit_func): Use __read_gcov_type and __write_gcov_type.
	* profile.c (LONG_TYPE_SIZE, LONG_LONG_TYPE_SIZE): Set default.
	(GCOV_TYPE_SIZE): Define.
	(struct bb_info): succ_count and pred_count is gcov_type.
	(compute_branch_probabilities): Use __read_gcov_type,
	print read edges to the dump file.
	(total): Is gcov_type.
	(gen_edge_profiler): Use GCOV_TYPE_SIZE.

*** Makefile.in.old	Thu Jun 29 13:52:14 2000
--- Makefile.in	Thu Jun 29 13:52:32 2000
*************** recog.o : recog.c $(CONFIG_H) system.h $
*** 1380,1386 ****
     insn-flags.h insn-codes.h real.h toplev.h output.h
  reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) $(RECOG_H) \
     $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h \
!    varray.h function.h
  predict.o: predict.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
     insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
     $(RECOG_H) insn-flags.h function.h except.h $(EXPR_H)
--- 1380,1386 ----
     insn-flags.h insn-codes.h real.h toplev.h output.h
  reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) $(RECOG_H) \
     $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h \
!    varray.h function.h $(BASIC_BLOCK_H)
  predict.o: predict.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
     insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
     $(RECOG_H) insn-flags.h function.h except.h $(EXPR_H)
*** basic-block.h.old	Tue Jun 27 16:13:50 2000
--- basic-block.h	Thu Jun 29 13:45:12 2000
*************** Boston, MA 02111-1307, USA.  */
*** 26,31 ****
--- 26,42 ----
  #include "varray.h"
  #include "partition.h"
  
+ /* Look for 64bit data type, if available.  */
+ #if HOST_BITS_PER_LONG == 64
+ typedef long gcov_type;
+ #else
+ #if HOST_BITS_PER_LONGLONG == 64
+ typedef long long gcov_type;
+ #else
+ typedef long gcov_type;
+ #endif
+ #endif
+ 
  /* Head of register set linked list.  */
  typedef bitmap_head regset_head;
  /* A pointer to a regset_head.  */
*************** typedef struct edge_def {
*** 127,133 ****
  
    int flags;			/* see EDGE_* below  */
    int probability;		/* biased by REG_BR_PROB_BASE */
!   int count;			/* Expected number of executions calculated
  				   in profile.c  */
  } *edge;
  
--- 138,144 ----
  
    int flags;			/* see EDGE_* below  */
    int probability;		/* biased by REG_BR_PROB_BASE */
!   gcov_type count;		/* Expected number of executions calculated
  				   in profile.c  */
  } *edge;
  
*************** typedef struct basic_block_def {
*** 167,173 ****
    /* The active eh region before head and after end.  */
    int eh_beg, eh_end;
  
!   int count;		/* Expected number of executions: calculated in
                             profile.c */
  } *basic_block;
  
--- 178,184 ----
    /* The active eh region before head and after end.  */
    int eh_beg, eh_end;
  
!   gcov_type count;	/* Expected number of executions: calculated in
                             profile.c */
  } *basic_block;
  
*** final.c.old	Tue Jun 27 17:10:53 2000
--- final.c	Tue Jun 27 17:37:41 2000
*************** Boston, MA 02111-1307, USA.  */
*** 81,86 ****
--- 81,100 ----
  
  #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
  
+ #ifndef LONG_TYPE_SIZE
+ #define LONG_TYPE_SIZE BITS_PER_WORD
+ #endif
+ #ifndef LONG_LONG_TYPE_SIZE
+ #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
+ #endif
+ 
+ /* When there is 64 integer type, go for it.  */
+ #if LONG_TYPE_SIZE == 64 || LONG_LONG_TYPE_SIZE == 64
+ #define GCOV_TYPE_SIZE 64
+ #else
+ #define GCOV_TYPE_SIZE LONG_TYPE_SIZE
+ #endif
+ 
  #ifndef ACCUMULATE_OUTGOING_ARGS
  #define ACCUMULATE_OUTGOING_ARGS 0
  #endif
*************** end_final (filename)
*** 329,340 ****
        struct bb_list *ptr;
        struct bb_str *sptr;
        int long_bytes = LONG_TYPE_SIZE / BITS_PER_UNIT;
        int pointer_bytes = POINTER_SIZE / BITS_PER_UNIT;
  
        if (profile_block_flag)
  	size = long_bytes * count_basic_blocks;
        else
! 	size = long_bytes * count_instrumented_edges;
        rounded = size;
  
        rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
--- 343,355 ----
        struct bb_list *ptr;
        struct bb_str *sptr;
        int long_bytes = LONG_TYPE_SIZE / BITS_PER_UNIT;
+       int gcov_type_bytes = GCOV_TYPE_SIZE / BITS_PER_UNIT;
        int pointer_bytes = POINTER_SIZE / BITS_PER_UNIT;
  
        if (profile_block_flag)
  	size = long_bytes * count_basic_blocks;
        else
! 	size = gcov_type_bytes * count_instrumented_edges;
        rounded = size;
  
        rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
*** flow.c.old	Tue Jun 27 17:43:42 2000
--- flow.c	Thu Jun 29 14:37:34 2000
*************** dump_flow_info (file)
*** 5727,5734 ****
        register basic_block bb = BASIC_BLOCK (i);
        register edge e;
  
!       fprintf (file, "\nBasic block %d: first insn %d, last %d, loop_depth %d, count %d.\n",
! 	       i, INSN_UID (bb->head), INSN_UID (bb->end), bb->loop_depth, bb->count);
  
        fprintf (file, "Predecessors: ");
        for (e = bb->pred; e ; e = e->pred_next)
--- 5727,5736 ----
        register basic_block bb = BASIC_BLOCK (i);
        register edge e;
  
!       fprintf (file, "\nBasic block %d: first insn %d, last %d, loop_depth %d, count ",
! 	       i, INSN_UID (bb->head), INSN_UID (bb->end), bb->loop_depth);
!       fprintf (file, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
!       fprintf (file, ".\n");
  
        fprintf (file, "Predecessors: ");
        for (e = bb->pred; e ; e = e->pred_next)
*************** dump_edge_info (file, e, do_succ)
*** 5772,5778 ****
      fprintf (file, " %d", side->index);
  
    if (e->count)
!     fprintf (file, " count:%d", e->count);
  
    if (e->flags)
      {
--- 5774,5783 ----
      fprintf (file, " %d", side->index);
  
    if (e->count)
!     {
!       fprintf (file, " count:");
!       fprintf (file, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) e->count);
!     }
  
    if (e->flags)
      {
*************** dump_bb (bb, outf)
*** 5812,5819 ****
    rtx last;
    edge e;
  
!   fprintf (outf, ";; Basic block %d, loop depth %d, count %d",
! 	   bb->index, bb->loop_depth, bb->count);
    if (bb->eh_beg != -1 || bb->eh_end != -1)
      fprintf (outf, ", eh regions %d/%d", bb->eh_beg, bb->eh_end);
    putc ('\n', outf);
--- 5817,5825 ----
    rtx last;
    edge e;
  
!   fprintf (outf, ";; Basic block %d, loop depth %d, count ",
! 	   bb->index, bb->loop_depth);
!   fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
    if (bb->eh_beg != -1 || bb->eh_end != -1)
      fprintf (outf, ", eh regions %d/%d", bb->eh_beg, bb->eh_end);
    putc ('\n', outf);
*** gcov-io.h.old	Tue Jun 27 16:07:44 2000
--- gcov-io.h	Tue Jun 27 17:09:05 2000
*************** Boston, MA 02111-1307, USA.  */
*** 25,33 ****
  #include <sys/types.h>
  
  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)) ATTRIBUTE_UNUSED;
  
  /* These routines only work for signed values. */
  
--- 25,36 ----
  #include <sys/types.h>
  
  static int __fetch_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)) ATTRIBUTE_UNUSED;
+ static int __fetch_gcov_type PARAMS ((gcov_type *, char *, size_t)) ATTRIBUTE_UNUSED;
+ static int __store_gcov_type PARAMS ((gcov_type, char *, size_t)) ATTRIBUTE_UNUSED;
+ static int __read_gcov_type  PARAMS ((gcov_type *, FILE *, size_t)) ATTRIBUTE_UNUSED;
+ static int __write_gcov_type PARAMS ((gcov_type, FILE *, size_t)) ATTRIBUTE_UNUSED;
  
  /* These routines only work for signed values. */
  
*************** static int __write_long PARAMS ((long, F
*** 36,43 ****
     to store. */
  
  static int
! __store_long (value, dest, bytes)
!      long value;
       char *dest;
       size_t bytes;
  {
--- 39,46 ----
     to store. */
  
  static int
! __store_gcov_type (value, dest, bytes)
!      gcov_type value;
       char *dest;
       size_t bytes;
  {
*************** __store_long (value, dest, bytes)
*** 46,52 ****
  
    if (value < 0)
      {
!       long oldvalue = value;
        value = -value;
        if (oldvalue != -value)
  	return 1;
--- 49,55 ----
  
    if (value < 0)
      {
!       gcov_type oldvalue = value;
        value = -value;
        if (oldvalue != -value)
  	return 1;
*************** __store_long (value, dest, bytes)
*** 71,76 ****
--- 74,102 ----
     will not fit in DEST. */
  
  static int
+ __fetch_gcov_type (dest, source, bytes)
+      gcov_type *dest;
+      char *source;
+      size_t bytes;
+ {
+   gcov_type value = 0;
+   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;
*************** __fetch_long (dest, source, bytes)
*** 103,108 ****
--- 129,148 ----
     BYTES may be a maximum of 10. */
  
  static int
+ __write_gcov_type (value, file, bytes)
+      gcov_type value;
+      FILE *file;
+      size_t bytes;
+ {
+   char c[10];
+ 
+   if (bytes > 10 || __store_gcov_type (value, c, bytes))
+     return 1;
+   else
+     return fwrite(c, 1, bytes, file) != bytes;
+ }
+ 
+ static int
  __write_long (value, file, bytes)
       long value;
       FILE *file;
*************** __write_long (value, file, bytes)
*** 110,116 ****
  {
    char c[10];
  
!   if (bytes > 10 || __store_long (value, c, bytes))
      return 1;
    else
      return fwrite(c, 1, bytes, file) != bytes;
--- 150,156 ----
  {
    char c[10];
  
!   if (bytes > 10 || __store_gcov_type ((gcov_type)value, c, bytes))
      return 1;
    else
      return fwrite(c, 1, bytes, file) != bytes;
*************** __write_long (value, file, bytes)
*** 126,131 ****
--- 166,185 ----
     BYTES may be a maximum of 10. */
  
  static int
+ __read_gcov_type (dest, file, bytes)
+      gcov_type *dest;
+      FILE *file;
+      size_t bytes;
+ {
+   char c[10];
+ 
+   if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
+     return 1;
+   else
+     return __fetch_gcov_type (dest, c, bytes);
+ }
+ 
+ static int
  __read_long (dest, file, bytes)
       long *dest;
       FILE *file;
*************** __read_long (dest, file, bytes)
*** 138,142 ****
--- 192,197 ----
    else
      return __fetch_long (dest, c, bytes);
  }
+ 
  
  #endif
*** gcov.c.old	Tue Jun 27 16:20:45 2000
--- gcov.c	Thu Jun 29 14:33:40 2000
*************** Boston, MA 02111-1307, USA.  */
*** 48,53 ****
--- 48,64 ----
  #include "intl.h"
  #undef abort
  
+ /* Look for 64bit data type, if available.  */
+ #if HOST_BITS_PER_LONG == 64
+ typedef long gcov_type;
+ #else
+ #if HOST_BITS_PER_LONGLONG == 64
+ typedef long long gcov_type;
+ #else
+ typedef long gcov_type;
+ #endif
+ #endif
+ 
  #include "gcov-io.h"
  
  /* The .bb file format consists of several lists of 4-byte integers
*************** struct sourcefile *sources;
*** 104,110 ****
  struct adj_list {
    int source;
    int target;
!   int arc_count;
    unsigned int count_valid : 1;
    unsigned int on_tree : 1;
    unsigned int fake : 1;
--- 115,121 ----
  struct adj_list {
    int source;
    int target;
!   gcov_type arc_count;
    unsigned int count_valid : 1;
    unsigned int on_tree : 1;
    unsigned int fake : 1;
*************** struct adj_list {
*** 123,131 ****
  struct bb_info {
    struct adj_list *succ;
    struct adj_list *pred;
!   int succ_count;
!   int pred_count;
!   int exec_count;
    unsigned int count_valid : 1;
    unsigned int on_tree : 1;
  #if 0
--- 134,142 ----
  struct bb_info {
    struct adj_list *succ;
    struct adj_list *pred;
!   gcov_type succ_count;
!   gcov_type pred_count;
!   gcov_type exec_count;
    unsigned int count_valid : 1;
    unsigned int on_tree : 1;
  #if 0
*************** create_program_flow_graph (bptr)
*** 572,579 ****
      for (arcptr = bb_graph[i].succ; arcptr; arcptr = arcptr->succ_next)
        if (! arcptr->on_tree)
  	{
! 	  long tmp_count = 0;
! 	  if (da_file && __read_long (&tmp_count, da_file, 8))
  	    abort();
  
  	  arcptr->arc_count = tmp_count;
--- 583,590 ----
      for (arcptr = bb_graph[i].succ; arcptr; arcptr = arcptr->succ_next)
        if (! arcptr->on_tree)
  	{
! 	  gcov_type tmp_count = 0;
! 	  if (da_file && __read_gcov_type (&tmp_count, da_file, 8))
  	    abort();
  
  	  arcptr->arc_count = tmp_count;
*************** static void
*** 587,593 ****
  solve_program_flow_graph (bptr)
       struct bb_info_list *bptr;
  {
!   int passes, changes, total;
    int i;
    struct adj_list *arcptr;
    struct bb_info *bb_graph;
--- 598,605 ----
  solve_program_flow_graph (bptr)
       struct bb_info_list *bptr;
  {
!   int passes, changes;
!   gcov_type total;
    int i;
    struct adj_list *arcptr;
    struct bb_info *bb_graph;
*************** output_data ()
*** 968,974 ****
    int this_file;
    /* An array indexed by line number which indicates how many times that line
       was executed.  */
!   long *line_counts;
    /* An array indexed by line number which indicates whether the line was
       present in the bb file (i.e. whether it had code associate with it).
       Lines never executed are those which both exist, and have zero execution
--- 980,986 ----
    int this_file;
    /* An array indexed by line number which indicates how many times that line
       was executed.  */
!   gcov_type *line_counts;
    /* An array indexed by line number which indicates whether the line was
       present in the bb file (i.e. whether it had code associate with it).
       Lines never executed are those which both exist, and have zero execution
*************** output_data ()
*** 1028,1034 ****
        else
  	source_file_name = s_ptr->name;
  
!       line_counts = (long *) xcalloc (sizeof (long), s_ptr->maxlineno);
        line_exists = xcalloc (1, s_ptr->maxlineno);
        if (output_branch_probs)
  	branch_probs = (struct arcdata **)
--- 1040,1046 ----
        else
  	source_file_name = s_ptr->name;
  
!       line_counts = (long *) xcalloc (sizeof (gcov_type), s_ptr->maxlineno);
        line_exists = xcalloc (1, s_ptr->maxlineno);
        if (output_branch_probs)
  	branch_probs = (struct arcdata **)
*************** output_data ()
*** 1317,1324 ****
  	      if (line_exists[count])
  		{
  		  if (line_counts[count])
! 		    fprintf (gcov_file, "%12ld    %s", line_counts[count],
! 			     string);
  		  else
  		    fprintf (gcov_file, "      ######    %s", string);
  		}
--- 1329,1340 ----
  	      if (line_exists[count])
  		{
  		  if (line_counts[count])
! 		    {
! 		      char c[20];
! 		      sprintf (c, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)line_counts[count]);
! 		      fprintf (gcov_file, "%12s    %s", c,
! 			       string);
! 		    }
  		  else
  		    fprintf (gcov_file, "      ######    %s", string);
  		}
*** libgcc2.c.old	Tue Jun 27 16:20:27 2000
--- libgcc2.c	Tue Jun 27 17:35:08 2000
*************** __eprintf (const char *string, const cha
*** 1316,1327 ****
  
  #ifdef L_bb
  
  /* Structure emitted by -a  */
  struct bb
  {
    long zero_word;
    const char *filename;
!   long *counts;
    long ncounts;
    struct bb *next;
    const unsigned long *addresses;
--- 1316,1345 ----
  
  #ifdef L_bb
  
+ #ifndef LONG_TYPE_SIZE
+ #define LONG_TYPE_SIZE BITS_PER_WORD
+ #endif
+ #ifndef LONG_LONG_TYPE_SIZE
+ #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
+ #endif
+ 
+ #if LONG_TYPE_SIZE == 64
+ typedef long gcov_type;
+ #else
+ #if LONG_LONG_TYPE_SIZE == 64
+ typedef long long gcov_type;
+ #else
+ typedef long gcov_type;
+ #endif
+ #endif
+ 
+ 
  /* Structure emitted by -a  */
  struct bb
  {
    long zero_word;
    const char *filename;
!   gcov_type *counts;
    long ncounts;
    struct bb *next;
    const unsigned long *addresses;
*************** __bb_exit_func (void)
*** 1468,1476 ****
  
  		  for (i = 0; i < n_counts; i++)
  		    {
! 		      long v = 0;
  
! 		      if (__read_long (&v, da_file, 8) != 0)
  			{
  			  fprintf (stderr, "arc profiling: Can't read output file %s.\n",
  				   ptr->filename);
--- 1486,1494 ----
  
  		  for (i = 0; i < n_counts; i++)
  		    {
! 		      gcov_type v = 0;
  
! 		      if (__read_gcov_type (&v, da_file, 8) != 0)
  			{
  			  fprintf (stderr, "arc profiling: Can't read output file %s.\n",
  				   ptr->filename);
*************** __bb_exit_func (void)
*** 1492,1498 ****
  	     That way we can easily verify that the proper source/executable/
  	     data file combination is being used from gcov.  */
  
! 	  if (__write_long (ptr->ncounts, da_file, 8) != 0)
  	    {
  	      
  	      fprintf (stderr, "arc profiling: Error writing output file %s.\n",
--- 1510,1516 ----
  	     That way we can easily verify that the proper source/executable/
  	     data file combination is being used from gcov.  */
  
! 	  if (__write_gcov_type (ptr->ncounts, da_file, 8) != 0)
  	    {
  	      
  	      fprintf (stderr, "arc profiling: Error writing output file %s.\n",
*************** __bb_exit_func (void)
*** 1501,1511 ****
  	  else
  	    {
  	      int j;
! 	      long *count_ptr = ptr->counts;
  	      int ret = 0;
  	      for (j = ptr->ncounts; j > 0; j--)
  		{
! 		  if (__write_long (*count_ptr, da_file, 8) != 0)
  		    {
  		      ret=1;
  		      break;
--- 1519,1529 ----
  	  else
  	    {
  	      int j;
! 	      gcov_type *count_ptr = ptr->counts;
  	      int ret = 0;
  	      for (j = ptr->ncounts; j > 0; j--)
  		{
! 		  if (__write_gcov_type (*count_ptr, da_file, 8) != 0)
  		    {
  		      ret=1;
  		      break;
*** profile.c.old	Tue Jun 27 16:00:03 2000
--- profile.c	Thu Jun 29 13:50:24 2000
*************** Boston, MA 02111-1307, USA.  */
*** 43,53 ****
  #include "regs.h"
  #include "expr.h"
  #include "function.h"
- #include "gcov-io.h"
  #include "toplev.h"
  #include "ggc.h"
  #include "hard-reg-set.h"
  #include "basic-block.h"
  
  
  /* Additional information about the edges we need.  */
--- 43,67 ----
  #include "regs.h"
  #include "expr.h"
  #include "function.h"
  #include "toplev.h"
  #include "ggc.h"
  #include "hard-reg-set.h"
  #include "basic-block.h"
+ #include "gcov-io.h"
+ 
+ #ifndef LONG_TYPE_SIZE
+ #define LONG_TYPE_SIZE BITS_PER_WORD
+ #endif
+ #ifndef LONG_LONG_TYPE_SIZE
+ #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
+ #endif
+ 
+ /* When there is 64 integer type, go for it.  */
+ #if LONG_TYPE_SIZE == 64 || LONG_LONG_TYPE_SIZE == 64
+ #define GCOV_TYPE_SIZE 64
+ #else
+ #define GCOV_TYPE_SIZE LONG_TYPE_SIZE
+ #endif
  
  
  /* Additional information about the edges we need.  */
*************** struct edge_info
*** 60,67 ****
  struct bb_info
    {
      unsigned int count_valid : 1;
!     int succ_count;
!     int pred_count;
    };
  
  #define EDGE_INFO(e)  ((struct edge_info *) (e)->aux)
--- 74,81 ----
  struct bb_info
    {
      unsigned int count_valid : 1;
!     gcov_type succ_count;
!     gcov_type pred_count;
    };
  
  #define EDGE_INFO(e)  ((struct edge_info *) (e)->aux)
*************** static void compute_branch_probabilities
*** 119,128 ****
  static basic_block find_group PARAMS ((basic_block));
  static void union_groups PARAMS ((basic_block, basic_block));
  
- #ifndef LONG_TYPE_SIZE
- #define LONG_TYPE_SIZE BITS_PER_WORD
- #endif
- 
  /* If non-zero, we need to output a constructor to set up the
     per-object-file data. */
  static int need_func_profiler = 0;
--- 133,138 ----
*************** compute_branch_probabilities ()
*** 261,268 ****
  	    num_edges++;
  	    if (da_file)
  	      {
! 		long value;
! 		__read_long (&value, da_file, 8);
  		e->count = value;
  	      }
  	    else
--- 271,278 ----
  	    num_edges++;
  	    if (da_file)
  	      {
! 		gcov_type value;
! 		__read_gcov_type (&value, da_file, 8);
  		e->count = value;
  	      }
  	    else
*************** compute_branch_probabilities ()
*** 270,280 ****
  	    EDGE_INFO (e)->count_valid = 1;
  	    BB_INFO (bb)->succ_count--;
  	    BB_INFO (e->dest)->pred_count--;
  	  }
      }
  
    if (rtl_dump_file)
!     fprintf (rtl_dump_file, "%d edge counts read\n", num_edges);
  
    /* For every block in the file,
       - if every exit/entrance edge has a known count, then set the block count
--- 280,297 ----
  	    EDGE_INFO (e)->count_valid = 1;
  	    BB_INFO (bb)->succ_count--;
  	    BB_INFO (e->dest)->pred_count--;
+ 	    if (rtl_dump_file)
+ 	      {
+ 		fprintf (rtl_dump_file, "\nRead edge from %i to %i, count:",
+ 			 bb->index, e->dest->index);
+ 		fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,
+ 			 (HOST_WIDEST_INT) e->count);
+ 	      }
  	  }
      }
  
    if (rtl_dump_file)
!     fprintf (rtl_dump_file, "\n%d edge counts read\n", num_edges);
  
    /* For every block in the file,
       - if every exit/entrance edge has a known count, then set the block count
*************** compute_branch_probabilities ()
*** 308,314 ****
  	      if (bi->succ_count == 0)
  		{
  		  edge e;
! 		  int total = 0;
  
  		  for (e = bb->succ; e; e = e->succ_next)
  		    total += e->count;
--- 325,331 ----
  	      if (bi->succ_count == 0)
  		{
  		  edge e;
! 		  gcov_type total = 0;
  
  		  for (e = bb->succ; e; e = e->succ_next)
  		    total += e->count;
*************** compute_branch_probabilities ()
*** 319,325 ****
  	      else if (bi->pred_count == 0)
  		{
  		  edge e;
! 		  int total = 0;
  
  		  for (e = bb->pred; e; e = e->pred_next)
  		    total += e->count;
--- 336,342 ----
  	      else if (bi->pred_count == 0)
  		{
  		  edge e;
! 		  gcov_type total = 0;
  
  		  for (e = bb->pred; e; e = e->pred_next)
  		    total += e->count;
*************** compute_branch_probabilities ()
*** 333,339 ****
  	      if (bi->succ_count == 1)
  		{
  		  edge e;
! 		  int total = 0;
  
  		  /* One of the counts will be invalid, but it is zero,
  		     so adding it in also doesn't hurt.  */
--- 350,356 ----
  	      if (bi->succ_count == 1)
  		{
  		  edge e;
! 		  gcov_type total = 0;
  
  		  /* One of the counts will be invalid, but it is zero,
  		     so adding it in also doesn't hurt.  */
*************** compute_branch_probabilities ()
*** 360,366 ****
  	      if (bi->pred_count == 1)
  		{
  		  edge e;
! 		  int total = 0;
  
  		  /* One of the counts will be invalid, but it is zero,
  		     so adding it in also doesn't hurt.  */
--- 377,383 ----
  	      if (bi->pred_count == 1)
  		{
  		  edge e;
! 		  gcov_type total = 0;
  
  		  /* One of the counts will be invalid, but it is zero,
  		     so adding it in also doesn't hurt.  */
*************** compute_branch_probabilities ()
*** 416,422 ****
        basic_block bb = BASIC_BLOCK (i);
        edge e;
        rtx insn;
!       int total;
        rtx note;
  
        total = bb->count;
--- 433,439 ----
        basic_block bb = BASIC_BLOCK (i);
        edge e;
        rtx insn;
!       gcov_type total;
        rtx note;
  
        total = bb->count;
*************** static rtx
*** 1041,1054 ****
  gen_edge_profiler (edgeno)
       int edgeno;
  {
!   enum machine_mode mode = mode_for_size (LONG_TYPE_SIZE, MODE_INT, 0);
    rtx mem_ref, tmp;
    rtx sequence;
  
    start_sequence ();
  
    tmp = force_reg (Pmode, profiler_label);
!   tmp = plus_constant (tmp, LONG_TYPE_SIZE / BITS_PER_UNIT * edgeno);
    mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
  
    tmp = expand_binop (mode, add_optab, mem_ref, const1_rtx,
--- 1058,1071 ----
  gen_edge_profiler (edgeno)
       int edgeno;
  {
!   enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
    rtx mem_ref, tmp;
    rtx sequence;
  
    start_sequence ();
  
    tmp = force_reg (Pmode, profiler_label);
!   tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
    mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
  
    tmp = expand_binop (mode, add_optab, mem_ref, const1_rtx,
*************** output_func_start_profiler ()
*** 1071,1077 ****
    tree fnname, fndecl;
    char *name, *cfnname;
    rtx table_address;
!   enum machine_mode mode = mode_for_size (LONG_TYPE_SIZE, MODE_INT, 0);
    int save_flag_inline_functions = flag_inline_functions;
    int save_flag_test_coverage = flag_test_coverage;
    int save_profile_arc_flag = profile_arc_flag;
--- 1088,1094 ----
    tree fnname, fndecl;
    char *name, *cfnname;
    rtx table_address;
!   enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
    int save_flag_inline_functions = flag_inline_functions;
    int save_flag_test_coverage = flag_test_coverage;
    int save_profile_arc_flag = profile_arc_flag;


More information about the Gcc-patches mailing list