diff options
author | pinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-09-03 20:31:52 +0000 |
---|---|---|
committer | pinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-09-03 20:31:52 +0000 |
commit | ed0124a2ae6a42565a495a619aecf752d49682ef (patch) | |
tree | 5fbe5db82a98ffa2d46d0d28b36eb77d91279460 /gcc/tree-if-conv.c | |
parent | fe1dba6dac26261f1f8b72ca185aa156d13f94d3 (diff) | |
download | gcc-ed0124a2ae6a42565a495a619aecf752d49682ef.tar.gz |
2012-09-03 Andrew Pinski <apinski@cavium.com>
PR tree-opt/53395
* tree-if-conv.c (constant_or_ssa_name): New function.
(fold_build_cond_expr): New function.
(predicate_scalar_phi): Use fold_build_cond_expr instead of build3.
(predicate_mem_writes): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190904 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-if-conv.c')
-rw-r--r-- | gcc/tree-if-conv.c | 65 |
1 files changed, 62 insertions, 3 deletions
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 1086004d3fb..e9f65adddbd 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -307,6 +307,65 @@ fold_or_predicates (location_t loc, tree c1, tree c2) return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2); } +/* Returns true if N is either a constant or a SSA_NAME. */ + +static bool +constant_or_ssa_name (tree n) +{ + switch (TREE_CODE (n)) + { + case SSA_NAME: + case INTEGER_CST: + case REAL_CST: + case COMPLEX_CST: + case VECTOR_CST: + return true; + default: + return false; + } +} + +/* Returns either a COND_EXPR or the folded expression if the folded + expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR, + a constant or a SSA_NAME. */ + +static tree +fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs) +{ + tree rhs1, lhs1, cond_expr; + cond_expr = fold_ternary (COND_EXPR, type, cond, + rhs, lhs); + + if (cond_expr == NULL_TREE) + return build3 (COND_EXPR, type, cond, rhs, lhs); + + STRIP_USELESS_TYPE_CONVERSION (cond_expr); + + if (constant_or_ssa_name (cond_expr)) + return cond_expr; + + if (TREE_CODE (cond_expr) == ABS_EXPR) + { + rhs1 = TREE_OPERAND (cond_expr, 1); + STRIP_USELESS_TYPE_CONVERSION (rhs1); + if (constant_or_ssa_name (rhs1)) + return build1 (ABS_EXPR, type, rhs1); + } + + if (TREE_CODE (cond_expr) == MIN_EXPR + || TREE_CODE (cond_expr) == MAX_EXPR) + { + lhs1 = TREE_OPERAND (cond_expr, 0); + STRIP_USELESS_TYPE_CONVERSION (lhs1); + rhs1 = TREE_OPERAND (cond_expr, 1); + STRIP_USELESS_TYPE_CONVERSION (rhs1); + if (constant_or_ssa_name (rhs1) + && constant_or_ssa_name (lhs1)) + return build2 (TREE_CODE (cond_expr), type, lhs1, rhs1); + } + return build3 (COND_EXPR, type, cond, rhs, lhs); +} + /* Add condition NC to the predicate list of basic block BB. */ static inline void @@ -1293,8 +1352,8 @@ predicate_scalar_phi (gimple phi, tree cond, || bb_postdominates_preds (bb)); /* Build new RHS using selected condition and arguments. */ - rhs = build3 (COND_EXPR, TREE_TYPE (res), - unshare_expr (cond), arg_0, arg_1); + rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond), + arg_0, arg_1); } new_stmt = gimple_build_assign (res, rhs); @@ -1554,7 +1613,7 @@ predicate_mem_writes (loop_p loop) cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond), is_gimple_condexpr, NULL_TREE, true, GSI_SAME_STMT); - rhs = build3 (COND_EXPR, type, unshare_expr (cond), rhs, lhs); + rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs); gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi)); update_stmt (stmt); } |