[compiler-rt] r182563 - Performance improvement.

Bill Wendling isanbard at gmail.com
Thu May 23 00:18:59 PDT 2013


Author: void
Date: Thu May 23 02:18:59 2013
New Revision: 182563

URL: http://llvm.org/viewvc/llvm-project?rev=182563&view=rev
Log:
Performance improvement.

Using fwrite and fread was very *very* slow. The resulting code was multiple
times slower than GCC's implementation of gcov. Replace the fwrite/fread system
with an mmap() version.

If the `.gcda' file doesn't exist, we (re)allocate a buffer that we write
into. That gets written to the `.gcda' file in one chunk. If the `.gcda' file
already exists, we simply mmap() the file, modify the mapped data, and use
msync() to write the contents out to disk. It's much easier than implementing
our own buffering scheme, and we don't have to use fwrite's and fread's
buffering.

For those who are numbers-oriented, here are some timings:

GCC Verison
-----------

`.gcda' files don't exist:  23s
`.gcda' files do exist:     14s

LLVM Version (before this change)
---------------------------------

`.gcda' files don't exist:  28s
`.gcda' files do exist:     28s

LLVM Version (with this change)
-------------------------------

`.gcda' files don't exist:  18s
`.gcda' files do exist:      4s

It's a win-win-win-win-lose-win-win scenario!

<rdar://problem/13466086>

Added:
    compiler-rt/trunk/SDKs/darwin/usr/include/fcntl.h
    compiler-rt/trunk/SDKs/darwin/usr/include/sys/fcntl.h
    compiler-rt/trunk/SDKs/darwin/usr/include/sys/mman.h
    compiler-rt/trunk/SDKs/linux/usr/include/fcntl.h
    compiler-rt/trunk/SDKs/linux/usr/include/sys/fcntl.h
Modified:
    compiler-rt/trunk/SDKs/darwin/usr/include/stdio.h
    compiler-rt/trunk/SDKs/darwin/usr/include/stdlib.h
    compiler-rt/trunk/SDKs/linux/usr/include/stdio.h
    compiler-rt/trunk/SDKs/linux/usr/include/stdlib.h
    compiler-rt/trunk/SDKs/linux/usr/include/sys/mman.h
    compiler-rt/trunk/lib/profile/GCDAProfiling.c

