case NE_EXPR:
-         if (!flag_enable_cilk)
+         /* NE_EXPR is only allowed for Cilk Plus loops.  */
+         if (flag_enable_cilk

Very weird name of a flag.  Should have been flag_cilk or flag_cilkplus
IMHO.

I know. It was already there from Balaji's first iteration with array notation. I've asked him to submit a patch. If he can't, I'll post a separate patch to trunk next week.

I've fixed everything else Richard and you pointed out, with the exception of:

    if (copyin_by_ref || lastprivate_firstprivate)
      {
-      /* Don't add any barrier for #pragma omp simd.  */
+      /* Don't add any barrier for #pragma omp simd or #pragma simd.  */
        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))
        gimplify_and_add (build_omp_barrier (), ilist);

This one will clash with a change I'm working on right now (we don't
want a barrier for distribute either, so this is now
|| gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR

Did you mean "|| gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_SIMD)" here basically leaving things as they are, or did you actually mean change the original "!=" to "=="? I'm confused.

Otherwise, how does this look?

BTW, yes, I still need to massage the C++ FE appropriately.
diff --git a/gcc/ChangeLog.cilkplus b/gcc/ChangeLog.cilkplus
index 6a48ada..352d724 100644
--- a/gcc/ChangeLog.cilkplus
+++ b/gcc/ChangeLog.cilkplus
@@ -1,9 +1,25 @@
-2013-05-13  Aldy Hernandez  <al...@redhat.com>
+2013-06-20  Aldy Hernandez  <al...@redhat.com>
            Balaji V. Iyer  <balaji.v.i...@intel.com>
 
        * Makefile.in (C_COMMON_OBJS): Depend on c-family/c-cilkplus.o.
        (c-cilkplus.o): New dependency.
        * omp-low.c (extract_omp_for_data): Add case for NE_EXPR.
+       (build_outer_var_ref): Check for GF_OMP_FOR_KIND_SIMD bitwise.
+       (check_omp_nesting_restrictions): Same.
+       (lower_rec_input_clauses): Same.
+       (expand_omp_for): Same.
+       (lower_omp_for): Same.
+       (diagnose_sb_0): Adjust for Cilk Plus for loops.
+       (gate_expand_omp): Check for Cilk Plus.
+       (execute_lower_omp): Same.
+       (gate_diagnose_omp_blocks): Same.
+       * tree.def (CILK_SIMD): New entry.
+       * tree-pretty-print.c (dump_generic_node): Add case for CILK_SIMD.
+       * gimple-pretty-print.c (dump_gimple_omp_for): Add case for
+       GF_OMP_FOR_KIND_CILKSIMD.
+       * gimplify.c (gimplify_omp_for): Add case for CILK_SIMD.
+       (gimplify_expr): Same.
+       (is_gimple_stmt): Same.
 
 c-family/
        * c-cilkplus.c: New.
diff --git a/gcc/c-family/c-cilkplus.c b/gcc/c-family/c-cilkplus.c
index 12097e0..861bcbc 100644
--- a/gcc/c-family/c-cilkplus.c
+++ b/gcc/c-family/c-cilkplus.c
@@ -120,24 +120,8 @@ c_validate_cilk_plus_loop (tree *tp, int *walk_subtrees, 
void *data)
 
   bool *valid = (bool *) data;
 
