cilk-builtins.def (__cilkrts_cilk_for_32): New.

gcc/
	* cilk-builtins.def (__cilkrts_cilk_for_32): New.
	(__cilkrts_cilk_for_64): Likewise.
	* cilk-common.c (declare_cilk_for_builtin): New function.
	(cilk_init_builtins): Declare __cilkrts_cilk_for_32 and
	__cilkrts_cilk_for_64 bultins.
	* cilk.h (enum cilk_tree_index): Added CILK_TI_F_LOOP_32 and
	CILK_TI_F_LOOP_64.
	(cilk_for_32_fndecl): New define.
	(cilk_for_64_fndecl): Likewise.
	* gimple-pretty-print.c (dump_gimple_omp_for): Correct hadling of
	GF_OMP_FOR_KIND_CILKFOR cases; Added NE_EXPR case.
	* gimple.h (enum gf_mask): Added GF_OMP_FOR_KIND_CILKFOR; adjusted
	GF_OMP_FOR_KIND_MASK, GF_OMP_FOR_SIMD, GF_OMP_FOR_COMBINED,
	GF_OMP_FOR_COMBINED_INTO.
	* gimplify.c (gimplify_scan_omp_clauses): Added
	OMP_CLAUSE__CILK_FOR_COUNT_ case.
	(gimplify_adjust_omp_clauses): Ditto.
	(gimplify_omp_for): Added CILK_FOR case.
	(gimplify_expr): Ditto.
	* omp-low.c: Include cilk.h.
	(extract_omp_for_data): Set appropriate kind for
	GF_OMP_FOR_KIND_CILKFOR; added check for GF_OMP_FOR_KIND_CILKFOR.
	(scan_sharing_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_ cases.
	(create_omp_child_function_name): Added second argument to handle
	cilk_for case.
	(cilk_for_check_loop_diff_type): New function.
	(expand_cilk_for_call): Likewise.
	(expand_cilk_for): Likewise.
	(create_omp_child_function): Set cilk_for_count; handle the cases when
	it is true; call create_omp_child_function_name with second argument.
	(expand_omp_taskreg): Set is_cilk_for and handle cases when it's true.
	(expand_omp_for): Handle case of GF_OMP_FOR_KIND_CILKFOR.
	* tree-core.h (omp_clause_code): Added OMP_CLAUSE__CILK_FOR_COUNT_.
	* tree-nested.c (convert_nonlocal_omp_clauses): Added
	OMP_CLAUSE__CILK_FOR_COUNT_ case.
	(convert_local_omp_clauses): Ditto.
	* tree-pretty-print.c (dump_omp_clause): Added
	OMP_CLAUSE__CILK_FOR_COUNT_ and OMP_CLAUSE_SCHEDULE_CILKFOR cases.
	(dump_generic_node): Added CILK_FOR case.
	* tree.c (omp_clause_num_ops): New element
	OMP_CLAUSE__CILK_FOR_COUNT_ (1).
	(omp_clause_code_name): New element _Cilk_for_count_.
	(walk_tree_1): Added OMP_CLAUSE__CILK_FOR_COUNT_ case.
	* tree.def: Add tree code for CILK_FOR.

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

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

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

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

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

From-SVN: r214818
This commit is contained in:
Jakub Jelinek 2014-09-02 14:52:29 +02:00 committed by Kirill Yukhin
parent 794307309b
commit 9a771876d3
43 changed files with 2569 additions and 65 deletions

View File

@ -1,3 +1,52 @@
2014-09-02 Jakub Jelinek <jakub@redhat.com>
Balaji V. Iyer <balaji.v.iyer@intel.com>
Igor Zamyatin <igor.zamyatin@intel.com>
* cilk-builtins.def (__cilkrts_cilk_for_32): New.
(__cilkrts_cilk_for_64): Likewise.
* cilk-common.c (declare_cilk_for_builtin): New function.
(cilk_init_builtins): Declare __cilkrts_cilk_for_32 and
__cilkrts_cilk_for_64 bultins.
* cilk.h (enum cilk_tree_index): Added CILK_TI_F_LOOP_32 and
CILK_TI_F_LOOP_64.
(cilk_for_32_fndecl): New define.
(cilk_for_64_fndecl): Likewise.
* gimple-pretty-print.c (dump_gimple_omp_for): Correct hadling of
GF_OMP_FOR_KIND_CILKFOR cases; Added NE_EXPR case.
* gimple.h (enum gf_mask): Added GF_OMP_FOR_KIND_CILKFOR; adjusted
GF_OMP_FOR_KIND_MASK, GF_OMP_FOR_SIMD, GF_OMP_FOR_COMBINED,
GF_OMP_FOR_COMBINED_INTO.
* gimplify.c (gimplify_scan_omp_clauses): Added
OMP_CLAUSE__CILK_FOR_COUNT_ case.
(gimplify_adjust_omp_clauses): Ditto.
(gimplify_omp_for): Added CILK_FOR case.
(gimplify_expr): Ditto.
* omp-low.c: Include cilk.h.
(extract_omp_for_data): Set appropriate kind for
GF_OMP_FOR_KIND_CILKFOR; added check for GF_OMP_FOR_KIND_CILKFOR.
(scan_sharing_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_ cases.
(create_omp_child_function_name): Added second argument to handle
cilk_for case.
(cilk_for_check_loop_diff_type): New function.
(expand_cilk_for_call): Likewise.
(expand_cilk_for): Likewise.
(create_omp_child_function): Set cilk_for_count; handle the cases when
it is true; call create_omp_child_function_name with second argument.
(expand_omp_taskreg): Set is_cilk_for and handle cases when it's true.
(expand_omp_for): Handle case of GF_OMP_FOR_KIND_CILKFOR.
* tree-core.h (omp_clause_code): Added OMP_CLAUSE__CILK_FOR_COUNT_.
* tree-nested.c (convert_nonlocal_omp_clauses): Added
OMP_CLAUSE__CILK_FOR_COUNT_ case.
(convert_local_omp_clauses): Ditto.
* tree-pretty-print.c (dump_omp_clause): Added
OMP_CLAUSE__CILK_FOR_COUNT_ and OMP_CLAUSE_SCHEDULE_CILKFOR cases.
(dump_generic_node): Added CILK_FOR case.
* tree.c (omp_clause_num_ops): New element
OMP_CLAUSE__CILK_FOR_COUNT_ (1).
(omp_clause_code_name): New element _Cilk_for_count_.
(walk_tree_1): Added OMP_CLAUSE__CILK_FOR_COUNT_ case.
* tree.def: Add tree code for CILK_FOR.
2014-09-02 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/40x.md (ppc403-integer): Move "exts" to "no dot".

View File

@ -1,3 +1,16 @@
2014-09-02 Jakub Jelinek <jakub@redhat.com>
Balaji V. Iyer <balaji.v.iyer@intel.com>
Igor Zamyatin <igor.zamyatin@intel.com>
* c-cilkplus.c (cilk_for_number_of_iterations): New function.
* c-common.c (c_common_reswords): Added _Cilk_for.
* c-common.h (enum rid): Added RID_CILK_FOR.
(cilk_for_number_of_iterations): Add declaration.
* c-omp.c (c_finish_omp_for): Added checks for CILK_SIMD and
CILK_FOR.
* c-pragma.c (init_pragma): Register "grainsize" pragma.
* c-pragma.h (enum pragma_kind): Add PRAGMA_CILK_GRAINSIZE.
2014-08-29 Manuel López-Ibáñez <manu@gcc.gnu.org>
* c.opt (Wbuiltin-macro-redefined,Wdeprecated,Wendif-labels,

View File

@ -91,3 +91,136 @@ c_finish_cilk_clauses (tree clauses)
}
return clauses;
}
/* Calculate number of iterations of CILK_FOR. */
tree
cilk_for_number_of_iterations (tree cilk_for)
{
tree t, v, n1, n2, step, type, init, cond, incr, itype;
enum tree_code cond_code;
location_t loc = EXPR_LOCATION (cilk_for);
init = TREE_VEC_ELT (OMP_FOR_INIT (cilk_for), 0);
v = TREE_OPERAND (init, 0);
cond = TREE_VEC_ELT (OMP_FOR_COND (cilk_for), 0);
incr = TREE_VEC_ELT (OMP_FOR_INCR (cilk_for), 0);
type = TREE_TYPE (v);
gcc_assert (TREE_CODE (TREE_TYPE (v)) == INTEGER_TYPE
|| TREE_CODE (TREE_TYPE (v)) == POINTER_TYPE);
n1 = TREE_OPERAND (init, 1);
cond_code = TREE_CODE (cond);
n2 = TREE_OPERAND (cond, 1);
switch (cond_code)
{
case LT_EXPR:
case GT_EXPR:
case NE_EXPR:
break;
case LE_EXPR:
if (POINTER_TYPE_P (TREE_TYPE (n2)))
n2 = fold_build_pointer_plus_hwi_loc (loc, n2, 1);
else
n2 = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (n2), n2,
build_int_cst (TREE_TYPE (n2), 1));
cond_code = LT_EXPR;
break;
case GE_EXPR:
if (POINTER_TYPE_P (TREE_TYPE (n2)))
n2 = fold_build_pointer_plus_hwi_loc (loc, n2, -1);
else
n2 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (n2), n2,
build_int_cst (TREE_TYPE (n2), 1));
cond_code = GT_EXPR;
break;
default:
gcc_unreachable ();
}
step = NULL_TREE;
switch (TREE_CODE (incr))
{
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
step = build_int_cst (TREE_TYPE (v), 1);
break;
case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR:
step = build_int_cst (TREE_TYPE (v), -1);
break;
case MODIFY_EXPR:
t = TREE_OPERAND (incr, 1);
gcc_assert (TREE_OPERAND (t, 0) == v);
switch (TREE_CODE (t))
{
case PLUS_EXPR:
step = TREE_OPERAND (t, 1);
break;
case POINTER_PLUS_EXPR:
step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
break;
case MINUS_EXPR:
step = TREE_OPERAND (t, 1);
step = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (step), step);
break;
default:
gcc_unreachable ();
}
break;
default:
gcc_unreachable ();
}
itype = type;
if (POINTER_TYPE_P (itype))
itype = signed_type_for (itype);
if (cond_code == NE_EXPR)
{
/* For NE_EXPR, we need to find out if the iterator increases
or decreases from whether step is positive or negative. */
tree stype = itype;
if (TYPE_UNSIGNED (stype))
stype = signed_type_for (stype);
cond = fold_build2_loc (loc, GE_EXPR, boolean_type_node,
fold_convert_loc (loc, stype, step),
build_int_cst (stype, 0));
t = fold_build3_loc (loc, COND_EXPR, itype, cond,
build_int_cst (itype, -1),
build_int_cst (itype, 1));
}
else
t = build_int_cst (itype, (cond_code == LT_EXPR ? -1 : 1));
t = fold_build2_loc (loc, PLUS_EXPR, itype,
fold_convert_loc (loc, itype, step), t);
t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
fold_convert_loc (loc, itype, n2));
t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
fold_convert_loc (loc, itype, n1));
if (TYPE_UNSIGNED (itype) && cond_code == GT_EXPR)
t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
fold_build1_loc (loc, NEGATE_EXPR, itype, t),
fold_build1_loc (loc, NEGATE_EXPR, itype,
fold_convert_loc (loc, itype,
step)));
else if (TYPE_UNSIGNED (itype) && cond_code == NE_EXPR)
{
tree t1
= fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
fold_convert_loc (loc, itype, step));
tree t2
= fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
fold_build1_loc (loc, NEGATE_EXPR, itype, t),
fold_build1_loc (loc, NEGATE_EXPR, itype,
fold_convert_loc (loc, itype,
step)));
t = fold_build3_loc (loc, COND_EXPR, itype, cond, t1, t2);
}
else
t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
fold_convert_loc (loc, itype, step));
cond = fold_build2_loc (loc, cond_code, boolean_type_node, n1, n2);
t = fold_build3_loc (loc, COND_EXPR, itype, cond, t,
build_int_cst (itype, 0));
return t;
}

