Commit d6e8a41c by Kugan Vivekanandarajah Committed by Kugan Vivekanandarajah

Handle unary pass-through jump functions for ipa-vrp

Handle unary pass-through jump functions for ipa-vrp
gcc/testsuite/ChangeLog:

2016-11-09  Kugan Vivekanandarajah  <kuganv@linaro.org>

	* gcc.dg/ipa/vrp7.c: New test.


gcc/ChangeLog:

2016-11-09  Kugan Vivekanandarajah  <kuganv@linaro.org>

	* ipa-cp.c (ipa_get_jf_pass_through_result): Handle unary expressions.
	(propagate_vr_accross_jump_function): Likewise.
	* 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.
	(ipa_write_jump_function): Likewise.
	(ipa_read_jump_function): Likewise.

From-SVN: r241990
parent 5d5f1e95
2016-11-09 Kugan Vivekanandarajah <kuganv@linaro.org> 2016-11-09 Kugan Vivekanandarajah <kuganv@linaro.org>
* ipa-cp.c (ipa_get_jf_pass_through_result): Handle unary expressions.
(propagate_vr_accross_jump_function): Likewise.
* 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.
(ipa_write_jump_function): Likewise.
(ipa_read_jump_function): Likewise.
2016-11-09 Kugan Vivekanandarajah <kuganv@linaro.org>
PR ipa/78121 PR ipa/78121
* ipa-cp.c (propagate_vr_accross_jump_function): Pass param type. * ipa-cp.c (propagate_vr_accross_jump_function): Pass param type.
Also fold constant passed as argument while computing value range. Also fold constant passed as argument while computing value range.
...@@ -1219,13 +1219,19 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input) ...@@ -1219,13 +1219,19 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
return NULL_TREE; return NULL_TREE;
if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
== tcc_comparison) == tcc_unary)
restype = boolean_type_node; res = fold_unary (ipa_get_jf_pass_through_operation (jfunc),
TREE_TYPE (input), input);
else else
restype = TREE_TYPE (input); {
res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype, if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
input, ipa_get_jf_pass_through_operand (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)) if (res && !is_gimple_ip_invariant (res))
return NULL_TREE; return NULL_TREE;
...@@ -1864,6 +1870,25 @@ propagate_vr_accross_jump_function (cgraph_edge *cs, ...@@ -1864,6 +1870,25 @@ propagate_vr_accross_jump_function (cgraph_edge *cs,
if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
return dest_lat->meet_with (src_lats->m_value_range); 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 false;
extract_range_from_unary_expr (&vr,
operation,
param_type,
&src_lats->m_value_range.m_vr,
operand_type);
return dest_lat->meet_with (&vr);
}
} }
else if (jfunc->type == IPA_JF_CONST) 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, ...@@ -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; 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. */ /* Set JFUNC to be an arithmetic pass through jump function. */
static void static void
...@@ -849,21 +861,19 @@ parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index, ...@@ -849,21 +861,19 @@ parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
return !modified; return !modified;
} }
/* If STMT is an assignment that loads a value from an parameter declaration, /* Main worker for load_from_unmodified_param and load_from_param.
return the index of the parameter in ipa_node_params which has not been If STMT is an assignment that loads a value from an parameter declaration,
modified. Otherwise return -1. */ return the index of the parameter in ipa_node_params. Otherwise return -1. */
static int static int
load_from_unmodified_param (struct ipa_func_body_info *fbi, load_from_param_1 (struct ipa_func_body_info *fbi,
vec<ipa_param_descriptor> descriptors, vec<ipa_param_descriptor> descriptors,
gimple *stmt) gimple *stmt)
{ {
int index; int index;
tree op1; tree op1;
if (!gimple_assign_single_p (stmt)) gcc_checking_assert (is_gimple_assign (stmt));
return -1;
op1 = gimple_assign_rhs1 (stmt); op1 = gimple_assign_rhs1 (stmt);
if (TREE_CODE (op1) != PARM_DECL) if (TREE_CODE (op1) != PARM_DECL)
return -1; return -1;
...@@ -876,6 +886,40 @@ load_from_unmodified_param (struct ipa_func_body_info *fbi, ...@@ -876,6 +886,40 @@ load_from_unmodified_param (struct ipa_func_body_info *fbi,
return index; 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 /* 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 with INDEX) loads data that are known to be unmodified in this function
before reaching statement STMT. */ before reaching statement STMT. */
...@@ -1109,6 +1153,7 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi, ...@@ -1109,6 +1153,7 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
tree op1, tc_ssa, base, ssa; tree op1, tc_ssa, base, ssa;
bool reverse; bool reverse;
int index; int index;
gimple *stmt2 = stmt;
op1 = gimple_assign_rhs1 (stmt); op1 = gimple_assign_rhs1 (stmt);
...@@ -1117,13 +1162,16 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi, ...@@ -1117,13 +1162,16 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
if (SSA_NAME_IS_DEFAULT_DEF (op1)) if (SSA_NAME_IS_DEFAULT_DEF (op1))
index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1)); index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
else 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; tc_ssa = op1;
} }
else else
{ {
index = load_from_unmodified_param (fbi, info->descriptors, stmt); index = load_from_param (fbi, info->descriptors, stmt);
tc_ssa = gimple_assign_lhs (stmt); tc_ssa = gimple_assign_lhs (stmt);
} }
...@@ -1147,6 +1195,13 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi, ...@@ -1147,6 +1195,13 @@ 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); bool agg_p = parm_ref_data_pass_through_p (fbi, index, call, tc_ssa);
ipa_set_jf_simple_pass_through (jfunc, index, agg_p); 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; return;
} }
...@@ -4666,6 +4721,11 @@ ipa_write_jump_function (struct output_block *ob, ...@@ -4666,6 +4721,11 @@ ipa_write_jump_function (struct output_block *ob,
bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1); bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
streamer_write_bitpack (&bp); 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 else
{ {
stream_write_tree (ob, jump_func->value.pass_through.operand, true); stream_write_tree (ob, jump_func->value.pass_through.operand, true);
...@@ -4745,6 +4805,11 @@ ipa_read_jump_function (struct lto_input_block *ib, ...@@ -4745,6 +4805,11 @@ ipa_read_jump_function (struct lto_input_block *ib,
bool agg_preserved = bp_unpack_value (&bp, 1); bool agg_preserved = bp_unpack_value (&bp, 1);
ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved); 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 else
{ {
tree operand = stream_read_tree (ib, data_in); tree operand = stream_read_tree (ib, data_in);
......
2016-11-09 Kugan Vivekanandarajah <kuganv@linaro.org> 2016-11-09 Kugan Vivekanandarajah <kuganv@linaro.org>
* gcc.dg/ipa/vrp7.c: New test.
2016-11-09 Kugan Vivekanandarajah <kuganv@linaro.org>
PR ipa/78121 PR ipa/78121
* gcc.dg/ipa/pr78121.c: New test. * gcc.dg/ipa/pr78121.c: New test.
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-ipa-cp-details" } */
volatile int cond;
int abs (int);
static __attribute__((noinline, noclone))
int foo (int i)
{
if (i < 5)
__builtin_abort ();
return 0;
}
static __attribute__((noinline, noclone))
int bar (int j)
{
foo (~j);
foo (abs (j));
foo (j);
return 0;
}
int main ()
{
for (unsigned int i = 0; i < 10; ++i)
bar (i);
return 0;
}
/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\\[-10, 9\\\]" 1 "cp" } } */
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