Limit AA walking when inlining analysis examines parameters

2015-07-15  Paolo Bonzini  <bonzini@gnu.org>
	    Martin Jambor  <mjambor@suse.cz>

	* ipa-inline-analysis.c (unmodified_parm_or_parm_agg_item): Accept
	struct func_body_info* instead of struct ipa_node_params*, expecting
	fbi->info to be filled in.  Replace throughout.  Adjust call to
	ipa_load_from_parm_agg.
	(set_cond_stmt_execution_predicate): Accept struct func_body_info*
	instead of struct ipa_node_params*.  Adjust calls to other functions
	so that they pass either fbi or fbi->info.
	(set_switch_stmt_execution_predicate): Likewise.
	(will_be_nonconstant_predicate): Likewise.
	(compute_bb_predicates): Likewise.
	(estimate_function_body_sizes): Move asserts earlier.  Fill in
	struct func_body_info, replace parms_info with fbi.info.  Adjust
	calls to functions that now accept struct func_body_info.
	* ipa-prop.c (param_aa_status, struct ipa_bb_info): Move to ipa-prop.h.
	(struct func_body_info): Likewise.
	(ipa_load_from_parm_agg_1): Rename to ipa_load_from_parm_agg,
	remove static.  Adjust callers.
	(ipa_load_from_parm_agg): Remove.
	* ipa-prop.h (param_aa_status, ipa_bb_info): Move from ipa-prop.c.
	(func_body_info): Likewise.
	(ipa_load_from_parm_agg): Adjust prototype.


Co-Authored-By: Martin Jambor <mjambor@suse.cz>

From-SVN: r225838
This commit is contained in:
Paolo Bonzini 2015-07-15 15:58:43 +00:00 committed by Martin Jambor
parent 7392b0906f
commit ff302741f1
4 changed files with 129 additions and 109 deletions

View File

@ -1,3 +1,28 @@
2015-07-15 Paolo Bonzini <bonzini@gnu.org>
Martin Jambor <mjambor@suse.cz>
* ipa-inline-analysis.c (unmodified_parm_or_parm_agg_item): Accept
struct func_body_info* instead of struct ipa_node_params*, expecting
fbi->info to be filled in. Replace throughout. Adjust call to
ipa_load_from_parm_agg.
(set_cond_stmt_execution_predicate): Accept struct func_body_info*
instead of struct ipa_node_params*. Adjust calls to other functions
so that they pass either fbi or fbi->info.
(set_switch_stmt_execution_predicate): Likewise.
(will_be_nonconstant_predicate): Likewise.
(compute_bb_predicates): Likewise.
(estimate_function_body_sizes): Move asserts earlier. Fill in
struct func_body_info, replace parms_info with fbi.info. Adjust
calls to functions that now accept struct func_body_info.
* ipa-prop.c (param_aa_status, struct ipa_bb_info): Move to ipa-prop.h.
(struct func_body_info): Likewise.
(ipa_load_from_parm_agg_1): Rename to ipa_load_from_parm_agg,
remove static. Adjust callers.
(ipa_load_from_parm_agg): Remove.
* ipa-prop.h (param_aa_status, ipa_bb_info): Move from ipa-prop.c.
(func_body_info): Likewise.
(ipa_load_from_parm_agg): Adjust prototype.
2015-07-12 Trevor Saunders <tbsaunde+gcc@tbsaunde.org>
* gensupport.c (rtx_handle_directive): Adjust.

View File

