[PATCH] Add support for profile merging hooks

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Sat May 3 21:58:00 GMT 2003


Hello,

> could you commit your updated patch, I have some other changes I'd like
> to commence with.

OK this way?

Zdenek

Index: Makefile.in
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1047
diff -c -3 -p -r1.1047 Makefile.in
*** Makefile.in	3 May 2003 21:44:24 -0000	1.1047
--- Makefile.in	3 May 2003 21:56:00 -0000
*************** STAGESTUFF = *$(objext) insn-flags.h ins
*** 854,860 ****
  LIB2FUNCS_ST = _eprintf __gcc_bcmp
  
  # Defined in libgcov.c, included only in gcov library
! LIBGCOV = _gcov
  
  FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
      _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
--- 854,860 ----
  LIB2FUNCS_ST = _eprintf __gcc_bcmp
  
  # Defined in libgcov.c, included only in gcov library
! LIBGCOV = _gcov _gcov_merge_add
  
  FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
      _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
Index: coverage.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/coverage.c,v
retrieving revision 1.4
diff -c -3 -p -r1.4 coverage.c
*** coverage.c	1 May 2003 16:13:28 -0000	1.4
--- coverage.c	3 May 2003 21:56:00 -0000
*************** static htab_t counts_hash = NULL;
*** 98,103 ****
--- 98,106 ----
  /* The names of the counter tables.  */
  static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
  
+ /* The names of merge functions for counters.  */
+ static const char *ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
+ 
  /* Forward declarations.  */
  static hashval_t htab_counts_entry_hash PARAMS ((const void *));
  static int htab_counts_entry_eq PARAMS ((const void *, const void *));
