diff mbox

another gcov reworking

Message ID 53D69DB9.2020007@acm.org
State New
Headers show

Commit Message

Nathan Sidwell July 28, 2014, 7 p.m. UTC
It turned out that I needed to insert this cleanup before the final one.  This 
patch breaks out the dumping functionality from gcov exit, and thereby removes 
the global variables from the former.  This makes gcov-tool less dependent on 
what should be internal interfaces in libgcov.

I also noticed a couple of other problems:
1) gcov_var wasn't hidden, thus it'll be  shared between all shared objects
2) gcov_rewrite was no longer being inlined, and as it wasn't hidden would have 
the same problem.

Once committed, I'll be able to do the final cleanup to make cross-shared object 
dumping easy.

nathan
2014-07-28  Nathan Sidwell  <nathan@acm.org>

	libgcc/
	* libgcov.h: Move renaming of entry points to lib gcov specific
	portion.
	(gcov_do_dump): New rename.
	(gcov_rewrite): Remove inline, make HIDDEN.
	* libgcov-driver.c (gcov_clear, gcov_exit): Remove declarations.
	(gcov_exit_compute_summary): Rename to ...
	(compute_summary): ... here.  Add LIST argument.
	(gcov_exit_merge_gcda): Rename to ...
	(merge_one_data): ... here.
	(gcov_exit_write_gcda): Rename to ...
	(write_one_data): ... here.
	(gcov_exit_merge_summary): Rename to ...
	(merge_summary): Add RUN_COUNTED argument.
	(gcov_exit_dump_gcov): Rename to ...
	(dump_one_gcov): Add RUN_COUNTED argument.
	(gcov_do_dump): New function, broken out of ...
	(gcov_exit): ... here.  Call it.

	gcc/
	* gcov-io.c (gcov_var): Make hidden.
	* gcov-tool.c (gcov_list, gcov_exit): Remove declarations.
	(gcov_do_dump): Declare.
	(gcov_output_files): Call gcov_do_dump, not gcov_exit).
diff mbox

Patch

Index: gcc/gcov-io.c
===================================================================
--- gcc/gcov-io.c	(revision 213092)
+++ gcc/gcov-io.c	(working copy)
@@ -39,7 +39,7 @@  static void gcov_allocate (unsigned);
 /* Optimum number of gcov_unsigned_t's read from or written to disk.  */
 #define GCOV_BLOCK_SIZE (1 << 10)
 
