llvm.org GIT mirror llvm / 218042a
Remove GCDAProfiling.c. This copy is old, the copy in compiler-rt is newer and is the one that should be used. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176608 91177308-0d34-0410-b5e6-96231b3b80d8 Nick Lewycky 7 years ago
4 changed file(s) with 0 addition(s) and 225 deletion(s). Raw diff Collapse all Expand all
0 set(SOURCES
11 BasicBlockTracing.c
22 CommonProfiling.c
3 GCDAProfiling.c
43 PathProfiling.c
54 EdgeProfiling.c
65 OptimalEdgeProfiling.c
+0
-210
runtime/libprofile/GCDAProfiling.c less more
None /*===- GCDAProfiling.c - Support library for GCDA file emission -----------===*\
1 |*
2 |* The LLVM Compiler Infrastructure
3 |*
4 |* This file is distributed under the University of Illinois Open Source
5 |* License. See LICENSE.TXT for details.
6 |*
7 |*===----------------------------------------------------------------------===*|
8 |*
9 |* This file implements the call back routines for the gcov profiling
10 |* instrumentation pass. Link against this library when running code through
11 |* the -insert-gcov-profiling LLVM pass.
12 |*
13 |* We emit files in a corrupt version of GCOV's "gcda" file format. These files
14 |* are only close enough that LCOV will happily parse them. Anything that lcov
15 |* ignores is missing.
16 |*
17 |* TODO: gcov is multi-process safe by having each exit open the existing file
18 |* and append to it. We'd like to achieve that and be thread-safe too.
19 |*
20 \*===----------------------------------------------------------------------===*/
21
22 #include "llvm/Support/DataTypes.h"
23 #include
24 #include
25 #include
26 #include
27 #include
28 #ifdef _WIN32
29 #include
30 #endif
31
32 /* #define DEBUG_GCDAPROFILING */
33
34 /*
35 * --- GCOV file format I/O primitives ---
36 */
37
38 static FILE *output_file = NULL;
39
40 static void write_int32(uint32_t i) {
41 fwrite(&i, 4, 1, output_file);
42 }
43
44 static void write_int64(uint64_t i) {
45 uint32_t lo = i >> 0;
46 uint32_t hi = i >> 32;
47 write_int32(lo);
48 write_int32(hi);
49 }
50
51 static uint32_t length_of_string(const char *s) {
52 return (strlen(s) / 4) + 1;
53 }
54
55 static void write_string(const char *s) {
56 uint32_t len = length_of_string(s);
57 write_int32(len);
58 fwrite(s, strlen(s), 1, output_file);
59 fwrite("\0\0\0\0", 4 - (strlen(s) % 4), 1, output_file);
60 }
61
62 static char *mangle_filename(const char *orig_filename) {
63 /* TODO: handle GCOV_PREFIX_STRIP */
64 const char *prefix;
65 char *filename = 0;
66
67 prefix = getenv("GCOV_PREFIX");
68
69 if (!prefix)
70 return strdup(orig_filename);
71
72 filename = malloc(strlen(prefix) + 1 + strlen(orig_filename) + 1);
73 strcpy(filename, prefix);
74 strcat(filename, "/");
75 strcat(filename, orig_filename);
76 return filename;
77 }
78
79 static void recursive_mkdir(const char *filename) {
80 char *pathname;
81 int i, e;
82
83 for (i = 1, e = strlen(filename); i != e; ++i) {
84 if (filename[i] != '/') continue;
85 pathname = malloc(i + 1);
86 strncpy(pathname, filename, i);
87 pathname[i] = '\0';
88 #ifdef _WIN32
89 _mkdir(pathname);
90 #else
91 mkdir(pathname, 0750); /* some of these will fail, ignore it. */
92 #endif
93 free(pathname);
94 }
95 }
96
97 /*
98 * --- LLVM line counter API ---
99 */
100
101 /* A file in this case is a translation unit. Each .o file built with line
102 * profiling enabled will emit to a different file. Only one file may be
103 * started at a time.
104 */
105 void llvm_gcda_start_file(const char *orig_filename) {
106 char *filename;
107 filename = mangle_filename(orig_filename);
108 recursive_mkdir(filename);
109 output_file = fopen(filename, "w+b");
110
111 if (!output_file) {
112 const char *cptr = strrchr(orig_filename, '/');
113 output_file = fopen(cptr ? cptr + 1 : orig_filename, "w+b");
114
115 if (!output_file) {
116 fprintf(stderr, "LLVM profiling runtime: cannot open '%s': ",
117 cptr ? cptr + 1 : orig_filename);
118 perror("");
119 free(filename);
120 return;
121 }
122 }
123
124 /* gcda file, version 404*, stamp LLVM. */
125 #ifdef __APPLE__
126 fwrite("adcg*204MVLL", 12, 1, output_file);
127 #else
128 fwrite("adcg*404MVLL", 12, 1, output_file);
129 #endif
130
131 #ifdef DEBUG_GCDAPROFILING
132 printf("llvmgcda: [%s]\n", orig_filename);
133 #endif
134
135 free(filename);
136 }
137
138 /* Given an array of pointers to counters (counters), increment the n-th one,
139 * where we're also given a pointer to n (predecessor).
140 */
141 void llvm_gcda_increment_indirect_counter(uint32_t *predecessor,
142 uint64_t **counters) {
143 uint64_t *counter;
144 uint32_t pred;
145
146 pred = *predecessor;
147 if (pred == 0xffffffff)
148 return;
149 counter = counters[pred];
150
151 /* Don't crash if the pred# is out of sync. This can happen due to threads,
152 or because of a TODO in GCOVProfiling.cpp buildEdgeLookupTable(). */
153 if (counter)
154 ++*counter;
155 #ifdef DEBUG_GCDAPROFILING
156 else
157 printf("llvmgcda: increment_indirect_counter counters=%x, pred=%u\n",
158 state_table_row, *predecessor);
159 #endif
160 }
161
162 void llvm_gcda_emit_function(uint32_t ident, const char *function_name) {
163 uint32_t len = 3;
164 #ifdef DEBUG_GCDAPROFILING
165 printf("llvmgcda: function id=%x name=%s\n", ident,
166 function_name ? function_name : "NULL");
167 #endif
168 if (!output_file) return;
169
170 /* function tag */
171 fwrite("\0\0\0\1", 4, 1, output_file);
172 if (function_name)
173 len += 1 + length_of_string(function_name);
174 write_int32(len);
175 write_int32(ident);
176 write_int32(0);
177 write_int32(0);
178 if (function_name)
179 write_string(function_name);
180 }
181
182 void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) {
183 uint32_t i;
184
185 /* Counter #1 (arcs) tag */
186 if (!output_file) return;
187 fwrite("\0\0\xa1\1", 4, 1, output_file);
188 write_int32(num_counters * 2);
189 for (i = 0; i < num_counters; ++i)
190 write_int64(counters[i]);
191
192 #ifdef DEBUG_GCDAPROFILING
193 printf("llvmgcda: %u arcs\n", num_counters);
194 for (i = 0; i < num_counters; ++i)
195 printf("llvmgcda: %llu\n", (unsigned long long)counters[i]);
196 #endif
197 }
198
199 void llvm_gcda_end_file() {
200 /* Write out EOF record. */
201 if (!output_file) return;
202 fwrite("\0\0\0\0\0\0\0\0", 8, 1, output_file);
203 fclose(output_file);
204 output_file = NULL;
205
206 #ifdef DEBUG_GCDAPROFILING
207 printf("llvmgcda: -----\n");
208 #endif
209 }
1515 LIBRARYNAME = profile_rt
1616 LINK_LIBS_IN_SHARED = 1
1717 SHARED_LIBRARY = 1
18 EXTRA_DIST = libprofile.exports
19 EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/libprofile.exports
2018
2119 # Build and install this archive.
2220 BUILD_ARCHIVE = 1
+0
-12
runtime/libprofile/libprofile.exports less more
None llvm_start_edge_profiling
1 llvm_start_opt_edge_profiling
2 llvm_start_path_profiling
3 llvm_start_basic_block_tracing
4 llvm_trace_basic_block
5 llvm_increment_path_count
6 llvm_decrement_path_count
7 llvm_gcda_start_file
8 llvm_gcda_increment_indirect_counter
9 llvm_gcda_emit_function
10 llvm_gcda_emit_arcs
11 llvm_gcda_end_file