diff options
Diffstat (limited to 'gcc-4.4.0/gcc/dyn-ipa.c')
-rw-r--r-- | gcc-4.4.0/gcc/dyn-ipa.c | 79 |
1 files changed, 62 insertions, 17 deletions
diff --git a/gcc-4.4.0/gcc/dyn-ipa.c b/gcc-4.4.0/gcc/dyn-ipa.c index 99b7fd25a..ee7eeb464 100644 --- a/gcc-4.4.0/gcc/dyn-ipa.c +++ b/gcc-4.4.0/gcc/dyn-ipa.c @@ -72,6 +72,7 @@ struct dyn_cgraph_edge struct dyn_module_info { struct dyn_pointer_set *imported_modules; + gcov_unsigned_t max_func_ident; }; struct dyn_cgraph @@ -82,6 +83,7 @@ struct dyn_cgraph struct dyn_module_info *sup_modules; const struct gcov_fn_info ***functions; unsigned num_modules; + unsigned num_nodes_executed; }; struct dyn_pointer_set @@ -112,6 +114,8 @@ static void pointer_set_destroy (struct dyn_pointer_set *pset); static struct dyn_cgraph the_dyn_call_graph; +static int total_zero_count = 0; +static int total_insane_count = 0; static void init_dyn_cgraph_node (struct dyn_cgraph_node *node, gcov_type guid) @@ -156,7 +160,17 @@ get_cgraph_node (gcov_type func_guid) gcov_unsigned_t mod_id, func_id; mod_id = get_module_idx_from_func_glob_uid (func_guid); + + /* This is to workaround: calls in __static_initialization_and_destruction + should not be instrumented as the module id context for the callees have + not setup yet -- this leads to mod_id == (unsigned) (0 - 1). Multithreaded + programs may also produce insane func_guid in the profile counter. */ + if (mod_id >= the_dyn_call_graph.num_modules) + return 0; + func_id = get_intra_module_func_id (func_guid); + if (func_id > the_dyn_call_graph.sup_modules[mod_id].max_func_ident) + return 0; return &the_dyn_call_graph.call_graph_nodes[mod_id][func_id]; } @@ -182,6 +196,7 @@ init_dyn_call_graph (void) the_dyn_call_graph.call_graph_nodes = 0; the_dyn_call_graph.modules = 0; the_dyn_call_graph.functions = 0; + the_dyn_call_graph.num_nodes_executed = 0; gi_ptr = __gcov_list; @@ -242,6 +257,8 @@ init_dyn_call_graph (void) the_dyn_call_graph.call_graph_nodes[mod_id] = XNEWVEC (struct dyn_cgraph_node, max_func_ident + 1); + the_dyn_call_graph.sup_modules[mod_id].max_func_ident = max_func_ident; + for (j = 0; j < max_func_ident + 1; j++) init_dyn_cgraph_node (&the_dyn_call_graph.call_graph_nodes[mod_id][j], 0); @@ -366,16 +383,20 @@ gcov_build_callgraph_dc_fn (struct dyn_cgraph_node *caller, { struct dyn_cgraph_node *callee; gcov_type count; - gcov_type callee_guid = dir_call_counters[i]; + gcov_type callee_guid = dir_call_counters[i]; + count = dir_call_counters[i + 1]; if (count == 0) - continue; - /* This is to workaround: calls in __static_initialization_and_destruction - should not be instrumented as the module id context for the calles have - not setup yet. */ - if (EXTRACT_MODULE_ID_FROM_GLOBAL_ID (callee_guid) == 0) - continue; + { + total_zero_count++; + continue; + } callee = get_cgraph_node (callee_guid); + if (!callee) + { + total_insane_count++; + continue; + } gcov_add_cgraph_edge (caller, callee, count); } } @@ -398,15 +419,18 @@ gcov_build_callgraph_ic_fn (struct dyn_cgraph_node *caller, struct dyn_cgraph_node *callee; gcov_type count; gcov_type callee_guid = value_array[j]; + count = value_array[j + 1]; + /* Do not update zero edge count here as + it means no such target. */ if (count == 0) continue; - /* This is to workaround: calls in __static_initialization_and_destruction - should not be instrumented as the module id context for the calles have - not setup yet. */ - if (EXTRACT_MODULE_ID_FROM_GLOBAL_ID (callee_guid) == 0) - continue; callee = get_cgraph_node (callee_guid); + if (!callee) + { + total_insane_count++; + continue; + } gcov_add_cgraph_edge (caller, callee, count); } } @@ -427,6 +451,7 @@ gcov_build_callgraph (void) const struct gcov_fn_info *fi_ptr; unsigned c_ix, f_ix, n_counts, dp_cix = 0, ip_cix = 0; gcov_type *dcall_profile_values, *icall_profile_values; + gcov_type *arcs_values = 0; unsigned arcs_cix; gi_ptr = the_dyn_call_graph.modules[m_ix]; @@ -446,6 +471,11 @@ gcov_build_callgraph (void) icall_profile_values = gi_ptr->counts[c_ix].values; ip_cix = c_ix; } + if (t_ix == GCOV_COUNTER_ARCS) + { + arcs_values = gi_ptr->counts[c_ix].values; + arcs_cix = c_ix; + } c_ix++; } @@ -469,6 +499,17 @@ gcov_build_callgraph (void) gcov_build_callgraph_ic_fn (caller, icall_profile_values, n_counts); icall_profile_values += n_counts; } + if (arcs_values && 0) + { + gcov_type total_arc_count = 0; + unsigned arc; + n_counts = fi_ptr->n_ctrs[arcs_cix]; + for (arc = 0; arc < n_counts; arc++) + total_arc_count += arcs_values[arc]; + if (total_arc_count != 0) + the_dyn_call_graph.num_nodes_executed++; + arcs_values += n_counts; + } } } @@ -709,10 +750,13 @@ gcov_compute_cutoff_count (void) } if (do_dump) - fprintf (stderr, "//total = %.0f cum = %.0f cum/total = %.0f%%" - " cutoff_count = %lld [total edges: %d hot edges: %d perc: %d%%]\n", + fprintf (stderr, "// total = %.0f cum = %.0f cum/total = %.0f%%" + " cutoff_count = %lld [total edges: %d hot edges: %d perc: %d%%]\n" + " total_zero_count_edges = %d total_insane_count_edgess = %d\n" + " total_nodes_executed = %d\n", total, cum, (cum * 100)/total, (long long) cutoff_count, - num_edges, i, (i * 100)/num_edges); + num_edges, i, (i * 100)/num_edges, total_zero_count, + total_insane_count, the_dyn_call_graph.num_nodes_executed); XDELETEVEC (edges); return cutoff_count; @@ -1011,7 +1055,7 @@ gcov_write_module_info (const struct gcov_info *mod_info, len += 2; /* each name string is led by a length. */ num_strings = module_info->num_quote_paths + module_info->num_bracket_paths + - module_info->num_cpp_defines; + module_info->num_cpp_defines + module_info->num_cl_args; for (i = 0; i < num_strings; i++) { gcov_unsigned_t string_len @@ -1021,7 +1065,7 @@ gcov_write_module_info (const struct gcov_info *mod_info, len += 1; /* Each string is lead by a length. */ } - len += 7; /* 7 more fields */ + len += 8; /* 8 more fields */ gcov_write_tag_length (GCOV_TAG_MODULE_INFO, len); gcov_write_unsigned (module_info->ident); @@ -1031,6 +1075,7 @@ gcov_write_module_info (const struct gcov_info *mod_info, gcov_write_unsigned (module_info->num_quote_paths); gcov_write_unsigned (module_info->num_bracket_paths); gcov_write_unsigned (module_info->num_cpp_defines); + gcov_write_unsigned (module_info->num_cl_args); /* Now write the filenames */ aligned_fname = (gcov_unsigned_t *) alloca ((filename_len + src_filename_len + 2) * |