Commit 6cf67b62 by Jan Hubicka Committed by Jan Hubicka

cgraph.h (struct cgraph_node): Add ipcp_clone flag.


	* cgraph.h (struct cgraph_node): Add ipcp_clone flag.
	(cgraph_node::create_virtual_clone): Copy it.
	* ipa-cp.c (ipcp_versionable_function_p): Watch for missing
	summaries.
	(ignore_edge_p): If caller has ipa-cp disabled, skip the edge, too.
	(ipcp_verify_propagated_values): Do not verify nodes where ipcp
	is disabled.
	(propagate_constants_across_call): If callee is not analyzed, give up.
	(propagate_constants_topo): Lower to bottom latties of all callees of
	functions with ipa-cp disabled.
	(ipcp_propagate_stage): Skip functions with ipa-cp disabled.
	(cgraph_edge_brings_value_p): Check for availability first.
	(create_specialized_node): Set ipcp_clone.
	(ipcp_store_bits_results): Check that info is present.
	* ipa-fnsummary.c (evaluate_properties_for_edge): Do not analyze
	thunks.
	(ipa_call_context::duplicate_from, ipa_call_context::equal_to): Be
	conservative when callee summary is missing.
	(remap_edge_summaries): Lookup call summary only when needed.
	* ipa-icf.c (sem_function::param_used_p): Be ready for missing summary.
	* ipa-prpo.c (ipa_alloc_node_params, ipa_initialize_node_params):
	Use get_create.
	(ipa_analyze_node): Use get_create.
	(propagate_controlled_uses): Do not propagate when function is not
	analyzed.
	(ipa_propagate_indirect_call_infos): Remove summary of inline clone.
	(ipa_read_node_info): Use get_create.
	* ipa-prop.h (IPA_NODE_REF): Use get.
	(IPA_NODE_REF_GET_CREATE): New.

