aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2006-05-16 15:34:12 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2006-05-16 15:34:12 +0000
commitfaaf14368b72d741b4ea5bcb6b8cb172fb847c43 (patch)
treeedbdd4f49cf5e328f497b63f183f1354221dafa4 /gcc/tree-ssa-ccp.c
parent14c7833ccd0392c40505c4f707abc7ef64af7972 (diff)
downloadgcc-faaf14368b72d741b4ea5bcb6b8cb172fb847c43.zip
gcc-faaf14368b72d741b4ea5bcb6b8cb172fb847c43.tar.gz
gcc-faaf14368b72d741b4ea5bcb6b8cb172fb847c43.tar.bz2
re PR tree-optimization/22303 (CCP does not handle STRING_CSTs)
2006-05-16 Richard Guenther <rguenther@suse.de> PR tree-optimization/22303 * tree-ssa-ccp.c (fold_const_aggregate_ref): Handle reads from STRING_CSTs. (evaluate_stmt): Fall back to fold_const_aggregate_ref, if ccp_fold did not simplify the statement. * gcc.dg/tree-ssa/ssa-ccp-13.c: New testcase. From-SVN: r113826
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r--gcc/tree-ssa-ccp.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 83dce72..53050e6 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -1011,7 +1011,8 @@ fold_const_aggregate_ref (tree t)
}
if (ctor == NULL_TREE
- || TREE_CODE (ctor) != CONSTRUCTOR
+ || (TREE_CODE (ctor) != CONSTRUCTOR
+ && TREE_CODE (ctor) != STRING_CST)
|| !TREE_STATIC (ctor))
return NULL_TREE;
@@ -1036,6 +1037,20 @@ fold_const_aggregate_ref (tree t)
return NULL_TREE;
}
+ /* Fold read from constant string. */
+ if (TREE_CODE (ctor) == STRING_CST)
+ {
+ if ((TYPE_MODE (TREE_TYPE (t))
+ == TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor))))
+ && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor))))
+ == MODE_INT)
+ && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor)))) == 1
+ && compare_tree_int (idx, TREE_STRING_LENGTH (ctor)) < 0)
+ return build_int_cst (TREE_TYPE (t), (TREE_STRING_POINTER (ctor)
+ [TREE_INT_CST_LOW (idx)]));
+ return NULL_TREE;
+ }
+
/* Whoo-hoo! I'll fold ya baby. Yeah! */
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
if (tree_int_cst_equal (cfield, idx))
@@ -1104,7 +1119,7 @@ static prop_value_t
evaluate_stmt (tree stmt)
{
prop_value_t val;
- tree simplified;
+ tree simplified = NULL_TREE;
ccp_lattice_t likelyvalue = likely_value (stmt);
val.mem_ref = NULL_TREE;
@@ -1115,14 +1130,14 @@ 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. */
- else if (likelyvalue == VARYING)
+ 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
+ else if (!simplified)
simplified = fold_const_aggregate_ref (get_rhs (stmt));
if (simplified && is_gimple_min_invariant (simplified))