aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraphunit.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2005-06-28 04:20:29 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2005-06-28 02:20:29 +0000
commitd63db217aed8c803f7d8b85910d6c8cfedc2acca (patch)
tree02b6b104f2f54b8af2a5bad55640e994b28ecfb5 /gcc/cgraphunit.c
parent2aba33dd6f2d9cf16b2c2e25e73071b5e6d4368c (diff)
downloadgcc-d63db217aed8c803f7d8b85910d6c8cfedc2acca.zip
gcc-d63db217aed8c803f7d8b85910d6c8cfedc2acca.tar.gz
gcc-d63db217aed8c803f7d8b85910d6c8cfedc2acca.tar.bz2
cgraph.c (cgraph_remove_node): Do not release function bodies until full cgraph is built.
* cgraph.c (cgraph_remove_node): Do not release function bodies until full cgraph is built. * cgraph.h (cgraph_decide_inlining_incrementally): Add early argument. * cgraphunit.c (cgraph_finalize_function): Update call of cgraph_decide_inlining_incrementally. (initialize_inline_failed): Break out of ... (cgraph_analyze_function): ... here. (rebuild_cgraph_edges): New function. (pass_rebuild_cgraph_edges): New pass. * common.opt (fearly-inlining): New flag. * ipa-inline.c: Include ggc.h (cgraph_clone_inlined_nodes): Avoid re-using of original copy when cgraph is not fully built. (cgraph_decide_inlining_incrementally): Add early mode. (cgraph_early_inlining): New function. (cgraph_gate_early_inlining): Likewise. (pass_early_ipa_inline): New pass. * ipa.c (cgraph_postorder): NULLify aux pointer. * tree-inline.c (expand_call_inline): Avoid warning early. * tree-optimize.c (pass_early_local_passes): New. (execute_cleanup_cfg_pre_ipa): New. (pass_cleanup_cfg): New. (register_dump_files): Fix handling subpasses of IPA pass. (init_tree_optimization_passes): Add early passes. (execute_ipa_pass_list): Fix handling of subpasses of IPA pass. * passes.h (pass_early_tree_profile, pass_rebuild_cgraph_edges, pass_early_ipa_inline): New passes. * tree-profile.c (do_early_tree_profiling, pass_early_tree_profile): New. * invoke.texi: Document early-inlining. From-SVN: r101369
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r--gcc/cgraphunit.c81
1 files changed, 69 insertions, 12 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index ab8924d..a29dace 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -427,7 +427,7 @@ cgraph_finalize_function (tree decl, bool nested)
if (!flag_unit_at_a_time)
{
cgraph_analyze_function (node);
- cgraph_decide_inlining_incrementally (node);
+ cgraph_decide_inlining_incrementally (node, false);
}
if (decide_is_function_needed (node, decl))
@@ -569,6 +569,73 @@ cgraph_create_edges (struct cgraph_node *node, tree body)
visited_nodes = NULL;
}
+/* Give initial reasons why inlining would fail. Those gets
+ either NULLified or usually overwritten by more precise reason
+ later. */
+static void
+initialize_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");
+ else if (!node->local.inlinable)
+ e->inline_failed = N_("function not inlinable");
+ else
+ e->inline_failed = N_("function not considered for inlining");
+ }
+}
+
+/* Rebuild call edges from current function after a passes not aware
+ of cgraph updating. */
+static void
+rebuild_cgraph_edges (void)
+{
+ basic_block bb;
+ struct cgraph_node *node = cgraph_node (current_function_decl);
+ block_stmt_iterator bsi;
+
+ cgraph_node_remove_callees (node);
+
+ node->count = ENTRY_BLOCK_PTR->count;
+
+ FOR_EACH_BB (bb)
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+ tree call = get_call_expr_in (stmt);
+ tree decl;
+
+ if (call && (decl = get_callee_fndecl (call)))
+ cgraph_create_edge (node, cgraph_node (decl), stmt,
+ bb->count,
+ bb->loop_depth);
+ }
+ initialize_inline_failed (node);
+ gcc_assert (!node->global.inlined_to);
+}
+
+struct tree_opt_pass pass_rebuild_cgraph_edges =
+{
+ NULL, /* name */
+ NULL, /* gate */
+ rebuild_cgraph_edges, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+ 0 /* letter */
+};
/* Verify cgraph nodes of given cgraph node. */
void
@@ -764,7 +831,6 @@ static void
cgraph_analyze_function (struct cgraph_node *node)
{
tree decl = node->decl;
- struct cgraph_edge *e;
current_function_decl = decl;
push_cfun (DECL_STRUCT_FUNCTION (decl));
@@ -778,16 +844,7 @@ cgraph_analyze_function (struct cgraph_node *node)
if (node->local.inlinable)
node->local.disregard_inline_limits
= lang_hooks.tree_inlining.disregard_inline_limits (decl);
- for (e = node->callers; e; e = e->next_caller)
- {
- if (node->local.redefined_extern_inline)
- e->inline_failed = N_("redefined extern inline functions are not "
- "considered for inlining");
- else if (!node->local.inlinable)
- e->inline_failed = N_("function not inlinable");
- else
- e->inline_failed = N_("function not considered for inlining");
- }
+ initialize_inline_failed (node);
if (flag_really_no_inline && !node->local.disregard_inline_limits)
node->local.inlinable = 0;
/* Inlining characteristics are maintained by the cgraph_mark_inline. */