summaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authoraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2013-08-27 18:38:00 +0000
committeraldyh <aldyh@138bc75d-0d04-0410-961f-82ee72b054a4>2013-08-27 18:38:00 +0000
commit3d483a945121cb0af4aca43631e2454f50c9325a (patch)
treec96afad81f1d970413ba047262aa9f9765da99e4 /gcc/gimplify.c
parent0f227eb85928fd6f76dd49bff394869145d6c1a3 (diff)
downloadgcc-3d483a945121cb0af4aca43631e2454f50c9325a.tar.gz
* Makefile.in (omp-low.o): Depend on $(TARGET_H).
* cfgloop.h (struct loop): Add safelen, force_vect, simduid. * function.h (struct function): Add has_force_vect_loops and has_simduid_loops. * gimple-pretty-print.c (dump_gimple_omp_for): Handle GF_OMP_FOR_KIND*. * gimple.c (gimple_build_omp_critical): Add KIND argument and handle it. * gimple.def: Update CLAUSES comments. * gimple.h (enum gf_mask): Add GF_OMP_FOR_KIND_{FOR,SIMD}. (gimple_build_omp_for): Add argument to prototype. (gimple_omp_for_kind): New. (gimple_omp_for_set_kind): New. * gimplify.c (enum gimplify_omp_var_data): Add GOVD_LINEAR to GOVD_DATA_SHARE_CLASS. (enum omp_region_type): Add ORT_SIMD. (gimple_add_tmp_var): Handle ORT_SIMD. (gimplify_var_or_parm_decl): Same. (is_gimple_stmt): Same. (omp_firstprivatize_variable): Same. (omp_add_variable): Only use splay_tree_insert if lookup failed. (omp_notice_variable): Handle ORT_SIMD. (omp_is_private): Add SIMD argument and handle it as well as ORT_SIMD. (omp_check_private): Handle ORT_SIMD. (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_LINEAR and OMP_CLAUSE_SAFELEN. (gimplify_adjust_omp_clauses_1): Handle GOVD_LINEAR. Handle OMP_CLAUSE_LASTPRIVATE. (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_LINEAR and OMP_CLAUSE_SAFELEN. (gimplify_omp_for): Handle OMP_SIMD and OMP_CLAUSE_LINEAR. (gimplify_expr): Handle OMP_SIMD. * internal-fn.c (expand_GOMP_SIMD_LANE): New. (expand_GOMP_SIMD_VF): New. (expand_GOMP_SIMD_LAST_LANE): New. * internal-fn.def (GOMP_SIMD_LANE): New. (GOMP_SIMD_VF): New. (GOMP_SIMD_LAST_LANE): New. * omp-low.c: Include target.h. (extract_omp_for_data): Handle OMP_SIMD, OMP_CLAUSE_LINEAR, OMP_CLAUSE_SAFELEN. (check_omp_nesting_restrictions): Same. (omp_max_vf): New. (lower_rec_simd_input_clauses): New. (lower_rec_input_clauses): Handle OMP_SIMD, GF_OMP_FOR_KIND_SIMD, OMP_CLAUSE_LINEAR. (lower_lastprivate_clauses): Handle OMP_CLAUSE_LINEAR, GF_OMP_FOR_KIND_SIMD, OMP_SIMD. (expand_omp_build_assign): New. (expand_omp_for_init_counts): New. (expand_omp_for_init_vars): New. (extract_omp_for_update_vars): New. (expand_omp_for_generic): Use expand_omp_for_{init,update}_vars and rewrite accordingly. (expand_omp_simd): New. (expand_omp_for): Use expand_omp_simd. (lower_omp_for_lastprivate): Unshare vinit when appropriate. (lower_omp_for): Do not lower the body. * tree-data-ref (get_references_in_stmt): Allow IFN_GOMP_SIMD_LANE in their own loops. * tree-flow.h (find_omp_clause): Remove prototype. * tree-if-conv.c (main_tree_if_conversion): Run if doing if conversion, forcing vectorization of the loop, or if flag_tree_vectorize. (gate_tree_if_conversion): Similarly. * tree-inline.c (remap_gimple_stmt): Pass for kind argument to gimple_build_omp_for. (copy_cfg_body): set has_force_vect_loops and has_simduid_loops. * tree-parloops (create_parallel_loop): Pass kind argument to gimple_build_omp_for. * tree-pretty-print.c (dump_omp_clause): Add cases for OMP_CLAUSE_UNIFORM, OMP_CLAUSE_LINEAR, OMP_CLAUSE_SAFELEN, OMP_CLAUSE__SIMDUID_. (dump_generic_node): Handle OMP_SIMD. * tree-ssa-ccp.c (likely_value): Handle IFN_GOMP_SIMD*. * tree-ssa-loop-ivcanon.c (tree_unroll_loops_completely_1): Do not unroll OMP_SIMD loops here. * tree-ssa-loop.c (gate_tree_vectorize): Run if has_force_vect_loops. * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Handle loop->safelen (vect_analyze_data_refs): Handle simd loops. * tree-vect-loop.c (vectorizable_live_operation): Handle IFN_GOMP_SIMD*. * tree-vect-stmts.c (vectorizable_call): Handle IFN_GOMP_SIMD_LANE. (vectorizable_store): Handle STMT_VINFO_SIMD_LANE_ACCESS_P. (vectorizable_load): Same. * tree-vectorizer.c: Include hash-table.h and tree-ssa-propagate.h. (struct simduid_to_vf): New. (simduid_to_vf::hash): New. (simduid_to-vf::equal): New. (struct simd_array_to_simduid): New. (simd_array_to_simduid::hash): New. (simd_array_to_simduid::equal): New. (adjust_simduid_builtins): New. (struct note_simd_array_uses_struct): New. (note_simd_array_uses_cb): New. (note_simd_array_uses): New. (vectorize_loops): Handle simd hints and adjust simd builtins accordingly. * tree-vectorizer.h (struct _stmt_vec_info): Add simd_lane_access_p field. (STMT_VINFO_SIMD_LANE_ACCESS_P): New macro. * tree.c (omp_clause_num_ops): Add entries for OMP_CLAUSE_LINEAR, OMP_CLAUSE_SAFELEN, OMP_CLAUSE__SIMDUID_, OMP_CLAUSE_UNIFORM. (omp_clause_code_name): Same. (walk_tree_1): Handle OMP_CLAUSE_UNIFORM, OMP_CLAUSE_SAFELEN, OMP_CLAUSE__SIMDUID_, OMP_CLAUSE_LINEAR. * tree.def (OMP_SIMD): New entry. * tree.h (enum omp_clause_code): Add entries for OMP_CLAUSE_LINEAR, OMP_CLAUSE_UNIFORM, OMP_CLAUSE_SAFELEN, OMP_CLAUSE__SIMDUID_. (OMP_CLAUSE_DECL): Adjust range for new clauses. (OMP_CLAUSE_LINEAR_NO_COPYIN): New. (OMP_CLAUSE_LINEAR_NO_COPYOUT): New. (OMP_CLAUSE_LINEAR_STEP): New. (OMP_CLAUSE_SAFELEN_EXPR): New. (OMP_CLAUSE__SIMDUID__DECL): New. (find_omp_clause): New prototype. cp/ * cp-tree.h (CP_OMP_CLAUSE_INFO): Adjust range for new clauses. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@202029 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r--gcc/gimplify.c200
1 files changed, 182 insertions, 18 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 4d39d539f2d..3b3adb34317 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -58,14 +58,17 @@ enum gimplify_omp_var_data
GOVD_LOCAL = 128,
GOVD_DEBUG_PRIVATE = 256,
GOVD_PRIVATE_OUTER_REF = 512,
+ GOVD_LINEAR = 2048,
GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
- | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL)
+ | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
+ | GOVD_LOCAL)
};
enum omp_region_type
{
ORT_WORKSHARE = 0,
+ ORT_SIMD = 1,
ORT_PARALLEL = 2,
ORT_COMBINED_PARALLEL = 3,
ORT_TASK = 4,
@@ -710,7 +713,9 @@ gimple_add_tmp_var (tree tmp)
if (gimplify_omp_ctxp)
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
- while (ctx && ctx->region_type == ORT_WORKSHARE)
+ while (ctx
+ && (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD))
ctx = ctx->outer_context;
if (ctx)
omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
@@ -2061,7 +2066,9 @@ gimplify_var_or_parm_decl (tree *expr_p)
&& decl_function_context (decl) != current_function_decl)
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
- while (ctx && ctx->region_type == ORT_WORKSHARE)
+ while (ctx
+ && (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD))
ctx = ctx->outer_context;
if (!ctx && !pointer_set_insert (nonlocal_vlas, decl))
{
@@ -4702,6 +4709,7 @@ is_gimple_stmt (tree t)
case STATEMENT_LIST:
case OMP_PARALLEL:
case OMP_FOR:
+ case OMP_SIMD:
case OMP_SECTIONS:
case OMP_SECTION:
case OMP_SINGLE:
@@ -5714,7 +5722,8 @@ omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
else
return;
}
- else if (ctx->region_type != ORT_WORKSHARE)
+ else if (ctx->region_type != ORT_WORKSHARE
+ && ctx->region_type != ORT_SIMD)
omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
ctx = ctx->outer_context;
@@ -5806,7 +5815,8 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
FIRSTPRIVATE and LASTPRIVATE. */
nflags = n->value | flags;
gcc_assert ((nflags & GOVD_DATA_SHARE_CLASS)
- == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE));
+ == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE)
+ || (flags & GOVD_DATA_SHARE_CLASS) == 0);
n->value = nflags;
return;
}
@@ -5870,7 +5880,10 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
}
}
- splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
+ if (n != NULL)
+ n->value |= flags;
+ else
+ splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
}
/* Notice a threadprivate variable DECL used in OpenMP context CTX.
@@ -5936,7 +5949,8 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
enum omp_clause_default_kind default_kind, kind;
struct gimplify_omp_ctx *octx;
- if (ctx->region_type == ORT_WORKSHARE)
+ if (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD)
goto do_outer;
/* ??? Some compiler-generated variables (like SAVE_EXPRs) could be
@@ -6049,7 +6063,7 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
to the contrary in the innermost scope, generate an error. */
static bool
-omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
+omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, bool simd)
{
splay_tree_node n;
@@ -6060,8 +6074,12 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
{
if (ctx == gimplify_omp_ctxp)
{
- error ("iteration variable %qE should be private",
- DECL_NAME (decl));
+ if (simd)
+ error ("iteration variable %qE is predetermined linear",
+ DECL_NAME (decl));
+ else
+ error ("iteration variable %qE should be private",
+ DECL_NAME (decl));
n->value = GOVD_PRIVATE;
return true;
}
@@ -6079,16 +6097,26 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
else if ((n->value & GOVD_REDUCTION) != 0)
error ("iteration variable %qE should not be reduction",
DECL_NAME (decl));
+ else if (simd && (n->value & GOVD_LASTPRIVATE) != 0)
+ error ("iteration variable %qE should not be lastprivate",
+ DECL_NAME (decl));
+ else if (simd && (n->value & GOVD_PRIVATE) != 0)
+ error ("iteration variable %qE should not be private",
+ DECL_NAME (decl));
+ else if (simd && (n->value & GOVD_LINEAR) != 0)
+ error ("iteration variable %qE is predetermined linear",
+ DECL_NAME (decl));
}
return (ctx == gimplify_omp_ctxp
|| (ctx->region_type == ORT_COMBINED_PARALLEL
&& gimplify_omp_ctxp->outer_context == ctx));
}
- if (ctx->region_type != ORT_WORKSHARE)
+ if (ctx->region_type != ORT_WORKSHARE
+ && ctx->region_type != ORT_SIMD)
return false;
else if (ctx->outer_context)
- return omp_is_private (ctx->outer_context, decl);
+ return omp_is_private (ctx->outer_context, decl, simd);
return false;
}
@@ -6113,7 +6141,8 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl)
if (n != NULL)
return (n->value & GOVD_SHARED) == 0;
}
- while (ctx->region_type == ORT_WORKSHARE);
+ while (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD);
return false;
}
@@ -6166,6 +6195,15 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
check_non_private = "reduction";
goto do_add;
+ case OMP_CLAUSE_LINEAR:
+ if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
+ is_gimple_val, fb_rvalue) == GS_ERROR)
+ {
+ remove = true;
+ break;
+ }
+ flags = GOVD_LINEAR | GOVD_EXPLICIT;
+ goto do_add;
do_add:
decl = OMP_CLAUSE_DECL (c);
@@ -6264,6 +6302,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_SAFELEN:
break;
case OMP_CLAUSE_DEFAULT:
@@ -6321,7 +6360,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
splay_tree_node on
= splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
- | GOVD_PRIVATE | GOVD_REDUCTION)) != 0)
+ | GOVD_PRIVATE | GOVD_REDUCTION
+ | GOVD_LINEAR)) != 0)
break;
ctx = ctx->outer_context;
}
@@ -6334,6 +6374,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
code = OMP_CLAUSE_PRIVATE;
else if (flags & GOVD_FIRSTPRIVATE)
code = OMP_CLAUSE_FIRSTPRIVATE;
+ else if (flags & GOVD_LASTPRIVATE)
+ code = OMP_CLAUSE_LASTPRIVATE;
else
gcc_unreachable ();
@@ -6366,6 +6408,7 @@ gimplify_adjust_omp_clauses (tree *list_p)
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_SHARED:
case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_LINEAR:
decl = OMP_CLAUSE_DECL (c);
n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
remove = !(n->value & GOVD_SEEN);
@@ -6381,6 +6424,31 @@ gimplify_adjust_omp_clauses (tree *list_p)
OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
}
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && ctx->outer_context
+ && !(OMP_CLAUSE_LINEAR_NO_COPYIN (c)
+ && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
+ && !is_global_var (decl))
+ {
+ if (ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
+ {
+ n = splay_tree_lookup (ctx->outer_context->variables,
+ (splay_tree_key) decl);
+ if (n == NULL
+ || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
+ {
+ int flags = OMP_CLAUSE_LINEAR_NO_COPYIN (c)
+ ? GOVD_LASTPRIVATE : GOVD_SHARED;
+ if (n == NULL)
+ omp_add_variable (ctx->outer_context, decl,
+ flags | GOVD_SEEN);
+ else
+ n->value |= flags | GOVD_SEEN;
+ }
+ }
+ else
+ omp_notice_variable (ctx->outer_context, decl, true);
+ }
}
break;
@@ -6406,6 +6474,7 @@ gimplify_adjust_omp_clauses (tree *list_p)
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_SAFELEN:
break;
default:
@@ -6509,14 +6578,40 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gimple gfor;
gimple_seq for_body, for_pre_body;
int i;
+ bool simd;
+ bitmap has_decl_expr = NULL;
for_stmt = *expr_p;
+ simd = TREE_CODE (for_stmt) == OMP_SIMD;
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
- ORT_WORKSHARE);
+ simd ? ORT_SIMD : ORT_WORKSHARE);
/* Handle OMP_FOR_INIT. */
for_pre_body = NULL;
+ if (simd && OMP_FOR_PRE_BODY (for_stmt))
+ {
+ has_decl_expr = BITMAP_ALLOC (NULL);
+ if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
+ && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
+ == VAR_DECL)
+ {
+ t = OMP_FOR_PRE_BODY (for_stmt);
+ bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
+ }
+ else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator si;
+ for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
+ tsi_next (&si))
+ {
+ t = tsi_stmt (si);
+ if (TREE_CODE (t) == DECL_EXPR
+ && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
+ bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
+ }
+ }
+ }
gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
@@ -6535,7 +6630,44 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
|| POINTER_TYPE_P (TREE_TYPE (decl)));
/* Make sure the iteration variable is private. */
- if (omp_is_private (gimplify_omp_ctxp, decl))
+ tree c = NULL_TREE;
+ if (simd)
+ {
+ splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
+ (splay_tree_key)decl);
+ omp_is_private (gimplify_omp_ctxp, decl, simd);
+ if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
+ omp_notice_variable (gimplify_omp_ctxp, decl, true);
+ else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
+ OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
+ if (has_decl_expr
+ && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
+ OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
+ OMP_CLAUSE_DECL (c) = decl;
+ OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
+ OMP_FOR_CLAUSES (for_stmt) = c;
+ omp_add_variable (gimplify_omp_ctxp, decl,
+ GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
+ }
+ else
+ {
+ bool lastprivate
+ = (!has_decl_expr
+ || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
+ c = build_omp_clause (input_location,
+ lastprivate ? OMP_CLAUSE_LASTPRIVATE
+ : OMP_CLAUSE_PRIVATE);
+ OMP_CLAUSE_DECL (c) = decl;
+ OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
+ omp_add_variable (gimplify_omp_ctxp, decl,
+ (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
+ | GOVD_SEEN);
+ c = NULL_TREE;
+ }
+ }
+ else if (omp_is_private (gimplify_omp_ctxp, decl, simd))
omp_notice_variable (gimplify_omp_ctxp, decl, true);
else
omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
@@ -6577,6 +6709,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
t = build_int_cst (TREE_TYPE (decl), 1);
+ if (c)
+ OMP_CLAUSE_LINEAR_STEP (c) = t;
t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
@@ -6585,6 +6719,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR:
t = build_int_cst (TREE_TYPE (decl), -1);
+ if (c)
+ OMP_CLAUSE_LINEAR_STEP (c) = t;
t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
@@ -6618,6 +6754,20 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
is_gimple_val, fb_rvalue);
ret = MIN (ret, tret);
+ if (c)
+ {
+ OMP_CLAUSE_LINEAR_STEP (c) = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == MINUS_EXPR)
+ {
+ t = TREE_OPERAND (t, 1);
+ OMP_CLAUSE_LINEAR_STEP (c)
+ = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
+ tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
+ &for_pre_body, NULL,
+ is_gimple_val, fb_rvalue);
+ ret = MIN (ret, tret);
+ }
+ }
break;
default:
@@ -6648,11 +6798,21 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
}
+ BITMAP_FREE (has_decl_expr);
+
gimplify_and_add (OMP_FOR_BODY (for_stmt), &for_body);
gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt));
- gfor = gimple_build_omp_for (for_body, OMP_FOR_CLAUSES (for_stmt),
+ int kind;
+ switch (TREE_CODE (for_stmt))
+ {
+ case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
+ case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
+ default:
+ gcc_unreachable ();
+ }
+ gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (for_stmt),
TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
for_pre_body);
@@ -6669,7 +6829,10 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
gimplify_seq_add_stmt (pre_p, gfor);
- return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR;
+ if (ret != GS_ALL_DONE)
+ return GS_ERROR;
+ *expr_p = NULL_TREE;
+ return GS_ALL_DONE;
}
/* Gimplify the gross structure of other OpenMP worksharing constructs.
@@ -7587,6 +7750,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
break;
case OMP_FOR:
+ case OMP_SIMD:
ret = gimplify_omp_for (expr_p, pre_p);
break;