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
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
10 This file is part of GCC.
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
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
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/>. */
31 #include "coretypes.h"
40 #include "basic-block.h"
45 #include "langhooks.h"
47 #include "tree-iterator.h"
49 #include "tree-pass.h"
50 #include "diagnostic-core.h"
52 #include "filenames.h"
59 struct function_list
*next
; /* next function */
60 unsigned ident
; /* function ident */
61 unsigned lineno_checksum
; /* function lineno checksum */
62 unsigned cfg_checksum
; /* function cfg checksum */
63 unsigned n_ctrs
[GCOV_COUNTERS
];/* number of counters. */
66 /* Counts information for a function. */
67 typedef struct counts_entry
74 unsigned lineno_checksum
;
75 unsigned cfg_checksum
;
77 struct gcov_ctr_summary summary
;
80 struct counts_entry
*chain
;
84 static struct function_list
*functions_head
= 0;
85 static struct function_list
**functions_tail
= &functions_head
;
86 static unsigned no_coverage
= 0;
88 /* Cumulative counter information for whole program. */
89 static unsigned prg_ctr_mask
; /* Mask of counter types generated. */
90 static unsigned prg_n_ctrs
[GCOV_COUNTERS
]; /* Total counters allocated. */
92 /* Counter information for current function. */
93 static unsigned fn_ctr_mask
; /* Mask of counters used. */
94 static unsigned fn_n_ctrs
[GCOV_COUNTERS
]; /* Counters allocated. */
95 static unsigned fn_b_ctrs
[GCOV_COUNTERS
]; /* Allocation base. */
97 /* Name of the output file for coverage output file. */
98 static char *bbg_file_name
;
99 static unsigned bbg_file_opened
;
100 static int bbg_function_announced
;
102 /* Name of the count data file. */
103 static char *da_file_name
;
105 /* Hash table of count data. */
106 static htab_t counts_hash
= NULL
;
108 /* Trees representing the counter table arrays. */
109 static GTY(()) tree tree_ctr_tables
[GCOV_COUNTERS
];
111 /* The names of merge functions for counters. */
112 static const char *const ctr_merge_functions
[GCOV_COUNTERS
] = GCOV_MERGE_FUNCTIONS
;
113 static const char *const ctr_names
[GCOV_COUNTERS
] = GCOV_COUNTER_NAMES
;
115 /* Forward declarations. */
116 static hashval_t
htab_counts_entry_hash (const void *);
117 static int htab_counts_entry_eq (const void *, const void *);
118 static void htab_counts_entry_del (void *);
119 static void read_counts_file (void);
120 static tree
build_fn_info_type (unsigned);
121 static tree
build_fn_info_value (const struct function_list
*, tree
);
122 static tree
build_ctr_info_type (void);
123 static tree
build_ctr_info_value (unsigned, tree
);
124 static tree
build_gcov_info (void);
125 static void create_coverage (void);
127 /* Return the type node for gcov_type. */
132 return lang_hooks
.types
.type_for_size (GCOV_TYPE_SIZE
, false);
135 /* Return the type node for gcov_unsigned_t. */
138 get_gcov_unsigned_t (void)
140 return lang_hooks
.types
.type_for_size (32, true);
144 htab_counts_entry_hash (const void *of
)
146 const counts_entry_t
*const entry
= (const counts_entry_t
*) of
;
148 return entry
->ident
* GCOV_COUNTERS
+ entry
->ctr
;
152 htab_counts_entry_eq (const void *of1
, const void *of2
)
154 const counts_entry_t
*const entry1
= (const counts_entry_t
*) of1
;
155 const counts_entry_t
*const entry2
= (const counts_entry_t
*) of2
;
157 return entry1
->ident
== entry2
->ident
&& entry1
->ctr
== entry2
->ctr
;
161 htab_counts_entry_del (void *of
)
163 counts_entry_t
*const entry
= (counts_entry_t
*) of
;
165 free (entry
->counts
);
169 /* Read in the counts file, if available. */
172 read_counts_file (void)
174 gcov_unsigned_t fn_ident
= 0;
175 counts_entry_t
*summaried
= NULL
;
176 unsigned seen_summary
= 0;
179 unsigned lineno_checksum
= 0;
180 unsigned cfg_checksum
= 0;
182 if (!gcov_open (da_file_name
, 1))
185 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC
))
187 warning (0, "%qs is not a gcov data file", da_file_name
);
191 else if ((tag
= gcov_read_unsigned ()) != GCOV_VERSION
)
195 GCOV_UNSIGNED2STRING (v
, tag
);
196 GCOV_UNSIGNED2STRING (e
, GCOV_VERSION
);
198 warning (0, "%qs is version %q.*s, expected version %q.*s",
199 da_file_name
, 4, v
, 4, e
);
204 /* Read and discard the stamp. */
205 gcov_read_unsigned ();
207 counts_hash
= htab_create (10,
208 htab_counts_entry_hash
, htab_counts_entry_eq
,
209 htab_counts_entry_del
);
210 while ((tag
= gcov_read_unsigned ()))
212 gcov_unsigned_t length
;
213 gcov_position_t offset
;
215 length
= gcov_read_unsigned ();
216 offset
= gcov_position ();
217 if (tag
== GCOV_TAG_FUNCTION
)
219 fn_ident
= gcov_read_unsigned ();
220 lineno_checksum
= gcov_read_unsigned ();
221 cfg_checksum
= gcov_read_unsigned ();
224 /* We have already seen a summary, this means that this
225 new function begins a new set of program runs. We
226 must unlink the summaried chain. */
227 counts_entry_t
*entry
, *chain
;
229 for (entry
= summaried
; entry
; entry
= chain
)
231 chain
= entry
->chain
;
238 else if (tag
== GCOV_TAG_PROGRAM_SUMMARY
)
240 counts_entry_t
*entry
;
241 struct gcov_summary summary
;
243 gcov_read_summary (&summary
);
245 for (entry
= summaried
; entry
; entry
= entry
->chain
)
247 struct gcov_ctr_summary
*csum
= &summary
.ctrs
[entry
->ctr
];
249 entry
->summary
.runs
+= csum
->runs
;
250 entry
->summary
.sum_all
+= csum
->sum_all
;
251 if (entry
->summary
.run_max
< csum
->run_max
)
252 entry
->summary
.run_max
= csum
->run_max
;
253 entry
->summary
.sum_max
+= csum
->sum_max
;
256 else if (GCOV_TAG_IS_COUNTER (tag
) && fn_ident
)
258 counts_entry_t
**slot
, *entry
, elt
;
259 unsigned n_counts
= GCOV_TAG_COUNTER_NUM (length
);
262 elt
.ident
= fn_ident
;
263 elt
.ctr
= GCOV_COUNTER_FOR_TAG (tag
);
265 slot
= (counts_entry_t
**) htab_find_slot
266 (counts_hash
, &elt
, INSERT
);
270 *slot
= entry
= XCNEW (counts_entry_t
);
271 entry
->ident
= fn_ident
;
272 entry
->ctr
= elt
.ctr
;
273 entry
->lineno_checksum
= lineno_checksum
;
274 entry
->cfg_checksum
= cfg_checksum
;
275 entry
->summary
.num
= n_counts
;
276 entry
->counts
= XCNEWVEC (gcov_type
, n_counts
);
278 else if (entry
->lineno_checksum
!= lineno_checksum
279 || entry
->cfg_checksum
!= cfg_checksum
)
281 error ("Profile data for function %u is corrupted", fn_ident
);
282 error ("checksum is (%x,%x) instead of (%x,%x)",
283 entry
->lineno_checksum
, entry
->cfg_checksum
,
284 lineno_checksum
, cfg_checksum
);
285 htab_delete (counts_hash
);
288 else if (entry
->summary
.num
!= n_counts
)
290 error ("Profile data for function %u is corrupted", fn_ident
);
291 error ("number of counters is %d instead of %d", entry
->summary
.num
, n_counts
);
292 htab_delete (counts_hash
);
295 else if (elt
.ctr
>= GCOV_COUNTERS_SUMMABLE
)
297 error ("cannot merge separate %s counters for function %u",
298 ctr_names
[elt
.ctr
], fn_ident
);
302 if (elt
.ctr
< GCOV_COUNTERS_SUMMABLE
303 /* This should always be true for a just allocated entry,
304 and always false for an existing one. Check this way, in
305 case the gcov file is corrupt. */
306 && (!entry
->chain
|| summaried
!= entry
))
308 entry
->chain
= summaried
;
311 for (ix
= 0; ix
!= n_counts
; ix
++)
312 entry
->counts
[ix
] += gcov_read_counter ();
315 gcov_sync (offset
, length
);
316 if ((is_error
= gcov_is_error ()))
318 error (is_error
< 0 ? "%qs has overflowed" : "%qs is corrupted",
320 htab_delete (counts_hash
);
328 /* Returns the counters for a particular tag. */
331 get_coverage_counts (unsigned counter
, unsigned expected
,
332 unsigned cfg_checksum
, unsigned lineno_checksum
,
333 const struct gcov_ctr_summary
**summary
)
335 counts_entry_t
*entry
, elt
;
337 /* No hash table, no counts. */
340 static int warned
= 0;
343 inform (input_location
, (flag_guess_branch_prob
344 ? "file %s not found, execution counts estimated"
345 : "file %s not found, execution counts assumed to be zero"),
350 elt
.ident
= current_function_funcdef_no
+ 1;
352 entry
= (counts_entry_t
*) htab_find (counts_hash
, &elt
);
355 warning (0, "no coverage for function %qE found",
356 DECL_ASSEMBLER_NAME (current_function_decl
));
360 if (entry
->cfg_checksum
!= cfg_checksum
361 || entry
->summary
.num
!= expected
)
363 static int warned
= 0;
364 bool warning_printed
= false;
365 tree id
= DECL_ASSEMBLER_NAME (current_function_decl
);
368 warning_at (input_location
, OPT_Wcoverage_mismatch
,
369 "The control flow of function %qE does not match "
370 "its profile data (counter %qs)", id
, ctr_names
[counter
]);
373 inform (input_location
, "Use -Wno-error=coverage-mismatch to tolerate "
374 "the mismatch but performance may drop if the function is hot");
379 inform (input_location
, "coverage mismatch ignored");
380 inform (input_location
, flag_guess_branch_prob
381 ? G_("execution counts estimated")
382 : G_("execution counts assumed to be zero"));
383 if (!flag_guess_branch_prob
)
384 inform (input_location
,
385 "this can result in poorly optimized code");
391 else if (entry
->lineno_checksum
!= lineno_checksum
)
393 warning (0, "Source location for function %qE have changed,"
394 " the profile data may be out of date",
395 DECL_ASSEMBLER_NAME (current_function_decl
));
399 *summary
= &entry
->summary
;
401 return entry
->counts
;
404 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
405 allocation succeeded. */
408 coverage_counter_alloc (unsigned counter
, unsigned num
)
416 if (!tree_ctr_tables
[counter
])
418 /* Generate and save a copy of this so it can be shared. Leave
419 the index type unspecified for now; it will be set after all
420 functions have been compiled. */
422 tree gcov_type_node
= get_gcov_type ();
423 tree gcov_type_array_type
424 = build_array_type (gcov_type_node
, NULL_TREE
);
425 tree_ctr_tables
[counter
]
426 = build_decl (BUILTINS_LOCATION
,
427 VAR_DECL
, NULL_TREE
, gcov_type_array_type
);
428 TREE_STATIC (tree_ctr_tables
[counter
]) = 1;
429 ASM_GENERATE_INTERNAL_LABEL (buf
, "LPBX", counter
+ 1);
430 DECL_NAME (tree_ctr_tables
[counter
]) = get_identifier (buf
);
431 DECL_ALIGN (tree_ctr_tables
[counter
]) = TYPE_ALIGN (gcov_type_node
);
434 fprintf (dump_file
, "Using data file %s\n", da_file_name
);
436 fn_b_ctrs
[counter
] = fn_n_ctrs
[counter
];
437 fn_n_ctrs
[counter
] += num
;
438 fn_ctr_mask
|= 1 << counter
;
442 /* Generate a tree to access COUNTER NO. */
445 tree_coverage_counter_ref (unsigned counter
, unsigned no
)
447 tree gcov_type_node
= get_gcov_type ();
449 gcc_assert (no
< fn_n_ctrs
[counter
] - fn_b_ctrs
[counter
]);
450 no
+= prg_n_ctrs
[counter
] + fn_b_ctrs
[counter
];
452 /* "no" here is an array index, scaled to bytes later. */
453 return build4 (ARRAY_REF
, gcov_type_node
, tree_ctr_tables
[counter
],
454 build_int_cst (NULL_TREE
, no
), NULL
, NULL
);
457 /* Generate a tree to access the address of COUNTER NO. */
460 tree_coverage_counter_addr (unsigned counter
, unsigned no
)
462 tree gcov_type_node
= get_gcov_type ();
464 gcc_assert (no
< fn_n_ctrs
[counter
] - fn_b_ctrs
[counter
]);
465 no
+= prg_n_ctrs
[counter
] + fn_b_ctrs
[counter
];
467 TREE_ADDRESSABLE (tree_ctr_tables
[counter
]) = 1;
469 /* "no" here is an array index, scaled to bytes later. */
470 return build_fold_addr_expr (build4 (ARRAY_REF
, gcov_type_node
,
471 tree_ctr_tables
[counter
],
472 build_int_cst (NULL_TREE
, no
),
477 /* Generate a checksum for a string. CHKSUM is the current
481 coverage_checksum_string (unsigned chksum
, const char *string
)
486 /* Look for everything that looks if it were produced by
487 get_file_function_name and zero out the second part
488 that may result from flag_random_seed. This is not critical
489 as the checksums are used only for sanity checking. */
490 for (i
= 0; string
[i
]; i
++)
493 if (!strncmp (string
+ i
, "_GLOBAL__N_", 11))
495 if (!strncmp (string
+ i
, "_GLOBAL__", 9))
498 /* C++ namespaces do have scheme:
499 _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
500 since filename might contain extra underscores there seems
501 to be no better chance then walk all possible offsets looking
505 for (i
= i
+ offset
; string
[i
]; i
++)
510 for (y
= 1; y
< 9; y
++)
511 if (!(string
[i
+ y
] >= '0' && string
[i
+ y
] <= '9')
512 && !(string
[i
+ y
] >= 'A' && string
[i
+ y
] <= 'F'))
514 if (y
!= 9 || string
[i
+ 9] != '_')
516 for (y
= 10; y
< 18; y
++)
517 if (!(string
[i
+ y
] >= '0' && string
[i
+ y
] <= '9')
518 && !(string
[i
+ y
] >= 'A' && string
[i
+ y
] <= 'F'))
523 string
= dup
= xstrdup (string
);
524 for (y
= 10; y
< 18; y
++)
531 chksum
= crc32_string (chksum
, string
);
537 /* Compute checksum for the current function. We generate a CRC32. */
540 coverage_compute_lineno_checksum (void)
542 expanded_location xloc
543 = expand_location (DECL_SOURCE_LOCATION (current_function_decl
));
544 unsigned chksum
= xloc
.line
;
546 chksum
= coverage_checksum_string (chksum
, xloc
.file
);
547 chksum
= coverage_checksum_string
548 (chksum
, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl
)));
553 /* Compute cfg checksum for the current function.
554 The checksum is calculated carefully so that
555 source code changes that doesn't affect the control flow graph
556 won't change the checksum.
557 This is to make the profile data useable across source code change.
558 The downside of this is that the compiler may use potentially
559 wrong profile data - that the source code change has non-trivial impact
560 on the validity of profile data (e.g. the reversed condition)
561 but the compiler won't detect the change and use the wrong profile data. */
564 coverage_compute_cfg_checksum (void)
567 unsigned chksum
= n_basic_blocks
;
573 chksum
= crc32_byte (chksum
, bb
->index
);
574 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
576 chksum
= crc32_byte (chksum
, e
->dest
->index
);
583 /* Begin output to the graph file for the current function.
584 Opens the output file, if not already done. Writes the
585 function header, if not already done. Returns nonzero if data
589 coverage_begin_output (unsigned lineno_checksum
, unsigned cfg_checksum
)
591 /* We don't need to output .gcno file unless we're under -ftest-coverage
592 (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
593 if (no_coverage
|| !flag_test_coverage
|| flag_compare_debug
)
596 if (!bbg_function_announced
)
598 expanded_location xloc
599 = expand_location (DECL_SOURCE_LOCATION (current_function_decl
));
600 unsigned long offset
;
602 if (!bbg_file_opened
)
604 if (!gcov_open (bbg_file_name
, -1))
605 error ("cannot open %s", bbg_file_name
);
608 gcov_write_unsigned (GCOV_NOTE_MAGIC
);
609 gcov_write_unsigned (GCOV_VERSION
);
610 gcov_write_unsigned (local_tick
);
616 /* Announce function */
617 offset
= gcov_write_tag (GCOV_TAG_FUNCTION
);
618 gcov_write_unsigned (current_function_funcdef_no
+ 1);
619 gcov_write_unsigned (lineno_checksum
);
620 gcov_write_unsigned (cfg_checksum
);
621 gcov_write_string (IDENTIFIER_POINTER
622 (DECL_ASSEMBLER_NAME (current_function_decl
)));
623 gcov_write_string (xloc
.file
);
624 gcov_write_unsigned (xloc
.line
);
625 gcov_write_length (offset
);
627 bbg_function_announced
= 1;
629 return !gcov_is_error ();
632 /* Finish coverage data for the current function. Verify no output
633 error has occurred. Save function coverage counts. */
636 coverage_end_function (unsigned lineno_checksum
, unsigned cfg_checksum
)
640 if (bbg_file_opened
> 1 && gcov_is_error ())
642 warning (0, "error writing %qs", bbg_file_name
);
643 bbg_file_opened
= -1;
648 struct function_list
*item
;
650 item
= XNEW (struct function_list
);
652 *functions_tail
= item
;
653 functions_tail
= &item
->next
;
657 item
->ident
= current_function_funcdef_no
+ 1;
658 item
->lineno_checksum
= lineno_checksum
;
659 item
->cfg_checksum
= cfg_checksum
;
660 for (i
= 0; i
!= GCOV_COUNTERS
; i
++)
662 item
->n_ctrs
[i
] = fn_n_ctrs
[i
];
663 prg_n_ctrs
[i
] += fn_n_ctrs
[i
];
664 fn_n_ctrs
[i
] = fn_b_ctrs
[i
] = 0;
666 prg_ctr_mask
|= fn_ctr_mask
;
669 bbg_function_announced
= 0;
672 /* Creates the gcov_fn_info RECORD_TYPE. */
675 build_fn_info_type (unsigned int counters
)
677 tree type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
682 fields
= build_decl (BUILTINS_LOCATION
,
683 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
684 /* lineno_checksum */
685 field
= build_decl (BUILTINS_LOCATION
,
686 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
687 DECL_CHAIN (field
) = fields
;
691 field
= build_decl (BUILTINS_LOCATION
,
692 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
693 DECL_CHAIN (field
) = fields
;
696 array_type
= build_int_cst (NULL_TREE
, counters
- 1);
697 array_type
= build_index_type (array_type
);
698 array_type
= build_array_type (get_gcov_unsigned_t (), array_type
);
701 field
= build_decl (BUILTINS_LOCATION
,
702 FIELD_DECL
, NULL_TREE
, array_type
);
703 DECL_CHAIN (field
) = fields
;
706 finish_builtin_struct (type
, "__gcov_fn_info", fields
, NULL_TREE
);
711 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
712 the function being processed and TYPE is the gcov_fn_info
716 build_fn_info_value (const struct function_list
*function
, tree type
)
718 tree fields
= TYPE_FIELDS (type
);
720 VEC(constructor_elt
,gc
) *v1
= NULL
;
721 VEC(constructor_elt
,gc
) *v2
= NULL
;
724 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
725 build_int_cstu (get_gcov_unsigned_t (),
727 fields
= DECL_CHAIN (fields
);
729 /* lineno_checksum */
730 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
731 build_int_cstu (get_gcov_unsigned_t (),
732 function
->lineno_checksum
));
733 fields
= DECL_CHAIN (fields
);
736 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
737 build_int_cstu (get_gcov_unsigned_t (),
738 function
->cfg_checksum
));
739 fields
= DECL_CHAIN (fields
);
742 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
743 if (prg_ctr_mask
& (1 << ix
))
744 CONSTRUCTOR_APPEND_ELT (v2
, NULL
,
745 build_int_cstu (get_gcov_unsigned_t (),
746 function
->n_ctrs
[ix
]));
748 CONSTRUCTOR_APPEND_ELT (v1
, fields
,
749 build_constructor (TREE_TYPE (fields
), v2
));
751 return build_constructor (type
, v1
);
754 /* Creates the gcov_ctr_info RECORD_TYPE. */
757 build_ctr_info_type (void)
759 tree type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
760 tree field
, fields
= NULL_TREE
;
761 tree gcov_ptr_type
= build_pointer_type (get_gcov_type ());
762 tree gcov_merge_fn_type
;
765 field
= build_decl (BUILTINS_LOCATION
,
766 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
767 DECL_CHAIN (field
) = fields
;
771 field
= build_decl (BUILTINS_LOCATION
,
772 FIELD_DECL
, NULL_TREE
, gcov_ptr_type
);
773 DECL_CHAIN (field
) = fields
;
778 build_function_type_list (void_type_node
,
779 gcov_ptr_type
, get_gcov_unsigned_t (),
781 field
= build_decl (BUILTINS_LOCATION
,
782 FIELD_DECL
, NULL_TREE
,
783 build_pointer_type (gcov_merge_fn_type
));
784 DECL_CHAIN (field
) = fields
;
787 finish_builtin_struct (type
, "__gcov_ctr_info", fields
, NULL_TREE
);
792 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
793 the counter being processed and TYPE is the gcov_ctr_info
797 build_ctr_info_value (unsigned int counter
, tree type
)
799 tree fields
= TYPE_FIELDS (type
);
801 VEC(constructor_elt
,gc
) *v
= NULL
;
804 CONSTRUCTOR_APPEND_ELT (v
, fields
,
805 build_int_cstu (get_gcov_unsigned_t (),
806 prg_n_ctrs
[counter
]));
807 fields
= DECL_CHAIN (fields
);
809 if (prg_n_ctrs
[counter
])
813 array_type
= build_int_cstu (get_gcov_unsigned_t (),
814 prg_n_ctrs
[counter
] - 1);
815 array_type
= build_index_type (array_type
);
816 array_type
= build_array_type (TREE_TYPE (TREE_TYPE (fields
)),
819 TREE_TYPE (tree_ctr_tables
[counter
]) = array_type
;
820 DECL_SIZE (tree_ctr_tables
[counter
]) = TYPE_SIZE (array_type
);
821 DECL_SIZE_UNIT (tree_ctr_tables
[counter
]) = TYPE_SIZE_UNIT (array_type
);
822 varpool_finalize_decl (tree_ctr_tables
[counter
]);
824 CONSTRUCTOR_APPEND_ELT (v
, fields
,
825 build1 (ADDR_EXPR
, TREE_TYPE (fields
),
826 tree_ctr_tables
[counter
]));
829 CONSTRUCTOR_APPEND_ELT (v
, fields
, null_pointer_node
);
830 fields
= DECL_CHAIN (fields
);
832 fn
= build_decl (BUILTINS_LOCATION
,
834 get_identifier (ctr_merge_functions
[counter
]),
835 TREE_TYPE (TREE_TYPE (fields
)));
836 DECL_EXTERNAL (fn
) = 1;
837 TREE_PUBLIC (fn
) = 1;
838 DECL_ARTIFICIAL (fn
) = 1;
839 TREE_NOTHROW (fn
) = 1;
840 DECL_ASSEMBLER_NAME (fn
); /* Initialize assembler name so we can stream out. */
841 CONSTRUCTOR_APPEND_ELT (v
, fields
, build1 (ADDR_EXPR
, TREE_TYPE (fields
), fn
));
843 return build_constructor (type
, v
);
846 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
850 build_gcov_info (void)
852 unsigned n_ctr_types
, ix
;
853 tree type
, const_type
;
854 tree fn_info_type
, fn_info_value
= NULL_TREE
;
855 tree fn_info_ptr_type
;
856 tree ctr_info_type
, ctr_info_ary_type
, ctr_info_value
= NULL_TREE
;
857 tree field
, fields
= NULL_TREE
;
858 tree filename_string
;
859 int da_file_name_len
;
861 const struct function_list
*fn
;
863 VEC(constructor_elt
,gc
) *v1
= NULL
;
864 VEC(constructor_elt
,gc
) *v2
= NULL
;
866 /* Count the number of active counters. */
867 for (n_ctr_types
= 0, ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
868 if (prg_ctr_mask
& (1 << ix
))
871 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
872 const_type
= build_qualified_type (type
, TYPE_QUAL_CONST
);
875 field
= build_decl (BUILTINS_LOCATION
,
876 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
877 DECL_CHAIN (field
) = fields
;
879 CONSTRUCTOR_APPEND_ELT (v1
, field
,
880 build_int_cstu (TREE_TYPE (field
), GCOV_VERSION
));
883 field
= build_decl (BUILTINS_LOCATION
,
884 FIELD_DECL
, NULL_TREE
, build_pointer_type (const_type
));
885 DECL_CHAIN (field
) = fields
;
887 CONSTRUCTOR_APPEND_ELT (v1
, field
, null_pointer_node
);
890 field
= build_decl (BUILTINS_LOCATION
,
891 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
892 DECL_CHAIN (field
) = fields
;
894 CONSTRUCTOR_APPEND_ELT (v1
, field
,
895 build_int_cstu (TREE_TYPE (field
), local_tick
));
898 string_type
= build_pointer_type (build_qualified_type (char_type_node
,
900 field
= build_decl (BUILTINS_LOCATION
,
901 FIELD_DECL
, NULL_TREE
, string_type
);
902 DECL_CHAIN (field
) = fields
;
904 da_file_name_len
= strlen (da_file_name
);
905 filename_string
= build_string (da_file_name_len
+ 1, da_file_name
);
906 TREE_TYPE (filename_string
) = build_array_type
907 (char_type_node
, build_index_type
908 (build_int_cst (NULL_TREE
, da_file_name_len
)));
909 CONSTRUCTOR_APPEND_ELT (v1
, field
,
910 build1 (ADDR_EXPR
, string_type
, filename_string
));
912 /* Build the fn_info type and initializer. */
913 fn_info_type
= build_fn_info_type (n_ctr_types
);
914 fn_info_ptr_type
= build_pointer_type (build_qualified_type
915 (fn_info_type
, TYPE_QUAL_CONST
));
916 for (fn
= functions_head
, n_fns
= 0; fn
; fn
= fn
->next
, n_fns
++)
917 CONSTRUCTOR_APPEND_ELT (v2
, NULL_TREE
,
918 build_fn_info_value (fn
, fn_info_type
));
924 array_type
= build_index_type (build_int_cst (NULL_TREE
, n_fns
- 1));
925 array_type
= build_array_type (fn_info_type
, array_type
);
927 fn_info_value
= build_constructor (array_type
, v2
);
928 fn_info_value
= build1 (ADDR_EXPR
, fn_info_ptr_type
, fn_info_value
);
931 fn_info_value
= null_pointer_node
;
933 /* number of functions */
934 field
= build_decl (BUILTINS_LOCATION
,
935 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
936 DECL_CHAIN (field
) = fields
;
938 CONSTRUCTOR_APPEND_ELT (v1
, field
,
939 build_int_cstu (get_gcov_unsigned_t (), n_fns
));
942 field
= build_decl (BUILTINS_LOCATION
,
943 FIELD_DECL
, NULL_TREE
, fn_info_ptr_type
);
944 DECL_CHAIN (field
) = fields
;
946 CONSTRUCTOR_APPEND_ELT (v1
, field
, fn_info_value
);
949 field
= build_decl (BUILTINS_LOCATION
,
950 FIELD_DECL
, NULL_TREE
, get_gcov_unsigned_t ());
951 DECL_CHAIN (field
) = fields
;
953 CONSTRUCTOR_APPEND_ELT (v1
, field
,
954 build_int_cstu (get_gcov_unsigned_t (),
958 ctr_info_type
= build_ctr_info_type ();
959 ctr_info_ary_type
= build_index_type (build_int_cst (NULL_TREE
,
961 ctr_info_ary_type
= build_array_type (ctr_info_type
, ctr_info_ary_type
);
963 for (ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
964 if (prg_ctr_mask
& (1 << ix
))
965 CONSTRUCTOR_APPEND_ELT (v2
, NULL_TREE
,
966 build_ctr_info_value (ix
, ctr_info_type
));
967 ctr_info_value
= build_constructor (ctr_info_ary_type
, v2
);
969 field
= build_decl (BUILTINS_LOCATION
,
970 FIELD_DECL
, NULL_TREE
, ctr_info_ary_type
);
971 DECL_CHAIN (field
) = fields
;
973 CONSTRUCTOR_APPEND_ELT (v1
, field
, ctr_info_value
);
975 finish_builtin_struct (type
, "__gcov_info", fields
, NULL_TREE
);
977 return build_constructor (type
, v1
);
980 /* Write out the structure which libgcov uses to locate all the
981 counters. The structures used here must match those defined in
982 gcov-io.h. Write out the constructor to call __gcov_init. */
985 create_coverage (void)
987 tree gcov_info
, gcov_init
, body
, t
;
990 no_coverage
= 1; /* Disable any further coverage. */
995 t
= build_gcov_info ();
997 gcov_info
= build_decl (BUILTINS_LOCATION
,
998 VAR_DECL
, NULL_TREE
, TREE_TYPE (t
));
999 TREE_STATIC (gcov_info
) = 1;
1000 ASM_GENERATE_INTERNAL_LABEL (name_buf
, "LPBX", 0);
1001 DECL_NAME (gcov_info
) = get_identifier (name_buf
);
1002 DECL_INITIAL (gcov_info
) = t
;
1004 /* Build structure. */
1005 varpool_finalize_decl (gcov_info
);
1007 /* Build a decl for __gcov_init. */
1008 t
= build_pointer_type (TREE_TYPE (gcov_info
));
1009 t
= build_function_type_list (void_type_node
, t
, NULL
);
1010 t
= build_decl (BUILTINS_LOCATION
,
1011 FUNCTION_DECL
, get_identifier ("__gcov_init"), t
);
1012 TREE_PUBLIC (t
) = 1;
1013 DECL_EXTERNAL (t
) = 1;
1014 DECL_ASSEMBLER_NAME (t
); /* Initialize assembler name so we can stream out. */
1017 /* Generate a call to __gcov_init(&gcov_info). */
1019 t
= build_fold_addr_expr (gcov_info
);
1020 t
= build_call_expr (gcov_init
, 1, t
);
1021 append_to_statement_list (t
, &body
);
1023 /* Generate a constructor to run it. */
1024 cgraph_build_static_cdtor ('I', body
, DEFAULT_INIT_PRIORITY
);
1027 /* Perform file-level initialization. Read in data file, generate name
1031 coverage_init (const char *filename
)
1033 int len
= strlen (filename
);
1034 /* + 1 for extra '/', in case prefix doesn't end with /. */
1037 if (profile_data_prefix
== 0 && !IS_ABSOLUTE_PATH(&filename
[0]))
1038 profile_data_prefix
= getpwd ();
1040 prefix_len
= (profile_data_prefix
) ? strlen (profile_data_prefix
) + 1 : 0;
1042 /* Name of da file. */
1043 da_file_name
= XNEWVEC (char, len
+ strlen (GCOV_DATA_SUFFIX
)
1046 if (profile_data_prefix
)
1048 strcpy (da_file_name
, profile_data_prefix
);
1049 da_file_name
[prefix_len
- 1] = '/';
1050 da_file_name
[prefix_len
] = 0;
1053 da_file_name
[0] = 0;
1054 strcat (da_file_name
, filename
);
1055 strcat (da_file_name
, GCOV_DATA_SUFFIX
);
1057 /* Name of bbg file. */
1058 bbg_file_name
= XNEWVEC (char, len
+ strlen (GCOV_NOTE_SUFFIX
) + 1);
1059 strcpy (bbg_file_name
, filename
);
1060 strcat (bbg_file_name
, GCOV_NOTE_SUFFIX
);
1062 if (flag_profile_use
)
1063 read_counts_file ();
1066 /* Performs file-level cleanup. Close graph file, generate coverage
1067 variables and constructor. */
1070 coverage_finish (void)
1073 if (bbg_file_opened
)
1075 int error
= gcov_close ();
1078 unlink (bbg_file_name
);
1080 /* Only remove the da file, if we cannot stamp it. If we can
1081 stamp it, libgcov will DTRT. */
1082 unlink (da_file_name
);
1086 #include "gt-coverage.h"