diff options
author | Andrew Pinski <apinski@cavium.com> | 2012-09-03 20:31:52 +0000 |
---|---|---|
committer | Andrew Pinski <pinskia@gcc.gnu.org> | 2012-09-03 13:31:52 -0700 |
commit | f35613b29cb15939a2a2f25b0275f7ee6c00a200 (patch) | |
tree | 5fbe5db82a98ffa2d46d0d28b36eb77d91279460 /gcc/tree-if-conv.c | |
parent | aa369472a27746c266746fac3f3568b173654a95 (diff) | |
download | gcc-f35613b29cb15939a2a2f25b0275f7ee6c00a200.zip gcc-f35613b29cb15939a2a2f25b0275f7ee6c00a200.tar.gz gcc-f35613b29cb15939a2a2f25b0275f7ee6c00a200.tar.bz2 |
re PR tree-optimization/53395 (The LAPACK functions i(d|s)amax are more than two times slower after revision 187183)
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.
From-SVN: r190904
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 1086004..e9f65ad 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); } |