-GCOV_LINKAGE struct gcov_var
+GCOV_LINKAGE ATTRIBUTE_HIDDEN struct gcov_var
 {
   FILE *file;
   gcov_position_t start;	/* Position of first byte of block */
Index: gcc/gcov-tool.c
===================================================================
--- gcc/gcov-tool.c	(revision 213092)
+++ gcc/gcov-tool.c	(working copy)
@@ -38,13 +38,11 @@  see the files COPYING3 and COPYING.RUNTI
 #include <ftw.h>
 #include <getopt.h>
 
-extern struct gcov_info *gcov_list;
-
 extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
 extern struct gcov_info* gcov_read_profile_dir (const char*, int);
-extern void gcov_exit (void);
+extern void gcov_do_dump (struct gcov_info *, int);
 extern void gcov_set_verbose (void);
 
 /* Set to verbose output mode.  */
@@ -110,8 +108,7 @@  gcov_output_files (const char *out, stru
   if (ret)
     fatal_error ("Cannot change directory to %s", out);
 
-  gcov_list = profile;
-  gcov_exit ();
+  gcov_do_dump (profile, 0);
 
   ret = chdir (pwd);
   if (ret)
Index: libgcc/libgcov-driver.c
===================================================================
--- libgcc/libgcov-driver.c	(revision 213092)
+++ libgcc/libgcov-driver.c	(working copy)
@@ -48,10 +48,6 @@  static int gcov_error (const char *, ...
 
 #include "gcov-io.c"
 
-/* The following functions can be called from outside of this file.  */
-extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
-extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
-
 struct gcov_fn_buffer
 {
   struct gcov_fn_buffer *next;
@@ -293,8 +289,8 @@  static int run_accounted = 0;
    Also determines the longest filename length of the info files.  */
 
 static gcov_unsigned_t
-gcov_exit_compute_summary (struct gcov_summary *this_prg,
-			   size_t *max_length)
+compute_summary (struct gcov_info *list, struct gcov_summary *this_prg,
+		 size_t *max_length)
 {
   struct gcov_info *gi_ptr;
   const struct gcov_fn_info *gfi_ptr;
@@ -308,7 +304,7 @@  gcov_exit_compute_summary (struct gcov_s
   /* Find the totals for this execution.  */
   memset (this_prg, 0, sizeof (*this_prg));
   *max_length = 0;
-  for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
+  for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
     {
       size_t len = strlen (gi_ptr->filename);
       if (len > *max_length)
@@ -362,13 +358,13 @@  gcov_exit_compute_summary (struct gcov_s
    Return -1 on error. In this case, caller will goto read_fatal.  */
 
 static int
-gcov_exit_merge_gcda (const char *filename,
-		      struct gcov_info *gi_ptr,
-                      struct gcov_summary *prg_p,
-                      struct gcov_summary *this_prg,
-                      gcov_position_t *summary_pos_p,
-                      gcov_position_t *eof_pos_p,
-		      gcov_unsigned_t crc32)
+merge_one_data (const char *filename,
+		struct gcov_info *gi_ptr,
+		struct gcov_summary *prg_p,
+		struct gcov_summary *this_prg,
+		gcov_position_t *summary_pos_p,
+		gcov_position_t *eof_pos_p,
+		gcov_unsigned_t crc32)
 {
   gcov_unsigned_t tag, length;
   unsigned t_ix;
@@ -512,10 +508,10 @@  read_error:
    We will write the file starting from SUMMAY_POS.  */
 
 static void
-gcov_exit_write_gcda (const struct gcov_info *gi_ptr,
-                      const struct gcov_summary *prg_p,
-                      const gcov_position_t eof_pos,
-                      const gcov_position_t summary_pos)
+write_one_data (const struct gcov_info *gi_ptr,
+		const struct gcov_summary *prg_p,
+		const gcov_position_t eof_pos,
+		const gcov_position_t summary_pos)
 {
   unsigned f_ix;
   struct gcov_summary_buffer *next_sum_buffer;
@@ -607,10 +603,10 @@  gcov_exit_write_gcda (const struct gcov_
    Return -1 on error. Return 0 on success.  */
 
 static int
-gcov_exit_merge_summary (const char *filename,
-			 const struct gcov_info *gi_ptr, struct gcov_summary *prg,
-                         struct gcov_summary *this_prg, gcov_unsigned_t crc32,
-			 struct gcov_summary *all_prg __attribute__ ((unused)))
+merge_summary (const char *filename, int run_counted,
+	       const struct gcov_info *gi_ptr, struct gcov_summary *prg,
+	       struct gcov_summary *this_prg, gcov_unsigned_t crc32,
+	       struct gcov_summary *all_prg __attribute__ ((unused)))
 {
   struct gcov_ctr_summary *cs_prg, *cs_tprg;
   unsigned t_ix;
@@ -629,7 +625,7 @@  gcov_exit_merge_summary (const char *fil
         {
 	  int first = !cs_prg->runs;
 
-	  if (!run_accounted)
+	  if (!run_counted)
 	    cs_prg->runs++;
           if (first)
             cs_prg->num = cs_tprg->num;
@@ -691,9 +687,10 @@  gcov_exit_merge_summary (const char *fil
    summaries separate.  */
 
 static void
-gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
-		     gcov_unsigned_t crc32, struct gcov_summary *all_prg,
-                     struct gcov_summary *this_prg)
+dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
+	       unsigned run_counted,
+	       gcov_unsigned_t crc32, struct gcov_summary *all_prg,
+	       struct gcov_summary *this_prg)
 {
   struct gcov_summary prg; /* summary for this object over all program.  */
   int error;
@@ -717,8 +714,8 @@  gcov_exit_dump_gcov (struct gcov_info *g
           gcov_error ("profiling:%s:Not a gcov data file\n", gf->filename);
           goto read_fatal;
         }
-      error = gcov_exit_merge_gcda (gf->filename, gi_ptr, &prg, this_prg,
-				    &summary_pos, &eof_pos, crc32);
+      error = merge_one_data (gf->filename, gi_ptr, &prg, this_prg,
+			      &summary_pos, &eof_pos, crc32);
       if (error == -1)
         goto read_fatal;
     }
@@ -731,12 +728,12 @@  gcov_exit_dump_gcov (struct gcov_info *g
       summary_pos = eof_pos;
     }
 
-  error = gcov_exit_merge_summary (gf->filename, gi_ptr, &prg, this_prg,
-				   crc32, all_prg);
+  error = merge_summary (gf->filename, run_counted, gi_ptr, &prg, this_prg,
+			 crc32, all_prg);
   if (error == -1)
     goto read_fatal;
 
-  gcov_exit_write_gcda (gi_ptr, &prg, eof_pos, summary_pos);
+  write_one_data (gi_ptr, &prg, eof_pos, summary_pos);
   /* fall through */
 
 read_fatal:;
@@ -755,8 +752,8 @@  read_fatal:;
    summary and then traverses gcov_list list and dumps the gcov_info
    objects one by one.  */
 
-void
-gcov_exit (void)
+void ATTRIBUTE_HIDDEN
+gcov_do_dump (struct gcov_info *list, int run_counted)
 {
   struct gcov_info *gi_ptr;
   struct gcov_filename gf;
@@ -764,14 +761,7 @@  gcov_exit (void)
   struct gcov_summary all_prg;
   struct gcov_summary this_prg;
 
-  /* Prevent the counters from being dumped a second time on exit when the
-     application already wrote out the profile using __gcov_dump().  */
-  if (gcov_dump_complete)
-    return;
-
-  gcov_dump_complete = 1;
-
-  crc32 = gcov_exit_compute_summary (&this_prg, &gf.max_length);
+  crc32 = compute_summary (list, &this_prg, &gf.max_length);
 
   allocate_filename_struct (&gf);
 #if !GCOV_LOCKED
@@ -779,13 +769,27 @@  gcov_exit (void)
 #endif
 
   /* Now merge each file.  */
-  for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
-    gcov_exit_dump_gcov (gi_ptr, &gf, crc32, &all_prg, &this_prg);
-  run_accounted = 1;
+  for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
+    dump_one_gcov (gi_ptr, &gf, run_counted, crc32, &all_prg, &this_prg);
 
   free (gf.filename);
 }
 
+void
+gcov_exit (void)
+{
+  /* Prevent the counters from being dumped a second time on exit when the
+     application already wrote out the profile using __gcov_dump().  */
+  if (gcov_dump_complete)
+    return;
+
+  gcov_dump_complete = 1;
+
+  gcov_do_dump (gcov_list, run_accounted);
+  
+  run_accounted = 1;
+}
+
 /* Reset all counters to zero.  */
 
 void
Index: libgcc/libgcov.h
===================================================================
--- libgcc/libgcov.h	(revision 213092)
+++ libgcc/libgcov.h	(working copy)
@@ -83,6 +83,25 @@  typedef unsigned gcov_type_unsigned __at
 #define GCOV_LOCKED 0
 #endif
 
+/* In libgcov we need these functions to be extern, so prefix them with
+   __gcov.  In libgcov they must also be hidden so that the instance in
+   the executable is not also used in a DSO.  */
+#define gcov_var __gcov_var
+#define gcov_open __gcov_open
+#define gcov_close __gcov_close
+#define gcov_write_tag_length __gcov_write_tag_length
+#define gcov_position __gcov_position
+#define gcov_seek __gcov_seek
+#define gcov_rewrite __gcov_rewrite
+#define gcov_is_error __gcov_is_error
+#define gcov_write_unsigned __gcov_write_unsigned
+#define gcov_write_counter __gcov_write_counter
+#define gcov_write_summary __gcov_write_summary
+#define gcov_read_unsigned __gcov_read_unsigned
+#define gcov_read_counter __gcov_read_counter
+#define gcov_read_summary __gcov_read_summary
+#define gcov_do_dump __gcov_do_dump
+
 #else /* IN_GCOV_TOOL */
 /* About the host.  */
 /* This path will be compiled for the host and linked into
@@ -126,24 +145,6 @@  extern struct gcov_info *gcov_list;
 #endif
 #endif
 
-/* In libgcov we need these functions to be extern, so prefix them with
-   __gcov.  In libgcov they must also be hidden so that the instance in
-   the executable is not also used in a DSO.  */
-#define gcov_var __gcov_var
-#define gcov_open __gcov_open
-#define gcov_close __gcov_close
-#define gcov_write_tag_length __gcov_write_tag_length
-#define gcov_position __gcov_position
-#define gcov_seek __gcov_seek
-#define gcov_rewrite __gcov_rewrite
-#define gcov_is_error __gcov_is_error
-#define gcov_write_unsigned __gcov_write_unsigned
-#define gcov_write_counter __gcov_write_counter
-#define gcov_write_summary __gcov_write_summary
-#define gcov_read_unsigned __gcov_read_unsigned
-#define gcov_read_counter __gcov_read_counter
-#define gcov_read_summary __gcov_read_summary
-
 /* Poison these, so they don't accidentally slip in.  */
 #pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length
 #pragma GCC poison gcov_time gcov_magic
@@ -265,7 +266,7 @@  GCOV_LINKAGE void gcov_write_summary (gc
                                       const struct gcov_summary *)
     ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE inline void gcov_rewrite (void);
+GCOV_LINKAGE void gcov_rewrite (void) ATTRIBUTE_HIDDEN;
 
 /* "Counts" stored in gcda files can be a real counter value, or
    an target address. When differentiate these two types because