diff options
Diffstat (limited to 'gcc-4.9/libgcc/dyn-ipa.c')
-rw-r--r-- | gcc-4.9/libgcc/dyn-ipa.c | 111 |
1 files changed, 61 insertions, 50 deletions
diff --git a/gcc-4.9/libgcc/dyn-ipa.c b/gcc-4.9/libgcc/dyn-ipa.c index e66b02bbc..ef6da8db8 100644 --- a/gcc-4.9/libgcc/dyn-ipa.c +++ b/gcc-4.9/libgcc/dyn-ipa.c @@ -107,8 +107,9 @@ struct checksum_alias struct checksum_alias *next_alias; gcov_type guid; const struct gcov_fn_info *fi_ptr; - /* Does this function have all-zero arc counts? */ - int zero_counts; + /* Non-NULL pointer to flag if this function has all-zero arc counts, to be + set if we perform fixup. */ + char *zero_count_fixup; }; /* Module info is stored in dyn_caph->sup_modules @@ -178,10 +179,10 @@ extern gcov_unsigned_t __gcov_lipo_merge_modu_edges; extern gcov_unsigned_t __gcov_lipo_weak_inclusion; #if defined(inhibit_libc) -void __gcov_build_callgraph (void) {} +void __gcov_build_callgraph (char **zero_counts) {} #else -int __gcov_compute_module_groups (void) ATTRIBUTE_HIDDEN; +int __gcov_compute_module_groups (char **zero_counts) ATTRIBUTE_HIDDEN; void __gcov_finalize_dyn_callgraph (void) ATTRIBUTE_HIDDEN; static void gcov_dump_callgraph (gcov_type); static void gcov_dump_cgraph_node_short (struct dyn_cgraph_node *node); @@ -378,18 +379,19 @@ lineno_checksum_get_key (const void *p) } /* Create a new checksum_alias struct for function with GUID, FI_PTR, - and ZERO_COUNTS flag. Prepends to list NEXT and returns new struct. */ + and ZERO_COUNT_FIXUP flag pointer. Prepends to list NEXT and returns + new struct. */ static struct checksum_alias * new_checksum_alias (gcov_type guid, const struct gcov_fn_info *fi_ptr, - int zero_counts, + char *zero_count_fixup, struct checksum_alias *next) { struct checksum_alias *alias = XNEW (struct checksum_alias); alias->next_alias = next; alias->fi_ptr = fi_ptr; alias->guid = guid; - alias->zero_counts = zero_counts; + alias->zero_count_fixup = zero_count_fixup; return alias; } @@ -407,11 +409,12 @@ find_cfg_checksum (struct checksum_alias_info *list, unsigned cfg_checksum) } /* Insert a new checksum_alias struct into LIST for function with - CFG_CHECKSUM and associated GUID, FI_PTR, and ZERO_COUNTS flag. */ + CFG_CHECKSUM and associated GUID, FI_PTR, and ZERO_COUNT_FIXUP + flag pointer. */ static struct checksum_alias_info * cfg_checksum_insert (unsigned cfg_checksum, gcov_type guid, - const struct gcov_fn_info *fi_ptr, int zero_counts, + const struct gcov_fn_info *fi_ptr, char *zero_count_fixup, struct checksum_alias_info *list) { struct checksum_alias_info *alias_info; @@ -419,7 +422,8 @@ cfg_checksum_insert (unsigned cfg_checksum, gcov_type guid, if (alias_info) { gcc_assert (alias_info->alias_list); - alias_info->alias_list = new_checksum_alias (guid, fi_ptr, zero_counts, + alias_info->alias_list = new_checksum_alias (guid, fi_ptr, + zero_count_fixup, alias_info->alias_list); return list; } @@ -428,7 +432,8 @@ cfg_checksum_insert (unsigned cfg_checksum, gcov_type guid, alias_info = XNEW (struct checksum_alias_info); alias_info->next_cfg_checksum = list; alias_info->cfg_checksum = cfg_checksum; - alias_info->alias_list = new_checksum_alias (guid, fi_ptr, zero_counts, + alias_info->alias_list = new_checksum_alias (guid, fi_ptr, + zero_count_fixup, NULL); return alias_info; } @@ -436,12 +441,12 @@ cfg_checksum_insert (unsigned cfg_checksum, gcov_type guid, /* Insert a new checksum_alias struct into lineno_pointer_sets for function with LINENO_CHECKSUM and CFG_CHECKSUM with associated GUID, FI_PTR, and - ZERO_COUNTS flag. */ + ZERO_COUNT_FIXUP flag pointer. */ static void checksum_set_insert (unsigned lineno_checksum, unsigned cfg_checksum, gcov_type guid, const struct gcov_fn_info *fi_ptr, - int zero_counts) + char *zero_count_fixup) { struct dyn_pointer_set *p = the_dyn_call_graph.lineno_pointer_sets; if (!p) @@ -452,7 +457,7 @@ checksum_set_insert (unsigned lineno_checksum, unsigned cfg_checksum, if (*m) { (*m)->cfg_checksum_list = cfg_checksum_insert (cfg_checksum, guid, - fi_ptr, zero_counts, + fi_ptr, zero_count_fixup, (*m)->cfg_checksum_list); } else @@ -460,7 +465,8 @@ checksum_set_insert (unsigned lineno_checksum, unsigned cfg_checksum, *m = XNEW (struct lineno_checksum_alias); (*m)->lineno_checksum = lineno_checksum; (*m)->cfg_checksum_list = cfg_checksum_insert (cfg_checksum, guid, - fi_ptr, zero_counts, NULL); + fi_ptr, zero_count_fixup, + NULL); p->n_elements++; } } @@ -801,10 +807,10 @@ gcov_build_callgraph_ic_fn (struct dyn_cgraph_node *caller, } } -/* Build the dynamic call graph. */ +/* Build the dynamic call graph and update ZERO_COUNTS flags. */ static void -gcov_build_callgraph (void) +gcov_build_callgraph (char **zero_counts) { struct gcov_info *gi_ptr; unsigned m_ix; @@ -852,9 +858,19 @@ gcov_build_callgraph (void) if (total_arc_count != 0) the_dyn_call_graph.num_nodes_executed++; if (fixup_type) - checksum_set_insert (fi_ptr->lineno_checksum, - fi_ptr->cfg_checksum, caller->guid, - fi_ptr, total_arc_count == 0); + { + char *zero_count_fixup = NULL; + /* Passing in a non-NULL zero_count_fixup pointer + indicates that the counts were all zero for this + function, and the fixup routine will set the flag + if the function's counters are updated to non-zero + values. */ + if (total_arc_count == 0) + zero_count_fixup = &zero_counts[m_ix][f_ix]; + checksum_set_insert (fi_ptr->lineno_checksum, + fi_ptr->cfg_checksum, caller->guid, + fi_ptr, zero_count_fixup); + } } ci_ptr++; } @@ -1251,7 +1267,14 @@ gcov_collect_imported_modules (const void *value, out_array = (struct gcov_import_mod_array *) data1; if (m->imp_mod != out_array->importing_module) + { out_array->imported_modules[out_array->len++] = m; + /* Sanity check that the importing (primary) module is not + actually the same as the new aux module. This could happen if + we accidentally read in the same gcda file twice. */ + gcc_assert (m->imp_mod->mod_info->ident != + out_array->importing_module->mod_info->ident); + } return 1; } @@ -2234,6 +2257,7 @@ gcov_compute_random_module_groups (unsigned max_group_size) } } +#if 0 /* Write out MOD_INFO into the gcda file. IS_PRIMARY is a flag indicating if the module is the primary module in the group. */ @@ -2241,7 +2265,7 @@ static void gcov_write_module_info (const struct gcov_info *mod_info, unsigned is_primary) { - gcov_unsigned_t len = 0, filename_len = 0, src_filename_len = 0, i, j; + gcov_unsigned_t len = 0, filename_len = 0, src_filename_len = 0, i; gcov_unsigned_t num_strings; gcov_unsigned_t *aligned_fname; struct gcov_module_info *module_info = mod_info->mod_info; @@ -2256,14 +2280,8 @@ gcov_write_module_info (const struct gcov_info *mod_info, + module_info->num_system_paths + module_info->num_cpp_defines + module_info->num_cpp_includes + module_info->num_cl_args; - for (i = 0; i < num_strings; i++) - { - gcov_unsigned_t string_len - = (strlen (module_info->string_array[i]) + sizeof (gcov_unsigned_t)) - / sizeof (gcov_unsigned_t); - len += string_len; - len += 1; /* Each string is lead by a length. */ - } + len += gcov_compute_string_array_len (module_info->string_array, + num_strings); len += 11; /* 11 more fields */ @@ -2296,21 +2314,9 @@ gcov_write_module_info (const struct gcov_info *mod_info, gcov_write_unsigned (aligned_fname[i]); /* Now write the string array. */ - for (j = 0; j < num_strings; j++) - { - gcov_unsigned_t *aligned_string; - gcov_unsigned_t string_len = - (strlen (module_info->string_array[j]) + sizeof (gcov_unsigned_t)) / - sizeof (gcov_unsigned_t); - aligned_string = (gcov_unsigned_t *) - alloca ((string_len + 1) * sizeof (gcov_unsigned_t)); - memset (aligned_string, 0, (string_len + 1) * sizeof (gcov_unsigned_t)); - aligned_string[0] = string_len; - strcpy ((char*) (aligned_string + 1), module_info->string_array[j]); - for (i = 0; i < (string_len + 1); i++) - gcov_write_unsigned (aligned_string[i]); - } + gcov_write_string_array (module_info->string_array, num_strings); } +#endif /* Write out MOD_INFO and its imported modules into gcda file. */ @@ -2320,6 +2326,8 @@ gcov_write_module_infos (struct gcov_info *mod_info) unsigned imp_len = 0; const struct dyn_imp_mod **imp_mods; + if (flag_alg_mode == INCLUSION_BASED_PRIORITY_ALGORITHM) + SET_MODULE_INCLUDE_ALL_AUX (mod_info->mod_info); gcov_write_module_info (mod_info, 1); imp_mods = gcov_get_sorted_import_module_array (mod_info, &imp_len); @@ -2976,7 +2984,7 @@ gcov_fixup_counters_checksum (const struct checksum_alias_info *info, for (alias = info->alias_list; alias; alias = alias->next_alias) { - if (alias->zero_counts) + if (alias->zero_count_fixup) { found = 1; break; @@ -2991,7 +2999,7 @@ gcov_fixup_counters_checksum (const struct checksum_alias_info *info, for (alias = info->alias_list; alias; alias = alias->next_alias) { - if (alias->zero_counts) + if (alias->zero_count_fixup) continue; merge_ctrs (merged_ctrs, alias->fi_ptr->ctrs, alias->guid); found = 1; @@ -3009,9 +3017,10 @@ gcov_fixup_counters_checksum (const struct checksum_alias_info *info, for (alias = info->alias_list; alias; alias = alias->next_alias) { - if (!alias->zero_counts) + if (!alias->zero_count_fixup) continue; copy_ctrs (alias->fi_ptr->ctrs, alias->guid, merged_ctrs); + *alias->zero_count_fixup = 1; } return 1; @@ -3059,11 +3068,13 @@ gcov_fixup_zero_counters (void) return changed; } -/* Compute module groups needed for L-IPO compilation. Returns 1 if any - counter fixups were applied, requiring a profile rewrite, 0 otherwise. */ +/* Compute module groups needed for L-IPO compilation. The ZERO_COUNTS + flags are set for functions with zero count fixups applied. Returns 1 + if any counter fixups were applied, requiring a profile rewrite, + 0 otherwise. */ int -__gcov_compute_module_groups (void) +__gcov_compute_module_groups (char **zero_counts) { gcov_type cut_off_count; char *seed = getenv ("LIPO_RANDOM_GROUPING"); @@ -3110,7 +3121,7 @@ __gcov_compute_module_groups (void) fixup_type = atoi (do_fixup); /* First compute dynamic call graph. */ - gcov_build_callgraph (); + gcov_build_callgraph (zero_counts); cut_off_count = gcov_compute_cutoff_count (); |