From-SVN: r278016
parent 64166bf0
2019-11-09 Jan Hubicka <hubicka@ucw.cz> 2019-11-09 Jan Hubicka <hubicka@ucw.cz>
* cgraph.h (struct cgraph_node): Add ipcp_clone flag.
(cgraph_node::create_virtual_clone): Copy it.
* ipa-cp.c (ipcp_versionable_function_p): Watch for missing
summaries.
(ignore_edge_p): If caller has ipa-cp disabled, skip the edge, too.
(ipcp_verify_propagated_values): Do not verify nodes where ipcp
is disabled.
(propagate_constants_across_call): If callee is not analyzed, give up.
(propagate_constants_topo): Lower to bottom latties of all callees of
functions with ipa-cp disabled.
(ipcp_propagate_stage): Skip functions with ipa-cp disabled.
(cgraph_edge_brings_value_p): Check for availability first.
(create_specialized_node): Set ipcp_clone.
(ipcp_store_bits_results): Check that info is present.
* ipa-fnsummary.c (evaluate_properties_for_edge): Do not analyze
thunks.
(ipa_call_context::duplicate_from, ipa_call_context::equal_to): Be
conservative when callee summary is missing.
(remap_edge_summaries): Lookup call summary only when needed.
* ipa-icf.c (sem_function::param_used_p): Be ready for missing summary.
* ipa-prpo.c (ipa_alloc_node_params, ipa_initialize_node_params):
Use get_create.
(ipa_analyze_node): Use get_create.
(propagate_controlled_uses): Do not propagate when function is not
analyzed.
(ipa_propagate_indirect_call_infos): Remove summary of inline clone.
(ipa_read_node_info): Use get_create.
* ipa-prop.h (IPA_NODE_REF): Use get.
(IPA_NODE_REF_GET_CREATE): New.
2019-11-09 Jan Hubicka <hubicka@ucw.cz>
* ipa-fnsummary.c (evaluate_properties_for_edge): Call IPA_NODE_REF * ipa-fnsummary.c (evaluate_properties_for_edge): Call IPA_NODE_REF
on function symbol. on function symbol.
...@@ -1484,6 +1484,8 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node ...@@ -1484,6 +1484,8 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
unsigned redefined_extern_inline : 1; unsigned redefined_extern_inline : 1;
/* True if the function may enter serial irrevocable mode. */ /* True if the function may enter serial irrevocable mode. */
unsigned tm_may_enter_irr : 1; unsigned tm_may_enter_irr : 1;
/* True if this was a clone created by ipa-cp. */
unsigned ipcp_clone : 1;
private: private:
/* Unique id of the node. */ /* Unique id of the node. */
......
...@@ -570,6 +570,7 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers, ...@@ -570,6 +570,7 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
??? We cannot use COMDAT linkage because there is no ??? We cannot use COMDAT linkage because there is no
ABI support for this. */ ABI support for this. */
set_new_clone_decl_and_node_flags (new_node); set_new_clone_decl_and_node_flags (new_node);
new_node->ipcp_clone = ipcp_clone;
new_node->clone.tree_map = tree_map; new_node->clone.tree_map = tree_map;
if (!implicit_section) if (!implicit_section)
new_node->set_section (get_section ()); new_node->set_section (get_section ());
......
...@@ -656,7 +656,7 @@ determine_versionability (struct cgraph_node *node, ...@@ -656,7 +656,7 @@ determine_versionability (struct cgraph_node *node,
static bool static bool
ipcp_versionable_function_p (struct cgraph_node *node) ipcp_versionable_function_p (struct cgraph_node *node)
{ {
return IPA_NODE_REF (node)->versionable; return IPA_NODE_REF (node) && IPA_NODE_REF (node)->versionable;
} }
/* Structure holding accumulated information about callers of a node. */ /* Structure holding accumulated information about callers of a node. */
...@@ -817,6 +817,7 @@ ignore_edge_p (cgraph_edge *e) ...@@ -817,6 +817,7 @@ ignore_edge_p (cgraph_edge *e)
= e->callee->function_or_virtual_thunk_symbol (&avail, e->caller); = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
return (avail <= AVAIL_INTERPOSABLE return (avail <= AVAIL_INTERPOSABLE
|| !opt_for_fn (e->caller->decl, flag_ipa_cp)
|| !opt_for_fn (ultimate_target->decl, flag_ipa_cp)); || !opt_for_fn (ultimate_target->decl, flag_ipa_cp));
} }
...@@ -1471,6 +1472,8 @@ ipcp_verify_propagated_values (void) ...@@ -1471,6 +1472,8 @@ ipcp_verify_propagated_values (void)
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
{ {
class ipa_node_params *info = IPA_NODE_REF (node); class ipa_node_params *info = IPA_NODE_REF (node);
if (!opt_for_fn (node->decl, flag_ipa_cp))
continue;
int i, count = ipa_get_param_count (info); int i, count = ipa_get_param_count (info);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
...@@ -2307,6 +2310,8 @@ propagate_constants_across_call (struct cgraph_edge *cs) ...@@ -2307,6 +2310,8 @@ propagate_constants_across_call (struct cgraph_edge *cs)
return false; return false;
gcc_checking_assert (callee->has_gimple_body_p ()); gcc_checking_assert (callee->has_gimple_body_p ());
callee_info = IPA_NODE_REF (callee); callee_info = IPA_NODE_REF (callee);
if (!callee_info)
return false;
args = IPA_EDGE_REF (cs); args = IPA_EDGE_REF (cs);
parms_count = ipa_get_param_count (callee_info); parms_count = ipa_get_param_count (callee_info);
...@@ -3233,7 +3238,17 @@ propagate_constants_topo (class ipa_topo_info *topo) ...@@ -3233,7 +3238,17 @@ propagate_constants_topo (class ipa_topo_info *topo)
until all lattices stabilize. */ until all lattices stabilize. */
FOR_EACH_VEC_ELT (cycle_nodes, j, v) FOR_EACH_VEC_ELT (cycle_nodes, j, v)
if (v->has_gimple_body_p ()) if (v->has_gimple_body_p ())
{
if (opt_for_fn (v->decl, flag_ipa_cp))
push_node_to_stack (topo, v); push_node_to_stack (topo, v);
/* When V is not optimized, we can not push it to stac, but
still we need to set all its callees lattices to bottom. */
else
{
for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
propagate_constants_across_call (cs);
}
}
v = pop_node_from_stack (topo); v = pop_node_from_stack (topo);
while (v) while (v)
...@@ -3254,7 +3269,8 @@ propagate_constants_topo (class ipa_topo_info *topo) ...@@ -3254,7 +3269,8 @@ propagate_constants_topo (class ipa_topo_info *topo)
the local effects of the discovered constants and all valid values to the local effects of the discovered constants and all valid values to
their topological sort. */ their topological sort. */
FOR_EACH_VEC_ELT (cycle_nodes, j, v) FOR_EACH_VEC_ELT (cycle_nodes, j, v)
if (v->has_gimple_body_p ()) if (v->has_gimple_body_p ()
&& opt_for_fn (v->decl, flag_ipa_cp))
{ {
struct cgraph_edge *cs; struct cgraph_edge *cs;
...@@ -3333,11 +3349,10 @@ ipcp_propagate_stage (class ipa_topo_info *topo) ...@@ -3333,11 +3349,10 @@ ipcp_propagate_stage (class ipa_topo_info *topo)
FOR_EACH_DEFINED_FUNCTION (node) FOR_EACH_DEFINED_FUNCTION (node)
{ {
if (node->has_gimple_body_p () && opt_for_fn (node->decl, flag_ipa_cp))
{
class ipa_node_params *info = IPA_NODE_REF (node); class ipa_node_params *info = IPA_NODE_REF (node);
determine_versionability (node, info); determine_versionability (node, info);
if (node->has_gimple_body_p ())
{
info->lattices = XCNEWVEC (class ipcp_param_lattices, info->lattices = XCNEWVEC (class ipcp_param_lattices,
ipa_get_param_count (info)); ipa_get_param_count (info));
initialize_node_lattices (node); initialize_node_lattices (node);
...@@ -3526,8 +3541,8 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src, ...@@ -3526,8 +3541,8 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
enum availability availability; enum availability availability;
cgraph_node *real_dest = cs->callee->function_symbol (&availability); cgraph_node *real_dest = cs->callee->function_symbol (&availability);
if (!same_node_or_its_all_contexts_clone_p (real_dest, dest) if (availability <= AVAIL_INTERPOSABLE
|| availability <= AVAIL_INTERPOSABLE || !same_node_or_its_all_contexts_clone_p (real_dest, dest)
|| caller_info->node_dead) || caller_info->node_dead)
return false; return false;
...@@ -3583,9 +3598,11 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ...@@ -3583,9 +3598,11 @@ cgraph_edge_brings_value_p (cgraph_edge *cs,
ipcp_value<ipa_polymorphic_call_context> *) ipcp_value<ipa_polymorphic_call_context> *)
{ {
class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller); class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
cgraph_node *real_dest = cs->callee->function_symbol (); enum availability avail;
cgraph_node *real_dest = cs->callee->function_symbol (&avail);
if (!same_node_or_its_all_contexts_clone_p (real_dest, dest) if (avail <= AVAIL_INTERPOSABLE
|| !same_node_or_its_all_contexts_clone_p (real_dest, dest)
|| caller_info->node_dead) || caller_info->node_dead)
return false; return false;
if (!src->val) if (!src->val)
...@@ -4018,6 +4035,7 @@ create_specialized_node (struct cgraph_node *node, ...@@ -4018,6 +4035,7 @@ create_specialized_node (struct cgraph_node *node,
update_profiling_info (node, new_node); update_profiling_info (node, new_node);
new_info = IPA_NODE_REF (new_node); new_info = IPA_NODE_REF (new_node);
new_info->ipcp_orig_node = node; new_info->ipcp_orig_node = node;
new_node->ipcp_clone = true;
new_info->known_csts = known_csts; new_info->known_csts = known_csts;
new_info->known_contexts = known_contexts; new_info->known_contexts = known_contexts;
...@@ -5053,7 +5071,7 @@ ipcp_store_bits_results (void) ...@@ -5053,7 +5071,7 @@ ipcp_store_bits_results (void)
bool dumped_sth = false; bool dumped_sth = false;
bool found_useful_result = false; bool found_useful_result = false;
if (!opt_for_fn (node->decl, flag_ipa_bit_cp)) if (!opt_for_fn (node->decl, flag_ipa_bit_cp) || !info)
{ {
if (dump_file) if (dump_file)
fprintf (dump_file, "Not considering %s for ipa bitwise propagation " fprintf (dump_file, "Not considering %s for ipa bitwise propagation "
......
...@@ -483,6 +483,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, ...@@ -483,6 +483,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
if (count && known_contexts_ptr) if (count && known_contexts_ptr)
known_contexts_ptr->safe_grow_cleared (count); known_contexts_ptr->safe_grow_cleared (count);
if (callee_pi)
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i); struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
...@@ -513,6 +514,8 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, ...@@ -513,6 +514,8 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
scalar case above. */ scalar case above. */
known_aggs[i] = &jf->agg; known_aggs[i] = &jf->agg;
} }
else
gcc_assert (callee->thunk.thunk_p);
} }
else if (e->call_stmt && !e->call_stmt_cannot_inline_p else if (e->call_stmt && !e->call_stmt_cannot_inline_p
&& ((clause_ptr && info->conds) || known_vals_ptr)) && ((clause_ptr && info->conds) || known_vals_ptr))
...@@ -3004,7 +3007,8 @@ ipa_call_context::duplicate_from (const ipa_call_context &ctx) ...@@ -3004,7 +3007,8 @@ ipa_call_context::duplicate_from (const ipa_call_context &ctx)
m_possible_truths = ctx.m_possible_truths; m_possible_truths = ctx.m_possible_truths;
m_nonspec_possible_truths = ctx.m_nonspec_possible_truths; m_nonspec_possible_truths = ctx.m_nonspec_possible_truths;
class ipa_node_params *params_summary = IPA_NODE_REF (m_node); class ipa_node_params *params_summary = IPA_NODE_REF (m_node);
unsigned int nargs = ipa_get_param_count (params_summary); unsigned int nargs = params_summary
? ipa_get_param_count (params_summary) : 0;
m_inline_param_summary = vNULL; m_inline_param_summary = vNULL;
/* Copy the info only if there is at least one useful entry. */ /* Copy the info only if there is at least one useful entry. */
...@@ -3093,7 +3097,8 @@ ipa_call_context::equal_to (const ipa_call_context &ctx) ...@@ -3093,7 +3097,8 @@ ipa_call_context::equal_to (const ipa_call_context &ctx)
return false; return false;
class ipa_node_params *params_summary = IPA_NODE_REF (m_node); class ipa_node_params *params_summary = IPA_NODE_REF (m_node);
unsigned int nargs = ipa_get_param_count (params_summary); unsigned int nargs = params_summary
? ipa_get_param_count (params_summary) : 0;
if (m_inline_param_summary.exists () || ctx.m_inline_param_summary.exists ()) if (m_inline_param_summary.exists () || ctx.m_inline_param_summary.exists ())
{ {
...@@ -3404,7 +3409,7 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth) ...@@ -3404,7 +3409,7 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
} }
/* Update change_prob of EDGE after INLINED_EDGE has been inlined. /* Update change_prob of EDGE after INLINED_EDGE has been inlined.
When functoin A is inlined in B and A calls C with parameter that When function A is inlined in B and A calls C with parameter that
changes with probability PROB1 and C is known to be passthroug changes with probability PROB1 and C is known to be passthroug
of argument if B that change with probability PROB2, the probability of argument if B that change with probability PROB2, the probability
of change is now PROB1*PROB2. */ of change is now PROB1*PROB2. */
...@@ -3472,12 +3477,12 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge, ...@@ -3472,12 +3477,12 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
struct cgraph_edge *e, *next; struct cgraph_edge *e, *next;
for (e = node->callees; e; e = next) for (e = node->callees; e; e = next)
{ {
class ipa_call_summary *es = ipa_call_summaries->get (e);
predicate p; predicate p;
next = e->next_callee; next = e->next_callee;
if (e->inline_failed) if (e->inline_failed)
{ {
class ipa_call_summary *es = ipa_call_summaries->get (e);
remap_edge_change_prob (inlined_edge, e); remap_edge_change_prob (inlined_edge, e);
if (es->predicate) if (es->predicate)
......
...@@ -484,7 +484,7 @@ sem_function::param_used_p (unsigned int i) ...@@ -484,7 +484,7 @@ sem_function::param_used_p (unsigned int i)
class ipa_node_params *parms_info = IPA_NODE_REF (get_node ()); class ipa_node_params *parms_info = IPA_NODE_REF (get_node ());
if (vec_safe_length (parms_info->descriptors) <= i) if (!parms_info || vec_safe_length (parms_info->descriptors) <= i)
return true; return true;
return ipa_is_param_used (IPA_NODE_REF (get_node ()), i); return ipa_is_param_used (IPA_NODE_REF (get_node ()), i);
......
...@@ -271,7 +271,7 @@ ipa_dump_param (FILE *file, class ipa_node_params *info, int i) ...@@ -271,7 +271,7 @@ ipa_dump_param (FILE *file, class ipa_node_params *info, int i)
static bool static bool
ipa_alloc_node_params (struct cgraph_node *node, int param_count) ipa_alloc_node_params (struct cgraph_node *node, int param_count)
{ {
class ipa_node_params *info = IPA_NODE_REF (node); class ipa_node_params *info = IPA_NODE_REF_GET_CREATE (node);
if (!info->descriptors && param_count) if (!info->descriptors && param_count)
{ {
...@@ -289,7 +289,7 @@ ipa_alloc_node_params (struct cgraph_node *node, int param_count) ...@@ -289,7 +289,7 @@ ipa_alloc_node_params (struct cgraph_node *node, int param_count)
void void
ipa_initialize_node_params (struct cgraph_node *node) ipa_initialize_node_params (struct cgraph_node *node)
{ {
class ipa_node_params *info = IPA_NODE_REF (node); class ipa_node_params *info = IPA_NODE_REF_GET_CREATE (node);
if (!info->descriptors if (!info->descriptors
&& ipa_alloc_node_params (node, count_formal_params (node->decl))) && ipa_alloc_node_params (node, count_formal_params (node->decl)))
...@@ -2605,7 +2605,7 @@ ipa_analyze_node (struct cgraph_node *node) ...@@ -2605,7 +2605,7 @@ ipa_analyze_node (struct cgraph_node *node)
ipa_check_create_node_params (); ipa_check_create_node_params ();
ipa_check_create_edge_args (); ipa_check_create_edge_args ();
info = IPA_NODE_REF (node); info = IPA_NODE_REF_GET_CREATE (node);
if (info->analysis_done) if (info->analysis_done)
return; return;
...@@ -3601,6 +3601,9 @@ propagate_controlled_uses (struct cgraph_edge *cs) ...@@ -3601,6 +3601,9 @@ propagate_controlled_uses (struct cgraph_edge *cs)
class ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee); class ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
int count, i; int count, i;
if (!old_root_info)
return;
count = MIN (ipa_get_cs_argument_count (args), count = MIN (ipa_get_cs_argument_count (args),
ipa_get_param_count (old_root_info)); ipa_get_param_count (old_root_info));
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
...@@ -3662,8 +3665,8 @@ propagate_controlled_uses (struct cgraph_edge *cs) ...@@ -3662,8 +3665,8 @@ propagate_controlled_uses (struct cgraph_edge *cs)
clone = cs->caller; clone = cs->caller;
while (clone->inlined_to while (clone->inlined_to
&& clone != rdesc->cs->caller && clone->ipcp_clone
&& IPA_NODE_REF (clone)->ipcp_orig_node) && clone != rdesc->cs->caller)
{ {
struct ipa_ref *ref; struct ipa_ref *ref;
ref = clone->find_reference (n, NULL, 0); ref = clone->find_reference (n, NULL, 0);
...@@ -3722,6 +3725,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, ...@@ -3722,6 +3725,7 @@ ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
propagate_controlled_uses (cs); propagate_controlled_uses (cs);
changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges); changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
ipa_node_params_sum->remove (cs->callee);
return changed; return changed;
} }
...@@ -4507,7 +4511,8 @@ ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node, ...@@ -4507,7 +4511,8 @@ ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
struct cgraph_edge *e; struct cgraph_edge *e;
struct bitpack_d bp; struct bitpack_d bp;
bool prevails = node->prevailing_p (); bool prevails = node->prevailing_p ();
class ipa_node_params *info = prevails ? IPA_NODE_REF (node) : NULL; class ipa_node_params *info = prevails
? IPA_NODE_REF_GET_CREATE (node) : NULL;
int param_count = streamer_read_uhwi (ib); int param_count = streamer_read_uhwi (ib);
if (prevails) if (prevails)
......
...@@ -766,7 +766,8 @@ extern GTY(()) function_summary <ipcp_transformation *> *ipcp_transformation_sum ...@@ -766,7 +766,8 @@ extern GTY(()) function_summary <ipcp_transformation *> *ipcp_transformation_sum
/* Return the associated parameter/argument info corresponding to the given /* Return the associated parameter/argument info corresponding to the given
node/edge. */ node/edge. */
#define IPA_NODE_REF(NODE) (ipa_node_params_sum->get_create (NODE)) #define IPA_NODE_REF(NODE) (ipa_node_params_sum->get (NODE))
#define IPA_NODE_REF_GET_CREATE(NODE) (ipa_node_params_sum->get_create (NODE))
#define IPA_EDGE_REF(EDGE) (ipa_edge_args_sum->get (EDGE)) #define IPA_EDGE_REF(EDGE) (ipa_edge_args_sum->get (EDGE))
#define IPA_EDGE_REF_GET_CREATE(EDGE) (ipa_edge_args_sum->get_create (EDGE)) #define IPA_EDGE_REF_GET_CREATE(EDGE) (ipa_edge_args_sum->get_create (EDGE))
/* This macro checks validity of index returned by /* This macro checks validity of index returned by
......
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