diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-09-02 14:52:29 +0200 |
---|---|---|
committer | Kirill Yukhin <kyukhin@gcc.gnu.org> | 2014-09-02 12:52:29 +0000 |
commit | 9a771876d342f9cf0b64c2ceada267ff50e18206 (patch) | |
tree | 88fc4c24c6347b42ca239861cc28a6716e4730ab /gcc/cp | |
parent | 794307309bbf58d4cc9de19bd2a7017b92dd7eef (diff) | |
download | gcc-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/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/cp/cp-cilkplus.c | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 127 | ||||
-rw-r--r-- | gcc/cp/pt.c | 1 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 152 |
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; } |