diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-12-06 11:06:38 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-12-06 11:06:38 +0100 |
commit | aea744402793cf5f295c638d76844b3290ce30a5 (patch) | |
tree | d3ee7ca422466e7b440771e07c8bd5951262c11a /gcc/gimplify.c | |
parent | 12959abe9ee629768541ebcba0cbc12865d5b8af (diff) | |
download | gcc-aea744402793cf5f295c638d76844b3290ce30a5.zip gcc-aea744402793cf5f295c638d76844b3290ce30a5.tar.gz gcc-aea744402793cf5f295c638d76844b3290ce30a5.tar.bz2 |
[multiple changes]
2007-12-06 Zdenek Dvorak <ook@ucw.cz>
Dorit Nuzman <dorit@il.ibm.com>
Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/34005
* tree-gimple.c (is_gimple_formal_tmp_rhs): Add a case for COND_EXPR.
* gimplify.c (gimplify_ctx): Add a new member allow_rhs_cond_expr.
(gimplify_pure_cond_expr): New function.
(generic_expr_could_trap_p): New function.
(gimplify_cond_expr): Call gimplify_pure_cond_expr.
(force_gimple_operand): Initialize new field allow_rhs_cond_expr.
2007-12-06 Martin Michlmayr <tbm@cyrius.com>
Dorit Nuzman <dorit@il.ibm.com>
PR tree-optimization/34005
* gcc.dg/vect/pr34005.c: New test.
From-SVN: r130647
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 8a74c3c..06f7380 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -94,6 +94,7 @@ struct gimplify_ctx int conditions; bool save_stack; bool into_ssa; + bool allow_rhs_cond_expr; }; static struct gimplify_ctx *gimplify_ctxp; @@ -2546,6 +2547,61 @@ gimple_boolify (tree expr) } } +/* Given a conditional expression *EXPR_P without side effects, gimplify + its operands. New statements are inserted to PRE_P. */ + +static enum gimplify_status +gimplify_pure_cond_expr (tree *expr_p, tree *pre_p) +{ + tree expr = *expr_p, cond; + enum gimplify_status ret, tret; + enum tree_code code; + + cond = gimple_boolify (COND_EXPR_COND (expr)); + + /* We need to handle && and || specially, as their gimplification + creates pure cond_expr, thus leading to an infinite cycle otherwise. */ + code = TREE_CODE (cond); + if (code == TRUTH_ANDIF_EXPR) + TREE_SET_CODE (cond, TRUTH_AND_EXPR); + else if (code == TRUTH_ORIF_EXPR) + TREE_SET_CODE (cond, TRUTH_OR_EXPR); + ret = gimplify_expr (&cond, pre_p, NULL, + is_gimple_condexpr, fb_rvalue); + COND_EXPR_COND (*expr_p) = cond; + + tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL, + is_gimple_val, fb_rvalue); + ret = MIN (ret, tret); + tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL, + is_gimple_val, fb_rvalue); + + return MIN (ret, tret); +} + +/* Returns true if evaluating EXPR could trap. + EXPR is GENERIC, while tree_could_trap_p can be called + only on GIMPLE. */ + +static bool +generic_expr_could_trap_p (tree expr) +{ + unsigned i, n; + + if (!expr || is_gimple_val (expr)) + return false; + + if (!EXPR_P (expr) || tree_could_trap_p (expr)) + return true; + + n = TREE_OPERAND_LENGTH (expr); + for (i = 0; i < n; i++) + if (generic_expr_could_trap_p (TREE_OPERAND (expr, i))) + return true; + + return false; +} + /* Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;' into @@ -2579,6 +2635,15 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback) if ((fallback & fb_lvalue) == 0) { + if (gimplify_ctxp->allow_rhs_cond_expr + /* If either branch has side effects or could trap, it can't be + evaluated unconditionally. */ + && !TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1)) + && !generic_expr_could_trap_p (TREE_OPERAND (*expr_p, 1)) + && !TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 2)) + && !generic_expr_could_trap_p (TREE_OPERAND (*expr_p, 2))) + return gimplify_pure_cond_expr (expr_p, pre_p); + result = tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp"); ret = GS_ALL_DONE; } @@ -2593,7 +2658,7 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback) if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node) TREE_OPERAND (expr, 2) = build_fold_addr_expr (TREE_OPERAND (expr, 2)); - + tmp2 = tmp = create_tmp_var (type, "iftmp"); expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (expr, 0), @@ -6444,6 +6509,7 @@ force_gimple_operand (tree expr, tree *stmts, bool simple, tree var) push_gimplify_context (); gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun); + gimplify_ctxp->allow_rhs_cond_expr = true; if (var) expr = build_gimple_modify_stmt (var, expr); |