diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 29 | ||||
-rw-r--r-- | gcc/ipa-inline-analysis.c | 63 | ||||
-rw-r--r-- | gcc/ipa-inline-transform.c | 2 | ||||
-rw-r--r-- | gcc/ipa-inline.c | 6 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 41 | ||||
-rw-r--r-- | gcc/ipa-prop.h | 1 |
6 files changed, 78 insertions, 64 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7291c09..d5cd52f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2011-09-22 Jan Hubicka <jh@suse.cz> + + * ipa-inline-transform.c (inline_call): Always update jump functions + after inlining. + * ipa-inline.c (ipa_inline): Likewise; do not call + ipa_create_all_structures_for_iinln. + (ipa_inline): Always free jump functions. + * ipa-inline-analysis.c (evaluate_conditions_for_edge): Remove + hack. + (remap_edge_predicates): Fix pasto. + (inline_merge_summary): Remove nlined edge predicate; remove hack. + (inline_analyze_function): Always initialize jump functions. + (inline_generate_summary): Likewise. + (inline_write_summary): Always write jump functions when ipa-cp + is not doing that. + (inline_read_summary): Always read jump functions when ipa-cp + is not doing that. + * ipa-prop.c (iinlining_processed_edges): Remove. + (update_indirect_edges_after_inlining): Do not use + iinlining_processed_edges; instead set param_index to -1. + (propagate_info_to_inlined_callees): Only try to indirect inlining + when asked to do so; update jump functions of indirect calls, too; + remove jump functions of the inlined edge. + (ipa_edge_duplication_hook): Do not copy iinlining_processed_edges. + (ipa_create_all_structures_for_iinln): Remove. + (ipa_free_all_structures_after_iinln): Do not free + iinlining_processed_edges. + * ipa-prop.h (ipa_create_all_structures_for_iinln): Remove. + 2011-09-22 Richard Sandiford <richard.sandiford@linaro.org> * config/arm/predicates.md (expandable_comparison_operator): New diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 3437c1c..5047424 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -619,10 +619,7 @@ evaluate_conditions_for_edge (struct cgraph_edge *e, bool inline_p) struct inline_summary *info = inline_summary (callee); int i; - if (ipa_node_params_vector && info->conds - /* FIXME: it seems that we forget to get argument count in some cases, - probaby for previously indirect edges or so. */ - && ipa_get_cs_argument_count (IPA_EDGE_REF (e))) + if (ipa_node_params_vector && info->conds) { struct ipa_node_params *parms_info; struct ipa_edge_args *args = IPA_EDGE_REF (e); @@ -634,7 +631,8 @@ evaluate_conditions_for_edge (struct cgraph_edge *e, bool inline_p) else parms_info = IPA_NODE_REF (e->caller); - VEC_safe_grow_cleared (tree, heap, known_vals, count); + if (count) + VEC_safe_grow_cleared (tree, heap, known_vals, count); for (i = 0; i < count; i++) { tree cst = ipa_cst_from_jfunc (parms_info, @@ -2062,26 +2060,29 @@ remap_edge_predicates (struct cgraph_node *node, { struct inline_edge_summary *es = inline_edge_summary (e); struct predicate p; - if (es->predicate) + if (e->inline_failed) { - p = remap_predicate (info, callee_info, - es->predicate, operand_map, possible_truths, - toplev_predicate); - edge_set_predicate (e, &p); - /* TODO: We should remove the edge for code that will be optimized out, - but we need to keep verifiers and tree-inline happy. - Make it cold for now. */ - if (false_predicate_p (&p)) + if (es->predicate) { - e->count = 0; - e->frequency = 0; + p = remap_predicate (info, callee_info, + es->predicate, operand_map, possible_truths, + toplev_predicate); + edge_set_predicate (e, &p); + /* TODO: We should remove the edge for code that will be optimized out, + but we need to keep verifiers and tree-inline happy. + Make it cold for now. */ + if (false_predicate_p (&p)) + { + e->count = 0; + e->frequency = 0; + } } + else + edge_set_predicate (e, toplev_predicate); } - if (!e->inline_failed) + else remap_edge_predicates (e->callee, info, callee_info, operand_map, possible_truths, toplev_predicate); - else - edge_set_predicate (e, toplev_predicate); } for (e = node->indirect_calls; e; e = e->next_callee) { @@ -2122,6 +2123,7 @@ inline_merge_summary (struct cgraph_edge *edge) VEC (int, heap) *operand_map = NULL; int i; struct predicate toplev_predicate; + struct predicate true_p = true_predicate (); struct inline_edge_summary *es = inline_edge_summary (edge); if (es->predicate) @@ -2129,18 +2131,15 @@ inline_merge_summary (struct cgraph_edge *edge) else toplev_predicate = true_predicate (); - if (ipa_node_params_vector && callee_info->conds - /* FIXME: it seems that we forget to get argument count in some cases, - probaby for previously indirect edges or so. - Removing the test leads to ICE on tramp3d. */ - && ipa_get_cs_argument_count (IPA_EDGE_REF (edge))) + if (ipa_node_params_vector && callee_info->conds) { struct ipa_edge_args *args = IPA_EDGE_REF (edge); int count = ipa_get_cs_argument_count (args); int i; clause = evaluate_conditions_for_edge (edge, true); - VEC_safe_grow_cleared (int, heap, operand_map, count); + if (count) + VEC_safe_grow_cleared (int, heap, operand_map, count); for (i = 0; i < count; i++) { struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i); @@ -2176,6 +2175,9 @@ inline_merge_summary (struct cgraph_edge *edge) inline_update_callee_summaries (edge->callee, inline_edge_summary (edge)->loop_depth); + /* We do not maintain predicates of inlined edges, free it. */ + edge_set_predicate (edge, &true_p); + info->time = (info->time + INLINE_TIME_SCALE / 2) / INLINE_TIME_SCALE; info->size = (info->size + INLINE_SIZE_SCALE / 2) / INLINE_SIZE_SCALE; } @@ -2389,9 +2391,7 @@ inline_analyze_function (struct cgraph_node *node) if (dump_file) fprintf (dump_file, "\nAnalyzing function: %s/%u\n", cgraph_node_name (node), node->uid); - /* FIXME: We should remove the optimize check after we ensure we never run - IPA passes when not optimizing. */ - if (flag_indirect_inlining && optimize && !node->thunk.thunk_p) + if (optimize && !node->thunk.thunk_p) inline_indirect_intraprocedural_analysis (node); compute_inline_parameters (node, false); @@ -2419,8 +2419,7 @@ inline_generate_summary (void) function_insertion_hook_holder = cgraph_add_function_insertion_hook (&add_new_function, NULL); - if (flag_indirect_inlining) - ipa_register_cgraph_hooks (); + ipa_register_cgraph_hooks (); FOR_EACH_DEFINED_FUNCTION (node) if (!node->alias) @@ -2572,7 +2571,7 @@ inline_read_summary (void) this should never happen. */ fatal_error ("ipa inline summary is missing in input file"); } - if (flag_indirect_inlining) + if (optimize) { ipa_register_cgraph_hooks (); if (!flag_ipa_cp) @@ -2676,7 +2675,7 @@ inline_write_summary (cgraph_node_set set, produce_asm (ob, NULL); destroy_output_block (ob); - if (flag_indirect_inlining && !flag_ipa_cp) + if (optimize && !flag_ipa_cp) ipa_prop_write_jump_functions (set); } diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index 600eb0d..2609e42 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -248,7 +248,7 @@ inline_call (struct cgraph_edge *e, bool update_original, *overall_size += new_size - old_size; ncalls_inlined++; - if (flag_indirect_inlining && optimize) + if (optimize) return ipa_propagate_indirect_call_infos (curr, new_edges); else return false; diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 304a4df..f069914 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1659,10 +1659,8 @@ ipa_inline (void) XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); int i; - if (in_lto_p && flag_indirect_inlining) + if (in_lto_p && optimize) ipa_update_after_lto_read (); - if (flag_indirect_inlining) - ipa_create_all_structures_for_iinln (); if (dump_file) dump_inline_summaries (dump_file); @@ -1757,7 +1755,7 @@ ipa_inline (void) } /* Free ipa-prop structures if they are no longer needed. */ - if (flag_indirect_inlining) + if (optimize) ipa_free_all_structures_after_iinln (); if (dump_file) diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 066bbdb..52f583a 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -56,10 +56,6 @@ VEC (ipa_node_params_t, heap) *ipa_node_params_vector; /* Vector where the parameter infos are actually stored. */ VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector; -/* Bitmap with all UIDs of call graph edges that have been already processed - by indirect inlining. */ -static bitmap iinlining_processed_edges; - /* Holders of ipa cgraph hooks: */ static struct cgraph_edge_hook_list *edge_removal_hook_holder; static struct cgraph_node_hook_list *node_removal_hook_holder; @@ -1699,18 +1695,14 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, struct ipa_jump_func *jfunc; next_ie = ie->next_callee; - if (bitmap_bit_p (iinlining_processed_edges, ie->uid)) - continue; - /* If we ever use indirect edges for anything other than indirect - inlining, we will need to skip those with negative param_indices. */ if (ici->param_index == -1) continue; /* We must check range due to calls with variable number of arguments: */ if (ici->param_index >= ipa_get_cs_argument_count (top)) { - bitmap_set_bit (iinlining_processed_edges, ie->uid); + ici->param_index = -1; continue; } @@ -1725,7 +1717,10 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, } else /* Either we can find a destination for this edge now or never. */ - bitmap_set_bit (iinlining_processed_edges, ie->uid); + ici->param_index = -1; + + if (!flag_indirect_inlining) + continue; if (ici->polymorphic) new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc); @@ -1771,6 +1766,8 @@ propagate_info_to_inlined_callees (struct cgraph_edge *cs, res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges); else update_jump_functions_after_inlining (cs, e); + for (e = node->indirect_calls; e; e = e->next_callee) + update_jump_functions_after_inlining (cs, e); return res; } @@ -1785,13 +1782,19 @@ bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, VEC (cgraph_edge_p, heap) **new_edges) { + bool changed; /* Do nothing if the preparation phase has not been carried out yet (i.e. during early inlining). */ if (!ipa_node_params_vector) return false; gcc_assert (ipa_edge_args_vector); - return propagate_info_to_inlined_callees (cs, cs->callee, new_edges); + changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges); + + /* We do not keep jump functions of inlined edges up to date. Better to free + them so we do not access them accidentally. */ + ipa_free_edge_args_substructures (IPA_EDGE_REF (cs)); + return changed; } /* Frees all dynamically allocated structures that the argument info points @@ -1889,10 +1892,6 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, new_args->jump_functions = VEC_copy (ipa_jump_func_t, gc, old_args->jump_functions); - - if (iinlining_processed_edges - && bitmap_bit_p (iinlining_processed_edges, src->uid)) - bitmap_set_bit (iinlining_processed_edges, dst->uid); } /* Hook that is called by cgraph.c when a node is duplicated. */ @@ -1963,21 +1962,13 @@ ipa_unregister_cgraph_hooks (void) function_insertion_hook_holder = NULL; } -/* Allocate all necessary data structures necessary for indirect inlining. */ - -void -ipa_create_all_structures_for_iinln (void) -{ - iinlining_processed_edges = BITMAP_ALLOC (NULL); -} - /* Free all ipa_node_params and all ipa_edge_args structures if they are no longer needed after ipa-cp. */ void ipa_free_all_structures_after_ipa_cp (void) { - if (!flag_indirect_inlining) + if (!optimize) { ipa_free_all_edge_args (); ipa_free_all_node_params (); @@ -1993,8 +1984,6 @@ ipa_free_all_structures_after_ipa_cp (void) void ipa_free_all_structures_after_iinln (void) { - BITMAP_FREE (iinlining_processed_edges); - ipa_free_all_edge_args (); ipa_free_all_node_params (); ipa_unregister_cgraph_hooks (); diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index fafd17d..1b7ba69 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -282,7 +282,6 @@ void ipa_free_edge_args_substructures (struct ipa_edge_args *); void ipa_free_node_params_substructures (struct ipa_node_params *); void ipa_free_all_node_params (void); void ipa_free_all_edge_args (void); -void ipa_create_all_structures_for_iinln (void); void ipa_free_all_structures_after_ipa_cp (void); void ipa_free_all_structures_after_iinln (void); void ipa_register_cgraph_hooks (void); |