diff options
author | Jan Hubicka <jh@suse.cz> | 2005-06-28 04:20:29 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2005-06-28 02:20:29 +0000 |
commit | d63db217aed8c803f7d8b85910d6c8cfedc2acca (patch) | |
tree | 02b6b104f2f54b8af2a5bad55640e994b28ecfb5 /gcc/cgraphunit.c | |
parent | 2aba33dd6f2d9cf16b2c2e25e73071b5e6d4368c (diff) | |
download | gcc-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.c | 81 |
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. */ |