From 367f2e2a94ca7fd9ac642d4d0b6a43b67b5446b4 Mon Sep 17 00:00:00 2001 From: jakub Date: Thu, 6 Dec 2007 10:06:38 +0000 Subject: [PATCH] 2007-12-06 Zdenek Dvorak Dorit Nuzman Jakub Jelinek 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 Dorit Nuzman PR tree-optimization/34005 * gcc.dg/vect/pr34005.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130647 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 12 +++++++ gcc/gimplify.c | 68 ++++++++++++++++++++++++++++++++++++- gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/gcc.dg/vect/pr34005.c | 15 ++++++++ gcc/tree-gimple.c | 1 + 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr34005.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 92d0b3b..5a6d8ac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2007-12-06 Zdenek Dvorak + Dorit Nuzman + Jakub Jelinek + + 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 Andreas Krebbel * config/s390/s390.c (s390_emit_stack_tie): New function. 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 94e7273..42e0539 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2007-12-06 Martin Michlmayr + Dorit Nuzman + + PR tree-optimization/34005 + * gcc.dg/vect/pr34005.c: New test. + 2007-12-06 Jakub Jelinek PR c++/34336 diff --git a/gcc/testsuite/gcc.dg/vect/pr34005.c b/gcc/testsuite/gcc.dg/vect/pr34005.c new file mode 100644 index 0000000..813f950 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr34005.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/34005 */ +/* { dg-do compile } */ + +/* Testcase by Martin Michlmayr */ + +void XdmcpUnwrap (unsigned char *output, int k) +{ + int i; + unsigned char blocks[2][8]; + k = (k == 0) ? 1 : 0; + for (i = 0; i < 32; i++) + output[i] = blocks[k][i]; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c index 92c7b41..abd35f7 100644 --- a/gcc/tree-gimple.c +++ b/gcc/tree-gimple.c @@ -61,6 +61,7 @@ is_gimple_formal_tmp_rhs (tree t) case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: + case COND_EXPR: case ADDR_EXPR: case CALL_EXPR: case CONSTRUCTOR: -- 2.7.4