[llvm-commits] [compiler-rt] r163923 - in /compiler-rt/trunk: SDKs/darwin/usr/include/stdio.h lib/profile/GCDAProfiling.c

Bill Wendling isanbard at gmail.com
Fri Sep 14 11:55:33 PDT 2012


Author: void
Date: Fri Sep 14 13:55:32 2012
New Revision: 163923

URL: http://llvm.org/viewvc/llvm-project?rev=163923&view=rev
Log:
Add support for reading the GCDA file and merging the arc information.

With the advent of the __llvm_gcov_flush function, we need to be able to merge
counts into the .gcda files in an intelligent manner. This involves reading the
file if it exists, adding the counts together, and then writing the results.
<rdar://problem/12185886>

Modified:
    compiler-rt/trunk/SDKs/darwin/usr/include/stdio.h
    compiler-rt/trunk/lib/profile/GCDAProfiling.c

Modified: compiler-rt/trunk/SDKs/darwin/usr/include/stdio.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/SDKs/darwin/usr/include/stdio.h?rev=163923&r1=163922&r2=163923&view=diff
==============================================================================
--- compiler-rt/trunk/SDKs/darwin/usr/include/stdio.h (original)
+++ compiler-rt/trunk/SDKs/darwin/usr/include/stdio.h Fri Sep 14 13:55:32 2012
@@ -51,11 +51,24 @@
 #    define stderr __stderrp
 extern FILE *__stderrp;
 
+#ifndef SEEK_SET
+#define	SEEK_SET	0	/* set file offset to offset */
+#endif
+#ifndef SEEK_CUR
+#define	SEEK_CUR	1	/* set file offset to current plus offset */
+#endif
+#ifndef SEEK_END
+#define	SEEK_END	2	/* set file offset to EOF plus offset */
+#endif
+
 int fclose(FILE *);
 int fflush(FILE *);
 FILE *fopen(const char * restrict, const char * restrict) __asm(__FOPEN_NAME);
 int fprintf(FILE * restrict, const char * restrict, ...);
 size_t fwrite(const void * restrict, size_t, size_t, FILE * restrict)
   __asm(__FWRITE_NAME);
+size_t fread(void * __restrict, size_t, size_t, FILE * __restrict);
+long ftell(FILE *);
+int fseek(FILE *, long, int);
 
 #endif /* __STDIO_H__ */

Modified: compiler-rt/trunk/lib/profile/GCDAProfiling.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/GCDAProfiling.c?rev=163923&r1=163922&r2=163923&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/GCDAProfiling.c (original)
+++ compiler-rt/trunk/lib/profile/GCDAProfiling.c Fri Sep 14 13:55:32 2012
@@ -66,6 +66,24 @@
   fwrite("\0\0\0\0", 4 - (strlen(s) % 4), 1, output_file);
 }
 
