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>
llvm-svn: 182563
The calls to fwrite/fread can be very expensive. GCC avoids this by using a
buffer to read and write from the file, thus limiting the number of fwrite/fread
calls.
<rdar://problem/13466086>
llvm-svn: 181924
The fread / fwrite calls were happening for each timer. However, that could be
pretty expensive for a large number of timers. Instead, read and write the
timers in one call.
This gives ~10% speedup in compilation time.
llvm-svn: 179990
This function replaces the call of `atexit' from being generated in the compile
units. Basically, it registers the "writeout" and "flush" functions (if
present). It will generate calls to the `atexit' function for cleanups and final
writeout functions, but only once. This is better than checking for `main',
because a library may not have a `main' function in it.
<rdar://problem/12439551>
llvm-svn: 177578
It may be prohibitively expensive to write out >1000 files at the same time. So
we would rather emit them serially. These functions allow the GCOV
implementation to register the functions that writeout the GCOV information per
compile unit. At exit, they are written.
<rdar://problem/12439551>
llvm-svn: 177436
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>
llvm-svn: 177337
it. Fortunately, versions of gcov that predate the extra checksum also ignore
any extra data, so this isn't a problem. This matches the API change made in
r176745.
llvm-svn: 176746
didn't delete the original, and now they've diverged. I have no idea what's
going on. Apply my patch in r176173 to this one too, this one looks newer?
llvm-svn: 176236
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>
llvm-svn: 163923
sets of functions/objects into high level groups. Currently we have "builtins"
(the main compiler-rt code), "profile", and "asan".
- Use this to define CommonFunctions and ArchFunctions to only reference the
builtins functions.
llvm-svn: 145674