X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcoverage.c;h=5da5464ad5da8e46f633a96f9d52fb5547527e86;hb=e21b444cfb76b8d67c9ad45766f55730901b6957;hp=b2ac87651d30f28fc0899aa58d5737da97a32620;hpb=f67192ed80f8f3040c6b0ff957f17d5024f837c5;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/coverage.c b/gcc/coverage.c index b2ac87651d3..5da5464ad5d 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -1,7 +1,7 @@ /* Read and write coverage files, and associated functionality. Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999, - 2000, 2001, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, - Inc. + 2000, 2001, 2003, 2004, 2005, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by James E. Wilson, UC Berkeley/Cygnus Support; based on some ideas from Dain Samples of UC Berkeley. Further mangling by Bob Manson, Cygnus Support. @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "regs.h" #include "expr.h" #include "function.h" +#include "basic-block.h" #include "toplev.h" #include "tm_p.h" #include "ggc.h" @@ -46,6 +47,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-iterator.h" #include "cgraph.h" #include "tree-pass.h" +#include "diagnostic-core.h" +#include "intl.h" #include "gcov-io.c" @@ -101,10 +104,6 @@ static htab_t counts_hash = NULL; /* Trees representing the counter table arrays. */ static GTY(()) tree tree_ctr_tables[GCOV_COUNTERS]; -/* The names of the counter tables. Not used if we're - generating counters at tree level. */ -static GTY(()) rtx ctr_labels[GCOV_COUNTERS]; - /* The names of merge functions for counters. */ static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS; static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES; @@ -201,7 +200,7 @@ read_counts_file (void) /* Read and discard the stamp. */ gcov_read_unsigned (); - + counts_hash = htab_create (10, htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del); @@ -347,8 +346,8 @@ get_coverage_counts (unsigned counter, unsigned expected, entry = (counts_entry_t *) htab_find (counts_hash, &elt); if (!entry) { - warning (0, "no coverage for function %qs found", IDENTIFIER_POINTER - (DECL_ASSEMBLER_NAME (current_function_decl))); + warning (0, "no coverage for function %qE found", + DECL_ASSEMBLER_NAME (current_function_decl)); return NULL; } @@ -357,35 +356,33 @@ get_coverage_counts (unsigned counter, unsigned expected, || entry->summary.num != expected) { static int warned = 0; - const char *id = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME - (current_function_decl)); - - if (warn_coverage_mismatch) - warning (OPT_Wcoverage_mismatch, "coverage mismatch for function " - "%qs while reading counter %qs", id, ctr_names[counter]); - else - error ("coverage mismatch for function %qs while reading counter %qs", - id, ctr_names[counter]); - - if (!inhibit_warnings) + bool warning_printed = false; + tree id = DECL_ASSEMBLER_NAME (current_function_decl); + + warning_printed = + warning_at (input_location, OPT_Wcoverage_mismatch, + "coverage mismatch for function " + "%qE while reading counter %qs", id, ctr_names[counter]); + if (warning_printed) { if (entry->checksum != checksum) - inform (input_location, "checksum is %x instead of %x", entry->checksum, checksum); + inform (input_location, "checksum is %x instead of %x", + entry->checksum, checksum); else inform (input_location, "number of counters is %d instead of %d", entry->summary.num, expected); - } - - if (warn_coverage_mismatch - && !inhibit_warnings - && !warned++) - { - inform (input_location, "coverage mismatch ignored due to -Wcoverage-mismatch"); - inform (input_location, flag_guess_branch_prob - ? "execution counts estimated" - : "execution counts assumed to be zero"); - if (!flag_guess_branch_prob) - inform (input_location, "this can result in poorly optimized code"); + + if (!seen_error () + && !warned++) + { + inform (input_location, "coverage mismatch ignored"); + inform (input_location, flag_guess_branch_prob + ? G_("execution counts estimated") + : G_("execution counts assumed to be zero")); + if (!flag_guess_branch_prob) + inform (input_location, + "this can result in poorly optimized code"); + } } return NULL; @@ -419,7 +416,8 @@ coverage_counter_alloc (unsigned counter, unsigned num) tree gcov_type_array_type = build_array_type (gcov_type_node, NULL_TREE); tree_ctr_tables[counter] - = build_decl (VAR_DECL, NULL_TREE, gcov_type_array_type); + = build_decl (BUILTINS_LOCATION, + VAR_DECL, NULL_TREE, gcov_type_array_type); TREE_STATIC (tree_ctr_tables[counter]) = 1; ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1); DECL_NAME (tree_ctr_tables[counter]) = get_identifier (buf); @@ -459,6 +457,8 @@ tree_coverage_counter_addr (unsigned counter, unsigned no) gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]); no += prg_n_ctrs[counter] + fn_b_ctrs[counter]; + TREE_ADDRESSABLE (tree_ctr_tables[counter]) = 1; + /* "no" here is an array index, scaled to bytes later. */ return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node, tree_ctr_tables[counter], @@ -553,7 +553,7 @@ coverage_begin_output (void) { /* We don't need to output .gcno file unless we're under -ftest-coverage (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */ - if (no_coverage || !flag_test_coverage) + if (no_coverage || !flag_test_coverage || flag_compare_debug) return 0; if (!bbg_function_announced) @@ -638,11 +638,13 @@ build_fn_info_type (unsigned int counters) tree array_type; /* ident */ - fields = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); + fields = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); /* checksum */ - field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); + DECL_CHAIN (field) = fields; fields = field; array_type = build_int_cst (NULL_TREE, counters - 1); @@ -650,8 +652,9 @@ build_fn_info_type (unsigned int counters) array_type = build_array_type (get_gcov_unsigned_t (), array_type); /* counters */ - field = build_decl (FIELD_DECL, NULL_TREE, array_type); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, array_type); + DECL_CHAIN (field) = fields; fields = field; finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE); @@ -666,40 +669,34 @@ build_fn_info_type (unsigned int counters) static tree build_fn_info_value (const struct function_list *function, tree type) { - tree value = NULL_TREE; tree fields = TYPE_FIELDS (type); unsigned ix; - tree array_value = NULL_TREE; + VEC(constructor_elt,gc) *v1 = NULL; + VEC(constructor_elt,gc) *v2 = NULL; /* ident */ - value = tree_cons (fields, build_int_cstu (get_gcov_unsigned_t (), - function->ident), value); - fields = TREE_CHAIN (fields); + CONSTRUCTOR_APPEND_ELT (v1, fields, + build_int_cstu (get_gcov_unsigned_t (), + function->ident)); + fields = DECL_CHAIN (fields); /* checksum */ - value = tree_cons (fields, build_int_cstu (get_gcov_unsigned_t (), - function->checksum), value); - fields = TREE_CHAIN (fields); + CONSTRUCTOR_APPEND_ELT (v1, fields, + build_int_cstu (get_gcov_unsigned_t (), + function->checksum)); + fields = DECL_CHAIN (fields); /* counters */ for (ix = 0; ix != GCOV_COUNTERS; ix++) if (prg_ctr_mask & (1 << ix)) - { - tree counters = build_int_cstu (get_gcov_unsigned_t (), - function->n_ctrs[ix]); - - array_value = tree_cons (NULL_TREE, counters, array_value); - } + CONSTRUCTOR_APPEND_ELT (v2, NULL, + build_int_cstu (get_gcov_unsigned_t (), + function->n_ctrs[ix])); - /* FIXME: use build_constructor directly. */ - array_value = build_constructor_from_list (TREE_TYPE (fields), - nreverse (array_value)); - value = tree_cons (fields, array_value, value); + CONSTRUCTOR_APPEND_ELT (v1, fields, + build_constructor (TREE_TYPE (fields), v2)); - /* FIXME: use build_constructor directly. */ - value = build_constructor_from_list (type, nreverse (value)); - - return value; + return build_constructor (type, v1); } /* Creates the gcov_ctr_info RECORD_TYPE. */ @@ -713,13 +710,15 @@ build_ctr_info_type (void) tree gcov_merge_fn_type; /* counters */ - field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); + DECL_CHAIN (field) = fields; fields = field; /* values */ - field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, gcov_ptr_type); + DECL_CHAIN (field) = fields; fields = field; /* merge */ @@ -727,9 +726,10 @@ build_ctr_info_type (void) build_function_type_list (void_type_node, gcov_ptr_type, get_gcov_unsigned_t (), NULL_TREE); - field = build_decl (FIELD_DECL, NULL_TREE, + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, build_pointer_type (gcov_merge_fn_type)); - TREE_CHAIN (field) = fields; + DECL_CHAIN (field) = fields; fields = field; finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE); @@ -744,16 +744,15 @@ build_ctr_info_type (void) static tree build_ctr_info_value (unsigned int counter, tree type) { - tree value = NULL_TREE; tree fields = TYPE_FIELDS (type); tree fn; + VEC(constructor_elt,gc) *v = NULL; /* counters */ - value = tree_cons (fields, - build_int_cstu (get_gcov_unsigned_t (), - prg_n_ctrs[counter]), - value); - fields = TREE_CHAIN (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, + build_int_cstu (get_gcov_unsigned_t (), + prg_n_ctrs[counter])); + fields = DECL_CHAIN (fields); if (prg_n_ctrs[counter]) { @@ -768,32 +767,28 @@ build_ctr_info_value (unsigned int counter, tree type) TREE_TYPE (tree_ctr_tables[counter]) = array_type; DECL_SIZE (tree_ctr_tables[counter]) = TYPE_SIZE (array_type); DECL_SIZE_UNIT (tree_ctr_tables[counter]) = TYPE_SIZE_UNIT (array_type); - assemble_variable (tree_ctr_tables[counter], 0, 0, 0); + varpool_finalize_decl (tree_ctr_tables[counter]); - value = tree_cons (fields, - build1 (ADDR_EXPR, TREE_TYPE (fields), - tree_ctr_tables[counter]), - value); + CONSTRUCTOR_APPEND_ELT (v, fields, + build1 (ADDR_EXPR, TREE_TYPE (fields), + tree_ctr_tables[counter])); } else - value = tree_cons (fields, null_pointer_node, value); - fields = TREE_CHAIN (fields); + CONSTRUCTOR_APPEND_ELT (v, fields, null_pointer_node); + fields = DECL_CHAIN (fields); - fn = build_decl (FUNCTION_DECL, + fn = build_decl (BUILTINS_LOCATION, + FUNCTION_DECL, get_identifier (ctr_merge_functions[counter]), TREE_TYPE (TREE_TYPE (fields))); DECL_EXTERNAL (fn) = 1; TREE_PUBLIC (fn) = 1; DECL_ARTIFICIAL (fn) = 1; TREE_NOTHROW (fn) = 1; - value = tree_cons (fields, - build1 (ADDR_EXPR, TREE_TYPE (fields), fn), - value); - - /* FIXME: use build_constructor directly. */ - value = build_constructor_from_list (type, nreverse (value)); + DECL_ASSEMBLER_NAME (fn); /* Initialize assembler name so we can stream out. */ + CONSTRUCTOR_APPEND_ELT (v, fields, build1 (ADDR_EXPR, TREE_TYPE (fields), fn)); - return value; + return build_constructor (type, v); } /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a @@ -808,12 +803,13 @@ build_gcov_info (void) tree fn_info_ptr_type; tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE; tree field, fields = NULL_TREE; - tree value = NULL_TREE; tree filename_string; int da_file_name_len; unsigned n_fns; const struct function_list *fn; tree string_type; + VEC(constructor_elt,gc) *v1 = NULL; + VEC(constructor_elt,gc) *v2 = NULL; /* Count the number of active counters. */ for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++) @@ -824,47 +820,51 @@ build_gcov_info (void) const_type = build_qualified_type (type, TYPE_QUAL_CONST); /* Version ident */ - field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); + DECL_CHAIN (field) = fields; fields = field; - value = tree_cons (field, build_int_cstu (TREE_TYPE (field), GCOV_VERSION), - value); + CONSTRUCTOR_APPEND_ELT (v1, field, + build_int_cstu (TREE_TYPE (field), GCOV_VERSION)); /* next -- NULL */ - field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type (const_type)); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, build_pointer_type (const_type)); + DECL_CHAIN (field) = fields; fields = field; - value = tree_cons (field, null_pointer_node, value); + CONSTRUCTOR_APPEND_ELT (v1, field, null_pointer_node); /* stamp */ - field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); + DECL_CHAIN (field) = fields; fields = field; - value = tree_cons (field, build_int_cstu (TREE_TYPE (field), local_tick), - value); + CONSTRUCTOR_APPEND_ELT (v1, field, + build_int_cstu (TREE_TYPE (field), local_tick)); /* Filename */ string_type = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST)); - field = build_decl (FIELD_DECL, NULL_TREE, string_type); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, string_type); + DECL_CHAIN (field) = fields; fields = field; da_file_name_len = strlen (da_file_name); filename_string = build_string (da_file_name_len + 1, da_file_name); TREE_TYPE (filename_string) = build_array_type (char_type_node, build_index_type (build_int_cst (NULL_TREE, da_file_name_len))); - value = tree_cons (field, build1 (ADDR_EXPR, string_type, filename_string), - value); + CONSTRUCTOR_APPEND_ELT (v1, field, + build1 (ADDR_EXPR, string_type, filename_string)); /* Build the fn_info type and initializer. */ fn_info_type = build_fn_info_type (n_ctr_types); fn_info_ptr_type = build_pointer_type (build_qualified_type (fn_info_type, TYPE_QUAL_CONST)); for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++) - fn_info_value = tree_cons (NULL_TREE, - build_fn_info_value (fn, fn_info_type), - fn_info_value); + CONSTRUCTOR_APPEND_ELT (v2, NULL_TREE, + build_fn_info_value (fn, fn_info_type)); + if (n_fns) { tree array_type; @@ -872,61 +872,57 @@ build_gcov_info (void) array_type = build_index_type (build_int_cst (NULL_TREE, n_fns - 1)); array_type = build_array_type (fn_info_type, array_type); - /* FIXME: use build_constructor directly. */ - fn_info_value = build_constructor_from_list (array_type, - nreverse (fn_info_value)); + fn_info_value = build_constructor (array_type, v2); fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value); } else fn_info_value = null_pointer_node; /* number of functions */ - field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); + DECL_CHAIN (field) = fields; fields = field; - value = tree_cons (field, - build_int_cstu (get_gcov_unsigned_t (), n_fns), - value); + CONSTRUCTOR_APPEND_ELT (v1, field, + build_int_cstu (get_gcov_unsigned_t (), n_fns)); /* fn_info table */ - field = build_decl (FIELD_DECL, NULL_TREE, fn_info_ptr_type); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, fn_info_ptr_type); + DECL_CHAIN (field) = fields; fields = field; - value = tree_cons (field, fn_info_value, value); + CONSTRUCTOR_APPEND_ELT (v1, field, fn_info_value); /* counter_mask */ - field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); - TREE_CHAIN (field) = fields; + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ()); + DECL_CHAIN (field) = fields; fields = field; - value = tree_cons (field, - build_int_cstu (get_gcov_unsigned_t (), prg_ctr_mask), - value); + CONSTRUCTOR_APPEND_ELT (v1, field, + build_int_cstu (get_gcov_unsigned_t (), + prg_ctr_mask)); /* counters */ ctr_info_type = build_ctr_info_type (); ctr_info_ary_type = build_index_type (build_int_cst (NULL_TREE, n_ctr_types)); ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type); + v2 = NULL; for (ix = 0; ix != GCOV_COUNTERS; ix++) if (prg_ctr_mask & (1 << ix)) - ctr_info_value = tree_cons (NULL_TREE, - build_ctr_info_value (ix, ctr_info_type), - ctr_info_value); - /* FIXME: use build_constructor directly. */ - ctr_info_value = build_constructor_from_list (ctr_info_ary_type, - nreverse (ctr_info_value)); - - field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type); - TREE_CHAIN (field) = fields; + CONSTRUCTOR_APPEND_ELT (v2, NULL_TREE, + build_ctr_info_value (ix, ctr_info_type)); + ctr_info_value = build_constructor (ctr_info_ary_type, v2); + + field = build_decl (BUILTINS_LOCATION, + FIELD_DECL, NULL_TREE, ctr_info_ary_type); + DECL_CHAIN (field) = fields; fields = field; - value = tree_cons (field, ctr_info_value, value); + CONSTRUCTOR_APPEND_ELT (v1, field, ctr_info_value); finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE); - /* FIXME: use build_constructor directly. */ - value = build_constructor_from_list (type, nreverse (value)); - - return value; + return build_constructor (type, v1); } /* Write out the structure which libgcov uses to locate all the @@ -946,21 +942,24 @@ create_coverage (void) t = build_gcov_info (); - gcov_info = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (t)); + gcov_info = build_decl (BUILTINS_LOCATION, + VAR_DECL, NULL_TREE, TREE_TYPE (t)); TREE_STATIC (gcov_info) = 1; ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0); DECL_NAME (gcov_info) = get_identifier (name_buf); DECL_INITIAL (gcov_info) = t; /* Build structure. */ - assemble_variable (gcov_info, 0, 0, 0); + varpool_finalize_decl (gcov_info); /* Build a decl for __gcov_init. */ t = build_pointer_type (TREE_TYPE (gcov_info)); t = build_function_type_list (void_type_node, t, NULL); - t = build_decl (FUNCTION_DECL, get_identifier ("__gcov_init"), t); + t = build_decl (BUILTINS_LOCATION, + FUNCTION_DECL, get_identifier ("__gcov_init"), t); TREE_PUBLIC (t) = 1; DECL_EXTERNAL (t) = 1; + DECL_ASSEMBLER_NAME (t); /* Initialize assembler name so we can stream out. */ gcov_init = t; /* Generate a call to __gcov_init(&gcov_info). */ @@ -982,14 +981,14 @@ coverage_init (const char *filename) int len = strlen (filename); /* + 1 for extra '/', in case prefix doesn't end with /. */ int prefix_len; - + if (profile_data_prefix == 0 && filename[0] != '/') profile_data_prefix = getpwd (); prefix_len = (profile_data_prefix) ? strlen (profile_data_prefix) + 1 : 0; /* Name of da file. */ - da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX) + da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX) + prefix_len + 1); if (profile_data_prefix)