View File

@ -418,6 +418,7 @@ const struct c_common_resword c_common_reswords[] =
{ "_Complex", RID_COMPLEX, 0 },
{ "_Cilk_spawn", RID_CILK_SPAWN, 0 },
{ "_Cilk_sync", RID_CILK_SYNC, 0 },
{ "_Cilk_for", RID_CILK_FOR, 0 },
{ "_Imaginary", RID_IMAGINARY, D_CONLY },
{ "_Decimal32", RID_DFLOAT32, D_CONLY | D_EXT },
{ "_Decimal64", RID_DFLOAT64, D_CONLY | D_EXT },

View File

@ -149,7 +149,7 @@ enum rid
RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT,
/* Cilk Plus keywords. */
RID_CILK_SPAWN, RID_CILK_SYNC,
RID_CILK_SPAWN, RID_CILK_SYNC, RID_CILK_FOR,
/* Objective-C ("AT" reserved words - they are only keywords when
they follow '@') */
@ -1395,4 +1395,5 @@ extern tree create_cilk_function_exit (tree, bool, bool);
extern tree cilk_install_body_pedigree_operations (tree);
extern void cilk_outline (tree, tree *, void *);
extern bool contains_cilk_spawn_stmt (tree);
extern tree cilk_for_number_of_iterations (tree);
#endif /* ! GCC_C_COMMON_H */

View File

@ -396,7 +396,7 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
bool fail = false;
int i;
if (code == CILK_SIMD
if ((code == CILK_SIMD || code == CILK_FOR)
&& !c_check_cilk_loop (locus, TREE_VEC_ELT (declv, 0)))
fail = true;
@ -515,7 +515,10 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
|| TREE_CODE (cond) == EQ_EXPR)
{
if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
cond_ok = false;
{
if (code != CILK_SIMD && code != CILK_FOR)
cond_ok = false;
}
else if (operand_equal_p (TREE_OPERAND (cond, 1),
TYPE_MIN_VALUE (TREE_TYPE (decl)),
0))
@ -526,7 +529,7 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
0))
TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
? LT_EXPR : GE_EXPR);
else if (code != CILK_SIMD)
else if (code != CILK_SIMD && code != CILK_FOR)
cond_ok = false;
}
}

View File

@ -1405,6 +1405,11 @@ init_pragma (void)
if (!flag_preprocess_only)
cpp_register_deferred_pragma (parse_in, "GCC", "ivdep", PRAGMA_IVDEP, false,
false);
if (flag_cilkplus && !flag_preprocess_only)
cpp_register_deferred_pragma (parse_in, "cilk", "grainsize",
PRAGMA_CILK_GRAINSIZE, true, false);
#ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
#else

View File

