* [PATCH] Make non-store CCP stronger
@ 2008-03-15 20:34 Richard Guenther
0 siblings, 0 replies; only message in thread
From: Richard Guenther @ 2008-03-15 20:34 UTC (permalink / raw)
To: gcc-patches
I wondered why early CCP does not recognize
static const int x;
int foo(void)
{
return "hello"[x];
}
but in fact it does notice that "hello"[x] is likely constant.
It just fails to try folding constant aggregate refs in ccp_fold
which then returns not NULL as advertised, but the original tree.
So we do not fall back to the !simplified case, but simply fail.
Duh. This part of evaluate_stmt was "interesting" everytime
I looked at it, so I just simplified it and moved the foldings
that should be done for likely constant values into ccp_fold
itself. Of course it had some shortcomings which were thus
fixed.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
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.
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c 2008-03-15 16:46:24.000000000 +0100
***************
*** 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" } } */
Index: trunk/gcc/tree-ssa-ccp.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ccp.c 2008-03-15 15:35:15.000000000 +0100
--- trunk/gcc/tree-ssa-ccp.c 2008-03-15 16:39:52.000000000 +0100
*************** ccp_fold (tree stmt)
*** 984,989 ****
--- 984,995 ----
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
*************** fold_const_aggregate_ref (tree t)
*** 1062,1067 ****
--- 1068,1078 ----
ctor = fold_const_aggregate_ref (base);
break;
+ case STRING_CST:
+ case CONSTRUCTOR:
+ ctor = base;
+ break;
+
default:
return NULL_TREE;
}
*************** fold_const_aggregate_ref (tree t)
*** 1162,1168 ****
return fold_build1 (TREE_CODE (t), TREE_TYPE (t), c);
break;
}
!
default:
break;
}
--- 1173,1190 ----
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;
}
*************** evaluate_stmt (tree stmt)
*** 1190,1204 ****
simplified = ccp_fold (stmt);
/* If the statement is likely to have a VARYING result, then do not
bother folding the statement. */
! 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);
--- 1212,1219 ----
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)
simplified = get_rhs (stmt);
is_constant = simplified && is_gimple_min_invariant (simplified);
*************** visit_assignment (tree stmt, tree *outpu
*** 1265,1271 ****
}
else
/* Evaluate the statement. */
! 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.
--- 1280,1286 ----
}
else
/* Evaluate the statement. */
! 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.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-03-15 18:20 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-15 20:34 [PATCH] Make non-store CCP stronger Richard Guenther
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).