-  /* FIXME: Jumps are disallowed into or out of the body of a
-     _Cilk_for.  We can't just check for GOTO_EXPR here, since
-     GOTO_EXPR's can also be generated by switches and loops.
-
-     We should check for this case after we have built the CFG,
-     possibly at OMP expansion (ompexp).  However, since by then we
-     have expanded the _Cilk_for into an OMP_FOR, we should probably
-     set a tree bit in OMP_FOR differentiating it from the Cilk SIMD
-     construct and handle it appropriately.  */
-
   switch (TREE_CODE (*tp))
     {
-    case RETURN_EXPR:
-      error_at (EXPR_LOCATION (*tp), "return statments are not allowed "
-               "within loops annotated with #pragma simd");
-      *valid = false;
-      *walk_subtrees = 0;
-      break;
     case CALL_EXPR:
       {
        tree fndecl = CALL_EXPR_FN (*tp);
@@ -358,23 +342,11 @@ c_finish_cilk_simd_loop (location_t loc,
   TREE_VEC_ELT (condv, 0) = cond;
   TREE_VEC_ELT (incrv, 0) = incr;
 
-  /* The OpenMP <#pragma omp simd> construct is exactly the same as
-     the Cilk Plus one, with the exception of the vectorlength()
-     clause in Cilk Plus.  Emitting an OMP_SIMD simlifies
-     everything.  */
-  tree t = make_node (OMP_SIMD);
+  tree t = make_node (CILK_SIMD);
   TREE_TYPE (t) = void_type_node;
   OMP_FOR_INIT (t) = initv;
-
-  /* ?? The spec says "The increment and limit expressions may be
-     evaluated fewer times than in the serialization.  If different
-     evaluations of the same expression yield different values, the
-     behavior of the program is undefined."  Perhaps the RHS of the
-     condition and increment could be wrapped in a SAVE_EXPR to
-     evaluate only once.  */
   OMP_FOR_COND (t) = condv;
   OMP_FOR_INCR (t) = incrv;
-
   OMP_FOR_BODY (t) = body;
   OMP_FOR_PRE_BODY (t) = NULL;
   OMP_FOR_CLAUSES (t) = adjust_clauses_for_omp (clauses);
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 3793bd9..c20d91c 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -12123,11 +12123,6 @@ c_parser_cilk_simd_construct (c_parser *parser)
 {
   tree clauses = c_parser_cilk_all_clauses (parser);
 
-  /* For <#pragma simd> we will be generating OMP_SIMD's and let the
-     OpenMP mechanism handle everything.  */
-  if (!flag_openmp)
-    flag_openmp = true;
-
   c_parser_cilk_for_statement (parser, RID_FOR, clauses);
 }
 
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index bced6c3..a4ef585 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -30420,10 +30420,6 @@ cp_parser_cilk_simd_construct (cp_parser *parser, 
cp_token *pragma_token)
       return;
     }
 
-  /* #pragma simd is built on top of OpenMP 4.0's OMP_SIMD trees.  */
-  if (!flag_openmp)
-    flag_openmp = true;
-
   tree sb = begin_omp_structured_block ();
   int save = cp_parser_begin_omp_structured_block (parser);
   cp_parser_cilk_for (parser, RID_FOR, clauses);
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index ba7993a..8c92b5b 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1110,6 +1110,9 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, 
int spc, int flags)
        case GF_OMP_FOR_KIND_SIMD:
          kind = " simd";
          break;
+       case GF_OMP_FOR_KIND_CILKSIMD:
+         kind = " cilksimd";
+         break;
        case GF_OMP_FOR_KIND_DISTRIBUTE:
          kind = " distribute";
          break;
@@ -1141,6 +1144,9 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, 
int spc, int flags)
        case GF_OMP_FOR_KIND_SIMD:
          pp_string (buffer, "#pragma omp simd");
          break;
+       case GF_OMP_FOR_KIND_CILKSIMD:
+         pp_string (buffer, "#pragma simd");
+         break;
        case GF_OMP_FOR_KIND_DISTRIBUTE:
          pp_string (buffer, "#pragma omp distribute");
          break;
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 08dacc5..6987df5 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -111,9 +111,10 @@ enum gf_mask {
     GF_CALL_INTERNAL           = 1 << 6,
     GF_OMP_PARALLEL_COMBINED   = 1 << 0,
     GF_OMP_FOR_KIND_MASK       = 3 << 0,
-    GF_OMP_FOR_KIND_FOR                = 0 << 0,
-    GF_OMP_FOR_KIND_SIMD       = 1 << 0,
-    GF_OMP_FOR_KIND_DISTRIBUTE = 2 << 0,
+    GF_OMP_FOR_KIND_FOR                = 0 << 0, /* #pragma omp for */
+    GF_OMP_FOR_KIND_DISTRIBUTE = 1 << 0, /* #pragma omp distribute */
+    GF_OMP_FOR_KIND_SIMD       = 2 << 0, /* #pragma omp simd */
+    GF_OMP_FOR_KIND_CILKSIMD   = 3 << 0, /* (Cilk Plus) #pragma simd */
     GF_OMP_FOR_COMBINED                = 4 << 0,
     GF_OMP_TARGET_KIND_MASK    = 3 << 0,
     GF_OMP_TARGET_KIND_REGION  = 0 << 0,
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 78ba9da..b4cddb0 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -4716,6 +4716,7 @@ is_gimple_stmt (tree t)
     case OMP_PARALLEL:
     case OMP_FOR:
     case OMP_SIMD:
+    case CILK_SIMD:
     case OMP_DISTRIBUTE:
     case OMP_SECTIONS:
     case OMP_SECTION:
@@ -6868,10 +6869,10 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
 
   orig_for_stmt = for_stmt = *expr_p;
 
-  simd = TREE_CODE (for_stmt) == OMP_SIMD;
+  simd = TREE_CODE (for_stmt) == OMP_SIMD
+    || TREE_CODE (for_stmt) == CILK_SIMD;
   gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
-                            TREE_CODE (for_stmt) == OMP_SIMD
-                            ? ORT_SIMD : ORT_WORKSHARE);
+                            simd ? ORT_SIMD : ORT_WORKSHARE);
 
   /* Handle OMP_FOR_INIT.  */
   for_pre_body = NULL;
@@ -7108,6 +7109,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
     {
     case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
     case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
+    case CILK_SIMD: kind = GF_OMP_FOR_KIND_CILKSIMD; break;
     case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
     default:
       gcc_unreachable ();
@@ -8112,6 +8114,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
 
        case OMP_FOR:
        case OMP_SIMD:
+       case CILK_SIMD:
        case OMP_DISTRIBUTE:
          ret = gimplify_omp_for (expr_p, pre_p);
          break;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 0065443..45831cf 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -223,7 +223,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 non_ws = gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_SIMD;
+  bool non_ws = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_KIND_SIMD;
   bool distribute = gimple_omp_for_kind (for_stmt)
                    == GF_OMP_FOR_KIND_DISTRIBUTE;
 
@@ -317,10 +317,8 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data 
*fd,
        case GT_EXPR:
          break;
        case NE_EXPR:
-         if (!flag_enable_cilk)
-           gcc_unreachable ();
-         /* NE_EXPR is technically not allowed in OpenMP, but it is
-            allowed in Cilk Plus, which generates OMP_SIMD constructs.  */
+         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)))
@@ -945,7 +943,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.  */
@@ -1891,7 +1889,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");
@@ -1922,7 +1920,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)
        {
@@ -2763,9 +2761,9 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, 
gimple_seq *dlist,
      happens after firstprivate copying in all threads.  */
   if (copyin_by_ref || lastprivate_firstprivate)
     {
-      /* Don't add any barrier for #pragma omp simd.  */
+      /* Don't add any barrier for #pragma omp simd or #pragma simd.  */
       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))
        gimplify_and_add (build_omp_barrier (), ilist);
     }
 }
@@ -5511,7 +5509,7 @@ expand_omp_for (struct omp_region *region)
        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
@@ -6628,7 +6626,7 @@ execute_expand_omp (void)
 static bool
 gate_expand_omp (void)
 {
-  return (flag_openmp != 0 && !seen_error ());
+  return ((flag_openmp || flag_enable_cilk) && !seen_error ());
 }
 
 struct gimple_opt_pass pass_expand_omp =