@ -55,6 +55,9 @@ typedef enum pragma_kind {
/* Top level clause to handle all Cilk Plus pragma simd clauses. */
PRAGMA_CILK_SIMD,
/* This pragma handles setting of grainsize for a _Cilk_for. */
PRAGMA_CILK_GRAINSIZE,
PRAGMA_GCC_PCH_PREPROCESS,
PRAGMA_IVDEP,

View File

@ -1,3 +1,16 @@
2014-09-02 Jakub Jelinek <jakub@redhat.com>
Balaji V. Iyer <balaji.v.iyer@intel.com>
Igor Zamyatin <igor.zamyatin@intel.com>
* c-parser.c (c_parser_cilk_for): New function.
(c_parser_cilk_grainsize): Likewise.
(c_get_temp_regvar): Likewise.
(c_parser_statement_after_labels): Added RID_CILK_FOR case.
(c_parser_pragma): Added PRAGMA_CILK_GRAINSIZE case.
(c_parser_omp_for_loop): Added CILK_FOR and CILK_SIMD checks.
* c-typeck.c (c_finish_omp_clauses): Added OMP_CLAUSE__CILK_FOR_COUNT_
case.
2014-08-27 Chen Gang <gang.chen.5i5j@gmail.com>
* c-aux-info.c (gen_type): Resize 'buff' from 10 to 23 bytes,

View File

@ -1264,9 +1264,11 @@ static bool c_parser_objc_diagnose_bad_element_prefix
/* Cilk Plus supporting routines. */
static void c_parser_cilk_simd (c_parser *);
static void c_parser_cilk_for (c_parser *, tree);
static bool c_parser_cilk_verify_simd (c_parser *, enum pragma_context);
static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool);
static void c_parser_cilk_grainsize (c_parser *);
/* Parse a translation unit (C90 6.7, C99 6.9).
@ -4895,6 +4897,16 @@ c_parser_statement_after_labels (c_parser *parser)
case RID_FOR:
c_parser_for_statement (parser, false);
break;
case RID_CILK_FOR:
if (!flag_cilkplus)
{
error_at (c_parser_peek_token (parser)->location,
"-fcilkplus must be enabled to use %<_Cilk_for%>");
c_parser_skip_to_end_of_block_or_statement (parser);
}
else
c_parser_cilk_for (parser, integer_zero_node);
break;
case RID_CILK_SYNC:
c_parser_consume_token (parser);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
@ -9582,6 +9594,23 @@ c_parser_pragma (c_parser *parser, enum pragma_context context)
c_parser_consume_pragma (parser);
c_parser_cilk_simd (parser);
return false;
case PRAGMA_CILK_GRAINSIZE:
if (!flag_cilkplus)
{
warning (0, "%<#pragma grainsize%> ignored because -fcilkplus is not"
" enabled");
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
}
if (context == pragma_external)
{
error_at (c_parser_peek_token (parser)->location,
"%<#pragma grainsize%> must be inside a function");
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
}
c_parser_cilk_grainsize (parser);
return false;
default:
if (id < PRAGMA_FIRST_EXTERNAL)
@ -11715,11 +11744,18 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
condv = make_tree_vec (collapse);
incrv = make_tree_vec (collapse);
if (!c_parser_next_token_is_keyword (parser, RID_FOR))
if (code != CILK_FOR
&& !c_parser_next_token_is_keyword (parser, RID_FOR))
{
c_parser_error (parser, "for statement expected");
return NULL;
}
if (code == CILK_FOR
&& !c_parser_next_token_is_keyword (parser, RID_CILK_FOR))
{
c_parser_error (parser, "_Cilk_for statement expected");
return NULL;
}
for_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
@ -11797,7 +11833,7 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
case LE_EXPR:
break;
case NE_EXPR:
if (code == CILK_SIMD)
if (code == CILK_SIMD || code == CILK_FOR)
break;
/* FALLTHRU. */
default:
@ -13890,8 +13926,48 @@ c_parser_cilk_all_clauses (c_parser *parser)
return c_finish_cilk_clauses (clauses);
}
/* Main entry point for parsing Cilk Plus <#pragma simd> for
loops. */
/* This function helps parse the grainsize pragma for a _Cilk_for statement.
Here is the correct syntax of this pragma:
#pragma cilk grainsize = <EXP>
*/
static void
c_parser_cilk_grainsize (c_parser *parser)
{
extern tree convert_to_integer (tree, tree);
/* consume the 'grainsize' keyword. */
c_parser_consume_pragma (parser);
if (c_parser_require (parser, CPP_EQ, "expected %<=%>") != 0)
{
struct c_expr g_expr = c_parser_binary_expression (parser, NULL, NULL);
if (g_expr.value == error_mark_node)
{
c_parser_skip_to_pragma_eol (parser);
return;
}
tree grain = convert_to_integer (long_integer_type_node,
c_fully_fold (g_expr.value, false,
NULL));
c_parser_skip_to_pragma_eol (parser);
c_token *token = c_parser_peek_token (parser);
if (token && token->type == CPP_KEYWORD
&& token->keyword == RID_CILK_FOR)
{
if (grain == NULL_TREE || grain == error_mark_node)
grain = integer_zero_node;
c_parser_cilk_for (parser, grain);
}
else
warning (0, "%<#pragma cilk grainsize%> is not followed by "
"%<_Cilk_for%>");
}
else
c_parser_skip_to_pragma_eol (parser);
}
/* Main entry point for parsing Cilk Plus <#pragma simd> for loops. */
static void
c_parser_cilk_simd (c_parser *parser)
@ -13903,6 +13979,105 @@ c_parser_cilk_simd (c_parser *parser)
block = c_end_compound_stmt (loc, block, true);
add_stmt (block);
}
/* Create an artificial decl with TYPE and emit initialization of it with
INIT. */
static tree
c_get_temp_regvar (tree type, tree init)
{
location_t loc = EXPR_LOCATION (init);
tree decl = build_decl (loc, VAR_DECL, NULL_TREE, type);
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
pushdecl (decl);
tree t = build2 (INIT_EXPR, type, decl, init);
add_stmt (t);
return decl;
}
/* Main entry point for parsing Cilk Plus _Cilk_for loops.
GRAIN is the grain value passed in through pragma or 0. */
static void
c_parser_cilk_for (c_parser *parser, tree grain)
{
tree clauses = build_omp_clause (EXPR_LOCATION (grain), OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (clauses) = OMP_CLAUSE_SCHEDULE_CILKFOR;
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clauses) = grain;
clauses = c_finish_omp_clauses (clauses);
tree block = c_begin_compound_stmt (true);
tree sb = push_stmt_list ();
location_t loc = c_parser_peek_token (parser)->location;
tree omp_for = c_parser_omp_for_loop (loc, parser, CILK_FOR, clauses, NULL);
sb = pop_stmt_list (sb);
if (omp_for)
{
tree omp_par = make_node (OMP_PARALLEL);
TREE_TYPE (omp_par) = void_type_node;
OMP_PARALLEL_CLAUSES (omp_par) = NULL_TREE;
tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
TREE_SIDE_EFFECTS (bind) = 1;
BIND_EXPR_BODY (bind) = sb;
OMP_PARALLEL_BODY (omp_par) = bind;
if (OMP_FOR_PRE_BODY (omp_for))
{
add_stmt (OMP_FOR_PRE_BODY (omp_for));
OMP_FOR_PRE_BODY (omp_for) = NULL_TREE;
}
tree init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0);
tree decl = TREE_OPERAND (init, 0);
tree cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), 0);
tree incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
tree t = TREE_OPERAND (cond, 1), c, clauses = NULL_TREE;
if (TREE_CODE (t) != INTEGER_CST)
{
TREE_OPERAND (cond, 1) = c_get_temp_regvar (TREE_TYPE (t), t);
c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (cond, 1);
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
}
if (TREE_CODE (incr) == MODIFY_EXPR)
{
t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
if (TREE_CODE (t) != INTEGER_CST)
{
TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
= c_get_temp_regvar (TREE_TYPE (t), t);
c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
}
}
t = TREE_OPERAND (init, 1);
if (TREE_CODE (t) != INTEGER_CST)
{
TREE_OPERAND (init, 1) = c_get_temp_regvar (TREE_TYPE (t), t);
c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (init, 1);
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
}
c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_DECL (c) = decl;
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
c = build_omp_clause (input_location, OMP_CLAUSE__CILK_FOR_COUNT_);
OMP_CLAUSE_OPERAND (c, 0)
= cilk_for_number_of_iterations (omp_for);
OMP_CLAUSE_CHAIN (c) = clauses;
OMP_PARALLEL_CLAUSES (omp_par) = c_finish_omp_clauses (c);
add_stmt (omp_par);
}
block = c_end_compound_stmt (loc, block, true);
add_stmt (block);
}
/* Parse a transaction attribute (GCC Extension).

View File

@ -12229,6 +12229,7 @@ c_finish_omp_clauses (tree clauses)
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
case OMP_CLAUSE_PROC_BIND:
case OMP_CLAUSE__CILK_FOR_COUNT_:
pc = &OMP_CLAUSE_CHAIN (c);
continue;

View File

@ -31,3 +31,5 @@ DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_SYNC, "__cilkrts_sync")
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_LEAVE_FRAME, "__cilkrts_leave_frame")
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_POP_FRAME, "__cilkrts_pop_frame")
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_SAVE_FP, "__cilkrts_save_fp_ctrl_state")
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_FOR_32, "__cilkrts_cilk_for_32")
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_FOR_64, "__cilkrts_cilk_for_64")

View File

@ -105,6 +105,27 @@ install_builtin (const char *name, tree fntype, enum built_in_function code,
return fndecl;
}
/* Returns a FUNCTION_DECL of type TYPE whose name is *NAME. */
static tree
declare_cilk_for_builtin (const char *name, tree type,
enum built_in_function code)
{
tree cb, ft, fn;
cb = build_function_type_list (void_type_node,
ptr_type_node, type, type,
NULL_TREE);
cb = build_pointer_type (cb);
ft = build_function_type_list (void_type_node,
cb, ptr_type_node, type,
integer_type_node, NULL_TREE);
fn = install_builtin (name, ft, code, false);
TREE_NOTHROW (fn) = 0;
return fn;
}
/* Creates and initializes all the built-in Cilk keywords functions and three
structures: __cilkrts_stack_frame, __cilkrts_pedigree and __cilkrts_worker.
Detailed information about __cilkrts_stack_frame and
@ -119,7 +140,7 @@ cilk_init_builtins (void)
uint64_t rank;
struct __cilkrts_pedigree *parent;
} */
tree pedigree_type = lang_hooks.types.make_type (RECORD_TYPE);
tree pedigree_ptr = build_pointer_type (pedigree_type);
tree field = add_field ("rank", uint64_type_node, NULL_TREE);
@ -131,7 +152,7 @@ cilk_init_builtins (void)
lang_hooks.types.register_builtin_type (pedigree_type,
"__cilkrts_pedigree_t");
cilk_pedigree_type_decl = pedigree_type;
/* Build the Cilk Stack Frame:
struct __cilkrts_stack_frame {
uint32_t flags;
@ -212,7 +233,7 @@ cilk_init_builtins (void)
tree sysdep_t = lang_hooks.types.make_type (RECORD_TYPE);
finish_builtin_struct (sysdep_t, "__cilkrts_worker_sysdep_state", NULL_TREE,
NULL_TREE);
field = add_field ("tail", fptr_vol_ptr_vol, NULL_TREE);
cilk_trees[CILK_TI_WORKER_TAIL] = field;
field = add_field ("head", fptr_vol_ptr_vol, field);
@ -234,16 +255,16 @@ cilk_init_builtins (void)
tree fptr_arglist = tree_cons (NULL_TREE, frame_ptr, void_list_node);
tree fptr_fun = build_function_type (void_type_node, fptr_arglist);
/* void __cilkrts_enter_frame_1 (__cilkrts_stack_frame *); */
cilk_enter_fndecl = install_builtin ("__cilkrts_enter_frame_1", fptr_fun,
BUILT_IN_CILK_ENTER_FRAME, false);
/* void __cilkrts_enter_frame_fast_1 (__cilkrts_stack_frame *); */
cilk_enter_fast_fndecl =
install_builtin ("__cilkrts_enter_frame_fast_1", fptr_fun,
install_builtin ("__cilkrts_enter_frame_fast_1", fptr_fun,
BUILT_IN_CILK_ENTER_FRAME_FAST, false);
/* void __cilkrts_pop_frame (__cilkrts_stack_frame *); */
cilk_pop_fndecl = install_builtin ("__cilkrts_pop_frame", fptr_fun,
BUILT_IN_CILK_POP_FRAME, false);
@ -261,14 +282,22 @@ cilk_init_builtins (void)
BUILT_IN_CILK_DETACH, false);
/* __cilkrts_rethrow (struct stack_frame *); */
cilk_rethrow_fndecl = install_builtin ("__cilkrts_rethrow", fptr_fun,
cilk_rethrow_fndecl = install_builtin ("__cilkrts_rethrow", fptr_fun,
BUILT_IN_CILK_RETHROW, false);
TREE_NOTHROW (cilk_rethrow_fndecl) = 0;
/* __cilkrts_save_fp_ctrl_state (__cilkrts_stack_frame *); */
cilk_save_fp_fndecl = install_builtin ("__cilkrts_save_fp_ctrl_state",
cilk_save_fp_fndecl = install_builtin ("__cilkrts_save_fp_ctrl_state",
fptr_fun, BUILT_IN_CILK_SAVE_FP,
false);
/* __cilkrts_cilk_for_32 (...); */
cilk_for_32_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_32",
unsigned_intSI_type_node,
BUILT_IN_CILK_FOR_32);
/* __cilkrts_cilk_for_64 (...); */
cilk_for_64_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_64",
unsigned_intDI_type_node,
BUILT_IN_CILK_FOR_64);
}
/* Get the appropriate frame arguments for CALL that is of type CALL_EXPR. */

