]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cilk-builtins.def (__cilkrts_cilk_for_32): New.
authorJakub Jelinek <jakub@redhat.com>
Tue, 2 Sep 2014 12:52:29 +0000 (14:52 +0200)
committerKirill Yukhin <kyukhin@gcc.gnu.org>
Tue, 2 Sep 2014 12:52:29 +0000 (12:52 +0000)
gcc/
* cilk-builtins.def (__cilkrts_cilk_for_32): New.
(__cilkrts_cilk_for_64): Likewise.
* cilk-common.c (declare_cilk_for_builtin): New function.
(cilk_init_builtins): Declare __cilkrts_cilk_for_32 and
__cilkrts_cilk_for_64 bultins.
* cilk.h (enum cilk_tree_index): Added CILK_TI_F_LOOP_32 and
CILK_TI_F_LOOP_64.
(cilk_for_32_fndecl): New define.
(cilk_for_64_fndecl): Likewise.
* gimple-pretty-print.c (dump_gimple_omp_for): Correct hadling of
GF_OMP_FOR_KIND_CILKFOR cases; Added NE_EXPR case.
* gimple.h (enum gf_mask): Added GF_OMP_FOR_KIND_CILKFOR; adjusted
GF_OMP_FOR_KIND_MASK, GF_OMP_FOR_SIMD, GF_OMP_FOR_COMBINED,
GF_OMP_FOR_COMBINED_INTO.
* gimplify.c (gimplify_scan_omp_clauses): Added
OMP_CLAUSE__CILK_FOR_COUNT_ case.
(gimplify_adjust_omp_clauses): Ditto.
(gimplify_omp_for): Added CILK_FOR case.
(gimplify_expr): Ditto.
* omp-low.c: Include cilk.h.
(extract_omp_for_data): Set appropriate kind for
GF_OMP_FOR_KIND_CILKFOR; added check for GF_OMP_FOR_KIND_CILKFOR.
(scan_sharing_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_ cases.
(create_omp_child_function_name): Added second argument to handle
cilk_for case.
(cilk_for_check_loop_diff_type): New function.
(expand_cilk_for_call): Likewise.
(expand_cilk_for): Likewise.
(create_omp_child_function): Set cilk_for_count; handle the cases when
it is true; call create_omp_child_function_name with second argument.
(expand_omp_taskreg): Set is_cilk_for and handle cases when it's true.
(expand_omp_for): Handle case of GF_OMP_FOR_KIND_CILKFOR.
* tree-core.h (omp_clause_code): Added OMP_CLAUSE__CILK_FOR_COUNT_.
* tree-nested.c (convert_nonlocal_omp_clauses): Added
OMP_CLAUSE__CILK_FOR_COUNT_ case.
(convert_local_omp_clauses): Ditto.
* tree-pretty-print.c (dump_omp_clause): Added
OMP_CLAUSE__CILK_FOR_COUNT_ and OMP_CLAUSE_SCHEDULE_CILKFOR cases.
(dump_generic_node): Added CILK_FOR case.
* tree.c (omp_clause_num_ops): New element
OMP_CLAUSE__CILK_FOR_COUNT_ (1).
(omp_clause_code_name): New element _Cilk_for_count_.
(walk_tree_1): Added OMP_CLAUSE__CILK_FOR_COUNT_ case.
* tree.def: Add tree code for CILK_FOR.

gcc/c/
* c-parser.c (c_parser_cilk_for): New function.
(c_parser_cilk_grainsize): Likewise.
(c_get_temp_regvar): Likewise.
(c_parser_statement_after_labels): Added RID_CILK_FOR case.
(c_parser_pragma): Added PRAGMA_CILK_GRAINSIZE case.
(c_parser_omp_for_loop): Added CILK_FOR and CILK_SIMD checks.
* c-typeck.c (c_finish_omp_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_
case.

gcc/cp/
* cp-cilkplus.c (cpp_validate_cilk_plus_loop_aux): Loc definition
simplified.
* parser.c (cp_parser_cilk_for): New function.
(cp_parser_cilk_grainsize): Likewise.
(cp_parser_statement): Added RID_CILK_FOR case.
(cp_parser_omp_for_cond): Added CILK_FOR check.
(cp_parser_omp_for_loop_init): Change function argument to accept
tree_code instead just a bool flag; change the check to use that
tree_code; check for initialization declaration in case of Cilk_for.
(cp_parser_omp_for_loop): Added checks for CILK_FOR and RID_CILK_FOR;
changed call to cp_parser_omp_for_loop_init according new arguments'
list.
(cp_parser_pragma): Added PRAGMA_CILK_GRAINSIZE case.
* pt.c (tsubst_expr): Added CILK_FOR case.
* semantics.c: Include convert.h.
(finish_omp_clauses): Properly handle OMP_CLAUSE_SCHEDULE_CILKFOR
case; added OMP_CLAUSE__CILK_FOR_COUNT_.
(handle_omp_for_class_iterator): New argument lastp and its usage;
added NE_EXPR case.
(finish_omp_for): Changed call to handle_omp_for_class_iterator
according new arguments' list; in case of Cilk_for save very first
decl and create empty stmt_list block; use block to build correct
statement tree.

gcc/c-family/
* c-cilkplus.c (cilk_for_number_of_iterations): New function.
* c-common.c (c_common_reswords): Added _Cilk_for.
* c-common.h (enum rid): Added RID_CILK_FOR.
(cilk_for_number_of_iterations): Add declaration.
* c-omp.c (c_finish_omp_for): Added checks for CILK_SIMD and
CILK_FOR.
* c-pragma.c (init_pragma): Register "grainsize" pragma.
* c-pragma.h (enum pragma_kind): Add PRAGMA_CILK_GRAINSIZE.

gcc/testsuite/
* c-c++-common/cilk-plus/CK/cilk-fors.c: New test.
* c-c++-common/cilk-plus/CK/cilk-for-2.c: New test.
* c-c++-common/cilk-plus/CK/cilk-for-3.c: New test.
* c-c++-common/cilk-plus/CK/cilk_for_errors.c: New test.
* c-c++-common/cilk-plus/CK/cilk_for_grain.c: New test.
* c-c++-common/cilk-plus/CK/cilk_for_grain_errors.c: New test.
* c-c++-common/cilk-plus/CK/cilk_for_ptr_iter.c: New test.
* c-c++-common/cilk-plus/CK/nested_cilk_for.c: New test.
* g++.dg/cilk-plus/CK/cf3.cc: New test.
* g++.dg/cilk-plus/CK/cilk-for-tplt.cc: New test.
* g++.dg/cilk-plus/CK/for1.cc: New test.
* g++.dg/cilk-plus/CK/stl_iter.cc: New test.
* g++.dg/cilk-plus/CK/stl_rev_iter.cc: New test.
* g++.dg/cilk-plus/CK/stl_test.cc: New test.

Co-Authored-By: Balaji V. Iyer <balaji.v.iyer@intel.com>
Co-Authored-By: Igor Zamyatin <igor.zamyatin@intel.com>
From-SVN: r214818

43 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-cilkplus.c
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c-family/c-omp.c
gcc/c-family/c-pragma.c
gcc/c-family/c-pragma.h
gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/c/c-typeck.c
gcc/cilk-builtins.def
gcc/cilk-common.c
gcc/cilk.h
gcc/cp/ChangeLog
gcc/cp/cp-cilkplus.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/gimple-pretty-print.c
gcc/gimple.h
gcc/gimplify.c
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-for-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-for-3.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-fors.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_errors.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_grain.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_grain_errors.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_ptr_iter.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/CK/nested_cilk_for.c [new file with mode: 0644]
gcc/testsuite/g++.dg/cilk-plus/CK/cf3.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/cilk-plus/CK/cilk-for-tplt.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/cilk-plus/CK/for1.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/cilk-plus/CK/stl_iter.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/cilk-plus/CK/stl_rev_iter.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/cilk-plus/CK/stl_test.cc [new file with mode: 0644]
gcc/tree-core.h
gcc/tree-nested.c
gcc/tree-pretty-print.c
gcc/tree.c
gcc/tree.def

index b615fab05d69f235098ad37ee7b2b14d7026823b..a59c8a4cd8c71c97a3b08fd2bd9a250623aa8fdb 100644 (file)
@@ -1,3 +1,52 @@
+2014-09-02  Jakub Jelinek  <jakub@redhat.com>
+           Balaji V. Iyer  <balaji.v.iyer@intel.com>
+           Igor Zamyatin  <igor.zamyatin@intel.com>
+
+       * cilk-builtins.def (__cilkrts_cilk_for_32): New.
+       (__cilkrts_cilk_for_64): Likewise.
+       * cilk-common.c (declare_cilk_for_builtin): New function.
+       (cilk_init_builtins): Declare __cilkrts_cilk_for_32 and
+       __cilkrts_cilk_for_64 bultins.
+       * cilk.h (enum cilk_tree_index): Added CILK_TI_F_LOOP_32 and
+       CILK_TI_F_LOOP_64.
+       (cilk_for_32_fndecl): New define.
+       (cilk_for_64_fndecl): Likewise.
+       * gimple-pretty-print.c (dump_gimple_omp_for): Correct hadling of
+       GF_OMP_FOR_KIND_CILKFOR cases; Added NE_EXPR case.
+       * gimple.h (enum gf_mask): Added GF_OMP_FOR_KIND_CILKFOR; adjusted
+       GF_OMP_FOR_KIND_MASK, GF_OMP_FOR_SIMD, GF_OMP_FOR_COMBINED,
+       GF_OMP_FOR_COMBINED_INTO.
+       * gimplify.c (gimplify_scan_omp_clauses): Added
+       OMP_CLAUSE__CILK_FOR_COUNT_ case.
+       (gimplify_adjust_omp_clauses): Ditto.
+       (gimplify_omp_for): Added CILK_FOR case.
+       (gimplify_expr): Ditto.
+       * omp-low.c: Include cilk.h.
+       (extract_omp_for_data): Set appropriate kind for
+       GF_OMP_FOR_KIND_CILKFOR; added check for GF_OMP_FOR_KIND_CILKFOR.
+       (scan_sharing_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_ cases.
+       (create_omp_child_function_name): Added second argument to handle
+       cilk_for case.
+       (cilk_for_check_loop_diff_type): New function.
+       (expand_cilk_for_call): Likewise.
+       (expand_cilk_for): Likewise.
+       (create_omp_child_function): Set cilk_for_count; handle the cases when
+       it is true; call create_omp_child_function_name with second argument.
+       (expand_omp_taskreg): Set is_cilk_for and handle cases when it's true.
+       (expand_omp_for): Handle case of GF_OMP_FOR_KIND_CILKFOR.
+       * tree-core.h (omp_clause_code): Added OMP_CLAUSE__CILK_FOR_COUNT_.
+       * tree-nested.c (convert_nonlocal_omp_clauses): Added
+       OMP_CLAUSE__CILK_FOR_COUNT_ case.
+       (convert_local_omp_clauses): Ditto.
+       * tree-pretty-print.c (dump_omp_clause): Added
+       OMP_CLAUSE__CILK_FOR_COUNT_ and OMP_CLAUSE_SCHEDULE_CILKFOR cases.
+       (dump_generic_node): Added CILK_FOR case.
+       * tree.c (omp_clause_num_ops): New element
+       OMP_CLAUSE__CILK_FOR_COUNT_ (1).
+       (omp_clause_code_name): New element _Cilk_for_count_.
+       (walk_tree_1): Added OMP_CLAUSE__CILK_FOR_COUNT_ case.
+       * tree.def: Add tree code for CILK_FOR.
+
 2014-09-02  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * config/rs6000/40x.md (ppc403-integer): Move "exts" to "no dot".
index 762f7e9a71fc6d774a34e0064ca3be45b80c8b63..fdcaa0d2392c177a715bfb0efc296314c58ad48d 100644 (file)
@@ -1,3 +1,16 @@
+2014-09-02  Jakub Jelinek  <jakub@redhat.com>
+           Balaji V. Iyer  <balaji.v.iyer@intel.com>
+           Igor Zamyatin  <igor.zamyatin@intel.com>
+
+       * c-cilkplus.c (cilk_for_number_of_iterations): New function.
+       * c-common.c (c_common_reswords): Added _Cilk_for.
+       * c-common.h (enum rid): Added RID_CILK_FOR.
+       (cilk_for_number_of_iterations): Add declaration.
+       * c-omp.c (c_finish_omp_for): Added checks for CILK_SIMD and
+       CILK_FOR.
+       * c-pragma.c (init_pragma): Register "grainsize" pragma.
+       * c-pragma.h (enum pragma_kind): Add PRAGMA_CILK_GRAINSIZE.
+
 2014-08-29  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        * c.opt (Wbuiltin-macro-redefined,Wdeprecated,Wendif-labels,
index 1a16f6690b067b2c36488e59dc52b688b212abfd..131da0b3fea0f153ced2b8de429904877c13a886 100644 (file)
@@ -91,3 +91,136 @@ c_finish_cilk_clauses (tree clauses)
     }
   return clauses;
 }
+
+/* Calculate number of iterations of CILK_FOR.  */
+
+tree
+cilk_for_number_of_iterations (tree cilk_for)
+{
+  tree t, v, n1, n2, step, type, init, cond, incr, itype;
+  enum tree_code cond_code;
+  location_t loc = EXPR_LOCATION (cilk_for);
+
+  init = TREE_VEC_ELT (OMP_FOR_INIT (cilk_for), 0);
+  v = TREE_OPERAND (init, 0);
+  cond = TREE_VEC_ELT (OMP_FOR_COND (cilk_for), 0);
+  incr = TREE_VEC_ELT (OMP_FOR_INCR (cilk_for), 0);
+  type = TREE_TYPE (v);
+
+  gcc_assert (TREE_CODE (TREE_TYPE (v)) == INTEGER_TYPE
+             || TREE_CODE (TREE_TYPE (v)) == POINTER_TYPE);
+  n1 = TREE_OPERAND (init, 1);
+  cond_code = TREE_CODE (cond);
+  n2 = TREE_OPERAND (cond, 1);
+  switch (cond_code)
+    {
+    case LT_EXPR:
+    case GT_EXPR:
+    case NE_EXPR:
+      break;
+    case LE_EXPR:
+      if (POINTER_TYPE_P (TREE_TYPE (n2)))
+       n2 = fold_build_pointer_plus_hwi_loc (loc, n2, 1);
+      else
+       n2 = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (n2), n2,
+                             build_int_cst (TREE_TYPE (n2), 1));
+      cond_code = LT_EXPR;
+      break;
+    case GE_EXPR:
+      if (POINTER_TYPE_P (TREE_TYPE (n2)))
+       n2 = fold_build_pointer_plus_hwi_loc (loc, n2, -1);
+      else
+       n2 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (n2), n2,
+                             build_int_cst (TREE_TYPE (n2), 1));
+      cond_code = GT_EXPR;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  step = NULL_TREE;
+  switch (TREE_CODE (incr))
+    {
+    case PREINCREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
+      step = build_int_cst (TREE_TYPE (v), 1);
+      break;
+    case PREDECREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
+      step = build_int_cst (TREE_TYPE (v), -1);
+      break;
+    case MODIFY_EXPR:
+      t = TREE_OPERAND (incr, 1);
+      gcc_assert (TREE_OPERAND (t, 0) == v);
+      switch (TREE_CODE (t))
+       {
+       case PLUS_EXPR:
+         step = TREE_OPERAND (t, 1);
+         break;
+       case POINTER_PLUS_EXPR:
+         step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
+         break;
+       case MINUS_EXPR:
+         step = TREE_OPERAND (t, 1);
+         step = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (step), step);
+         break;
+       default:
+         gcc_unreachable ();
+       }
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  itype = type;
+  if (POINTER_TYPE_P (itype))
+    itype = signed_type_for (itype);
+  if (cond_code == NE_EXPR)
+    {
+      /* For NE_EXPR, we need to find out if the iterator increases
+        or decreases from whether step is positive or negative.  */
+      tree stype = itype;
+      if (TYPE_UNSIGNED (stype))
+       stype = signed_type_for (stype);
+      cond = fold_build2_loc (loc, GE_EXPR, boolean_type_node,
+                             fold_convert_loc (loc, stype, step),
+                             build_int_cst (stype, 0));
+      t = fold_build3_loc (loc, COND_EXPR, itype, cond,
+                          build_int_cst (itype, -1),
+                          build_int_cst (itype, 1));
+    }
+  else
+    t = build_int_cst (itype, (cond_code == LT_EXPR ? -1 : 1));
+  t = fold_build2_loc (loc, PLUS_EXPR, itype,
+                      fold_convert_loc (loc, itype, step), t);
+  t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
+                      fold_convert_loc (loc, itype, n2));
+  t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
+                      fold_convert_loc (loc, itype, n1));
+  if (TYPE_UNSIGNED (itype) && cond_code == GT_EXPR)
+    t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
+                        fold_build1_loc (loc, NEGATE_EXPR, itype, t),
+                        fold_build1_loc (loc, NEGATE_EXPR, itype,
+                                         fold_convert_loc (loc, itype,
+                                                           step)));
+  else if (TYPE_UNSIGNED (itype) && cond_code == NE_EXPR)
+    {
+      tree t1
+       = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
+                          fold_convert_loc (loc, itype, step));
+      tree t2
+       = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
+                          fold_build1_loc (loc, NEGATE_EXPR, itype, t),
+                          fold_build1_loc (loc, NEGATE_EXPR, itype,
+                                           fold_convert_loc (loc, itype,
+                                                             step)));
+      t = fold_build3_loc (loc, COND_EXPR, itype, cond, t1, t2);
+    }
+  else
+    t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
+                        fold_convert_loc (loc, itype, step));
+  cond = fold_build2_loc (loc, cond_code, boolean_type_node, n1, n2);
+  t = fold_build3_loc (loc, COND_EXPR, itype, cond, t,
+                      build_int_cst (itype, 0));
+  return t;
+}
index 58b976378d5e14e23707a5aa81fc63fed1d6947c..16cc5f6ed7afcec4abf245a390c5b837bc40d6e8 100644 (file)
@@ -418,6 +418,7 @@ const struct c_common_resword c_common_reswords[] =
   { "_Complex",                RID_COMPLEX,    0 },
   { "_Cilk_spawn",      RID_CILK_SPAWN, 0 },
   { "_Cilk_sync",       RID_CILK_SYNC,  0 },
