[compiler-rt] r182563 - Performance improvement.
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Thu May 23 02:17:06 PDT 2013
projects/compiler-rt/lib/profile/GCDAProfiling.c:234
open with O_CREAT in second argument needs 3 arguments
I wonder why bots did not catch this. I guess none of them is building
clang with FORTIFY_SOURCE.
On Thu, May 23, 2013 at 11:18 AM, Bill Wendling <isanbard at gmail.com> wrote:
> 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");
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list