aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.0/gcc/dyn-ipa.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.0/gcc/dyn-ipa.c')
-rw-r--r--gcc-4.4.0/gcc/dyn-ipa.c79
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) *