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> 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 * ipa-fnsummary.c (ipa_call_context::duplicate_from): New
member function. member function.
(ipa_call_context::release): Add ALL parameter. (ipa_call_context::release): Add ALL parameter.
...@@ -505,6 +505,7 @@ predicate::remap_after_duplication (clause_t possible_truths) ...@@ -505,6 +505,7 @@ predicate::remap_after_duplication (clause_t possible_truths)
predicate predicate
predicate::remap_after_inlining (class ipa_fn_summary *info, predicate::remap_after_inlining (class ipa_fn_summary *info,
class ipa_node_params *params_summary,
class ipa_fn_summary *callee_info, class ipa_fn_summary *callee_info,
vec<int> operand_map, vec<int> operand_map,
vec<int> offset_map, vec<int> offset_map,
...@@ -566,7 +567,7 @@ predicate::remap_after_inlining (class ipa_fn_summary *info, ...@@ -566,7 +567,7 @@ predicate::remap_after_inlining (class ipa_fn_summary *info,
ap.offset = c->offset + offset_delta; ap.offset = c->offset + offset_delta;
ap.agg_contents = c->agg_contents; ap.agg_contents = c->agg_contents;
ap.by_ref = c->by_ref; ap.by_ref = c->by_ref;
cond_predicate = add_condition (info, cond_predicate = add_condition (info, params_summary,
operand_map[c->operand_num], operand_map[c->operand_num],
c->type, &ap, c->code, c->type, &ap, c->code,
c->val, c->param_ops); c->val, c->param_ops);
...@@ -629,7 +630,9 @@ predicate::stream_out (struct output_block *ob) ...@@ -629,7 +630,9 @@ predicate::stream_out (struct output_block *ob)
aggregate. */ aggregate. */
predicate 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, tree type, struct agg_position_info *aggpos,
enum tree_code code, tree val, expr_eval_ops param_ops) 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, ...@@ -640,6 +643,9 @@ add_condition (class ipa_fn_summary *summary, int operand_num,
bool agg_contents, by_ref; bool agg_contents, by_ref;
expr_eval_op *op; expr_eval_op *op;
if (params_summary)
ipa_set_param_used_by_ipa_predicates (params_summary, operand_num, true);
if (aggpos) if (aggpos)
{ {
offset = aggpos->offset; offset = aggpos->offset;
......
...@@ -77,10 +77,14 @@ struct inline_param_summary ...@@ -77,10 +77,14 @@ struct inline_param_summary
Value 0 is reserved for compile time invariants. */ Value 0 is reserved for compile time invariants. */
int change_prob; 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; return change_prob == other.change_prob;
} }
bool useless_p (void) const
{
return change_prob == REG_BR_PROB_BASE;
}
}; };
typedef vec<condition, va_gc> *conditions; typedef vec<condition, va_gc> *conditions;
...@@ -233,6 +237,7 @@ public: ...@@ -233,6 +237,7 @@ public:
/* Return predicate equal to THIS after inlining. */ /* Return predicate equal to THIS after inlining. */
predicate remap_after_inlining (class ipa_fn_summary *, predicate remap_after_inlining (class ipa_fn_summary *,
class ipa_node_params *params_summary,
class ipa_fn_summary *, class ipa_fn_summary *,
vec<int>, vec<int>, clause_t, const predicate &); vec<int>, vec<int>, clause_t, const predicate &);
...@@ -254,7 +259,9 @@ private: ...@@ -254,7 +259,9 @@ private:
}; };
void dump_condition (FILE *f, conditions conditions, int cond); 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, tree type, struct agg_position_info *aggpos,
enum tree_code code, tree val, enum tree_code code, tree val,
expr_eval_ops param_ops = NULL); expr_eval_ops param_ops = NULL);
...@@ -227,8 +227,10 @@ ipa_populate_param_decls (struct cgraph_node *node, ...@@ -227,8 +227,10 @@ ipa_populate_param_decls (struct cgraph_node *node,
for (parm = fnargs; parm; parm = DECL_CHAIN (parm)) for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
{ {
descriptors[param_num].decl_or_type = parm; descriptors[param_num].decl_or_type = parm;
descriptors[param_num].move_cost = estimate_move_cost (TREE_TYPE (parm), unsigned int cost = estimate_move_cost (TREE_TYPE (parm), true);
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++; param_num++;
} }
} }
...@@ -2116,11 +2118,12 @@ ipa_is_ssa_with_stmt_def (tree t) ...@@ -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 /* 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 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 * static struct cgraph_edge *
ipa_note_param_call (struct cgraph_node *node, int param_index, ipa_note_param_call (struct cgraph_node *node, int param_index,
gcall *stmt) gcall *stmt, bool polymorphic)
{ {
struct cgraph_edge *cs; struct cgraph_edge *cs;
...@@ -2129,6 +2132,11 @@ ipa_note_param_call (struct cgraph_node *node, int param_index, ...@@ -2129,6 +2132,11 @@ ipa_note_param_call (struct cgraph_node *node, int param_index,
cs->indirect_info->agg_contents = 0; cs->indirect_info->agg_contents = 0;
cs->indirect_info->member_ptr = 0; cs->indirect_info->member_ptr = 0;
cs->indirect_info->guaranteed_unmodified = 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; return cs;
} }
...@@ -2204,7 +2212,7 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call, ...@@ -2204,7 +2212,7 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
tree var = SSA_NAME_VAR (target); tree var = SSA_NAME_VAR (target);
int index = ipa_get_param_decl_index (info, var); int index = ipa_get_param_decl_index (info, var);
if (index >= 0) if (index >= 0)
ipa_note_param_call (fbi->node, index, call); ipa_note_param_call (fbi->node, index, call, false);
return; return;
} }
...@@ -2216,7 +2224,8 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call, ...@@ -2216,7 +2224,8 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
gimple_assign_rhs1 (def), &index, &offset, gimple_assign_rhs1 (def), &index, &offset,
NULL, &by_ref, &guaranteed_unmodified)) 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->offset = offset;
cs->indirect_info->agg_contents = 1; cs->indirect_info->agg_contents = 1;
cs->indirect_info->by_ref = by_ref; cs->indirect_info->by_ref = by_ref;
...@@ -2317,7 +2326,8 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call, ...@@ -2317,7 +2326,8 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
if (index >= 0 if (index >= 0
&& parm_preserved_before_stmt_p (fbi, index, call, rec)) && 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->offset = offset;
cs->indirect_info->agg_contents = 1; cs->indirect_info->agg_contents = 1;
cs->indirect_info->member_ptr = 1; cs->indirect_info->member_ptr = 1;
...@@ -2377,7 +2387,8 @@ ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi, ...@@ -2377,7 +2387,8 @@ ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
return; 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; class cgraph_indirect_call_info *ii = cs->indirect_info;
ii->offset = anc_offset; ii->offset = anc_offset;
ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target)); ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
...@@ -3510,6 +3521,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, ...@@ -3510,6 +3521,11 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
if (ici->polymorphic if (ici->polymorphic
&& !ipa_get_jf_pass_through_type_preserved (jfunc)) && !ipa_get_jf_pass_through_type_preserved (jfunc))
ici->vptr_changed = true; 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) else if (jfunc->type == IPA_JF_ANCESTOR)
...@@ -4055,6 +4071,12 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node) ...@@ -4055,6 +4071,12 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
ipa_dump_param (f, info, i); ipa_dump_param (f, info, i);
if (ipa_is_param_used (info, i)) if (ipa_is_param_used (info, i))
fprintf (f, " used"); 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); c = ipa_get_controlled_uses (info, i);
if (c == IPA_UNDESCRIBED_USE) if (c == IPA_UNDESCRIBED_USE)
fprintf (f, " undescribed_use"); fprintf (f, " undescribed_use");
...@@ -4331,7 +4353,8 @@ ipa_write_indirect_edge_info (struct output_block *ob, ...@@ -4331,7 +4353,8 @@ ipa_write_indirect_edge_info (struct output_block *ob,
static void static void
ipa_read_indirect_edge_info (class lto_input_block *ib, ipa_read_indirect_edge_info (class lto_input_block *ib,
class data_in *data_in, 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; class cgraph_indirect_call_info *ii = cs->indirect_info;
struct bitpack_d bp; struct bitpack_d bp;
...@@ -4354,6 +4377,14 @@ ipa_read_indirect_edge_info (class lto_input_block *ib, ...@@ -4354,6 +4377,14 @@ ipa_read_indirect_edge_info (class lto_input_block *ib,
ii->otr_type = stream_read_tree (ib, data_in); ii->otr_type = stream_read_tree (ib, data_in);
ii->context.stream_in (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. */ /* Stream out NODE info to OB. */
...@@ -4523,7 +4554,7 @@ ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node, ...@@ -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) for (e = node->indirect_calls; e; e = e->next_callee)
{ {
ipa_read_edge_info (ib, data_in, e, prevails); 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 ...@@ -333,9 +333,12 @@ struct GTY(()) ipa_param_descriptor
says how many there are. If any use could not be described by means of says how many there are. If any use could not be described by means of
ipa-prop structures, this is IPA_UNDESCRIBED_USE. */ ipa-prop structures, this is IPA_UNDESCRIBED_USE. */
int controlled_uses; int controlled_uses;
unsigned int move_cost : 31; unsigned int move_cost : 28;
/* The parameter is used. */ /* The parameter is used. */
unsigned used : 1; 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 /* 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) ...@@ -519,6 +522,36 @@ ipa_set_param_used (class ipa_node_params *info, int i, bool val)
(*info->descriptors)[i].used = 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 /* 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 IPA_UNDESCRIBED_USE if there is a use that is not described by these
structures. */ structures. */
...@@ -550,6 +583,36 @@ ipa_is_param_used (class ipa_node_params *info, int i) ...@@ -550,6 +583,36 @@ ipa_is_param_used (class ipa_node_params *info, int i)
return (*info->descriptors)[i].used; 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 /* Information about replacements done in aggregates for a given node (each
node has its linked list). */ node has its linked list). */
struct GTY(()) ipa_agg_replacement_value 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