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
This commit is contained in:
parent
4bcd578ab4
commit
40a777e840
6 changed files with 386 additions and 97 deletions
|
@ -1,3 +1,42 @@
|
|||
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
|
||||
|
|
|
@ -1312,6 +1312,7 @@ fail:
|
|||
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;
|
||||
|
@ -1354,7 +1355,8 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
|||
&& !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;
|
||||
|
@ -1387,7 +1389,8 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
|||
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;
|
||||
|
@ -1401,6 +1404,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
|||
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;
|
||||
|
@ -1470,15 +1474,15 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
|||
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
|
||||
|
@ -1559,7 +1563,8 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
|||
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
|
||||
{
|
||||
|
@ -1567,7 +1572,8 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
|||
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);
|
||||
}
|
||||
|
@ -1580,7 +1586,8 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1599,7 +1606,8 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
|||
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;
|
||||
|
@ -1607,8 +1615,8 @@ compute_bb_predicates (struct ipa_func_body_info *fbi,
|
|||
|
||||
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. */
|
||||
|
@ -1701,6 +1709,7 @@ compute_bb_predicates (struct ipa_func_body_info *fbi,
|
|||
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)
|
||||
{
|
||||
|
@ -1712,7 +1721,7 @@ will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
|
|||
|
||||
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;
|
||||
|
@ -1722,6 +1731,7 @@ will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
|
|||
{
|
||||
predicate p1
|
||||
= will_be_nonconstant_expr_predicate (fbi, summary,
|
||||
params_summary,
|
||||
TREE_OPERAND (expr, 0),
|
||||
nonconstant_names);
|
||||
if (p1 == true)
|
||||
|
@ -1729,6 +1739,7 @@ will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
|
|||
|
||||
predicate p2
|
||||
= will_be_nonconstant_expr_predicate (fbi, summary,
|
||||
params_summary,
|
||||
TREE_OPERAND (expr, 1),
|
||||
nonconstant_names);
|
||||
return p1.or_with (summary->conds, p2);
|
||||
|
@ -1737,6 +1748,7 @@ will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
|
|||
{
|
||||
predicate p1
|
||||
= will_be_nonconstant_expr_predicate (fbi, summary,
|
||||
params_summary,
|
||||
TREE_OPERAND (expr, 0),
|
||||
nonconstant_names);
|
||||
if (p1 == true)
|
||||
|
@ -1744,12 +1756,14 @@ will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
|
|||
|
||||
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);
|
||||
|
@ -1771,6 +1785,7 @@ will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
|
|||
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)
|
||||
{
|
||||
|
@ -1828,7 +1843,8 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
|
|||
|
||||
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;
|
||||
|
@ -1840,7 +1856,8 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
|
|||
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;
|
||||
|
@ -2027,7 +2044,9 @@ param_change_prob (ipa_func_body_info *fbi, gimple *stmt, int i)
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -2071,7 +2090,7 @@ phi_result_unknown_predicate (ipa_func_body_info *fbi,
|
|||
|| !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)
|
||||
|
@ -2264,6 +2283,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
|
|||
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;
|
||||
|
@ -2329,7 +2349,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
|
|||
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++)
|
||||
|
@ -2371,7 +2391,9 @@ analyze_function_body (struct cgraph_node *node, bool early)
|
|||
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;
|
||||
|
@ -2469,7 +2491,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
|
|||
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;
|
||||
|
@ -2536,7 +2558,8 @@ analyze_function_body (struct cgraph_node *node, bool early)
|
|||
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)
|
||||
{
|
||||
|
@ -2581,6 +2604,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
|
|||
{
|
||||
predicate will_be_nonconstant
|
||||
= will_be_nonconstant_expr_predicate (&fbi, info,
|
||||
params_summary,
|
||||
niter_desc.niter,
|
||||
nonconstant_names);
|
||||
if (will_be_nonconstant != true)
|
||||
|
@ -2625,7 +2649,9 @@ analyze_function_body (struct cgraph_node *node, bool early)
|
|||
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;
|
||||
|
@ -2964,29 +2990,73 @@ ipa_call_context::ipa_call_context (cgraph_node *node,
|
|||
{
|
||||
}
|
||||
|
||||
/* 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.
|
||||
|
@ -3016,49 +3086,107 @@ ipa_call_context::equal_to (const ipa_call_context &ctx)
|
|||
|| 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 ())
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (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++)
|
||||
{
|
||||
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)))
|
||||
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 ())
|
||||
{
|
||||
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_contexts.exists ())
|
||||
if (m_known_vals.exists () || ctx.m_known_vals.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_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_aggs.exists ())
|
||||
if (m_known_contexts.exists () || ctx.m_known_contexts.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_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 () || ctx.m_known_aggs.exists ())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -3319,6 +3447,7 @@ static void
|
|||
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,
|
||||
|
@ -3339,7 +3468,8 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
|
|||
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);
|
||||
|
@ -3348,7 +3478,8 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
|
|||
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);
|
||||
}
|
||||
|
@ -3362,7 +3493,8 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
|
|||
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);
|
||||
}
|
||||
|
@ -3375,6 +3507,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
|
|||
|
||||
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,
|
||||
|
@ -3387,7 +3520,7 @@ remap_hint_predicate (class ipa_fn_summary *info,
|
|||
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)
|
||||
|
@ -3415,6 +3548,8 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
|
|||
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;
|
||||
|
@ -3461,19 +3596,21 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
|
|||
}
|
||||
}
|
||||
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)
|
||||
|
@ -3491,12 +3628,13 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
|
|||
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);
|
||||
|
||||
|
@ -3687,6 +3825,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
|
|||
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;
|
||||
|
@ -3698,6 +3837,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
|
|||
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;
|
||||
|
||||
|
@ -3746,6 +3886,9 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
|
|||
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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue