1 /* Read and write coverage files, and associated functionality. 2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 3 2000, 2001, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012 4 Free Software Foundation, Inc. 5 Contributed by James E. Wilson, UC Berkeley/Cygnus Support; 6 based on some ideas from Dain Samples of UC Berkeley. 7 Further mangling by Bob Manson, Cygnus Support. 8 Further mangled by Nathan Sidwell, CodeSourcery 9 10 This file is part of GCC. 11 12 GCC is free software; you can redistribute it and/or modify it under 13 the terms of the GNU General Public License as published by the Free 14 Software Foundation; either version 3, or (at your option) any later 15 version. 16 17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 18 WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with GCC; see the file COPYING3. If not see 24 <http://www.gnu.org/licenses/>. */ 25 26 27 #define GCOV_LINKAGE 28 29 #include "config.h" 30 #include "system.h" 31 #include "coretypes.h" 32 #include "tm.h" 33 #include "rtl.h" 34 #include "tree.h" 35 #include "flags.h" 36 #include "output.h" 37 #include "regs.h" 38 #include "expr.h" 39 #include "function.h" 40 #include "basic-block.h" 41 #include "toplev.h" 42 #include "tm_p.h" 43 #include "ggc.h" 44 #include "coverage.h" 45 #include "langhooks.h" 46 #include "hashtab.h" 47 #include "tree-iterator.h" 48 #include "cgraph.h" 49 #include "tree-pass.h" 50 #include "diagnostic-core.h" 51 #include "intl.h" 52 #include "filenames.h" 53 #include "target.h" 54 55 #include "gcov-io.h" 56 #include "gcov-io.c" 57 58 struct GTY((chain_next ("%h.next"))) coverage_data 59 { 60 struct coverage_data *next; /* next function */ 61 unsigned ident; /* function ident */ 62 unsigned lineno_checksum; /* function lineno checksum */ 63 unsigned cfg_checksum; /* function cfg checksum */ 64 tree fn_decl; /* the function decl */ 65 tree ctr_vars[GCOV_COUNTERS]; /* counter variables. */ 66 }; 67 68 /* Counts information for a function. */ 69 typedef struct counts_entry 70 { 71 /* We hash by */ 72 unsigned ident; 73 unsigned ctr; 74 75 /* Store */ 76 unsigned lineno_checksum; 77 unsigned cfg_checksum; 78 gcov_type *counts; 79 struct gcov_ctr_summary summary; 80 } counts_entry_t; 81 82 static GTY(()) struct coverage_data *functions_head = 0; 83 static struct coverage_data **functions_tail = &functions_head; 84 static unsigned no_coverage = 0; 85 86 /* Cumulative counter information for whole program. */ 87 static unsigned prg_ctr_mask; /* Mask of counter types generated. */ 88 89 /* Counter information for current function. */ 90 static unsigned fn_ctr_mask; /* Mask of counters used. */ 91 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS]; /* counter variables. */ 92 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */ 93 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */ 94 95 /* Coverage info VAR_DECL and function info type nodes. */ 96 static GTY(()) tree gcov_info_var; 97 static GTY(()) tree gcov_fn_info_type; 98 static GTY(()) tree gcov_fn_info_ptr_type; 99 100 /* Name of the output file for coverage output file. If this is NULL 101 we're not writing to the notes file. */ 102 static char *bbg_file_name; 103 104 /* Name of the count data file. */ 105 static char *da_file_name; 106 107 /* Hash table of count data. */ 108 static htab_t counts_hash = NULL; 109 110 /* The names of merge functions for counters. */ 111 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS; 112 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES; 113 114 /* Forward declarations. */ 115 static hashval_t htab_counts_entry_hash (const void *); 116 static int htab_counts_entry_eq (const void *, const void *); 117 static void htab_counts_entry_del (void *); 118 static void read_counts_file (void); 119 static tree build_var (tree, tree, int); 120 static void build_fn_info_type (tree, unsigned, tree); 121 static void build_info_type (tree, tree); 122 static tree build_fn_info (const struct coverage_data *, tree, tree); 123 static tree build_info (tree, tree); 124 static bool coverage_obj_init (void); 125 static VEC(constructor_elt,gc) *coverage_obj_fn 126 (VEC(constructor_elt,gc) *, tree, struct coverage_data const *); 127 static void coverage_obj_finish (VEC(constructor_elt,gc) *); 128 129 /* Return the type node for gcov_type. */ 130 131 tree 132 get_gcov_type (void) 133 { 134 return lang_hooks.types.type_for_size (GCOV_TYPE_SIZE, false); 135 } 136 137 /* Return the type node for gcov_unsigned_t. */ 138 139 static tree 140 get_gcov_unsigned_t (void) 141 { 142 return lang_hooks.types.type_for_size (32, true); 143 } 144 145 static hashval_t 146 htab_counts_entry_hash (const void *of) 147 { 148 const counts_entry_t *const entry = (const counts_entry_t *) of; 149 150 return entry->ident * GCOV_COUNTERS + entry->ctr; 151 } 152 153 static int 154 htab_counts_entry_eq (const void *of1, const void *of2) 155 { 156 const counts_entry_t *const entry1 = (const counts_entry_t *) of1; 157 const counts_entry_t *const entry2 = (const counts_entry_t *) of2; 158 159 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr; 160 } 161 162 static void 163 htab_counts_entry_del (void *of) 164 { 165 counts_entry_t *const entry = (counts_entry_t *) of; 166 167 free (entry->counts); 168 free (entry); 169 } 170 171 /* Read in the counts file, if available. */ 172 173 static void 174 read_counts_file (void) 175 { 176 gcov_unsigned_t fn_ident = 0; 177 struct gcov_summary summary; 178 unsigned new_summary = 1; 179 gcov_unsigned_t tag; 180 int is_error = 0; 181 unsigned lineno_checksum = 0; 182 unsigned cfg_checksum = 0; 183 184 if (!gcov_open (da_file_name, 1)) 185 return; 186 187 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC)) 188 { 189 warning (0, "%qs is not a gcov data file", da_file_name); 190 gcov_close (); 191 return; 192 } 193 else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION) 194 { 195 char v[4], e[4]; 196 197 GCOV_UNSIGNED2STRING (v, tag); 198 GCOV_UNSIGNED2STRING (e, GCOV_VERSION); 199 200 warning (0, "%qs is version %q.*s, expected version %q.*s", 201 da_file_name, 4, v, 4, e); 202 gcov_close (); 203 return; 204 } 205 206 /* Read and discard the stamp. */ 207 gcov_read_unsigned (); 208 209 counts_hash = htab_create (10, 210 htab_counts_entry_hash, htab_counts_entry_eq, 211 htab_counts_entry_del); 212 while ((tag = gcov_read_unsigned ())) 213 { 214 gcov_unsigned_t length; 215 gcov_position_t offset; 216 217 length = gcov_read_unsigned (); 218 offset = gcov_position (); 219 if (tag == GCOV_TAG_FUNCTION) 220 { 221 if (length) 222 { 223 fn_ident = gcov_read_unsigned (); 224 lineno_checksum = gcov_read_unsigned (); 225 cfg_checksum = gcov_read_unsigned (); 226 } 227 else 228 fn_ident = lineno_checksum = cfg_checksum = 0; 229 new_summary = 1; 230 } 231 else if (tag == GCOV_TAG_PROGRAM_SUMMARY) 232 { 233 struct gcov_summary sum; 234 unsigned ix; 235 236 if (new_summary) 237 memset (&summary, 0, sizeof (summary)); 238 239 gcov_read_summary (&sum); 240 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++) 241 { 242 summary.ctrs[ix].runs += sum.ctrs[ix].runs; 243 summary.ctrs[ix].sum_all += sum.ctrs[ix].sum_all; 244 if (summary.ctrs[ix].run_max < sum.ctrs[ix].run_max) 245 summary.ctrs[ix].run_max = sum.ctrs[ix].run_max; 246 summary.ctrs[ix].sum_max += sum.ctrs[ix].sum_max; 247 } 248 new_summary = 0; 249 } 250 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident) 251 { 252 counts_entry_t **slot, *entry, elt; 253 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length); 254 unsigned ix; 255 256 elt.ident = fn_ident; 257 elt.ctr = GCOV_COUNTER_FOR_TAG (tag); 258 259 slot = (counts_entry_t **) htab_find_slot 260 (counts_hash, &elt, INSERT); 261 entry = *slot; 262 if (!entry) 263 { 264 *slot = entry = XCNEW (counts_entry_t); 265 entry->ident = fn_ident; 266 entry->ctr = elt.ctr; 267 entry->lineno_checksum = lineno_checksum; 268 entry->cfg_checksum = cfg_checksum; 269 entry->summary = summary.ctrs[elt.ctr]; 270 entry->summary.num = n_counts; 271 entry->counts = XCNEWVEC (gcov_type, n_counts); 272 } 273 else if (entry->lineno_checksum != lineno_checksum 274 || entry->cfg_checksum != cfg_checksum) 275 { 276 error ("Profile data for function %u is corrupted", fn_ident); 277 error ("checksum is (%x,%x) instead of (%x,%x)", 278 entry->lineno_checksum, entry->cfg_checksum, 279 lineno_checksum, cfg_checksum); 280 htab_delete (counts_hash); 281 break; 282 } 283 else if (entry->summary.num != n_counts) 284 { 285 error ("Profile data for function %u is corrupted", fn_ident); 286 error ("number of counters is %d instead of %d", entry->summary.num, n_counts); 287 htab_delete (counts_hash); 288 break; 289 } 290 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE) 291 { 292 error ("cannot merge separate %s counters for function %u", 293 ctr_names[elt.ctr], fn_ident); 294 goto skip_merge; 295 } 296 else 297 { 298 entry->summary.runs += summary.ctrs[elt.ctr].runs; 299 entry->summary.sum_all += summary.ctrs[elt.ctr].sum_all; 300 if (entry->summary.run_max < summary.ctrs[elt.ctr].run_max) 301 entry->summary.run_max = summary.ctrs[elt.ctr].run_max; 302 entry->summary.sum_max += summary.ctrs[elt.ctr].sum_max; 303 } 304 for (ix = 0; ix != n_counts; ix++) 305 entry->counts[ix] += gcov_read_counter (); 306 skip_merge:; 307 } 308 gcov_sync (offset, length); 309 if ((is_error = gcov_is_error ())) 310 { 311 error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted", 312 da_file_name); 313 htab_delete (counts_hash); 314 break; 315 } 316 } 317 318 gcov_close (); 319 } 320 321 /* Returns the counters for a particular tag. */ 322 323 gcov_type * 324 get_coverage_counts (unsigned counter, unsigned expected, 325 unsigned cfg_checksum, unsigned lineno_checksum, 326 const struct gcov_ctr_summary **summary) 327 { 328 counts_entry_t *entry, elt; 329 330 /* No hash table, no counts. */ 331 if (!counts_hash) 332 { 333 static int warned = 0; 334 335 if (!warned++) 336 inform (input_location, (flag_guess_branch_prob 337 ? "file %s not found, execution counts estimated" 338 : "file %s not found, execution counts assumed to be zero"), 339 da_file_name); 340 return NULL; 341 } 342 343 elt.ident = current_function_funcdef_no + 1; 344 elt.ctr = counter; 345 entry = (counts_entry_t *) htab_find (counts_hash, &elt); 346 if (!entry || !entry->summary.num) 347 /* The function was not emitted, or is weak and not chosen in the 348 final executable. Silently fail, because there's nothing we 349 can do about it. */ 350 return NULL; 351 352 if (entry->cfg_checksum != cfg_checksum 353 || entry->summary.num != expected) 354 { 355 static int warned = 0; 356 bool warning_printed = false; 357 tree id = DECL_ASSEMBLER_NAME (current_function_decl); 358 359 warning_printed = 360 warning_at (input_location, OPT_Wcoverage_mismatch, 361 "the control flow of function %qE does not match " 362 "its profile data (counter %qs)", id, ctr_names[counter]); 363 if (warning_printed) 364 { 365 inform (input_location, "use -Wno-error=coverage-mismatch to tolerate " 366 "the mismatch but performance may drop if the function is hot"); 367 368 if (!seen_error () 369 && !warned++) 370 { 371 inform (input_location, "coverage mismatch ignored"); 372 inform (input_location, flag_guess_branch_prob 373 ? G_("execution counts estimated") 374 : G_("execution counts assumed to be zero")); 375 if (!flag_guess_branch_prob) 376 inform (input_location, 377 "this can result in poorly optimized code"); 378 } 379 } 380 381 return NULL; 382 } 383 else if (entry->lineno_checksum != lineno_checksum) 384 { 385 warning (0, "source locations for function %qE have changed," 386 " the profile data may be out of date", 387 DECL_ASSEMBLER_NAME (current_function_decl)); 388 } 389 390 if (summary) 391 *summary = &entry->summary; 392 393 return entry->counts; 394 } 395 396 /* Allocate NUM counters of type COUNTER. Returns nonzero if the 397 allocation succeeded. */ 398 399 int 400 coverage_counter_alloc (unsigned counter, unsigned num) 401 { 402 if (no_coverage) 403 return 0; 404 405 if (!num) 406 return 1; 407 408 if (!fn_v_ctrs[counter]) 409 { 410 tree array_type = build_array_type (get_gcov_type (), NULL_TREE); 411 412 fn_v_ctrs[counter] 413 = build_var (current_function_decl, array_type, counter); 414 } 415 416 fn_b_ctrs[counter] = fn_n_ctrs[counter]; 417 fn_n_ctrs[counter] += num; 418 419 fn_ctr_mask |= 1 << counter; 420 return 1; 421 } 422 423 /* Generate a tree to access COUNTER NO. */ 424 425 tree 426 tree_coverage_counter_ref (unsigned counter, unsigned no) 427 { 428 tree gcov_type_node = get_gcov_type (); 429 430 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]); 431 432 no += fn_b_ctrs[counter]; 433 434 /* "no" here is an array index, scaled to bytes later. */ 435 return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter], 436 build_int_cst (integer_type_node, no), NULL, NULL); 437 } 438 439 /* Generate a tree to access the address of COUNTER NO. */ 440 441 tree 442 tree_coverage_counter_addr (unsigned counter, unsigned no) 443 { 444 tree gcov_type_node = get_gcov_type (); 445 446 gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]); 447 no += fn_b_ctrs[counter]; 448 449 /* "no" here is an array index, scaled to bytes later. */ 450 return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node, 451 fn_v_ctrs[counter], 452 build_int_cst (integer_type_node, no), 453 NULL, NULL)); 454 } 455 456 457 /* Generate a checksum for a string. CHKSUM is the current 458 checksum. */ 459 460 static unsigned 461 coverage_checksum_string (unsigned chksum, const char *string) 462 { 463 int i; 464 char *dup = NULL; 465 466 /* Look for everything that looks if it were produced by 467 get_file_function_name and zero out the second part 468 that may result from flag_random_seed. This is not critical 469 as the checksums are used only for sanity checking. */ 470 for (i = 0; string[i]; i++) 471 { 472 int offset = 0; 473 if (!strncmp (string + i, "_GLOBAL__N_", 11)) 474 offset = 11; 475 if (!strncmp (string + i, "_GLOBAL__", 9)) 476 offset = 9; 477 478 /* C++ namespaces do have scheme: 479 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname 480 since filename might contain extra underscores there seems 481 to be no better chance then walk all possible offsets looking 482 for magicnumber. */ 483 if (offset) 484 { 485 for (i = i + offset; string[i]; i++) 486 if (string[i]=='_') 487 { 488 int y; 489 490 for (y = 1; y < 9; y++) 491 if (!(string[i + y] >= '0' && string[i + y] <= '9') 492 && !(string[i + y] >= 'A' && string[i + y] <= 'F')) 493 break; 494 if (y != 9 || string[i + 9] != '_') 495 continue; 496 for (y = 10; y < 18; y++) 497 if (!(string[i + y] >= '0' && string[i + y] <= '9') 498 && !(string[i + y] >= 'A' && string[i + y] <= 'F')) 499 break; 500 if (y != 18) 501 continue; 502 if (!dup) 503 string = dup = xstrdup (string); 504 for (y = 10; y < 18; y++) 505 dup[i + y] = '0'; 506 } 507 break; 508 } 509 } 510 511 chksum = crc32_string (chksum, string); 512 free (dup); 513 514 return chksum; 515 } 516 517 /* Compute checksum for the current function. We generate a CRC32. */ 518 519 unsigned 520 coverage_compute_lineno_checksum (void) 521 { 522 expanded_location xloc 523 = expand_location (DECL_SOURCE_LOCATION (current_function_decl)); 524 unsigned chksum = xloc.line; 525 526 chksum = coverage_checksum_string (chksum, xloc.file); 527 chksum = coverage_checksum_string 528 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); 529 530 return chksum; 531 } 532 533 /* Compute cfg checksum for the current function. 534 The checksum is calculated carefully so that 535 source code changes that doesn't affect the control flow graph 536 won't change the checksum. 537 This is to make the profile data useable across source code change. 538 The downside of this is that the compiler may use potentially 539 wrong profile data - that the source code change has non-trivial impact 540 on the validity of profile data (e.g. the reversed condition) 541 but the compiler won't detect the change and use the wrong profile data. */ 542 543 unsigned 544 coverage_compute_cfg_checksum (void) 545 { 546 basic_block bb; 547 unsigned chksum = n_basic_blocks; 548 549 FOR_EACH_BB (bb) 550 { 551 edge e; 552 edge_iterator ei; 553 chksum = crc32_byte (chksum, bb->index); 554 FOR_EACH_EDGE (e, ei, bb->succs) 555 { 556 chksum = crc32_byte (chksum, e->dest->index); 557 } 558 } 559 560 return chksum; 561 } 562 563 /* Begin output to the graph file for the current function. 564 Writes the function header. Returns nonzero if data should be output. */ 565 566 int 567 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum) 568 { 569 expanded_location xloc; 570 unsigned long offset; 571 572 /* We don't need to output .gcno file unless we're under -ftest-coverage 573 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */ 574 if (no_coverage || !bbg_file_name) 575 return 0; 576 577 xloc = expand_location (DECL_SOURCE_LOCATION (current_function_decl)); 578 579 /* Announce function */ 580 offset = gcov_write_tag (GCOV_TAG_FUNCTION); 581 gcov_write_unsigned (current_function_funcdef_no + 1); 582 gcov_write_unsigned (lineno_checksum); 583 gcov_write_unsigned (cfg_checksum); 584 gcov_write_string (IDENTIFIER_POINTER 585 (DECL_ASSEMBLER_NAME (current_function_decl))); 586 gcov_write_string (xloc.file); 587 gcov_write_unsigned (xloc.line); 588 gcov_write_length (offset); 589 590 return !gcov_is_error (); 591 } 592 593 /* Finish coverage data for the current function. Verify no output 594 error has occurred. Save function coverage counts. */ 595 596 void 597 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum) 598 { 599 unsigned i; 600 601 if (bbg_file_name && gcov_is_error ()) 602 { 603 warning (0, "error writing %qs", bbg_file_name); 604 unlink (bbg_file_name); 605 bbg_file_name = NULL; 606 } 607 608 if (fn_ctr_mask) 609 { 610 struct coverage_data *item = 0; 611 612 /* If the function is extern (i.e. extern inline), then we won't 613 be outputting it, so don't chain it onto the function 614 list. */ 615 if (!DECL_EXTERNAL (current_function_decl)) 616 { 617 item = ggc_alloc_coverage_data (); 618 619 item->ident = current_function_funcdef_no + 1; 620 item->lineno_checksum = lineno_checksum; 621 item->cfg_checksum = cfg_checksum; 622 623 item->fn_decl = current_function_decl; 624 item->next = 0; 625 *functions_tail = item; 626 functions_tail = &item->next; 627 } 628 629 for (i = 0; i != GCOV_COUNTERS; i++) 630 { 631 tree var = fn_v_ctrs[i]; 632 633 if (item) 634 item->ctr_vars[i] = var; 635 if (var) 636 { 637 tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1)); 638 array_type = build_array_type (get_gcov_type (), array_type); 639 TREE_TYPE (var) = array_type; 640 DECL_SIZE (var) = TYPE_SIZE (array_type); 641 DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type); 642 varpool_finalize_decl (var); 643 } 644 645 fn_b_ctrs[i] = fn_n_ctrs[i] = 0; 646 fn_v_ctrs[i] = NULL_TREE; 647 } 648 prg_ctr_mask |= fn_ctr_mask; 649 fn_ctr_mask = 0; 650 } 651 } 652 653 /* Build a coverage variable of TYPE for function FN_DECL. If COUNTER 654 >= 0 it is a counter array, otherwise it is the function structure. */ 655 656 static tree 657 build_var (tree fn_decl, tree type, int counter) 658 { 659 tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type); 660 const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl)); 661 char *buf; 662 size_t fn_name_len, len; 663 664 fn_name = targetm.strip_name_encoding (fn_name); 665 fn_name_len = strlen (fn_name); 666 buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3); 667 668 if (counter < 0) 669 strcpy (buf, "__gcov__"); 670 else 671 sprintf (buf, "__gcov%u_", counter); 672 len = strlen (buf); 673 #ifndef NO_DOT_IN_LABEL 674 buf[len - 1] = '.'; 675 #elif !defined NO_DOLLAR_IN_LABEL 676 buf[len - 1] = '$'; 677 #endif 678 memcpy (buf + len, fn_name, fn_name_len + 1); 679 DECL_NAME (var) = get_identifier (buf); 680 TREE_STATIC (var) = 1; 681 TREE_ADDRESSABLE (var) = 1; 682 DECL_ALIGN (var) = TYPE_ALIGN (type); 683 684 return var; 685 } 686 687 /* Creates the gcov_fn_info RECORD_TYPE. */ 688 689 static void 690 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type) 691 { 692 tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE); 693 tree field, fields; 694 tree array_type; 695 696 gcc_assert (counters); 697 698 /* ctr_info::num */ 699 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 700 get_gcov_unsigned_t ()); 701 fields = field; 702 703 /* ctr_info::values */ 704 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 705 build_pointer_type (get_gcov_type ())); 706 DECL_CHAIN (field) = fields; 707 fields = field; 708 709 finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE); 710 711 /* key */ 712 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 713 build_pointer_type (build_qualified_type 714 (gcov_info_type, TYPE_QUAL_CONST))); 715 fields = field; 716 717 /* ident */ 718 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 719 get_gcov_unsigned_t ()); 720 DECL_CHAIN (field) = fields; 721 fields = field; 722 723 /* lineno_checksum */ 724 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 725 get_gcov_unsigned_t ()); 726 DECL_CHAIN (field) = fields; 727 fields = field; 728 729 /* cfg checksum */ 730 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 731 get_gcov_unsigned_t ()); 732 DECL_CHAIN (field) = fields; 733 fields = field; 734 735 array_type = build_index_type (size_int (counters - 1)); 736 array_type = build_array_type (ctr_info, array_type); 737 738 /* counters */ 739 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type); 740 DECL_CHAIN (field) = fields; 741 fields = field; 742 743 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE); 744 } 745 746 /* Returns a CONSTRUCTOR for a gcov_fn_info. DATA is 747 the coverage data for the function and TYPE is the gcov_fn_info 748 RECORD_TYPE. KEY is the object file key. */ 749 750 static tree 751 build_fn_info (const struct coverage_data *data, tree type, tree key) 752 { 753 tree fields = TYPE_FIELDS (type); 754 tree ctr_type; 755 unsigned ix; 756 VEC(constructor_elt,gc) *v1 = NULL; 757 VEC(constructor_elt,gc) *v2 = NULL; 758 759 /* key */ 760 CONSTRUCTOR_APPEND_ELT (v1, fields, 761 build1 (ADDR_EXPR, TREE_TYPE (fields), key)); 762 fields = DECL_CHAIN (fields); 763 764 /* ident */ 765 CONSTRUCTOR_APPEND_ELT (v1, fields, 766 build_int_cstu (get_gcov_unsigned_t (), 767 data->ident)); 768 fields = DECL_CHAIN (fields); 769 770 /* lineno_checksum */ 771 CONSTRUCTOR_APPEND_ELT (v1, fields, 772 build_int_cstu (get_gcov_unsigned_t (), 773 data->lineno_checksum)); 774 fields = DECL_CHAIN (fields); 775 776 /* cfg_checksum */ 777 CONSTRUCTOR_APPEND_ELT (v1, fields, 778 build_int_cstu (get_gcov_unsigned_t (), 779 data->cfg_checksum)); 780 fields = DECL_CHAIN (fields); 781 782 /* counters */ 783 ctr_type = TREE_TYPE (TREE_TYPE (fields)); 784 for (ix = 0; ix != GCOV_COUNTERS; ix++) 785 if (prg_ctr_mask & (1 << ix)) 786 { 787 VEC(constructor_elt,gc) *ctr = NULL; 788 tree var = data->ctr_vars[ix]; 789 unsigned count = 0; 790 791 if (var) 792 count 793 = tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))), 0) 794 + 1; 795 796 CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type), 797 build_int_cstu (get_gcov_unsigned_t (), 798 count)); 799 800 if (var) 801 CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)), 802 build_fold_addr_expr (var)); 803 804 CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr)); 805 } 806 807 CONSTRUCTOR_APPEND_ELT (v1, fields, 808 build_constructor (TREE_TYPE (fields), v2)); 809 810 return build_constructor (type, v1); 811 } 812 813 /* Create gcov_info struct. TYPE is the incomplete RECORD_TYPE to be 814 completed, and FN_INFO_PTR_TYPE is a pointer to the function info type. */ 815 816 static void 817 build_info_type (tree type, tree fn_info_ptr_type) 818 { 819 tree field, fields = NULL_TREE; 820 tree merge_fn_type; 821 822 /* Version ident */ 823 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 824 get_gcov_unsigned_t ()); 825 DECL_CHAIN (field) = fields; 826 fields = field; 827 828 /* next pointer */ 829 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 830 build_pointer_type (build_qualified_type 831 (type, TYPE_QUAL_CONST))); 832 DECL_CHAIN (field) = fields; 833 fields = field; 834 835 /* stamp */ 836 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 837 get_gcov_unsigned_t ()); 838 DECL_CHAIN (field) = fields; 839 fields = field; 840 841 /* Filename */ 842 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 843 build_pointer_type (build_qualified_type 844 (char_type_node, TYPE_QUAL_CONST))); 845 DECL_CHAIN (field) = fields; 846 fields = field; 847 848 /* merge fn array */ 849 merge_fn_type 850 = build_function_type_list (void_type_node, 851 build_pointer_type (get_gcov_type ()), 852 get_gcov_unsigned_t (), NULL_TREE); 853 merge_fn_type 854 = build_array_type (build_pointer_type (merge_fn_type), 855 build_index_type (size_int (GCOV_COUNTERS - 1))); 856 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 857 merge_fn_type); 858 DECL_CHAIN (field) = fields; 859 fields = field; 860 861 /* n_functions */ 862 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 863 get_gcov_unsigned_t ()); 864 DECL_CHAIN (field) = fields; 865 fields = field; 866 867 /* function_info pointer pointer */ 868 fn_info_ptr_type = build_pointer_type 869 (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST)); 870 field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, 871 fn_info_ptr_type); 872 DECL_CHAIN (field) = fields; 873 fields = field; 874 875 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE); 876 } 877 878 /* Returns a CONSTRUCTOR for the gcov_info object. INFO_TYPE is the 879 gcov_info structure type, FN_ARY is the array of pointers to 880 function info objects. */ 881 882 static tree 883 build_info (tree info_type, tree fn_ary) 884 { 885 tree info_fields = TYPE_FIELDS (info_type); 886 tree merge_fn_type, n_funcs; 887 unsigned ix; 888 tree filename_string; 889 int da_file_name_len; 890 VEC(constructor_elt,gc) *v1 = NULL; 891 VEC(constructor_elt,gc) *v2 = NULL; 892 893 /* Version ident */ 894 CONSTRUCTOR_APPEND_ELT (v1, info_fields, 895 build_int_cstu (TREE_TYPE (info_fields), 896 GCOV_VERSION)); 897 info_fields = DECL_CHAIN (info_fields); 898 899 /* next -- NULL */ 900 CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node); 901 info_fields = DECL_CHAIN (info_fields); 902 903 /* stamp */ 904 CONSTRUCTOR_APPEND_ELT (v1, info_fields, 905 build_int_cstu (TREE_TYPE (info_fields), 906 local_tick)); 907 info_fields = DECL_CHAIN (info_fields); 908 909 /* Filename */ 910 da_file_name_len = strlen (da_file_name); 911 filename_string = build_string (da_file_name_len + 1, da_file_name); 912 TREE_TYPE (filename_string) = build_array_type 913 (char_type_node, build_index_type (size_int (da_file_name_len))); 914 CONSTRUCTOR_APPEND_ELT (v1, info_fields, 915 build1 (ADDR_EXPR, TREE_TYPE (info_fields), 916 filename_string)); 917 info_fields = DECL_CHAIN (info_fields); 918 919 /* merge fn array -- NULL slots indicate unmeasured counters */ 920 merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields)); 921 for (ix = 0; ix != GCOV_COUNTERS; ix++) 922 { 923 tree ptr = null_pointer_node; 924 925 if ((1u << ix) & prg_ctr_mask) 926 { 927 tree merge_fn = build_decl (BUILTINS_LOCATION, 928 FUNCTION_DECL, 929 get_identifier (ctr_merge_functions[ix]), 930 TREE_TYPE (merge_fn_type)); 931 DECL_EXTERNAL (merge_fn) = 1; 932 TREE_PUBLIC (merge_fn) = 1; 933 DECL_ARTIFICIAL (merge_fn) = 1; 934 TREE_NOTHROW (merge_fn) = 1; 935 /* Initialize assembler name so we can stream out. */ 936 DECL_ASSEMBLER_NAME (merge_fn); 937 ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn); 938 } 939 CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr); 940 } 941 CONSTRUCTOR_APPEND_ELT (v1, info_fields, 942 build_constructor (TREE_TYPE (info_fields), v2)); 943 info_fields = DECL_CHAIN (info_fields); 944 945 /* n_functions */ 946 n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary))); 947 n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields), 948 n_funcs, size_one_node); 949 CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs); 950 info_fields = DECL_CHAIN (info_fields); 951 952 /* functions */ 953 CONSTRUCTOR_APPEND_ELT (v1, info_fields, 954 build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary)); 955 info_fields = DECL_CHAIN (info_fields); 956 957 gcc_assert (!info_fields); 958 return build_constructor (info_type, v1); 959 } 960 961 /* Create the gcov_info types and object. Generate the constructor 962 function to call __gcov_init. Does not generate the initializer 963 for the object. Returns TRUE if coverage data is being emitted. */ 964 965 static bool 966 coverage_obj_init (void) 967 { 968 tree gcov_info_type, ctor, stmt, init_fn; 969 unsigned n_counters = 0; 970 unsigned ix; 971 struct coverage_data *fn; 972 struct coverage_data **fn_prev; 973 char name_buf[32]; 974 975 no_coverage = 1; /* Disable any further coverage. */ 976 977 if (!prg_ctr_mask) 978 return false; 979 980 if (cgraph_dump_file) 981 fprintf (cgraph_dump_file, "Using data file %s\n", da_file_name); 982 983 /* Prune functions. */ 984 for (fn_prev = &functions_head; (fn = *fn_prev);) 985 if (DECL_STRUCT_FUNCTION (fn->fn_decl)) 986 fn_prev = &fn->next; 987 else 988 /* The function is not being emitted, remove from list. */ 989 *fn_prev = fn->next; 990 991 for (ix = 0; ix != GCOV_COUNTERS; ix++) 992 if ((1u << ix) & prg_ctr_mask) 993 n_counters++; 994 995 /* Build the info and fn_info types. These are mutually recursive. */ 996 gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE); 997 gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE); 998 gcov_fn_info_ptr_type = build_pointer_type 999 (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST)); 1000 build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type); 1001 build_info_type (gcov_info_type, gcov_fn_info_ptr_type); 1002 1003 /* Build the gcov info var, this is referred to in its own 1004 initializer. */ 1005 gcov_info_var = build_decl (BUILTINS_LOCATION, 1006 VAR_DECL, NULL_TREE, gcov_info_type); 1007 TREE_STATIC (gcov_info_var) = 1; 1008 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0); 1009 DECL_NAME (gcov_info_var) = get_identifier (name_buf); 1010 1011 /* Build a decl for __gcov_init. */ 1012 init_fn = build_pointer_type (gcov_info_type); 1013 init_fn = build_function_type_list (void_type_node, init_fn, NULL); 1014 init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, 1015 get_identifier ("__gcov_init"), init_fn); 1016 TREE_PUBLIC (init_fn) = 1; 1017 DECL_EXTERNAL (init_fn) = 1; 1018 DECL_ASSEMBLER_NAME (init_fn); 1019 1020 /* Generate a call to __gcov_init(&gcov_info). */ 1021 ctor = NULL; 1022 stmt = build_fold_addr_expr (gcov_info_var); 1023 stmt = build_call_expr (init_fn, 1, stmt); 1024 append_to_statement_list (stmt, &ctor); 1025 1026 /* Generate a constructor to run it. */ 1027 cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY); 1028 1029 return true; 1030 } 1031 1032 /* Generate the coverage function info for FN and DATA. Append a 1033 pointer to that object to CTOR and return the appended CTOR. */ 1034 1035 static VEC(constructor_elt,gc) * 1036 coverage_obj_fn (VEC(constructor_elt,gc) *ctor, tree fn, 1037 struct coverage_data const *data) 1038 { 1039 tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var); 1040 tree var = build_var (fn, gcov_fn_info_type, -1); 1041 1042 DECL_INITIAL (var) = init; 1043 varpool_finalize_decl (var); 1044 1045 CONSTRUCTOR_APPEND_ELT (ctor, NULL, 1046 build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var)); 1047 return ctor; 1048 } 1049 1050 /* Finalize the coverage data. Generates the array of pointers to 1051 function objects from CTOR. Generate the gcov_info initializer. */ 1052 1053 static void 1054 coverage_obj_finish (VEC(constructor_elt,gc) *ctor) 1055 { 1056 unsigned n_functions = VEC_length(constructor_elt, ctor); 1057 tree fn_info_ary_type = build_array_type 1058 (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST), 1059 build_index_type (size_int (n_functions - 1))); 1060 tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, 1061 fn_info_ary_type); 1062 char name_buf[32]; 1063 1064 TREE_STATIC (fn_info_ary) = 1; 1065 ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1); 1066 DECL_NAME (fn_info_ary) = get_identifier (name_buf); 1067 DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor); 1068 varpool_finalize_decl (fn_info_ary); 1069 1070 DECL_INITIAL (gcov_info_var) 1071 = build_info (TREE_TYPE (gcov_info_var), fn_info_ary); 1072 varpool_finalize_decl (gcov_info_var); 1073 } 1074 1075 /* Perform file-level initialization. Read in data file, generate name 1076 of graph file. */ 1077 1078 void 1079 coverage_init (const char *filename) 1080 { 1081 int len = strlen (filename); 1082 int prefix_len = 0; 1083 1084 if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename)) 1085 profile_data_prefix = getpwd (); 1086 1087 if (profile_data_prefix) 1088 prefix_len = strlen (profile_data_prefix); 1089 1090 /* Name of da file. */ 1091 da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX) 1092 + prefix_len + 2); 1093 1094 if (profile_data_prefix) 1095 { 1096 memcpy (da_file_name, profile_data_prefix, prefix_len); 1097 da_file_name[prefix_len++] = '/'; 1098 } 1099 memcpy (da_file_name + prefix_len, filename, len); 1100 strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX); 1101 1102 /* Name of bbg file. */ 1103 if (flag_test_coverage && !flag_compare_debug) 1104 { 1105 bbg_file_name = XNEWVEC (char, len + strlen (GCOV_NOTE_SUFFIX) + 1); 1106 memcpy (bbg_file_name, filename, len); 1107 strcpy (bbg_file_name + len, GCOV_NOTE_SUFFIX); 1108 1109 if (!gcov_open (bbg_file_name, -1)) 1110 { 1111 error ("cannot open %s", bbg_file_name); 1112 bbg_file_name = NULL; 1113 } 1114 else 1115 { 1116 gcov_write_unsigned (GCOV_NOTE_MAGIC); 1117 gcov_write_unsigned (GCOV_VERSION); 1118 gcov_write_unsigned (local_tick); 1119 } 1120 } 1121 1122 if (flag_branch_probabilities) 1123 read_counts_file (); 1124 } 1125 1126 /* Performs file-level cleanup. Close graph file, generate coverage 1127 variables and constructor. */ 1128 1129 void 1130 coverage_finish (void) 1131 { 1132 if (bbg_file_name && gcov_close ()) 1133 unlink (bbg_file_name); 1134 1135 if (!local_tick || local_tick == (unsigned)-1) 1136 /* Only remove the da file, if we cannot stamp it. If we can 1137 stamp it, libgcov will DTRT. */ 1138 unlink (da_file_name); 1139 1140 if (coverage_obj_init ()) 1141 { 1142 VEC(constructor_elt,gc) *fn_ctor = NULL; 1143 struct coverage_data *fn; 1144 1145 for (fn = functions_head; fn; fn = fn->next) 1146 fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn); 1147 coverage_obj_finish (fn_ctor); 1148 } 1149 } 1150 1151 #include "gt-coverage.h" 1152