summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-09-02 12:52:29 +0000
committerkyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4>2014-09-02 12:52:29 +0000
commit407509954982a4c81744de81eeb6c01ad67c4707 (patch)
tree88fc4c24c6347b42ca239861cc28a6716e4730ab
parent88599a7ab3e2747a5908c4446ea5fb16f7e0ba89 (diff)
downloadgcc-407509954982a4c81744de81eeb6c01ad67c4707.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@214818 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog49
-rw-r--r--gcc/c-family/ChangeLog13
-rw-r--r--gcc/c-family/c-cilkplus.c133
-rw-r--r--gcc/c-family/c-common.c1
-rw-r--r--gcc/c-family/c-common.h3
-rw-r--r--gcc/c-family/c-omp.c9
-rw-r--r--gcc/c-family/c-pragma.c5
-rw-r--r--gcc/c-family/c-pragma.h3
-rw-r--r--gcc/c/ChangeLog13
-rw-r--r--gcc/c/c-parser.c183
-rw-r--r--gcc/c/c-typeck.c1
-rw-r--r--gcc/cilk-builtins.def2
-rw-r--r--gcc/cilk-common.c45
-rw-r--r--gcc/cilk.h5
-rw-r--r--gcc/cp/ChangeLog28
-rw-r--r--gcc/cp/cp-cilkplus.c4
-rw-r--r--gcc/cp/parser.c127
-rw-r--r--gcc/cp/pt.c1
-rw-r--r--gcc/cp/semantics.c152
-rw-r--r--gcc/gimple-pretty-print.c22
-rw-r--r--gcc/gimple.h9
-rw-r--r--gcc/gimplify.c4
-rw-r--r--gcc/omp-low.c337
-rw-r--r--gcc/testsuite/ChangeLog19
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-for-2.c393
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-for-3.c19
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-fors.c87
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_errors.c53
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_grain.c35
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_grain_errors.c48
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_ptr_iter.c35
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/CK/nested_cilk_for.c79
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/CK/cf3.cc96
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/CK/cilk-for-tplt.cc25
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/CK/for1.cc376
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/CK/stl_iter.cc50
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/CK/stl_rev_iter.cc68
-rw-r--r--gcc/testsuite/g++.dg/cilk-plus/CK/stl_test.cc50
-rw-r--r--gcc/tree-core.h7
-rw-r--r--gcc/tree-nested.c2
-rw-r--r--gcc/tree-pretty-print.c34
-rw-r--r--gcc/tree.c5
-rw-r--r--gcc/tree.def4
43 files changed, 2569 insertions, 65 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b615fab05d6..a59c8a4cd8c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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".
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 762f7e9a71f..fdcaa0d2392 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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,
diff --git a/gcc/c-family/c-cilkplus.c b/gcc/c-family/c-cilkplus.c
index 1a16f6690b0..131da0b3fea 100644
--- a/gcc/c-family/c-cilkplus.c
+++ b/gcc/c-family/c-cilkplus.c
@@ -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;
+}
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 58b976378d5..16cc5f6ed7a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -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 },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index d1cc810e2a7..993a97b5a66 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -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 */
diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index 6a0e41988a7..d6ca3df51e8 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -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;
}
}
diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c
index 804f37cee51..da928b2abdd 100644
--- a/gcc/c-family/c-pragma.c
+++ b/gcc/c-family/c-pragma.c
@@ -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
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index 6f1bf74c2a9..b9f09ba9f98 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -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,
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index c4661ff0dc8..2d02c7b9466 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -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,
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 34f1e4701f1..03c68309493 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -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);
+}
+
/* Parse a transaction attribute (GCC Extension).
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index a7de8f3c734..da71ab263f9 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -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;
diff --git a/gcc/cilk-builtins.def b/gcc/cilk-builtins.def
index 9f3240a892f..bf319d594fa 100644
--- a/gcc/cilk-builtins.def
+++ b/gcc/cilk-builtins.def
@@ -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")
diff --git a/gcc/cilk-common.c b/gcc/cilk-common.c
index a6a1aa2a968..35c47e19cd7 100644
--- a/gcc/cilk-common.c
+++ b/gcc/cilk-common.c
@@ -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. */
diff --git a/gcc/cilk.h b/gcc/cilk.h
index ae96f53c37c..1fee929af19 100644
--- a/gcc/cilk.h
+++ b/gcc/cilk.h
@@ -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]
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 58890b47248..7a72097c646 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-cilkplus.c b/gcc/cp/cp-cilkplus.c
index daa9b8ebb38..565dd402f70 100644
--- a/gcc/cp/cp-cilkplus.c
+++ b/gcc/cp/cp-cilkplus.c
@@ -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);
}
-
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ad99cab38cf..05fa86a655b 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index eac837f0a03..5ea5a5854d8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 168bde8fc7c..01748dab0e8 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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;
}
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 283aca279ba..60b56b0d3d4 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -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);
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 51814baa65a..ec415850bc3 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -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,
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 658c5d2fac3..0ebc24c4524 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -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;
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 9d1cd2ce0f8..22a8fcab57f 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -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)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6825ea16f6b..7281fd92da4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..fd30667f8dc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-for-2.c
@@ -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
index 00000000000..04c1635b012
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-for-3.c
@@ -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
index 00000000000..0a8f046b637
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk-fors.c
@@ -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
index 00000000000..60a9e7dbf36
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_errors.c
@@ -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
index 00000000000..ec02613ee91
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_grain.c
@@ -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
index 00000000000..214c6be1e94
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_grain_errors.c
@@ -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
index 00000000000..f4a1f4c1324
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/cilk_for_ptr_iter.c
@@ -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
index 00000000000..3daaca9ae87
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/nested_cilk_for.c
@@ -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
index 00000000000..8d88c5f346c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/cf3.cc
@@ -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
index 00000000000..ff9a324a13f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/cilk-for-tplt.cc
@@ -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
index 00000000000..d2243acf581
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/for1.cc
@@ -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
index 00000000000..d68ee7b7e7b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/stl_iter.cc
@@ -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
index 00000000000..6eee0d99ed1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/stl_rev_iter.cc
@@ -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
index 00000000000..84518f34344
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/stl_test.cc
@@ -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;
+}
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 9e9ca8c072d..0761f95df45 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -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
};
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 6ca594d9ffe..a378a02196d 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -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,
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index aee03319cf0..ce0c655bd3d 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -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))
{
diff --git a/gcc/tree.c b/gcc/tree.c
index 33922a03c51..d1d67efa629 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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 */
diff --git a/gcc/tree.def b/gcc/tree.def
index 84ffe93aa6f..bd39e4b89bd 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -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)