@ -1574,7 +1574,7 @@ unmodified_parm (gimple stmt, tree op)
loaded. */
static bool
unmodified_parm_or_parm_agg_item (struct ipa_node_params *info,
unmodified_parm_or_parm_agg_item (struct func_body_info *fbi,
gimple stmt, tree op, int *index_p,
struct agg_position_info *aggpos)
{
@ -1583,7 +1583,7 @@ unmodified_parm_or_parm_agg_item (struct ipa_node_params *info,
gcc_checking_assert (aggpos);
if (res)
{
*index_p = ipa_get_param_decl_index (info, res);
*index_p = ipa_get_param_decl_index (fbi->info, res);
if (*index_p < 0)
return false;
aggpos->agg_contents = false;
@ -1599,13 +1599,14 @@ unmodified_parm_or_parm_agg_item (struct ipa_node_params *info,
stmt = SSA_NAME_DEF_STMT (op);
op = gimple_assign_rhs1 (stmt);
if (!REFERENCE_CLASS_P (op))
return unmodified_parm_or_parm_agg_item (info, stmt, op, index_p,
return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p,
aggpos);
}
aggpos->agg_contents = true;
return ipa_load_from_parm_agg (info, stmt, op, index_p, &aggpos->offset,
&aggpos->by_ref);
return ipa_load_from_parm_agg (fbi, fbi->info->descriptors,
stmt, op, index_p, &aggpos->offset,
NULL, &aggpos->by_ref);
}
/* See if statement might disappear after inlining.
@ -1744,7 +1745,7 @@ eliminated_by_inlining_prob (gimple stmt)
predicates to the CFG edges. */
static void
set_cond_stmt_execution_predicate (struct ipa_node_params *info,
set_cond_stmt_execution_predicate (struct func_body_info *fbi,
struct inline_summary *summary,
basic_block bb)
{
@ -1767,7 +1768,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
/* TODO: handle conditionals like
var = op0 < 4;
if (var != 0). */
if (unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos))
if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos))
{
code = gimple_cond_code (last);
inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
@ -1810,8 +1811,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
|| gimple_call_num_args (set_stmt) != 1)
return;
op2 = gimple_call_arg (set_stmt, 0);
if (!unmodified_parm_or_parm_agg_item
(info, set_stmt, op2, &index, &aggpos))
if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &aggpos))
return;
FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
{
@ -1827,7 +1827,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
predicates to the CFG edges. */
static void
set_switch_stmt_execution_predicate (struct ipa_node_params *info,
set_switch_stmt_execution_predicate (struct func_body_info *fbi,
struct inline_summary *summary,
basic_block bb)
{
@ -1845,7 +1845,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
return;
gswitch *last = as_a <gswitch *> (lastg);
op = gimple_switch_index (last);
if (!unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos))
if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos))
return;
FOR_EACH_EDGE (e, ei, bb->succs)
@ -1888,8 +1888,8 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
which it is executable. */
static void
compute_bb_predicates (struct cgraph_node *node,
struct ipa_node_params *parms_info,
compute_bb_predicates (struct func_body_info *fbi,
struct cgraph_node *node,
struct inline_summary *summary)
{
struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
@ -1898,8 +1898,8 @@ compute_bb_predicates (struct cgraph_node *node,
FOR_EACH_BB_FN (bb, my_function)
{
set_cond_stmt_execution_predicate (parms_info, summary, bb);
set_switch_stmt_execution_predicate (parms_info, summary, bb);
set_cond_stmt_execution_predicate (fbi, summary, bb);
set_switch_stmt_execution_predicate (fbi, summary, bb);
}
/* Entry block is always executable. */
@ -2031,7 +2031,7 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
a compile time constant. */
static struct predicate
will_be_nonconstant_predicate (struct ipa_node_params *info,
will_be_nonconstant_predicate (struct func_body_info *fbi,
struct inline_summary *summary,
gimple stmt,
vec<predicate_t> nonconstant_names)
@ -2065,7 +2065,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
tree op;
gcc_assert (gimple_assign_single_p (stmt));
op = gimple_assign_rhs1 (stmt);
if (!unmodified_parm_or_parm_agg_item (info, stmt, op, &base_index,
if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index,
&aggpos))
return p;
}
@ -2078,7 +2078,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
{
tree parm = unmodified_parm (stmt, use);
/* For arguments we can build a condition. */
if (parm && ipa_get_param_decl_index (info, parm) >= 0)
if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0)
continue;
if (TREE_CODE (use) != SSA_NAME)
return p;
@ -2099,7 +2099,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
tree parm = unmodified_parm (stmt, use);
int index;
if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0)
if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
{
if (index != base_index)
p = add_condition (summary, index, NULL, CHANGED, NULL_TREE);
@ -2481,13 +2481,17 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
int freq;
struct inline_summary *info = inline_summaries->get (node);
struct predicate bb_predicate;
struct ipa_node_params *parms_info = NULL;
struct func_body_info fbi;
vec<predicate_t> nonconstant_names = vNULL;
int nblocks, n;
int *order;
predicate array_index = true_predicate ();
gimple fix_builtin_expect_stmt;
gcc_assert (my_function && my_function->cfg);
gcc_assert (cfun == my_function);
memset(&fbi, 0, sizeof(fbi));
info->conds = NULL;
info->entry = NULL;
@ -2510,7 +2514,11 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
if (ipa_node_params_sum)
{
parms_info = IPA_NODE_REF (node);
fbi.node = node;
fbi.info = IPA_NODE_REF (node);
fbi.bb_infos = vNULL;
fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
fbi.param_count = count_formal_params(node->decl);
nonconstant_names.safe_grow_cleared
(SSANAMES (my_function)->length ());
}
@ -2528,10 +2536,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
bb_predicate = not_inlined_predicate ();
account_size_time (info, 2 * INLINE_SIZE_SCALE, 0, &bb_predicate);
gcc_assert (my_function && my_function->cfg);
if (parms_info)
compute_bb_predicates (node, parms_info, info);
gcc_assert (cfun == my_function);
if (fbi.info)
compute_bb_predicates (&fbi, node, info);
order = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
nblocks = pre_and_rev_post_order_compute (NULL, order, false);
for (n = 0; n < nblocks; n++)
@ -2548,7 +2554,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
}
/* TODO: Obviously predicates can be propagated down across CFG. */
if (parms_info)
if (fbi.info)
{
if (bb->aux)
bb_predicate = *(struct predicate *) bb->aux;
@ -2564,7 +2570,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
dump_predicate (dump_file, info->conds, &bb_predicate);
}
if (parms_info && nonconstant_names.exists ())
if (fbi.info && nonconstant_names.exists ())
{
struct predicate phi_predicate;
bool first_phi = true;
@ -2573,7 +2579,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
gsi_next (&bsi))
{
if (first_phi
&& !phi_result_unknown_predicate (parms_info, info, bb,
&& !phi_result_unknown_predicate (fbi.info, info, bb,
&phi_predicate,
nonconstant_names))
break;
@ -2682,9 +2688,9 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
/* TODO: When conditional jump or swithc is known to be constant, but
we did not translate it into the predicates, we really can account
just maximum of the possible paths. */
if (parms_info)
if (fbi.info)
will_be_nonconstant
= will_be_nonconstant_predicate (parms_info, info,
= will_be_nonconstant_predicate (&fbi, info,
stmt, nonconstant_names);
if (this_time || this_size)
{
@ -2699,7 +2705,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\t\tWill be eliminated by inlining\n");
if (parms_info)
if (fbi.info)
p = and_predicates (info->conds, &bb_predicate,
&will_be_nonconstant);
else
@ -2767,7 +2773,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
&& !is_gimple_min_invariant (niter_desc.niter))
{
predicate will_be_nonconstant
= will_be_nonconstant_expr_predicate (parms_info, info,
= will_be_nonconstant_expr_predicate (fbi.info, info,
niter_desc.niter,
nonconstant_names);
if (!true_predicate_p (&will_be_nonconstant))
@ -2805,7 +2811,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
|| is_gimple_min_invariant (iv.step))
continue;
will_be_nonconstant
= will_be_nonconstant_expr_predicate (parms_info, info,
= will_be_nonconstant_expr_predicate (fbi.info, info,
iv.step,
nonconstant_names);
if (!true_predicate_p (&will_be_nonconstant))

View File

@ -70,57 +70,6 @@ along with GCC; see the file COPYING3. If not see
#include "domwalk.h"
#include "builtins.h"
/* Intermediate information that we get from alias analysis about a particular
parameter in a particular basic_block. When a parameter or the memory it
references is marked modified, we use that information in all dominatd
blocks without cosulting alias analysis oracle. */
struct param_aa_status
{
/* Set when this structure contains meaningful information. If not, the
structure describing a dominating BB should be used instead. */
bool valid;
/* Whether we have seen something which might have modified the data in
question. PARM is for the parameter itself, REF is for data it points to
but using the alias type of individual accesses and PT is the same thing
but for computing aggregate pass-through functions using a very inclusive
ao_ref. */
bool parm_modified, ref_modified, pt_modified;
};
/* Information related to a given BB that used only when looking at function
body. */
struct ipa_bb_info
{
/* Call graph edges going out of this BB. */
vec<cgraph_edge *> cg_edges;
/* Alias analysis statuses of each formal parameter at this bb. */
vec<param_aa_status> param_aa_statuses;
};
/* Structure with global information that is only used when looking at function
body. */
struct func_body_info
{
/* The node that is being analyzed. */
cgraph_node *node;
/* Its info. */
struct ipa_node_params *info;
/* Information about individual BBs. */
vec<ipa_bb_info> bb_infos;
/* Number of parameters. */
int param_count;
/* Number of statements already walked by when analyzing this function. */
unsigned int aa_walked;
};
/* Function summary where the parameter infos are actually stored. */
ipa_node_params_t *ipa_node_params_sum = NULL;
/* Vector of IPA-CP transformation data for each clone. */
@ -1010,12 +959,12 @@ parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
within the aggregate and whether it is a load from a value passed by
reference respectively. */
static bool
ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
vec<ipa_param_descriptor> descriptors,
gimple stmt, tree op, int *index_p,
HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
bool *by_ref_p)
bool
ipa_load_from_parm_agg (struct func_body_info *fbi,
vec<ipa_param_descriptor> descriptors,
gimple stmt, tree op, int *index_p,
HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
bool *by_ref_p)
{
int index;
HOST_WIDE_INT size, max_size;
@ -1082,18 +1031,6 @@ ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
return false;
}
/* Just like the previous function, just without the param_analysis_info
pointer, for users outside of this file. */
bool
ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
tree op, int *index_p, HOST_WIDE_INT *offset_p,
bool *by_ref_p)
{
return ipa_load_from_parm_agg_1 (NULL, info->descriptors, stmt, op, index_p,
offset_p, NULL, by_ref_p);
}
/* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
of an assignment statement STMT, try to determine whether we are actually
handling any of the following cases and construct an appropriate jump
@ -1977,9 +1914,9 @@ ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gcall *call,
int index;
gimple def = SSA_NAME_DEF_STMT (target);
if (gimple_assign_single_p (def)
&& ipa_load_from_parm_agg_1 (fbi, info->descriptors, def,
gimple_assign_rhs1 (def), &index, &offset,
NULL, &by_ref))
&& ipa_load_from_parm_agg (fbi, info->descriptors, def,
gimple_assign_rhs1 (def), &index, &offset,
NULL, &by_ref))
{
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
cs->indirect_info->offset = offset;
@ -5192,8 +5129,8 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
if (vce)
continue;
if (!ipa_load_from_parm_agg_1 (m_fbi, m_descriptors, stmt, rhs, &index,
&offset, &size, &by_ref))
if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
&offset, &size, &by_ref))
continue;
for (v = m_aggval; v; v = v->next)
if (v->index == index

View File

@ -336,6 +336,57 @@ struct ipa_node_params
unsigned node_calling_single_call : 1;
};
/* Intermediate information that we get from alias analysis about a particular
parameter in a particular basic_block. When a parameter or the memory it
references is marked modified, we use that information in all dominatd
blocks without cosulting alias analysis oracle. */
struct param_aa_status
{
/* Set when this structure contains meaningful information. If not, the
structure describing a dominating BB should be used instead. */
bool valid;
/* Whether we have seen something which might have modified the data in
question. PARM is for the parameter itself, REF is for data it points to
but using the alias type of individual accesses and PT is the same thing
but for computing aggregate pass-through functions using a very inclusive
ao_ref. */
bool parm_modified, ref_modified, pt_modified;
};
/* Information related to a given BB that used only when looking at function
body. */
struct ipa_bb_info
{
/* Call graph edges going out of this BB. */
vec<cgraph_edge *> cg_edges;
/* Alias analysis statuses of each formal parameter at this bb. */
vec<param_aa_status> param_aa_statuses;
};
/* Structure with global information that is only used when looking at function
body. */
struct func_body_info
{
/* The node that is being analyzed. */
cgraph_node *node;
/* Its info. */
struct ipa_node_params *info;
/* Information about individual BBs. */
vec<ipa_bb_info> bb_infos;
/* Number of parameters. */
int param_count;
/* Number of statements already walked by when analyzing this function. */
unsigned int aa_walked;
};
/* ipa_node_params access functions. Please use these to access fields that
are or will be shared among various passes. */
@ -585,8 +636,9 @@ void ipa_analyze_node (struct cgraph_node *);
/* Aggregate jump function related functions. */
tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
bool);
bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
HOST_WIDE_INT *, bool *);
bool ipa_load_from_parm_agg (struct func_body_info *,
vec<ipa_param_descriptor>, gimple, tree, int *,
HOST_WIDE_INT *, HOST_WIDE_INT *, bool *);
/* Debugging interface. */
void ipa_print_node_params (FILE *, struct cgraph_node *node);