Mercurial > hg > CbC > CbC_gcc
diff gcc/cgraphbuild.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
line wrap: on
line diff
--- a/gcc/cgraphbuild.c Sun Feb 07 18:28:00 2010 +0900 +++ b/gcc/cgraphbuild.c Fri Feb 12 23:39:51 2010 +0900 @@ -1,5 +1,5 @@ /* Callgraph construction. - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Jan Hubicka @@ -33,13 +33,16 @@ #include "tree-pass.h" /* Walk tree and record all calls and references to functions/variables. - Called via walk_tree: TP is pointer to tree to be examined. */ + Called via walk_tree: TP is pointer to tree to be examined. + When DATA is non-null, record references to callgraph. + */ static tree -record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) +record_reference (tree *tp, int *walk_subtrees, void *data) { tree t = *tp; tree decl; + bool do_callgraph = data != NULL; switch (TREE_CODE (t)) { @@ -57,8 +60,8 @@ /* Record dereferences to the functions. This makes the functions reachable unconditionally. */ decl = TREE_OPERAND (*tp, 0); - if (TREE_CODE (decl) == FUNCTION_DECL) - cgraph_mark_needed_node (cgraph_node (decl)); + if (TREE_CODE (decl) == FUNCTION_DECL && do_callgraph) + cgraph_mark_address_taken_node (cgraph_node (decl)); break; default: @@ -78,39 +81,41 @@ return NULL_TREE; } -/* Give initial reasons why inlining would fail on all calls from - NODE. Those get either nullified or usually overwritten by more precise - reason later. */ +/* Reset inlining information of all incoming call edges of NODE. */ -static void -initialize_inline_failed (struct cgraph_node *node) +void +reset_inline_failed (struct cgraph_node *node) { struct cgraph_edge *e; for (e = node->callers; e; e = e->next_caller) { - gcc_assert (!e->callee->global.inlined_to); - gcc_assert (e->inline_failed); - if (node->local.redefined_extern_inline) - e->inline_failed = N_("redefined extern inline functions are not " - "considered for inlining"); + e->callee->global.inlined_to = NULL; + if (!node->analyzed) + e->inline_failed = CIF_BODY_NOT_AVAILABLE; + else if (node->local.redefined_extern_inline) + e->inline_failed = CIF_REDEFINED_EXTERN_INLINE; else if (!node->local.inlinable) - e->inline_failed = N_("function not inlinable"); - else if (gimple_call_cannot_inline_p (e->call_stmt)) - e->inline_failed = N_("mismatched arguments"); + e->inline_failed = CIF_FUNCTION_NOT_INLINABLE; + else if (e->call_stmt_cannot_inline_p) + e->inline_failed = CIF_MISMATCHED_ARGUMENTS; else - e->inline_failed = N_("function not considered for inlining"); + e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED; } } /* Computes the frequency of the call statement so that it can be stored in cgraph_edge. BB is the basic block of the call statement. */ int -compute_call_stmt_bb_frequency (basic_block bb) +compute_call_stmt_bb_frequency (tree decl, basic_block bb) { - int entry_freq = ENTRY_BLOCK_PTR->frequency; + int entry_freq = ENTRY_BLOCK_PTR_FOR_FUNCTION + (DECL_STRUCT_FUNCTION (decl))->frequency; int freq = bb->frequency; + if (profile_status_for_function (DECL_STRUCT_FUNCTION (decl)) == PROFILE_ABSENT) + return CGRAPH_FREQ_BASE; + if (!entry_freq) entry_freq = 1, freq++; @@ -146,7 +151,7 @@ size_t i; size_t n = gimple_call_num_args (stmt); cgraph_create_edge (node, cgraph_node (decl), stmt, - bb->count, compute_call_stmt_bb_frequency (bb), + bb->count, compute_call_stmt_bb_frequency (current_function_decl, bb), bb->loop_depth); for (i = 0; i < n; i++) walk_tree (gimple_call_arg_ptr (stmt, i), record_reference, @@ -194,7 +199,6 @@ } pointer_set_destroy (visited_nodes); - initialize_inline_failed (node); return 0; } @@ -202,13 +206,13 @@ { { GIMPLE_PASS, - NULL, /* name */ + "*build_cgraph_edges", /* name */ NULL, /* gate */ build_cgraph_edges, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ - 0, /* tv_id */ + TV_NONE, /* tv_id */ PROP_cfg, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ @@ -218,13 +222,15 @@ }; /* Record references to functions and other variables present in the - initial value of DECL, a variable. */ + initial value of DECL, a variable. + When ONLY_VARS is true, we mark needed only variables, not functions. */ void -record_references_in_initializer (tree decl) +record_references_in_initializer (tree decl, bool only_vars) { struct pointer_set_t *visited_nodes = pointer_set_create (); - walk_tree (&DECL_INITIAL (decl), record_reference, NULL, visited_nodes); + walk_tree (&DECL_INITIAL (decl), record_reference, + only_vars ? NULL : decl, visited_nodes); pointer_set_destroy (visited_nodes); } @@ -250,12 +256,14 @@ if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt))) cgraph_create_edge (node, cgraph_node (decl), stmt, - bb->count, compute_call_stmt_bb_frequency (bb), + bb->count, + compute_call_stmt_bb_frequency + (current_function_decl, bb), bb->loop_depth); } - initialize_inline_failed (node); gcc_assert (!node->global.inlined_to); + return 0; } @@ -263,13 +271,13 @@ { { GIMPLE_PASS, - NULL, /* name */ + "*rebuild_cgraph_edges", /* name */ NULL, /* gate */ rebuild_cgraph_edges, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ - 0, /* tv_id */ + TV_NONE, /* tv_id */ PROP_cfg, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ @@ -277,3 +285,30 @@ 0, /* todo_flags_finish */ } }; + + +static unsigned int +remove_cgraph_callee_edges (void) +{ + cgraph_node_remove_callees (cgraph_node (current_function_decl)); + return 0; +} + +struct gimple_opt_pass pass_remove_cgraph_callee_edges = +{ + { + GIMPLE_PASS, + "*remove_cgraph_callee_edges", /* name */ + NULL, /* gate */ + remove_cgraph_callee_edges, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_NONE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + } +};