aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-04-21 12:52:43 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-04-21 12:52:43 +0000
commit0ff093d85530159d74f77edc0da5d8bd176fe953 (patch)
tree2360651c91e90b4d553f511d0ad13639ea0d08ca /gcc/tree-ssa-ccp.c
parent9588d24871d34967389a1396e3df16c61eacd54c (diff)
downloadgcc-0ff093d85530159d74f77edc0da5d8bd176fe953.zip
gcc-0ff093d85530159d74f77edc0da5d8bd176fe953.tar.gz
gcc-0ff093d85530159d74f77edc0da5d8bd176fe953.tar.bz2
re PR tree-optimization/65650 (CCP does not propgate copies)
2015-04-21 Richard Biener <rguenther@suse.de> PR tree-optimization/65650 * tree-ssa-ccp.c (valid_lattice_transition): Allow lattice transitions involving copies. (set_lattice_value): Adjust for copy lattice state. (ccp_lattice_meet): Do not merge UNDEFINED and a copy to the copy if that doesn't dominate the merge point. (bit_value_unop): Adjust what we treat as varying mask. (bit_value_binop): Likewise. (bit_value_assume_aligned): Likewise. (evaluate_stmt): When we simplified to a SSA name record a copy instead of dropping to varying. (visit_assignment): Simplify. * gimple-match.h (gimple_simplify): Add another callback. * gimple-fold.c (fold_stmt_1): Adjust caller. (gimple_fold_stmt_to_constant_1): Likewise - pass valueize for the 2nd callback. * gimple-match-head.c (gimple_simplify): Add a callback that is used to valueize the stmt operands and use it that way. * gcc.dg/tree-ssa/ssa-ccp-37.c: New testcase. * gcc.dg/tree-ssa/forwprop-11.c: Adjust. * gcc.dg/tree-ssa/ssa-fre-3.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-4.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-5.c: Likewise. * gcc.dg/tree-ssa/ssa-fre-32.c: Likewise. From-SVN: r222267
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r--gcc/tree-ssa-ccp.c77
1 files changed, 49 insertions, 28 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 47fbf7f..1d7cafe 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -439,6 +439,17 @@ valid_lattice_transition (ccp_prop_value_t old_val, ccp_prop_value_t new_val)
/* Now both lattice values are CONSTANT. */
+ /* Allow arbitrary copy changes as we might look through PHI <a_1, ...>
+ when only a single copy edge is executable. */
+ if (TREE_CODE (old_val.value) == SSA_NAME
+ && TREE_CODE (new_val.value) == SSA_NAME)
+ return true;
+
+ /* Allow transitioning from a constant to a copy. */
+ if (is_gimple_min_invariant (old_val.value)
+ && TREE_CODE (new_val.value) == SSA_NAME)
+ return true;
+
/* Allow transitioning from PHI <&x, not executable> == &x
to PHI <&x, &y> == common alignment. */
if (TREE_CODE (old_val.value) != INTEGER_CST
@@ -527,9 +538,10 @@ set_lattice_value (tree var, ccp_prop_value_t new_val)
caller that this was a non-transition. */
if (old_val->lattice_val != new_val.lattice_val
|| (new_val.lattice_val == CONSTANT
- && TREE_CODE (new_val.value) == INTEGER_CST
- && (TREE_CODE (old_val->value) != INTEGER_CST
- || new_val.mask != old_val->mask)))
+ && (TREE_CODE (new_val.value) != TREE_CODE (old_val->value)
+ || simple_cst_equal (new_val.value, old_val->value) != 1
+ || (TREE_CODE (new_val.value) == INTEGER_CST
+ && new_val.mask != old_val->mask))))
{
/* ??? We would like to delay creation of INTEGER_CSTs from
partially constants here. */
@@ -965,14 +977,23 @@ ccp_finalize (void)
*/
static void
-ccp_lattice_meet (ccp_prop_value_t *val1, ccp_prop_value_t *val2)
+ccp_lattice_meet (basic_block where,
+ ccp_prop_value_t *val1, ccp_prop_value_t *val2)
{
- if (val1->lattice_val == UNDEFINED)
+ if (val1->lattice_val == UNDEFINED
+ /* For UNDEFINED M SSA we can't always SSA because its definition
+ may not dominate the PHI node. Doing optimistic copy propagation
+ also causes a lot of gcc.dg/uninit-pred*.c FAILs. */
+ && (val2->lattice_val != CONSTANT
+ || TREE_CODE (val2->value) != SSA_NAME))
{
/* UNDEFINED M any = any */
*val1 = *val2;
}
- else if (val2->lattice_val == UNDEFINED)
+ else if (val2->lattice_val == UNDEFINED
+ /* See above. */
+ && (val1->lattice_val != CONSTANT
+ || TREE_CODE (val1->value) != SSA_NAME))
{
/* any M UNDEFINED = any
Nothing to do. VAL1 already contains the value we want. */
@@ -1026,7 +1047,7 @@ ccp_lattice_meet (ccp_prop_value_t *val1, ccp_prop_value_t *val2)
*val1 = get_value_for_expr (val1->value, true);
if (TREE_CODE (val2->value) == ADDR_EXPR)
tem = get_value_for_expr (val2->value, true);
- ccp_lattice_meet (val1, &tem);
+ ccp_lattice_meet (where, val1, &tem);
}
else
{
@@ -1095,7 +1116,7 @@ ccp_visit_phi_node (gphi *phi)
tree arg = gimple_phi_arg (phi, i)->def;
ccp_prop_value_t arg_val = get_value_for_expr (arg, false);
- ccp_lattice_meet (&new_val, &arg_val);
+ ccp_lattice_meet (gimple_bb (phi), &new_val, &arg_val);
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -1929,9 +1950,21 @@ evaluate_stmt (gimple stmt)
/* The statement produced a nonconstant value. */
if (!is_constant)
{
- val.lattice_val = VARYING;
- val.mask = -1;
- val.value = NULL_TREE;
+ /* The statement produced a copy. */
+ if (simplified && TREE_CODE (simplified) == SSA_NAME
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (simplified))
+ {
+ val.lattice_val = CONSTANT;
+ val.value = simplified;
+ val.mask = -1;
+ }
+ /* The statement is VARYING. */
+ else
+ {
+ val.lattice_val = VARYING;
+ val.value = NULL_TREE;
+ val.mask = -1;
+ }
}
return val;
@@ -2243,27 +2276,15 @@ static enum ssa_prop_result
visit_assignment (gimple stmt, tree *output_p)
{
ccp_prop_value_t val;
- enum ssa_prop_result retval;
+ enum ssa_prop_result retval = SSA_PROP_NOT_INTERESTING;
tree lhs = gimple_get_lhs (stmt);
-
- gcc_assert (gimple_code (stmt) != GIMPLE_CALL
- || gimple_call_lhs (stmt) != NULL_TREE);
-
- if (gimple_assign_single_p (stmt)
- && gimple_assign_rhs_code (stmt) == SSA_NAME)
- /* For a simple copy operation, we copy the lattice values. */
- val = *get_value (gimple_assign_rhs1 (stmt));
- else
- /* Evaluate the statement, which could be
- either a GIMPLE_ASSIGN or a GIMPLE_CALL. */
- val = evaluate_stmt (stmt);
-
- retval = SSA_PROP_NOT_INTERESTING;
-
- /* Set the lattice value of the statement's output. */
if (TREE_CODE (lhs) == SSA_NAME)
{
+ /* Evaluate the statement, which could be
+ either a GIMPLE_ASSIGN or a GIMPLE_CALL. */
+ val = evaluate_stmt (stmt);
+
/* If STMT is an assignment to an SSA_NAME, we only have one
value to set. */
if (set_lattice_value (lhs, val))