static void
set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
class ipa_fn_summary *summary,
+ class ipa_node_params *params_summary,
basic_block bb)
{
gimple *last;
&& !dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
{
predicate p
- = add_condition (summary, index, param_type, &aggpos,
+ = add_condition (summary, params_summary, index,
+ param_type, &aggpos,
this_code, gimple_cond_rhs (last), param_ops);
e->aux = edge_predicate_pool.allocate ();
*(predicate *) e->aux = p;
return;
FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
{
- predicate p = add_condition (summary, index, param_type, &aggpos,
+ predicate p = add_condition (summary, params_summary, index,
+ param_type, &aggpos,
predicate::is_not_constant, NULL_TREE);
e->aux = edge_predicate_pool.allocate ();
*(predicate *) e->aux = p;
static void
set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
class ipa_fn_summary *summary,
+ class ipa_node_params *params_summary,
basic_block bb)
{
gimple *lastg;
if (dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
p = true;
else if (min == max)
- p = add_condition (summary, index, param_type, &aggpos, EQ_EXPR,
- min, param_ops);
+ p = add_condition (summary, params_summary, index, param_type,
+ &aggpos, EQ_EXPR, min, param_ops);
else
{
predicate p1, p2;
- p1 = add_condition (summary, index, param_type, &aggpos, GE_EXPR,
- min, param_ops);
- p2 = add_condition (summary, index, param_type, &aggpos, LE_EXPR,
- max, param_ops);
+ p1 = add_condition (summary, params_summary, index, param_type,
+ &aggpos, GE_EXPR, min, param_ops);
+ p2 = add_condition (summary, params_summary,index, param_type,
+ &aggpos, LE_EXPR, max, param_ops);
p = p1 & p2;
}
*(class predicate *) e->aux
tree max = ranges[i].second;
if (min == max)
- p_seg &= add_condition (summary, index, param_type, &aggpos, NE_EXPR,
+ p_seg &= add_condition (summary, params_summary, index,
+ param_type, &aggpos, NE_EXPR,
min, param_ops);
else
{
of switch index. */
if (wi::lt_p (vr_wmin, wi::to_wide (min), TYPE_SIGN (type)))
{
- p_seg &= add_condition (summary, index, param_type, &aggpos,
+ p_seg &= add_condition (summary, params_summary, index,
+ param_type, &aggpos,
LT_EXPR, min, param_ops);
p_all = p_all.or_with (summary->conds, p_seg);
}
break;
}
- p_seg = add_condition (summary, index, param_type, &aggpos, GT_EXPR,
+ p_seg = add_condition (summary, params_summary, index,
+ param_type, &aggpos, GT_EXPR,
max, param_ops);
}
}
static void
compute_bb_predicates (struct ipa_func_body_info *fbi,
struct cgraph_node *node,
- class ipa_fn_summary *summary)
+ class ipa_fn_summary *summary,
+ class ipa_node_params *params_summary)
{
struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
bool done = false;
FOR_EACH_BB_FN (bb, my_function)
{
- set_cond_stmt_execution_predicate (fbi, summary, bb);
- set_switch_stmt_execution_predicate (fbi, summary, bb);
+ set_cond_stmt_execution_predicate (fbi, summary, params_summary, bb);
+ set_switch_stmt_execution_predicate (fbi, summary, params_summary, bb);
}
/* Entry block is always executable. */
static predicate
will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
class ipa_fn_summary *summary,
+ class ipa_node_params *params_summary,
tree expr,
vec<predicate> nonconstant_names)
{
parm = unmodified_parm (fbi, NULL, expr, NULL);
if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
- return add_condition (summary, index, TREE_TYPE (parm), NULL,
+ return add_condition (summary, params_summary, index, TREE_TYPE (parm), NULL,
predicate::changed, NULL_TREE);
if (is_gimple_min_invariant (expr))
return false;
{
predicate p1
= will_be_nonconstant_expr_predicate (fbi, summary,
+ params_summary,
TREE_OPERAND (expr, 0),
nonconstant_names);
if (p1 == true)
predicate p2
= will_be_nonconstant_expr_predicate (fbi, summary,
+ params_summary,
TREE_OPERAND (expr, 1),
nonconstant_names);
return p1.or_with (summary->conds, p2);
{
predicate p1
= will_be_nonconstant_expr_predicate (fbi, summary,
+ params_summary,
TREE_OPERAND (expr, 0),
nonconstant_names);
if (p1 == true)
predicate p2
= will_be_nonconstant_expr_predicate (fbi, summary,
+ params_summary,
TREE_OPERAND (expr, 1),
nonconstant_names);
if (p2 == true)
return p2;
p1 = p1.or_with (summary->conds, p2);
p2 = will_be_nonconstant_expr_predicate (fbi, summary,
+ params_summary,
TREE_OPERAND (expr, 2),
nonconstant_names);
return p2.or_with (summary->conds, p1);
static predicate
will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
class ipa_fn_summary *summary,
+ class ipa_node_params *params_summary,
gimple *stmt,
vec<predicate> nonconstant_names)
{
if (is_load)
op_non_const =
- add_condition (summary, base_index, param_type, &aggpos,
+ add_condition (summary, params_summary,
+ base_index, param_type, &aggpos,
predicate::changed, NULL_TREE);
else
op_non_const = false;
if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
{
if (index != base_index)
- p = add_condition (summary, index, TREE_TYPE (parm), NULL,
+ p = add_condition (summary, params_summary, index,
+ TREE_TYPE (parm), NULL,
predicate::changed, NULL_TREE);
else
continue;
static bool
phi_result_unknown_predicate (ipa_func_body_info *fbi,
- ipa_fn_summary *summary, basic_block bb,
+ ipa_fn_summary *summary,
+ class ipa_node_params *params_summary,
+ basic_block bb,
predicate *p,
vec<predicate> nonconstant_names)
{
|| !is_gimple_ip_invariant (gimple_cond_rhs (stmt)))
return false;
- *p = will_be_nonconstant_expr_predicate (fbi, summary,
+ *p = will_be_nonconstant_expr_predicate (fbi, summary, params_summary,
gimple_cond_lhs (stmt),
nonconstant_names);
if (*p == true)
struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
sreal freq;
class ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
+ class ipa_node_params *params_summary = early ? NULL : IPA_NODE_REF (node);
predicate bb_predicate;
struct ipa_func_body_info fbi;
vec<predicate> nonconstant_names = vNULL;
bb_predicate);
if (fbi.info)
- compute_bb_predicates (&fbi, node, info);
+ compute_bb_predicates (&fbi, node, info, params_summary);
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++)
gsi_next (&bsi))
{
if (first_phi
- && !phi_result_unknown_predicate (&fbi, info, bb,
+ && !phi_result_unknown_predicate (&fbi, info,
+ params_summary,
+ bb,
&phi_predicate,
nonconstant_names))
break;
just maximum of the possible paths. */
if (fbi.info)
will_be_nonconstant
- = will_be_nonconstant_predicate (&fbi, info,
+ = will_be_nonconstant_predicate (&fbi, info, params_summary,
stmt, nonconstant_names);
else
will_be_nonconstant = true;
predicate p = bb_predicate;
if (fbi.info)
p = p & will_be_nonconstant_expr_predicate
- (&fbi, info, TREE_OPERAND (op, 1),
+ (&fbi, info, params_summary,
+ TREE_OPERAND (op, 1),
nonconstant_names);
if (p != false)
{
{
predicate will_be_nonconstant
= will_be_nonconstant_expr_predicate (&fbi, info,
+ params_summary,
niter_desc.niter,
nonconstant_names);
if (will_be_nonconstant != true)
continue;
predicate will_be_nonconstant
- = will_be_nonconstant_expr_predicate (&fbi, info, iv.step,
+ = will_be_nonconstant_expr_predicate (&fbi, info,
+ params_summary,
+ iv.step,
nonconstant_names);
if (will_be_nonconstant != true)
will_be_nonconstant = bb_predicate & will_be_nonconstant;
{
}
+/* Set THIS to be a duplicate of CTX. Copy all relevant info. */
+
void
ipa_call_context::duplicate_from (const ipa_call_context &ctx)
{
m_node = ctx.m_node;
m_possible_truths = ctx.m_possible_truths;
m_nonspec_possible_truths = ctx.m_nonspec_possible_truths;
+ class ipa_node_params *params_summary = IPA_NODE_REF (m_node);
+ unsigned int nargs = ipa_get_param_count (params_summary);
+ m_inline_param_summary = vNULL;
+ /* Copy the info only if there is at least one useful entry. */
if (ctx.m_inline_param_summary.exists ())
- m_inline_param_summary = ctx.m_inline_param_summary.copy ();
- else
- m_inline_param_summary = vNULL;
+ {
+ unsigned int n = MIN (ctx.m_inline_param_summary.length (), nargs);
+
+ for (unsigned int i = 0; i < n; i++)
+ if (ipa_is_param_used_by_ipa_predicates (params_summary, i)
+ && !ctx.m_inline_param_summary[i].useless_p ())
+ {
+ m_inline_param_summary
+ = ctx.m_inline_param_summary.copy ();
+ break;
+ }
+ }
+ m_known_vals = vNULL;
if (ctx.m_known_vals.exists ())
- m_known_vals = ctx.m_known_vals.copy ();
- else
- m_known_vals = vNULL;
+ {
+ unsigned int n = MIN (ctx.m_known_vals.length (), nargs);
+
+ for (unsigned int i = 0; i < n; i++)
+ if (ipa_is_param_used_by_indirect_call (params_summary, i)
+ && ctx.m_known_vals[i])
+ {
+ m_known_vals = ctx.m_known_vals.copy ();
+ break;
+ }
+ }
+
+ m_known_contexts = vNULL;
if (ctx.m_known_contexts.exists ())
- m_known_contexts = ctx.m_known_contexts.copy ();
- else
- m_known_contexts = vNULL;
+ {
+ unsigned int n = MIN (ctx.m_known_contexts.length (), nargs);
+
+ for (unsigned int i = 0; i < n; i++)
+ if (ipa_is_param_used_by_polymorphic_call (params_summary, i)
+ && !ctx.m_known_contexts[i].useless_p ())
+ {
+ m_known_contexts = ctx.m_known_contexts.copy ();
+ break;
+ }
+ }
+
+ m_known_aggs = vNULL;
if (ctx.m_known_aggs.exists ())
- m_known_aggs = ctx.m_known_aggs.copy ();
- else
- m_known_aggs = vNULL;
+ {
+ unsigned int n = MIN (ctx.m_known_aggs.length (), nargs);
+
+ for (unsigned int i = 0; i < n; i++)
+ if (ipa_is_param_used_by_indirect_call (params_summary, i)
+ && ctx.m_known_aggs[i])
+ {
+ m_known_aggs = ctx.m_known_aggs.copy ();
+ break;
+ }
+ }
}
/* Release memory used by known_vals/contexts/aggs vectors.
|| m_possible_truths != ctx.m_possible_truths
|| m_nonspec_possible_truths != ctx.m_nonspec_possible_truths)
return false;
- if (m_inline_param_summary.exists () != ctx.m_inline_param_summary.exists ()
- || m_known_vals.exists () != ctx.m_known_vals.exists()
- || m_known_contexts.exists () != ctx.m_known_contexts.exists ()
- || m_known_aggs.exists () != ctx.m_known_aggs.exists ())
- return false;
- if (m_inline_param_summary.exists ())
+
+ class ipa_node_params *params_summary = IPA_NODE_REF (m_node);
+ unsigned int nargs = ipa_get_param_count (params_summary);
+
+ if (m_inline_param_summary.exists () || ctx.m_inline_param_summary.exists ())
{
- if (m_inline_param_summary.length () != ctx.m_inline_param_summary.length ())
- return false;
- for (unsigned int i = 0; i < m_inline_param_summary.length (); i++)
- if (!m_inline_param_summary[i].equal_to (ctx.m_inline_param_summary[i]))
- return false;
+ for (unsigned int i = 0; i < nargs; i++)
+ {
+ if (!ipa_is_param_used_by_ipa_predicates (params_summary, i))
+ continue;
+ if (i >= m_inline_param_summary.length ()
+ || m_inline_param_summary[i].useless_p ())
+ {
+ if (i < ctx.m_inline_param_summary.length ()
+ && !ctx.m_inline_param_summary[i].useless_p ())
+ return false;
+ continue;
+ }
+ if (i >= ctx.m_inline_param_summary.length ()
+ || ctx.m_inline_param_summary[i].useless_p ())
+ {
+ if (i < m_inline_param_summary.length ()
+ && !m_inline_param_summary[i].useless_p ())
+ return false;
+ continue;
+ }
+ if (!m_inline_param_summary[i].equal_to
+ (ctx.m_inline_param_summary[i]))
+ return false;
+ }
}
- if (m_known_vals.exists ())
+ if (m_known_vals.exists () || ctx.m_known_vals.exists ())
{
- if (m_known_vals.length () != ctx.m_known_vals.length ())
- return false;
- for (unsigned int i = 0; i < m_known_vals.length (); i++)
+ for (unsigned int i = 0; i < nargs; i++)
{
- tree t1 = m_known_vals[i];
- tree t2 = ctx.m_known_vals[i];
-
- if (t1 != t2
- && (!t1 || !t2 || !operand_equal_p (m_known_vals[i],
- ctx.m_known_vals[i], 0)))
+ if (!ipa_is_param_used_by_indirect_call (params_summary, i))
+ continue;
+ if (i >= m_known_vals.length () || !m_known_vals[i])
+ {
+ if (i < ctx.m_known_vals.length () && ctx.m_known_vals[i])
+ return false;
+ continue;
+ }
+ if (i >= ctx.m_known_vals.length () || !ctx.m_known_vals[i])
+ {
+ if (i < m_known_vals.length () && m_known_vals[i])
+ return false;
+ continue;
+ }
+ if (m_known_vals[i] != ctx.m_known_vals[i])
return false;
}
}
- if (m_known_contexts.exists ())
+ if (m_known_contexts.exists () || ctx.m_known_contexts.exists ())
{
- if (m_known_contexts.length () != ctx.m_known_contexts.length ())
- return false;
- for (unsigned int i = 0; i < m_known_contexts.length (); i++)
- if (!m_known_contexts[i].equal_to (ctx.m_known_contexts[i]))
- return false;
+ for (unsigned int i = 0; i < nargs; i++)
+ {
+ if (!ipa_is_param_used_by_polymorphic_call (params_summary, i))
+ continue;
+ if (i >= m_known_contexts.length ()
+ || m_known_contexts[i].useless_p ())
+ {
+ if (i < ctx.m_known_contexts.length ()
+ && !ctx.m_known_contexts[i].useless_p ())
+ return false;
+ continue;
+ }
+ if (i >= ctx.m_known_contexts.length ()
+ || ctx.m_known_contexts[i].useless_p ())
+ {
+ if (i < m_known_contexts.length ()
+ && !m_known_contexts[i].useless_p ())
+ return false;
+ continue;
+ }
+ if (!m_known_contexts[i].equal_to
+ (ctx.m_known_contexts[i]))
+ return false;
+ }
}
- if (m_known_aggs.exists ())
+ if (m_known_aggs.exists () || ctx.m_known_aggs.exists ())
{
- if (m_known_aggs.length () != ctx.m_known_aggs.length ())
- return false;
- for (unsigned int i = 0; i < m_known_aggs.length (); i++)
- if (!m_known_aggs[i]->equal_to (*ctx.m_known_aggs[i]))
- return false;
+ for (unsigned int i = 0; i < nargs; i++)
+ {
+ if (!ipa_is_param_used_by_indirect_call (params_summary, i))
+ continue;
+ if (i >= m_known_aggs.length () || !m_known_aggs[i])
+ {
+ if (i < ctx.m_known_aggs.length () && ctx.m_known_aggs[i])
+ return false;
+ continue;
+ }
+ if (i >= ctx.m_known_aggs.length () || !ctx.m_known_aggs[i])
+ {
+ if (i < m_known_aggs.length () && m_known_aggs[i])
+ return false;
+ continue;
+ }
+ if (m_known_aggs[i] != ctx.m_known_aggs[i])
+ return false;
+ }
}
return true;
}
remap_edge_summaries (struct cgraph_edge *inlined_edge,
struct cgraph_node *node,
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,
if (es->predicate)
{
p = es->predicate->remap_after_inlining
- (info, callee_info, operand_map,
+ (info, params_summary,
+ callee_info, operand_map,
offset_map, possible_truths,
*toplev_predicate);
edge_set_predicate (e, &p);
edge_set_predicate (e, toplev_predicate);
}
else
- remap_edge_summaries (inlined_edge, e->callee, info, callee_info,
+ remap_edge_summaries (inlined_edge, e->callee, info,
+ params_summary, callee_info,
operand_map, offset_map, possible_truths,
toplev_predicate);
}
if (es->predicate)
{
p = es->predicate->remap_after_inlining
- (info, callee_info, operand_map, offset_map,
+ (info, params_summary,
+ callee_info, operand_map, offset_map,
possible_truths, *toplev_predicate);
edge_set_predicate (e, &p);
}
static void
remap_hint_predicate (class ipa_fn_summary *info,
+ class ipa_node_params *params_summary,
class ipa_fn_summary *callee_info,
predicate **hint,
vec<int> operand_map,
if (!*hint)
return;
p = (*hint)->remap_after_inlining
- (info, callee_info,
+ (info, params_summary, callee_info,
operand_map, offset_map,
possible_truths, *toplev_predicate);
if (p != false && p != true)
int i;
predicate toplev_predicate;
class ipa_call_summary *es = ipa_call_summaries->get (edge);
+ class ipa_node_params *params_summary = (ipa_node_params_sum
+ ? IPA_NODE_REF (to) : NULL);
if (es->predicate)
toplev_predicate = *es->predicate;
}
}
operand_map[i] = map;
- gcc_assert (map < ipa_get_param_count (IPA_NODE_REF (to)));
+ gcc_assert (map < ipa_get_param_count (params_summary));
}
}
for (i = 0; vec_safe_iterate (callee_info->size_time_table, i, &e); i++)
{
predicate p;
p = e->exec_predicate.remap_after_inlining
- (info, callee_info, operand_map,
+ (info, params_summary,
+ callee_info, operand_map,
offset_map, clause,
toplev_predicate);
predicate nonconstp;
nonconstp = e->nonconst_predicate.remap_after_inlining
- (info, callee_info, operand_map,
+ (info, params_summary,
+ callee_info, operand_map,
offset_map, clause,
toplev_predicate);
if (p != false && nonconstp != false)
info->account_size_time (e->size, add_time, p, nonconstp);
}
}
- remap_edge_summaries (edge, edge->callee, info, callee_info, operand_map,
+ remap_edge_summaries (edge, edge->callee, info, params_summary,
+ callee_info, operand_map,
offset_map, clause, &toplev_predicate);
- remap_hint_predicate (info, callee_info,
+ remap_hint_predicate (info, params_summary, callee_info,
&callee_info->loop_iterations,
operand_map, offset_map, clause, &toplev_predicate);
- remap_hint_predicate (info, callee_info,
+ remap_hint_predicate (info, params_summary, callee_info,
&callee_info->loop_stride,
operand_map, offset_map, clause, &toplev_predicate);
unsigned int index;
struct cgraph_node *node;
class ipa_fn_summary *info;
+ class ipa_node_params *params_summary;
class ipa_size_summary *size_info;
lto_symtab_encoder_t encoder;
struct bitpack_d bp;
node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
index));
info = node->prevailing_p () ? ipa_fn_summaries->get_create (node) : NULL;
+ params_summary = node->prevailing_p () ? IPA_NODE_REF (node) : NULL;
size_info = node->prevailing_p ()
? ipa_size_summaries->get_create (node) : NULL;
c.param_ops = NULL;
if (info)
vec_safe_reserve_exact (c.param_ops, count3);
+ if (params_summary)
+ ipa_set_param_used_by_ipa_predicates
+ (params_summary, c.operand_num, true);
for (k = 0; k < count3; k++)
{
struct expr_eval_op op;
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++;
}
}
/* 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;
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;
}
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;
}
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;
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;
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));
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)
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");
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;
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. */
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);
}
}