comparison gcc/coverage.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Read and write coverage files, and associated functionality. 1 /* Read and write coverage files, and associated functionality.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2 Copyright (C) 1990-2017 Free Software Foundation, Inc.
3 2000, 2001, 2003, 2004, 2005, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by James E. Wilson, UC Berkeley/Cygnus Support; 3 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
6 based on some ideas from Dain Samples of UC Berkeley. 4 based on some ideas from Dain Samples of UC Berkeley.
7 Further mangling by Bob Manson, Cygnus Support. 5 Further mangling by Bob Manson, Cygnus Support.
8 Further mangled by Nathan Sidwell, CodeSourcery 6 Further mangled by Nathan Sidwell, CodeSourcery
9 7
27 #define GCOV_LINKAGE 25 #define GCOV_LINKAGE
28 26
29 #include "config.h" 27 #include "config.h"
30 #include "system.h" 28 #include "system.h"
31 #include "coretypes.h" 29 #include "coretypes.h"
32 #include "tm.h" 30 #include "backend.h"
31 #include "target.h"
33 #include "rtl.h" 32 #include "rtl.h"
34 #include "tree.h" 33 #include "tree.h"
35 #include "flags.h" 34 #include "tree-pass.h"
35 #include "memmodel.h"
36 #include "tm_p.h"
37 #include "stringpool.h"
38 #include "cgraph.h"
39 #include "coverage.h"
40 #include "diagnostic-core.h"
41 #include "fold-const.h"
42 #include "stor-layout.h"
36 #include "output.h" 43 #include "output.h"
37 #include "regs.h"
38 #include "expr.h"
39 #include "function.h"
40 #include "basic-block.h"
41 #include "toplev.h" 44 #include "toplev.h"
42 #include "tm_p.h"
43 #include "ggc.h"
44 #include "coverage.h"
45 #include "langhooks.h" 45 #include "langhooks.h"
46 #include "hashtab.h"
47 #include "tree-iterator.h" 46 #include "tree-iterator.h"
48 #include "cgraph.h" 47 #include "context.h"
49 #include "tree-pass.h" 48 #include "pass_manager.h"
50 #include "diagnostic-core.h"
51 #include "intl.h" 49 #include "intl.h"
50 #include "params.h"
51 #include "auto-profile.h"
52 52
53 #include "gcov-io.c" 53 #include "gcov-io.c"
54 54
55 struct function_list 55 struct GTY((chain_next ("%h.next"))) coverage_data
56 { 56 {
57 struct function_list *next; /* next function */ 57 struct coverage_data *next; /* next function */
58 unsigned ident; /* function ident */ 58 unsigned ident; /* function ident */
59 unsigned checksum; /* function checksum */ 59 unsigned lineno_checksum; /* function lineno checksum */
60 unsigned n_ctrs[GCOV_COUNTERS];/* number of counters. */ 60 unsigned cfg_checksum; /* function cfg checksum */
61 tree fn_decl; /* the function decl */
62 tree ctr_vars[GCOV_COUNTERS]; /* counter variables. */
61 }; 63 };
62 64
63 /* Counts information for a function. */ 65 /* Counts information for a function. */
64 typedef struct counts_entry 66 struct counts_entry : pointer_hash <counts_entry>
65 { 67 {
66 /* We hash by */ 68 /* We hash by */
67 unsigned ident; 69 unsigned ident;
68 unsigned ctr; 70 unsigned ctr;
69 71
70 /* Store */ 72 /* Store */
71 unsigned checksum; 73 unsigned lineno_checksum;
74 unsigned cfg_checksum;
72 gcov_type *counts; 75 gcov_type *counts;
73 struct gcov_ctr_summary summary; 76 struct gcov_ctr_summary summary;
74 77
75 /* Workspace */ 78 /* hash_table support. */
76 struct counts_entry *chain; 79 static inline hashval_t hash (const counts_entry *);
77 80 static int equal (const counts_entry *, const counts_entry *);
78 } counts_entry_t; 81 static void remove (counts_entry *);
79 82 };
80 static struct function_list *functions_head = 0; 83
81 static struct function_list **functions_tail = &functions_head; 84 static GTY(()) struct coverage_data *functions_head = 0;
85 static struct coverage_data **functions_tail = &functions_head;
82 static unsigned no_coverage = 0; 86 static unsigned no_coverage = 0;
83 87
84 /* Cumulative counter information for whole program. */ 88 /* Cumulative counter information for whole program. */
85 static unsigned prg_ctr_mask; /* Mask of counter types generated. */ 89 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
86 static unsigned prg_n_ctrs[GCOV_COUNTERS]; /* Total counters allocated. */
87 90
88 /* Counter information for current function. */ 91 /* Counter information for current function. */
89 static unsigned fn_ctr_mask; /* Mask of counters used. */ 92 static unsigned fn_ctr_mask; /* Mask of counters used. */
93 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */
90 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */ 94 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
91 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */ 95 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
92 96
93 /* Name of the output file for coverage output file. */ 97 /* Coverage info VAR_DECL and function info type nodes. */
98 static GTY(()) tree gcov_info_var;
99 static GTY(()) tree gcov_fn_info_type;
100 static GTY(()) tree gcov_fn_info_ptr_type;
101
102 /* Name of the notes (gcno) output file. The "bbg" prefix is for
103 historical reasons, when the notes file contained only the
104 basic block graph notes.
105 If this is NULL we're not writing to the notes file. */
94 static char *bbg_file_name; 106 static char *bbg_file_name;
95 static unsigned bbg_file_opened; 107
96 static int bbg_function_announced; 108 /* File stamp for notes file. */
97 109 static unsigned bbg_file_stamp;
98 /* Name of the count data file. */ 110
111 /* Name of the count data (gcda) file. */
99 static char *da_file_name; 112 static char *da_file_name;
100 113
101 /* Hash table of count data. */
102 static htab_t counts_hash = NULL;
103
104 /* Trees representing the counter table arrays. */
105 static GTY(()) tree tree_ctr_tables[GCOV_COUNTERS];
106
107 /* The names of merge functions for counters. */ 114 /* The names of merge functions for counters. */
108 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS; 115 #define STR(str) #str
109 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES; 116 #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) STR(__gcov_merge ## FN_TYPE),
117 static const char *const ctr_merge_functions[GCOV_COUNTERS] = {
118 #include "gcov-counter.def"
119 };
120 #undef DEF_GCOV_COUNTER
121 #undef STR
122
123 #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) NAME,
124 static const char *const ctr_names[GCOV_COUNTERS] = {
125 #include "gcov-counter.def"
126 };
127 #undef DEF_GCOV_COUNTER
110 128
111 /* Forward declarations. */ 129 /* Forward declarations. */
112 static hashval_t htab_counts_entry_hash (const void *);
113 static int htab_counts_entry_eq (const void *, const void *);
114 static void htab_counts_entry_del (void *);
115 static void read_counts_file (void); 130 static void read_counts_file (void);
116 static unsigned compute_checksum (void); 131 static tree build_var (tree, tree, int);
117 static unsigned coverage_checksum_string (unsigned, const char *); 132 static void build_fn_info_type (tree, unsigned, tree);
118 static tree build_fn_info_type (unsigned); 133 static void build_info_type (tree, tree);
119 static tree build_fn_info_value (const struct function_list *, tree); 134 static tree build_fn_info (const struct coverage_data *, tree, tree);
120 static tree build_ctr_info_type (void); 135 static tree build_info (tree, tree);
121 static tree build_ctr_info_value (unsigned, tree); 136 static bool coverage_obj_init (void);
122 static tree build_gcov_info (void); 137 static vec<constructor_elt, va_gc> *coverage_obj_fn
123 static void create_coverage (void); 138 (vec<constructor_elt, va_gc> *, tree, struct coverage_data const *);
139 static void coverage_obj_finish (vec<constructor_elt, va_gc> *);
124 140
125 /* Return the type node for gcov_type. */ 141 /* Return the type node for gcov_type. */
126 142
127 tree 143 tree
128 get_gcov_type (void) 144 get_gcov_type (void)
129 { 145 {
130 return lang_hooks.types.type_for_size (GCOV_TYPE_SIZE, false); 146 scalar_int_mode mode
147 = smallest_int_mode_for_size (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32);
148 return lang_hooks.types.type_for_mode (mode, false);
131 } 149 }
132 150
133 /* Return the type node for gcov_unsigned_t. */ 151 /* Return the type node for gcov_unsigned_t. */
134 152
135 static tree 153 static tree
136 get_gcov_unsigned_t (void) 154 get_gcov_unsigned_t (void)
137 { 155 {
138 return lang_hooks.types.type_for_size (32, true); 156 scalar_int_mode mode = smallest_int_mode_for_size (32);
157 return lang_hooks.types.type_for_mode (mode, true);
139 } 158 }
140 159
141 static hashval_t 160 inline hashval_t
142 htab_counts_entry_hash (const void *of) 161 counts_entry::hash (const counts_entry *entry)
143 { 162 {
144 const counts_entry_t *const entry = (const counts_entry_t *) of;
145
146 return entry->ident * GCOV_COUNTERS + entry->ctr; 163 return entry->ident * GCOV_COUNTERS + entry->ctr;
147 } 164 }
148 165
149 static int 166 inline int
150 htab_counts_entry_eq (const void *of1, const void *of2) 167 counts_entry::equal (const counts_entry *entry1, const counts_entry *entry2)
151 { 168 {
152 const counts_entry_t *const entry1 = (const counts_entry_t *) of1;
153 const counts_entry_t *const entry2 = (const counts_entry_t *) of2;
154
155 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr; 169 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
156 } 170 }
157 171
158 static void 172 inline void
159 htab_counts_entry_del (void *of) 173 counts_entry::remove (counts_entry *entry)
160 { 174 {
161 counts_entry_t *const entry = (counts_entry_t *) of;
162
163 free (entry->counts); 175 free (entry->counts);
164 free (entry); 176 free (entry);
165 } 177 }
166 178
179 /* Hash table of count data. */
180 static hash_table<counts_entry> *counts_hash;
181
167 /* Read in the counts file, if available. */ 182 /* Read in the counts file, if available. */
168 183
169 static void 184 static void
170 read_counts_file (void) 185 read_counts_file (void)
171 { 186 {
172 gcov_unsigned_t fn_ident = 0; 187 gcov_unsigned_t fn_ident = 0;
173 gcov_unsigned_t checksum = -1; 188 struct gcov_summary summary;
174 counts_entry_t *summaried = NULL; 189 unsigned new_summary = 1;
175 unsigned seen_summary = 0;
176 gcov_unsigned_t tag; 190 gcov_unsigned_t tag;
177 int is_error = 0; 191 int is_error = 0;
192 unsigned lineno_checksum = 0;
193 unsigned cfg_checksum = 0;
178 194
179 if (!gcov_open (da_file_name, 1)) 195 if (!gcov_open (da_file_name, 1))
180 return; 196 return;
181 197
182 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC)) 198 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
196 da_file_name, 4, v, 4, e); 212 da_file_name, 4, v, 4, e);
197 gcov_close (); 213 gcov_close ();
198 return; 214 return;
199 } 215 }
200 216
201 /* Read and discard the stamp. */ 217 /* Read the stamp, used for creating a generation count. */
202 gcov_read_unsigned (); 218 tag = gcov_read_unsigned ();
203 219 bbg_file_stamp = crc32_unsigned (bbg_file_stamp, tag);
204 counts_hash = htab_create (10, 220
205 htab_counts_entry_hash, htab_counts_entry_eq, 221 counts_hash = new hash_table<counts_entry> (10);
206 htab_counts_entry_del);
207 while ((tag = gcov_read_unsigned ())) 222 while ((tag = gcov_read_unsigned ()))
208 { 223 {
209 gcov_unsigned_t length; 224 gcov_unsigned_t length;
210 gcov_position_t offset; 225 gcov_position_t offset;
211 226
212 length = gcov_read_unsigned (); 227 length = gcov_read_unsigned ();
213 offset = gcov_position (); 228 offset = gcov_position ();
214 if (tag == GCOV_TAG_FUNCTION) 229 if (tag == GCOV_TAG_FUNCTION)
215 { 230 {
216 fn_ident = gcov_read_unsigned (); 231 if (length)
217 checksum = gcov_read_unsigned ();
218 if (seen_summary)
219 { 232 {
220 /* We have already seen a summary, this means that this 233 fn_ident = gcov_read_unsigned ();
221 new function begins a new set of program runs. We 234 lineno_checksum = gcov_read_unsigned ();
222 must unlink the summaried chain. */ 235 cfg_checksum = gcov_read_unsigned ();
223 counts_entry_t *entry, *chain;
224
225 for (entry = summaried; entry; entry = chain)
226 {
227 chain = entry->chain;
228 entry->chain = NULL;
229 }
230 summaried = NULL;
231 seen_summary = 0;
232 } 236 }
237 else
238 fn_ident = lineno_checksum = cfg_checksum = 0;
239 new_summary = 1;
233 } 240 }
234 else if (tag == GCOV_TAG_PROGRAM_SUMMARY) 241 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
235 { 242 {
236 counts_entry_t *entry; 243 struct gcov_summary sum;
237 struct gcov_summary summary; 244 unsigned ix;
238 245
239 gcov_read_summary (&summary); 246 if (new_summary)
240 seen_summary = 1; 247 memset (&summary, 0, sizeof (summary));
241 for (entry = summaried; entry; entry = entry->chain) 248
249 gcov_read_summary (&sum);
250 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
242 { 251 {
243 struct gcov_ctr_summary *csum = &summary.ctrs[entry->ctr]; 252 summary.ctrs[ix].runs += sum.ctrs[ix].runs;
244 253 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all;
245 entry->summary.runs += csum->runs; 254 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max)
246 entry->summary.sum_all += csum->sum_all; 255 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max;
247 if (entry->summary.run_max < csum->run_max) 256 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max;
248 entry->summary.run_max = csum->run_max;
249 entry->summary.sum_max += csum->sum_max;
250 } 257 }
258 if (new_summary)
259 memcpy (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
260 sum.ctrs[GCOV_COUNTER_ARCS].histogram,
261 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
262 else
263 gcov_histogram_merge (summary.ctrs[GCOV_COUNTER_ARCS].histogram,
264 sum.ctrs[GCOV_COUNTER_ARCS].histogram);
265 new_summary = 0;
251 } 266 }
252 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident) 267 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
253 { 268 {
254 counts_entry_t **slot, *entry, elt; 269 counts_entry **slot, *entry, elt;
255 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length); 270 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
256 unsigned ix; 271 unsigned ix;
257 272
258 elt.ident = fn_ident; 273 elt.ident = fn_ident;
259 elt.ctr = GCOV_COUNTER_FOR_TAG (tag); 274 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
260 275
261 slot = (counts_entry_t **) htab_find_slot 276 slot = counts_hash->find_slot (&elt, INSERT);
262 (counts_hash, &elt, INSERT);
263 entry = *slot; 277 entry = *slot;
264 if (!entry) 278 if (!entry)
265 { 279 {
266 *slot = entry = XCNEW (counts_entry_t); 280 *slot = entry = XCNEW (counts_entry);
267 entry->ident = elt.ident; 281 entry->ident = fn_ident;
268 entry->ctr = elt.ctr; 282 entry->ctr = elt.ctr;
269 entry->checksum = checksum; 283 entry->lineno_checksum = lineno_checksum;
270 entry->summary.num = n_counts; 284 entry->cfg_checksum = cfg_checksum;
285 if (elt.ctr < GCOV_COUNTERS_SUMMABLE)
286 entry->summary = summary.ctrs[elt.ctr];
287 entry->summary.num = n_counts;
271 entry->counts = XCNEWVEC (gcov_type, n_counts); 288 entry->counts = XCNEWVEC (gcov_type, n_counts);
272 } 289 }
273 else if (entry->checksum != checksum) 290 else if (entry->lineno_checksum != lineno_checksum
291 || entry->cfg_checksum != cfg_checksum)
274 { 292 {
275 error ("coverage mismatch for function %u while reading execution counters", 293 error ("Profile data for function %u is corrupted", fn_ident);
276 fn_ident); 294 error ("checksum is (%x,%x) instead of (%x,%x)",
277 error ("checksum is %x instead of %x", entry->checksum, checksum); 295 entry->lineno_checksum, entry->cfg_checksum,
278 htab_delete (counts_hash); 296 lineno_checksum, cfg_checksum);
297 delete counts_hash;
298 counts_hash = NULL;
279 break; 299 break;
280 } 300 }
281 else if (entry->summary.num != n_counts) 301 else if (entry->summary.num != n_counts)
282 { 302 {
283 error ("coverage mismatch for function %u while reading execution counters", 303 error ("Profile data for function %u is corrupted", fn_ident);
284 fn_ident);
285 error ("number of counters is %d instead of %d", entry->summary.num, n_counts); 304 error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
286 htab_delete (counts_hash); 305 delete counts_hash;
306 counts_hash = NULL;
287 break; 307 break;
288 } 308 }
289 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE) 309 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
290 { 310 {
291 error ("cannot merge separate %s counters for function %u", 311 error ("cannot merge separate %s counters for function %u",
292 ctr_names[elt.ctr], fn_ident); 312 ctr_names[elt.ctr], fn_ident);
293 goto skip_merge; 313 goto skip_merge;
294 } 314 }
295 315 else
296 if (elt.ctr < GCOV_COUNTERS_SUMMABLE
297 /* This should always be true for a just allocated entry,
298 and always false for an existing one. Check this way, in
299 case the gcov file is corrupt. */
300 && (!entry->chain || summaried != entry))
301 { 316 {
302 entry->chain = summaried; 317 entry->summary.runs += summary.ctrs[elt.ctr].runs;
303 summaried = entry; 318 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all;
319 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max)
320 entry->summary.run_max = summary.ctrs[elt.ctr].run_max;
321 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max;
304 } 322 }
305 for (ix = 0; ix != n_counts; ix++) 323 for (ix = 0; ix != n_counts; ix++)
306 entry->counts[ix] += gcov_read_counter (); 324 entry->counts[ix] += gcov_read_counter ();
307 skip_merge:; 325 skip_merge:;
308 } 326 }
309 gcov_sync (offset, length); 327 gcov_sync (offset, length);
310 if ((is_error = gcov_is_error ())) 328 if ((is_error = gcov_is_error ()))
311 { 329 {
312 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted", 330 error (is_error < 0
331 ? G_("%qs has overflowed")
332 : G_("%qs is corrupted"),
313 da_file_name); 333 da_file_name);
314 htab_delete (counts_hash); 334 delete counts_hash;
335 counts_hash = NULL;
315 break; 336 break;
316 } 337 }
317 } 338 }
318 339
319 gcov_close (); 340 gcov_close ();
321 342
322 /* Returns the counters for a particular tag. */ 343 /* Returns the counters for a particular tag. */
323 344
324 gcov_type * 345 gcov_type *
325 get_coverage_counts (unsigned counter, unsigned expected, 346 get_coverage_counts (unsigned counter, unsigned expected,
347 unsigned cfg_checksum, unsigned lineno_checksum,
326 const struct gcov_ctr_summary **summary) 348 const struct gcov_ctr_summary **summary)
327 { 349 {
328 counts_entry_t *entry, elt; 350 counts_entry *entry, elt;
329 gcov_unsigned_t checksum = -1;
330 351
331 /* No hash table, no counts. */ 352 /* No hash table, no counts. */
332 if (!counts_hash) 353 if (!counts_hash)
333 { 354 {
334 static int warned = 0; 355 static int warned = 0;
335 356
336 if (!warned++) 357 if (!warned++ && dump_enabled_p ())
337 inform (input_location, (flag_guess_branch_prob 358 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
338 ? "file %s not found, execution counts estimated" 359 (flag_guess_branch_prob
339 : "file %s not found, execution counts assumed to be zero"), 360 ? "file %s not found, execution counts estimated\n"
340 da_file_name); 361 : "file %s not found, execution counts assumed to "
362 "be zero\n"),
363 da_file_name);
341 return NULL; 364 return NULL;
342 } 365 }
343 366 if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
344 elt.ident = current_function_funcdef_no + 1; 367 elt.ident = current_function_funcdef_no + 1;
368 else
369 {
370 gcc_assert (coverage_node_map_initialized_p ());
371 elt.ident = cgraph_node::get (cfun->decl)->profile_id;
372 }
345 elt.ctr = counter; 373 elt.ctr = counter;
346 entry = (counts_entry_t *) htab_find (counts_hash, &elt); 374 entry = counts_hash->find (&elt);
347 if (!entry) 375 if (!entry || !entry->summary.num)
348 { 376 /* The function was not emitted, or is weak and not chosen in the
349 warning (0, "no coverage for function %qE found", 377 final executable. Silently fail, because there's nothing we
350 DECL_ASSEMBLER_NAME (current_function_decl)); 378 can do about it. */
351 return NULL; 379 return NULL;
352 } 380
353 381 if (entry->cfg_checksum != cfg_checksum
354 checksum = compute_checksum ();
355 if (entry->checksum != checksum
356 || entry->summary.num != expected) 382 || entry->summary.num != expected)
357 { 383 {
358 static int warned = 0; 384 static int warned = 0;
359 bool warning_printed = false; 385 bool warning_printed = false;
360 tree id = DECL_ASSEMBLER_NAME (current_function_decl); 386 tree id = DECL_ASSEMBLER_NAME (current_function_decl);
361 387
362 warning_printed = 388 warning_printed =
363 warning_at (input_location, OPT_Wcoverage_mismatch, 389 warning_at (input_location, OPT_Wcoverage_mismatch,
364 "coverage mismatch for function " 390 "the control flow of function %qE does not match "
365 "%qE while reading counter %qs", id, ctr_names[counter]); 391 "its profile data (counter %qs)", id, ctr_names[counter]);
366 if (warning_printed) 392 if (warning_printed && dump_enabled_p ())
367 { 393 {
368 if (entry->checksum != checksum) 394 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
369 inform (input_location, "checksum is %x instead of %x", 395 "use -Wno-error=coverage-mismatch to tolerate "
370 entry->checksum, checksum); 396 "the mismatch but performance may drop if the "
371 else 397 "function is hot\n");
372 inform (input_location, "number of counters is %d instead of %d",
373 entry->summary.num, expected);
374 398
375 if (!seen_error () 399 if (!seen_error ()
376 && !warned++) 400 && !warned++)
377 { 401 {
378 inform (input_location, "coverage mismatch ignored"); 402 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
379 inform (input_location, flag_guess_branch_prob 403 "coverage mismatch ignored\n");
380 ? G_("execution counts estimated") 404 dump_printf (MSG_OPTIMIZED_LOCATIONS,
381 : G_("execution counts assumed to be zero")); 405 flag_guess_branch_prob
406 ? G_("execution counts estimated\n")
407 : G_("execution counts assumed to be zero\n"));
382 if (!flag_guess_branch_prob) 408 if (!flag_guess_branch_prob)
383 inform (input_location, 409 dump_printf (MSG_OPTIMIZED_LOCATIONS,
384 "this can result in poorly optimized code"); 410 "this can result in poorly optimized code\n");
385 } 411 }
386 } 412 }
387 413
388 return NULL; 414 return NULL;
389 } 415 }
416 else if (entry->lineno_checksum != lineno_checksum)
417 {
418 warning (OPT_Wcoverage_mismatch,
419 "source locations for function %qE have changed,"
420 " the profile data may be out of date",
421 DECL_ASSEMBLER_NAME (current_function_decl));
422 }
390 423
391 if (summary) 424 if (summary)
392 *summary = &entry->summary; 425 *summary = &entry->summary;
393 426
394 return entry->counts; 427 return entry->counts;
404 return 0; 437 return 0;
405 438
406 if (!num) 439 if (!num)
407 return 1; 440 return 1;
408 441
409 if (!tree_ctr_tables[counter]) 442 if (!fn_v_ctrs[counter])
410 { 443 {
411 /* Generate and save a copy of this so it can be shared. Leave 444 tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
412 the index type unspecified for now; it will be set after all 445
413 functions have been compiled. */ 446 fn_v_ctrs[counter]
414 char buf[20]; 447 = build_var (current_function_decl, array_type, counter);
415 tree gcov_type_node = get_gcov_type (); 448 }
416 tree gcov_type_array_type 449
417 = build_array_type (gcov_type_node, NULL_TREE);
418 tree_ctr_tables[counter]
419 = build_decl (BUILTINS_LOCATION,
420 VAR_DECL, NULL_TREE, gcov_type_array_type);
421 TREE_STATIC (tree_ctr_tables[counter]) = 1;
422 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
423 DECL_NAME (tree_ctr_tables[counter]) = get_identifier (buf);
424 DECL_ALIGN (tree_ctr_tables[counter]) = TYPE_ALIGN (gcov_type_node);
425
426 if (dump_file)
427 fprintf (dump_file, "Using data file %s\n", da_file_name);
428 }
429 fn_b_ctrs[counter] = fn_n_ctrs[counter]; 450 fn_b_ctrs[counter] = fn_n_ctrs[counter];
430 fn_n_ctrs[counter] += num; 451 fn_n_ctrs[counter] += num;
452
431 fn_ctr_mask |= 1 << counter; 453 fn_ctr_mask |= 1 << counter;
432 return 1; 454 return 1;
433 } 455 }
434 456
435 /* Generate a tree to access COUNTER NO. */ 457 /* Generate a tree to access COUNTER NO. */
438 tree_coverage_counter_ref (unsigned counter, unsigned no) 460 tree_coverage_counter_ref (unsigned counter, unsigned no)
439 { 461 {
440 tree gcov_type_node = get_gcov_type (); 462 tree gcov_type_node = get_gcov_type ();
441 463
442 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]); 464 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
443 no += prg_n_ctrs[counter] + fn_b_ctrs[counter]; 465
444 466 no += fn_b_ctrs[counter];
467
445 /* "no" here is an array index, scaled to bytes later. */ 468 /* "no" here is an array index, scaled to bytes later. */
446 return build4 (ARRAY_REF, gcov_type_node, tree_ctr_tables[counter], 469 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
447 build_int_cst (NULL_TREE, no), NULL, NULL); 470 build_int_cst (integer_type_node, no), NULL, NULL);
448 } 471 }
449 472
450 /* Generate a tree to access the address of COUNTER NO. */ 473 /* Generate a tree to access the address of COUNTER NO. */
451 474
452 tree 475 tree
453 tree_coverage_counter_addr (unsigned counter, unsigned no) 476 tree_coverage_counter_addr (unsigned counter, unsigned no)
454 { 477 {
455 tree gcov_type_node = get_gcov_type (); 478 tree gcov_type_node = get_gcov_type ();
456 479
457 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]); 480 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
458 no += prg_n_ctrs[counter] + fn_b_ctrs[counter]; 481 no += fn_b_ctrs[counter];
459
460 TREE_ADDRESSABLE (tree_ctr_tables[counter]) = 1;
461 482
462 /* "no" here is an array index, scaled to bytes later. */ 483 /* "no" here is an array index, scaled to bytes later. */
463 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node, 484 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
464 tree_ctr_tables[counter], 485 fn_v_ctrs[counter],
465 build_int_cst (NULL_TREE, no), 486 build_int_cst (integer_type_node, no),
466 NULL, NULL)); 487 NULL, NULL));
467 } 488 }
468 489
490
469 /* Generate a checksum for a string. CHKSUM is the current 491 /* Generate a checksum for a string. CHKSUM is the current
470 checksum. */ 492 checksum. */
471 493
472 static unsigned 494 static unsigned
473 coverage_checksum_string (unsigned chksum, const char *string) 495 coverage_checksum_string (unsigned chksum, const char *string)
519 break; 541 break;
520 } 542 }
521 } 543 }
522 544
523 chksum = crc32_string (chksum, string); 545 chksum = crc32_string (chksum, string);
524 if (dup) 546 free (dup);
525 free (dup);
526 547
527 return chksum; 548 return chksum;
528 } 549 }
529 550
530 /* Compute checksum for the current function. We generate a CRC32. */ 551 /* Compute checksum for the current function. We generate a CRC32. */
531 552
532 static unsigned 553 unsigned
533 compute_checksum (void) 554 coverage_compute_lineno_checksum (void)
534 { 555 {
535 expanded_location xloc 556 expanded_location xloc
536 = expand_location (DECL_SOURCE_LOCATION (current_function_decl)); 557 = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
537 unsigned chksum = xloc.line; 558 unsigned chksum = xloc.line;
538 559
539 chksum = coverage_checksum_string (chksum, xloc.file); 560 if (xloc.file)
561 chksum = coverage_checksum_string (chksum, xloc.file);
540 chksum = coverage_checksum_string 562 chksum = coverage_checksum_string
541 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); 563 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
542 564
543 return chksum; 565 return chksum;
544 } 566 }
567
568 /* Compute profile ID. This is better to be unique in whole program. */
569
570 unsigned
571 coverage_compute_profile_id (struct cgraph_node *n)
572 {
573 unsigned chksum;
574
575 /* Externally visible symbols have unique name. */
576 if (TREE_PUBLIC (n->decl) || DECL_EXTERNAL (n->decl) || n->unique_name)
577 {
578 chksum = coverage_checksum_string
579 (0, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
580 }
581 else
582 {
583 expanded_location xloc
584 = expand_location (DECL_SOURCE_LOCATION (n->decl));
585 bool use_name_only = (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID) == 0);
586
587 chksum = (use_name_only ? 0 : xloc.line);
588 if (xloc.file)
589 chksum = coverage_checksum_string (chksum, xloc.file);
590 chksum = coverage_checksum_string
591 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
592 if (!use_name_only && first_global_object_name)
593 chksum = coverage_checksum_string
594 (chksum, first_global_object_name);
595 chksum = coverage_checksum_string
596 (chksum, aux_base_name);
597 }
598
599 /* Non-negative integers are hopefully small enough to fit in all targets.
600 Gcov file formats wants non-zero function IDs. */
601 chksum = chksum & 0x7fffffff;
602 return chksum + (!chksum);
603 }
604
605 /* Compute cfg checksum for the function FN given as argument.
606 The checksum is calculated carefully so that
607 source code changes that doesn't affect the control flow graph
608 won't change the checksum.
609 This is to make the profile data useable across source code change.
610 The downside of this is that the compiler may use potentially
611 wrong profile data - that the source code change has non-trivial impact
612 on the validity of profile data (e.g. the reversed condition)
613 but the compiler won't detect the change and use the wrong profile data. */
614
615 unsigned
616 coverage_compute_cfg_checksum (struct function *fn)
617 {
618 basic_block bb;
619 unsigned chksum = n_basic_blocks_for_fn (fn);
620
621 FOR_EACH_BB_FN (bb, fn)
622 {
623 edge e;
624 edge_iterator ei;
625 chksum = crc32_byte (chksum, bb->index);
626 FOR_EACH_EDGE (e, ei, bb->succs)
627 {
628 chksum = crc32_byte (chksum, e->dest->index);
629 }
630 }
631
632 return chksum;
633 }
545 634
546 /* Begin output to the graph file for the current function. 635 /* Begin output to the notes file for the current function.
547 Opens the output file, if not already done. Writes the 636 Writes the function header. Returns nonzero if data should be output. */
548 function header, if not already done. Returns nonzero if data
549 should be output. */
550 637
551 int 638 int
552 coverage_begin_output (void) 639 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
553 { 640 {
641 expanded_location xloc;
642 unsigned long offset;
643
554 /* We don't need to output .gcno file unless we're under -ftest-coverage 644 /* We don't need to output .gcno file unless we're under -ftest-coverage
555 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */ 645 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
556 if (no_coverage || !flag_test_coverage || flag_compare_debug) 646 if (no_coverage || !bbg_file_name)
557 return 0; 647 return 0;
558 648
559 if (!bbg_function_announced) 649 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
560 { 650
561 expanded_location xloc 651 /* Announce function */
562 = expand_location (DECL_SOURCE_LOCATION (current_function_decl)); 652 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
563 unsigned long offset; 653 if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
564 654 gcov_write_unsigned (current_function_funcdef_no + 1);
565 if (!bbg_file_opened) 655 else
566 { 656 {
567 if (!gcov_open (bbg_file_name, -1)) 657 gcc_assert (coverage_node_map_initialized_p ());
568 error ("cannot open %s", bbg_file_name); 658 gcov_write_unsigned (
569 else 659 cgraph_node::get (current_function_decl)->profile_id);
570 { 660 }
571 gcov_write_unsigned (GCOV_NOTE_MAGIC); 661
572 gcov_write_unsigned (GCOV_VERSION); 662 gcov_write_unsigned (lineno_checksum);
573 gcov_write_unsigned (local_tick); 663 gcov_write_unsigned (cfg_checksum);
574 } 664 gcov_write_string (IDENTIFIER_POINTER
575 bbg_file_opened = 1; 665 (DECL_ASSEMBLER_NAME (current_function_decl)));
576 } 666 gcov_write_filename (xloc.file);
577 667 gcov_write_unsigned (xloc.line);
578 /* Announce function */ 668 gcov_write_length (offset);
579 offset = gcov_write_tag (GCOV_TAG_FUNCTION); 669
580 gcov_write_unsigned (current_function_funcdef_no + 1);
581 gcov_write_unsigned (compute_checksum ());
582 gcov_write_string (IDENTIFIER_POINTER
583 (DECL_ASSEMBLER_NAME (current_function_decl)));
584 gcov_write_string (xloc.file);
585 gcov_write_unsigned (xloc.line);
586 gcov_write_length (offset);
587
588 bbg_function_announced = 1;
589 }
590 return !gcov_is_error (); 670 return !gcov_is_error ();
591 } 671 }
592 672
593 /* Finish coverage data for the current function. Verify no output 673 /* Finish coverage data for the current function. Verify no output
594 error has occurred. Save function coverage counts. */ 674 error has occurred. Save function coverage counts. */
595 675
596 void 676 void
597 coverage_end_function (void) 677 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
598 { 678 {
599 unsigned i; 679 unsigned i;
600 680
601 if (bbg_file_opened > 1 && gcov_is_error ()) 681 if (bbg_file_name && gcov_is_error ())
602 { 682 {
603 warning (0, "error writing %qs", bbg_file_name); 683 warning (0, "error writing %qs", bbg_file_name);
604 bbg_file_opened = -1; 684 unlink (bbg_file_name);
685 bbg_file_name = NULL;
605 } 686 }
606 687
607 if (fn_ctr_mask) 688 if (fn_ctr_mask)
608 { 689 {
609 struct function_list *item; 690 struct coverage_data *item = 0;
610 691
611 item = XNEW (struct function_list); 692 item = ggc_alloc<coverage_data> ();
612 693
694 if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
695 item->ident = current_function_funcdef_no + 1;
696 else
697 {
698 gcc_assert (coverage_node_map_initialized_p ());
699 item->ident = cgraph_node::get (cfun->decl)->profile_id;
700 }
701
702 item->lineno_checksum = lineno_checksum;
703 item->cfg_checksum = cfg_checksum;
704
705 item->fn_decl = current_function_decl;
706 item->next = 0;
613 *functions_tail = item; 707 *functions_tail = item;
614 functions_tail = &item->next; 708 functions_tail = &item->next;
615 709
616 item->next = 0;
617 item->ident = current_function_funcdef_no + 1;
618 item->checksum = compute_checksum ();
619 for (i = 0; i != GCOV_COUNTERS; i++) 710 for (i = 0; i != GCOV_COUNTERS; i++)
620 { 711 {
621 item->n_ctrs[i] = fn_n_ctrs[i]; 712 tree var = fn_v_ctrs[i];
622 prg_n_ctrs[i] += fn_n_ctrs[i]; 713
623 fn_n_ctrs[i] = fn_b_ctrs[i] = 0; 714 if (item)
715 item->ctr_vars[i] = var;
716 if (var)
717 {
718 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
719 array_type = build_array_type (get_gcov_type (), array_type);
720 TREE_TYPE (var) = array_type;
721 DECL_SIZE (var) = TYPE_SIZE (array_type);
722 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
723 varpool_node::finalize_decl (var);
724 }
725
726 fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
727 fn_v_ctrs[i] = NULL_TREE;
624 } 728 }
625 prg_ctr_mask |= fn_ctr_mask; 729 prg_ctr_mask |= fn_ctr_mask;
626 fn_ctr_mask = 0; 730 fn_ctr_mask = 0;
627 } 731 }
628 bbg_function_announced = 0; 732 }
733
734 /* Remove coverage file if opened. */
735
736 void
737 coverage_remove_note_file (void)
738 {
739 if (bbg_file_name)
740 {
741 gcov_close ();
742 unlink (bbg_file_name);
743 }
744 }
745
746 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER
747 >= 0 it is a counter array, otherwise it is the function structure. */
748
749 static tree
750 build_var (tree fn_decl, tree type, int counter)
751 {
752 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
753 const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
754 char *buf;
755 size_t fn_name_len, len;
756
757 fn_name = targetm.strip_name_encoding (fn_name);
758 fn_name_len = strlen (fn_name);
759 buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
760
761 if (counter < 0)
762 strcpy (buf, "__gcov__");
763 else
764 sprintf (buf, "__gcov%u_", counter);
765 len = strlen (buf);
766 buf[len - 1] = symbol_table::symbol_suffix_separator ();
767 memcpy (buf + len, fn_name, fn_name_len + 1);
768 DECL_NAME (var) = get_identifier (buf);
769 TREE_STATIC (var) = 1;
770 TREE_ADDRESSABLE (var) = 1;
771 DECL_NONALIASED (var) = 1;
772 SET_DECL_ALIGN (var, TYPE_ALIGN (type));
773
774 return var;
629 } 775 }
630 776
631 /* Creates the gcov_fn_info RECORD_TYPE. */ 777 /* Creates the gcov_fn_info RECORD_TYPE. */
632 778
633 static tree 779 static void
634 build_fn_info_type (unsigned int counters) 780 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
635 { 781 {
636 tree type = lang_hooks.types.make_type (RECORD_TYPE); 782 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
637 tree field, fields; 783 tree field, fields;
638 tree array_type; 784 tree array_type;
639 785
640 /* ident */ 786 gcc_assert (counters);
641 fields = build_decl (BUILTINS_LOCATION, 787
642 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); 788 /* ctr_info::num */
643 789 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
644 /* checksum */ 790 get_gcov_unsigned_t ());
645 field = build_decl (BUILTINS_LOCATION, 791 fields = field;
646 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); 792
793 /* ctr_info::values */
794 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
795 build_pointer_type (get_gcov_type ()));
647 DECL_CHAIN (field) = fields; 796 DECL_CHAIN (field) = fields;
648 fields = field; 797 fields = field;
649 798
650 array_type = build_int_cst (NULL_TREE, counters - 1); 799 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
651 array_type = build_index_type (array_type); 800
652 array_type = build_array_type (get_gcov_unsigned_t (), array_type); 801 /* key */
653 802 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
654 /* counters */ 803 build_pointer_type (build_qualified_type
655 field = build_decl (BUILTINS_LOCATION, 804 (gcov_info_type, TYPE_QUAL_CONST)));
656 FIELD_DECL, NULL_TREE, array_type); 805 fields = field;
806
807 /* ident */
808 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
809 get_gcov_unsigned_t ());
657 DECL_CHAIN (field) = fields; 810 DECL_CHAIN (field) = fields;
658 fields = field; 811 fields = field;
812
813 /* lineno_checksum */
814 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
815 get_gcov_unsigned_t ());
816 DECL_CHAIN (field) = fields;
817 fields = field;
818
819 /* cfg checksum */
820 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
821 get_gcov_unsigned_t ());
822 DECL_CHAIN (field) = fields;
823 fields = field;
824
825 array_type = build_index_type (size_int (counters - 1));
826 array_type = build_array_type (ctr_info, array_type);
827
828 /* counters */
829 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
830 DECL_CHAIN (field) = fields;
831 fields = field;
659 832
660 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE); 833 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
661 834 }
662 return type; 835
663 } 836 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is
664 837 the coverage data for the function and TYPE is the gcov_fn_info
665 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is 838 RECORD_TYPE. KEY is the object file key. */
666 the function being processed and TYPE is the gcov_fn_info
667 RECORD_TYPE. */
668 839
669 static tree 840 static tree
670 build_fn_info_value (const struct function_list *function, tree type) 841 build_fn_info (const struct coverage_data *data, tree type, tree key)
671 { 842 {
672 tree fields = TYPE_FIELDS (type); 843 tree fields = TYPE_FIELDS (type);
844 tree ctr_type;
673 unsigned ix; 845 unsigned ix;
674 VEC(constructor_elt,gc) *v1 = NULL; 846 vec<constructor_elt, va_gc> *v1 = NULL;
675 VEC(constructor_elt,gc) *v2 = NULL; 847 vec<constructor_elt, va_gc> *v2 = NULL;
676 848
849 /* key */
850 CONSTRUCTOR_APPEND_ELT (v1, fields,
851 build1 (ADDR_EXPR, TREE_TYPE (fields), key));
852 fields = DECL_CHAIN (fields);
853
677 /* ident */ 854 /* ident */
678 CONSTRUCTOR_APPEND_ELT (v1, fields, 855 CONSTRUCTOR_APPEND_ELT (v1, fields,
679 build_int_cstu (get_gcov_unsigned_t (), 856 build_int_cstu (get_gcov_unsigned_t (),
680 function->ident)); 857 data->ident));
681 fields = DECL_CHAIN (fields); 858 fields = DECL_CHAIN (fields);
682 859
683 /* checksum */ 860 /* lineno_checksum */
684 CONSTRUCTOR_APPEND_ELT (v1, fields, 861 CONSTRUCTOR_APPEND_ELT (v1, fields,
685 build_int_cstu (get_gcov_unsigned_t (), 862 build_int_cstu (get_gcov_unsigned_t (),
686 function->checksum)); 863 data->lineno_checksum));
687 fields = DECL_CHAIN (fields); 864 fields = DECL_CHAIN (fields);
688 865
866 /* cfg_checksum */
867 CONSTRUCTOR_APPEND_ELT (v1, fields,
868 build_int_cstu (get_gcov_unsigned_t (),
869 data->cfg_checksum));
870 fields = DECL_CHAIN (fields);
871
689 /* counters */ 872 /* counters */
873 ctr_type = TREE_TYPE (TREE_TYPE (fields));
690 for (ix = 0; ix != GCOV_COUNTERS; ix++) 874 for (ix = 0; ix != GCOV_COUNTERS; ix++)
691 if (prg_ctr_mask & (1 << ix)) 875 if (prg_ctr_mask & (1 << ix))
692 CONSTRUCTOR_APPEND_ELT (v2, NULL, 876 {
693 build_int_cstu (get_gcov_unsigned_t (), 877 vec<constructor_elt, va_gc> *ctr = NULL;
694 function->n_ctrs[ix])); 878 tree var = data->ctr_vars[ix];
695 879 unsigned count = 0;
880
881 if (var)
882 count
883 = tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))))
884 + 1;
885
886 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
887 build_int_cstu (get_gcov_unsigned_t (),
888 count));
889
890 if (var)
891 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
892 build_fold_addr_expr (var));
893
894 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
895 }
896
696 CONSTRUCTOR_APPEND_ELT (v1, fields, 897 CONSTRUCTOR_APPEND_ELT (v1, fields,
697 build_constructor (TREE_TYPE (fields), v2)); 898 build_constructor (TREE_TYPE (fields), v2));
698 899
699 return build_constructor (type, v1); 900 return build_constructor (type, v1);
700 } 901 }
701 902
702 /* Creates the gcov_ctr_info RECORD_TYPE. */ 903 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be
703 904 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */
704 static tree 905
705 build_ctr_info_type (void) 906 static void
706 { 907 build_info_type (tree type, tree fn_info_ptr_type)
707 tree type = lang_hooks.types.make_type (RECORD_TYPE); 908 {
708 tree field, fields = NULL_TREE; 909 tree field, fields = NULL_TREE;
709 tree gcov_ptr_type = build_pointer_type (get_gcov_type ()); 910 tree merge_fn_type;
710 tree gcov_merge_fn_type; 911
711 912 /* Version ident */
712 /* counters */ 913 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
713 field = build_decl (BUILTINS_LOCATION, 914 get_gcov_unsigned_t ());
714 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
715 DECL_CHAIN (field) = fields; 915 DECL_CHAIN (field) = fields;
716 fields = field; 916 fields = field;
717 917
718 /* values */ 918 /* next pointer */
719 field = build_decl (BUILTINS_LOCATION, 919 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
720 FIELD_DECL, NULL_TREE, gcov_ptr_type); 920 build_pointer_type (build_qualified_type
921 (type, TYPE_QUAL_CONST)));
721 DECL_CHAIN (field) = fields; 922 DECL_CHAIN (field) = fields;
722 fields = field; 923 fields = field;
723 924
724 /* merge */ 925 /* stamp */
725 gcov_merge_fn_type = 926 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
726 build_function_type_list (void_type_node, 927 get_gcov_unsigned_t ());
727 gcov_ptr_type, get_gcov_unsigned_t (),
728 NULL_TREE);
729 field = build_decl (BUILTINS_LOCATION,
730 FIELD_DECL, NULL_TREE,
731 build_pointer_type (gcov_merge_fn_type));
732 DECL_CHAIN (field) = fields; 928 DECL_CHAIN (field) = fields;
733 fields = field; 929 fields = field;
734 930
735 finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE); 931 /* Filename */
736 932 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
737 return type; 933 build_pointer_type (build_qualified_type
738 } 934 (char_type_node, TYPE_QUAL_CONST)));
739 935 DECL_CHAIN (field) = fields;
740 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is 936 fields = field;
741 the counter being processed and TYPE is the gcov_ctr_info 937
742 RECORD_TYPE. */ 938 /* merge fn array */
939 merge_fn_type
940 = build_function_type_list (void_type_node,
941 build_pointer_type (get_gcov_type ()),
942 get_gcov_unsigned_t (), NULL_TREE);
943 merge_fn_type
944 = build_array_type (build_pointer_type (merge_fn_type),
945 build_index_type (size_int (GCOV_COUNTERS - 1)));
946 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
947 merge_fn_type);
948 DECL_CHAIN (field) = fields;
949 fields = field;
950
951 /* n_functions */
952 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
953 get_gcov_unsigned_t ());
954 DECL_CHAIN (field) = fields;
955 fields = field;
956
957 /* function_info pointer pointer */
958 fn_info_ptr_type = build_pointer_type
959 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
960 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
961 fn_info_ptr_type);
962 DECL_CHAIN (field) = fields;
963 fields = field;
964
965 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
966 }
967
968 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the
969 gcov_info structure type, FN_ARY is the array of pointers to
970 function info objects. */
743 971
744 static tree 972 static tree
745 build_ctr_info_value (unsigned int counter, tree type) 973 build_info (tree info_type, tree fn_ary)
746 { 974 {
747 tree fields = TYPE_FIELDS (type); 975 tree info_fields = TYPE_FIELDS (info_type);
748 tree fn; 976 tree merge_fn_type, n_funcs;
749 VEC(constructor_elt,gc) *v = NULL; 977 unsigned ix;
750
751 /* counters */
752 CONSTRUCTOR_APPEND_ELT (v, fields,
753 build_int_cstu (get_gcov_unsigned_t (),
754 prg_n_ctrs[counter]));
755 fields = DECL_CHAIN (fields);
756
757 if (prg_n_ctrs[counter])
758 {
759 tree array_type;
760
761 array_type = build_int_cstu (get_gcov_unsigned_t (),
762 prg_n_ctrs[counter] - 1);
763 array_type = build_index_type (array_type);
764 array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
765 array_type);
766
767 TREE_TYPE (tree_ctr_tables[counter]) = array_type;
768 DECL_SIZE (tree_ctr_tables[counter]) = TYPE_SIZE (array_type);
769 DECL_SIZE_UNIT (tree_ctr_tables[counter]) = TYPE_SIZE_UNIT (array_type);
770 varpool_finalize_decl (tree_ctr_tables[counter]);
771
772 CONSTRUCTOR_APPEND_ELT (v, fields,
773 build1 (ADDR_EXPR, TREE_TYPE (fields),
774 tree_ctr_tables[counter]));
775 }
776 else
777 CONSTRUCTOR_APPEND_ELT (v, fields, null_pointer_node);
778 fields = DECL_CHAIN (fields);
779
780 fn = build_decl (BUILTINS_LOCATION,
781 FUNCTION_DECL,
782 get_identifier (ctr_merge_functions[counter]),
783 TREE_TYPE (TREE_TYPE (fields)));
784 DECL_EXTERNAL (fn) = 1;
785 TREE_PUBLIC (fn) = 1;
786 DECL_ARTIFICIAL (fn) = 1;
787 TREE_NOTHROW (fn) = 1;
788 DECL_ASSEMBLER_NAME (fn); /* Initialize assembler name so we can stream out. */
789 CONSTRUCTOR_APPEND_ELT (v, fields, build1 (ADDR_EXPR, TREE_TYPE (fields), fn));
790
791 return build_constructor (type, v);
792 }
793
794 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
795 CONSTRUCTOR. */
796
797 static tree
798 build_gcov_info (void)
799 {
800 unsigned n_ctr_types, ix;
801 tree type, const_type;
802 tree fn_info_type, fn_info_value = NULL_TREE;
803 tree fn_info_ptr_type;
804 tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
805 tree field, fields = NULL_TREE;
806 tree filename_string; 978 tree filename_string;
807 int da_file_name_len; 979 int da_file_name_len;
808 unsigned n_fns; 980 vec<constructor_elt, va_gc> *v1 = NULL;
809 const struct function_list *fn; 981 vec<constructor_elt, va_gc> *v2 = NULL;
810 tree string_type;
811 VEC(constructor_elt,gc) *v1 = NULL;
812 VEC(constructor_elt,gc) *v2 = NULL;
813
814 /* Count the number of active counters. */
815 for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
816 if (prg_ctr_mask & (1 << ix))
817 n_ctr_types++;
818
819 type = lang_hooks.types.make_type (RECORD_TYPE);
820 const_type = build_qualified_type (type, TYPE_QUAL_CONST);
821 982
822 /* Version ident */ 983 /* Version ident */
823 field = build_decl (BUILTINS_LOCATION, 984 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
824 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); 985 build_int_cstu (TREE_TYPE (info_fields),
825 DECL_CHAIN (field) = fields; 986 GCOV_VERSION));
826 fields = field; 987 info_fields = DECL_CHAIN (info_fields);
827 CONSTRUCTOR_APPEND_ELT (v1, field,
828 build_int_cstu (TREE_TYPE (field), GCOV_VERSION));
829 988
830 /* next -- NULL */ 989 /* next -- NULL */
831 field = build_decl (BUILTINS_LOCATION, 990 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
832 FIELD_DECL, NULL_TREE, build_pointer_type (const_type)); 991 info_fields = DECL_CHAIN (info_fields);
833 DECL_CHAIN (field) = fields; 992
834 fields = field;
835 CONSTRUCTOR_APPEND_ELT (v1, field, null_pointer_node);
836
837 /* stamp */ 993 /* stamp */
838 field = build_decl (BUILTINS_LOCATION, 994 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
839 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); 995 build_int_cstu (TREE_TYPE (info_fields),
840 DECL_CHAIN (field) = fields; 996 bbg_file_stamp));
841 fields = field; 997 info_fields = DECL_CHAIN (info_fields);
842 CONSTRUCTOR_APPEND_ELT (v1, field,
843 build_int_cstu (TREE_TYPE (field), local_tick));
844 998
845 /* Filename */ 999 /* Filename */
846 string_type = build_pointer_type (build_qualified_type (char_type_node,
847 TYPE_QUAL_CONST));
848 field = build_decl (BUILTINS_LOCATION,
849 FIELD_DECL, NULL_TREE, string_type);
850 DECL_CHAIN (field) = fields;
851 fields = field;
852 da_file_name_len = strlen (da_file_name); 1000 da_file_name_len = strlen (da_file_name);
853 filename_string = build_string (da_file_name_len + 1, da_file_name); 1001 filename_string = build_string (da_file_name_len + 1, da_file_name);
854 TREE_TYPE (filename_string) = build_array_type 1002 TREE_TYPE (filename_string) = build_array_type
855 (char_type_node, build_index_type 1003 (char_type_node, build_index_type (size_int (da_file_name_len)));
856 (build_int_cst (NULL_TREE, da_file_name_len))); 1004 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
857 CONSTRUCTOR_APPEND_ELT (v1, field, 1005 build1 (ADDR_EXPR, TREE_TYPE (info_fields),
858 build1 (ADDR_EXPR, string_type, filename_string)); 1006 filename_string));
859 1007 info_fields = DECL_CHAIN (info_fields);
860 /* Build the fn_info type and initializer. */ 1008
861 fn_info_type = build_fn_info_type (n_ctr_types); 1009 /* merge fn array -- NULL slots indicate unmeasured counters */
862 fn_info_ptr_type = build_pointer_type (build_qualified_type 1010 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
863 (fn_info_type, TYPE_QUAL_CONST));
864 for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
865 CONSTRUCTOR_APPEND_ELT (v2, NULL_TREE,
866 build_fn_info_value (fn, fn_info_type));
867
868 if (n_fns)
869 {
870 tree array_type;
871
872 array_type = build_index_type (build_int_cst (NULL_TREE, n_fns - 1));
873 array_type = build_array_type (fn_info_type, array_type);
874
875 fn_info_value = build_constructor (array_type, v2);
876 fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
877 }
878 else
879 fn_info_value = null_pointer_node;
880
881 /* number of functions */
882 field = build_decl (BUILTINS_LOCATION,
883 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
884 DECL_CHAIN (field) = fields;
885 fields = field;
886 CONSTRUCTOR_APPEND_ELT (v1, field,
887 build_int_cstu (get_gcov_unsigned_t (), n_fns));
888
889 /* fn_info table */
890 field = build_decl (BUILTINS_LOCATION,
891 FIELD_DECL, NULL_TREE, fn_info_ptr_type);
892 DECL_CHAIN (field) = fields;
893 fields = field;
894 CONSTRUCTOR_APPEND_ELT (v1, field, fn_info_value);
895
896 /* counter_mask */
897 field = build_decl (BUILTINS_LOCATION,
898 FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
899 DECL_CHAIN (field) = fields;
900 fields = field;
901 CONSTRUCTOR_APPEND_ELT (v1, field,
902 build_int_cstu (get_gcov_unsigned_t (),
903 prg_ctr_mask));
904
905 /* counters */
906 ctr_info_type = build_ctr_info_type ();
907 ctr_info_ary_type = build_index_type (build_int_cst (NULL_TREE,
908 n_ctr_types));
909 ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
910 v2 = NULL;
911 for (ix = 0; ix != GCOV_COUNTERS; ix++) 1011 for (ix = 0; ix != GCOV_COUNTERS; ix++)
912 if (prg_ctr_mask & (1 << ix)) 1012 {
913 CONSTRUCTOR_APPEND_ELT (v2, NULL_TREE, 1013 tree ptr = null_pointer_node;
914 build_ctr_info_value (ix, ctr_info_type)); 1014
915 ctr_info_value = build_constructor (ctr_info_ary_type, v2); 1015 if ((1u << ix) & prg_ctr_mask)
916 1016 {
917 field = build_decl (BUILTINS_LOCATION, 1017 tree merge_fn = build_decl (BUILTINS_LOCATION,
918 FIELD_DECL, NULL_TREE, ctr_info_ary_type); 1018 FUNCTION_DECL,
919 DECL_CHAIN (field) = fields; 1019 get_identifier (ctr_merge_functions[ix]),
920 fields = field; 1020 TREE_TYPE (merge_fn_type));
921 CONSTRUCTOR_APPEND_ELT (v1, field, ctr_info_value); 1021 DECL_EXTERNAL (merge_fn) = 1;
922 1022 TREE_PUBLIC (merge_fn) = 1;
923 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE); 1023 DECL_ARTIFICIAL (merge_fn) = 1;
924 1024 TREE_NOTHROW (merge_fn) = 1;
925 return build_constructor (type, v1); 1025 /* Initialize assembler name so we can stream out. */
926 } 1026 DECL_ASSEMBLER_NAME (merge_fn);
927 1027 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
928 /* Write out the structure which libgcov uses to locate all the 1028 }
929 counters. The structures used here must match those defined in 1029 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
930 gcov-io.h. Write out the constructor to call __gcov_init. */ 1030 }
1031 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1032 build_constructor (TREE_TYPE (info_fields), v2));
1033 info_fields = DECL_CHAIN (info_fields);
1034
1035 /* n_functions */
1036 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
1037 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
1038 n_funcs, size_one_node);
1039 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
1040 info_fields = DECL_CHAIN (info_fields);
1041
1042 /* functions */
1043 CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1044 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
1045 info_fields = DECL_CHAIN (info_fields);
1046
1047 gcc_assert (!info_fields);
1048 return build_constructor (info_type, v1);
1049 }
1050
1051 /* Generate the constructor function to call __gcov_init. */
931 1052
932 static void 1053 static void
933 create_coverage (void) 1054 build_init_ctor (tree gcov_info_type)
934 { 1055 {
935 tree gcov_info, gcov_init, body, t; 1056 tree ctor, stmt, init_fn;
1057
1058 /* Build a decl for __gcov_init. */
1059 init_fn = build_pointer_type (gcov_info_type);
1060 init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1061 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1062 get_identifier ("__gcov_init"), init_fn);
1063 TREE_PUBLIC (init_fn) = 1;
1064 DECL_EXTERNAL (init_fn) = 1;
1065 DECL_ASSEMBLER_NAME (init_fn);
1066
1067 /* Generate a call to __gcov_init(&gcov_info). */
1068 ctor = NULL;
1069 stmt = build_fold_addr_expr (gcov_info_var);
1070 stmt = build_call_expr (init_fn, 1, stmt);
1071 append_to_statement_list (stmt, &ctor);
1072
1073 /* Generate a constructor to run it. */
1074 int priority = SUPPORTS_INIT_PRIORITY
1075 ? MAX_RESERVED_INIT_PRIORITY: DEFAULT_INIT_PRIORITY;
1076 cgraph_build_static_cdtor ('I', ctor, priority);
1077 }
1078
1079 /* Generate the destructor function to call __gcov_exit. */
1080
1081 static void
1082 build_gcov_exit_decl (void)
1083 {
1084 tree init_fn = build_function_type_list (void_type_node, void_type_node,
1085 NULL);
1086 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1087 get_identifier ("__gcov_exit"), init_fn);
1088 TREE_PUBLIC (init_fn) = 1;
1089 DECL_EXTERNAL (init_fn) = 1;
1090 DECL_ASSEMBLER_NAME (init_fn);
1091
1092 /* Generate a call to __gcov_exit (). */
1093 tree dtor = NULL;
1094 tree stmt = build_call_expr (init_fn, 0);
1095 append_to_statement_list (stmt, &dtor);
1096
1097 /* Generate a destructor to run it. */
1098 int priority = SUPPORTS_INIT_PRIORITY
1099 ? MAX_RESERVED_INIT_PRIORITY: DEFAULT_INIT_PRIORITY;
1100
1101 cgraph_build_static_cdtor ('D', dtor, priority);
1102 }
1103
1104 /* Create the gcov_info types and object. Generate the constructor
1105 function to call __gcov_init. Does not generate the initializer
1106 for the object. Returns TRUE if coverage data is being emitted. */
1107
1108 static bool
1109 coverage_obj_init (void)
1110 {
1111 tree gcov_info_type;
1112 unsigned n_counters = 0;
1113 unsigned ix;
1114 struct coverage_data *fn;
1115 struct coverage_data **fn_prev;
936 char name_buf[32]; 1116 char name_buf[32];
937 1117
938 no_coverage = 1; /* Disable any further coverage. */ 1118 no_coverage = 1; /* Disable any further coverage. */
939 1119
940 if (!prg_ctr_mask) 1120 if (!prg_ctr_mask)
941 return; 1121 return false;
942 1122
943 t = build_gcov_info (); 1123 if (symtab->dump_file)
944 1124 fprintf (symtab->dump_file, "Using data file %s\n", da_file_name);
945 gcov_info = build_decl (BUILTINS_LOCATION, 1125
946 VAR_DECL, NULL_TREE, TREE_TYPE (t)); 1126 /* Prune functions. */
947 TREE_STATIC (gcov_info) = 1; 1127 for (fn_prev = &functions_head; (fn = *fn_prev);)
1128 if (DECL_STRUCT_FUNCTION (fn->fn_decl))
1129 fn_prev = &fn->next;
1130 else
1131 /* The function is not being emitted, remove from list. */
1132 *fn_prev = fn->next;
1133
1134 if (functions_head == NULL)
1135 return false;
1136
1137 for (ix = 0; ix != GCOV_COUNTERS; ix++)
1138 if ((1u << ix) & prg_ctr_mask)
1139 n_counters++;
1140
1141 /* Build the info and fn_info types. These are mutually recursive. */
1142 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1143 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1144 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
1145 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1146 gcov_fn_info_ptr_type = build_pointer_type
1147 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
1148 build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1149
1150 /* Build the gcov info var, this is referred to in its own
1151 initializer. */
1152 gcov_info_var = build_decl (BUILTINS_LOCATION,
1153 VAR_DECL, NULL_TREE, gcov_info_type);
1154 TREE_STATIC (gcov_info_var) = 1;
948 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0); 1155 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
949 DECL_NAME (gcov_info) = get_identifier (name_buf); 1156 DECL_NAME (gcov_info_var) = get_identifier (name_buf);
950 DECL_INITIAL (gcov_info) = t; 1157
951 1158 build_init_ctor (gcov_info_type);
952 /* Build structure. */ 1159 build_gcov_exit_decl ();
953 varpool_finalize_decl (gcov_info); 1160
954 1161 return true;
955 /* Build a decl for __gcov_init. */ 1162 }
956 t = build_pointer_type (TREE_TYPE (gcov_info)); 1163
957 t = build_function_type_list (void_type_node, t, NULL); 1164 /* Generate the coverage function info for FN and DATA. Append a
958 t = build_decl (BUILTINS_LOCATION, 1165 pointer to that object to CTOR and return the appended CTOR. */
959 FUNCTION_DECL, get_identifier ("__gcov_init"), t); 1166
960 TREE_PUBLIC (t) = 1; 1167 static vec<constructor_elt, va_gc> *
961 DECL_EXTERNAL (t) = 1; 1168 coverage_obj_fn (vec<constructor_elt, va_gc> *ctor, tree fn,
962 DECL_ASSEMBLER_NAME (t); /* Initialize assembler name so we can stream out. */ 1169 struct coverage_data const *data)
963 gcov_init = t; 1170 {
964 1171 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
965 /* Generate a call to __gcov_init(&gcov_info). */ 1172 tree var = build_var (fn, gcov_fn_info_type, -1);
966 body = NULL; 1173
967 t = build_fold_addr_expr (gcov_info); 1174 DECL_INITIAL (var) = init;
968 t = build_call_expr (gcov_init, 1, t); 1175 varpool_node::finalize_decl (var);
969 append_to_statement_list (t, &body); 1176
970 1177 CONSTRUCTOR_APPEND_ELT (ctor, NULL,
971 /* Generate a constructor to run it. */ 1178 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
972 cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY); 1179 return ctor;
973 } 1180 }
974 1181
1182 /* Finalize the coverage data. Generates the array of pointers to
1183 function objects from CTOR. Generate the gcov_info initializer. */
1184
1185 static void
1186 coverage_obj_finish (vec<constructor_elt, va_gc> *ctor)
1187 {
1188 unsigned n_functions = vec_safe_length (ctor);
1189 tree fn_info_ary_type = build_array_type
1190 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1191 build_index_type (size_int (n_functions - 1)));
1192 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1193 fn_info_ary_type);
1194 char name_buf[32];
1195
1196 TREE_STATIC (fn_info_ary) = 1;
1197 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1198 DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1199 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1200 varpool_node::finalize_decl (fn_info_ary);
1201
1202 DECL_INITIAL (gcov_info_var)
1203 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary);
1204 varpool_node::finalize_decl (gcov_info_var);
1205 }
1206
975 /* Perform file-level initialization. Read in data file, generate name 1207 /* Perform file-level initialization. Read in data file, generate name
976 of graph file. */ 1208 of notes file. */
977 1209
978 void 1210 void
979 coverage_init (const char *filename) 1211 coverage_init (const char *filename)
980 { 1212 {
981 int len = strlen (filename); 1213 int len = strlen (filename);
982 /* + 1 for extra '/', in case prefix doesn't end with /. */ 1214 int prefix_len = 0;
983 int prefix_len; 1215
984 1216 /* Since coverage_init is invoked very early, before the pass
985 if (profile_data_prefix == 0 && filename[0] != '/') 1217 manager, we need to set up the dumping explicitly. This is
1218 similar to the handling in finish_optimization_passes. */
1219 int profile_pass_num =
1220 g->get_passes ()->get_pass_profile ()->static_pass_number;
1221 g->get_dumps ()->dump_start (profile_pass_num, NULL);
1222
1223 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
986 profile_data_prefix = getpwd (); 1224 profile_data_prefix = getpwd ();
987 1225
988 prefix_len = (profile_data_prefix) ? strlen (profile_data_prefix) + 1 : 0; 1226 if (profile_data_prefix)
1227 prefix_len = strlen (profile_data_prefix);
989 1228
990 /* Name of da file. */ 1229 /* Name of da file. */
991 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX) 1230 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
992 + prefix_len + 1); 1231 + prefix_len + 2);
993 1232
994 if (profile_data_prefix) 1233 if (profile_data_prefix)
995 { 1234 {
996 strcpy (da_file_name, profile_data_prefix); 1235 memcpy (da_file_name, profile_data_prefix, prefix_len);
997 da_file_name[prefix_len - 1] = '/'; 1236 da_file_name[prefix_len++] = '/';
998 da_file_name[prefix_len] = 0; 1237 }
999 } 1238 memcpy (da_file_name + prefix_len, filename, len);
1000 else 1239 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1001 da_file_name[0] = 0; 1240
1002 strcat (da_file_name, filename); 1241 bbg_file_stamp = local_tick;
1003 strcat (da_file_name, GCOV_DATA_SUFFIX); 1242
1243 if (flag_auto_profile)
1244 read_autofdo_file ();
1245 else if (flag_branch_probabilities)
1246 read_counts_file ();
1004 1247
1005 /* Name of bbg file. */ 1248 /* Name of bbg file. */
1006 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1); 1249 if (flag_test_coverage && !flag_compare_debug)
1007 strcpy (bbg_file_name, filename); 1250 {
1008 strcat (bbg_file_name, GCOV_NOTE_SUFFIX); 1251 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1);
1009 1252 memcpy (bbg_file_name, filename, len);
1010 if (flag_profile_use) 1253 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX);
1011 read_counts_file (); 1254
1012 } 1255 if (!gcov_open (bbg_file_name, -1))
1013 1256 {
1014 /* Performs file-level cleanup. Close graph file, generate coverage 1257 error ("cannot open %s", bbg_file_name);
1258 bbg_file_name = NULL;
1259 }
1260 else
1261 {
1262 gcov_write_unsigned (GCOV_NOTE_MAGIC);
1263 gcov_write_unsigned (GCOV_VERSION);
1264 gcov_write_unsigned (bbg_file_stamp);
1265 }
1266 }
1267
1268 g->get_dumps ()->dump_finish (profile_pass_num);
1269 }
1270
1271 /* Performs file-level cleanup. Close notes file, generate coverage
1015 variables and constructor. */ 1272 variables and constructor. */
1016 1273
1017 void 1274 void
1018 coverage_finish (void) 1275 coverage_finish (void)
1019 { 1276 {
1020 create_coverage (); 1277 if (bbg_file_name && gcov_close ())
1021 if (bbg_file_opened) 1278 unlink (bbg_file_name);
1022 { 1279
1023 int error = gcov_close (); 1280 if (!flag_branch_probabilities && flag_test_coverage
1024 1281 && (!local_tick || local_tick == (unsigned)-1))
1025 if (error) 1282 /* Only remove the da file, if we're emitting coverage code and
1026 unlink (bbg_file_name); 1283 cannot uniquely stamp it. If we can stamp it, libgcov will DTRT. */
1027 if (!local_tick) 1284 unlink (da_file_name);
1028 /* Only remove the da file, if we cannot stamp it. If we can 1285
1029 stamp it, libgcov will DTRT. */ 1286 if (coverage_obj_init ())
1030 unlink (da_file_name); 1287 {
1031 } 1288 vec<constructor_elt, va_gc> *fn_ctor = NULL;
1289 struct coverage_data *fn;
1290
1291 for (fn = functions_head; fn; fn = fn->next)
1292 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1293 coverage_obj_finish (fn_ctor);
1294 }
1295
1296 XDELETEVEC (da_file_name);
1297 da_file_name = NULL;
1032 } 1298 }
1033 1299
1034 #include "gt-coverage.h" 1300 #include "gt-coverage.h"