diff options
author | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-23 19:45:45 +0000 |
---|---|---|
committer | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-23 19:45:45 +0000 |
commit | f8daee9bad3067f34c8061fc0fcb2f9dc9525a1b (patch) | |
tree | 425c693ef81efc3a4ab38d1ddfbc42bc63047cc2 /gcc/ipa-inline.c | |
parent | 5cd72fe59d2227a76053c6e4f80ca59dce966a20 (diff) | |
download | gcc-f8daee9bad3067f34c8061fc0fcb2f9dc9525a1b.tar.gz |
2008-07-23 Martin Jambor <mjambor@suse.cz>
* ipa-cp.c (ipcp_print_edge_profiles): Test for node->analyzed
rather than for DECL_SAVED_TREE.
* ipa-prop.c: Include diagnostic.h.
(ipa_check_stmt_modifications): Check LHS of GIMPLE_MODIFY_EXPRs
thoroughly.
(ipa_detect_param_modifications): Function rewritten from scratch.
(ipa_compute_jump_functions): Changed accesses to modification flags.
(ipa_free_node_params_substructures): Update flags destruction.
(ipa_node_duplication_hook): Update flags duplication.
(ipa_print_all_params_modified): Updated flag access.
* ipa-prop.h (struct ipa_param_flags): New structure.
(struct ipa_node_params): New field modification_analysis_done,
modified_flags changed into param_flags.
(ipa_is_ith_param_modified): Changed to use new flags.
* Makefile.in (ipa-prop.o): Add $(DIAGNOSTIC_H) to dependencies.
* ipa-prop.c (ipa_print_all_jump_functions): Moved here from
ipa-cp.c and split into two functions.
(ipa_print_node_jump_functions): New function.
(compute_scalar_jump_functions): New function.
(type_like_member_ptr_p): New function.
(compute_pass_through_member_ptrs): New function.
(fill_member_ptr_cst_jump_function): New function.
(determine_cst_member_ptr): New function.
(compute_cst_member_ptr_arguments): New function.
(ipa_compute_jump_functions): Complete rewrite.
* ipa-prop.h (enum jump_func_type): Make explicit that we depend
on IPA_UNKNOWN being zero. Added value IPA_CONST_MEMBER_PTR.
(struct ipa_member_ptr_cst): New structure.
(union jump_func_value): New field member_cst.
* ipa-cp.c (ipcp_lat_is_insertable): New function.
(ipcp_lattice_from_jfunc): Produces bottom lattices for unhandled
jump function types.
(ipcp_print_all_lattices): Slight fprintf rearrangement.
(ipcp_print_all_structures): Call ipa_print_all_jump_functions
instead of ipcp_print_all_jump_functions.
(ipcp_insert_stage): Use ipcp_lat_is_insertable, create replace maps
only for replacable scalars.
* doc/invoke.texi (Optimize options): Add description of
-findirect-inlining.
* common.opt (flag_indirect_inlining): New flag.
* opts.c (decode_options): Set flag_indirect_inlining when
optimize >= 3.
* ipa-inline.c: Include ipa-prop.h.
(inline_indirect_intraprocedural_analysis): New function.
(inline_generate_summary): Allocate parameter and argument info
structures, call inline_indirect_intraprocedural_analysis on each
node when doing indirect inlining and deallocate indirect inlining
data structures in the end.
* ipa-prop.c (ipa_create_param_decls_array): Return if already done.
(free_all_ipa_structures_after_iinln): New function.
(free_all_ipa_structures_after_ipa_cp): Checks whether iinln will be
done.
* Makefile.in (ipa-inline.o): Added $(IPA_PROP_H) to dependencies.
* cgraphbuild.c (compute_call_stmt_bb_frequency): New function.
(build_cgraph_edges): Call compute_call_stmt_bb_frequency instead
of computing the frequency separately.
(rebuild_cgraph_edges): Call compute_call_stmt_bb_frequency instead
of computing the frequency separately.
* ipa-cp.c (ipcp_print_all_structures): Replace a call to
ipa_print_all_param_modified with a call to ipa_print_all_param_flags.
* ipa-prop.c (ipa_get_member_ptr_load_param): New function.
(ipa_get_stmt_member_ptr_load_param): New function.
(ipa_is_ssa_with_stmt_def): New function.
(ipa_note_param_call): New function.
(ipa_analyze_call_uses): New function.
(ipa_analyze_stmt_uses): New function.
(ipa_analyze_params_uses): New function.
(ipa_free_node_params_substructures): Also free the param_calls linked
list.
(ipa_node_duplication_hook): Also duplicate the param_calls linked list.
(ipa_print_node_param_flags): New function.
(ipa_print_all_params_modified): Renamed to ipa_print_all_param_flags.
(ipa_print_all_param_flags): Calls ipa_print_node_param_flags.
* ipa-prop.h (struct ipa_param_flags): New field called.
(struct ipa_param_call_note): New structure.
(struct ipa_node_params): New fields param_calls and
uses_analysis_done.
(ipa_is_ith_param_called): New function.
* ipa-inline.c (inline_indirect_intraprocedural_analysis): Call
ipa_analyze_params_uses and dump parameter flags.
* ipa-inline.c (cgraph_decide_recursive_inlining): Call
ipa_propagate_indirect_call_infos if performing indirect inlining,
pass a new parameter new_edges to it.
(add_new_edges_to_heap): New fucntion.
(cgraph_decide_inlining_of_small_functions): New vector
new_indirect_edges for newly found indirect edges , call
ipa_propagate_indirect_call_infos after inlining.
(cgraph_decide_inlining): Call ipa_propagate_indirect_call_infos after
inlining if performing indirect inlining. Call
free_all_ipa_structures_after_iinln when doing so too.
(inline_generate_summary): Do not call
free_all_ipa_structures_after_iinln here.
* ipa-prop.c (update_jump_functions_after_inlining): New function.
(print_edge_addition_message): New function.
(update_call_notes_after_inlining): New function.
(propagate_info_to_inlined_callees): New function.
(ipa_propagate_indirect_call_infos): New function.
* ipa-prop.h: Include cgraph.h
(struct ipa_param_call_note): Fields reordered, new field processed.
* cgraph.h (cgraph_edge): Shrink loop_nest field to 31 bits, add a new
flag indirect_call.
* cgraphunit.c (verify_cgraph_node): Allow indirect edges not to have
rediscovered call statements.
* cgraph.c (cgraph_create_edge): Initialize indirect_call to zero.
(dump_cgraph_node): Dump also the indirect_call flag.
(cgraph_clone_edge): Copy also the indirect_call flag.
* tree-inline.c (copy_bb): Do not check for fndecls from call
expressions, check for edge availability when moving clones.
(get_indirect_callee_fndecl): New function.
(expand_call_inline): If callee declaration is not apprent from
the statement, try calling get_indirect_callee_fndecl. Do not
issue warnings or call sorry when not inlinings an indirect edge.
* Makefile.in (IPA_PROP_H): Added $(CGRAPH_H) to dependencies.
* ipa-prop.c (ipa_print_node_param_flags): Make the dump format a
bit more frandly to matching.
* testsuite/g++.dg/ipa/iinline-1.C: New testcase.
* testsuite/gcc.dg/ipa/iinline-1.c: New testcase.
* testsuite/gcc.dg/ipa/modif-1.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@138092 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline.c')
-rw-r--r-- | gcc/ipa-inline.c | 82 |
1 files changed, 79 insertions, 3 deletions
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index b7f1597691a..3683ec772ac 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -139,6 +139,7 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "tree-flow.h" #include "rtl.h" +#include "ipa-prop.h" /* Mode incremental inliner operate on: @@ -660,10 +661,12 @@ lookup_recursive_calls (struct cgraph_node *node, struct cgraph_node *where, } /* Decide on recursive inlining: in the case function has recursive calls, - inline until body size reaches given argument. */ + inline until body size reaches given argument. If any new indirect edges + are discovered in the process, add them to NEW_EDGES, unless it is NULL. */ static bool -cgraph_decide_recursive_inlining (struct cgraph_node *node) +cgraph_decide_recursive_inlining (struct cgraph_node *node, + VEC (cgraph_edge_p, heap) *new_edges) { int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO); int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO); @@ -760,6 +763,8 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node) } 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); lookup_recursive_calls (node, curr->callee, heap); n++; } @@ -817,6 +822,20 @@ compute_max_insns (int insns) * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100); } +/* Compute badness of all edges in NEW_EDGES and add them to the HEAP. */ +static void +add_new_edges_to_heap (fibheap_t heap, VEC (cgraph_edge_p, heap) *new_edges) +{ + while (VEC_length (cgraph_edge_p, new_edges) > 0) + { + struct cgraph_edge *edge = VEC_pop (cgraph_edge_p, new_edges); + + gcc_assert (!edge->aux); + edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge), edge); + } +} + + /* We use greedy algorithm for inlining of small functions: All inline candidates are put into prioritized heap based on estimated growth of the overall number of instructions and then update the estimates. @@ -833,6 +852,10 @@ cgraph_decide_inlining_of_small_functions (void) fibheap_t heap = fibheap_new (); bitmap updated_nodes = BITMAP_ALLOC (NULL); int min_insns, max_insns; + VEC (cgraph_edge_p, heap) *new_indirect_edges = NULL; + + if (flag_indirect_inlining) + new_indirect_edges = VEC_alloc (cgraph_edge_p, heap, 8); if (dump_file) fprintf (dump_file, "\nDeciding on smaller functions:\n"); @@ -968,8 +991,10 @@ cgraph_decide_inlining_of_small_functions (void) where = edge->caller; if (where->global.inlined_to) where = where->global.inlined_to; - if (!cgraph_decide_recursive_inlining (where)) + if (!cgraph_decide_recursive_inlining (where, new_indirect_edges)) continue; + if (flag_indirect_inlining) + add_new_edges_to_heap (heap, new_indirect_edges); update_callee_keys (heap, where, updated_nodes); } else @@ -986,6 +1011,11 @@ cgraph_decide_inlining_of_small_functions (void) } callee = edge->callee; cgraph_mark_inline_edge (edge, true); + if (flag_indirect_inlining) + { + ipa_propagate_indirect_call_infos (edge, new_indirect_edges); + add_new_edges_to_heap (heap, new_indirect_edges); + } update_callee_keys (heap, callee, updated_nodes); } where = edge->caller; @@ -1028,6 +1058,9 @@ cgraph_decide_inlining_of_small_functions (void) &edge->inline_failed)) edge->inline_failed = N_("--param inline-unit-growth limit reached"); } + + if (new_indirect_edges) + VEC_free (cgraph_edge_p, heap, new_indirect_edges); fibheap_delete (heap); BITMAP_FREE (updated_nodes); } @@ -1112,6 +1145,8 @@ cgraph_decide_inlining (void) continue; } cgraph_mark_inline_edge (e, true); + if (flag_indirect_inlining) + ipa_propagate_indirect_call_infos (e, NULL); if (dump_file) fprintf (dump_file, " Inlined into %s which now has %i insns.\n", @@ -1133,6 +1168,11 @@ cgraph_decide_inlining (void) if (!flag_really_no_inline) 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_really_no_inline && flag_inline_functions_called_once) { @@ -1612,6 +1652,31 @@ struct gimple_opt_pass pass_inline_parameters = } }; +/* This function performs intraprocedural analyzis in NODE that is required to + inline indirect calls. */ +static void +inline_indirect_intraprocedural_analysis (struct cgraph_node *node) +{ + struct cgraph_edge *cs; + + ipa_count_formal_params (node); + ipa_create_param_decls_array (node); + ipa_detect_param_modifications (node); + ipa_analyze_params_uses (node); + + if (dump_file) + ipa_print_node_param_flags (dump_file, node); + + for (cs = node->callees; cs; cs = cs->next_callee) + { + ipa_count_arguments (cs); + ipa_compute_jump_functions (cs); + } + + if (dump_file) + ipa_print_node_jump_functions (dump_file, node); +} + /* Note function body size. */ static void inline_generate_summary (void) @@ -1621,6 +1686,13 @@ inline_generate_summary (void) int nnodes = cgraph_postorder (order); int i; + if (flag_indirect_inlining) + { + ipa_register_cgraph_hooks (); + ipa_check_create_node_params (); + ipa_check_create_edge_args (); + } + for (i = nnodes - 1; i >= 0; i--) { struct cgraph_node *node = order[i]; @@ -1632,6 +1704,10 @@ inline_generate_summary (void) push_cfun (DECL_STRUCT_FUNCTION (node->decl)); current_function_decl = node->decl; compute_inline_parameters (node); + + if (flag_indirect_inlining) + inline_indirect_intraprocedural_analysis (node); + pop_cfun (); } } |