View File

@ -40,6 +40,9 @@ enum cilk_tree_index {
CILK_TI_F_POP, /* __cilkrts_pop_frame (...). */
CILK_TI_F_RETHROW, /* __cilkrts_rethrow (...). */
CILK_TI_F_SAVE_FP, /* __cilkrts_save_fp_ctrl_state (...). */
CILK_TI_F_LOOP_32, /* __cilkrts_cilk_for_32 (...). */
CILK_TI_F_LOOP_64, /* __cilkrts_cilk_for_64 (...). */
/* __cilkrts_stack_frame struct fields. */
CILK_TI_FRAME_FLAGS, /* stack_frame->flags. */
CILK_TI_FRAME_PARENT, /* stack_frame->parent. */
@ -77,6 +80,8 @@ extern GTY (()) tree cilk_trees[CILK_TI_MAX];
#define cilk_rethrow_fndecl cilk_trees[CILK_TI_F_RETHROW]
#define cilk_pop_fndecl cilk_trees[CILK_TI_F_POP]
#define cilk_save_fp_fndecl cilk_trees[CILK_TI_F_SAVE_FP]
#define cilk_for_32_fndecl cilk_trees[CILK_TI_F_LOOP_32]
#define cilk_for_64_fndecl cilk_trees[CILK_TI_F_LOOP_64]
#define cilk_worker_type_fndecl cilk_trees[CILK_TI_WORKER_TYPE]
#define cilk_frame_type_decl cilk_trees[CILK_TI_FRAME_TYPE]

View File

@ -1,3 +1,31 @@
2014-09-02 Jakub Jelinek <jakub@redhat.com>
Balaji V. Iyer <balaji.v.iyer@intel.com>
Igor Zamyatin <igor.zamyatin@intel.com>
* cp-cilkplus.c (cpp_validate_cilk_plus_loop_aux): Loc definition
simplified.
* parser.c (cp_parser_cilk_for): New function.
(cp_parser_cilk_grainsize): Likewise.
(cp_parser_statement): Added RID_CILK_FOR case.
(cp_parser_omp_for_cond): Added CILK_FOR check.
(cp_parser_omp_for_loop_init): Change function argument to accept
tree_code instead just a bool flag; change the check to use that
tree_code; check for initialization declaration in case of Cilk_for.
(cp_parser_omp_for_loop): Added checks for CILK_FOR and RID_CILK_FOR;
changed call to cp_parser_omp_for_loop_init according new arguments'
list.
(cp_parser_pragma): Added PRAGMA_CILK_GRAINSIZE case.
* pt.c (tsubst_expr): Added CILK_FOR case.
* semantics.c: Include convert.h.
(finish_omp_clauses): Properly handle OMP_CLAUSE_SCHEDULE_CILKFOR
case; added OMP_CLAUSE__CILK_FOR_COUNT_.
(handle_omp_for_class_iterator): New argument lastp and its usage;
added NE_EXPR case.
(finish_omp_for): Changed call to handle_omp_for_class_iterator
according new arguments' list; in case of Cilk_for save very first
decl and create empty stmt_list block; use block to build correct
statement tree.
2014-08-31 Jason Merrill <jason@redhat.com>
PR c++/62302

View File

@ -42,12 +42,11 @@ static tree
cpp_validate_cilk_plus_loop_aux (tree *tp, int *walk_subtrees, void *data)
{
bool *valid = (bool *) data;
location_t loc = EXPR_HAS_LOCATION (*tp) ? EXPR_LOCATION (*tp) :
UNKNOWN_LOCATION;
if (!tp || !*tp)
return NULL_TREE;
location_t loc = EXPR_LOCATION (*tp);
if (TREE_CODE (*tp) == THROW_EXPR)
{
error_at (loc, "throw expressions are not allowed inside loops "
@ -142,4 +141,3 @@ cilk_install_body_with_frame_cleanup (tree fndecl, tree orig_body, void *wd)
append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, body, dtor),
&list);
}

View File

@ -239,6 +239,8 @@ static tree cp_literal_operator_id
static void cp_parser_cilk_simd
(cp_parser *, cp_token *);
static tree cp_parser_cilk_for
(cp_parser *, tree);
static bool cp_parser_omp_declare_reduction_exprs
(tree, cp_parser *);
static tree cp_parser_cilk_simd_vectorlength
@ -9532,6 +9534,18 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
statement = cp_parser_iteration_statement (parser, false);
break;
case RID_CILK_FOR:
if (!flag_cilkplus)
{
error_at (cp_lexer_peek_token (parser->lexer)->location,
"-fcilkplus must be enabled to use %<_Cilk_for%>");
cp_lexer_consume_token (parser->lexer);
statement = error_mark_node;
}
else
statement = cp_parser_cilk_for (parser, integer_zero_node);
break;
case RID_BREAK:
case RID_CONTINUE:
case RID_RETURN:
@ -29222,7 +29236,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
case LE_EXPR:
break;
case NE_EXPR:
if (code == CILK_SIMD)
if (code == CILK_SIMD || code == CILK_FOR)
break;
/* Fall through: OpenMP disallows NE_EXPR. */
default:
@ -29337,15 +29351,12 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
/* Parse the initialization statement of either an OpenMP for loop or
a Cilk Plus for loop.
PARSING_OPENMP is true if parsing OpenMP, or false if parsing Cilk
Plus.
Return true if the resulting construct should have an
OMP_CLAUSE_PRIVATE added to it. */
static bool
cp_parser_omp_for_loop_init (cp_parser *parser,
bool parsing_openmp,
enum tree_code code,
tree &this_pre_body,
vec<tree, va_gc> *for_block,
tree &init,
@ -29408,7 +29419,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
if (cp_lexer_next_token_is (parser->lexer,
CPP_OPEN_PAREN))
{
if (parsing_openmp)
if (code != CILK_SIMD && code != CILK_FOR)
error ("parenthesized initialization is not allowed in "
"OpenMP %<for%> loop");
else
@ -29480,6 +29491,9 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
cp_id_kind idk;
/* If parsing a type specifier sequence failed, then
this MUST be a simple expression. */
if (code == CILK_FOR)
error ("%<_Cilk_for%> allows expression instead of declaration only "
"in C, not in C++");
cp_parser_parse_tentatively (parser);
decl = cp_parser_primary_expression (parser, false, false,
false, &idk);
@ -29548,11 +29562,18 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
bool add_private_clause = false;
location_t loc;
if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
if (code != CILK_FOR
&& !cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
{
cp_parser_error (parser, "for statement expected");
return NULL;
}
if (code == CILK_FOR
&& !cp_lexer_next_token_is_keyword (parser->lexer, RID_CILK_FOR))
{
cp_parser_error (parser, "_Cilk_for statement expected");
return NULL;
}
loc = cp_lexer_consume_token (parser->lexer)->location;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
@ -29562,8 +29583,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
this_pre_body = push_stmt_list ();
add_private_clause
|= cp_parser_omp_for_loop_init (parser,
/*parsing_openmp=*/code != CILK_SIMD,
|= cp_parser_omp_for_loop_init (parser, code,
this_pre_body, for_block,
init, decl, real_decl);
@ -29733,7 +29753,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
/* Note that we saved the original contents of this flag when we entered
the structured block, and so we don't need to re-save it here. */
if (code == CILK_SIMD)
if (code == CILK_SIMD || code == CILK_FOR)
parser->in_statement = IN_CILK_SIMD_FOR;
else
parser->in_statement = IN_OMP_FOR;
@ -31692,6 +31712,36 @@ cp_parser_initial_pragma (cp_token *first_token)
cp_lexer_get_preprocessor_token (NULL, first_token);
}
/* Parses the grainsize pragma for the _Cilk_for statement.
Syntax:
#pragma cilk grainsize = <VALUE>. */
static void
cp_parser_cilk_grainsize (cp_parser *parser, cp_token *pragma_tok)
{
if (cp_parser_require (parser, CPP_EQ, RT_EQ))
{
tree exp = cp_parser_binary_expression (parser, false, false,
PREC_NOT_OPERATOR, NULL);
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
if (!exp || exp == error_mark_node)
{
error_at (pragma_tok->location, "invalid grainsize for _Cilk_for");
return;
}
/* Make sure the next token is _Cilk_for, it is invalid otherwise. */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_CILK_FOR))
cp_parser_cilk_for (parser, exp);
else
warning_at (cp_lexer_peek_token (parser->lexer)->location, 0,
"%<#pragma cilk grainsize%> is not followed by "
"%<_Cilk_for%>");
return;
}
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
}
/* Normal parsing of a pragma token. Here we can (and must) use the
regular lexer. */
@ -31874,6 +31924,27 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
cp_parser_cilk_simd (parser, pragma_tok);
return true;
case PRAGMA_CILK_GRAINSIZE:
if (context == pragma_external)
{
error_at (pragma_tok->location,
"%<#pragma cilk grainsize%> must be inside a function");
break;
}
/* Ignore the pragma if Cilk Plus is not enabled. */
if (flag_cilkplus)
{
cp_parser_cilk_grainsize (parser, pragma_tok);
return true;
}
else
{
error_at (pragma_tok->location, "-fcilkplus must be enabled to use "
"%<#pragma cilk grainsize%>");
break;
}
default:
gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
c_invoke_pragma_handler (id);
@ -31960,10 +32031,10 @@ cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses,
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return error_mark_node;
expr = cp_parser_constant_expression (parser, false, NULL);
expr = maybe_constant_value (expr);
/* If expr == error_mark_node, then don't emit any errors nor
create a clause. if any of the above functions returns
error mark node then they would have emitted an error message. */
@ -32197,7 +32268,7 @@ cp_parser_cilk_simd (cp_parser *parser, cp_token *pragma_token)
if (clauses == error_mark_node)
return;
if (cp_lexer_next_token_is_not_keyword (parser->lexer, RID_FOR))
{
error_at (cp_lexer_peek_token (parser->lexer)->location,
@ -32212,7 +32283,35 @@ cp_parser_cilk_simd (cp_parser *parser, cp_token *pragma_token)
cpp_validate_cilk_plus_loop (OMP_FOR_BODY (ret));
cp_parser_end_omp_structured_block (parser, save);
add_stmt (finish_omp_structured_block (sb));
return;
}
/* Main entry-point for parsing Cilk Plus _Cilk_for
loops. The return value is error_mark_node
when errors happen and CILK_FOR tree on success. */
static tree
cp_parser_cilk_for (cp_parser *parser, tree grain)
{
if (cp_lexer_next_token_is_not_keyword (parser->lexer, RID_CILK_FOR))
gcc_unreachable ();
tree sb = begin_omp_structured_block ();
int save = cp_parser_begin_omp_structured_block (parser);
tree clauses = build_omp_clause (EXPR_LOCATION (grain), OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (clauses) = OMP_CLAUSE_SCHEDULE_CILKFOR;
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clauses) = grain;
clauses = finish_omp_clauses (clauses);
tree ret = cp_parser_omp_for_loop (parser, CILK_FOR, clauses, NULL);
if (ret)
cpp_validate_cilk_plus_loop (ret);
else
ret = error_mark_node;
cp_parser_end_omp_structured_block (parser, save);
add_stmt (finish_omp_structured_block (sb));
return ret;
}
/* Create an identifier for a generic parameter type (a synthesized

View File

@ -14012,6 +14012,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OMP_FOR:
case OMP_SIMD:
case CILK_SIMD:
case CILK_FOR:
case OMP_DISTRIBUTE:
{
tree clauses, body, pre_body;

View File

@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h"
#include "omp-low.h"
#include "builtins.h"
#include "convert.h"
static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \
@ -5424,6 +5425,8 @@ finish_omp_clauses (tree clauses)
else if (t == error_mark_node)
remove = true;
else if (!type_dependent_expression_p (t)
&& (OMP_CLAUSE_SCHEDULE_KIND (c)
!= OMP_CLAUSE_SCHEDULE_CILKFOR)
&& !INTEGRAL_TYPE_P (TREE_TYPE (t)))
{
error ("schedule chunk size expression must be integral");
@ -5433,7 +5436,19 @@ finish_omp_clauses (tree clauses)
{
t = mark_rvalue_use (t);
if (!processing_template_decl)
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
{
if (OMP_CLAUSE_SCHEDULE_KIND (c)
== OMP_CLAUSE_SCHEDULE_CILKFOR)
{
t = convert_to_integer (long_integer_type_node, t);
if (t == error_mark_node)
{
remove = true;
break;
}
}
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
}
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
}
break;
@ -5734,6 +5749,7 @@ finish_omp_clauses (tree clauses)
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
case OMP_CLAUSE_PROC_BIND:
case OMP_CLAUSE__CILK_FOR_COUNT_:
break;
case OMP_CLAUSE_INBRANCH:
@ -6053,7 +6069,7 @@ finish_omp_task (tree clauses, tree body)
static bool
handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
tree condv, tree incrv, tree *body,
tree *pre_body, tree clauses)
tree *pre_body, tree clauses, tree *lastp)
{
tree diff, iter_init, iter_incr = NULL, last;
tree incr_var = NULL, orig_pre_body, orig_body, c;
@ -6073,6 +6089,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
case GE_EXPR:
case LT_EXPR:
case LE_EXPR:
case NE_EXPR:
if (TREE_OPERAND (cond, 1) == iter)
cond = build2 (swap_tree_comparison (TREE_CODE (cond)),
TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0));
@ -6285,6 +6302,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
TREE_VEC_ELT (initv, i) = init;
TREE_VEC_ELT (condv, i) = cond;
TREE_VEC_ELT (incrv, i) = incr;
*lastp = last;
return false;
}
@ -6301,7 +6319,8 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
tree condv, tree incrv, tree body, tree pre_body, tree clauses)
{
tree omp_for = NULL, orig_incr = NULL;
tree decl, init, cond, incr;
tree decl = NULL, init, cond, incr, orig_decl = NULL_TREE, block = NULL_TREE;
tree last = NULL_TREE;
location_t elocus;
int i;
@ -6431,8 +6450,11 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
"iteration variable %qE", decl);
return NULL;
}
if (code == CILK_FOR && i == 0)
orig_decl = decl;
if (handle_omp_for_class_iterator (i, locus, declv, initv, condv,
incrv, &body, &pre_body, clauses))
incrv, &body, &pre_body,
clauses, &last))
return NULL;
continue;
}
@ -6485,11 +6507,18 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
if (IS_EMPTY_STMT (pre_body))
pre_body = NULL;
if (code == CILK_FOR && !processing_template_decl)
block = push_stmt_list ();
omp_for = c_finish_omp_for (locus, code, declv, initv, condv, incrv,
body, pre_body);
if (omp_for == NULL)
return NULL;
{
if (block)
pop_stmt_list (block);
return NULL;
}
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
{
@ -6523,8 +6552,117 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
if (orig_incr)
TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i) = TREE_VEC_ELT (orig_incr, i);
}
if (omp_for != NULL)
OMP_FOR_CLAUSES (omp_for) = clauses;
OMP_FOR_CLAUSES (omp_for) = clauses;
if (block)
{
tree omp_par = make_node (OMP_PARALLEL);
TREE_TYPE (omp_par) = void_type_node;
OMP_PARALLEL_CLAUSES (omp_par) = NULL_TREE;
tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
TREE_SIDE_EFFECTS (bind) = 1;
BIND_EXPR_BODY (bind) = pop_stmt_list (block);
OMP_PARALLEL_BODY (omp_par) = bind;
if (OMP_FOR_PRE_BODY (omp_for))
{
add_stmt (OMP_FOR_PRE_BODY (omp_for));
OMP_FOR_PRE_BODY (omp_for) = NULL_TREE;
}
init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0);
decl = TREE_OPERAND (init, 0);
cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), 0);
incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
tree t = TREE_OPERAND (cond, 1), c, clauses, *pc;
clauses = OMP_FOR_CLAUSES (omp_for);
OMP_FOR_CLAUSES (omp_for) = NULL_TREE;
for (pc = &clauses; *pc; )
if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_SCHEDULE)
{
gcc_assert (OMP_FOR_CLAUSES (omp_for) == NULL_TREE);
OMP_FOR_CLAUSES (omp_for) = *pc;
*pc = OMP_CLAUSE_CHAIN (*pc);
OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (omp_for)) = NULL_TREE;
}
else
{
gcc_assert (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_FIRSTPRIVATE);
pc = &OMP_CLAUSE_CHAIN (*pc);
}
if (TREE_CODE (t) != INTEGER_CST)
{
TREE_OPERAND (cond, 1) = get_temp_regvar (TREE_TYPE (t), t);
c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (cond, 1);
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
}
if (TREE_CODE (incr) == MODIFY_EXPR)
{
t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
if (TREE_CODE (t) != INTEGER_CST)
{
TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
= get_temp_regvar (TREE_TYPE (t), t);
c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
}
}
t = TREE_OPERAND (init, 1);
if (TREE_CODE (t) != INTEGER_CST)
{
TREE_OPERAND (init, 1) = get_temp_regvar (TREE_TYPE (t), t);
c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (init, 1);
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
}
if (orig_decl && orig_decl != decl)
{
c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = orig_decl;
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
}
if (last)
{
c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = last;
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
}
c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_DECL (c) = decl;
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
c = build_omp_clause (input_location, OMP_CLAUSE__CILK_FOR_COUNT_);
OMP_CLAUSE_OPERAND (c, 0)
= cilk_for_number_of_iterations (omp_for);
OMP_CLAUSE_CHAIN (c) = clauses;
OMP_PARALLEL_CLAUSES (omp_par) = finish_omp_clauses (c);
add_stmt (omp_par);
return omp_par;
}
else if (code == CILK_FOR && processing_template_decl)
{
tree c, clauses = OMP_FOR_CLAUSES (omp_for);
if (orig_decl && orig_decl != decl)
{
c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = orig_decl;
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
}
if (last)
{
c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = last;
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
}
OMP_FOR_CLAUSES (omp_for) = clauses;
}
return omp_for;
}

View File

@ -1135,6 +1135,9 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
case GF_OMP_FOR_KIND_DISTRIBUTE:
kind = " distribute";
break;
case GF_OMP_FOR_KIND_CILKFOR:
kind = " _Cilk_for";
break;
default:
gcc_unreachable ();
}
@ -1169,16 +1172,24 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
case GF_OMP_FOR_KIND_DISTRIBUTE:
pp_string (buffer, "#pragma omp distribute");
break;
case GF_OMP_FOR_KIND_CILKFOR:
break;
default:
gcc_unreachable ();
}
dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
if (gimple_omp_for_kind (gs) != GF_OMP_FOR_KIND_CILKFOR)
dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
for (i = 0; i < gimple_omp_for_collapse (gs); i++)
{
if (i)
spc += 2;
newline_and_indent (buffer, spc);
pp_string (buffer, "for (");
if (gimple_omp_for_kind (gs) == GF_OMP_FOR_KIND_CILKFOR)
pp_string (buffer, "_Cilk_for (");
else
{
newline_and_indent (buffer, spc);
pp_string (buffer, "for (");
}
dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
flags, false);
pp_string (buffer, " = ");
@ -1203,6 +1214,9 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
case GE_EXPR:
pp_greater_equal (buffer);
break;
case NE_EXPR:
pp_string (buffer, "!=");
break;
default:
gcc_unreachable ();
}
@ -1221,6 +1235,8 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
if (!gimple_seq_empty_p (gimple_omp_body (gs)))
{
if (gimple_omp_for_kind (gs) == GF_OMP_FOR_KIND_CILKFOR)
dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
newline_and_indent (buffer, spc + 2);
pp_left_brace (buffer);
pp_newline (buffer);

View File

@ -92,15 +92,16 @@ enum gf_mask {
GF_CALL_INTERNAL = 1 << 6,
GF_CALL_CTRL_ALTERING = 1 << 7,
GF_OMP_PARALLEL_COMBINED = 1 << 0,
GF_OMP_FOR_KIND_MASK = (1 << 2) - 1,
GF_OMP_FOR_KIND_MASK = 7 << 0,
GF_OMP_FOR_KIND_FOR = 0,
GF_OMP_FOR_KIND_DISTRIBUTE = 1,
GF_OMP_FOR_KIND_CILKFOR = 2,
/* Flag for SIMD variants of OMP_FOR kinds. */
GF_OMP_FOR_SIMD = 1 << 1,
GF_OMP_FOR_SIMD = 1 << 2,
GF_OMP_FOR_KIND_SIMD = GF_OMP_FOR_SIMD | 0,
GF_OMP_FOR_KIND_CILKSIMD = GF_OMP_FOR_SIMD | 1,
GF_OMP_FOR_COMBINED = 1 << 2,
GF_OMP_FOR_COMBINED_INTO = 1 << 3,
GF_OMP_FOR_COMBINED = 1 << 3,
GF_OMP_FOR_COMBINED_INTO = 1 << 4,
GF_OMP_TARGET_KIND_MASK = (1 << 2) - 1,
GF_OMP_TARGET_KIND_REGION = 0,
GF_OMP_TARGET_KIND_DATA = 1,

View File

@ -6208,6 +6208,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_DIST_SCHEDULE:
case OMP_CLAUSE_DEVICE:
case OMP_CLAUSE__CILK_FOR_COUNT_:
if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
is_gimple_val, fb_rvalue) == GS_ERROR)
remove = true;
@ -6584,6 +6585,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, tree *list_p)
case OMP_CLAUSE_PROC_BIND:
case OMP_CLAUSE_SAFELEN:
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE__CILK_FOR_COUNT_:
break;
default:
@ -7056,6 +7058,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
case CILK_SIMD: kind = GF_OMP_FOR_KIND_CILKSIMD; break;
case CILK_FOR: kind = GF_OMP_FOR_KIND_CILKFOR; break;
case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
default:
gcc_unreachable ();
@ -8128,6 +8131,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
case OMP_FOR:
case OMP_SIMD:
case CILK_SIMD:
case CILK_FOR:
case OMP_DISTRIBUTE:
ret = gimplify_omp_for (expr_p, pre_p);
break;

