summaryrefslogtreecommitdiff
path: root/gcc/ipa-inline-analysis.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-11 18:14:35 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-11 18:14:35 +0000
commitbe343a9c2c6c0a688b3c299da498cbeb8e8ead72 (patch)
tree5c72b6d621b40aab51257d773d939ff6d2be4567 /gcc/ipa-inline-analysis.c
parentfa3448f1d003fd36bb176f4cf2d497d44287271a (diff)
downloadgcc-be343a9c2c6c0a688b3c299da498cbeb8e8ead72.tar.gz
PR middle-end/48636
* ipa-inline.c (want_inline_small_function_p): Take aray index hint. (edge_badness): Likewise. * ipa-inline.h (inline_hints_vals): Add array_index and comments. (inline_summary_: Add ARRAY_INDEX. * ipa-inline-analysis.c (dump_inline_hints): Dump array_index hint. (reset_inline_summary): Handle array_index hint. (inline_node_duplication_hook): Likewise. (dump_inline_summary): Likewise. (array_index_predicate): New function. (estimate_function_body_sizes): Use it. (estimate_node_size_and_time): Use array_index hint. (inline_merge_summary, inline_read_section): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193406 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r--gcc/ipa-inline-analysis.c116
1 files changed, 101 insertions, 15 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 75dc3085106..f7b3af13cf6 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -659,6 +659,11 @@ dump_inline_hints (FILE *f, inline_hints hints)
hints &= ~INLINE_HINT_declared_inline;
fprintf (f, " declared_inline");
}
+ if (hints & INLINE_HINT_array_index)
+ {
+ hints &= ~INLINE_HINT_array_index;
+ fprintf (f, " array_index");
+ }
gcc_assert (!hints);
}
@@ -1007,6 +1012,11 @@ reset_inline_summary (struct cgraph_node *node)
pool_free (edge_predicate_pool, info->loop_stride);
info->loop_stride = NULL;
}
+ if (info->array_index)
+ {
+ pool_free (edge_predicate_pool, info->array_index);
+ info->array_index = NULL;
+ }
VEC_free (condition, gc, info->conds);
VEC_free (size_time_entry,gc, info->entry);
for (e = node->callees; e; e = e->next_callee)
@@ -1201,6 +1211,9 @@ inline_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
remap_hint_predicate_after_duplication (&info->loop_stride,
possible_truths,
info);
+ remap_hint_predicate_after_duplication (&info->array_index,
+ possible_truths,
+ info);
/* If inliner or someone after inliner will ever start producing
non-trivial clones, we will get trouble with lack of information
@@ -1224,6 +1237,12 @@ inline_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
info->loop_stride = NULL;
set_hint_predicate (&info->loop_stride, p);
}
+ if (info->array_index)
+ {
+ predicate p = *info->array_index;
+ info->array_index = NULL;
+ set_hint_predicate (&info->array_index, p);
+ }
}
inline_update_overall_summary (dst);
}
@@ -1413,6 +1432,11 @@ dump_inline_summary (FILE * f, struct cgraph_node *node)
fprintf (f, " loop stride:");
dump_predicate (f, s->conds, s->loop_stride);
}
+ if (s->array_index)
+ {
+ fprintf (f, " array index:");
+ dump_predicate (f, s->conds, s->array_index);
+ }
fprintf (f, " calls:\n");
dump_inline_edge_summary (f, 4, node, s);
fprintf (f, "\n");
@@ -2262,6 +2286,28 @@ predicate_for_phi_result (struct inline_summary *summary, gimple phi,
SSA_NAME_VERSION (gimple_phi_result (phi)), *p);
}
+/* Return predicate specifying when array index in access OP becomes non-constant. */
+
+static struct predicate
+array_index_predicate (struct inline_summary *info,
+ VEC (predicate_t, heap) *nonconstant_names, tree op)
+{
+ struct predicate p = false_predicate ();
+ while (handled_component_p (op))
+ {
+ if (TREE_CODE (op) == ARRAY_REF
+ || TREE_CODE (op) == ARRAY_RANGE_REF)
+ {
+ if (TREE_CODE (TREE_OPERAND (op, 1)) == SSA_NAME)
+ p = or_predicates (info->conds, &p,
+ &VEC_index (predicate_t, nonconstant_names,
+ SSA_NAME_VERSION (TREE_OPERAND (op, 1))));
+ }
+ op = TREE_OPERAND (op, 0);
+ }
+ return p;
+}
+
/* Compute function body size parameters for NODE.
When EARLY is true, we compute only simple summaries without
non-trivial predicates to drive the early inliner. */
@@ -2284,6 +2330,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
VEC (predicate_t, heap) *nonconstant_names = NULL;
int nblocks, n;
int *order;
+ predicate array_index = true_predicate ();
info->conds = 0;
info->entry = 0;
@@ -2380,6 +2427,24 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
((double)freq)/CGRAPH_FREQ_BASE, this_size, this_time);
}
+ if (gimple_assign_load_p (stmt) && nonconstant_names)
+ {
+ struct predicate this_array_index;
+ this_array_index = array_index_predicate (info, nonconstant_names,
+ gimple_assign_rhs1 (stmt));
+ if (!false_predicate_p (&this_array_index))
+ array_index = and_predicates (info->conds, &array_index, &this_array_index);
+ }
+ if (gimple_store_p (stmt) && nonconstant_names)
+ {
+ struct predicate this_array_index;
+ this_array_index = array_index_predicate (info, nonconstant_names,
+ gimple_get_lhs (stmt));
+ if (!false_predicate_p (&this_array_index))
+ array_index = and_predicates (info->conds, &array_index, &this_array_index);
+ }
+
+
if (is_gimple_call (stmt))
{
struct cgraph_edge *edge = cgraph_edge (node, stmt);
@@ -2476,21 +2541,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
}
}
}
- FOR_ALL_BB_FN (bb, my_function)
- {
- edge e;
- edge_iterator ei;
-
- if (bb->aux)
- pool_free (edge_predicate_pool, bb->aux);
- bb->aux = NULL;
- FOR_EACH_EDGE (e, ei, bb->succs)
- {
- if (e->aux)
- pool_free (edge_predicate_pool, e->aux);
- e->aux = NULL;
- }
- }
+ set_hint_predicate (&inline_summary (node)->array_index, array_index);
time = (time + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
if (time > MAX_TIME)
time = MAX_TIME;
@@ -2513,6 +2564,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
unsigned int j, i;
struct tree_niter_desc niter_desc;
basic_block *body = get_loop_body (loop);
+ bb_predicate = *(struct predicate *)loop->header->aux;
exits = get_loop_exit_edges (loop);
FOR_EACH_VEC_ELT (edge, exits, j, ex)
@@ -2522,6 +2574,10 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
predicate will_be_nonconstant
= will_be_nonconstant_expr_predicate (parms_info, info,
niter_desc.niter, nonconstant_names);
+ if (!true_predicate_p (&will_be_nonconstant))
+ will_be_nonconstant = and_predicates (info->conds,
+ &bb_predicate,
+ &will_be_nonconstant);
if (!true_predicate_p (&will_be_nonconstant)
&& !false_predicate_p (&will_be_nonconstant))
/* This is slightly inprecise. We may want to represent each loop with
@@ -2533,6 +2589,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
for (i = 0; i < loop->num_nodes; i++)
{
gimple_stmt_iterator gsi;
+ bb_predicate = *(struct predicate *)body[i]->aux;
for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
@@ -2550,6 +2607,10 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
will_be_nonconstant
= will_be_nonconstant_expr_predicate (parms_info, info,
iv.step, nonconstant_names);
+ if (!true_predicate_p (&will_be_nonconstant))
+ will_be_nonconstant = and_predicates (info->conds,
+ &bb_predicate,
+ &will_be_nonconstant);
if (!true_predicate_p (&will_be_nonconstant)
&& !false_predicate_p (&will_be_nonconstant))
/* This is slightly inprecise. We may want to represent each loop with
@@ -2564,6 +2625,21 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
set_hint_predicate (&inline_summary (node)->loop_stride, loop_stride);
scev_finalize ();
}
+ FOR_ALL_BB_FN (bb, my_function)
+ {
+ edge e;
+ edge_iterator ei;
+
+ if (bb->aux)
+ pool_free (edge_predicate_pool, bb->aux);
+ bb->aux = NULL;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ if (e->aux)
+ pool_free (edge_predicate_pool, e->aux);
+ e->aux = NULL;
+ }
+ }
inline_summary (node)->self_time = time;
inline_summary (node)->self_size = size;
VEC_free (predicate_t, heap, nonconstant_names);
@@ -2881,6 +2957,9 @@ estimate_node_size_and_time (struct cgraph_node *node,
if (info->loop_stride
&& !evaluate_predicate (info->loop_stride, possible_truths))
hints |=INLINE_HINT_loop_stride;
+ if (info->array_index
+ && !evaluate_predicate (info->array_index, possible_truths))
+ hints |=INLINE_HINT_array_index;
if (info->scc_no)
hints |= INLINE_HINT_in_scc;
if (DECL_DECLARED_INLINE_P (node->symbol.decl))
@@ -3311,6 +3390,10 @@ inline_merge_summary (struct cgraph_edge *edge)
&callee_info->loop_stride,
operand_map, offset_map,
clause, &toplev_predicate);
+ remap_hint_predicate (info, callee_info,
+ &callee_info->array_index,
+ operand_map, offset_map,
+ clause, &toplev_predicate);
inline_update_callee_summaries (edge->callee,
inline_edge_summary (edge)->loop_depth);
@@ -3803,6 +3886,8 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
set_hint_predicate (&info->loop_iterations, p);
p = read_predicate (&ib);
set_hint_predicate (&info->loop_stride, p);
+ p = read_predicate (&ib);
+ set_hint_predicate (&info->array_index, p);
for (e = node->callees; e; e = e->next_callee)
read_inline_edge_summary (&ib, e);
for (e = node->indirect_calls; e; e = e->next_callee)
@@ -3954,6 +4039,7 @@ inline_write_summary (void)
}
write_predicate (ob, info->loop_iterations);
write_predicate (ob, info->loop_stride);
+ write_predicate (ob, info->array_index);
for (edge = node->callees; edge; edge = edge->next_callee)
write_inline_edge_summary (ob, edge);
for (edge = node->indirect_calls; edge; edge = edge->next_callee)