aboutsummaryrefslogtreecommitdiff
path: root/gcc/omp-low.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/omp-low.c')
-rw-r--r--gcc/omp-low.c116
1 files changed, 85 insertions, 31 deletions
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 5be9ff8..e2fc53c 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -285,7 +285,7 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
int i;
struct omp_for_data_loop dummy_loop;
location_t loc = gimple_location (for_stmt);
- bool simd = gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_SIMD;
+ bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_KIND_SIMD;
bool distribute = gimple_omp_for_kind (for_stmt)
== GF_OMP_FOR_KIND_DISTRIBUTE;
@@ -377,6 +377,10 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
case LT_EXPR:
case GT_EXPR:
break;
+ case NE_EXPR:
+ gcc_assert (gimple_omp_for_kind (for_stmt)
+ == GF_OMP_FOR_KIND_CILKSIMD);
+ break;
case LE_EXPR:
if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
@@ -1003,7 +1007,7 @@ build_outer_var_ref (tree var, omp_context *ctx)
x = build_receiver_ref (var, by_ref, ctx);
}
else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
{
/* #pragma omp simd isn't a worksharing construct, and can reference even
private vars in its linear etc. clauses. */
@@ -2230,7 +2234,7 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
if (ctx != NULL)
{
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
{
error_at (gimple_location (stmt),
"OpenMP constructs may not be nested inside simd region");
@@ -2253,7 +2257,7 @@ check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
switch (gimple_code (stmt))
{
case GIMPLE_OMP_FOR:
- if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
+ if (gimple_omp_for_kind (stmt) & GF_OMP_FOR_KIND_SIMD)
return true;
if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
{
@@ -2536,6 +2540,23 @@ scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
+/* Return true if FNDECL is a setjmp or a longjmp. */
+
+static bool
+setjmp_or_longjmp_p (const_tree fndecl)
+{
+ if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
+ || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
+ return true;
+
+ tree declname = DECL_NAME (fndecl);
+ if (!declname)
+ return false;
+ const char *name = IDENTIFIER_POINTER (declname);
+ return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
+}
+
/* Helper function for scan_omp.
@@ -2559,22 +2580,33 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
else if (is_gimple_call (stmt))
{
tree fndecl = gimple_call_fndecl (stmt);
- if (fndecl
- && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
- switch (DECL_FUNCTION_CODE (fndecl))
- {
- case BUILT_IN_GOMP_BARRIER:
- case BUILT_IN_GOMP_CANCEL:
- case BUILT_IN_GOMP_CANCELLATION_POINT:
- case BUILT_IN_GOMP_TASKYIELD:
- case BUILT_IN_GOMP_TASKWAIT:
- case BUILT_IN_GOMP_TASKGROUP_START:
- case BUILT_IN_GOMP_TASKGROUP_END:
- remove = !check_omp_nesting_restrictions (stmt, ctx);
- break;
- default:
- break;
- }
+ if (fndecl)
+ {
+ if (setjmp_or_longjmp_p (fndecl)
+ && ctx
+ && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
+ {
+ remove = true;
+ error_at (gimple_location (stmt),
+ "setjmp/longjmp inside simd construct");
+ }
+ else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_GOMP_BARRIER:
+ case BUILT_IN_GOMP_CANCEL:
+ case BUILT_IN_GOMP_CANCELLATION_POINT:
+ case BUILT_IN_GOMP_TASKYIELD:
+ case BUILT_IN_GOMP_TASKWAIT:
+ case BUILT_IN_GOMP_TASKGROUP_START:
+ case BUILT_IN_GOMP_TASKGROUP_END:
+ remove = !check_omp_nesting_restrictions (stmt, ctx);
+ break;
+ default:
+ break;
+ }
+ }
}
if (remove)
{
@@ -2967,7 +2999,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
bool reduction_omp_orig_ref = false;
int pass;
bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD);
int max_vf = 0;
tree lane = NULL_TREE, idx = NULL_TREE;
tree ivar = NULL_TREE, lvar = NULL_TREE;
@@ -3587,7 +3619,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
/* Don't add any barrier for #pragma omp simd or
#pragma omp distribute. */
if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
- || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR)
+ || gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_FOR)
gimple_seq_add_stmt (ilist, build_omp_barrier (NULL_TREE));
}
@@ -3666,7 +3698,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
}
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
{
simduid = find_omp_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
if (simduid)
@@ -3761,7 +3793,7 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
/* SIMD reductions are handled in lower_rec_input_clauses. */
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_KIND_SIMD)
return;
/* First see if there is exactly one reduction clause. Use OMP_ATOMIC
@@ -6794,7 +6826,7 @@ expand_omp_for (struct omp_region *region, gimple inner_stmt)
original loops from being detected. Fix that up. */
loops_state_set (LOOPS_NEED_FIXUP);
- if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_SIMD)
+ if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_KIND_SIMD)
expand_omp_simd (region, &fd);
else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
&& !fd.have_ordered)
@@ -8236,7 +8268,8 @@ execute_expand_omp (void)
static bool
gate_expand_omp (void)
{
- return ((flag_openmp != 0 || flag_openmp_simd != 0) && !seen_error ());
+ return ((flag_openmp != 0 || flag_openmp_simd != 0
+ || flag_enable_cilkplus != 0) && !seen_error ());
}
namespace {
@@ -10057,7 +10090,7 @@ execute_lower_omp (void)
/* This pass always runs, to provide PROP_gimple_lomp.
But there is nothing to do unless -fopenmp is given. */
- if (flag_openmp == 0 && flag_openmp_simd == 0)
+ if (flag_openmp == 0 && flag_openmp_simd == 0 && flag_enable_cilkplus == 0)
return 0;
all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
@@ -10177,12 +10210,33 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
error ("invalid entry to OpenMP structured block");
#endif
+ bool cilkplus_block = false;
+ if (flag_enable_cilkplus)
+ {
+ if ((branch_ctx
+ && gimple_code (branch_ctx) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (branch_ctx) == GF_OMP_FOR_KIND_CILKSIMD)
+ || (gimple_code (label_ctx) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (label_ctx) == GF_OMP_FOR_KIND_CILKSIMD))
+ cilkplus_block = true;
+ }
+
/* If it's obvious we have an invalid entry, be specific about the error. */
if (branch_ctx == NULL)
- error ("invalid entry to OpenMP structured block");
+ {
+ if (cilkplus_block)
+ error ("invalid entry to Cilk Plus structured block");
+ else
+ error ("invalid entry to OpenMP structured block");
+ }
else
- /* Otherwise, be vague and lazy, but efficient. */
- error ("invalid branch to/from an OpenMP structured block");
+ {
+ /* Otherwise, be vague and lazy, but efficient. */
+ if (cilkplus_block)
+ error ("invalid branch to/from a Cilk Plus structured block");
+ else
+ error ("invalid branch to/from an OpenMP structured block");
+ }
gsi_replace (gsi_p, gimple_build_nop (), false);
return true;
@@ -10486,7 +10540,7 @@ diagnose_omp_structured_block_errors (void)
static bool
gate_diagnose_omp_blocks (void)
{
- return flag_openmp != 0;
+ return flag_openmp || flag_enable_cilkplus;
}
namespace {