diff options
Diffstat (limited to 'lib/profile/GCDAProfiling.c')
-rw-r--r-- | lib/profile/GCDAProfiling.c | 91 |
1 files changed, 75 insertions, 16 deletions
diff --git a/lib/profile/GCDAProfiling.c b/lib/profile/GCDAProfiling.c index 8f92a915484b..7c52a1740999 100644 --- a/lib/profile/GCDAProfiling.c +++ b/lib/profile/GCDAProfiling.c @@ -66,6 +66,24 @@ static void write_string(const char *s) { 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,23 @@ static void recursive_mkdir(char *filename) { */ void llvm_gcda_start_file(const char *orig_filename) { char *filename = mangle_filename(orig_filename); - output_file = fopen(filename, "w+b"); + + /* 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 +174,11 @@ void llvm_gcda_start_file(const char *orig_filename) { 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 +201,14 @@ void llvm_gcda_increment_indirect_counter(uint32_t *predecessor, #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 +223,51 @@ void llvm_gcda_emit_function(uint32_t ident, const char *function_name) { 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(); + + 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(); + } + + /* 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 +279,6 @@ void llvm_gcda_end_file() { output_file = NULL; #ifdef DEBUG_GCDAPROFILING - printf("llvmgcda: -----\n"); + fprintf(stderr, "llvmgcda: -----\n"); #endif } |