coarray_43.f90: Add "-latomic" option if libatomic_available.
[gcc.git] / libgcc / libgcov-interface.c
index 76d3f9731d7f8f58461dfc07a5bcd37dde2ff434..61089e970064910fc91e8ab5d1b0019a16d0a3b6 100644 (file)
@@ -1,6 +1,6 @@
 /* Routines required for instrumenting a program.  */
 /* Compile this one with gcc.  */
-/* Copyright (C) 1989-2014 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2017 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -42,11 +42,14 @@ void __gcov_dump (void) {}
 
 #else
 
-
 /* Some functions we want to bind in this dynamic object, but have an
-   overridable global alias.  */
-#define STRONG_ALIAS(src,dst) \
-  extern __typeof (src) dst __attribute__((alias (#src)))
+   overridable global alias.  Unfortunately not all targets support
+   aliases, so we just have a forwarding function.  That'll be tail
+   called, so the cost is a single jump instruction.*/
+
+#define ALIAS_void_fn(src,dst) \
+  void dst (void)          \
+  { src (); }
 
 extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
 extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
@@ -82,7 +85,7 @@ __gcov_flush (void)
   init_mx_once ();
   __gthread_mutex_lock (&__gcov_flush_mx);
 
-  __gcov_dump_one (&__gcov_root);
+  __gcov_dump_int ();
   __gcov_reset_int ();
 
   __gthread_mutex_unlock (&__gcov_flush_mx);
@@ -129,11 +132,19 @@ gcov_clear (const struct gcov_info *list)
 void
 __gcov_reset_int (void)
 {
-  gcov_clear (__gcov_root.list);
-  __gcov_root.dumped = 0;
+  struct gcov_root *root;
+
+  /* If we're compatible with the master, iterate over everything,
+     otherise just do us.  */
+  for (root = __gcov_master.version == GCOV_VERSION
+        ? __gcov_master.root : &__gcov_root; root; root = root->next)
+    {
+      gcov_clear (root->list);
+      root->dumped = 0;
+    }
 }
 
-STRONG_ALIAS (__gcov_reset_int, __gcov_reset);
+ALIAS_void_fn (__gcov_reset_int, __gcov_reset);
 
 #endif /* L_gcov_reset */
 
@@ -142,11 +153,19 @@ STRONG_ALIAS (__gcov_reset_int, __gcov_reset);
    so far, in order to collect profile in region of interest.  */
 
 void
-__gcov_dump (void)
+__gcov_dump_int (void)
 {
-  __gcov_dump_one (&__gcov_root);
+  struct gcov_root *root;
+
+  /* If we're compatible with the master, iterate over everything,
+     otherise just do us.  */
+  for (root = __gcov_master.version == GCOV_VERSION
+        ? __gcov_master.root : &__gcov_root; root; root = root->next)
+    __gcov_dump_one (root);
 }
 
+ALIAS_void_fn (__gcov_dump_int, __gcov_dump);
+
 #endif /* L_gcov_dump */
 
 #ifdef L_gcov_fork
@@ -166,8 +185,8 @@ __gcov_fork (void)
 #endif
 
 #ifdef L_gcov_execl
-/* A wrapper for the execl function.  Flushes the accumulated profiling data, so
-   that they are not lost.  */
+/* A wrapper for the execl function.  Flushes the accumulated
+   profiling data, so that they are not lost.  */
 
 int
 __gcov_execl (const char *path, char *arg, ...)