@@ -7203,7 +7201,7 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context 
*ctx)
   /* Once lowered, extract the bounds and clauses.  */
   extract_omp_for_data (stmt, &fd, NULL);
 
-  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))
     lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
 
   gimple_seq_add_stmt (&body, stmt);
@@ -7220,7 +7218,7 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context 
*ctx)
 
   /* Region exit marker goes at the end of the loop body.  */
   gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
-  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)
     {
       dlist = NULL;
       lower_lastprivate_clauses (gimple_omp_for_clauses (fd.for_stmt),
@@ -7785,7 +7783,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)
+  if (!flag_openmp && !flag_enable_cilk)
     return 0;
 
   all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
@@ -7888,12 +7886,33 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
     error ("invalid entry to OpenMP structured block");
 #endif
 
+  bool cilkplus_block = false;
+  if (flag_enable_cilk)
+    {
+      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;
@@ -8076,7 +8095,7 @@ diagnose_omp_structured_block_errors (void)
 static bool
 gate_diagnose_omp_blocks (void)
 {
-  return flag_openmp != 0;
+  return flag_openmp || flag_enable_cilk;
 }
 
 struct gimple_opt_pass pass_diagnose_omp_blocks =
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c 
b/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c
index fe8b630..e8e2066 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/body.c
@@ -11,8 +11,6 @@ void foo()
 #pragma simd
   for (int i=0; i < 1000; ++i)
     {
-      if (c == 5)
-       return;  /* { dg-error "\(return statments are not allowed\|invalid 
exit\)" } */
       if (c == 6)
        __builtin_setjmp (jmpbuf); /* { dg-error "calls to setjmp are not 
allowed" } */
       a[i] = b[i];
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/jump.c 
b/gcc/testsuite/gcc.dg/cilk-plus/jump.c
new file mode 100644
index 0000000..9ec3293
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/jump.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+int *a, *b, c;
+
+void foo()
+{
+#pragma simd
+  for (int i=0; i < 1000; ++i)
+    {
+      a[i] = b[i];
+      if (c == 5)
+       return;  /* { dg-error "invalid branch to.from a Cilk" } */
+    }
+}
+
+void bar()
+{
+#pragma simd
+  for (int i=0; i < 1000; ++i)
+    {
+    lab:
+      a[i] = b[i];
+    }
+  if (c == 6)
+    goto lab; /* { dg-error "invalid entry to Cilk Plus" } */
+}
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 9c3d15e..9c29a5b 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -2364,6 +2364,10 @@ dump_generic_node (pretty_printer *buffer, tree node, 
int spc, int flags,
       pp_string (buffer, "#pragma omp simd");
       goto dump_omp_loop;
 
+    case CILK_SIMD:
+      pp_string (buffer, "#pragma simd");
+      goto dump_omp_loop;
+
     case OMP_DISTRIBUTE:
       pp_string (buffer, "#pragma omp distribute");
       goto dump_omp_loop;
diff --git a/gcc/tree.def b/gcc/tree.def
index a23d5bf..75b4d8a 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -1034,6 +1034,13 @@ DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 6)
    Operands like for OMP_FOR.  */
 DEFTREECODE (OMP_SIMD, "omp_simd", tcc_statement, 6)
 
+/* Cilk Plus - #pragma simd [clause1 ... clauseN]
+   Operands like for OMP_FOR.
+
+   NOTE: This must go between OMP_FOR and OMP_DISTRIBUTE, so
+   OMP_LOOP_CHECK works as expected.  */
+DEFTREECODE (CILK_SIMD, "cilk_simd", tcc_statement, 6)
+
 /* OpenMP - #pragma omp distribute [clause1 ... clauseN]
    Operands like for OMP_FOR.  */
 DEFTREECODE (OMP_DISTRIBUTE, "omp_distribute", tcc_statement, 6)

Reply via email to