Hi! I've committed following patch to add support for C++ random access iterators in taskloop constructs.
2015-06-23 Jakub Jelinek <ja...@redhat.com> * tree.h (OMP_CLAUSE_PRIVATE_TASKLOOP_IV, OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV): Define. * gimplify.c (gimplify_omp_for): Handle gimplification of OMP_TASKLOOP with C++ random access iterator clauses. * omp-low.c (scan_sharing_clauses): Ignore OMP_CLAUSE_SHARED with OMP_CLAUSE_SHARED_FIRSTPRIVATE if it is a global var outside of the outer taskloop for. (lower_lastprivate_clauses): Handle OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV lastprivate if the decl is global outside of outer taskloop for. (lower_send_clauses): Look beyond the outer taskloop for. gcc/cp/ * semantics.c (handle_omp_for_class_iterator): Handle OMP_TASKLOOP class iterators. (finish_omp_for): Adjust handle_omp_for_class_iterator caller. libgomp/ * testsuite/libgomp.c++/taskloop-6.C: New test. * testsuite/libgomp.c++/taskloop-7.C: New test. * testsuite/libgomp.c++/taskloop-8.C: New test. * testsuite/libgomp.c++/taskloop-9.C: New test. --- gcc/tree.h.jj 2015-06-17 21:02:00.000000000 +0200 +++ gcc/tree.h 2015-06-22 15:19:37.501110534 +0200 @@ -1356,6 +1356,12 @@ extern void protected_set_expr_location #define OMP_CLAUSE_PRIVATE_OUTER_REF(NODE) \ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PRIVATE)) +/* True if a PRIVATE clause is for a C++ class IV on taskloop construct + (thus should be private on the outer taskloop and firstprivate on + task). */ +#define OMP_CLAUSE_PRIVATE_TASKLOOP_IV(NODE) \ + TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PRIVATE)) + /* True on a LASTPRIVATE clause if a FIRSTPRIVATE clause for the same decl is present in the chain. */ #define OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE(NODE) \ @@ -1367,6 +1373,12 @@ extern void protected_set_expr_location #define OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ(NODE) \ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init +/* True if a LASTPRIVATE clause is for a C++ class IV on taskloop construct + (thus should be lastprivate on the outer taskloop and firstprivate on + task). */ +#define OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV(NODE) \ + TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LASTPRIVATE)) + /* True on a SHARED clause if a FIRSTPRIVATE clause for the same decl is present in the chain (this can happen only for taskloop with FIRSTPRIVATE/LASTPRIVATE on it originally. */ --- gcc/gimplify.c.jj 2015-06-18 15:16:18.000000000 +0200 +++ gcc/gimplify.c 2015-06-23 10:03:28.908079507 +0200 @@ -7230,7 +7230,8 @@ gimplify_omp_for (tree *expr_p, gimple_s { TREE_OPERAND (t, 1) = get_initialized_tmp_var (TREE_OPERAND (t, 1), - pre_p, NULL); + gimple_seq_empty_p (for_pre_body) + ? pre_p : &for_pre_body, NULL); tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE); OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1); @@ -7250,7 +7251,9 @@ gimplify_omp_for (tree *expr_p, gimple_s if (!is_gimple_constant (*tp)) { - *tp = get_initialized_tmp_var (*tp, pre_p, NULL); + gimple_seq *seq = gimple_seq_empty_p (for_pre_body) + ? pre_p : &for_pre_body; + *tp = get_initialized_tmp_var (*tp, seq, NULL); tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE); OMP_CLAUSE_DECL (c) = *tp; @@ -7683,7 +7686,6 @@ gimplify_omp_for (tree *expr_p, gimple_s { /* These clauses are allowed on task, move them there. */ case OMP_CLAUSE_SHARED: - case OMP_CLAUSE_PRIVATE: case OMP_CLAUSE_FIRSTPRIVATE: case OMP_CLAUSE_DEFAULT: case OMP_CLAUSE_IF: @@ -7694,6 +7696,26 @@ gimplify_omp_for (tree *expr_p, gimple_s *gtask_clauses_ptr = c; gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c); break; + case OMP_CLAUSE_PRIVATE: + if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c)) + { + /* We want private on outer for and firstprivate + on task. */ + *gtask_clauses_ptr + = build_omp_clause (OMP_CLAUSE_LOCATION (c), + OMP_CLAUSE_FIRSTPRIVATE); + OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c); + lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL); + gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); + *gforo_clauses_ptr = c; + gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c); + } + else + { + *gtask_clauses_ptr = c; + gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c); + } + break; /* These clauses go into outer taskloop clauses. */ case OMP_CLAUSE_GRAINSIZE: case OMP_CLAUSE_NUM_TASKS: @@ -7712,6 +7734,26 @@ gimplify_omp_for (tree *expr_p, gimple_s a shared clause on task. If the same decl is also firstprivate, add also firstprivate clause on the inner taskloop. */ case OMP_CLAUSE_LASTPRIVATE: + if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c)) + { + /* For taskloop C++ lastprivate IVs, we want: + 1) private on outer taskloop + 2) firstprivate and shared on task + 3) lastprivate on inner taskloop */ + *gtask_clauses_ptr + = build_omp_clause (OMP_CLAUSE_LOCATION (c), + OMP_CLAUSE_FIRSTPRIVATE); + OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c); + lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL); + gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr); + OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1; + *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c), + OMP_CLAUSE_PRIVATE); + OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c); + OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1; + TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c); + gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr); + } *gfor_clauses_ptr = c; gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c); *gtask_clauses_ptr @@ -7735,7 +7777,9 @@ gimplify_omp_for (tree *expr_p, gimple_s g = gimple_build_bind (NULL_TREE, g, NULL_TREE); gomp_for *gforo = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses, - gimple_omp_for_collapse (gfor), NULL); + gimple_omp_for_collapse (gfor), + gimple_omp_for_pre_body (gfor)); + gimple_omp_for_set_pre_body (gfor, NULL); gimple_omp_for_set_combined_p (gforo, true); gimple_omp_for_set_combined_into_p (gfor, true); for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++) --- gcc/omp-low.c.jj 2015-06-22 11:17:39.000000000 +0200 +++ gcc/omp-low.c 2015-06-23 14:19:13.466669690 +0200 @@ -2169,6 +2169,9 @@ scan_sharing_clauses (tree clauses, omp_ break; if (OMP_CLAUSE_SHARED_FIRSTPRIVATE (c)) { + if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, + ctx->outer))) + break; bool by_ref = use_pointer_for_field (decl, ctx); install_var_field (decl, by_ref, 11, ctx); break; @@ -4965,7 +4968,18 @@ lower_lastprivate_clauses (tree clauses, OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL; } - x = build_outer_var_ref (var, ctx, true); + x = NULL_TREE; + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE + && OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c)) + { + gcc_checking_assert (is_taskloop_ctx (ctx)); + tree ovar = maybe_lookup_decl_in_outer_ctx (var, + ctx->outer->outer); + if (is_global_var (ovar)) + x = ovar; + } + if (!x) + x = build_outer_var_ref (var, ctx, true); if (is_reference (var)) new_var = build_simple_mem_ref_loc (clause_loc, new_var); x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var); @@ -5326,11 +5340,15 @@ lower_send_clauses (tree clauses, gimple { tree c, t; int ignored_looptemp = 0; + bool is_taskloop = false; /* For taskloop, ignore first two _looptemp_ clauses, those are initialized by GOMP_taskloop. */ if (is_task_ctx (ctx) && gimple_omp_task_taskloop_p (ctx->stmt)) - ignored_looptemp = 2; + { + ignored_looptemp = 2; + is_taskloop = true; + } for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) { @@ -5375,7 +5393,16 @@ lower_send_clauses (tree clauses, gimple if (is_variable_sized (val)) continue; } - var = lookup_decl_in_outer_ctx (val, ctx); + + /* For OMP_CLAUSE_SHARED_FIRSTPRIVATE, look beyond the + outer taskloop region. */ + omp_context *ctx_for_o = ctx; + if (is_taskloop + && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED + && OMP_CLAUSE_SHARED_FIRSTPRIVATE (c)) + ctx_for_o = ctx->outer; + + var = lookup_decl_in_outer_ctx (val, ctx_for_o); if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN && is_global_var (var)) @@ -5385,7 +5412,7 @@ lower_send_clauses (tree clauses, gimple if (t) { var = DECL_VALUE_EXPR (var); - tree o = maybe_lookup_decl_in_outer_ctx (t, ctx); + tree o = maybe_lookup_decl_in_outer_ctx (t, ctx_for_o); if (o != t) var = unshare_and_remap (var, t, o); else --- gcc/cp/semantics.c.jj 2015-06-22 11:17:39.000000000 +0200 +++ gcc/cp/semantics.c 2015-06-23 10:12:08.618129457 +0200 @@ -6791,9 +6791,10 @@ finish_omp_task (tree clauses, tree body into integral iterator. Return FALSE if successful. */ 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 *lastp) +handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code, + tree declv, tree initv, tree condv, tree incrv, + tree *body, 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; @@ -6951,10 +6952,25 @@ handle_omp_for_class_iterator (int i, lo } incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error); + bool taskloop_iv_seen = false; for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE && OMP_CLAUSE_DECL (c) == iter) - break; + { + if (code == OMP_TASKLOOP) + { + taskloop_iv_seen = true; + OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c) = 1; + } + break; + } + else if (code == OMP_TASKLOOP + && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE + && OMP_CLAUSE_DECL (c) == iter) + { + taskloop_iv_seen = true; + OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1; + } decl = create_temporary_var (TREE_TYPE (diff)); pushdecl (decl); @@ -6962,13 +6978,32 @@ handle_omp_for_class_iterator (int i, lo last = create_temporary_var (TREE_TYPE (diff)); pushdecl (last); add_decl_expr (last); - if (c && iter_incr == NULL) + if (c && iter_incr == NULL && TREE_CODE (incr) != INTEGER_CST) { incr_var = create_temporary_var (TREE_TYPE (diff)); pushdecl (incr_var); add_decl_expr (incr_var); } gcc_assert (stmts_are_full_exprs_p ()); + tree diffvar = NULL_TREE; + if (code == OMP_TASKLOOP) + { + if (!taskloop_iv_seen) + { + tree ivc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE); + OMP_CLAUSE_DECL (ivc) = iter; + cxx_omp_finish_clause (ivc, NULL); + OMP_CLAUSE_CHAIN (ivc) = clauses; + clauses = ivc; + } + tree lvc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE); + OMP_CLAUSE_DECL (lvc) = last; + OMP_CLAUSE_CHAIN (lvc) = clauses; + clauses = lvc; + diffvar = create_temporary_var (TREE_TYPE (diff)); + pushdecl (diffvar); + add_decl_expr (diffvar); + } orig_pre_body = *pre_body; *pre_body = push_stmt_list (); @@ -6981,10 +7016,13 @@ handle_omp_for_class_iterator (int i, lo init = build_int_cst (TREE_TYPE (diff), 0); if (c && iter_incr == NULL) { - finish_expr_stmt (build_x_modify_expr (elocus, - incr_var, NOP_EXPR, - incr, tf_warning_or_error)); - incr = incr_var; + if (incr_var) + { + finish_expr_stmt (build_x_modify_expr (elocus, + incr_var, NOP_EXPR, + incr, tf_warning_or_error)); + incr = incr_var; + } iter_incr = build_x_modify_expr (elocus, iter, PLUS_EXPR, incr, tf_warning_or_error); @@ -6992,6 +7030,13 @@ handle_omp_for_class_iterator (int i, lo finish_expr_stmt (build_x_modify_expr (elocus, last, NOP_EXPR, init, tf_warning_or_error)); + if (diffvar) + { + finish_expr_stmt (build_x_modify_expr (elocus, + diffvar, NOP_EXPR, + diff, tf_warning_or_error)); + diff = diffvar; + } *pre_body = pop_stmt_list (*pre_body); cond = cp_build_binary_op (elocus, @@ -7176,8 +7221,8 @@ finish_omp_for (location_t locus, enum t } if (code == CILK_FOR && i == 0) orig_decl = decl; - if (handle_omp_for_class_iterator (i, locus, declv, initv, condv, - incrv, &body, &pre_body, + if (handle_omp_for_class_iterator (i, locus, code, declv, initv, + condv, incrv, &body, &pre_body, clauses, &last)) return NULL; continue; --- libgomp/testsuite/libgomp.c++/taskloop-6.C.jj 2015-06-23 14:25:31.717932978 +0200 +++ libgomp/testsuite/libgomp.c++/taskloop-6.C 2015-06-23 15:56:31.022700214 +0200 @@ -0,0 +1,442 @@ +// { dg-do run } + +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) + abort (); + results[*i]++; +} + +void +f1 (const I<int> &x, const I<int> &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop num_tasks(22) + for (I<int> i = x; i <= y; i += 6) + baz (i); +} + +void +f2 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop grainsize(384) private(i) + for (i = x; i < y - 1; i = 1 - 6 + 7 + i) + baz (i); +} + +template <typename T> +void +f3 (const I<int> &x, const I<int> &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop default(none) firstprivate (x, y) + for (I<int> i = x; i <= y; i = i + 9 - 8) + baz (i); +} + +template <typename T> +void +f4 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x + 2000 - 64; i > y + 10; --i) + baz (i); +} + +void +f5 (const I<int> &x, const I<int> &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (I<int> i = x + 2000 - 64; i > y + 10; i -= 10) + baz (i); +} + +template <int N> +void +f6 (const I<int> &x, const I<int> &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (I<int> i = x + 2000 - 64; i > y + 10; i = i - 12 + 2) + { + I<int> j = i + N; + baz (j); + } +} + +template <int N> +void +f7 (I<int> i, const I<int> &x, const I<int> &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop default(none) firstprivate (x, y) + for (i = x - 10; i <= y + 10; i += N) + baz (i); +} + +template <int N> +void +f8 (J<int> j) +{ + I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop default(none) num_tasks(*I<int> (j.begin ())) firstprivate (j) + for (i = j.begin (); i <= j.end () + N; i += 2) + baz (i); +} + +template <typename T, int N> +void +f9 (const I<T> &x, const I<T> &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop grainsize(163) + for (I<T> i = x; i <= y; i = i + N) + baz (i); +} + +template <typename T, int N> +void +f10 (const I<T> &x, const I<T> &y) +{ + I<T> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (i = x; i > y; i = i + N) + baz (i); +} + +template <typename T> +void +f11 (const T &x, const T &y) +{ +#pragma omp parallel + { +#pragma omp single nowait +#pragma omp taskloop nogroup + for (T i = x; i <= y; i += 3) + baz (i); +#pragma omp single nowait + { + T j = y + 3; + baz (j); + } + } +} + +template <typename T> +void +f12 (const T &x, const T &y) +{ + T i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (i = x; i > y; --i) + baz (i); +} + +template <int N> +struct K +{ + template <typename T> + static void + f13 (const T &x, const T &y) + { +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (T i = x; i <= y + N; i += N) + baz (i); + } +}; + +I<int> +f14 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x; i < y - 1; i = 1 - 6 + 7 + i) + baz (i); + return i; +} + +template <typename T> +I<int> +f15 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x + 2000 - 64; i > y + 10; --i) + baz (i); + return i; +} + +template <int N> +I<int> +f16 (I<int> i, const I<int> &x, const I<int> &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x - 10; i <= y + 10; i += N) + baz (i); + return i; +} + +template <int N> +I<int> +f17 (J<int> j) +{ + static I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = j.begin (); i <= j.end () + N; i += 2) + baz (i); + return i; +} + +template <typename T, int N> +I<T> +f18 (const I<T> &x, const I<T> &y) +{ + static I<T> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x; i > y; i = i + N) + baz (i); + return i; +} + +template <typename T> +T +f19 (const T &x, const T &y) +{ + T i; +#pragma omp parallel + { +#pragma omp single nowait +#pragma omp taskloop nogroup lastprivate(i) + for (i = x; i <= y; i += 3) + baz (i); +#pragma omp single nowait + { + T j = y + 3; + baz (j); + } + } + return i; +} + +template <typename T> +T +f20 (const T &x, const T &y) +{ + T i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x; i > y; --i) + baz (i); + return i; +} + +#define check(expr) \ + for (int i = 0; i < 2000; i++) \ + if (expr) \ + { \ + if (results[i] != 1) \ + 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<char> (&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); + if (f14 (&a[0], &a[1999]) != I<int>(&a[1998])) + abort (); + check (i < 1998 && (i & 1) == 0); + if (f15<int> (&a[0], &a[30]) != I<int>(&a[40])) + abort (); + check (i > 40 && i <= 2000 - 64); + if (f16<6> (I<int> (), &a[12], &a[1800]) != I<int>(&a[1814])) + abort (); + check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0); + if (f17<121> (J<int> (&a[14], &a[1803])) != I<int>(&a[1926])) + abort (); + check (i >= 14 && i <= 1924 && (i & 1) == 0); + if (f18<int, -7> (&a[1939], &a[17]) != I<int>(&a[14])) + abort (); + check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0); + if (f19<I<int> > (&a[16], &a[1981]) != I<int>(&a[1984])) + abort (); + check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0); + if (f20<I<int> > (&a[1761], &a[37]) != I<int>(&a[37])) + abort (); + check (i > 37 && i <= 1761); + 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); + if (f18<long, -7> (&b[1939], &b[17]) != I<long>(&b[14])) + abort (); + check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0); + if (f19<I<long> > (&b[16], &b[1981]) != I<long>(&b[1984])) + abort (); + check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0); + if (f20<I<long> > (&b[1761], &b[37]) != I<long>(&b[37])) + abort (); + check (i > 37 && i <= 1761); +} --- libgomp/testsuite/libgomp.c++/taskloop-7.C.jj 2015-06-23 14:36:24.771027568 +0200 +++ libgomp/testsuite/libgomp.c++/taskloop-7.C 2015-06-23 15:34:09.847959682 +0200 @@ -0,0 +1,400 @@ +// { dg-do run } + +#include <vector> +#include <cstdlib> + +template <typename T> +class J +{ +public: + typedef typename std::vector<T>::const_iterator const_iterator; + J(const const_iterator &x, const const_iterator &y) : b (x), e (y) {} + const const_iterator &begin (); + const const_iterator &end (); +private: + const_iterator b, e; +}; + +template <typename T> +const typename std::vector<T>::const_iterator &J<T>::begin () { return b; } +template <typename T> +const typename std::vector<T>::const_iterator &J<T>::end () { return e; } + +int results[2000]; + +template <typename T> +void +baz (T &i) +{ + if (*i < 0 || *i >= 2000) + std::abort (); + results[*i]++; +} + +void +f1 (const std::vector<int>::const_iterator &x, + const std::vector<int>::const_iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (std::vector<int>::const_iterator i = x; i <= y; i += 6) + baz (i); +} + +void +f2 (const std::vector<int>::const_iterator &x, + const std::vector<int>::const_iterator &y) +{ + std::vector<int>::const_iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop private(i) + for (i = x; i < y - 1; i = 1 - 6 + 7 + i) + baz (i); +} + +template <typename T> +void +f3 (const std::vector<int>::const_iterator &x, + const std::vector<int>::const_iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (std::vector<int>::const_iterator i = x; i <= y; i = i + 9 - 8) + baz (i); +} + +template <typename T> +void +f4 (const std::vector<int>::const_iterator &x, + const std::vector<int>::const_iterator &y) +{ + std::vector<int>::const_iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x + 2000 - 64; i > y + 10; --i) + baz (i); +} + +void +f5 (const std::vector<int>::const_iterator &x, + const std::vector<int>::const_iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (std::vector<int>::const_iterator i = x + 2000 - 64; i > y + 10; i -= 10) + baz (i); +} + +template <int N> +void +f6 (const std::vector<int>::const_iterator &x, + const std::vector<int>::const_iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (std::vector<int>::const_iterator i = x + 2000 - 64; + i > y + 10; i = i - 12 + 2) + { + std::vector<int>::const_iterator j = i + N; + baz (j); + } +} + +template <int N> +void +f7 (std::vector<int>::const_iterator i, + const std::vector<int>::const_iterator &x, + const std::vector<int>::const_iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (i = x - 10; i <= y + 10; i += N) + baz (i); +} + +template <int N> +void +f8 (J<int> j) +{ + std::vector<int>::const_iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (i = j.begin (); i <= j.end () + N; i += 2) + baz (i); +} + +template <typename T, int N> +void +f9 (const typename std::vector<T>::const_iterator &x, + const typename std::vector<T>::const_iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (typename std::vector<T>::const_iterator i = x; i <= y; i = i + N) + baz (i); +} + +template <typename T, int N> +void +f10 (const typename std::vector<T>::const_iterator &x, + const typename std::vector<T>::const_iterator &y) +{ + typename std::vector<T>::const_iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (i = x; i > y; i = i + N) + baz (i); +} + +template <typename T> +void +f11 (const T &x, const T &y) +{ +#pragma omp parallel + { +#pragma omp single nowait +#pragma omp taskloop nogroup + for (T i = x; i <= y; i += 3) + baz (i); +#pragma omp single nowait + { + T j = y + 3; + baz (j); + } + } +} + +template <typename T> +void +f12 (const T &x, const T &y) +{ + T i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (i = x; i > y; --i) + baz (i); +} + +template <int N> +struct K +{ + template <typename T> + static void + f13 (const T &x, const T &y) + { +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (T i = x; i <= y + N; i += N) + baz (i); + } +}; + +std::vector<int>::const_iterator +f14 (const std::vector<int>::const_iterator &x, + const std::vector<int>::const_iterator &y) +{ + std::vector<int>::const_iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x; i < y - 1; i = 1 - 6 + 7 + i) + baz (i); + return i; +} + +template <typename T> +std::vector<int>::const_iterator +f15 (const std::vector<int>::const_iterator &x, + const std::vector<int>::const_iterator &y) +{ + std::vector<int>::const_iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x + 2000 - 64; i > y + 10; --i) + baz (i); + return i; +} + +template <int N> +std::vector<int>::const_iterator +f16 (std::vector<int>::const_iterator i, + const std::vector<int>::const_iterator &x, + const std::vector<int>::const_iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x - 10; i <= y + 10; i += N) + baz (i); + return i; +} + +template <int N> +std::vector<int>::const_iterator +f17 (J<int> j) +{ + static std::vector<int>::const_iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = j.begin (); i <= j.end () + N; i += 2) + baz (i); + return i; +} + +template <typename T, int N> +typename std::vector<T>::const_iterator +f18 (const typename std::vector<T>::const_iterator &x, + const typename std::vector<T>::const_iterator &y) +{ + static typename std::vector<T>::const_iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x; i > y; i = i + N) + baz (i); + return i; +} + +template <typename T> +T +f19 (const T &x, const T &y) +{ + T i; +#pragma omp parallel + { +#pragma omp single nowait +#pragma omp taskloop nogroup lastprivate(i) + for (i = x; i <= y; i += 3) + baz (i); +#pragma omp single nowait + { + T j = y + 3; + baz (j); + } + } + return i; +} + +template <typename T> +T +f20 (const T &x, const T &y) +{ + T i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x; i > y; --i) + baz (i); + return i; +} + +#define check(expr) \ + for (int i = 0; i < 2000; i++) \ + if (expr) \ + { \ + if (results[i] != 1) \ + std::abort (); \ + results[i] = 0; \ + } \ + else if (results[i]) \ + std::abort () + +int +main () +{ + std::vector<int> a(2000); + std::vector<long> b(2000); + for (int i = 0; i < 2000; i++) + { + a[i] = i; + b[i] = i; + } + f1 (a.begin () + 10, a.begin () + 1990); + check (i >= 10 && i <= 1990 && (i - 10) % 6 == 0); + f2 (a.begin () + 0, a.begin () + 1999); + check (i < 1998 && (i & 1) == 0); + f3<char> (a.begin () + 20, a.begin () + 1837); + check (i >= 20 && i <= 1837); + f4<int> (a.begin () + 0, a.begin () + 30); + check (i > 40 && i <= 2000 - 64); + f5 (a.begin () + 0, a.begin () + 100); + check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0); + f6<-10> (a.begin () + 10, a.begin () + 110); + check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0); + f7<6> (std::vector<int>::const_iterator (), a.begin () + 12, + a.begin () + 1800); + check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0); + f8<121> (J<int> (a.begin () + 14, a.begin () + 1803)); + check (i >= 14 && i <= 1924 && (i & 1) == 0); + f9<int, 7> (a.begin () + 33, a.begin () + 1967); + check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0); + f10<int, -7> (a.begin () + 1939, a.begin () + 17); + check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0); + f11<std::vector<int>::const_iterator > (a.begin () + 16, a.begin () + 1981); + check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0); + f12<std::vector<int>::const_iterator > (a.begin () + 1761, a.begin () + 37); + check (i > 37 && i <= 1761); + K<5>::f13<std::vector<int>::const_iterator > (a.begin () + 1, + a.begin () + 1935); + check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0); + if (f14 (a.begin () + 0, a.begin () + 1999) != a.begin () + 1998) + std::abort (); + check (i < 1998 && (i & 1) == 0); + if (f15<int> (a.begin () + 0, a.begin () + 30) != a.begin () + 40) + std::abort (); + check (i > 40 && i <= 2000 - 64); + if (f16<6> (std::vector<int>::const_iterator (), a.begin () + 12, + a.begin () + 1800) != a.begin () + 1814) + std::abort (); + check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0); + if (f17<121> (J<int> (a.begin () + 14, a.begin () + 1803)) != a.begin () + 1926) + std::abort (); + check (i >= 14 && i <= 1924 && (i & 1) == 0); + if (f18<int, -7> (a.begin () + 1939, a.begin () + 17) != a.begin () + 14) + std::abort (); + check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0); + if (f19<std::vector<int>::const_iterator > (a.begin () + 16, a.begin () + 1981) + != a.begin () + 1984) + std::abort (); + check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0); + if (f20<std::vector<int>::const_iterator > (a.begin () + 1761, a.begin () + 37) + != a.begin () + 37) + std::abort (); + check (i > 37 && i <= 1761); + f9<long, 7> (b.begin () + 33, b.begin () + 1967); + check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0); + f10<long, -7> (b.begin () + 1939, b.begin () + 17); + check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0); + f11<std::vector<long>::const_iterator > (b.begin () + 16, b.begin () + 1981); + check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0); + f12<std::vector<long>::const_iterator > (b.begin () + 1761, b.begin () + 37); + check (i > 37 && i <= 1761); + K<5>::f13<std::vector<long>::const_iterator > (b.begin () + 1, + b.begin () + 1935); + check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0); + if (f18<long, -7> (b.begin () + 1939, b.begin () + 17) != b.begin () + 14) + std::abort (); + check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0); + if (f19<std::vector<long>::const_iterator > (b.begin () + 16, b.begin () + 1981) + != b.begin () + 1984) + std::abort (); + check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0); + if (f20<std::vector<long>::const_iterator > (b.begin () + 1761, b.begin () + 37) + != b.begin () + 37) + std::abort (); + check (i > 37 && i <= 1761); +} --- libgomp/testsuite/libgomp.c++/taskloop-8.C.jj 2015-06-23 15:38:19.107160655 +0200 +++ libgomp/testsuite/libgomp.c++/taskloop-8.C 2015-06-23 15:40:44.694941712 +0200 @@ -0,0 +1,250 @@ +// { dg-do run } + +#include <string> +#include <cstdlib> + +template <typename T> +class J +{ +public: + typedef typename std::basic_string<T>::iterator iterator; + J(const iterator &x, const iterator &y) : b (x), e (y) {} + const iterator &begin (); + const iterator &end (); +private: + iterator b, e; +}; + +template <typename T> +const typename std::basic_string<T>::iterator &J<T>::begin () { return b; } +template <typename T> +const typename std::basic_string<T>::iterator &J<T>::end () { return e; } + +template <typename T> +void +baz (T &i) +{ + if (*i < L'a' || *i >= L'a' + 2000) + std::abort (); + (*i)++; +} + +void +f1 (const std::basic_string<wchar_t>::iterator &x, + const std::basic_string<wchar_t>::iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (std::basic_string<wchar_t>::iterator i = x; i <= y; i += 6) + baz (i); +} + +void +f2 (const std::basic_string<wchar_t>::iterator &x, + const std::basic_string<wchar_t>::iterator &y) +{ + std::basic_string<wchar_t>::iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop private(i) + for (i = x; i < y - 1; i = 1 - 6 + 7 + i) + baz (i); +} + +template <typename T> +void +f3 (const std::basic_string<wchar_t>::iterator &x, + const std::basic_string<wchar_t>::iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (std::basic_string<wchar_t>::iterator i = x; i <= y; i = i + 9 - 8) + baz (i); +} + +template <typename T> +void +f4 (const std::basic_string<wchar_t>::iterator &x, + const std::basic_string<wchar_t>::iterator &y) +{ + std::basic_string<wchar_t>::iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate(i) + for (i = x + 2000 - 64; i > y + 10; --i) + baz (i); +} + +void +f5 (const std::basic_string<wchar_t>::iterator &x, + const std::basic_string<wchar_t>::iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (std::basic_string<wchar_t>::iterator i = x + 2000 - 64; + i > y + 10; i -= 10) + baz (i); +} + +template <int N> +void +f6 (const std::basic_string<wchar_t>::iterator &x, + const std::basic_string<wchar_t>::iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (std::basic_string<wchar_t>::iterator i = x + 2000 - 64; + i > y + 10; i = i - 12 + 2) + { + std::basic_string<wchar_t>::iterator j = i + N; + baz (j); + } +} + +template <int N> +void +f7 (std::basic_string<wchar_t>::iterator i, + const std::basic_string<wchar_t>::iterator &x, + const std::basic_string<wchar_t>::iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (i = x - 10; i <= y + 10; i += N) + baz (i); +} + +template <wchar_t N> +void +f8 (J<wchar_t> j) +{ + std::basic_string<wchar_t>::iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (i = j.begin (); i <= j.end () + N; i += 2) + baz (i); +} + +template <typename T, int N> +void +f9 (const typename std::basic_string<T>::iterator &x, + const typename std::basic_string<T>::iterator &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (typename std::basic_string<T>::iterator i = x; i <= y; i = i + N) + baz (i); +} + +template <typename T, int N> +void +f10 (const typename std::basic_string<T>::iterator &x, + const typename std::basic_string<T>::iterator &y) +{ + typename std::basic_string<T>::iterator i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (i = x; i > y; i = i + N) + baz (i); +} + +template <typename T> +void +f11 (const T &x, const T &y) +{ +#pragma omp parallel + { +#pragma omp single nowait +#pragma omp taskloop nogroup + for (T i = x; i <= y; i += 3) + baz (i); +#pragma omp single nowait + { + T j = y + 3; + baz (j); + } + } +} + +template <typename T> +void +f12 (const T &x, const T &y) +{ + T i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop private(i) + for (i = x; i > y; --i) + baz (i); +} + +template <int N> +struct K +{ + template <typename T> + static void + f13 (const T &x, const T &y) + { +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (T i = x; i <= y + N; i += N) + baz (i); + } +}; + +#define check(expr) \ + for (int i = 0; i < 2000; i++) \ + if (expr) \ + { \ + if (a[i] != L'a' + i + 1) \ + std::abort (); \ + a[i] = L'a' + i; \ + } \ + else if (a[i] != L'a' + i) \ + std::abort () + +int +main () +{ + std::basic_string<wchar_t> a = L""; + for (int i = 0; i < 2000; i++) + a += L'a' + i; + f1 (a.begin () + 10, a.begin () + 1990); + check (i >= 10 && i <= 1990 && (i - 10) % 6 == 0); + f2 (a.begin () + 0, a.begin () + 1999); + check (i < 1998 && (i & 1) == 0); + f3<char> (a.begin () + 20, a.begin () + 1837); + check (i >= 20 && i <= 1837); + f4<int> (a.begin () + 0, a.begin () + 30); + check (i > 40 && i <= 2000 - 64); + f5 (a.begin () + 0, a.begin () + 100); + check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0); + f6<-10> (a.begin () + 10, a.begin () + 110); + check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0); + f7<6> (std::basic_string<wchar_t>::iterator (), a.begin () + 12, + a.begin () + 1800); + check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0); + f8<121> (J<wchar_t> (a.begin () + 14, a.begin () + 1803)); + check (i >= 14 && i <= 1924 && (i & 1) == 0); + f9<wchar_t, 7> (a.begin () + 33, a.begin () + 1967); + check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0); + f10<wchar_t, -7> (a.begin () + 1939, a.begin () + 17); + check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0); + f11<std::basic_string<wchar_t>::iterator > (a.begin () + 16, + a.begin () + 1981); + check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0); + f12<std::basic_string<wchar_t>::iterator > (a.begin () + 1761, + a.begin () + 37); + check (i > 37 && i <= 1761); + K<5>::f13<std::basic_string<wchar_t>::iterator > (a.begin () + 1, + a.begin () + 1935); + check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0); +} --- libgomp/testsuite/libgomp.c++/taskloop-9.C.jj 2015-06-23 15:41:50.575937601 +0200 +++ libgomp/testsuite/libgomp.c++/taskloop-9.C 2015-06-23 15:47:27.416900471 +0200 @@ -0,0 +1,323 @@ +// { dg-do run } + +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 () { p = (T *) 0; } +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) + abort (); + results[*i]++; +} + +I<int> +f1 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel shared (i) + { + #pragma omp single + #pragma omp taskloop lastprivate (i) + for (i = x; i < y - 1; ++i) + baz (i); + #pragma omp single + i += 3; + } + return I<int> (i); +} + +I<int> +f2 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate (i) + for (i = x; i < y - 1; i = 1 - 6 + 7 + i) + baz (i); + return I<int> (i); +} + +template <typename T> +I<int> +f3 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate (i) + for (i = x + 1000 - 64; i <= y - 10; i++) + baz (i); + return i; +} + +template <typename T> +I<int> +f4 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate (i) + for (i = x + 2000 - 64; i > y + 10; --i) + baz (i); + return I<int> (i); +} + +template <typename T> +I<int> +f5 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate (i) + for (i = x; i > y + T (6); i--) + baz (i); + return i; +} + +template <typename T> +I<int> +f6 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate (i) + for (i = x - T (7); i > y; i -= T (2)) + baz (i); + return I<int> (i); +} + +template <int N> +I<int> +f7 (I<int> i, const I<int> &x, const I<int> &y) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate (i) + for (i = x - 10; i <= y + 10; i += N) + baz (i); + return I<int> (i); +} + +template <int N> +I<int> +f8 (J<int> j) +{ + I<int> i; +#pragma omp parallel shared (i) + #pragma omp single + #pragma omp taskloop lastprivate (i) + for (i = j.begin (); i <= j.end () + N; i += 2) + baz (i); + return i; +} + +I<int> i9; + +template <long N> +I<int> & +f9 (J<int> j) +{ +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate (i9) + for (i9 = j.begin () + N; i9 <= j.end () - N; i9 = i9 - N) + baz (i9); + return i9; +} + +template <typename T, int N> +I<T> +f10 (const I<T> &x, const I<T> &y) +{ + I<T> i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate (i) + for (i = x; i > y; i = i + N) + baz (i); + return i; +} + +template <typename T, typename U> +T +f11 (T i, const T &x, const T &y) +{ +#pragma omp parallel + #pragma omp single + #pragma omp taskloop lastprivate (i) + for (i = x + U (2); i <= y + U (1); i = U (2) + U (3) + i) + baz (i); + return T (i); +} + +template <typename T> +T +f12 (const T &x, const T &y) +{ + T i; +#pragma omp parallel +#pragma omp single +#pragma omp taskloop lastprivate (i) + for (i = x; i > y; --i) + baz (i); + return i; +} + +#define check(expr) \ + for (int i = 0; i < 2000; i++) \ + if (expr) \ + { \ + if (results[i] != 1) \ + 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; + } + if (*f1 (&a[10], &a[1873]) != 1875) + abort (); + check (i >= 10 && i < 1872); + if (*f2 (&a[0], &a[1998]) != 1998) + abort (); + check (i < 1997 && (i & 1) == 0); + if (*f3<int> (&a[10], &a[1971]) != 1962) + abort (); + check (i >= 946 && i <= 1961); + if (*f4<int> (&a[0], &a[30]) != 40) + abort (); + check (i > 40 && i <= 2000 - 64); + if (*f5<short> (&a[1931], &a[17]) != 23) + abort (); + check (i > 23 && i <= 1931); + if (*f6<long> (&a[1931], &a[17]) != 16) + abort (); + check (i > 17 && i <= 1924 && (i & 1) == 0); + if (*f7<6> (I<int> (), &a[12], &a[1800]) != 1814) + abort (); + check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0); + if (*f8<121> (J<int> (&a[14], &a[1803])) != 1926) + abort (); + check (i >= 14 && i <= 1924 && (i & 1) == 0); + if (*f9<-3L> (J<int> (&a[27], &a[1761])) != 1767) + abort (); + check (i >= 24 && i <= 1764 && (i % 3) == 0); + if (*f10<int, -7> (&a[1939], &a[17]) != 14) + abort (); + check (i >= 21 && i <= 1939 && i % 7 == 0); + if (*f11<I<int>, short> (I<int> (), &a[71], &a[1941]) != 1943) + abort (); + check (i >= 73 && i <= 1938 && (i - 73) % 5 == 0); + if (*f12<I<int> > (&a[1761], &a[37]) != 37) + abort (); + check (i > 37 && i <= 1761); + if (*f10<long, -7> (&b[1939], &b[17]) != 14) + abort (); + check (i >= 21 && i <= 1939 && i % 7 == 0); + if (*f11<I<long>, short> (I<long> (), &b[71], &b[1941]) != 1943) + abort (); + check (i >= 73 && i <= 1938 && (i - 73) % 5 == 0); + if (*f12<I<long> > (&b[1761], &b[37]) != 37) + abort (); + check (i > 37 && i <= 1761); +} Jakub