Added: compiler-rt/trunk/SDKs/darwin/usr/include/fcntl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/SDKs/darwin/usr/include/fcntl.h?rev=182563&view=auto
==============================================================================
--- compiler-rt/trunk/SDKs/darwin/usr/include/fcntl.h (added)
+++ compiler-rt/trunk/SDKs/darwin/usr/include/fcntl.h Thu May 23 02:18:59 2013
@@ -0,0 +1,17 @@
+/* ===-- fcntl.h - stub SDK header for compiler-rt --------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===-----------------------------------------------------------------------===
+ *
+ * This is a stub SDK header file. This file is not part of the interface of
+ * this library nor an official version of the appropriate SDK header. It is
+ * intended only to stub the features of this header required by compiler-rt.
+ *
+ * ===-----------------------------------------------------------------------===
+ */
+
+#include <sys/fcntl.h>

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=182563&r1=182562&r2=182563&view=diff
==============================================================================
--- compiler-rt/trunk/SDKs/darwin/usr/include/stdio.h (original)
+++ compiler-rt/trunk/SDKs/darwin/usr/include/stdio.h Thu May 23 02:18:59 2013
@@ -24,15 +24,18 @@ extern "C" {
 typedef struct __sFILE FILE;
 typedef __SIZE_TYPE__ size_t;
 
-/* Determine the appropriate fopen() and fwrite() functions. */
+/* Determine the appropriate fdopen, fopen(), and fwrite() functions. */
 #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
 #  if defined(__i386)
+#    define __FDOPEN_NAME  "_fdopen$UNIX2003"
 #    define __FOPEN_NAME "_fopen$UNIX2003"
 #    define __FWRITE_NAME "_fwrite$UNIX2003"
 #  elif defined(__x86_64__)
+#    define __FDOPEN_NAME  "_fdopen"
 #    define __FOPEN_NAME "_fopen"
 #    define __FWRITE_NAME "_fwrite"
 #  elif defined(__arm)
+#    define __FDOPEN_NAME  "_fdopen"
 #    define __FOPEN_NAME "_fopen"
 #    define __FWRITE_NAME "_fwrite"
 #  else
@@ -40,9 +43,11 @@ typedef __SIZE_TYPE__ size_t;
 #  endif
 #elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
 #  if defined(__i386) || defined (__x86_64)
+#    define __FDOPEN_NAME  "_fdopen"
 #    define __FOPEN_NAME "_fopen"
 #    define __FWRITE_NAME "_fwrite"
 #  elif defined(__arm)
+#    define __FDOPEN_NAME  "_fdopen"
 #    define __FOPEN_NAME "_fopen"
 #    define __FWRITE_NAME "_fwrite"
 #  else
@@ -68,14 +73,13 @@ extern FILE *__stderrp;
 int fclose(FILE *);
 int fflush(FILE *);
 FILE *fopen(const char * __restrict, const char * __restrict) __asm(__FOPEN_NAME);
+FILE *fdopen(int, const char *) __asm(__FDOPEN_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);
-void setbuf(FILE * __restrict, char * __restrict);
-
 int snprintf(char * __restrict, size_t, const char * __restrict, ...);
 
 #if defined(__cplusplus)

Modified: compiler-rt/trunk/SDKs/darwin/usr/include/stdlib.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/SDKs/darwin/usr/include/stdlib.h?rev=182563&r1=182562&r2=182563&view=diff
==============================================================================
--- compiler-rt/trunk/SDKs/darwin/usr/include/stdlib.h (original)
+++ compiler-rt/trunk/SDKs/darwin/usr/include/stdlib.h Thu May 23 02:18:59 2013
@@ -27,5 +27,6 @@ int atoi(const char *);
 void free(void *);
 char *getenv(const char *);
 void *malloc(size_t);
+void *realloc(void *, size_t);
 
 #endif /* __STDLIB_H__ */

Added: compiler-rt/trunk/SDKs/darwin/usr/include/sys/fcntl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/SDKs/darwin/usr/include/sys/fcntl.h?rev=182563&view=auto
==============================================================================
--- compiler-rt/trunk/SDKs/darwin/usr/include/sys/fcntl.h (added)
+++ compiler-rt/trunk/SDKs/darwin/usr/include/sys/fcntl.h Thu May 23 02:18:59 2013
@@ -0,0 +1,52 @@
+/* ===-- fcntl.h - stub SDK header for compiler-rt --------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===-----------------------------------------------------------------------===
+ *
+ * This is a stub SDK header file. This file is not part of the interface of
+ * this library nor an official version of the appropriate SDK header. It is
+ * intended only to stub the features of this header required by compiler-rt.
+ *
+ * ===-----------------------------------------------------------------------===
+ */
+
+#ifndef _SYS_FCNTL_H_
+#define _SYS_FCNTL_H_
+
+/* Determine the appropriate open function. */
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
+#  if defined(__i386)
+#    define __OPEN_NAME  "_open$UNIX2003"
+#  elif defined(__x86_64__)
+#    define __OPEN_NAME  "_open"
+#  elif defined(__arm)
+#    define __OPEN_NAME  "_open"
+#  else
+#    error "unrecognized architecture for targetting OS X"
+#  endif
+#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
+#  if defined(__i386) || defined (__x86_64)
+#    define __OPEN_NAME  "_open"
+#  elif defined(__arm)
+#    define __OPEN_NAME  "_open"
+#  else
+#    error "unrecognized architecture for targetting iOS"
+#  endif
+#else
+#  error "unrecognized architecture for targetting Darwin"
+#endif
+
+#define O_RDONLY   0x0000    /* open for reading only */
+#define O_WRONLY   0x0001    /* open for writing only */
+#define O_RDWR     0x0002    /* open for reading and writing */
+#define O_ACCMODE  0x0003    /* mask for above modes */
+
+#define O_CREAT    0x0200    /* create if nonexistant */
+
+int open(const char *, int, ...) __asm(__OPEN_NAME);
+
+#endif /* !_SYS_FCNTL_H_ */

Added: compiler-rt/trunk/SDKs/darwin/usr/include/sys/mman.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/SDKs/darwin/usr/include/sys/mman.h?rev=182563&view=auto
==============================================================================
--- compiler-rt/trunk/SDKs/darwin/usr/include/sys/mman.h (added)
+++ compiler-rt/trunk/SDKs/darwin/usr/include/sys/mman.h Thu May 23 02:18:59 2013
@@ -0,0 +1,42 @@
+/* ===-- mman.h - stub SDK header for compiler-rt ---------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===-----------------------------------------------------------------------===
+ *
+ * This is a stub SDK header file. This file is not part of the interface of
+ * this library nor an official version of the appropriate SDK header. It is
+ * intended only to stub the features of this header required by compiler-rt.
+ *
+ * ===-----------------------------------------------------------------------===
+ */
+
+#ifndef __SYS_MMAN_H__
+#define __SYS_MMAN_H__
+
+typedef __SIZE_TYPE__ size_t;
+
+#define PROT_NONE     0x00
+#define PROT_READ     0x01
+#define PROT_WRITE    0x02
+#define PROT_EXEC     0x04
+
+#define MAP_SHARED    0x0001
+#define MAP_PRIVATE   0x0002
+
+#define MAP_FILE      0x0000
+#define MAP_ANON      0x1000
+
+#define MS_ASYNC      0x0001
+#define MS_INVALIDATE 0x0002
+#define MS_SYNC       0x0010
+
+void *mmap(void *addr, size_t len, int prot, int flags, int fd,
+           long long offset);
+int munmap(void *addr, size_t len);
+int msync(void *addr, size_t len, int flags);
+
+#endif /* __SYS_MMAN_H__ */

Added: compiler-rt/trunk/SDKs/linux/usr/include/fcntl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/SDKs/linux/usr/include/fcntl.h?rev=182563&view=auto
==============================================================================
--- compiler-rt/trunk/SDKs/linux/usr/include/fcntl.h (added)
+++ compiler-rt/trunk/SDKs/linux/usr/include/fcntl.h Thu May 23 02:18:59 2013
@@ -0,0 +1,17 @@
+/* ===-- fcntl.h - stub SDK header for compiler-rt --------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===-----------------------------------------------------------------------===
+ *
+ * This is a stub SDK header file. This file is not part of the interface of
+ * this library nor an official version of the appropriate SDK header. It is
+ * intended only to stub the features of this header required by compiler-rt.
+ *
+ * ===-----------------------------------------------------------------------===
+ */
+
+#include <sys/fcntl.h>

Modified: compiler-rt/trunk/SDKs/linux/usr/include/stdio.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/SDKs/linux/usr/include/stdio.h?rev=182563&r1=182562&r2=182563&view=diff
==============================================================================
--- compiler-rt/trunk/SDKs/linux/usr/include/stdio.h (original)
+++ compiler-rt/trunk/SDKs/linux/usr/include/stdio.h Thu May 23 02:18:59 2013
@@ -33,11 +33,11 @@ extern struct _IO_FILE *stderr;
 extern int fclose(FILE *);
 extern int fflush(FILE *);
 extern FILE *fopen(const char * restrict, const char * restrict);
+extern FILE *fdopen(int, const char * restrict);
 extern int fprintf(FILE * restrict, const char * restrict, ...);
 extern size_t fwrite(const void * restrict, size_t, size_t, FILE * restrict);
 extern size_t fread(void * restrict, size_t, size_t, FILE * restrict);
 extern long ftell(FILE *);
 extern int fseek(FILE *, long, int);
-extern void setbuf(FILE * restrict, char * restrict);
 
 #endif /* __STDIO_H__ */

Modified: compiler-rt/trunk/SDKs/linux/usr/include/stdlib.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/SDKs/linux/usr/include/stdlib.h?rev=182563&r1=182562&r2=182563&view=diff
==============================================================================
--- compiler-rt/trunk/SDKs/linux/usr/include/stdlib.h (original)
+++ compiler-rt/trunk/SDKs/linux/usr/include/stdlib.h Thu May 23 02:18:59 2013
@@ -30,5 +30,7 @@ char *getenv(const char *) __attribute__
   __attribute__((__warn_unused_result__));
 void *malloc(size_t) __attribute__((__nothrow__)) __attribute((__malloc__))
      __attribute__((__warn_unused_result__));
+void *realloc(void *, size_t) __attribute__((__nothrow__)) __attribute((__malloc__))
+     __attribute__((__warn_unused_result__));
 
 #endif /* __STDLIB_H__ */

Added: compiler-rt/trunk/SDKs/linux/usr/include/sys/fcntl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/SDKs/linux/usr/include/sys/fcntl.h?rev=182563&view=auto
==============================================================================
--- compiler-rt/trunk/SDKs/linux/usr/include/sys/fcntl.h (added)
+++ compiler-rt/trunk/SDKs/linux/usr/include/sys/fcntl.h Thu May 23 02:18:59 2013
@@ -0,0 +1,29 @@
+/* ===-- fcntl.h - stub SDK header for compiler-rt --------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===-----------------------------------------------------------------------===
+ *
+ * This is a stub SDK header file. This file is not part of the interface of
+ * this library nor an official version of the appropriate SDK header. It is
+ * intended only to stub the features of this header required by compiler-rt.
+ *
+ * ===-----------------------------------------------------------------------===
+ */
+
+#ifndef _SYS_FCNTL_H_
+#define _SYS_FCNTL_H_
+
+#define O_RDONLY   0x0000
+#define O_WRONLY   0x0001
+#define O_RDWR     0x0002
+#define O_ACCMODE  0x0003
+
+#define O_CREAT    0x0200
+
+int open(const char *, int, ...);
+
+#endif /* _SYS_FCNTL_H_ */

Modified: compiler-rt/trunk/SDKs/linux/usr/include/sys/mman.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/SDKs/linux/usr/include/sys/mman.h?rev=182563&r1=182562&r2=182563&view=diff
==============================================================================
--- compiler-rt/trunk/SDKs/linux/usr/include/sys/mman.h (original)
+++ compiler-rt/trunk/SDKs/linux/usr/include/sys/mman.h Thu May 23 02:18:59 2013
@@ -19,10 +19,28 @@
 
 typedef __SIZE_TYPE__ size_t;
 
-#define PROT_READ 0x1
-#define PROT_WRITE 0x2
-#define PROT_EXEC 0x4
+#define PROT_NONE     0x00
+#define PROT_READ     0x01
+#define PROT_WRITE    0x02
+#define PROT_EXEC     0x04
 
+#define MAP_SHARED    0x0001
+#define MAP_PRIVATE   0x0002
+
+#define MAP_FILE      0x0000
+#define MAP_ANON      0x1000
+
+#define MS_ASYNC      0x0001
+#define MS_INVALIDATE 0x0002
+#define MS_SYNC       0x0010
+
+extern void *mmap(void *addr, size_t len, int prot, int flags, int fd,
+                  long long offset)
+  __attribute__((__nothrow__));
+extern int munmap(void *addr, size_t len)
+  __attribute__((__nothrow__));
+extern int msync(void *addr, size_t len, int flags)
+  __attribute__((__nothrow__));
 extern int mprotect (void *__addr, size_t __len, int __prot)
   __attribute__((__nothrow__));
 

Modified: compiler-rt/trunk/lib/profile/GCDAProfiling.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/GCDAProfiling.c?rev=182563&r1=182562&r2=182563&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/GCDAProfiling.c (original)
+++ compiler-rt/trunk/lib/profile/GCDAProfiling.c Thu May 23 02:18:59 2013
@@ -20,10 +20,12 @@
 |*
 \*===----------------------------------------------------------------------===*/
 
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <sys/mman.h>
 #include <sys/types.h>
 #ifdef _WIN32
 #include <direct.h>
@@ -50,11 +52,13 @@ static FILE *output_file = NULL;
 /*
  * Buffer that we write things into.
  */
-#define WRITE_BUFFER_SIZE (1 << 12)
-static char write_buffer[WRITE_BUFFER_SIZE];
-static int64_t cur_file_pos = 0;
-static uint32_t cur_offset = 0;
+#define NEW_WRITE_BUFFER_SIZE (128 * 1024)
+static char *new_write_buffer = NULL;
+static uint64_t cur_buffer_size = 0;
+static uint64_t cur_pos = 0;
+static uint64_t file_size = 0;
 static int new_file = 0;
+static int fd = -1;
 
 /*
  * A list of functions to write out the data.
@@ -82,30 +86,20 @@ struct flush_fn_node {
 static struct flush_fn_node *flush_fn_head = NULL;
 static struct flush_fn_node *flush_fn_tail = NULL;
 
-static void flush_buffer() {
-  /* Flush the buffer to file. */
-  fwrite(write_buffer, cur_offset, 1, output_file);
-
-  if (new_file) {
-    cur_offset = 0;
-    return;
-  }
-
-  /* Read in more of the file. */
-  fread(write_buffer,1, WRITE_BUFFER_SIZE, output_file);
-  fseek(output_file, cur_file_pos, SEEK_SET);
-
-  cur_offset = 0;
+static void resize_write_buffer(uint64_t size) {
+  if (!new_file) return;
+  size += cur_pos;
+  if (size <= cur_buffer_size) return;
+  size = (size - 1) / NEW_WRITE_BUFFER_SIZE + 1;
+  size *= NEW_WRITE_BUFFER_SIZE;
+  new_write_buffer = realloc(new_write_buffer, size);
+  cur_buffer_size = size;
 }
 
 static void write_bytes(const char *s, size_t len) {
-  if (cur_offset + len > WRITE_BUFFER_SIZE)
-    flush_buffer();
-
-  cur_file_pos += len;
-
-  for (; len > 0; --len)
-    write_buffer[cur_offset++] = *s++;
+  resize_write_buffer(len);
+  memcpy(&new_write_buffer[cur_pos], s, len);
+  cur_pos += len;
 }
 
 static void write_32bit_value(uint32_t i) {
@@ -130,30 +124,22 @@ static void write_string(const char *s)
 static uint32_t read_32bit_value() {
   uint32_t val;
 
-  if (cur_offset + 4 > WRITE_BUFFER_SIZE)
-    flush_buffer();
-
   if (new_file)
     return (uint32_t)-1;
 
-  val = *(uint32_t*)&write_buffer[cur_offset];
-  cur_file_pos += 4;
-  cur_offset += 4;
+  val = *(uint32_t*)&new_write_buffer[cur_pos];
+  cur_pos += 4;
   return val;
 }
 
 static uint64_t read_64bit_value() {
   uint64_t val;
 
-  if (cur_offset + 8 > WRITE_BUFFER_SIZE)
-    flush_buffer();
-
   if (new_file)
-    return (uint32_t)-1;
+    return (uint64_t)-1;
 
-  val = *(uint64_t*)&write_buffer[cur_offset];
-  cur_file_pos += 8;
-  cur_offset += 8;
+  val = *(uint64_t*)&new_write_buffer[cur_pos];
+  cur_pos += 8;
   return val;
 }
 
@@ -210,6 +196,21 @@ static void recursive_mkdir(char *filena
   }
 }
 
+static void map_file() {
+  fseek(output_file, 0L, SEEK_END);
+  file_size = ftell(output_file);
+
+  new_write_buffer = mmap(0, file_size, PROT_READ | PROT_WRITE,
+                          MAP_FILE | MAP_SHARED, fd, 0);
+}
+
+static void unmap_file() {
+  msync(new_write_buffer, file_size, MS_SYNC);
+  munmap(new_write_buffer, file_size);
+  new_write_buffer = NULL;
+  file_size = 0;
+}
+
 /*
  * --- LLVM line counter API ---
  */
@@ -220,18 +221,21 @@ static void recursive_mkdir(char *filena
  */
 void llvm_gcda_start_file(const char *orig_filename, const char version[4]) {
   char *filename = mangle_filename(orig_filename);
+  const char *mode = "r+b";
 
   /* Try just opening the file. */
-  output_file = fopen(filename, "r+b");
+  new_file = 0;
+  fd = open(filename, O_RDWR);
 
-  if (!output_file) {
+  if (fd == -1) {
     /* Try opening the file, creating it if necessary. */
     new_file = 1;
-    output_file = fopen(filename, "w+b");
-    if (!output_file) {
+    mode = "w+b";
+    fd = open(filename, O_RDWR | O_CREAT);
+    if (fd == -1) {
       /* Try creating the directories first then opening the file. */
       recursive_mkdir(filename);
-      output_file = fopen(filename, "w+b");
+      fd = open(filename, O_RDWR | O_CREAT);
       if (!output_file) {
         /* Bah! It's hopeless. */
         fprintf(stderr, "profiling:%s: cannot open\n", filename);
@@ -241,14 +245,19 @@ void llvm_gcda_start_file(const char *or
     }
   }
 
-  setbuf(output_file, 0);
+  output_file = fdopen(fd, mode);
 
   /* Initialize the write buffer. */
-  memset(write_buffer, 0, WRITE_BUFFER_SIZE);
-  fread(write_buffer, 1, WRITE_BUFFER_SIZE, output_file);
-  fseek(output_file, 0L, SEEK_SET);
-  cur_file_pos = 0;
-  cur_offset = 0;
+  new_write_buffer = NULL;
+  cur_buffer_size = 0;
+  cur_pos = 0;
+
+  if (new_file) {
+    resize_write_buffer(NEW_WRITE_BUFFER_SIZE);
+    memset(new_write_buffer, 0, NEW_WRITE_BUFFER_SIZE);
+  } else {
+    map_file();
+  }
 
   /* gcda file, version, stamp LLVM. */
   write_bytes("adcg", 4);
@@ -315,12 +324,11 @@ void llvm_gcda_emit_function(uint32_t id
 void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) {
   uint32_t i;
   uint64_t *old_ctrs = NULL;
-  int64_t save_cur_file_pos = cur_file_pos;
   uint32_t val = 0;
+  uint64_t save_cur_pos = cur_pos;
 
   if (!output_file) return;
 
-  flush_buffer();
   val = read_32bit_value();
 
   if (val != (uint32_t)-1) {
@@ -339,15 +347,10 @@ void llvm_gcda_emit_arcs(uint32_t num_co
     old_ctrs = malloc(sizeof(uint64_t) * num_counters);
     for (i = 0; i < num_counters; ++i)
       old_ctrs[i] = read_64bit_value();
-
-    /* Reset the current buffer and file position. */
-    memset(write_buffer, 0, WRITE_BUFFER_SIZE);
-    cur_file_pos = save_cur_file_pos;
-    cur_offset = 0;
-
-    fseek(output_file, cur_file_pos, SEEK_SET);
   }
 
+  cur_pos = save_cur_pos;
+
   /* Counter #1 (arcs) tag */
   write_bytes("\0\0\xa1\1", 4);
   write_32bit_value(num_counters * 2);
@@ -369,9 +372,17 @@ void llvm_gcda_end_file() {
   /* Write out EOF record. */
   if (!output_file) return;
   write_bytes("\0\0\0\0\0\0\0\0", 8);
-  flush_buffer();
+
+  if (new_file) {
+    fwrite(new_write_buffer, cur_pos, 1, output_file);
+    free(new_write_buffer);
+  } else {
+    unmap_file();
+  }
+
   fclose(output_file);
   output_file = NULL;
+  new_write_buffer = NULL;
 
 #ifdef DEBUG_GCDAPROFILING
   fprintf(stderr, "llvmgcda: -----\n");





More information about the llvm-commits mailing list