Commit 5ee53a06 by Jan Hubicka Committed by Jan Hubicka

ipa-inline-transform.c (inline_call): Always update jump functions after inlining.

	* 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.

From-SVN: r179083
parent aa0b3f8f
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> 2011-09-22 Richard Sandiford <richard.sandiford@linaro.org>
* config/arm/predicates.md (expandable_comparison_operator): New * config/arm/predicates.md (expandable_comparison_operator): New
...@@ -619,10 +619,7 @@ evaluate_conditions_for_edge (struct cgraph_edge *e, bool inline_p) ...@@ -619,10 +619,7 @@ evaluate_conditions_for_edge (struct cgraph_edge *e, bool inline_p)
struct inline_summary *info = inline_summary (callee); struct inline_summary *info = inline_summary (callee);
int i; int i;
if (ipa_node_params_vector && info->conds 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)))
{ {
struct ipa_node_params *parms_info; struct ipa_node_params *parms_info;
struct ipa_edge_args *args = IPA_EDGE_REF (e); struct ipa_edge_args *args = IPA_EDGE_REF (e);
...@@ -634,6 +631,7 @@ evaluate_conditions_for_edge (struct cgraph_edge *e, bool inline_p) ...@@ -634,6 +631,7 @@ evaluate_conditions_for_edge (struct cgraph_edge *e, bool inline_p)
else else
parms_info = IPA_NODE_REF (e->caller); parms_info = IPA_NODE_REF (e->caller);
if (count)
VEC_safe_grow_cleared (tree, heap, known_vals, count); VEC_safe_grow_cleared (tree, heap, known_vals, count);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
...@@ -2062,6 +2060,8 @@ remap_edge_predicates (struct cgraph_node *node, ...@@ -2062,6 +2060,8 @@ remap_edge_predicates (struct cgraph_node *node,
{ {
struct inline_edge_summary *es = inline_edge_summary (e); struct inline_edge_summary *es = inline_edge_summary (e);
struct predicate p; struct predicate p;
if (e->inline_failed)
{
if (es->predicate) if (es->predicate)
{ {
p = remap_predicate (info, callee_info, p = remap_predicate (info, callee_info,
...@@ -2077,12 +2077,13 @@ remap_edge_predicates (struct cgraph_node *node, ...@@ -2077,12 +2077,13 @@ remap_edge_predicates (struct cgraph_node *node,
e->frequency = 0; e->frequency = 0;
} }
} }
if (!e->inline_failed)
remap_edge_predicates (e->callee, info, callee_info, operand_map,
possible_truths, toplev_predicate);
else else
edge_set_predicate (e, toplev_predicate); edge_set_predicate (e, toplev_predicate);
} }
else
remap_edge_predicates (e->callee, info, callee_info, operand_map,
possible_truths, toplev_predicate);
}
for (e = node->indirect_calls; e; e = e->next_callee) for (e = node->indirect_calls; e; e = e->next_callee)
{ {
struct inline_edge_summary *es = inline_edge_summary (e); struct inline_edge_summary *es = inline_edge_summary (e);
...@@ -2122,6 +2123,7 @@ inline_merge_summary (struct cgraph_edge *edge) ...@@ -2122,6 +2123,7 @@ inline_merge_summary (struct cgraph_edge *edge)
VEC (int, heap) *operand_map = NULL; VEC (int, heap) *operand_map = NULL;
int i; int i;
struct predicate toplev_predicate; struct predicate toplev_predicate;
struct predicate true_p = true_predicate ();
struct inline_edge_summary *es = inline_edge_summary (edge); struct inline_edge_summary *es = inline_edge_summary (edge);
if (es->predicate) if (es->predicate)
...@@ -2129,17 +2131,14 @@ inline_merge_summary (struct cgraph_edge *edge) ...@@ -2129,17 +2131,14 @@ inline_merge_summary (struct cgraph_edge *edge)
else else
toplev_predicate = true_predicate (); toplev_predicate = true_predicate ();
if (ipa_node_params_vector && callee_info->conds 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)))
{ {
struct ipa_edge_args *args = IPA_EDGE_REF (edge); struct ipa_edge_args *args = IPA_EDGE_REF (edge);
int count = ipa_get_cs_argument_count (args); int count = ipa_get_cs_argument_count (args);
int i; int i;
clause = evaluate_conditions_for_edge (edge, true); clause = evaluate_conditions_for_edge (edge, true);
if (count)
VEC_safe_grow_cleared (int, heap, operand_map, count); VEC_safe_grow_cleared (int, heap, operand_map, count);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
...@@ -2176,6 +2175,9 @@ inline_merge_summary (struct cgraph_edge *edge) ...@@ -2176,6 +2175,9 @@ inline_merge_summary (struct cgraph_edge *edge)
inline_update_callee_summaries (edge->callee, inline_update_callee_summaries (edge->callee,
inline_edge_summary (edge)->loop_depth); 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->time = (info->time + INLINE_TIME_SCALE / 2) / INLINE_TIME_SCALE;
info->size = (info->size + INLINE_SIZE_SCALE / 2) / INLINE_SIZE_SCALE; info->size = (info->size + INLINE_SIZE_SCALE / 2) / INLINE_SIZE_SCALE;
} }
...@@ -2389,9 +2391,7 @@ inline_analyze_function (struct cgraph_node *node) ...@@ -2389,9 +2391,7 @@ inline_analyze_function (struct cgraph_node *node)
if (dump_file) if (dump_file)
fprintf (dump_file, "\nAnalyzing function: %s/%u\n", fprintf (dump_file, "\nAnalyzing function: %s/%u\n",
cgraph_node_name (node), node->uid); cgraph_node_name (node), node->uid);
/* FIXME: We should remove the optimize check after we ensure we never run if (optimize && !node->thunk.thunk_p)
IPA passes when not optimizing. */
if (flag_indirect_inlining && optimize && !node->thunk.thunk_p)
inline_indirect_intraprocedural_analysis (node); inline_indirect_intraprocedural_analysis (node);
compute_inline_parameters (node, false); compute_inline_parameters (node, false);
...@@ -2419,7 +2419,6 @@ inline_generate_summary (void) ...@@ -2419,7 +2419,6 @@ inline_generate_summary (void)
function_insertion_hook_holder = function_insertion_hook_holder =
cgraph_add_function_insertion_hook (&add_new_function, NULL); 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) FOR_EACH_DEFINED_FUNCTION (node)
...@@ -2572,7 +2571,7 @@ inline_read_summary (void) ...@@ -2572,7 +2571,7 @@ inline_read_summary (void)
this should never happen. */ this should never happen. */
fatal_error ("ipa inline summary is missing in input file"); fatal_error ("ipa inline summary is missing in input file");
} }
if (flag_indirect_inlining) if (optimize)
{ {
ipa_register_cgraph_hooks (); ipa_register_cgraph_hooks ();
if (!flag_ipa_cp) if (!flag_ipa_cp)
...@@ -2676,7 +2675,7 @@ inline_write_summary (cgraph_node_set set, ...@@ -2676,7 +2675,7 @@ inline_write_summary (cgraph_node_set set,
produce_asm (ob, NULL); produce_asm (ob, NULL);
destroy_output_block (ob); destroy_output_block (ob);
if (flag_indirect_inlining && !flag_ipa_cp) if (optimize && !flag_ipa_cp)
ipa_prop_write_jump_functions (set); ipa_prop_write_jump_functions (set);
} }
......
...@@ -248,7 +248,7 @@ inline_call (struct cgraph_edge *e, bool update_original, ...@@ -248,7 +248,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
*overall_size += new_size - old_size; *overall_size += new_size - old_size;
ncalls_inlined++; ncalls_inlined++;
if (flag_indirect_inlining && optimize) if (optimize)
return ipa_propagate_indirect_call_infos (curr, new_edges); return ipa_propagate_indirect_call_infos (curr, new_edges);
else else
return false; return false;
......
...@@ -1659,10 +1659,8 @@ ipa_inline (void) ...@@ -1659,10 +1659,8 @@ ipa_inline (void)
XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
int i; int i;
if (in_lto_p && flag_indirect_inlining) if (in_lto_p && optimize)
ipa_update_after_lto_read (); ipa_update_after_lto_read ();
if (flag_indirect_inlining)
ipa_create_all_structures_for_iinln ();
if (dump_file) if (dump_file)
dump_inline_summaries (dump_file); dump_inline_summaries (dump_file);
...@@ -1757,7 +1755,7 @@ ipa_inline (void) ...@@ -1757,7 +1755,7 @@ ipa_inline (void)
} }
/* Free ipa-prop structures if they are no longer needed. */ /* Free ipa-prop structures if they are no longer needed. */
if (flag_indirect_inlining) if (optimize)
ipa_free_all_structures_after_iinln (); ipa_free_all_structures_after_iinln ();
if (dump_file) if (dump_file)
......
...@@ -56,10 +56,6 @@ VEC (ipa_node_params_t, heap) *ipa_node_params_vector; ...@@ -56,10 +56,6 @@ VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
/* Vector where the parameter infos are actually stored. */ /* Vector where the parameter infos are actually stored. */
VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector; 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: */ /* Holders of ipa cgraph hooks: */
static struct cgraph_edge_hook_list *edge_removal_hook_holder; static struct cgraph_edge_hook_list *edge_removal_hook_holder;
static struct cgraph_node_hook_list *node_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, ...@@ -1699,18 +1695,14 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
struct ipa_jump_func *jfunc; struct ipa_jump_func *jfunc;
next_ie = ie->next_callee; 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) if (ici->param_index == -1)
continue; continue;
/* We must check range due to calls with variable number of arguments: */ /* We must check range due to calls with variable number of arguments: */
if (ici->param_index >= ipa_get_cs_argument_count (top)) if (ici->param_index >= ipa_get_cs_argument_count (top))
{ {
bitmap_set_bit (iinlining_processed_edges, ie->uid); ici->param_index = -1;
continue; continue;
} }
...@@ -1725,7 +1717,10 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, ...@@ -1725,7 +1717,10 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
} }
else else
/* Either we can find a destination for this edge now or never. */ /* 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) if (ici->polymorphic)
new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc); new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc);
...@@ -1771,6 +1766,8 @@ propagate_info_to_inlined_callees (struct cgraph_edge *cs, ...@@ -1771,6 +1766,8 @@ propagate_info_to_inlined_callees (struct cgraph_edge *cs,
res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges); res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
else else
update_jump_functions_after_inlining (cs, e); 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; return res;
} }
...@@ -1785,13 +1782,19 @@ bool ...@@ -1785,13 +1782,19 @@ bool
ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
VEC (cgraph_edge_p, heap) **new_edges) VEC (cgraph_edge_p, heap) **new_edges)
{ {
bool changed;
/* Do nothing if the preparation phase has not been carried out yet /* Do nothing if the preparation phase has not been carried out yet
(i.e. during early inlining). */ (i.e. during early inlining). */
if (!ipa_node_params_vector) if (!ipa_node_params_vector)
return false; return false;
gcc_assert (ipa_edge_args_vector); 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 /* 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, ...@@ -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, new_args->jump_functions = VEC_copy (ipa_jump_func_t, gc,
old_args->jump_functions); 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. */ /* Hook that is called by cgraph.c when a node is duplicated. */
...@@ -1963,21 +1962,13 @@ ipa_unregister_cgraph_hooks (void) ...@@ -1963,21 +1962,13 @@ ipa_unregister_cgraph_hooks (void)
function_insertion_hook_holder = NULL; 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 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
longer needed after ipa-cp. */ longer needed after ipa-cp. */
void void
ipa_free_all_structures_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_edge_args ();
ipa_free_all_node_params (); ipa_free_all_node_params ();
...@@ -1993,8 +1984,6 @@ ipa_free_all_structures_after_ipa_cp (void) ...@@ -1993,8 +1984,6 @@ ipa_free_all_structures_after_ipa_cp (void)
void void
ipa_free_all_structures_after_iinln (void) ipa_free_all_structures_after_iinln (void)
{ {
BITMAP_FREE (iinlining_processed_edges);
ipa_free_all_edge_args (); ipa_free_all_edge_args ();
ipa_free_all_node_params (); ipa_free_all_node_params ();
ipa_unregister_cgraph_hooks (); ipa_unregister_cgraph_hooks ();
......
...@@ -282,7 +282,6 @@ void ipa_free_edge_args_substructures (struct ipa_edge_args *); ...@@ -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_node_params_substructures (struct ipa_node_params *);
void ipa_free_all_node_params (void); void ipa_free_all_node_params (void);
void ipa_free_all_edge_args (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_ipa_cp (void);
void ipa_free_all_structures_after_iinln (void); void ipa_free_all_structures_after_iinln (void);
void ipa_register_cgraph_hooks (void); void ipa_register_cgraph_hooks (void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment