diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-23 21:33:15 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-23 21:33:15 +0000 |
commit | 1962cebaa32153a93d9eb93d120caa1b789d09d4 (patch) | |
tree | 0ff6a29f85740fedc59f8fc702e20fae58f30e68 /gcc/tree-ssa-loop-niter.c | |
parent | c4d3b42853583ec88202ae5fd9470203b6a276b2 (diff) | |
download | gcc-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.c | 91 |
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 |