The following patch adds support for a new libgcov interface,
__gcov_profiling_enabled, that can be used by applications to
determine whether a binary has been instrumented for test coverage or
profile optimization.

Passes regression tests and manual testing with different options. Ok
for google branches?

Thanks,
Teresa

2014-07-02  Teresa Johnson  <tejohn...@google.com>

        Google ref b/15378201.
        * gcc/tree-profile.c (gcov_test_coverage_decl): Declare.
        (tree_init_instrumentation): Initialize gcov_test_coverage_decl.
        * libgcc/libgcov-driver.c (__gcov_dummy_ref7): Define.
        * libgcc/libgcov-interface.c (__gcov_profiling_enabled): New function.

Index: gcc/tree-profile.c
===================================================================
--- gcc/tree-profile.c  (revision 212044)
+++ gcc/tree-profile.c  (working copy)
@@ -164,6 +164,9 @@ static GTY(()) tree gcov_sample_counter_decl = NUL
 /* extern gcov_unsigned_t __gcov_profile_prefix  */
 static tree GTY(()) gcov_profile_prefix_decl = NULL_TREE;

+/* extern gcov_unsigned_t __gcov_test_coverage  */
+static tree GTY(()) gcov_test_coverage_decl = NULL_TREE;
+
 /* extern gcov_unsigned_t __gcov_sampling_period  */
 static GTY(()) tree gcov_sampling_period_decl = NULL_TREE;

@@ -498,6 +501,27 @@ tree_init_instrumentation (void)
       DECL_INITIAL (gcov_profile_prefix_decl) = prefix_ptr;
       varpool_finalize_decl (gcov_profile_prefix_decl);
     }
+
+  if (!gcov_test_coverage_decl)
+    {
+      /* Initialize __gcov_test_coverage to 1 if -ftest-coverage
+         specified, 0 otherwise. Used by libgcov to determine whether
+         a binary was instrumented for coverage or profile optimization.  */
+      gcov_test_coverage_decl = build_decl (
+          UNKNOWN_LOCATION,
+          VAR_DECL,
+          get_identifier ("__gcov_test_coverage"),
+          get_gcov_unsigned_t ());
+      TREE_PUBLIC (gcov_test_coverage_decl) = 1;
+      DECL_ARTIFICIAL (gcov_test_coverage_decl) = 1;
+      DECL_COMDAT_GROUP (gcov_test_coverage_decl)
+          = DECL_ASSEMBLER_NAME (gcov_test_coverage_decl);
+      TREE_STATIC (gcov_test_coverage_decl) = 1;
+      DECL_INITIAL (gcov_test_coverage_decl) = build_int_cst (
+          get_gcov_unsigned_t (),
+          flag_test_coverage ? 1 : 0);
+      varpool_finalize_decl (gcov_test_coverage_decl);
+    }
 }

 /* Initialization function for FDO sampling.  */
Index: libgcc/libgcov-driver.c
===================================================================
--- libgcc/libgcov-driver.c     (revision 212044)
+++ libgcc/libgcov-driver.c     (working copy)
@@ -79,6 +79,8 @@ extern unsigned int __gcov_sampling_enabled (void)
 char *(*__gcov_dummy_ref5)(void) = &__gcov_sampling_enabled;
 extern void __gcov_flush (void);
 char *(*__gcov_dummy_ref6)(void) = &__gcov_flush;
+extern unsigned int __gcov_profiling_enabled (void);
+char *(*__gcov_dummy_ref7)(void) = &__gcov_profiling_enabled;

 /* Default callback function for profile instrumentation callback.  */
 extern void __coverage_callback (gcov_type, int);
Index: libgcc/libgcov-interface.c
===================================================================
--- libgcc/libgcov-interface.c  (revision 212044)
+++ libgcc/libgcov-interface.c  (working copy)
@@ -116,6 +116,20 @@ __gcov_dump (void)
   set_gcov_dump_complete ();
 }

+/* Emitted in coverage.c.  */
+extern gcov_unsigned_t __gcov_test_coverage;
+
+unsigned int __gcov_profiling_enabled (void);
+
+/* Function that can be called from application to distinguish binaries
+   instrumented from coverage fro those instrumented for profiling
+   (e.g. -fprofile-generate).  */
+
+unsigned int __gcov_profiling_enabled (void)
+{
+  return !__gcov_test_coverage;
+}
+
 #endif /* L_gcov_dump */

 #ifdef L_gcov_sampling


-- 
Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413

Reply via email to