summaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-06-06 20:39:46 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-06-06 20:39:46 +0000
commite97da9acca05b56be99bfd9abd8b83e5db5268fb (patch)
treefcab715a6c79d738a81d753254714e02889ad105 /gcc/gimplify.c
parent76d6e5e429f5ca1ba89341e4fd3cbd5f4a6f055f (diff)
downloadgcc-e97da9acca05b56be99bfd9abd8b83e5db5268fb.tar.gz
2008-06-06 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r136492 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@136504 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r--gcc/gimplify.c362
1 files changed, 258 insertions, 104 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 2d0ecbf20d9..47a2fe7b43d 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -62,10 +62,19 @@ enum gimplify_omp_var_data
GOVD_REDUCTION = 64,
GOVD_LOCAL = 128,
GOVD_DEBUG_PRIVATE = 256,
+ GOVD_PRIVATE_OUTER_REF = 512,
GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL)
};
+enum omp_region_type
+{
+ ORT_WORKSHARE = 0,
+ ORT_TASK = 1,
+ ORT_PARALLEL = 2,
+ ORT_COMBINED_PARALLEL = 3
+};
+
struct gimplify_omp_ctx
{
struct gimplify_omp_ctx *outer_context;
@@ -73,8 +82,7 @@ struct gimplify_omp_ctx
struct pointer_set_t *privatized_types;
location_t location;
enum omp_clause_default_kind default_kind;
- bool is_parallel;
- bool is_combined_parallel;
+ enum omp_region_type region_type;
};
struct gimplify_ctx
@@ -270,7 +278,7 @@ splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
/* Create a new omp construct that deals with variable remapping. */
static struct gimplify_omp_ctx *
-new_omp_context (bool is_parallel, bool is_combined_parallel)
+new_omp_context (enum omp_region_type region_type)
{
struct gimplify_omp_ctx *c;
@@ -279,9 +287,11 @@ new_omp_context (bool is_parallel, bool is_combined_parallel)
c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
c->privatized_types = pointer_set_create ();
c->location = input_location;
- c->is_parallel = is_parallel;
- c->is_combined_parallel = is_combined_parallel;
- c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
+ c->region_type = region_type;
+ if (region_type != ORT_TASK)
+ c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
+ else
+ c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
return c;
}
@@ -756,7 +766,7 @@ gimple_add_tmp_var (tree tmp)
if (gimplify_omp_ctxp)
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
- while (ctx && !ctx->is_parallel)
+ while (ctx && ctx->region_type == ORT_WORKSHARE)
ctx = ctx->outer_context;
if (ctx)
omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
@@ -4711,7 +4721,7 @@ omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
else
return;
}
- else if (ctx->is_parallel)
+ else if (ctx->region_type != ORT_WORKSHARE)
omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
ctx = ctx->outer_context;
@@ -4904,8 +4914,9 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
if (n == NULL)
{
enum omp_clause_default_kind default_kind, kind;
+ struct gimplify_omp_ctx *octx;
- if (!ctx->is_parallel)
+ if (ctx->region_type == ORT_WORKSHARE)
goto do_outer;
/* ??? Some compiler-generated variables (like SAVE_EXPRs) could be
@@ -4929,10 +4940,47 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
case OMP_CLAUSE_DEFAULT_PRIVATE:
flags |= GOVD_PRIVATE;
break;
+ case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
+ flags |= GOVD_FIRSTPRIVATE;
+ break;
+ case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
+ /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED. */
+ gcc_assert (ctx->region_type == ORT_TASK);
+ if (ctx->outer_context)
+ omp_notice_variable (ctx->outer_context, decl, in_code);
+ for (octx = ctx->outer_context; octx; octx = octx->outer_context)
+ {
+ splay_tree_node n2;
+
+ n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
+ if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
+ {
+ flags |= GOVD_FIRSTPRIVATE;
+ break;
+ }
+ if ((octx->region_type & ORT_PARALLEL) != 0)
+ break;
+ }
+ if (flags & GOVD_FIRSTPRIVATE)
+ break;
+ if (octx == NULL
+ && (TREE_CODE (decl) == PARM_DECL
+ || (!is_global_var (decl)
+ && DECL_CONTEXT (decl) == current_function_decl)))
+ {
+ flags |= GOVD_FIRSTPRIVATE;
+ break;
+ }
+ flags |= GOVD_SHARED;
+ break;
default:
gcc_unreachable ();
}
+ if ((flags & GOVD_PRIVATE)
+ && lang_hooks.decls.omp_private_outer_ref (decl))
+ flags |= GOVD_PRIVATE_OUTER_REF;
+
omp_add_variable (ctx, decl, flags);
shared = (flags & GOVD_SHARED) != 0;
@@ -4952,7 +5000,7 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
do_outer:
/* If the variable is private in the current context, then we don't
need to propagate anything to an outer context. */
- if (flags & GOVD_PRIVATE)
+ if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
return ret;
if (ctx->outer_context
&& omp_notice_variable (ctx->outer_context, decl, in_code))
@@ -4985,7 +5033,7 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
}
else if ((n->value & GOVD_EXPLICIT) != 0
&& (ctx == gimplify_omp_ctxp
- || (ctx->is_combined_parallel
+ || (ctx->region_type == ORT_COMBINED_PARALLEL
&& gimplify_omp_ctxp->outer_context == ctx)))
{
if ((n->value & GOVD_FIRSTPRIVATE) != 0)
@@ -4998,7 +5046,7 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
return true;
}
- if (ctx->is_parallel)
+ if (ctx->region_type != ORT_WORKSHARE)
return false;
else if (ctx->outer_context)
return omp_is_private (ctx->outer_context, decl);
@@ -5027,7 +5075,7 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl)
if (n != NULL)
return (n->value & GOVD_SHARED) == 0;
}
- while (!ctx->is_parallel);
+ while (ctx->region_type == ORT_WORKSHARE);
return false;
}
@@ -5035,13 +5083,13 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl)
and previous omp contexts. */
static void
-gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel,
- bool in_combined_parallel)
+gimplify_scan_omp_clauses (tree *list_p, tree *pre_p,
+ enum omp_region_type region_type)
{
struct gimplify_omp_ctx *ctx, *outer_ctx;
tree c;
- ctx = new_omp_context (in_parallel, in_combined_parallel);
+ ctx = new_omp_context (region_type);
outer_ctx = ctx->outer_context;
while ((c = *list_p) != NULL)
@@ -5057,7 +5105,13 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel,
{
case OMP_CLAUSE_PRIVATE:
flags = GOVD_PRIVATE | GOVD_EXPLICIT;
- notice_outer = false;
+ if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
+ {
+ flags |= GOVD_PRIVATE_OUTER_REF;
+ OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
+ }
+ else
+ notice_outer = false;
goto do_add;
case OMP_CLAUSE_SHARED:
flags = GOVD_SHARED | GOVD_EXPLICIT;
@@ -5097,6 +5151,23 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel,
pop_gimplify_context (OMP_CLAUSE_REDUCTION_MERGE (c));
gimplify_omp_ctxp = outer_ctx;
}
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_LASTPRIVATE_STMT (c))
+ {
+ gimplify_omp_ctxp = ctx;
+ push_gimplify_context ();
+ if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
+ {
+ tree bind = build3 (BIND_EXPR, void_type_node, NULL,
+ NULL, NULL);
+ TREE_SIDE_EFFECTS (bind) = 1;
+ BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
+ OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
+ }
+ gimplify_stmt (&OMP_CLAUSE_LASTPRIVATE_STMT (c));
+ pop_gimplify_context (OMP_CLAUSE_LASTPRIVATE_STMT (c));
+ gimplify_omp_ctxp = outer_ctx;
+ }
if (notice_outer)
goto do_notice;
break;
@@ -5113,7 +5184,7 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel,
if (outer_ctx)
omp_notice_variable (outer_ctx, decl, true);
if (check_non_private
- && !in_parallel
+ && region_type == ORT_WORKSHARE
&& omp_check_private (ctx, decl))
{
error ("%s variable %qs is private in outer context",
@@ -5137,6 +5208,8 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel,
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_ORDERED:
+ case OMP_CLAUSE_UNTIED:
+ case OMP_CLAUSE_COLLAPSE:
break;
case OMP_CLAUSE_DEFAULT:
@@ -5215,7 +5288,10 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
OMP_CLAUSE_CHAIN (clause) = *list_p;
if (private_debug)
OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
+ else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
+ OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
*list_p = clause;
+ lang_hooks.decls.omp_finish_clause (clause);
return 0;
}
@@ -5272,6 +5348,8 @@ gimplify_adjust_omp_clauses (tree *list_p)
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_DEFAULT:
+ case OMP_CLAUSE_UNTIED:
+ case OMP_CLAUSE_COLLAPSE:
break;
default:
@@ -5301,8 +5379,10 @@ gimplify_omp_parallel (tree *expr_p, tree *pre_p)
{
tree expr = *expr_p;
- gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p, true,
- OMP_PARALLEL_COMBINED (expr));
+ gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
+ OMP_PARALLEL_COMBINED (expr)
+ ? ORT_COMBINED_PARALLEL
+ : ORT_PARALLEL);
push_gimplify_context ();
@@ -5318,124 +5398,187 @@ gimplify_omp_parallel (tree *expr_p, tree *pre_p)
return GS_ALL_DONE;
}
-/* Gimplify the gross structure of an OMP_FOR statement. */
+/* Gimplify the contents of an OMP_TASK statement. This involves
+ gimplification of the body, as well as scanning the body for used
+ variables. We need to do this scan now, because variable-sized
+ decls will be decomposed during gimplification. */
static enum gimplify_status
-gimplify_omp_for (tree *expr_p, tree *pre_p)
+gimplify_omp_task (tree *expr_p, tree *pre_p)
{
- tree for_stmt, decl, var, t;
- enum gimplify_status ret = GS_OK;
- tree body, init_decl = NULL_TREE;
+ tree expr = *expr_p;
- for_stmt = *expr_p;
+ gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p, ORT_TASK);
- gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, false, false);
+ push_gimplify_context ();
- t = OMP_FOR_INIT (for_stmt);
- gcc_assert (TREE_CODE (t) == MODIFY_EXPR
- || TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- decl = GENERIC_TREE_OPERAND (t, 0);
- gcc_assert (DECL_P (decl));
- gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl)));
+ gimplify_stmt (&OMP_TASK_BODY (expr));
- /* Make sure the iteration variable is private. */
- if (omp_is_private (gimplify_omp_ctxp, decl))
- omp_notice_variable (gimplify_omp_ctxp, decl, true);
+ if (TREE_CODE (OMP_TASK_BODY (expr)) == BIND_EXPR)
+ pop_gimplify_context (OMP_TASK_BODY (expr));
else
- omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
+ pop_gimplify_context (NULL_TREE);
- /* 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;
+ gimplify_adjust_omp_clauses (&OMP_TASK_CLAUSES (expr));
- init_decl = build_gimple_modify_stmt (decl, var);
- omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
- }
- else
- var = decl;
+ return GS_ALL_DONE;
+}
+
+/* Gimplify the gross structure of an OMP_FOR statement. */
+
+static enum gimplify_status
+gimplify_omp_for (tree *expr_p, tree *pre_p)
+{
+ tree for_stmt, decl, var, t, bodylist;
+ enum gimplify_status ret = GS_OK;
+ tree body, init_decl = NULL_TREE;
+ int i;
+
+ for_stmt = *expr_p;
+
+ gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
+ ORT_WORKSHARE);
/* If OMP_FOR is re-gimplified, ensure all variables in pre-body
are noticed. */
gimplify_stmt (&OMP_FOR_PRE_BODY (for_stmt));
- ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
- &OMP_FOR_PRE_BODY (for_stmt),
- NULL, is_gimple_val, fb_rvalue);
+ bodylist = alloc_stmt_list ();
+
+ gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
+ == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
+ gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
+ == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
+ for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
+ {
+ t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
+ gcc_assert (TREE_CODE (t) == MODIFY_EXPR
+ || TREE_CODE (t) == GIMPLE_MODIFY_STMT);
+ decl = GENERIC_TREE_OPERAND (t, 0);
+ gcc_assert (DECL_P (decl));
+ gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
+ || POINTER_TYPE_P (TREE_TYPE (decl)));
+
+ /* Make sure the iteration variable is private. */
+ if (omp_is_private (gimplify_omp_ctxp, decl))
+ omp_notice_variable (gimplify_omp_ctxp, decl, true);
+ else
+ omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
- tree_to_gimple_tuple (&OMP_FOR_INIT (for_stmt));
+ /* 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;
- 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;
+ 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);
+ ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
+ &OMP_FOR_PRE_BODY (for_stmt),
+ NULL, is_gimple_val, fb_rvalue);
- tree_to_gimple_tuple (&OMP_FOR_INCR (for_stmt));
- t = OMP_FOR_INCR (for_stmt);
- switch (TREE_CODE (t))
- {
- case PREINCREMENT_EXPR:
- case POSTINCREMENT_EXPR:
- t = build_int_cst (TREE_TYPE (decl), 1);
- t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
- t = build_gimple_modify_stmt (var, t);
- OMP_FOR_INCR (for_stmt) = t;
- break;
+ tree_to_gimple_tuple (&TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i));
- case PREDECREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- t = build_int_cst (TREE_TYPE (decl), -1);
- 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 = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
+ gcc_assert (COMPARISON_CLASS_P (t));
+ gcc_assert (GENERIC_TREE_OPERAND (t, 0) == decl);
+ TREE_OPERAND (t, 0) = var;
- t = GIMPLE_STMT_OPERAND (t, 1);
+ ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
+ &OMP_FOR_PRE_BODY (for_stmt),
+ NULL, is_gimple_val, fb_rvalue);
+
+ tree_to_gimple_tuple (&TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i));
+ t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
switch (TREE_CODE (t))
{
- case PLUS_EXPR:
- if (TREE_OPERAND (t, 1) == decl)
+ case PREINCREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ t = build_int_cst (TREE_TYPE (decl), 1);
+ t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
+ t = build_gimple_modify_stmt (var, t);
+ TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
+ break;
+
+ case PREDECREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ t = build_int_cst (TREE_TYPE (decl), -1);
+ t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
+ t = build_gimple_modify_stmt (var, t);
+ TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = 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))
{
- TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
+ case PLUS_EXPR:
+ if (TREE_OPERAND (t, 1) == decl)
+ {
+ TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
+ TREE_OPERAND (t, 0) = var;
+ break;
+ }
+
+ /* Fallthru. */
+ case MINUS_EXPR:
+ case POINTER_PLUS_EXPR:
+ gcc_assert (TREE_OPERAND (t, 0) == decl);
TREE_OPERAND (t, 0) = var;
break;
+ default:
+ gcc_unreachable ();
}
- /* Fallthru. */
- case MINUS_EXPR:
- gcc_assert (TREE_OPERAND (t, 0) == decl);
- TREE_OPERAND (t, 0) = var;
+ ret |= gimplify_expr (&TREE_OPERAND (t, 1),
+ &OMP_FOR_PRE_BODY (for_stmt),
+ NULL, is_gimple_val, fb_rvalue);
break;
+
default:
gcc_unreachable ();
}
- ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
- NULL, is_gimple_val, fb_rvalue);
- break;
+ if (init_decl)
+ append_to_statement_list (init_decl, &bodylist);
- default:
- gcc_unreachable ();
+ if (var != decl || TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
+ {
+ tree c;
+ for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_DECL (c) == decl
+ && OMP_CLAUSE_LASTPRIVATE_STMT (c) == NULL)
+ {
+ t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
+ gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
+ gcc_assert (GIMPLE_STMT_OPERAND (t, 0) == var);
+ t = GIMPLE_STMT_OPERAND (t, 1);
+ gcc_assert (TREE_CODE (t) == PLUS_EXPR
+ || TREE_CODE (t) == MINUS_EXPR
+ || TREE_CODE (t) == POINTER_PLUS_EXPR);
+ gcc_assert (TREE_OPERAND (t, 0) == var);
+ t = build2 (TREE_CODE (t), TREE_TYPE (decl), decl,
+ TREE_OPERAND (t, 1));
+ OMP_CLAUSE_LASTPRIVATE_STMT (c)
+ = build_gimple_modify_stmt (decl, t);
+ }
+ }
}
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;
+ append_to_statement_list (body, &bodylist);
+ OMP_FOR_BODY (for_stmt) = bodylist;
gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt));
return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR;
@@ -5449,7 +5592,7 @@ gimplify_omp_workshare (tree *expr_p, tree *pre_p)
{
tree stmt = *expr_p;
- gimplify_scan_omp_clauses (&OMP_CLAUSES (stmt), pre_p, false, false);
+ gimplify_scan_omp_clauses (&OMP_CLAUSES (stmt), pre_p, ORT_WORKSHARE);
gimplify_to_stmt_list (&OMP_BODY (stmt));
gimplify_adjust_omp_clauses (&OMP_CLAUSES (stmt));
@@ -5747,8 +5890,14 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
break;
case TRUTH_NOT_EXPR:
- TREE_OPERAND (*expr_p, 0)
- = gimple_boolify (TREE_OPERAND (*expr_p, 0));
+ if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
+ {
+ tree type = TREE_TYPE (*expr_p);
+ *expr_p = fold_convert (type, gimple_boolify (*expr_p));
+ ret = GS_OK;
+ break;
+ }
+
ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
is_gimple_val, fb_rvalue);
recalculate_side_effects (*expr_p);
@@ -6025,6 +6174,10 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
ret = gimplify_omp_parallel (expr_p, pre_p);
break;
+ case OMP_TASK:
+ ret = gimplify_omp_task (expr_p, pre_p);
+ break;
+
case OMP_FOR:
ret = gimplify_omp_for (expr_p, pre_p);
break;
@@ -6048,6 +6201,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
case OMP_RETURN:
case OMP_CONTINUE:
case OMP_ATOMIC_STORE:
+ case OMP_SECTIONS_SWITCH:
ret = GS_ALL_DONE;
break;
@@ -6494,7 +6648,7 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms)
unshare_body (body_p, fndecl);
unvisit_body (body_p, fndecl);
- /* Make sure input_location isn't set to something wierd. */
+ /* Make sure input_location isn't set to something weird. */
input_location = DECL_SOURCE_LOCATION (fndecl);
/* Resolve callee-copies. This has to be done before processing