+  { "_Cilk_for",        RID_CILK_FOR,   0 },
   { "_Imaginary",      RID_IMAGINARY, D_CONLY },
   { "_Decimal32",       RID_DFLOAT32,  D_CONLY | D_EXT },
   { "_Decimal64",       RID_DFLOAT64,  D_CONLY | D_EXT },
index d1cc810e2a773c1c7e62b9239d997124228f7972..993a97b5a665c4dae679aa4bed7d3d3c69818c05 100644 (file)
@@ -149,7 +149,7 @@ enum rid
   RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT,
 
   /* Cilk Plus keywords.  */
-  RID_CILK_SPAWN, RID_CILK_SYNC,
+  RID_CILK_SPAWN, RID_CILK_SYNC, RID_CILK_FOR,
   
   /* Objective-C ("AT" reserved words - they are only keywords when
      they follow '@')  */
@@ -1395,4 +1395,5 @@ extern tree create_cilk_function_exit (tree, bool, bool);
 extern tree cilk_install_body_pedigree_operations (tree);
 extern void cilk_outline (tree, tree *, void *);
 extern bool contains_cilk_spawn_stmt (tree);
+extern tree cilk_for_number_of_iterations (tree);
 #endif /* ! GCC_C_COMMON_H */
index 6a0e41988a714a7680fe00304cf5469b70d2ad8d..d6ca3df51e8d221d66a3dcc11e6f355a3e3d6704 100644 (file)
@@ -396,7 +396,7 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
   bool fail = false;
   int i;
 
-  if (code == CILK_SIMD
+  if ((code == CILK_SIMD || code == CILK_FOR)
       && !c_check_cilk_loop (locus, TREE_VEC_ELT (declv, 0)))
     fail = true;
 
@@ -515,7 +515,10 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
                  || TREE_CODE (cond) == EQ_EXPR)
                {
                  if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
-                   cond_ok = false;
+                   {
+                     if (code != CILK_SIMD && code != CILK_FOR)
+                       cond_ok = false;
+                   }
                  else if (operand_equal_p (TREE_OPERAND (cond, 1),
                                            TYPE_MIN_VALUE (TREE_TYPE (decl)),
                                            0))
@@ -526,7 +529,7 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
                                            0))
                    TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
                                         ? LT_EXPR : GE_EXPR);
-                 else if (code != CILK_SIMD)
+                 else if (code != CILK_SIMD && code != CILK_FOR)
                    cond_ok = false;
                }
            }
index 804f37cee5167804669c519c5634be1bd05854e6..da928b2abddf1d1749a7f0b6b7967a8169e6745f 100644 (file)
@@ -1405,6 +1405,11 @@ init_pragma (void)
   if (!flag_preprocess_only)
     cpp_register_deferred_pragma (parse_in, "GCC", "ivdep", PRAGMA_IVDEP, false,
                                  false);
+
+  if (flag_cilkplus && !flag_preprocess_only)
+    cpp_register_deferred_pragma (parse_in, "cilk", "grainsize",
+                                 PRAGMA_CILK_GRAINSIZE, true, false);
+
 #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
   c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
 #else
index 6f1bf74c2a91dfe4d5aaa6de10350b19f20288e7..b9f09ba9f98a78d0b743b56ab4b8d0fb804fb151 100644 (file)
@@ -55,6 +55,9 @@ typedef enum pragma_kind {
   /* Top level clause to handle all Cilk Plus pragma simd clauses.  */
   PRAGMA_CILK_SIMD,
 
+  /* This pragma handles setting of grainsize for a _Cilk_for.  */
+  PRAGMA_CILK_GRAINSIZE,
+
   PRAGMA_GCC_PCH_PREPROCESS,
   PRAGMA_IVDEP,
 
index c4661ff0dc894449b46830b744a4bbbf597f6980..2d02c7b9466f30faee8ae39586b43fb1697aa31e 100644 (file)
@@ -1,3 +1,16 @@
+2014-09-02  Jakub Jelinek  <jakub@redhat.com>
+           Balaji V. Iyer  <balaji.v.iyer@intel.com>
+           Igor Zamyatin  <igor.zamyatin@intel.com>
+
+       * c-parser.c (c_parser_cilk_for): New function.
+       (c_parser_cilk_grainsize): Likewise.
+       (c_get_temp_regvar): Likewise.
+       (c_parser_statement_after_labels): Added RID_CILK_FOR case.
+       (c_parser_pragma): Added PRAGMA_CILK_GRAINSIZE case.
+       (c_parser_omp_for_loop): Added CILK_FOR and CILK_SIMD checks.
+       * c-typeck.c (c_finish_omp_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_
+       case.
+
 2014-08-27  Chen Gang  <gang.chen.5i5j@gmail.com>
 
        * c-aux-info.c (gen_type): Resize 'buff' from 10 to 23 bytes,
index 34f1e4701f1ab482b9addf39ca2b2beefc97ccbf..03c68309493429a5f8d67e75ea7803b81ebb5c54 100644 (file)
@@ -1264,9 +1264,11 @@ static bool c_parser_objc_diagnose_bad_element_prefix
 
 /* Cilk Plus supporting routines.  */
 static void c_parser_cilk_simd (c_parser *);
+static void c_parser_cilk_for (c_parser *, tree);
 static bool c_parser_cilk_verify_simd (c_parser *, enum pragma_context);
 static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
 static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool);
+static void c_parser_cilk_grainsize (c_parser *);
 
 /* Parse a translation unit (C90 6.7, C99 6.9).
 
@@ -4895,6 +4897,16 @@ c_parser_statement_after_labels (c_parser *parser)
        case RID_FOR:
          c_parser_for_statement (parser, false);
          break;
+       case RID_CILK_FOR:
+         if (!flag_cilkplus)
+           {
+             error_at (c_parser_peek_token (parser)->location,
+                       "-fcilkplus must be enabled to use %<_Cilk_for%>");
+             c_parser_skip_to_end_of_block_or_statement (parser);
+           }
+         else
+           c_parser_cilk_for (parser, integer_zero_node);
+         break;
        case RID_CILK_SYNC:
          c_parser_consume_token (parser);
          c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
@@ -9582,6 +9594,23 @@ c_parser_pragma (c_parser *parser, enum pragma_context context)
       c_parser_consume_pragma (parser);
       c_parser_cilk_simd (parser);
       return false;
+    case PRAGMA_CILK_GRAINSIZE:
+      if (!flag_cilkplus)
+       {
+         warning (0, "%<#pragma grainsize%> ignored because -fcilkplus is not"
+                  " enabled");
+         c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
+         return false;
+       }
+      if (context == pragma_external)
+       {
+         error_at (c_parser_peek_token (parser)->location,
+                   "%<#pragma grainsize%> must be inside a function");
+         c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
+         return false;
+       }
+      c_parser_cilk_grainsize (parser);
+      return false;
 
     default:
       if (id < PRAGMA_FIRST_EXTERNAL)
@@ -11715,11 +11744,18 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
   condv = make_tree_vec (collapse);
   incrv = make_tree_vec (collapse);
 
-  if (!c_parser_next_token_is_keyword (parser, RID_FOR))
+  if (code != CILK_FOR
+      && !c_parser_next_token_is_keyword (parser, RID_FOR))
     {
       c_parser_error (parser, "for statement expected");
       return NULL;
     }
+  if (code == CILK_FOR
+      && !c_parser_next_token_is_keyword (parser, RID_CILK_FOR))
+    {
+      c_parser_error (parser, "_Cilk_for statement expected");
+      return NULL;
+    }
   for_loc = c_parser_peek_token (parser)->location;
   c_parser_consume_token (parser);
 
@@ -11797,7 +11833,7 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
            case LE_EXPR:
              break;
            case NE_EXPR:
-             if (code == CILK_SIMD)
+             if (code == CILK_SIMD || code == CILK_FOR)
                break;
              /* FALLTHRU.  */
            default:
@@ -13890,8 +13926,48 @@ c_parser_cilk_all_clauses (c_parser *parser)
   return c_finish_cilk_clauses (clauses);
 }
 
-/* Main entry point for parsing Cilk Plus <#pragma simd> for
-   loops.  */
+/* This function helps parse the grainsize pragma for a _Cilk_for statement.
+   Here is the correct syntax of this pragma:
+           #pragma cilk grainsize = <EXP>
+ */
+
+static void
+c_parser_cilk_grainsize (c_parser *parser)
+{
+  extern tree convert_to_integer (tree, tree);
+
+  /* consume the 'grainsize' keyword.  */
+  c_parser_consume_pragma (parser);
+
+  if (c_parser_require (parser, CPP_EQ, "expected %<=%>") != 0)
+    {
+      struct c_expr g_expr = c_parser_binary_expression (parser, NULL, NULL);
+      if (g_expr.value == error_mark_node)
+       {
+         c_parser_skip_to_pragma_eol (parser);
+         return;
+       }
+      tree grain = convert_to_integer (long_integer_type_node,
+                                      c_fully_fold (g_expr.value, false,
+                                                    NULL));
+      c_parser_skip_to_pragma_eol (parser);
+      c_token *token = c_parser_peek_token (parser);
+      if (token && token->type == CPP_KEYWORD
+         && token->keyword == RID_CILK_FOR)
+       {
+         if (grain == NULL_TREE || grain == error_mark_node)
+           grain = integer_zero_node;
+         c_parser_cilk_for (parser, grain);
+       }
+      else
+       warning (0, "%<#pragma cilk grainsize%> is not followed by "
+                   "%<_Cilk_for%>");
+    }
+  else
+    c_parser_skip_to_pragma_eol (parser);
+}
+
+/* Main entry point for parsing Cilk Plus <#pragma simd> for loops.  */
 
 static void
 c_parser_cilk_simd (c_parser *parser)
@@ -13903,6 +13979,105 @@ c_parser_cilk_simd (c_parser *parser)
   block = c_end_compound_stmt (loc, block, true);
   add_stmt (block);
 }
+
+/* Create an artificial decl with TYPE and emit initialization of it with
+   INIT.  */
+
+static tree
+c_get_temp_regvar (tree type, tree init)
+{
+  location_t loc = EXPR_LOCATION (init);
+  tree decl = build_decl (loc, VAR_DECL, NULL_TREE, type);
+  DECL_ARTIFICIAL (decl) = 1;
+  DECL_IGNORED_P (decl) = 1;
+  pushdecl (decl);
+  tree t = build2 (INIT_EXPR, type, decl, init);
+  add_stmt (t);
+  return decl;
+}
+
+/* Main entry point for parsing Cilk Plus _Cilk_for loops.
+  GRAIN is the grain value passed in through pragma or 0.  */
+
+static void
+c_parser_cilk_for (c_parser *parser, tree grain)
+{
+  tree clauses = build_omp_clause (EXPR_LOCATION (grain), OMP_CLAUSE_SCHEDULE);
+  OMP_CLAUSE_SCHEDULE_KIND (clauses) = OMP_CLAUSE_SCHEDULE_CILKFOR;
+  OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clauses) = grain;
+  clauses = c_finish_omp_clauses (clauses);
+
+  tree block = c_begin_compound_stmt (true);
+  tree sb = push_stmt_list ();
+  location_t loc = c_parser_peek_token (parser)->location;
+  tree omp_for = c_parser_omp_for_loop (loc, parser, CILK_FOR, clauses, NULL);
+  sb = pop_stmt_list (sb);
+
+  if (omp_for)
+    {
+      tree omp_par = make_node (OMP_PARALLEL);
+      TREE_TYPE (omp_par) = void_type_node;
+      OMP_PARALLEL_CLAUSES (omp_par) = NULL_TREE;
+      tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+      TREE_SIDE_EFFECTS (bind) = 1;
+      BIND_EXPR_BODY (bind) = sb;
+      OMP_PARALLEL_BODY (omp_par) = bind;
+      if (OMP_FOR_PRE_BODY (omp_for))
+       {
+         add_stmt (OMP_FOR_PRE_BODY (omp_for));
+         OMP_FOR_PRE_BODY (omp_for) = NULL_TREE;
+       }
+      tree init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0);
+      tree decl = TREE_OPERAND (init, 0);
+      tree cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), 0);
+      tree incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
+      tree t = TREE_OPERAND (cond, 1), c, clauses = NULL_TREE;
+      if (TREE_CODE (t) != INTEGER_CST)
+       {
+         TREE_OPERAND (cond, 1) = c_get_temp_regvar (TREE_TYPE (t), t);
+         c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+         OMP_CLAUSE_DECL (c) = TREE_OPERAND (cond, 1);
+         OMP_CLAUSE_CHAIN (c) = clauses;
+         clauses = c;
+       }
+      if (TREE_CODE (incr) == MODIFY_EXPR)
+       {
+         t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
+         if (TREE_CODE (t) != INTEGER_CST)
+           {
+             TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
+               = c_get_temp_regvar (TREE_TYPE (t), t);
+             c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+             OMP_CLAUSE_DECL (c) = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
+             OMP_CLAUSE_CHAIN (c) = clauses;
+             clauses = c;
+           }
+       }
+      t = TREE_OPERAND (init, 1);
+      if (TREE_CODE (t) != INTEGER_CST)
+       {
+         TREE_OPERAND (init, 1) = c_get_temp_regvar (TREE_TYPE (t), t);
+         c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+         OMP_CLAUSE_DECL (c) = TREE_OPERAND (init, 1);
+         OMP_CLAUSE_CHAIN (c) = clauses;
+         clauses = c;
+       }
+      c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
+      OMP_CLAUSE_DECL (c) = decl;
+      OMP_CLAUSE_CHAIN (c) = clauses;
+      clauses = c;
+      c = build_omp_clause (input_location, OMP_CLAUSE__CILK_FOR_COUNT_);
+      OMP_CLAUSE_OPERAND (c, 0)
+       = cilk_for_number_of_iterations (omp_for);
+      OMP_CLAUSE_CHAIN (c) = clauses;
+      OMP_PARALLEL_CLAUSES (omp_par) = c_finish_omp_clauses (c);
+      add_stmt (omp_par);
+    }
+
+  block = c_end_compound_stmt (loc, block, true);
+  add_stmt (block);
+}
+
 \f
 /* Parse a transaction attribute (GCC Extension).
 
index a7de8f3c7343d252ffc4c513c59b332b6807a252..da71ab263f9e3f6a69e09f32e058d186ee5a745a 100644 (file)
@@ -12229,6 +12229,7 @@ c_finish_omp_clauses (tree clauses)
        case OMP_CLAUSE_SECTIONS:
        case OMP_CLAUSE_TASKGROUP:
        case OMP_CLAUSE_PROC_BIND:
+       case OMP_CLAUSE__CILK_FOR_COUNT_:
          pc = &OMP_CLAUSE_CHAIN (c);
          continue;
 
index 9f3240a892f90d5bfa033ee21366bd6fb22e9181..bf319d594fa1cd2581b9e56422d25313fe2ae365 100644 (file)
@@ -31,3 +31,5 @@ DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_SYNC, "__cilkrts_sync")
 DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_LEAVE_FRAME, "__cilkrts_leave_frame")
 DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_POP_FRAME, "__cilkrts_pop_frame")
 DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_SAVE_FP, "__cilkrts_save_fp_ctrl_state")
+DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_FOR_32, "__cilkrts_cilk_for_32")
+DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_FOR_64, "__cilkrts_cilk_for_64")
index a6a1aa2a9681ddee5eca2fb5b4065137baf96f69..35c47e19cd754c61327c8cdef658c8c2cf88a709 100644 (file)
@@ -105,6 +105,27 @@ install_builtin (const char *name, tree fntype, enum built_in_function code,
   return fndecl;
 }
 
+/* Returns a FUNCTION_DECL of type TYPE whose name is *NAME.  */
+
+static tree
+declare_cilk_for_builtin (const char *name, tree type,
+                         enum built_in_function code)
+{
+  tree cb, ft, fn;
+
+  cb = build_function_type_list (void_type_node,
+                                ptr_type_node, type, type,
+                                NULL_TREE);
+  cb = build_pointer_type (cb);
+  ft = build_function_type_list (void_type_node,
+                                cb, ptr_type_node, type,
+                                integer_type_node, NULL_TREE);
+  fn = install_builtin (name, ft, code, false);
+  TREE_NOTHROW (fn) = 0;
+
+  return fn;
+}
+
 /* Creates and initializes all the built-in Cilk keywords functions and three
    structures: __cilkrts_stack_frame, __cilkrts_pedigree and __cilkrts_worker.
    Detailed information about __cilkrts_stack_frame and
@@ -119,7 +140,7 @@ cilk_init_builtins (void)
         uint64_t rank;
         struct __cilkrts_pedigree *parent;
       }  */
