#include "bitmap.h"
#include "langhooks.h"
#include "cfgloop.h"
+#include "tree-ssa-propagate.h"
#include "tree-ssa-sccvn.h"
/* This algorithm is based on the SCC algorithm presented by Keith
case INTEGER_CST:
case COMPLEX_CST:
case VECTOR_CST:
+ case REAL_CST:
case VALUE_HANDLE:
case VAR_DECL:
case PARM_DECL:
static inline bool
set_ssa_val_to (tree from, tree to)
{
+ tree currval;
gcc_assert (to != NULL);
- /* Make sure we don't create chains of copies, so that we get the
- best value numbering. visit_copy has code to make sure this doesn't
- happen, we are doing this here to assert that nothing else breaks
- this. */
- gcc_assert (TREE_CODE (to) != SSA_NAME
- || TREE_CODE (SSA_VAL (to)) != SSA_NAME
- || SSA_VAL (to) == to
- || to == from);
/* The only thing we allow as value numbers are ssa_names and
invariants. So assert that here. */
gcc_assert (TREE_CODE (to) == SSA_NAME || is_gimple_min_invariant (to));
fprintf (dump_file, "\n");
}
- if (SSA_VAL (from) != to)
+ currval = SSA_VAL (from);
+
+ if (currval != to && !operand_equal_p (currval, to, OEP_PURE_SAME))
{
SSA_VAL (from) = to;
return true;
/* Constants inside reference ops are rarely interesting, but
it can take a lot of looking to find them. */
case tcc_reference:
+ case tcc_declaration:
return false;
default:
return is_gimple_min_invariant (expr);
else if (SSA_VAL (op1) != VN_TOP && SSA_VAL (op1) != op1)
op1 = VN_INFO (op1)->valnum;
}
+
result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);
- /* Make sure result is not a complex expression consiting
+ /* Make sure result is not a complex expression consisting
of operators of operators (IE (a + b) + (a + c))
Otherwise, we will end up with unbounded expressions if
fold does anything at all. */
- if (result)
- {
- if (is_gimple_min_invariant (result))
- return result;
- else if (SSA_VAR_P (result))
- return result;
- else if (EXPR_P (result))
- {
- switch (TREE_CODE_CLASS (TREE_CODE (result)))
- {
- case tcc_unary:
- {
- tree op0 = TREE_OPERAND (result, 0);
- if (!EXPR_P (op0))
- return result;
- }
- break;
- case tcc_binary:
- {
- tree op0 = TREE_OPERAND (result, 0);
- tree op1 = TREE_OPERAND (result, 1);
- if (!EXPR_P (op0) && !EXPR_P (op1))
- return result;
- }
- break;
- default:
- break;
- }
- }
- }
+ if (result && valid_gimple_expression_p (result))
+ return result;
+
return NULL_TREE;
}
{
/* For references, see if we find a result for the lookup,
and use it if we do. */
-
+ case tcc_declaration:
+ /* Pull out any truly constant values. */
+ if (TREE_READONLY (rhs)
+ && TREE_STATIC (rhs)
+ && DECL_INITIAL (rhs)
+ && is_gimple_min_invariant (DECL_INITIAL (rhs)))
+ return DECL_INITIAL (rhs);
+
+ /* Fallthrough. */
case tcc_reference:
{
tree result = vn_reference_lookup (rhs,
STRIP_USELESS_TYPE_CONVERSION (rhs);
+ /* Shortcut for copies. Simplifying copies is pointless,
+ since we copy the expression and value they represent. */
+ if (TREE_CODE (rhs) == SSA_NAME && TREE_CODE (lhs) == SSA_NAME)
+ {
+ changed = visit_copy (lhs, rhs);
+ goto done;
+ }
simplified = try_to_simplify (stmt, rhs);
if (simplified && simplified != rhs)
{
if (TREE_CODE (lhs) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
changed = defs_to_varying (stmt);
- else if (REFERENCE_CLASS_P (lhs))
+ else if (REFERENCE_CLASS_P (lhs) || DECL_P (lhs))
{
changed = visit_reference_op_store (lhs, rhs, stmt);
}
VN_INFO (lhs)->expr = rhs;
changed = set_ssa_val_to (lhs, rhs);
}
- else if (TREE_CODE (rhs) == SSA_NAME)
- changed = visit_copy (lhs, rhs);
else
{
switch (TREE_CODE_CLASS (TREE_CODE (rhs)))