diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c | 22 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 35 |
4 files changed, 60 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c10c75..c3f2d7d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2008-03-15 Richard Guenther <rguenther@suse.de> + + * tree-ssa-ccp.c (ccp_fold): Also read from constant values + and fold constant aggregate refs. + (fold_const_aggregate_ref): Handle string constants + and constructors in ARRAY_REFs. Handle INDIRECT_REF. + (evaluate_stmt): Simplify now that ccp_fold folds constant + aggregate refs. + 2008-03-15 Paul Brook <paul@codesourcery.com> * config/arm/arm.md (insv): Use gen_insv_t2 and gen_insv_zero. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ec3196b..da901b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-03-15 Richard Guenther <rguenther@suse.de> + + * gcc.dg/tree-ssa/ssa-ccp-16.c: New testcase. + 2008-03-15 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR testsuite/35184 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c new file mode 100644 index 0000000..33f9744 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-ccp1" } */ + +static const int x; + +int test1 (void) +{ + char *p = "hello"; + int i = x; + i = i + 5; + return p[i]; +} + +int test2 (void) +{ + int i = x; + i = i + 5; + return "hello"[i]; +} + +/* { dg-final { scan-tree-dump-times "return 0;" 2 "ccp1" } } */ +/* { dg-final { cleanup-tree-dump "ccp1" } } */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index a1eaab2..f087a8d 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -984,6 +984,12 @@ ccp_fold (tree stmt) return fold_binary (code, TREE_TYPE (rhs), op0, op1); } + else if (kind == tcc_declaration) + return get_symbol_constant_value (rhs); + + else if (kind == tcc_reference) + return fold_const_aggregate_ref (rhs); + /* We may be able to fold away calls to builtin functions if their arguments are constants. */ else if (code == CALL_EXPR @@ -1062,6 +1068,11 @@ fold_const_aggregate_ref (tree t) ctor = fold_const_aggregate_ref (base); break; + case STRING_CST: + case CONSTRUCTOR: + ctor = base; + break; + default: return NULL_TREE; } @@ -1162,7 +1173,18 @@ fold_const_aggregate_ref (tree t) return fold_build1 (TREE_CODE (t), TREE_TYPE (t), c); break; } - + + case INDIRECT_REF: + { + tree base = TREE_OPERAND (t, 0); + if (TREE_CODE (base) == SSA_NAME + && (value = get_value (base)) + && value->lattice_val == CONSTANT + && TREE_CODE (value->value) == ADDR_EXPR) + return fold_const_aggregate_ref (TREE_OPERAND (value->value, 0)); + break; + } + default: break; } @@ -1190,15 +1212,8 @@ evaluate_stmt (tree stmt) simplified = ccp_fold (stmt); /* If the statement is likely to have a VARYING result, then do not bother folding the statement. */ - if (likelyvalue == VARYING) + else if (likelyvalue == VARYING) simplified = get_rhs (stmt); - /* If the statement is an ARRAY_REF or COMPONENT_REF into constant - aggregates, extract the referenced constant. Otherwise the - statement is likely to have an UNDEFINED value, and there will be - nothing to do. Note that fold_const_aggregate_ref returns - NULL_TREE if the first case does not match. */ - else if (!simplified) - simplified = fold_const_aggregate_ref (get_rhs (stmt)); is_constant = simplified && is_gimple_min_invariant (simplified); @@ -1265,7 +1280,7 @@ visit_assignment (tree stmt, tree *output_p) } else /* Evaluate the statement. */ - val = evaluate_stmt (stmt); + val = evaluate_stmt (stmt); /* If the original LHS was a VIEW_CONVERT_EXPR, modify the constant value to be a VIEW_CONVERT_EXPR of the old constant value. |