-       
+
   tree pedigree_type = lang_hooks.types.make_type (RECORD_TYPE);
   tree pedigree_ptr  = build_pointer_type (pedigree_type);
   tree field = add_field ("rank", uint64_type_node, NULL_TREE);
@@ -131,7 +152,7 @@ cilk_init_builtins (void)
   lang_hooks.types.register_builtin_type (pedigree_type,
                                          "__cilkrts_pedigree_t");
   cilk_pedigree_type_decl = pedigree_type; 
-  
+
   /* Build the Cilk Stack Frame:
      struct __cilkrts_stack_frame {
        uint32_t flags;
@@ -212,7 +233,7 @@ cilk_init_builtins (void)
   tree sysdep_t = lang_hooks.types.make_type (RECORD_TYPE);
   finish_builtin_struct (sysdep_t, "__cilkrts_worker_sysdep_state", NULL_TREE,
                         NULL_TREE);
-  
+
   field = add_field ("tail", fptr_vol_ptr_vol, NULL_TREE);
   cilk_trees[CILK_TI_WORKER_TAIL] = field;
   field = add_field ("head", fptr_vol_ptr_vol, field);
@@ -234,16 +255,16 @@ cilk_init_builtins (void)
 
   tree fptr_arglist = tree_cons (NULL_TREE, frame_ptr, void_list_node);
   tree fptr_fun = build_function_type (void_type_node, fptr_arglist);
-  
+
   /* void __cilkrts_enter_frame_1 (__cilkrts_stack_frame *);  */
   cilk_enter_fndecl = install_builtin ("__cilkrts_enter_frame_1", fptr_fun,
                                       BUILT_IN_CILK_ENTER_FRAME, false);
 
   /* void __cilkrts_enter_frame_fast_1 (__cilkrts_stack_frame *);  */
   cilk_enter_fast_fndecl = 
-    install_builtin ("__cilkrts_enter_frame_fast_1", fptr_fun, 
+    install_builtin ("__cilkrts_enter_frame_fast_1", fptr_fun,
                     BUILT_IN_CILK_ENTER_FRAME_FAST, false);
-  
+
   /* void __cilkrts_pop_frame (__cilkrts_stack_frame *);  */
   cilk_pop_fndecl = install_builtin ("__cilkrts_pop_frame", fptr_fun,
                                     BUILT_IN_CILK_POP_FRAME, false);
@@ -261,14 +282,22 @@ cilk_init_builtins (void)
                                        BUILT_IN_CILK_DETACH, false);
 
   /* __cilkrts_rethrow (struct stack_frame *);  */
-  cilk_rethrow_fndecl = install_builtin ("__cilkrts_rethrow", fptr_fun, 
+  cilk_rethrow_fndecl = install_builtin ("__cilkrts_rethrow", fptr_fun,
                                         BUILT_IN_CILK_RETHROW, false);
   TREE_NOTHROW (cilk_rethrow_fndecl) = 0;
 
   /* __cilkrts_save_fp_ctrl_state (__cilkrts_stack_frame *);  */
-  cilk_save_fp_fndecl = install_builtin ("__cilkrts_save_fp_ctrl_state", 
+  cilk_save_fp_fndecl = install_builtin ("__cilkrts_save_fp_ctrl_state",
                                         fptr_fun, BUILT_IN_CILK_SAVE_FP,
                                         false);
+  /* __cilkrts_cilk_for_32 (...);  */
+  cilk_for_32_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_32",
+                                                unsigned_intSI_type_node,
+                                                BUILT_IN_CILK_FOR_32);
+  /* __cilkrts_cilk_for_64 (...);  */
+  cilk_for_64_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_64",
+                                                unsigned_intDI_type_node,
+                                                BUILT_IN_CILK_FOR_64);
 }
 
 /* Get the appropriate frame arguments for CALL that is of type CALL_EXPR.  */
