From 0ff093d85530159d74f77edc0da5d8bd176fe953 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 21 Apr 2015 12:52:43 +0000 Subject: [PATCH] re PR tree-optimization/65650 (CCP does not propgate copies) 2015-04-21 Richard Biener 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 --- gcc/ChangeLog | 22 ++++++ gcc/gimple-fold.c | 5 +- gcc/gimple-match-head.c | 75 ++++++++++---------- gcc/gimple-match.h | 2 +- gcc/testsuite/ChangeLog | 10 +++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c | 14 ++++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c | 2 +- gcc/tree-ssa-ccp.c | 77 +++++++++++++-------- 12 files changed, 142 insertions(+), 73 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 19b0ed417e7..85c2ba33aed 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2015-04-21 Richard Biener + + 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. + 2015-04-21 Richard Biener PR tree-optimization/65788 diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index d607e8fe0ba..2cc56286084 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -3621,7 +3621,8 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree)) gimple_seq seq = NULL; code_helper rcode; tree ops[3] = {}; - if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq, valueize)) + if (gimple_simplify (stmt, &rcode, ops, inplace ? NULL : &seq, + valueize, valueize)) { if (replace_stmt_with_simplification (gsi, rcode, ops, &seq, inplace)) changed = true; @@ -4928,7 +4929,7 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree), edges if there are intermediate VARYING defs. For this reason do not follow SSA edges here even though SCCVN can technically just deal fine with that. */ - if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize) + if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize) && rcode.is_tree_code () && (TREE_CODE_LENGTH ((tree_code) rcode) == 0 || ((tree_code) rcode) == ADDR_EXPR) diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c index 0ca189dfe97..c7b2f957bac 100644 --- a/gcc/gimple-match-head.c +++ b/gcc/gimple-match-head.c @@ -601,7 +601,8 @@ gimple_simplify (enum built_in_function fn, tree type, bool gimple_simplify (gimple stmt, code_helper *rcode, tree *ops, - gimple_seq *seq, tree (*valueize)(tree)) + gimple_seq *seq, + tree (*valueize)(tree), tree (*top_valueize)(tree)) { switch (gimple_code (stmt)) { @@ -617,9 +618,9 @@ gimple_simplify (gimple stmt, || code == VIEW_CONVERT_EXPR) { tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); - if (valueize && TREE_CODE (op0) == SSA_NAME) + if (top_valueize && TREE_CODE (op0) == SSA_NAME) { - tree tem = valueize (op0); + tree tem = top_valueize (op0); if (tem) op0 = tem; } @@ -631,9 +632,9 @@ gimple_simplify (gimple stmt, { tree rhs1 = gimple_assign_rhs1 (stmt); tree op0 = TREE_OPERAND (rhs1, 0); - if (valueize && TREE_CODE (op0) == SSA_NAME) + if (top_valueize && TREE_CODE (op0) == SSA_NAME) { - tree tem = valueize (op0); + tree tem = top_valueize (op0); if (tem) op0 = tem; } @@ -644,10 +645,10 @@ gimple_simplify (gimple stmt, return gimple_resimplify3 (seq, rcode, type, ops, valueize); } else if (code == SSA_NAME - && valueize) + && top_valueize) { tree op0 = gimple_assign_rhs1 (stmt); - tree valueized = valueize (op0); + tree valueized = top_valueize (op0); if (!valueized || op0 == valueized) return false; ops[0] = valueized; @@ -658,9 +659,9 @@ gimple_simplify (gimple stmt, case GIMPLE_UNARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); - if (valueize && TREE_CODE (rhs1) == SSA_NAME) + if (top_valueize && TREE_CODE (rhs1) == SSA_NAME) { - tree tem = valueize (rhs1); + tree tem = top_valueize (rhs1); if (tem) rhs1 = tem; } @@ -671,16 +672,16 @@ gimple_simplify (gimple stmt, case GIMPLE_BINARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); - if (valueize && TREE_CODE (rhs1) == SSA_NAME) + if (top_valueize && TREE_CODE (rhs1) == SSA_NAME) { - tree tem = valueize (rhs1); + tree tem = top_valueize (rhs1); if (tem) rhs1 = tem; } tree rhs2 = gimple_assign_rhs2 (stmt); - if (valueize && TREE_CODE (rhs2) == SSA_NAME) + if (top_valueize && TREE_CODE (rhs2) == SSA_NAME) { - tree tem = valueize (rhs2); + tree tem = top_valueize (rhs2); if (tem) rhs2 = tem; } @@ -692,23 +693,23 @@ gimple_simplify (gimple stmt, case GIMPLE_TERNARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); - if (valueize && TREE_CODE (rhs1) == SSA_NAME) + if (top_valueize && TREE_CODE (rhs1) == SSA_NAME) { - tree tem = valueize (rhs1); + tree tem = top_valueize (rhs1); if (tem) rhs1 = tem; } tree rhs2 = gimple_assign_rhs2 (stmt); - if (valueize && TREE_CODE (rhs2) == SSA_NAME) + if (top_valueize && TREE_CODE (rhs2) == SSA_NAME) { - tree tem = valueize (rhs2); + tree tem = top_valueize (rhs2); if (tem) rhs2 = tem; } tree rhs3 = gimple_assign_rhs3 (stmt); - if (valueize && TREE_CODE (rhs3) == SSA_NAME) + if (top_valueize && TREE_CODE (rhs3) == SSA_NAME) { - tree tem = valueize (rhs3); + tree tem = top_valueize (rhs3); if (tem) rhs3 = tem; } @@ -732,9 +733,9 @@ gimple_simplify (gimple stmt, /* ??? Internal function support missing. */ if (!fn) return false; - if (valueize && TREE_CODE (fn) == SSA_NAME) + if (top_valueize && TREE_CODE (fn) == SSA_NAME) { - tree tem = valueize (fn); + tree tem = top_valueize (fn); if (tem) fn = tem; } @@ -754,9 +755,9 @@ gimple_simplify (gimple stmt, case 1: { tree arg1 = gimple_call_arg (stmt, 0); - if (valueize && TREE_CODE (arg1) == SSA_NAME) + if (top_valueize && TREE_CODE (arg1) == SSA_NAME) { - tree tem = valueize (arg1); + tree tem = top_valueize (arg1); if (tem) arg1 = tem; } @@ -767,16 +768,16 @@ gimple_simplify (gimple stmt, case 2: { tree arg1 = gimple_call_arg (stmt, 0); - if (valueize && TREE_CODE (arg1) == SSA_NAME) + if (top_valueize && TREE_CODE (arg1) == SSA_NAME) { - tree tem = valueize (arg1); + tree tem = top_valueize (arg1); if (tem) arg1 = tem; } tree arg2 = gimple_call_arg (stmt, 1); - if (valueize && TREE_CODE (arg2) == SSA_NAME) + if (top_valueize && TREE_CODE (arg2) == SSA_NAME) { - tree tem = valueize (arg2); + tree tem = top_valueize (arg2); if (tem) arg2 = tem; } @@ -788,23 +789,23 @@ gimple_simplify (gimple stmt, case 3: { tree arg1 = gimple_call_arg (stmt, 0); - if (valueize && TREE_CODE (arg1) == SSA_NAME) + if (top_valueize && TREE_CODE (arg1) == SSA_NAME) { - tree tem = valueize (arg1); + tree tem = top_valueize (arg1); if (tem) arg1 = tem; } tree arg2 = gimple_call_arg (stmt, 1); - if (valueize && TREE_CODE (arg2) == SSA_NAME) + if (top_valueize && TREE_CODE (arg2) == SSA_NAME) { - tree tem = valueize (arg2); + tree tem = top_valueize (arg2); if (tem) arg2 = tem; } tree arg3 = gimple_call_arg (stmt, 2); - if (valueize && TREE_CODE (arg3) == SSA_NAME) + if (top_valueize && TREE_CODE (arg3) == SSA_NAME) { - tree tem = valueize (arg3); + tree tem = top_valueize (arg3); if (tem) arg3 = tem; } @@ -823,16 +824,16 @@ gimple_simplify (gimple stmt, case GIMPLE_COND: { tree lhs = gimple_cond_lhs (stmt); - if (valueize && TREE_CODE (lhs) == SSA_NAME) + if (top_valueize && TREE_CODE (lhs) == SSA_NAME) { - tree tem = valueize (lhs); + tree tem = top_valueize (lhs); if (tem) lhs = tem; } tree rhs = gimple_cond_rhs (stmt); - if (valueize && TREE_CODE (rhs) == SSA_NAME) + if (top_valueize && TREE_CODE (rhs) == SSA_NAME) { - tree tem = valueize (rhs); + tree tem = top_valueize (rhs); if (tem) rhs = tem; } diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h index 47ee2cc4de6..f9e35175484 100644 --- a/gcc/gimple-match.h +++ b/gcc/gimple-match.h @@ -41,7 +41,7 @@ private: }; bool gimple_simplify (gimple, code_helper *, tree *, gimple_seq *, - tree (*)(tree)); + tree (*)(tree), tree (*)(tree)); tree maybe_push_res_to_seq (code_helper, tree, tree *, gimple_seq *, tree res = NULL_TREE); void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4ca31e0f2ad..5573e423ca8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2015-04-21 Richard Biener + + PR tree-optimization/65650 + * 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. + 2015-04-21 Tom de Vries PR tree-optimization/65802 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c index 08d0864af55..7252801e423 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-11.c @@ -16,5 +16,5 @@ int g(int *p, int n) return q[-1]; } -/* { dg-final { scan-tree-dump-times "= MEM\\\[\\\(int \\\*\\\)\[ap\]_.. \\\+ 4B\\\];" 2 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "= MEM\\\[\\\(int \\\*\\\)\[ap\]_\[0-9\]+(?:\\(D\\))? \\\+ 4B\\\];" 2 "forwprop1" } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c new file mode 100644 index 00000000000..518448273a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-37.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-ccp1" } */ + +int foo (int i) +{ + int j = i; + int k = 0; + int l = j + k; + int m = l - j; + return m; +} + +/* { dg-final { scan-tree-dump "return 0;" "ccp1" } } */ +/* { dg-final { cleanup-tree-dump "ccp1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c index 6813b432302..762a15059dd 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c @@ -6,7 +6,7 @@ When the condition is true, we distribute "(int) (a + b)" as "(int) a + (int) b", otherwise we keep the original. */ /* { dg-do compile { target { { ! mips64 } && { ! spu-*-* } } } } */ -/* { dg-options "-O -fno-tree-forwprop -fwrapv -fdump-tree-fre1-details" } */ +/* { dg-options "-O -fno-tree-forwprop -fno-tree-ccp -fwrapv -fdump-tree-fre1-details" } */ /* From PR14844. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c index 53a20f84c17..792b4ab686d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-32.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */ +/* { dg-options "-O -fno-tree-forwprop -fno-tree-ccp -fdump-tree-fre1-details" } */ _Complex float m; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c index 96738305bbc..74e751072a1 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c @@ -1,7 +1,7 @@ /* If the target returns false for TARGET_PROMOTE_PROTOTYPES, then there will be no casts for FRE to eliminate and the test will fail. */ /* { dg-do compile { target i?86-*-* x86_64-*-* hppa*-*-* mips*-*-* m68k*-*-* } } */ -/* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */ +/* { dg-options "-O -fno-tree-ccp -fno-tree-forwprop -fdump-tree-fre1-details" } */ /* From PR21608. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c index e6010ca0318..968e3778d69 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O -fno-tree-forwprop -fdump-tree-fre1-details" } */ +/* { dg-options "-O -fno-tree-ccp -fno-tree-forwprop -fdump-tree-fre1-details" } */ /* From PR19792. */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 47fbf7f113e..1d7cafeb807 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 + 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)) -- 2.30.2