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>
* config/arm/predicates.md (expandable_comparison_operator): New
......@@ -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);
}
......
......@@ -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;
......
......@@ -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)
......
......@@ -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 ();
......
......@@ -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);
......
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