index ae96f53c37c26cef8510f6859d724eacedcc1b89..1fee929af19ccc3d40bf0b64af2df042c4a7c892 100644 (file)
@@ -40,6 +40,9 @@ enum cilk_tree_index  {
   CILK_TI_F_POP,                      /* __cilkrts_pop_frame (...).  */
   CILK_TI_F_RETHROW,                  /* __cilkrts_rethrow (...).  */
   CILK_TI_F_SAVE_FP,                  /* __cilkrts_save_fp_ctrl_state (...).  */
+  CILK_TI_F_LOOP_32,                  /* __cilkrts_cilk_for_32 (...).  */
+  CILK_TI_F_LOOP_64,                  /* __cilkrts_cilk_for_64 (...).  */
+
   /* __cilkrts_stack_frame struct fields.  */
   CILK_TI_FRAME_FLAGS,                /* stack_frame->flags.  */
   CILK_TI_FRAME_PARENT,               /* stack_frame->parent.  */
@@ -77,6 +80,8 @@ extern GTY (()) tree cilk_trees[CILK_TI_MAX];
 #define cilk_rethrow_fndecl           cilk_trees[CILK_TI_F_RETHROW]
 #define cilk_pop_fndecl               cilk_trees[CILK_TI_F_POP]
 #define cilk_save_fp_fndecl           cilk_trees[CILK_TI_F_SAVE_FP]
+#define cilk_for_32_fndecl            cilk_trees[CILK_TI_F_LOOP_32]
+#define cilk_for_64_fndecl            cilk_trees[CILK_TI_F_LOOP_64]
 
 #define cilk_worker_type_fndecl       cilk_trees[CILK_TI_WORKER_TYPE]
 #define cilk_frame_type_decl          cilk_trees[CILK_TI_FRAME_TYPE]
index 58890b47248473a4c1ef5bdc8f68aa7f676090f4..7a72097c64676a863858546e2ff17e61cfaf9a45 100644 (file)
@@ -1,3 +1,31 @@
+2014-09-02  Jakub Jelinek  <jakub@redhat.com>
+           Balaji V. Iyer  <balaji.v.iyer@intel.com>
+           Igor Zamyatin  <igor.zamyatin@intel.com>
+
+       * cp-cilkplus.c (cpp_validate_cilk_plus_loop_aux): Loc definition
+       simplified.
+       * parser.c (cp_parser_cilk_for): New function.
+       (cp_parser_cilk_grainsize): Likewise.
+       (cp_parser_statement): Added RID_CILK_FOR case.
+       (cp_parser_omp_for_cond): Added CILK_FOR check.
+       (cp_parser_omp_for_loop_init): Change function argument to accept
+       tree_code instead just a bool flag; change the check to use that
+       tree_code; check for initialization declaration in case of Cilk_for.
+       (cp_parser_omp_for_loop): Added checks for CILK_FOR and RID_CILK_FOR;
+       changed call to cp_parser_omp_for_loop_init according new arguments'
+       list.
+       (cp_parser_pragma): Added PRAGMA_CILK_GRAINSIZE case.
+       * pt.c (tsubst_expr): Added CILK_FOR case.
+       * semantics.c: Include convert.h.
+       (finish_omp_clauses): Properly handle OMP_CLAUSE_SCHEDULE_CILKFOR
+       case; added OMP_CLAUSE__CILK_FOR_COUNT_.
+       (handle_omp_for_class_iterator): New argument lastp and its usage;
+       added NE_EXPR case.
+       (finish_omp_for): Changed call to handle_omp_for_class_iterator
+       according new arguments' list; in case of Cilk_for save very first
+       decl and create empty stmt_list block; use block to build correct
+       statement tree.
+
 2014-08-31  Jason Merrill  <jason@redhat.com>
 
        PR c++/62302
index daa9b8ebb38ea6ed06d576a6788bf0827863420d..565dd402f70da1db530b174ac7382a8a3e895484 100644 (file)
@@ -42,12 +42,11 @@ static tree
 cpp_validate_cilk_plus_loop_aux (tree *tp, int *walk_subtrees, void *data)
 {
   bool *valid = (bool *) data;
-  location_t loc = EXPR_HAS_LOCATION (*tp) ? EXPR_LOCATION (*tp) :
-    UNKNOWN_LOCATION;
 
   if (!tp || !*tp)
     return NULL_TREE;
 
+  location_t loc = EXPR_LOCATION (*tp);
   if (TREE_CODE (*tp) == THROW_EXPR)
     {
       error_at (loc, "throw expressions are not allowed inside loops "
@@ -142,4 +141,3 @@ cilk_install_body_with_frame_cleanup (tree fndecl, tree orig_body, void *wd)
   append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, body, dtor),
                            &list);
 }
-
index ad99cab38cf64969e3e50aa6e4cc9a7e67cbd5f7..05fa86a655b96ad0b3509a585349bc8de94798c5 100644 (file)
@@ -239,6 +239,8 @@ static tree cp_literal_operator_id
 
 static void cp_parser_cilk_simd
   (cp_parser *, cp_token *);
+static tree cp_parser_cilk_for
+  (cp_parser *, tree);
 static bool cp_parser_omp_declare_reduction_exprs
   (tree, cp_parser *);
 static tree cp_parser_cilk_simd_vectorlength 
@@ -9532,6 +9534,18 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
          statement = cp_parser_iteration_statement (parser, false);
          break;
 
+       case RID_CILK_FOR:
+         if (!flag_cilkplus)
+           {
+             error_at (cp_lexer_peek_token (parser->lexer)->location,
+                       "-fcilkplus must be enabled to use %<_Cilk_for%>");
+             cp_lexer_consume_token (parser->lexer);
+             statement = error_mark_node;
+           }
+         else
+           statement = cp_parser_cilk_for (parser, integer_zero_node);
+         break;
+
        case RID_BREAK:
        case RID_CONTINUE:
        case RID_RETURN:
@@ -29222,7 +29236,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
     case LE_EXPR:
       break;
     case NE_EXPR:
-      if (code == CILK_SIMD)
+      if (code == CILK_SIMD || code == CILK_FOR)
        break;
       /* Fall through: OpenMP disallows NE_EXPR.  */
     default:
@@ -29337,15 +29351,12 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
 /* Parse the initialization statement of either an OpenMP for loop or
    a Cilk Plus for loop.
 
-   PARSING_OPENMP is true if parsing OpenMP, or false if parsing Cilk
-   Plus.
-
    Return true if the resulting construct should have an
    OMP_CLAUSE_PRIVATE added to it.  */
 
 static bool
 cp_parser_omp_for_loop_init (cp_parser *parser,
-                            bool parsing_openmp,
+                            enum tree_code code,
                             tree &this_pre_body,
                             vec<tree, va_gc> *for_block,
                             tree &init,
@@ -29408,7 +29419,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
              if (cp_lexer_next_token_is (parser->lexer, 
                                          CPP_OPEN_PAREN))
                {
-                 if (parsing_openmp)
+                 if (code != CILK_SIMD && code != CILK_FOR)
                    error ("parenthesized initialization is not allowed in "
                           "OpenMP %<for%> loop");
                  else
@@ -29480,6 +29491,9 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
       cp_id_kind idk;
       /* If parsing a type specifier sequence failed, then
         this MUST be a simple expression.  */
+      if (code == CILK_FOR)
+       error ("%<_Cilk_for%> allows expression instead of declaration only "
+              "in C, not in C++");
       cp_parser_parse_tentatively (parser);
       decl = cp_parser_primary_expression (parser, false, false,
                                           false, &idk);
@@ -29548,11 +29562,18 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
       bool add_private_clause = false;
       location_t loc;
 
-      if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
+      if (code != CILK_FOR
+         && !cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
        {
          cp_parser_error (parser, "for statement expected");
          return NULL;
        }
+      if (code == CILK_FOR
+         && !cp_lexer_next_token_is_keyword (parser->lexer, RID_CILK_FOR))
+       {
+         cp_parser_error (parser, "_Cilk_for statement expected");
+         return NULL;
+       }
       loc = cp_lexer_consume_token (parser->lexer)->location;
 
       if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
@@ -29562,8 +29583,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
       this_pre_body = push_stmt_list ();
 
       add_private_clause
-       |= cp_parser_omp_for_loop_init (parser,
-                                       /*parsing_openmp=*/code != CILK_SIMD,
+       |= cp_parser_omp_for_loop_init (parser, code,
                                        this_pre_body, for_block,
                                        init, decl, real_decl);
 
@@ -29733,7 +29753,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
 
   /* Note that we saved the original contents of this flag when we entered
      the structured block, and so we don't need to re-save it here.  */
-  if (code == CILK_SIMD)
+  if (code == CILK_SIMD || code == CILK_FOR)
     parser->in_statement = IN_CILK_SIMD_FOR;
   else
     parser->in_statement = IN_OMP_FOR;
@@ -31692,6 +31712,36 @@ cp_parser_initial_pragma (cp_token *first_token)
   cp_lexer_get_preprocessor_token (NULL, first_token);
 }
 
+/* Parses the grainsize pragma for the _Cilk_for statement.
+   Syntax:
+   #pragma cilk grainsize = <VALUE>.  */
+
+static void
+cp_parser_cilk_grainsize (cp_parser *parser, cp_token *pragma_tok)
+{
+  if (cp_parser_require (parser, CPP_EQ, RT_EQ))
+    {
+      tree exp = cp_parser_binary_expression (parser, false, false,
+                                             PREC_NOT_OPERATOR, NULL);
+      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+      if (!exp || exp == error_mark_node)
+       {
+         error_at (pragma_tok->location, "invalid grainsize for _Cilk_for");
+         return;
+       }
+
+      /* Make sure the next token is _Cilk_for, it is invalid otherwise.  */
+      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_CILK_FOR))
+       cp_parser_cilk_for (parser, exp);
+      else
+       warning_at (cp_lexer_peek_token (parser->lexer)->location, 0,
+                   "%<#pragma cilk grainsize%> is not followed by "
+                   "%<_Cilk_for%>");
+      return;
+    }
+  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+}
+
 /* Normal parsing of a pragma token.  Here we can (and must) use the
    regular lexer.  */
 
@@ -31874,6 +31924,27 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
       cp_parser_cilk_simd (parser, pragma_tok);
       return true;
 
+    case PRAGMA_CILK_GRAINSIZE:
+      if (context == pragma_external)
+       {
+         error_at (pragma_tok->location,
+                   "%<#pragma cilk grainsize%> must be inside a function");
+         break;
+       }
+
+      /* Ignore the pragma if Cilk Plus is not enabled.  */
+      if (flag_cilkplus)
+       {
+         cp_parser_cilk_grainsize (parser, pragma_tok);
+         return true;
+       }
+      else
+       {
+         error_at (pragma_tok->location, "-fcilkplus must be enabled to use "
+                   "%<#pragma cilk grainsize%>");
+         break;
+       }
+
     default:
       gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
       c_invoke_pragma_handler (id);
@@ -31960,10 +32031,10 @@ cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses,
 
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return error_mark_node;
-  
+
   expr = cp_parser_constant_expression (parser, false, NULL);
   expr = maybe_constant_value (expr);
-  
+
   /* If expr == error_mark_node, then don't emit any errors nor
      create a clause.  if any of the above functions returns
      error mark node then they would have emitted an error message.  */
@@ -32197,7 +32268,7 @@ cp_parser_cilk_simd (cp_parser *parser, cp_token *pragma_token)
 
   if (clauses == error_mark_node)
     return;
-  
+
   if (cp_lexer_next_token_is_not_keyword (parser->lexer, RID_FOR))
     {
       error_at (cp_lexer_peek_token (parser->lexer)->location,
@@ -32212,7 +32283,35 @@ cp_parser_cilk_simd (cp_parser *parser, cp_token *pragma_token)
     cpp_validate_cilk_plus_loop (OMP_FOR_BODY (ret));
   cp_parser_end_omp_structured_block (parser, save);
   add_stmt (finish_omp_structured_block (sb));
-  return;
+}
+
+/* Main entry-point for parsing Cilk Plus _Cilk_for
+   loops.  The return value is error_mark_node
+   when errors happen and CILK_FOR tree on success.  */
+
+static tree
+cp_parser_cilk_for (cp_parser *parser, tree grain)
+{
+  if (cp_lexer_next_token_is_not_keyword (parser->lexer, RID_CILK_FOR))
+    gcc_unreachable ();
+
+  tree sb = begin_omp_structured_block ();
+  int save = cp_parser_begin_omp_structured_block (parser);
+
+  tree clauses = build_omp_clause (EXPR_LOCATION (grain), OMP_CLAUSE_SCHEDULE);
+  OMP_CLAUSE_SCHEDULE_KIND (clauses) = OMP_CLAUSE_SCHEDULE_CILKFOR;
+  OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clauses) = grain;
+  clauses = finish_omp_clauses (clauses);
+
+  tree ret = cp_parser_omp_for_loop (parser, CILK_FOR, clauses, NULL);
+  if (ret)
+    cpp_validate_cilk_plus_loop (ret);
+  else
+    ret = error_mark_node;
+
+  cp_parser_end_omp_structured_block (parser, save);
+  add_stmt (finish_omp_structured_block (sb));
+  return ret;
 }
 
 /* Create an identifier for a generic parameter type (a synthesized
index eac837f0a032207f58b59d9461045635d61753f3..5ea5a5854d89325da9e9cb3db446a9b1ed3973ec 100644 (file)
@@ -14012,6 +14012,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
     case OMP_FOR:
     case OMP_SIMD:
     case CILK_SIMD:
+    case CILK_FOR:
     case OMP_DISTRIBUTE:
       {
        tree clauses, body, pre_body;
index 168bde8fc7cafad3f95ca4495db08b8c40b85444..01748dab0e8fda2b050b8161c6eca90b3b97eed4 100644 (file)
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "bitmap.h"
 #include "omp-low.h"
 #include "builtins.h"
+#include "convert.h"
 
 static bool verify_constant (tree, bool, bool *, bool *);
 #define VERIFY_CONSTANT(X)                                             \
@@ -5424,6 +5425,8 @@ finish_omp_clauses (tree clauses)
          else if (t == error_mark_node)
            remove = true;
          else if (!type_dependent_expression_p (t)
+                  && (OMP_CLAUSE_SCHEDULE_KIND (c)
+                      != OMP_CLAUSE_SCHEDULE_CILKFOR)
                   && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
            {
              error ("schedule chunk size expression must be integral");
@@ -5433,7 +5436,19 @@ finish_omp_clauses (tree clauses)
            {
              t = mark_rvalue_use (t);
              if (!processing_template_decl)
-               t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+               {
+                 if (OMP_CLAUSE_SCHEDULE_KIND (c)
+                     == OMP_CLAUSE_SCHEDULE_CILKFOR)
+                   {
+                     t = convert_to_integer (long_integer_type_node, t);
+                     if (t == error_mark_node)
+                       {
+                         remove = true;
+                         break;
+                       }
+                   }
+                 t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+               }
              OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
            }
          break;
@@ -5734,6 +5749,7 @@ finish_omp_clauses (tree clauses)
        case OMP_CLAUSE_SECTIONS:
        case OMP_CLAUSE_TASKGROUP:
        case OMP_CLAUSE_PROC_BIND:
+       case OMP_CLAUSE__CILK_FOR_COUNT_:
          break;
 
        case OMP_CLAUSE_INBRANCH:
@@ -6053,7 +6069,7 @@ finish_omp_task (tree clauses, tree body)
 static bool
 handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
                               tree condv, tree incrv, tree *body,
-                              tree *pre_body, tree clauses)
+                              tree *pre_body, tree clauses, tree *lastp)
 {
   tree diff, iter_init, iter_incr = NULL, last;
   tree incr_var = NULL, orig_pre_body, orig_body, c;
@@ -6073,6 +6089,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
     case GE_EXPR:
     case LT_EXPR:
     case LE_EXPR:
+    case NE_EXPR:
       if (TREE_OPERAND (cond, 1) == iter)
        cond = build2 (swap_tree_comparison (TREE_CODE (cond)),
                       TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0));
@@ -6285,6 +6302,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
   TREE_VEC_ELT (initv, i) = init;
   TREE_VEC_ELT (condv, i) = cond;
   TREE_VEC_ELT (incrv, i) = incr;
+  *lastp = last;
 
   return false;
 }
@@ -6301,7 +6319,8 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
                tree condv, tree incrv, tree body, tree pre_body, tree clauses)
 {
   tree omp_for = NULL, orig_incr = NULL;
-  tree decl, init, cond, incr;
+  tree decl = NULL, init, cond, incr, orig_decl = NULL_TREE, block = NULL_TREE;
+  tree last = NULL_TREE;
   location_t elocus;
   int i;
 
@@ -6431,8 +6450,11 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
                                "iteration variable %qE", decl);
              return NULL;
            }
+         if (code == CILK_FOR && i == 0)
+           orig_decl = decl;
          if (handle_omp_for_class_iterator (i, locus, declv, initv, condv,
-                                            incrv, &body, &pre_body, clauses))
+                                            incrv, &body, &pre_body,
+                                            clauses, &last))
            return NULL;
          continue;
        }
@@ -6485,11 +6507,18 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
   if (IS_EMPTY_STMT (pre_body))
     pre_body = NULL;
 
+  if (code == CILK_FOR && !processing_template_decl)
+    block = push_stmt_list ();
+
   omp_for = c_finish_omp_for (locus, code, declv, initv, condv, incrv,
                              body, pre_body);
 
   if (omp_for == NULL)
-    return NULL;
+    {
+      if (block)
+       pop_stmt_list (block);
+      return NULL;
+    }
 
   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
     {
@@ -6523,8 +6552,117 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
       if (orig_incr)
        TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i) = TREE_VEC_ELT (orig_incr, i);
     }
-  if (omp_for != NULL)
-    OMP_FOR_CLAUSES (omp_for) = clauses;
+  OMP_FOR_CLAUSES (omp_for) = clauses;
+
+  if (block)
+    {
+      tree omp_par = make_node (OMP_PARALLEL);
+      TREE_TYPE (omp_par) = void_type_node;
+      OMP_PARALLEL_CLAUSES (omp_par) = NULL_TREE;
+      tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+      TREE_SIDE_EFFECTS (bind) = 1;
+      BIND_EXPR_BODY (bind) = pop_stmt_list (block);
+      OMP_PARALLEL_BODY (omp_par) = bind;
+      if (OMP_FOR_PRE_BODY (omp_for))
+       {
+         add_stmt (OMP_FOR_PRE_BODY (omp_for));
+         OMP_FOR_PRE_BODY (omp_for) = NULL_TREE;
+       }
+      init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0);
+      decl = TREE_OPERAND (init, 0);
+      cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), 0);
+      incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
+      tree t = TREE_OPERAND (cond, 1), c, clauses, *pc;
+      clauses = OMP_FOR_CLAUSES (omp_for);
+      OMP_FOR_CLAUSES (omp_for) = NULL_TREE;
+      for (pc = &clauses; *pc; )
+       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_SCHEDULE)
+         {
+           gcc_assert (OMP_FOR_CLAUSES (omp_for) == NULL_TREE);
+           OMP_FOR_CLAUSES (omp_for) = *pc;
+           *pc = OMP_CLAUSE_CHAIN (*pc);
+           OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (omp_for)) = NULL_TREE;
+         }
+       else
+         {
+           gcc_assert (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_FIRSTPRIVATE);
+           pc = &OMP_CLAUSE_CHAIN (*pc);
+         }
+      if (TREE_CODE (t) != INTEGER_CST)
+       {
+         TREE_OPERAND (cond, 1) = get_temp_regvar (TREE_TYPE (t), t);
+         c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+         OMP_CLAUSE_DECL (c) = TREE_OPERAND (cond, 1);
+         OMP_CLAUSE_CHAIN (c) = clauses;
+         clauses = c;
+       }
+      if (TREE_CODE (incr) == MODIFY_EXPR)
+       {
+         t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
+         if (TREE_CODE (t) != INTEGER_CST)
+           {
+             TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
+               = get_temp_regvar (TREE_TYPE (t), t);
+             c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+             OMP_CLAUSE_DECL (c) = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
+             OMP_CLAUSE_CHAIN (c) = clauses;
+             clauses = c;
+           }
+       }
+      t = TREE_OPERAND (init, 1);
+      if (TREE_CODE (t) != INTEGER_CST)
+       {
+         TREE_OPERAND (init, 1) = get_temp_regvar (TREE_TYPE (t), t);
+         c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+         OMP_CLAUSE_DECL (c) = TREE_OPERAND (init, 1);
+         OMP_CLAUSE_CHAIN (c) = clauses;
+         clauses = c;
+       }
+      if (orig_decl && orig_decl != decl)
+       {
+         c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+         OMP_CLAUSE_DECL (c) = orig_decl;
+         OMP_CLAUSE_CHAIN (c) = clauses;
+         clauses = c;
+       }
+      if (last)
+       {
+         c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+         OMP_CLAUSE_DECL (c) = last;
+         OMP_CLAUSE_CHAIN (c) = clauses;
+         clauses = c;
+       }
+      c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
+      OMP_CLAUSE_DECL (c) = decl;
+      OMP_CLAUSE_CHAIN (c) = clauses;
+      clauses = c;
+      c = build_omp_clause (input_location, OMP_CLAUSE__CILK_FOR_COUNT_);
+      OMP_CLAUSE_OPERAND (c, 0)
+       = cilk_for_number_of_iterations (omp_for);
+      OMP_CLAUSE_CHAIN (c) = clauses;
+      OMP_PARALLEL_CLAUSES (omp_par) = finish_omp_clauses (c);
+      add_stmt (omp_par);
+      return omp_par;
+    }
+  else if (code == CILK_FOR && processing_template_decl)
+    {
+      tree c, clauses = OMP_FOR_CLAUSES (omp_for);
+      if (orig_decl && orig_decl != decl)
+       {
+         c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+         OMP_CLAUSE_DECL (c) = orig_decl;
+         OMP_CLAUSE_CHAIN (c) = clauses;
+         clauses = c;
+       }
+      if (last)
+       {
+         c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+         OMP_CLAUSE_DECL (c) = last;
+         OMP_CLAUSE_CHAIN (c) = clauses;
+         clauses = c;
+       }
+      OMP_FOR_CLAUSES (omp_for) = clauses;
+    }
   return omp_for;
 }
 
index 283aca279bae23d49b67ddd6e762f55eb8b222f0..60b56b0d3d4bc7133fa89873321898a29f9591af 100644 (file)
@@ -1135,6 +1135,9 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
        case GF_OMP_FOR_KIND_DISTRIBUTE:
          kind = " distribute";
          break;
+       case GF_OMP_FOR_KIND_CILKFOR:
+         kind = " _Cilk_for";
+         break;
        default:
          gcc_unreachable ();
        }
@@ -1169,16 +1172,24 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
        case GF_OMP_FOR_KIND_DISTRIBUTE:
          pp_string (buffer, "#pragma omp distribute");
          break;
+       case GF_OMP_FOR_KIND_CILKFOR:
+         break;
        default:
          gcc_unreachable ();
        }
-      dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
+      if (gimple_omp_for_kind (gs) != GF_OMP_FOR_KIND_CILKFOR)
+       dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
       for (i = 0; i < gimple_omp_for_collapse (gs); i++)
        {
          if (i)
            spc += 2;
-         newline_and_indent (buffer, spc);
-         pp_string (buffer, "for (");
+         if (gimple_omp_for_kind (gs) == GF_OMP_FOR_KIND_CILKFOR)
+           pp_string (buffer, "_Cilk_for (");
+         else
+           {
+             newline_and_indent (buffer, spc);
+             pp_string (buffer, "for (");
+           }
          dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
                             flags, false);
          pp_string (buffer, " = ");
@@ -1203,6 +1214,9 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
            case GE_EXPR:
              pp_greater_equal (buffer);
              break;
+           case NE_EXPR:
+             pp_string (buffer, "!=");
+             break;
            default:
              gcc_unreachable ();
            }
@@ -1221,6 +1235,8 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
 
       if (!gimple_seq_empty_p (gimple_omp_body (gs)))
        {
+         if (gimple_omp_for_kind (gs) == GF_OMP_FOR_KIND_CILKFOR)
+           dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
          newline_and_indent (buffer, spc + 2);
          pp_left_brace (buffer);
          pp_newline (buffer);
index 51814baa65ab51c89a16309294b715fed7d26b12..ec415850bc35dd1ea1129b3da2b9e6bad6535a39 100644 (file)
@@ -92,15 +92,16 @@ enum gf_mask {
     GF_CALL_INTERNAL           = 1 << 6,
     GF_CALL_CTRL_ALTERING       = 1 << 7,
     GF_OMP_PARALLEL_COMBINED   = 1 << 0,
-    GF_OMP_FOR_KIND_MASK       = (1 << 2) - 1,
+    GF_OMP_FOR_KIND_MASK       = 7 << 0,
     GF_OMP_FOR_KIND_FOR                = 0,
     GF_OMP_FOR_KIND_DISTRIBUTE = 1,
+    GF_OMP_FOR_KIND_CILKFOR     = 2,
     /* Flag for SIMD variants of OMP_FOR kinds.  */
-    GF_OMP_FOR_SIMD            = 1 << 1,
+    GF_OMP_FOR_SIMD            = 1 << 2,
     GF_OMP_FOR_KIND_SIMD       = GF_OMP_FOR_SIMD | 0,
     GF_OMP_FOR_KIND_CILKSIMD   = GF_OMP_FOR_SIMD | 1,
-    GF_OMP_FOR_COMBINED                = 1 << 2,
-    GF_OMP_FOR_COMBINED_INTO   = 1 << 3,
+    GF_OMP_FOR_COMBINED                = 1 << 3,
+    GF_OMP_FOR_COMBINED_INTO   = 1 << 4,
     GF_OMP_TARGET_KIND_MASK    = (1 << 2) - 1,
     GF_OMP_TARGET_KIND_REGION  = 0,
     GF_OMP_TARGET_KIND_DATA    = 1,
index 658c5d2fac39ec2d22533b1174876e175f6c2626..0ebc24c45240f6e84957590aff9c4ebb75ba4259 100644 (file)
@@ -6208,6 +6208,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
        case OMP_CLAUSE_THREAD_LIMIT:
        case OMP_CLAUSE_DIST_SCHEDULE:
        case OMP_CLAUSE_DEVICE:
+       case OMP_CLAUSE__CILK_FOR_COUNT_:
          if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
                             is_gimple_val, fb_rvalue) == GS_ERROR)
            remove = true;
@@ -6584,6 +6585,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, tree *list_p)
        case OMP_CLAUSE_PROC_BIND:
        case OMP_CLAUSE_SAFELEN:
        case OMP_CLAUSE_DEPEND:
+       case OMP_CLAUSE__CILK_FOR_COUNT_:
          break;
 
        default:
@@ -7056,6 +7058,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 CILK_FOR: kind = GF_OMP_FOR_KIND_CILKFOR; break;
     case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
     default:
       gcc_unreachable ();
@@ -8128,6 +8131,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
        case OMP_FOR:
        case OMP_SIMD:
        case CILK_SIMD:
+       case CILK_FOR:
        case OMP_DISTRIBUTE:
          ret = gimplify_omp_for (expr_p, pre_p);
          break;
index 9d1cd2ce0f8d62309aa6c94f487d5c98d67e00ff..22a8fcab57fa390efd9be9d56e398e8b9b9fbebc 100644 (file)
@@ -70,6 +70,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-prop.h"
 #include "tree-nested.h"
 #include "tree-eh.h"
+#include "cilk.h"
 
 
 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
@@ -313,6 +314,8 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
   fd->have_ordered = false;
   fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
   fd->chunk_size = NULL_TREE;
+  if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
+    fd->sched_kind = OMP_CLAUSE_SCHEDULE_CILKFOR;
   collapse_iter = NULL;
   collapse_count = NULL;
 
@@ -392,7 +395,9 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
          break;
        case NE_EXPR:
          gcc_assert (gimple_omp_for_kind (for_stmt)
-                     == GF_OMP_FOR_KIND_CILKSIMD);
+                     == GF_OMP_FOR_KIND_CILKSIMD
+                     || (gimple_omp_for_kind (for_stmt)
+                         == GF_OMP_FOR_KIND_CILKFOR));
          break;
        case LE_EXPR:
          if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
@@ -1604,6 +1609,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
        case OMP_CLAUSE_SCHEDULE:
        case OMP_CLAUSE_DIST_SCHEDULE:
        case OMP_CLAUSE_DEPEND:
+       case OMP_CLAUSE__CILK_FOR_COUNT_:
          if (ctx->outer)
            scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
          break;
@@ -1812,6 +1818,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
        case OMP_CLAUSE__LOOPTEMP_:
        case OMP_CLAUSE_TO:
        case OMP_CLAUSE_FROM:
+       case OMP_CLAUSE__CILK_FOR_COUNT_:
          break;
 
        default:
@@ -1835,13 +1842,39 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
        scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
 }
 
-/* Create a new name for omp child function.  Returns an identifier.  */
+/* Create a new name for omp child function.  Returns an identifier.  If
+   IS_CILK_FOR is true then the suffix for the child function is
+   "_cilk_for_fn."  */
 
 static tree
-create_omp_child_function_name (bool task_copy)
+create_omp_child_function_name (bool task_copy, bool is_cilk_for)
 {
-  return (clone_function_name (current_function_decl,
-                              task_copy ? "_omp_cpyfn" : "_omp_fn"));
+  if (is_cilk_for)
+    return clone_function_name (current_function_decl, "_cilk_for_fn");
+  return clone_function_name (current_function_decl,
+                             task_copy ? "_omp_cpyfn" : "_omp_fn");
+}
+
+/* Returns the type of the induction variable for the child function for
+   _Cilk_for and the types for _high and _low variables based on TYPE.  */
+
+static tree
+cilk_for_check_loop_diff_type (tree type)
+{
+  if (TYPE_PRECISION (type) <= TYPE_PRECISION (uint32_type_node))
+    {
+      if (TYPE_UNSIGNED (type))
+       return uint32_type_node;
+      else
+       return integer_type_node;
+    }
+  else
+    {
+      if (TYPE_UNSIGNED (type))
+       return uint64_type_node;
+      else
+       return long_long_integer_type_node;
+    }
 }
 
 /* Build a decl for the omp child function.  It'll not contain a body
@@ -1852,15 +1885,28 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
 {
   tree decl, type, name, t;
 
-  name = create_omp_child_function_name (task_copy);
+  tree cilk_for_count
+    = (flag_cilkplus && gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
+      ? find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
+                        OMP_CLAUSE__CILK_FOR_COUNT_) : NULL_TREE;
+  tree cilk_var_type = NULL_TREE;
+
+  name = create_omp_child_function_name (task_copy,
+                                        cilk_for_count != NULL_TREE);
   if (task_copy)
     type = build_function_type_list (void_type_node, ptr_type_node,
                                     ptr_type_node, NULL_TREE);
+  else if (cilk_for_count)
+    {
+      type = TREE_TYPE (OMP_CLAUSE_OPERAND (cilk_for_count, 0));
+      cilk_var_type = cilk_for_check_loop_diff_type (type);
+      type = build_function_type_list (void_type_node, ptr_type_node,
+                                      cilk_var_type, cilk_var_type, NULL_TREE);
+    }
   else
     type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
 
-  decl = build_decl (gimple_location (ctx->stmt),
-                    FUNCTION_DECL, name, type);
+  decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);
 
   if (!task_copy)
     ctx->cb.dst_fn = decl;
@@ -1904,13 +1950,42 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
   DECL_CONTEXT (t) = decl;
   DECL_RESULT (decl) = t;
 
-  t = build_decl (DECL_SOURCE_LOCATION (decl),
-                 PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
+  /* _Cilk_for's child function requires two extra parameters called
+     __low and __high that are set the by Cilk runtime when it calls this
+     function.  */
+  if (cilk_for_count)
+    {
+      t = build_decl (DECL_SOURCE_LOCATION (decl),
+                     PARM_DECL, get_identifier ("__high"), cilk_var_type);
+      DECL_ARTIFICIAL (t) = 1;
+      DECL_NAMELESS (t) = 1;
+      DECL_ARG_TYPE (t) = ptr_type_node;
+      DECL_CONTEXT (t) = current_function_decl;
+      TREE_USED (t) = 1;
+      DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
+      DECL_ARGUMENTS (decl) = t;
+
+      t = build_decl (DECL_SOURCE_LOCATION (decl),
+                     PARM_DECL, get_identifier ("__low"), cilk_var_type);
+      DECL_ARTIFICIAL (t) = 1;
+      DECL_NAMELESS (t) = 1;
+      DECL_ARG_TYPE (t) = ptr_type_node;
+      DECL_CONTEXT (t) = current_function_decl;
+      TREE_USED (t) = 1;
+      DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
+      DECL_ARGUMENTS (decl) = t;
+    }
+
+  tree data_name = get_identifier (".omp_data_i");
+  t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
+                 ptr_type_node);
   DECL_ARTIFICIAL (t) = 1;
   DECL_NAMELESS (t) = 1;
   DECL_ARG_TYPE (t) = ptr_type_node;
   DECL_CONTEXT (t) = current_function_decl;
   TREE_USED (t) = 1;
+  if (cilk_for_count)
+    DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
   DECL_ARGUMENTS (decl) = t;
   if (!task_copy)
     ctx->receiver_decl = t;
@@ -4382,6 +4457,44 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
                            false, GSI_CONTINUE_LINKING);
 }
 
+/* Insert a function call whose name is FUNC_NAME with the information from
+   ENTRY_STMT into the basic_block BB.  */
+
+static void
+expand_cilk_for_call (basic_block bb, gimple entry_stmt,
+                     vec <tree, va_gc> *ws_args)
+{
+  tree t, t1, t2;
+  gimple_stmt_iterator gsi;
+  vec <tree, va_gc> *args;
+
+  gcc_assert (vec_safe_length (ws_args) == 2);
+  tree func_name = (*ws_args)[0];
+  tree grain = (*ws_args)[1];
+
+  tree clauses = gimple_omp_parallel_clauses (entry_stmt);
+  tree count = find_omp_clause (clauses, OMP_CLAUSE__CILK_FOR_COUNT_);
+  gcc_assert (count != NULL_TREE);
+  count = OMP_CLAUSE_OPERAND (count, 0);
+
+  gsi = gsi_last_bb (bb);
+  t = gimple_omp_parallel_data_arg (entry_stmt);
+  if (t == NULL)
+    t1 = null_pointer_node;
+  else
+    t1 = build_fold_addr_expr (t);
+  t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
+
+  vec_alloc (args, 4);
+  args->quick_push (t2);
+  args->quick_push (t1);
+  args->quick_push (count);
+  args->quick_push (grain);
+  t = build_call_expr_loc_vec (UNKNOWN_LOCATION, func_name, args);
+
+  force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, false,
+                           GSI_CONTINUE_LINKING);
+}
 
 /* Build the function call to GOMP_task to actually
    generate the task operation.  BB is the block where to insert the code.  */
@@ -4717,7 +4830,18 @@ expand_omp_taskreg (struct omp_region *region)
   entry_bb = region->entry;
   exit_bb = region->exit;
 
-  if (is_combined_parallel (region))
+  bool is_cilk_for
+    = (flag_cilkplus
+       && gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL
+       && find_omp_clause (gimple_omp_parallel_clauses (entry_stmt),
+                          OMP_CLAUSE__CILK_FOR_COUNT_) != NULL_TREE);
+
+  if (is_cilk_for)
+    /* If it is a _Cilk_for statement, it is modelled *like* a parallel for,
+       and the inner statement contains the name of the built-in function
+       and grain.  */
+    ws_args = region->inner->ws_args;
+  else if (is_combined_parallel (region))
     ws_args = region->ws_args;
   else
     ws_args = NULL;
@@ -4929,7 +5053,9 @@ expand_omp_taskreg (struct omp_region *region)
     }
 
   /* Emit a library call to launch the children threads.  */
-  if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
+  if (is_cilk_for)
+    expand_cilk_for_call (new_bb, entry_stmt, ws_args);
+  else if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
     expand_parallel_call (region, new_bb, entry_stmt, ws_args);
   else
     expand_task_call (new_bb, entry_stmt);
@@ -6621,6 +6747,191 @@ expand_omp_for_static_chunk (struct omp_region *region,
     }
 }
 
