diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6e74362fbe5..ce3df3d38a3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2011-04-21 Xinliang David Li + + * cgraph.h: Remove pid. + * cgraph.c: Remove pid. + * value-prof.c (init_node_map): New function. + (del_node_map): New function. + (find_func_by_funcdef_no): New function. + (gimple_ic_transform): Call new function. + * cgraphunit.c (cgraph_finalize_function): Remove pid. + * function.c (get_last_funcdef_no): New function. + * function.h (get_last_funcdef_no): New function. + * tree-profile.c (gimple_gen_ic_func_profiler): Pass funcdef_no + to libgcov function. + (tree-profiling): Call node map init and delete function. + 2011-04-21 Ian Lance Taylor * godump.c (go_format_type): Use exported Go name for anonymous diff --git a/gcc/cgraph.c b/gcc/cgraph.c index eb49bc7c3f2..85266467284 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -142,9 +142,6 @@ int cgraph_max_uid; /* Maximal uid used in cgraph edges. */ int cgraph_edge_max_uid; -/* Maximal pid used for profiling */ -int cgraph_max_pid; - /* Set when whole unit has been analyzed so we can access global info. */ bool cgraph_global_info_ready = false; @@ -472,7 +469,6 @@ cgraph_create_node_1 (void) struct cgraph_node *node = cgraph_allocate_node (); node->next = cgraph_nodes; - node->pid = -1; node->order = cgraph_order++; if (cgraph_nodes) cgraph_nodes->previous = node; @@ -1827,8 +1823,7 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) struct cgraph_edge *edge; int indirect_calls_count = 0; - fprintf (f, "%s/%i(%i)", cgraph_node_name (node), node->uid, - node->pid); + fprintf (f, "%s/%i", cgraph_node_name (node), node->uid); dump_addr (f, " @", (void *)node); if (DECL_ASSEMBLER_NAME_SET_P (node->decl)) fprintf (f, " (asm: %s)", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))); diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 032c837a228..b57a5e07c75 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -200,9 +200,6 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node { /* Ordering of all cgraph nodes. */ int order; - /* unique id for profiling. pid is not suitable because of different - number of cfg nodes with -fprofile-generate and -fprofile-use */ - int pid; enum ld_plugin_symbol_resolution resolution; /* Set when function must be output for some reason. The primary @@ -472,7 +469,6 @@ extern GTY(()) struct cgraph_node *cgraph_nodes; extern GTY(()) int cgraph_n_nodes; extern GTY(()) int cgraph_max_uid; extern GTY(()) int cgraph_edge_max_uid; -extern GTY(()) int cgraph_max_pid; extern bool cgraph_global_info_ready; enum cgraph_state { @@ -730,7 +726,6 @@ void cgraph_clone_inlined_nodes (struct cgraph_edge *, bool, bool); void compute_inline_parameters (struct cgraph_node *); cgraph_inline_failed_t cgraph_edge_inlinable_p (struct cgraph_edge *); - /* Create a new static variable of type TYPE. */ tree add_new_static_var (tree type); diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 1a687fbbc7a..7e7530b4ee9 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -348,7 +348,6 @@ cgraph_finalize_function (tree decl, bool nested) if (node->local.finalized) cgraph_reset_node (node); - node->pid = cgraph_max_pid ++; notice_global_symbol (decl); node->local.finalized = true; node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL; diff --git a/gcc/function.c b/gcc/function.c index d7d56ddfb5e..1ba9dbbed28 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -4378,6 +4378,13 @@ get_next_funcdef_no (void) return funcdef_no++; } +/* Return value of funcdef. */ +int +get_last_funcdef_no (void) +{ + return funcdef_no; +} + /* Allocate a function structure for FNDECL and set its contents to the defaults. Set cfun to the newly-allocated object. Some of the helper functions invoked during initialization assume diff --git a/gcc/function.h b/gcc/function.h index 73af2948eb8..fa449585a42 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -755,6 +755,7 @@ extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode, extern void used_types_insert (tree); extern int get_next_funcdef_no (void); +extern int get_last_funcdef_no (void); /* In predict.c */ extern bool optimize_function_for_size_p (struct function *); diff --git a/gcc/profile.h b/gcc/profile.h index fe3c2f997b7..a77d3c51e1d 100644 --- a/gcc/profile.h +++ b/gcc/profile.h @@ -44,4 +44,7 @@ extern void mcf_smooth_cfg (void); extern gcov_type sum_edge_counts (VEC (edge, gc) *edges); +extern void init_node_map (void); +extern void del_node_map (void); + #endif /* PROFILE_H */ diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index 9619ae8ee12..c296dffe3c3 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "timevar.h" #include "value-prof.h" #include "cgraph.h" +#include "profile.h" static GTY(()) tree gcov_type_node; static GTY(()) tree gcov_type_tmp_var; @@ -369,7 +370,7 @@ gimple_gen_ic_func_profiler (void) ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var, true, NULL_TREE, true, GSI_SAME_STMT); - tree_uid = build_int_cst (gcov_type_node, c_node->pid); + tree_uid = build_int_cst (gcov_type_node, current_function_funcdef_no); stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4, counter_ptr, tree_uid, cur_func, ptr_var); gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); @@ -454,6 +455,8 @@ tree_profiling (void) if (cgraph_state == CGRAPH_STATE_FINISHED) return 0; + init_node_map(); + for (node = cgraph_nodes; node; node = node->next) { if (!node->analyzed @@ -548,6 +551,7 @@ tree_profiling (void) pop_cfun (); } + del_node_map(); return 0; } diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 056bcbe5693..586a9b9204e 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see #include "timevar.h" #include "tree-pass.h" #include "pointer-set.h" +#include "profile.h" /* In this file value profile based optimizations are placed. Currently the following optimizations are implemented (for more detailed descriptions @@ -1059,35 +1060,56 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si) return true; } -static struct cgraph_node** pid_map = NULL; +static VEC(cgraph_node_ptr, heap) *cgraph_node_map = NULL; -/* Initialize map of pids (pid -> cgraph node) */ +/* Initialize map from FUNCDEF_NO to CGRAPH_NODE. */ -static void -init_pid_map (void) +void +init_node_map (void) { struct cgraph_node *n; - if (pid_map != NULL) - return; - - pid_map = XCNEWVEC (struct cgraph_node*, cgraph_max_pid); + if (get_last_funcdef_no ()) + VEC_safe_grow_cleared (cgraph_node_ptr, heap, + cgraph_node_map, get_last_funcdef_no ()); for (n = cgraph_nodes; n; n = n->next) { - if (n->pid != -1) - pid_map [n->pid] = n; + if (DECL_STRUCT_FUNCTION (n->decl)) + VEC_replace (cgraph_node_ptr, cgraph_node_map, + DECL_STRUCT_FUNCTION (n->decl)->funcdef_no, n); } } +/* Delete the CGRAPH_NODE_MAP. */ + +void +del_node_map (void) +{ + VEC_free (cgraph_node_ptr, heap, cgraph_node_map); + cgraph_node_map = NULL; +} + /* Return cgraph node for function with pid */ static inline struct cgraph_node* -find_func_by_pid (int pid) +find_func_by_funcdef_no (int func_id) { - init_pid_map (); + int max_id = get_last_funcdef_no (); + if (func_id >= max_id || VEC_index (cgraph_node_ptr, + cgraph_node_map, + func_id) == NULL) + { + if (flag_profile_correction) + inform (DECL_SOURCE_LOCATION (current_function_decl), + "Inconsistent profile: indirect call target (%d) does not exist", func_id); + else + error ("Inconsistent profile: indirect call target (%d) does not exist", func_id); - return pid_map [pid]; + return NULL; + } + + return VEC_index (cgraph_node_ptr, cgraph_node_map, func_id); } /* Perform sanity check on the indirect call target. Due to race conditions, @@ -1285,7 +1307,7 @@ gimple_ic_transform (gimple stmt) prob = (count * REG_BR_PROB_BASE + all / 2) / all; else prob = 0; - direct_call = find_func_by_pid ((int)val); + direct_call = find_func_by_funcdef_no ((int)val); if (direct_call == NULL) return false;