View File

@ -70,6 +70,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-prop.h"
#include "tree-nested.h"
#include "tree-eh.h"
#include "cilk.h"
/* Lowering of OpenMP parallel and workshare constructs proceeds in two
@ -313,6 +314,8 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
fd->have_ordered = false;
fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
fd->chunk_size = NULL_TREE;
if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
fd->sched_kind = OMP_CLAUSE_SCHEDULE_CILKFOR;
collapse_iter = NULL;
collapse_count = NULL;
@ -392,7 +395,9 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
break;
case NE_EXPR:
gcc_assert (gimple_omp_for_kind (for_stmt)
== GF_OMP_FOR_KIND_CILKSIMD);
== GF_OMP_FOR_KIND_CILKSIMD
|| (gimple_omp_for_kind (for_stmt)
== GF_OMP_FOR_KIND_CILKFOR));
break;
case LE_EXPR:
if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
@ -1604,6 +1609,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_SCHEDULE:
case OMP_CLAUSE_DIST_SCHEDULE:
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE__CILK_FOR_COUNT_:
if (ctx->outer)
scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
break;
@ -1812,6 +1818,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE__LOOPTEMP_:
case OMP_CLAUSE_TO:
case OMP_CLAUSE_FROM:
case OMP_CLAUSE__CILK_FOR_COUNT_:
break;
default:
@ -1835,13 +1842,39 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
}
/* Create a new name for omp child function. Returns an identifier. */
/* Create a new name for omp child function. Returns an identifier. If
IS_CILK_FOR is true then the suffix for the child function is
"_cilk_for_fn." */
static tree
create_omp_child_function_name (bool task_copy)
create_omp_child_function_name (bool task_copy, bool is_cilk_for)
{
return (clone_function_name (current_function_decl,
task_copy ? "_omp_cpyfn" : "_omp_fn"));
if (is_cilk_for)
return clone_function_name (current_function_decl, "_cilk_for_fn");
return clone_function_name (current_function_decl,
task_copy ? "_omp_cpyfn" : "_omp_fn");
}
/* Returns the type of the induction variable for the child function for
_Cilk_for and the types for _high and _low variables based on TYPE. */
static tree
cilk_for_check_loop_diff_type (tree type)
{
if (TYPE_PRECISION (type) <= TYPE_PRECISION (uint32_type_node))
{
if (TYPE_UNSIGNED (type))
return uint32_type_node;
else
return integer_type_node;
}
else
{
if (TYPE_UNSIGNED (type))
return uint64_type_node;
else
return long_long_integer_type_node;
}
}
/* Build a decl for the omp child function. It'll not contain a body
@ -1852,15 +1885,28 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
{
tree decl, type, name, t;
name = create_omp_child_function_name (task_copy);
tree cilk_for_count
= (flag_cilkplus && gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
? find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
OMP_CLAUSE__CILK_FOR_COUNT_) : NULL_TREE;
tree cilk_var_type = NULL_TREE;
name = create_omp_child_function_name (task_copy,
cilk_for_count != NULL_TREE);
if (task_copy)
type = build_function_type_list (void_type_node, ptr_type_node,
ptr_type_node, NULL_TREE);
else if (cilk_for_count)
{
type = TREE_TYPE (OMP_CLAUSE_OPERAND (cilk_for_count, 0));
cilk_var_type = cilk_for_check_loop_diff_type (type);
type = build_function_type_list (void_type_node, ptr_type_node,
cilk_var_type, cilk_var_type, NULL_TREE);
}
else
type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
decl = build_decl (gimple_location (ctx->stmt),
FUNCTION_DECL, name, type);
decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);
if (!task_copy)
ctx->cb.dst_fn = decl;
@ -1904,13 +1950,42 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
DECL_CONTEXT (t) = decl;
DECL_RESULT (decl) = t;
t = build_decl (DECL_SOURCE_LOCATION (decl),
PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
/* _Cilk_for's child function requires two extra parameters called
__low and __high that are set the by Cilk runtime when it calls this
function. */
if (cilk_for_count)
{
t = build_decl (DECL_SOURCE_LOCATION (decl),
PARM_DECL, get_identifier ("__high"), cilk_var_type);
DECL_ARTIFICIAL (t) = 1;
DECL_NAMELESS (t) = 1;
DECL_ARG_TYPE (t) = ptr_type_node;
DECL_CONTEXT (t) = current_function_decl;
TREE_USED (t) = 1;
DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
DECL_ARGUMENTS (decl) = t;
t = build_decl (DECL_SOURCE_LOCATION (decl),
PARM_DECL, get_identifier ("__low"), cilk_var_type);
DECL_ARTIFICIAL (t) = 1;
DECL_NAMELESS (t) = 1;
DECL_ARG_TYPE (t) = ptr_type_node;
DECL_CONTEXT (t) = current_function_decl;
TREE_USED (t) = 1;
DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
DECL_ARGUMENTS (decl) = t;
}
tree data_name = get_identifier (".omp_data_i");
t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
ptr_type_node);
DECL_ARTIFICIAL (t) = 1;
DECL_NAMELESS (t) = 1;
DECL_ARG_TYPE (t) = ptr_type_node;
DECL_CONTEXT (t) = current_function_decl;
TREE_USED (t) = 1;
if (cilk_for_count)
DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
DECL_ARGUMENTS (decl) = t;
if (!task_copy)
ctx->receiver_decl = t;
@ -4382,6 +4457,44 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
false, GSI_CONTINUE_LINKING);
}
/* Insert a function call whose name is FUNC_NAME with the information from
ENTRY_STMT into the basic_block BB. */
static void
expand_cilk_for_call (basic_block bb, gimple entry_stmt,
vec <tree, va_gc> *ws_args)
{
tree t, t1, t2;
gimple_stmt_iterator gsi;
vec <tree, va_gc> *args;
gcc_assert (vec_safe_length (ws_args) == 2);
tree func_name = (*ws_args)[0];
tree grain = (*ws_args)[1];
tree clauses = gimple_omp_parallel_clauses (entry_stmt);
tree count = find_omp_clause (clauses, OMP_CLAUSE__CILK_FOR_COUNT_);
gcc_assert (count != NULL_TREE);
count = OMP_CLAUSE_OPERAND (count, 0);
gsi = gsi_last_bb (bb);
t = gimple_omp_parallel_data_arg (entry_stmt);
if (t == NULL)
t1 = null_pointer_node;
else
t1 = build_fold_addr_expr (t);
t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
vec_alloc (args, 4);
args->quick_push (t2);
args->quick_push (t1);
args->quick_push (count);
args->quick_push (grain);
t = build_call_expr_loc_vec (UNKNOWN_LOCATION, func_name, args);
force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, false,
GSI_CONTINUE_LINKING);
}
/* Build the function call to GOMP_task to actually
generate the task operation. BB is the block where to insert the code. */
@ -4717,7 +4830,18 @@ expand_omp_taskreg (struct omp_region *region)
entry_bb = region->entry;
exit_bb = region->exit;
if (is_combined_parallel (region))
bool is_cilk_for
= (flag_cilkplus
&& gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL
&& find_omp_clause (gimple_omp_parallel_clauses (entry_stmt),
OMP_CLAUSE__CILK_FOR_COUNT_) != NULL_TREE);
if (is_cilk_for)
/* If it is a _Cilk_for statement, it is modelled *like* a parallel for,
and the inner statement contains the name of the built-in function
and grain. */
ws_args = region->inner->ws_args;
else if (is_combined_parallel (region))
ws_args = region->ws_args;
else
ws_args = NULL;
@ -4929,7 +5053,9 @@ expand_omp_taskreg (struct omp_region *region)
}
/* Emit a library call to launch the children threads. */
if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
if (is_cilk_for)
expand_cilk_for_call (new_bb, entry_stmt, ws_args);
else if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
expand_parallel_call (region, new_bb, entry_stmt, ws_args);
else
expand_task_call (new_bb, entry_stmt);
@ -6621,6 +6747,191 @@ expand_omp_for_static_chunk (struct omp_region *region,
}
}
/* A subroutine of expand_omp_for. Generate code for _Cilk_for loop.
Given parameters:
for (V = N1; V cond N2; V += STEP) BODY;
where COND is "<" or ">" or "!=", we generate pseudocode
for (ind_var = low; ind_var < high; ind_var++)
{
V = n1 + (ind_var * STEP)
<BODY>
}
In the above pseudocode, low and high are function parameters of the
child function. In the function below, we are inserting a temp.
variable that will be making a call to two OMP functions that will not be
found in the body of _Cilk_for (since OMP_FOR cannot be mixed
with _Cilk_for). These functions are replaced with low and high
by the function that handles taskreg. */
static void
expand_cilk_for (struct omp_region *region, struct omp_for_data *fd)
{
bool broken_loop = region->cont == NULL;
basic_block entry_bb = region->entry;
basic_block cont_bb = region->cont;
gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
gcc_assert (broken_loop
|| BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
basic_block l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
basic_block l1_bb, l2_bb;
if (!broken_loop)
{
gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
l2_bb = BRANCH_EDGE (entry_bb)->dest;
}
else
{
BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
l1_bb = split_edge (BRANCH_EDGE (entry_bb));
l2_bb = single_succ (l1_bb);
}
basic_block exit_bb = region->exit;
basic_block l2_dom_bb = NULL;
gimple_stmt_iterator gsi = gsi_last_bb (entry_bb);
/* Below statements until the "tree high_val = ..." are pseudo statements
used to pass information to be used by expand_omp_taskreg.
low_val and high_val will be replaced by the __low and __high
parameter from the child function.
The call_exprs part is a place-holder, it is mainly used
to distinctly identify to the top-level part that this is
where we should put low and high (reasoning given in header
comment). */
tree child_fndecl
= gimple_omp_parallel_child_fn (last_stmt (region->outer->entry));
tree t, low_val = NULL_TREE, high_val = NULL_TREE;
for (t = DECL_ARGUMENTS (child_fndecl); t; t = TREE_CHAIN (t))
{
if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__high"))
high_val = t;
else if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__low"))
low_val = t;
}
gcc_assert (low_val && high_val);
tree type = TREE_TYPE (low_val);
tree ind_var = create_tmp_reg (type, "__cilk_ind_var");
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
/* Not needed in SSA form right now. */
gcc_assert (!gimple_in_ssa_p (cfun));
if (l2_dom_bb == NULL)
l2_dom_bb = l1_bb;
tree n1 = low_val;
tree n2 = high_val;
gimple stmt = gimple_build_assign (ind_var, n1);
/* Replace the GIMPLE_OMP_FOR statement. */
gsi_replace (&gsi, stmt, true);
if (!broken_loop)
{
/* Code to control the increment goes in the CONT_BB. */
gsi = gsi_last_bb (cont_bb);
stmt = gsi_stmt (gsi);
gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
stmt = gimple_build_assign_with_ops (PLUS_EXPR, ind_var, ind_var,
build_one_cst (type));
/* Replace GIMPLE_OMP_CONTINUE. */
gsi_replace (&gsi, stmt, true);
}
/* Emit the condition in L1_BB. */
gsi = gsi_after_labels (l1_bb);
t = fold_build2 (MULT_EXPR, TREE_TYPE (fd->loop.step),
fold_convert (TREE_TYPE (fd->loop.step), ind_var),
fd->loop.step);
if (POINTER_TYPE_P (TREE_TYPE (fd->loop.n1)))
t = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (fd->loop.n1),
fd->loop.n1, fold_convert (sizetype, t));
else
t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loop.n1),
fd->loop.n1, fold_convert (TREE_TYPE (fd->loop.n1), t));
t = fold_convert (TREE_TYPE (fd->loop.v), t);
expand_omp_build_assign (&gsi, fd->loop.v, t);
/* The condition is always '<' since the runtime will fill in the low
and high values. */
stmt = gimple_build_cond (LT_EXPR, ind_var, n2, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
/* Remove GIMPLE_OMP_RETURN. */
gsi = gsi_last_bb (exit_bb);
gsi_remove (&gsi, true);
/* Connect the new blocks. */
remove_edge (FALLTHRU_EDGE (entry_bb));
edge e, ne;
if (!broken_loop)
{
remove_edge (BRANCH_EDGE (entry_bb));
make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
e = BRANCH_EDGE (l1_bb);
ne = FALLTHRU_EDGE (l1_bb);
e->flags = EDGE_TRUE_VALUE;
}
else
{
single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
ne = single_succ_edge (l1_bb);
e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
}
ne->flags = EDGE_FALSE_VALUE;
e->probability = REG_BR_PROB_BASE * 7 / 8;
ne->probability = REG_BR_PROB_BASE / 8;
set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
if (!broken_loop)
{
struct loop *loop = alloc_loop ();
loop->header = l1_bb;
loop->latch = cont_bb;
add_loop (loop, l1_bb->loop_father);
loop->safelen = INT_MAX;
}
/* Pick the correct library function based on the precision of the
induction variable type. */
tree lib_fun = NULL_TREE;
if (TYPE_PRECISION (type) == 32)
lib_fun = cilk_for_32_fndecl;
else if (TYPE_PRECISION (type) == 64)
lib_fun = cilk_for_64_fndecl;
else
gcc_unreachable ();
gcc_assert (fd->sched_kind == OMP_CLAUSE_SCHEDULE_CILKFOR);
/* WS_ARGS contains the library function flavor to call:
__libcilkrts_cilk_for_64 or __libcilkrts_cilk_for_32), and the
user-defined grain value. If the user does not define one, then zero
is passed in by the parser. */
vec_alloc (region->ws_args, 2);
region->ws_args->quick_push (lib_fun);
region->ws_args->quick_push (fd->chunk_size);
}
/* A subroutine of expand_omp_for. Generate code for a simd non-worksharing
loop. Given parameters:
@ -6964,6 +7275,8 @@ expand_omp_for (struct omp_region *region, gimple inner_stmt)
if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_SIMD)
expand_omp_simd (region, &fd);
else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
expand_cilk_for (region, &fd);
else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
&& !fd.have_ordered)
{

View File

@ -1,3 +1,22 @@
2014-09-02 Jakub Jelinek <jakub@redhat.com>
Balaji V. Iyer <balaji.v.iyer@intel.com>
Igor Zamyatin <igor.zamyatin@intel.com>
* c-c++-common/cilk-plus/CK/cilk-fors.c: New test.
* c-c++-common/cilk-plus/CK/cilk-for-2.c: New test.
* c-c++-common/cilk-plus/CK/cilk-for-3.c: New test.
* c-c++-common/cilk-plus/CK/cilk_for_errors.c: New test.
* c-c++-common/cilk-plus/CK/cilk_for_grain.c: New test.
* c-c++-common/cilk-plus/CK/cilk_for_grain_errors.c: New test.
* c-c++-common/cilk-plus/CK/cilk_for_ptr_iter.c: New test.
* c-c++-common/cilk-plus/CK/nested_cilk_for.c: New test.
* g++.dg/cilk-plus/CK/cf3.cc: New test.
* g++.dg/cilk-plus/CK/cilk-for-tplt.cc: New test.
* g++.dg/cilk-plus/CK/for1.cc: New test.
* g++.dg/cilk-plus/CK/stl_iter.cc: New test.
* g++.dg/cilk-plus/CK/stl_rev_iter.cc: New test.
* g++.dg/cilk-plus/CK/stl_test.cc: New test.
2014-09-02 Richard Biener <rguenther@suse.de>
PR tree-optimization/62695

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -334,7 +334,11 @@ enum omp_clause_code {
OMP_CLAUSE_TASKGROUP,
/* Internally used only clause, holding SIMD uid. */
OMP_CLAUSE__SIMDUID_
OMP_CLAUSE__SIMDUID_,
/* Internally used only clause, holding _Cilk_for # of iterations
on OMP_PARALLEL. */
OMP_CLAUSE__CILK_FOR_COUNT_
};
#undef DEFTREESTRUCT
@ -351,6 +355,7 @@ enum omp_clause_schedule_kind {
OMP_CLAUSE_SCHEDULE_GUIDED,
OMP_CLAUSE_SCHEDULE_AUTO,
OMP_CLAUSE_SCHEDULE_RUNTIME,
OMP_CLAUSE_SCHEDULE_CILKFOR,
OMP_CLAUSE_SCHEDULE_LAST
};