+/* A subroutine of expand_omp_for.  Generate code for _Cilk_for loop.
+   Given parameters:
+   for (V = N1; V cond N2; V += STEP) BODY;
+
+   where COND is "<" or ">" or "!=", we generate pseudocode
+
+   for (ind_var = low; ind_var < high; ind_var++)
+     {
+       V = n1 + (ind_var * STEP)
+
+       <BODY>
+     }
+
+   In the above pseudocode, low and high are function parameters of the
+   child function.  In the function below, we are inserting a temp.
+   variable that will be making a call to two OMP functions that will not be
+   found in the body of _Cilk_for (since OMP_FOR cannot be mixed
+   with _Cilk_for).  These functions are replaced with low and high
+   by the function that handles taskreg.  */
+
+
+static void
+expand_cilk_for (struct omp_region *region, struct omp_for_data *fd)
+{
+  bool broken_loop = region->cont == NULL;
+  basic_block entry_bb = region->entry;
+  basic_block cont_bb = region->cont;
+
+  gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
+  gcc_assert (broken_loop
+             || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
+  basic_block l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
+  basic_block l1_bb, l2_bb;
+
+  if (!broken_loop)
+    {
+      gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
+      gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
+      l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
+      l2_bb = BRANCH_EDGE (entry_bb)->dest;
+    }
+  else
+    {
+      BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
+      l1_bb = split_edge (BRANCH_EDGE (entry_bb));
+      l2_bb = single_succ (l1_bb);
+    }
+  basic_block exit_bb = region->exit;
+  basic_block l2_dom_bb = NULL;
+
+  gimple_stmt_iterator gsi = gsi_last_bb (entry_bb);
+
+  /* Below statements until the "tree high_val = ..." are pseudo statements
+     used to pass information to be used by expand_omp_taskreg.
+     low_val and high_val will be replaced by the __low and __high
+     parameter from the child function.
+
+     The call_exprs part is a place-holder, it is mainly used
+     to distinctly identify to the top-level part that this is
+     where we should put low and high (reasoning given in header
+     comment).  */
+
+  tree child_fndecl
+    = gimple_omp_parallel_child_fn (last_stmt (region->outer->entry));
+  tree t, low_val = NULL_TREE, high_val = NULL_TREE;
+  for (t = DECL_ARGUMENTS (child_fndecl); t; t = TREE_CHAIN (t))
+    {
+      if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__high"))
+       high_val = t;
+      else if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__low"))
+       low_val = t;
+    }
+  gcc_assert (low_val && high_val);
+
+  tree type = TREE_TYPE (low_val);
+  tree ind_var = create_tmp_reg (type, "__cilk_ind_var");
+  gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
+
+  /* Not needed in SSA form right now.  */
+  gcc_assert (!gimple_in_ssa_p (cfun));
+  if (l2_dom_bb == NULL)
+    l2_dom_bb = l1_bb;
+
+  tree n1 = low_val;
+  tree n2 = high_val;
+
+  gimple stmt = gimple_build_assign (ind_var, n1);
+
+  /* Replace the GIMPLE_OMP_FOR statement.  */
+  gsi_replace (&gsi, stmt, true);
+
+  if (!broken_loop)
+    {
+      /* Code to control the increment goes in the CONT_BB.  */
+      gsi = gsi_last_bb (cont_bb);
+      stmt = gsi_stmt (gsi);
+      gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
+      stmt = gimple_build_assign_with_ops (PLUS_EXPR, ind_var, ind_var,
+                                          build_one_cst (type));
+
+      /* Replace GIMPLE_OMP_CONTINUE.  */
+      gsi_replace (&gsi, stmt, true);
+    }
+
+  /* Emit the condition in L1_BB.  */
+  gsi = gsi_after_labels (l1_bb);
+  t = fold_build2 (MULT_EXPR, TREE_TYPE (fd->loop.step),
+                  fold_convert (TREE_TYPE (fd->loop.step), ind_var),
+                  fd->loop.step);
+  if (POINTER_TYPE_P (TREE_TYPE (fd->loop.n1)))
+    t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (fd->loop.n1),
+                    fd->loop.n1, fold_convert (sizetype, t));
+  else
+    t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loop.n1),
+                    fd->loop.n1, fold_convert (TREE_TYPE (fd->loop.n1), t));
+  t = fold_convert (TREE_TYPE (fd->loop.v), t);
+  expand_omp_build_assign (&gsi, fd->loop.v, t);
+
+  /* The condition is always '<' since the runtime will fill in the low
+     and high values.  */
+  stmt = gimple_build_cond (LT_EXPR, ind_var, n2, NULL_TREE, NULL_TREE);
+  gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
+  /* Remove GIMPLE_OMP_RETURN.  */
+  gsi = gsi_last_bb (exit_bb);
+  gsi_remove (&gsi, true);
+
+  /* Connect the new blocks.  */
+  remove_edge (FALLTHRU_EDGE (entry_bb));
+
+  edge e, ne;
+  if (!broken_loop)
+    {
+      remove_edge (BRANCH_EDGE (entry_bb));
+      make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
+
+      e = BRANCH_EDGE (l1_bb);
+      ne = FALLTHRU_EDGE (l1_bb);
+      e->flags = EDGE_TRUE_VALUE;
+    }
+  else
+    {
+      single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
+
+      ne = single_succ_edge (l1_bb);
+      e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
+
+    }
+  ne->flags = EDGE_FALSE_VALUE;
+  e->probability = REG_BR_PROB_BASE * 7 / 8;
+  ne->probability = REG_BR_PROB_BASE / 8;
+
+  set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
+  set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
+  set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
+
+  if (!broken_loop)
+    {
+      struct loop *loop = alloc_loop ();
+      loop->header = l1_bb;
+      loop->latch = cont_bb;
+      add_loop (loop, l1_bb->loop_father);
+      loop->safelen = INT_MAX;
+    }
+
+  /* Pick the correct library function based on the precision of the
+     induction variable type.  */
+  tree lib_fun = NULL_TREE;
+  if (TYPE_PRECISION (type) == 32)
+    lib_fun = cilk_for_32_fndecl;
+  else if (TYPE_PRECISION (type) == 64)
+    lib_fun = cilk_for_64_fndecl;
+  else
+    gcc_unreachable ();
+
+  gcc_assert (fd->sched_kind == OMP_CLAUSE_SCHEDULE_CILKFOR);
+
+  /* WS_ARGS contains the library function flavor to call:
+     __libcilkrts_cilk_for_64 or __libcilkrts_cilk_for_32), and the
+     user-defined grain value.  If the user does not define one, then zero
+     is passed in by the parser.  */
+  vec_alloc (region->ws_args, 2);
+  region->ws_args->quick_push (lib_fun);
+  region->ws_args->quick_push (fd->chunk_size);
+}
 
 /* A subroutine of expand_omp_for.  Generate code for a simd non-worksharing
    loop.  Given parameters:
@@ -6964,6 +7275,8 @@ expand_omp_for (struct omp_region *region, gimple inner_stmt)
 
   if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_SIMD)
     expand_omp_simd (region, &fd);
+  else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
+    expand_cilk_for (region, &fd);
   else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
           && !fd.have_ordered)
     {
index 6825ea16f6bb7cacc65df15ae47de4ea9cd90986..7281fd92da46379a0d2435e1ccfcc5ffe8a6d887 100644 (file)
@@ -1,3 +1,22 @@
+2014-09-02  Jakub Jelinek  <jakub@redhat.com>
+           Balaji V. Iyer  <balaji.v.iyer@intel.com>
+           Igor Zamyatin  <igor.zamyatin@intel.com>
+
+       * c-c++-common/cilk-plus/CK/cilk-fors.c: New test.
+       * c-c++-common/cilk-plus/CK/cilk-for-2.c: New test.
+       * c-c++-common/cilk-plus/CK/cilk-for-3.c: New test.
+       * c-c++-common/cilk-plus/CK/cilk_for_errors.c: New test.
+       * c-c++-common/cilk-plus/CK/cilk_for_grain.c: New test.
+       * c-c++-common/cilk-plus/CK/cilk_for_grain_errors.c: New test.
+       * c-c++-common/cilk-plus/CK/cilk_for_ptr_iter.c: New test.
+       * c-c++-common/cilk-plus/CK/nested_cilk_for.c: New test.
+       * g++.dg/cilk-plus/CK/cf3.cc: New test.
+       * g++.dg/cilk-plus/CK/cilk-for-tplt.cc: New test.
+       * g++.dg/cilk-plus/CK/for1.cc: New test.
+       * g++.dg/cilk-plus/CK/stl_iter.cc: New test.
+       * g++.dg/cilk-plus/CK/stl_rev_iter.cc: New test.
+       * g++.dg/cilk-plus/CK/stl_test.cc: New test.
+
 2014-09-02  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/62695
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-for-2.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-for-2.c
new file mode 100644 (file)
index 0000000..fd30667
--- /dev/null
@@ -0,0 +1,393 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-additional-options "-std=gnu99" { target c } } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+int msk;
+
+#define BODY \
+  do {                                                                 \
+    int j = (i >= 30U) ? 30 : i;                                       \
+    if (__atomic_fetch_or (&msk, 1 << j, __ATOMIC_RELAXED) & (1 << j)) \
+      __builtin_abort ();                                              \
+  } while (0)
+#define TEST(x) if (msk != (x)) __builtin_abort (); msk = 0
+
+__attribute__((noinline, noclone)) void
+test (int seven, int three, int two, int minustwo, int ten,
+      int zero, int eleven, int six, int one, int threealt,
+      unsigned long int sevenUL, unsigned long int threeUL,
+      unsigned long int twoUL, unsigned long int minustwoUL,
+      unsigned long int tenUL, unsigned long int zeroUL,
+      unsigned long int elevenUL, unsigned long int sixUL,
+      unsigned long int oneUL, unsigned long int threealtUL)
+{
+  _Cilk_for (int i = seven; i < three; ++i)
+    __builtin_abort ();
+  _Cilk_for (int i = seven; i <= three; ++i)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i != threealt; ++i)
+    __builtin_abort ();
+  _Cilk_for (int i = seven; i < three; i += two)
+    __builtin_abort ();
+  _Cilk_for (int i = seven; i <= three; i += two)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i != threealt; i += two)
+    __builtin_abort ();
+  _Cilk_for (int i = seven; i < three; i -= minustwo)
+    __builtin_abort ();
+  _Cilk_for (int i = seven; i <= three; i -= minustwo)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i != threealt; i -= minustwo)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i > seven; --i)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i >= seven; i--)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i != threealt; i--)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i > seven; i -= two)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i >= seven; i -= two)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i != threealt; i -= two)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i > seven; i += minustwo)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i >= seven; i += minustwo)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i != threealt; i += minustwo)
+    __builtin_abort ();
+  _Cilk_for (int i = three; i < seven; ++i)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (int i = three; i <= seven; i++)
+    BODY;
+  TEST (0xf8);
+  _Cilk_for (int i = three; i != seven; i++)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (int i = zero; i < ten; i += two)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (int i = zero; i <= ten; i += two)
+    BODY;
+  TEST (0x555);
+  _Cilk_for (int i = zero; i != ten; i += two)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (int i = zero; i < ten; i -= minustwo)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (int i = zero; i <= ten; i -= minustwo)
+    BODY;
+  TEST (0x555);
+  _Cilk_for (int i = zero; i != ten; i -= minustwo)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (int i = six; i > two; --i)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (int i = seven; i >= three; i--)
+    BODY;
+  TEST (0xf8);
+  _Cilk_for (int i = seven; i != three; i--)
+    BODY;
+  TEST (0xf0);
+  _Cilk_for (int i = eleven; i > one; i += minustwo)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (int i = eleven; i >= two; i += minustwo)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (int i = eleven; i != one; i += minustwo)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (int i = eleven; i > one; i -= two)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (int i = eleven; i >= two; i -= two)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (int i = eleven; i != one; i -= two)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = sevenUL; i < threeUL; ++i)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = sevenUL; i <= threeUL; ++i)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i != threealtUL; ++i)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = sevenUL; i < threeUL; i += twoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = sevenUL; i <= threeUL; i += twoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i != threealtUL; i += twoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = sevenUL; i < threeUL; i -= minustwoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = sevenUL; i <= threeUL; i -= minustwoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i != threealtUL; i -= minustwoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i > sevenUL; --i)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i >= sevenUL; i--)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i != threealtUL; i--)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i > sevenUL; i -= twoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i >= sevenUL; i -= twoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i != threealtUL; i -= twoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i > sevenUL; i += minustwoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i >= sevenUL; i += minustwoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i != threealtUL; i += minustwoUL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = threeUL; i < sevenUL; ++i)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (unsigned long int i = threeUL; i <= sevenUL; i++)
+    BODY;
+  TEST (0xf8);
+  _Cilk_for (unsigned long int i = threeUL; i != sevenUL; i++)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (unsigned long int i = zeroUL; i < tenUL; i += twoUL)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (unsigned long int i = zeroUL; i <= tenUL; i += twoUL)
+    BODY;
+  TEST (0x555);
+  _Cilk_for (unsigned long int i = zeroUL; i != tenUL; i += twoUL)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (unsigned long int i = zeroUL; i < tenUL; i -= minustwoUL)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (unsigned long int i = zeroUL; i <= tenUL; i -= minustwoUL)
+    BODY;
+  TEST (0x555);
+  _Cilk_for (unsigned long int i = zeroUL; i != tenUL; i -= minustwoUL)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (unsigned long int i = sixUL; i > twoUL; --i)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (unsigned long int i = sevenUL; i >= threeUL; i--)
+    BODY;
+  TEST (0xf8);
+  _Cilk_for (unsigned long int i = sevenUL; i != threeUL; i--)
+    BODY;
+  TEST (0xf0);
+  _Cilk_for (unsigned long int i = elevenUL; i > oneUL; i += minustwoUL)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = elevenUL; i >= twoUL; i += minustwoUL)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = elevenUL; i != oneUL; i += minustwoUL)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = elevenUL; i > oneUL; i -= twoUL)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = elevenUL; i >= twoUL; i -= twoUL)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = elevenUL; i != oneUL; i -= twoUL)
+    BODY;
+  TEST (0xaa8);
+}
+
+int
+main ()
+{
+  _Cilk_for (int i = 7; i < 3; ++i)
+    __builtin_abort ();
+  _Cilk_for (int i = 7; i <= 3; ++i)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i != 3; ++i)
+    __builtin_abort ();
+  _Cilk_for (int i = 7; i < 3; i += 2)
+    __builtin_abort ();
+  _Cilk_for (int i = 7; i <= 3; i += 2)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i != 3; i += 2)
+    __builtin_abort ();
+  _Cilk_for (int i = 7; i < 3; i -= -2)
+    __builtin_abort ();
+  _Cilk_for (int i = 7; i <= 3; i -= -2)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i != 3; i -= -2)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i > 7; --i)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i >= 7; i--)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i != 3; i--)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i > 7; i -= 2)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i >= 7; i -= 2)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i != 3; i -= 2)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i > 7; i += -2)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i >= 7; i += -2)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i != 3; i += -2)
+    __builtin_abort ();
+  _Cilk_for (int i = 3; i < 7; ++i)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (int i = 3; i <= 7; i++)
+    BODY;
+  TEST (0xf8);
+  _Cilk_for (int i = 3; i != 7; i++)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (int i = 0; i < 10; i += 2)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (int i = 0; i <= 10; i += 2)
+    BODY;
+  TEST (0x555);
+  _Cilk_for (int i = 0; i != 10; i += 2)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (int i = 0; i < 10; i -= -2)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (int i = 0; i <= 10; i -= -2)
+    BODY;
+  TEST (0x555);
+  _Cilk_for (int i = 0; i != 10; i -= -2)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (int i = 6; i > 2; --i)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (int i = 7; i >= 3; i--)
+    BODY;
+  TEST (0xf8);
+  _Cilk_for (int i = 7; i != 3; i--)
+    BODY;
+  TEST (0xf0);
+  _Cilk_for (int i = 11; i > 1; i += -2)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (int i = 11; i >= 2; i += -2)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (int i = 11; i != 1; i += -2)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (int i = 11; i > 1; i -= 2)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (int i = 11; i >= 2; i -= 2)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (int i = 11; i != 1; i -= 2)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = 7UL; i < 3UL; ++i)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 7UL; i <= 3UL; ++i)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i != 3UL; ++i)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 7UL; i < 3UL; i += 2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 7UL; i <= 3UL; i += 2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i != 3UL; i += 2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 7UL; i < 3UL; i -= -2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 7UL; i <= 3UL; i -= -2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i != 3UL; i -= -2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i > 7UL; --i)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i >= 7UL; i--)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i != 3UL; i--)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i > 7UL; i -= 2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i >= 7UL; i -= 2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i != 3UL; i -= 2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i > 7UL; i += -2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i >= 7UL; i += -2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i != 3UL; i += -2UL)
+    __builtin_abort ();
+  _Cilk_for (unsigned long int i = 3UL; i < 7UL; ++i)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (unsigned long int i = 3UL; i <= 7UL; i++)
+    BODY;
+  TEST (0xf8);
+  _Cilk_for (unsigned long int i = 3UL; i != 7UL; i++)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (unsigned long int i = 0UL; i < 10UL; i += 2UL)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (unsigned long int i = 0UL; i <= 10UL; i += 2UL)
+    BODY;
+  TEST (0x555);
+  _Cilk_for (unsigned long int i = 0UL; i != 10UL; i += 2UL)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (unsigned long int i = 0UL; i < 10UL; i -= -2UL)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (unsigned long int i = 0UL; i <= 10UL; i -= -2UL)
+    BODY;
+  TEST (0x555);
+  _Cilk_for (unsigned long int i = 0UL; i != 10UL; i -= -2UL)
+    BODY;
+  TEST (0x155);
+  _Cilk_for (unsigned long int i = 6UL; i > 2UL; --i)
+    BODY;
+  TEST (0x78);
+  _Cilk_for (unsigned long int i = 7UL; i >= 3UL; i--)
+    BODY;
+  TEST (0xf8);
+  _Cilk_for (unsigned long int i = 7UL; i != 3UL; i--)
+    BODY;
+  TEST (0xf0);
+  _Cilk_for (unsigned long int i = 11UL; i > 1UL; i += -2UL)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = 11UL; i >= 2UL; i += -2UL)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = 11UL; i != 1UL; i += -2UL)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = 11UL; i > 1UL; i -= 2UL)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = 11UL; i >= 2UL; i -= 2UL)
+    BODY;
+  TEST (0xaa8);
+  _Cilk_for (unsigned long int i = 11UL; i != 1UL; i -= 2UL)
+    BODY;
+  TEST (0xaa8);
+  test (7, 3, 2, -2, 10, 0, 11, 6, 1, 3,
+       7UL, 3UL, 2UL, -2UL, 10UL, 0UL, 11UL, 6UL, 1UL, 3UL);
+  return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-for-3.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-for-3.c
new file mode 100644 (file)
index 0000000..04c1635
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-additional-options "-std=gnu99" { target c } } */
+
+void bar (int *, int *, int *, int *);
+void baz (char **, char **, char **, int *);
+
+void
+foo ()
+{
+  int a, b, c;
+  char *d, *e;
+  bar (0, &a, &b, &c);
+  _Cilk_for (int i = a; i < b; i += c)
+    bar (&i, &a, &b, &c);
+  baz (0, &d, &e, &c);
+  _Cilk_for (char *p = d; p != e; p += c)
+    baz (&p, &d, &e, &c);
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-fors.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-fors.c
new file mode 100644 (file)
index 0000000..0a8f046
--- /dev/null
@@ -0,0 +1,87 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-additional-options "-std=gnu99" { target c } } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+
+static void check (int *Array, int start, int end, int incr, int value)
+{
+  int ii = 0;
+  for (ii = start;  ii < end; ii = ii + incr)
+    if (Array[ii] != value)
+      __builtin_abort ();
+#if HAVE_IO
+  printf ("Passed\n");
+#endif
+}
+
+static void check_reverse (int *Array, int start, int end, int incr, int value)
+{
+  int ii = 0;
+  for (ii = start; ii >= end; ii = ii - incr)
+    if (Array[ii] != value)
+      __builtin_abort ();
+#if HAVE_IO
+  printf ("Passed\n");
+#endif
+}
+
+
+int main (void)
+{
+  int Array[10];
+  int x = 9, y = 0, z = 3;
+
+
+  _Cilk_for (int ii = 0; ii < 10; ii++)
+    Array[ii] = 1133;
+  check (Array, 0, 10, 1, 1133);
+
+  _Cilk_for (int ii = 0; ii < 10; ++ii)
+    Array[ii] = 3311;
+  check (Array, 0, 10, 1, 3311);
+
+  _Cilk_for (int ii = 9; ii > -1; ii--)
+    Array[ii] = 4433;
+  check_reverse (Array, 9, 0, 1, 4433);
+
+  _Cilk_for (int ii = 9; ii > -1; --ii)
+    Array[ii] = 9988;
+  check_reverse (Array, 9, 0, 1, 9988);
+
+  _Cilk_for (int ii = 0; ii < 10; ++ii)
+    Array[ii] = 3311;
+  check (Array, 0, 10, 1, 3311);
+
+  _Cilk_for (int ii = 0; ii < 10; ii += 2)
+    Array[ii] = 1328;
+  check (Array, 0, 10, 2, 1328);
+
+  _Cilk_for (int ii = 9; ii >= 0; ii -= 2)
+    Array[ii] = 1738;
+  check_reverse (Array, 9, 0, 2, 1738);
+
+
+  _Cilk_for (int ii = 0; ii < 10; ii++)
+    {
+      if (ii % 2)
+       Array[ii] = 1343;
+      else
+       Array[ii] = 3413;
+    }
+
+  check (Array, 1, 10, 2, 1343);
+  check (Array, 0, 10, 2, 3413);
+
+  _Cilk_for (short cc = 0; cc < 10; cc++)
+    Array[cc] = 1343;
+  check (Array, 0, 10,  1,1343);
+
+  _Cilk_for (short cc = 9; cc >= 0; cc--)
+    Array[cc] = 1348;
+  check_reverse (Array, 9, 0, 1, 1348);
+  return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_errors.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_errors.c
new file mode 100644 (file)
index 0000000..60a9e7d
--- /dev/null
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+
+
+int main (void)
+{
+  int q = 0, ii = 0, jj = 0;
+
+  _Cilk_for (int ii; ii < 10; ii++) /* { dg-error "is not initialized" "" { target c } } */
+    /* { dg-error "expected" "" { target c++ } 10 } */
+    q = 5;
+
+  _Cilk_for (; ii < 10; ii++) /* { dg-error "expected iteration declaration" } */
+    q = 2;
+
+  _Cilk_for (int ii = 0; ; ii++) /* { dg-error "missing controlling predicate" } */
+    q = 2;
+
+  _Cilk_for (int ii = 0; ii < 10, jj < 10; ii++)  /* { dg-error "expected ';' before ',' token" "" { target c } } */
+    /* { dg-error "invalid controlling predicate" "" { target c++ }  20 } */
+    q = 5;
+
+  _Cilk_for (int ii = 0; ii < 10; ) /* { dg-error "missing increment" } */
+    q = 5;
+
+  _Cilk_for (int ii = 0, jj = 0; ii < 10; ii++) /* { dg-error "expected|invalid" } */
+    q = 5;
+
+  _Cilk_for (volatile int vii = 0; vii < 10; vii++) /* { dg-error "iteration variable cannot be volatile" } */
+    q = 5;
+
+  _Cilk_for (static int sii = 0; sii < 10; sii++) /* { dg-error "static|expected|declared|expression" } */
+    q = 5;
+
+  _Cilk_for (float fii = 3.47; fii < 5.23; fii++) /* { dg-error "invalid type for iteration variable" } */
+    q = 5;
+
+  _Cilk_for (int ii = 0; 10 > jj; ii++) /* { dg-error "invalid controlling predicate" } */
+    q = 5;
+
+  _Cilk_for (int ii = 0; ii < 10; ii >> 1) /* { dg-error "invalid increment expression" } */
+    q = 5;
+
+  _Cilk_for (int ii = 10; ii >= 0; ii--) /* This is OK!  */
+    q = 5;
+
+  _Cilk_for (int ii; ii < 10; ii++) /* { dg-error "is not initialized" "" { target c } } */
+    /* { dg-error "expected" "" { target c++ } 48 } */
+    q = 5;
+
+  return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_grain.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_grain.c
new file mode 100644 (file)
index 0000000..ec02613
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-additional-options "-std=gnu99" { target c } } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+
+int grain_value = 2;
+int main (void)
+{
+  int Array1[200], Array1_Serial[200];
+
+  for (int ii = 0; ii < 200; ii++)
+    {
+      Array1_Serial[ii] = 2;
+      Array1[ii] = 1;
+    }
+
+#pragma cilk grainsize = 2
+  _Cilk_for (int ii = 0; ii < 200; ii++)
+    Array1[ii] = 2;
+
+  for (int ii = 0; ii < 200; ii++)
+    if (Array1[ii] != Array1_Serial[ii])
+      return (ii+1);
+
+#pragma cilk grainsize = grain_value
+  _Cilk_for (int ii = 0; ii < 200; ii++)
+    Array1[ii] = 2;
+
+  for (int ii = 0; ii < 200; ii++)
+    if (Array1[ii] != Array1_Serial[ii])
+      return (ii+1);
+
+  return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_grain_errors.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_grain_errors.c
new file mode 100644 (file)
index 0000000..214c6be
--- /dev/null
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus -Wunknown-pragmas" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+
+
+char Array1[26];
+
+#pragma cilk grainsize = 2 /* { dg-error "must be inside a function" } */
+
+int main(int argc, char **argv)
+{
+/* This is OK.  */
+#pragma cilk grainsize = 2
+  _Cilk_for (int ii = 0; ii < 10; ii++)
+    Array1[ii] = 0;
+
+#pragma cilk grainsize 2 /* { dg-error "expected '=' before numeric constant" } */
+  _Cilk_for (int ii = 0; ii < 10; ii++)
+    Array1[ii] = 0;
+
+#pragma cilk grainsiz = 2 /* { dg-warning "ignoring #pragma cilk grainsiz" } */
+  _Cilk_for (int ii = 0; ii < 10; ii++)
+    Array1[ii] = 0;
+
+
+/* This is OK, it will do a type conversion to long int.  */
+#pragma cilk grainsize = 0.5
+  _Cilk_for (int ii = 0; ii < 10; ii++)
+    Array1[ii] = 0;
+
+#pragma cilk grainsize = 1
+  while (Array1[5] != 0) /* { dg-warning "is not followed by" } */
+    {
+    /* Blah */
+    }
+
+#pragma cilk grainsize = 1
+  int q = 0; /* { dg-warning "is not followed by" } */
+  _Cilk_for (q = 0; q < 10; q++) /* { dg-error "allows expression instead of declaration" "" { target c++ } } */
+    Array1[q] = 5;
+
+  while (Array1[5] != 0)
+    {
+    /* Blah */
+    }
+
+  return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_ptr_iter.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_ptr_iter.c
new file mode 100644 (file)
index 0000000..f4a1f4c
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-additional-options "-std=gnu99" { target c } } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+
+
+/* <feature> loop control variable must have integer, pointer or class type
+   </feature>
+*/
+
+#define ARRAY_SIZE 10000
+int a[ARRAY_SIZE];
+
+int main(void)
+{
+  int ii = 0;
+
+  for (ii =0; ii < ARRAY_SIZE; ii++)
+    a[ii] = 5;
+  _Cilk_for(int *aa = a; aa < a + ARRAY_SIZE; aa++)
+    *aa = 0;
+  for (ii = 0; ii < ARRAY_SIZE; ii++)
+    if (a[ii] != 0)
+      __builtin_abort ();
+
+  _Cilk_for (int *aa = a; aa < a + ARRAY_SIZE; aa = aa + 2)
+    *aa = 4;
+
+  for (ii = 0; ii < ARRAY_SIZE; ii = ii + 2)
+    if (a[ii] != 4)
+      __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/nested_cilk_for.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/nested_cilk_for.c
new file mode 100644 (file)
index 0000000..3daaca9
--- /dev/null
@@ -0,0 +1,79 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-additional-options "-std=gnu99" { target c } } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+#if HAVE_IO
+#include <stdio.h>
+#endif
+
+int main (void)
+{
+  int Array[10][10];
+
+
+  for (int ii = 0; ii < 10; ii++)
+    for (int jj = 0; jj < 10; jj++)
+       {
+         Array[ii][jj] = 0;
+       }
+
+  _Cilk_for (int ii = 0; ii < 10; ii++)
+    _Cilk_for (int jj = 0; jj < 5; jj++)
+      Array[ii][jj] = 5;
+
+  for (int ii = 0; ii < 10; ii++)
+    for (int jj = 0; jj < 5; jj++)
+      if (Array[ii][jj] != 5)
+#if HAVE_IO
+       printf("Array[%d][%d] = %d\n", ii, jj, Array[ii][jj]);
+#else
+       __builtin_abort ();
+#endif
+
+
+  /* One goes up and one goes down.  */
+  _Cilk_for (int ii = 0; ii < 10; ii++)
+    _Cilk_for (int jj = 9; jj >= 0; jj--)
+      Array[ii][jj] = 7;
+
+  for (int ii = 0; ii < 10; ii++)
+    for (int jj = 9; jj >= 0; jj--)
+      if (Array[ii][jj] != 7)
+#if HAVE_IO
+       printf("Array[%d][%d] = %d\n", ii, jj, Array[ii][jj]);
+#else
+       __builtin_abort ();
+#endif
+
+  /* different step sizes.  */
+  _Cilk_for (int ii = 0; ii < 10; ii++)
+    _Cilk_for (int jj = 0; jj < 10; jj += 2)
+      Array[ii][jj] = 9;
+
+  for (int ii = 0; ii < 10; ii++)
+    for (int jj = 0; jj < 10; jj += 2)
+      if (Array[ii][jj] != 9)
+#if HAVE_IO
+       printf("Array[%d][%d] = %d\n", ii, jj, Array[ii][jj]);
+#else
+       __builtin_abort ();
+#endif
+
+  /* different step sizes.  */
+  _Cilk_for (int ii = 0; ii < 10; ii += 2)
+    _Cilk_for (int jj = 5; jj < 9; jj++)
+      Array[ii][jj] = 11;
+
+  for (int ii = 0; ii < 10; ii += 2)
+    for (int jj = 5; jj < 9; jj++)
+      if (Array[ii][jj] != 11)
+#if HAVE_IO
+       printf("Array[%d][%d] = %d\n", ii, jj, Array[ii][jj]);
+#else
+       __builtin_abort ();
+#endif
+
+  return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/cf3.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/cf3.cc
new file mode 100644 (file)
index 0000000..8d88c5f
--- /dev/null
@@ -0,0 +1,96 @@
+/* { dg-options "-fcilkplus" } */
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+
+template <typename T>
+class I
+{
+public:
+  typedef ptrdiff_t difference_type;
+  I ();
+  ~I ();
+  I (T *);
+  I (const I &);
+  T &operator * ();
+  T *operator -> ();
+  T &operator [] (const difference_type &) const;
+  I &operator = (const I &);
+  I &operator ++ ();
+  I operator ++ (int);
+  I &operator -- ();
+  I operator -- (int);
+  I &operator += (const difference_type &);
+  I &operator -= (const difference_type &);
+  I operator + (const difference_type &) const;
+  I operator - (const difference_type &) const;
+  template <typename S> friend bool operator == (I<S> &, I<S> &);
+  template <typename S> friend bool operator == (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator < (I<S> &, I<S> &);
+  template <typename S> friend bool operator < (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator <= (I<S> &, I<S> &);
+  template <typename S> friend bool operator <= (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator > (I<S> &, I<S> &);
+  template <typename S> friend bool operator > (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator >= (I<S> &, I<S> &);
+  template <typename S> friend bool operator >= (const I<S> &, const I<S> &);
+  template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &);
+  template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &);
+  template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &);
+private:
+  T *p;
+};
+template <typename T> I<T>::I () : p (0) {}
+template <typename T> I<T>::~I () {}
+template <typename T> I<T>::I (T *x) : p (x) {}
+template <typename T> I<T>::I (const I &x) : p (x.p) {}
+template <typename T> T &I<T>::operator * () { return *p; }
+template <typename T> T *I<T>::operator -> () { return p; }
+template <typename T> T &I<T>::operator [] (const difference_type &x) const { return p[x]; }
+template <typename T> I<T> &I<T>::operator = (const I &x) { p = x.p; return *this; }
+template <typename T> I<T> &I<T>::operator ++ () { ++p; return *this; }
+template <typename T> I<T> I<T>::operator ++ (int) { return I (p++); }
+template <typename T> I<T> &I<T>::operator -- () { --p; return *this; }
+template <typename T> I<T> I<T>::operator -- (int) { return I (p--); }
+template <typename T> I<T> &I<T>::operator += (const difference_type &x) { p += x; return *this; }
+template <typename T> I<T> &I<T>::operator -= (const difference_type &x) { p -= x; return *this; }
+template <typename T> I<T> I<T>::operator + (const difference_type &x) const { return I (p + x); }
+template <typename T> I<T> I<T>::operator - (const difference_type &x) const { return I (p - x); }
+template <typename T> bool operator == (I<T> &x, I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator == (const I<T> &x, const I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator != (I<T> &x, I<T> &y) { return !(x == y); }
+template <typename T> bool operator != (const I<T> &x, const I<T> &y) { return !(x == y); }
+template <typename T> bool operator < (I<T> &x, I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator < (const I<T> &x, const I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator <= (I<T> &x, I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator <= (const I<T> &x, const I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator > (I<T> &x, I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator > (const I<T> &x, const I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator >= (I<T> &x, I<T> &y) { return x.p >= y.p; }
+template <typename T> bool operator >= (const I<T> &x, const I<T> &y) { return x.p >= y.p; }
+template <typename T> typename I<T>::difference_type operator - (I<T> &x, I<T> &y) { return x.p - y.p; }
+template <typename T> typename I<T>::difference_type operator - (const I<T> &x, const I<T> &y) { return x.p - y.p; }
+template <typename T> I<T> operator + (typename I<T>::difference_type x, const I<T> &y) { return I<T> (x + y.p); }
+
+template <typename T>
+class J
+{
+public:
+  J(const I<T> &x, const I<T> &y) : b (x), e (y) {}
+  const I<T> &begin ();
+  const I<T> &end ();
+private:
+  I<T> b, e;
+};
+
+template <typename T> const I<T> &J<T>::begin () { return b; }
+template <typename T> const I<T> &J<T>::end () { return e; }
+
+template <typename T>
+void baz (I<T> &i);
+
+void
+foo (J<int> j)
+{
+  _Cilk_for (I<int> i = j.begin (); i < j.end (); i += 2)
+    baz (i);
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/cilk-for-tplt.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/cilk-for-tplt.cc
new file mode 100644 (file)
index 0000000..ff9a324
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+#define SIZE 100
+#define CHECK_VALUE 5
+
+template <class T>
+int func (T start, T end)
+{
+  int Array[SIZE];
+  _Cilk_for (T ii = 0; ii < end; ii++)
+    Array[ii] = CHECK_VALUE;
+
+  for (T ii = 0; ii < end; ii++)
+    if (Array[ii] != CHECK_VALUE)
+      __builtin_abort ();
+
+  return 0;
+}
+
+int main (void)
+{
+  return func <int> (0, 100) + func <long> (0, 100);
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/for1.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/for1.cc
new file mode 100644 (file)
index 0000000..d2243ac
--- /dev/null
@@ -0,0 +1,376 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-additional-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+#if HAVE_IO
+#include <cstdio>
+#endif
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+template <typename T>
+class I
+{
+public:
+  typedef ptrdiff_t difference_type;
+  I ();
+  ~I ();
+  I (T *);
+  I (const I &);
+  T &operator * ();
+  T *operator -> ();
+  T &operator [] (const difference_type &) const;
+  I &operator = (const I &);
+  I &operator ++ ();
+  I operator ++ (int);
+  I &operator -- ();
+  I operator -- (int);
+  I &operator += (const difference_type &);
+  I &operator -= (const difference_type &);
+  I operator + (const difference_type &) const;
+  I operator - (const difference_type &) const;
+  template <typename S> friend bool operator == (I<S> &, I<S> &);
+  template <typename S> friend bool operator == (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator < (I<S> &, I<S> &);
+  template <typename S> friend bool operator < (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator <= (I<S> &, I<S> &);
+  template <typename S> friend bool operator <= (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator > (I<S> &, I<S> &);
+  template <typename S> friend bool operator > (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator >= (I<S> &, I<S> &);
+  template <typename S> friend bool operator >= (const I<S> &, const I<S> &);
+  template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &);
+  template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &);
+  template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &);
+private:
+  T *p;
+};
+template <typename T> I<T>::I () : p (0) {}
+template <typename T> I<T>::~I () {}
+template <typename T> I<T>::I (T *x) : p (x) {}
+template <typename T> I<T>::I (const I &x) : p (x.p) {}
+template <typename T> T &I<T>::operator * () { return *p; }
+template <typename T> T *I<T>::operator -> () { return p; }
+template <typename T> T &I<T>::operator [] (const difference_type &x) const { return p[x]; }
+template <typename T> I<T> &I<T>::operator = (const I &x) { p = x.p; return *this; }
+template <typename T> I<T> &I<T>::operator ++ () { ++p; return *this; }
+template <typename T> I<T> I<T>::operator ++ (int) { return I (p++); }
+template <typename T> I<T> &I<T>::operator -- () { --p; return *this; }
+template <typename T> I<T> I<T>::operator -- (int) { return I (p--); }
+template <typename T> I<T> &I<T>::operator += (const difference_type &x) { p += x; return *this; }
+template <typename T> I<T> &I<T>::operator -= (const difference_type &x) { p -= x; return *this; }
+template <typename T> I<T> I<T>::operator + (const difference_type &x) const { return I (p + x); }
+template <typename T> I<T> I<T>::operator - (const difference_type &x) const { return I (p - x); }
+template <typename T> bool operator == (I<T> &x, I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator == (const I<T> &x, const I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator != (I<T> &x, I<T> &y) { return !(x == y); }
+template <typename T> bool operator != (const I<T> &x, const I<T> &y) { return !(x == y); }
+template <typename T> bool operator < (I<T> &x, I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator < (const I<T> &x, const I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator <= (I<T> &x, I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator <= (const I<T> &x, const I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator > (I<T> &x, I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator > (const I<T> &x, const I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator >= (I<T> &x, I<T> &y) { return x.p >= y.p; }
+template <typename T> bool operator >= (const I<T> &x, const I<T> &y) { return x.p >= y.p; }
+template <typename T> typename I<T>::difference_type operator - (I<T> &x, I<T> &y) { return x.p - y.p; }
+template <typename T> typename I<T>::difference_type operator - (const I<T> &x, const I<T> &y) { return x.p - y.p; }
+template <typename T> I<T> operator + (typename I<T>::difference_type x, const I<T> &y) { return I<T> (x + y.p); }
+
+template <typename T>
+class J
+{
+public:
+  J(const I<T> &x, const I<T> &y) : b (x), e (y) {}
+  const I<T> &begin ();
+  const I<T> &end ();
+private:
+  I<T> b, e;
+};
+
+template <typename T> const I<T> &J<T>::begin () { return b; }
+template <typename T> const I<T> &J<T>::end () { return e; }
+
+int results[2000];
+
+template <typename T>
+void
+baz (I<T> &i)
+{
+  if (*i < 0 || *i >= 2000)
+    {
+#if HAVE_IO
+      printf ("*i(%d) is < 0 or >= 2000\n", *i);
+      fflush (stdout);
+#endif
+     __builtin_abort ();
+    }
+  else
+    results[*i]++;
+}
+
+void
+f1 (const I<int> &x, const I<int> &y)
+{
+  _Cilk_for (I<int> i = x; i <= y; i += 6)
+    {
+      baz (i);
+    }
+
+#if HAVE_IO
+  printf("===== Starting F1 =========\n");
+  for (I<int> i = x; i <= y; i+= 6) {
+    printf("Result[%4d] = %2d\n", *i, results[*i]);
+    fflush (stdout);
+  }
+#endif
+}
+
+void
+f2 (const I<int> &x, const I<int> &y)
+{
+  _Cilk_for (I<int> i = x; i < y - 1; i += 2)
+    baz (i);
+
+#if HAVE_IO
+  printf("===== Starting F2 =========\n");
+  for (int ii = 0; ii < 1998; ii += 2) {
+    printf("Result[%4d] = %2d\n", ii, results[ii]);
+    fflush (stdout);
+  }
+#endif
+}
+
+template <typename T>
+void
+f3 (const I<int> &x, const I<int> &y)
+{
+  _Cilk_for (I<int> i = x; i <= y; i += 1)
+    baz (i);
+#if HAVE_IO
+  printf("===== Starting F3 =========\n");
+  for (int ii = 20; ii < 1987; ii += 1) {
+    printf("Result[%4d] = %2d\n", ii, results[ii]);
+    fflush (stdout);
+  }
+
+#endif
+}
+
+template <typename T>
+void
+f4 (const I<int> &x, const I<int> &y)
+{
+  _Cilk_for (I<int> i = x + (2000 - 64); i > y + 10; --i)
+    baz (i);
+#if HAVE_IO
+  printf("===== Starting F3 =========\n");
+  for (I<int> i = x + (2000 - 64); i > y + 10; --i) {
+    printf("Result[%4d] = %2d\n", *i, results[*i]);
+    fflush (stdout);
+  }
+#endif
+}
+void
+f5 (const I<int> &x, const I<int> &y)
+{
+  _Cilk_for (I<int> i = x + 2000 - 64; i > y + 10; i -= 10)
+    baz (i);
+#if HAVE_IO
+  for (I<int> i = x + 2000 - 64; i > y + 10; i -= 10) {
+    printf("Result[%4d] = %2d\n", *i, results[*i]);
+    fflush (stdout);
+  }
+#endif
+}
+
+template <int N>
+void
+f6 (const I<int> &x, const I<int> &y)
+{
+  _Cilk_for (I<int> i = x + 2000 - 64; i > y + 10; i -= 10)
+    {
+      I<int> j = i + N;
+      baz (j);
+    }
+#if HAVE_IO
+  for (I<int> i = x + 2000 - 64; i > y + 10; i = i - 12 + 2)
+    {
+      I<int> j = i + N;
+      printf("Result[%4d] = %2d\n", *j, results[*j]);
+      fflush (stdout);
+    }
+#endif
+}
+template <int N>
+void
+f7 (I<int> ii, const I<int> &x, const I<int> &y)
+{
+  _Cilk_for (I <int> i = x - 10; i <= y + 10; i += N)
+    baz (i);
+#if HAVE_IO
+  for (I<int> i = x - 10; i <= y + 10; i += N)
+    {
+      printf("Result[%4d] = %2d\n", *i, results[*i]);
+      fflush (stdout);
+    }
+#endif
+}
+
+template <int N>
+void
+f8 (J<int> j)
+{
+  _Cilk_for (I<int> i = j.begin (); i <= j.end () + N; i += 2)
+    baz (i);
+#if HAVE_IO
+  for (I<int> i = j.begin (); i <= j.end () + N; i += 2) {
+    printf("Result[%4d] = %2d\n", *i, results[*i]);
+    fflush (stdout);
+  }
+#endif
+
+}
+
+template <typename T, int N>
+void
+f9 (const I<T> &x, const I<T> &y)
+{
+  _Cilk_for (I<T> i = x; i <= y; i += N)
+    baz (i);
+#if HAVE_IO
+  for (I<T> i = x; i <= y;  i  = i + N)
+    {
+      printf("Result[%4d] = %2d\n", *i, results[*i]);
+      fflush (stdout);
+    }
+#endif
+}
+
+template <typename T, int N>
+void
+f10 (const I<T> &x, const I<T> &y)
+{
+  _Cilk_for (I<T> i = x; i > y; i += N)
+    baz (i);
+#if HAVE_IO
+  for (I<T> i = x; i > y;  i  = i + N) {
+    printf("Result[%4d] = %2d\n", *i, results[*i]);
+    fflush (stdout);
+  }
+#endif
+}
+
+template <typename T>
+void
+f11 (const T &x, const T &y)
+{
+    _Cilk_for (T i = x; i <= y; i += 3)
+      baz (i);
+
+#if HAVE_IO
+  for (T i = x; i <= y;  i  += 3) {
+    printf("Result[%4d] = %2d\n", *i, results[*i]);
+    fflush (stdout);
+  }
+#endif
+      T j = y + 3;
+      baz (j);
+
+}
+
+template <typename T>
+void
+f12 (const T &x, const T &y)
+{
+  _Cilk_for (T i = x; i > y; --i)
+    baz (i);
+#if HAVE_IO
+  for (T i = x; i > y;  --i) {
+    printf("Result[%4d] = %2d\n", *i, results[*i]);
+    fflush (stdout);
+  }
+#endif
+}
+template <int N>
+struct K
+{
+  template <typename T>
+  static void
+  f13 (const T &x, const T &y)
+  {
+    _Cilk_for (T i = x; i <= y + N; i += N)
+      baz (i);
+#if HAVE_IO
+  for (T i = x; i < y+N;  i += N) {
+    printf("Result[%4d] = %2d\n", *i, results[*i]);
+    fflush (stdout);
+  }
+#endif
+  }
+};
+
+#define check(expr) \
+  for (int i = 0; i < 2000; i++)                       \
+    if (expr)                                          \
+      {                                                        \
+       if (results[i] != 1) {                          \
+         __builtin_abort ();                           \
+       }                                               \
+       results[i] = 0;                                 \
+      }                                                        \
+    else if (results[i])                               \
+      abort ()
+
+int
+main ()
+{
+  int a[2000];
+  long b[2000];
+  for (int i = 0; i < 2000; i++)
+    {
+      a[i] = i;
+      b[i] = i;
+    }
+  f1 (&a[10], &a[1990]);
+  check (i >= 10 && i <= 1990 && (i - 10) % 6 == 0);
+  f2 (&a[0], &a[1999]);
+  check (i < 1998 && (i & 1) == 0);
+  f3<int> (&a[20], &a[1837]);
+  check (i >= 20 && i <= 1837);
+  f4<int> (&a[0], &a[30]);
+  check (i > 40 && i <= 2000 - 64);
+
+  f5 (&a[0], &a[100]);
+  check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0);
+  f6<-10> (&a[10], &a[110]);
+  check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0);
+
+  f7<6> (I<int> (), &a[12], &a[1800]);
+  check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0);
+
+  f8<121> (J<int> (&a[14], &a[1803]));
+  check (i >= 14 && i <= 1924 && (i & 1) == 0);
+  f9<int, 7> (&a[33], &a[1967]);
+  check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0);
+  f10<int, -7> (&a[1939], &a[17]);
+  check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0);
+  f11<I<int> > (&a[16], &a[1981]);
+  check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0);
+  f12<I<int> > (&a[1761], &a[37]);
+  check (i > 37 && i <= 1761);
+  K<5>::f13<I<int> > (&a[1], &a[1935]);
+  check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0);
+  f9<long, 7> (&b[33], &b[1967]);
+  check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0);
+  f10<long, -7> (&b[1939], &b[17]);
+  check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0);
+  f11<I<long> > (&b[16], &b[1981]);
+  check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0);
+  f12<I<long> > (&b[1761], &b[37]);
+  check (i > 37 && i <= 1761);
+  K<5>::f13<I<long> > (&b[1], &b[1935]);
+  check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0);
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/stl_iter.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/stl_iter.cc
new file mode 100644 (file)
index 0000000..d68ee7b
--- /dev/null
@@ -0,0 +1,50 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+#include <vector>
+#include <cstdio>
+#include <iostream>
+#include <algorithm>
+
+using namespace std;
+
+
+int main(void)
+{
+vector <int> array;
+vector <int> array_serial;
+
+for (int ii = -1; ii < 10; ii++)
+{
+  array.push_back(ii);
+  array_serial.push_back (ii);
+}
+_Cilk_for (vector<int>::iterator iter = array.begin(); iter != array.end();
+         iter++)
+{
+   if (*iter == 6)
+     *iter = 13;
+}
+for (vector<int>::iterator iter = array_serial.begin();
+     iter != array_serial.end(); iter++)
+{
+   if (*iter == 6)
+     *iter = 13;
+}
+sort (array.begin(), array.end());
+sort (array_serial.begin(), array_serial.end());
+
+vector <int>::iterator iter = array.begin ();
+vector <int>::iterator iter_serial = array_serial.begin ();
+
+while (iter != array.end () && iter_serial != array_serial.end ())
+{
+  if (*iter != *iter_serial)
+    __builtin_abort ();
+  iter++;
+  iter_serial++;
+}
+
+return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/stl_rev_iter.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/stl_rev_iter.cc
new file mode 100644 (file)
index 0000000..6eee0d9
--- /dev/null
@@ -0,0 +1,68 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+
+#include <vector>
+#include <cstdio>
+#include <iostream>
+#include <algorithm>
+
+using namespace std;
+
+
+int main(void)
+{
+vector <int> array,array_serial;
+
+for (int ii = -1; ii < 10; ii++)
+{
+  array.push_back(ii);
+  array_serial.push_back(ii);
+}
+_Cilk_for (vector<int>::reverse_iterator iter4 = array.rbegin();
+          iter4 != array.rend(); iter4++)
+{
+  if (*iter4 == 0x8) {
+    *iter4 = 9;
+  }
+}
+
+_Cilk_for (vector<int>::reverse_iterator iter4 = array_serial.rbegin();
+          iter4 != array_serial.rend(); iter4++)
+{
+  if (*iter4 == 0x8) {
+    *iter4 = 9;
+  }
+}
+_Cilk_for (vector<int>::reverse_iterator iter2 = array.rbegin();
+          iter2 != array.rend();
+         iter2 += 1)
+{
+   if ((*iter2 == 0x4) || (*iter2 == 0x7)) {
+    *iter2 = 0x3;
+   }
+}
+for (vector<int>::reverse_iterator iter2 = array_serial.rbegin();
+     iter2 != array_serial.rend();
+         iter2 += 1)
+{
+   if ((*iter2 == 0x4) || (*iter2 == 0x7)) {
+    *iter2 = 0x3;
+   }
+}
+sort (array.begin(), array.end());
+sort (array_serial.begin(), array_serial.end());
+
+vector <int>::iterator iter = array.begin ();
+vector <int>::iterator iter_serial = array_serial.begin ();
+while (iter != array.end () && iter_serial != array_serial.end ())
+{
+  if (*iter != *iter_serial)
+    __builtin_abort ();
+  iter++;
+  iter_serial++;
+}
+
+return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/stl_test.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/stl_test.cc
new file mode 100644 (file)
index 0000000..84518f3
--- /dev/null
@@ -0,0 +1,50 @@
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus" } */
+/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
+
+
+#include <iostream>
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+#include <algorithm>
+#include <list>
+
+using namespace std;
+
+
+int main(int argc, char **argv)
+{
+  vector <int> number_list, number_list_serial;
+  int new_number = 0;
+  int no_elements = 0;
+
+  if (argc != 2)
+  {
+    no_elements = 10;
+  }
+
+
+  number_list.clear();
+  number_list_serial.clear();
+  for (int ii = 0; ii < no_elements; ii++)
+  {
+    number_list.push_back(new_number);
+    number_list_serial.push_back(new_number);
+  }
+
+  _Cilk_for (int jj = 0; jj < no_elements; jj++)
+  {
+    number_list[jj] = jj + no_elements;
+  }
+  for (int jj = 0; jj < no_elements; jj++)
+  {
+    number_list_serial[jj] = jj + no_elements;
+  }
+
+  for (int jj = 0; jj < no_elements; jj++)
+    if (number_list_serial[jj] != number_list[jj])
+      __builtin_abort ();
+
+  return 0;
+}
index 9e9ca8c072d9b1a5fbe157fa209f85cf11bdd1a5..0761f95df45b77b544b064d0908a35a664d3a182 100644 (file)
@@ -334,7 +334,11 @@ enum omp_clause_code {
   OMP_CLAUSE_TASKGROUP,
 
   /* Internally used only clause, holding SIMD uid.  */
-  OMP_CLAUSE__SIMDUID_
+  OMP_CLAUSE__SIMDUID_,
+
+  /* Internally used only clause, holding _Cilk_for # of iterations
+     on OMP_PARALLEL.  */
+  OMP_CLAUSE__CILK_FOR_COUNT_
 };
 
 #undef DEFTREESTRUCT
@@ -351,6 +355,7 @@ enum omp_clause_schedule_kind {
   OMP_CLAUSE_SCHEDULE_GUIDED,
   OMP_CLAUSE_SCHEDULE_AUTO,
   OMP_CLAUSE_SCHEDULE_RUNTIME,
+  OMP_CLAUSE_SCHEDULE_CILKFOR,
   OMP_CLAUSE_SCHEDULE_LAST
 };
 
index 6ca594d9ffece005ab5b65021d57e322dc55156e..a378a02196d15213a88611bee0da3f4f11ec5d3e 100644 (file)
@@ -1115,6 +1115,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
        case OMP_CLAUSE_NUM_TEAMS:
        case OMP_CLAUSE_THREAD_LIMIT:
        case OMP_CLAUSE_SAFELEN:
+       case OMP_CLAUSE__CILK_FOR_COUNT_:
          wi->val_only = true;
          wi->is_lhs = false;
          convert_nonlocal_reference_op (&OMP_CLAUSE_OPERAND (clause, 0),
@@ -1744,6 +1745,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
        case OMP_CLAUSE_NUM_TEAMS:
        case OMP_CLAUSE_THREAD_LIMIT:
        case OMP_CLAUSE_SAFELEN:
+       case OMP_CLAUSE__CILK_FOR_COUNT_:
          wi->val_only = true;
          wi->is_lhs = false;
          convert_local_reference_op (&OMP_CLAUSE_OPERAND (clause, 0), &dummy,
index aee03319cf0bb8fa06fb420d111461b036749164..ce0c655bd3d8781c4246bede1245710f9a4c07d9 100644 (file)
@@ -361,6 +361,13 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
       pp_right_paren (buffer);
       break;
 
+    case OMP_CLAUSE__CILK_FOR_COUNT_:
+      pp_string (buffer, "_Cilk_for_count_(");
+      dump_generic_node (buffer, OMP_CLAUSE_OPERAND (clause, 0),
+                        spc, flags, false);
+      pp_right_paren (buffer);
+      break;
+
     case OMP_CLAUSE_NOWAIT:
       pp_string (buffer, "nowait");
       break;
@@ -411,6 +418,9 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
        case OMP_CLAUSE_SCHEDULE_AUTO:
          pp_string (buffer, "auto");
          break;
+       case OMP_CLAUSE_SCHEDULE_CILKFOR:
+         pp_string (buffer, "cilk-for grain");
+         break;
        default:
          gcc_unreachable ();
        }
@@ -2421,6 +2431,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       pp_string (buffer, "#pragma simd");
       goto dump_omp_loop;
 
+    case CILK_FOR:
+      /* This label points one line after dumping the clauses.
+        For _Cilk_for the clauses are dumped after the _Cilk_for (...)
+        parameters are printed out.  */
+      goto dump_omp_loop_cilk_for;
+
     case OMP_DISTRIBUTE:
       pp_string (buffer, "#pragma omp distribute");
       goto dump_omp_loop;
@@ -2449,18 +2465,22 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
     dump_omp_loop:
       dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
 
+    dump_omp_loop_cilk_for:
       if (!(flags & TDF_SLIM))
        {
          int i;
 
          if (OMP_FOR_PRE_BODY (node))
            {
-             newline_and_indent (buffer, spc + 2);
+             if (TREE_CODE (node) == CILK_FOR)
+               pp_string (buffer, "  ");
+             else
+               newline_and_indent (buffer, spc + 2);
              pp_left_brace (buffer);
              spc += 4;
              newline_and_indent (buffer, spc);
              dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
-                 spc, flags, false);
+                                spc, flags, false);
            }
          if (OMP_FOR_INIT (node))
            {
@@ -2468,8 +2488,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
              for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (node)); i++)
                {
                  spc += 2;
-                 newline_and_indent (buffer, spc);
-                 pp_string (buffer, "for (");
+                 if (TREE_CODE (node) != CILK_FOR || OMP_FOR_PRE_BODY (node))
+                   newline_and_indent (buffer, spc);
+                 if (TREE_CODE (node) == CILK_FOR)
+                   pp_string (buffer, "_Cilk_for (");
+                 else
+                   pp_string (buffer, "for (");
                  dump_generic_node (buffer,
                                     TREE_VEC_ELT (OMP_FOR_INIT (node), i),
                                     spc, flags, false);
@@ -2483,6 +2507,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
                                     spc, flags, false);
                  pp_right_paren (buffer);
                }
+             if (TREE_CODE (node) == CILK_FOR)
+               dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
            }
          if (OMP_FOR_BODY (node))
            {
index 33922a03c51f46e461f7ea21581e36d02fc55dc8..d1d67efa62942cb9662ebb48127e7c83cccc0c77 100644 (file)
@@ -281,6 +281,7 @@ unsigned const char omp_clause_num_ops[] =
   0, /* OMP_CLAUSE_SECTIONS  */
   0, /* OMP_CLAUSE_TASKGROUP  */
   1, /* OMP_CLAUSE__SIMDUID_  */
+  1, /* OMP_CLAUSE__CILK_FOR_COUNT_  */
 };
 
 const char * const omp_clause_code_name[] =
@@ -324,7 +325,8 @@ const char * const omp_clause_code_name[] =
   "parallel",
   "sections",
   "taskgroup",
-  "_simduid_"
+  "_simduid_",
+  "_Cilk_for_count_"
 };
 
 
@@ -11041,6 +11043,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
        case OMP_CLAUSE_SIMDLEN:
        case OMP_CLAUSE__LOOPTEMP_:
        case OMP_CLAUSE__SIMDUID_:
+       case OMP_CLAUSE__CILK_FOR_COUNT_:
          WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0));
          /* FALLTHRU */
 
index 84ffe93aa6fdc827f18ca81225bca007d50b50f6..bd39e4b89bd4cbdb6fae1c563702511c09fb108a 100644 (file)
@@ -1064,6 +1064,10 @@ DEFTREECODE (OMP_SIMD, "omp_simd", tcc_statement, 6)
    Operands like for OMP_FOR.  */
 DEFTREECODE (CILK_SIMD, "cilk_simd", tcc_statement, 6)
 
+/* Cilk Plus - _Cilk_for (..)
+   Operands like for OMP_FOR.  */
+DEFTREECODE (CILK_FOR, "cilk_for", tcc_statement, 6)
+
 /* OpenMP - #pragma omp distribute [clause1 ... clauseN]
    Operands like for OMP_FOR.  */
 DEFTREECODE (OMP_DISTRIBUTE, "omp_distribute", tcc_statement, 6)