aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-09-02 14:52:29 +0200
committerKirill Yukhin <kyukhin@gcc.gnu.org>2014-09-02 12:52:29 +0000
commit9a771876d342f9cf0b64c2ceada267ff50e18206 (patch)
tree88fc4c24c6347b42ca239861cc28a6716e4730ab /gcc/cp
parent794307309bbf58d4cc9de19bd2a7017b92dd7eef (diff)
downloadgcc-9a771876d342f9cf0b64c2ceada267ff50e18206.zip
gcc-9a771876d342f9cf0b64c2ceada267ff50e18206.tar.gz
gcc-9a771876d342f9cf0b64c2ceada267ff50e18206.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog28
-rw-r--r--gcc/cp/cp-cilkplus.c4
-rw-r--r--gcc/cp/parser.c127
-rw-r--r--gcc/cp/pt.c1
-rw-r--r--gcc/cp/semantics.c152
5 files changed, 288 insertions, 24 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 58890b4..7a72097 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,31 @@
+2014-09-02 Jakub Jelinek <jakub@redhat.com>
+ Balaji V. Iyer <balaji.v.iyer@intel.com>
+ Igor Zamyatin <igor.zamyatin@intel.com>
+
+ * cp-cilkplus.c (cpp_validate_cilk_plus_loop_aux): Loc definition
+ simplified.
+ * parser.c (cp_parser_cilk_for): New function.
+ (cp_parser_cilk_grainsize): Likewise.
+ (cp_parser_statement): Added RID_CILK_FOR case.
+ (cp_parser_omp_for_cond): Added CILK_FOR check.
+ (cp_parser_omp_for_loop_init): Change function argument to accept
+ tree_code instead just a bool flag; change the check to use that
+ tree_code; check for initialization declaration in case of Cilk_for.
+ (cp_parser_omp_for_loop): Added checks for CILK_FOR and RID_CILK_FOR;
+ changed call to cp_parser_omp_for_loop_init according new arguments'
+ list.
+ (cp_parser_pragma): Added PRAGMA_CILK_GRAINSIZE case.
+ * pt.c (tsubst_expr): Added CILK_FOR case.
+ * semantics.c: Include convert.h.
+ (finish_omp_clauses): Properly handle OMP_CLAUSE_SCHEDULE_CILKFOR
+ case; added OMP_CLAUSE__CILK_FOR_COUNT_.
+ (handle_omp_for_class_iterator): New argument lastp and its usage;
+ added NE_EXPR case.
+ (finish_omp_for): Changed call to handle_omp_for_class_iterator
+ according new arguments' list; in case of Cilk_for save very first
+ decl and create empty stmt_list block; use block to build correct
+ statement tree.
+
2014-08-31 Jason Merrill <jason@redhat.com>
PR c++/62302
diff --git a/gcc/cp/cp-cilkplus.c b/gcc/cp/cp-cilkplus.c
index daa9b8e..565dd40 100644
--- a/gcc/cp/cp-cilkplus.c
+++ b/gcc/cp/cp-cilkplus.c
@@ -42,12 +42,11 @@ static tree
cpp_validate_cilk_plus_loop_aux (tree *tp, int *walk_subtrees, void *data)
{
bool *valid = (bool *) data;
- location_t loc = EXPR_HAS_LOCATION (*tp) ? EXPR_LOCATION (*tp) :
- UNKNOWN_LOCATION;
if (!tp || !*tp)
return NULL_TREE;
+ location_t loc = EXPR_LOCATION (*tp);
if (TREE_CODE (*tp) == THROW_EXPR)
{
error_at (loc, "throw expressions are not allowed inside loops "
@@ -142,4 +141,3 @@ cilk_install_body_with_frame_cleanup (tree fndecl, tree orig_body, void *wd)
append_to_statement_list (build_stmt (loc, TRY_FINALLY_EXPR, body, dtor),
&list);
}
-
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ad99cab..05fa86a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -239,6 +239,8 @@ static tree cp_literal_operator_id
static void cp_parser_cilk_simd
(cp_parser *, cp_token *);
+static tree cp_parser_cilk_for
+ (cp_parser *, tree);
static bool cp_parser_omp_declare_reduction_exprs
(tree, cp_parser *);
static tree cp_parser_cilk_simd_vectorlength
@@ -9532,6 +9534,18 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
statement = cp_parser_iteration_statement (parser, false);
break;
+ case RID_CILK_FOR:
+ if (!flag_cilkplus)
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "-fcilkplus must be enabled to use %<_Cilk_for%>");
+ cp_lexer_consume_token (parser->lexer);
+ statement = error_mark_node;
+ }
+ else
+ statement = cp_parser_cilk_for (parser, integer_zero_node);
+ break;
+
case RID_BREAK:
case RID_CONTINUE:
case RID_RETURN:
@@ -29222,7 +29236,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
case LE_EXPR:
break;
case NE_EXPR:
- if (code == CILK_SIMD)
+ if (code == CILK_SIMD || code == CILK_FOR)
break;
/* Fall through: OpenMP disallows NE_EXPR. */
default:
@@ -29337,15 +29351,12 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
/* Parse the initialization statement of either an OpenMP for loop or
a Cilk Plus for loop.
- PARSING_OPENMP is true if parsing OpenMP, or false if parsing Cilk
- Plus.
-
Return true if the resulting construct should have an
OMP_CLAUSE_PRIVATE added to it. */
static bool
cp_parser_omp_for_loop_init (cp_parser *parser,
- bool parsing_openmp,
+ enum tree_code code,
tree &this_pre_body,
vec<tree, va_gc> *for_block,
tree &init,
@@ -29408,7 +29419,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
if (cp_lexer_next_token_is (parser->lexer,
CPP_OPEN_PAREN))
{
- if (parsing_openmp)
+ if (code != CILK_SIMD && code != CILK_FOR)
error ("parenthesized initialization is not allowed in "
"OpenMP %<for%> loop");
else
@@ -29480,6 +29491,9 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
cp_id_kind idk;
/* If parsing a type specifier sequence failed, then
this MUST be a simple expression. */
+ if (code == CILK_FOR)
+ error ("%<_Cilk_for%> allows expression instead of declaration only "
+ "in C, not in C++");
cp_parser_parse_tentatively (parser);
decl = cp_parser_primary_expression (parser, false, false,
false, &idk);
@@ -29548,11 +29562,18 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
bool add_private_clause = false;
location_t loc;
- if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
+ if (code != CILK_FOR
+ && !cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
{
cp_parser_error (parser, "for statement expected");
return NULL;
}
+ if (code == CILK_FOR
+ && !cp_lexer_next_token_is_keyword (parser->lexer, RID_CILK_FOR))
+ {
+ cp_parser_error (parser, "_Cilk_for statement expected");
+ return NULL;
+ }
loc = cp_lexer_consume_token (parser->lexer)->location;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
@@ -29562,8 +29583,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
this_pre_body = push_stmt_list ();
add_private_clause
- |= cp_parser_omp_for_loop_init (parser,
- /*parsing_openmp=*/code != CILK_SIMD,
+ |= cp_parser_omp_for_loop_init (parser, code,
this_pre_body, for_block,
init, decl, real_decl);
@@ -29733,7 +29753,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
/* Note that we saved the original contents of this flag when we entered
the structured block, and so we don't need to re-save it here. */
- if (code == CILK_SIMD)
+ if (code == CILK_SIMD || code == CILK_FOR)
parser->in_statement = IN_CILK_SIMD_FOR;
else
parser->in_statement = IN_OMP_FOR;
@@ -31692,6 +31712,36 @@ cp_parser_initial_pragma (cp_token *first_token)
cp_lexer_get_preprocessor_token (NULL, first_token);
}
+/* Parses the grainsize pragma for the _Cilk_for statement.
+ Syntax:
+ #pragma cilk grainsize = <VALUE>. */
+
+static void
+cp_parser_cilk_grainsize (cp_parser *parser, cp_token *pragma_tok)
+{
+ if (cp_parser_require (parser, CPP_EQ, RT_EQ))
+ {
+ tree exp = cp_parser_binary_expression (parser, false, false,
+ PREC_NOT_OPERATOR, NULL);
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ if (!exp || exp == error_mark_node)
+ {
+ error_at (pragma_tok->location, "invalid grainsize for _Cilk_for");
+ return;
+ }
+
+ /* Make sure the next token is _Cilk_for, it is invalid otherwise. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_CILK_FOR))
+ cp_parser_cilk_for (parser, exp);
+ else
+ warning_at (cp_lexer_peek_token (parser->lexer)->location, 0,
+ "%<#pragma cilk grainsize%> is not followed by "
+ "%<_Cilk_for%>");
+ return;
+ }
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+}
+
/* Normal parsing of a pragma token. Here we can (and must) use the
regular lexer. */
@@ -31874,6 +31924,27 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
cp_parser_cilk_simd (parser, pragma_tok);
return true;
+ case PRAGMA_CILK_GRAINSIZE:
+ if (context == pragma_external)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma cilk grainsize%> must be inside a function");
+ break;
+ }
+
+ /* Ignore the pragma if Cilk Plus is not enabled. */
+ if (flag_cilkplus)
+ {
+ cp_parser_cilk_grainsize (parser, pragma_tok);
+ return true;
+ }
+ else
+ {
+ error_at (pragma_tok->location, "-fcilkplus must be enabled to use "
+ "%<#pragma cilk grainsize%>");
+ break;
+ }
+
default:
gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
c_invoke_pragma_handler (id);
@@ -31960,10 +32031,10 @@ cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses,
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return error_mark_node;
-
+
expr = cp_parser_constant_expression (parser, false, NULL);
expr = maybe_constant_value (expr);
-
+
/* If expr == error_mark_node, then don't emit any errors nor
create a clause. if any of the above functions returns
error mark node then they would have emitted an error message. */
@@ -32197,7 +32268,7 @@ cp_parser_cilk_simd (cp_parser *parser, cp_token *pragma_token)
if (clauses == error_mark_node)
return;
-
+
if (cp_lexer_next_token_is_not_keyword (parser->lexer, RID_FOR))
{
error_at (cp_lexer_peek_token (parser->lexer)->location,
@@ -32212,7 +32283,35 @@ cp_parser_cilk_simd (cp_parser *parser, cp_token *pragma_token)
cpp_validate_cilk_plus_loop (OMP_FOR_BODY (ret));
cp_parser_end_omp_structured_block (parser, save);
add_stmt (finish_omp_structured_block (sb));
- return;
+}
+
+/* Main entry-point for parsing Cilk Plus _Cilk_for
+ loops. The return value is error_mark_node
+ when errors happen and CILK_FOR tree on success. */
+
+static tree
+cp_parser_cilk_for (cp_parser *parser, tree grain)
+{
+ if (cp_lexer_next_token_is_not_keyword (parser->lexer, RID_CILK_FOR))
+ gcc_unreachable ();
+
+ tree sb = begin_omp_structured_block ();
+ int save = cp_parser_begin_omp_structured_block (parser);
+
+ tree clauses = build_omp_clause (EXPR_LOCATION (grain), OMP_CLAUSE_SCHEDULE);
+ OMP_CLAUSE_SCHEDULE_KIND (clauses) = OMP_CLAUSE_SCHEDULE_CILKFOR;
+ OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clauses) = grain;
+ clauses = finish_omp_clauses (clauses);
+
+ tree ret = cp_parser_omp_for_loop (parser, CILK_FOR, clauses, NULL);
+ if (ret)
+ cpp_validate_cilk_plus_loop (ret);
+ else
+ ret = error_mark_node;
+
+ cp_parser_end_omp_structured_block (parser, save);
+ add_stmt (finish_omp_structured_block (sb));
+ return ret;
}
/* Create an identifier for a generic parameter type (a synthesized
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index eac837f..5ea5a58 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -14012,6 +14012,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OMP_FOR:
case OMP_SIMD:
case CILK_SIMD:
+ case CILK_FOR:
case OMP_DISTRIBUTE:
{
tree clauses, body, pre_body;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 168bde8..01748da 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h"
#include "omp-low.h"
#include "builtins.h"
+#include "convert.h"
static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \
@@ -5424,6 +5425,8 @@ finish_omp_clauses (tree clauses)
else if (t == error_mark_node)
remove = true;
else if (!type_dependent_expression_p (t)
+ && (OMP_CLAUSE_SCHEDULE_KIND (c)
+ != OMP_CLAUSE_SCHEDULE_CILKFOR)
&& !INTEGRAL_TYPE_P (TREE_TYPE (t)))
{
error ("schedule chunk size expression must be integral");
@@ -5433,7 +5436,19 @@ finish_omp_clauses (tree clauses)
{
t = mark_rvalue_use (t);
if (!processing_template_decl)
- t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ {
+ if (OMP_CLAUSE_SCHEDULE_KIND (c)
+ == OMP_CLAUSE_SCHEDULE_CILKFOR)
+ {
+ t = convert_to_integer (long_integer_type_node, t);
+ if (t == error_mark_node)
+ {
+ remove = true;
+ break;
+ }
+ }
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
}
break;
@@ -5734,6 +5749,7 @@ finish_omp_clauses (tree clauses)
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
case OMP_CLAUSE_PROC_BIND:
+ case OMP_CLAUSE__CILK_FOR_COUNT_:
break;
case OMP_CLAUSE_INBRANCH:
@@ -6053,7 +6069,7 @@ finish_omp_task (tree clauses, tree body)
static bool
handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
tree condv, tree incrv, tree *body,
- tree *pre_body, tree clauses)
+ tree *pre_body, tree clauses, tree *lastp)
{
tree diff, iter_init, iter_incr = NULL, last;
tree incr_var = NULL, orig_pre_body, orig_body, c;
@@ -6073,6 +6089,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
case GE_EXPR:
case LT_EXPR:
case LE_EXPR:
+ case NE_EXPR:
if (TREE_OPERAND (cond, 1) == iter)
cond = build2 (swap_tree_comparison (TREE_CODE (cond)),
TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0));
@@ -6285,6 +6302,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
TREE_VEC_ELT (initv, i) = init;
TREE_VEC_ELT (condv, i) = cond;
TREE_VEC_ELT (incrv, i) = incr;
+ *lastp = last;
return false;
}
@@ -6301,7 +6319,8 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
tree condv, tree incrv, tree body, tree pre_body, tree clauses)
{
tree omp_for = NULL, orig_incr = NULL;
- tree decl, init, cond, incr;
+ tree decl = NULL, init, cond, incr, orig_decl = NULL_TREE, block = NULL_TREE;
+ tree last = NULL_TREE;
location_t elocus;
int i;
@@ -6431,8 +6450,11 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
"iteration variable %qE", decl);
return NULL;
}
+ if (code == CILK_FOR && i == 0)
+ orig_decl = decl;
if (handle_omp_for_class_iterator (i, locus, declv, initv, condv,
- incrv, &body, &pre_body, clauses))
+ incrv, &body, &pre_body,
+ clauses, &last))
return NULL;
continue;
}
@@ -6485,11 +6507,18 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
if (IS_EMPTY_STMT (pre_body))
pre_body = NULL;
+ if (code == CILK_FOR && !processing_template_decl)
+ block = push_stmt_list ();
+
omp_for = c_finish_omp_for (locus, code, declv, initv, condv, incrv,
body, pre_body);
if (omp_for == NULL)
- return NULL;
+ {
+ if (block)
+ pop_stmt_list (block);
+ return NULL;
+ }
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
{
@@ -6523,8 +6552,117 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv,
if (orig_incr)
TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i) = TREE_VEC_ELT (orig_incr, i);
}
- if (omp_for != NULL)
- OMP_FOR_CLAUSES (omp_for) = clauses;
+ OMP_FOR_CLAUSES (omp_for) = clauses;
+
+ if (block)
+ {
+ tree omp_par = make_node (OMP_PARALLEL);
+ TREE_TYPE (omp_par) = void_type_node;
+ OMP_PARALLEL_CLAUSES (omp_par) = NULL_TREE;
+ tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+ TREE_SIDE_EFFECTS (bind) = 1;
+ BIND_EXPR_BODY (bind) = pop_stmt_list (block);
+ OMP_PARALLEL_BODY (omp_par) = bind;
+ if (OMP_FOR_PRE_BODY (omp_for))
+ {
+ add_stmt (OMP_FOR_PRE_BODY (omp_for));
+ OMP_FOR_PRE_BODY (omp_for) = NULL_TREE;
+ }
+ init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0);
+ decl = TREE_OPERAND (init, 0);
+ cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), 0);
+ incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
+ tree t = TREE_OPERAND (cond, 1), c, clauses, *pc;
+ clauses = OMP_FOR_CLAUSES (omp_for);
+ OMP_FOR_CLAUSES (omp_for) = NULL_TREE;
+ for (pc = &clauses; *pc; )
+ if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_SCHEDULE)
+ {
+ gcc_assert (OMP_FOR_CLAUSES (omp_for) == NULL_TREE);
+ OMP_FOR_CLAUSES (omp_for) = *pc;
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (omp_for)) = NULL_TREE;
+ }
+ else
+ {
+ gcc_assert (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_FIRSTPRIVATE);
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
+ if (TREE_CODE (t) != INTEGER_CST)
+ {
+ TREE_OPERAND (cond, 1) = get_temp_regvar (TREE_TYPE (t), t);
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = TREE_OPERAND (cond, 1);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ if (TREE_CODE (incr) == MODIFY_EXPR)
+ {
+ t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
+ if (TREE_CODE (t) != INTEGER_CST)
+ {
+ TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
+ = get_temp_regvar (TREE_TYPE (t), t);
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ }
+ t = TREE_OPERAND (init, 1);
+ if (TREE_CODE (t) != INTEGER_CST)
+ {
+ TREE_OPERAND (init, 1) = get_temp_regvar (TREE_TYPE (t), t);
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = TREE_OPERAND (init, 1);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ if (orig_decl && orig_decl != decl)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = orig_decl;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ if (last)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = last;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
+ OMP_CLAUSE_DECL (c) = decl;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ c = build_omp_clause (input_location, OMP_CLAUSE__CILK_FOR_COUNT_);
+ OMP_CLAUSE_OPERAND (c, 0)
+ = cilk_for_number_of_iterations (omp_for);
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ OMP_PARALLEL_CLAUSES (omp_par) = finish_omp_clauses (c);
+ add_stmt (omp_par);
+ return omp_par;
+ }
+ else if (code == CILK_FOR && processing_template_decl)
+ {
+ tree c, clauses = OMP_FOR_CLAUSES (omp_for);
+ if (orig_decl && orig_decl != decl)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = orig_decl;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ if (last)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = last;
+ OMP_CLAUSE_CHAIN (c) = clauses;
+ clauses = c;
+ }
+ OMP_FOR_CLAUSES (omp_for) = clauses;
+ }
return omp_for;
}