diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2011-04-28 21:35:49 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2011-04-28 21:35:49 +0000 |
commit | 7a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efe (patch) | |
tree | 200b3836943920c5e4d8fd322784e7ce3e3b2e89 /runtime | |
parent | f86500bc4f9b0e7078df9a17b84e95fbf37080a7 (diff) |
Only read *predecessor once so as to fix a theoretical issue where it changes
between two reads (threading).
Fix an off-by-one in the indirect counter table that I meant to revert after an
earlier experiment. Whoops!
Implement GCOV_PREFIX. Doesn't handle GCOV_PREFIX_STRIP yet.
Fix an off-by-one in string emission. Extra whoops!
Tolerate DISubprograms that have null Function*'s attached to them. I don't yet
understand what this means, but it happens when you have a global static with
a non-trivial constructor/destructor.
Fix a crash on switch statements with a single successor (default-only).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130443 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/libprofile/GCDAProfiling.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/runtime/libprofile/GCDAProfiling.c b/runtime/libprofile/GCDAProfiling.c index c8161d44b0..2dcf22d964 100644 --- a/runtime/libprofile/GCDAProfiling.c +++ b/runtime/libprofile/GCDAProfiling.c @@ -46,6 +46,24 @@ static void write_int64(uint64_t i) { write_int32(hi); } +static char *mangle_filename(const char *orig_filename) { + /* TODO: handle GCOV_PREFIX_STRIP */ + const char *prefix; + char *filename = 0; + + prefix = getenv("GCOV_PREFIX"); + + if (!prefix) + return strdup(filename); + + filename = malloc(strlen(prefix) + 1 + strlen(orig_filename) + 1); + strcpy(filename, prefix); + strcat(filename, "/"); + strcat(filename, orig_filename); + + return filename; +} + /* * --- LLVM line counter API --- */ @@ -54,15 +72,19 @@ static void write_int64(uint64_t i) { * profiling enabled will emit to a different file. Only one file may be * started at a time. */ -void llvm_gcda_start_file(const char *filename) { - output_file = fopen(filename, "w+"); +void llvm_gcda_start_file(const char *orig_filename) { + char *filename; + filename = mangle_filename(orig_filename); + output_file = fopen(filename, "wb"); /* gcda file, version 404*, stamp LLVM. */ fwrite("adcg*404MVLL", 12, 1, output_file); #ifdef DEBUG_GCDAPROFILING - printf("llvmgcda: [%s]\n", filename); + printf("llvmgcda: [%s]\n", orig_filename); #endif + + free(filename); } /* Given an array of pointers to counters (counters), increment the n-th one, @@ -71,12 +93,16 @@ void llvm_gcda_start_file(const char *filename) { void llvm_gcda_increment_indirect_counter(uint32_t *predecessor, uint64_t **counters) { uint64_t *counter; - if (*predecessor == 0xffffffff) + uint32_t pred; + + pred = *predecessor; + if (pred == 0xffffffff) return; + counter = counters[pred]; /* Don't crash if the pred# is out of sync. This can happen due to threads, or because of a TODO in GCOVProfiling.cpp buildEdgeLookupTable(). */ - if ((counter = counters[*predecessor])) + if (counter) ++*counter; #ifdef DEBUG_GCDAPROFILING else |