mirror of git://gcc.gnu.org/git/gcc.git
pr78268.C: New test.
gcc/testsuite/ChangeLog: 2016-11-13 Kugan Vivekanandarajah <kuganv@linaro.org> * g++.dg/torture/pr78268.C: New test. gcc/ChangeLog: 2016-11-13 Kugan Vivekanandarajah <kuganv@linaro.org> * ipa-cp.c (ipa_get_jf_pass_through_result): Skip unary expressions. (propagate_vr_accross_jump_function): Handle unary expressions. * ipa-prop.c (ipa_set_jf_unary_pass_through): New. (load_from_param_1): New. (load_from_unmodified_param): Factor common part into load_from_param_1. (load_from_param): New. (compute_complex_assign_jump_func): Handle unary expressions. (update_jump_functions_after_inlining): Likewise. (ipa_write_jump_function): Likewise. (ipa_read_jump_function): Likewise. From-SVN: r242368
This commit is contained in:
parent
1701800580
commit
a2b4c18823
|
|
@ -1,3 +1,16 @@
|
|||
2016-11-13 Kugan Vivekanandarajah <kuganv@linaro.org>
|
||||
|
||||
* ipa-cp.c (ipa_get_jf_pass_through_result): Skip unary expressions.
|
||||
(propagate_vr_accross_jump_function): Handle unary expressions.
|
||||
* ipa-prop.c (ipa_set_jf_unary_pass_through): New.
|
||||
(load_from_param_1): New.
|
||||
(load_from_unmodified_param): Factor common part into load_from_param_1.
|
||||
(load_from_param): New.
|
||||
(compute_complex_assign_jump_func): Handle unary expressions.
|
||||
(update_jump_functions_after_inlining): Likewise.
|
||||
(ipa_write_jump_function): Likewise.
|
||||
(ipa_read_jump_function): Likewise.
|
||||
|
||||
2016-11-13 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
|
||||
|
||||
PR c/35503
|
||||
|
|
|
|||
41
gcc/ipa-cp.c
41
gcc/ipa-cp.c
|
|
@ -1219,13 +1219,19 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
|
|||
return NULL_TREE;
|
||||
|
||||
if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
|
||||
== tcc_comparison)
|
||||
restype = boolean_type_node;
|
||||
== tcc_unary)
|
||||
res = fold_unary (ipa_get_jf_pass_through_operation (jfunc),
|
||||
TREE_TYPE (input), input);
|
||||
else
|
||||
restype = TREE_TYPE (input);
|
||||
res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype,
|
||||
input, ipa_get_jf_pass_through_operand (jfunc));
|
||||
|
||||
{
|
||||
if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
|
||||
== tcc_comparison)
|
||||
restype = boolean_type_node;
|
||||
else
|
||||
restype = TREE_TYPE (input);
|
||||
res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype,
|
||||
input, ipa_get_jf_pass_through_operand (jfunc));
|
||||
}
|
||||
if (res && !is_gimple_ip_invariant (res))
|
||||
return NULL_TREE;
|
||||
|
||||
|
|
@ -1857,13 +1863,32 @@ propagate_vr_accross_jump_function (cgraph_edge *cs,
|
|||
if (jfunc->type == IPA_JF_PASS_THROUGH)
|
||||
{
|
||||
struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
|
||||
if (dest_lat->bottom_p ())
|
||||
return false;
|
||||
int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
|
||||
src_lats = ipa_get_parm_lattices (caller_info, src_idx);
|
||||
|
||||
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))
|
||||
{
|
||||
value_range vr;
|
||||
memset (&vr, 0, sizeof (vr));
|
||||
tree operand_type = ipa_get_type (caller_info, src_idx);
|
||||
enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
|
||||
|
||||
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)
|
||||
return dest_lat->meet_with (&vr);
|
||||
}
|
||||
}
|
||||
else if (jfunc->type == IPA_JF_CONST)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -446,6 +446,18 @@ ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
|
|||
jfunc->value.pass_through.agg_preserved = agg_preserved;
|
||||
}
|
||||
|
||||
/* Set JFUNC to be an unary pass through jump function. */
|
||||
|
||||
static void
|
||||
ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
|
||||
enum tree_code operation)
|
||||
{
|
||||
jfunc->type = IPA_JF_PASS_THROUGH;
|
||||
jfunc->value.pass_through.operand = NULL_TREE;
|
||||
jfunc->value.pass_through.formal_id = formal_id;
|
||||
jfunc->value.pass_through.operation = operation;
|
||||
jfunc->value.pass_through.agg_preserved = false;
|
||||
}
|
||||
/* Set JFUNC to be an arithmetic pass through jump function. */
|
||||
|
||||
static void
|
||||
|
|
@ -849,21 +861,19 @@ parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
|
|||
return !modified;
|
||||
}
|
||||
|
||||
/* If STMT is an assignment that loads a value from an parameter declaration,
|
||||
return the index of the parameter in ipa_node_params which has not been
|
||||
modified. Otherwise return -1. */
|
||||
/* Main worker for load_from_unmodified_param and load_from_param.
|
||||
If STMT is an assignment that loads a value from an parameter declaration,
|
||||
return the index of the parameter in ipa_node_params. Otherwise return -1. */
|
||||
|
||||
static int
|
||||
load_from_unmodified_param (struct ipa_func_body_info *fbi,
|
||||
vec<ipa_param_descriptor> descriptors,
|
||||
gimple *stmt)
|
||||
load_from_param_1 (struct ipa_func_body_info *fbi,
|
||||
vec<ipa_param_descriptor> descriptors,
|
||||
gimple *stmt)
|
||||
{
|
||||
int index;
|
||||
tree op1;
|
||||
|
||||
if (!gimple_assign_single_p (stmt))
|
||||
return -1;
|
||||
|
||||
gcc_checking_assert (is_gimple_assign (stmt));
|
||||
op1 = gimple_assign_rhs1 (stmt);
|
||||
if (TREE_CODE (op1) != PARM_DECL)
|
||||
return -1;
|
||||
|
|
@ -876,6 +886,40 @@ load_from_unmodified_param (struct ipa_func_body_info *fbi,
|
|||
return index;
|
||||
}
|
||||
|
||||
/* If STMT is an assignment that loads a value from an parameter declaration,
|
||||
return the index of the parameter in ipa_node_params which has not been
|
||||
modified. Otherwise return -1. */
|
||||
|
||||
static int
|
||||
load_from_unmodified_param (struct ipa_func_body_info *fbi,
|
||||
vec<ipa_param_descriptor> descriptors,
|
||||
gimple *stmt)
|
||||
{
|
||||
if (!gimple_assign_single_p (stmt))
|
||||
return -1;
|
||||
|
||||
return load_from_param_1 (fbi, descriptors, stmt);
|
||||
}
|
||||
|
||||
/* If STMT is an assignment that loads a value from an parameter declaration,
|
||||
return the index of the parameter in ipa_node_params. Otherwise return -1. */
|
||||
|
||||
static int
|
||||
load_from_param (struct ipa_func_body_info *fbi,
|
||||
vec<ipa_param_descriptor> descriptors,
|
||||
gimple *stmt)
|
||||
{
|
||||
if (!is_gimple_assign (stmt))
|
||||
return -1;
|
||||
|
||||
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
|
||||
if ((get_gimple_rhs_class (rhs_code) != GIMPLE_SINGLE_RHS)
|
||||
&& (get_gimple_rhs_class (rhs_code) != GIMPLE_UNARY_RHS))
|
||||
return -1;
|
||||
|
||||
return load_from_param_1 (fbi, descriptors, stmt);
|
||||
}
|
||||
|
||||
/* Return true if memory reference REF (which must be a load through parameter
|
||||
with INDEX) loads data that are known to be unmodified in this function
|
||||
before reaching statement STMT. */
|
||||
|
|
@ -1109,6 +1153,7 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
|
|||
tree op1, tc_ssa, base, ssa;
|
||||
bool reverse;
|
||||
int index;
|
||||
gimple *stmt2 = stmt;
|
||||
|
||||
op1 = gimple_assign_rhs1 (stmt);
|
||||
|
||||
|
|
@ -1117,13 +1162,16 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
|
|||
if (SSA_NAME_IS_DEFAULT_DEF (op1))
|
||||
index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
|
||||
else
|
||||
index = load_from_unmodified_param (fbi, info->descriptors,
|
||||
SSA_NAME_DEF_STMT (op1));
|
||||
{
|
||||
index = load_from_param (fbi, info->descriptors,
|
||||
SSA_NAME_DEF_STMT (op1));
|
||||
stmt2 = SSA_NAME_DEF_STMT (op1);
|
||||
}
|
||||
tc_ssa = op1;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = load_from_unmodified_param (fbi, info->descriptors, stmt);
|
||||
index = load_from_param (fbi, info->descriptors, stmt);
|
||||
tc_ssa = gimple_assign_lhs (stmt);
|
||||
}
|
||||
|
||||
|
|
@ -1147,6 +1195,11 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
|
|||
bool agg_p = parm_ref_data_pass_through_p (fbi, index, call, tc_ssa);
|
||||
ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
|
||||
}
|
||||
else if (is_gimple_assign (stmt2)
|
||||
&& (gimple_expr_code (stmt2) != NOP_EXPR)
|
||||
&& (TREE_CODE_CLASS (gimple_expr_code (stmt2)) == tcc_unary))
|
||||
ipa_set_jf_unary_pass_through (jfunc, index,
|
||||
gimple_assign_rhs_code (stmt2));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2518,6 +2571,12 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
|
|||
dst->value.ancestor.agg_preserved &=
|
||||
src->value.pass_through.agg_preserved;
|
||||
}
|
||||
else if (src->type == IPA_JF_PASS_THROUGH
|
||||
&& TREE_CODE_CLASS (src->value.pass_through.operation) == tcc_unary)
|
||||
{
|
||||
dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
|
||||
dst->value.ancestor.agg_preserved = false;
|
||||
}
|
||||
else if (src->type == IPA_JF_ANCESTOR)
|
||||
{
|
||||
dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
|
||||
|
|
@ -2583,6 +2642,8 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
|
|||
&& ipa_get_jf_pass_through_agg_preserved (src);
|
||||
ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
|
||||
}
|
||||
else if (TREE_CODE_CLASS (operation) == tcc_unary)
|
||||
ipa_set_jf_unary_pass_through (dst, formal_id, operation);
|
||||
else
|
||||
{
|
||||
tree operand = ipa_get_jf_pass_through_operand (src);
|
||||
|
|
@ -4666,6 +4727,9 @@ ipa_write_jump_function (struct output_block *ob,
|
|||
bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
|
||||
streamer_write_bitpack (&bp);
|
||||
}
|
||||
else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
|
||||
== tcc_unary)
|
||||
streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
|
||||
else
|
||||
{
|
||||
stream_write_tree (ob, jump_func->value.pass_through.operand, true);
|
||||
|
|
@ -4745,6 +4809,11 @@ ipa_read_jump_function (struct lto_input_block *ib,
|
|||
bool agg_preserved = bp_unpack_value (&bp, 1);
|
||||
ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
|
||||
}
|
||||
else if (TREE_CODE_CLASS (operation) == tcc_unary)
|
||||
{
|
||||
int formal_id = streamer_read_uhwi (ib);
|
||||
ipa_set_jf_unary_pass_through (jump_func, formal_id, operation);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree operand = stream_read_tree (ib, data_in);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
2016-11-13 Kugan Vivekanandarajah <kuganv@linaro.org>
|
||||
|
||||
* g++.dg/torture/pr78268.C: New test.
|
||||
|
||||
2016-11-13 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
|
||||
|
||||
PR c/35503
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
// { dg-do compile }
|
||||
typedef enum {} nsresult;
|
||||
|
||||
struct A {
|
||||
virtual nsresult m_fn1(bool);
|
||||
};
|
||||
|
||||
struct B {
|
||||
A *operator[](int);
|
||||
};
|
||||
|
||||
struct C {
|
||||
nsresult m_fn2(bool);
|
||||
bool m_fn3(bool);
|
||||
B mDataSources;
|
||||
};
|
||||
nsresult C::m_fn2(bool p1)
|
||||
{
|
||||
m_fn3(!p1);
|
||||
}
|
||||
|
||||
bool C::m_fn3(bool p1)
|
||||
{
|
||||
mDataSources[0]->m_fn1(p1);
|
||||
}
|
||||
Loading…
Reference in New Issue