aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-03-28 12:52:13 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-03-28 12:52:13 +0000
commite8114fbacc9e1f4702e754288d39913d4c8f3f35 (patch)
tree85a9bc8a34934b447056abbe2c2ba3dddef031c3 /gcc
parentd3d3011f933aaeb59829db58cc44d19e47e32e22 (diff)
downloadgcc-e8114fbacc9e1f4702e754288d39913d4c8f3f35.zip
gcc-e8114fbacc9e1f4702e754288d39913d4c8f3f35.tar.gz
gcc-e8114fbacc9e1f4702e754288d39913d4c8f3f35.tar.bz2
re PR tree-optimization/38180 (CCP does not propagate through constant initializers)
2009-03-28 Richard Guenther <rguenther@suse.de> PR tree-optimization/38180 * tree-ssa-ccp.c (get_default_value): Simplify. (likely_value): Likewise. (surely_varying_stmt_p): Properly handle VOP case. (ccp_initialize): Likewise. (ccp_fold): Handle propagating through *&. (fold_const_aggregate_ref): Also handle decls. * gcc.dg/tree-ssa/ssa-ccp-24.c: New testcase. From-SVN: r145184
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-24.c23
-rw-r--r--gcc/tree-ssa-ccp.c144
4 files changed, 107 insertions, 75 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f6adff6..4b746cd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2009-03-28 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/38180
+ * tree-ssa-ccp.c (get_default_value): Simplify.
+ (likely_value): Likewise.
+ (surely_varying_stmt_p): Properly handle VOP case.
+ (ccp_initialize): Likewise.
+ (ccp_fold): Handle propagating through *&.
+ (fold_const_aggregate_ref): Also handle decls.
+
2009-03-28 Jan Hubicka <jh@suse.cz>
* cgraph.c (dump_cgraph_node): Add replace output flag by process.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1cc8e4f..a2e329e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2009-03-28 Richard Guenther <rguenther@suse.de>
+ PR tree-optimization/38180
+ * gcc.dg/tree-ssa/ssa-ccp-24.c: New testcase.
+
+2009-03-28 Richard Guenther <rguenther@suse.de>
+
PR tree-optimization/38513
* gcc.dg/tree-ssa/ssa-fre-21.c: New testcase.
* gcc.dg/tree-ssa/ssa-dse-11.c: Adjust.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-24.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-24.c
new file mode 100644
index 0000000..84f69e9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-24.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ccp1" } */
+
+static const int x;
+int foo()
+{
+ const int *p = &x;
+ int y = *p;
+ return y + 1;
+}
+
+static const int x2[3] = { 1, 0, 2 };
+int bar()
+{
+ int i = 1;
+ const int *p = &x2[i];
+ int y = *p;
+ return y + 1;
+}
+
+/* { dg-final { scan-tree-dump-times "return 1;" 2 "ccp1" } } */
+/* { dg-final { cleanup-tree-dump "ccp1" } } */
+
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 5080cc3..26b6722 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -320,52 +320,45 @@ get_default_value (tree var)
{
tree sym = SSA_NAME_VAR (var);
prop_value_t val = { UNINITIALIZED, NULL_TREE };
- tree cst_val;
-
- if (!is_gimple_reg (var))
- {
- /* Short circuit for regular CCP. We are not interested in any
- non-register when DO_STORE_CCP is false. */
- val.lattice_val = VARYING;
- }
- else if ((cst_val = get_symbol_constant_value (sym)) != NULL_TREE)
+ gimple stmt;
+
+ stmt = SSA_NAME_DEF_STMT (var);
+
+ if (gimple_nop_p (stmt))
{
- /* Globals and static variables declared 'const' take their
- initial value. */
- val.lattice_val = CONSTANT;
- val.value = cst_val;
+ /* Variables defined by an empty statement are those used
+ before being initialized. If VAR is a local variable, we
+ can assume initially that it is UNDEFINED, otherwise we must
+ consider it VARYING. */
+ if (is_gimple_reg (sym) && TREE_CODE (sym) != PARM_DECL)
+ val.lattice_val = UNDEFINED;
+ else
+ val.lattice_val = VARYING;
}
- else
- {
- gimple stmt = SSA_NAME_DEF_STMT (var);
-
- if (gimple_nop_p (stmt))
+ else if (is_gimple_assign (stmt)
+ /* Value-returning GIMPLE_CALL statements assign to
+ a variable, and are treated similarly to GIMPLE_ASSIGN. */
+ || (is_gimple_call (stmt)
+ && gimple_call_lhs (stmt) != NULL_TREE)
+ || gimple_code (stmt) == GIMPLE_PHI)
+ {
+ tree cst;
+ if (gimple_assign_single_p (stmt)
+ && DECL_P (gimple_assign_rhs1 (stmt))
+ && (cst = get_symbol_constant_value (gimple_assign_rhs1 (stmt))))
{
- /* Variables defined by an empty statement are those used
- before being initialized. If VAR is a local variable, we
- can assume initially that it is UNDEFINED, otherwise we must
- consider it VARYING. */
- if (is_gimple_reg (sym) && TREE_CODE (sym) != PARM_DECL)
- val.lattice_val = UNDEFINED;
- else
- val.lattice_val = VARYING;
- }
- else if (is_gimple_assign (stmt)
- /* Value-returning GIMPLE_CALL statements assign to
- a variable, and are treated similarly to GIMPLE_ASSIGN. */
- || (is_gimple_call (stmt)
- && gimple_call_lhs (stmt) != NULL_TREE)
- || gimple_code (stmt) == GIMPLE_PHI)
- {
- /* Any other variable defined by an assignment or a PHI node
- is considered UNDEFINED. */
- val.lattice_val = UNDEFINED;
+ val.lattice_val = CONSTANT;
+ val.value = cst;
}
else
- {
- /* Otherwise, VAR will never take on a constant value. */
- val.lattice_val = VARYING;
- }
+ /* Any other variable defined by an assignment or a PHI node
+ is considered UNDEFINED. */
+ val.lattice_val = UNDEFINED;
+ }
+ else
+ {
+ /* Otherwise, VAR will never take on a constant value. */
+ val.lattice_val = VARYING;
}
return val;
@@ -501,6 +494,7 @@ likely_value (gimple stmt)
bool has_constant_operand, has_undefined_operand, all_undefined_operands;
tree use;
ssa_op_iter iter;
+ unsigned i;
enum gimple_code code = gimple_code (stmt);
@@ -516,33 +510,11 @@ likely_value (gimple stmt)
if (gimple_has_volatile_ops (stmt))
return VARYING;
- /* If we are not doing store-ccp, statements with loads
- and/or stores will never fold into a constant. */
- if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
- return VARYING;
-
- /* Note that only a GIMPLE_SINGLE_RHS assignment can satisfy
- is_gimple_min_invariant, so we do not consider calls or
- other forms of assignment. */
- if (gimple_assign_single_p (stmt)
- && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
- return CONSTANT;
-
- if (code == GIMPLE_COND
- && is_gimple_min_invariant (gimple_cond_lhs (stmt))
- && is_gimple_min_invariant (gimple_cond_rhs (stmt)))
- return CONSTANT;
-
- if (code == GIMPLE_SWITCH
- && is_gimple_min_invariant (gimple_switch_index (stmt)))
- return CONSTANT;
-
/* Arrive here for more complex cases. */
-
has_constant_operand = false;
has_undefined_operand = false;
all_undefined_operands = true;
- FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
+ FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{
prop_value_t *val = get_value (use);
@@ -555,6 +527,17 @@ likely_value (gimple stmt)
has_constant_operand = true;
}
+ /* There may be constants in regular rhs operands. */
+ for (i = is_gimple_call (stmt) + gimple_has_lhs (stmt);
+ i < gimple_num_ops (stmt); ++i)
+ {
+ tree op = gimple_op (stmt, i);
+ if (!op || TREE_CODE (op) == SSA_NAME)
+ continue;
+ if (is_gimple_min_invariant (op))
+ has_constant_operand = true;
+ }
+
/* If the operation combines operands like COMPLEX_EXPR make sure to
not mark the result UNDEFINED if only one part of the result is
undefined. */
@@ -585,11 +568,11 @@ likely_value (gimple stmt)
if (has_undefined_operand)
return VARYING;
+ /* We do not consider virtual operands here -- load from read-only
+ memory may have only VARYING virtual operands, but still be
+ constant. */
if (has_constant_operand
- /* We do not consider virtual operands here -- load from read-only
- memory may have only VARYING virtual operands, but still be
- constant. */
- || ZERO_SSA_OPERANDS (stmt, SSA_OP_USE))
+ || gimple_references_memory_p (stmt))
return CONSTANT;
return VARYING;
@@ -605,9 +588,6 @@ surely_varying_stmt_p (gimple stmt)
if (gimple_has_volatile_ops (stmt))
return true;
- if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
- return true;
-
/* If it is a call and does not return a value or is not a
builtin and not an indirect call, it is varying. */
if (is_gimple_call (stmt))
@@ -619,6 +599,10 @@ surely_varying_stmt_p (gimple stmt)
return true;
}
+ /* Any other store operation is not interesting. */
+ else if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
+ return true;
+
/* Anything other than assignments and conditional jumps are not
interesting for CCP. */
if (gimple_code (stmt) != GIMPLE_ASSIGN
@@ -657,10 +641,7 @@ ccp_initialize (void)
/* If the statement will not produce a constant, mark
all its outputs VARYING. */
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
- {
- if (is_varying)
- set_value_varying (def);
- }
+ set_value_varying (def);
}
prop_set_simulate_again (stmt, !is_varying);
}
@@ -953,6 +934,16 @@ ccp_fold (gimple stmt)
return fold_unary (VIEW_CONVERT_EXPR,
TREE_TYPE (rhs), val->value);
}
+ else if (TREE_CODE (rhs) == INDIRECT_REF
+ && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+ {
+ prop_value_t *val = get_value (TREE_OPERAND (rhs, 0));
+ if (val->lattice_val == CONSTANT
+ && TREE_CODE (val->value) == ADDR_EXPR
+ && useless_type_conversion_p (TREE_TYPE (rhs),
+ TREE_TYPE (TREE_TYPE (val->value))))
+ rhs = TREE_OPERAND (val->value, 0);
+ }
return fold_const_aggregate_ref (rhs);
}
else if (kind == tcc_declaration)
@@ -1144,6 +1135,9 @@ fold_const_aggregate_ref (tree t)
unsigned HOST_WIDE_INT cnt;
tree cfield, cval;
+ if (TREE_CODE_CLASS (TREE_CODE (t)) == tcc_declaration)
+ return get_symbol_constant_value (t);
+
switch (TREE_CODE (t))
{
case ARRAY_REF: