diff options
author | Martin Jambor <mjambor@suse.cz> | 2008-09-11 19:03:23 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2008-09-11 19:03:23 +0200 |
commit | f8e2a1ed3b746951a5d07e03f91d1f8209ebe775 (patch) | |
tree | 73228742f0647af60cdfe7e96540801e3f8ad3ef /gcc/ipa-inline.c | |
parent | 420da8caae151d84ef45e31cf058e9832d856b9e (diff) | |
download | gcc-f8e2a1ed3b746951a5d07e03f91d1f8209ebe775.zip gcc-f8e2a1ed3b746951a5d07e03f91d1f8209ebe775.tar.gz gcc-f8e2a1ed3b746951a5d07e03f91d1f8209ebe775.tar.bz2 |
ipa-prop.h (struct ipa_param_flags): Removed.
2008-09-11 Martin Jambor <mjambor@suse.cz>
* ipa-prop.h (struct ipa_param_flags): Removed.
(struct ipa_param_descriptor): New structure.
(struct ipa_node_params): ipcp_lattices, param_decls and
param_flags moved to ipa_param_description.
(ipa_get_ith_param): Renamed to ipa_get_param, changed to access
descriptors. Renamed all users.
(ipa_is_ith_param_modified): Renamed to ipa_is_param_modified,
changed to access descriptors. Renamed all users.
(ipa_is_ith_param_called): Renamed to ipa_is_param_called, changed
to access descriptors. Renamed all users.
* ipa-cp.c (ipcp_init_cloned_node): Call
ipa_initialize_node_params instead of ipa_count_formal_params and
ipa_create_param_decls_array.
(ipcp_analyze_node): Likewise.
(ipcp_get_ith_lattice): Renamed to ipcp_get_lattice, changed to access
descriptors. Renamed all users.
(ipcp_initialize_node_lattices): Remove allocation.
* ipa-inline.c (inline_indirect_intraprocedural_analysis): Call
ipa_initialize_node_params instead of ipa_count_formal_params and
ipa_create_param_decls_array.
* ipa-prop.c (ipa_create_param_decls_array): Renamed to
ipa_populate_param_decls, made static, added parameter info,
renamed mt to node, removed allocation, changed to use
descriptors.
(ipa_count_formal_params): Made static, added parameter info,
renamed mt to node.
(ipa_initialize_node_params): New function.
(ipa_check_stmt_modifications): Changed to use descriptors.
(ipa_detect_param_modifications): Removed allocation, changed to
use descriptors.
(ipa_note_param_call): Changed to use descriptors.
(ipa_analyze_params_uses): Removed allocation.
(ipa_free_node_params_substructures): Changed to use descriptors.
(ipa_edge_duplication_hook): Use the unused attribute.
(ipa_node_duplication_hook): Use the unused attribute, changed to
use descriptors, changed to duplicate descriptors.
* ipa-inline.c (cgraph_mark_inline_edge): New parameter new_edges,
changed all callers. Call ipa_propagate_indirect_call_infos if doing
indirect inlining. Made static.
(cgraph_decide_inlining): Freeing ipa-prop structures after inlining
functions called only once.
(cgraph_decide_recursive_inlining): Don't call
ipa_propagate_indirect_call_infos, pass new_edges to
cgraph_mark_inline_edge instead.
(cgraph_decide_inlining_of_small_functions): Don't call
ipa_propagate_indirect_call_infos, pass new_edges to
cgraph_mark_inline_edge instead.
(cgraph_decide_inlining): Don't call
ipa_propagate_indirect_call_infos.
* ipa-prop.c: Check that vectors are allocated.
* ipa-inline.c (cgraph_mark_inline_edge): Returns boolean, true
iff a new cgraph edges have been created.
(cgraph_decide_inlining): New variable redo_always_inline.
Flattening and always_inlining loop until callgraph stabilizes.
* ipa-prop.c (update_call_notes_after_inlining): Returns boolean,
true iff new cgraph edges have been created.
(propagate_info_to_inlined_callees): Likewise.
(ipa_propagate_indirect_call_infos): Likewise.
From-SVN: r140293
Diffstat (limited to 'gcc/ipa-inline.c')
-rw-r--r-- | gcc/ipa-inline.c | 140 |
1 files changed, 75 insertions, 65 deletions
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 88566fe..662cff6 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -243,15 +243,19 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, cgraph_clone_inlined_nodes (e, duplicate, update_original); } -/* Mark edge E as inlined and update callgraph accordingly. - UPDATE_ORIGINAL specify whether profile of original function should be - updated. */ +/* Mark edge E as inlined and update callgraph accordingly. UPDATE_ORIGINAL + specify whether profile of original function should be updated. If any new + indirect edges are discovered in the process, add them to NEW_EDGES, unless + it is NULL. Return true iff any new callgraph edges were discovered as a + result of inlining. */ -void -cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original) +static bool +cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original, + VEC (cgraph_edge_p, heap) **new_edges) { int old_insns = 0, new_insns = 0; struct cgraph_node *to = NULL, *what; + struct cgraph_edge *curr = e; if (e->callee->inline_decl) cgraph_redirect_edge_callee (e, cgraph_node (e->callee->inline_decl)); @@ -281,6 +285,11 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original) if (new_insns > old_insns) overall_insns += new_insns - old_insns; ncalls_inlined++; + + if (flag_indirect_inlining) + return ipa_propagate_indirect_call_infos (curr, new_edges); + else + return false; } /* Mark all calls of EDGE->CALLEE inlined into EDGE->CALLER. @@ -302,7 +311,7 @@ cgraph_mark_inline (struct cgraph_edge *edge) next = e->next_caller; if (e->caller == to && e->inline_failed) { - cgraph_mark_inline_edge (e, true); + cgraph_mark_inline_edge (e, true, NULL); if (e == edge) edge = next; } @@ -747,9 +756,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node, fprintf (dump_file, "\n"); } cgraph_redirect_edge_callee (curr, master_clone); - cgraph_mark_inline_edge (curr, false); - if (flag_indirect_inlining) - ipa_propagate_indirect_call_infos (curr, new_edges); + cgraph_mark_inline_edge (curr, false, new_edges); lookup_recursive_calls (node, curr->callee, heap); n++; } @@ -1002,12 +1009,10 @@ cgraph_decide_inlining_of_small_functions (void) continue; } callee = edge->callee; - cgraph_mark_inline_edge (edge, true); + cgraph_mark_inline_edge (edge, true, &new_indirect_edges); if (flag_indirect_inlining) - { - ipa_propagate_indirect_call_infos (edge, &new_indirect_edges); - add_new_edges_to_heap (heap, new_indirect_edges); - } + add_new_edges_to_heap (heap, new_indirect_edges); + update_callee_keys (heap, callee, updated_nodes); } where = edge->caller; @@ -1070,6 +1075,7 @@ cgraph_decide_inlining (void) int old_insns = 0; int i; int initial_insns = 0; + bool redo_always_inline = true; cgraph_remove_function_insertion_hook (function_insertion_hook_holder); @@ -1103,69 +1109,70 @@ cgraph_decide_inlining (void) /* In the first pass mark all always_inline edges. Do this with a priority so none of our later choices will make this impossible. */ - for (i = nnodes - 1; i >= 0; i--) + while (redo_always_inline) { - struct cgraph_edge *e, *next; + redo_always_inline = false; + for (i = nnodes - 1; i >= 0; i--) + { + struct cgraph_edge *e, *next; - node = order[i]; + node = order[i]; - /* Handle nodes to be flattened, but don't update overall unit size. */ - if (lookup_attribute ("flatten", DECL_ATTRIBUTES (node->decl)) != NULL) - { - if (dump_file) - fprintf (dump_file, - "Flattening %s\n", cgraph_node_name (node)); - cgraph_decide_inlining_incrementally (node, INLINE_ALL, 0); - } + /* Handle nodes to be flattened, but don't update overall unit + size. */ + if (lookup_attribute ("flatten", + DECL_ATTRIBUTES (node->decl)) != NULL) + { + if (dump_file) + fprintf (dump_file, + "Flattening %s\n", cgraph_node_name (node)); + cgraph_decide_inlining_incrementally (node, INLINE_ALL, 0); + } - if (!node->local.disregard_inline_limits) - continue; - if (dump_file) - fprintf (dump_file, - "\nConsidering %s %i insns (always inline)\n", - cgraph_node_name (node), node->global.insns); - old_insns = overall_insns; - for (e = node->callers; e; e = next) - { - next = e->next_caller; - if (!e->inline_failed || gimple_call_cannot_inline_p (e->call_stmt)) + if (!node->local.disregard_inline_limits) continue; - if (cgraph_recursive_inlining_p (e->caller, e->callee, - &e->inline_failed)) - continue; - if (!tree_can_inline_p (e->caller->decl, e->callee->decl)) + if (dump_file) + fprintf (dump_file, + "\nConsidering %s %i insns (always inline)\n", + cgraph_node_name (node), node->global.insns); + old_insns = overall_insns; + for (e = node->callers; e; e = next) { - gimple_call_set_cannot_inline (e->call_stmt, true); - continue; + next = e->next_caller; + if (!e->inline_failed + || gimple_call_cannot_inline_p (e->call_stmt)) + continue; + if (cgraph_recursive_inlining_p (e->caller, e->callee, + &e->inline_failed)) + continue; + if (!tree_can_inline_p (e->caller->decl, e->callee->decl)) + { + gimple_call_set_cannot_inline (e->call_stmt, true); + continue; + } + if (cgraph_mark_inline_edge (e, true, NULL)) + redo_always_inline = true; + if (dump_file) + fprintf (dump_file, + " Inlined into %s which now has %i insns.\n", + cgraph_node_name (e->caller), + e->caller->global.insns); } - cgraph_mark_inline_edge (e, true); - if (flag_indirect_inlining) - ipa_propagate_indirect_call_infos (e, NULL); + /* Inlining self recursive function might introduce new calls to + themselves we didn't see in the loop above. Fill in the proper + reason why inline failed. */ + for (e = node->callers; e; e = e->next_caller) + if (e->inline_failed) + e->inline_failed = N_("recursive inlining"); if (dump_file) fprintf (dump_file, - " Inlined into %s which now has %i insns.\n", - cgraph_node_name (e->caller), - e->caller->global.insns); + " Inlined for a net change of %+i insns.\n", + overall_insns - old_insns); } - /* Inlining self recursive function might introduce new calls to - themselves we didn't see in the loop above. Fill in the proper - reason why inline failed. */ - for (e = node->callers; e; e = e->next_caller) - if (e->inline_failed) - e->inline_failed = N_("recursive inlining"); - if (dump_file) - fprintf (dump_file, - " Inlined for a net change of %+i insns.\n", - overall_insns - old_insns); } cgraph_decide_inlining_of_small_functions (); - /* After this point, any edge discovery performed by indirect inlining is no - good so let's give up. */ - if (flag_indirect_inlining) - free_all_ipa_structures_after_iinln (); - if (flag_inline_functions_called_once) { if (dump_file) @@ -1220,6 +1227,10 @@ cgraph_decide_inlining (void) } } + /* Free ipa-prop structures if they are no longer needed. */ + if (flag_indirect_inlining) + free_all_ipa_structures_after_iinln (); + if (dump_file) fprintf (dump_file, "\nInlined %i calls, eliminated %i functions, " @@ -1635,8 +1646,7 @@ inline_indirect_intraprocedural_analysis (struct cgraph_node *node) if (!flag_ipa_cp) { - ipa_count_formal_params (node); - ipa_create_param_decls_array (node); + ipa_initialize_node_params (node); ipa_detect_param_modifications (node); } ipa_analyze_params_uses (node); |