[PR 78365] Prudent type handling in IPA VR-prop
2017-01-09 Martin Jambor <mjambor@suse.cz> PR ipa/78365 PR ipa/78599 * ipa-prop.h (ipa_jump_func): Swap positions of vr_known and m_vr. * ipa-cp.c (ipa_vr_operation_and_type_effects): New function. (propagate_vr_accross_jump_function): Use the above function for all value range computations for pass-through jump functions and type converasion from explicit value range values. (ipcp_propagate_stage): Do not attempt to deduce types of formal parameters from TYPE_ARG_TYPES. * ipa-prop.c (ipa_write_jump_function): Remove trailing whitespace. (ipa_write_node_info): Stream type of the actual argument. (ipa_read_node_info): Likewise. Also remove trailing whitespace. testsuite/ * gcc.dg/torture/pr78365.c: New test. From-SVN: r244232
This commit is contained in:
parent
a7765de8ef
commit
a5e14a42da
6 changed files with 90 additions and 42 deletions
|
@ -1,3 +1,18 @@
|
|||
2017-01-09 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
PR ipa/78365
|
||||
PR ipa/78599
|
||||
* ipa-prop.h (ipa_jump_func): Swap positions of vr_known and m_vr.
|
||||
* ipa-cp.c (ipa_vr_operation_and_type_effects): New function.
|
||||
(propagate_vr_accross_jump_function): Use the above function for all
|
||||
value range computations for pass-through jump functions and type
|
||||
converasion from explicit value range values.
|
||||
(ipcp_propagate_stage): Do not attempt to deduce types of formal
|
||||
parameters from TYPE_ARG_TYPES.
|
||||
* ipa-prop.c (ipa_write_jump_function): Remove trailing whitespace.
|
||||
(ipa_write_node_info): Stream type of the actual argument.
|
||||
(ipa_read_node_info): Likewise. Also remove trailing whitespace.
|
||||
|
||||
2017-01-09 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR pch/78970
|
||||
|
|
71
gcc/ipa-cp.c
71
gcc/ipa-cp.c
|
@ -1837,6 +1837,23 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
|
|||
return dest_lattice->set_to_bottom ();
|
||||
}
|
||||
|
||||
/* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
|
||||
DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
|
||||
the result is a range or an anti-range. */
|
||||
|
||||
static bool
|
||||
ipa_vr_operation_and_type_effects (value_range *dst_vr, value_range *src_vr,
|
||||
enum tree_code operation,
|
||||
tree dst_type, tree src_type)
|
||||
{
|
||||
memset (dst_vr, 0, sizeof (*dst_vr));
|
||||
extract_range_from_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
|
||||
if (dst_vr->type == VR_RANGE || dst_vr->type == VR_ANTI_RANGE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Propagate value range across jump function JFUNC that is associated with
|
||||
edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
|
||||
accordingly. */
|
||||
|
@ -1846,7 +1863,6 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
|
|||
struct ipcp_param_lattices *dest_plats,
|
||||
tree param_type)
|
||||
{
|
||||
struct ipcp_param_lattices *src_lats;
|
||||
ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
|
||||
|
||||
if (dest_lat->bottom_p ())
|
||||
|
@ -1859,31 +1875,23 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
|
|||
|
||||
if (jfunc->type == IPA_JF_PASS_THROUGH)
|
||||
{
|
||||
struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
|
||||
int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
|
||||
src_lats = ipa_get_parm_lattices (caller_info, src_idx);
|
||||
enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
|
||||
|
||||
if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
|
||||
return dest_lat->meet_with (src_lats->m_value_range);
|
||||
else if (param_type
|
||||
&& (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
|
||||
== tcc_unary))
|
||||
if (TREE_CODE_CLASS (operation) == tcc_unary)
|
||||
{
|
||||
value_range vr;
|
||||
memset (&vr, 0, sizeof (vr));
|
||||
struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
|
||||
int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
|
||||
tree operand_type = ipa_get_type (caller_info, src_idx);
|
||||
enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
|
||||
struct ipcp_param_lattices *src_lats
|
||||
= ipa_get_parm_lattices (caller_info, src_idx);
|
||||
|
||||
if (src_lats->m_value_range.bottom_p ())
|
||||
return dest_lat->set_to_bottom ();
|
||||
|
||||
extract_range_from_unary_expr (&vr,
|
||||
operation,
|
||||
param_type,
|
||||
&src_lats->m_value_range.m_vr,
|
||||
operand_type);
|
||||
if (vr.type == VR_RANGE
|
||||
|| vr.type == VR_ANTI_RANGE)
|
||||
value_range vr;
|
||||
if (ipa_vr_operation_and_type_effects (&vr,
|
||||
&src_lats->m_value_range.m_vr,
|
||||
operation, param_type,
|
||||
operand_type))
|
||||
return dest_lat->meet_with (&vr);
|
||||
}
|
||||
}
|
||||
|
@ -1903,8 +1911,12 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
|
|||
}
|
||||
}
|
||||
|
||||
if (jfunc->vr_known)
|
||||
return dest_lat->meet_with (&jfunc->m_vr);
|
||||
value_range vr;
|
||||
if (jfunc->vr_known
|
||||
&& ipa_vr_operation_and_type_effects (&vr, &jfunc->m_vr, NOP_EXPR,
|
||||
param_type,
|
||||
TREE_TYPE (jfunc->m_vr.min)))
|
||||
return dest_lat->meet_with (&vr);
|
||||
else
|
||||
return dest_lat->set_to_bottom ();
|
||||
}
|
||||
|
@ -2244,7 +2256,7 @@ propagate_constants_across_call (struct cgraph_edge *cs)
|
|||
{
|
||||
struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
|
||||
struct ipcp_param_lattices *dest_plats;
|
||||
tree param_type = ipa_get_callee_param_type (cs, i);
|
||||
tree param_type = ipa_get_type (callee_info, i);
|
||||
|
||||
dest_plats = ipa_get_parm_lattices (callee_info, i);
|
||||
if (availability == AVAIL_INTERPOSABLE)
|
||||
|
@ -3230,19 +3242,6 @@ ipcp_propagate_stage (struct ipa_topo_info *topo)
|
|||
{
|
||||
struct ipa_node_params *info = IPA_NODE_REF (node);
|
||||
|
||||
/* In LTO we do not have PARM_DECLs but we would still like to be able to
|
||||
look at types of parameters. */
|
||||
if (in_lto_p)
|
||||
{
|
||||
tree t = TYPE_ARG_TYPES (TREE_TYPE (node->decl));
|
||||
for (int k = 0; k < ipa_get_param_count (info) && t; k++)
|
||||
{
|
||||
gcc_assert (t != void_list_node);
|
||||
info->descriptors[k].decl_or_type = TREE_VALUE (t);
|
||||
t = t ? TREE_CHAIN (t) : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
determine_versionability (node, info);
|
||||
if (node->has_gimple_body_p ())
|
||||
{
|
||||
|
|
|
@ -4775,7 +4775,7 @@ ipa_write_jump_function (struct output_block *ob,
|
|||
{
|
||||
streamer_write_widest_int (ob, jump_func->bits.value);
|
||||
streamer_write_widest_int (ob, jump_func->bits.mask);
|
||||
}
|
||||
}
|
||||
bp_pack_value (&bp, jump_func->vr_known, 1);
|
||||
streamer_write_bitpack (&bp);
|
||||
if (jump_func->vr_known)
|
||||
|
@ -4973,7 +4973,10 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
|
|||
bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
|
||||
streamer_write_bitpack (&bp);
|
||||
for (j = 0; j < ipa_get_param_count (info); j++)
|
||||
streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
|
||||
{
|
||||
streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
|
||||
stream_write_tree (ob, ipa_get_type (info, j), true);
|
||||
}
|
||||
for (e = node->callees; e; e = e->next_callee)
|
||||
{
|
||||
struct ipa_edge_args *args = IPA_EDGE_REF (e);
|
||||
|
@ -5020,7 +5023,7 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
|
|||
|
||||
for (k = 0; k < ipa_get_param_count (info); k++)
|
||||
info->descriptors[k].move_cost = streamer_read_uhwi (ib);
|
||||
|
||||
|
||||
bp = streamer_read_bitpack (ib);
|
||||
if (ipa_get_param_count (info) != 0)
|
||||
info->analysis_done = true;
|
||||
|
@ -5028,7 +5031,10 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
|
|||
for (k = 0; k < ipa_get_param_count (info); k++)
|
||||
ipa_set_param_used (info, k, bp_unpack_value (&bp, 1));
|
||||
for (k = 0; k < ipa_get_param_count (info); k++)
|
||||
ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
|
||||
{
|
||||
ipa_set_controlled_uses (info, k, streamer_read_hwi (ib));
|
||||
info->descriptors[k].decl_or_type = stream_read_tree (ib, data_in);
|
||||
}
|
||||
for (e = node->callees; e; e = e->next_callee)
|
||||
{
|
||||
struct ipa_edge_args *args = IPA_EDGE_REF (e);
|
||||
|
|
|
@ -178,9 +178,10 @@ struct GTY (()) ipa_jump_func
|
|||
/* Information about zero/non-zero bits. */
|
||||
struct ipa_bits bits;
|
||||
|
||||
/* Information about value range. */
|
||||
bool vr_known;
|
||||
/* Information about value range, containing valid data only when vr_known is
|
||||
true. */
|
||||
value_range m_vr;
|
||||
bool vr_known;
|
||||
|
||||
enum jump_func_type type;
|
||||
/* Represents a value of a jump function. pass_through is used only in jump
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2017-01-09 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
PR ipa/78365
|
||||
PR ipa/78599
|
||||
* gcc.dg/torture/pr78365.c: New test.
|
||||
|
||||
2017-01-09 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/78948
|
||||
|
|
21
gcc/testsuite/gcc.dg/torture/pr78365.c
Normal file
21
gcc/testsuite/gcc.dg/torture/pr78365.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do compile } */
|
||||
|
||||
int a, b, c;
|
||||
char d;
|
||||
static void fn1 (void *, int);
|
||||
int fn2 (int);
|
||||
|
||||
void fn1 (cc, yh) void *cc;
|
||||
char yh;
|
||||
{
|
||||
char y;
|
||||
a = fn2(c - b + 1);
|
||||
for (; y <= yh; y++)
|
||||
;
|
||||
}
|
||||
|
||||
void fn3()
|
||||
{
|
||||
fn1((void *)fn3, 1);
|
||||
fn1((void *)fn3, d - 1);
|
||||
}
|
Loading…
Add table
Reference in a new issue