View File

@ -1115,6 +1115,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_SAFELEN:
case OMP_CLAUSE__CILK_FOR_COUNT_:
wi->val_only = true;
wi->is_lhs = false;
convert_nonlocal_reference_op (&OMP_CLAUSE_OPERAND (clause, 0),
@ -1744,6 +1745,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_SAFELEN:
case OMP_CLAUSE__CILK_FOR_COUNT_:
wi->val_only = true;
wi->is_lhs = false;
convert_local_reference_op (&OMP_CLAUSE_OPERAND (clause, 0), &dummy,

View File

@ -361,6 +361,13 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
pp_right_paren (buffer);
break;
case OMP_CLAUSE__CILK_FOR_COUNT_:
pp_string (buffer, "_Cilk_for_count_(");
dump_generic_node (buffer, OMP_CLAUSE_OPERAND (clause, 0),
spc, flags, false);
pp_right_paren (buffer);
break;
case OMP_CLAUSE_NOWAIT:
pp_string (buffer, "nowait");
break;
@ -411,6 +418,9 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
case OMP_CLAUSE_SCHEDULE_AUTO:
pp_string (buffer, "auto");
break;
case OMP_CLAUSE_SCHEDULE_CILKFOR:
pp_string (buffer, "cilk-for grain");
break;
default:
gcc_unreachable ();
}
@ -2421,6 +2431,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_string (buffer, "#pragma simd");
goto dump_omp_loop;
case CILK_FOR:
/* This label points one line after dumping the clauses.
For _Cilk_for the clauses are dumped after the _Cilk_for (...)
parameters are printed out. */
goto dump_omp_loop_cilk_for;
case OMP_DISTRIBUTE:
pp_string (buffer, "#pragma omp distribute");
goto dump_omp_loop;
@ -2449,18 +2465,22 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_omp_loop:
dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
dump_omp_loop_cilk_for:
if (!(flags & TDF_SLIM))
{
int i;
if (OMP_FOR_PRE_BODY (node))
{
newline_and_indent (buffer, spc + 2);
if (TREE_CODE (node) == CILK_FOR)
pp_string (buffer, " ");
else
newline_and_indent (buffer, spc + 2);
pp_left_brace (buffer);
spc += 4;
newline_and_indent (buffer, spc);
dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
spc, flags, false);
spc, flags, false);
}
if (OMP_FOR_INIT (node))
{
@ -2468,8 +2488,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (node)); i++)
{
spc += 2;
newline_and_indent (buffer, spc);
pp_string (buffer, "for (");
if (TREE_CODE (node) != CILK_FOR || OMP_FOR_PRE_BODY (node))
newline_and_indent (buffer, spc);
if (TREE_CODE (node) == CILK_FOR)
pp_string (buffer, "_Cilk_for (");
else
pp_string (buffer, "for (");
dump_generic_node (buffer,
TREE_VEC_ELT (OMP_FOR_INIT (node), i),
spc, flags, false);
@ -2483,6 +2507,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
spc, flags, false);
pp_right_paren (buffer);
}
if (TREE_CODE (node) == CILK_FOR)
dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
}
if (OMP_FOR_BODY (node))
{

View File

@ -281,6 +281,7 @@ unsigned const char omp_clause_num_ops[] =
0, /* OMP_CLAUSE_SECTIONS */
0, /* OMP_CLAUSE_TASKGROUP */
1, /* OMP_CLAUSE__SIMDUID_ */
1, /* OMP_CLAUSE__CILK_FOR_COUNT_ */
};
const char * const omp_clause_code_name[] =
@ -324,7 +325,8 @@ const char * const omp_clause_code_name[] =
"parallel",
"sections",
"taskgroup",
"_simduid_"
"_simduid_",
"_Cilk_for_count_"
};
@ -11041,6 +11043,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
case OMP_CLAUSE_SIMDLEN:
case OMP_CLAUSE__LOOPTEMP_:
case OMP_CLAUSE__SIMDUID_:
case OMP_CLAUSE__CILK_FOR_COUNT_:
WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0));
/* FALLTHRU */

View File

@ -1064,6 +1064,10 @@ DEFTREECODE (OMP_SIMD, "omp_simd", tcc_statement, 6)
Operands like for OMP_FOR. */
DEFTREECODE (CILK_SIMD, "cilk_simd", tcc_statement, 6)
/* Cilk Plus - _Cilk_for (..)
Operands like for OMP_FOR. */
DEFTREECODE (CILK_FOR, "cilk_for", tcc_statement, 6)
/* OpenMP - #pragma omp distribute [clause1 ... clauseN]
Operands like for OMP_FOR. */
DEFTREECODE (OMP_DISTRIBUTE, "omp_distribute", tcc_statement, 6)