aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r--gcc/gimplify.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index c4d4f62..d10c848 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -5114,8 +5114,9 @@ gimplify_omp_parallel (tree *expr_p, tree *pre_p)
static enum gimplify_status
gimplify_omp_for (tree *expr_p, tree *pre_p)
{
- tree for_stmt, decl, t;
+ tree for_stmt, decl, var, t;
enum gimplify_status ret = GS_OK;
+ tree body, init_decl = NULL_TREE;
for_stmt = *expr_p;
@@ -5134,6 +5135,20 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
else
omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
+ /* If DECL is not a gimple register, create a temporary variable to act as an
+ iteration counter. This is valid, since DECL cannot be modified in the
+ body of the loop. */
+ if (!is_gimple_reg (decl))
+ {
+ var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
+ GENERIC_TREE_OPERAND (t, 0) = var;
+
+ init_decl = build_gimple_modify_stmt (decl, var);
+ omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
+ }
+ else
+ var = decl;
+
ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
&OMP_FOR_PRE_BODY (for_stmt),
NULL, is_gimple_val, fb_rvalue);
@@ -5143,6 +5158,7 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
t = OMP_FOR_COND (for_stmt);
gcc_assert (COMPARISON_CLASS_P (t));
gcc_assert (GENERIC_TREE_OPERAND (t, 0) == decl);
+ TREE_OPERAND (t, 0) = var;
ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
&OMP_FOR_PRE_BODY (for_stmt),
@@ -5155,21 +5171,23 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
t = build_int_cst (TREE_TYPE (decl), 1);
- t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
- t = build_gimple_modify_stmt (decl, t);
+ t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
+ t = build_gimple_modify_stmt (var, t);
OMP_FOR_INCR (for_stmt) = t;
break;
case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR:
t = build_int_cst (TREE_TYPE (decl), -1);
- t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
- t = build_gimple_modify_stmt (decl, t);
+ t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
+ t = build_gimple_modify_stmt (var, t);
OMP_FOR_INCR (for_stmt) = t;
break;
case GIMPLE_MODIFY_STMT:
gcc_assert (GIMPLE_STMT_OPERAND (t, 0) == decl);
+ GIMPLE_STMT_OPERAND (t, 0) = var;
+
t = GIMPLE_STMT_OPERAND (t, 1);
switch (TREE_CODE (t))
{
@@ -5177,11 +5195,14 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
if (TREE_OPERAND (t, 1) == decl)
{
TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
- TREE_OPERAND (t, 0) = decl;
+ TREE_OPERAND (t, 0) = var;
break;
}
+
+ /* Fallthru. */
case MINUS_EXPR:
gcc_assert (TREE_OPERAND (t, 0) == decl);
+ TREE_OPERAND (t, 0) = var;
break;
default:
gcc_unreachable ();
@@ -5195,7 +5216,13 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
gcc_unreachable ();
}
- gimplify_to_stmt_list (&OMP_FOR_BODY (for_stmt));
+ body = OMP_FOR_BODY (for_stmt);
+ gimplify_to_stmt_list (&body);
+ t = alloc_stmt_list ();
+ if (init_decl)
+ append_to_statement_list (init_decl, &t);
+ append_to_statement_list (body, &t);
+ OMP_FOR_BODY (for_stmt) = t;
gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt));
return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR;
@@ -6591,9 +6618,18 @@ force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
if (var)
expr = build_gimple_modify_stmt (var, expr);
- ret = gimplify_expr (&expr, stmts, NULL,
- gimple_test_f, fb_rvalue);
- gcc_assert (ret != GS_ERROR);
+ if (TREE_CODE (expr) != GIMPLE_MODIFY_STMT
+ && TREE_TYPE (expr) == void_type_node)
+ {
+ gimplify_and_add (expr, stmts);
+ expr = NULL_TREE;
+ }
+ else
+ {
+ ret = gimplify_expr (&expr, stmts, NULL,
+ gimple_test_f, fb_rvalue);
+ gcc_assert (ret != GS_ERROR);
+ }
if (gimple_referenced_vars (cfun))
{