aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2011-09-22 13:57:43 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2011-09-22 11:57:43 +0000
commit5ee53a067403d9cccadb7f599652581c298088b3 (patch)
treeb8f1b5b279159d592c4f9d9ddd21e222f26b5fd4
parentaa0b3f8f8d4748aaaee4892ed0d5d85abb2e86f6 (diff)
downloadgcc-5ee53a067403d9cccadb7f599652581c298088b3.zip
gcc-5ee53a067403d9cccadb7f599652581c298088b3.tar.gz
gcc-5ee53a067403d9cccadb7f599652581c298088b3.tar.bz2
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
-rw-r--r--gcc/ChangeLog29
-rw-r--r--gcc/ipa-inline-analysis.c63
-rw-r--r--gcc/ipa-inline-transform.c2
-rw-r--r--gcc/ipa-inline.c6
-rw-r--r--gcc/ipa-prop.c41
-rw-r--r--gcc/ipa-prop.h1
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);