summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-niter.c
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-23 21:33:15 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-23 21:33:15 +0000
commit1962cebaa32153a93d9eb93d120caa1b789d09d4 (patch)
tree0ff6a29f85740fedc59f8fc702e20fae58f30e68 /gcc/tree-ssa-loop-niter.c
parentc4d3b42853583ec88202ae5fd9470203b6a276b2 (diff)
downloadgcc-1962cebaa32153a93d9eb93d120caa1b789d09d4.tar.gz
* tree-ssa-loop-niter.c (tree_simplify_using_condition): Expand simple
definitions of ssa names in condition. Split recusive part to ... (tree_simplify_using_condition_1): New function. (expand_simple_operations): New function. * gcc.dg/vect/vect-99.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98635 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-loop-niter.c')
-rw-r--r--gcc/tree-ssa-loop-niter.c91
1 files changed, 81 insertions, 10 deletions
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index b1af67f0011..ab9de0b07f2 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -624,14 +624,70 @@ simplify_replace_tree (tree expr, tree old, tree new)
return (ret ? fold (ret) : expr);
}
+/* Expand definitions of ssa names in EXPR as long as they are simple
+ enough, and return the new expression. */
+
+static tree
+expand_simple_operations (tree expr)
+{
+ unsigned i, n;
+ tree ret = NULL_TREE, e, ee, stmt;
+ enum tree_code code = TREE_CODE (expr);
+
+ if (is_gimple_min_invariant (expr))
+ return expr;
+
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
+ {
+ n = TREE_CODE_LENGTH (code);
+ for (i = 0; i < n; i++)
+ {
+ e = TREE_OPERAND (expr, i);
+ ee = expand_simple_operations (e);
+ if (e == ee)
+ continue;
+
+ if (!ret)
+ ret = copy_node (expr);
+
+ TREE_OPERAND (ret, i) = ee;
+ }
+
+ return (ret ? fold (ret) : expr);
+ }
+
+ if (TREE_CODE (expr) != SSA_NAME)
+ return expr;
+
+ stmt = SSA_NAME_DEF_STMT (expr);
+ if (TREE_CODE (stmt) != MODIFY_EXPR)
+ return expr;
+
+ e = TREE_OPERAND (stmt, 1);
+ if (/* Casts are simple. */
+ TREE_CODE (e) != NOP_EXPR
+ && TREE_CODE (e) != CONVERT_EXPR
+ /* Copies are simple. */
+ && TREE_CODE (e) != SSA_NAME
+ /* Assignments of invariants are simple. */
+ && !is_gimple_min_invariant (e)
+ /* And increments and decrements by a constant are simple. */
+ && !((TREE_CODE (e) == PLUS_EXPR
+ || TREE_CODE (e) == MINUS_EXPR)
+ && is_gimple_min_invariant (TREE_OPERAND (e, 1))))
+ return expr;
+
+ return expand_simple_operations (e);
+}
+
/* Tries to simplify EXPR using the condition COND. Returns the simplified
- expression (or EXPR unchanged, if no simplification was possible).*/
+ expression (or EXPR unchanged, if no simplification was possible). */
static tree
-tree_simplify_using_condition (tree cond, tree expr)
+tree_simplify_using_condition_1 (tree cond, tree expr)
{
bool changed;
- tree e, e0, e1, e2, notcond;
+ tree e, te, e0, e1, e2, notcond;
enum tree_code code = TREE_CODE (expr);
if (code == INTEGER_CST)
@@ -643,17 +699,17 @@ tree_simplify_using_condition (tree cond, tree expr)
{
changed = false;
- e0 = tree_simplify_using_condition (cond, TREE_OPERAND (expr, 0));
+ e0 = tree_simplify_using_condition_1 (cond, TREE_OPERAND (expr, 0));
if (TREE_OPERAND (expr, 0) != e0)
changed = true;
- e1 = tree_simplify_using_condition (cond, TREE_OPERAND (expr, 1));
+ e1 = tree_simplify_using_condition_1 (cond, TREE_OPERAND (expr, 1));
if (TREE_OPERAND (expr, 1) != e1)
changed = true;
if (code == COND_EXPR)
{
- e2 = tree_simplify_using_condition (cond, TREE_OPERAND (expr, 2));
+ e2 = tree_simplify_using_condition_1 (cond, TREE_OPERAND (expr, 2));
if (TREE_OPERAND (expr, 2) != e2)
changed = true;
}
@@ -716,22 +772,37 @@ tree_simplify_using_condition (tree cond, tree expr)
return boolean_true_node;
}
+ te = expand_simple_operations (expr);
+
/* Check whether COND ==> EXPR. */
notcond = invert_truthvalue (cond);
- e = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
- notcond, expr);
+ e = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, notcond, te);
if (nonzero_p (e))
return e;
/* Check whether COND ==> not EXPR. */
- e = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
- cond, expr);
+ e = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond, te);
if (zero_p (e))
return e;
return expr;
}
+/* Tries to simplify EXPR using the condition COND. Returns the simplified
+ expression (or EXPR unchanged, if no simplification was possible).
+ Wrapper around tree_simplify_using_condition_1 that ensures that chains
+ of simple operations in definitions of ssa names in COND are expanded,
+ so that things like casts or incrementing the value of the bound before
+ the loop do not cause us to fail. */
+
+static tree
+tree_simplify_using_condition (tree cond, tree expr)
+{
+ cond = expand_simple_operations (cond);
+
+ return tree_simplify_using_condition_1 (cond, expr);
+}
+
/* Tries to simplify EXPR using the conditions on entry to LOOP.
Record the conditions used for simplification to CONDS_USED.
Returns the simplified expression (or EXPR unchanged, if no