diff options
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r-- | gcc/cp/semantics.c | 152 |
1 files changed, 145 insertions, 7 deletions
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; } |