+2018-10-25 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-builtins.def (BUILT_IN_GOMP_LOOP_NONMONOTONIC_RUNTIME_START,
+ BUILT_IN_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START,
+ BUILT_IN_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT,
+ BUILT_IN_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT,
+ BUILT_IN_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START,
+ BUILT_IN_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START,
+ BUILT_IN_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT,
+ BUILT_IN_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT,
+ BUILT_IN_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME,
+ BUILT_IN_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME): New builtins.
+ * omp-expand.c (expand_parallel_call, expand_omp_for): Emit
+ the GOMP_*nonmonotonic_runtime* or GOMP_*maybe_nonmonotonic_runtime*
+ builtins instead of GOMP_*runtime* if there is nonmonotonic modifier
+ or if there is no modifier and no ordered clause.
+
2018-10-23 Jakub Jelinek <jakub@redhat.com>
* builtin-types.def (BT_FN_UINT_OMPFN_PTR_UINT_UINT): New.
+2018-10-25 Jakub Jelinek <jakub@redhat.com>
+
+ * c-typeck.c (c_finish_omp_clauses): Don't diagnose nonmonotonic clause
+ with static, runtime or auto schedule kinds.
+
2018-10-18 Jakub Jelinek <jakub@redhat.com>
* c-parser.c (c_parser_omp_taskloop): Add forward declaration.
continue;
case OMP_CLAUSE_SCHEDULE:
- if (OMP_CLAUSE_SCHEDULE_KIND (c) & OMP_CLAUSE_SCHEDULE_NONMONOTONIC)
- {
- const char *p = NULL;
- switch (OMP_CLAUSE_SCHEDULE_KIND (c) & OMP_CLAUSE_SCHEDULE_MASK)
- {
- case OMP_CLAUSE_SCHEDULE_STATIC: p = "static"; break;
- case OMP_CLAUSE_SCHEDULE_DYNAMIC: break;
- case OMP_CLAUSE_SCHEDULE_GUIDED: break;
- case OMP_CLAUSE_SCHEDULE_AUTO: p = "auto"; break;
- case OMP_CLAUSE_SCHEDULE_RUNTIME: p = "runtime"; break;
- default: gcc_unreachable ();
- }
- if (p)
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "%<nonmonotonic%> modifier specified for %qs "
- "schedule kind", p);
- OMP_CLAUSE_SCHEDULE_KIND (c)
- = (enum omp_clause_schedule_kind)
- (OMP_CLAUSE_SCHEDULE_KIND (c)
- & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
- }
- }
schedule_clause = c;
pc = &OMP_CLAUSE_CHAIN (c);
continue;
+2018-10-25 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_clauses): Don't diagnose nonmonotonic clause
+ with static, runtime or auto schedule kinds.
+
2018-10-19 Jakub Jelinek <jakub@redhat.com>
* parser.c (cp_parser_omp_for_loop): Disallow ordered clause with
break;
case OMP_CLAUSE_SCHEDULE:
- if (OMP_CLAUSE_SCHEDULE_KIND (c) & OMP_CLAUSE_SCHEDULE_NONMONOTONIC)
- {
- const char *p = NULL;
- switch (OMP_CLAUSE_SCHEDULE_KIND (c) & OMP_CLAUSE_SCHEDULE_MASK)
- {
- case OMP_CLAUSE_SCHEDULE_STATIC: p = "static"; break;
- case OMP_CLAUSE_SCHEDULE_DYNAMIC: break;
- case OMP_CLAUSE_SCHEDULE_GUIDED: break;
- case OMP_CLAUSE_SCHEDULE_AUTO: p = "auto"; break;
- case OMP_CLAUSE_SCHEDULE_RUNTIME: p = "runtime"; break;
- default: gcc_unreachable ();
- }
- if (p)
- {
- error_at (OMP_CLAUSE_LOCATION (c),
- "%<nonmonotonic%> modifier specified for %qs "
- "schedule kind", p);
- OMP_CLAUSE_SCHEDULE_KIND (c)
- = (enum omp_clause_schedule_kind)
- (OMP_CLAUSE_SCHEDULE_KIND (c)
- & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
- }
- }
-
t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c);
if (t == NULL)
;
"GOMP_loop_nonmonotonic_guided_start",
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_NONMONOTONIC_RUNTIME_START,
+ "GOMP_loop_nonmonotonic_runtime_start",
+ BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
+ ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START,
+ "GOMP_loop_maybe_nonmonotonic_runtime_start",
+ BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
+ ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_STATIC_START,
"GOMP_loop_ordered_static_start",
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_NONMONOTONIC_GUIDED_NEXT,
"GOMP_loop_nonmonotonic_guided_next",
BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT,
+ "GOMP_loop_nonmonotonic_runtime_next",
+ BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT,
+ "GOMP_loop_maybe_nonmonotonic_runtime_next",
+ BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_STATIC_NEXT,
"GOMP_loop_ordered_static_next",
BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LEAF_LIST)
"GOMP_loop_ull_nonmonotonic_guided_start",
BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START,
+ "GOMP_loop_ull_nonmonotonic_runtime_start",
+ BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
+ ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START,
+ "GOMP_loop_ull_maybe_nonmonotonic_runtime_start",
+ BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
+ ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_STATIC_START,
"GOMP_loop_ull_ordered_static_start",
BT_FN_BOOL_BOOL_ULL_ULL_ULL_ULL_ULLPTR_ULLPTR,
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_NEXT,
"GOMP_loop_ull_nonmonotonic_guided_next",
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT,
+ "GOMP_loop_ull_nonmonotonic_runtime_next",
+ BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT,
+ "GOMP_loop_ull_maybe_nonmonotonic_runtime_next",
+ BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT,
"GOMP_loop_ull_ordered_static_next",
BT_FN_BOOL_ULONGLONGPTR_ULONGLONGPTR, ATTR_NOTHROW_LEAF_LIST)
"GOMP_parallel_loop_nonmonotonic_guided",
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME,
+ "GOMP_parallel_loop_nonmonotonic_runtime",
+ BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
+ ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME,
+ "GOMP_parallel_loop_maybe_nonmonotonic_runtime",
+ BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG_UINT,
+ ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_END, "GOMP_loop_end",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_END_CANCEL, "GOMP_loop_end_cancel",
switch (region->inner->sched_kind)
{
case OMP_CLAUSE_SCHEDULE_RUNTIME:
- start_ix2 = 3;
+ if ((region->inner->sched_modifiers
+ & OMP_CLAUSE_SCHEDULE_NONMONOTONIC) != 0)
+ start_ix2 = 6;
+ else if ((region->inner->sched_modifiers
+ & OMP_CLAUSE_SCHEDULE_MONOTONIC) == 0)
+ start_ix2 = 7;
+ else
+ start_ix2 = 3;
break;
case OMP_CLAUSE_SCHEDULE_DYNAMIC:
case OMP_CLAUSE_SCHEDULE_GUIDED:
if (fd.chunk_size == NULL
&& fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
fd.chunk_size = integer_zero_node;
- gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
switch (fd.sched_kind)
{
case OMP_CLAUSE_SCHEDULE_RUNTIME:
- fn_index = 3;
+ if ((fd.sched_modifiers & OMP_CLAUSE_SCHEDULE_NONMONOTONIC) != 0)
+ {
+ gcc_assert (!fd.have_ordered);
+ fn_index = 6;
+ }
+ else if ((fd.sched_modifiers & OMP_CLAUSE_SCHEDULE_MONOTONIC) == 0
+ && !fd.have_ordered)
+ fn_index = 7;
+ else
+ fn_index = 3;
break;
case OMP_CLAUSE_SCHEDULE_DYNAMIC:
case OMP_CLAUSE_SCHEDULE_GUIDED:
if ((fd.sched_modifiers & OMP_CLAUSE_SCHEDULE_MONOTONIC) == 0
- && !fd.ordered
&& !fd.have_ordered)
{
fn_index = 3 + fd.sched_kind;
break;
}
- /* FALLTHRU */
- default:
fn_index = fd.sched_kind;
break;
+ case OMP_CLAUSE_SCHEDULE_STATIC:
+ gcc_assert (fd.have_ordered);
+ fn_index = 0;
+ break;
+ default:
+ gcc_unreachable ();
}
if (!fd.ordered)
- fn_index += fd.have_ordered * 6;
+ fn_index += fd.have_ordered * 8;
if (fd.ordered)
start_ix = ((int)BUILT_IN_GOMP_LOOP_DOACROSS_STATIC_START) + fn_index;
else
+2018-10-25 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/gomp/for-6.C: Change expected library call.
+ * gcc.dg/gomp/for-6.c: Likewise.
+ * gcc.dg/gomp/combined-1.c: Moved to ...
+ * c-c++-common/gomp/combined-1.c: ... here. Adjust expected library
+ call.
+ * c-c++-common/gomp/combined-2.c: New test.
+ * c-c++-common/gomp/combined-3.c: New test.
+ * c-c++-common/gomp/for-6.c: New test.
+ * c-c++-common/gomp/for-7.c: New test.
+ * c-c++-common/gomp/schedule-modifiers-1.c (bar): Don't expect
+ diagnostics for nonmonotonic modifier with static, runtime or auto
+ schedule kinds.
+
2018-10-19 Jakub Jelinek <jakub@redhat.com>
* g++.dg/gomp/doacross-1.C: New test.
/* { dg-options "-O1 -fopenmp -fdump-tree-optimized" } */
int a[10];
-int foo (void)
+void foo (void)
{
int i;
#pragma omp parallel for schedule(runtime)
}
}
-/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_runtime" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_maybe_nonmonotonic_runtime" 3 "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O1 -fopenmp -fdump-tree-optimized" } */
+
+int a[10];
+void foo (void)
+{
+ int i;
+#pragma omp parallel for schedule(monotonic:runtime)
+ for (i = 0; i < 10; i++)
+ a[i] = i;
+#pragma omp parallel
+#pragma omp for schedule(monotonic :runtime)
+ for (i = 0; i < 10; i++)
+ a[i] = 10 - i;
+#pragma omp parallel
+ {
+#pragma omp for schedule(monotonic: runtime)
+ for (i = 0; i < 10; i++)
+ a[i] = i;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_runtime" 3 "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O1 -fopenmp -fdump-tree-optimized" } */
+
+int a[10];
+void foo (void)
+{
+ int i;
+#pragma omp parallel for schedule(nonmonotonic:runtime)
+ for (i = 0; i < 10; i++)
+ a[i] = i;
+#pragma omp parallel
+#pragma omp for schedule(nonmonotonic :runtime)
+ for (i = 0; i < 10; i++)
+ a[i] = 10 - i;
+#pragma omp parallel
+ {
+#pragma omp for schedule(nonmonotonic: runtime)
+ for (i = 0; i < 10; i++)
+ a[i] = i;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_nonmonotonic_runtime" 3 "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
+
+extern void bar(int);
+
+void foo (int n)
+{
+ int i;
+
+ #pragma omp for schedule(monotonic:runtime)
+ for (i = 0; i < n; ++i)
+ bar(i);
+}
+
+/* { dg-final { scan-tree-dump-times "GOMP_loop_runtime_start" 1 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_loop_runtime_next" 1 "ompexp" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
+
+extern void bar(int);
+
+void foo (int n)
+{
+ int i;
+
+ #pragma omp for schedule(nonmonotonic:runtime)
+ for (i = 0; i < n; ++i)
+ bar(i);
+}
+
+/* { dg-final { scan-tree-dump-times "GOMP_loop_nonmonotonic_runtime_start" 1 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_loop_nonmonotonic_runtime_next" 1 "ompexp" } } */
bar (void)
{
int i;
- #pragma omp for schedule (nonmonotonic: static, 2) /* { dg-error ".nonmonotonic. modifier specified for .static. schedule kind" } */
+ #pragma omp for schedule (nonmonotonic: static, 2)
for (i = 0; i < 64; i++)
;
- #pragma omp for schedule (nonmonotonic : static) /* { dg-error ".nonmonotonic. modifier specified for .static. schedule kind" } */
+ #pragma omp for schedule (nonmonotonic : static)
for (i = 0; i < 64; i++)
;
- #pragma omp for schedule (nonmonotonic : runtime) /* { dg-error ".nonmonotonic. modifier specified for .runtime. schedule kind" } */
+ #pragma omp for schedule (nonmonotonic : runtime)
for (i = 0; i < 64; i++)
;
- #pragma omp for schedule (nonmonotonic : auto) /* { dg-error ".nonmonotonic. modifier specified for .auto. schedule kind" } */
+ #pragma omp for schedule (nonmonotonic : auto)
for (i = 0; i < 64; i++)
;
- #pragma omp for schedule (nonmonotonic, dynamic) ordered /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+ #pragma omp for schedule (nonmonotonic : static) ordered /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
for (i = 0; i < 64; i++)
#pragma omp ordered
;
- #pragma omp for ordered schedule(nonmonotonic, dynamic, 5) /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+ #pragma omp for ordered schedule (nonmonotonic: static, 4) /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
for (i = 0; i < 64; i++)
#pragma omp ordered
;
- #pragma omp for schedule (nonmonotonic, guided) ordered(1) /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+ #pragma omp for schedule (nonmonotonic : dynamic) ordered /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+ for (i = 0; i < 64; i++)
+ #pragma omp ordered
+ ;
+ #pragma omp for ordered schedule(nonmonotonic : dynamic, 5) /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+ for (i = 0; i < 64; i++)
+ #pragma omp ordered
+ ;
+ #pragma omp for schedule (nonmonotonic : guided) ordered(1) /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
for (i = 0; i < 64; i++)
{
#pragma omp ordered depend(sink: i - 1)
#pragma omp ordered depend(source)
}
- #pragma omp for ordered(1) schedule(nonmonotonic, guided, 2) /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+ #pragma omp for ordered(1) schedule(nonmonotonic : guided, 2) /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp ordered depend(source)
+ #pragma omp ordered depend(sink: i - 1)
+ }
+ #pragma omp for schedule(nonmonotonic : runtime) ordered(1) /* { dg-error ".nonmonotonic. schedule modifier specified together with .ordered. clause" } */
for (i = 0; i < 64; i++)
{
#pragma omp ordered depend(source)
bar(i);
}
-/* { dg-final { scan-tree-dump-times "GOMP_loop_runtime_start" 1 "ompexp" } } */
-/* { dg-final { scan-tree-dump-times "GOMP_loop_runtime_next" 1 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_loop_maybe_nonmonotonic_runtime_start" 1 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_loop_maybe_nonmonotonic_runtime_next" 1 "ompexp" } } */
bar(i);
}
-/* { dg-final { scan-tree-dump-times "GOMP_loop_runtime_start" 1 "ompexp" } } */
-/* { dg-final { scan-tree-dump-times "GOMP_loop_runtime_next" 1 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_loop_maybe_nonmonotonic_runtime_start" 1 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_loop_maybe_nonmonotonic_runtime_next" 1 "ompexp" } } */
+2018-10-25 Jakub Jelinek <jakub@redhat.com>
+
+ * omp.h.in (enum omp_sched_t): Add omp_sched_monotonic.
+ * libgomp_g.h (GOMP_loop_nonmonotonic_runtime_start,
+ GOMP_loop_maybe_nonmonotonic_runtime_start,
+ GOMP_loop_nonmonotonic_runtime_next,
+ GOMP_loop_maybe_nonmonotonic_runtime_next,
+ GOMP_parallel_loop_nonmonotonic_runtime,
+ GOMP_parallel_loop_maybe_nonmonotonic_runtime,
+ GOMP_loop_ull_nonmonotonic_runtime_start,
+ GOMP_loop_ull_maybe_nonmonotonic_runtime_start,
+ GOMP_loop_ull_nonmonotonic_runtime_next,
+ GOMP_loop_ull_maybe_nonmonotonic_runtime_next): New prototypes.
+ * libgomp.h (enum gomp_schedule_type): Add GFS_MONOTONIC.
+ * libgomp.map (GOMP_5.0): Export
+ GOMP_loop_maybe_nonmonotonic_runtime_next,
+ GOMP_loop_maybe_nonmonotonic_runtime_start,
+ GOMP_loop_nonmonotonic_runtime_next,
+ GOMP_loop_nonmonotonic_runtime_start,
+ GOMP_loop_ull_maybe_nonmonotonic_runtime_next,
+ GOMP_loop_ull_maybe_nonmonotonic_runtime_start,
+ GOMP_loop_ull_nonmonotonic_runtime_next,
+ GOMP_loop_ull_nonmonotonic_runtime_start,
+ GOMP_parallel_loop_maybe_nonmonotonic_runtime,
+ GOMP_parallel_loop_nonmonotonic_runtime.
+ * env.c (parse_schedule): Parse monotonic and nonmonotonic modifiers
+ in OMP_SCHEDULE variable. Set GFS_MONOTONIC for monotonic schedules.
+ (handle_omp_display_env): Display monotonic/nonmonotonic schedule
+ modifiers. Display (non-default) chunk sizes.
+ * fortran.c (omp_get_schedule_, omp_get_schedule_8_): Mask off
+ GFS_MONOTONIC bit.
+ * icv.c (omp_set_schedule): Mask off omp_sched_monotonic bit in switch.
+ * loop.c (GOMP_loop_runtime_start, GOMP_loop_ordered_runtime_start,
+ GOMP_loop_doacross_runtime_start, GOMP_parallel_loop_runtime_start):
+ Mask off GFS_MONOTONIC bit.
+ (GOMP_loop_maybe_nonmonotonic_runtime_next,
+ GOMP_loop_maybe_nonmonotonic_runtime_start,
+ GOMP_loop_nonmonotonic_runtime_next,
+ GOMP_loop_nonmonotonic_runtime_start,
+ GOMP_parallel_loop_maybe_nonmonotonic_runtime,
+ GOMP_parallel_loop_nonmonotonic_runtime): New aliases or wrapper
+ functions.
+ * loop_ull.c (GOMP_loop_ull_runtime_start,
+ GOMP_loop_ull_ordered_runtime_start,
+ GOMP_loop_ull_doacross_runtime_start): Mask off GFS_MONOTONIC bit.
+ (GOMP_loop_ull_maybe_nonmonotonic_runtime_next,
+ GOMP_loop_ull_maybe_nonmonotonic_runtime_start,
+ GOMP_loop_ull_nonmonotonic_runtime_next,
+ GOMP_loop_ull_nonmonotonic_runtime_start): Likewise.
+
2018-10-23 Jakub Jelinek <jakub@redhat.com>
* libgomp.h (gomp_parallel_reduction_register): Declare.
{
char *env, *end;
unsigned long value;
+ int monotonic = 0;
env = getenv ("OMP_SCHEDULE");
if (env == NULL)
while (isspace ((unsigned char) *env))
++env;
+ if (strncasecmp (env, "monotonic", 9) == 0)
+ {
+ monotonic = 1;
+ env += 9;
+ }
+ else if (strncasecmp (env, "nonmonotonic", 12) == 0)
+ {
+ monotonic = -1;
+ env += 12;
+ }
+ if (monotonic)
+ {
+ while (isspace ((unsigned char) *env))
+ ++env;
+ if (*env != ':')
+ goto unknown;
+ ++env;
+ while (isspace ((unsigned char) *env))
+ ++env;
+ }
if (strncasecmp (env, "static", 6) == 0)
{
gomp_global_icv.run_sched_var = GFS_STATIC;
else
goto unknown;
+ if (monotonic == 1
+ || (monotonic == 0 && gomp_global_icv.run_sched_var == GFS_STATIC))
+ gomp_global_icv.run_sched_var |= GFS_MONOTONIC;
+
while (isspace ((unsigned char) *env))
++env;
if (*env == '\0')
{
gomp_global_icv.run_sched_chunk_size
- = gomp_global_icv.run_sched_var != GFS_STATIC;
+ = (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC) != GFS_STATIC;
return;
}
if (*env++ != ',')
if ((int)value != value)
goto invalid;
- if (value == 0 && gomp_global_icv.run_sched_var != GFS_STATIC)
+ if (value == 0
+ && (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC) != GFS_STATIC)
value = 1;
gomp_global_icv.run_sched_chunk_size = value;
return;
fputs ("'\n", stderr);
fprintf (stderr, " OMP_SCHEDULE = '");
- switch (gomp_global_icv.run_sched_var)
+ if ((gomp_global_icv.run_sched_var & GFS_MONOTONIC))
+ {
+ if (gomp_global_icv.run_sched_var != (GFS_MONOTONIC | GFS_STATIC))
+ fputs ("MONOTONIC:", stderr);
+ }
+ else if (gomp_global_icv.run_sched_var == GFS_STATIC)
+ fputs ("NONMONOTONIC:", stderr);
+ switch (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC)
{
case GFS_RUNTIME:
fputs ("RUNTIME", stderr);
+ if (gomp_global_icv.run_sched_chunk_size != 1)
+ fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
break;
case GFS_STATIC:
fputs ("STATIC", stderr);
+ if (gomp_global_icv.run_sched_chunk_size != 0)
+ fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
break;
case GFS_DYNAMIC:
fputs ("DYNAMIC", stderr);
+ if (gomp_global_icv.run_sched_chunk_size != 1)
+ fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
break;
case GFS_GUIDED:
fputs ("GUIDED", stderr);
+ if (gomp_global_icv.run_sched_chunk_size != 1)
+ fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
break;
case GFS_AUTO:
fputs ("AUTO", stderr);
omp_sched_t k;
int cs;
omp_get_schedule (&k, &cs);
- *kind = k;
+ /* For now mask off GFS_MONOTONIC, because OpenMP 4.5 code will not
+ expect to see it. */
+ *kind = k & ~GFS_MONOTONIC;
*chunk_size = cs;
}
omp_sched_t k;
int cs;
omp_get_schedule (&k, &cs);
- *kind = k;
+ /* See above. */
+ *kind = k & ~GFS_MONOTONIC;
*chunk_size = cs;
}
omp_set_schedule (omp_sched_t kind, int chunk_size)
{
struct gomp_task_icv *icv = gomp_icv (true);
- switch (kind)
+ switch (kind & ~omp_sched_monotonic)
{
case omp_sched_static:
if (chunk_size < 1)
GFS_STATIC,
GFS_DYNAMIC,
GFS_GUIDED,
- GFS_AUTO
+ GFS_AUTO,
+ GFS_MONOTONIC = 0x80000000U
};
struct gomp_doacross_work_share
GOMP_5.0 {
global:
+ GOMP_loop_maybe_nonmonotonic_runtime_next;
+ GOMP_loop_maybe_nonmonotonic_runtime_start;
+ GOMP_loop_nonmonotonic_runtime_next;
+ GOMP_loop_nonmonotonic_runtime_start;
+ GOMP_loop_ull_maybe_nonmonotonic_runtime_next;
+ GOMP_loop_ull_maybe_nonmonotonic_runtime_start;
+ GOMP_loop_ull_nonmonotonic_runtime_next;
+ GOMP_loop_ull_nonmonotonic_runtime_start;
+ GOMP_parallel_loop_maybe_nonmonotonic_runtime;
+ GOMP_parallel_loop_nonmonotonic_runtime;
GOMP_parallel_reductions;
GOMP_taskgroup_reduction_register;
GOMP_taskgroup_reduction_unregister;
long *, long *);
extern bool GOMP_loop_nonmonotonic_guided_start (long, long, long, long,
long *, long *);
+extern bool GOMP_loop_nonmonotonic_runtime_start (long, long, long,
+ long *, long *);
+extern bool GOMP_loop_maybe_nonmonotonic_runtime_start (long, long, long,
+ long *, long *);
extern bool GOMP_loop_ordered_static_start (long, long, long, long,
long *, long *);
extern bool GOMP_loop_runtime_next (long *, long *);
extern bool GOMP_loop_nonmonotonic_dynamic_next (long *, long *);
extern bool GOMP_loop_nonmonotonic_guided_next (long *, long *);
+extern bool GOMP_loop_nonmonotonic_runtime_next (long *, long *);
+extern bool GOMP_loop_maybe_nonmonotonic_runtime_next (long *, long *);
extern bool GOMP_loop_ordered_static_next (long *, long *);
extern bool GOMP_loop_ordered_dynamic_next (long *, long *);
extern void GOMP_parallel_loop_nonmonotonic_guided (void (*)(void *), void *,
unsigned, long, long,
long, long, unsigned);
+extern void GOMP_parallel_loop_nonmonotonic_runtime (void (*)(void *), void *,
+ unsigned, long, long,
+ long, unsigned);
+extern void GOMP_parallel_loop_maybe_nonmonotonic_runtime (void (*)(void *),
+ void *, unsigned,
+ long, long,
+ long, unsigned);
extern void GOMP_loop_end (void);
extern void GOMP_loop_end_nowait (void);
unsigned long long,
unsigned long long *,
unsigned long long *);
+extern bool GOMP_loop_ull_nonmonotonic_runtime_start (bool, unsigned long long,
+ unsigned long long,
+ unsigned long long,
+ unsigned long long *,
+ unsigned long long *);
+extern bool GOMP_loop_ull_maybe_nonmonotonic_runtime_start (bool,
+ unsigned long long,
+ unsigned long long,
+ unsigned long long,
+ unsigned long long *,
+ unsigned long long *);
extern bool GOMP_loop_ull_ordered_static_start (bool, unsigned long long,
unsigned long long,
unsigned long long *);
extern bool GOMP_loop_ull_nonmonotonic_guided_next (unsigned long long *,
unsigned long long *);
+extern bool GOMP_loop_ull_nonmonotonic_runtime_next (unsigned long long *,
+ unsigned long long *);
+extern bool GOMP_loop_ull_maybe_nonmonotonic_runtime_next (unsigned long long *,
+ unsigned long long *);
extern bool GOMP_loop_ull_ordered_static_next (unsigned long long *,
unsigned long long *);
}
/* The *_start routines are called when first encountering a loop construct
- that is not bound directly to a parallel construct. The first thread
+ that is not bound directly to a parallel construct. The first thread
that arrives will create the work-share construct; subsequent threads
will see the construct exists and allocate work from it.
START, END, INCR are the bounds of the loop; due to the restrictions of
- OpenMP, these values must be the same in every thread. This is not
+ OpenMP, these values must be the same in every thread. This is not
verified (nor is it entirely verifiable, since START is not necessarily
retained intact in the work-share data structure). CHUNK_SIZE is the
scheduling parameter; again this must be identical in all threads.
long *istart, long *iend)
{
struct gomp_task_icv *icv = gomp_icv (false);
- switch (icv->run_sched_var)
+ switch (icv->run_sched_var & ~GFS_MONOTONIC)
{
case GFS_STATIC:
return gomp_loop_static_start (start, end, incr,
long *istart, long *iend)
{
struct gomp_task_icv *icv = gomp_icv (false);
- switch (icv->run_sched_var)
+ switch (icv->run_sched_var & ~GFS_MONOTONIC)
{
case GFS_STATIC:
return gomp_loop_ordered_static_start (start, end, incr,
long *istart, long *iend)
{
struct gomp_task_icv *icv = gomp_icv (false);
- switch (icv->run_sched_var)
+ switch (icv->run_sched_var & ~GFS_MONOTONIC)
{
case GFS_STATIC:
return gomp_loop_doacross_static_start (ncounts, counts,
}
}
-/* The *_next routines are called when the thread completes processing of
- the iteration block currently assigned to it. If the work-share
+/* The *_next routines are called when the thread completes processing of
+ the iteration block currently assigned to it. If the work-share
construct is bound directly to a parallel construct, then the iteration
bounds may have been set up before the parallel. In which case, this
may be the first iteration for the thread.
GOMP_loop_runtime_next (long *istart, long *iend)
{
struct gomp_thread *thr = gomp_thread ();
-
+
switch (thr->ts.work_share->sched)
{
case GFS_STATIC:
GOMP_loop_ordered_runtime_next (long *istart, long *iend)
{
struct gomp_thread *thr = gomp_thread ();
-
+
switch (thr->ts.work_share->sched)
{
case GFS_STATIC:
{
struct gomp_task_icv *icv = gomp_icv (false);
gomp_parallel_loop_start (fn, data, num_threads, start, end, incr,
- icv->run_sched_var, icv->run_sched_chunk_size, 0);
+ icv->run_sched_var & ~GFS_MONOTONIC,
+ icv->run_sched_chunk_size, 0);
}
ialias_redirect (GOMP_parallel_end)
GOMP_parallel_end ();
}
+void
+GOMP_parallel_loop_runtime (void (*fn) (void *), void *data,
+ unsigned num_threads, long start, long end,
+ long incr, unsigned flags)
+{
+ struct gomp_task_icv *icv = gomp_icv (false);
+ gomp_parallel_loop_start (fn, data, num_threads, start, end, incr,
+ icv->run_sched_var & ~GFS_MONOTONIC,
+ icv->run_sched_chunk_size, flags);
+ fn (data);
+ GOMP_parallel_end ();
+}
+
#ifdef HAVE_ATTRIBUTE_ALIAS
extern __typeof(GOMP_parallel_loop_dynamic) GOMP_parallel_loop_nonmonotonic_dynamic
__attribute__((alias ("GOMP_parallel_loop_dynamic")));
extern __typeof(GOMP_parallel_loop_guided) GOMP_parallel_loop_nonmonotonic_guided
__attribute__((alias ("GOMP_parallel_loop_guided")));
+extern __typeof(GOMP_parallel_loop_runtime) GOMP_parallel_loop_nonmonotonic_runtime
+ __attribute__((alias ("GOMP_parallel_loop_runtime")));
+extern __typeof(GOMP_parallel_loop_runtime) GOMP_parallel_loop_maybe_nonmonotonic_runtime
+ __attribute__((alias ("GOMP_parallel_loop_runtime")));
#else
void
GOMP_parallel_loop_nonmonotonic_dynamic (void (*fn) (void *), void *data,
fn (data);
GOMP_parallel_end ();
}
-#endif
void
-GOMP_parallel_loop_runtime (void (*fn) (void *), void *data,
- unsigned num_threads, long start, long end,
- long incr, unsigned flags)
+GOMP_parallel_loop_nonmonotonic_runtime (void (*fn) (void *), void *data,
+ unsigned num_threads, long start,
+ long end, long incr, unsigned flags)
{
struct gomp_task_icv *icv = gomp_icv (false);
gomp_parallel_loop_start (fn, data, num_threads, start, end, incr,
- icv->run_sched_var, icv->run_sched_chunk_size,
- flags);
+ icv->run_sched_var & ~GFS_MONOTONIC,
+ icv->run_sched_chunk_size, flags);
fn (data);
GOMP_parallel_end ();
}
+void
+GOMP_parallel_loop_maybe_nonmonotonic_runtime (void (*fn) (void *), void *data,
+ unsigned num_threads, long start,
+ long end, long incr,
+ unsigned flags)
+{
+ struct gomp_task_icv *icv = gomp_icv (false);
+ gomp_parallel_loop_start (fn, data, num_threads, start, end, incr,
+ icv->run_sched_var & ~GFS_MONOTONIC,
+ icv->run_sched_chunk_size, flags);
+ fn (data);
+ GOMP_parallel_end ();
+}
+#endif
+
/* The GOMP_loop_end* routines are called after the thread is told that
all loop iterations are complete. The first two versions synchronize
all threads; the nowait version does not. */
__attribute__((alias ("gomp_loop_dynamic_start")));
extern __typeof(gomp_loop_guided_start) GOMP_loop_nonmonotonic_guided_start
__attribute__((alias ("gomp_loop_guided_start")));
+extern __typeof(GOMP_loop_runtime_start) GOMP_loop_nonmonotonic_runtime_start
+ __attribute__((alias ("GOMP_loop_runtime_start")));
+extern __typeof(GOMP_loop_runtime_start) GOMP_loop_maybe_nonmonotonic_runtime_start
+ __attribute__((alias ("GOMP_loop_runtime_start")));
extern __typeof(gomp_loop_ordered_static_start) GOMP_loop_ordered_static_start
__attribute__((alias ("gomp_loop_ordered_static_start")));
__attribute__((alias ("gomp_loop_dynamic_next")));
extern __typeof(gomp_loop_guided_next) GOMP_loop_nonmonotonic_guided_next
__attribute__((alias ("gomp_loop_guided_next")));
+extern __typeof(GOMP_loop_runtime_next) GOMP_loop_nonmonotonic_runtime_next
+ __attribute__((alias ("GOMP_loop_runtime_next")));
+extern __typeof(GOMP_loop_runtime_next) GOMP_loop_maybe_nonmonotonic_runtime_next
+ __attribute__((alias ("GOMP_loop_runtime_next")));
extern __typeof(gomp_loop_ordered_static_next) GOMP_loop_ordered_static_next
__attribute__((alias ("gomp_loop_ordered_static_next")));
return gomp_loop_guided_start (start, end, incr, chunk_size, istart, iend);
}
+bool
+GOMP_loop_nonmonotonic_runtime_start (long start, long end, long incr,
+ long *istart, long *iend)
+{
+ return GOMP_loop_runtime_start (start, end, incr, istart, iend);
+}
+
+bool
+GOMP_loop_maybe_nonmonotonic_runtime_start (long start, long end, long incr,
+ long *istart, long *iend)
+{
+ return GOMP_loop_runtime_start (start, end, incr, istart, iend);
+}
+
bool
GOMP_loop_ordered_static_start (long start, long end, long incr,
long chunk_size, long *istart, long *iend)
return gomp_loop_guided_next (istart, iend);
}
+bool
+GOMP_loop_nonmonotonic_runtime_next (long *istart, long *iend)
+{
+ return GOMP_loop_runtime_next (istart, iend);
+}
+
+bool
+GOMP_loop_maybe_nonmonotonic_runtime_next (long *istart, long *iend)
+{
+ return GOMP_loop_runtime_next (istart, iend);
+}
+
bool
GOMP_loop_ordered_static_next (long *istart, long *iend)
{
gomp_ull incr, gomp_ull *istart, gomp_ull *iend)
{
struct gomp_task_icv *icv = gomp_icv (false);
- switch (icv->run_sched_var)
+ switch (icv->run_sched_var & ~GFS_MONOTONIC)
{
case GFS_STATIC:
return gomp_loop_ull_static_start (up, start, end, incr,
gomp_ull *iend)
{
struct gomp_task_icv *icv = gomp_icv (false);
- switch (icv->run_sched_var)
+ switch (icv->run_sched_var & ~GFS_MONOTONIC)
{
case GFS_STATIC:
return gomp_loop_ull_ordered_static_start (up, start, end, incr,
gomp_ull *istart, gomp_ull *iend)
{
struct gomp_task_icv *icv = gomp_icv (false);
- switch (icv->run_sched_var)
+ switch (icv->run_sched_var & ~GFS_MONOTONIC)
{
case GFS_STATIC:
return gomp_loop_ull_doacross_static_start (ncounts, counts,
__attribute__((alias ("gomp_loop_ull_dynamic_start")));
extern __typeof(gomp_loop_ull_guided_start) GOMP_loop_ull_nonmonotonic_guided_start
__attribute__((alias ("gomp_loop_ull_guided_start")));
+extern __typeof(GOMP_loop_ull_runtime_start) GOMP_loop_ull_nonmonotonic_runtime_start
+ __attribute__((alias ("GOMP_loop_ull_runtime_start")));
+extern __typeof(GOMP_loop_ull_runtime_start) GOMP_loop_ull_maybe_nonmonotonic_runtime_start
+ __attribute__((alias ("GOMP_loop_ull_runtime_start")));
extern __typeof(gomp_loop_ull_ordered_static_start) GOMP_loop_ull_ordered_static_start
__attribute__((alias ("gomp_loop_ull_ordered_static_start")));
__attribute__((alias ("gomp_loop_ull_dynamic_next")));
extern __typeof(gomp_loop_ull_guided_next) GOMP_loop_ull_nonmonotonic_guided_next
__attribute__((alias ("gomp_loop_ull_guided_next")));
+extern __typeof(GOMP_loop_ull_runtime_next) GOMP_loop_ull_nonmonotonic_runtime_next
+ __attribute__((alias ("GOMP_loop_ull_runtime_next")));
+extern __typeof(GOMP_loop_ull_runtime_next) GOMP_loop_ull_maybe_nonmonotonic_runtime_next
+ __attribute__((alias ("GOMP_loop_ull_runtime_next")));
extern __typeof(gomp_loop_ull_ordered_static_next) GOMP_loop_ull_ordered_static_next
__attribute__((alias ("gomp_loop_ull_ordered_static_next")));
iend);
}
+bool
+GOMP_loop_ull_nonmonotonic_runtime_start (bool up, gomp_ull start,
+ gomp_ull end, gomp_ull incr,
+ gomp_ull *istart, gomp_ull *iend)
+{
+ return GOMP_loop_ull_runtime_start (up, start, end, incr, istart, iend);
+}
+
+bool
+GOMP_loop_ull_maybe_nonmonotonic_runtime_start (bool up, gomp_ull start,
+ gomp_ull end, gomp_ull incr,
+ gomp_ull *istart,
+ gomp_ull *iend)
+{
+ return GOMP_loop_ull_runtime_start (up, start, end, incr, istart, iend);
+}
+
bool
GOMP_loop_ull_ordered_static_start (bool up, gomp_ull start, gomp_ull end,
gomp_ull incr, gomp_ull chunk_size,
return gomp_loop_ull_guided_next (istart, iend);
}
+bool
+GOMP_loop_ull_nonmonotonic_runtime_next (gomp_ull *istart, gomp_ull *iend)
+{
+ return GOMP_loop_ull_runtime_next (istart, iend);
+}
+
+bool
+GOMP_loop_ull_maybe_nonmonotonic_runtime_next (gomp_ull *istart,
+ gomp_ull *iend)
+{
+ return GOMP_loop_ull_runtime_next (istart, iend);
+}
+
bool
GOMP_loop_ull_ordered_static_next (gomp_ull *istart, gomp_ull *iend)
{
omp_sched_static = 1,
omp_sched_dynamic = 2,
omp_sched_guided = 3,
- omp_sched_auto = 4
+ omp_sched_auto = 4,
+ omp_sched_monotonic = 0x80000000U
} omp_sched_t;
typedef enum omp_proc_bind_t