diff options
author | Richard Biener <rguenther@suse.de> | 2015-04-21 12:52:43 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-04-21 12:52:43 +0000 |
commit | 0ff093d85530159d74f77edc0da5d8bd176fe953 (patch) | |
tree | 2360651c91e90b4d553f511d0ad13639ea0d08ca /gcc/tree-ssa-ccp.c | |
parent | 9588d24871d34967389a1396e3df16c61eacd54c (diff) | |
download | gcc-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.c | 77 |
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)) |