*************** build_ctr_info_type ()
*** 559,564 ****
--- 562,568 ----
  {
    tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
    tree field, fields = NULL_TREE;
+   tree gcov_merge_fn_type;
    
    /* counters */
    field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
*************** build_ctr_info_type ()
*** 571,576 ****
--- 575,592 ----
    TREE_CHAIN (field) = fields;
    fields = field;
  
+   /* merge */
+   gcov_merge_fn_type =
+ 	build_function_type_list (
+ 		void_type_node,
+ 		build_pointer_type (make_signed_type (GCOV_TYPE_SIZE)),
+ 		unsigned_type_node,
+ 		NULL_TREE);
+   field = build_decl (FIELD_DECL, NULL_TREE,
+ 		      build_pointer_type (gcov_merge_fn_type));
+   TREE_CHAIN (field) = fields;
+   fields = field;
+ 
    finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
  
    return type;
*************** build_ctr_info_value (counter, type)
*** 587,592 ****
--- 604,610 ----
  {
    tree value = NULL_TREE;
    tree fields = TYPE_FIELDS (type);
+   tree fn;
  
    /* counters */
    value = tree_cons (fields,
*************** build_ctr_info_value (counter, type)
*** 614,619 ****
--- 632,651 ----
      }
    else
      value = tree_cons (fields, null_pointer_node, value);
+   fields = TREE_CHAIN (fields);
+ 
+   fn = build_decl (FUNCTION_DECL,
+ 		   get_identifier (ctr_merge_functions[counter]),
+ 		   TREE_TYPE (TREE_TYPE (fields)));
+   DECL_EXTERNAL (fn) = 1;
+   TREE_PUBLIC (fn) = 1;
+   DECL_ARTIFICIAL (fn) = 1;
+   TREE_NOTHROW (fn) = 1;
+   value = tree_cons (fields,
+ 		     build1 (ADDR_EXPR,
+ 			     TREE_TYPE (fields),
+ 			     fn),
+ 		     value);
  
    value = build_constructor (type, nreverse (value));
    
Index: gcov-io.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/gcov-io.h,v
retrieving revision 1.30
diff -c -3 -p -r1.30 gcov-io.h
*** gcov-io.h	24 Apr 2003 09:46:16 -0000	1.30
--- gcov-io.h	3 May 2003 21:56:00 -0000
*************** typedef HOST_WIDEST_INT gcov_type;
*** 176,190 ****
  #endif
  #endif
  
! /* In lib gcov we want function linkage to be static, so we do not
!    polute the global namespace. In the compiler we want it extern, so
!    that they can be accessed from elsewhere.  */
! #if IN_LIBGCOV || IN_GCOV
  #define GCOV_LINKAGE static
! #else
  #ifndef GCOV_LINKAGE
  #define GCOV_LINKAGE extern
  #endif
  #endif
  
  /* File suffixes.  */
--- 176,221 ----
  #endif
  #endif
  
! /* In gcov we want function linkage to be static, so we do not
!    polute the global namespace. In libgcov we need these functions
!    to be extern, so prefix them with __gcov so that we do not conflict.
!    In the compiler we want it extern, so that they can be accessed from
!    elsewhere.  */
! #if IN_LIBGCOV
! 
! #define GCOV_LINKAGE /* nothing */
! #define gcov_var __gcov_var
! #define gcov_open __gcov_open
! #define gcov_close __gcov_close
! #define gcov_write_bytes __gcov_write_bytes
! #define gcov_write_unsigned __gcov_write_unsigned
! #define gcov_write_counter __gcov_write_counter
! #define gcov_write_string __gcov_write_string
! #define gcov_write_tag __gcov_write_tag
! #define gcov_write_length __gcov_write_length
! #define gcov_write_summary __gcov_write_summary
! #define gcov_read_bytes __gcov_read_bytes
! #define gcov_read_unsigned __gcov_read_unsigned
! #define gcov_read_counter __gcov_read_counter
! #define gcov_read_string __gcov_read_string
! #define gcov_read_summary __gcov_read_summary
! #define gcov_position __gcov_position
! #define gcov_seek __gcov_seek
! #define gcov_seek_end __gcov_seek_end
! #define gcov_is_eof __gcov_is_eof
! #define gcov_is_error __gcov_is_error
! #define gcov_time __gcov_time
! 
! #elif IN_GCOV
! 
  #define GCOV_LINKAGE static
! 
! #else /* !IN_LIBGCOV && !IN_GCOV */
! 
  #ifndef GCOV_LINKAGE
  #define GCOV_LINKAGE extern
  #endif
+ 
  #endif
  
  /* File suffixes.  */
*************** typedef HOST_WIDEST_INT gcov_type;
*** 220,225 ****
--- 251,259 ----
  /* A list of human readable names of the counters */
  #define GCOV_COUNTER_NAMES	{"arcs"}
  
+ /* Names of merge functions for counters.  */
+ #define GCOV_MERGE_FUNCTIONS	{"__gcov_merge_add"}
+ 
  /* Convert a counter index to a tag. */
  #define GCOV_TAG_FOR_COUNTER(COUNT)				\
  	(GCOV_TAG_COUNTER_BASE + ((COUNT) << 17))
*************** struct gcov_fn_info
*** 286,296 ****
--- 320,334 ----
    unsigned n_ctrs[0];		/* instrumented counters */
  };
  
+ /* Type of function used to merge counters.  */
+ typedef void (*gcov_merge_fn) (gcov_type *, unsigned);
+ 
  /* Information about counters.  */
  struct gcov_ctr_info
  {
    unsigned num;		/* number of counters.  */
    gcov_type *values;	/* their values.  */
+   gcov_merge_fn merge;  /* The function used to merge them.  */
  };
  
  /* Information about a single object file.  */
*************** extern void __gcov_init (struct gcov_inf
*** 317,322 ****
--- 355,362 ----
  /* Called before fork, to avoid double counting.  */
  extern void __gcov_flush (void);
  
+ /* The merge function that just sums the counters.  */
+ extern void __gcov_merge_add (gcov_type *, unsigned);
  #endif /* IN_LIBGCOV */
  
  /* Because small reads and writes, interspersed with seeks cause lots
Index: libgcov.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/libgcov.c,v
retrieving revision 1.10
diff -c -3 -p -r1.10 libgcov.c
*** libgcov.c	24 Apr 2003 09:46:17 -0000	1.10
--- libgcov.c	3 May 2003 21:56:00 -0000
*************** Software Foundation, 59 Temple Place - S
*** 32,42 ****
--- 32,50 ----
  #if defined(inhibit_libc)
  /* If libc and its header files are not available, provide dummy functions.  */
  
+ #ifdef L_gcov
  void __gcov_init (void *p);
  void __gcov_flush (void);
  
  void __gcov_init (void *p) { }
  void __gcov_flush (void) { }
+ #endif
+ 
+ #ifdef L_gcov_merge_add
+ void __gcov_merge_add (gcov_type *, unsigned);
+ 
+ void __gcov_merge_add (gcov_type *counters, unsigned n_counters) { }
+ #endif
  
  #else
  
*************** void __gcov_flush (void) { }
*** 59,64 ****
--- 67,74 ----
  #endif
  #define IN_LIBGCOV 1
  #include "gcov-io.h"
+ 
+ #ifdef L_gcov
  #include "gcov-io.c"
  
  /* Chain of per-object gcov structures.  */
*************** gcov_exit (void)
*** 227,233 ****
  		if ((1 << t_ix) & gi_ptr->ctr_mask)
  		  {
  		    unsigned n_counts;
! 		    gcov_type *c_ptr;
  		    
  		    tag = gcov_read_unsigned ();
  		    length = gcov_read_unsigned ();
--- 237,243 ----
  		if ((1 << t_ix) & gi_ptr->ctr_mask)
  		  {
  		    unsigned n_counts;
! 		    gcov_merge_fn merge;
  		    
  		    tag = gcov_read_unsigned ();
  		    length = gcov_read_unsigned ();
*************** gcov_exit (void)
*** 235,245 ****
  		    if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
  			|| fi_ptr->n_ctrs[c_ix] * 8 != length)
  		      goto read_mismatch;
! 		    c_ptr = values[c_ix];
! 		    for (n_counts = fi_ptr->n_ctrs[c_ix];
! 			 n_counts--; c_ptr++)
! 		      *c_ptr += gcov_read_counter ();
! 		    values[c_ix] = c_ptr;
  		    c_ix++;
  		}
  	      if ((error = gcov_is_error ()))
--- 245,254 ----
  		    if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
  			|| fi_ptr->n_ctrs[c_ix] * 8 != length)
  		      goto read_mismatch;
! 		    n_counts = fi_ptr->n_ctrs[c_ix];
! 		    merge = gi_ptr->counts[c_ix].merge;
! 		    (*merge) (values[c_ix], n_counts);
! 		    values[c_ix] += n_counts;
  		    c_ix++;
  		}
  	      if ((error = gcov_is_error ()))
*************** __gcov_flush (void)
*** 449,453 ****
--- 458,478 ----
  	  }
      }
  }
+ 
+ #endif /* L_gcov */
+ 
+ #ifdef L_gcov_merge_add
+ /* The profile merging function that just adds the counters.  It is given
+    an array COUNTERS of N_COUNTERS old counters and it reads the same number
+    of counters from the gcov file.  */
+ void
+ __gcov_merge_add (counters, n_counters)
+      gcov_type *counters;
+      unsigned n_counters;
+ {
+   for (; n_counters; counters++, n_counters--)
+     *counters += gcov_read_counter ();
+ }
+ #endif /* L_gcov_merge_add */
  
  #endif /* inhibit_libc */



More information about the Gcc-patches mailing list