summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-28 16:03:09 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-28 16:03:09 +0000
commit6d0bf6d6a78b47891f0397395dc63d298a5189fb (patch)
treea39f84dc9ca118ac88aa33df39a3b8e2d319becb /gcc/tree-ssa-ccp.c
parent0f2c14c0bcd2ec771c1ef0d168727392b45721c0 (diff)
downloadgcc-6d0bf6d6a78b47891f0397395dc63d298a5189fb.tar.gz
2010-07-28 Richard Guenther <rguenther@suse.de>
* tree-ssa-ccp.c: Remove comment regarding STORE-CCP. (set_lattice_value): Do not query an old default value. (get_value_for_expr): New function. Properly canonicalize float values. (ccp_visit_phi_node): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162638 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r--gcc/tree-ssa-ccp.c115
1 files changed, 28 insertions, 87 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 27e09396860..f573b0d8ade 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -99,81 +99,6 @@ along with GCC; see the file COPYING3. If not see
array CONST_VAL[i].VALUE. That is fed into substitute_and_fold for
final substitution and folding.
-
- Constant propagation in stores and loads (STORE-CCP)
- ----------------------------------------------------
-
- While CCP has all the logic to propagate constants in GIMPLE
- registers, it is missing the ability to associate constants with
- stores and loads (i.e., pointer dereferences, structures and
- global/aliased variables). We don't keep loads and stores in
- SSA, but we do build a factored use-def web for them (in the
- virtual operands).
-
- For instance, consider the following code fragment:
-
- struct A a;
- const int B = 42;
-
- void foo (int i)
- {
- if (i > 10)
- a.a = 42;
- else
- {
- a.b = 21;
- a.a = a.b + 21;
- }
-
- if (a.a != B)
- never_executed ();
- }
-
- We should be able to deduce that the predicate 'a.a != B' is always
- false. To achieve this, we associate constant values to the SSA
- names in the VDEF operands for each store. Additionally,
- since we also glob partial loads/stores with the base symbol, we
- also keep track of the memory reference where the constant value
- was stored (in the MEM_REF field of PROP_VALUE_T). For instance,
-
- # a_5 = VDEF <a_4>
- a.a = 2;
-
- # VUSE <a_5>
- x_3 = a.b;
-
- In the example above, CCP will associate value '2' with 'a_5', but
- it would be wrong to replace the load from 'a.b' with '2', because
- '2' had been stored into a.a.
-
- Note that the initial value of virtual operands is VARYING, not
- UNDEFINED. Consider, for instance global variables:
-
- int A;
-
- foo (int i)
- {
- if (i_3 > 10)
- A_4 = 3;
- # A_5 = PHI (A_4, A_2);
-
- # VUSE <A_5>
- A.0_6 = A;
-
- return A.0_6;
- }
-
- The value of A_2 cannot be assumed to be UNDEFINED, as it may have
- been defined outside of foo. If we were to assume it UNDEFINED, we
- would erroneously optimize the above into 'return 3;'.
-
- Though STORE-CCP is not too expensive, it does have to do more work
- than regular CCP, so it is only enabled at -O2. Both regular CCP
- and STORE-CCP use the exact same algorithm. The only distinction
- is that when doing STORE-CCP, the boolean variable DO_STORE_CCP is
- set to true. This affects the evaluation of statements and PHI
- nodes.
-
References:
Constant propagation with conditional branches,
@@ -420,7 +345,8 @@ canonicalize_float_value (prop_value_t *val)
static bool
set_lattice_value (tree var, prop_value_t new_val)
{
- prop_value_t *old_val = get_value (var);
+ /* We can deal with old UNINITIALIZED values just fine here. */
+ prop_value_t *old_val = &const_val[SSA_NAME_VERSION (var)];
canonicalize_float_value (&new_val);
@@ -443,13 +369,37 @@ set_lattice_value (tree var, prop_value_t new_val)
*old_val = new_val;
- gcc_assert (new_val.lattice_val != UNDEFINED);
+ gcc_assert (new_val.lattice_val != UNINITIALIZED);
return true;
}
return false;
}
+/* Return the value for the tree operand EXPR. */
+
+static prop_value_t
+get_value_for_expr (tree expr)
+{
+ prop_value_t val;
+
+ if (TREE_CODE (expr) == SSA_NAME)
+ val = *(get_value (expr));
+ else if (is_gimple_min_invariant (expr))
+ {
+ val.lattice_val = CONSTANT;
+ val.value = expr;
+ canonicalize_float_value (&val);
+ }
+ else
+ {
+ val.lattice_val = VARYING;
+ val.value = NULL_TREE;
+ }
+
+ return val;
+}
+
/* Return the likely CCP lattice value for STMT.
@@ -797,15 +747,7 @@ ccp_visit_phi_node (gimple phi)
if (e->flags & EDGE_EXECUTABLE)
{
tree arg = gimple_phi_arg (phi, i)->def;
- prop_value_t arg_val;
-
- if (is_gimple_min_invariant (arg))
- {
- arg_val.lattice_val = CONSTANT;
- arg_val.value = arg;
- }
- else
- arg_val = *(get_value (arg));
+ prop_value_t arg_val = get_value_for_expr (arg);
ccp_lattice_meet (&new_val, &arg_val);
@@ -1137,7 +1079,6 @@ ccp_fold (gimple stmt)
}
}
-
/* Return the tree representing the element referenced by T if T is an
ARRAY_REF or COMPONENT_REF into constant aggregates. Return
NULL_TREE otherwise. */