Commit 40a777e8 by Jan Hubicka Committed by Jan Hubicka

Improve effectivity of ipa_polymorphi_context cache.

        * ipa-fnsummary.c (set_cond_stmt_execution_predicate,
	set_switch_stmt_execution_predicate, compute_bb_predicates,
	will_be_nonconstant_expr_predicate,
	phi_result_unknown_predicate,
	analyze_function_body): Pass arround params summary.
	(ipa_call_context::duplicate_from): New comment;
	only duplicate useful values.
	(ipa_call_context::equal_to): Only compare useful values.
	(remap_edge_summaries): Pass params_summary.
	(remap_hint_predicate): Likewise.
	(ipa_merge_fn_summary_after_inlining): Likewise.
	(inline_read_section): Initialize params summary used flags.
	* ipa-predicate.c (predicate::remap_after_inlining): Pass
	around param_summary.
	(add_condition): Initialized used params summary flags.
	* ipa-predicate.h (inline_param_summary::equals_to): Make const.
	(inline_param_summary::useless_p): New predicate.
	(remap_after_inlining, add_condition): Update prototype
	* ipa-prop.c (ipa_populate_param_decls): Watch overflow in
	move_cost.
	(ipa_note_param_call): Add parameter POLYMORPHIC; update params
	summaries.
	(ipa_analyze_indirect_call_uses): Update use of ipa_note_param_call.
	(ipa_analyze_virtual_call_uses): Likewise.
	(update_indirect_edges_after_inlining): Update param summaries.
	(ipa_print_node_params): Print used flags.
	(ipa_read_indirect_edge_info): Update param summareis.
	* ipa-prop.h (ipa_param_descriptor): Add
	used_by_ipa_predicates, used_by_indirect_call
	and used_by_polymorphic_call.
	(ipa_set_param_used_by_ipa_predicates,
	ipa_set_param_used_by_indirect_call,
	ipa_set_param_used_by_polymorphic_call,
	ipa_is_param_used_by_ipa_predicates,
	ipa_is_param_used_by_indirect_call,
	ipa_is_param_used_by_polymorphic_call): New inline functions.

From-SVN: r277759
parent 4bcd578a
2019-11-02 Jan Hubicka <hubicka@ucw.cz>
* ipa-fnsummary.c (set_cond_stmt_execution_predicate,
set_switch_stmt_execution_predicate, compute_bb_predicates,
will_be_nonconstant_expr_predicate,
phi_result_unknown_predicate,
analyze_function_body): Pass arround params summary.
(ipa_call_context::duplicate_from): New comment;
only duplicate useful values.
(ipa_call_context::equal_to): Only compare useful values.
(remap_edge_summaries): Pass params_summary.
(remap_hint_predicate): Likewise.
(ipa_merge_fn_summary_after_inlining): Likewise.
(inline_read_section): Initialize params summary used flags.
* ipa-predicate.c (predicate::remap_after_inlining): Pass
around param_summary.
(add_condition): Initialized used params summary flags.
* ipa-predicate.h (inline_param_summary::equals_to): Make const.
(inline_param_summary::useless_p): New predicate.
(remap_after_inlining, add_condition): Update prototype
* ipa-prop.c (ipa_populate_param_decls): Watch overflow in
move_cost.
(ipa_note_param_call): Add parameter POLYMORPHIC; update params
summaries.
(ipa_analyze_indirect_call_uses): Update use of ipa_note_param_call.
(ipa_analyze_virtual_call_uses): Likewise.
(update_indirect_edges_after_inlining): Update param summaries.
(ipa_print_node_params): Print used flags.
(ipa_read_indirect_edge_info): Update param summareis.
* ipa-prop.h (ipa_param_descriptor): Add
used_by_ipa_predicates, used_by_indirect_call
and used_by_polymorphic_call.
(ipa_set_param_used_by_ipa_predicates,
ipa_set_param_used_by_indirect_call,
ipa_set_param_used_by_polymorphic_call,
ipa_is_param_used_by_ipa_predicates,
ipa_is_param_used_by_indirect_call,
ipa_is_param_used_by_polymorphic_call): New inline functions.
2019-11-02 Jan Hubicka <hubicka@ucw.cz>
* ipa-fnsummary.c (ipa_call_context::duplicate_from): New
member function.
(ipa_call_context::release): Add ALL parameter.
......@@ -505,6 +505,7 @@ predicate::remap_after_duplication (clause_t possible_truths)
predicate
predicate::remap_after_inlining (class ipa_fn_summary *info,
class ipa_node_params *params_summary,
class ipa_fn_summary *callee_info,
vec<int> operand_map,
vec<int> offset_map,
......@@ -566,7 +567,7 @@ predicate::remap_after_inlining (class ipa_fn_summary *info,
ap.offset = c->offset + offset_delta;
ap.agg_contents = c->agg_contents;
ap.by_ref = c->by_ref;
cond_predicate = add_condition (info,
cond_predicate = add_condition (info, params_summary,
operand_map[c->operand_num],
c->type, &ap, c->code,
c->val, c->param_ops);
......@@ -629,7 +630,9 @@ predicate::stream_out (struct output_block *ob)
aggregate. */
predicate
add_condition (class ipa_fn_summary *summary, int operand_num,
add_condition (class ipa_fn_summary *summary,
class ipa_node_params *params_summary,
int operand_num,
tree type, struct agg_position_info *aggpos,
enum tree_code code, tree val, expr_eval_ops param_ops)
{
......@@ -640,6 +643,9 @@ add_condition (class ipa_fn_summary *summary, int operand_num,
bool agg_contents, by_ref;
expr_eval_op *op;
if (params_summary)
ipa_set_param_used_by_ipa_predicates (params_summary, operand_num, true);
if (aggpos)
{
offset = aggpos->offset;
......
......@@ -77,10 +77,14 @@ struct inline_param_summary
Value 0 is reserved for compile time invariants. */
int change_prob;
bool equal_to (const inline_param_summary &other)
bool equal_to (const inline_param_summary &other) const
{
return change_prob == other.change_prob;
}
bool useless_p (void) const
{
return change_prob == REG_BR_PROB_BASE;
}
};
typedef vec<condition, va_gc> *conditions;
......@@ -233,6 +237,7 @@ public:
/* Return predicate equal to THIS after inlining. */
predicate remap_after_inlining (class ipa_fn_summary *,
class ipa_node_params *params_summary,
class ipa_fn_summary *,
vec<int>, vec<int>, clause_t, const predicate &);
......@@ -254,7 +259,9 @@ private:
};
void dump_condition (FILE *f, conditions conditions, int cond);
predicate add_condition (class ipa_fn_summary *summary, int operand_num,
predicate add_condition (class ipa_fn_summary *summary,
class ipa_node_params *params_summary,
int operand_num,
tree type, struct agg_position_info *aggpos,
enum tree_code code, tree val,
expr_eval_ops param_ops = NULL);
......@@ -227,8 +227,10 @@ ipa_populate_param_decls (struct cgraph_node *node,
for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
{
descriptors[param_num].decl_or_type = parm;
descriptors[param_num].move_cost = estimate_move_cost (TREE_TYPE (parm),
true);
unsigned int cost = estimate_move_cost (TREE_TYPE (parm), true);
descriptors[param_num].move_cost = cost;
/* Watch overflow, move_cost is a bitfield. */
gcc_checking_assert (cost == descriptors[param_num].move_cost);
param_num++;
}
}
......@@ -2116,11 +2118,12 @@ ipa_is_ssa_with_stmt_def (tree t)
/* Find the indirect call graph edge corresponding to STMT and mark it as a
call to a parameter number PARAM_INDEX. NODE is the caller. Return the
indirect call graph edge. */
indirect call graph edge.
If POLYMORPHIC is true record is as a destination of polymorphic call. */
static struct cgraph_edge *
ipa_note_param_call (struct cgraph_node *node, int param_index,
gcall *stmt)
gcall *stmt, bool polymorphic)
{
struct cgraph_edge *cs;
......@@ -2129,6 +2132,11 @@ ipa_note_param_call (struct cgraph_node *node, int param_index,
cs->indirect_info->agg_contents = 0;
cs->indirect_info->member_ptr = 0;
cs->indirect_info->guaranteed_unmodified = 0;
ipa_set_param_used_by_indirect_call (IPA_NODE_REF (node),
param_index, true);
if (cs->indirect_info->polymorphic || polymorphic)
ipa_set_param_used_by_polymorphic_call
(IPA_NODE_REF (node), param_index, true);
return cs;
}
......@@ -2204,7 +2212,7 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
tree var = SSA_NAME_VAR (target);
int index = ipa_get_param_decl_index (info, var);
if (index >= 0)
ipa_note_param_call (fbi->node, index, call);
ipa_note_param_call (fbi->node, index, call, false);
return;
}
......@@ -2216,7 +2224,8 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
gimple_assign_rhs1 (def), &index, &offset,
NULL, &by_ref, &guaranteed_unmodified))
{
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
call, false);
cs->indirect_info->offset = offset;
cs->indirect_info->agg_contents = 1;
cs->indirect_info->by_ref = by_ref;
......@@ -2317,7 +2326,8 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
if (index >= 0
&& parm_preserved_before_stmt_p (fbi, index, call, rec))
{
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
call, false);
cs->indirect_info->offset = offset;
cs->indirect_info->agg_contents = 1;
cs->indirect_info->member_ptr = 1;
......@@ -2377,7 +2387,8 @@ ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
return;
}
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index,
call, true);
class cgraph_indirect_call_info *ii = cs->indirect_info;
ii->offset = anc_offset;
ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
......@@ -3510,6 +3521,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
if (ici->polymorphic
&& !ipa_get_jf_pass_through_type_preserved (jfunc))
ici->vptr_changed = true;
ipa_set_param_used_by_indirect_call (new_root_info,
ici->param_index, true);
if (ici->polymorphic)
ipa_set_param_used_by_polymorphic_call (new_root_info,
ici->param_index, true);
}
}
else if (jfunc->type == IPA_JF_ANCESTOR)
......@@ -4055,6 +4071,12 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
ipa_dump_param (f, info, i);
if (ipa_is_param_used (info, i))
fprintf (f, " used");
if (ipa_is_param_used_by_ipa_predicates (info, i))
fprintf (f, " used_by_ipa_predicates");
if (ipa_is_param_used_by_indirect_call (info, i))
fprintf (f, " used_by_indirect_call");
if (ipa_is_param_used_by_polymorphic_call (info, i))
fprintf (f, " used_by_polymorphic_call");
c = ipa_get_controlled_uses (info, i);
if (c == IPA_UNDESCRIBED_USE)
fprintf (f, " undescribed_use");
......@@ -4331,7 +4353,8 @@ ipa_write_indirect_edge_info (struct output_block *ob,
static void
ipa_read_indirect_edge_info (class lto_input_block *ib,
class data_in *data_in,
struct cgraph_edge *cs)
struct cgraph_edge *cs,
class ipa_node_params *info)
{
class cgraph_indirect_call_info *ii = cs->indirect_info;
struct bitpack_d bp;
......@@ -4354,6 +4377,14 @@ ipa_read_indirect_edge_info (class lto_input_block *ib,
ii->otr_type = stream_read_tree (ib, data_in);
ii->context.stream_in (ib, data_in);
}
if (info && ii->param_index >= 0)
{
if (ii->polymorphic)
ipa_set_param_used_by_polymorphic_call (info,
ii->param_index , true);
ipa_set_param_used_by_indirect_call (info,
ii->param_index, true);
}
}
/* Stream out NODE info to OB. */
......@@ -4523,7 +4554,7 @@ ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
for (e = node->indirect_calls; e; e = e->next_callee)
{
ipa_read_edge_info (ib, data_in, e, prevails);
ipa_read_indirect_edge_info (ib, data_in, e);
ipa_read_indirect_edge_info (ib, data_in, e, info);
}
}
......
......@@ -333,9 +333,12 @@ struct GTY(()) ipa_param_descriptor
says how many there are. If any use could not be described by means of
ipa-prop structures, this is IPA_UNDESCRIBED_USE. */
int controlled_uses;
unsigned int move_cost : 31;
unsigned int move_cost : 28;
/* The parameter is used. */
unsigned used : 1;
unsigned used_by_ipa_predicates : 1;
unsigned used_by_indirect_call : 1;
unsigned used_by_polymorphic_call : 1;
};
/* ipa_node_params stores information related to formal parameters of functions
......@@ -519,6 +522,36 @@ ipa_set_param_used (class ipa_node_params *info, int i, bool val)
(*info->descriptors)[i].used = val;
}
/* Set the used_by_ipa_predicates flag corresponding to the Ith formal
parameter of the function associated with INFO to VAL. */
static inline void
ipa_set_param_used_by_ipa_predicates (class ipa_node_params *info, int i, bool val)
{
gcc_checking_assert (info->descriptors);
(*info->descriptors)[i].used_by_ipa_predicates = val;
}
/* Set the used_by_indirect_call flag corresponding to the Ith formal
parameter of the function associated with INFO to VAL. */
static inline void
ipa_set_param_used_by_indirect_call (class ipa_node_params *info, int i, bool val)
{
gcc_checking_assert (info->descriptors);
(*info->descriptors)[i].used_by_indirect_call = val;
}
/* Set the .used_by_polymorphic_call flag corresponding to the Ith formal
parameter of the function associated with INFO to VAL. */
static inline void
ipa_set_param_used_by_polymorphic_call (class ipa_node_params *info, int i, bool val)
{
gcc_checking_assert (info->descriptors);
(*info->descriptors)[i].used_by_polymorphic_call = val;
}
/* Return how many uses described by ipa-prop a parameter has or
IPA_UNDESCRIBED_USE if there is a use that is not described by these
structures. */
......@@ -550,6 +583,36 @@ ipa_is_param_used (class ipa_node_params *info, int i)
return (*info->descriptors)[i].used;
}
/* Return the used_by_ipa_predicates flag corresponding to the Ith formal
parameter of the function associated with INFO. */
static inline bool
ipa_is_param_used_by_ipa_predicates (class ipa_node_params *info, int i)
{
gcc_checking_assert (info->descriptors);
return (*info->descriptors)[i].used_by_ipa_predicates;
}
/* Return the used_by_indirect_call flag corresponding to the Ith formal
parameter of the function associated with INFO. */
static inline bool
ipa_is_param_used_by_indirect_call (class ipa_node_params *info, int i)
{
gcc_checking_assert (info->descriptors);
return (*info->descriptors)[i].used_by_indirect_call;
}
/* Return the used_by_polymorphic_call flag corresponding to the Ith formal
parameter of the function associated with INFO. */
static inline bool
ipa_is_param_used_by_polymorphic_call (class ipa_node_params *info, int i)
{
gcc_checking_assert (info->descriptors);
return (*info->descriptors)[i].used_by_polymorphic_call;
}
/* Information about replacements done in aggregates for a given node (each
node has its linked list). */
struct GTY(()) ipa_agg_replacement_value
......
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