+static uint32_t read_int32() {
+  uint32_t tmp;
+
+  if (fread(&tmp, 1, 4, output_file) != 4)
+    return (uint32_t)-1;
+
+  return tmp;
+}
+
+static uint64_t read_int64() {
+  uint64_t tmp;
+
+  if (fread(&tmp, 1, 8, output_file) != 8)
+    return (uint64_t)-1;
+
+  return tmp;
+}
+
 static char *mangle_filename(const char *orig_filename) {
   char *filename = 0;
   int prefix_len = 0;
@@ -129,15 +147,24 @@
  */
 void llvm_gcda_start_file(const char *orig_filename) {
   char *filename = mangle_filename(orig_filename);
-  output_file = fopen(filename, "w+b");
+  char buffer[13];
+
+  /* Try just opening the file. */
+  output_file = fopen(filename, "r+b");
 
   if (!output_file) {
-    recursive_mkdir(filename);
+    /* Try opening the file, creating it if necessary. */
     output_file = fopen(filename, "w+b");
     if (!output_file) {
-      fprintf(stderr, "profiling:%s: cannot open\n", filename);
-      free(filename);
-      return;
+      /* Try creating the directories first then opening the file. */
+      recursive_mkdir(filename);
+      output_file = fopen(filename, "w+b");
+      if (!output_file) {
+        /* Bah! It's hopeless. */
+        fprintf(stderr, "profiling:%s: cannot open\n", filename);
+        free(filename);
+        return;
+      }
     }
   }
 
@@ -148,11 +175,11 @@
   fwrite("adcg*404MVLL", 12, 1, output_file);
 #endif
 
+  free(filename);
+
 #ifdef DEBUG_GCDAPROFILING
-  printf("llvmgcda: [%s]\n", orig_filename);
+  fprintf(stderr, "llvmgcda: [%s]\n", orig_filename);
 #endif
-
-  free(filename);
 }
 
 /* Given an array of pointers to counters (counters), increment the n-th one,
@@ -175,14 +202,14 @@
 #ifdef DEBUG_GCDAPROFILING
   else
     fprintf(stderr,
-            "llvmgcda: increment_indirect_counter counters=%x, pred=%u\n",
-            state_table_row, *predecessor);
+            "llvmgcda: increment_indirect_counter counters=%08llx, pred=%u\n",
+            *counter, *predecessor);
 #endif
 }
 
 void llvm_gcda_emit_function(uint32_t ident, const char *function_name) {
 #ifdef DEBUG_GCDAPROFILING
-  printf("llvmgcda: function id=%x\n", ident);
+  fprintf(stderr, "llvmgcda: function id=0x%08x\n", ident);
 #endif
   if (!output_file) return;
 
@@ -197,18 +224,55 @@
 
 void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) {
   uint32_t i;
+  uint64_t *old_ctrs = NULL;
+  uint32_t val = 0;
+  long pos = 0;
 
-  /* Counter #1 (arcs) tag */
   if (!output_file) return;
+
+  pos = ftell(output_file);
+  val = read_int32();
+
+  fprintf(stderr, "Read: 0x%08x\n", val);
+
+  if (val != (uint32_t)-1) {
+    /* There are counters present in the file. Merge them. */
+    uint32_t j;
+
+    if (val != 0x01a10000) {
+      fprintf(stderr, "profiling: invalid magic number (0x%08x)\n", val);
+      return;
+    }
+
+    val = read_int32();
+    if (val == (uint32_t)-1 || val / 2 != num_counters) {
+      fprintf(stderr, "profiling: invalid number of counters (%d)\n", val);
+      return;
+    }
+
+    old_ctrs = malloc(sizeof(uint64_t) * num_counters);
+
+    for (j = 0; j < num_counters; ++j) {
+      old_ctrs[j] = read_int64();
+      fprintf(stderr, "old counter[%d]: %lld\n", j, old_ctrs[j]);
+    }
+  }
+
+  /* Reset for writing. */
+  fseek(output_file, pos, SEEK_SET);
+
+  /* Counter #1 (arcs) tag */
   fwrite("\0\0\xa1\1", 4, 1, output_file);
   write_int32(num_counters * 2);
   for (i = 0; i < num_counters; ++i)
-    write_int64(counters[i]);
+    write_int64(counters[i] + (old_ctrs ? old_ctrs[i] : 0));
+
+  free(old_ctrs);
 
 #ifdef DEBUG_GCDAPROFILING
-  printf("llvmgcda:   %u arcs\n", num_counters);
+  fprintf(stderr, "llvmgcda:   %u arcs\n", num_counters);
   for (i = 0; i < num_counters; ++i)
-    printf("llvmgcda:   %llu\n", (unsigned long long)counters[i]);
+    fprintf(stderr, "llvmgcda:   %llu\n", (unsigned long long)counters[i]);
 #endif
 }
 
@@ -220,6 +284,6 @@
   output_file = NULL;
 
 #ifdef DEBUG_GCDAPROFILING
-  printf("llvmgcda: -----\n");
+  fprintf(stderr, "llvmgcda: -----\n");
 #endif
 }





More information about the llvm-commits mailing list