[compiler-rt] r177337 - Add some GCOV functions that register all of the __llvm_gcov_flush() functions.

Bill Wendling isanbard at gmail.com
Mon Mar 18 15:59:47 PDT 2013


Author: void
Date: Mon Mar 18 17:59:47 2013
New Revision: 177337

URL: http://llvm.org/viewvc/llvm-project?rev=177337&view=rev
Log:
Add some GCOV functions that register all of the __llvm_gcov_flush() functions.

The __llvm_gcov_flush() functions only work for the local compile unit. However,
when __gcov_flush() is called, the user expects all of the counters to be
flushed, not just the ones in the current compile unit.

This adds some library functions that register the flush functions. It also
defined __gcov_flush() so that loops through that list and calls the functions.

PR15191 & <rdar://problem/13167507>

Modified:
    compiler-rt/trunk/lib/profile/GCDAProfiling.c

Modified: compiler-rt/trunk/lib/profile/GCDAProfiling.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/GCDAProfiling.c?rev=177337&r1=177336&r2=177337&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/GCDAProfiling.c (original)
+++ compiler-rt/trunk/lib/profile/GCDAProfiling.c Mon Mar 18 17:59:47 2013
@@ -42,8 +42,24 @@ typedef unsigned int uint64_t;
  * --- GCOV file format I/O primitives ---
  */
 
+/*
+ * The current file we're outputting.
+ */ 
 static FILE *output_file = NULL;
 
+/*
+ *  A list of flush functions that our __gcov_flush() function should call.
+ */
+typedef void (*flush_fn)();
+
+struct flush_fn_node {
+  flush_fn fn;
+  struct flush_fn_node *next;
+};
+
+struct flush_fn_node *flush_fn_head = NULL;
+struct flush_fn_node *flush_fn_tail = NULL;
+
 static void write_int32(uint32_t i) {
   fwrite(&i, 4, 1, output_file);
 }
@@ -288,3 +304,35 @@ void llvm_gcda_end_file() {
   fprintf(stderr, "llvmgcda: -----\n");
 #endif
 }
+
+void llvm_register_flush_function(flush_fn fn) {
+  struct flush_fn_node *new_node = malloc(sizeof(struct flush_fn_node));
+  new_node->fn = fn;
+  new_node->next = NULL;
+
+  if (!flush_fn_head) {
+    flush_fn_head = flush_fn_tail = new_node;
+  } else {
+    flush_fn_tail->next = new_node;
+    flush_fn_tail = new_node;
+  }
+}
+
+void __gcov_flush() {
+  struct flush_fn_node *curr = flush_fn_head;
+
+  while (curr) {
+    curr->fn();
+    curr = curr->next;
+  }
+}
+
+void llvm_delete_flush_function_list() {
+  while (flush_fn_head) {
+    struct flush_fn_node *node = flush_fn_head;
+    flush_fn_head = flush_fn_head->next;
+    free(node);
+  }
+
+  flush_fn_head = flush_fn_tail = NULL;
+}





More information about the llvm-commits mailing list