tree-ssa-ccp.c (ccp_fold): Also read from constant values and fold constant aggregate refs.

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.

	* gcc.dg/tree-ssa/ssa-ccp-16.c: New testcase.

From-SVN: r133257
This commit is contained in:
Richard Guenther 2008-03-15 18:22:26 +00:00 committed by Richard Biener
parent 107276837f
commit 87e1e42b70
4 changed files with 60 additions and 10 deletions

View File

@ -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.

View File

@ -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

View File

@ -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" } } */

View File

@ -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.