summaryrefslogtreecommitdiff
path: root/libgomp
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@gcc.gnu.org>2019-12-12 20:46:39 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2019-12-12 20:46:39 +0000
commit3a8c69ecd95f708f5d489d92ff12dfbe2a93b00b (patch)
tree1596316424f3ab3df4c378a866d87ddca07e342f /libgomp
parent3fceb4462a7484503f3048a2c402e7996c72cc7c (diff)
parentbdaf8be1b2e3514b8bbcdd1042136e7d91b3c3f3 (diff)
Merged latest trunk changes to ira-select.devel/ira-select
From-SVN: r279316
Diffstat (limited to 'libgomp')
-rw-r--r--libgomp/ChangeLog2286
-rw-r--r--libgomp/Makefile.am10
-rw-r--r--libgomp/Makefile.in628
-rw-r--r--libgomp/acc_prof.h252
-rw-r--r--libgomp/acinclude.m42
-rw-r--r--libgomp/aclocal.m4719
-rw-r--r--libgomp/affinity-fmt.c495
-rw-r--r--libgomp/affinity.c16
-rw-r--r--libgomp/alloc.c50
-rw-r--r--libgomp/atomic.c2
-rw-r--r--libgomp/barrier.c2
-rw-r--r--libgomp/config.h.in43
-rw-r--r--libgomp/config/accel/libgomp-plugin.c (renamed from libgomp/config/nvptx/libgomp-plugin.c)0
-rw-r--r--libgomp/config/accel/lock.c (renamed from libgomp/config/nvptx/lock.c)2
-rw-r--r--libgomp/config/accel/mutex.c (renamed from libgomp/config/nvptx/mutex.c)0
-rw-r--r--libgomp/config/accel/mutex.h (renamed from libgomp/config/nvptx/mutex.h)2
-rw-r--r--libgomp/config/accel/oacc-async.c (renamed from libgomp/config/nvptx/oacc-async.c)0
-rw-r--r--libgomp/config/accel/oacc-cuda.c (renamed from libgomp/config/nvptx/oacc-cuda.c)0
-rw-r--r--libgomp/config/accel/oacc-host.c (renamed from libgomp/config/nvptx/oacc-host.c)0
-rw-r--r--libgomp/config/accel/oacc-init.c (renamed from libgomp/config/nvptx/oacc-init.c)2
-rw-r--r--libgomp/config/accel/oacc-mem.c (renamed from libgomp/config/nvptx/oacc-mem.c)0
-rw-r--r--libgomp/config/accel/oacc-plugin.c (renamed from libgomp/config/nvptx/oacc-plugin.c)0
-rw-r--r--libgomp/config/accel/omp-lock.h (renamed from libgomp/config/nvptx/omp-lock.h)0
-rw-r--r--libgomp/config/accel/openacc.f90 (renamed from libgomp/config/nvptx/openacc.f90)3
-rw-r--r--libgomp/config/accel/pool.h (renamed from libgomp/config/nvptx/pool.h)2
-rw-r--r--libgomp/config/accel/proc.c (renamed from libgomp/config/nvptx/proc.c)2
-rw-r--r--libgomp/config/accel/ptrlock.c (renamed from libgomp/config/nvptx/ptrlock.c)0
-rw-r--r--libgomp/config/accel/ptrlock.h (renamed from libgomp/config/nvptx/ptrlock.h)2
-rw-r--r--libgomp/config/accel/sem.c (renamed from libgomp/config/nvptx/sem.c)0
-rw-r--r--libgomp/config/accel/sem.h (renamed from libgomp/config/nvptx/sem.h)2
-rw-r--r--libgomp/config/accel/thread-stacksize.h (renamed from libgomp/config/nvptx/thread-stacksize.h)2
-rw-r--r--libgomp/config/bsd/proc.c2
-rw-r--r--libgomp/config/darwin/plugin-suffix.h2
-rw-r--r--libgomp/config/darwin/thread-stacksize.h2
-rw-r--r--libgomp/config/gcn/affinity-fmt.c51
-rw-r--r--libgomp/config/gcn/bar.c232
-rw-r--r--libgomp/config/gcn/bar.h168
-rw-r--r--libgomp/config/gcn/doacross.h58
-rw-r--r--libgomp/config/gcn/icv-device.c72
-rw-r--r--libgomp/config/gcn/oacc-target.c31
-rw-r--r--libgomp/config/gcn/simple-bar.h61
-rw-r--r--libgomp/config/gcn/target.c67
-rw-r--r--libgomp/config/gcn/task.c39
-rw-r--r--libgomp/config/gcn/team.c214
-rw-r--r--libgomp/config/gcn/time.c52
-rw-r--r--libgomp/config/hpux/plugin-suffix.h2
-rw-r--r--libgomp/config/linux/affinity.c52
-rw-r--r--libgomp/config/linux/alpha/futex.h2
-rw-r--r--libgomp/config/linux/bar.c2
-rw-r--r--libgomp/config/linux/bar.h2
-rw-r--r--libgomp/config/linux/doacross.h2
-rw-r--r--libgomp/config/linux/futex.h2
-rw-r--r--libgomp/config/linux/ia64/futex.h6
-rw-r--r--libgomp/config/linux/lock.c2
-rw-r--r--libgomp/config/linux/mips/futex.h2
-rw-r--r--libgomp/config/linux/mutex.c2
-rw-r--r--libgomp/config/linux/mutex.h2
-rw-r--r--libgomp/config/linux/powerpc/futex.h2
-rw-r--r--libgomp/config/linux/proc.c2
-rw-r--r--libgomp/config/linux/proc.h2
-rw-r--r--libgomp/config/linux/ptrlock.c2
-rw-r--r--libgomp/config/linux/ptrlock.h2
-rw-r--r--libgomp/config/linux/s390/futex.h2
-rw-r--r--libgomp/config/linux/sem.c2
-rw-r--r--libgomp/config/linux/sem.h2
-rw-r--r--libgomp/config/linux/sparc/futex.h2
-rw-r--r--libgomp/config/linux/tile/futex.h2
-rw-r--r--libgomp/config/linux/wait.h2
-rw-r--r--libgomp/config/linux/x86/futex.h2
-rw-r--r--libgomp/config/mingw32/affinity-fmt.c68
-rw-r--r--libgomp/config/mingw32/proc.c2
-rw-r--r--libgomp/config/mingw32/time.c2
-rw-r--r--libgomp/config/nvptx/affinity-fmt.c51
-rw-r--r--libgomp/config/nvptx/bar.c2
-rw-r--r--libgomp/config/nvptx/bar.h2
-rw-r--r--libgomp/config/nvptx/doacross.h2
-rw-r--r--libgomp/config/nvptx/error.c2
-rw-r--r--libgomp/config/nvptx/icv-device.c18
-rw-r--r--libgomp/config/nvptx/oacc-parallel.c358
-rw-r--r--libgomp/config/nvptx/simple-bar.h2
-rw-r--r--libgomp/config/nvptx/target.c20
-rw-r--r--libgomp/config/nvptx/task.c2
-rw-r--r--libgomp/config/nvptx/team.c13
-rw-r--r--libgomp/config/nvptx/teams.c57
-rw-r--r--libgomp/config/nvptx/time.c2
-rw-r--r--libgomp/config/posix/bar.c2
-rw-r--r--libgomp/config/posix/bar.h2
-rw-r--r--libgomp/config/posix/doacross.h2
-rw-r--r--libgomp/config/posix/lock.c2
-rw-r--r--libgomp/config/posix/mutex.h2
-rw-r--r--libgomp/config/posix/plugin-suffix.h2
-rw-r--r--libgomp/config/posix/pool.h2
-rw-r--r--libgomp/config/posix/proc.c2
-rw-r--r--libgomp/config/posix/ptrlock.h2
-rw-r--r--libgomp/config/posix/sem.c2
-rw-r--r--libgomp/config/posix/sem.h2
-rw-r--r--libgomp/config/posix/simple-bar.h2
-rw-r--r--libgomp/config/posix/thread-stacksize.h2
-rw-r--r--libgomp/config/posix/time.c2
-rw-r--r--libgomp/config/rtems/affinity-fmt.c49
-rw-r--r--libgomp/config/rtems/bar.c185
-rw-r--r--libgomp/config/rtems/bar.h2
-rw-r--r--libgomp/config/rtems/mutex.h2
-rw-r--r--libgomp/config/rtems/pool.h2
-rw-r--r--libgomp/config/rtems/proc.c2
-rw-r--r--libgomp/config/rtems/sem.h2
-rwxr-xr-xlibgomp/configure2622
-rw-r--r--libgomp/configure.ac45
-rw-r--r--libgomp/configure.tgt8
-rw-r--r--libgomp/critical.c2
-rw-r--r--libgomp/env.c67
-rw-r--r--libgomp/error.c2
-rw-r--r--libgomp/fortran.c106
-rw-r--r--libgomp/hashtab.h2
-rw-r--r--libgomp/icv-device.c18
-rw-r--r--libgomp/icv.c4
-rw-r--r--libgomp/iter.c2
-rw-r--r--libgomp/iter_ull.c2
-rw-r--r--libgomp/libgomp-plugin.c2
-rw-r--r--libgomp/libgomp-plugin.h50
-rw-r--r--libgomp/libgomp.h268
-rw-r--r--libgomp/libgomp.map92
-rw-r--r--libgomp/libgomp.texi447
-rw-r--r--libgomp/libgomp_f.h.in2
-rw-r--r--libgomp/libgomp_g.h66
-rw-r--r--libgomp/lock.c2
-rw-r--r--libgomp/loop.c357
-rw-r--r--libgomp/loop_ull.c302
-rw-r--r--libgomp/oacc-async.c332
-rw-r--r--libgomp/oacc-cuda.c110
-rw-r--r--libgomp/oacc-host.c95
-rw-r--r--libgomp/oacc-init.c130
-rw-r--r--libgomp/oacc-int.h47
-rw-r--r--libgomp/oacc-mem.c297
-rw-r--r--libgomp/oacc-parallel.c608
-rw-r--r--libgomp/oacc-plugin.c28
-rw-r--r--libgomp/oacc-plugin.h9
-rw-r--r--libgomp/oacc-profiling.c662
-rw-r--r--libgomp/oacc-target.c1
-rw-r--r--libgomp/omp.h.in64
-rw-r--r--libgomp/omp_lib.f90.in53
-rw-r--r--libgomp/omp_lib.h.in17
-rw-r--r--libgomp/openacc.f90425
-rw-r--r--libgomp/openacc.h13
-rw-r--r--libgomp/openacc_lib.h158
-rw-r--r--libgomp/ordered.c66
-rw-r--r--libgomp/parallel.c53
-rw-r--r--libgomp/plugin/Makefrag.am16
-rw-r--r--libgomp/plugin/configfrag.ac133
-rw-r--r--libgomp/plugin/cuda-lib.def50
-rw-r--r--libgomp/plugin/cuda/cuda.h13
-rw-r--r--libgomp/plugin/hsa_ext_finalize.h2
-rw-r--r--libgomp/plugin/plugin-gcn.c4012
-rw-r--r--libgomp/plugin/plugin-hsa.c35
-rw-r--r--libgomp/plugin/plugin-nvptx.c1808
-rw-r--r--libgomp/priority_queue.c2
-rw-r--r--libgomp/priority_queue.h2
-rw-r--r--libgomp/sections.c85
-rw-r--r--libgomp/secure_getenv.h2
-rw-r--r--libgomp/single.c6
-rw-r--r--libgomp/splay-tree.c2
-rw-r--r--libgomp/splay-tree.h2
-rw-r--r--libgomp/target.c505
-rw-r--r--libgomp/task.c570
-rw-r--r--libgomp/taskloop.c57
-rw-r--r--libgomp/team.c160
-rw-r--r--libgomp/teams.c74
-rw-r--r--libgomp/testsuite/Makefile.am66
-rw-r--r--libgomp/testsuite/Makefile.in230
-rw-r--r--libgomp/testsuite/config/default.exp2
-rw-r--r--libgomp/testsuite/lib/libgomp.exp103
-rw-r--r--libgomp/testsuite/libgomp-test-support.exp.in1
-rw-r--r--libgomp/testsuite/libgomp.c++/depend-1.C31
-rw-r--r--libgomp/testsuite/libgomp.c++/depend-iterator-1.C167
-rw-r--r--libgomp/testsuite/libgomp.c++/depobj-1.C103
-rw-r--r--libgomp/testsuite/libgomp.c++/for-15.C14
-rw-r--r--libgomp/testsuite/libgomp.c++/for-16.C218
-rw-r--r--libgomp/testsuite/libgomp.c++/for-21.C291
-rw-r--r--libgomp/testsuite/libgomp.c++/for-22.C314
-rw-r--r--libgomp/testsuite/libgomp.c++/for-23.C416
-rw-r--r--libgomp/testsuite/libgomp.c++/for-24.C425
-rw-r--r--libgomp/testsuite/libgomp.c++/for-25.C420
-rw-r--r--libgomp/testsuite/libgomp.c++/for-26.C422
-rw-r--r--libgomp/testsuite/libgomp.c++/for-27.C169
-rw-r--r--libgomp/testsuite/libgomp.c++/lastprivate-conditional-1.C62
-rw-r--r--libgomp/testsuite/libgomp.c++/lastprivate-conditional-2.C104
-rw-r--r--libgomp/testsuite/libgomp.c++/loop-13.C298
-rw-r--r--libgomp/testsuite/libgomp.c++/loop-14.C301
-rw-r--r--libgomp/testsuite/libgomp.c++/loop-15.C417
-rw-r--r--libgomp/testsuite/libgomp.c++/pr88988.C28
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-1.C151
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-10.C120
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-11.C123
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-12.C154
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-13.C162
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-14.C124
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-15.C122
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-16.C154
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-2.C116
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-3.C119
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-4.C150
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-5.C158
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-6.C120
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-7.C118
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-8.C150
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-9.C155
-rw-r--r--libgomp/testsuite/libgomp.c++/target-22.C99
-rw-r--r--libgomp/testsuite/libgomp.c++/target-9.C43
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-1.C63
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-10.C125
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-11.C237
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-12.C321
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-13.C342
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-14.C72
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-15.C75
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-16.C130
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-17.C300
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-18.C325
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-19.C343
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-2.C119
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-3.C126
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-4.C238
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-5.C320
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-6.C341
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-7.C145
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-8.C70
-rw-r--r--libgomp/testsuite/libgomp.c++/task-reduction-9.C128
-rw-r--r--libgomp/testsuite/libgomp.c++/taskloop-reduction-1.C153
-rw-r--r--libgomp/testsuite/libgomp.c++/taskloop-reduction-2.C253
-rw-r--r--libgomp/testsuite/libgomp.c++/taskloop-reduction-3.C314
-rw-r--r--libgomp/testsuite/libgomp.c++/taskloop-reduction-4.C315
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/cancel-parallel-1.c42
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-3.c73
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c32
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/depend-iterator-1.c115
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/depend-iterator-2.c63
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-1.c28
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-2.c59
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/depobj-1.c99
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/display-affinity-1.c91
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-10.c4
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-11.c4
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-12.c4
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-13.c99
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-14.c110
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-15.c115
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-16.c114
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-2.h290
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-7.c4
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-8.c4
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/for-9.c4
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/function-not-offloaded-aux.c12
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/function-not-offloaded.c16
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-1.c144
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-10.c57
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-2.c171
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-3.c57
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-4.c161
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c143
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c159
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-7.c63
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-8.c60
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-9.c60
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/loop-1.c127
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c66
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/pause-1.c23
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/pause-2.c41
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/pr66199-10.c60
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/pr66199-11.c38
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/pr66199-12.c60
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/pr66199-13.c64
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/pr66199-14.c39
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/simd-1.c71
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-1.c58
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-11.c56
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-12.c67
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-13.c50
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-14.c51
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-2.c90
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-3.c218
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-4.c70
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-5.c65
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-6.c125
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-7.c216
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-8.c142
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/task-reduction-9.c217
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-1.c119
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-2.c212
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c45
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c65
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/taskwait-depend-1.c29
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/variable-not-offloaded.c19
-rw-r--r--libgomp/testsuite/libgomp.c/affinity-1.c2
-rw-r--r--libgomp/testsuite/libgomp.c/cancel-for-2.c6
-rw-r--r--libgomp/testsuite/libgomp.c/pr39591-1.c6
-rw-r--r--libgomp/testsuite/libgomp.c/pr39591-2.c6
-rw-r--r--libgomp/testsuite/libgomp.c/pr39591-3.c6
-rw-r--r--libgomp/testsuite/libgomp.c/pr86660.c28
-rw-r--r--libgomp/testsuite/libgomp.c/pr89002.c43
-rw-r--r--libgomp/testsuite/libgomp.c/pr90779.c18
-rw-r--r--libgomp/testsuite/libgomp.c/pr90811.c29
-rw-r--r--libgomp/testsuite/libgomp.c/private-1.c6
-rw-r--r--libgomp/testsuite/libgomp.c/scan-1.c115
-rw-r--r--libgomp/testsuite/libgomp.c/scan-10.c116
-rw-r--r--libgomp/testsuite/libgomp.c/scan-11.c119
-rw-r--r--libgomp/testsuite/libgomp.c/scan-12.c121
-rw-r--r--libgomp/testsuite/libgomp.c/scan-13.c92
-rw-r--r--libgomp/testsuite/libgomp.c/scan-14.c183
-rw-r--r--libgomp/testsuite/libgomp.c/scan-15.c119
-rw-r--r--libgomp/testsuite/libgomp.c/scan-16.c121
-rw-r--r--libgomp/testsuite/libgomp.c/scan-17.c90
-rw-r--r--libgomp/testsuite/libgomp.c/scan-18.c183
-rw-r--r--libgomp/testsuite/libgomp.c/scan-19.c120
-rw-r--r--libgomp/testsuite/libgomp.c/scan-2.c117
-rw-r--r--libgomp/testsuite/libgomp.c/scan-20.c120
-rw-r--r--libgomp/testsuite/libgomp.c/scan-21.c6
-rw-r--r--libgomp/testsuite/libgomp.c/scan-22.c6
-rw-r--r--libgomp/testsuite/libgomp.c/scan-3.c88
-rw-r--r--libgomp/testsuite/libgomp.c/scan-4.c179
-rw-r--r--libgomp/testsuite/libgomp.c/scan-5.c115
-rw-r--r--libgomp/testsuite/libgomp.c/scan-6.c117
-rw-r--r--libgomp/testsuite/libgomp.c/scan-7.c86
-rw-r--r--libgomp/testsuite/libgomp.c/scan-8.c179
-rw-r--r--libgomp/testsuite/libgomp.c/scan-9.c116
-rw-r--r--libgomp/testsuite/libgomp.c/sort-1.c2
-rw-r--r--libgomp/testsuite/libgomp.c/target-18.c30
-rw-r--r--libgomp/testsuite/libgomp.c/target-37.c71
-rw-r--r--libgomp/testsuite/libgomp.c/target-print-1.c17
-rw-r--r--libgomp/testsuite/libgomp.c/task-1.c6
-rw-r--r--libgomp/testsuite/libgomp.c/task-5.c24
-rw-r--r--libgomp/testsuite/libgomp.c/task-reduction-1.c137
-rw-r--r--libgomp/testsuite/libgomp.c/task-reduction-2.c86
-rw-r--r--libgomp/testsuite/libgomp.c/task-reduction-3.c60
-rw-r--r--libgomp/testsuite/libgomp.c/teams-1.c27
-rw-r--r--libgomp/testsuite/libgomp.c/teams-2.c123
-rw-r--r--libgomp/testsuite/libgomp.c/thread-limit-4.c57
-rw-r--r--libgomp/testsuite/libgomp.c/thread-limit-5.c11
-rw-r--r--libgomp/testsuite/libgomp.fortran/aligned1.f0310
-rw-r--r--libgomp/testsuite/libgomp.fortran/alloc-comp-1.f9020
-rw-r--r--libgomp/testsuite/libgomp.fortran/alloc-comp-2.f9036
-rw-r--r--libgomp/testsuite/libgomp.fortran/alloc-comp-3.f9042
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable1.f9020
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable10.f90136
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable11.f9072
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable12.f9062
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable2.f9010
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable3.f903
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable4.f9012
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable5.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable6.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable7.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable8.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable9.f90210
-rw-r--r--libgomp/testsuite/libgomp.fortran/appendix-a/a.28.5.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/associate1.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/associate2.f9016
-rw-r--r--libgomp/testsuite/libgomp.fortran/associate3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/async_io_1.f9048
-rw-r--r--libgomp/testsuite/libgomp.fortran/async_io_2.f9018
-rw-r--r--libgomp/testsuite/libgomp.fortran/async_io_3.f9016
-rw-r--r--libgomp/testsuite/libgomp.fortran/async_io_4.f9090
-rw-r--r--libgomp/testsuite/libgomp.fortran/async_io_5.f90132
-rw-r--r--libgomp/testsuite/libgomp.fortran/async_io_6.f9030
-rw-r--r--libgomp/testsuite/libgomp.fortran/async_io_7.f9022
-rw-r--r--libgomp/testsuite/libgomp.fortran/async_io_8.f9030
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-do-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-do-2.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-parallel-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-sections-1.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/cancel-taskgroup-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/character1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/character2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/collapse1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/collapse2.f906
-rw-r--r--libgomp/testsuite/libgomp.fortran/collapse3.f9024
-rw-r--r--libgomp/testsuite/libgomp.fortran/collapse4.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/crayptr1.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/crayptr2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/crayptr3.f906
-rw-r--r--libgomp/testsuite/libgomp.fortran/declare-simd-1.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/declare-simd-3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/declare-target-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/depend-1.f9034
-rw-r--r--libgomp/testsuite/libgomp.fortran/depend-2.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/depend-3.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/display-affinity-1.f9034
-rw-r--r--libgomp/testsuite/libgomp.fortran/do1.f9010
-rw-r--r--libgomp/testsuite/libgomp.fortran/do2.f9010
-rw-r--r--libgomp/testsuite/libgomp.fortran/do_concurrent_5.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/doacross1.f9036
-rw-r--r--libgomp/testsuite/libgomp.fortran/doacross2.f9048
-rw-r--r--libgomp/testsuite/libgomp.fortran/doacross3.f9048
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/array_sections-3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/array_sections-4.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/async_target-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/async_target-2.f906
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/declare_target-1.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/declare_target-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/declare_target-3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/declare_target-4.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/declare_target-5.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/device-1.f906
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/device-2.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/device-3.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/simd-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/simd-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/simd-3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/simd-4.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/simd-5.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/simd-6.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/simd-7.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/simd-8.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target-3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target-4.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target-5.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target_data-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target_data-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target_data-3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target_data-4.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target_data-5.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target_data-6.f906
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target_data-7.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target_update-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/target_update-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/task_dep-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/task_dep-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/task_dep-3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/task_dep-4.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/task_dep-5.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/teams-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/teams-3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/teams-4.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/teams-5.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/examples-4/teams-6.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/fortran.exp6
-rw-r--r--libgomp/testsuite/libgomp.fortran/lastprivate1.f9025
-rw-r--r--libgomp/testsuite/libgomp.fortran/lastprivate2.f9025
-rw-r--r--libgomp/testsuite/libgomp.fortran/lib1.f9044
-rw-r--r--libgomp/testsuite/libgomp.fortran/lib4.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/lock-1.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/lock-2.f906
-rw-r--r--libgomp/testsuite/libgomp.fortran/nested1.f9022
-rw-r--r--libgomp/testsuite/libgomp.fortran/nestedfn1.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/nestedfn2.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/nestedfn3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/nestedfn4.f909
-rw-r--r--libgomp/testsuite/libgomp.fortran/nestedfn5.f9014
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_atomic1.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_atomic2.f9012
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_atomic3.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_atomic4.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_atomic5.f9014
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_cond1.f6
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_cond2.f6
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_cond3.F906
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_cond4.F906
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_parse1.f9026
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_parse2.f9018
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_parse3.f9014
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_parse4.f9016
-rw-r--r--libgomp/testsuite/libgomp.fortran/openmp_version-1.f2
-rw-r--r--libgomp/testsuite/libgomp.fortran/openmp_version-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt-2.f952
-rw-r--r--libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt.f952
-rw-r--r--libgomp/testsuite/libgomp.fortran/pointer1.f9012
-rw-r--r--libgomp/testsuite/libgomp.fortran/pointer2.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr25219.f903
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr27395-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr27395-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr27416-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr27916-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr27916-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr28390.f3
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr29629.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr32550.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr33880.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr34020.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr35130.f903
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr42162.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr46753.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr48894.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr49792-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr49792-2.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr63938-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr63938-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr65597.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr66199-1.f9011
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr66199-2.f901
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr71014.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr81304.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr81841.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr84418-1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr84418-2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr88463-1.f9019
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr88463-2.f909
-rw-r--r--libgomp/testsuite/libgomp.fortran/pr90779.f9013
-rw-r--r--libgomp/testsuite/libgomp.fortran/procptr1.f9014
-rw-r--r--libgomp/testsuite/libgomp.fortran/recursion1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/reduction1.f9042
-rw-r--r--libgomp/testsuite/libgomp.fortran/reduction2.f9012
-rw-r--r--libgomp/testsuite/libgomp.fortran/reduction3.f9016
-rw-r--r--libgomp/testsuite/libgomp.fortran/reduction4.f9058
-rw-r--r--libgomp/testsuite/libgomp.fortran/reduction5.f9012
-rw-r--r--libgomp/testsuite/libgomp.fortran/reduction6.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/reference1.f906
-rw-r--r--libgomp/testsuite/libgomp.fortran/reference2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/retval1.f9028
-rw-r--r--libgomp/testsuite/libgomp.fortran/retval2.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/sharing1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/sharing2.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd1.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd2.f9036
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd3.f9036
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd4.f9036
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd5.f9024
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd6.f9024
-rw-r--r--libgomp/testsuite/libgomp.fortran/simd7.f90112
-rw-r--r--libgomp/testsuite/libgomp.fortran/stack.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/strassen.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/tabs1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/tabs2.f2
-rw-r--r--libgomp/testsuite/libgomp.fortran/target-allocatable-1-1.f9069
-rw-r--r--libgomp/testsuite/libgomp.fortran/target-allocatable-1-2.f9082
-rw-r--r--libgomp/testsuite/libgomp.fortran/target-print-1.f9015
-rw-r--r--libgomp/testsuite/libgomp.fortran/target-simd.f9026
-rw-r--r--libgomp/testsuite/libgomp.fortran/target1.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/target2.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/target3.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/target4.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/target5.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/target6.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/target7.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/target8.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/target9.f90124
-rw-r--r--libgomp/testsuite/libgomp.fortran/task1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/task2.f903
-rw-r--r--libgomp/testsuite/libgomp.fortran/task3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/task4.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/taskgroup1.f9013
-rw-r--r--libgomp/testsuite/libgomp.fortran/taskloop1.f903
-rw-r--r--libgomp/testsuite/libgomp.fortran/taskloop2.f9021
-rw-r--r--libgomp/testsuite/libgomp.fortran/taskloop3.f9015
-rw-r--r--libgomp/testsuite/libgomp.fortran/taskloop4.f9023
-rw-r--r--libgomp/testsuite/libgomp.fortran/threadprivate1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/threadprivate2.f9028
-rw-r--r--libgomp/testsuite/libgomp.fortran/threadprivate3.f9016
-rw-r--r--libgomp/testsuite/libgomp.fortran/threadprivate4.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr1.f9012
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr10.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr11.f908
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr12.f906
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr13.f9024
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr14.f9036
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr15.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr2.f9012
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr3.f9010
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr4.f9010
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr5.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr6.f906
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr7.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr8.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/udr9.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/use_device_addr-1.f901233
-rw-r--r--libgomp/testsuite/libgomp.fortran/use_device_addr-2.f901233
-rw-r--r--libgomp/testsuite/libgomp.fortran/use_device_addr-3.f90765
-rw-r--r--libgomp/testsuite/libgomp.fortran/use_device_addr-4.f90765
-rw-r--r--libgomp/testsuite/libgomp.fortran/use_device_ptr-1.f90597
-rw-r--r--libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-1.f9059
-rw-r--r--libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f9033
-rw-r--r--libgomp/testsuite/libgomp.fortran/vla1.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/vla2.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/vla3.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/vla4.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/vla5.f904
-rw-r--r--libgomp/testsuite/libgomp.fortran/vla6.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/vla7.f9016
-rw-r--r--libgomp/testsuite/libgomp.fortran/vla8.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/workshare1.f907
-rw-r--r--libgomp/testsuite/libgomp.fortran/workshare2.f9013
-rw-r--r--libgomp/testsuite/libgomp.graphite/force-parallel-5.c2
-rw-r--r--libgomp/testsuite/libgomp.graphite/graphite.exp2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/c++.exp31
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/firstprivate-mappings-1.C3
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/non-scalar-data.C3
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/pr71959-aux.cc35
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/pr71959.C31
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/routine-1-auto.C2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/routine-1-template-auto.C2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/routine-1-template-trailing-return-type.C2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/routine-1-template.C2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/routine-1-trailing-return-type.C2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/this.C43
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-dispatch-1.c353
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-init-1.c316
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c229
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-parallel-1.c719
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-valid_bytes-1.c226
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-version-1.c76
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/acc_set_cuda_stream-1.c42
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/async_queue-1.c127
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/asyncwait-nop-1.c75
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c28
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c35
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-2-lib.c131
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-2.c150
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-3.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-1.c20
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-2.c20
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-3.c20
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-4.c18
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-5.c18
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-6.c18
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-7.c18
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-8.c20
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/data-firstprivate-1.c165
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/declare-1.c98
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla.c47
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/firstprivate-mappings-1.c6
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/function-not-offloaded.c18
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/gang-reduction-var-assignment.c16
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/insufficient-resources.c21
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-20.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-22.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-23.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-30.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-69.c7
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-71.c122
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-74.c4
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-77.c138
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-79.c24
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-80.c135
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-84.c31
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-85.c27
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-94.c42
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/lib-95.c45
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/loop-default.h7
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/loop-dim-default.c7
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/mapping-1.c63
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/nvptx-merged-loop.c30
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/nvptx-sese-1.c35
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-1.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-2.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-3.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-4.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/parallel-dims.c85
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr84955-1.c31
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-2.c18
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-3.c35
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-4.c24
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-5.c24
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381.c18
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486-2.c52
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486-3.c54
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486.c51
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr87835.c61
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr88288.c41
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr88941.c15
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr88946.c15
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr89376.c15
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/pr90009.c34
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-1.c9
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-2.c9
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-3.c9
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-4.c9
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-5.c9
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/routine-1.c2
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/variable-not-offloaded.c17
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-1.c38
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-10.c39
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-2.c39
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-3.c42
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-4.c40
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-5.c41
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-6.c41
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-7.c40
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-1.c17
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-2.c21
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-3.c17
-rw-r--r--libgomp/testsuite/libgomp.oacc-c-c++-common/vred2d-128.c55
-rw-r--r--libgomp/testsuite/libgomp.oacc-c/c.exp31
-rw-r--r--libgomp/testsuite/libgomp.oacc-c/print-1.c17
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/abort-1.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/abort-2.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f2
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f2
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-1.f9068
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-2.f9081
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/allocatable-array-1.f9027
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/common-block-1.f90107
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/common-block-2.f90152
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/common-block-3.f90139
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-1.f90100
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-2.f904
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-5.f9012
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-already-1.f16
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-already-2.f16
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-already-3.f15
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-already-4.f14
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-already-5.f14
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-already-6.f14
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-already-7.f14
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/data-already-8.f16
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/dummy-array.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/fortran.exp31
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/gemm-2.f9080
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/gemm.f9079
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/host_data-2.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/host_data-3.f2
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/host_data-4.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction-2.f904
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction.f904
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-collapse-3.f904
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-collapse-4.f904
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-independent.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-loop-1.f904
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-map-1.f904
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-parallel-loop-data-enter-exit.f952
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-1.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-2.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-3.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-6.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-vector-1.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-vector-2.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-1.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-2.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-3.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-4.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-5.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-6.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-7.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/kernels-reduction-1.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-1.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-12.f9011
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-13.f9010
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-14.f9026
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-15.f9010
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-16-2.f9058
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-16.f9058
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-2.f2
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/lib-3.f2
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/map-1.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/parallel-dims-aux.c45
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/parallel-dims.f90120
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/parallel-loop-1.f904
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/pointer-align-1.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/pr68813.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/pr70289.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/pr70643.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/print-1.f9015
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/pset-1.f9026
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/reference-reductions.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/routine-7.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/subarrays-1.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/subarrays-2.f902
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/vector-routine.f902
-rw-r--r--libgomp/work.c48
759 files changed, 49303 insertions, 6860 deletions
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index baa675d61be..65478302ba8 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,2268 @@
+2019-11-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * testsuite/libgomp.c/pr39591-1.c: Rename err to e.
+ * testsuite/libgomp.c/pr39591-2.c: Likewise.
+ * testsuite/libgomp.c/pr39591-3.c: Likewise.
+ * testsuite/libgomp.c/private-1.c: Likewise.
+ * testsuite/libgomp.c/task-1.c: Likewise.
+ * testsuite/libgomp.c/task-5.c: Renamed err to serr.
+
+2019-11-20 Julian Brown <julian@codesourcery.com>
+
+ * plugin/plugin-gcn.c (wait_for_queue_nonfull): Don't lock/unlock
+ aq->mutex here.
+ (queue_push_launch): Lock aq->mutex before calling
+ wait_for_queue_nonfull.
+ (queue_push_callback): Likewise.
+ (queue_push_asyncwait): Likewise.
+ (queue_push_placeholder): Likewise.
+
+2019-11-20 Julian Brown <julian@codesourcery.com>
+
+ * plugin/plugin-gcn.c (hsa_memory_copy_wrapper): New.
+ (copy_data, GOMP_OFFLOAD_host2dev): Use above function.
+ (GOMP_OFFLOAD_dev2host, GOMP_OFFLOAD_dev2dev): Check hsa_memory_copy
+ return code.
+
+2019-11-20 Julian Brown <julian@codesourcery.com>
+
+ PR libgomp/92511
+
+ * oacc-mem.c (present_create_copy): Fix device pointer return value in
+ case of "present" subarray. Use tgt->tgt_start instead of tgt->to_free
+ in non-present/create case.
+ (delete_copyout): Change error condition to fail only on copies outside
+ of mapped block. Adjust error message accordingly.
+ * testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/lib-20.c: Adjust expected error
+ message.
+ * testsuite/libgomp.oacc-c-c++-common/lib-23.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/lib-22.c: Allow test to pass now.
+ * testsuite/libgomp.oacc-c-c++-common/lib-30.c: Likewise.
+
+2019-11-20 Maciej W. Rozycki <macro@wdc.com>
+
+ * testsuite/lib/libgomp.exp (libgomp_init): Add flags to find
+ libatomic in build-tree testing.
+
+2019-11-18 Maciej W. Rozycki <macro@wdc.com>
+
+ * testsuite/Makefile.in: Regenerate.
+
+2019-11-15 Andrew Stubbs <ams@codesourcery.com>
+
+ * testsuite/libgomp.c/target-print-1.c: New file.
+ * testsuite/libgomp.fortran/target-print-1.f90: New file.
+ * testsuite/libgomp.oacc-c/print-1.c: New file.
+ * testsuite/libgomp.oacc-fortran/print-1.f90: New file.
+
+2019-11-13 Andrew Stubbs <ams@codesourcery.com>
+ Kwok Cheung Yeung <kcy@codesourcery.com>
+ Julian Brown <julian@codesourcery.com>
+ Tom de Vries <tom@codesourcery.com>
+
+ * plugin/Makefrag.am: Add amdgcn plugin support.
+ * plugin/configfrag.ac: Likewise.
+ * plugin/plugin-gcn.c: New file.
+ * configure: Regenerate.
+ * Makefile.in: Regenerate.
+ * testsuite/Makefile.in: Regenerate.
+
+2019-11-13 Andrew Stubbs <ams@codesourcery.com>
+
+ * config/gcn/team.c (gomp_gcn_enter_kernel): Set up the team arena
+ and use team_malloc variants.
+ (gomp_gcn_exit_kernel): Use team_free.
+ * libgomp.h (TEAM_ARENA_SIZE): Define.
+ (TEAM_ARENA_START): Define.
+ (TEAM_ARENA_FREE): Define.
+ (TEAM_ARENA_END): Define.
+ (team_malloc): New function.
+ (team_malloc_cleared): New function.
+ (team_free): New function.
+ * team.c (gomp_new_team): Initialize and use team_malloc.
+ (free_team): Use team_free.
+ (gomp_free_thread): Use team_free.
+ (gomp_pause_host): Use team_free.
+ * work.c (gomp_init_work_share): Use team_malloc.
+ (gomp_fini_work_share): Use team_free.
+
+2019-11-13 Andrew Stubbs <ams@codesourcery.com>
+ Kwok Cheung Yeung <kcy@codesourcery.com>
+ Julian Brown <julian@codesourcery.com>
+ Tom de Vries <tom@codesourcery.com>
+
+ * Makefile.am (libgomp_la_SOURCES): Add oacc-target.c.
+ * Makefile.in: Regenerate.
+ * config.h.in (PLUGIN_GCN): Add new undef.
+ * config/accel/openacc.f90 (acc_device_gcn): New parameter.
+ * config/gcn/affinity-fmt.c: New file.
+ * config/gcn/bar.c: New file.
+ * config/gcn/bar.h: New file.
+ * config/gcn/doacross.h: New file.
+ * config/gcn/icv-device.c: New file.
+ * config/gcn/oacc-target.c: New file.
+ * config/gcn/simple-bar.h: New file.
+ * config/gcn/target.c: New file.
+ * config/gcn/task.c: New file.
+ * config/gcn/team.c: New file.
+ * config/gcn/time.c: New file.
+ * configure.ac: Add amdgcn*-*-*.
+ * configure: Regenerate.
+ * configure.tgt: Add amdgcn*-*-*.
+ * libgomp-plugin.h (offload_target_type): Add OFFLOAD_TARGET_TYPE_GCN.
+ * libgomp.h (gcn_thrs): Add amdgcn variant.
+ (set_gcn_thrs): Likewise.
+ (gomp_thread): Likewise.
+ * oacc-int.h (goacc_thread): Likewise.
+ * oacc-target.c: New file.
+ * openacc.f90 (acc_device_gcn): New parameter.
+ * openacc.h (acc_device_t): Add acc_device_gcn.
+ * team.c (gomp_free_pool_helper): Add amdgcn support.
+
+2019-11-13 Andrew Stubbs <ams@codesourcery.com>
+ Julian Brown <julian@codesourcery.com>
+
+ * libgomp-plugin.h (GOMP_OFFLOAD_openacc_async_construct): Add int
+ parameter.
+ * oacc-async.c (lookup_goacc_asyncqueue): Pass device number to the
+ queue constructor.
+ * oacc-host.c (host_openacc_async_construct): Add device parameter.
+ * plugin/plugin-nvptx.c (GOMP_OFFLOAD_openacc_async_construct): Add
+ device parameter.
+
+2019-11-13 Andrew Stubbs <ams@codesourcery.com>
+
+ * configure.tgt (nvptx*-*-*): Add "accel" directory.
+ * config/nvptx/libgomp-plugin.c: Move ...
+ * config/accel/libgomp-plugin.c: ... to here.
+ * config/nvptx/lock.c: Move ...
+ * config/accel/lock.c: ... to here.
+ * config/nvptx/mutex.c: Move ...
+ * config/accel/mutex.c: ... to here.
+ * config/nvptx/mutex.h: Move ...
+ * config/accel/mutex.h: ... to here.
+ * config/nvptx/oacc-async.c: Move ...
+ * config/accel/oacc-async.c: ... to here.
+ * config/nvptx/oacc-cuda.c: Move ...
+ * config/accel/oacc-cuda.c: ... to here.
+ * config/nvptx/oacc-host.c: Move ...
+ * config/accel/oacc-host.c: ... to here.
+ * config/nvptx/oacc-init.c: Move ...
+ * config/accel/oacc-init.c: ... to here.
+ * config/nvptx/oacc-mem.c: Move ...
+ * config/accel/oacc-mem.c: ... to here.
+ * config/nvptx/oacc-plugin.c: Move ...
+ * config/accel/oacc-plugin.c: ... to here.
+ * config/nvptx/omp-lock.h: Move ...
+ * config/accel/omp-lock.h: ... to here.
+ * config/nvptx/openacc.f90: Move ...
+ * config/accel/openacc.f90: ... to here.
+ * config/nvptx/pool.h: Move ...
+ * config/accel/pool.h: ... to here.
+ * config/nvptx/proc.c: Move ...
+ * config/accel/proc.c: ... to here.
+ * config/nvptx/ptrlock.c: Move ...
+ * config/accel/ptrlock.c: ... to here.
+ * config/nvptx/ptrlock.h: Move ...
+ * config/accel/ptrlock.h: ... to here.
+ * config/nvptx/sem.c: Move ...
+ * config/accel/sem.c: ... to here.
+ * config/nvptx/sem.h: Move ...
+ * config/accel/sem.h: ... to here.
+ * config/nvptx/thread-stacksize.h: Move ...
+ * config/accel/thread-stacksize.h: ... to here.
+
+2019-11-12 Maciej W. Rozycki <macro@codesourcery.com>
+ Tobias Burnus <tobias@codesourcery.com>
+ Frederik Harwath <frederik@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ libgomp/
+ * testsuite/libgomp.oacc-c-c++-common/parallel-dims.c: New test.
+ * testsuite/libgomp.oacc-fortran/parallel-dims-aux.c: New test.
+ * testsuite/libgomp.oacc-fortran/parallel-dims.f89: New test.
+
+2019-11-11 Tobias Burnus <tobias@codesourcery.com>
+ Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * testsuite/libgomp.fortran/use_device_ptr-optional-1.f90: Extend.
+ * testsuite/libgomp.fortran/use_device_ptr-optional-2.f90: New.
+
+2019-11-11 Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.fortran/target9.f90: Specify 'dg-do run'.
+
+ * testsuite/libgomp.fortran/use_device_addr-3.f90: Specify 'dg-do
+ run'.
+ * testsuite/libgomp.fortran/use_device_addr-4.f90: Likewise.
+ * testsuite/libgomp.fortran/use_device_ptr-1.f90: Likewise.
+
+2019-11-06 Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-1.c:
+ Add expected warnings about missing reduction clauses.
+ * testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-2.c:
+ Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-3.c:
+ Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-4.c:
+ Likewise.
+
+2019-11-04 Tobias Burnus <tobias@codesourcery.com>
+
+ * testsuite/libgomp.fortran/pr66199-1.f90: Remove
+ 'dg-do run' (implies torture test) as 'dg-options "O2"' is used.
+ * testsuite/libgomp.fortran/pr66199-2.f90: Ditto.
+ * testsuite/libgomp.fortran/taskloop2.f90: Ditto.
+ * testsuite/libgomp.fortran/taskloop3.f90: Ditto.
+ * testsuite/libgomp.fortran/taskloop4.f90: Ditto.
+
+2019-11-04 Tobias Burnus <tobias@codesourcery.com>
+
+ PR fortran/92305
+ * testsuite/libgomp.fortran/allocatable2.f90: Use
+ unique numbers with 'stop'.
+ * testsuite/libgomp.fortran/use_device_addr-1.f90: Ditto.
+ * testsuite/libgomp.fortran/use_device_addr-2.f90: Ditto.
+ * testsuite/libgomp.fortran/use_device_ptr-1.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/lib-15.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/pset-1.f90: Ditto.
+
+2019-11-01 Tobias Burnus <tobias@codesourcery.com>
+
+ * testsuite/libgomp.fortran/use_device_addr-1.f90 (test_nullptr_1,
+ test_dummy_opt_nullptr_callee_1): Add present but unallocated test.
+ * testsuite/libgomp.fortran/use_device_addr-2.f90: Likewise.
+ * testsuite/libgomp.fortran/use_device_addr-3.f90: New.
+ * testsuite/libgomp.fortran/use_device_addr-4.f90: New.
+ * testsuite/testsuite/libgomp.fortran/use_device_ptr-1.f90: New.
+
+2019-10-30 Tobias Burnus <tobias@codesourcery.com>
+
+ * testsuite/libgomp.fortran/target9.f90: New.
+
+2019-10-30 Tobias Burnus <tobias@codesourcery.com>
+
+ * testsuite/libgomp.fortran/aligned1.f03: Replace 'STOP' by 'stop'.
+ * testsuite/libgomp.fortran/alloc-comp-1.f90: Ditto.
+ * testsuite/libgomp.fortran/alloc-comp-2.f90: Ditto.
+ * testsuite/libgomp.fortran/alloc-comp-3.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable1.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable10.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable11.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable12.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable2.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable3.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable4.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable5.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable6.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable7.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable8.f90: Ditto.
+ * testsuite/libgomp.fortran/allocatable9.f90: Ditto.
+ * testsuite/libgomp.fortran/associate1.f90: Ditto.
+ * testsuite/libgomp.fortran/associate2.f90: Ditto.
+ * testsuite/libgomp.fortran/associate3.f90: Ditto.
+ * testsuite/libgomp.fortran/async_io_4.f90: Ditto.
+ * testsuite/libgomp.fortran/async_io_5.f90: Ditto.
+ * testsuite/libgomp.fortran/async_io_6.f90: Ditto.
+ * testsuite/libgomp.fortran/async_io_7.f90: Ditto.
+ * testsuite/libgomp.fortran/cancel-do-1.f90: Ditto.
+ * testsuite/libgomp.fortran/cancel-do-2.f90: Ditto.
+ * testsuite/libgomp.fortran/cancel-parallel-1.f90: Ditto.
+ * testsuite/libgomp.fortran/cancel-sections-1.f90: Ditto.
+ * testsuite/libgomp.fortran/cancel-taskgroup-2.f90: Ditto.
+ * testsuite/libgomp.fortran/character1.f90: Ditto.
+ * testsuite/libgomp.fortran/character2.f90: Ditto.
+ * testsuite/libgomp.fortran/collapse1.f90: Ditto.
+ * testsuite/libgomp.fortran/collapse2.f90: Ditto.
+ * testsuite/libgomp.fortran/collapse3.f90: Ditto.
+ * testsuite/libgomp.fortran/collapse4.f90: Ditto.
+ * testsuite/libgomp.fortran/crayptr1.f90: Ditto.
+ * testsuite/libgomp.fortran/crayptr2.f90: Ditto.
+ * testsuite/libgomp.fortran/crayptr3.f90: Ditto.
+ * testsuite/libgomp.fortran/declare-simd-1.f90: Ditto.
+ * testsuite/libgomp.fortran/declare-simd-3.f90: Ditto.
+ * testsuite/libgomp.fortran/declare-target-2.f90: Ditto.
+ * testsuite/libgomp.fortran/depend-1.f90: Ditto.
+ * testsuite/libgomp.fortran/depend-2.f90: Ditto.
+ * testsuite/libgomp.fortran/depend-3.f90: Ditto.
+ * testsuite/libgomp.fortran/do1.f90: Ditto.
+ * testsuite/libgomp.fortran/do2.f90: Ditto.
+ * testsuite/libgomp.fortran/do_concurrent_5.f90: Ditto.
+ * testsuite/libgomp.fortran/doacross1.f90: Ditto.
+ * testsuite/libgomp.fortran/doacross2.f90: Ditto.
+ * testsuite/libgomp.fortran/doacross3.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/array_sections-3.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/array_sections-4.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/async_target-1.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/async_target-2.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/declare_target-1.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/declare_target-2.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/declare_target-3.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/declare_target-4.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/declare_target-5.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/device-1.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/device-2.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/device-3.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/simd-1.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/simd-2.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/simd-3.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/simd-4.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/simd-5.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/simd-6.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/simd-7.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/simd-8.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target-1.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target-2.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target-3.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target-4.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target-5.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target_data-1.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target_data-2.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target_data-3.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target_data-4.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target_data-5.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target_data-6.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target_data-7.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target_update-1.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/target_update-2.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/task_dep-1.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/task_dep-2.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/task_dep-3.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/task_dep-4.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/task_dep-5.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/teams-2.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/teams-3.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/teams-4.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/teams-5.f90: Ditto.
+ * testsuite/libgomp.fortran/examples-4/teams-6.f90: Ditto.
+ * testsuite/libgomp.fortran/lastprivate1.f90: Ditto.
+ * testsuite/libgomp.fortran/lastprivate2.f90: Ditto.
+ * testsuite/libgomp.fortran/lib1.f90: Ditto.
+ * testsuite/libgomp.fortran/lib4.f90: Ditto.
+ * testsuite/libgomp.fortran/lock-1.f90: Ditto.
+ * testsuite/libgomp.fortran/lock-2.f90: Ditto.
+ * testsuite/libgomp.fortran/nested1.f90: Ditto.
+ * testsuite/libgomp.fortran/nestedfn1.f90: Ditto.
+ * testsuite/libgomp.fortran/nestedfn2.f90: Ditto.
+ * testsuite/libgomp.fortran/nestedfn3.f90: Ditto.
+ * testsuite/libgomp.fortran/nestedfn4.f90: Ditto.
+ * testsuite/libgomp.fortran/nestedfn5.f90: Ditto.
+ * testsuite/libgomp.fortran/omp_atomic1.f90: Ditto.
+ * testsuite/libgomp.fortran/omp_atomic2.f90: Ditto.
+ * testsuite/libgomp.fortran/omp_atomic3.f90: Ditto.
+ * testsuite/libgomp.fortran/omp_atomic4.f90: Ditto.
+ * testsuite/libgomp.fortran/omp_atomic5.f90: Ditto.
+ * testsuite/libgomp.fortran/omp_cond1.f: Ditto.
+ * testsuite/libgomp.fortran/omp_cond2.f: Ditto.
+ * testsuite/libgomp.fortran/omp_cond3.F90: Ditto.
+ * testsuite/libgomp.fortran/omp_cond4.F90: Ditto.
+ * testsuite/libgomp.fortran/omp_parse1.f90: Ditto.
+ * testsuite/libgomp.fortran/omp_parse2.f90: Ditto.
+ * testsuite/libgomp.fortran/omp_parse3.f90: Ditto.
+ * testsuite/libgomp.fortran/omp_parse4.f90: Ditto.
+ * testsuite/libgomp.fortran/openmp_version-1.f: Ditto.
+ * testsuite/libgomp.fortran/openmp_version-2.f90: Ditto.
+ * testsuite/libgomp.fortran/parloops-exit-first-loop-alt-2.f95: Ditto.
+ * testsuite/libgomp.fortran/parloops-exit-first-loop-alt.f95: Ditto.
+ * testsuite/libgomp.fortran/pointer1.f90: Ditto.
+ * testsuite/libgomp.fortran/pointer2.f90: Ditto.
+ * testsuite/libgomp.fortran/pr25219.f90: Ditto.
+ * testsuite/libgomp.fortran/pr27395-1.f90: Ditto.
+ * testsuite/libgomp.fortran/pr27395-2.f90: Ditto.
+ * testsuite/libgomp.fortran/pr27416-1.f90: Ditto.
+ * testsuite/libgomp.fortran/pr27916-1.f90: Ditto.
+ * testsuite/libgomp.fortran/pr27916-2.f90: Ditto.
+ * testsuite/libgomp.fortran/pr28390.f: Ditto.
+ * testsuite/libgomp.fortran/pr29629.f90: Ditto.
+ * testsuite/libgomp.fortran/pr32550.f90: Ditto.
+ * testsuite/libgomp.fortran/pr33880.f90: Ditto.
+ * testsuite/libgomp.fortran/pr34020.f90: Ditto.
+ * testsuite/libgomp.fortran/pr35130.f90: Ditto.
+ * testsuite/libgomp.fortran/pr42162.f90: Ditto.
+ * testsuite/libgomp.fortran/pr46753.f90: Ditto.
+ * testsuite/libgomp.fortran/pr48894.f90: Ditto.
+ * testsuite/libgomp.fortran/pr49792-1.f90: Ditto.
+ * testsuite/libgomp.fortran/pr49792-2.f90: Ditto.
+ * testsuite/libgomp.fortran/pr63938-1.f90: Ditto.
+ * testsuite/libgomp.fortran/pr63938-2.f90: Ditto.
+ * testsuite/libgomp.fortran/pr65597.f90: Ditto.
+ * testsuite/libgomp.fortran/pr66199-1.f90: Ditto.
+ * testsuite/libgomp.fortran/pr71014.f90: Ditto.
+ * testsuite/libgomp.fortran/pr81304.f90: Ditto.
+ * testsuite/libgomp.fortran/pr81841.f90: Ditto.
+ * testsuite/libgomp.fortran/pr84418-1.f90: Ditto.
+ * testsuite/libgomp.fortran/pr84418-2.f90: Ditto.
+ * testsuite/libgomp.fortran/procptr1.f90: Ditto.
+ * testsuite/libgomp.fortran/recursion1.f90: Ditto.
+ * testsuite/libgomp.fortran/reduction1.f90: Ditto.
+ * testsuite/libgomp.fortran/reduction2.f90: Ditto.
+ * testsuite/libgomp.fortran/reduction3.f90: Ditto.
+ * testsuite/libgomp.fortran/reduction4.f90: Ditto.
+ * testsuite/libgomp.fortran/reduction5.f90: Ditto.
+ * testsuite/libgomp.fortran/reduction6.f90: Ditto.
+ * testsuite/libgomp.fortran/reference1.f90: Ditto.
+ * testsuite/libgomp.fortran/reference2.f90: Ditto.
+ * testsuite/libgomp.fortran/retval1.f90: Ditto.
+ * testsuite/libgomp.fortran/retval2.f90: Ditto.
+ * testsuite/libgomp.fortran/sharing1.f90: Ditto.
+ * testsuite/libgomp.fortran/sharing2.f90: Ditto.
+ * testsuite/libgomp.fortran/simd1.f90: Ditto.
+ * testsuite/libgomp.fortran/simd2.f90: Ditto.
+ * testsuite/libgomp.fortran/simd3.f90: Ditto.
+ * testsuite/libgomp.fortran/simd4.f90: Ditto.
+ * testsuite/libgomp.fortran/simd5.f90: Ditto.
+ * testsuite/libgomp.fortran/simd6.f90: Ditto.
+ * testsuite/libgomp.fortran/simd7.f90: Ditto.
+ * testsuite/libgomp.fortran/stack.f90: Ditto.
+ * testsuite/libgomp.fortran/strassen.f90: Ditto.
+ * testsuite/libgomp.fortran/tabs1.f90: Ditto.
+ * testsuite/libgomp.fortran/tabs2.f: Ditto.
+ * testsuite/libgomp.fortran/target1.f90: Ditto.
+ * testsuite/libgomp.fortran/target2.f90: Ditto.
+ * testsuite/libgomp.fortran/target3.f90: Ditto.
+ * testsuite/libgomp.fortran/target4.f90: Ditto.
+ * testsuite/libgomp.fortran/target5.f90: Ditto.
+ * testsuite/libgomp.fortran/target6.f90: Ditto.
+ * testsuite/libgomp.fortran/target7.f90: Ditto.
+ * testsuite/libgomp.fortran/target8.f90: Ditto.
+ * testsuite/libgomp.fortran/task1.f90: Ditto.
+ * testsuite/libgomp.fortran/task2.f90: Ditto.
+ * testsuite/libgomp.fortran/task3.f90: Ditto.
+ * testsuite/libgomp.fortran/task4.f90: Ditto.
+ * testsuite/libgomp.fortran/taskgroup1.f90: Ditto.
+ * testsuite/libgomp.fortran/taskloop1.f90: Ditto.
+ * testsuite/libgomp.fortran/taskloop2.f90: Ditto.
+ * testsuite/libgomp.fortran/taskloop3.f90: Ditto.
+ * testsuite/libgomp.fortran/taskloop4.f90: Ditto.
+ * testsuite/libgomp.fortran/threadprivate1.f90: Ditto.
+ * testsuite/libgomp.fortran/threadprivate2.f90: Ditto.
+ * testsuite/libgomp.fortran/threadprivate3.f90: Ditto.
+ * testsuite/libgomp.fortran/threadprivate4.f90: Ditto.
+ * testsuite/libgomp.fortran/udr1.f90: Ditto.
+ * testsuite/libgomp.fortran/udr10.f90: Ditto.
+ * testsuite/libgomp.fortran/udr11.f90: Ditto.
+ * testsuite/libgomp.fortran/udr12.f90: Ditto.
+ * testsuite/libgomp.fortran/udr13.f90: Ditto.
+ * testsuite/libgomp.fortran/udr14.f90: Ditto.
+ * testsuite/libgomp.fortran/udr15.f90: Ditto.
+ * testsuite/libgomp.fortran/udr2.f90: Ditto.
+ * testsuite/libgomp.fortran/udr3.f90: Ditto.
+ * testsuite/libgomp.fortran/udr4.f90: Ditto.
+ * testsuite/libgomp.fortran/udr5.f90: Ditto.
+ * testsuite/libgomp.fortran/udr6.f90: Ditto.
+ * testsuite/libgomp.fortran/udr7.f90: Ditto.
+ * testsuite/libgomp.fortran/udr8.f90: Ditto.
+ * testsuite/libgomp.fortran/udr9.f90: Ditto.
+ * testsuite/libgomp.fortran/vla1.f90: Ditto.
+ * testsuite/libgomp.fortran/vla2.f90: Ditto.
+ * testsuite/libgomp.fortran/vla3.f90: Ditto.
+ * testsuite/libgomp.fortran/vla4.f90: Ditto.
+ * testsuite/libgomp.fortran/vla5.f90: Ditto.
+ * testsuite/libgomp.fortran/vla6.f90: Ditto.
+ * testsuite/libgomp.fortran/vla7.f90: Ditto.
+ * testsuite/libgomp.fortran/vla8.f90: Ditto.
+ * testsuite/libgomp.fortran/workshare1.f90: Ditto.
+ * testsuite/libgomp.fortran/workshare2.f90: Ditto.
+
+2019-10-30 Tobias Burnus <tobias@codesourcery.com>
+
+ * testsuite/libgomp.fortran/target-simd.f90: Use stop not abort.
+ * testsuite/libgomp.fortran/use_device_ptr-optional-1.f90:
+ Ditto; add 'dg-do run' for torture testing.
+ * testsuite/libgomp.fortran/lastprivate1.f90: Add 'dg-do run'.
+ * testsuite/libgomp.fortran/lastprivate2.f90: Ditto.
+ * testsuite/libgomp.fortran/nestedfn4.f90: Ditto.
+ * testsuite/libgomp.fortran/pr25219.f90: Ditto.
+ * testsuite/libgomp.fortran/pr28390.f: Ditto.
+ * testsuite/libgomp.fortran/pr35130.f90: Ditto.
+ * testsuite/libgomp.fortran/pr90779.f90: Ditto.
+ * testsuite/libgomp.fortran/task2.f90: Ditto.
+ * testsuite/libgomp.fortran/taskgroup1.f90: Ditto.
+ * testsuite/libgomp.fortran/taskloop1.f90: Ditto.
+ * testsuite/libgomp.fortran/use_device_addr-1.f90: Ditto.
+ * testsuite/libgomp.fortran/use_device_addr-2.f90: Ditto.
+ * testsuite/libgomp.fortran/workshare1.f90: Ditto.
+ * testsuite/libgomp.fortran/workshare2.f90: Ditto.
+
+2019-10-28 Tobias Burnus <tobias@codesourcery.com>
+
+ * testsuite/libgomp.oacc-fortran/abort-1.f90: Add 'dg-do run'.
+ * testsuite/libgomp.oacc-fortran/abort-2.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/lib-1.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/common-block-1.f90:
+ Use 'stop' not abort().
+ * testsuite/libgomp.oacc-fortran/common-block-2.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/common-block-3.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/data-1.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/data-2.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/data-5.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/dummy-array.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/gemm-2.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/gemm.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/host_data-2.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/host_data-3.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/host_data-4.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-collapse-3.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-collapse-4.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-independent.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-loop-1.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-map-1.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-parallel-loop-data-enter-exit.f95:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-1.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-2.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-3.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-6.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-vector-1.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-vector-2.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-worker-1.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-worker-2.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-worker-3.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-worker-4.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-worker-5.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-worker-6.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-private-vars-worker-7.f90:
+ Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-reduction-1.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/lib-12.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/lib-13.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/lib-14.f90: Ditto.
+ * testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction-2.f90:
+ Likewise and also add 'dg-do run'.
+ * testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction.f90:
+ Ditto.
+
+2019-10-25 Cesar Philippidis <cesar@codesourcery.com>
+ Tobias Burnus <tobias@codesourcery.com>
+
+ * testsuite/libgomp.oacc-fortran/common-block-1.f90: New test.
+ * testsuite/libgomp.oacc-fortran/common-block-2.f90: New test.
+ * testsuite/libgomp.oacc-fortran/common-block-3.f90: New test.
+
+2019-10-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/92081
+ * testsuite/libgomp.fortran/target-simd.f90: Iterate from 1 rather
+ than 0.
+
+2019-10-11 Tobias Burnus <tobias@codesourcery.com>
+
+ * testsuite/libgomp.fortran/use_device_addr-1.f90: New.
+ * testsuite/libgomp.fortran/use_device_addr-2.f90: New.
+
+2019-10-09 Thomas Schwinge <thomas@codesourcery.com>
+
+ PR middle-end/92036
+ * testsuite/libgomp.oacc-c-c++-common/data-firstprivate-1.c: New
+ file.
+
+2019-10-09 Tobias Burnus <tobias@codesourcery.com>
+
+ PR testsuite/91884
+ * testsuite/libgomp.fortran/fortran.exp: Conditionally
+ add -lquadmath.
+ * testsuite/libgomp.oacc-fortran/fortran.exp: Ditto.
+
+2019-10-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/92028
+ * target.c (gomp_map_vars_internal): Readd the previous
+ GOMP_MAP_USE_DEVICE_PTR handling code in the first loop,
+ though do that just in the !not_found_cnt case.
+
+2019-10-08 Tobias Burnus <tobias@codesourcery.com>
+
+ * gfortran.dg/gomp/target-simd.f90: New.
+
+2019-10-02 Julian Brown <julian@codesourcery.com>
+ Cesar Philippidis <cesar@codesourcery.com>
+
+ * libgomp.h (OFFSET_INLINED, OFFSET_POINTER, OFFSET_STRUCT): Define.
+ * target.c (FIELD_TGT_EMPTY): Define.
+ (gomp_map_val): Use OFFSET_* macros instead of magic constants. Write
+ as switch instead of list of ifs.
+ (gomp_map_vars_internal): Use OFFSET_* and FIELD_TGT_EMPTY macros.
+
+2019-10-02 Andreas Tobler <andreast@gcc.gnu.org>
+
+ * testsuite/libgomp.oacc-c-c++-common/loop-default.h: Remove alloca.h
+ include. Replace alloca () with __builtin_alloca ().
+ * testsuite/libgomp.oacc-c-c++-common/loop-dim-default.c: Likewise.
+
+2019-10-01 Jakub Jelinek <jakub@redhat.com>
+
+ * configure.ac: Remove GCC_HEADER_STDINT(gstdint.h).
+ * libgomp.h: Include <stdint.h> instead of "gstdint.h".
+ * oacc-parallel.c: Don't include "libgomp_g.h".
+ * plugin/plugin-hsa.c: Include <stdint.h> instead of "gstdint.h".
+ * plugin/plugin-nvptx.c: Don't include "gstdint.h".
+ * aclocal.m4: Regenerated.
+ * config.h.in: Regenerated.
+ * configure: Regenerated.
+ * Makefile.in: Regenerated.
+
+2019-09-30 Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * libgomp_g.h: Include stdint.h instead of gstdint.h.
+
+2019-09-27 Maciej W. Rozycki <macro@wdc.com>
+
+ * configure: Regenerate.
+
+2019-09-13 Tobias Burnus <tobias@codesourcery.com>
+
+ * plugin/plugin-hsa.c (hsa_warn, hsa_fatal, hsa_error): Ensure
+ string is initialized.
+
+2019-09-06 Florian Weimer <fweimer@redhat.com>
+
+ * configure: Regenerate.
+
+2019-09-03 Chung-Lin Tang <cltang@codesourcery.com>
+
+ PR other/79543
+ * acinclude.m4 (LIBGOMP_CHECK_LINKER_FEATURES): Fix GNU ld --version
+ scanning to conform to the GNU Coding Standards.
+ * configure: Regenerate.
+
+2019-08-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/91530
+ * testsuite/libgomp.c/scan-21.c: New test.
+ * testsuite/libgomp.c/scan-22.c: New test.
+
+2019-08-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/91530
+ * testsuite/libgomp.c/scan-11.c: Add -msse2 option for sse2_runtime
+ targets.
+ * testsuite/libgomp.c/scan-12.c: Likewise.
+ * testsuite/libgomp.c/scan-13.c: Likewise.
+ * testsuite/libgomp.c/scan-14.c: Likewise.
+ * testsuite/libgomp.c/scan-15.c: Likewise.
+ * testsuite/libgomp.c/scan-16.c: Likewise.
+ * testsuite/libgomp.c/scan-17.c: Likewise.
+ * testsuite/libgomp.c/scan-18.c: Likewise.
+ * testsuite/libgomp.c/scan-19.c: Likewise.
+ * testsuite/libgomp.c/scan-20.c: Likewise.
+ * testsuite/libgomp.c++/scan-9.C: Likewise.
+ * testsuite/libgomp.c++/scan-10.C: Likewise.
+ * testsuite/libgomp.c++/scan-11.C: Likewise.
+ * testsuite/libgomp.c++/scan-12.C: Likewise.
+ * testsuite/libgomp.c++/scan-14.C: Likewise.
+ * testsuite/libgomp.c++/scan-15.C: Likewise.
+ * testsuite/libgomp.c++/scan-13.C: Likewise. Use sse2_runtime
+ instead of i?86-*-* x86_64-*-* as target for scan-tree-dump-times.
+ * testsuite/libgomp.c++/scan-16.C: Likewise.
+
+2019-08-17 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/91473
+ * testsuite/libgomp.fortran/appendix-a/a.28.5.f90: Add
+ -std=legacy so invalid code in the test case is accepted.
+
+2019-08-12 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/91422
+ * testsuite/libgomp.oacc-fortran/routine-7.f90: Correct array
+ dimension.
+
+2019-08-08 Jakub Jelinek <jakub@redhat.com>
+
+ * target.c (gomp_map_vars_internal): For GOMP_MAP_USE_DEVICE_PTR
+ perform the lookup in the first loop only if !not_found_cnt, otherwise
+ perform lookups for it in the second loop guarded with
+ if (not_found_cnt || has_firstprivate).
+ * testsuite/libgomp.c/target-37.c: New test.
+ * testsuite/libgomp.c++/target-22.C: New test.
+
+2019-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c/target-18.c (struct S): New type.
+ (foo): Use use_device_addr clause instead of use_device_ptr clause
+ where required by OpenMP 5.0, add further tests for both use_device_ptr
+ and use_device_addr clauses.
+ * testsuite/libgomp.c++/target-9.C (struct S): New type.
+ (foo): Use use_device_addr clause instead of use_device_ptr clause
+ where required by OpenMP 5.0, add further tests for both use_device_ptr
+ and use_device_addr clauses. Add t and u arguments.
+ (main): Adjust caller.
+
+2019-08-06 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c++/loop-13.C: New test.
+ * testsuite/libgomp.c++/loop-14.C: New test.
+ * testsuite/libgomp.c++/loop-15.C: New test.
+
+2019-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/91301
+ * testsuite/libgomp.c++/for-27.C: New test.
+
+2019-07-23 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * testsuite/libgomp.fortran/reduction4.f90: Update BOZ usage.
+ * testsuite/libgomp.fortran/reduction5.f90: Ditto.
+
+2019-07-20 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c-c++-common/loop-1.c: New test.
+
+2019-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c++/scan-13.C: Replace xfail with target x86.
+ * testsuite/libgomp.c++/scan-16.C: Likewise.
+
+2019-07-06 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c/scan-19.c: New test.
+ * testsuite/libgomp.c/scan-20.c: New test.
+
+ * testsuite/libgomp.c/scan-11.c: New test.
+ * testsuite/libgomp.c/scan-12.c: New test.
+ * testsuite/libgomp.c/scan-13.c: New test.
+ * testsuite/libgomp.c/scan-14.c: New test.
+ * testsuite/libgomp.c/scan-15.c: New test.
+ * testsuite/libgomp.c/scan-16.c: New test.
+ * testsuite/libgomp.c/scan-17.c: New test.
+ * testsuite/libgomp.c/scan-18.c: New test.
+ * testsuite/libgomp.c++/scan-9.C: New test.
+ * testsuite/libgomp.c++/scan-10.C: New test.
+ * testsuite/libgomp.c++/scan-11.C: New test.
+ * testsuite/libgomp.c++/scan-12.C: New test.
+ * testsuite/libgomp.c++/scan-13.C: New test.
+ * testsuite/libgomp.c++/scan-14.C: New test.
+ * testsuite/libgomp.c++/scan-15.C: New test.
+ * testsuite/libgomp.c++/scan-16.C: New test.
+
+2019-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c/scan-9.c: New test.
+ * testsuite/libgomp.c/scan-10.c: New test.
+
+2019-07-03 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c++/scan-1.C: New test.
+ * testsuite/libgomp.c++/scan-2.C: New test.
+ * testsuite/libgomp.c++/scan-3.C: New test.
+ * testsuite/libgomp.c++/scan-4.C: New test.
+ * testsuite/libgomp.c++/scan-5.C: New test.
+ * testsuite/libgomp.c++/scan-6.C: New test.
+ * testsuite/libgomp.c++/scan-7.C: New test.
+ * testsuite/libgomp.c++/scan-8.C: New test.
+ * testsuite/libgomp.c/scan-1.c: New test.
+ * testsuite/libgomp.c/scan-2.c: New test.
+ * testsuite/libgomp.c/scan-3.c: New test.
+ * testsuite/libgomp.c/scan-4.c: New test.
+ * testsuite/libgomp.c/scan-5.c: New test.
+ * testsuite/libgomp.c/scan-6.c: New test.
+ * testsuite/libgomp.c/scan-7.c: New test.
+ * testsuite/libgomp.c/scan-8.c: New test.
+
+2019-06-18 Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c++/firstprivate-mappings-1.C: New file.
+ * testsuite/libgomp.oacc-c-c++-common/firstprivate-mappings-1.c:
+ Likewise.
+
+ * testsuite/libgomp.fortran/allocatable3.f90: Add missing results
+ check.
+
+2019-06-18 Cesar Philippidis <cesar@codesourcery.com>
+
+ * testsuite/libgomp.oacc-fortran/allocatable-array-1.f90: New
+ file.
+
+2019-06-18 Thomas Schwinge <thomas@codesourcery.com>
+
+ PR fortran/90743
+ * oacc-parallel.c (GOACC_parallel_keyed): Handle NULL mapping
+ case.
+ * testsuite/libgomp.fortran/target-allocatable-1-1.f90: New file.
+ * testsuite/libgomp.fortran/target-allocatable-1-2.f90: Likewise.
+ * testsuite/libgomp.oacc-fortran/allocatable-1-1.f90: Likewise.
+ * testsuite/libgomp.oacc-fortran/allocatable-1-2.f90: Likewise.
+
+ PR testsuite/90861
+ * testsuite/libgomp.oacc-c-c++-common/declare-vla.c: Update.
+
+ PR middle-end/90862
+ * testsuite/libgomp.oacc-c-c++-common/declare-1.c: Update.
+
+2019-06-16 Tom de Vries <tdevries@suse.de>
+
+ PR tree-optimization/89376
+ * testsuite/libgomp.oacc-c-c++-common/pr89376.c: New test.
+
+2019-06-15 Tom de Vries <tdevries@suse.de>
+
+ PR tree-optimization/89713
+ * testsuite/libgomp.oacc-c-c++-common/pr85381-2.c: Expect no bar.sync.
+ * testsuite/libgomp.oacc-c-c++-common/pr85381-4.c: Same.
+
+2019-06-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/90779
+ * testsuite/libgomp.c/pr90779.c: New test.
+ * testsuite/libgomp.fortran/pr90779.f90: New test.
+
+2019-06-15 Tom de Vries <tdevries@suse.de>
+
+ PR tree-optimization/90009
+ * testsuite/libgomp.oacc-c-c++-common/pr90009.c: New test.
+
+2019-06-13 Feng Xue <fxue@os.amperecomputing.com>
+
+ PR tree-optimization/89713
+ * testsuite/libgomp.oacc-c-c++-common/pr84955-1.c: New test.
+
+2019-06-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/90811
+ * testsuite/libgomp.c/pr90811.c: New test.
+
+2019-06-05 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c++/lastprivate-conditional-1.C: New test.
+ * testsuite/libgomp.c++/lastprivate-conditional-2.C: New test.
+
+2019-06-04 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c-c++-common/lastprivate-conditional-7.c: New test.
+ * testsuite/libgomp.c-c++-common/lastprivate-conditional-8.c: New test.
+ * testsuite/libgomp.c-c++-common/lastprivate-conditional-9.c: New test.
+ * testsuite/libgomp.c-c++-common/lastprivate-conditional-10.c: New test.
+
+2019-05-30 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * configure.ac: Call AX_COUNT_CPUS.
+ Substitute CPU_COUNT.
+ * testsuite/Makefile.am (check-am): Use CPU_COUNT as processor
+ count fallback.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+ * Makefile.in, testsuite/Makefile.in: Regenerate.
+
+2019-05-29 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: Rename
+ to ...
+ * testsuite/libgomp.c-c++-common/lastprivate-conditional-4.c: ... this.
+ * testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c: New test.
+ * testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c: New test.
+
+2019-05-27 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: New test.
+
+ * testsuite/libgomp.c-c++-common/lastprivate-conditional-3.c: New test.
+
+ PR libgomp/90641
+ * work.c (gomp_init_work_share): Instead of aligning final ordered
+ value to multiples of long long alignment, align to that the
+ first part (ordered team ids) and if inline_ordered_team_ids
+ is not on a long long alignment boundary within the structure,
+ use __alignof__ (long long) - 1 pad size always.
+ * loop.c (GOMP_loop_start): Fix *mem computation if
+ inline_ordered_team_ids is not aligned on long long alignment boundary
+ within the structure.
+ * loop-ull.c (GOMP_loop_ull_start): Likewise.
+ * sections.c (GOMP_sections2_start): Likewise.
+
+2019-05-24 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c-c++-common/lastprivate-conditional-1.c: New test.
+ * testsuite/libgomp.c-c++-common/lastprivate-conditional-2.c: New test.
+
+ PR libgomp/90585
+ * plugin/plugin-hsa.c: Include gstdint.h. Include inttypes.h only if
+ HAVE_INTTYPES_H is defined.
+ (print_uint64_t): New typedef.
+ (PRIu64): Define if HAVE_INTTYPES_H is not defined.
+ (print_kernel_dispatch, run_kernel): Use PRIu64 macro instead of
+ "lu", cast uint64_t HSA_DEBUG and fprintf arguments to print_uint64_t.
+ (release_kernel_dispatch): Likewise. Cast shadow->debug to uintptr_t
+ before casting to void *.
+ * plugin/plugin-nvptx.c: Include gstdint.h instead of stdint.h.
+ * oacc-mem.c: Don't include config.h nor stdint.h.
+ * target.c: Don't include config.h.
+ * oacc-cuda.c: Likewise.
+ * oacc-host.c: Don't include stdint.h.
+
+2019-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/90527
+ * alloc.c (_GNU_SOURCE): Define.
+
+2019-05-17 Thomas Schwinge <thomas@codesourcery.com>
+
+ * acc_prof.h: New file.
+ * oacc-profiling.c: Likewise.
+ * Makefile.am (nodist_libsubinclude_HEADERS, libgomp_la_SOURCES):
+ Add these, respectively.
+ * Makefile.in: Regenerate.
+ * env.c (initialize_env): Call goacc_profiling_initialize.
+ * oacc-plugin.c (GOMP_PLUGIN_goacc_thread)
+ (GOMP_PLUGIN_goacc_profiling_dispatch): New functions.
+ * oacc-plugin.h (GOMP_PLUGIN_goacc_thread)
+ (GOMP_PLUGIN_goacc_profiling_dispatch): Declare.
+ * libgomp.map (OACC_2.5.1): Add acc_prof_lookup,
+ acc_prof_register, acc_prof_unregister, and acc_register_library.
+ (GOMP_PLUGIN_1.3): Add GOMP_PLUGIN_goacc_profiling_dispatch, and
+ GOMP_PLUGIN_goacc_thread.
+ * oacc-int.h (struct goacc_thread): Add prof_info, api_info,
+ prof_callbacks_enabled members.
+ (goacc_prof_enabled, goacc_profiling_initialize)
+ (_goacc_profiling_dispatch_p, _goacc_profiling_setup_p)
+ (goacc_profiling_dispatch): Declare.
+ (GOACC_PROF_ENABLED, GOACC_PROFILING_DISPATCH_P)
+ (GOACC_PROFILING_SETUP_P): Define.
+ * oacc-async.c (acc_async_test, acc_async_test_all, acc_wait)
+ (acc_wait_async, acc_wait_all, acc_wait_all_async): Update for
+ OpenACC Profiling Interface.
+ * oacc-cuda.c (acc_get_current_cuda_device)
+ (acc_get_current_cuda_context, acc_get_cuda_stream)
+ (acc_set_cuda_stream): Likewise.
+ * oacc-init.c (acc_init_1, goacc_attach_host_thread_to_device)
+ (acc_init, acc_set_device_type, acc_get_device_type)
+ (acc_get_device_num, goacc_lazy_initialize): Likewise.
+ * oacc-mem.c (acc_malloc, acc_free, memcpy_tofrom_device)
+ (acc_deviceptr, acc_hostptr, acc_is_present, acc_map_data)
+ (acc_unmap_data, present_create_copy, delete_copyout)
+ (update_dev_host): Likewise.
+ * oacc-parallel.c (GOACC_parallel_keyed, GOACC_data_start)
+ (GOACC_data_end, GOACC_enter_exit_data, GOACC_update, GOACC_wait):
+ Likewise.
+ * plugin/plugin-nvptx.c (nvptx_exec, nvptx_alloc, nvptx_free)
+ (GOMP_OFFLOAD_openacc_exec, GOMP_OFFLOAD_openacc_async_exec):
+ Likewise.
+ * libgomp.texi: Update.
+ * testsuite/libgomp.oacc-c-c++-common/acc_prof-dispatch-1.c: New
+ file.
+ * testsuite/libgomp.oacc-c-c++-common/acc_prof-init-1.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c:
+ Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/acc_prof-parallel-1.c:
+ Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/acc_prof-valid_bytes-1.c:
+ Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/acc_prof-version-1.c:
+ Likewise.
+
+2019-05-13 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * libgomp-plugin.h (struct goacc_asyncqueue): Declare.
+ (struct goacc_asyncqueue_list): Likewise.
+ (goacc_aq): Likewise.
+ (goacc_aq_list): Likewise.
+ (GOMP_OFFLOAD_openacc_register_async_cleanup): Remove.
+ (GOMP_OFFLOAD_openacc_async_test): Remove.
+ (GOMP_OFFLOAD_openacc_async_test_all): Remove.
+ (GOMP_OFFLOAD_openacc_async_wait): Remove.
+ (GOMP_OFFLOAD_openacc_async_wait_async): Remove.
+ (GOMP_OFFLOAD_openacc_async_wait_all): Remove.
+ (GOMP_OFFLOAD_openacc_async_wait_all_async): Remove.
+ (GOMP_OFFLOAD_openacc_async_set_async): Remove.
+ (GOMP_OFFLOAD_openacc_exec): Adjust declaration.
+ (GOMP_OFFLOAD_openacc_cuda_get_stream): Likewise.
+ (GOMP_OFFLOAD_openacc_cuda_set_stream): Likewise.
+ (GOMP_OFFLOAD_openacc_async_exec): Declare.
+ (GOMP_OFFLOAD_openacc_async_construct): Declare.
+ (GOMP_OFFLOAD_openacc_async_destruct): Declare.
+ (GOMP_OFFLOAD_openacc_async_test): Declare.
+ (GOMP_OFFLOAD_openacc_async_synchronize): Declare.
+ (GOMP_OFFLOAD_openacc_async_serialize): Declare.
+ (GOMP_OFFLOAD_openacc_async_queue_callback): Declare.
+ (GOMP_OFFLOAD_openacc_async_host2dev): Declare.
+ (GOMP_OFFLOAD_openacc_async_dev2host): Declare.
+
+ * libgomp.h (struct acc_dispatch_t): Define 'async' sub-struct.
+ (gomp_acc_insert_pointer): Adjust declaration.
+ (gomp_copy_host2dev): New declaration.
+ (gomp_copy_dev2host): Likewise.
+ (gomp_map_vars_async): Likewise.
+ (gomp_unmap_tgt): Likewise.
+ (gomp_unmap_vars_async): Likewise.
+ (gomp_fini_device): Likewise.
+
+ * oacc-async.c (get_goacc_thread): New function.
+ (get_goacc_thread_device): New function.
+ (lookup_goacc_asyncqueue): New function.
+ (get_goacc_asyncqueue): New function.
+ (acc_async_test): Adjust code to use new async design.
+ (acc_async_test_all): Likewise.
+ (acc_wait): Likewise.
+ (acc_wait_async): Likewise.
+ (acc_wait_all): Likewise.
+ (acc_wait_all_async): Likewise.
+ (goacc_async_free): New function.
+ (goacc_init_asyncqueues): Likewise.
+ (goacc_fini_asyncqueues): Likewise.
+ * oacc-cuda.c (acc_get_cuda_stream): Adjust code to use new async
+ design.
+ (acc_set_cuda_stream): Likewise.
+ * oacc-host.c (host_openacc_exec): Adjust parameters, remove 'async'.
+ (host_openacc_register_async_cleanup): Remove.
+ (host_openacc_async_exec): New function.
+ (host_openacc_async_test): Adjust parameters.
+ (host_openacc_async_test_all): Remove.
+ (host_openacc_async_wait): Remove.
+ (host_openacc_async_wait_async): Remove.
+ (host_openacc_async_wait_all): Remove.
+ (host_openacc_async_wait_all_async): Remove.
+ (host_openacc_async_set_async): Remove.
+ (host_openacc_async_synchronize): New function.
+ (host_openacc_async_serialize): New function.
+ (host_openacc_async_host2dev): New function.
+ (host_openacc_async_dev2host): New function.
+ (host_openacc_async_queue_callback): New function.
+ (host_openacc_async_construct): New function.
+ (host_openacc_async_destruct): New function.
+ (struct gomp_device_descr host_dispatch): Remove initialization of old
+ interface, add intialization of new async sub-struct.
+ * oacc-init.c (acc_shutdown_1): Adjust to use gomp_fini_device.
+ (goacc_attach_host_thread_to_device): Remove old async code usage.
+ * oacc-int.h (goacc_init_asyncqueues): New declaration.
+ (goacc_fini_asyncqueues): Likewise.
+ (goacc_async_copyout_unmap_vars): Likewise.
+ (goacc_async_free): Likewise.
+ (get_goacc_asyncqueue): Likewise.
+ (lookup_goacc_asyncqueue): Likewise.
+ * oacc-mem.c (memcpy_tofrom_device): Adjust code to use new async
+ design.
+ (present_create_copy): Adjust code to use new async design.
+ (delete_copyout): Likewise.
+ (update_dev_host): Likewise.
+ (gomp_acc_insert_pointer): Add async parameter, adjust code to use new
+ async design.
+ (gomp_acc_remove_pointer): Adjust code to use new async design.
+ * oacc-parallel.c (GOACC_parallel_keyed): Adjust code to use new async
+ design.
+ (GOACC_enter_exit_data): Likewise.
+ (goacc_wait): Likewise.
+ (GOACC_update): Likewise.
+ * oacc-plugin.c (GOMP_PLUGIN_async_unmap_vars): Change to assert fail
+ when called, warn as obsolete in comment.
+ * target.c (goacc_device_copy_async): New function.
+ (gomp_copy_host2dev): Remove 'static', add goacc_asyncqueue parameter,
+ add goacc_device_copy_async case.
+ (gomp_copy_dev2host): Likewise.
+ (gomp_map_vars_existing): Add goacc_asyncqueue parameter, adjust code.
+ (gomp_map_pointer): Likewise.
+ (gomp_map_fields_existing): Likewise.
+ (gomp_map_vars_internal): New always_inline function, renamed from
+ gomp_map_vars.
+ (gomp_map_vars): Implement by calling gomp_map_vars_internal.
+ (gomp_map_vars_async): Implement by calling gomp_map_vars_internal,
+ passing goacc_asyncqueue argument.
+ (gomp_unmap_tgt): Remove static, add attribute_hidden.
+ (gomp_unref_tgt): New function.
+ (gomp_unmap_vars_internal): New always_inline function, renamed from
+ gomp_unmap_vars.
+ (gomp_unmap_vars): Implement by calling gomp_unmap_vars_internal.
+ (gomp_unmap_vars_async): Implement by calling
+ gomp_unmap_vars_internal, passing goacc_asyncqueue argument.
+ (gomp_fini_device): New function.
+ (gomp_exit_data): Adjust gomp_copy_dev2host call.
+ (gomp_load_plugin_for_device): Remove old interface, adjust to load
+ new async interface.
+ (gomp_target_fini): Adjust code to call gomp_fini_device.
+
+ * plugin/plugin-nvptx.c (struct cuda_map): Remove.
+ (struct ptx_stream): Remove.
+ (struct nvptx_thread): Remove current_stream field.
+ (cuda_map_create): Remove.
+ (cuda_map_destroy): Remove.
+ (map_init): Remove.
+ (map_fini): Remove.
+ (map_pop): Remove.
+ (map_push): Remove.
+ (struct goacc_asyncqueue): Define.
+ (struct nvptx_callback): Define.
+ (struct ptx_free_block): Define.
+ (struct ptx_device): Remove null_stream, active_streams, async_streams,
+ stream_lock, and next fields.
+ (enum ptx_event_type): Remove.
+ (struct ptx_event): Remove.
+ (ptx_event_lock): Remove.
+ (ptx_events): Remove.
+ (init_streams_for_device): Remove.
+ (fini_streams_for_device): Remove.
+ (select_stream_for_async): Remove.
+ (nvptx_init): Remove ptx_events and ptx_event_lock references.
+ (nvptx_attach_host_thread_to_device): Remove CUDA_ERROR_NOT_PERMITTED
+ case.
+ (nvptx_open_device): Add free_blocks initialization, remove
+ init_streams_for_device call.
+ (nvptx_close_device): Remove fini_streams_for_device call, add
+ free_blocks destruct code.
+ (event_gc): Remove.
+ (event_add): Remove.
+ (nvptx_exec): Adjust parameters and code.
+ (nvptx_free): Likewise.
+ (nvptx_host2dev): Remove.
+ (nvptx_dev2host): Remove.
+ (nvptx_set_async): Remove.
+ (nvptx_async_test): Remove.
+ (nvptx_async_test_all): Remove.
+ (nvptx_wait): Remove.
+ (nvptx_wait_async): Remove.
+ (nvptx_wait_all): Remove.
+ (nvptx_wait_all_async): Remove.
+ (nvptx_get_cuda_stream): Remove.
+ (nvptx_set_cuda_stream): Remove.
+ (GOMP_OFFLOAD_alloc): Adjust code.
+ (GOMP_OFFLOAD_free): Likewise.
+ (GOMP_OFFLOAD_openacc_register_async_cleanup): Remove.
+ (GOMP_OFFLOAD_openacc_exec): Adjust parameters and code.
+ (GOMP_OFFLOAD_openacc_async_test_all): Remove.
+ (GOMP_OFFLOAD_openacc_async_wait): Remove.
+ (GOMP_OFFLOAD_openacc_async_wait_async): Remove.
+ (GOMP_OFFLOAD_openacc_async_wait_all): Remove.
+ (GOMP_OFFLOAD_openacc_async_wait_all_async): Remove.
+ (GOMP_OFFLOAD_openacc_async_set_async): Remove.
+ (cuda_free_argmem): New function.
+ (GOMP_OFFLOAD_openacc_async_exec): New plugin hook function.
+ (GOMP_OFFLOAD_openacc_create_thread_data): Adjust code.
+ (GOMP_OFFLOAD_openacc_cuda_get_stream): Adjust code.
+ (GOMP_OFFLOAD_openacc_cuda_set_stream): Adjust code.
+ (GOMP_OFFLOAD_openacc_async_construct): New plugin hook function.
+ (GOMP_OFFLOAD_openacc_async_destruct): New plugin hook function.
+ (GOMP_OFFLOAD_openacc_async_test): Remove and re-implement.
+ (GOMP_OFFLOAD_openacc_async_synchronize): New plugin hook function.
+ (GOMP_OFFLOAD_openacc_async_serialize): New plugin hook function.
+ (GOMP_OFFLOAD_openacc_async_queue_callback): New plugin hook function.
+ (cuda_callback_wrapper): New function.
+ (cuda_memcpy_sanity_check): New function.
+ (GOMP_OFFLOAD_host2dev): Remove and re-implement.
+ (GOMP_OFFLOAD_dev2host): Remove and re-implement.
+ (GOMP_OFFLOAD_openacc_async_host2dev): New plugin hook function.
+ (GOMP_OFFLOAD_openacc_async_dev2host): New plugin hook function.
+
+2019-05-07 Thomas Schwinge <thomas@codesourcery.com>
+
+ PR target/87835
+ * testsuite/libgomp.oacc-c-c++-common/pr87835.c: Update.
+
+2019-05-06 Thomas Schwinge <thomas@codesourcery.com>
+
+ * oacc-parallel.c: Add comments to legacy entry points (GCC 5).
+
+2019-03-27 Kevin Buettner <kevinb@redhat.com>
+
+ * team.c (gomp_team_start): Initialize pool->threads[0].
+
+2019-02-22 Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c++/c++.exp: Specify
+ "-foffload=$offload_target".
+ * testsuite/libgomp.oacc-c/c.exp: Likewise.
+ * testsuite/libgomp.oacc-fortran/fortran.exp: Likewise.
+ * testsuite/lib/libgomp.exp
+ (check_effective_target_openacc_nvidia_accel_configured): Remove,
+ as (conceptually) merged into
+ check_effective_target_openacc_nvidia_accel_selected. Adjust all
+ users.
+
+ * plugin/configfrag.ac: Populate and AC_SUBST offload_targets.
+ * testsuite/libgomp-test-support.exp.in: Adjust.
+ * testsuite/lib/libgomp.exp: Likewise. Don't populate
+ openacc_device_types_s.
+ (offload_target_to_openacc_device_type): New proc.
+ * testsuite/libgomp.oacc-c++/c++.exp: Adjust.
+ * testsuite/libgomp.oacc-c/c.exp: Likewise.
+ * testsuite/libgomp.oacc-fortran/fortran.exp: Likewise.
+ * Makefile.in: Regenerate.
+ * configure: Likewise.
+ * testsuite/Makefile.in: Likewise.
+
+ * plugin/configfrag.ac: Populate and AC_SUBST offload_plugins
+ instead of offload_targets, and AC_DEFINE_UNQUOTED OFFLOAD_PLUGINS
+ instead of OFFLOAD_TARGETS.
+ * target.c (gomp_target_init): Adjust.
+ * testsuite/libgomp-test-support.exp.in: Likewise.
+ * testsuite/lib/libgomp.exp: Likewise. Populate
+ openacc_device_types_s instead of offload_targets_s_openacc.
+ (check_effective_target_openacc_nvidia_accel_selected)
+ (check_effective_target_openacc_host_selected): Adjust.
+ * testsuite/libgomp.oacc-c++/c++.exp: Likewise.
+ * testsuite/libgomp.oacc-c/c.exp: Likewise.
+ * testsuite/libgomp.oacc-fortran/fortran.exp: Likewise.
+ * Makefile.in: Regenerate.
+ * config.h.in: Likewise.
+ * configure: Likewise.
+ * testsuite/Makefile.in: Likewise.
+
+ * testsuite/lib/libgomp.exp: Error out for unknown offload target.
+ * testsuite/libgomp.oacc-c++/c++.exp: Likewise. Report if
+ "offloading: supported, but hardware not accessible".
+ * testsuite/libgomp.oacc-c/c.exp: Likewise.
+ * testsuite/libgomp.oacc-fortran/fortran.exp: Likewise.
+
+2019-02-19 Chung-Lin Tang <cltang@codesourcery.com>
+
+ PR c/87924
+ * oacc-parallel.c (GOACC_parallel_keyed): Remove condition on call to
+ goacc_wait().
+ (goacc_wait): Handle ACC_ASYNC_NOVAL case, remove goacc_thread() call
+ and related adjustment.
+
+2019-01-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/88988
+ * testsuite/libgomp.c++/pr88988.C: New test.
+
+2019-01-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/89002
+ * testsuite/libgomp.c/pr89002.c: New test.
+
+2019-01-28 Richard Biener <rguenther@suse.de>
+
+ PR testsuite/89064
+ PR tree-optimization/86865
+ * testsuite/libgomp.graphite/force-parallel-5.c: XFAIL.
+
+2019-01-24 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (GOMP_OFFLOAD_fini_device): Free ptx_devices
+ once instantiated_devices drops to 0.
+
+2019-01-23 Tom de Vries <tdevries@suse.de>
+
+ PR target/PR88946
+ * plugin/plugin-nvptx.c (cuda_map_destroy): Use CUDA_CALL_NOCHECK for
+ cuMemFree.
+ (nvptx_exec): Don't call map_push if mapnum == 0.
+ * testsuite/libgomp.oacc-c-c++-common/pr88946.c: New test.
+
+2019-01-23 Tom de Vries <tdevries@suse.de>
+
+ PR target/88941
+ PR target/88939
+ * plugin/plugin-nvptx.c (cuda_map_destroy): Handle map->active case.
+ (map_fini): Remove "assert (!s->map->active)".
+ * testsuite/libgomp.oacc-c-c++-common/pr88941.c: New test.
+
+2019-01-23 Tom de Vries <tdevries@suse.de>
+
+ PR target/87835
+ * plugin/plugin-nvptx.c (map_push): Fix adding of allocated element.
+ * testsuite/libgomp.oacc-c-c++-common/pr87835.c: New test.
+
+2019-01-15 Tom de Vries <tdevries@suse.de>
+
+ PR target/80547
+ * testsuite/libgomp.oacc-c-c++-common/gang-reduction-var-assignment.c:
+ New test.
+
+2019-01-12 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-c-c++-common/pr85486-2.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-128-2.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-128-5.c: New test.
+ * testsuite/libgomp.oacc-fortran/gemm-2.f90: New test.
+
+2019-01-12 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (nvptx_exec): Update error message.
+
+2019-01-12 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-64-1.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-64-2.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-64-3.c: New test.
+
+2019-01-12 Tom de Vries <tdevries@suse.de>
+
+ PR target/85486
+ * testsuite/libgomp.oacc-c-c++-common/pr85486-3.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/pr85486.c: New test.
+
+2019-01-12 Tom de Vries <tdevries@suse.de>
+
+ PR target/85381
+ * testsuite/libgomp.oacc-c-c++-common/pr85381-5.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/pr85381.c: New test.
+
+2019-01-12 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-c-c++-common/vred2d-128.c: New test.
+ * testsuite/libgomp.oacc-fortran/gemm.f90: New test.
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-128-10.c: New test.
+
+2019-01-12 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-128-7.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-128-4.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-128-6.c: New test.
+
+2019-01-12 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (nvptx_exec): Update insufficient hardware
+ resources diagnostic.
+
+2019-01-12 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-128-1.c: Expect
+ vector length to be 128.
+ * testsuite/libgomp.oacc-c-c++-common/parallel-dims.c: Expect vector
+ length 2097152 to be reduced to 1024 instead of 32.
+
+2019-01-11 Thomas Schwinge <thomas@codesourcery.com>
+ James Norris <jnorris@codesourcery.com>
+
+ * libgomp.texi: Better distinguish OpenACC and OpenMP "Runtime
+ Library Routines", and "Environment Variables".
+
+2019-01-11 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (nvptx_exec): Prevent vector_length 64 and
+ num_workers 16.
+
+2019-01-11 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-c-c++-common/reduction-1.c: Remove
+ -foffload=-w.
+ * testsuite/libgomp.oacc-c-c++-common/reduction-2.c: Same.
+ * testsuite/libgomp.oacc-c-c++-common/reduction-3.c: Same.
+ * testsuite/libgomp.oacc-c-c++-common/reduction-4.c: Same.
+ * testsuite/libgomp.oacc-c-c++-common/reduction-5.c: Same.
+
+2019-01-11 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-c-c++-common/insufficient-resources.c: New
+ test.
+
+2019-01-10 Nathan Sidwell <nathan@acm.org>
+ Julian Brown <julian@codesourcery.com>
+
+ PR lto/71959
+ * testsuite/libgomp.oacc-c++/pr71959-aux.cc: New.
+ * testsuite/libgomp.oacc-c++/pr71959.C: New.
+
+2019-01-09 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * config/rtems/bar.c: Include "../linux/bar.c" and delete copy
+ and paste code.
+
+2019-01-09 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * config/rtems/affinity-fmt.c: New file. Include affinity-fmt.c,
+ undefining HAVE_GETPID and HAVE_GETHOSTNAME, and mapping fwrite to
+ write.
+
+2019-01-09 Tom de Vries <tdevries@suse.de>
+
+ PR target/88756
+ * testsuite/libgomp.oacc-c-c++-common/reduction-1.c (ng, nw, vl): Use
+ #define instead of "const int".
+ * testsuite/libgomp.oacc-c-c++-common/reduction-2.c (ng, nw, vl): Same.
+ * testsuite/libgomp.oacc-c-c++-common/reduction-3.c (ng, nw, vl): Same.
+ * testsuite/libgomp.oacc-c-c++-common/reduction-4.c (ng, nw, vl): Same.
+ * testsuite/libgomp.oacc-c-c++-common/reduction-5.c (ng, nw, vl): Same.
+
+2019-01-09 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (nvptx_exec): Make sure to launch with at least
+ one worker.
+
+2019-01-07 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-128-3.c: Fix
+ GOMP_OPENACC_DIM argument.
+
+2019-01-03 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-128-1.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/vector-length-128-3.c: New test.
+
+2019-01-01 Jakub Jelinek <jakub@redhat.com>
+
+ Update copyright years.
+
+2019-01-01 Jakub Jelinek <jakub@redhat.com>
+
+ * libgomp.texi: Bump @copying's copyright year.
+
+2018-12-28 Thomas Schwinge <thomas@codesourcery.com>
+
+ * oacc-parallel.c (GOACC_parallel_keyed, GOACC_parallel)
+ (GOACC_data_start, GOACC_enter_exit_data, GOACC_update)
+ (GOACC_declare): Redefine the "device" argument to "flags".
+
+2018-12-28 Thomas Schwinge <thomas@codesourcery.com>
+ Cesar Philippidis <cesar@codesourcery.com>
+
+ * target.c (struct gomp_coalesce_chunk): New structure.
+ (struct gomp_coalesce_buf): Update the chunks member to use that
+ type. Adjust all users.
+
+2018-12-19 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-c-c++-common/pr85381-2.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/pr85381-3.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/pr85381-4.c: New test.
+
+2018-12-19 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/lib/libgomp.exp: Add load_lib of scanoffloadrtl.exp.
+ * testsuite/libgomp.oacc-c-c++-common/nvptx-merged-loop.c: Move from
+ gcc/testsuite/gcc.dg/goacc.
+ * testsuite/libgomp.oacc-c-c++-common/nvptx-sese-1.c: Same.
+
+2018-12-14 Thomas Schwinge <thomas@codesourcery.com>
+ Chung-Lin Tang <cltang@codesourcery.com>
+
+ * oacc-mem.c (acc_present_or_create): Remove definition and change
+ to alias of acc_create.
+ (acc_present_or_copyin): Remove definition and change to alias of
+ acc_copyin.
+ * oacc-parallel.c (GOACC_enter_exit_data): Call acc_create instead
+ of acc_present_or_create.
+ * testsuite/libgomp.oacc-c-c++-common/data-already-1.c: Remove.
+ * testsuite/libgomp.oacc-c-c++-common/data-already-2.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/data-already-3.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/data-already-4.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/data-already-5.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/data-already-6.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/data-already-7.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/data-already-8.c: Likewise.
+ * testsuite/libgomp.oacc-fortran/data-already-1.f: Likewise.
+ * testsuite/libgomp.oacc-fortran/data-already-2.f: Likewise.
+ * testsuite/libgomp.oacc-fortran/data-already-3.f: Likewise.
+ * testsuite/libgomp.oacc-fortran/data-already-4.f: Likewise.
+ * testsuite/libgomp.oacc-fortran/data-already-5.f: Likewise.
+ * testsuite/libgomp.oacc-fortran/data-already-6.f: Likewise.
+ * testsuite/libgomp.oacc-fortran/data-already-7.f: Likewise.
+ * testsuite/libgomp.oacc-fortran/data-already-8.f: Likewise.
+
+2018-12-14 Thomas Schwinge <thomas@codesourcery.com>
+
+ PR libgomp/88495
+ * plugin/plugin-nvptx.c (nvptx_wait_async): Don't refuse
+ "identical parameters".
+ * testsuite/libgomp.oacc-c-c++-common/asyncwait-nop-1.c: Update.
+ * testsuite/libgomp.oacc-c-c++-common/lib-80.c: Remove.
+
+ PR libgomp/88484
+ * oacc-parallel.c (GOACC_wait): Correct handling for "async >= 0".
+ * testsuite/libgomp.oacc-c-c++-common/asyncwait-nop-1.c: New file.
+
+ PR libgomp/88407
+ * plugin/plugin-nvptx.c (nvptx_async_test, nvptx_wait)
+ (nvptx_wait_async): Unseen async-argument is a no-op.
+ * testsuite/libgomp.oacc-c-c++-common/async_queue-1.c: Update.
+ * testsuite/libgomp.oacc-c-c++-common/data-2-lib.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/data-2.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/lib-79.c: Likewise.
+ * testsuite/libgomp.oacc-fortran/lib-12.f90: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/lib-71.c: Merge into...
+ * testsuite/libgomp.oacc-c-c++-common/lib-69.c: ... this. Update.
+ * testsuite/libgomp.oacc-c-c++-common/lib-77.c: Merge into...
+ * testsuite/libgomp.oacc-c-c++-common/lib-74.c: ... this. Update
+
+ * testsuite/libgomp.oacc-c-c++-common/data-2-lib.c: Revise.
+ * testsuite/libgomp.oacc-c-c++-common/data-2.c: Likewise.
+
+2018-12-14 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c-c++-common/data-2-lib.c: Adjust.
+ * testsuite/libgomp.oacc-c-c++-common/data-2.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/data-3.c: Likewise.
+
+2018-12-14 Thomas Schwinge <thomas@codesourcery.com>
+
+ PR libgomp/88370
+ * libgomp.texi (acc_get_current_cuda_context, acc_get_cuda_stream)
+ (acc_set_cuda_stream): Clarify.
+ * oacc-cuda.c (acc_get_cuda_stream, acc_set_cuda_stream): Use
+ "async_valid_p".
+ * plugin/plugin-nvptx.c (nvptx_set_cuda_stream): Refuse "async ==
+ acc_async_sync".
+ * testsuite/libgomp.oacc-c-c++-common/acc_set_cuda_stream-1.c: New file.
+ * testsuite/libgomp.oacc-c-c++-common/async_queue-1.c: Likewise.
+ * testsuite/libgomp.oacc-c-c++-common/lib-84.c: Update.
+ * testsuite/libgomp.oacc-c-c++-common/lib-85.c: Likewise.
+
+2018-12-14 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.c-c++-common/function-not-offloaded-aux.c: New test.
+ * testsuite/libgomp.c-c++-common/function-not-offloaded.c: New test.
+ * testsuite/libgomp.c-c++-common/variable-not-offloaded.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/function-not-offloaded.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/variable-not-offloaded.c: New test.
+
+2018-12-13 Tom de Vries <tdevries@suse.de>
+
+ * affinity-fmt.c (gomp_print_string): New function, factored out of ...
+ (omp_display_affinity, gomp_display_affinity_thread): ... here, and ...
+ * fortran.c (omp_display_affinity_): ... here.
+ * libgomp.h (gomp_print_string): Declare.
+ * config/nvptx/affinity-fmt.c: New file. Include affinity-fmt.c,
+ undefining HAVE_GETPID and HAVE_GETHOSTNAME, and mapping fwrite to
+ write.
+
+2018-12-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/88460
+ * testsuite/libgomp.c++/for-24.C (results): Include it in
+ omp declare target region.
+ (main): Use map (always, tofrom: results) instead of
+ map (tofrom: results).
+
+2018-12-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/88463
+ * testsuite/libgomp.fortran/pr88463-1.f90: New test.
+ * testsuite/libgomp.fortran/pr88463-2.f90: New test.
+
+ * testsuite/libgomp.c-c++-common/for-16.c: New test.
+
+2018-12-12 Andreas Schwab <schwab@suse.de>
+
+ * config/linux/ia64/futex.h (sys_futex0): Don't mark r12 as
+ clobbered.
+
+2018-12-09 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/88411
+ * testsuite/libgomp.fortran/async_io_8.f90: New test.
+
+2018-12-09 Thomas Schwinge <thomas@codesourcery.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * target.c (gomp_map_vars): Call gomp_copy_host2dev instead of
+ devicep->host2dev_func.
+
+2018-12-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/87995
+ * testsuite/libgomp.c-c++-common/cancel-taskgroup-3.c: Require
+ tls_runtime effective target.
+ (t): New threadprivate variable.
+ (main): Set t in threads which execute iterations of the worksharing
+ loop. Propagate that to the task after the loop and don't abort
+ if the current taskgroup hasn't been cancelled.
+
+2018-12-02 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c/task-reduction-3.c: New test.
+
+ * testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c: New test.
+
+2018-11-30 Cesar Philippidis <cesar@codesourcery.com>
+
+ PR libgomp/88288
+ * oacc-parallel.c (GOACC_parallel_keyed): Add offset to devaddrs.
+ * testsuite/libgomp.oacc-c-c++-common/pr88288.c: New test.
+
+2018-11-30 Thomas Schwinge <thomas@codesourcery.com>
+
+ * testsuite/libgomp.oacc-fortran/lib-16-2.f90: New file.
+
+2018-10-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/88182
+ * testsuite/libgomp.c++/pr88182.C: Move to g++.dg/gomp.
+
+2018-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/Makefile.am (AUTOMAKE_OPTIONS): Drop dejagnu.
+ (RUNTEST): Don't define.
+ (RUNTESTDEFAULTFLAGS): Add.
+ (check-DEJAGNU, site.exp, distclean-DEJAGNU): New goals.
+ (distclean-am): Depend on distclean-DEJAGNU.
+ (check-am): If -j% option is present in MFLAGS and if
+ `getconf _NPROCESSORS_ONLN` is more than 8, export OMP_NUM_THREADS=8.
+ (.PHONY): Add check-DEJAGNU and distclean-DEJAGNU.
+ * testsuite/Makefile.in: Regenerated.
+
+2018-11-26 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/88182
+ * testsuite/libgomp.c++/pr88182.C: New testcase.
+
+2018-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/88106
+ * config/mingw32/affinity-fmt.c: New file.
+
+2018-11-09 Jakub Jelinek <jakub@redhat.com>
+
+ * affinity-fmt.c: Include inttypes.h if HAVE_INTTYPES_H.
+ (gomp_display_affinity): Use __builtin_choose_expr to handle
+ properly handle argument having integral, or pointer or some other
+ type. If inttypes.h is available and PRIx64 is defined, use PRIx64
+ with uint64_t type instead of %llx and unsigned long long.
+
+ * testsuite/libgomp.c-c++-common/task-reduction-13.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-14.c: New test.
+
+2018-11-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * affinity.c: Include <string.h>, <stdio.h>.
+ (gomp_display_affinity_place): Remove cpusetp.
+ * teams.c: Include <limits.h>.
+
+2018-11-08 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c-c++-common/task-reduction-8.c (bar): Add
+ in_reduction clause for s[0].
+
+ * affinity.c (gomp_display_affinity_place): New function.
+ * affinity-fmt.c: New file.
+ * alloc.c (gomp_aligned_alloc, gomp_aligned_free): New functions.
+ * config/linux/affinity.c (gomp_display_affinity_place): New function.
+ * config/nvptx/icv-device.c (omp_get_num_teams, omp_get_team_num):
+ Move these functions to ...
+ * config/nvptx/teams.c: ... here. New file.
+ * config/nvptx/target.c (omp_pause_resource, omp_pause_resource_all):
+ New functions.
+ * config/nvptx/team.c (gomp_team_start, gomp_pause_host): New
+ functions.
+ * configure.ac: Check for aligned_alloc, posix_memalign, memalign
+ and _aligned_malloc.
+ (HAVE_UNAME, HAVE_GETHOSTNAME, HAVE_GETPID): Add new tests.
+ * configure.tgt: Add -DUSING_INITIAL_EXEC_TLS to XCFLAGS for Linux.
+ * env.c (gomp_display_affinity_var, gomp_affinity_format_var,
+ gomp_affinity_format_len): New variables.
+ (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. Print
+ OMP_DISPLAY_AFFINITY and OMP_AFFINITY_FORMAT.
+ (initialize_env): Don't call pthread_attr_setdetachstate. Handle
+ OMP_DISPLAY_AFFINITY and OMP_AFFINITY_FORMAT env vars.
+ * fortran.c: Include stdio.h and string.h.
+ (omp_pause_resource, omp_pause_resource_all): Add ialias_redirect.
+ (omp_get_schedule_, omp_get_schedule_8_): Mask off GFS_MONOTONIC bit.
+ (omp_set_affinity_format_, omp_get_affinity_format_,
+ omp_display_affinity_, omp_capture_affinity_, omp_pause_resource_,
+ omp_pause_resource_all_): New functions.
+ * icv.c (omp_set_schedule): Mask off omp_sched_monotonic bit in
+ switch.
+ * icv-device.c (omp_get_num_teams, omp_get_team_num): Move these
+ functions to ...
+ * teams.c: ... here. New file.
+ * libgomp_g.h: Include gstdint.h.
+ (GOMP_loop_nonmonotonic_runtime_start,
+ GOMP_loop_maybe_nonmonotonic_runtime_start, GOMP_loop_start,
+ GOMP_loop_ordered_start, GOMP_loop_nonmonotonic_runtime_next,
+ GOMP_loop_maybe_nonmonotonic_runtime_next, GOMP_loop_doacross_start,
+ 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_start,
+ GOMP_loop_ull_ordered_start, GOMP_loop_ull_nonmonotonic_runtime_next,
+ GOMP_loop_ull_maybe_nonmonotonic_runtime_next,
+ GOMP_loop_ull_doacross_start, GOMP_parallel_reductions,
+ GOMP_taskwait_depend, GOMP_taskgroup_reduction_register,
+ GOMP_taskgroup_reduction_unregister, GOMP_task_reduction_remap,
+ GOMP_workshare_task_reduction_unregister, GOMP_sections2_start,
+ GOMP_teams_reg): Declare.
+ * libgomp.h (GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC): Define unless
+ gomp_aligned_alloc uses fallback implementation.
+ (gomp_aligned_alloc, gomp_aligned_free): Declare.
+ (enum gomp_schedule_type): Add GFS_MONOTONIC.
+ (struct gomp_doacross_work_share): Add extra field.
+ (struct gomp_work_share): Add task_reductions field.
+ (struct gomp_taskgroup): Add workshare and reductions fields.
+ (GOMP_NEEDS_THREAD_HANDLE): Define if needed.
+ (gomp_thread_handle): New typedef.
+ (gomp_display_affinity_place, gomp_set_affinity_format,
+ gomp_display_string, gomp_display_affinity,
+ gomp_display_affinity_thread): Declare.
+ (gomp_doacross_init, gomp_doacross_ull_init): Add size_t argument.
+ (gomp_parallel_reduction_register, gomp_workshare_taskgroup_start,
+ gomp_workshare_task_reduction_register): Declare.
+ (gomp_team_start): Add taskgroup argument.
+ (gomp_pause_host): Declare.
+ (gomp_init_work_share, gomp_work_share_start): Change bool argument
+ to size_t.
+ (gomp_thread_self, gomp_thread_to_pthread_t): New inline functions.
+ * libgomp.map (GOMP_5.0): Export GOMP_loop_start,
+ GOMP_loop_ordered_start, GOMP_loop_doacross_start,
+ GOMP_loop_ull_start, GOMP_loop_ull_ordered_start,
+ GOMP_loop_ull_doacross_start,
+ GOMP_workshare_task_reduction_unregister, GOMP_sections2_start,
+ 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, GOMP_task_reduction_remap,
+ GOMP_teams_reg and GOMP_taskwait_depend.
+ (OMP_5.0): Export omp_pause_resource{,_all}{,_},
+ omp_{capture,display}_affinity{,_}, and
+ omp_[gs]et_affinity_format{,_}.
+ * loop.c: Include string.h.
+ (GOMP_loop_runtime_next): Add ialias.
+ (GOMP_taskgroup_reduction_register): Add ialias_redirect.
+ (gomp_loop_static_start, gomp_loop_dynamic_start,
+ gomp_loop_guided_start, gomp_loop_ordered_static_start,
+ gomp_loop_ordered_dynamic_start, gomp_loop_ordered_guided_start,
+ gomp_loop_doacross_static_start, gomp_loop_doacross_dynamic_start,
+ gomp_loop_doacross_guided_start): Adjust gomp_work_share_start
+ or gomp_doacross_init callers.
+ (gomp_adjust_sched, GOMP_loop_start, GOMP_loop_ordered_start,
+ GOMP_loop_doacross_start): New functions.
+ (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.
+ (gomp_parallel_loop_start): Pass NULL as taskgroup to
+ gomp_team_start.
+ * loop_ull.c: Include string.h.
+ (GOMP_loop_ull_runtime_next): Add ialias.
+ (GOMP_taskgroup_reduction_register): Add ialias_redirect.
+ (gomp_loop_ull_static_start, gomp_loop_ull_dynamic_start,
+ gomp_loop_ull_guided_start, gomp_loop_ull_ordered_static_start,
+ gomp_loop_ull_ordered_dynamic_start,
+ gomp_loop_ull_ordered_guided_start,
+ gomp_loop_ull_doacross_static_start,
+ gomp_loop_ull_doacross_dynamic_start,
+ gomp_loop_ull_doacross_guided_start): Adjust gomp_work_share_start
+ and gomp_doacross_ull_init callers.
+ (gomp_adjust_sched, GOMP_loop_ull_start, GOMP_loop_ull_ordered_start,
+ GOMP_loop_ull_doacross_start): New functions.
+ (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.
+ * Makefile.am (libgomp_la_SOURCES): Add teams.c and affinity-fmt.c.
+ * omp.h.in (enum omp_sched_t): Add omp_sched_monotonic.
+ (omp_pause_resource_t, omp_depend_t): New typedefs.
+ (enum omp_lock_hint_t): Renamed to ...
+ (enum omp_sync_hint_t): ... this. Define omp_sync_hint_*
+ enumerators using numbers and omp_lock_hint_* as their aliases.
+ (omp_lock_hint_t): New typedef. Rename to ...
+ (omp_sync_hint_t): ... this.
+ (omp_init_lock_with_hint, omp_init_nest_lock_with_hint): Use
+ omp_sync_hint_t instead of omp_lock_hint_t.
+ (omp_pause_resource, omp_pause_resource_all, omp_set_affinity_format,
+ omp_get_affinity_format, omp_display_affinity, omp_capture_affinity):
+ Declare.
+ (omp_target_is_present, omp_target_disassociate_ptr):
+ Change first argument from void * to const void *.
+ (omp_target_memcpy, omp_target_memcpy_rect): Change second argument
+ from void * to const void *.
+ (omp_target_associate_ptr): Change first and second arguments from
+ void * to const void *.
+ * omp_lib.f90.in (omp_pause_resource_kind, omp_pause_soft,
+ omp_pause_hard): New parameters.
+ (omp_pause_resource, omp_pause_resource_all, omp_set_affinity_format,
+ omp_get_affinity_format, omp_display_affinity, omp_capture_affinity):
+ New interfaces.
+ * omp_lib.h.in (omp_pause_resource_kind, omp_pause_soft,
+ omp_pause_hard): New parameters.
+ (omp_pause_resource, omp_pause_resource_all, omp_set_affinity_format,
+ omp_get_affinity_format, omp_display_affinity, omp_capture_affinity):
+ New externals.
+ * ordered.c (gomp_doacross_init, gomp_doacross_ull_init): Add
+ EXTRA argument. If not needed to prepare array, if extra is 0,
+ clear ws->doacross, otherwise allocate just doacross structure and
+ extra payload. If array is needed, allocate also extra payload.
+ (GOMP_doacross_post, GOMP_doacross_wait, GOMP_doacross_ull_post,
+ GOMP_doacross_ull_wait): Handle doacross->array == NULL like
+ doacross == NULL.
+ * parallel.c (GOMP_parallel_start): Pass NULL as taskgroup to
+ gomp_team_start.
+ (GOMP_parallel): Likewise. Formatting fix.
+ (GOMP_parallel_reductions): New function.
+ (GOMP_cancellation_point): If taskgroup has workshare
+ flag set, check cancelled of prev taskgroup if any.
+ (GOMP_cancel): If taskgroup has workshare flag set, set cancelled
+ on prev taskgroup if any.
+ * sections.c: Include string.h.
+ (GOMP_taskgroup_reduction_register): Add ialias_redirect.
+ (GOMP_sections_start): Adjust gomp_work_share_start caller.
+ (GOMP_sections2_start): New function.
+ (GOMP_parallel_sections_start, GOMP_parallel_sections):
+ Pass NULL as taskgroup to gomp_team_start.
+ * single.c (GOMP_single_start, GOMP_single_copy_start): Adjust
+ gomp_work_share_start callers.
+ * target.c (GOMP_target_update_ext, GOMP_target_enter_exit_data):
+ If taskgroup has workshare flag set, check cancelled on prev
+ taskgroup if any. Guard all cancellation tests with
+ gomp_cancel_var test.
+ (omp_target_is_present, omp_target_disassociate_ptr):
+ Change ptr argument from void * to const void *.
+ (omp_target_memcpy): Change src argument from void * to const void *.
+ (omp_target_memcpy_rect): Likewise.
+ (omp_target_memcpy_rect_worker): Likewise. Use const char * casts
+ instead of char * where needed.
+ (omp_target_associate_ptr): Change host_ptr and device_ptr arguments
+ from void * to const void *.
+ (omp_pause_resource, omp_pause_resource_all): New functions.
+ * task.c (gomp_task_handle_depend): Handle new depend array format
+ in addition to the old. Handle mutexinoutset kinds the same as
+ inout for now, handle unspecified kinds.
+ (gomp_create_target_task): If taskgroup has workshare flag set, check
+ cancelled on prev taskgroup if any. Guard all cancellation tests with
+ gomp_cancel_var test. Handle new depend array format count in
+ addition to the old.
+ (GOMP_task): Likewise. Adjust function comment.
+ (gomp_task_run_pre): If taskgroup has workshare flag set, check
+ cancelled on prev taskgroup if any. Guard all cancellation tests with
+ gomp_cancel_var test.
+ (GOMP_taskwait_depend): New function.
+ (gomp_task_maybe_wait_for_dependencies): Handle new depend array
+ format in addition to the old. Handle mutexinoutset kinds the same as
+ inout for now, handle unspecified kinds. Fix a function comment typo.
+ (gomp_taskgroup_init): New function.
+ (GOMP_taskgroup_start): Use it.
+ (gomp_reduction_register, gomp_create_artificial_team,
+ GOMP_taskgroup_reduction_register,
+ GOMP_taskgroup_reduction_unregister, GOMP_task_reduction_remap,
+ gomp_parallel_reduction_register,
+ gomp_workshare_task_reduction_register,
+ gomp_workshare_taskgroup_start,
+ GOMP_workshare_task_reduction_unregister): New functions.
+ * taskloop.c (GOMP_taskloop): If taskgroup has workshare flag set,
+ check cancelled on prev taskgroup if any. Guard all cancellation
+ tests with gomp_cancel_var test. Handle GOMP_TASK_FLAG_REDUCTION flag
+ by calling GOMP_taskgroup_reduction_register.
+ * team.c (gomp_thread_attr): Remove comment.
+ (struct gomp_thread_start_data): Add handle field.
+ (gomp_thread_start): Call pthread_detach.
+ (gomp_new_team): Adjust gomp_init_work_share caller.
+ (gomp_free_pool_helper): Call pthread_detach.
+ (gomp_team_start): Add taskgroup argument, initialize implicit
+ tasks' taskgroup field to that. Don't call
+ pthread_attr_setdetachstate. Handle OMP_DISPLAY_AFFINITY env var.
+ (gomp_team_end): Determine nesting by thr->ts.level != 0
+ rather than thr->ts.team != NULL.
+ (gomp_pause_pool_helper, gomp_pause_host): New functions.
+ * work.c (alloc_work_share): Use gomp_aligned_alloc instead of
+ gomp_malloc if GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC is defined.
+ (gomp_init_work_share): Change ORDERED argument from bool to size_t,
+ if more than 1 allocate also extra payload at the end of array. Never
+ keep ordered_team_ids NULL, set it to inline_ordered_team_ids instead.
+ (gomp_work_share_start): Change ORDERED argument from bool to size_t,
+ return true instead of ws.
+ * Makefile.in: Regenerated.
+ * configure: Regenerated.
+ * config.h.in: Regenerated.
+ * testsuite/libgomp.c/cancel-for-2.c (foo): Use cancel modifier
+ in some cases.
+ * testsuite/libgomp.c-c++-common/cancel-parallel-1.c: New test.
+ * testsuite/libgomp.c-c++-common/cancel-taskgroup-3.c: New test.
+ * testsuite/libgomp.c-c++-common/depend-iterator-1.c: New test.
+ * testsuite/libgomp.c-c++-common/depend-iterator-2.c: New test.
+ * testsuite/libgomp.c-c++-common/depend-mutexinout-1.c: New test.
+ * testsuite/libgomp.c-c++-common/depend-mutexinout-2.c: New test.
+ * testsuite/libgomp.c-c++-common/depobj-1.c: New test.
+ * testsuite/libgomp.c-c++-common/display-affinity-1.c: New test.
+ * testsuite/libgomp.c-c++-common/for-10.c: New test.
+ * testsuite/libgomp.c-c++-common/for-11.c: New test.
+ * testsuite/libgomp.c-c++-common/for-12.c: New test.
+ * testsuite/libgomp.c-c++-common/for-13.c: New test.
+ * testsuite/libgomp.c-c++-common/for-14.c: New test.
+ * testsuite/libgomp.c-c++-common/for-15.c: New test.
+ * testsuite/libgomp.c-c++-common/for-2.h: If CONDNE macro is defined,
+ define a different N(test), don't define N(f0) to N(f14), but instead
+ define N(f20) to N(f34) using != comparisons.
+ * testsuite/libgomp.c-c++-common/for-7.c: New test.
+ * testsuite/libgomp.c-c++-common/for-8.c: New test.
+ * testsuite/libgomp.c-c++-common/for-9.c: New test.
+ * testsuite/libgomp.c-c++-common/master-combined-1.c: New test.
+ * testsuite/libgomp.c-c++-common/pause-1.c: New test.
+ * testsuite/libgomp.c-c++-common/pause-2.c: New test.
+ * testsuite/libgomp.c-c++-common/pr66199-10.c: New test.
+ * testsuite/libgomp.c-c++-common/pr66199-11.c: New test.
+ * testsuite/libgomp.c-c++-common/pr66199-12.c: New test.
+ * testsuite/libgomp.c-c++-common/pr66199-13.c: New test.
+ * testsuite/libgomp.c-c++-common/pr66199-14.c: New test.
+ * testsuite/libgomp.c-c++-common/simd-1.c: New test.
+ * testsuite/libgomp.c-c++-common/taskloop-reduction-1.c: New test.
+ * testsuite/libgomp.c-c++-common/taskloop-reduction-2.c: New test.
+ * testsuite/libgomp.c-c++-common/taskloop-reduction-3.c: New test.
+ * testsuite/libgomp.c-c++-common/taskloop-reduction-4.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-11.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-12.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-1.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-2.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-3.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-4.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-5.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-6.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-7.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-8.c: New test.
+ * testsuite/libgomp.c-c++-common/task-reduction-9.c: New test.
+ * testsuite/libgomp.c-c++-common/taskwait-depend-1.c: New test.
+ * testsuite/libgomp.c++/depend-1.C: New test.
+ * testsuite/libgomp.c++/depend-iterator-1.C: New test.
+ * testsuite/libgomp.c++/depobj-1.C: New test.
+ * testsuite/libgomp.c++/for-16.C: New test.
+ * testsuite/libgomp.c++/for-21.C: New test.
+ * testsuite/libgomp.c++/for-22.C: New test.
+ * testsuite/libgomp.c++/for-23.C: New test.
+ * testsuite/libgomp.c++/for-24.C: New test.
+ * testsuite/libgomp.c++/for-25.C: New test.
+ * testsuite/libgomp.c++/for-26.C: New test.
+ * testsuite/libgomp.c++/taskloop-reduction-1.C: New test.
+ * testsuite/libgomp.c++/taskloop-reduction-2.C: New test.
+ * testsuite/libgomp.c++/taskloop-reduction-3.C: New test.
+ * testsuite/libgomp.c++/taskloop-reduction-4.C: New test.
+ * testsuite/libgomp.c++/task-reduction-10.C: New test.
+ * testsuite/libgomp.c++/task-reduction-11.C: New test.
+ * testsuite/libgomp.c++/task-reduction-12.C: New test.
+ * testsuite/libgomp.c++/task-reduction-13.C: New test.
+ * testsuite/libgomp.c++/task-reduction-14.C: New test.
+ * testsuite/libgomp.c++/task-reduction-15.C: New test.
+ * testsuite/libgomp.c++/task-reduction-16.C: New test.
+ * testsuite/libgomp.c++/task-reduction-17.C: New test.
+ * testsuite/libgomp.c++/task-reduction-18.C: New test.
+ * testsuite/libgomp.c++/task-reduction-19.C: New test.
+ * testsuite/libgomp.c/task-reduction-1.c: New test.
+ * testsuite/libgomp.c++/task-reduction-1.C: New test.
+ * testsuite/libgomp.c/task-reduction-2.c: New test.
+ * testsuite/libgomp.c++/task-reduction-2.C: New test.
+ * testsuite/libgomp.c++/task-reduction-3.C: New test.
+ * testsuite/libgomp.c++/task-reduction-4.C: New test.
+ * testsuite/libgomp.c++/task-reduction-5.C: New test.
+ * testsuite/libgomp.c++/task-reduction-6.C: New test.
+ * testsuite/libgomp.c++/task-reduction-7.C: New test.
+ * testsuite/libgomp.c++/task-reduction-8.C: New test.
+ * testsuite/libgomp.c++/task-reduction-9.C: New test.
+ * testsuite/libgomp.c/teams-1.c: New test.
+ * testsuite/libgomp.c/teams-2.c: New test.
+ * testsuite/libgomp.c/thread-limit-4.c: New test.
+ * testsuite/libgomp.c/thread-limit-5.c: New test.
+ * testsuite/libgomp.fortran/display-affinity-1.f90: New test.
+
+2018-11-06 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * oacc-mem.c (memcpy_tofrom_device): New function, combined from
+ acc_memcpy_to/from_device functions, now with async parameter.
+ (acc_memcpy_to_device): Modify to use memcpy_tofrom_device.
+ (acc_memcpy_from_device): Likewise.
+ (acc_memcpy_to_device_async): New API function.
+ (acc_memcpy_from_device_async): Likewise.
+ (present_create_copy): Add async parameter and async setting/unsetting.
+ (acc_create): Adjust present_create_copy call.
+ (acc_copyin): Likewise.
+ (acc_present_or_create): Likewise.
+ (acc_present_or_copyin): Likewise.
+ (acc_create_async): New API function.
+ (acc_copyin_async): New API function.
+ (delete_copyout): Add async parameter and async setting/unsetting.
+ (acc_delete): Adjust delete_copyout call.
+ (acc_copyout): Likewise.
+ (acc_delete_async): New API function.
+ (acc_copyout_async): Likewise.
+ (update_dev_host): Add async parameter and async setting/unsetting.
+ (acc_update_device): Adjust update_dev_host call.
+ (acc_update_self): Likewise.
+ (acc_update_device_async): New API function.
+ (acc_update_self_async): Likewise.
+ * openacc.h (acc_copyin_async): Declare new API function.
+ (acc_create_async): Likewise.
+ (acc_copyout_async): Likewise.
+ (acc_delete_async): Likewise.
+ (acc_update_device_async): Likewise.
+ (acc_update_self_async): Likewise.
+ (acc_memcpy_to_device_async): Likewise.
+ (acc_memcpy_from_device_async): Likewise.
+ * openacc_lib.h (acc_copyin_async_32_h): New subroutine.
+ (acc_copyin_async_64_h): New subroutine.
+ (acc_copyin_async_array_h): New subroutine.
+ (acc_create_async_32_h): New subroutine.
+ (acc_create_async_64_h): New subroutine.
+ (acc_create_async_array_h): New subroutine.
+ (acc_copyout_async_32_h): New subroutine.
+ (acc_copyout_async_64_h): New subroutine.
+ (acc_copyout_async_array_h): New subroutine.
+ (acc_delete_async_32_h): New subroutine.
+ (acc_delete_async_64_h): New subroutine.
+ (acc_delete_async_array_h): New subroutine.
+ (acc_update_device_async_32_h): New subroutine.
+ (acc_update_device_async_64_h): New subroutine.
+ (acc_update_device_async_array_h): New subroutine.
+ (acc_update_self_async_32_h): New subroutine.
+ (acc_update_self_async_64_h): New subroutine.
+ (acc_update_self_async_array_h): New subroutine.
+ * openacc.f90 (acc_copyin_async_32_h): New subroutine.
+ (acc_copyin_async_64_h): New subroutine.
+ (acc_copyin_async_array_h): New subroutine.
+ (acc_create_async_32_h): New subroutine.
+ (acc_create_async_64_h): New subroutine.
+ (acc_create_async_array_h): New subroutine.
+ (acc_copyout_async_32_h): New subroutine.
+ (acc_copyout_async_64_h): New subroutine.
+ (acc_copyout_async_array_h): New subroutine.
+ (acc_delete_async_32_h): New subroutine.
+ (acc_delete_async_64_h): New subroutine.
+ (acc_delete_async_array_h): New subroutine.
+ (acc_update_device_async_32_h): New subroutine.
+ (acc_update_device_async_64_h): New subroutine.
+ (acc_update_device_async_array_h): New subroutine.
+ (acc_update_self_async_32_h): New subroutine.
+ (acc_update_self_async_64_h): New subroutine.
+ (acc_update_self_async_array_h): New subroutine.
+ * libgomp.map (OACC_2.5): Add acc_copyin_async*, acc_copyout_async*,
+ acc_copyout_finalize_async*, acc_create_async*, acc_delete_async*,
+ acc_delete_finalize_async*, acc_memcpy_from_device_async*,
+ acc_memcpy_to_device_async*, acc_update_device_async*, and
+ acc_update_self_async* entries.
+ * testsuite/libgomp.oacc-c-c++-common/lib-94.c: New test.
+ * testsuite/libgomp.oacc-c-c++-common/lib-95.c: New test.
+ * testsuite/libgomp.oacc-fortran/lib-16.f90: New test.
+
+2018-10-31 Joseph Myers <joseph@codesourcery.com>
+
+ PR bootstrap/82856
+ * Makefile.am: Include multilib.am
+ (AUTOMAKE_OPTIONS): Add info-in-builddir.
+ (CLEANFILES): Remove libgomp.info.
+ * configure.ac: Remove AC_PREREQ.
+ * testsuite/Makefile.am (RUNTEST): Remove quotes.
+ * Makefile.in, aclocal.m4, configure, testsuite/Makefile.in:
+ Regenerate.
+
+2018-10-29 Joseph Myers <joseph@codesourcery.com>
+ Julian Brown <julian@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c++/this.C: New.
+
+2018-09-18 Cesar Philippidis <cesar@codesourcery.com>
+
+ * plugin/plugin-nvptx.c (struct cuda_map): New.
+ (struct ptx_stream): Replace d, h, h_begin, h_end, h_next, h_prev,
+ h_tail with (cuda_map *) map.
+ (cuda_map_create): New function.
+ (cuda_map_destroy): New function.
+ (map_init): Update to use a linked list of cuda_map objects.
+ (map_fini): Likewise.
+ (map_pop): Likewise.
+ (map_push): Likewise. Return CUdeviceptr instead of void.
+ (init_streams_for_device): Remove stales references to ptx_stream
+ members.
+ (select_stream_for_async): Likewise.
+ (nvptx_exec): Update call to map_init.
+
+2018-09-09 Cesar Philippidis <cesar@codesourcery.com>
+ Julian Brown <julian@codesourcery.com>
+
+ PR middle-end/86336
+ * testsuite/libgomp.oacc-c++/non-scalar-data.C: Remove XFAIL.
+
+2018-08-21 Nicolas Koenig <koenigni@gcc.gnu.org>
+ Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/25829
+ * testsuite/libgomp.fortran/async_io_1.f90: New test.
+ * testsuite/libgomp.fortran/async_io_2.f90: New test.
+ * testsuite/libgomp.fortran/async_io_3.f90: New test.
+ * testsuite/libgomp.fortran/async_io_4.f90: New test.
+ * testsuite/libgomp.fortran/async_io_5.f90: New test.
+ * testsuite/libgomp.fortran/async_io_6.f90: New test.
+ * testsuite/libgomp.fortran/async_io_7.f90: New test.
+
+2018-08-13 Cesar Philippidis <cesar@codesourcery.com>
+ Tom de Vries <tdevries@suse.de>
+
+ PR target/85590
+ * plugin/cuda/cuda.h (CUoccupancyB2DSize): New typedef.
+ (cuOccupancyMaxPotentialBlockSize): Declare.
+ * plugin/cuda-lib.def (cuOccupancyMaxPotentialBlockSize): New
+ CUDA_ONE_CALL_MAYBE_NULL.
+ * plugin/plugin-nvptx.c (CUDA_VERSION < 6050): Define
+ CUoccupancyB2DSize and declare
+ cuOccupancyMaxPotentialBlockSize.
+ (nvptx_exec): Use cuOccupancyMaxPotentialBlockSize to set the
+ default num_gangs and num_workers when the driver supports it.
+
+2018-08-08 Tom de Vries <tdevries@suse.de>
+
+ * plugin/cuda-lib.def (cuLinkAddData_v2, cuLinkCreate_v2): Declare using
+ CUDA_ONE_CALL_MAYBE_NULL.
+ * plugin/plugin-nvptx.c (cuLinkAddData, cuLinkCreate): Undef and declare.
+ (cuLinkAddData_v2, cuLinkCreate_v2): Declare.
+ (link_ptx): Fall back to cuLinkAddData/cuLinkCreate if the _v2 versions
+ are not found.
+
+2018-08-08 Tom de Vries <tdevries@suse.de>
+
+ * plugin/cuda-lib.def (cuGetErrorString): Use CUDA_ONE_CALL_MAYBE_NULL.
+ * plugin/plugin-nvptx.c (cuda_error): Handle if cuGetErrorString is not
+ present.
+
+2018-08-08 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c
+ (CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_MULTIPROCESSOR): Define.
+ (nvptx_open_device): Use
+ CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_MULTIPROCESSOR.
+
+2018-08-08 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (cuda_error): Move declaration of cuGetErrorString ...
+ (cuGetErrorString): ... here. Guard with CUDA_VERSION < 6000.
+
+2018-08-07 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (DO_PRAGMA): Define.
+ (struct cuda_lib_s): Add def/undef of CUDA_ONE_CALL_MAYBE_NULL.
+ (init_cuda_lib): Add new param to CUDA_ONE_CALL_1. Add arg to
+ corresponding call in CUDA_ONE_CALL. Add def/undef of
+ CUDA_ONE_CALL_MAYBE_NULL.
+ (CUDA_CALL_EXISTS): Define.
+
+2018-08-07 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (struct cuda_lib_s, init_cuda_lib): Put
+ CUDA_ONE_CALL defines right before the cuda-lib.def include, and the
+ corresponding undefs right after.
+
+2018-08-04 Tom de Vries <tdevries@suse.de>
+
+ * plugin/configfrag.ac: For --without-cuda-driver, set
+ CUDA_DRIVER_INCLUDE and CUDA_DRIVER_LIB to no. Handle
+ CUDA_DRIVER_INCLUDE == no and CUDA_DRIVER_LIB == no.
+ * configure: Regenerate.
+
+2018-08-02 Tom de Vries <tdevries@suse.de>
+
+ PR target/86660
+ * testsuite/libgomp.oacc-c++/routine-1-auto.C: Remove -fno-exceptions.
+ * testsuite/libgomp.oacc-c++/routine-1-template-auto.C: Same.
+ * testsuite/libgomp.oacc-c++/routine-1-template-trailing-return-type.C:
+ Same.
+ * testsuite/libgomp.oacc-c++/routine-1-template.C: Same.
+ * testsuite/libgomp.oacc-c++/routine-1-trailing-return-type.C: Same.
+ * testsuite/libgomp.oacc-c-c++-common/routine-1.c: Same.
+
+2018-08-01 Cesar Philippidis <cesar@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
+
+ * config/nvptx/oacc-parallel.c: Truncate.
+
+2018-08-01 Cesar Philippidis <cesar@codesourcery.com>
+ James Norris <jnorris@codesourcery.com>
+
+ * plugin/plugin-nvptx.c (struct map): Removed.
+ (map_init, map_pop): Remove use of struct map.
+ (map_push): Likewise and change argument list.
+ * testsuite/libgomp.oacc-c-c++-common/mapping-1.c: New
+
+2018-08-01 Tom de Vries <tdevries@suse.de>
+
+ * plugin/cuda-lib.def: New file. Factor out of ...
+ * plugin/plugin-nvptx.c (CUDA_CALLS): ... here.
+ (struct cuda_lib_s, init_cuda_lib): Include cuda-lib.def instead of
+ using CUDA_CALLS.
+
+2018-07-31 Andre Vieira <andre.simoesdiasvieira@arm.com>
+
+ Revert 'AsyncI/O patch committed'.
+ 2018-07-25 Nicolas Koenig <koenigni@gcc.gnu.org>
+ Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/25829
+ * testsuite/libgomp.fortran/async_io_1.f90: New test.
+ * testsuite/libgomp.fortran/async_io_2.f90: New test.
+ * testsuite/libgomp.fortran/async_io_3.f90: New test.
+ * testsuite/libgomp.fortran/async_io_4.f90: New test.
+ * testsuite/libgomp.fortran/async_io_5.f90: New test.
+ * testsuite/libgomp.fortran/async_io_6.f90: New test.
+ * testsuite/libgomp.fortran/async_io_7.f90: New test.
+
+2018-07-30 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (MIN, MAX): Redefine.
+ (nvptx_exec): Ensure worker and vector default dims don't exceed
+ targ_fn->max_threads_per_block.
+
+2018-07-30 Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (struct ptx_device): Add default_dims field.
+ (nvptx_open_device): Init default_dims for device.
+ (nvptx_exec): Use default_dims from device.
+
+2018-07-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR testsuite/86660
+ * testsuite/libgomp.c++/for-15.C (results): Include it in
+ omp declare target region.
+ (main): Use map (always, tofrom: results) instead of
+ map (tofrom: results).
+
+ PR middle-end/86660
+ * testsuite/libgomp.c/pr86660.c: New test.
+
+2018-07-26 Cesar Philippidis <cesar@codesourcery.com>
+ Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (nvptx_exec): Error if the hardware doesn't have
+ sufficient resources to launch a kernel, and give a hint on how to fix
+ it.
+
+2018-07-26 Cesar Philippidis <cesar@codesourcery.com>
+ Tom de Vries <tdevries@suse.de>
+
+ * plugin/plugin-nvptx.c (struct ptx_device): Add warp_size,
+ max_threads_per_block and max_threads_per_multiprocessor fields.
+ (nvptx_open_device): Initialize new fields.
+ (nvptx_exec): Use num_sms, and new fields.
+
+2018-07-26 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-fortran/lib-12.f90: Move acc_async_test calls
+ to correct locations. Remove xfail.
+
+2018-07-26 Tom de Vries <tdevries@suse.de>
+
+ * testsuite/libgomp.oacc-fortran/lib-13.f90: Replace acc_wait_all with
+ acc_wait. Move acc_async_test calls to correct locations. Remove
+ xfail.
+
+2018-07-25 Nicolas Koenig <koenigni@gcc.gnu.org>
+ Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/25829
+ * testsuite/libgomp.fortran/async_io_1.f90: New test.
+ * testsuite/libgomp.fortran/async_io_2.f90: New test.
+ * testsuite/libgomp.fortran/async_io_3.f90: New test.
+ * testsuite/libgomp.fortran/async_io_4.f90: New test.
+ * testsuite/libgomp.fortran/async_io_5.f90: New test.
+ * testsuite/libgomp.fortran/async_io_6.f90: New test.
+ * testsuite/libgomp.fortran/async_io_7.f90: New test.
+
2018-07-17 Jakub Jelinek <jakub@redhat.com>
PR middle-end/86542
@@ -619,6 +2884,17 @@
* testsuite/libgomp.fortran/do_concurrent_5.f90: Move modified
test from gfortran.dg to here.
+2018-04-12 Cesar Philippidis <cesar@codesourcery.com>
+
+ * testsuite/libgomp.oacc-c-c++-common/pr84955.c: Revert 259346.
+ * testsuite/libgomp.oacc-fortran/pr84955.f90: Likewise.
+
+2018-04-12 Cesar Philippidis <cesar@codesourcery.com>
+
+ PR middle-end/84955
+ * testsuite/libgomp.oacc-c-c++-common/pr84955.c: New test.
+ * testsuite/libgomp.oacc-fortran/pr84955.f90: New test.
+
2018-04-05 Tom de Vries <tom@codesourcery.com>
PR target/85204
@@ -1691,7 +3967,7 @@
* config/nvptx/affinity.c: Delete to use fallback implementation.
2016-11-23 Alexander Monakov <amonakov@ispras.ru>
- Jakub Jelinek <jakub@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
Dmitry Melnik <dm@ispras.ru>
* Makefile.am (libgomp_la_SOURCES): Add atomic.c, icv.c, icv-device.c.
@@ -1793,7 +4069,7 @@
* testsuite/libgomp.hsa.c/tiling-2.c: Likewise.
2016-11-23 Martin Liska <mliska@suse.cz>
- Martin Jambor <mjambor@suse.cz>
+ Martin Jambor <mjambor@suse.cz>
* plugin/hsa.h: New file.
* plugin/hsa_ext_finalize.h: New file.
@@ -1843,7 +4119,7 @@
* testsuite/Makefile.in: Likewise.
2016-11-15 Martin Jambor <mjambor@suse.cz>
- Alexander Monakov <amonakov@ispras.ru>
+ Alexander Monakov <amonakov@ispras.ru>
* testsuite/libgomp.fortran/examples-4/device-1.f90 (e_57_1): Add
mapping clauses to target constructs.
@@ -2233,7 +4509,7 @@
2016-05-16 Martin Jambor <mjambor@suse.cz>
- * testsuite/libgomp.hsa.c/complex-align-2.c: New test.
+ * testsuite/libgomp.hsa.c/complex-align-2.c: New test.
2016-05-02 Nathan Sidwell <nathan@codesourcery.com>
@@ -9977,7 +12253,7 @@
Initial implementation and checkin.
-Copyright (C) 2005-2018 Free Software Foundation, Inc.
+Copyright (C) 2005-2019 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am
index 17af7d71d7d..669b9e4defd 100644
--- a/libgomp/Makefile.am
+++ b/libgomp/Makefile.am
@@ -1,5 +1,6 @@
## Process this file with automake to produce Makefile.in
+AUTOMAKE_OPTIONS = info-in-builddir
ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = testsuite
@@ -63,7 +64,8 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c error.c \
parallel.c sections.c single.c task.c team.c work.c lock.c mutex.c \
proc.c sem.c bar.c ptrlock.c time.c fortran.c affinity.c target.c \
splay-tree.c libgomp-plugin.c oacc-parallel.c oacc-host.c oacc-init.c \
- oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c
+ oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \
+ affinity-fmt.c teams.c oacc-profiling.c oacc-target.c
include $(top_srcdir)/plugin/Makefrag.am
@@ -72,7 +74,7 @@ libgomp_la_SOURCES += openacc.f90
endif
nodist_noinst_HEADERS = libgomp_f.h
-nodist_libsubinclude_HEADERS = omp.h openacc.h
+nodist_libsubinclude_HEADERS = omp.h openacc.h acc_prof.h
if USE_FORTRAN
nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod \
openacc_lib.h openacc.f90 openacc.mod openacc_kinds.mod
@@ -136,5 +138,7 @@ stamp-build-info: libgomp.texi
@touch $@
-CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO) libgomp.info
+CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO)
MAINTAINERCLEANFILES = $(srcdir)/libgomp.info
+
+include $(top_srcdir)/../multilib.am
diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in
index 3970adf8555..3d772ee3007 100644
--- a/libgomp/Makefile.in
+++ b/libgomp/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -17,7 +16,7 @@
# Plugins for offload execution, Makefile.am fragment.
#
-# Copyright (C) 2014-2018 Free Software Foundation, Inc.
+# Copyright (C) 2014-2019 Free Software Foundation, Inc.
#
# Contributed by Mentor Embedded.
#
@@ -45,23 +44,61 @@
VPATH = @srcdir@
-am__make_dryrun = \
- { \
- am__dry=no; \
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
- echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
- | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
- *) \
- for am__flg in $$MAKEFLAGS; do \
- case $$am__flg in \
- *=*|--*) ;; \
- *n*) am__dry=yes; break;; \
- esac; \
- done;; \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
- test $$am__dry = yes; \
- }
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -81,19 +118,14 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-DIST_COMMON = $(top_srcdir)/plugin/Makefrag.am ChangeLog \
- $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/configure $(am__configure_deps) \
- $(srcdir)/config.h.in $(srcdir)/../mkinstalldirs \
- $(srcdir)/omp.h.in $(srcdir)/omp_lib.h.in \
- $(srcdir)/omp_lib.f90.in $(srcdir)/libgomp_f.h.in \
- $(srcdir)/libgomp.spec.in $(srcdir)/../depcomp
@PLUGIN_NVPTX_TRUE@am__append_1 = libgomp-plugin-nvptx.la
@PLUGIN_HSA_TRUE@am__append_2 = libgomp-plugin-hsa.la
-@USE_FORTRAN_TRUE@am__append_3 = openacc.f90
+@PLUGIN_GCN_TRUE@am__append_3 = libgomp-plugin-gcn.la
+@USE_FORTRAN_TRUE@am__append_4 = openacc.f90
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+ $(top_srcdir)/../config/ax_count_cpus.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/enable.m4 \
$(top_srcdir)/../config/futex.m4 \
@@ -101,7 +133,6 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/lthostflags.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/override.m4 \
- $(top_srcdir)/../config/stdint.m4 \
$(top_srcdir)/../config/tls.m4 $(top_srcdir)/../ltoptions.m4 \
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
@@ -109,6 +140,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/plugin/configfrag.ac $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
@@ -148,12 +181,27 @@ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(infodir)" \
"$(DESTDIR)$(toolexeclibdir)"
LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
am__DEPENDENCIES_1 =
+@PLUGIN_GCN_TRUE@libgomp_plugin_gcn_la_DEPENDENCIES = libgomp.la \
+@PLUGIN_GCN_TRUE@ $(am__DEPENDENCIES_1)
+@PLUGIN_GCN_TRUE@am_libgomp_plugin_gcn_la_OBJECTS = \
+@PLUGIN_GCN_TRUE@ libgomp_plugin_gcn_la-plugin-gcn.lo
+libgomp_plugin_gcn_la_OBJECTS = $(am_libgomp_plugin_gcn_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libgomp_plugin_gcn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(libgomp_plugin_gcn_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libgomp_plugin_gcn_la_LDFLAGS) $(LDFLAGS) -o $@
+@PLUGIN_GCN_TRUE@am_libgomp_plugin_gcn_la_rpath = -rpath \
+@PLUGIN_GCN_TRUE@ $(toolexeclibdir)
@PLUGIN_HSA_TRUE@libgomp_plugin_hsa_la_DEPENDENCIES = libgomp.la \
@PLUGIN_HSA_TRUE@ $(am__DEPENDENCIES_1)
@PLUGIN_HSA_TRUE@am_libgomp_plugin_hsa_la_OBJECTS = \
@PLUGIN_HSA_TRUE@ libgomp_plugin_hsa_la-plugin-hsa.lo
libgomp_plugin_hsa_la_OBJECTS = $(am_libgomp_plugin_hsa_la_OBJECTS)
-libgomp_plugin_hsa_la_LINK = $(LIBTOOL) --tag=CC \
+libgomp_plugin_hsa_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(libgomp_plugin_hsa_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libgomp_plugin_hsa_la_LDFLAGS) $(LDFLAGS) -o $@
@@ -165,7 +213,7 @@ libgomp_plugin_hsa_la_LINK = $(LIBTOOL) --tag=CC \
@PLUGIN_NVPTX_TRUE@ libgomp_plugin_nvptx_la-plugin-nvptx.lo
libgomp_plugin_nvptx_la_OBJECTS = \
$(am_libgomp_plugin_nvptx_la_OBJECTS)
-libgomp_plugin_nvptx_la_LINK = $(LIBTOOL) --tag=CC \
+libgomp_plugin_nvptx_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(libgomp_plugin_nvptx_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libgomp_plugin_nvptx_la_LDFLAGS) $(LDFLAGS) -o $@
@@ -180,33 +228,86 @@ am_libgomp_la_OBJECTS = alloc.lo atomic.lo barrier.lo critical.lo \
sem.lo bar.lo ptrlock.lo time.lo fortran.lo affinity.lo \
target.lo splay-tree.lo libgomp-plugin.lo oacc-parallel.lo \
oacc-host.lo oacc-init.lo oacc-mem.lo oacc-async.lo \
- oacc-plugin.lo oacc-cuda.lo priority_queue.lo $(am__objects_1)
+ oacc-plugin.lo oacc-cuda.lo priority_queue.lo affinity-fmt.lo \
+ teams.lo oacc-profiling.lo oacc-target.lo $(am__objects_1)
libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
CCLD = $(CC)
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
FCCOMPILE = $(FC) $(AM_FCFLAGS) $(FCFLAGS)
-LTFCCOMPILE = $(LIBTOOL) --tag=FC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(FC) $(AM_FCFLAGS) $(FCFLAGS)
+LTFCCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=FC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(FC) $(AM_FCFLAGS) $(FCFLAGS)
+AM_V_FC = $(am__v_FC_@AM_V@)
+am__v_FC_ = $(am__v_FC_@AM_DEFAULT_V@)
+am__v_FC_0 = @echo " FC " $@;
+am__v_FC_1 =
FCLD = $(FC)
-FCLINK = $(LIBTOOL) --tag=FC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(FCLD) $(AM_FCFLAGS) $(FCFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
-SOURCES = $(libgomp_plugin_hsa_la_SOURCES) \
+FCLINK = $(LIBTOOL) $(AM_V_lt) --tag=FC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(FCLD) $(AM_FCFLAGS) $(FCFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_FCLD = $(am__v_FCLD_@AM_V@)
+am__v_FCLD_ = $(am__v_FCLD_@AM_DEFAULT_V@)
+am__v_FCLD_0 = @echo " FCLD " $@;
+am__v_FCLD_1 =
+SOURCES = $(libgomp_plugin_gcn_la_SOURCES) \
+ $(libgomp_plugin_hsa_la_SOURCES) \
$(libgomp_plugin_nvptx_la_SOURCES) $(libgomp_la_SOURCES)
-MULTISRCTOP =
-MULTIBUILDTOP =
-MULTIDIRS =
-MULTISUBDIR =
-MULTIDO = true
-MULTICLEAN = true
+AM_V_DVIPS = $(am__v_DVIPS_@AM_V@)
+am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@)
+am__v_DVIPS_0 = @echo " DVIPS " $@;
+am__v_DVIPS_1 =
+AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@)
+am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@)
+am__v_MAKEINFO_0 = @echo " MAKEINFO" $@;
+am__v_MAKEINFO_1 =
+AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@)
+am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@)
+am__v_INFOHTML_0 = @echo " INFOHTML" $@;
+am__v_INFOHTML_1 =
+AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@)
+am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@)
+am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@;
+am__v_TEXI2DVI_1 =
+AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@)
+am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@)
+am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@;
+am__v_TEXI2PDF_1 =
+AM_V_texinfo = $(am__v_texinfo_@AM_V@)
+am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@)
+am__v_texinfo_0 = -q
+am__v_texinfo_1 =
+AM_V_texidevnull = $(am__v_texidevnull_@AM_V@)
+am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@)
+am__v_texidevnull_0 = > /dev/null
+am__v_texidevnull_1 =
INFO_DEPS = libgomp.info
am__TEXINFO_TEX_DIR = $(srcdir)/../gcc/doc/include
DVIS = libgomp.dvi
@@ -219,13 +320,14 @@ TEXI2PDF = $(TEXI2DVI) --pdf --batch
MAKEINFOHTML = $(MAKEINFO) --html
AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
DVIPS = dvips
-RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
- html-recursive info-recursive install-data-recursive \
- install-dvi-recursive install-exec-recursive \
- install-html-recursive install-info-recursive \
- install-pdf-recursive install-ps-recursive install-recursive \
- installcheck-recursive installdirs-recursive pdf-recursive \
- ps-recursive uninstall-recursive
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -235,13 +337,37 @@ HEADERS = $(nodist_finclude_HEADERS) $(nodist_libsubinclude_HEADERS) \
$(nodist_noinst_HEADERS) $(nodist_toolexeclib_HEADERS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
-AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
- $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ cscope
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
+CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
@@ -252,6 +378,7 @@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CPU_COUNT = @CPU_COUNT@
CUDA_DRIVER_INCLUDE = @CUDA_DRIVER_INCLUDE@
CUDA_DRIVER_LIB = @CUDA_DRIVER_LIB@
CYGPATH_W = @CYGPATH_W@
@@ -314,6 +441,10 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
+PLUGIN_GCN = @PLUGIN_GCN@
+PLUGIN_GCN_CPPFLAGS = @PLUGIN_GCN_CPPFLAGS@
+PLUGIN_GCN_LDFLAGS = @PLUGIN_GCN_LDFLAGS@
+PLUGIN_GCN_LIBS = @PLUGIN_GCN_LIBS@
PLUGIN_HSA = @PLUGIN_HSA@
PLUGIN_HSA_CPPFLAGS = @PLUGIN_HSA_CPPFLAGS@
PLUGIN_HSA_LDFLAGS = @PLUGIN_HSA_LDFLAGS@
@@ -380,6 +511,7 @@ mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
offload_additional_lib_paths = @offload_additional_lib_paths@
offload_additional_options = @offload_additional_options@
+offload_plugins = @offload_plugins@
offload_targets = @offload_targets@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
@@ -400,6 +532,7 @@ toolexeclibdir = @toolexeclibdir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = info-in-builddir
ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = testsuite
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
@@ -411,7 +544,8 @@ libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
AM_CPPFLAGS = $(addprefix -I, $(search_path))
AM_CFLAGS = $(XCFLAGS)
AM_LDFLAGS = $(XLDFLAGS) $(SECTION_LDFLAGS) $(OPT_LDFLAGS)
-toolexeclib_LTLIBRARIES = libgomp.la $(am__append_1) $(am__append_2)
+toolexeclib_LTLIBRARIES = libgomp.la $(am__append_1) $(am__append_2) \
+ $(am__append_3)
nodist_toolexeclib_HEADERS = libgomp.spec
# -Wc is only a libtool option.
@@ -436,7 +570,8 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c \
affinity.c target.c splay-tree.c libgomp-plugin.c \
oacc-parallel.c oacc-host.c oacc-init.c oacc-mem.c \
oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \
- $(am__append_3)
+ affinity-fmt.c teams.c oacc-profiling.c oacc-target.c \
+ $(am__append_4)
# Nvidia PTX OpenACC plugin.
@PLUGIN_NVPTX_TRUE@libgomp_plugin_nvptx_version_info = -version-info $(libtool_VERSION)
@@ -459,8 +594,20 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c \
@PLUGIN_HSA_TRUE@ $(lt_host_flags) $(PLUGIN_HSA_LDFLAGS)
@PLUGIN_HSA_TRUE@libgomp_plugin_hsa_la_LIBADD = libgomp.la $(PLUGIN_HSA_LIBS)
@PLUGIN_HSA_TRUE@libgomp_plugin_hsa_la_LIBTOOLFLAGS = --tag=disable-static
+
+# AMD GCN plugin
+@PLUGIN_GCN_TRUE@libgomp_plugin_gcn_version_info = -version-info $(libtool_VERSION)
+@PLUGIN_GCN_TRUE@libgomp_plugin_gcn_la_SOURCES = plugin/plugin-gcn.c
+@PLUGIN_GCN_TRUE@libgomp_plugin_gcn_la_CPPFLAGS = $(AM_CPPFLAGS) $(PLUGIN_GCN_CPPFLAGS) \
+@PLUGIN_GCN_TRUE@ -D_GNU_SOURCE
+
+@PLUGIN_GCN_TRUE@libgomp_plugin_gcn_la_LDFLAGS = \
+@PLUGIN_GCN_TRUE@ $(libgomp_plugin_gcn_version_info) \
+@PLUGIN_GCN_TRUE@ $(lt_host_flags) $(PLUGIN_GCN_LDFLAGS)
+@PLUGIN_GCN_TRUE@libgomp_plugin_gcn_la_LIBADD = libgomp.la $(PLUGIN_GCN_LIBS)
+@PLUGIN_GCN_TRUE@libgomp_plugin_gcn_la_LIBTOOLFLAGS = --tag=disable-static
nodist_noinst_HEADERS = libgomp_f.h
-nodist_libsubinclude_HEADERS = omp.h openacc.h
+nodist_libsubinclude_HEADERS = omp.h openacc.h acc_prof.h
@USE_FORTRAN_TRUE@nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod \
@USE_FORTRAN_TRUE@ openacc_lib.h openacc.f90 openacc.mod openacc_kinds.mod
@@ -487,8 +634,14 @@ info_TEXINFOS = libgomp.texi
# AM_CONDITIONAL on configure check ACX_CHECK_PROG_VER([MAKEINFO])
@BUILD_INFO_TRUE@STAMP_BUILD_INFO = stamp-build-info
-CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO) libgomp.info
+CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO)
MAINTAINERCLEANFILES = $(srcdir)/libgomp.info
+MULTISRCTOP =
+MULTIBUILDTOP =
+MULTIDIRS =
+MULTISUBDIR =
+MULTIDO = true
+MULTICLEAN = true
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -496,7 +649,7 @@ all: config.h
.SUFFIXES: .c .dvi .f90 .lo .o .obj .ps
am--refresh: Makefile
@:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/plugin/Makefrag.am $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/plugin/Makefrag.am $(top_srcdir)/../multilib.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -509,7 +662,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -519,7 +671,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
-$(top_srcdir)/plugin/Makefrag.am:
+$(top_srcdir)/plugin/Makefrag.am $(top_srcdir)/../multilib.am $(am__empty):
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
@@ -531,8 +683,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
config.h: stamp-h1
- @if test ! -f $@; then rm -f stamp-h1; else :; fi
- @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
+ @test -f $@ || rm -f stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
@@ -554,6 +706,7 @@ libgomp_f.h: $(top_builddir)/config.status $(srcdir)/libgomp_f.h.in
cd $(top_builddir) && $(SHELL) ./config.status $@
libgomp.spec: $(top_builddir)/config.status $(srcdir)/libgomp.spec.in
cd $(top_builddir) && $(SHELL) ./config.status $@
+
install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
@@ -580,18 +733,26 @@ uninstall-toolexeclibLTLIBRARIES:
clean-toolexeclibLTLIBRARIES:
-test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES)
- @list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
+ @list='$(toolexeclib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libgomp-plugin-gcn.la: $(libgomp_plugin_gcn_la_OBJECTS) $(libgomp_plugin_gcn_la_DEPENDENCIES) $(EXTRA_libgomp_plugin_gcn_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libgomp_plugin_gcn_la_LINK) $(am_libgomp_plugin_gcn_la_rpath) $(libgomp_plugin_gcn_la_OBJECTS) $(libgomp_plugin_gcn_la_LIBADD) $(LIBS)
+
libgomp-plugin-hsa.la: $(libgomp_plugin_hsa_la_OBJECTS) $(libgomp_plugin_hsa_la_DEPENDENCIES) $(EXTRA_libgomp_plugin_hsa_la_DEPENDENCIES)
- $(libgomp_plugin_hsa_la_LINK) $(am_libgomp_plugin_hsa_la_rpath) $(libgomp_plugin_hsa_la_OBJECTS) $(libgomp_plugin_hsa_la_LIBADD) $(LIBS)
+ $(AM_V_CCLD)$(libgomp_plugin_hsa_la_LINK) $(am_libgomp_plugin_hsa_la_rpath) $(libgomp_plugin_hsa_la_OBJECTS) $(libgomp_plugin_hsa_la_LIBADD) $(LIBS)
+
libgomp-plugin-nvptx.la: $(libgomp_plugin_nvptx_la_OBJECTS) $(libgomp_plugin_nvptx_la_DEPENDENCIES) $(EXTRA_libgomp_plugin_nvptx_la_DEPENDENCIES)
- $(libgomp_plugin_nvptx_la_LINK) $(am_libgomp_plugin_nvptx_la_rpath) $(libgomp_plugin_nvptx_la_OBJECTS) $(libgomp_plugin_nvptx_la_LIBADD) $(LIBS)
+ $(AM_V_CCLD)$(libgomp_plugin_nvptx_la_LINK) $(am_libgomp_plugin_nvptx_la_rpath) $(libgomp_plugin_nvptx_la_OBJECTS) $(libgomp_plugin_nvptx_la_LIBADD) $(LIBS)
+
libgomp.la: $(libgomp_la_OBJECTS) $(libgomp_la_DEPENDENCIES) $(EXTRA_libgomp_la_DEPENDENCIES)
- $(libgomp_la_LINK) -rpath $(toolexeclibdir) $(libgomp_la_OBJECTS) $(libgomp_la_LIBADD) $(LIBS)
+ $(AM_V_GEN)$(libgomp_la_LINK) -rpath $(toolexeclibdir) $(libgomp_la_OBJECTS) $(libgomp_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -599,6 +760,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affinity-fmt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affinity.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic.Plo@am__quote@
@@ -613,6 +775,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iter_ull.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgomp-plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgomp_plugin_gcn_la-plugin-gcn.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgomp_plugin_hsa_la-plugin-hsa.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgomp_plugin_nvptx_la-plugin-nvptx.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lock.Plo@am__quote@
@@ -626,6 +789,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-mem.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-parallel.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-profiling.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-target.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ordered.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parallel.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/priority_queue.Plo@am__quote@
@@ -638,52 +803,60 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/team.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/teams.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/work.Plo@am__quote@
.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+libgomp_plugin_gcn_la-plugin-gcn.lo: plugin/plugin-gcn.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgomp_plugin_gcn_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgomp_plugin_gcn_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgomp_plugin_gcn_la-plugin-gcn.lo -MD -MP -MF $(DEPDIR)/libgomp_plugin_gcn_la-plugin-gcn.Tpo -c -o libgomp_plugin_gcn_la-plugin-gcn.lo `test -f 'plugin/plugin-gcn.c' || echo '$(srcdir)/'`plugin/plugin-gcn.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgomp_plugin_gcn_la-plugin-gcn.Tpo $(DEPDIR)/libgomp_plugin_gcn_la-plugin-gcn.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin/plugin-gcn.c' object='libgomp_plugin_gcn_la-plugin-gcn.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgomp_plugin_gcn_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgomp_plugin_gcn_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgomp_plugin_gcn_la-plugin-gcn.lo `test -f 'plugin/plugin-gcn.c' || echo '$(srcdir)/'`plugin/plugin-gcn.c
libgomp_plugin_hsa_la-plugin-hsa.lo: plugin/plugin-hsa.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(libgomp_plugin_hsa_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgomp_plugin_hsa_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgomp_plugin_hsa_la-plugin-hsa.lo -MD -MP -MF $(DEPDIR)/libgomp_plugin_hsa_la-plugin-hsa.Tpo -c -o libgomp_plugin_hsa_la-plugin-hsa.lo `test -f 'plugin/plugin-hsa.c' || echo '$(srcdir)/'`plugin/plugin-hsa.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgomp_plugin_hsa_la-plugin-hsa.Tpo $(DEPDIR)/libgomp_plugin_hsa_la-plugin-hsa.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin/plugin-hsa.c' object='libgomp_plugin_hsa_la-plugin-hsa.lo' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgomp_plugin_hsa_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgomp_plugin_hsa_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgomp_plugin_hsa_la-plugin-hsa.lo -MD -MP -MF $(DEPDIR)/libgomp_plugin_hsa_la-plugin-hsa.Tpo -c -o libgomp_plugin_hsa_la-plugin-hsa.lo `test -f 'plugin/plugin-hsa.c' || echo '$(srcdir)/'`plugin/plugin-hsa.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgomp_plugin_hsa_la-plugin-hsa.Tpo $(DEPDIR)/libgomp_plugin_hsa_la-plugin-hsa.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin/plugin-hsa.c' object='libgomp_plugin_hsa_la-plugin-hsa.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(libgomp_plugin_hsa_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgomp_plugin_hsa_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgomp_plugin_hsa_la-plugin-hsa.lo `test -f 'plugin/plugin-hsa.c' || echo '$(srcdir)/'`plugin/plugin-hsa.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgomp_plugin_hsa_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgomp_plugin_hsa_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgomp_plugin_hsa_la-plugin-hsa.lo `test -f 'plugin/plugin-hsa.c' || echo '$(srcdir)/'`plugin/plugin-hsa.c
libgomp_plugin_nvptx_la-plugin-nvptx.lo: plugin/plugin-nvptx.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(libgomp_plugin_nvptx_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgomp_plugin_nvptx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgomp_plugin_nvptx_la-plugin-nvptx.lo -MD -MP -MF $(DEPDIR)/libgomp_plugin_nvptx_la-plugin-nvptx.Tpo -c -o libgomp_plugin_nvptx_la-plugin-nvptx.lo `test -f 'plugin/plugin-nvptx.c' || echo '$(srcdir)/'`plugin/plugin-nvptx.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgomp_plugin_nvptx_la-plugin-nvptx.Tpo $(DEPDIR)/libgomp_plugin_nvptx_la-plugin-nvptx.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin/plugin-nvptx.c' object='libgomp_plugin_nvptx_la-plugin-nvptx.lo' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgomp_plugin_nvptx_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgomp_plugin_nvptx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgomp_plugin_nvptx_la-plugin-nvptx.lo -MD -MP -MF $(DEPDIR)/libgomp_plugin_nvptx_la-plugin-nvptx.Tpo -c -o libgomp_plugin_nvptx_la-plugin-nvptx.lo `test -f 'plugin/plugin-nvptx.c' || echo '$(srcdir)/'`plugin/plugin-nvptx.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgomp_plugin_nvptx_la-plugin-nvptx.Tpo $(DEPDIR)/libgomp_plugin_nvptx_la-plugin-nvptx.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin/plugin-nvptx.c' object='libgomp_plugin_nvptx_la-plugin-nvptx.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(libgomp_plugin_nvptx_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgomp_plugin_nvptx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgomp_plugin_nvptx_la-plugin-nvptx.lo `test -f 'plugin/plugin-nvptx.c' || echo '$(srcdir)/'`plugin/plugin-nvptx.c
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgomp_plugin_nvptx_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgomp_plugin_nvptx_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgomp_plugin_nvptx_la-plugin-nvptx.lo `test -f 'plugin/plugin-nvptx.c' || echo '$(srcdir)/'`plugin/plugin-nvptx.c
.f90.o:
- $(FCCOMPILE) -c -o $@ $<
+ $(AM_V_FC)$(FCCOMPILE) -c -o $@ $<
.f90.obj:
- $(FCCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+ $(AM_V_FC)$(FCCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.f90.lo:
- $(LTFCCOMPILE) -c -o $@ $<
+ $(AM_V_FC)$(LTFCCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
@@ -694,49 +867,30 @@ clean-libtool:
distclean-libtool:
-rm -f libtool config.lt
-# GNU Make needs to see an explicit $(MAKE) variable in the command it
-# runs to enable its job server during parallel builds. Hence the
-# comments below.
-all-multi:
- $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
-install-multi:
- $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do # $(MAKE)
-
-mostlyclean-multi:
- $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean # $(MAKE)
-clean-multi:
- $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean # $(MAKE)
-distclean-multi:
- $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
-maintainer-clean-multi:
- $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
-
libgomp.dvi: libgomp.texi
- TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
- $(TEXI2DVI) -o $@ `test -f 'libgomp.texi' || echo '$(srcdir)/'`libgomp.texi
+ $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \
+ `test -f 'libgomp.texi' || echo '$(srcdir)/'`libgomp.texi
libgomp.pdf: libgomp.texi
- TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
- $(TEXI2PDF) -o $@ `test -f 'libgomp.texi' || echo '$(srcdir)/'`libgomp.texi
+ $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \
+ `test -f 'libgomp.texi' || echo '$(srcdir)/'`libgomp.texi
libgomp.html: libgomp.texi
- rm -rf $(@:.html=.htp)
- if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp)
+ $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
-o $(@:.html=.htp) `test -f 'libgomp.texi' || echo '$(srcdir)/'`libgomp.texi; \
then \
- rm -rf $@; \
- if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
- mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+ rm -rf $@ && mv $(@:.html=.htp) $@; \
else \
- if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
- rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
- exit 1; \
+ rm -rf $(@:.html=.htp); exit 1; \
fi
.dvi.ps:
- TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
- $(DVIPS) -o $@ $<
+ $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(DVIPS) $(AM_V_texinfo) -o $@ $<
uninstall-dvi-am:
@$(NORMAL_UNINSTALL)
@@ -815,10 +969,7 @@ dist-info: $(INFO_DEPS)
done
mostlyclean-aminfo:
- -rm -rf libgomp.aux libgomp.cp libgomp.cps libgomp.fn libgomp.fns \
- libgomp.ky libgomp.kys libgomp.log libgomp.pg libgomp.pgs \
- libgomp.tmp libgomp.toc libgomp.tp libgomp.tps libgomp.vr \
- libgomp.vrs
+ -rm -rf libgomp.t2d libgomp.t2p
clean-aminfo:
-test -z "libgomp.dvi libgomp.pdf libgomp.ps libgomp.html" \
@@ -895,22 +1046,25 @@ uninstall-nodist_toolexeclibHEADERS:
dir='$(DESTDIR)$(toolexeclibdir)'; $(am__uninstall_files_from_dir)
# This directory's subdirectories are mostly independent; you can cd
-# into them and run `make' without going through this Makefile.
-# To change the values of `make' variables: instead of editing Makefiles,
-# (1) if the variable is set in `config.status', edit `config.status'
-# (which will cause the Makefiles to be regenerated when you run `make');
-# (2) otherwise, pass the desired values on the `make' command line.
-$(RECURSIVE_TARGETS):
- @fail= failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
@@ -925,57 +1079,12 @@ $(RECURSIVE_TARGETS):
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
-$(RECURSIVE_CLEAN_TARGETS):
- @fail= failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
- dot_seen=no; \
- case "$@" in \
- distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
- *) list='$(SUBDIRS)' ;; \
- esac; \
- rev=''; for subdir in $$list; do \
- if test "$$subdir" = "."; then :; else \
- rev="$$subdir $$rev"; \
- fi; \
- done; \
- rev="$$rev ."; \
- target=`echo $@ | sed s/-recursive//`; \
- for subdir in $$rev; do \
- echo "Making $$target in $$subdir"; \
- if test "$$subdir" = "."; then \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done && test -z "$$fail"
-tags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
- done
-ctags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
- done
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
@@ -991,12 +1100,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ $(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
@@ -1008,15 +1112,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$$unique; \
fi; \
fi
-ctags: CTAGS
-CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
@@ -1025,13 +1125,35 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
check-am: all-am
check: check-recursive
-all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) all-multi $(HEADERS) \
- config.h all-local
+all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) $(HEADERS) config.h \
+ all-local
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(infodir)" "$(DESTDIR)$(fincludedir)" "$(DESTDIR)$(libsubincludedir)" "$(DESTDIR)$(toolexeclibdir)"; do \
@@ -1069,17 +1191,17 @@ maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-clean: clean-multi clean-recursive
+clean: clean-recursive
-clean-am: clean-aminfo clean-generic clean-libtool \
+clean-am: clean-aminfo clean-generic clean-libtool clean-local \
clean-toolexeclibLTLIBRARIES mostlyclean-am
-distclean: distclean-multi distclean-recursive
+distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
- distclean-hdr distclean-libtool distclean-tags
+ distclean-hdr distclean-libtool distclean-local distclean-tags
dvi: dvi-recursive
@@ -1113,7 +1235,7 @@ install-dvi-am: $(DVIS)
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
done
-install-exec-am: install-multi install-nodist_toolexeclibHEADERS \
+install-exec-am: install-exec-local install-nodist_toolexeclibHEADERS \
install-toolexeclibLTLIBRARIES
install-html: install-html-recursive
@@ -1214,18 +1336,18 @@ install-ps-am: $(PSS)
$(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
installcheck-am:
-maintainer-clean: maintainer-clean-multi maintainer-clean-recursive
+maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-aminfo \
- maintainer-clean-generic
+ maintainer-clean-generic maintainer-clean-local
-mostlyclean: mostlyclean-multi mostlyclean-recursive
+mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-aminfo mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool
+ mostlyclean-generic mostlyclean-libtool mostlyclean-local
pdf: pdf-recursive
@@ -1241,37 +1363,36 @@ uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
uninstall-nodist_toolexeclibHEADERS uninstall-pdf-am \
uninstall-ps-am uninstall-toolexeclibLTLIBRARIES
-.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all all-multi \
- clean-multi ctags-recursive distclean-multi install-am \
- install-multi install-strip maintainer-clean-multi \
- mostlyclean-multi tags-recursive
-
-.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
- all all-am all-local all-multi am--refresh check check-am \
- clean clean-aminfo clean-generic clean-libtool clean-multi \
- clean-toolexeclibLTLIBRARIES ctags ctags-recursive dist-info \
- distclean distclean-compile distclean-generic distclean-hdr \
- distclean-libtool distclean-multi distclean-tags dvi dvi-am \
- html html-am info info-am install install-am install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-man install-multi \
- install-nodist_fincludeHEADERS \
+.MAKE: $(am__recursive_targets) all install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \
+ am--refresh check check-am clean clean-aminfo clean-cscope \
+ clean-generic clean-libtool clean-local \
+ clean-toolexeclibLTLIBRARIES cscope cscopelist-am ctags \
+ ctags-am dist-info distclean distclean-compile \
+ distclean-generic distclean-hdr distclean-libtool \
+ distclean-local distclean-tags dvi dvi-am html html-am info \
+ info-am install install-am install-data install-data-am \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-exec-local install-html install-html-am install-info \
+ install-info-am install-man install-nodist_fincludeHEADERS \
install-nodist_libsubincludeHEADERS \
install-nodist_toolexeclibHEADERS install-pdf install-pdf-am \
install-ps install-ps-am install-strip \
install-toolexeclibLTLIBRARIES installcheck installcheck-am \
installdirs installdirs-am maintainer-clean \
maintainer-clean-aminfo maintainer-clean-generic \
- maintainer-clean-multi mostlyclean mostlyclean-aminfo \
+ maintainer-clean-local mostlyclean mostlyclean-aminfo \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- mostlyclean-multi pdf pdf-am ps ps-am tags tags-recursive \
- uninstall uninstall-am uninstall-dvi-am uninstall-html-am \
+ mostlyclean-local pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am uninstall-dvi-am uninstall-html-am \
uninstall-info-am uninstall-nodist_fincludeHEADERS \
uninstall-nodist_libsubincludeHEADERS \
uninstall-nodist_toolexeclibHEADERS uninstall-pdf-am \
uninstall-ps-am uninstall-toolexeclibLTLIBRARIES
+.PRECIOUS: Makefile
+
vpath % $(strip $(search_path))
@@ -1313,6 +1434,33 @@ stamp-build-info: libgomp.texi
$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -o libgomp.info $(srcdir)/libgomp.texi
@touch $@
+# GNU Make needs to see an explicit $(MAKE) variable in the command it
+# runs to enable its job server during parallel builds. Hence the
+# comments below.
+all-multi:
+ $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
+install-multi:
+ $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do # $(MAKE)
+mostlyclean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean # $(MAKE)
+clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean # $(MAKE)
+distclean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
+maintainer-clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
+
+.MAKE .PHONY: all-multi clean-multi distclean-multi install-am \
+ install-multi maintainer-clean-multi mostlyclean-multi
+
+install-exec-local: install-multi
+
+all-local: all-multi
+mostlyclean-local: mostlyclean-multi
+clean-local: clean-multi
+distclean-local: distclean-multi
+maintainer-clean-local: maintainer-clean-multi
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/libgomp/acc_prof.h b/libgomp/acc_prof.h
new file mode 100644
index 00000000000..c7a2197d11a
--- /dev/null
+++ b/libgomp/acc_prof.h
@@ -0,0 +1,252 @@
+/* OpenACC Profiling Interface
+
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+ Contributed by Mentor, a Siemens Business.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _ACC_PROF_H
+#define _ACC_PROF_H 1
+
+
+/* The OpenACC specification doesn't say so explicitly, but as its Profiling
+ Interface explicitly makes use of, for example, <openacc.h>'s
+ 'acc_device_t', we supposedly are to '#include' that file here. */
+
+#include <openacc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Events. */
+
+typedef enum acc_event_t
+{
+ acc_ev_none = 0,
+ acc_ev_device_init_start,
+ acc_ev_device_init_end,
+ acc_ev_device_shutdown_start,
+ acc_ev_device_shutdown_end,
+ acc_ev_runtime_shutdown,
+ acc_ev_create,
+ acc_ev_delete,
+ acc_ev_alloc,
+ acc_ev_free,
+ acc_ev_enter_data_start,
+ acc_ev_enter_data_end,
+ acc_ev_exit_data_start,
+ acc_ev_exit_data_end,
+ acc_ev_update_start,
+ acc_ev_update_end,
+ acc_ev_compute_construct_start,
+ acc_ev_compute_construct_end,
+ acc_ev_enqueue_launch_start,
+ acc_ev_enqueue_launch_end,
+ acc_ev_enqueue_upload_start,
+ acc_ev_enqueue_upload_end,
+ acc_ev_enqueue_download_start,
+ acc_ev_enqueue_download_end,
+ acc_ev_wait_start,
+ acc_ev_wait_end,
+ acc_ev_last
+} acc_event_t;
+
+
+/* Callbacks Signature. */
+
+/* "The datatype 'ssize_t' means a signed 32-bit integer for a 32-bit binary
+ and a 64-bit integer for a 64-bit binary". */
+typedef signed long int _acc_prof_ssize_t;
+/* "The datatype 'size_t' means an unsigned 32-bit integer for a 32-bit binary
+ and a 64-bit integer for a 64-bit binary". */
+typedef unsigned long int _acc_prof_size_t;
+/* "The datatype 'int' means a 32-bit integer for both 32-bit and 64-bit
+ binaries". */
+typedef int _acc_prof_int_t;
+
+/* Internal helpers: a struct's 'valid_bytes' may be less than its 'sizeof'. */
+#define _ACC_PROF_VALID_BYTES_STRUCT(_struct, _lastfield, _valid_bytes_lastfield) \
+ offsetof (_struct, _lastfield) + (_valid_bytes_lastfield)
+#if 0 /* Untested. */
+#define _ACC_PROF_VALID_BYTES_TYPE_N(_type, _n, _valid_bytes_type) \
+ ((_n - 1) * sizeof (_type) + (_valid_bytes_type))
+#endif
+#define _ACC_PROF_VALID_BYTES_BASICTYPE(_basictype) \
+ (sizeof (_basictype))
+
+typedef struct acc_prof_info
+{
+ acc_event_t event_type;
+ _acc_prof_int_t valid_bytes;
+ _acc_prof_int_t version;
+ acc_device_t device_type;
+ _acc_prof_int_t device_number;
+ _acc_prof_int_t thread_id;
+ _acc_prof_ssize_t async;
+ _acc_prof_ssize_t async_queue;
+ const char *src_file;
+ const char *func_name;
+ _acc_prof_int_t line_no, end_line_no;
+ _acc_prof_int_t func_line_no, func_end_line_no;
+#define _ACC_PROF_INFO_VALID_BYTES \
+ _ACC_PROF_VALID_BYTES_STRUCT (acc_prof_info, func_end_line_no, \
+ _ACC_PROF_VALID_BYTES_BASICTYPE (_acc_prof_int_t))
+} acc_prof_info;
+
+/* We implement the OpenACC 2.6 Profiling Interface. */
+
+#define _ACC_PROF_INFO_VERSION 201711
+
+typedef enum acc_construct_t
+{
+ acc_construct_parallel = 0,
+ acc_construct_kernels,
+ acc_construct_loop,
+ acc_construct_data,
+ acc_construct_enter_data,
+ acc_construct_exit_data,
+ acc_construct_host_data,
+ acc_construct_atomic,
+ acc_construct_declare,
+ acc_construct_init,
+ acc_construct_shutdown,
+ acc_construct_set,
+ acc_construct_update,
+ acc_construct_routine,
+ acc_construct_wait,
+ acc_construct_runtime_api,
+ acc_construct_serial
+} acc_construct_t;
+
+typedef struct acc_data_event_info
+{
+ acc_event_t event_type;
+ _acc_prof_int_t valid_bytes;
+ acc_construct_t parent_construct;
+ _acc_prof_int_t implicit;
+ void *tool_info;
+ const char *var_name;
+ _acc_prof_size_t bytes;
+ const void *host_ptr;
+ const void *device_ptr;
+#define _ACC_DATA_EVENT_INFO_VALID_BYTES \
+ _ACC_PROF_VALID_BYTES_STRUCT (acc_data_event_info, device_ptr, \
+ _ACC_PROF_VALID_BYTES_BASICTYPE (void *))
+} acc_data_event_info;
+
+typedef struct acc_launch_event_info
+{
+ acc_event_t event_type;
+ _acc_prof_int_t valid_bytes;
+ acc_construct_t parent_construct;
+ _acc_prof_int_t implicit;
+ void *tool_info;
+ const char *kernel_name;
+ _acc_prof_size_t num_gangs, num_workers, vector_length;
+#define _ACC_LAUNCH_EVENT_INFO_VALID_BYTES \
+ _ACC_PROF_VALID_BYTES_STRUCT (acc_launch_event_info, vector_length, \
+ _ACC_PROF_VALID_BYTES_BASICTYPE (_acc_prof_size_t))
+} acc_launch_event_info;
+
+typedef struct acc_other_event_info
+{
+ acc_event_t event_type;
+ _acc_prof_int_t valid_bytes;
+ acc_construct_t parent_construct;
+ _acc_prof_int_t implicit;
+ void *tool_info;
+#define _ACC_OTHER_EVENT_INFO_VALID_BYTES \
+ _ACC_PROF_VALID_BYTES_STRUCT (acc_other_event_info, tool_info, \
+ _ACC_PROF_VALID_BYTES_BASICTYPE (void *))
+} acc_other_event_info;
+
+typedef union acc_event_info
+{
+ acc_event_t event_type;
+ acc_data_event_info data_event;
+ acc_launch_event_info launch_event;
+ acc_other_event_info other_event;
+} acc_event_info;
+
+typedef enum acc_device_api
+{
+ acc_device_api_none = 0,
+ acc_device_api_cuda,
+ acc_device_api_opencl,
+ acc_device_api_coi,
+ acc_device_api_other
+} acc_device_api;
+
+typedef struct acc_api_info
+{
+ acc_device_api device_api;
+ _acc_prof_int_t valid_bytes;
+ acc_device_t device_type;
+ _acc_prof_int_t vendor;
+ const void *device_handle;
+ const void *context_handle;
+ const void *async_handle;
+#define _ACC_API_INFO_VALID_BYTES \
+ _ACC_PROF_VALID_BYTES_STRUCT (acc_api_info, async_handle, \
+ _ACC_PROF_VALID_BYTES_BASICTYPE (void *))
+} acc_api_info;
+
+/* Don't tag 'acc_prof_callback' as '__GOACC_NOTHROW': these functions are
+ provided by user code, and must be expected to do anything. */
+typedef void (*acc_prof_callback) (acc_prof_info *, acc_event_info *,
+ acc_api_info *);
+
+
+/* Loading the Library. */
+
+typedef enum acc_register_t
+{
+ acc_reg = 0,
+ acc_toggle = 1,
+ acc_toggle_per_thread = 2
+} acc_register_t;
+
+typedef void (*acc_prof_reg) (acc_event_t, acc_prof_callback, acc_register_t);
+extern void acc_prof_register (acc_event_t, acc_prof_callback,
+ acc_register_t) __GOACC_NOTHROW;
+extern void acc_prof_unregister (acc_event_t, acc_prof_callback,
+ acc_register_t) __GOACC_NOTHROW;
+typedef void (*acc_query_fn) ();
+typedef acc_query_fn (*acc_prof_lookup_func) (const char *);
+extern acc_query_fn acc_prof_lookup (const char *) __GOACC_NOTHROW;
+/* Don't tag 'acc_register_library' as '__GOACC_NOTHROW': this function can be
+ overridden by user code, and must be expected to do anything. */
+extern void acc_register_library (acc_prof_reg, acc_prof_reg,
+ acc_prof_lookup_func);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _ACC_PROF_H */
diff --git a/libgomp/acinclude.m4 b/libgomp/acinclude.m4
index 51f4f30256c..dbf54d06db9 100644
--- a/libgomp/acinclude.m4
+++ b/libgomp/acinclude.m4
@@ -154,7 +154,7 @@ AC_DEFUN([LIBGOMP_CHECK_LINKER_FEATURES], [
fi
changequote(,)
ldver=`$LD --version 2>/dev/null |
- sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
+ sed -e 's/[. ][0-9]\{8\}$//;s/.* \([^ ]\{1,\}\)$/\1/; q'`
changequote([,])
libgomp_gnu_ld_version=`echo $ldver | \
$AWK -F. '{ if (NF<3) [$]3=0; print ([$]1*100+[$]2)*100+[$]3 }'`
diff --git a/libgomp/aclocal.m4 b/libgomp/aclocal.m4
index a1f51f27651..12125996425 100644
--- a/libgomp/aclocal.m4
+++ b/libgomp/aclocal.m4
@@ -1,8 +1,7 @@
-# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
+# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
-# Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -12,33 +11,31 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
-[m4_warning([this file was generated for autoconf 2.64.
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 2002-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.11'
+[am__api_version='1.15'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.6], [],
+m4_if([$1], [1.15.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -54,24 +51,22 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.6])dnl
+[AM_AUTOMAKE_VERSION([1.15.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
@@ -90,7 +85,7 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
+# harmless because $srcdir is '.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
@@ -108,30 +103,26 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 9
-
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ(2.52)dnl
- ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
@@ -150,16 +141,14 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
-# 2010, 2011 Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 12
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
@@ -169,7 +158,7 @@ fi])])
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
@@ -182,12 +171,13 @@ AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
-ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
- [$1], CXX, [depcc="$CXX" am_compiler_list=],
- [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], UPC, [depcc="$UPC" am_compiler_list=],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
@@ -195,8 +185,8 @@ AC_CACHE_CHECK([dependency style of $depcc],
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
@@ -236,16 +226,16 @@ AC_CACHE_CHECK([dependency style of $depcc],
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -254,8 +244,8 @@ AC_CACHE_CHECK([dependency style of $depcc],
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
if test "x$enable_dependency_tracking" = xyes; then
continue
else
@@ -263,7 +253,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -311,7 +301,7 @@ AM_CONDITIONAL([am__fastdep$1], [
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
@@ -321,9 +311,13 @@ AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[ --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors])
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
@@ -338,20 +332,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-#serial 5
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[{
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
@@ -364,7 +356,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
+ # We used to match only the files named 'Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
@@ -376,21 +368,19 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
+ # from the Makefile without running 'make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
+ test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
@@ -408,7 +398,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each `.P' file that we will
+# is enabled. FIXME. This creates each '.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
@@ -418,18 +408,21 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# Do all the work for Automake. -*- Autoconf -*-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 16
-
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
@@ -442,7 +435,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
+[AC_PREREQ([2.65])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
@@ -471,33 +464,42 @@ AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -506,34 +508,82 @@ _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
- [_AM_DEPENDENCIES(CC)],
- [define([AC_PROG_CC],
- defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [_AM_DEPENDENCIES(CXX)],
- [define([AC_PROG_CXX],
- defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES(OBJC)],
- [define([AC_PROG_OBJC],
- defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
-dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
])
-dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
@@ -555,21 +605,18 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
-# Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
-
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -577,25 +624,22 @@ if test x"${install_sh}" != xset; then
install_sh="\${SHELL} $am_aux_dir/install-sh"
esac
fi
-AC_SUBST(install_sh)])
+AC_SUBST([install_sh])])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
-# 2011 Free Software Foundation, Inc.
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 5
-
# AM_MAINTAINER_MODE([DEFAULT-MODE])
# ----------------------------------
# Control maintainer-specific portions of Makefiles.
-# Default is to disable them, unless `enable' is passed literally.
-# For symmetry, `disable' may be passed as well. Anyway, the user
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well. Anyway, the user
# can override the default with the --enable/--disable switch.
AC_DEFUN([AM_MAINTAINER_MODE],
[m4_case(m4_default([$1], [disable]),
@@ -606,10 +650,11 @@ AC_DEFUN([AM_MAINTAINER_MODE],
AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
dnl maintainer-mode's default is 'disable' unless 'enable' is passed
AC_ARG_ENABLE([maintainer-mode],
-[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
- (and sometimes confusing) to the casual installer],
- [USE_MAINTAINER_MODE=$enableval],
- [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+ am_maintainer_other[ make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer])],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
AC_MSG_RESULT([$USE_MAINTAINER_MODE])
AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
MAINT=$MAINTAINER_MODE_TRUE
@@ -617,18 +662,14 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
]
)
-AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-
# Check to see how 'make' treats includes. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 4
-
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
@@ -646,7 +687,7 @@ am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
+# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
@@ -673,15 +714,12 @@ rm -f confinc confmf
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1997-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 6
-
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
@@ -689,11 +727,10 @@ AC_DEFUN([AM_MISSING_PROG],
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
-
# AM_MISSING_HAS_RUN
# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
@@ -706,54 +743,22 @@ if test x"${MISSING+set}" != xset; then
esac
fi
# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
else
am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
+ AC_MSG_WARN(['missing' script is too old or missing])
fi
])
-# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
-# Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 1
-
-# AM_PROG_MKDIR_P
-# ---------------
-# Check for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
- [[\\/$]]* | ?:[[\\/]]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 5
-
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
@@ -763,7 +768,7 @@ AC_DEFUN([_AM_MANGLE_OPTION],
# --------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
# _AM_SET_OPTIONS(OPTIONS)
# ------------------------
@@ -777,24 +782,82 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-# Check to make sure that the build environment is sane. -*- Autoconf -*-
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 5
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
@@ -805,32 +868,40 @@ case `pwd` in
esac
case $srcdir in
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
- AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
esac
-# Do `set' in a subshell so we don't clobber the current shell's
+# Do 'set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
-alias in your environment])
- fi
-
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
test "$[2]" = conftest.file
)
then
@@ -840,46 +911,118 @@ else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
-AC_MSG_RESULT(yes)])
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
-# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2009-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 1
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_STRIP
# ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
+# One issue with vendor 'install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
+# always use install-sh in "make install-strip", and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
+# Copyright (C) 2006-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 3
-
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
@@ -893,18 +1036,16 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
+# Copyright (C) 2004-2017 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
-
# _AM_PROG_TAR(FORMAT)
# --------------------
# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
#
# Substitute a variable $(am__tar) that is a command
# writing to stdout a FORMAT-tarball containing the directory
@@ -914,81 +1055,120 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
+#
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AC_SUBST([AMTAR], ['$${TAR-tar}'])
-m4_if([$1], [v7],
- [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
- [m4_case([$1], [ustar],, [pax],,
- [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
+
+# We'll loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar;
- do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
- # tar/untar a dummy directory, and stop if the command works
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
-done
-rm -rf conftest.dir
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
m4_include([../config/acx.m4])
+m4_include([../config/ax_count_cpus.m4])
m4_include([../config/depstand.m4])
m4_include([../config/enable.m4])
m4_include([../config/futex.m4])
@@ -996,7 +1176,6 @@ m4_include([../config/lead-dot.m4])
m4_include([../config/lthostflags.m4])
m4_include([../config/multi.m4])
m4_include([../config/override.m4])
-m4_include([../config/stdint.m4])
m4_include([../config/tls.m4])
m4_include([../ltoptions.m4])
m4_include([../ltsugar.m4])
diff --git a/libgomp/affinity-fmt.c b/libgomp/affinity-fmt.c
new file mode 100644
index 00000000000..d9c6e181233
--- /dev/null
+++ b/libgomp/affinity-fmt.c
@@ -0,0 +1,495 @@
+/* Copyright (C) 2018-2019 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "libgomp.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h> /* For PRIx64. */
+#endif
+#ifdef HAVE_UNAME
+#include <sys/utsname.h>
+#endif
+
+void
+gomp_print_string (const char *str, size_t len)
+{
+ fwrite (str, 1, len, stderr);
+}
+
+void
+gomp_set_affinity_format (const char *format, size_t len)
+{
+ if (len < gomp_affinity_format_len)
+ memcpy (gomp_affinity_format_var, format, len);
+ else
+ {
+ char *p;
+ if (gomp_affinity_format_len)
+ p = gomp_realloc (gomp_affinity_format_var, len + 1);
+ else
+ p = gomp_malloc (len + 1);
+ memcpy (p, format, len);
+ gomp_affinity_format_var = p;
+ gomp_affinity_format_len = len + 1;
+ }
+ gomp_affinity_format_var[len] = '\0';
+}
+
+void
+omp_set_affinity_format (const char *format)
+{
+ gomp_set_affinity_format (format, strlen (format));
+}
+
+size_t
+omp_get_affinity_format (char *buffer, size_t size)
+{
+ size_t len = strlen (gomp_affinity_format_var);
+ if (size)
+ {
+ if (len < size)
+ memcpy (buffer, gomp_affinity_format_var, len + 1);
+ else
+ {
+ memcpy (buffer, gomp_affinity_format_var, size - 1);
+ buffer[size - 1] = '\0';
+ }
+ }
+ return len;
+}
+
+void
+gomp_display_string (char *buffer, size_t size, size_t *ret,
+ const char *str, size_t len)
+{
+ size_t r = *ret;
+ if (size && r < size)
+ {
+ size_t l = len;
+ if (size - r < len)
+ l = size - r;
+ memcpy (buffer + r, str, l);
+ }
+ *ret += len;
+ if (__builtin_expect (r > *ret, 0))
+ gomp_fatal ("overflow in omp_capture_affinity");
+}
+
+static void
+gomp_display_repeat (char *buffer, size_t size, size_t *ret,
+ char c, size_t len)
+{
+ size_t r = *ret;
+ if (size && r < size)
+ {
+ size_t l = len;
+ if (size - r < len)
+ l = size - r;
+ memset (buffer + r, c, l);
+ }
+ *ret += len;
+ if (__builtin_expect (r > *ret, 0))
+ gomp_fatal ("overflow in omp_capture_affinity");
+}
+
+static void
+gomp_display_num (char *buffer, size_t size, size_t *ret,
+ bool zero, bool right, size_t sz, char *buf)
+{
+ size_t l = strlen (buf);
+ if (sz == (size_t) -1 || l >= sz)
+ {
+ gomp_display_string (buffer, size, ret, buf, l);
+ return;
+ }
+ if (zero)
+ {
+ if (buf[0] == '-')
+ gomp_display_string (buffer, size, ret, buf, 1);
+ else if (buf[0] == '0' && buf[1] == 'x')
+ gomp_display_string (buffer, size, ret, buf, 2);
+ gomp_display_repeat (buffer, size, ret, '0', sz - l);
+ if (buf[0] == '-')
+ gomp_display_string (buffer, size, ret, buf + 1, l - 1);
+ else if (buf[0] == '0' && buf[1] == 'x')
+ gomp_display_string (buffer, size, ret, buf + 2, l - 2);
+ else
+ gomp_display_string (buffer, size, ret, buf, l);
+ }
+ else if (right)
+ {
+ gomp_display_repeat (buffer, size, ret, ' ', sz - l);
+ gomp_display_string (buffer, size, ret, buf, l);
+ }
+ else
+ {
+ gomp_display_string (buffer, size, ret, buf, l);
+ gomp_display_repeat (buffer, size, ret, ' ', sz - l);
+ }
+}
+
+static void
+gomp_display_int (char *buffer, size_t size, size_t *ret,
+ bool zero, bool right, size_t sz, int num)
+{
+ char buf[3 * sizeof (int) + 2];
+ sprintf (buf, "%d", num);
+ gomp_display_num (buffer, size, ret, zero, right, sz, buf);
+}
+
+static void
+gomp_display_string_len (char *buffer, size_t size, size_t *ret,
+ bool right, size_t sz, char *str, size_t len)
+{
+ if (sz == (size_t) -1 || len >= sz)
+ {
+ gomp_display_string (buffer, size, ret, str, len);
+ return;
+ }
+
+ if (right)
+ {
+ gomp_display_repeat (buffer, size, ret, ' ', sz - len);
+ gomp_display_string (buffer, size, ret, str, len);
+ }
+ else
+ {
+ gomp_display_string (buffer, size, ret, str, len);
+ gomp_display_repeat (buffer, size, ret, ' ', sz - len);
+ }
+}
+
+static void
+gomp_display_hostname (char *buffer, size_t size, size_t *ret,
+ bool right, size_t sz)
+{
+#ifdef HAVE_GETHOSTNAME
+ {
+ char buf[256];
+ char *b = buf;
+ size_t len = 256;
+ do
+ {
+ b[len - 1] = '\0';
+ if (gethostname (b, len - 1) == 0)
+ {
+ size_t l = strlen (b);
+ if (l < len - 1)
+ {
+ gomp_display_string_len (buffer, size, ret,
+ right, sz, b, l);
+ if (b != buf)
+ free (b);
+ return;
+ }
+ }
+ if (len == 1048576)
+ break;
+ len = len * 2;
+ if (len == 512)
+ b = gomp_malloc (len);
+ else
+ b = gomp_realloc (b, len);
+ }
+ while (1);
+ if (b != buf)
+ free (b);
+ }
+#endif
+#ifdef HAVE_UNAME
+ {
+ struct utsname buf;
+ if (uname (&buf) == 0)
+ {
+ gomp_display_string_len (buffer, size, ret, right, sz,
+ buf.nodename, strlen (buf.nodename));
+ return;
+ }
+ }
+#endif
+ gomp_display_string_len (buffer, size, ret, right, sz, "node", 4);
+}
+
+struct affinity_types_struct {
+ char long_str[18];
+ char long_len;
+ char short_c; };
+
+static struct affinity_types_struct affinity_types[] =
+{
+#define AFFINITY_TYPE(l, s) \
+ { #l, sizeof (#l) - 1, s }
+ AFFINITY_TYPE (team_num, 't'),
+ AFFINITY_TYPE (num_teams, 'T'),
+ AFFINITY_TYPE (nesting_level, 'L'),
+ AFFINITY_TYPE (thread_num, 'n'),
+ AFFINITY_TYPE (num_threads, 'N'),
+ AFFINITY_TYPE (ancestor_tnum, 'a'),
+ AFFINITY_TYPE (host, 'H'),
+ AFFINITY_TYPE (process_id, 'P'),
+ AFFINITY_TYPE (native_thread_id, 'i'),
+ AFFINITY_TYPE (thread_affinity, 'A')
+#undef AFFINITY_TYPE
+};
+
+size_t
+gomp_display_affinity (char *buffer, size_t size,
+ const char *format, gomp_thread_handle handle,
+ struct gomp_team_state *ts, unsigned int place)
+{
+ size_t ret = 0;
+ do
+ {
+ const char *p = strchr (format, '%');
+ bool zero = false;
+ bool right = false;
+ size_t sz = -1;
+ char c;
+ int val;
+ if (p == NULL)
+ p = strchr (format, '\0');
+ if (p != format)
+ gomp_display_string (buffer, size, &ret,
+ format, p - format);
+ if (*p == '\0')
+ break;
+ p++;
+ if (*p == '%')
+ {
+ gomp_display_string (buffer, size, &ret, "%", 1);
+ format = p + 1;
+ continue;
+ }
+ if (*p == '0')
+ {
+ zero = true;
+ p++;
+ if (*p != '.')
+ gomp_fatal ("leading zero not followed by dot in affinity format");
+ }
+ if (*p == '.')
+ {
+ right = true;
+ p++;
+ }
+ if (*p >= '1' && *p <= '9')
+ {
+ char *end;
+ sz = strtoul (p, &end, 10);
+ p = end;
+ }
+ else if (zero || right)
+ gomp_fatal ("leading zero or right justification in affinity format "
+ "requires size");
+ c = *p;
+ if (c == '{')
+ {
+ int i;
+ for (i = 0;
+ i < sizeof (affinity_types) / sizeof (affinity_types[0]); ++i)
+ if (strncmp (p + 1, affinity_types[i].long_str,
+ affinity_types[i].long_len) == 0
+ && p[affinity_types[i].long_len + 1] == '}')
+ {
+ c = affinity_types[i].short_c;
+ p += affinity_types[i].long_len + 1;
+ break;
+ }
+ if (c == '{')
+ {
+ char *q = strchr (p + 1, '}');
+ if (q)
+ gomp_fatal ("unsupported long type name '%.*s' in affinity "
+ "format", (int) (q - (p + 1)), p + 1);
+ else
+ gomp_fatal ("unterminated long type name '%s' in affinity "
+ "format", p + 1);
+ }
+ }
+ switch (c)
+ {
+ case 't':
+ val = omp_get_team_num ();
+ goto do_int;
+ case 'T':
+ val = omp_get_num_teams ();
+ goto do_int;
+ case 'L':
+ val = ts->level;
+ goto do_int;
+ case 'n':
+ val = ts->team_id;
+ goto do_int;
+ case 'N':
+ val = ts->team ? ts->team->nthreads : 1;
+ goto do_int;
+ case 'a':
+ val = ts->team ? ts->team->prev_ts.team_id : -1;
+ goto do_int;
+ case 'H':
+ gomp_display_hostname (buffer, size, &ret, right, sz);
+ break;
+ case 'P':
+#ifdef HAVE_GETPID
+ val = getpid ();
+#else
+ val = 0;
+#endif
+ goto do_int;
+ case 'i':
+#if defined(LIBGOMP_USE_PTHREADS) && defined(__GNUC__)
+ {
+ char buf[3 * (sizeof (handle) + sizeof (uintptr_t) + sizeof (int))
+ + 4];
+ /* This macro returns expr unmodified for integral or pointer
+ types and 0 for anything else (e.g. aggregates). */
+#define gomp_nonaggregate(expr) \
+ __builtin_choose_expr (__builtin_classify_type (expr) == 1 \
+ || __builtin_classify_type (expr) == 5, expr, 0)
+ /* This macro returns expr unmodified for integral types,
+ (uintptr_t) (expr) for pointer types and 0 for anything else
+ (e.g. aggregates). */
+#define gomp_integral(expr) \
+ __builtin_choose_expr (__builtin_classify_type (expr) == 5, \
+ (uintptr_t) gomp_nonaggregate (expr), \
+ gomp_nonaggregate (expr))
+
+ if (sizeof (gomp_integral (handle)) == sizeof (unsigned long))
+ sprintf (buf, "0x%lx", (unsigned long) gomp_integral (handle));
+#if defined (HAVE_INTTYPES_H) && defined (PRIx64)
+ else if (sizeof (gomp_integral (handle)) == sizeof (uint64_t))
+ sprintf (buf, "0x%" PRIx64, (uint64_t) gomp_integral (handle));
+#else
+ else if (sizeof (gomp_integral (handle))
+ == sizeof (unsigned long long))
+ sprintf (buf, "0x%llx",
+ (unsigned long long) gomp_integral (handle));
+#endif
+ else
+ sprintf (buf, "0x%x", (unsigned int) gomp_integral (handle));
+ gomp_display_num (buffer, size, &ret, zero, right, sz, buf);
+ break;
+ }
+#else
+ val = 0;
+ goto do_int;
+#endif
+ case 'A':
+ if (sz == (size_t) -1)
+ gomp_display_affinity_place (buffer, size, &ret,
+ place - 1);
+ else if (right)
+ {
+ size_t len = 0;
+ gomp_display_affinity_place (NULL, 0, &len, place - 1);
+ if (len < sz)
+ gomp_display_repeat (buffer, size, &ret, ' ', sz - len);
+ gomp_display_affinity_place (buffer, size, &ret, place - 1);
+ }
+ else
+ {
+ size_t start = ret;
+ gomp_display_affinity_place (buffer, size, &ret, place - 1);
+ if (ret - start < sz)
+ gomp_display_repeat (buffer, size, &ret, ' ', sz - (ret - start));
+ }
+ break;
+ do_int:
+ gomp_display_int (buffer, size, &ret, zero, right, sz, val);
+ break;
+ default:
+ gomp_fatal ("unsupported type %c in affinity format", c);
+ }
+ format = p + 1;
+ }
+ while (1);
+ return ret;
+}
+
+size_t
+omp_capture_affinity (char *buffer, size_t size, const char *format)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ size_t ret
+ = gomp_display_affinity (buffer, size,
+ format && *format
+ ? format : gomp_affinity_format_var,
+ gomp_thread_self (), &thr->ts, thr->place);
+ if (size)
+ {
+ if (ret >= size)
+ buffer[size - 1] = '\0';
+ else
+ buffer[ret] = '\0';
+ }
+ return ret;
+}
+ialias (omp_capture_affinity)
+
+void
+omp_display_affinity (const char *format)
+{
+ char buf[512];
+ char *b;
+ size_t ret = ialias_call (omp_capture_affinity) (buf, sizeof buf, format);
+ if (ret < sizeof buf)
+ {
+ buf[ret] = '\n';
+ gomp_print_string (buf, ret + 1);
+ return;
+ }
+ b = gomp_malloc (ret + 1);
+ ialias_call (omp_capture_affinity) (b, ret + 1, format);
+ b[ret] = '\n';
+ gomp_print_string (b, ret + 1);
+ free (b);
+}
+
+void
+gomp_display_affinity_thread (gomp_thread_handle handle,
+ struct gomp_team_state *ts, unsigned int place)
+{
+ char buf[512];
+ char *b;
+ size_t ret = gomp_display_affinity (buf, sizeof buf, gomp_affinity_format_var,
+ handle, ts, place);
+ if (ret < sizeof buf)
+ {
+ buf[ret] = '\n';
+ gomp_print_string (buf, ret + 1);
+ return;
+ }
+ b = gomp_malloc (ret + 1);
+ gomp_display_affinity (b, ret + 1, gomp_affinity_format_var,
+ handle, ts, place);
+ b[ret] = '\n';
+ gomp_print_string (b, ret + 1);
+ free (b);
+}
diff --git a/libgomp/affinity.c b/libgomp/affinity.c
index 3f98e56c002..59c9c2b60f7 100644
--- a/libgomp/affinity.c
+++ b/libgomp/affinity.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -26,6 +26,8 @@
/* This is a generic stub implementation of a CPU affinity setting. */
#include "libgomp.h"
+#include <string.h>
+#include <stdio.h>
void
gomp_init_affinity (void)
@@ -138,5 +140,17 @@ gomp_get_place_proc_ids_8 (int place_num, int64_t *ids)
(void) ids;
}
+void
+gomp_display_affinity_place (char *buffer, size_t size, size_t *ret,
+ int place)
+{
+ char buf[sizeof (long) * 3 + 4];
+ if (gomp_available_cpus > 1)
+ sprintf (buf, "0-%lu", gomp_available_cpus - 1);
+ else
+ strcpy (buf, "0");
+ gomp_display_string (buffer, size, ret, buf, strlen (buf));
+}
+
ialias(omp_get_place_num_procs)
ialias(omp_get_place_proc_ids)
diff --git a/libgomp/alloc.c b/libgomp/alloc.c
index 1bf40423579..c28e32f961e 100644
--- a/libgomp/alloc.c
+++ b/libgomp/alloc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -27,6 +27,7 @@
places in the OpenMP API do not make any provision for failure, so in
general we cannot allow memory allocation to fail. */
+#define _GNU_SOURCE
#include "libgomp.h"
#include <stdlib.h>
@@ -57,3 +58,50 @@ gomp_realloc (void *old, size_t size)
gomp_fatal ("Out of memory allocating %lu bytes", (unsigned long) size);
return ret;
}
+
+void *
+gomp_aligned_alloc (size_t al, size_t size)
+{
+ void *ret;
+ if (al < sizeof (void *))
+ al = sizeof (void *);
+#ifdef HAVE_ALIGNED_ALLOC
+ ret = aligned_alloc (al, size);
+#elif defined(HAVE__ALIGNED_MALLOC)
+ ret = _aligned_malloc (size, al);
+#elif defined(HAVE_POSIX_MEMALIGN)
+ if (posix_memalign (&ret, al, size) != 0)
+ ret = NULL;
+#elif defined(HAVE_MEMALIGN)
+ {
+ extern void *memalign (size_t, size_t);
+ ret = memalign (al, size);
+ }
+#else
+ ret = NULL;
+ if ((al & (al - 1)) == 0 && size)
+ {
+ void *p = malloc (size + al);
+ if (p)
+ {
+ void *ap = (void *) (((uintptr_t) p + al) & -al);
+ ((void **) ap)[-1] = p;
+ ret = ap;
+ }
+ }
+#endif
+ if (ret == NULL)
+ gomp_fatal ("Out of memory allocating %lu bytes", (unsigned long) size);
+ return ret;
+}
+
+void
+gomp_aligned_free (void *ptr)
+{
+#ifdef GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC
+ free (ptr);
+#else
+ if (ptr)
+ free (((void **) ptr)[-1]);
+#endif
+}
diff --git a/libgomp/atomic.c b/libgomp/atomic.c
index 7bb2d810626..aede501d23c 100644
--- a/libgomp/atomic.c
+++ b/libgomp/atomic.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/barrier.c b/libgomp/barrier.c
index 7115515fdc4..d4c9001bd93 100644
--- a/libgomp/barrier.c
+++ b/libgomp/barrier.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config.h.in b/libgomp/config.h.in
index e7bc4d97374..2d50fcd5c1a 100644
--- a/libgomp/config.h.in
+++ b/libgomp/config.h.in
@@ -1,5 +1,8 @@
/* config.h.in. Generated from configure.ac by autoheader. */
+/* Define to 1 if you have the `aligned_alloc' function. */
+#undef HAVE_ALIGNED_ALLOC
+
/* Define to 1 if the target assembler supports .symver directive. */
#undef HAVE_AS_SYMVER_DIRECTIVE
@@ -33,9 +36,15 @@
/* Define to 1 if you have the `getgid' function. */
#undef HAVE_GETGID
+/* Define if gethostname is supported. */
+#undef HAVE_GETHOSTNAME
+
/* Define to 1 if you have the `getloadavg' function. */
#undef HAVE_GETLOADAVG
+/* Define if getpid is supported. */
+#undef HAVE_GETPID
+
/* Define to 1 if you have the `getuid' function. */
#undef HAVE_GETUID
@@ -45,9 +54,15 @@
/* Define to 1 if you have the `dl' library (-ldl). */
#undef HAVE_LIBDL
+/* Define to 1 if you have the `memalign' function. */
+#undef HAVE_MEMALIGN
+
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
+/* Define to 1 if you have the `posix_memalign' function. */
+#undef HAVE_POSIX_MEMALIGN
+
/* Define if pthread_{,attr_}{g,s}etaffinity_np is supported. */
#undef HAVE_PTHREAD_AFFINITY_NP
@@ -103,9 +118,15 @@
/* Define to 1 if the target supports thread-local storage. */
#undef HAVE_TLS
+/* Define if uname is supported and struct utsname has nodename field. */
+#undef HAVE_UNAME
+
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the `_aligned_malloc' function. */
+#undef HAVE__ALIGNED_MALLOC
+
/* Define to 1 if you have the `__secure_getenv' function. */
#undef HAVE___SECURE_GETENV
@@ -125,8 +146,8 @@
*/
#undef LT_OBJDIR
-/* Define to offload targets, separated by commas. */
-#undef OFFLOAD_TARGETS
+/* Define to offload plugins, separated by commas. */
+#undef OFFLOAD_PLUGINS
/* Name of package */
#undef PACKAGE
@@ -149,6 +170,9 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
+/* Define to 1 if the GCN plugin is built, 0 if not. */
+#undef PLUGIN_GCN
+
/* Define to 1 if the HSA plugin is built, 0 if not. */
#undef PLUGIN_HSA
@@ -162,21 +186,6 @@
/* Define if all infrastructure, needed for plugins, is supported. */
#undef PLUGIN_SUPPORT
-/* The size of `char', as computed by sizeof. */
-#undef SIZEOF_CHAR
-
-/* The size of `int', as computed by sizeof. */
-#undef SIZEOF_INT
-
-/* The size of `long', as computed by sizeof. */
-#undef SIZEOF_LONG
-
-/* The size of `short', as computed by sizeof. */
-#undef SIZEOF_SHORT
-
-/* The size of `void *', as computed by sizeof. */
-#undef SIZEOF_VOID_P
-
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
diff --git a/libgomp/config/nvptx/libgomp-plugin.c b/libgomp/config/accel/libgomp-plugin.c
index e69de29bb2d..e69de29bb2d 100644
--- a/libgomp/config/nvptx/libgomp-plugin.c
+++ b/libgomp/config/accel/libgomp-plugin.c
diff --git a/libgomp/config/nvptx/lock.c b/libgomp/config/accel/lock.c
index e658a22e68d..6ee6957b0d5 100644
--- a/libgomp/config/nvptx/lock.c
+++ b/libgomp/config/accel/lock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2016-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2016-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/mutex.c b/libgomp/config/accel/mutex.c
index e69de29bb2d..e69de29bb2d 100644
--- a/libgomp/config/nvptx/mutex.c
+++ b/libgomp/config/accel/mutex.c
diff --git a/libgomp/config/nvptx/mutex.h b/libgomp/config/accel/mutex.h
index 1bf72ee1502..3feae56b464 100644
--- a/libgomp/config/nvptx/mutex.h
+++ b/libgomp/config/accel/mutex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/oacc-async.c b/libgomp/config/accel/oacc-async.c
index e69de29bb2d..e69de29bb2d 100644
--- a/libgomp/config/nvptx/oacc-async.c
+++ b/libgomp/config/accel/oacc-async.c
diff --git a/libgomp/config/nvptx/oacc-cuda.c b/libgomp/config/accel/oacc-cuda.c
index e69de29bb2d..e69de29bb2d 100644
--- a/libgomp/config/nvptx/oacc-cuda.c
+++ b/libgomp/config/accel/oacc-cuda.c
diff --git a/libgomp/config/nvptx/oacc-host.c b/libgomp/config/accel/oacc-host.c
index e69de29bb2d..e69de29bb2d 100644
--- a/libgomp/config/nvptx/oacc-host.c
+++ b/libgomp/config/accel/oacc-host.c
diff --git a/libgomp/config/nvptx/oacc-init.c b/libgomp/config/accel/oacc-init.c
index 0ac79e6a166..c7dc64eb0a8 100644
--- a/libgomp/config/nvptx/oacc-init.c
+++ b/libgomp/config/accel/oacc-init.c
@@ -1,6 +1,6 @@
/* OpenACC Runtime initialization routines
- Copyright (C) 2014-2018 Free Software Foundation, Inc.
+ Copyright (C) 2014-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
diff --git a/libgomp/config/nvptx/oacc-mem.c b/libgomp/config/accel/oacc-mem.c
index e69de29bb2d..e69de29bb2d 100644
--- a/libgomp/config/nvptx/oacc-mem.c
+++ b/libgomp/config/accel/oacc-mem.c
diff --git a/libgomp/config/nvptx/oacc-plugin.c b/libgomp/config/accel/oacc-plugin.c
index e69de29bb2d..e69de29bb2d 100644
--- a/libgomp/config/nvptx/oacc-plugin.c
+++ b/libgomp/config/accel/oacc-plugin.c
diff --git a/libgomp/config/nvptx/omp-lock.h b/libgomp/config/accel/omp-lock.h
index 2ca7c5e1d60..2ca7c5e1d60 100644
--- a/libgomp/config/nvptx/omp-lock.h
+++ b/libgomp/config/accel/omp-lock.h
diff --git a/libgomp/config/nvptx/openacc.f90 b/libgomp/config/accel/openacc.f90
index e77bea617e5..6a8c5e9cb3d 100644
--- a/libgomp/config/nvptx/openacc.f90
+++ b/libgomp/config/accel/openacc.f90
@@ -1,6 +1,6 @@
! OpenACC Runtime Library Definitions.
-! Copyright (C) 2014-2018 Free Software Foundation, Inc.
+! Copyright (C) 2014-2019 Free Software Foundation, Inc.
! Contributed by Tobias Burnus <burnus@net-b.de>
! and Mentor Embedded.
@@ -51,6 +51,7 @@ module openacc_kinds
! integer (acc_device_kind), parameter :: acc_device_host_nonshm = 3 removed.
integer (acc_device_kind), parameter :: acc_device_not_host = 4
integer (acc_device_kind), parameter :: acc_device_nvidia = 5
+ integer (acc_device_kind), parameter :: acc_device_gcn = 8
end module
diff --git a/libgomp/config/nvptx/pool.h b/libgomp/config/accel/pool.h
index 681d68d1294..20c2e62f7c8 100644
--- a/libgomp/config/nvptx/pool.h
+++ b/libgomp/config/accel/pool.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/proc.c b/libgomp/config/accel/proc.c
index c03ce509166..8ca0b0a1ee1 100644
--- a/libgomp/config/nvptx/proc.c
+++ b/libgomp/config/accel/proc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/ptrlock.c b/libgomp/config/accel/ptrlock.c
index e69de29bb2d..e69de29bb2d 100644
--- a/libgomp/config/nvptx/ptrlock.c
+++ b/libgomp/config/accel/ptrlock.c
diff --git a/libgomp/config/nvptx/ptrlock.h b/libgomp/config/accel/ptrlock.h
index 5cb38a484ba..69ff2e26359 100644
--- a/libgomp/config/nvptx/ptrlock.h
+++ b/libgomp/config/accel/ptrlock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/sem.c b/libgomp/config/accel/sem.c
index e69de29bb2d..e69de29bb2d 100644
--- a/libgomp/config/nvptx/sem.c
+++ b/libgomp/config/accel/sem.c
diff --git a/libgomp/config/nvptx/sem.h b/libgomp/config/accel/sem.h
index f923862f1f5..574945ca998 100644
--- a/libgomp/config/nvptx/sem.h
+++ b/libgomp/config/accel/sem.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/thread-stacksize.h b/libgomp/config/accel/thread-stacksize.h
index b48b91821d6..de89519eb27 100644
--- a/libgomp/config/nvptx/thread-stacksize.h
+++ b/libgomp/config/accel/thread-stacksize.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/bsd/proc.c b/libgomp/config/bsd/proc.c
index e5b5df71e86..5e6743dd7d0 100644
--- a/libgomp/config/bsd/proc.c
+++ b/libgomp/config/bsd/proc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/darwin/plugin-suffix.h b/libgomp/config/darwin/plugin-suffix.h
index c70cdfbca15..c0b7bab010a 100644
--- a/libgomp/config/darwin/plugin-suffix.h
+++ b/libgomp/config/darwin/plugin-suffix.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Jack Howarth <howarth.at.gcc@gmail.com>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/darwin/thread-stacksize.h b/libgomp/config/darwin/thread-stacksize.h
index 6f45f4a2db7..90e1f00c18d 100644
--- a/libgomp/config/darwin/thread-stacksize.h
+++ b/libgomp/config/darwin/thread-stacksize.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/gcn/affinity-fmt.c b/libgomp/config/gcn/affinity-fmt.c
new file mode 100644
index 00000000000..3585f414460
--- /dev/null
+++ b/libgomp/config/gcn/affinity-fmt.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "libgomp.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h> /* For PRIx64. */
+#endif
+#ifdef HAVE_UNAME
+#include <sys/utsname.h>
+#endif
+
+/* The HAVE_GETPID and HAVE_GETHOSTNAME configure tests are passing for nvptx,
+ while the nvptx newlib implementation does not support those functions.
+ Override the configure test results here. */
+#undef HAVE_GETPID
+#undef HAVE_GETHOSTNAME
+
+/* The GCN newlib implementation does not support fwrite, but it does support
+ write. Map fwrite to write. */
+#undef fwrite
+#define fwrite(ptr, size, nmemb, stream) write (1, (ptr), (nmemb) * (size))
+
+#include "../../affinity-fmt.c"
+
diff --git a/libgomp/config/gcn/bar.c b/libgomp/config/gcn/bar.c
new file mode 100644
index 00000000000..fb709be26ce
--- /dev/null
+++ b/libgomp/config/gcn/bar.c
@@ -0,0 +1,232 @@
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
+ Contributed by Mentor Embedded.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This is an AMD GCN specific implementation of a barrier synchronization
+ mechanism for libgomp. This type is private to the library. This
+ implementation uses atomic instructions and s_barrier instruction. It
+ uses MEMMODEL_RELAXED here because barriers are within workgroups and
+ therefore don't need to flush caches. */
+
+#include <limits.h>
+#include "libgomp.h"
+
+
+void
+gomp_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
+{
+ if (__builtin_expect (state & BAR_WAS_LAST, 0))
+ {
+ /* Next time we'll be awaiting TOTAL threads again. */
+ bar->awaited = bar->total;
+ __atomic_store_n (&bar->generation, bar->generation + BAR_INCR,
+ MEMMODEL_RELAXED);
+ }
+ asm ("s_barrier" ::: "memory");
+}
+
+void
+gomp_barrier_wait (gomp_barrier_t *bar)
+{
+ gomp_barrier_wait_end (bar, gomp_barrier_wait_start (bar));
+}
+
+/* Like gomp_barrier_wait, except that if the encountering thread
+ is not the last one to hit the barrier, it returns immediately.
+ The intended usage is that a thread which intends to gomp_barrier_destroy
+ this barrier calls gomp_barrier_wait, while all other threads
+ call gomp_barrier_wait_last. When gomp_barrier_wait returns,
+ the barrier can be safely destroyed. */
+
+void
+gomp_barrier_wait_last (gomp_barrier_t *bar)
+{
+ /* Deferring to gomp_barrier_wait does not use the optimization opportunity
+ allowed by the interface contract for all-but-last participants. The
+ original implementation in config/linux/bar.c handles this better. */
+ gomp_barrier_wait (bar);
+}
+
+void
+gomp_team_barrier_wake (gomp_barrier_t *bar, int count)
+{
+ asm ("s_barrier" ::: "memory");
+}
+
+void
+gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
+{
+ unsigned int generation, gen;
+
+ if (__builtin_expect (state & BAR_WAS_LAST, 0))
+ {
+ /* Next time we'll be awaiting TOTAL threads again. */
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_team *team = thr->ts.team;
+
+ bar->awaited = bar->total;
+ team->work_share_cancelled = 0;
+ if (__builtin_expect (team->task_count, 0))
+ {
+ gomp_barrier_handle_tasks (state);
+ state &= ~BAR_WAS_LAST;
+ }
+ else
+ {
+ state &= ~BAR_CANCELLED;
+ state += BAR_INCR - BAR_WAS_LAST;
+ __atomic_store_n (&bar->generation, state, MEMMODEL_RELAXED);
+ asm ("s_barrier" ::: "memory");
+ return;
+ }
+ }
+
+ generation = state;
+ state &= ~BAR_CANCELLED;
+ int retry = 100;
+ do
+ {
+ if (retry-- == 0)
+ {
+ /* It really shouldn't happen that barriers get out of sync, but
+ if they do then this will loop until they realign, so we need
+ to avoid an infinite loop where the thread just isn't there. */
+ const char msg[] = ("Barrier sync failed (another thread died?);"
+ " aborting.");
+ write (2, msg, sizeof (msg)-1);
+ abort();
+ }
+
+ asm ("s_barrier" ::: "memory");
+ gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE);
+ if (__builtin_expect (gen & BAR_TASK_PENDING, 0))
+ {
+ gomp_barrier_handle_tasks (state);
+ gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE);
+ }
+ generation |= gen & BAR_WAITING_FOR_TASK;
+ }
+ while (gen != state + BAR_INCR);
+}
+
+void
+gomp_team_barrier_wait (gomp_barrier_t *bar)
+{
+ gomp_team_barrier_wait_end (bar, gomp_barrier_wait_start (bar));
+}
+
+void
+gomp_team_barrier_wait_final (gomp_barrier_t *bar)
+{
+ gomp_barrier_state_t state = gomp_barrier_wait_final_start (bar);
+ if (__builtin_expect (state & BAR_WAS_LAST, 0))
+ bar->awaited_final = bar->total;
+ gomp_team_barrier_wait_end (bar, state);
+}
+
+bool
+gomp_team_barrier_wait_cancel_end (gomp_barrier_t *bar,
+ gomp_barrier_state_t state)
+{
+ unsigned int generation, gen;
+
+ if (__builtin_expect (state & BAR_WAS_LAST, 0))
+ {
+ /* Next time we'll be awaiting TOTAL threads again. */
+ /* BAR_CANCELLED should never be set in state here, because
+ cancellation means that at least one of the threads has been
+ cancelled, thus on a cancellable barrier we should never see
+ all threads to arrive. */
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_team *team = thr->ts.team;
+
+ bar->awaited = bar->total;
+ team->work_share_cancelled = 0;
+ if (__builtin_expect (team->task_count, 0))
+ {
+ gomp_barrier_handle_tasks (state);
+ state &= ~BAR_WAS_LAST;
+ }
+ else
+ {
+ state += BAR_INCR - BAR_WAS_LAST;
+ __atomic_store_n (&bar->generation, state, MEMMODEL_RELAXED);
+ asm ("s_barrier" ::: "memory");
+ return false;
+ }
+ }
+
+ if (__builtin_expect (state & BAR_CANCELLED, 0))
+ return true;
+
+ generation = state;
+ int retry = 100;
+ do
+ {
+ if (retry-- == 0)
+ {
+ /* It really shouldn't happen that barriers get out of sync, but
+ if they do then this will loop until they realign, so we need
+ to avoid an infinite loop where the thread just isn't there. */
+ const char msg[] = ("Barrier sync failed (another thread died?);"
+ " aborting.");
+ write (2, msg, sizeof (msg)-1);
+ abort();
+ }
+
+ asm ("s_barrier" ::: "memory");
+ gen = __atomic_load_n (&bar->generation, MEMMODEL_RELAXED);
+ if (__builtin_expect (gen & BAR_CANCELLED, 0))
+ return true;
+ if (__builtin_expect (gen & BAR_TASK_PENDING, 0))
+ {
+ gomp_barrier_handle_tasks (state);
+ gen = __atomic_load_n (&bar->generation, MEMMODEL_RELAXED);
+ }
+ generation |= gen & BAR_WAITING_FOR_TASK;
+ }
+ while (gen != state + BAR_INCR);
+
+ return false;
+}
+
+bool
+gomp_team_barrier_wait_cancel (gomp_barrier_t *bar)
+{
+ return gomp_team_barrier_wait_cancel_end (bar, gomp_barrier_wait_start (bar));
+}
+
+void
+gomp_team_barrier_cancel (struct gomp_team *team)
+{
+ gomp_mutex_lock (&team->task_lock);
+ if (team->barrier.generation & BAR_CANCELLED)
+ {
+ gomp_mutex_unlock (&team->task_lock);
+ return;
+ }
+ team->barrier.generation |= BAR_CANCELLED;
+ gomp_mutex_unlock (&team->task_lock);
+ gomp_team_barrier_wake (&team->barrier, INT_MAX);
+}
diff --git a/libgomp/config/gcn/bar.h b/libgomp/config/gcn/bar.h
new file mode 100644
index 00000000000..ec8851ba078
--- /dev/null
+++ b/libgomp/config/gcn/bar.h
@@ -0,0 +1,168 @@
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
+ Contributed by Mentor Embedded.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This is an AMD GCN specific implementation of a barrier synchronization
+ mechanism for libgomp. This type is private to the library. This
+ implementation uses atomic instructions and s_barrier instruction. It
+ uses MEMMODEL_RELAXED here because barriers are within workgroups and
+ therefore don't need to flush caches. */
+
+#ifndef GOMP_BARRIER_H
+#define GOMP_BARRIER_H 1
+
+#include "mutex.h"
+
+typedef struct
+{
+ unsigned total;
+ unsigned generation;
+ unsigned awaited;
+ unsigned awaited_final;
+} gomp_barrier_t;
+
+typedef unsigned int gomp_barrier_state_t;
+
+/* The generation field contains a counter in the high bits, with a few
+ low bits dedicated to flags. Note that TASK_PENDING and WAS_LAST can
+ share space because WAS_LAST is never stored back to generation. */
+#define BAR_TASK_PENDING 1
+#define BAR_WAS_LAST 1
+#define BAR_WAITING_FOR_TASK 2
+#define BAR_CANCELLED 4
+#define BAR_INCR 8
+
+static inline void gomp_barrier_init (gomp_barrier_t *bar, unsigned count)
+{
+ bar->total = count;
+ bar->awaited = count;
+ bar->awaited_final = count;
+ bar->generation = 0;
+}
+
+static inline void gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count)
+{
+ __atomic_add_fetch (&bar->awaited, count - bar->total, MEMMODEL_RELAXED);
+ bar->total = count;
+}
+
+static inline void gomp_barrier_destroy (gomp_barrier_t *bar)
+{
+}
+
+extern void gomp_barrier_wait (gomp_barrier_t *);
+extern void gomp_barrier_wait_last (gomp_barrier_t *);
+extern void gomp_barrier_wait_end (gomp_barrier_t *, gomp_barrier_state_t);
+extern void gomp_team_barrier_wait (gomp_barrier_t *);
+extern void gomp_team_barrier_wait_final (gomp_barrier_t *);
+extern void gomp_team_barrier_wait_end (gomp_barrier_t *,
+ gomp_barrier_state_t);
+extern bool gomp_team_barrier_wait_cancel (gomp_barrier_t *);
+extern bool gomp_team_barrier_wait_cancel_end (gomp_barrier_t *,
+ gomp_barrier_state_t);
+extern void gomp_team_barrier_wake (gomp_barrier_t *, int);
+struct gomp_team;
+extern void gomp_team_barrier_cancel (struct gomp_team *);
+
+static inline gomp_barrier_state_t
+gomp_barrier_wait_start (gomp_barrier_t *bar)
+{
+ unsigned int ret = __atomic_load_n (&bar->generation, MEMMODEL_RELAXED);
+ ret &= -BAR_INCR | BAR_CANCELLED;
+ /* A memory barrier is needed before exiting from the various forms
+ of gomp_barrier_wait, to satisfy OpenMP API version 3.1 section
+ 2.8.6 flush Construct, which says there is an implicit flush during
+ a barrier region. This is a convenient place to add the barrier,
+ so we use MEMMODEL_ACQ_REL here rather than MEMMODEL_ACQUIRE. */
+ if (__atomic_add_fetch (&bar->awaited, -1, MEMMODEL_RELAXED) == 0)
+ ret |= BAR_WAS_LAST;
+ return ret;
+}
+
+static inline gomp_barrier_state_t
+gomp_barrier_wait_cancel_start (gomp_barrier_t *bar)
+{
+ return gomp_barrier_wait_start (bar);
+}
+
+/* This is like gomp_barrier_wait_start, except it decrements
+ bar->awaited_final rather than bar->awaited and should be used
+ for the gomp_team_end barrier only. */
+static inline gomp_barrier_state_t
+gomp_barrier_wait_final_start (gomp_barrier_t *bar)
+{
+ unsigned int ret = __atomic_load_n (&bar->generation, MEMMODEL_RELAXED);
+ ret &= -BAR_INCR | BAR_CANCELLED;
+ /* See above gomp_barrier_wait_start comment. */
+ if (__atomic_add_fetch (&bar->awaited_final, -1, MEMMODEL_RELAXED) == 0)
+ ret |= BAR_WAS_LAST;
+ return ret;
+}
+
+static inline bool
+gomp_barrier_last_thread (gomp_barrier_state_t state)
+{
+ return state & BAR_WAS_LAST;
+}
+
+/* All the inlines below must be called with team->task_lock
+ held. */
+
+static inline void
+gomp_team_barrier_set_task_pending (gomp_barrier_t *bar)
+{
+ bar->generation |= BAR_TASK_PENDING;
+}
+
+static inline void
+gomp_team_barrier_clear_task_pending (gomp_barrier_t *bar)
+{
+ bar->generation &= ~BAR_TASK_PENDING;
+}
+
+static inline void
+gomp_team_barrier_set_waiting_for_tasks (gomp_barrier_t *bar)
+{
+ bar->generation |= BAR_WAITING_FOR_TASK;
+}
+
+static inline bool
+gomp_team_barrier_waiting_for_tasks (gomp_barrier_t *bar)
+{
+ return (bar->generation & BAR_WAITING_FOR_TASK) != 0;
+}
+
+static inline bool
+gomp_team_barrier_cancelled (gomp_barrier_t *bar)
+{
+ return __builtin_expect ((bar->generation & BAR_CANCELLED) != 0, 0);
+}
+
+static inline void
+gomp_team_barrier_done (gomp_barrier_t *bar, gomp_barrier_state_t state)
+{
+ bar->generation = (state & -BAR_INCR) + BAR_INCR;
+}
+
+#endif /* GOMP_BARRIER_H */
diff --git a/libgomp/config/gcn/doacross.h b/libgomp/config/gcn/doacross.h
new file mode 100644
index 00000000000..2bff18ae1a8
--- /dev/null
+++ b/libgomp/config/gcn/doacross.h
@@ -0,0 +1,58 @@
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
+ Contributed by Mentor Embedded.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This is the AMD GCN implementation of doacross spinning. */
+
+#ifndef GOMP_DOACROSS_H
+#define GOMP_DOACROSS_H 1
+
+#include "libgomp.h"
+
+static inline int
+cpu_relax (void)
+{
+ /* This can be implemented as just a memory barrier, but a sleep seems
+ like it should allow the wavefront to yield (maybe?)
+ Use the shortest possible sleep time of 1*64 cycles. */
+ asm volatile ("s_sleep\t1" ::: "memory");
+ return 0;
+}
+
+static inline void doacross_spin (unsigned long *addr, unsigned long expected,
+ unsigned long cur)
+{
+ /* Prevent compiler from optimizing based on bounds of containing object. */
+ asm ("" : "+r" (addr));
+ do
+ {
+ /* An alternative implementation might use s_setprio to lower the
+ priority temporarily, and then restore it after. */
+ int i = cpu_relax ();
+ cur = addr[i];
+ }
+ while (cur <= expected);
+}
+
+#endif /* GOMP_DOACROSS_H */
diff --git a/libgomp/config/gcn/icv-device.c b/libgomp/config/gcn/icv-device.c
new file mode 100644
index 00000000000..cbb9dfa1133
--- /dev/null
+++ b/libgomp/config/gcn/icv-device.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
+ Contributed by Mentor Embedded.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file defines OpenMP API entry points that accelerator targets are
+ expected to replace. */
+
+#include "libgomp.h"
+
+void
+omp_set_default_device (int device_num __attribute__((unused)))
+{
+}
+
+int
+omp_get_default_device (void)
+{
+ return 0;
+}
+
+int
+omp_get_num_devices (void)
+{
+ return 0;
+}
+
+int
+omp_get_num_teams (void)
+{
+ return gomp_num_teams_var + 1;
+}
+
+int __attribute__ ((__optimize__ ("O2")))
+omp_get_team_num (void)
+{
+ return __builtin_gcn_dim_pos (0);
+}
+
+int
+omp_is_initial_device (void)
+{
+ /* AMD GCN is an accelerator-only target. */
+ return 0;
+}
+
+ialias (omp_set_default_device)
+ialias (omp_get_default_device)
+ialias (omp_get_num_devices)
+ialias (omp_get_num_teams)
+ialias (omp_get_team_num)
+ialias (omp_is_initial_device)
diff --git a/libgomp/config/gcn/oacc-target.c b/libgomp/config/gcn/oacc-target.c
new file mode 100644
index 00000000000..bdcc9153d96
--- /dev/null
+++ b/libgomp/config/gcn/oacc-target.c
@@ -0,0 +1,31 @@
+/* Oversized reductions lock variable
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
+ Contributed by Mentor Graphics.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* We use a global lock variable for reductions on objects larger than
+ 64 bits. Until and unless proven that lock contention for
+ different reductions is a problem, a single lock will suffice. */
+
+unsigned volatile __reduction_lock = 0;
diff --git a/libgomp/config/gcn/simple-bar.h b/libgomp/config/gcn/simple-bar.h
new file mode 100644
index 00000000000..802e0f5c301
--- /dev/null
+++ b/libgomp/config/gcn/simple-bar.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
+ Contributed by Mentor Embedded.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This is a simplified barrier that is suitable for thread pool
+ synchronizaton. Only a subset of full barrier API (bar.h) is exposed.
+ Here in the AMD GCN-specific implementation, we expect that thread pool
+ corresponds to the wavefronts within a work group. */
+
+#ifndef GOMP_SIMPLE_BARRIER_H
+#define GOMP_SIMPLE_BARRIER_H 1
+
+/* AMD GCN has no use for this type. */
+typedef int gomp_simple_barrier_t;
+
+/* GCN barriers block all wavefronts, so the count is not interesting. */
+static inline void
+gomp_simple_barrier_init (gomp_simple_barrier_t *bar, unsigned count)
+{
+}
+
+static inline void
+gomp_simple_barrier_destroy (gomp_simple_barrier_t *bar)
+{
+}
+
+static inline void
+gomp_simple_barrier_wait (gomp_simple_barrier_t *bar)
+{
+ asm volatile ("s_barrier" ::: "memory");
+}
+
+static inline void
+gomp_simple_barrier_wait_last (gomp_simple_barrier_t *bar)
+{
+ /* GCN has no way to signal a barrier without waiting. */
+ asm volatile ("s_barrier" ::: "memory");
+}
+
+#endif /* GOMP_SIMPLE_BARRIER_H */
diff --git a/libgomp/config/gcn/target.c b/libgomp/config/gcn/target.c
new file mode 100644
index 00000000000..db00551e695
--- /dev/null
+++ b/libgomp/config/gcn/target.c
@@ -0,0 +1,67 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+ Contributed by Mentor Embedded.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "libgomp.h"
+#include <limits.h>
+
+void
+GOMP_teams (unsigned int num_teams, unsigned int thread_limit)
+{
+ if (thread_limit)
+ {
+ struct gomp_task_icv *icv = gomp_icv (true);
+ icv->thread_limit_var
+ = thread_limit > INT_MAX ? UINT_MAX : thread_limit;
+ }
+ unsigned int num_workgroups, workgroup_id;
+ num_workgroups = __builtin_gcn_dim_size (0);
+ workgroup_id = __builtin_gcn_dim_pos (0);
+ if (!num_teams || num_teams >= num_workgroups)
+ num_teams = num_workgroups;
+ else if (workgroup_id >= num_teams)
+ {
+ gomp_free_thread (gcn_thrs ());
+ exit (0);
+ }
+ gomp_num_teams_var = num_teams - 1;
+}
+
+int
+omp_pause_resource (omp_pause_resource_t kind, int device_num)
+{
+ (void) kind;
+ (void) device_num;
+ return -1;
+}
+
+int
+omp_pause_resource_all (omp_pause_resource_t kind)
+{
+ (void) kind;
+ return -1;
+}
+
+ialias (omp_pause_resource)
+ialias (omp_pause_resource_all)
diff --git a/libgomp/config/gcn/task.c b/libgomp/config/gcn/task.c
new file mode 100644
index 00000000000..a13565034b6
--- /dev/null
+++ b/libgomp/config/gcn/task.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+ Contributed by Mentor Embedded.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file handles the maintainence of tasks in response to task
+ creation and termination. */
+
+#include "libgomp.h"
+
+/* AMD GCN is an accelerator-only target, so this should never be called. */
+
+bool
+gomp_target_task_fn (void *data)
+{
+ __builtin_unreachable ();
+}
+
+#include "../../task.c"
diff --git a/libgomp/config/gcn/team.c b/libgomp/config/gcn/team.c
new file mode 100644
index 00000000000..20d419198e0
--- /dev/null
+++ b/libgomp/config/gcn/team.c
@@ -0,0 +1,214 @@
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
+ Contributed by Mentor Embedded.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file handles maintainance of threads on AMD GCN. */
+
+#include "libgomp.h"
+#include <stdlib.h>
+#include <string.h>
+
+static void gomp_thread_start (struct gomp_thread_pool *);
+
+/* This externally visible function handles target region entry. It
+ sets up a per-team thread pool and transfers control by returning to
+ the kernel in the master thread or gomp_thread_start in other threads.
+
+ The name of this function is part of the interface with the compiler: for
+ each OpenMP kernel the compiler configures the stack, then calls here.
+
+ Likewise, gomp_gcn_exit_kernel is called during the kernel epilogue. */
+
+void
+gomp_gcn_enter_kernel (void)
+{
+ int threadid = __builtin_gcn_dim_pos (1);
+
+ if (threadid == 0)
+ {
+ int numthreads = __builtin_gcn_dim_size (1);
+ int teamid = __builtin_gcn_dim_pos(0);
+
+ /* Set up the global state.
+ Every team will do this, but that should be harmless. */
+ gomp_global_icv.nthreads_var = 16;
+ gomp_global_icv.thread_limit_var = numthreads;
+ /* Starting additional threads is not supported. */
+ gomp_global_icv.dyn_var = true;
+
+ /* Initialize the team arena for optimized memory allocation.
+ The arena has been allocated on the host side, and the address
+ passed in via the kernargs. Each team takes a small slice of it. */
+ register void **kernargs asm("s8");
+ void *team_arena = (kernargs[4] + TEAM_ARENA_SIZE*teamid);
+ void * __lds *arena_start = (void * __lds *)TEAM_ARENA_START;
+ void * __lds *arena_free = (void * __lds *)TEAM_ARENA_FREE;
+ void * __lds *arena_end = (void * __lds *)TEAM_ARENA_END;
+ *arena_start = team_arena;
+ *arena_free = team_arena;
+ *arena_end = team_arena + TEAM_ARENA_SIZE;
+
+ /* Allocate and initialize the team-local-storage data. */
+ struct gomp_thread *thrs = team_malloc_cleared (sizeof (*thrs)
+ * numthreads);
+ set_gcn_thrs (thrs);
+
+ /* Allocate and initailize a pool of threads in the team.
+ The threads are already running, of course, we just need to manage
+ the communication between them. */
+ struct gomp_thread_pool *pool = team_malloc (sizeof (*pool));
+ pool->threads = team_malloc (sizeof (void *) * numthreads);
+ for (int tid = 0; tid < numthreads; tid++)
+ pool->threads[tid] = &thrs[tid];
+ pool->threads_size = numthreads;
+ pool->threads_used = numthreads;
+ pool->threads_busy = 1;
+ pool->last_team = NULL;
+ gomp_simple_barrier_init (&pool->threads_dock, numthreads);
+ thrs->thread_pool = pool;
+
+ asm ("s_barrier" ::: "memory");
+ return; /* Return to kernel. */
+ }
+ else
+ {
+ asm ("s_barrier" ::: "memory");
+ gomp_thread_start (gcn_thrs ()[0].thread_pool);
+ /* gomp_thread_start does not return. */
+ }
+}
+
+void
+gomp_gcn_exit_kernel (void)
+{
+ gomp_free_thread (gcn_thrs ());
+ team_free (gcn_thrs ());
+}
+
+/* This function contains the idle loop in which a thread waits
+ to be called up to become part of a team. */
+
+static void
+gomp_thread_start (struct gomp_thread_pool *pool)
+{
+ struct gomp_thread *thr = gomp_thread ();
+
+ gomp_sem_init (&thr->release, 0);
+ thr->thread_pool = pool;
+
+ /* The loop exits only when "fn" is assigned "gomp_free_pool_helper",
+ which contains "s_endpgm", or an infinite no-op loop is
+ suspected (this happens when the thread master crashes). */
+ int nul_limit = 99;
+ do
+ {
+ gomp_simple_barrier_wait (&pool->threads_dock);
+ if (!thr->fn)
+ {
+ if (nul_limit-- > 0)
+ continue;
+ else
+ {
+ const char msg[] = ("team master not responding;"
+ " slave thread aborting");
+ write (2, msg, sizeof (msg)-1);
+ abort();
+ }
+ }
+ thr->fn (thr->data);
+ thr->fn = NULL;
+
+ struct gomp_task *task = thr->task;
+ gomp_team_barrier_wait_final (&thr->ts.team->barrier);
+ gomp_finish_task (task);
+ }
+ while (1);
+}
+
+/* Launch a team. */
+
+void
+gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
+ unsigned flags, struct gomp_team *team,
+ struct gomp_taskgroup *taskgroup)
+{
+ struct gomp_thread *thr, *nthr;
+ struct gomp_task *task;
+ struct gomp_task_icv *icv;
+ struct gomp_thread_pool *pool;
+ unsigned long nthreads_var;
+
+ thr = gomp_thread ();
+ pool = thr->thread_pool;
+ task = thr->task;
+ icv = task ? &task->icv : &gomp_global_icv;
+
+ /* Always save the previous state, even if this isn't a nested team.
+ In particular, we should save any work share state from an outer
+ orphaned work share construct. */
+ team->prev_ts = thr->ts;
+
+ thr->ts.team = team;
+ thr->ts.team_id = 0;
+ ++thr->ts.level;
+ if (nthreads > 1)
+ ++thr->ts.active_level;
+ thr->ts.work_share = &team->work_shares[0];
+ thr->ts.last_work_share = NULL;
+ thr->ts.single_count = 0;
+ thr->ts.static_trip = 0;
+ thr->task = &team->implicit_task[0];
+ nthreads_var = icv->nthreads_var;
+ gomp_init_task (thr->task, task, icv);
+ team->implicit_task[0].icv.nthreads_var = nthreads_var;
+ team->implicit_task[0].taskgroup = taskgroup;
+
+ if (nthreads == 1)
+ return;
+
+ /* Release existing idle threads. */
+ for (unsigned i = 1; i < nthreads; ++i)
+ {
+ nthr = pool->threads[i];
+ nthr->ts.team = team;
+ nthr->ts.work_share = &team->work_shares[0];
+ nthr->ts.last_work_share = NULL;
+ nthr->ts.team_id = i;
+ nthr->ts.level = team->prev_ts.level + 1;
+ nthr->ts.active_level = thr->ts.active_level;
+ nthr->ts.single_count = 0;
+ nthr->ts.static_trip = 0;
+ nthr->task = &team->implicit_task[i];
+ gomp_init_task (nthr->task, task, icv);
+ team->implicit_task[i].icv.nthreads_var = nthreads_var;
+ team->implicit_task[i].taskgroup = taskgroup;
+ nthr->fn = fn;
+ nthr->data = data;
+ team->ordered_release[i] = &nthr->release;
+ }
+
+ gomp_simple_barrier_wait (&pool->threads_dock);
+}
+
+#include "../../team.c"
diff --git a/libgomp/config/gcn/time.c b/libgomp/config/gcn/time.c
new file mode 100644
index 00000000000..f189e55889c
--- /dev/null
+++ b/libgomp/config/gcn/time.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
+ Contributed by Mentor Embedded.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file implements timer routines for AMD GCN. */
+
+#include "libgomp.h"
+
+/* According to AMD:
+ dGPU RTC is 27MHz
+ AGPU RTC is 100MHz
+ FIXME: DTRT on an APU. */
+#define RTC_TICKS (1.0 / 27000000.0) /* 27MHz */
+
+double
+omp_get_wtime (void)
+{
+ uint64_t clock;
+ asm ("s_memrealtime %0\n\t"
+ "s_waitcnt 0" : "=r" (clock));
+ return clock * RTC_TICKS;
+}
+
+double
+omp_get_wtick (void)
+{
+ return RTC_TICKS;
+}
+
+ialias (omp_get_wtime)
+ialias (omp_get_wtick)
diff --git a/libgomp/config/hpux/plugin-suffix.h b/libgomp/config/hpux/plugin-suffix.h
index 5eb4d074ce8..144745d7d27 100644
--- a/libgomp/config/hpux/plugin-suffix.h
+++ b/libgomp/config/hpux/plugin-suffix.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Jack Howarth <howarth.at.gcc@gmail.com>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/affinity.c b/libgomp/config/linux/affinity.c
index a2aefb8977c..647d241b741 100644
--- a/libgomp/config/linux/affinity.c
+++ b/libgomp/config/linux/affinity.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -396,6 +396,56 @@ gomp_get_place_proc_ids_8 (int place_num, int64_t *ids)
*ids++ = i;
}
+void
+gomp_display_affinity_place (char *buffer, size_t size, size_t *ret,
+ int place)
+{
+ cpu_set_t *cpusetp;
+ char buf[sizeof (long) * 3 + 4];
+ if (place >= 0 && place < gomp_places_list_len)
+ cpusetp = (cpu_set_t *) gomp_places_list[place];
+ else if (gomp_cpusetp)
+ cpusetp = gomp_cpusetp;
+ else
+ {
+ if (gomp_available_cpus > 1)
+ sprintf (buf, "0-%lu", gomp_available_cpus - 1);
+ else
+ strcpy (buf, "0");
+ gomp_display_string (buffer, size, ret, buf, strlen (buf));
+ return;
+ }
+
+ unsigned long i, max = 8 * gomp_cpuset_size, start;
+ bool prev_set = false;
+ start = max;
+ for (i = 0; i <= max; i++)
+ {
+ bool this_set;
+ if (i == max)
+ this_set = false;
+ else
+ this_set = CPU_ISSET_S (i, gomp_cpuset_size, cpusetp);
+ if (this_set != prev_set)
+ {
+ prev_set = this_set;
+ if (this_set)
+ {
+ char *p = buf;
+ if (start != max)
+ *p++ = ',';
+ sprintf (p, "%lu", i);
+ start = i;
+ }
+ else if (i == start + 1)
+ continue;
+ else
+ sprintf (buf, "-%lu", i - 1);
+ gomp_display_string (buffer, size, ret, buf, strlen (buf));
+ }
+ }
+}
+
ialias(omp_get_place_num_procs)
ialias(omp_get_place_proc_ids)
diff --git a/libgomp/config/linux/alpha/futex.h b/libgomp/config/linux/alpha/futex.h
index 2d7e3e6f4db..8d4bbe2bf60 100644
--- a/libgomp/config/linux/alpha/futex.h
+++ b/libgomp/config/linux/alpha/futex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/bar.c b/libgomp/config/linux/bar.c
index c01237ac282..c128670acdb 100644
--- a/libgomp/config/linux/bar.c
+++ b/libgomp/config/linux/bar.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/bar.h b/libgomp/config/linux/bar.h
index ae12f202ca2..7987fddf6fd 100644
--- a/libgomp/config/linux/bar.h
+++ b/libgomp/config/linux/bar.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/doacross.h b/libgomp/config/linux/doacross.h
index cfbc9c246e6..03e8d766efa 100644
--- a/libgomp/config/linux/doacross.h
+++ b/libgomp/config/linux/doacross.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/futex.h b/libgomp/config/linux/futex.h
index 9ae85578eca..7fca93a9f8c 100644
--- a/libgomp/config/linux/futex.h
+++ b/libgomp/config/linux/futex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2010-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2010-2019 Free Software Foundation, Inc.
Contributed by ARM Ltd.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/ia64/futex.h b/libgomp/config/linux/ia64/futex.h
index 6efec3c8132..27bd3a2913c 100644
--- a/libgomp/config/linux/ia64/futex.h
+++ b/libgomp/config/linux/ia64/futex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -45,8 +45,8 @@ sys_futex0(int *addr, int op, int val)
"=r"(r8), "=r"(r10)
: "r"(r15), "r"(out0), "r"(out1), "r"(out2), "r"(out3)
: "memory", "out4", "out5", "out6", "out7",
- /* Non-stacked integer registers, minus r8, r10, r15. */
- "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18",
+ /* Non-stacked integer registers, minus r8, r10, r12, r15. */
+ "r2", "r3", "r9", "r11", "r13", "r14", "r16", "r17", "r18",
"r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27",
"r28", "r29", "r30", "r31",
/* Predicate registers. */
diff --git a/libgomp/config/linux/lock.c b/libgomp/config/linux/lock.c
index d90cf423cfa..bc77e22a121 100644
--- a/libgomp/config/linux/lock.c
+++ b/libgomp/config/linux/lock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/mips/futex.h b/libgomp/config/linux/mips/futex.h
index e1c104024a8..bfce7939a75 100644
--- a/libgomp/config/linux/mips/futex.h
+++ b/libgomp/config/linux/mips/futex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Ilie Garbacea <ilie@mips.com>, Chao-ying Fu <fu@mips.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/mutex.c b/libgomp/config/linux/mutex.c
index 33d15c6f54d..aa4ef8c100f 100644
--- a/libgomp/config/linux/mutex.c
+++ b/libgomp/config/linux/mutex.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/mutex.h b/libgomp/config/linux/mutex.h
index d89fc99ec71..19d188d88d2 100644
--- a/libgomp/config/linux/mutex.h
+++ b/libgomp/config/linux/mutex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/powerpc/futex.h b/libgomp/config/linux/powerpc/futex.h
index 0f0f3df15ec..037e14b5f1d 100644
--- a/libgomp/config/linux/powerpc/futex.h
+++ b/libgomp/config/linux/powerpc/futex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/proc.c b/libgomp/config/linux/proc.c
index 1156b65a469..57b065199f6 100644
--- a/libgomp/config/linux/proc.c
+++ b/libgomp/config/linux/proc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/proc.h b/libgomp/config/linux/proc.h
index a9d625880ef..362cae9b79f 100644
--- a/libgomp/config/linux/proc.h
+++ b/libgomp/config/linux/proc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2011-2019 Free Software Foundation, Inc.
Contributed by Uros Bizjak <ubizjak@gmail.com>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/ptrlock.c b/libgomp/config/linux/ptrlock.c
index 691918bf721..563114948ae 100644
--- a/libgomp/config/linux/ptrlock.c
+++ b/libgomp/config/linux/ptrlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/ptrlock.h b/libgomp/config/linux/ptrlock.h
index 334d3c92847..6909203a7cd 100644
--- a/libgomp/config/linux/ptrlock.h
+++ b/libgomp/config/linux/ptrlock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/s390/futex.h b/libgomp/config/linux/s390/futex.h
index de08d9de07b..7b150a48c2b 100644
--- a/libgomp/config/linux/s390/futex.h
+++ b/libgomp/config/linux/s390/futex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/sem.c b/libgomp/config/linux/sem.c
index 3739123222a..7713f54ddcc 100644
--- a/libgomp/config/linux/sem.c
+++ b/libgomp/config/linux/sem.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/sem.h b/libgomp/config/linux/sem.h
index b85a6a5cec1..b9283955cd4 100644
--- a/libgomp/config/linux/sem.h
+++ b/libgomp/config/linux/sem.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/sparc/futex.h b/libgomp/config/linux/sparc/futex.h
index fea5aed8fca..a9121faad16 100644
--- a/libgomp/config/linux/sparc/futex.h
+++ b/libgomp/config/linux/sparc/futex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/tile/futex.h b/libgomp/config/linux/tile/futex.h
index f63a6e8a23d..da54bc3b3cd 100644
--- a/libgomp/config/linux/tile/futex.h
+++ b/libgomp/config/linux/tile/futex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2011-2019 Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/wait.h b/libgomp/config/linux/wait.h
index b1c2868c7ab..7967f59a493 100644
--- a/libgomp/config/linux/wait.h
+++ b/libgomp/config/linux/wait.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/linux/x86/futex.h b/libgomp/config/linux/x86/futex.h
index 02d5b95581f..21150490f5a 100644
--- a/libgomp/config/linux/x86/futex.h
+++ b/libgomp/config/linux/x86/futex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/mingw32/affinity-fmt.c b/libgomp/config/mingw32/affinity-fmt.c
new file mode 100644
index 00000000000..842dcec9d57
--- /dev/null
+++ b/libgomp/config/mingw32/affinity-fmt.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 2018-2019 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "libgomp.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h> /* For PRIx64. */
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <errno.h>
+
+static int
+gomp_gethostname (char *name, size_t len)
+{
+ /* On Win9x GetComputerName fails if the input size is less
+ than MAX_COMPUTERNAME_LENGTH + 1. */
+ char buffer[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD size = sizeof (buffer);
+ int ret = 0;
+
+ if (!GetComputerName (buffer, &size))
+ return -1;
+
+ if ((size = strlen (buffer) + 1) > len)
+ {
+ errno = EINVAL;
+ /* Truncate as per POSIX spec. We do not NUL-terminate. */
+ size = len;
+ ret = -1;
+ }
+ memcpy (name, buffer, (size_t) size);
+
+ return ret;
+}
+
+#undef gethostname
+#define gethostname gomp_gethostname
+#define HAVE_GETHOSTNAME 1
+
+#include "../../affinity-fmt.c"
diff --git a/libgomp/config/mingw32/proc.c b/libgomp/config/mingw32/proc.c
index 97060876851..3398a63aa25 100644
--- a/libgomp/config/mingw32/proc.c
+++ b/libgomp/config/mingw32/proc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2019 Free Software Foundation, Inc.
Contributed by Danny Smith <dannysmith@users.sourceforge.net>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/mingw32/time.c b/libgomp/config/mingw32/time.c
index c8d2dd0c0db..056f71b7a24 100644
--- a/libgomp/config/mingw32/time.c
+++ b/libgomp/config/mingw32/time.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2019 Free Software Foundation, Inc.
Contributed by Francois-Xavier Coudert <coudert@clipper.ens.fr>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/affinity-fmt.c b/libgomp/config/nvptx/affinity-fmt.c
new file mode 100644
index 00000000000..02b95a79f3c
--- /dev/null
+++ b/libgomp/config/nvptx/affinity-fmt.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "libgomp.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h> /* For PRIx64. */
+#endif
+#ifdef HAVE_UNAME
+#include <sys/utsname.h>
+#endif
+
+/* The HAVE_GETPID and HAVE_GETHOSTNAME configure tests are passing for nvptx,
+ while the nvptx newlib implementation does not support those functions.
+ Override the configure test results here. */
+#undef HAVE_GETPID
+#undef HAVE_GETHOSTNAME
+
+/* The nvptx newlib implementation does not support fwrite, but it does support
+ write. Map fwrite to write. */
+#undef fwrite
+#define fwrite(ptr, size, nmemb, stream) write (1, (ptr), (nmemb) * (size))
+
+#include "../../affinity-fmt.c"
+
diff --git a/libgomp/config/nvptx/bar.c b/libgomp/config/nvptx/bar.c
index fe342e9786e..05704e0a1be 100644
--- a/libgomp/config/nvptx/bar.c
+++ b/libgomp/config/nvptx/bar.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/bar.h b/libgomp/config/nvptx/bar.h
index f38d9e3be7b..63a7bc7dda1 100644
--- a/libgomp/config/nvptx/bar.h
+++ b/libgomp/config/nvptx/bar.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/doacross.h b/libgomp/config/nvptx/doacross.h
index 858536e533e..b48cae7a7f3 100644
--- a/libgomp/config/nvptx/doacross.h
+++ b/libgomp/config/nvptx/doacross.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/error.c b/libgomp/config/nvptx/error.c
index 914b8b6be82..6026e6434eb 100644
--- a/libgomp/config/nvptx/error.c
+++ b/libgomp/config/nvptx/error.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/icv-device.c b/libgomp/config/nvptx/icv-device.c
index 562db95f328..8efb2008a1b 100644
--- a/libgomp/config/nvptx/icv-device.c
+++ b/libgomp/config/nvptx/icv-device.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
@@ -46,20 +46,6 @@ omp_get_num_devices (void)
}
int
-omp_get_num_teams (void)
-{
- return gomp_num_teams_var + 1;
-}
-
-int
-omp_get_team_num (void)
-{
- int ctaid;
- asm ("mov.u32 %0, %%ctaid.x;" : "=r" (ctaid));
- return ctaid;
-}
-
-int
omp_is_initial_device (void)
{
/* NVPTX is an accelerator-only target. */
@@ -69,6 +55,4 @@ omp_is_initial_device (void)
ialias (omp_set_default_device)
ialias (omp_get_default_device)
ialias (omp_get_num_devices)
-ialias (omp_get_num_teams)
-ialias (omp_get_team_num)
ialias (omp_is_initial_device)
diff --git a/libgomp/config/nvptx/oacc-parallel.c b/libgomp/config/nvptx/oacc-parallel.c
index 5dc53da21eb..e69de29bb2d 100644
--- a/libgomp/config/nvptx/oacc-parallel.c
+++ b/libgomp/config/nvptx/oacc-parallel.c
@@ -1,358 +0,0 @@
-/* OpenACC constructs
-
- Copyright (C) 2014-2018 Free Software Foundation, Inc.
-
- Contributed by Mentor Embedded.
-
- This file is part of the GNU Offloading and Multi Processing Library
- (libgomp).
-
- Libgomp is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- Under Section 7 of GPL version 3, you are granted additional
- permissions described in the GCC Runtime Library Exception, version
- 3.1, as published by the Free Software Foundation.
-
- You should have received a copy of the GNU General Public License and
- a copy of the GCC Runtime Library Exception along with this program;
- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- <http://www.gnu.org/licenses/>. */
-
-#include "libgomp_g.h"
-
-__asm__ (".visible .func (.param .u32 %out_retval) GOACC_tid (.param .u32 %in_ar1);\n"
- ".visible .func (.param .u32 %out_retval) GOACC_ntid (.param .u32 %in_ar1);\n"
- ".visible .func (.param .u32 %out_retval) GOACC_ctaid (.param .u32 %in_ar1);\n"
- ".visible .func (.param .u32 %out_retval) GOACC_nctaid (.param .u32 %in_ar1);\n"
- "// BEGIN GLOBAL FUNCTION DECL: GOACC_get_num_threads\n"
- ".visible .func (.param .u32 %out_retval) GOACC_get_num_threads;\n"
- "// BEGIN GLOBAL FUNCTION DECL: GOACC_get_thread_num\n"
- ".visible .func (.param .u32 %out_retval) GOACC_get_thread_num;\n"
- "// BEGIN GLOBAL FUNCTION DECL: abort\n"
- ".extern .func abort;\n"
- ".visible .func (.param .u32 %out_retval) GOACC_tid (.param .u32 %in_ar1)\n"
- "{\n"
- ".reg .u32 %ar1;\n"
- ".reg .u32 %retval;\n"
- ".reg .u64 %hr10;\n"
- ".reg .u32 %r22;\n"
- ".reg .u32 %r23;\n"
- ".reg .u32 %r24;\n"
- ".reg .u32 %r25;\n"
- ".reg .u32 %r26;\n"
- ".reg .u32 %r27;\n"
- ".reg .u32 %r28;\n"
- ".reg .u32 %r29;\n"
- ".reg .pred %r30;\n"
- ".reg .u32 %r31;\n"
- ".reg .pred %r32;\n"
- ".reg .u32 %r33;\n"
- ".reg .pred %r34;\n"
- ".local .align 8 .b8 %frame[4];\n"
- "ld.param.u32 %ar1,[%in_ar1];\n"
- "mov.u32 %r27,%ar1;\n"
- "st.local.u32 [%frame],%r27;\n"
- "ld.local.u32 %r28,[%frame];\n"
- "mov.u32 %r29,1;\n"
- "setp.eq.u32 %r30,%r28,%r29;\n"
- "@%r30 bra $L4;\n"
- "mov.u32 %r31,2;\n"
- "setp.eq.u32 %r32,%r28,%r31;\n"
- "@%r32 bra $L5;\n"
- "mov.u32 %r33,0;\n"
- "setp.eq.u32 %r34,%r28,%r33;\n"
- "@!%r34 bra $L8;\n"
- "mov.u32 %r23,%tid.x;\n"
- "mov.u32 %r22,%r23;\n"
- "bra $L7;\n"
- "$L4:\n"
- "mov.u32 %r24,%tid.y;\n"
- "mov.u32 %r22,%r24;\n"
- "bra $L7;\n"
- "$L5:\n"
- "mov.u32 %r25,%tid.z;\n"
- "mov.u32 %r22,%r25;\n"
- "bra $L7;\n"
- "$L8:\n"
- "{\n"
- "{\n"
- "call abort;\n"
- "}\n"
- "}\n"
- "$L7:\n"
- "mov.u32 %r26,%r22;\n"
- "mov.u32 %retval,%r26;\n"
- "st.param.u32 [%out_retval],%retval;\n"
- "ret;\n"
- "}\n"
- ".visible .func (.param .u32 %out_retval) GOACC_ntid (.param .u32 %in_ar1)\n"
- "{\n"
- ".reg .u32 %ar1;\n"
- ".reg .u32 %retval;\n"
- ".reg .u64 %hr10;\n"
- ".reg .u32 %r22;\n"
- ".reg .u32 %r23;\n"
- ".reg .u32 %r24;\n"
- ".reg .u32 %r25;\n"
- ".reg .u32 %r26;\n"
- ".reg .u32 %r27;\n"
- ".reg .u32 %r28;\n"
- ".reg .u32 %r29;\n"
- ".reg .pred %r30;\n"
- ".reg .u32 %r31;\n"
- ".reg .pred %r32;\n"
- ".reg .u32 %r33;\n"
- ".reg .pred %r34;\n"
- ".local .align 8 .b8 %frame[4];\n"
- "ld.param.u32 %ar1,[%in_ar1];\n"
- "mov.u32 %r27,%ar1;\n"
- "st.local.u32 [%frame],%r27;\n"
- "ld.local.u32 %r28,[%frame];\n"
- "mov.u32 %r29,1;\n"
- "setp.eq.u32 %r30,%r28,%r29;\n"
- "@%r30 bra $L11;\n"
- "mov.u32 %r31,2;\n"
- "setp.eq.u32 %r32,%r28,%r31;\n"
- "@%r32 bra $L12;\n"
- "mov.u32 %r33,0;\n"
- "setp.eq.u32 %r34,%r28,%r33;\n"
- "@!%r34 bra $L15;\n"
- "mov.u32 %r23,%ntid.x;\n"
- "mov.u32 %r22,%r23;\n"
- "bra $L14;\n"
- "$L11:\n"
- "mov.u32 %r24,%ntid.y;\n"
- "mov.u32 %r22,%r24;\n"
- "bra $L14;\n"
- "$L12:\n"
- "mov.u32 %r25,%ntid.z;\n"
- "mov.u32 %r22,%r25;\n"
- "bra $L14;\n"
- "$L15:\n"
- "{\n"
- "{\n"
- "call abort;\n"
- "}\n"
- "}\n"
- "$L14:\n"
- "mov.u32 %r26,%r22;\n"
- "mov.u32 %retval,%r26;\n"
- "st.param.u32 [%out_retval],%retval;\n"
- "ret;\n"
- "}\n"
- ".visible .func (.param .u32 %out_retval) GOACC_ctaid (.param .u32 %in_ar1)\n"
- "{\n"
- ".reg .u32 %ar1;\n"
- ".reg .u32 %retval;\n"
- ".reg .u64 %hr10;\n"
- ".reg .u32 %r22;\n"
- ".reg .u32 %r23;\n"
- ".reg .u32 %r24;\n"
- ".reg .u32 %r25;\n"
- ".reg .u32 %r26;\n"
- ".reg .u32 %r27;\n"
- ".reg .u32 %r28;\n"
- ".reg .u32 %r29;\n"
- ".reg .pred %r30;\n"
- ".reg .u32 %r31;\n"
- ".reg .pred %r32;\n"
- ".reg .u32 %r33;\n"
- ".reg .pred %r34;\n"
- ".local .align 8 .b8 %frame[4];\n"
- "ld.param.u32 %ar1,[%in_ar1];\n"
- "mov.u32 %r27,%ar1;\n"
- "st.local.u32 [%frame],%r27;\n"
- "ld.local.u32 %r28,[%frame];\n"
- "mov.u32 %r29,1;\n"
- "setp.eq.u32 %r30,%r28,%r29;\n"
- "@%r30 bra $L18;\n"
- "mov.u32 %r31,2;\n"
- "setp.eq.u32 %r32,%r28,%r31;\n"
- "@%r32 bra $L19;\n"
- "mov.u32 %r33,0;\n"
- "setp.eq.u32 %r34,%r28,%r33;\n"
- "@!%r34 bra $L22;\n"
- "mov.u32 %r23,%ctaid.x;\n"
- "mov.u32 %r22,%r23;\n"
- "bra $L21;\n"
- "$L18:\n"
- "mov.u32 %r24,%ctaid.y;\n"
- "mov.u32 %r22,%r24;\n"
- "bra $L21;\n"
- "$L19:\n"
- "mov.u32 %r25,%ctaid.z;\n"
- "mov.u32 %r22,%r25;\n"
- "bra $L21;\n"
- "$L22:\n"
- "{\n"
- "{\n"
- "call abort;\n"
- "}\n"
- "}\n"
- "$L21:\n"
- "mov.u32 %r26,%r22;\n"
- "mov.u32 %retval,%r26;\n"
- "st.param.u32 [%out_retval],%retval;\n"
- "ret;\n"
- "}\n"
- ".visible .func (.param .u32 %out_retval) GOACC_nctaid (.param .u32 %in_ar1)\n"
- "{\n"
- ".reg .u32 %ar1;\n"
- ".reg .u32 %retval;\n"
- ".reg .u64 %hr10;\n"
- ".reg .u32 %r22;\n"
- ".reg .u32 %r23;\n"
- ".reg .u32 %r24;\n"
- ".reg .u32 %r25;\n"
- ".reg .u32 %r26;\n"
- ".reg .u32 %r27;\n"
- ".reg .u32 %r28;\n"
- ".reg .u32 %r29;\n"
- ".reg .pred %r30;\n"
- ".reg .u32 %r31;\n"
- ".reg .pred %r32;\n"
- ".reg .u32 %r33;\n"
- ".reg .pred %r34;\n"
- ".local .align 8 .b8 %frame[4];\n"
- "ld.param.u32 %ar1,[%in_ar1];\n"
- "mov.u32 %r27,%ar1;\n"
- "st.local.u32 [%frame],%r27;\n"
- "ld.local.u32 %r28,[%frame];\n"
- "mov.u32 %r29,1;\n"
- "setp.eq.u32 %r30,%r28,%r29;\n"
- "@%r30 bra $L25;\n"
- "mov.u32 %r31,2;\n"
- "setp.eq.u32 %r32,%r28,%r31;\n"
- "@%r32 bra $L26;\n"
- "mov.u32 %r33,0;\n"
- "setp.eq.u32 %r34,%r28,%r33;\n"
- "@!%r34 bra $L29;\n"
- "mov.u32 %r23,%nctaid.x;\n"
- "mov.u32 %r22,%r23;\n"
- "bra $L28;\n"
- "$L25:\n"
- "mov.u32 %r24,%nctaid.y;\n"
- "mov.u32 %r22,%r24;\n"
- "bra $L28;\n"
- "$L26:\n"
- "mov.u32 %r25,%nctaid.z;\n"
- "mov.u32 %r22,%r25;\n"
- "bra $L28;\n"
- "$L29:\n"
- "{\n"
- "{\n"
- "call abort;\n"
- "}\n"
- "}\n"
- "$L28:\n"
- "mov.u32 %r26,%r22;\n"
- "mov.u32 %retval,%r26;\n"
- "st.param.u32 [%out_retval],%retval;\n"
- "ret;\n"
- "}\n"
- "// BEGIN GLOBAL FUNCTION DEF: GOACC_get_num_threads\n"
- ".visible .func (.param .u32 %out_retval) GOACC_get_num_threads\n"
- "{\n"
- ".reg .u32 %retval;\n"
- ".reg .u64 %hr10;\n"
- ".reg .u32 %r22;\n"
- ".reg .u32 %r23;\n"
- ".reg .u32 %r24;\n"
- ".reg .u32 %r25;\n"
- ".reg .u32 %r26;\n"
- ".reg .u32 %r27;\n"
- ".reg .u32 %r28;\n"
- ".reg .u32 %r29;\n"
- "mov.u32 %r26,0;\n"
- "{\n"
- ".param .u32 %retval_in;\n"
- "{\n"
- ".param .u32 %out_arg0;\n"
- "st.param.u32 [%out_arg0],%r26;\n"
- "call (%retval_in),GOACC_ntid,(%out_arg0);\n"
- "}\n"
- "ld.param.u32 %r27,[%retval_in];\n"
- "}\n"
- "mov.u32 %r22,%r27;\n"
- "mov.u32 %r28,0;\n"
- "{\n"
- ".param .u32 %retval_in;\n"
- "{\n"
- ".param .u32 %out_arg0;\n"
- "st.param.u32 [%out_arg0],%r28;\n"
- "call (%retval_in),GOACC_nctaid,(%out_arg0);\n"
- "}\n"
- "ld.param.u32 %r29,[%retval_in];\n"
- "}\n"
- "mov.u32 %r23,%r29;\n"
- "mul.lo.u32 %r24,%r22,%r23;\n"
- "mov.u32 %r25,%r24;\n"
- "mov.u32 %retval,%r25;\n"
- "st.param.u32 [%out_retval],%retval;\n"
- "ret;\n"
- "}\n"
- "// BEGIN GLOBAL FUNCTION DEF: GOACC_get_thread_num\n"
- ".visible .func (.param .u32 %out_retval) GOACC_get_thread_num\n"
- "{\n"
- ".reg .u32 %retval;\n"
- ".reg .u64 %hr10;\n"
- ".reg .u32 %r22;\n"
- ".reg .u32 %r23;\n"
- ".reg .u32 %r24;\n"
- ".reg .u32 %r25;\n"
- ".reg .u32 %r26;\n"
- ".reg .u32 %r27;\n"
- ".reg .u32 %r28;\n"
- ".reg .u32 %r29;\n"
- ".reg .u32 %r30;\n"
- ".reg .u32 %r31;\n"
- ".reg .u32 %r32;\n"
- ".reg .u32 %r33;\n"
- "mov.u32 %r28,0;\n"
- "{\n"
- ".param .u32 %retval_in;\n"
- "{\n"
- ".param .u32 %out_arg0;\n"
- "st.param.u32 [%out_arg0],%r28;\n"
- "call (%retval_in),GOACC_ntid,(%out_arg0);\n"
- "}\n"
- "ld.param.u32 %r29,[%retval_in];\n"
- "}\n"
- "mov.u32 %r22,%r29;\n"
- "mov.u32 %r30,0;\n"
- "{\n"
- ".param .u32 %retval_in;\n"
- "{\n"
- ".param .u32 %out_arg0;\n"
- "st.param.u32 [%out_arg0],%r30;\n"
- "call (%retval_in),GOACC_ctaid,(%out_arg0);\n"
- "}\n"
- "ld.param.u32 %r31,[%retval_in];\n"
- "}\n"
- "mov.u32 %r23,%r31;\n"
- "mul.lo.u32 %r24,%r22,%r23;\n"
- "mov.u32 %r32,0;\n"
- "{\n"
- ".param .u32 %retval_in;\n"
- "{\n"
- ".param .u32 %out_arg0;\n"
- "st.param.u32 [%out_arg0],%r32;\n"
- "call (%retval_in),GOACC_tid,(%out_arg0);\n"
- "}\n"
- "ld.param.u32 %r33,[%retval_in];\n"
- "}\n"
- "mov.u32 %r25,%r33;\n"
- "add.u32 %r26,%r24,%r25;\n"
- "mov.u32 %r27,%r26;\n"
- "mov.u32 %retval,%r27;\n"
- "st.param.u32 [%out_retval],%retval;\n"
- "ret;\n"
- "}\n");
diff --git a/libgomp/config/nvptx/simple-bar.h b/libgomp/config/nvptx/simple-bar.h
index e80a6bf1849..ba13001e8dd 100644
--- a/libgomp/config/nvptx/simple-bar.h
+++ b/libgomp/config/nvptx/simple-bar.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/target.c b/libgomp/config/nvptx/target.c
index 64004acb422..69853902e1c 100644
--- a/libgomp/config/nvptx/target.c
+++ b/libgomp/config/nvptx/target.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -47,3 +47,21 @@ GOMP_teams (unsigned int num_teams, unsigned int thread_limit)
}
gomp_num_teams_var = num_teams - 1;
}
+
+int
+omp_pause_resource (omp_pause_resource_t kind, int device_num)
+{
+ (void) kind;
+ (void) device_num;
+ return -1;
+}
+
+int
+omp_pause_resource_all (omp_pause_resource_t kind)
+{
+ (void) kind;
+ return -1;
+}
+
+ialias (omp_pause_resource)
+ialias (omp_pause_resource_all)
diff --git a/libgomp/config/nvptx/task.c b/libgomp/config/nvptx/task.c
index f49db458ddc..643e301bd12 100644
--- a/libgomp/config/nvptx/task.c
+++ b/libgomp/config/nvptx/task.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/nvptx/team.c b/libgomp/config/nvptx/team.c
index 34059d389f2..8ad438df707 100644
--- a/libgomp/config/nvptx/team.c
+++ b/libgomp/config/nvptx/team.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
@@ -116,7 +116,8 @@ gomp_thread_start (struct gomp_thread_pool *pool)
void
gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
- unsigned flags, struct gomp_team *team)
+ unsigned flags, struct gomp_team *team,
+ struct gomp_taskgroup *taskgroup)
{
struct gomp_thread *thr, *nthr;
struct gomp_task *task;
@@ -147,6 +148,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
nthreads_var = icv->nthreads_var;
gomp_init_task (thr->task, task, icv);
team->implicit_task[0].icv.nthreads_var = nthreads_var;
+ team->implicit_task[0].taskgroup = taskgroup;
if (nthreads == 1)
return;
@@ -166,6 +168,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
nthr->task = &team->implicit_task[i];
gomp_init_task (nthr->task, task, icv);
team->implicit_task[i].icv.nthreads_var = nthreads_var;
+ team->implicit_task[i].taskgroup = taskgroup;
nthr->fn = fn;
nthr->data = data;
team->ordered_release[i] = &nthr->release;
@@ -174,5 +177,11 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
gomp_simple_barrier_wait (&pool->threads_dock);
}
+int
+gomp_pause_host (void)
+{
+ return -1;
+}
+
#include "../../team.c"
#endif
diff --git a/libgomp/config/nvptx/teams.c b/libgomp/config/nvptx/teams.c
new file mode 100644
index 00000000000..b941befba1a
--- /dev/null
+++ b/libgomp/config/nvptx/teams.c
@@ -0,0 +1,57 @@
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
+ Contributed by Alexander Monakov <amonakov@ispras.ru>
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file defines OpenMP API entry points that accelerator targets are
+ expected to replace. */
+
+#include "libgomp.h"
+
+void
+GOMP_teams_reg (void (*fn) (void *), void *data, unsigned int num_teams,
+ unsigned int thread_limit, unsigned int flags)
+{
+ (void) fn;
+ (void) data;
+ (void) flags;
+ (void) num_teams;
+ (void) thread_limit;
+}
+
+int
+omp_get_num_teams (void)
+{
+ return gomp_num_teams_var + 1;
+}
+
+int
+omp_get_team_num (void)
+{
+ int ctaid;
+ asm ("mov.u32 %0, %%ctaid.x;" : "=r" (ctaid));
+ return ctaid;
+}
+
+ialias (omp_get_num_teams)
+ialias (omp_get_team_num)
diff --git a/libgomp/config/nvptx/time.c b/libgomp/config/nvptx/time.c
index 92742a03e64..d4286c1db4d 100644
--- a/libgomp/config/nvptx/time.c
+++ b/libgomp/config/nvptx/time.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Dmitry Melnik <dm@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/bar.c b/libgomp/config/posix/bar.c
index f42256953e9..fea3ee139d3 100644
--- a/libgomp/config/posix/bar.c
+++ b/libgomp/config/posix/bar.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/bar.h b/libgomp/config/posix/bar.h
index e51c773c1a5..5aeabd41695 100644
--- a/libgomp/config/posix/bar.h
+++ b/libgomp/config/posix/bar.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/doacross.h b/libgomp/config/posix/doacross.h
index fd7c6f201bf..6f4d013c53c 100644
--- a/libgomp/config/posix/doacross.h
+++ b/libgomp/config/posix/doacross.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/lock.c b/libgomp/config/posix/lock.c
index ed81a9e03b9..6fb22b9471d 100644
--- a/libgomp/config/posix/lock.c
+++ b/libgomp/config/posix/lock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/mutex.h b/libgomp/config/posix/mutex.h
index 46edb9066e6..a2068770db1 100644
--- a/libgomp/config/posix/mutex.h
+++ b/libgomp/config/posix/mutex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/plugin-suffix.h b/libgomp/config/posix/plugin-suffix.h
index 1f8efec021f..224a9ab4cc1 100644
--- a/libgomp/config/posix/plugin-suffix.h
+++ b/libgomp/config/posix/plugin-suffix.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Jack Howarth <howarth.at.gcc@gmail.com>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/pool.h b/libgomp/config/posix/pool.h
index 4d5c3555726..61d180e9811 100644
--- a/libgomp/config/posix/pool.h
+++ b/libgomp/config/posix/pool.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/proc.c b/libgomp/config/posix/proc.c
index 8b2fb346cb4..c87438baa24 100644
--- a/libgomp/config/posix/proc.c
+++ b/libgomp/config/posix/proc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/ptrlock.h b/libgomp/config/posix/ptrlock.h
index 337e325a615..045675e7983 100644
--- a/libgomp/config/posix/ptrlock.h
+++ b/libgomp/config/posix/ptrlock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/sem.c b/libgomp/config/posix/sem.c
index 7aa04eaeb71..5f3e03dca91 100644
--- a/libgomp/config/posix/sem.c
+++ b/libgomp/config/posix/sem.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/sem.h b/libgomp/config/posix/sem.h
index cb698e9053d..70d59055676 100644
--- a/libgomp/config/posix/sem.h
+++ b/libgomp/config/posix/sem.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/simple-bar.h b/libgomp/config/posix/simple-bar.h
index 749a0ccf9b1..40146200146 100644
--- a/libgomp/config/posix/simple-bar.h
+++ b/libgomp/config/posix/simple-bar.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Alexander Monakov <amonakov@ispras.ru>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/thread-stacksize.h b/libgomp/config/posix/thread-stacksize.h
index 3254216a2a3..dfe4932e5c7 100644
--- a/libgomp/config/posix/thread-stacksize.h
+++ b/libgomp/config/posix/thread-stacksize.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/posix/time.c b/libgomp/config/posix/time.c
index 51b3f0e6c5a..60ac0d0af51 100644
--- a/libgomp/config/posix/time.c
+++ b/libgomp/config/posix/time.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/rtems/affinity-fmt.c b/libgomp/config/rtems/affinity-fmt.c
new file mode 100644
index 00000000000..e4e14c163e9
--- /dev/null
+++ b/libgomp/config/rtems/affinity-fmt.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "libgomp.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h> /* For PRIx64. */
+#endif
+#ifdef HAVE_UNAME
+#include <sys/utsname.h>
+#endif
+
+/* The HAVE_GETPID and HAVE_GETHOSTNAME configure tests are passing for RTEMS,
+ but the extra information they give are of little value for the user.
+ Override the configure test results here. */
+#undef HAVE_GETPID
+#undef HAVE_GETHOSTNAME
+
+/* Avoid the complex fwrite() in favour of the simple write(). */
+#undef fwrite
+#define fwrite(ptr, size, nmemb, stream) write (1, (ptr), (nmemb) * (size))
+
+#include "../../affinity-fmt.c"
diff --git a/libgomp/config/rtems/bar.c b/libgomp/config/rtems/bar.c
index 2ee7909cddd..e15327d9b71 100644
--- a/libgomp/config/rtems/bar.c
+++ b/libgomp/config/rtems/bar.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -72,184 +72,5 @@ do_wait (int *addr, int val)
futex_wait (addr, val);
}
-/* Everything below this point should be identical to the Linux
- implementation. */
-
-void
-gomp_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
-{
- if (__builtin_expect (state & BAR_WAS_LAST, 0))
- {
- /* Next time we'll be awaiting TOTAL threads again. */
- bar->awaited = bar->total;
- __atomic_store_n (&bar->generation, bar->generation + BAR_INCR,
- MEMMODEL_RELEASE);
- futex_wake ((int *) &bar->generation, INT_MAX);
- }
- else
- {
- do
- do_wait ((int *) &bar->generation, state);
- while (__atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE) == state);
- }
-}
-
-void
-gomp_barrier_wait (gomp_barrier_t *bar)
-{
- gomp_barrier_wait_end (bar, gomp_barrier_wait_start (bar));
-}
-
-/* Like gomp_barrier_wait, except that if the encountering thread
- is not the last one to hit the barrier, it returns immediately.
- The intended usage is that a thread which intends to gomp_barrier_destroy
- this barrier calls gomp_barrier_wait, while all other threads
- call gomp_barrier_wait_last. When gomp_barrier_wait returns,
- the barrier can be safely destroyed. */
-
-void
-gomp_barrier_wait_last (gomp_barrier_t *bar)
-{
- gomp_barrier_state_t state = gomp_barrier_wait_start (bar);
- if (state & BAR_WAS_LAST)
- gomp_barrier_wait_end (bar, state);
-}
-
-void
-gomp_team_barrier_wake (gomp_barrier_t *bar, int count)
-{
- futex_wake ((int *) &bar->generation, count == 0 ? INT_MAX : count);
-}
-
-void
-gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
-{
- unsigned int generation, gen;
-
- if (__builtin_expect (state & BAR_WAS_LAST, 0))
- {
- /* Next time we'll be awaiting TOTAL threads again. */
- struct gomp_thread *thr = gomp_thread ();
- struct gomp_team *team = thr->ts.team;
-
- bar->awaited = bar->total;
- team->work_share_cancelled = 0;
- if (__builtin_expect (team->task_count, 0))
- {
- gomp_barrier_handle_tasks (state);
- state &= ~BAR_WAS_LAST;
- }
- else
- {
- state &= ~BAR_CANCELLED;
- state += BAR_INCR - BAR_WAS_LAST;
- __atomic_store_n (&bar->generation, state, MEMMODEL_RELEASE);
- futex_wake ((int *) &bar->generation, INT_MAX);
- return;
- }
- }
-
- generation = state;
- state &= ~BAR_CANCELLED;
- do
- {
- do_wait ((int *) &bar->generation, generation);
- gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE);
- if (__builtin_expect (gen & BAR_TASK_PENDING, 0))
- {
- gomp_barrier_handle_tasks (state);
- gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE);
- }
- generation |= gen & BAR_WAITING_FOR_TASK;
- }
- while (gen != state + BAR_INCR);
-}
-
-void
-gomp_team_barrier_wait (gomp_barrier_t *bar)
-{
- gomp_team_barrier_wait_end (bar, gomp_barrier_wait_start (bar));
-}
-
-void
-gomp_team_barrier_wait_final (gomp_barrier_t *bar)
-{
- gomp_barrier_state_t state = gomp_barrier_wait_final_start (bar);
- if (__builtin_expect (state & BAR_WAS_LAST, 0))
- bar->awaited_final = bar->total;
- gomp_team_barrier_wait_end (bar, state);
-}
-
-bool
-gomp_team_barrier_wait_cancel_end (gomp_barrier_t *bar,
- gomp_barrier_state_t state)
-{
- unsigned int generation, gen;
-
- if (__builtin_expect (state & BAR_WAS_LAST, 0))
- {
- /* Next time we'll be awaiting TOTAL threads again. */
- /* BAR_CANCELLED should never be set in state here, because
- cancellation means that at least one of the threads has been
- cancelled, thus on a cancellable barrier we should never see
- all threads to arrive. */
- struct gomp_thread *thr = gomp_thread ();
- struct gomp_team *team = thr->ts.team;
-
- bar->awaited = bar->total;
- team->work_share_cancelled = 0;
- if (__builtin_expect (team->task_count, 0))
- {
- gomp_barrier_handle_tasks (state);
- state &= ~BAR_WAS_LAST;
- }
- else
- {
- state += BAR_INCR - BAR_WAS_LAST;
- __atomic_store_n (&bar->generation, state, MEMMODEL_RELEASE);
- futex_wake ((int *) &bar->generation, INT_MAX);
- return false;
- }
- }
-
- if (__builtin_expect (state & BAR_CANCELLED, 0))
- return true;
-
- generation = state;
- do
- {
- do_wait ((int *) &bar->generation, generation);
- gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE);
- if (__builtin_expect (gen & BAR_CANCELLED, 0))
- return true;
- if (__builtin_expect (gen & BAR_TASK_PENDING, 0))
- {
- gomp_barrier_handle_tasks (state);
- gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE);
- }
- generation |= gen & BAR_WAITING_FOR_TASK;
- }
- while (gen != state + BAR_INCR);
-
- return false;
-}
-
-bool
-gomp_team_barrier_wait_cancel (gomp_barrier_t *bar)
-{
- return gomp_team_barrier_wait_cancel_end (bar, gomp_barrier_wait_start (bar));
-}
-
-void
-gomp_team_barrier_cancel (struct gomp_team *team)
-{
- gomp_mutex_lock (&team->task_lock);
- if (team->barrier.generation & BAR_CANCELLED)
- {
- gomp_mutex_unlock (&team->task_lock);
- return;
- }
- team->barrier.generation |= BAR_CANCELLED;
- gomp_mutex_unlock (&team->task_lock);
- futex_wake ((int *) &team->barrier.generation, INT_MAX);
-}
+#define GOMP_WAIT_H 1
+#include "../linux/bar.c"
diff --git a/libgomp/config/rtems/bar.h b/libgomp/config/rtems/bar.h
index 19a3b14717d..b216841de9e 100644
--- a/libgomp/config/rtems/bar.h
+++ b/libgomp/config/rtems/bar.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>.
This file is part of the GNU OpenMP Library (libgomp).
diff --git a/libgomp/config/rtems/mutex.h b/libgomp/config/rtems/mutex.h
index 1e30c726779..fa010b26b21 100644
--- a/libgomp/config/rtems/mutex.h
+++ b/libgomp/config/rtems/mutex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>.
This file is part of the GNU OpenMP Library (libgomp).
diff --git a/libgomp/config/rtems/pool.h b/libgomp/config/rtems/pool.h
index 6c0398cdd7c..43ce41898d6 100644
--- a/libgomp/config/rtems/pool.h
+++ b/libgomp/config/rtems/pool.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/rtems/proc.c b/libgomp/config/rtems/proc.c
index 4b3c120baa4..3a552c553ce 100644
--- a/libgomp/config/rtems/proc.c
+++ b/libgomp/config/rtems/proc.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/config/rtems/sem.h b/libgomp/config/rtems/sem.h
index 53c98142bee..2fb60e3e80c 100644
--- a/libgomp/config/rtems/sem.h
+++ b/libgomp/config/rtems/sem.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>.
This file is part of the GNU OpenMP Library (libgomp).
diff --git a/libgomp/configure b/libgomp/configure
index ced7606b355..04a6fd96610 100755
--- a/libgomp/configure
+++ b/libgomp/configure
@@ -1,10 +1,10 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.64 for GNU Offloading and Multi Processing Runtime Library 1.0.
+# Generated by GNU Autoconf 2.69 for GNU Offloading and Multi Processing Runtime Library 1.0.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-# Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
@@ -87,6 +87,7 @@ fi
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -131,6 +132,31 @@ export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
@@ -164,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -217,14 +244,25 @@ IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
fi
if test x$as_have_required = xno; then :
@@ -322,10 +360,18 @@ $as_echo X"$as_dir" |
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -362,19 +408,19 @@ else
fi # as_fn_arith
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
- as_status=$?; test $as_status -eq 0 && as_status=1
- if test "$3"; then
- as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
- $as_echo "$as_me: error: $1" >&2
+ $as_echo "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
@@ -447,6 +493,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
@@ -481,16 +531,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -502,28 +552,8 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -534,10 +564,11 @@ as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
SHELL=${CONFIG_SHELL-/bin/sh}
-exec 7<&0 </dev/null 6>&1
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
@@ -622,6 +653,7 @@ link_gomp
XLDFLAGS
XCFLAGS
config_path
+CPU_COUNT
LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_FALSE
LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE
LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_FALSE
@@ -630,12 +662,20 @@ LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE
LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE
OPT_LDFLAGS
SECTION_LDFLAGS
+PLUGIN_GCN_FALSE
+PLUGIN_GCN_TRUE
PLUGIN_HSA_FALSE
PLUGIN_HSA_TRUE
PLUGIN_NVPTX_FALSE
PLUGIN_NVPTX_TRUE
offload_additional_lib_paths
offload_additional_options
+offload_targets
+offload_plugins
+PLUGIN_GCN_LIBS
+PLUGIN_GCN_LDFLAGS
+PLUGIN_GCN_CPPFLAGS
+PLUGIN_GCN
PLUGIN_HSA_LIBS
PLUGIN_HSA_LDFLAGS
PLUGIN_HSA_CPPFLAGS
@@ -648,7 +688,6 @@ PLUGIN_NVPTX_CPPFLAGS
PLUGIN_NVPTX
CUDA_DRIVER_LIB
CUDA_DRIVER_INCLUDE
-offload_targets
libtool_VERSION
ac_ct_FC
FCFLAGS
@@ -701,6 +740,10 @@ CC
toolexeclibdir
toolexecdir
multi_basedir
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
am__untar
am__tar
AMTAR
@@ -781,6 +824,7 @@ ac_user_opts='
enable_option_checking
enable_version_specific_runtime_libs
enable_generated_files_in_srcdir
+enable_silent_rules
enable_multilib
enable_dependency_tracking
enable_shared
@@ -873,8 +917,9 @@ do
fi
case $ac_option in
- *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *) ac_optarg=yes ;;
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
esac
# Accept the important Cygnus configure options, so we can diagnose typos.
@@ -919,7 +964,7 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid feature name: $ac_useropt"
+ as_fn_error $? "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -945,7 +990,7 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid feature name: $ac_useropt"
+ as_fn_error $? "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1149,7 +1194,7 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid package name: $ac_useropt"
+ as_fn_error $? "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1165,7 +1210,7 @@ do
ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid package name: $ac_useropt"
+ as_fn_error $? "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1195,8 +1240,8 @@ do
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries=$ac_optarg ;;
- -*) as_fn_error "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information."
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
;;
*=*)
@@ -1204,7 +1249,7 @@ Try \`$0 --help' for more information."
# Reject names that are not valid shell variable names.
case $ac_envvar in #(
'' | [0-9]* | *[!_$as_cr_alnum]* )
- as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
esac
eval $ac_envvar=\$ac_optarg
export $ac_envvar ;;
@@ -1214,7 +1259,7 @@ Try \`$0 --help' for more information."
$as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
$as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
;;
esac
@@ -1222,13 +1267,13 @@ done
if test -n "$ac_prev"; then
ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- as_fn_error "missing argument to $ac_option"
+ as_fn_error $? "missing argument to $ac_option"
fi
if test -n "$ac_unrecognized_opts"; then
case $enable_option_checking in
no) ;;
- fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
*) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
esac
fi
@@ -1251,7 +1296,7 @@ do
[\\/$]* | ?:[\\/]* ) continue;;
NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
esac
- as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done
# There might be people who depend on the old broken behavior: `$host'
@@ -1265,8 +1310,6 @@ target=$target_alias
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used." >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -1281,9 +1324,9 @@ test "$silent" = yes && exec 6>/dev/null
ac_pwd=`pwd` && test -n "$ac_pwd" &&
ac_ls_di=`ls -di .` &&
ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- as_fn_error "working directory cannot be determined"
+ as_fn_error $? "working directory cannot be determined"
test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- as_fn_error "pwd does not report name of working directory"
+ as_fn_error $? "pwd does not report name of working directory"
# Find the source files, if location was not specified.
@@ -1322,11 +1365,11 @@ else
fi
if test ! -r "$srcdir/$ac_unique_file"; then
test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
fi
ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
@@ -1366,7 +1409,7 @@ Configuration:
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking...' messages
+ -q, --quiet, --silent do not print \`checking ...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for \`--cache-file=config.cache'
-n, --no-create do not create output files
@@ -1438,16 +1481,21 @@ Optional Features:
put copies of generated files in source dir intended
for creating source tarballs for users without
texinfo bison or flex. [default=no]
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
--enable-multilib build many library versions (default)
- --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=yes]
--enable-fast-install[=PKGS]
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
- --enable-maintainer-mode enable make rules and dependencies not useful
- (and sometimes confusing) to the casual installer
+ --enable-maintainer-mode
+ enable make rules and dependencies not useful (and
+ sometimes confusing) to the casual installer
--enable-linux-futex use the Linux futex system call [default=default]
--enable-tls Use thread-local storage [default=yes]
--enable-symvers=STYLE enables symbol versioning of the shared library
@@ -1489,7 +1537,7 @@ Some influential environment variables:
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
LIBS libraries to pass to the linker, e.g. -l<library>
- CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
you have headers in a nonstandard directory <include dir>
CPP C preprocessor
FC Fortran compiler command
@@ -1564,9 +1612,9 @@ test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
GNU Offloading and Multi Processing Runtime Library configure 1.0
-generated by GNU Autoconf 2.64
+generated by GNU Autoconf 2.69
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1610,8 +1658,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
} # ac_fn_c_try_compile
@@ -1642,7 +1690,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -1656,8 +1704,8 @@ fi
# interfere with the next link command; also delete a directory that is
# left behind by Apple's compiler. We do this before executing the actions.
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
} # ac_fn_c_try_link
@@ -1670,7 +1718,7 @@ ac_fn_c_check_header_compile ()
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -1688,7 +1736,7 @@ fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_header_compile
@@ -1713,7 +1761,7 @@ $as_echo "$ac_try_echo"; } >&5
mv -f conftest.er1 conftest.err
fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } >/dev/null && {
+ test $ac_status = 0; } > conftest.i && {
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
test ! -s conftest.err
}; then :
@@ -1724,8 +1772,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
} # ac_fn_c_try_cpp
@@ -1766,8 +1814,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=$ac_status
fi
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
} # ac_fn_c_try_run
@@ -1779,7 +1827,7 @@ ac_fn_c_check_func ()
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -1834,7 +1882,7 @@ fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_func
@@ -1871,8 +1919,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
} # ac_fn_fc_try_compile
@@ -1903,7 +1951,7 @@ $as_echo "$ac_try_echo"; } >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -1917,8 +1965,8 @@ fi
# interfere with the next link command; also delete a directory that is
# left behind by Apple's compiler. We do this before executing the actions.
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
} # ac_fn_fc_try_link
@@ -1930,10 +1978,10 @@ fi
ac_fn_c_check_header_mongrel ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ if eval \${$3+:} false; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
@@ -1969,7 +2017,7 @@ if ac_fn_c_try_cpp "$LINENO"; then :
else
ac_header_preproc=no
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
$as_echo "$ac_header_preproc" >&6; }
@@ -1996,7 +2044,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
eval "$3=\$ac_header_compiler"
@@ -2005,7 +2053,7 @@ eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_header_mongrel
@@ -2018,7 +2066,7 @@ ac_fn_c_check_type ()
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
@@ -2059,7 +2107,7 @@ fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_type
@@ -2080,7 +2128,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2096,7 +2145,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2122,7 +2172,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2138,7 +2189,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2172,7 +2224,8 @@ int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2236,8 +2289,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
rm -f conftest.val
fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
} # ac_fn_c_compute_int
cat >config.log <<_ACEOF
@@ -2245,7 +2298,7 @@ This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by GNU Offloading and Multi Processing Runtime Library $as_me 1.0, which was
-generated by GNU Autoconf 2.64. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2355,11 +2408,9 @@ trap 'exit_status=$?
{
echo
- cat <<\_ASBOX
-## ---------------- ##
+ $as_echo "## ---------------- ##
## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
echo
# The following way of writing the cache mishandles newlines in values,
(
@@ -2393,11 +2444,9 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
)
echo
- cat <<\_ASBOX
-## ----------------- ##
+ $as_echo "## ----------------- ##
## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
echo
for ac_var in $ac_subst_vars
do
@@ -2410,11 +2459,9 @@ _ASBOX
echo
if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------------- ##
+ $as_echo "## ------------------- ##
## File substitutions. ##
-## ------------------- ##
-_ASBOX
+## ------------------- ##"
echo
for ac_var in $ac_subst_files
do
@@ -2428,11 +2475,9 @@ _ASBOX
fi
if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
+ $as_echo "## ----------- ##
## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
echo
cat confdefs.h
echo
@@ -2487,7 +2532,12 @@ _ACEOF
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
- ac_site_file1=$CONFIG_SITE
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
elif test "x$prefix" != xNONE; then
ac_site_file1=$prefix/share/config.site
ac_site_file2=$prefix/etc/config.site
@@ -2498,18 +2548,22 @@ fi
for ac_site_file in "$ac_site_file1" "$ac_site_file2"
do
test "x$ac_site_file" = xNONE && continue
- if test -r "$ac_site_file"; then
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
$as_echo "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file"
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
fi
done
if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special
- # files actually), so we avoid doing that.
- if test -f "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
$as_echo "$as_me: loading cache $cache_file" >&6;}
case $cache_file in
@@ -2585,7 +2639,7 @@ if $ac_cache_corrupted; then
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
fi
## -------------------- ##
## Main body of script. ##
@@ -2615,7 +2669,7 @@ if test "${enable_version_specific_runtime_libs+set}" = set; then :
enableval=$enable_version_specific_runtime_libs;
case "$enableval" in
yes|no) ;;
- *) as_fn_error "Unknown argument to enable/disable version-specific-runtime-libs" "$LINENO" 5 ;;
+ *) as_fn_error $? "Unknown argument to enable/disable version-specific-runtime-libs" "$LINENO" 5 ;;
esac
else
@@ -2638,7 +2692,7 @@ if test "${enable_generated_files_in_srcdir+set}" = set; then :
enableval=$enable_generated_files_in_srcdir;
case "$enableval" in
yes|no) ;;
- *) as_fn_error "Unknown argument to enable/disable generated-files-in-srcdir" "$LINENO" 5 ;;
+ *) as_fn_error $? "Unknown argument to enable/disable generated-files-in-srcdir" "$LINENO" 5 ;;
esac
else
@@ -2678,16 +2732,22 @@ fi
# http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html
ac_aux_dir=
for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- for ac_t in install-sh install.sh shtool; do
- if test -f "$ac_dir/$ac_t"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/$ac_t -c"
- break 2
- fi
- done
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
done
if test -z "$ac_aux_dir"; then
- as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
fi
# These three variables are undocumented and unsupported,
@@ -2701,27 +2761,27 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
# Make sure we can run config.sub.
$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
- as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
$as_echo_n "checking build system type... " >&6; }
-if test "${ac_cv_build+set}" = set; then :
+if ${ac_cv_build+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_build_alias=$build_alias
test "x$ac_build_alias" = x &&
ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
test "x$ac_build_alias" = x &&
- as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
- as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
$as_echo "$ac_cv_build" >&6; }
case $ac_cv_build in
*-*-*) ;;
-*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
esac
build=$ac_cv_build
ac_save_IFS=$IFS; IFS='-'
@@ -2739,14 +2799,14 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
$as_echo_n "checking host system type... " >&6; }
-if test "${ac_cv_host+set}" = set; then :
+if ${ac_cv_host+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "x$host_alias" = x; then
ac_cv_host=$ac_cv_build
else
ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
- as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
fi
fi
@@ -2754,7 +2814,7 @@ fi
$as_echo "$ac_cv_host" >&6; }
case $ac_cv_host in
*-*-*) ;;
-*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
esac
host=$ac_cv_host
ac_save_IFS=$IFS; IFS='-'
@@ -2772,14 +2832,14 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
$as_echo_n "checking target system type... " >&6; }
-if test "${ac_cv_target+set}" = set; then :
+if ${ac_cv_target+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "x$target_alias" = x; then
ac_cv_target=$ac_cv_host
else
ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
- as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
fi
fi
@@ -2787,7 +2847,7 @@ fi
$as_echo "$ac_cv_target" >&6; }
case $ac_cv_target in
*-*-*) ;;
-*) as_fn_error "invalid value of canonical target" "$LINENO" 5;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
esac
target=$ac_cv_target
ac_save_IFS=$IFS; IFS='-'
@@ -2824,7 +2884,7 @@ target_alias=${target_alias-$host_alias}
# -Wall: turns on all automake warnings...
# -Wno-portability: ...except this one, since GNU make is required.
# -Wno-override: ... and this one, since we do want this in testsuite.
-am__api_version='1.11'
+am__api_version='1.15'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -2843,7 +2903,7 @@ am__api_version='1.11'
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
$as_echo_n "checking for a BSD-compatible install... " >&6; }
if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then :
+if ${ac_cv_path_install+:} false; then :
$as_echo_n "(cached) " >&6
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -2863,7 +2923,7 @@ case $as_dir/ in #((
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
@@ -2921,56 +2981,71 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
$as_echo_n "checking whether build environment is sane... " >&6; }
-# Just in case
-sleep 1
-echo timestamp > conftest.file
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
'
case `pwd` in
*[\\\"\#\$\&\'\`$am_lf]*)
- as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
esac
case $srcdir in
*[\\\"\#\$\&\'\`$am_lf\ \ ]*)
- as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
esac
-# Do `set' in a subshell so we don't clobber the current shell's
+# Do 'set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$*" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$*" != "X $srcdir/configure conftest.file" \
- && test "$*" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- as_fn_error "ls -t appears to fail. Make sure there is not a broken
-alias in your environment" "$LINENO" 5
- fi
-
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
test "$2" = conftest.file
)
then
# Ok.
:
else
- as_fn_error "newly created file is older than distributed files!
+ as_fn_error $? "newly created file is older than distributed files!
Check your system clock" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
test "$program_prefix" != NONE &&
program_transform_name="s&^&$program_prefix&;$program_transform_name"
# Use a double $ so make ignores it.
@@ -2981,8 +3056,8 @@ test "$program_suffix" != NONE &&
ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
if test x"${MISSING+set}" != xset; then
case $am_aux_dir in
@@ -2993,15 +3068,15 @@ if test x"${MISSING+set}" != xset; then
esac
fi
# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
else
am_missing_run=
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
-$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
fi
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -3010,17 +3085,17 @@ if test x"${install_sh}" != xset; then
esac
fi
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
+# will honor the 'STRIP' environment variable to overrule this program.
if test "$cross_compiling" != no; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
set dummy ${ac_tool_prefix}strip; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
+if ${ac_cv_prog_STRIP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$STRIP"; then
@@ -3032,7 +3107,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3060,7 +3135,7 @@ if test -z "$ac_cv_prog_STRIP"; then
set dummy strip; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_STRIP"; then
@@ -3072,7 +3147,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3113,7 +3188,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
if test -z "$MKDIR_P"; then
- if test "${ac_cv_path_mkdir+set}" = set; then :
+ if ${ac_cv_path_mkdir+:} false; then :
$as_echo_n "(cached) " >&6
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -3123,7 +3198,7 @@ do
test -z "$as_dir" && as_dir=.
for ac_prog in mkdir gmkdir; do
for ac_exec_ext in '' $ac_executable_extensions; do
- { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
'mkdir (GNU coreutils) '* | \
'mkdir (coreutils) '* | \
@@ -3138,6 +3213,7 @@ IFS=$as_save_IFS
fi
+ test -d ./--version && rmdir ./--version
if test "${ac_cv_path_mkdir+set}" = set; then
MKDIR_P="$ac_cv_path_mkdir -p"
else
@@ -3145,26 +3221,19 @@ fi
# value for MKDIR_P within a source directory, because that will
# break other packages using the cache if that directory is
# removed, or if the value is a relative name.
- test -d ./--version && rmdir ./--version
MKDIR_P="$ac_install_sh -d"
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
$as_echo "$MKDIR_P" >&6; }
-mkdir_p="$MKDIR_P"
-case $mkdir_p in
- [\\/$]* | ?:[\\/]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-
for ac_prog in gawk mawk nawk awk
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then :
+if ${ac_cv_prog_AWK+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$AWK"; then
@@ -3176,7 +3245,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3204,7 +3273,7 @@ done
$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
set x ${MAKE-make}
ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
$as_echo_n "(cached) " >&6
else
cat >conftest.make <<\_ACEOF
@@ -3212,7 +3281,7 @@ SHELL = /bin/sh
all:
@echo '@@@%%%=$(MAKE)=@@@%%%'
_ACEOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
case `${MAKE-make} -f conftest.make 2>/dev/null` in
*@@@%%%=?*=@@@%%%*)
eval ac_cv_prog_make_${ac_make}_set=yes;;
@@ -3240,13 +3309,52 @@ else
fi
rmdir .tst 2>/dev/null
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I."
am__isrc=' -I$(srcdir)'
# test to see if srcdir already configured
if test -f $srcdir/config.status; then
- as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
fi
fi
@@ -3290,25 +3398,78 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
# Always define AMTAR for backward compatibility. Yes, it's still used
# in the wild :-( We should find a proper way to deprecate it ...
AMTAR='$${TAR-tar}'
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
# Default to --enable-multilib
# Check whether --enable-multilib was given.
if test "${enable_multilib+set}" = set; then :
enableval=$enable_multilib; case "$enableval" in
yes) multilib=yes ;;
no) multilib=no ;;
- *) as_fn_error "bad value $enableval for multilib option" "$LINENO" 5 ;;
+ *) as_fn_error $? "bad value $enableval for multilib option" "$LINENO" 5 ;;
esac
else
multilib=yes
@@ -3388,7 +3549,7 @@ if test -n "$ac_tool_prefix"; then
set dummy ${ac_tool_prefix}gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
@@ -3400,7 +3561,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3428,7 +3589,7 @@ if test -z "$ac_cv_prog_CC"; then
set dummy gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_CC"; then
@@ -3440,7 +3601,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3481,7 +3642,7 @@ if test -z "$CC"; then
set dummy ${ac_tool_prefix}cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
@@ -3493,7 +3654,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3521,7 +3682,7 @@ if test -z "$CC"; then
set dummy cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
@@ -3534,7 +3695,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
@@ -3580,7 +3741,7 @@ if test -z "$CC"; then
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
@@ -3592,7 +3753,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3624,7 +3785,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_CC"; then
@@ -3636,7 +3797,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3678,8 +3839,8 @@ fi
test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "no acceptable C compiler found in \$PATH
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -3700,8 +3861,8 @@ $as_echo "$ac_try_echo"; } >&5
... rest of stderr output deleted ...
10q' conftest.err >conftest.er1
cat conftest.er1 >&5
- rm -f conftest.er1 conftest.err
fi
+ rm -f conftest.er1 conftest.err
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
done
@@ -3718,12 +3879,12 @@ main ()
}
_ACEOF
ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
# The possible output files:
@@ -3785,62 +3946,28 @@ test "$ac_cv_exeext" = no && ac_cv_exeext=
else
ac_file=''
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
if test -z "$ac_file"; then :
- $as_echo "$as_me: failed program was:" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "C compiler cannot create executables
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
ac_exeext=$ac_cv_exeext
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." "$LINENO" 5; }
- fi
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
$as_echo_n "checking for suffix of executables... " >&6; }
if { { ac_try="$ac_link"
@@ -3870,19 +3997,78 @@ done
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
fi
-rm -f conftest$ac_cv_exeext
+rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
$as_echo "$ac_cv_exeext" >&6; }
rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
$as_echo_n "checking for suffix of object files... " >&6; }
-if test "${ac_cv_objext+set}" = set; then :
+if ${ac_cv_objext+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3922,8 +4108,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
@@ -3933,7 +4119,7 @@ OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+if ${ac_cv_c_compiler_gnu+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3970,7 +4156,7 @@ ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then :
+if ${ac_cv_prog_cc_g+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_save_c_werror_flag=$ac_c_werror_flag
@@ -4048,7 +4234,7 @@ else
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then :
+if ${ac_cv_prog_cc_c89+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_prog_cc_c89=no
@@ -4057,8 +4243,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -4142,6 +4327,65 @@ ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
DEPDIR="${am__leading_dot}deps"
ac_config_commands="$ac_config_commands depfiles"
@@ -4161,7 +4405,7 @@ am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
+# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
@@ -4210,15 +4454,15 @@ depcc="$CC" am_compiler_list=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
$as_echo_n "checking dependency style of $depcc... " >&6; }
-if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
@@ -4253,16 +4497,16 @@ else
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
@@ -4271,8 +4515,8 @@ else
test "$am__universal" = false || continue
;;
nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
if test "x$enable_dependency_tracking" = xyes; then
continue
else
@@ -4280,7 +4524,7 @@ else
fi
;;
msvc7 | msvc7msys | msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
+ # This compiler won't grok '-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
@@ -4354,7 +4598,7 @@ if test -n "$ac_tool_prefix"; then
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then :
+if ${ac_cv_prog_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$AR"; then
@@ -4366,7 +4610,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="${ac_tool_prefix}ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4394,7 +4638,7 @@ if test -z "$ac_cv_prog_AR"; then
set dummy ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_AR"; then
@@ -4406,7 +4650,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4446,7 +4690,7 @@ if test -n "$ac_tool_prefix"; then
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then :
+if ${ac_cv_prog_RANLIB+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$RANLIB"; then
@@ -4458,7 +4702,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4486,7 +4730,7 @@ if test -z "$ac_cv_prog_RANLIB"; then
set dummy ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_RANLIB"; then
@@ -4498,7 +4742,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4537,7 +4781,7 @@ fi
set dummy perl; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_path_PERL+set}" = set; then :
+if ${ac_cv_path_PERL+:} false; then :
$as_echo_n "(cached) " >&6
else
case $PERL in
@@ -4551,7 +4795,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4578,7 +4822,7 @@ fi
$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
set x ${MAKE-make}
ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
$as_echo_n "(cached) " >&6
else
cat >conftest.make <<\_ACEOF
@@ -4586,7 +4830,7 @@ SHELL = /bin/sh
all:
@echo '@@@%%%=$(MAKE)=@@@%%%'
_ACEOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
case `${MAKE-make} -f conftest.make 2>/dev/null` in
*@@@%%%=?*=@@@%%%*)
eval ac_cv_prog_make_${ac_make}_set=yes;;
@@ -4614,7 +4858,7 @@ fi
set dummy makeinfo; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_MAKEINFO+set}" = set; then :
+if ${ac_cv_prog_MAKEINFO+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$MAKEINFO"; then
@@ -4626,7 +4870,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_MAKEINFO="makeinfo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4651,7 +4895,7 @@ fi
# Found it, now check the version.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for modern makeinfo" >&5
$as_echo_n "checking for modern makeinfo... " >&6; }
-if test "${gcc_cv_prog_makeinfo_modern+set}" = set; then :
+if ${gcc_cv_prog_makeinfo_modern+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_prog_version=`eval $MAKEINFO --version 2>&1 |
@@ -4780,7 +5024,7 @@ esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
$as_echo_n "checking for a sed that does not truncate output... " >&6; }
-if test "${ac_cv_path_SED+set}" = set; then :
+if ${ac_cv_path_SED+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
@@ -4800,7 +5044,7 @@ do
for ac_prog in sed gsed; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+ as_fn_executable_p "$ac_path_SED" || continue
# Check for GNU ac_path_SED and select it if it is found.
# Check for GNU $ac_path_SED
case `"$ac_path_SED" --version 2>&1` in
@@ -4835,7 +5079,7 @@ esac
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_SED"; then
- as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
fi
else
ac_cv_path_SED=$SED
@@ -4862,7 +5106,7 @@ Xsed="$SED -e 1s/^X//"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
+if ${ac_cv_path_GREP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -z "$GREP"; then
@@ -4876,7 +5120,7 @@ do
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+ as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
@@ -4911,7 +5155,7 @@ esac
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_GREP"; then
- as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_GREP=$GREP
@@ -4925,7 +5169,7 @@ $as_echo "$ac_cv_path_GREP" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
$as_echo_n "checking for egrep... " >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then :
+if ${ac_cv_path_EGREP+:} false; then :
$as_echo_n "(cached) " >&6
else
if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
@@ -4942,7 +5186,7 @@ do
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+ as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
@@ -4977,7 +5221,7 @@ esac
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_EGREP"; then
- as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_EGREP=$EGREP
@@ -4992,7 +5236,7 @@ $as_echo "$ac_cv_path_EGREP" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
$as_echo_n "checking for fgrep... " >&6; }
-if test "${ac_cv_path_FGREP+set}" = set; then :
+if ${ac_cv_path_FGREP+:} false; then :
$as_echo_n "(cached) " >&6
else
if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
@@ -5009,7 +5253,7 @@ do
for ac_prog in fgrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+ as_fn_executable_p "$ac_path_FGREP" || continue
# Check for GNU ac_path_FGREP and select it if it is found.
# Check for GNU $ac_path_FGREP
case `"$ac_path_FGREP" --version 2>&1` in
@@ -5044,7 +5288,7 @@ esac
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_FGREP"; then
- as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_FGREP=$FGREP
@@ -5123,7 +5367,7 @@ else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
$as_echo_n "checking for non-GNU ld... " >&6; }
fi
-if test "${lt_cv_path_LD+set}" = set; then :
+if ${lt_cv_path_LD+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -z "$LD"; then
@@ -5160,10 +5404,10 @@ else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
-test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+if ${lt_cv_prog_gnu_ld+:} false; then :
$as_echo_n "(cached) " >&6
else
# I'd rather use --version here, but apparently some GNU lds only accept -v.
@@ -5190,7 +5434,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
-if test "${lt_cv_path_NM+set}" = set; then :
+if ${lt_cv_path_NM+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$NM"; then
@@ -5253,7 +5497,7 @@ else
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+if ${ac_cv_prog_DUMPBIN+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$DUMPBIN"; then
@@ -5265,7 +5509,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5297,7 +5541,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_DUMPBIN"; then
@@ -5309,7 +5553,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5369,7 +5613,7 @@ test -z "$NM" && NM=nm
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
$as_echo_n "checking the name lister ($NM) interface... " >&6; }
-if test "${lt_cv_nm_interface+set}" = set; then :
+if ${lt_cv_nm_interface+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_nm_interface="BSD nm"
@@ -5404,7 +5648,7 @@ fi
# find the maximum length of command line arguments
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
$as_echo_n "checking the maximum length of command line arguments... " >&6; }
-if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
+if ${lt_cv_sys_max_cmd_len+:} false; then :
$as_echo_n "(cached) " >&6
else
i=0
@@ -5601,7 +5845,7 @@ esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
$as_echo_n "checking for $LD option to reload object files... " >&6; }
-if test "${lt_cv_ld_reload_flag+set}" = set; then :
+if ${lt_cv_ld_reload_flag+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_ld_reload_flag='-r'
@@ -5637,7 +5881,7 @@ if test -n "$ac_tool_prefix"; then
set dummy ${ac_tool_prefix}objdump; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+if ${ac_cv_prog_OBJDUMP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$OBJDUMP"; then
@@ -5649,7 +5893,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5677,7 +5921,7 @@ if test -z "$ac_cv_prog_OBJDUMP"; then
set dummy objdump; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_OBJDUMP"; then
@@ -5689,7 +5933,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OBJDUMP="objdump"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5736,7 +5980,7 @@ test -z "$OBJDUMP" && OBJDUMP=objdump
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
$as_echo_n "checking how to recognize dependent libraries... " >&6; }
-if test "${lt_cv_deplibs_check_method+set}" = set; then :
+if ${lt_cv_deplibs_check_method+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_file_magic_cmd='$MAGIC_CMD'
@@ -5856,7 +6100,7 @@ irix5* | irix6* | nonstopux*)
;;
# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi)
lt_cv_deplibs_check_method=pass_all
;;
@@ -5957,7 +6201,7 @@ if test -n "$ac_tool_prefix"; then
set dummy ${ac_tool_prefix}ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then :
+if ${ac_cv_prog_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$AR"; then
@@ -5969,7 +6213,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="${ac_tool_prefix}ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5997,7 +6241,7 @@ if test -z "$ac_cv_prog_AR"; then
set dummy ar; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_AR"; then
@@ -6009,7 +6253,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="ar"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6062,7 +6306,7 @@ if test -n "$ac_tool_prefix"; then
set dummy ${ac_tool_prefix}strip; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
+if ${ac_cv_prog_STRIP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$STRIP"; then
@@ -6074,7 +6318,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_STRIP="${ac_tool_prefix}strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6102,7 +6346,7 @@ if test -z "$ac_cv_prog_STRIP"; then
set dummy strip; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_STRIP"; then
@@ -6114,7 +6358,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_STRIP="strip"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6161,7 +6405,7 @@ if test -n "$ac_tool_prefix"; then
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then :
+if ${ac_cv_prog_RANLIB+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$RANLIB"; then
@@ -6173,7 +6417,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6201,7 +6445,7 @@ if test -z "$ac_cv_prog_RANLIB"; then
set dummy ranlib; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_RANLIB"; then
@@ -6213,7 +6457,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6330,7 +6574,7 @@ compiler=$CC
# Check for command to grab the raw symbol name followed by C symbol from nm.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
-if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
$as_echo_n "(cached) " >&6
else
@@ -6715,7 +6959,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
CFLAGS="$CFLAGS -belf"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
-if test "${lt_cv_cc_needs_belf+set}" = set; then :
+if ${lt_cv_cc_needs_belf+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_ext=c
@@ -6791,7 +7035,7 @@ need_locks="$enable_libtool_lock"
set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$DSYMUTIL"; then
@@ -6803,7 +7047,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6831,7 +7075,7 @@ if test -z "$ac_cv_prog_DSYMUTIL"; then
set dummy dsymutil; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_DSYMUTIL"; then
@@ -6843,7 +7087,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6883,7 +7127,7 @@ fi
set dummy ${ac_tool_prefix}nmedit; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_NMEDIT+set}" = set; then :
+if ${ac_cv_prog_NMEDIT+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$NMEDIT"; then
@@ -6895,7 +7139,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6923,7 +7167,7 @@ if test -z "$ac_cv_prog_NMEDIT"; then
set dummy nmedit; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_NMEDIT"; then
@@ -6935,7 +7179,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_NMEDIT="nmedit"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -6975,7 +7219,7 @@ fi
set dummy ${ac_tool_prefix}lipo; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_LIPO+set}" = set; then :
+if ${ac_cv_prog_LIPO+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$LIPO"; then
@@ -6987,7 +7231,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7015,7 +7259,7 @@ if test -z "$ac_cv_prog_LIPO"; then
set dummy lipo; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_LIPO"; then
@@ -7027,7 +7271,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_LIPO="lipo"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7067,7 +7311,7 @@ fi
set dummy ${ac_tool_prefix}otool; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OTOOL+set}" = set; then :
+if ${ac_cv_prog_OTOOL+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$OTOOL"; then
@@ -7079,7 +7323,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7107,7 +7351,7 @@ if test -z "$ac_cv_prog_OTOOL"; then
set dummy otool; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_OTOOL"; then
@@ -7119,7 +7363,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL="otool"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7159,7 +7403,7 @@ fi
set dummy ${ac_tool_prefix}otool64; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OTOOL64+set}" = set; then :
+if ${ac_cv_prog_OTOOL64+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$OTOOL64"; then
@@ -7171,7 +7415,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7199,7 +7443,7 @@ if test -z "$ac_cv_prog_OTOOL64"; then
set dummy otool64; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_OTOOL64"; then
@@ -7211,7 +7455,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_OTOOL64="otool64"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -7274,7 +7518,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
$as_echo_n "checking for -single_module linker flag... " >&6; }
-if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
+if ${lt_cv_apple_cc_single_mod+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_apple_cc_single_mod=no
@@ -7303,7 +7547,7 @@ fi
$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
-if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_ld_exported_symbols_list=no
@@ -7335,7 +7579,7 @@ fi
$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
$as_echo_n "checking for -force_load linker flag... " >&6; }
-if test "${lt_cv_ld_force_load+set}" = set; then :
+if ${lt_cv_ld_force_load+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_ld_force_load=no
@@ -7410,7 +7654,7 @@ if test -n "$CPP" && test -d "$CPP"; then
CPP=
fi
if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then :
+ if ${ac_cv_prog_CPP+:} false; then :
$as_echo_n "(cached) " >&6
else
# Double quotes because CPP needs to be expanded
@@ -7440,7 +7684,7 @@ else
# Broken: fails on valid input.
continue
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
# OK, works on sane cases. Now check whether nonexistent headers
# can be detected and how.
@@ -7456,11 +7700,11 @@ else
ac_preproc_ok=:
break
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
break
fi
@@ -7499,7 +7743,7 @@ else
# Broken: fails on valid input.
continue
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
# OK, works on sane cases. Now check whether nonexistent headers
# can be detected and how.
@@ -7515,18 +7759,18 @@ else
ac_preproc_ok=:
break
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
fi
ac_ext=c
@@ -7538,7 +7782,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
+if ${ac_cv_header_stdc+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -7655,8 +7899,7 @@ do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
@@ -7670,7 +7913,7 @@ for ac_header in dlfcn.h
do :
ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
"
-if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_DLFCN_H 1
_ACEOF
@@ -7857,7 +8100,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
$as_echo_n "checking for objdir... " >&6; }
-if test "${lt_cv_objdir+set}" = set; then :
+if ${lt_cv_objdir+:} false; then :
$as_echo_n "(cached) " >&6
else
rm -f .libs 2>/dev/null
@@ -7935,7 +8178,7 @@ file_magic*)
if test "$file_magic_cmd" = '$MAGIC_CMD'; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
$as_echo_n "(cached) " >&6
else
case $MAGIC_CMD in
@@ -8001,7 +8244,7 @@ if test -z "$lt_cv_path_MAGIC_CMD"; then
if test -n "$ac_tool_prefix"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
$as_echo_n "checking for file... " >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
$as_echo_n "(cached) " >&6
else
case $MAGIC_CMD in
@@ -8143,7 +8386,7 @@ if test "$GCC" = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
-if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler_rtti_exceptions=no
@@ -8496,7 +8739,7 @@ $as_echo "$lt_prog_compiler_pic" >&6; }
if test -n "$lt_prog_compiler_pic"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
-if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler_pic_works=no
@@ -8555,7 +8798,7 @@ fi
wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
-if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
+if ${lt_cv_prog_compiler_static_works+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler_static_works=no
@@ -8598,7 +8841,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+if ${lt_cv_prog_compiler_c_o+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler_c_o=no
@@ -8653,7 +8896,7 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+if ${lt_cv_prog_compiler_c_o+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler_c_o=no
@@ -8937,7 +9180,7 @@ _LT_EOF
archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
- gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi)
tmp_diet=no
if test "$host_os" = linux-dietlibc; then
case $cc_basename in
@@ -9469,7 +9712,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
$as_echo_n "checking if $CC understands -b... " >&6; }
-if test "${lt_cv_prog_compiler__b+set}" = set; then :
+if ${lt_cv_prog_compiler__b+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler__b=no
@@ -9841,7 +10084,7 @@ x|xyes)
# to ld, don't add -lc before -lgcc.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
-if test "${lt_cv_archive_cmds_need_lc+set}" = set; then :
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
$as_echo_n "(cached) " >&6
else
$RM conftest*
@@ -10468,7 +10711,12 @@ linux*oldld* | linux*aout* | linux*coff*)
;;
# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
+
+# uclinux* changes (here and below) have been submitted to the libtool
+# project, but have not yet been accepted: they are GCC-local changes
+# for the time being. (See
+# https://lists.gnu.org/archive/html/libtool-patches/2018-05/msg00000.html)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi)
version_type=linux
need_lib_prefix=no
need_version=no
@@ -10479,7 +10727,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu)
shlibpath_overrides_runpath=no
# Some binutils ld are patched to set DT_RUNPATH
- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then :
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_shlibpath_overrides_runpath=no
@@ -10899,7 +11147,7 @@ else
# if libdl is installed we need to link against it
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+if ${ac_cv_lib_dl_dlopen+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -10933,7 +11181,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
else
@@ -10947,12 +11195,12 @@ fi
*)
ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
-if test "x$ac_cv_func_shl_load" = x""yes; then :
+if test "x$ac_cv_func_shl_load" = xyes; then :
lt_cv_dlopen="shl_load"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
$as_echo_n "checking for shl_load in -ldld... " >&6; }
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+if ${ac_cv_lib_dld_shl_load+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -10986,16 +11234,16 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
-if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
else
ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
-if test "x$ac_cv_func_dlopen" = x""yes; then :
+if test "x$ac_cv_func_dlopen" = xyes; then :
lt_cv_dlopen="dlopen"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+if ${ac_cv_lib_dl_dlopen+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -11029,12 +11277,12 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
$as_echo_n "checking for dlopen in -lsvld... " >&6; }
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+if ${ac_cv_lib_svld_dlopen+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -11068,12 +11316,12 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
-if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
$as_echo_n "checking for dld_link in -ldld... " >&6; }
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+if ${ac_cv_lib_dld_dld_link+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -11107,7 +11355,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
-if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
fi
@@ -11148,7 +11396,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
$as_echo_n "checking whether a program can dlopen itself... " >&6; }
-if test "${lt_cv_dlopen_self+set}" = set; then :
+if ${lt_cv_dlopen_self+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then :
@@ -11157,7 +11405,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11160 "configure"
+#line 11408 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11254,7 +11502,7 @@ $as_echo "$lt_cv_dlopen_self" >&6; }
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
-if test "${lt_cv_dlopen_self_static+set}" = set; then :
+if ${lt_cv_dlopen_self_static+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then :
@@ -11263,7 +11511,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11266 "configure"
+#line 11514 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11578,7 +11826,7 @@ if test -n "$ac_tool_prefix"; then
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_FC+set}" = set; then :
+if ${ac_cv_prog_FC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$FC"; then
@@ -11590,7 +11838,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_FC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -11622,7 +11870,7 @@ do
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_FC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_FC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_FC"; then
@@ -11634,7 +11882,7 @@ do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_FC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -11691,8 +11939,8 @@ $as_echo "$ac_try_echo"; } >&5
... rest of stderr output deleted ...
10q' conftest.err >conftest.er1
cat conftest.er1 >&5
- rm -f conftest.er1 conftest.err
fi
+ rm -f conftest.er1 conftest.err
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
done
@@ -11704,7 +11952,7 @@ ac_save_ext=$ac_ext
ac_ext=F
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Fortran compiler" >&5
$as_echo_n "checking whether we are using the GNU Fortran compiler... " >&6; }
-if test "${ac_cv_fc_compiler_gnu+set}" = set; then :
+if ${ac_cv_fc_compiler_gnu+:} false; then :
$as_echo_n "(cached) " >&6
else
cat > conftest.$ac_ext <<_ACEOF
@@ -11732,7 +11980,7 @@ ac_save_FCFLAGS=$FCFLAGS
FCFLAGS=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $FC accepts -g" >&5
$as_echo_n "checking whether $FC accepts -g... " >&6; }
-if test "${ac_cv_prog_fc_g+set}" = set; then :
+if ${ac_cv_prog_fc_g+:} false; then :
$as_echo_n "(cached) " >&6
else
FCFLAGS=-g
@@ -11767,6 +12015,11 @@ else
fi
fi
+if test $ac_compiler_gnu = yes; then
+ GFC=yes
+else
+ GFC=
+fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -12368,7 +12621,7 @@ $as_echo "$lt_prog_compiler_pic_FC" >&6; }
if test -n "$lt_prog_compiler_pic_FC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_FC works" >&5
$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_FC works... " >&6; }
-if test "${lt_cv_prog_compiler_pic_works_FC+set}" = set; then :
+if ${lt_cv_prog_compiler_pic_works_FC+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler_pic_works_FC=no
@@ -12424,7 +12677,7 @@ fi
wl=$lt_prog_compiler_wl_FC eval lt_tmp_static_flag=\"$lt_prog_compiler_static_FC\"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
-if test "${lt_cv_prog_compiler_static_works_FC+set}" = set; then :
+if ${lt_cv_prog_compiler_static_works_FC+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler_static_works_FC=no
@@ -12464,7 +12717,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o_FC+set}" = set; then :
+if ${lt_cv_prog_compiler_c_o_FC+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler_c_o_FC=no
@@ -12516,7 +12769,7 @@ $as_echo "$lt_cv_prog_compiler_c_o_FC" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o_FC+set}" = set; then :
+if ${lt_cv_prog_compiler_c_o_FC+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_prog_compiler_c_o_FC=no
@@ -12797,7 +13050,7 @@ _LT_EOF
archive_expsym_cmds_FC='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
- gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi)
tmp_diet=no
if test "$host_os" = linux-dietlibc; then
case $cc_basename in
@@ -13640,7 +13893,7 @@ x|xyes)
# to ld, don't add -lc before -lgcc.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
-if test "${lt_cv_archive_cmds_need_lc_FC+set}" = set; then :
+if ${lt_cv_archive_cmds_need_lc_FC+:} false; then :
$as_echo_n "(cached) " >&6
else
$RM conftest*
@@ -14108,7 +14361,12 @@ linux*oldld* | linux*aout* | linux*coff*)
;;
# This must be Linux ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
+
+# uclinux* changes (here and below) have been submitted to the libtool
+# project, but have not yet been accepted: they are GCC-local changes
+# for the time being. (See
+# https://lists.gnu.org/archive/html/libtool-patches/2018-05/msg00000.html)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | uclinuxfdpiceabi)
version_type=linux
need_lib_prefix=no
need_version=no
@@ -14119,7 +14377,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu)
shlibpath_overrides_runpath=no
# Some binutils ld are patched to set DT_RUNPATH
- if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then :
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
$as_echo_n "(cached) " >&6
else
lt_cv_shlibpath_overrides_runpath=no
@@ -14473,7 +14731,7 @@ libtool_VERSION=1:0:0
# Check header files.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
+if ${ac_cv_header_stdc+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -14585,7 +14843,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
-if test "${ac_cv_header_time+set}" = set; then :
+if ${ac_cv_header_time+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -14620,7 +14878,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether string.h and strings.h may both be included" >&5
$as_echo_n "checking whether string.h and strings.h may both be included... " >&6; }
-if test "${gcc_cv_header_string+set}" = set; then :
+if ${gcc_cv_header_string+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -14654,8 +14912,7 @@ for ac_header in pthread.h unistd.h semaphore.h sys/loadavg.h sys/sysctl.h sys/t
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
@@ -14665,419 +14922,12 @@ fi
done
-
-
-inttype_headers=`echo inttypes.h sys/inttypes.h | sed -e 's/,/ /g'`
-
-acx_cv_header_stdint=stddef.h
-acx_cv_header_stdint_kind="(already complete)"
-for i in stdint.h $inttype_headers; do
- unset ac_cv_type_uintptr_t
- unset ac_cv_type_uintmax_t
- unset ac_cv_type_int_least32_t
- unset ac_cv_type_int_fast32_t
- unset ac_cv_type_uint64_t
- $as_echo_n "looking for a compliant stdint.h in $i, " >&6
- ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "#include <sys/types.h>
-#include <$i>
-"
-if test "x$ac_cv_type_uintmax_t" = x""yes; then :
- acx_cv_header_stdint=$i
-else
- continue
-fi
-
- ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "#include <sys/types.h>
-#include <$i>
-"
-if test "x$ac_cv_type_uintptr_t" = x""yes; then :
-
-else
- acx_cv_header_stdint_kind="(mostly complete)"
-fi
-
- ac_fn_c_check_type "$LINENO" "int_least32_t" "ac_cv_type_int_least32_t" "#include <sys/types.h>
-#include <$i>
-"
-if test "x$ac_cv_type_int_least32_t" = x""yes; then :
-
-else
- acx_cv_header_stdint_kind="(mostly complete)"
-fi
-
- ac_fn_c_check_type "$LINENO" "int_fast32_t" "ac_cv_type_int_fast32_t" "#include <sys/types.h>
-#include <$i>
-"
-if test "x$ac_cv_type_int_fast32_t" = x""yes; then :
-
-else
- acx_cv_header_stdint_kind="(mostly complete)"
-fi
-
- ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "#include <sys/types.h>
-#include <$i>
-"
-if test "x$ac_cv_type_uint64_t" = x""yes; then :
-
-else
- acx_cv_header_stdint_kind="(lacks uint64_t)"
-fi
-
- break
-done
-if test "$acx_cv_header_stdint" = stddef.h; then
- acx_cv_header_stdint_kind="(lacks uintmax_t)"
- for i in stdint.h $inttype_headers; do
- unset ac_cv_type_uintptr_t
- unset ac_cv_type_uint32_t
- unset ac_cv_type_uint64_t
- $as_echo_n "looking for an incomplete stdint.h in $i, " >&6
- ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "#include <sys/types.h>
-#include <$i>
-"
-if test "x$ac_cv_type_uint32_t" = x""yes; then :
- acx_cv_header_stdint=$i
-else
- continue
-fi
-
- ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "#include <sys/types.h>
-#include <$i>
-"
-if test "x$ac_cv_type_uint64_t" = x""yes; then :
-
-fi
-
- ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "#include <sys/types.h>
-#include <$i>
-"
-if test "x$ac_cv_type_uintptr_t" = x""yes; then :
-
-fi
-
- break
- done
-fi
-if test "$acx_cv_header_stdint" = stddef.h; then
- acx_cv_header_stdint_kind="(u_intXX_t style)"
- for i in sys/types.h $inttype_headers; do
- unset ac_cv_type_u_int32_t
- unset ac_cv_type_u_int64_t
- $as_echo_n "looking for u_intXX_t types in $i, " >&6
- ac_fn_c_check_type "$LINENO" "u_int32_t" "ac_cv_type_u_int32_t" "#include <sys/types.h>
-#include <$i>
-"
-if test "x$ac_cv_type_u_int32_t" = x""yes; then :
- acx_cv_header_stdint=$i
-else
- continue
-fi
-
- ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "#include <sys/types.h>
-#include <$i>
-"
-if test "x$ac_cv_type_u_int64_t" = x""yes; then :
-
-fi
-
- break
- done
-fi
-if test "$acx_cv_header_stdint" = stddef.h; then
- acx_cv_header_stdint_kind="(using manual detection)"
-fi
-
-test -z "$ac_cv_type_uintptr_t" && ac_cv_type_uintptr_t=no
-test -z "$ac_cv_type_uint64_t" && ac_cv_type_uint64_t=no
-test -z "$ac_cv_type_u_int64_t" && ac_cv_type_u_int64_t=no
-test -z "$ac_cv_type_int_least32_t" && ac_cv_type_int_least32_t=no
-test -z "$ac_cv_type_int_fast32_t" && ac_cv_type_int_fast32_t=no
-
-# ----------------- Summarize what we found so far
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what to include in gstdint.h" >&5
-$as_echo_n "checking what to include in gstdint.h... " >&6; }
-
-case `$as_basename -- gstdint.h ||
-$as_expr X/gstdint.h : '.*/\([^/][^/]*\)/*$' \| \
- Xgstdint.h : 'X\(//\)$' \| \
- Xgstdint.h : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/gstdint.h |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'` in
- stdint.h) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: are you sure you want it there?" >&5
-$as_echo "$as_me: WARNING: are you sure you want it there?" >&2;} ;;
- inttypes.h) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: are you sure you want it there?" >&5
-$as_echo "$as_me: WARNING: are you sure you want it there?" >&2;} ;;
- *) ;;
-esac
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_header_stdint $acx_cv_header_stdint_kind" >&5
-$as_echo "$acx_cv_header_stdint $acx_cv_header_stdint_kind" >&6; }
-
-# ----------------- done included file, check C basic types --------
-
-# Lacking an uintptr_t? Test size of void *
-case "$acx_cv_header_stdint:$ac_cv_type_uintptr_t" in
- stddef.h:* | *:no) # The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5
-$as_echo_n "checking size of void *... " >&6; }
-if test "${ac_cv_sizeof_void_p+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_void_p" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (void *)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof_void_p=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5
-$as_echo "$ac_cv_sizeof_void_p" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
-_ACEOF
-
- ;;
-esac
-
-# Lacking an uint64_t? Test size of long
-case "$acx_cv_header_stdint:$ac_cv_type_uint64_t:$ac_cv_type_u_int64_t" in
- stddef.h:*:* | *:no:no) # The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
-$as_echo_n "checking size of long... " >&6; }
-if test "${ac_cv_sizeof_long+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_long" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (long)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof_long=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
-$as_echo "$ac_cv_sizeof_long" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_LONG $ac_cv_sizeof_long
-_ACEOF
-
- ;;
-esac
-
-if test $acx_cv_header_stdint = stddef.h; then
- # Lacking a good header? Test size of everything and deduce all types.
- # The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
-$as_echo_n "checking size of int... " >&6; }
-if test "${ac_cv_sizeof_int+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_int" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (int)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof_int=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
-$as_echo "$ac_cv_sizeof_int" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_INT $ac_cv_sizeof_int
-_ACEOF
-
-
- # The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
-$as_echo_n "checking size of short... " >&6; }
-if test "${ac_cv_sizeof_short+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_short" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (short)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof_short=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
-$as_echo "$ac_cv_sizeof_short" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_SHORT $ac_cv_sizeof_short
-_ACEOF
-
-
- # The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5
-$as_echo_n "checking size of char... " >&6; }
-if test "${ac_cv_sizeof_char+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then :
-
-else
- if test "$ac_cv_type_char" = yes; then
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (char)
-See \`config.log' for more details." "$LINENO" 5; }; }
- else
- ac_cv_sizeof_char=0
- fi
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5
-$as_echo "$ac_cv_sizeof_char" >&6; }
-
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_CHAR $ac_cv_sizeof_char
-_ACEOF
-
-
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type equivalent to int8_t" >&5
-$as_echo_n "checking for type equivalent to int8_t... " >&6; }
- case "$ac_cv_sizeof_char" in
- 1) acx_cv_type_int8_t=char ;;
- *) as_fn_error "no 8-bit type, please report a bug" "$LINENO" 5
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_type_int8_t" >&5
-$as_echo "$acx_cv_type_int8_t" >&6; }
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type equivalent to int16_t" >&5
-$as_echo_n "checking for type equivalent to int16_t... " >&6; }
- case "$ac_cv_sizeof_int:$ac_cv_sizeof_short" in
- 2:*) acx_cv_type_int16_t=int ;;
- *:2) acx_cv_type_int16_t=short ;;
- *) as_fn_error "no 16-bit type, please report a bug" "$LINENO" 5
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_type_int16_t" >&5
-$as_echo "$acx_cv_type_int16_t" >&6; }
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type equivalent to int32_t" >&5
-$as_echo_n "checking for type equivalent to int32_t... " >&6; }
- case "$ac_cv_sizeof_int:$ac_cv_sizeof_long" in
- 4:*) acx_cv_type_int32_t=int ;;
- *:4) acx_cv_type_int32_t=long ;;
- *) as_fn_error "no 32-bit type, please report a bug" "$LINENO" 5
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_type_int32_t" >&5
-$as_echo "$acx_cv_type_int32_t" >&6; }
-fi
-
-# These tests are here to make the output prettier
-
-if test "$ac_cv_type_uint64_t" != yes && test "$ac_cv_type_u_int64_t" != yes; then
- case "$ac_cv_sizeof_long" in
- 8) acx_cv_type_int64_t=long ;;
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type equivalent to int64_t" >&5
-$as_echo_n "checking for type equivalent to int64_t... " >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${acx_cv_type_int64_t-'using preprocessor symbols'}" >&5
-$as_echo "${acx_cv_type_int64_t-'using preprocessor symbols'}" >&6; }
-fi
-
-# Now we can use the above types
-
-if test "$ac_cv_type_uintptr_t" != yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for type equivalent to intptr_t" >&5
-$as_echo_n "checking for type equivalent to intptr_t... " >&6; }
- case $ac_cv_sizeof_void_p in
- 2) acx_cv_type_intptr_t=int16_t ;;
- 4) acx_cv_type_intptr_t=int32_t ;;
- 8) acx_cv_type_intptr_t=int64_t ;;
- *) as_fn_error "no equivalent for intptr_t, please report a bug" "$LINENO" 5
- esac
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_type_intptr_t" >&5
-$as_echo "$acx_cv_type_intptr_t" >&6; }
-fi
-
-# ----------------- done all checks, emit header -------------
-ac_config_commands="$ac_config_commands gstdint.h"
-
-
-
-
XPCFLAGS=""
case "$host" in
*-*-rtems*)
# RTEMS supports Pthreads, but the library is not available at GCC build time.
;;
- nvptx*-*-*)
+ nvptx*-*-* | amdgcn*-*-*)
# NVPTX does not support Pthreads, has its own code replacement.
libgomp_use_pthreads=no
# NVPTX is an accelerator-only target
@@ -15118,7 +14968,7 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"; then :
else
- as_fn_error "Pthreads are required to build libgomp" "$LINENO" 5
+ as_fn_error $? "Pthreads are required to build libgomp" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
@@ -15141,7 +14991,7 @@ fi
# Plugins for offload execution, configure.ac fragment. -*- mode: autoconf -*-
#
-# Copyright (C) 2014-2018 Free Software Foundation, Inc.
+# Copyright (C) 2014-2019 Free Software Foundation, Inc.
#
# Contributed by Mentor Embedded.
#
@@ -15167,12 +15017,10 @@ fi
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# <http://www.gnu.org/licenses/>.
-offload_targets=
-
plugin_support=yes
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlsym in -ldl" >&5
$as_echo_n "checking for dlsym in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlsym+set}" = set; then :
+if ${ac_cv_lib_dl_dlsym+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -15206,7 +15054,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlsym" >&5
$as_echo "$ac_cv_lib_dl_dlsym" >&6; }
-if test "x$ac_cv_lib_dl_dlsym" = x""yes; then :
+if test "x$ac_cv_lib_dl_dlsym" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBDL 1
_ACEOF
@@ -15222,7 +15070,7 @@ if test x"$plugin_support" = xyes; then
$as_echo "#define PLUGIN_SUPPORT 1" >>confdefs.h
elif test "x${enable_offload_targets-no}" != xno; then
- as_fn_error "Can't support offloading without support for plugins" "$LINENO" 5
+ as_fn_error $? "Can't support offloading without support for plugins" "$LINENO" 5
fi
@@ -15232,8 +15080,7 @@ do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
@@ -15252,8 +15099,7 @@ done
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
@@ -15302,7 +15148,11 @@ if test "${with_cuda_driver_lib+set}" = set; then :
fi
case "x$with_cuda_driver" in
- x | xno) ;;
+ x) ;;
+ xno)
+ CUDA_DRIVER_INCLUDE=no
+ CUDA_DRIVER_LIB=no
+ ;;
*) CUDA_DRIVER_INCLUDE=$with_cuda_driver/include
CUDA_DRIVER_LIB=$with_cuda_driver/lib
;;
@@ -15313,10 +15163,12 @@ fi
if test "x$with_cuda_driver_lib" != x; then
CUDA_DRIVER_LIB=$with_cuda_driver_lib
fi
-if test "x$CUDA_DRIVER_INCLUDE" != x; then
+if test "x$CUDA_DRIVER_INCLUDE" != x \
+ && test "x$CUDA_DRIVER_INCLUDE" != xno; then
CUDA_DRIVER_CPPFLAGS=-I$CUDA_DRIVER_INCLUDE
fi
-if test "x$CUDA_DRIVER_LIB" != x; then
+if test "x$CUDA_DRIVER_LIB" != x \
+ && test "x$CUDA_DRIVER_LIB" != xno; then
CUDA_DRIVER_LDFLAGS=-L$CUDA_DRIVER_LIB
fi
@@ -15383,7 +15235,22 @@ PLUGIN_HSA_LIBS=
-# Get offload targets and path to install tree of offloading compiler.
+PLUGIN_GCN=0
+PLUGIN_GCN_CPPFLAGS=
+PLUGIN_GCN_LDFLAGS=
+PLUGIN_GCN_LIBS=
+
+
+
+
+
+# Parse '--enable-offload-targets', figure out the corresponding libgomp
+# plugins, and configure to find the corresponding offload compilers.
+# 'offload_plugins' and 'offload_targets' will be populated in the same order.
+offload_plugins=
+offload_targets=
+
+
offload_additional_options=
offload_additional_lib_paths=
@@ -15392,25 +15259,27 @@ if test x"$enable_offload_targets" != x; then
for tgt in `echo $enable_offload_targets | sed -e 's#,# #g'`; do
tgt_dir=`echo $tgt | grep '=' | sed 's/.*=//'`
tgt=`echo $tgt | sed 's/=.*//'`
- tgt_name=
+ tgt_plugin=
case $tgt in
*-intelmic-* | *-intelmicemul-*)
- tgt_name=intelmic
+ tgt_plugin=intelmic
;;
nvptx*)
- tgt_name=nvptx
+ tgt_plugin=nvptx
PLUGIN_NVPTX=$tgt
- PLUGIN_NVPTX_CPPFLAGS=$CUDA_DRIVER_CPPFLAGS
- PLUGIN_NVPTX_LDFLAGS=$CUDA_DRIVER_LDFLAGS
- PLUGIN_NVPTX_LIBS='-lcuda'
-
- PLUGIN_NVPTX_save_CPPFLAGS=$CPPFLAGS
- CPPFLAGS="$PLUGIN_NVPTX_CPPFLAGS $CPPFLAGS"
- PLUGIN_NVPTX_save_LDFLAGS=$LDFLAGS
- LDFLAGS="$PLUGIN_NVPTX_LDFLAGS $LDFLAGS"
- PLUGIN_NVPTX_save_LIBS=$LIBS
- LIBS="$PLUGIN_NVPTX_LIBS $LIBS"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ if test "x$CUDA_DRIVER_LIB" != xno \
+ && test "x$CUDA_DRIVER_LIB" != xno; then
+ PLUGIN_NVPTX_CPPFLAGS=$CUDA_DRIVER_CPPFLAGS
+ PLUGIN_NVPTX_LDFLAGS=$CUDA_DRIVER_LDFLAGS
+ PLUGIN_NVPTX_LIBS='-lcuda'
+
+ PLUGIN_NVPTX_save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$PLUGIN_NVPTX_CPPFLAGS $CPPFLAGS"
+ PLUGIN_NVPTX_save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$PLUGIN_NVPTX_LDFLAGS $LDFLAGS"
+ PLUGIN_NVPTX_save_LIBS=$LIBS
+ LIBS="$PLUGIN_NVPTX_LIBS $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include "cuda.h"
int
@@ -15426,20 +15295,23 @@ if ac_fn_c_try_link "$LINENO"; then :
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- CPPFLAGS=$PLUGIN_NVPTX_save_CPPFLAGS
- LDFLAGS=$PLUGIN_NVPTX_save_LDFLAGS
- LIBS=$PLUGIN_NVPTX_save_LIBS
+ CPPFLAGS=$PLUGIN_NVPTX_save_CPPFLAGS
+ LDFLAGS=$PLUGIN_NVPTX_save_LDFLAGS
+ LIBS=$PLUGIN_NVPTX_save_LIBS
+ fi
case $PLUGIN_NVPTX in
nvptx*)
- if test "x$CUDA_DRIVER_INCLUDE" = x \
- && test "x$CUDA_DRIVER_LIB" = x; then
+ if (test "x$CUDA_DRIVER_INCLUDE" = x \
+ || test "x$CUDA_DRIVER_INCLUDE" = xno) \
+ && (test "x$CUDA_DRIVER_LIB" = x \
+ || test "x$CUDA_DRIVER_LIB" = xno); then
PLUGIN_NVPTX=1
PLUGIN_NVPTX_CPPFLAGS='-I$(srcdir)/plugin/cuda'
PLUGIN_NVPTX_LIBS='-ldl'
PLUGIN_NVPTX_DYNAMIC=1
else
PLUGIN_NVPTX=0
- as_fn_error "CUDA driver package required for nvptx support" "$LINENO" 5
+ as_fn_error $? "CUDA driver package required for nvptx support" "$LINENO" 5
fi
;;
esac
@@ -15452,7 +15324,7 @@ rm -f core conftest.err conftest.$ac_objext \
PLUGIN_HSA=0
;;
*)
- tgt_name=hsa
+ tgt_plugin=hsa
PLUGIN_HSA=$tgt
PLUGIN_HSA_CPPFLAGS=$HSA_RUNTIME_CPPFLAGS
PLUGIN_HSA_LDFLAGS="$HSA_RUNTIME_LDFLAGS"
@@ -15470,9 +15342,9 @@ rm -f core conftest.err conftest.$ac_objext \
LDFLAGS=$PLUGIN_HSA_save_LDFLAGS
LIBS=$PLUGIN_HSA_save_LIBS
case $PLUGIN_HSA in
- hsa*)
+ hsa*)
HSA_PLUGIN=0
- as_fn_error "HSA run-time package required for HSA support" "$LINENO" 5
+ as_fn_error $? "HSA run-time package required for HSA support" "$LINENO" 5
;;
esac
;;
@@ -15483,20 +15355,46 @@ rm -f core conftest.err conftest.$ac_objext \
;;
esac
;;
+
+ amdgcn*)
+ case "${target}" in
+ x86_64-*-*)
+ case " ${CC} ${CFLAGS} " in
+ *" -m32 "*)
+ PLUGIN_GCN=0
+ ;;
+ *)
+ tgt_plugin=gcn
+ PLUGIN_GCN=$tgt
+ PLUGIN_GCN_CPPFLAGS=$HSA_RUNTIME_CPPFLAGS
+ PLUGIN_GCN_LDFLAGS="$HSA_RUNTIME_LDFLAGS"
+ PLUGIN_GCN_LIBS="-ldl"
+ PLUGIN_GCN=1
+ ;;
+ esac
+ ;;
+ *-*-*)
+ PLUGIN_GCN=0
+ ;;
+ esac
+ ;;
*)
- as_fn_error "unknown offload target specified" "$LINENO" 5
+ as_fn_error $? "unknown offload target specified" "$LINENO" 5
;;
esac
- if test x"$tgt_name" = x; then
- # Don't configure libgomp for this offloading target if we don't build
- # the corresponding plugin.
+ if test x"$tgt_plugin" = x; then
+ # Not configuring libgomp for this offload target if we're not building
+ # the corresponding offload plugin.
continue
- elif test x"$offload_targets" = x; then
- offload_targets=$tgt_name
+ elif test x"$offload_plugins" = x; then
+ offload_plugins=$tgt_plugin
+ offload_targets=$tgt
else
- offload_targets=$offload_targets,$tgt_name
+ offload_plugins=$offload_plugins,$tgt_plugin
+ offload_targets=$offload_targets,$tgt
fi
- if test "$tgt_name" = hsa; then
+ # Configure additional search paths.
+ if test "$tgt_plugin" = hsa; then
# Offloading compilation is all handled by the target compiler.
:
elif test x"$tgt_dir" != x; then
@@ -15510,7 +15408,7 @@ rm -f core conftest.err conftest.$ac_objext \
fi
cat >>confdefs.h <<_ACEOF
-#define OFFLOAD_TARGETS "$offload_targets"
+#define OFFLOAD_PLUGINS "$offload_plugins"
_ACEOF
if test $PLUGIN_NVPTX = 1; then
@@ -15544,6 +15442,19 @@ cat >>confdefs.h <<_ACEOF
#define PLUGIN_HSA $PLUGIN_HSA
_ACEOF
+ if test $PLUGIN_GCN = 1; then
+ PLUGIN_GCN_TRUE=
+ PLUGIN_GCN_FALSE='#'
+else
+ PLUGIN_GCN_TRUE='#'
+ PLUGIN_GCN_FALSE=
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define PLUGIN_GCN $PLUGIN_GCN
+_ACEOF
+
if test "$HSA_RUNTIME_LIB" != ""; then
HSA_RUNTIME_LIB="$HSA_RUNTIME_LIB/"
@@ -15561,8 +15472,19 @@ for ac_func in getloadavg clock_gettime strtoull
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in aligned_alloc posix_memalign memalign _aligned_malloc
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
@@ -15586,7 +15508,7 @@ case "$host" in
*-*-rtems*)
ac_fn_c_check_type "$LINENO" "struct _Mutex_Control" "ac_cv_type_struct__Mutex_Control" "#include <sys/lock.h>
"
-if test "x$ac_cv_type_struct__Mutex_Control" = x""yes; then :
+if test "x$ac_cv_type_struct__Mutex_Control" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STRUCT__MUTEX_CONTROL 1
@@ -15603,7 +15525,7 @@ if test "${enable_linux_futex+set}" = set; then :
enableval=$enable_linux_futex;
case "$enableval" in
yes|no|default) ;;
- *) as_fn_error "Unknown argument to enable/disable linux-futex" "$LINENO" 5 ;;
+ *) as_fn_error $? "Unknown argument to enable/disable linux-futex" "$LINENO" 5 ;;
esac
else
@@ -15612,7 +15534,7 @@ fi
case "$target" in
- *-linux*)
+ *-linux* | *-uclinux*)
case "$enable_linux_futex" in
default)
# If headers don't have gettid/futex syscalls definition, then
@@ -15625,6 +15547,7 @@ case "$target" in
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/syscall.h>
+ #include <unistd.h>
int lk;
int
main ()
@@ -15677,6 +15600,7 @@ rm -f core conftest.err conftest.$ac_objext \
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/syscall.h>
+ #include <unistd.h>
int lk;
int
main ()
@@ -15689,7 +15613,7 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"; then :
else
- as_fn_error "SYS_gettid and SYS_futex required for --enable-linux-futex" "$LINENO" 5
+ as_fn_error $? "SYS_gettid and SYS_futex required for --enable-linux-futex" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
@@ -15741,7 +15665,7 @@ rm -f core conftest.err conftest.$ac_objext \
if test $ac_cv_func_clock_gettime = no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
-if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then :
+if ${ac_cv_lib_rt_clock_gettime+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -15775,7 +15699,7 @@ LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
-if test "x$ac_cv_lib_rt_clock_gettime" = x""yes; then :
+if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
LIBS="-lrt $LIBS"
$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
@@ -15784,6 +15708,72 @@ fi
fi
+# Check for uname.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+ #include <stdlib.h>
+ #include <sys/utsname.h>
+int
+main ()
+{
+struct utsname buf;
+ volatile size_t len = 0;
+ if (!uname (buf))
+ len = strlen (buf.nodename);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_UNAME 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# Check for gethostname.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <unistd.h>
+int
+main ()
+{
+
+ char buf[256];
+ if (gethostname (buf, sizeof (buf) - 1) == 0)
+ buf[255] = '\0';
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_GETHOSTNAME 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+# Check for getpid.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <unistd.h>
+int
+main ()
+{
+int pid = getpid ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+$as_echo "#define HAVE_GETPID 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
# See if we support thread-local storage.
@@ -15792,7 +15782,7 @@ if test "${enable_tls+set}" = set; then :
enableval=$enable_tls;
case "$enableval" in
yes|no) ;;
- *) as_fn_error "Argument to enable/disable tls must be yes or no" "$LINENO" 5 ;;
+ *) as_fn_error $? "Argument to enable/disable tls must be yes or no" "$LINENO" 5 ;;
esac
else
@@ -15802,7 +15792,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target supports thread-local storage" >&5
$as_echo_n "checking whether the target supports thread-local storage... " >&6; }
-if test "${gcc_cv_have_tls+set}" = set; then :
+if ${gcc_cv_have_tls+:} false; then :
$as_echo_n "(cached) " >&6
else
@@ -15814,7 +15804,7 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"; then :
chktls_save_LDFLAGS="$LDFLAGS"
case $host in
- *-*-linux*)
+ *-*-linux* | -*-uclinuxfdpic*)
LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
;;
esac
@@ -15866,8 +15856,8 @@ if ac_fn_c_try_link "$LINENO"; then :
if test "$cross_compiling" = yes; then :
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot run test program while cross compiling
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -15920,8 +15910,8 @@ rm -f core conftest.err conftest.$ac_objext \
if test "$cross_compiling" = yes; then :
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot run test program while cross compiling
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -15983,7 +15973,7 @@ $as_echo "#define HAVE_TLS 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the thread-local storage support is from emutls" >&5
$as_echo_n "checking whether the thread-local storage support is from emutls... " >&6; }
-if test "${gcc_cv_use_emutls+set}" = set; then :
+if ${gcc_cv_use_emutls+:} false; then :
$as_echo_n "(cached) " >&6
else
@@ -16014,7 +16004,7 @@ $as_echo "#define USE_EMUTLS 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target supports hidden visibility" >&5
$as_echo_n "checking whether the target supports hidden visibility... " >&6; }
-if test "${libgomp_cv_have_attribute_visibility+set}" = set; then :
+if ${libgomp_cv_have_attribute_visibility+:} false; then :
$as_echo_n "(cached) " >&6
else
@@ -16049,7 +16039,7 @@ $as_echo "#define HAVE_ATTRIBUTE_VISIBILITY 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target supports dllexport" >&5
$as_echo_n "checking whether the target supports dllexport... " >&6; }
-if test "${libgomp_cv_have_attribute_dllexport+set}" = set; then :
+if ${libgomp_cv_have_attribute_dllexport+:} false; then :
$as_echo_n "(cached) " >&6
else
@@ -16084,7 +16074,7 @@ $as_echo "#define HAVE_ATTRIBUTE_DLLEXPORT 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target supports symbol aliases" >&5
$as_echo_n "checking whether the target supports symbol aliases... " >&6; }
-if test "${libgomp_cv_have_attribute_alias+set}" = set; then :
+if ${libgomp_cv_have_attribute_alias+:} false; then :
$as_echo_n "(cached) " >&6
else
@@ -16164,7 +16154,7 @@ else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
$as_echo_n "checking for non-GNU ld... " >&6; }
fi
-if test "${lt_cv_path_LD+set}" = set; then :
+if ${lt_cv_path_LD+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -z "$LD"; then
@@ -16201,10 +16191,10 @@ else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
-test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+if ${lt_cv_prog_gnu_ld+:} false; then :
$as_echo_n "(cached) " >&6
else
# I'd rather use --version here, but apparently some GNU lds only accept -v.
@@ -16258,7 +16248,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
fi
ldver=`$LD --version 2>/dev/null |
- sed -e 's/GNU gold /GNU ld /;s/GNU ld version /GNU ld /;s/GNU ld ([^)]*) /GNU ld /;s/GNU ld \([0-9.][0-9.]*\).*/\1/; q'`
+ sed -e 's/[. ][0-9]\{8\}$//;s/.* \([^ ]\{1,\}\)$/\1/; q'`
libgomp_gnu_ld_version=`echo $ldver | \
$AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
@@ -16333,7 +16323,7 @@ if test "${enable_symvers+set}" = set; then :
enableval=$enable_symvers;
case "$enableval" in
yes|no|gnu*|sun) ;;
- *) as_fn_error "Unknown argument to enable/disable symvers" "$LINENO" 5 ;;
+ *) as_fn_error $? "Unknown argument to enable/disable symvers" "$LINENO" 5 ;;
esac
else
@@ -16497,7 +16487,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target supports .symver directive" >&5
$as_echo_n "checking whether the target supports .symver directive... " >&6; }
-if test "${libgomp_cv_have_as_symver_directive+set}" = set; then :
+if ${libgomp_cv_have_as_symver_directive+:} false; then :
$as_echo_n "(cached) " >&6
else
@@ -16576,6 +16566,101 @@ $as_echo "#define LIBGOMP_GNU_SYMBOL_VERSIONING 1" >>confdefs.h
fi
+# Determine cpu count to limit testsuite parallelism.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking the number of available CPUs" >&5
+$as_echo_n "checking the number of available CPUs... " >&6; }
+ CPU_COUNT="0"
+
+ # Try generic methods
+
+ # 'getconf' is POSIX utility, but '_NPROCESSORS_ONLN' and
+ # 'NPROCESSORS_ONLN' are platform-specific
+ command -v getconf >/dev/null 2>&1 && \
+ CPU_COUNT=`getconf _NPROCESSORS_ONLN 2>/dev/null || getconf NPROCESSORS_ONLN 2>/dev/null` || CPU_COUNT="0"
+ if test "$CPU_COUNT" -gt "0" 2>/dev/null || ! command -v nproc >/dev/null 2>&1; then :
+ : # empty
+else
+ # 'nproc' is part of GNU Coreutils and is widely available
+ CPU_COUNT=`OMP_NUM_THREADS='' nproc 2>/dev/null` || CPU_COUNT=`nproc 2>/dev/null` || CPU_COUNT="0"
+
+fi
+ if test "$CPU_COUNT" -gt "0" 2>/dev/null; then :
+ : # empty
+else
+ # Try platform-specific preferred methods
+ case $host_os in #(
+ *linux*) :
+ CPU_COUNT=`lscpu -p 2>/dev/null | $EGREP -e '^[0-9]+,' -c` || CPU_COUNT="0" ;; #(
+ *darwin*) :
+ CPU_COUNT=`sysctl -n hw.logicalcpu 2>/dev/null` || CPU_COUNT="0" ;; #(
+ freebsd*) :
+ command -v sysctl >/dev/null 2>&1 && CPU_COUNT=`sysctl -n kern.smp.cpus 2>/dev/null` || CPU_COUNT="0" ;; #(
+ netbsd*) :
+ command -v sysctl >/dev/null 2>&1 && CPU_COUNT=`sysctl -n hw.ncpuonline 2>/dev/null` || CPU_COUNT="0" ;; #(
+ solaris*) :
+ command -v psrinfo >/dev/null 2>&1 && CPU_COUNT=`psrinfo 2>/dev/null | $EGREP -e '^[0-9].*on-line' -c 2>/dev/null` || CPU_COUNT="0" ;; #(
+ mingw*) :
+ CPU_COUNT=`ls -qpU1 /proc/registry/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/CentralProcessor/ 2>/dev/null | $EGREP -e '^[0-9]+/' -c` || CPU_COUNT="0" ;; #(
+ msys*) :
+ CPU_COUNT=`ls -qpU1 /proc/registry/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/CentralProcessor/ 2>/dev/null | $EGREP -e '^[0-9]+/' -c` || CPU_COUNT="0" ;; #(
+ cygwin*) :
+ CPU_COUNT=`ls -qpU1 /proc/registry/HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/System/CentralProcessor/ 2>/dev/null | $EGREP -e '^[0-9]+/' -c` || CPU_COUNT="0" ;; #(
+ *) :
+ ;;
+esac
+fi
+ if test "$CPU_COUNT" -gt "0" 2>/dev/null || ! command -v sysctl >/dev/null 2>&1; then :
+ : # empty
+else
+ # Try less preferred generic method
+ # 'hw.ncpu' exist on many platforms, but not on GNU/Linux
+ CPU_COUNT=`sysctl -n hw.ncpu 2>/dev/null` || CPU_COUNT="0"
+
+fi
+ if test "$CPU_COUNT" -gt "0" 2>/dev/null; then :
+ : # empty
+else
+ # Try platform-specific fallback methods
+ # They can be less accurate and slower then preferred methods
+ case $host_os in #(
+ *linux*) :
+ CPU_COUNT=`$EGREP -e '^processor' -c /proc/cpuinfo 2>/dev/null` || CPU_COUNT="0" ;; #(
+ *darwin*) :
+ CPU_COUNT=`system_profiler SPHardwareDataType 2>/dev/null | $EGREP -i -e 'number of cores:'|cut -d : -f 2 -s|tr -d ' '` || CPU_COUNT="0" ;; #(
+ freebsd*) :
+ CPU_COUNT=`dmesg 2>/dev/null| $EGREP -e '^cpu[0-9]+: '|sort -u|$EGREP -e '^' -c` || CPU_COUNT="0" ;; #(
+ netbsd*) :
+ CPU_COUNT=`command -v cpuctl >/dev/null 2>&1 && cpuctl list 2>/dev/null| $EGREP -e '^[0-9]+ .* online ' -c` || \
+ CPU_COUNT=`dmesg 2>/dev/null| $EGREP -e '^cpu[0-9]+ at'|sort -u|$EGREP -e '^' -c` || CPU_COUNT="0" ;; #(
+ solaris*) :
+ command -v kstat >/dev/null 2>&1 && CPU_COUNT=`kstat -m cpu_info -s state -p 2>/dev/null | $EGREP -c -e 'on-line'` || \
+ CPU_COUNT=`kstat -m cpu_info 2>/dev/null | $EGREP -c -e 'module: cpu_info'` || CPU_COUNT="0" ;; #(
+ mingw*) :
+ if CPU_COUNT=`reg query 'HKLM\\Hardware\\Description\\System\\CentralProcessor' 2>/dev/null | $EGREP -e '\\\\[0-9]+$' -c`; then :
+ : # empty
+else
+ test "$NUMBER_OF_PROCESSORS" -gt "0" 2>/dev/null && CPU_COUNT="$NUMBER_OF_PROCESSORS"
+fi ;; #(
+ msys*) :
+ test "$NUMBER_OF_PROCESSORS" -gt "0" 2>/dev/null && CPU_COUNT="$NUMBER_OF_PROCESSORS" ;; #(
+ cygwin*) :
+ test "$NUMBER_OF_PROCESSORS" -gt "0" 2>/dev/null && CPU_COUNT="$NUMBER_OF_PROCESSORS" ;; #(
+ *) :
+ ;;
+esac
+fi
+ if test "x$CPU_COUNT" != "x0" && test "$CPU_COUNT" -gt 0 2>/dev/null; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPU_COUNT" >&5
+$as_echo "$CPU_COUNT" >&6; }
+
+else
+ CPU_COUNT="1"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unable to detect (assuming 1)" >&5
+$as_echo "unable to detect (assuming 1)" >&6; }
+
+fi
+
+
# Get target configury.
. ${srcdir}/configure.tgt
CFLAGS="$save_CFLAGS $XCFLAGS"
@@ -16585,7 +16670,7 @@ CFLAGS="$save_CFLAGS $XCFLAGS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target supports __sync_*_compare_and_swap" >&5
$as_echo_n "checking whether the target supports __sync_*_compare_and_swap... " >&6; }
-if test "${libgomp_cv_have_sync_builtins+set}" = set; then :
+if ${libgomp_cv_have_sync_builtins+:} false; then :
$as_echo_n "(cached) " >&6
else
@@ -16624,7 +16709,7 @@ if test "${enable_cet+set}" = set; then :
enableval=$enable_cet;
case "$enableval" in
yes|no|auto) ;;
- *) as_fn_error "Unknown argument to enable/disable cet" "$LINENO" 5 ;;
+ *) as_fn_error $? "Unknown argument to enable/disable cet" "$LINENO" 5 ;;
esac
else
@@ -16681,7 +16766,7 @@ _ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
else
- as_fn_error "assembler with CET support is required for --enable-cet" "$LINENO" 5
+ as_fn_error $? "assembler with CET support is required for --enable-cet" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
;;
@@ -16773,10 +16858,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
:end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
if test -w "$cache_file"; then
- test "x$cache_file" != "x/dev/null" &&
+ if test "x$cache_file" != "x/dev/null"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
- cat confcache >$cache_file
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
@@ -16825,7 +16921,7 @@ done
if ac_fn_c_compute_int "$LINENO" "sizeof (omp_lock_t)" "OMP_LOCK_SIZE" ""; then :
else
- as_fn_error "unsupported system, cannot find sizeof (omp_lock_t)" "$LINENO" 5
+ as_fn_error $? "unsupported system, cannot find sizeof (omp_lock_t)" "$LINENO" 5
fi
@@ -16847,7 +16943,7 @@ fi
if ac_fn_c_compute_int "$LINENO" "sizeof (omp_lock_25_t)" "OMP_LOCK_25_SIZE" ""; then :
else
- as_fn_error "unsupported system, cannot find sizeof (omp_lock_25_t)" "$LINENO" 5
+ as_fn_error $? "unsupported system, cannot find sizeof (omp_lock_25_t)" "$LINENO" 5
fi
@@ -16988,10 +17084,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
:end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
if test -w "$cache_file"; then
- test "x$cache_file" != "x/dev/null" &&
+ if test "x$cache_file" != "x/dev/null"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
- cat confcache >$cache_file
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
@@ -17007,6 +17114,7 @@ DEFS=-DHAVE_CONFIG_H
ac_libobjs=
ac_ltlibobjs=
+U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
# 1. Remove the extension, and $U if already installed.
ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
@@ -17022,9 +17130,17 @@ LTLIBOBJS=$ac_ltlibobjs
if test -z "${GENINSRC_TRUE}" && test -z "${GENINSRC_FALSE}"; then
- as_fn_error "conditional \"GENINSRC\" was never defined.
+ as_fn_error $? "conditional \"GENINSRC\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
if test -n "$EXEEXT"; then
am__EXEEXT_TRUE=
am__EXEEXT_FALSE='#'
@@ -17034,47 +17150,51 @@ else
fi
if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
- as_fn_error "conditional \"AMDEP\" was never defined.
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
- as_fn_error "conditional \"am__fastdepCC\" was never defined.
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${BUILD_INFO_TRUE}" && test -z "${BUILD_INFO_FALSE}"; then
- as_fn_error "conditional \"BUILD_INFO\" was never defined.
+ as_fn_error $? "conditional \"BUILD_INFO\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
- as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${PLUGIN_NVPTX_TRUE}" && test -z "${PLUGIN_NVPTX_FALSE}"; then
- as_fn_error "conditional \"PLUGIN_NVPTX\" was never defined.
+ as_fn_error $? "conditional \"PLUGIN_NVPTX\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${PLUGIN_HSA_TRUE}" && test -z "${PLUGIN_HSA_FALSE}"; then
- as_fn_error "conditional \"PLUGIN_HSA\" was never defined.
+ as_fn_error $? "conditional \"PLUGIN_HSA\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${PLUGIN_GCN_TRUE}" && test -z "${PLUGIN_GCN_FALSE}"; then
+ as_fn_error $? "conditional \"PLUGIN_GCN\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE}" && test -z "${LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE}"; then
- as_fn_error "conditional \"LIBGOMP_BUILD_VERSIONED_SHLIB\" was never defined.
+ as_fn_error $? "conditional \"LIBGOMP_BUILD_VERSIONED_SHLIB\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE}" && test -z "${LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_FALSE}"; then
- as_fn_error "conditional \"LIBGOMP_BUILD_VERSIONED_SHLIB_GNU\" was never defined.
+ as_fn_error $? "conditional \"LIBGOMP_BUILD_VERSIONED_SHLIB_GNU\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE}" && test -z "${LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_FALSE}"; then
- as_fn_error "conditional \"LIBGOMP_BUILD_VERSIONED_SHLIB_SUN\" was never defined.
+ as_fn_error $? "conditional \"LIBGOMP_BUILD_VERSIONED_SHLIB_SUN\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${USE_FORTRAN_TRUE}" && test -z "${USE_FORTRAN_FALSE}"; then
- as_fn_error "conditional \"USE_FORTRAN\" was never defined.
+ as_fn_error $? "conditional \"USE_FORTRAN\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
-: ${CONFIG_STATUS=./config.status}
+: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
@@ -17175,6 +17295,7 @@ fi
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -17220,19 +17341,19 @@ export LANGUAGE
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
- as_status=$?; test $as_status -eq 0 && as_status=1
- if test "$3"; then
- as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
- $as_echo "$as_me: error: $1" >&2
+ $as_echo "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
@@ -17370,16 +17491,16 @@ if (echo >conf$$.file) 2>/dev/null; then
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -17428,7 +17549,7 @@ $as_echo X"$as_dir" |
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
} # as_fn_mkdir_p
@@ -17439,28 +17560,16 @@ else
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -17482,7 +17591,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# values after options handling.
ac_log="
This file was extended by GNU Offloading and Multi Processing Runtime Library $as_me 1.0, which was
-generated by GNU Autoconf 2.64. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -17522,6 +17631,7 @@ Usage: $0 [OPTION]... [TAG]...
-h, --help print this help, then exit
-V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
-q, --quiet, --silent
do not print progress messages
-d, --debug don't remove temporary files
@@ -17546,12 +17656,13 @@ General help using GNU software: <http://www.gnu.org/gethelp/>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
GNU Offloading and Multi Processing Runtime Library config.status 1.0
-configured by $0, generated by GNU Autoconf 2.64,
- with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -17569,11 +17680,16 @@ ac_need_defaults=:
while test $# != 0
do
case $1 in
- --*=*)
+ --*=?*)
ac_option=`expr "X$1" : 'X\([^=]*\)='`
ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
ac_shift=:
;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
*)
ac_option=$1
ac_optarg=$2
@@ -17587,12 +17703,15 @@ do
ac_cs_recheck=: ;;
--version | --versio | --versi | --vers | --ver | --ve | --v | -V )
$as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
--debug | --debu | --deb | --de | --d | -d )
debug=: ;;
--file | --fil | --fi | --f )
$ac_shift
case $ac_optarg in
*\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
esac
as_fn_append CONFIG_FILES " '$ac_optarg'"
ac_need_defaults=false;;
@@ -17605,7 +17724,7 @@ do
ac_need_defaults=false;;
--he | --h)
# Conflict between --help and --header
- as_fn_error "ambiguous option: \`$1'
+ as_fn_error $? "ambiguous option: \`$1'
Try \`$0 --help' for more information.";;
--help | --hel | -h )
$as_echo "$ac_cs_usage"; exit ;;
@@ -17614,7 +17733,7 @@ Try \`$0 --help' for more information.";;
ac_cs_silent=: ;;
# This is an error.
- -*) as_fn_error "unrecognized option: \`$1'
+ -*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;
*) as_fn_append ac_config_targets " $1"
@@ -17634,7 +17753,7 @@ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
@@ -17671,6 +17790,7 @@ CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
CC="$CC"
CXX="$CXX"
GFORTRAN="$GFORTRAN"
+GDC="$GDC"
AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
@@ -18033,24 +18153,6 @@ fi
-GCC="$GCC"
-CC="$CC"
-acx_cv_header_stdint="$acx_cv_header_stdint"
-acx_cv_type_int8_t="$acx_cv_type_int8_t"
-acx_cv_type_int16_t="$acx_cv_type_int16_t"
-acx_cv_type_int32_t="$acx_cv_type_int32_t"
-acx_cv_type_int64_t="$acx_cv_type_int64_t"
-acx_cv_type_intptr_t="$acx_cv_type_intptr_t"
-ac_cv_type_uintmax_t="$ac_cv_type_uintmax_t"
-ac_cv_type_uintptr_t="$ac_cv_type_uintptr_t"
-ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
-ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
-ac_cv_type_u_int32_t="$ac_cv_type_u_int32_t"
-ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
-ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
-ac_cv_sizeof_void_p="$ac_cv_sizeof_void_p"
-
-
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
@@ -18063,7 +18165,6 @@ do
"default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
"depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
- "gstdint.h") CONFIG_COMMANDS="$CONFIG_COMMANDS gstdint.h" ;;
"omp.h") CONFIG_FILES="$CONFIG_FILES omp.h" ;;
"omp_lib.h") CONFIG_FILES="$CONFIG_FILES omp_lib.h" ;;
"omp_lib.f90") CONFIG_FILES="$CONFIG_FILES omp_lib.f90" ;;
@@ -18073,7 +18174,7 @@ do
"libgomp.spec") CONFIG_FILES="$CONFIG_FILES libgomp.spec" ;;
"testsuite/libgomp-test-support.pt.exp") CONFIG_FILES="$CONFIG_FILES testsuite/libgomp-test-support.pt.exp:testsuite/libgomp-test-support.exp.in" ;;
- *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
@@ -18096,9 +18197,10 @@ fi
# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
- tmp=
+ tmp= ac_tmp=
trap 'exit_status=$?
- { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
trap 'as_fn_exit 1' 1 2 13 15
}
@@ -18106,12 +18208,13 @@ $debug ||
{
tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
+ test -d "$tmp"
} ||
{
tmp=./conf$$-$RANDOM
(umask 077 && mkdir "$tmp")
-} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
@@ -18128,12 +18231,12 @@ if test "x$ac_cr" = x; then
fi
ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
- ac_cs_awk_cr='\r'
+ ac_cs_awk_cr='\\r'
else
ac_cs_awk_cr=$ac_cr
fi
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
_ACEOF
@@ -18142,18 +18245,18 @@ _ACEOF
echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
echo "_ACEOF"
} >conf$$subs.sh ||
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
. ./conf$$subs.sh ||
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
if test $ac_delim_n = $ac_delim_num; then
break
elif $ac_last_try; then
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
else
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
fi
@@ -18161,7 +18264,7 @@ done
rm -f conf$$subs.sh
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
_ACEOF
sed -n '
h
@@ -18175,7 +18278,7 @@ s/'"$ac_delim"'$//
t delim
:nl
h
-s/\(.\{148\}\).*/\1/
+s/\(.\{148\}\)..*/\1/
t more1
s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
p
@@ -18189,7 +18292,7 @@ s/.\{148\}//
t nl
:delim
h
-s/\(.\{148\}\).*/\1/
+s/\(.\{148\}\)..*/\1/
t more2
s/["\\]/\\&/g; s/^/"/; s/$/"/
p
@@ -18209,7 +18312,7 @@ t delim
rm -f conf$$subs.awk
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
for (key in S) S_is_set[key] = 1
FS = ""
@@ -18241,21 +18344,29 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
else
cat
-fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
- || as_fn_error "could not setup config files machinery" "$LINENO" 5
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
_ACEOF
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[ ]*\):*/\1/
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
s/^[^=]*=[ ]*$//
}'
fi
@@ -18267,7 +18378,7 @@ fi # test -n "$CONFIG_FILES"
# No need to generate them if there are no CONFIG_HEADERS.
# This happens for instance with `./config.status Makefile'.
if test -n "$CONFIG_HEADERS"; then
-cat >"$tmp/defines.awk" <<\_ACAWK ||
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
BEGIN {
_ACEOF
@@ -18279,11 +18390,11 @@ _ACEOF
# handling of long lines.
ac_delim='%!_!# '
for ac_last_try in false false :; do
- ac_t=`sed -n "/$ac_delim/p" confdefs.h`
- if test -z "$ac_t"; then
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
break
elif $ac_last_try; then
- as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
else
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
fi
@@ -18368,7 +18479,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACAWK
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
- as_fn_error "could not setup config headers machinery" "$LINENO" 5
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
fi # test -n "$CONFIG_HEADERS"
@@ -18381,7 +18492,7 @@ do
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
- :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
@@ -18400,7 +18511,7 @@ do
for ac_f
do
case $ac_f in
- -) ac_f="$tmp/stdin";;
+ -) ac_f="$ac_tmp/stdin";;
*) # Look for the file first in the build tree, then in the source tree
# (if the path is not absolute). The absolute path cannot be DOS-style,
# because $ac_f cannot contain `:'.
@@ -18409,7 +18520,7 @@ do
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
- as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
@@ -18435,8 +18546,8 @@ $as_echo "$as_me: creating $ac_file" >&6;}
esac
case $ac_tag in
- *:-:* | *:-) cat >"$tmp/stdin" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
@@ -18572,23 +18683,24 @@ s&@INSTALL@&$ac_INSTALL&;t t
s&@MKDIR_P@&$ac_MKDIR_P&;t t
$ac_datarootdir_hack
"
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
- { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
- { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined." >&5
+which seems to be undefined. Please make sure it is defined" >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined." >&2;}
+which seems to be undefined. Please make sure it is defined" >&2;}
- rm -f "$tmp/stdin"
+ rm -f "$ac_tmp/stdin"
case $ac_file in
- -) cat "$tmp/out" && rm -f "$tmp/out";;
- *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
esac \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
;;
:H)
#
@@ -18597,21 +18709,21 @@ which seems to be undefined. Please make sure it is defined." >&2;}
if test x"$ac_file" != x-; then
{
$as_echo "/* $configure_input */" \
- && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
- } >"$tmp/config.h" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
- if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
$as_echo "$as_me: $ac_file is unchanged" >&6;}
else
rm -f "$ac_file"
- mv "$tmp/config.h" "$ac_file" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
fi
else
$as_echo "/* $configure_input */" \
- && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
- || as_fn_error "could not create -" "$LINENO" 5
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
fi
# Compute "$ac_file"'s index in $config_headers.
_am_arg="$ac_file"
@@ -18665,7 +18777,7 @@ case " $CONFIG_FILES " in
;;
esac ;;
"depfiles":C) test x"$AMDEP_TRUE" != x"" || {
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
@@ -18678,7 +18790,7 @@ esac ;;
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
+ # We used to match only the files named 'Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
@@ -18712,21 +18824,19 @@ $as_echo X"$mf" |
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
+ # from the Makefile without running 'make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
+ test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`$as_dirname -- "$file" ||
@@ -19569,378 +19679,6 @@ compiler_lib_search_path=$lt_compiler_lib_search_path_FC
_LT_EOF
;;
- "gstdint.h":C)
-if test "$GCC" = yes; then
- echo "/* generated for " `$CC --version | sed 1q` "*/" > tmp-stdint.h
-else
- echo "/* generated for $CC */" > tmp-stdint.h
-fi
-
-sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- #ifndef GCC_GENERATED_STDINT_H
- #define GCC_GENERATED_STDINT_H 1
-
- #include <sys/types.h>
-EOF
-
-if test "$acx_cv_header_stdint" != stdint.h; then
- echo "#include <stddef.h>" >> tmp-stdint.h
-fi
-if test "$acx_cv_header_stdint" != stddef.h; then
- echo "#include <$acx_cv_header_stdint>" >> tmp-stdint.h
-fi
-
-sed 's/^ *//' >> tmp-stdint.h <<EOF
- /* glibc uses these symbols as guards to prevent redefinitions. */
- #ifdef __int8_t_defined
- #define _INT8_T
- #define _INT16_T
- #define _INT32_T
- #endif
- #ifdef __uint32_t_defined
- #define _UINT32_T
- #endif
-
-EOF
-
-# ----------------- done header, emit basic int types -------------
-if test "$acx_cv_header_stdint" = stddef.h; then
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- #ifndef _UINT8_T
- #define _UINT8_T
- #ifndef __uint8_t_defined
- #define __uint8_t_defined
- #ifndef uint8_t
- typedef unsigned $acx_cv_type_int8_t uint8_t;
- #endif
- #endif
- #endif
-
- #ifndef _UINT16_T
- #define _UINT16_T
- #ifndef __uint16_t_defined
- #define __uint16_t_defined
- #ifndef uint16_t
- typedef unsigned $acx_cv_type_int16_t uint16_t;
- #endif
- #endif
- #endif
-
- #ifndef _UINT32_T
- #define _UINT32_T
- #ifndef __uint32_t_defined
- #define __uint32_t_defined
- #ifndef uint32_t
- typedef unsigned $acx_cv_type_int32_t uint32_t;
- #endif
- #endif
- #endif
-
- #ifndef _INT8_T
- #define _INT8_T
- #ifndef __int8_t_defined
- #define __int8_t_defined
- #ifndef int8_t
- typedef $acx_cv_type_int8_t int8_t;
- #endif
- #endif
- #endif
-
- #ifndef _INT16_T
- #define _INT16_T
- #ifndef __int16_t_defined
- #define __int16_t_defined
- #ifndef int16_t
- typedef $acx_cv_type_int16_t int16_t;
- #endif
- #endif
- #endif
-
- #ifndef _INT32_T
- #define _INT32_T
- #ifndef __int32_t_defined
- #define __int32_t_defined
- #ifndef int32_t
- typedef $acx_cv_type_int32_t int32_t;
- #endif
- #endif
- #endif
-EOF
-elif test "$ac_cv_type_u_int32_t" = yes; then
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- /* int8_t int16_t int32_t defined by inet code, we do the u_intXX types */
- #ifndef _INT8_T
- #define _INT8_T
- #endif
- #ifndef _INT16_T
- #define _INT16_T
- #endif
- #ifndef _INT32_T
- #define _INT32_T
- #endif
-
- #ifndef _UINT8_T
- #define _UINT8_T
- #ifndef __uint8_t_defined
- #define __uint8_t_defined
- #ifndef uint8_t
- typedef u_int8_t uint8_t;
- #endif
- #endif
- #endif
-
- #ifndef _UINT16_T
- #define _UINT16_T
- #ifndef __uint16_t_defined
- #define __uint16_t_defined
- #ifndef uint16_t
- typedef u_int16_t uint16_t;
- #endif
- #endif
- #endif
-
- #ifndef _UINT32_T
- #define _UINT32_T
- #ifndef __uint32_t_defined
- #define __uint32_t_defined
- #ifndef uint32_t
- typedef u_int32_t uint32_t;
- #endif
- #endif
- #endif
-EOF
-else
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- /* Some systems have guard macros to prevent redefinitions, define them. */
- #ifndef _INT8_T
- #define _INT8_T
- #endif
- #ifndef _INT16_T
- #define _INT16_T
- #endif
- #ifndef _INT32_T
- #define _INT32_T
- #endif
- #ifndef _UINT8_T
- #define _UINT8_T
- #endif
- #ifndef _UINT16_T
- #define _UINT16_T
- #endif
- #ifndef _UINT32_T
- #define _UINT32_T
- #endif
-EOF
-fi
-
-# ------------- done basic int types, emit int64_t types ------------
-if test "$ac_cv_type_uint64_t" = yes; then
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- /* system headers have good uint64_t and int64_t */
- #ifndef _INT64_T
- #define _INT64_T
- #endif
- #ifndef _UINT64_T
- #define _UINT64_T
- #endif
-EOF
-elif test "$ac_cv_type_u_int64_t" = yes; then
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- /* system headers have an u_int64_t (and int64_t) */
- #ifndef _INT64_T
- #define _INT64_T
- #endif
- #ifndef _UINT64_T
- #define _UINT64_T
- #ifndef __uint64_t_defined
- #define __uint64_t_defined
- #ifndef uint64_t
- typedef u_int64_t uint64_t;
- #endif
- #endif
- #endif
-EOF
-elif test -n "$acx_cv_type_int64_t"; then
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- /* architecture has a 64-bit type, $acx_cv_type_int64_t */
- #ifndef _INT64_T
- #define _INT64_T
- #ifndef int64_t
- typedef $acx_cv_type_int64_t int64_t;
- #endif
- #endif
- #ifndef _UINT64_T
- #define _UINT64_T
- #ifndef __uint64_t_defined
- #define __uint64_t_defined
- #ifndef uint64_t
- typedef unsigned $acx_cv_type_int64_t uint64_t;
- #endif
- #endif
- #endif
-EOF
-else
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- /* some common heuristics for int64_t, using compiler-specific tests */
- #if defined __STDC_VERSION__ && (__STDC_VERSION__-0) >= 199901L
- #ifndef _INT64_T
- #define _INT64_T
- #ifndef __int64_t_defined
- #ifndef int64_t
- typedef long long int64_t;
- #endif
- #endif
- #endif
- #ifndef _UINT64_T
- #define _UINT64_T
- #ifndef uint64_t
- typedef unsigned long long uint64_t;
- #endif
- #endif
-
- #elif defined __GNUC__ && defined (__STDC__) && __STDC__-0
- /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
- does not implement __extension__. But that compiler doesn't define
- __GNUC_MINOR__. */
- # if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
- # define __extension__
- # endif
-
- # ifndef _INT64_T
- # define _INT64_T
- # ifndef int64_t
- __extension__ typedef long long int64_t;
- # endif
- # endif
- # ifndef _UINT64_T
- # define _UINT64_T
- # ifndef uint64_t
- __extension__ typedef unsigned long long uint64_t;
- # endif
- # endif
-
- #elif !defined __STRICT_ANSI__
- # if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
-
- # ifndef _INT64_T
- # define _INT64_T
- # ifndef int64_t
- typedef __int64 int64_t;
- # endif
- # endif
- # ifndef _UINT64_T
- # define _UINT64_T
- # ifndef uint64_t
- typedef unsigned __int64 uint64_t;
- # endif
- # endif
- # endif /* compiler */
-
- #endif /* ANSI version */
-EOF
-fi
-
-# ------------- done int64_t types, emit intptr types ------------
-if test "$ac_cv_type_uintptr_t" != yes; then
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- /* Define intptr_t based on sizeof(void*) = $ac_cv_sizeof_void_p */
- #ifndef __uintptr_t_defined
- #ifndef uintptr_t
- typedef u$acx_cv_type_intptr_t uintptr_t;
- #endif
- #endif
- #ifndef __intptr_t_defined
- #ifndef intptr_t
- typedef $acx_cv_type_intptr_t intptr_t;
- #endif
- #endif
-EOF
-fi
-
-# ------------- done intptr types, emit int_least types ------------
-if test "$ac_cv_type_int_least32_t" != yes; then
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- /* Define int_least types */
- typedef int8_t int_least8_t;
- typedef int16_t int_least16_t;
- typedef int32_t int_least32_t;
- #ifdef _INT64_T
- typedef int64_t int_least64_t;
- #endif
-
- typedef uint8_t uint_least8_t;
- typedef uint16_t uint_least16_t;
- typedef uint32_t uint_least32_t;
- #ifdef _UINT64_T
- typedef uint64_t uint_least64_t;
- #endif
-EOF
-fi
-
-# ------------- done intptr types, emit int_fast types ------------
-if test "$ac_cv_type_int_fast32_t" != yes; then
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- /* Define int_fast types. short is often slow */
- typedef int8_t int_fast8_t;
- typedef int int_fast16_t;
- typedef int32_t int_fast32_t;
- #ifdef _INT64_T
- typedef int64_t int_fast64_t;
- #endif
-
- typedef uint8_t uint_fast8_t;
- typedef unsigned int uint_fast16_t;
- typedef uint32_t uint_fast32_t;
- #ifdef _UINT64_T
- typedef uint64_t uint_fast64_t;
- #endif
-EOF
-fi
-
-if test "$ac_cv_type_uintmax_t" != yes; then
- sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- /* Define intmax based on what we found */
- #ifndef intmax_t
- #ifdef _INT64_T
- typedef int64_t intmax_t;
- #else
- typedef long intmax_t;
- #endif
- #endif
- #ifndef uintmax_t
- #ifdef _UINT64_T
- typedef uint64_t uintmax_t;
- #else
- typedef unsigned long uintmax_t;
- #endif
- #endif
-EOF
-fi
-
-sed 's/^ *//' >> tmp-stdint.h <<EOF
-
- #endif /* GCC_GENERATED_STDINT_H */
-EOF
-
-if test -r gstdint.h && cmp -s tmp-stdint.h gstdint.h; then
- rm -f tmp-stdint.h
-else
- mv -f tmp-stdint.h gstdint.h
-fi
-
- ;;
esac
done # for ac_tag
@@ -19951,7 +19689,7 @@ _ACEOF
ac_clean_files=$ac_clean_files_save
test $ac_write_fail = 0 ||
- as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
# configure is writing to config.log, and then calls config.status.
@@ -19972,7 +19710,7 @@ if test "$no_create" != yes; then
exec 5>>config.log
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
- $ac_cs_success || as_fn_exit $?
+ $ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
diff --git a/libgomp/configure.ac b/libgomp/configure.ac
index 4e0bc8166a9..725f3bfd285 100644
--- a/libgomp/configure.ac
+++ b/libgomp/configure.ac
@@ -1,7 +1,6 @@
# Process this file with autoconf to produce a configure script, like so:
# aclocal -I ../config && autoconf && autoheader && automake
-AC_PREREQ(2.64)
AC_INIT([GNU Offloading and Multi Processing Runtime Library], 1.0,,[libgomp])
AC_CONFIG_HEADER(config.h)
@@ -172,14 +171,12 @@ AC_HEADER_TIME
ACX_HEADER_STRING
AC_CHECK_HEADERS(pthread.h unistd.h semaphore.h sys/loadavg.h sys/sysctl.h sys/time.h)
-GCC_HEADER_STDINT(gstdint.h)
-
XPCFLAGS=""
case "$host" in
*-*-rtems*)
# RTEMS supports Pthreads, but the library is not available at GCC build time.
;;
- nvptx*-*-*)
+ nvptx*-*-* | amdgcn*-*-*)
# NVPTX does not support Pthreads, has its own code replacement.
libgomp_use_pthreads=no
# NVPTX is an accelerator-only target
@@ -219,6 +216,7 @@ m4_include([plugin/configfrag.ac])
# Check for functions needed.
AC_CHECK_FUNCS(getloadavg clock_gettime strtoull)
+AC_CHECK_FUNCS(aligned_alloc posix_memalign memalign _aligned_malloc)
# Check for broken semaphore implementation on darwin.
# sem_init returns: sem_init error: Function not implemented.
@@ -266,6 +264,41 @@ if test $ac_cv_func_clock_gettime = no; then
[Define to 1 if you have the `clock_gettime' function.])])
fi
+# Check for uname.
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include <string.h>
+ #include <stdlib.h>
+ #include <sys/utsname.h>],
+ [struct utsname buf;
+ volatile size_t len = 0;
+ if (!uname (buf))
+ len = strlen (buf.nodename);])],
+ AC_DEFINE(HAVE_UNAME, 1,
+[ Define if uname is supported and struct utsname has nodename field.]))
+
+# Check for gethostname.
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include <unistd.h>],
+ [
+changequote(,)dnl
+ char buf[256];
+ if (gethostname (buf, sizeof (buf) - 1) == 0)
+ buf[255] = '\0';
+changequote([,])dnl
+ ])],
+ AC_DEFINE(HAVE_GETHOSTNAME, 1,
+[ Define if gethostname is supported.]))
+
+# Check for getpid.
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include <unistd.h>],
+ [int pid = getpid ();])],
+ AC_DEFINE(HAVE_GETPID, 1,
+[ Define if getpid is supported.]))
+
# See if we support thread-local storage.
GCC_CHECK_TLS
@@ -283,6 +316,10 @@ if test $enable_symvers = gnu; then
[Define to 1 if GNU symbol versioning is used for libgomp.])
fi
+# Determine cpu count to limit testsuite parallelism.
+AX_COUNT_CPUS
+AC_SUBST(CPU_COUNT)
+
# Get target configury.
. ${srcdir}/configure.tgt
CFLAGS="$save_CFLAGS $XCFLAGS"
diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt
index 74d95a570c7..06ee115ece9 100644
--- a/libgomp/configure.tgt
+++ b/libgomp/configure.tgt
@@ -18,7 +18,7 @@ if test $gcc_cv_have_tls = yes ; then
;;
*-*-linux* | *-*-gnu*)
- XCFLAGS="${XCFLAGS} -ftls-model=initial-exec"
+ XCFLAGS="${XCFLAGS} -ftls-model=initial-exec -DUSING_INITIAL_EXEC_TLS"
;;
*-*-rtems*)
@@ -154,7 +154,7 @@ case "${target}" in
;;
nvptx*-*-*)
- config_path="nvptx"
+ config_path="nvptx accel"
;;
*-*-rtems*)
@@ -164,6 +164,10 @@ case "${target}" in
fi
;;
+ amdgcn*-*-*)
+ config_path="gcn accel"
+ ;;
+
*)
;;
diff --git a/libgomp/critical.c b/libgomp/critical.c
index 6f3523cbc46..f9e40571d16 100644
--- a/libgomp/critical.c
+++ b/libgomp/critical.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/env.c b/libgomp/env.c
index 18c90bb09d0..29d9f58cba3 100644
--- a/libgomp/env.c
+++ b/libgomp/env.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -88,6 +88,9 @@ void **gomp_places_list;
unsigned long gomp_places_list_len;
int gomp_debug_var;
unsigned int gomp_num_teams_var;
+bool gomp_display_affinity_var;
+char *gomp_affinity_format_var = "level %L thread %i affinity %A";
+size_t gomp_affinity_format_len;
char *goacc_device_type;
int goacc_device_num;
int goacc_default_dims[GOMP_DIM_MAX];
@@ -101,6 +104,7 @@ parse_schedule (void)
{
char *env, *end;
unsigned long value;
+ int monotonic = 0;
env = getenv ("OMP_SCHEDULE");
if (env == NULL)
@@ -108,6 +112,26 @@ parse_schedule (void)
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;
@@ -131,12 +155,16 @@ parse_schedule (void)
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++ != ',')
@@ -159,7 +187,8 @@ parse_schedule (void)
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;
@@ -1150,19 +1179,34 @@ handle_omp_display_env (unsigned long stacksize, int wait_policy)
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);
@@ -1228,6 +1272,10 @@ handle_omp_display_env (unsigned long stacksize, int wait_policy)
gomp_global_icv.default_device_var);
fprintf (stderr, " OMP_MAX_TASK_PRIORITY = '%d'\n",
gomp_max_task_priority_var);
+ fprintf (stderr, " OMP_DISPLAY_AFFINITY = '%s'\n",
+ gomp_display_affinity_var ? "TRUE" : "FALSE");
+ fprintf (stderr, " OMP_AFFINITY_FORMAT = '%s'\n",
+ gomp_affinity_format_var);
if (verbose)
{
@@ -1259,6 +1307,7 @@ initialize_env (void)
parse_boolean ("OMP_DYNAMIC", &gomp_global_icv.dyn_var);
parse_boolean ("OMP_NESTED", &gomp_global_icv.nest_var);
parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var);
+ parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var);
parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv.default_device_var, true);
parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var, true);
parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var,
@@ -1308,6 +1357,13 @@ initialize_env (void)
}
if (gomp_global_icv.bind_var != omp_proc_bind_false)
gomp_init_affinity ();
+
+ {
+ const char *env = getenv ("OMP_AFFINITY_FORMAT");
+ if (env != NULL)
+ gomp_set_affinity_format (env, strlen (env));
+ }
+
wait_policy = parse_wait_policy ();
if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
{
@@ -1333,7 +1389,6 @@ initialize_env (void)
/* Not strictly environment related, but ordering constructors is tricky. */
pthread_attr_init (&gomp_thread_attr);
- pthread_attr_setdetachstate (&gomp_thread_attr, PTHREAD_CREATE_DETACHED);
if (parse_stacksize ("OMP_STACKSIZE", &stacksize)
|| parse_stacksize ("GOMP_STACKSIZE", &stacksize)
@@ -1370,5 +1425,7 @@ initialize_env (void)
parse_gomp_openacc_dim ();
goacc_runtime_initialize ();
+
+ goacc_profiling_initialize ();
}
#endif /* LIBGOMP_OFFLOADED_ONLY */
diff --git a/libgomp/error.c b/libgomp/error.c
index a59589859cc..0638a7aae40 100644
--- a/libgomp/error.c
+++ b/libgomp/error.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/fortran.c b/libgomp/fortran.c
index 24172a0f01a..4d544be1c99 100644
--- a/libgomp/fortran.c
+++ b/libgomp/fortran.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -28,6 +28,8 @@
#include "libgomp.h"
#include "libgomp_f.h"
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
#include <limits.h>
#ifdef HAVE_ATTRIBUTE_ALIAS
@@ -82,6 +84,8 @@ ialias_redirect (omp_get_team_num)
ialias_redirect (omp_is_initial_device)
ialias_redirect (omp_get_initial_device)
ialias_redirect (omp_get_max_task_priority)
+ialias_redirect (omp_pause_resource)
+ialias_redirect (omp_pause_resource_all)
#endif
#ifndef LIBGOMP_GNU_SYMBOL_VERSIONING
@@ -368,7 +372,9 @@ omp_get_schedule_ (int32_t *kind, int32_t *chunk_size)
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;
}
@@ -378,7 +384,8 @@ omp_get_schedule_8_ (int32_t *kind, int64_t *chunk_size)
omp_sched_t k;
int cs;
omp_get_schedule (&k, &cs);
- *kind = k;
+ /* See above. */
+ *kind = k & ~GFS_MONOTONIC;
*chunk_size = cs;
}
@@ -576,3 +583,96 @@ omp_get_max_task_priority_ (void)
{
return omp_get_max_task_priority ();
}
+
+void
+omp_set_affinity_format_ (const char *format, size_t format_len)
+{
+ gomp_set_affinity_format (format, format_len);
+}
+
+int32_t
+omp_get_affinity_format_ (char *buffer, size_t buffer_len)
+{
+ size_t len = strlen (gomp_affinity_format_var);
+ if (buffer_len)
+ {
+ if (len < buffer_len)
+ {
+ memcpy (buffer, gomp_affinity_format_var, len);
+ memset (buffer + len, ' ', buffer_len - len);
+ }
+ else
+ memcpy (buffer, gomp_affinity_format_var, buffer_len);
+ }
+ return len;
+}
+
+void
+omp_display_affinity_ (const char *format, size_t format_len)
+{
+ char *fmt = NULL, fmt_buf[256];
+ char buf[512];
+ if (format_len)
+ {
+ fmt = format_len < 256 ? fmt_buf : gomp_malloc (format_len + 1);
+ memcpy (fmt, format, format_len);
+ fmt[format_len] = '\0';
+ }
+ struct gomp_thread *thr = gomp_thread ();
+ size_t ret
+ = gomp_display_affinity (buf, sizeof buf,
+ format_len ? fmt : gomp_affinity_format_var,
+ gomp_thread_self (), &thr->ts, thr->place);
+ if (ret < sizeof buf)
+ {
+ buf[ret] = '\n';
+ gomp_print_string (buf, ret + 1);
+ }
+ else
+ {
+ char *b = gomp_malloc (ret + 1);
+ gomp_display_affinity (buf, sizeof buf,
+ format_len ? fmt : gomp_affinity_format_var,
+ gomp_thread_self (), &thr->ts, thr->place);
+ b[ret] = '\n';
+ gomp_print_string (b, ret + 1);
+ free (b);
+ }
+ if (fmt && fmt != fmt_buf)
+ free (fmt);
+}
+
+int32_t
+omp_capture_affinity_ (char *buffer, const char *format,
+ size_t buffer_len, size_t format_len)
+{
+ char *fmt = NULL, fmt_buf[256];
+ if (format_len)
+ {
+ fmt = format_len < 256 ? fmt_buf : gomp_malloc (format_len + 1);
+ memcpy (fmt, format, format_len);
+ fmt[format_len] = '\0';
+ }
+ struct gomp_thread *thr = gomp_thread ();
+ size_t ret
+ = gomp_display_affinity (buffer, buffer_len,
+ format_len ? fmt : gomp_affinity_format_var,
+ gomp_thread_self (), &thr->ts, thr->place);
+ if (fmt && fmt != fmt_buf)
+ free (fmt);
+ if (ret < buffer_len)
+ memset (buffer + ret, ' ', buffer_len - ret);
+ return ret;
+}
+
+int32_t
+omp_pause_resource_ (const int32_t *kind, const int32_t *device_num)
+{
+ return omp_pause_resource (*kind, *device_num);
+}
+
+int32_t
+omp_pause_resource_all_ (const int32_t *kind)
+{
+ return omp_pause_resource_all (*kind);
+}
diff --git a/libgomp/hashtab.h b/libgomp/hashtab.h
index 900b8238e20..b7deba5effe 100644
--- a/libgomp/hashtab.h
+++ b/libgomp/hashtab.h
@@ -1,5 +1,5 @@
/* An expandable hash tables datatype.
- Copyright (C) 1999-2018 Free Software Foundation, Inc.
+ Copyright (C) 1999-2019 Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@cygnus.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/icv-device.c b/libgomp/icv-device.c
index b643cb29ee7..2b74cbed508 100644
--- a/libgomp/icv-device.c
+++ b/libgomp/icv-device.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -49,20 +49,6 @@ omp_get_num_devices (void)
}
int
-omp_get_num_teams (void)
-{
- /* Hardcoded to 1 on host, MIC, HSAIL? Maybe variable on PTX. */
- return 1;
-}
-
-int
-omp_get_team_num (void)
-{
- /* Hardcoded to 0 on host, MIC, HSAIL? Maybe variable on PTX. */
- return 0;
-}
-
-int
omp_is_initial_device (void)
{
/* Hardcoded to 1 on host, should be 0 on MIC, HSAIL, PTX. */
@@ -72,6 +58,4 @@ omp_is_initial_device (void)
ialias (omp_set_default_device)
ialias (omp_get_default_device)
ialias (omp_get_num_devices)
-ialias (omp_get_num_teams)
-ialias (omp_get_team_num)
ialias (omp_is_initial_device)
diff --git a/libgomp/icv.c b/libgomp/icv.c
index 42db4fe6c88..095d57a93b1 100644
--- a/libgomp/icv.c
+++ b/libgomp/icv.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -69,7 +69,7 @@ void
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)
diff --git a/libgomp/iter.c b/libgomp/iter.c
index 8996c714c3f..8cc1a15fd21 100644
--- a/libgomp/iter.c
+++ b/libgomp/iter.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/iter_ull.c b/libgomp/iter_ull.c
index fba37af0f45..aa862ff1674 100644
--- a/libgomp/iter_ull.c
+++ b/libgomp/iter_ull.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/libgomp-plugin.c b/libgomp/libgomp-plugin.c
index d67b458f714..5b77a536bb8 100644
--- a/libgomp/libgomp-plugin.c
+++ b/libgomp/libgomp-plugin.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2014-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
diff --git a/libgomp/libgomp-plugin.h b/libgomp/libgomp-plugin.h
index 2fc35d56d1b..037558c43f5 100644
--- a/libgomp/libgomp-plugin.h
+++ b/libgomp/libgomp-plugin.h
@@ -1,6 +1,6 @@
/* The libgomp plugin API.
- Copyright (C) 2014-2018 Free Software Foundation, Inc.
+ Copyright (C) 2014-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -50,9 +50,24 @@ enum offload_target_type
/* OFFLOAD_TARGET_TYPE_HOST_NONSHM = 3 removed. */
OFFLOAD_TARGET_TYPE_NVIDIA_PTX = 5,
OFFLOAD_TARGET_TYPE_INTEL_MIC = 6,
- OFFLOAD_TARGET_TYPE_HSA = 7
+ OFFLOAD_TARGET_TYPE_HSA = 7,
+ OFFLOAD_TARGET_TYPE_GCN = 8
};
+/* Opaque type to represent plugin-dependent implementation of an
+ OpenACC asynchronous queue. */
+struct goacc_asyncqueue;
+
+/* Used to keep a list of active asynchronous queues. */
+struct goacc_asyncqueue_list
+{
+ struct goacc_asyncqueue *aq;
+ struct goacc_asyncqueue_list *next;
+};
+
+typedef struct goacc_asyncqueue *goacc_aq;
+typedef struct goacc_asyncqueue_list *goacc_aq_list;
+
/* Auxiliary struct, used for transferring pairs of addresses from plugin
to libgomp. */
struct addr_pair
@@ -93,22 +108,31 @@ extern bool GOMP_OFFLOAD_dev2dev (int, void *, const void *, size_t);
extern bool GOMP_OFFLOAD_can_run (void *);
extern void GOMP_OFFLOAD_run (int, void *, void *, void **);
extern void GOMP_OFFLOAD_async_run (int, void *, void *, void **, void *);
+
extern void GOMP_OFFLOAD_openacc_exec (void (*) (void *), size_t, void **,
- void **, int, unsigned *, void *);
-extern void GOMP_OFFLOAD_openacc_register_async_cleanup (void *, int);
-extern int GOMP_OFFLOAD_openacc_async_test (int);
-extern int GOMP_OFFLOAD_openacc_async_test_all (void);
-extern void GOMP_OFFLOAD_openacc_async_wait (int);
-extern void GOMP_OFFLOAD_openacc_async_wait_async (int, int);
-extern void GOMP_OFFLOAD_openacc_async_wait_all (void);
-extern void GOMP_OFFLOAD_openacc_async_wait_all_async (int);
-extern void GOMP_OFFLOAD_openacc_async_set_async (int);
+ void **, unsigned *, void *);
extern void *GOMP_OFFLOAD_openacc_create_thread_data (int);
extern void GOMP_OFFLOAD_openacc_destroy_thread_data (void *);
+extern struct goacc_asyncqueue *GOMP_OFFLOAD_openacc_async_construct (int);
+extern bool GOMP_OFFLOAD_openacc_async_destruct (struct goacc_asyncqueue *);
+extern int GOMP_OFFLOAD_openacc_async_test (struct goacc_asyncqueue *);
+extern bool GOMP_OFFLOAD_openacc_async_synchronize (struct goacc_asyncqueue *);
+extern bool GOMP_OFFLOAD_openacc_async_serialize (struct goacc_asyncqueue *,
+ struct goacc_asyncqueue *);
+extern void GOMP_OFFLOAD_openacc_async_queue_callback (struct goacc_asyncqueue *,
+ void (*)(void *), void *);
+extern void GOMP_OFFLOAD_openacc_async_exec (void (*) (void *), size_t, void **,
+ void **, unsigned *, void *,
+ struct goacc_asyncqueue *);
+extern bool GOMP_OFFLOAD_openacc_async_dev2host (int, void *, const void *, size_t,
+ struct goacc_asyncqueue *);
+extern bool GOMP_OFFLOAD_openacc_async_host2dev (int, void *, const void *, size_t,
+ struct goacc_asyncqueue *);
extern void *GOMP_OFFLOAD_openacc_cuda_get_current_device (void);
extern void *GOMP_OFFLOAD_openacc_cuda_get_current_context (void);
-extern void *GOMP_OFFLOAD_openacc_cuda_get_stream (int);
-extern int GOMP_OFFLOAD_openacc_cuda_set_stream (int, void *);
+extern void *GOMP_OFFLOAD_openacc_cuda_get_stream (struct goacc_asyncqueue *);
+extern int GOMP_OFFLOAD_openacc_cuda_set_stream (struct goacc_asyncqueue *,
+ void *);
#ifdef __cplusplus
}
diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index 3a8cc2bd7d6..bab733d2b2d 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -42,7 +42,7 @@
#endif
#include "config.h"
-#include "gstdint.h"
+#include <stdint.h>
#include "libgomp-plugin.h"
#include "gomp-constants.h"
@@ -86,14 +86,89 @@ enum memmodel
/* alloc.c */
+#if defined(HAVE_ALIGNED_ALLOC) \
+ || defined(HAVE__ALIGNED_MALLOC) \
+ || defined(HAVE_POSIX_MEMALIGN) \
+ || defined(HAVE_MEMALIGN)
+/* Defined if gomp_aligned_alloc doesn't use fallback version
+ and free can be used instead of gomp_aligned_free. */
+#define GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC 1
+#endif
+
extern void *gomp_malloc (size_t) __attribute__((malloc));
extern void *gomp_malloc_cleared (size_t) __attribute__((malloc));
extern void *gomp_realloc (void *, size_t);
+extern void *gomp_aligned_alloc (size_t, size_t)
+ __attribute__((malloc, alloc_size (2)));
+extern void gomp_aligned_free (void *);
/* Avoid conflicting prototypes of alloca() in system headers by using
GCC's builtin alloca(). */
#define gomp_alloca(x) __builtin_alloca(x)
+/* Optimized allocators for team-specific data that will die with the team. */
+
+#ifdef __AMDGCN__
+/* The arena is initialized in config/gcn/team.c. */
+#define TEAM_ARENA_SIZE 64*1024 /* Must match the value in plugin-gcn.c. */
+#define TEAM_ARENA_START 16 /* LDS offset of free pointer. */
+#define TEAM_ARENA_FREE 24 /* LDS offset of free pointer. */
+#define TEAM_ARENA_END 32 /* LDS offset of end pointer. */
+
+static inline void * __attribute__((malloc))
+team_malloc (size_t size)
+{
+ /* 4-byte align the size. */
+ size = (size + 3) & ~3;
+
+ /* Allocate directly from the arena.
+ The compiler does not support DS atomics, yet. */
+ void *result;
+ asm ("ds_add_rtn_u64 %0, %1, %2\n\ts_waitcnt 0"
+ : "=v"(result) : "v"(TEAM_ARENA_FREE), "v"(size), "e"(1L) : "memory");
+
+ /* Handle OOM. */
+ if (result + size > *(void * __lds *)TEAM_ARENA_END)
+ {
+ /* While this is experimental, let's make sure we know when OOM
+ happens. */
+ const char msg[] = "GCN team arena exhausted\n";
+ write (2, msg, sizeof(msg)-1);
+
+ /* Fall back to using the heap (slowly). */
+ result = gomp_malloc (size);
+ }
+ return result;
+}
+
+static inline void * __attribute__((malloc))
+team_malloc_cleared (size_t size)
+{
+ char *result = team_malloc (size);
+
+ /* Clear the allocated memory. */
+ __builtin_memset (result, 0, size);
+
+ return result;
+}
+
+static inline void
+team_free (void *ptr)
+{
+ /* The whole arena is freed when the kernel exits.
+ However, if we fell back to using heap then we should free it.
+ It would be better if this function could be a no-op, but at least
+ LDS loads are cheap. */
+ if (ptr < *(void * __lds *)TEAM_ARENA_START
+ || ptr >= *(void * __lds *)TEAM_ARENA_END)
+ free (ptr);
+}
+#else
+#define team_malloc(...) gomp_malloc (__VA_ARGS__)
+#define team_malloc_cleared(...) gomp_malloc_cleared (__VA_ARGS__)
+#define team_free(...) free (__VA_ARGS__)
+#endif
+
/* error.c */
extern void gomp_vdebug (int, const char *, va_list);
@@ -138,7 +213,8 @@ enum gomp_schedule_type
GFS_STATIC,
GFS_DYNAMIC,
GFS_GUIDED,
- GFS_AUTO
+ GFS_AUTO,
+ GFS_MONOTONIC = 0x80000000U
};
struct gomp_doacross_work_share
@@ -175,6 +251,8 @@ struct gomp_doacross_work_share
/* Likewise, but for the ull implementation. */
unsigned long long boundary_ull;
};
+ /* Pointer to extra memory if needed for lastprivate(conditional). */
+ void *extra;
/* Array of shift counts for each dimension if they can be flattened. */
unsigned int shift_counts[];
};
@@ -276,6 +354,9 @@ struct gomp_work_share
struct gomp_work_share *next_free;
};
+ /* Task reductions for this work-sharing construct. */
+ uintptr_t *task_reductions;
+
/* If only few threads are in the team, ordered_team_ids can point
to this array which fills the padding at the end of this struct. */
unsigned inline_ordered_team_ids[0];
@@ -366,6 +447,9 @@ extern void **gomp_places_list;
extern unsigned long gomp_places_list_len;
extern unsigned int gomp_num_teams_var;
extern int gomp_debug_var;
+extern bool gomp_display_affinity_var;
+extern char *gomp_affinity_format_var;
+extern size_t gomp_affinity_format_len;
extern int goacc_device_num;
extern char *goacc_device_type;
extern int goacc_default_dims[GOMP_DIM_MAX];
@@ -471,8 +555,10 @@ struct gomp_taskgroup
struct gomp_taskgroup *prev;
/* Queue of tasks that belong in this taskgroup. */
struct priority_queue taskgroup_queue;
+ uintptr_t *reductions;
bool in_taskgroup_wait;
bool cancelled;
+ bool workshare;
gomp_sem_t taskgroup_sem;
size_t num_children;
};
@@ -615,6 +701,19 @@ struct gomp_thread
/* User pthread thread pool */
struct gomp_thread_pool *thread_pool;
+
+#if defined(LIBGOMP_USE_PTHREADS) \
+ && (!defined(HAVE_TLS) \
+ || !defined(__GLIBC__) \
+ || !defined(USING_INITIAL_EXEC_TLS))
+ /* pthread_t of the thread containing this gomp_thread.
+ On Linux when using initial-exec TLS,
+ (typeof (pthread_t)) gomp_thread () - pthread_self ()
+ is constant in all threads, so we can optimize and not
+ store it. */
+#define GOMP_NEEDS_THREAD_HANDLE 1
+ pthread_t handle;
+#endif
};
@@ -656,6 +755,24 @@ static inline struct gomp_thread *gomp_thread (void)
asm ("mov.u32 %0, %%tid.y;" : "=r" (tid));
return nvptx_thrs + tid;
}
+#elif defined __AMDGCN__
+static inline struct gomp_thread *gcn_thrs (void)
+{
+ /* The value is at the bottom of LDS. */
+ struct gomp_thread * __lds *thrs = (struct gomp_thread * __lds *)4;
+ return *thrs;
+}
+static inline void set_gcn_thrs (struct gomp_thread *val)
+{
+ /* The value is at the bottom of LDS. */
+ struct gomp_thread * __lds *thrs = (struct gomp_thread * __lds *)4;
+ *thrs = val;
+}
+static inline struct gomp_thread *gomp_thread (void)
+{
+ int tid = __builtin_gcn_dim_pos(1);
+ return gcn_thrs () + tid;
+}
#elif defined HAVE_TLS || defined USE_EMUTLS
extern __thread struct gomp_thread gomp_tls_data;
static inline struct gomp_thread *gomp_thread (void)
@@ -711,6 +828,25 @@ extern bool gomp_affinity_finalize_place_list (bool);
extern bool gomp_affinity_init_level (int, unsigned long, bool);
extern void gomp_affinity_print_place (void *);
extern void gomp_get_place_proc_ids_8 (int, int64_t *);
+extern void gomp_display_affinity_place (char *, size_t, size_t *, int);
+
+/* affinity-fmt.c */
+
+extern void gomp_print_string (const char *str, size_t len);
+extern void gomp_set_affinity_format (const char *, size_t);
+extern void gomp_display_string (char *, size_t, size_t *, const char *,
+ size_t);
+#ifdef LIBGOMP_USE_PTHREADS
+typedef pthread_t gomp_thread_handle;
+#else
+typedef struct {} gomp_thread_handle;
+#endif
+extern size_t gomp_display_affinity (char *, size_t, const char *,
+ gomp_thread_handle,
+ struct gomp_team_state *, unsigned int);
+extern void gomp_display_affinity_thread (gomp_thread_handle,
+ struct gomp_team_state *,
+ unsigned int) __attribute__((cold));
/* iter.c */
@@ -747,9 +883,9 @@ extern void gomp_ordered_next (void);
extern void gomp_ordered_static_init (void);
extern void gomp_ordered_static_next (void);
extern void gomp_ordered_sync (void);
-extern void gomp_doacross_init (unsigned, long *, long);
+extern void gomp_doacross_init (unsigned, long *, long, size_t);
extern void gomp_doacross_ull_init (unsigned, unsigned long long *,
- unsigned long long);
+ unsigned long long, size_t);
/* parallel.c */
@@ -772,6 +908,10 @@ extern bool gomp_create_target_task (struct gomp_device_descr *,
size_t *, unsigned short *, unsigned int,
void **, void **,
enum gomp_target_task_state);
+extern struct gomp_taskgroup *gomp_parallel_reduction_register (uintptr_t *,
+ unsigned);
+extern void gomp_workshare_taskgroup_start (void);
+extern void gomp_workshare_task_reduction_register (uintptr_t *, uintptr_t *);
static void inline
gomp_finish_task (struct gomp_task *task)
@@ -784,9 +924,11 @@ gomp_finish_task (struct gomp_task *task)
extern struct gomp_team *gomp_new_team (unsigned);
extern void gomp_team_start (void (*) (void *), void *, unsigned,
- unsigned, struct gomp_team *);
+ unsigned, struct gomp_team *,
+ struct gomp_taskgroup *);
extern void gomp_team_end (void);
extern void gomp_free_thread (void *);
+extern int gomp_pause_host (void);
/* target.c */
@@ -842,6 +984,11 @@ struct target_mem_desc {
artificial pointer to "omp declare target link" object. */
#define REFCOUNT_LINK (~(uintptr_t) 1)
+/* Special offset values. */
+#define OFFSET_INLINED (~(uintptr_t) 0)
+#define OFFSET_POINTER (~(uintptr_t) 1)
+#define OFFSET_STRUCT (~(uintptr_t) 2)
+
struct splay_tree_key_s {
/* Address of the host object. */
uintptr_t host_start;
@@ -888,24 +1035,31 @@ typedef struct acc_dispatch_t
/* Execute. */
__typeof (GOMP_OFFLOAD_openacc_exec) *exec_func;
- /* Async cleanup callback registration. */
- __typeof (GOMP_OFFLOAD_openacc_register_async_cleanup)
- *register_async_cleanup_func;
-
- /* Asynchronous routines. */
- __typeof (GOMP_OFFLOAD_openacc_async_test) *async_test_func;
- __typeof (GOMP_OFFLOAD_openacc_async_test_all) *async_test_all_func;
- __typeof (GOMP_OFFLOAD_openacc_async_wait) *async_wait_func;
- __typeof (GOMP_OFFLOAD_openacc_async_wait_async) *async_wait_async_func;
- __typeof (GOMP_OFFLOAD_openacc_async_wait_all) *async_wait_all_func;
- __typeof (GOMP_OFFLOAD_openacc_async_wait_all_async)
- *async_wait_all_async_func;
- __typeof (GOMP_OFFLOAD_openacc_async_set_async) *async_set_async_func;
-
/* Create/destroy TLS data. */
__typeof (GOMP_OFFLOAD_openacc_create_thread_data) *create_thread_data_func;
__typeof (GOMP_OFFLOAD_openacc_destroy_thread_data)
*destroy_thread_data_func;
+
+ struct {
+ /* Once created and put into the "active" list, asyncqueues are then never
+ destructed and removed from the "active" list, other than if the TODO
+ device is shut down. */
+ gomp_mutex_t lock;
+ int nasyncqueue;
+ struct goacc_asyncqueue **asyncqueue;
+ struct goacc_asyncqueue_list *active;
+
+ __typeof (GOMP_OFFLOAD_openacc_async_construct) *construct_func;
+ __typeof (GOMP_OFFLOAD_openacc_async_destruct) *destruct_func;
+ __typeof (GOMP_OFFLOAD_openacc_async_test) *test_func;
+ __typeof (GOMP_OFFLOAD_openacc_async_synchronize) *synchronize_func;
+ __typeof (GOMP_OFFLOAD_openacc_async_serialize) *serialize_func;
+ __typeof (GOMP_OFFLOAD_openacc_async_queue_callback) *queue_callback_func;
+
+ __typeof (GOMP_OFFLOAD_openacc_async_exec) *exec_func;
+ __typeof (GOMP_OFFLOAD_openacc_async_dev2host) *dev2host_func;
+ __typeof (GOMP_OFFLOAD_openacc_async_host2dev) *host2dev_func;
+ } async;
/* NVIDIA target specific routines. */
struct {
@@ -992,26 +1146,42 @@ enum gomp_map_vars_kind
GOMP_MAP_VARS_ENTER_DATA
};
-extern void gomp_acc_insert_pointer (size_t, void **, size_t *, void *);
+extern void gomp_acc_insert_pointer (size_t, void **, size_t *, void *, int);
extern void gomp_acc_remove_pointer (void *, size_t, bool, int, int, int);
extern void gomp_acc_declare_allocate (bool, size_t, void **, size_t *,
unsigned short *);
+struct gomp_coalesce_buf;
+extern void gomp_copy_host2dev (struct gomp_device_descr *,
+ struct goacc_asyncqueue *, void *, const void *,
+ size_t, struct gomp_coalesce_buf *);
+extern void gomp_copy_dev2host (struct gomp_device_descr *,
+ struct goacc_asyncqueue *, void *, const void *,
+ size_t);
extern struct target_mem_desc *gomp_map_vars (struct gomp_device_descr *,
size_t, void **, void **,
size_t *, void *, bool,
enum gomp_map_vars_kind);
+extern struct target_mem_desc *gomp_map_vars_async (struct gomp_device_descr *,
+ struct goacc_asyncqueue *,
+ size_t, void **, void **,
+ size_t *, void *, bool,
+ enum gomp_map_vars_kind);
+extern void gomp_unmap_tgt (struct target_mem_desc *);
extern void gomp_unmap_vars (struct target_mem_desc *, bool);
+extern void gomp_unmap_vars_async (struct target_mem_desc *, bool,
+ struct goacc_asyncqueue *);
extern void gomp_init_device (struct gomp_device_descr *);
+extern bool gomp_fini_device (struct gomp_device_descr *);
extern void gomp_free_memmap (struct splay_tree_s *);
extern void gomp_unload_device (struct gomp_device_descr *);
extern bool gomp_remove_var (struct gomp_device_descr *, splay_tree_key);
/* work.c */
-extern void gomp_init_work_share (struct gomp_work_share *, bool, unsigned);
+extern void gomp_init_work_share (struct gomp_work_share *, size_t, unsigned);
extern void gomp_fini_work_share (struct gomp_work_share *);
-extern bool gomp_work_share_start (bool);
+extern bool gomp_work_share_start (size_t);
extern void gomp_work_share_end (void);
extern bool gomp_work_share_end_cancel (void);
extern void gomp_work_share_end_nowait (void);
@@ -1089,16 +1259,26 @@ extern int gomp_test_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
# define attribute_hidden
#endif
+#if __GNUC__ >= 9
+# define HAVE_ATTRIBUTE_COPY
+#endif
+
+#ifdef HAVE_ATTRIBUTE_COPY
+# define attribute_copy(arg) __attribute__ ((copy (arg)))
+#else
+# define attribute_copy(arg)
+#endif
+
#ifdef HAVE_ATTRIBUTE_ALIAS
# define strong_alias(fn, al) \
- extern __typeof (fn) al __attribute__ ((alias (#fn)));
+ extern __typeof (fn) al __attribute__ ((alias (#fn))) attribute_copy (fn);
# define ialias_ulp ialias_str1(__USER_LABEL_PREFIX__)
# define ialias_str1(x) ialias_str2(x)
# define ialias_str2(x) #x
# define ialias(fn) \
extern __typeof (fn) gomp_ialias_##fn \
- __attribute__ ((alias (#fn))) attribute_hidden;
+ __attribute__ ((alias (#fn))) attribute_hidden attribute_copy (fn);
# define ialias_redirect(fn) \
extern __typeof (fn) fn __asm__ (ialias_ulp "gomp_ialias_" #fn) attribute_hidden;
# define ialias_call(fn) gomp_ialias_ ## fn
@@ -1138,4 +1318,42 @@ task_to_priority_node (enum priority_queue_type type,
return (struct priority_node *) ((char *) task
+ priority_queue_offset (type));
}
+
+#ifdef LIBGOMP_USE_PTHREADS
+static inline gomp_thread_handle
+gomp_thread_self (void)
+{
+ return pthread_self ();
+}
+
+static inline gomp_thread_handle
+gomp_thread_to_pthread_t (struct gomp_thread *thr)
+{
+ struct gomp_thread *this_thr = gomp_thread ();
+ if (thr == this_thr)
+ return pthread_self ();
+#ifdef GOMP_NEEDS_THREAD_HANDLE
+ return thr->handle;
+#else
+ /* On Linux with initial-exec TLS, the pthread_t of the thread containing
+ thr can be computed from thr, this_thr and pthread_self (),
+ as the distance between this_thr and pthread_self () is constant. */
+ return pthread_self () + ((uintptr_t) thr - (uintptr_t) this_thr);
+#endif
+}
+#else
+static inline gomp_thread_handle
+gomp_thread_self (void)
+{
+ return (gomp_thread_handle) {};
+}
+
+static inline gomp_thread_handle
+gomp_thread_to_pthread_t (struct gomp_thread *thr)
+{
+ (void) thr;
+ return gomp_thread_self ();
+}
+#endif
+
#endif /* LIBGOMP_H */
diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map
index 2cd3bf524bc..c79430f8d8d 100644
--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -164,6 +164,22 @@ OMP_4.5 {
omp_target_disassociate_ptr;
} OMP_4.0;
+OMP_5.0 {
+ global:
+ omp_capture_affinity;
+ omp_capture_affinity_;
+ omp_display_affinity;
+ omp_display_affinity_;
+ omp_get_affinity_format;
+ omp_get_affinity_format_;
+ omp_set_affinity_format;
+ omp_set_affinity_format_;
+ omp_pause_resource;
+ omp_pause_resource_;
+ omp_pause_resource_all;
+ omp_pause_resource_all_;
+} OMP_4.5;
+
GOMP_1.0 {
global:
GOMP_atomic_end;
@@ -298,6 +314,34 @@ GOMP_4.5 {
GOMP_parallel_loop_nonmonotonic_guided;
} GOMP_4.0.1;
+GOMP_5.0 {
+ global:
+ GOMP_loop_doacross_start;
+ GOMP_loop_maybe_nonmonotonic_runtime_next;
+ GOMP_loop_maybe_nonmonotonic_runtime_start;
+ GOMP_loop_nonmonotonic_runtime_next;
+ GOMP_loop_nonmonotonic_runtime_start;
+ GOMP_loop_ordered_start;
+ GOMP_loop_start;
+ GOMP_loop_ull_doacross_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_loop_ull_ordered_start;
+ GOMP_loop_ull_start;
+ GOMP_parallel_loop_maybe_nonmonotonic_runtime;
+ GOMP_parallel_loop_nonmonotonic_runtime;
+ GOMP_parallel_reductions;
+ GOMP_sections2_start;
+ GOMP_taskgroup_reduction_register;
+ GOMP_taskgroup_reduction_unregister;
+ GOMP_task_reduction_remap;
+ GOMP_taskwait_depend;
+ GOMP_teams_reg;
+ GOMP_workshare_task_reduction_unregister;
+} GOMP_4.5;
+
OACC_2.0 {
global:
acc_get_num_devices;
@@ -388,16 +432,58 @@ OACC_2.0.1 {
OACC_2.5 {
global:
+ acc_copyin_async;
+ acc_copyin_async_32_h_;
+ acc_copyin_async_64_h_;
+ acc_copyin_async_array_h_;
+ acc_copyout_async;
+ acc_copyout_async_32_h_;
+ acc_copyout_async_64_h_;
+ acc_copyout_async_array_h_;
acc_copyout_finalize;
acc_copyout_finalize_32_h_;
acc_copyout_finalize_64_h_;
acc_copyout_finalize_array_h_;
+ acc_copyout_finalize_async;
+ acc_copyout_finalize_async_32_h_;
+ acc_copyout_finalize_async_64_h_;
+ acc_copyout_finalize_async_array_h_;
+ acc_create_async;
+ acc_create_async_32_h_;
+ acc_create_async_64_h_;
+ acc_create_async_array_h_;
+ acc_delete_async;
+ acc_delete_async_32_h_;
+ acc_delete_async_64_h_;
+ acc_delete_async_array_h_;
acc_delete_finalize;
acc_delete_finalize_32_h_;
acc_delete_finalize_64_h_;
acc_delete_finalize_array_h_;
+ acc_delete_finalize_async;
+ acc_delete_finalize_async_32_h_;
+ acc_delete_finalize_async_64_h_;
+ acc_delete_finalize_async_array_h_;
+ acc_memcpy_from_device_async;
+ acc_memcpy_to_device_async;
+ acc_update_device_async;
+ acc_update_device_async_32_h_;
+ acc_update_device_async_64_h_;
+ acc_update_device_async_array_h_;
+ acc_update_self_async;
+ acc_update_self_async_32_h_;
+ acc_update_self_async_64_h_;
+ acc_update_self_async_array_h_;
} OACC_2.0.1;
+OACC_2.5.1 {
+ global:
+ acc_prof_lookup;
+ acc_prof_register;
+ acc_prof_unregister;
+ acc_register_library;
+} OACC_2.5;
+
GOACC_2.0 {
global:
GOACC_data_end;
@@ -437,3 +523,9 @@ GOMP_PLUGIN_1.2 {
global:
GOMP_PLUGIN_acc_default_dim;
} GOMP_PLUGIN_1.1;
+
+GOMP_PLUGIN_1.3 {
+ global:
+ GOMP_PLUGIN_goacc_profiling_dispatch;
+ GOMP_PLUGIN_goacc_thread;
+} GOMP_PLUGIN_1.2;
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 3fa8eb8165e..6db895f6272 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -7,7 +7,7 @@
@copying
-Copyright @copyright{} 2006-2018 Free Software Foundation, Inc.
+Copyright @copyright{} 2006-2019 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -95,10 +95,12 @@ changed to GNU Offloading and Multi Processing Runtime Library.
@comment
@menu
* Enabling OpenMP:: How to enable OpenMP for your applications.
-* Runtime Library Routines:: The OpenMP runtime application programming
+* OpenMP Runtime Library Routines: Runtime Library Routines.
+ The OpenMP runtime application programming
interface.
-* Environment Variables:: Influencing runtime behavior with environment
- variables.
+* OpenMP Environment Variables: Environment Variables.
+ Influencing OpenMP runtime behavior with
+ environment variables.
* Enabling OpenACC:: How to enable OpenACC for your
applications.
* OpenACC Runtime Library Routines:: The OpenACC runtime application
@@ -109,6 +111,7 @@ changed to GNU Offloading and Multi Processing Runtime Library.
asynchronous operations.
* OpenACC Library Interoperability:: OpenACC library interoperability with the
NVIDIA CUBLAS library.
+* OpenACC Profiling Interface::
* The libgomp ABI:: Notes on the external ABI presented by libgomp.
* Reporting Bugs:: How to report bugs in the GNU Offloading and
Multi Processing Runtime Library.
@@ -144,11 +147,11 @@ version 4.5.
@c ---------------------------------------------------------------------
-@c Runtime Library Routines
+@c OpenMP Runtime Library Routines
@c ---------------------------------------------------------------------
@node Runtime Library Routines
-@chapter Runtime Library Routines
+@chapter OpenMP Runtime Library Routines
The runtime routines described here are defined by Section 3 of the OpenMP
specification in version 4.5. The routines are structured in following
@@ -1327,11 +1330,11 @@ guaranteed not to change during the execution of the program.
@c ---------------------------------------------------------------------
-@c Environment Variables
+@c OpenMP Environment Variables
@c ---------------------------------------------------------------------
@node Environment Variables
-@chapter Environment Variables
+@chapter OpenMP Environment Variables
The environment variables which beginning with @env{OMP_} are defined by
section 4 of the OpenMP specification in version 4.5, while those
@@ -1895,6 +1898,13 @@ API routines for target platforms.
* acc_get_current_cuda_context::Get CUDA context handle.
* acc_get_cuda_stream:: Get CUDA stream handle.
* acc_set_cuda_stream:: Set CUDA stream handle.
+
+API routines for the OpenACC Profiling Interface.
+
+* acc_prof_register:: Register callbacks.
+* acc_prof_unregister:: Unregister callbacks.
+* acc_prof_lookup:: Obtain inquiry functions.
+* acc_register_library:: Library registration.
@end menu
@@ -2768,7 +2778,7 @@ as used by the CUDA Runtime or Driver API's.
@item @emph{C/C++}:
@multitable @columnfractions .20 .80
-@item @emph{Prototype}: @tab @code{acc_get_current_cuda_context(void);}
+@item @emph{Prototype}: @tab @code{void *acc_get_current_cuda_context(void);}
@end multitable
@item @emph{Reference}:
@@ -2782,12 +2792,12 @@ A.2.1.2.
@section @code{acc_get_cuda_stream} -- Get CUDA stream handle.
@table @asis
@item @emph{Description}
-This function returns the CUDA stream handle. This handle is the same
-as used by the CUDA Runtime or Driver API's.
+This function returns the CUDA stream handle for the queue @var{async}.
+This handle is the same as used by the CUDA Runtime or Driver API's.
@item @emph{C/C++}:
@multitable @columnfractions .20 .80
-@item @emph{Prototype}: @tab @code{acc_get_cuda_stream(void);}
+@item @emph{Prototype}: @tab @code{void *acc_get_cuda_stream(int async);}
@end multitable
@item @emph{Reference}:
@@ -2802,11 +2812,16 @@ A.2.1.3.
@table @asis
@item @emph{Description}
This function associates the stream handle specified by @var{stream} with
-the asynchronous value specified by @var{async}.
+the queue @var{async}.
+
+This cannot be used to change the stream handle associated with
+@code{acc_async_sync}.
+
+The return value is not specified.
@item @emph{C/C++}:
@multitable @columnfractions .20 .80
-@item @emph{Prototype}: @tab @code{acc_set_cuda_stream(int async void *stream);}
+@item @emph{Prototype}: @tab @code{int acc_set_cuda_stream(int async, void *stream);}
@end multitable
@item @emph{Reference}:
@@ -2816,6 +2831,90 @@ A.2.1.4.
+@node acc_prof_register
+@section @code{acc_prof_register} -- Register callbacks.
+@table @asis
+@item @emph{Description}:
+This function registers callbacks.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void acc_prof_register (acc_event_t, acc_prof_callback, acc_register_t);}
+@end multitable
+
+@item @emph{See also}:
+@ref{OpenACC Profiling Interface}
+
+@item @emph{Reference}:
+@uref{https://www.openacc.org, OpenACC specification v2.6}, section
+5.3.
+@end table
+
+
+
+@node acc_prof_unregister
+@section @code{acc_prof_unregister} -- Unregister callbacks.
+@table @asis
+@item @emph{Description}:
+This function unregisters callbacks.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void acc_prof_unregister (acc_event_t, acc_prof_callback, acc_register_t);}
+@end multitable
+
+@item @emph{See also}:
+@ref{OpenACC Profiling Interface}
+
+@item @emph{Reference}:
+@uref{https://www.openacc.org, OpenACC specification v2.6}, section
+5.3.
+@end table
+
+
+
+@node acc_prof_lookup
+@section @code{acc_prof_lookup} -- Obtain inquiry functions.
+@table @asis
+@item @emph{Description}:
+Function to obtain inquiry functions.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{acc_query_fn acc_prof_lookup (const char *);}
+@end multitable
+
+@item @emph{See also}:
+@ref{OpenACC Profiling Interface}
+
+@item @emph{Reference}:
+@uref{https://www.openacc.org, OpenACC specification v2.6}, section
+5.3.
+@end table
+
+
+
+@node acc_register_library
+@section @code{acc_register_library} -- Library registration.
+@table @asis
+@item @emph{Description}:
+Function for library registration.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{void acc_register_library (acc_prof_reg, acc_prof_reg, acc_prof_lookup_func);}
+@end multitable
+
+@item @emph{See also}:
+@ref{OpenACC Profiling Interface}, @ref{ACC_PROFLIB}
+
+@item @emph{Reference}:
+@uref{https://www.openacc.org, OpenACC specification v2.6}, section
+5.3.
+@end table
+
+
+
@c ---------------------------------------------------------------------
@c OpenACC Environment Variables
@c ---------------------------------------------------------------------
@@ -2825,11 +2924,14 @@ A.2.1.4.
The variables @env{ACC_DEVICE_TYPE} and @env{ACC_DEVICE_NUM}
are defined by section 4 of the OpenACC specification in version 2.0.
+The variable @env{ACC_PROFLIB}
+is defined by section 4 of the OpenACC specification in version 2.6.
The variable @env{GCC_ACC_NOTIFY} is used for diagnostic purposes.
@menu
* ACC_DEVICE_TYPE::
* ACC_DEVICE_NUM::
+* ACC_PROFLIB::
* GCC_ACC_NOTIFY::
@end menu
@@ -2855,6 +2957,19 @@ The variable @env{GCC_ACC_NOTIFY} is used for diagnostic purposes.
+@node ACC_PROFLIB
+@section @code{ACC_PROFLIB}
+@table @asis
+@item @emph{See also}:
+@ref{acc_register_library}, @ref{OpenACC Profiling Interface}
+
+@item @emph{Reference}:
+@uref{https://www.openacc.org, OpenACC specification v2.6}, section
+4.3.
+@end table
+
+
+
@node GCC_ACC_NOTIFY
@section @code{GCC_ACC_NOTIFY}
@table @asis
@@ -3071,6 +3186,310 @@ Application Programming Interface”, Version 2.0.}
@c ---------------------------------------------------------------------
+@c OpenACC Profiling Interface
+@c ---------------------------------------------------------------------
+
+@node OpenACC Profiling Interface
+@chapter OpenACC Profiling Interface
+
+@section Implementation Status and Implementation-Defined Behavior
+
+We're implementing the OpenACC Profiling Interface as defined by the
+OpenACC 2.6 specification. We're clarifying some aspects here as
+@emph{implementation-defined behavior}, while they're still under
+discussion within the OpenACC Technical Committee.
+
+This implementation is tuned to keep the performance impact as low as
+possible for the (very common) case that the Profiling Interface is
+not enabled. This is relevant, as the Profiling Interface affects all
+the @emph{hot} code paths (in the target code, not in the offloaded
+code). Users of the OpenACC Profiling Interface can be expected to
+understand that performance will be impacted to some degree once the
+Profiling Interface has gotten enabled: for example, because of the
+@emph{runtime} (libgomp) calling into a third-party @emph{library} for
+every event that has been registered.
+
+We're not yet accounting for the fact that @cite{OpenACC events may
+occur during event processing}.
+
+We're not yet implementing initialization via a
+@code{acc_register_library} function that is either statically linked
+in, or dynamically via @env{LD_PRELOAD}.
+Initialization via @code{acc_register_library} functions dynamically
+loaded via the @env{ACC_PROFLIB} environment variable does work, as
+does directly calling @code{acc_prof_register},
+@code{acc_prof_unregister}, @code{acc_prof_lookup}.
+
+As currently there are no inquiry functions defined, calls to
+@code{acc_prof_lookup} will always return @code{NULL}.
+
+There aren't separate @emph{start}, @emph{stop} events defined for the
+event types @code{acc_ev_create}, @code{acc_ev_delete},
+@code{acc_ev_alloc}, @code{acc_ev_free}. It's not clear if these
+should be triggered before or after the actual device-specific call is
+made. We trigger them after.
+
+Remarks about data provided to callbacks:
+
+@table @asis
+
+@item @code{acc_prof_info.event_type}
+It's not clear if for @emph{nested} event callbacks (for example,
+@code{acc_ev_enqueue_launch_start} as part of a parent compute
+construct), this should be set for the nested event
+(@code{acc_ev_enqueue_launch_start}), or if the value of the parent
+construct should remain (@code{acc_ev_compute_construct_start}). In
+this implementation, the value will generally correspond to the
+innermost nested event type.
+
+@item @code{acc_prof_info.device_type}
+@itemize
+
+@item
+For @code{acc_ev_compute_construct_start}, and in presence of an
+@code{if} clause with @emph{false} argument, this will still refer to
+the offloading device type.
+It's not clear if that's the expected behavior.
+
+@item
+Complementary to the item before, for
+@code{acc_ev_compute_construct_end}, this is set to
+@code{acc_device_host} in presence of an @code{if} clause with
+@emph{false} argument.
+It's not clear if that's the expected behavior.
+
+@end itemize
+
+@item @code{acc_prof_info.thread_id}
+Always @code{-1}; not yet implemented.
+
+@item @code{acc_prof_info.async}
+@itemize
+
+@item
+Not yet implemented correctly for
+@code{acc_ev_compute_construct_start}.
+
+@item
+In a compute construct, for host-fallback
+execution/@code{acc_device_host} it will always be
+@code{acc_async_sync}.
+It's not clear if that's the expected behavior.
+
+@item
+For @code{acc_ev_device_init_start} and @code{acc_ev_device_init_end},
+it will always be @code{acc_async_sync}.
+It's not clear if that's the expected behavior.
+
+@end itemize
+
+@item @code{acc_prof_info.async_queue}
+There is no @cite{limited number of asynchronous queues} in libgomp.
+This will always have the same value as @code{acc_prof_info.async}.
+
+@item @code{acc_prof_info.src_file}
+Always @code{NULL}; not yet implemented.
+
+@item @code{acc_prof_info.func_name}
+Always @code{NULL}; not yet implemented.
+
+@item @code{acc_prof_info.line_no}
+Always @code{-1}; not yet implemented.
+
+@item @code{acc_prof_info.end_line_no}
+Always @code{-1}; not yet implemented.
+
+@item @code{acc_prof_info.func_line_no}
+Always @code{-1}; not yet implemented.
+
+@item @code{acc_prof_info.func_end_line_no}
+Always @code{-1}; not yet implemented.
+
+@item @code{acc_event_info.event_type}, @code{acc_event_info.*.event_type}
+Relating to @code{acc_prof_info.event_type} discussed above, in this
+implementation, this will always be the same value as
+@code{acc_prof_info.event_type}.
+
+@item @code{acc_event_info.*.parent_construct}
+@itemize
+
+@item
+Will be @code{acc_construct_parallel} for all OpenACC compute
+constructs as well as many OpenACC Runtime API calls; should be the
+one matching the actual construct, or
+@code{acc_construct_runtime_api}, respectively.
+
+@item
+Will be @code{acc_construct_enter_data} or
+@code{acc_construct_exit_data} when processing variable mappings
+specified in OpenACC @emph{declare} directives; should be
+@code{acc_construct_declare}.
+
+@item
+For implicit @code{acc_ev_device_init_start},
+@code{acc_ev_device_init_end}, and explicit as well as implicit
+@code{acc_ev_alloc}, @code{acc_ev_free},
+@code{acc_ev_enqueue_upload_start}, @code{acc_ev_enqueue_upload_end},
+@code{acc_ev_enqueue_download_start}, and
+@code{acc_ev_enqueue_download_end}, will be
+@code{acc_construct_parallel}; should reflect the real parent
+construct.
+
+@end itemize
+
+@item @code{acc_event_info.*.implicit}
+For @code{acc_ev_alloc}, @code{acc_ev_free},
+@code{acc_ev_enqueue_upload_start}, @code{acc_ev_enqueue_upload_end},
+@code{acc_ev_enqueue_download_start}, and
+@code{acc_ev_enqueue_download_end}, this currently will be @code{1}
+also for explicit usage.
+
+@item @code{acc_event_info.data_event.var_name}
+Always @code{NULL}; not yet implemented.
+
+@item @code{acc_event_info.data_event.host_ptr}
+For @code{acc_ev_alloc}, and @code{acc_ev_free}, this is always
+@code{NULL}.
+
+@item @code{typedef union acc_api_info}
+@dots{} as printed in @cite{5.2.3. Third Argument: API-Specific
+Information}. This should obviously be @code{typedef @emph{struct}
+acc_api_info}.
+
+@item @code{acc_api_info.device_api}
+Possibly not yet implemented correctly for
+@code{acc_ev_compute_construct_start},
+@code{acc_ev_device_init_start}, @code{acc_ev_device_init_end}:
+will always be @code{acc_device_api_none} for these event types.
+For @code{acc_ev_enter_data_start}, it will be
+@code{acc_device_api_none} in some cases.
+
+@item @code{acc_api_info.device_type}
+Always the same as @code{acc_prof_info.device_type}.
+
+@item @code{acc_api_info.vendor}
+Always @code{-1}; not yet implemented.
+
+@item @code{acc_api_info.device_handle}
+Always @code{NULL}; not yet implemented.
+
+@item @code{acc_api_info.context_handle}
+Always @code{NULL}; not yet implemented.
+
+@item @code{acc_api_info.async_handle}
+Always @code{NULL}; not yet implemented.
+
+@end table
+
+Remarks about certain event types:
+
+@table @asis
+
+@item @code{acc_ev_device_init_start}, @code{acc_ev_device_init_end}
+@itemize
+
+@item
+@c See 'DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT' in
+@c 'libgomp.oacc-c-c++-common/acc_prof-kernels-1.c',
+@c 'libgomp.oacc-c-c++-common/acc_prof-parallel-1.c'.
+Whan a compute construct triggers implicit
+@code{acc_ev_device_init_start} and @code{acc_ev_device_init_end}
+events, they currently aren't @emph{nested within} the corresponding
+@code{acc_ev_compute_construct_start} and
+@code{acc_ev_compute_construct_end}, but they're currently observed
+@emph{before} @code{acc_ev_compute_construct_start}.
+It's not clear what to do: the standard asks us provide a lot of
+details to the @code{acc_ev_compute_construct_start} callback, without
+(implicitly) initializing a device before?
+
+@item
+Callbacks for these event types will not be invoked for calls to the
+@code{acc_set_device_type} and @code{acc_set_device_num} functions.
+It's not clear if they should be.
+
+@end itemize
+
+@item @code{acc_ev_enter_data_start}, @code{acc_ev_enter_data_end}, @code{acc_ev_exit_data_start}, @code{acc_ev_exit_data_end}
+@itemize
+
+@item
+Callbacks for these event types will also be invoked for OpenACC
+@emph{host_data} constructs.
+It's not clear if they should be.
+
+@item
+Callbacks for these event types will also be invoked when processing
+variable mappings specified in OpenACC @emph{declare} directives.
+It's not clear if they should be.
+
+@end itemize
+
+@end table
+
+Callbacks for the following event types will be invoked, but dispatch
+and information provided therein has not yet been thoroughly reviewed:
+
+@itemize
+@item @code{acc_ev_alloc}
+@item @code{acc_ev_free}
+@item @code{acc_ev_update_start}, @code{acc_ev_update_end}
+@item @code{acc_ev_enqueue_upload_start}, @code{acc_ev_enqueue_upload_end}
+@item @code{acc_ev_enqueue_download_start}, @code{acc_ev_enqueue_download_end}
+@end itemize
+
+During device initialization, and finalization, respectively,
+callbacks for the following event types will not yet be invoked:
+
+@itemize
+@item @code{acc_ev_alloc}
+@item @code{acc_ev_free}
+@end itemize
+
+Callbacks for the following event types have not yet been implemented,
+so currently won't be invoked:
+
+@itemize
+@item @code{acc_ev_device_shutdown_start}, @code{acc_ev_device_shutdown_end}
+@item @code{acc_ev_runtime_shutdown}
+@item @code{acc_ev_create}, @code{acc_ev_delete}
+@item @code{acc_ev_wait_start}, @code{acc_ev_wait_end}
+@end itemize
+
+For the following runtime library functions, not all expected
+callbacks will be invoked (mostly concerning implicit device
+initialization):
+
+@itemize
+@item @code{acc_get_num_devices}
+@item @code{acc_set_device_type}
+@item @code{acc_get_device_type}
+@item @code{acc_set_device_num}
+@item @code{acc_get_device_num}
+@item @code{acc_init}
+@item @code{acc_shutdown}
+@end itemize
+
+Aside from implicit device initialization, for the following runtime
+library functions, no callbacks will be invoked for shared-memory
+offloading devices (it's not clear if they should be):
+
+@itemize
+@item @code{acc_malloc}
+@item @code{acc_free}
+@item @code{acc_copyin}, @code{acc_present_or_copyin}, @code{acc_copyin_async}
+@item @code{acc_create}, @code{acc_present_or_create}, @code{acc_create_async}
+@item @code{acc_copyout}, @code{acc_copyout_async}, @code{acc_copyout_finalize}, @code{acc_copyout_finalize_async}
+@item @code{acc_delete}, @code{acc_delete_async}, @code{acc_delete_finalize}, @code{acc_delete_finalize_async}
+@item @code{acc_update_device}, @code{acc_update_device_async}
+@item @code{acc_update_self}, @code{acc_update_self_async}
+@item @code{acc_map_data}, @code{acc_unmap_data}
+@item @code{acc_memcpy_to_device}, @code{acc_memcpy_to_device_async}
+@item @code{acc_memcpy_from_device}, @code{acc_memcpy_from_device_async}
+@end itemize
+
+
+
+@c ---------------------------------------------------------------------
@c The libgomp ABI
@c ---------------------------------------------------------------------
diff --git a/libgomp/libgomp_f.h.in b/libgomp/libgomp_f.h.in
index a27da78b58a..4fa1dab9173 100644
--- a/libgomp/libgomp_f.h.in
+++ b/libgomp/libgomp_f.h.in
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h
index c99b5129f70..dfb55fb66dc 100644
--- a/libgomp/libgomp_g.h
+++ b/libgomp/libgomp_g.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -31,6 +31,7 @@
#include <stdbool.h>
#include <stddef.h>
+#include <stdint.h>
/* barrier.c */
@@ -56,6 +57,12 @@ extern bool GOMP_loop_nonmonotonic_dynamic_start (long, long, long, long,
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_start (long, long, long, long, long, long *, long *,
+ uintptr_t *, void **);
extern bool GOMP_loop_ordered_static_start (long, long, long, long,
long *, long *);
@@ -64,6 +71,8 @@ extern bool GOMP_loop_ordered_dynamic_start (long, long, long, long,
extern bool GOMP_loop_ordered_guided_start (long, long, long, long,
long *, long *);
extern bool GOMP_loop_ordered_runtime_start (long, long, long, long *, long *);
+extern bool GOMP_loop_ordered_start (long, long, long, long, long, long *,
+ long *, uintptr_t *, void **);
extern bool GOMP_loop_static_next (long *, long *);
extern bool GOMP_loop_dynamic_next (long *, long *);
@@ -71,6 +80,8 @@ extern bool GOMP_loop_guided_next (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 *);
@@ -85,6 +96,8 @@ extern bool GOMP_loop_doacross_guided_start (unsigned, long *, long, long *,
long *);
extern bool GOMP_loop_doacross_runtime_start (unsigned, long *, long *,
long *);
+extern bool GOMP_loop_doacross_start (unsigned, long *, long, long, long *,
+ long *, uintptr_t *, void **);
extern void GOMP_parallel_loop_static_start (void (*)(void *), void *,
unsigned, long, long, long, long);
@@ -112,6 +125,13 @@ extern void GOMP_parallel_loop_nonmonotonic_dynamic (void (*)(void *), void *,
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);
@@ -154,6 +174,21 @@ extern bool GOMP_loop_ull_nonmonotonic_guided_start (bool, unsigned long long,
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_start (bool, unsigned long long, unsigned long long,
+ unsigned long long, long, unsigned long long,
+ unsigned long long *, unsigned long long *,
+ uintptr_t *, void **);
extern bool GOMP_loop_ull_ordered_static_start (bool, unsigned long long,
unsigned long long,
@@ -178,6 +213,13 @@ extern bool GOMP_loop_ull_ordered_runtime_start (bool, unsigned long long,
unsigned long long,
unsigned long long *,
unsigned long long *);
+extern bool GOMP_loop_ull_ordered_start (bool, unsigned long long,
+ unsigned long long,
+ unsigned long long, long,
+ unsigned long long,
+ unsigned long long *,
+ unsigned long long *,
+ uintptr_t *, void **);
extern bool GOMP_loop_ull_static_next (unsigned long long *,
unsigned long long *);
@@ -191,6 +233,10 @@ extern bool GOMP_loop_ull_nonmonotonic_dynamic_next (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 *);
@@ -220,6 +266,11 @@ extern bool GOMP_loop_ull_doacross_runtime_start (unsigned,
unsigned long long *,
unsigned long long *,
unsigned long long *);
+extern bool GOMP_loop_ull_doacross_start (unsigned, unsigned long long *,
+ long, unsigned long long,
+ unsigned long long *,
+ unsigned long long *,
+ uintptr_t *, void **);
/* ordered.c */
@@ -235,6 +286,8 @@ extern void GOMP_doacross_ull_wait (unsigned long long, ...);
extern void GOMP_parallel_start (void (*) (void *), void *, unsigned);
extern void GOMP_parallel_end (void);
extern void GOMP_parallel (void (*) (void *), void *, unsigned, unsigned);
+extern unsigned GOMP_parallel_reductions (void (*) (void *), void *, unsigned,
+ unsigned);
extern bool GOMP_cancel (int, bool);
extern bool GOMP_cancellation_point (int);
@@ -251,13 +304,19 @@ extern void GOMP_taskloop_ull (void (*) (void *), void *,
unsigned long long, unsigned long long,
unsigned long long);
extern void GOMP_taskwait (void);
+extern void GOMP_taskwait_depend (void **);
extern void GOMP_taskyield (void);
extern void GOMP_taskgroup_start (void);
extern void GOMP_taskgroup_end (void);
+extern void GOMP_taskgroup_reduction_register (uintptr_t *);
+extern void GOMP_taskgroup_reduction_unregister (uintptr_t *);
+extern void GOMP_task_reduction_remap (size_t, size_t, void **);
+extern void GOMP_workshare_task_reduction_unregister (bool);
/* sections.c */
extern unsigned GOMP_sections_start (unsigned);
+extern unsigned GOMP_sections2_start (unsigned, uintptr_t *, void **);
extern unsigned GOMP_sections_next (void);
extern void GOMP_parallel_sections_start (void (*) (void *), void *,
unsigned, unsigned);
@@ -293,6 +352,11 @@ extern void GOMP_target_enter_exit_data (int, size_t, void **, size_t *,
void **);
extern void GOMP_teams (unsigned int, unsigned int);
+/* teams.c */
+
+extern void GOMP_teams_reg (void (*) (void *), void *, unsigned, unsigned,
+ unsigned);
+
/* oacc-parallel.c */
extern void GOACC_parallel_keyed (int, void (*) (void *), size_t,
diff --git a/libgomp/lock.c b/libgomp/lock.c
index 09597a1e559..5fcdb1454ef 100644
--- a/libgomp/lock.c
+++ b/libgomp/lock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/loop.c b/libgomp/loop.c
index a8c7e246333..37861d1d4f3 100644
--- a/libgomp/loop.c
+++ b/libgomp/loop.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -27,9 +27,13 @@
#include <limits.h>
#include <stdlib.h>
+#include <string.h>
#include "libgomp.h"
+ialias (GOMP_loop_runtime_next)
+ialias_redirect (GOMP_taskgroup_reduction_register)
+
/* Initialize the given work share construct from the given arguments. */
static inline void
@@ -79,12 +83,12 @@ gomp_loop_init (struct gomp_work_share *ws, long start, long end, long incr,
}
/* 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.
@@ -101,7 +105,7 @@ gomp_loop_static_start (long start, long end, long incr, long chunk_size,
struct gomp_thread *thr = gomp_thread ();
thr->ts.static_trip = 0;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_init (thr->ts.work_share, start, end, incr,
GFS_STATIC, chunk_size);
@@ -123,7 +127,7 @@ gomp_loop_dynamic_start (long start, long end, long incr, long chunk_size,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_init (thr->ts.work_share, start, end, incr,
GFS_DYNAMIC, chunk_size);
@@ -151,7 +155,7 @@ gomp_loop_guided_start (long start, long end, long incr, long chunk_size,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_init (thr->ts.work_share, start, end, incr,
GFS_GUIDED, chunk_size);
@@ -174,7 +178,7 @@ GOMP_loop_runtime_start (long start, long end, long 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_static_start (start, end, incr,
@@ -197,6 +201,114 @@ GOMP_loop_runtime_start (long start, long end, long incr,
}
}
+static long
+gomp_adjust_sched (long sched, long *chunk_size)
+{
+ sched &= ~GFS_MONOTONIC;
+ switch (sched)
+ {
+ case GFS_STATIC:
+ case GFS_DYNAMIC:
+ case GFS_GUIDED:
+ return sched;
+ /* GFS_RUNTIME is used for runtime schedule without monotonic
+ or nonmonotonic modifiers on the clause.
+ GFS_RUNTIME|GFS_MONOTONIC for runtime schedule with monotonic
+ modifier. */
+ case GFS_RUNTIME:
+ /* GFS_AUTO is used for runtime schedule with nonmonotonic
+ modifier. */
+ case GFS_AUTO:
+ {
+ struct gomp_task_icv *icv = gomp_icv (false);
+ sched = icv->run_sched_var & ~GFS_MONOTONIC;
+ switch (sched)
+ {
+ case GFS_STATIC:
+ case GFS_DYNAMIC:
+ case GFS_GUIDED:
+ *chunk_size = icv->run_sched_chunk_size;
+ break;
+ case GFS_AUTO:
+ sched = GFS_STATIC;
+ *chunk_size = 0;
+ break;
+ default:
+ abort ();
+ }
+ return sched;
+ }
+ default:
+ abort ();
+ }
+}
+
+bool
+GOMP_loop_start (long start, long end, long incr, long sched,
+ long chunk_size, long *istart, long *iend,
+ uintptr_t *reductions, void **mem)
+{
+ struct gomp_thread *thr = gomp_thread ();
+
+ thr->ts.static_trip = 0;
+ if (reductions)
+ gomp_workshare_taskgroup_start ();
+ if (gomp_work_share_start (0))
+ {
+ sched = gomp_adjust_sched (sched, &chunk_size);
+ gomp_loop_init (thr->ts.work_share, start, end, incr,
+ sched, chunk_size);
+ if (reductions)
+ {
+ GOMP_taskgroup_reduction_register (reductions);
+ thr->task->taskgroup->workshare = true;
+ thr->ts.work_share->task_reductions = reductions;
+ }
+ if (mem)
+ {
+ uintptr_t size = (uintptr_t) *mem;
+#define INLINE_ORDERED_TEAM_IDS_OFF \
+ ((offsetof (struct gomp_work_share, inline_ordered_team_ids) \
+ + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
+ if (size > (sizeof (struct gomp_work_share)
+ - INLINE_ORDERED_TEAM_IDS_OFF))
+ *mem
+ = (void *) (thr->ts.work_share->ordered_team_ids
+ = gomp_malloc_cleared (size));
+ else
+ *mem = memset (((char *) thr->ts.work_share)
+ + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
+ }
+ gomp_work_share_init_done ();
+ }
+ else
+ {
+ if (reductions)
+ {
+ uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
+ gomp_workshare_task_reduction_register (reductions,
+ first_reductions);
+ }
+ if (mem)
+ {
+ if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+ & (__alignof__ (long long) - 1)) == 0)
+ *mem = (void *) thr->ts.work_share->ordered_team_ids;
+ else
+ {
+ uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
+ p += __alignof__ (long long) - 1;
+ p &= ~(__alignof__ (long long) - 1);
+ *mem = (void *) p;
+ }
+ }
+ }
+
+ if (!istart)
+ return true;
+ return ialias_call (GOMP_loop_runtime_next) (istart, iend);
+}
+
/* The *_ordered_*_start routines are similar. The only difference is that
this work-share construct is initialized to expect an ORDERED section. */
@@ -207,7 +319,7 @@ gomp_loop_ordered_static_start (long start, long end, long incr,
struct gomp_thread *thr = gomp_thread ();
thr->ts.static_trip = 0;
- if (gomp_work_share_start (true))
+ if (gomp_work_share_start (1))
{
gomp_loop_init (thr->ts.work_share, start, end, incr,
GFS_STATIC, chunk_size);
@@ -225,7 +337,7 @@ gomp_loop_ordered_dynamic_start (long start, long end, long incr,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (true))
+ if (gomp_work_share_start (1))
{
gomp_loop_init (thr->ts.work_share, start, end, incr,
GFS_DYNAMIC, chunk_size);
@@ -250,7 +362,7 @@ gomp_loop_ordered_guided_start (long start, long end, long incr,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (true))
+ if (gomp_work_share_start (1))
{
gomp_loop_init (thr->ts.work_share, start, end, incr,
GFS_GUIDED, chunk_size);
@@ -273,7 +385,7 @@ GOMP_loop_ordered_runtime_start (long start, long end, long 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,
@@ -297,6 +409,81 @@ GOMP_loop_ordered_runtime_start (long start, long end, long incr,
}
}
+bool
+GOMP_loop_ordered_start (long start, long end, long incr, long sched,
+ long chunk_size, long *istart, long *iend,
+ uintptr_t *reductions, void **mem)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ size_t ordered = 1;
+ bool ret;
+
+ thr->ts.static_trip = 0;
+ if (reductions)
+ gomp_workshare_taskgroup_start ();
+ if (mem)
+ ordered += (uintptr_t) *mem;
+ if (gomp_work_share_start (ordered))
+ {
+ sched = gomp_adjust_sched (sched, &chunk_size);
+ gomp_loop_init (thr->ts.work_share, start, end, incr,
+ sched, chunk_size);
+ if (reductions)
+ {
+ GOMP_taskgroup_reduction_register (reductions);
+ thr->task->taskgroup->workshare = true;
+ thr->ts.work_share->task_reductions = reductions;
+ }
+ if (sched == GFS_STATIC)
+ gomp_ordered_static_init ();
+ else
+ gomp_mutex_lock (&thr->ts.work_share->lock);
+ gomp_work_share_init_done ();
+ }
+ else
+ {
+ if (reductions)
+ {
+ uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
+ gomp_workshare_task_reduction_register (reductions,
+ first_reductions);
+ }
+ sched = thr->ts.work_share->sched;
+ if (sched != GFS_STATIC)
+ gomp_mutex_lock (&thr->ts.work_share->lock);
+ }
+
+ if (mem)
+ {
+ uintptr_t p
+ = (uintptr_t) (thr->ts.work_share->ordered_team_ids
+ + (thr->ts.team ? thr->ts.team->nthreads : 1));
+ p += __alignof__ (long long) - 1;
+ p &= ~(__alignof__ (long long) - 1);
+ *mem = (void *) p;
+ }
+
+ switch (sched)
+ {
+ case GFS_STATIC:
+ case GFS_AUTO:
+ return !gomp_iter_static_next (istart, iend);
+ case GFS_DYNAMIC:
+ ret = gomp_iter_dynamic_next_locked (istart, iend);
+ break;
+ case GFS_GUIDED:
+ ret = gomp_iter_guided_next_locked (istart, iend);
+ break;
+ default:
+ abort ();
+ }
+
+ if (ret)
+ gomp_ordered_first ();
+ gomp_mutex_unlock (&thr->ts.work_share->lock);
+ return ret;
+}
+
/* The *_doacross_*_start routines are similar. The only difference is that
this work-share construct is initialized to expect an ORDERED(N) - DOACROSS
section, and the worksharing loop iterates always from 0 to COUNTS[0] - 1
@@ -310,11 +497,11 @@ gomp_loop_doacross_static_start (unsigned ncounts, long *counts,
struct gomp_thread *thr = gomp_thread ();
thr->ts.static_trip = 0;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_init (thr->ts.work_share, 0, counts[0], 1,
GFS_STATIC, chunk_size);
- gomp_doacross_init (ncounts, counts, chunk_size);
+ gomp_doacross_init (ncounts, counts, chunk_size, 0);
gomp_work_share_init_done ();
}
@@ -328,11 +515,11 @@ gomp_loop_doacross_dynamic_start (unsigned ncounts, long *counts,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_init (thr->ts.work_share, 0, counts[0], 1,
GFS_DYNAMIC, chunk_size);
- gomp_doacross_init (ncounts, counts, chunk_size);
+ gomp_doacross_init (ncounts, counts, chunk_size, 0);
gomp_work_share_init_done ();
}
@@ -354,11 +541,11 @@ gomp_loop_doacross_guided_start (unsigned ncounts, long *counts,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_init (thr->ts.work_share, 0, counts[0], 1,
GFS_GUIDED, chunk_size);
- gomp_doacross_init (ncounts, counts, chunk_size);
+ gomp_doacross_init (ncounts, counts, chunk_size, 0);
gomp_work_share_init_done ();
}
@@ -378,7 +565,7 @@ GOMP_loop_doacross_runtime_start (unsigned ncounts, long *counts,
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,
@@ -402,8 +589,52 @@ GOMP_loop_doacross_runtime_start (unsigned ncounts, long *counts,
}
}
-/* The *_next routines are called when the thread completes processing of
- the iteration block currently assigned to it. If the work-share
+bool
+GOMP_loop_doacross_start (unsigned ncounts, long *counts, long sched,
+ long chunk_size, long *istart, long *iend,
+ uintptr_t *reductions, void **mem)
+{
+ struct gomp_thread *thr = gomp_thread ();
+
+ thr->ts.static_trip = 0;
+ if (reductions)
+ gomp_workshare_taskgroup_start ();
+ if (gomp_work_share_start (0))
+ {
+ size_t extra = 0;
+ if (mem)
+ extra = (uintptr_t) *mem;
+ sched = gomp_adjust_sched (sched, &chunk_size);
+ gomp_loop_init (thr->ts.work_share, 0, counts[0], 1,
+ sched, chunk_size);
+ gomp_doacross_init (ncounts, counts, chunk_size, extra);
+ if (reductions)
+ {
+ GOMP_taskgroup_reduction_register (reductions);
+ thr->task->taskgroup->workshare = true;
+ thr->ts.work_share->task_reductions = reductions;
+ }
+ gomp_work_share_init_done ();
+ }
+ else
+ {
+ if (reductions)
+ {
+ uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
+ gomp_workshare_task_reduction_register (reductions,
+ first_reductions);
+ }
+ sched = thr->ts.work_share->sched;
+ }
+
+ if (mem)
+ *mem = thr->ts.work_share->doacross->extra;
+
+ return ialias_call (GOMP_loop_runtime_next) (istart, iend);
+}
+
+/* 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.
@@ -456,7 +687,7 @@ bool
GOMP_loop_runtime_next (long *istart, long *iend)
{
struct gomp_thread *thr = gomp_thread ();
-
+
switch (thr->ts.work_share->sched)
{
case GFS_STATIC:
@@ -534,7 +765,7 @@ bool
GOMP_loop_ordered_runtime_next (long *istart, long *iend)
{
struct gomp_thread *thr = gomp_thread ();
-
+
switch (thr->ts.work_share->sched)
{
case GFS_STATIC:
@@ -563,7 +794,7 @@ gomp_parallel_loop_start (void (*fn) (void *), void *data,
num_threads = gomp_resolve_num_threads (num_threads, 0);
team = gomp_new_team (num_threads);
gomp_loop_init (&team->work_shares[0], start, end, incr, sched, chunk_size);
- gomp_team_start (fn, data, num_threads, flags, team);
+ gomp_team_start (fn, data, num_threads, flags, team, NULL);
}
void
@@ -600,7 +831,8 @@ GOMP_parallel_loop_runtime_start (void (*fn) (void *), void *data,
{
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)
@@ -638,11 +870,28 @@ GOMP_parallel_loop_guided (void (*fn) (void *), void *data,
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,
@@ -667,21 +916,35 @@ GOMP_parallel_loop_nonmonotonic_guided (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. */
@@ -721,6 +984,10 @@ extern __typeof(gomp_loop_dynamic_start) GOMP_loop_nonmonotonic_dynamic_start
__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")));
@@ -746,6 +1013,10 @@ extern __typeof(gomp_loop_dynamic_next) GOMP_loop_nonmonotonic_dynamic_next
__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")));
@@ -791,6 +1062,20 @@ GOMP_loop_nonmonotonic_guided_start (long start, long end, long incr,
}
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)
{
@@ -869,6 +1154,18 @@ GOMP_loop_nonmonotonic_guided_next (long *istart, long *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)
{
return gomp_loop_ordered_static_next (istart, iend);
diff --git a/libgomp/loop_ull.c b/libgomp/loop_ull.c
index 3d4ac994f0a..edf1c323f29 100644
--- a/libgomp/loop_ull.c
+++ b/libgomp/loop_ull.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -27,8 +27,12 @@
#include <limits.h>
#include <stdlib.h>
+#include <string.h>
#include "libgomp.h"
+ialias (GOMP_loop_ull_runtime_next)
+ialias_redirect (GOMP_taskgroup_reduction_register)
+
typedef unsigned long long gomp_ull;
/* Initialize the given work share construct from the given arguments. */
@@ -104,7 +108,7 @@ gomp_loop_ull_static_start (bool up, gomp_ull start, gomp_ull end,
struct gomp_thread *thr = gomp_thread ();
thr->ts.static_trip = 0;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
GFS_STATIC, chunk_size);
@@ -122,7 +126,7 @@ gomp_loop_ull_dynamic_start (bool up, gomp_ull start, gomp_ull end,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
GFS_DYNAMIC, chunk_size);
@@ -148,7 +152,7 @@ gomp_loop_ull_guided_start (bool up, gomp_ull start, gomp_ull end,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
GFS_GUIDED, chunk_size);
@@ -171,7 +175,7 @@ GOMP_loop_ull_runtime_start (bool up, gomp_ull start, gomp_ull end,
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,
@@ -195,6 +199,113 @@ GOMP_loop_ull_runtime_start (bool up, gomp_ull start, gomp_ull end,
}
}
+static long
+gomp_adjust_sched (long sched, gomp_ull *chunk_size)
+{
+ sched &= ~GFS_MONOTONIC;
+ switch (sched)
+ {
+ case GFS_STATIC:
+ case GFS_DYNAMIC:
+ case GFS_GUIDED:
+ return sched;
+ /* GFS_RUNTIME is used for runtime schedule without monotonic
+ or nonmonotonic modifiers on the clause.
+ GFS_RUNTIME|GFS_MONOTONIC for runtime schedule with monotonic
+ modifier. */
+ case GFS_RUNTIME:
+ /* GFS_AUTO is used for runtime schedule with nonmonotonic
+ modifier. */
+ case GFS_AUTO:
+ {
+ struct gomp_task_icv *icv = gomp_icv (false);
+ sched = icv->run_sched_var & ~GFS_MONOTONIC;
+ switch (sched)
+ {
+ case GFS_STATIC:
+ case GFS_DYNAMIC:
+ case GFS_GUIDED:
+ *chunk_size = icv->run_sched_chunk_size;
+ break;
+ case GFS_AUTO:
+ sched = GFS_STATIC;
+ *chunk_size = 0;
+ break;
+ default:
+ abort ();
+ }
+ return sched;
+ }
+ default:
+ abort ();
+ }
+}
+
+bool
+GOMP_loop_ull_start (bool up, gomp_ull start, gomp_ull end,
+ gomp_ull incr, long sched, gomp_ull chunk_size,
+ gomp_ull *istart, gomp_ull *iend,
+ uintptr_t *reductions, void **mem)
+{
+ struct gomp_thread *thr = gomp_thread ();
+
+ thr->ts.static_trip = 0;
+ if (reductions)
+ gomp_workshare_taskgroup_start ();
+ if (gomp_work_share_start (0))
+ {
+ sched = gomp_adjust_sched (sched, &chunk_size);
+ gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
+ sched, chunk_size);
+ if (reductions)
+ {
+ GOMP_taskgroup_reduction_register (reductions);
+ thr->task->taskgroup->workshare = true;
+ thr->ts.work_share->task_reductions = reductions;
+ }
+ if (mem)
+ {
+ uintptr_t size = (uintptr_t) *mem;
+#define INLINE_ORDERED_TEAM_IDS_OFF \
+ ((offsetof (struct gomp_work_share, inline_ordered_team_ids) \
+ + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
+ if (size > (sizeof (struct gomp_work_share)
+ - INLINE_ORDERED_TEAM_IDS_OFF))
+ *mem
+ = (void *) (thr->ts.work_share->ordered_team_ids
+ = gomp_malloc_cleared (size));
+ else
+ *mem = memset (((char *) thr->ts.work_share)
+ + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
+ }
+ gomp_work_share_init_done ();
+ }
+ else
+ {
+ if (reductions)
+ {
+ uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
+ gomp_workshare_task_reduction_register (reductions,
+ first_reductions);
+ }
+ if (mem)
+ {
+ if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+ & (__alignof__ (long long) - 1)) == 0)
+ *mem = (void *) thr->ts.work_share->ordered_team_ids;
+ else
+ {
+ uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
+ p += __alignof__ (long long) - 1;
+ p &= ~(__alignof__ (long long) - 1);
+ *mem = (void *) p;
+ }
+ }
+ }
+
+ return ialias_call (GOMP_loop_ull_runtime_next) (istart, iend);
+}
+
/* The *_ordered_*_start routines are similar. The only difference is that
this work-share construct is initialized to expect an ORDERED section. */
@@ -206,7 +317,7 @@ gomp_loop_ull_ordered_static_start (bool up, gomp_ull start, gomp_ull end,
struct gomp_thread *thr = gomp_thread ();
thr->ts.static_trip = 0;
- if (gomp_work_share_start (true))
+ if (gomp_work_share_start (1))
{
gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
GFS_STATIC, chunk_size);
@@ -225,7 +336,7 @@ gomp_loop_ull_ordered_dynamic_start (bool up, gomp_ull start, gomp_ull end,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (true))
+ if (gomp_work_share_start (1))
{
gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
GFS_DYNAMIC, chunk_size);
@@ -251,7 +362,7 @@ gomp_loop_ull_ordered_guided_start (bool up, gomp_ull start, gomp_ull end,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (true))
+ if (gomp_work_share_start (1))
{
gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
GFS_GUIDED, chunk_size);
@@ -275,7 +386,7 @@ GOMP_loop_ull_ordered_runtime_start (bool up, gomp_ull start, gomp_ull end,
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,
@@ -299,6 +410,82 @@ GOMP_loop_ull_ordered_runtime_start (bool up, gomp_ull start, gomp_ull end,
}
}
+bool
+GOMP_loop_ull_ordered_start (bool up, gomp_ull start, gomp_ull end,
+ gomp_ull incr, long sched, gomp_ull chunk_size,
+ gomp_ull *istart, gomp_ull *iend,
+ uintptr_t *reductions, void **mem)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ size_t ordered = 1;
+ bool ret;
+
+ thr->ts.static_trip = 0;
+ if (reductions)
+ gomp_workshare_taskgroup_start ();
+ if (mem)
+ ordered += (uintptr_t) *mem;
+ if (gomp_work_share_start (ordered))
+ {
+ sched = gomp_adjust_sched (sched, &chunk_size);
+ gomp_loop_ull_init (thr->ts.work_share, up, start, end, incr,
+ sched, chunk_size);
+ if (reductions)
+ {
+ GOMP_taskgroup_reduction_register (reductions);
+ thr->task->taskgroup->workshare = true;
+ thr->ts.work_share->task_reductions = reductions;
+ }
+ if (sched == GFS_STATIC)
+ gomp_ordered_static_init ();
+ else
+ gomp_mutex_lock (&thr->ts.work_share->lock);
+ gomp_work_share_init_done ();
+ }
+ else
+ {
+ if (reductions)
+ {
+ uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
+ gomp_workshare_task_reduction_register (reductions,
+ first_reductions);
+ }
+ sched = thr->ts.work_share->sched;
+ if (sched != GFS_STATIC)
+ gomp_mutex_lock (&thr->ts.work_share->lock);
+ }
+
+ if (mem)
+ {
+ uintptr_t p
+ = (uintptr_t) (thr->ts.work_share->ordered_team_ids
+ + (thr->ts.team ? thr->ts.team->nthreads : 1));
+ p += __alignof__ (long long) - 1;
+ p &= ~(__alignof__ (long long) - 1);
+ *mem = (void *) p;
+ }
+
+ switch (sched)
+ {
+ case GFS_STATIC:
+ case GFS_AUTO:
+ return !gomp_iter_ull_static_next (istart, iend);
+ case GFS_DYNAMIC:
+ ret = gomp_iter_ull_dynamic_next_locked (istart, iend);
+ break;
+ case GFS_GUIDED:
+ ret = gomp_iter_ull_guided_next_locked (istart, iend);
+ break;
+ default:
+ abort ();
+ }
+
+ if (ret)
+ gomp_ordered_first ();
+ gomp_mutex_unlock (&thr->ts.work_share->lock);
+ return ret;
+}
+
/* The *_doacross_*_start routines are similar. The only difference is that
this work-share construct is initialized to expect an ORDERED(N) - DOACROSS
section, and the worksharing loop iterates always from 0 to COUNTS[0] - 1
@@ -313,11 +500,11 @@ gomp_loop_ull_doacross_static_start (unsigned ncounts, gomp_ull *counts,
struct gomp_thread *thr = gomp_thread ();
thr->ts.static_trip = 0;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_ull_init (thr->ts.work_share, true, 0, counts[0], 1,
GFS_STATIC, chunk_size);
- gomp_doacross_ull_init (ncounts, counts, chunk_size);
+ gomp_doacross_ull_init (ncounts, counts, chunk_size, 0);
gomp_work_share_init_done ();
}
@@ -332,11 +519,11 @@ gomp_loop_ull_doacross_dynamic_start (unsigned ncounts, gomp_ull *counts,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_ull_init (thr->ts.work_share, true, 0, counts[0], 1,
GFS_DYNAMIC, chunk_size);
- gomp_doacross_ull_init (ncounts, counts, chunk_size);
+ gomp_doacross_ull_init (ncounts, counts, chunk_size, 0);
gomp_work_share_init_done ();
}
@@ -359,11 +546,11 @@ gomp_loop_ull_doacross_guided_start (unsigned ncounts, gomp_ull *counts,
struct gomp_thread *thr = gomp_thread ();
bool ret;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_loop_ull_init (thr->ts.work_share, true, 0, counts[0], 1,
GFS_GUIDED, chunk_size);
- gomp_doacross_ull_init (ncounts, counts, chunk_size);
+ gomp_doacross_ull_init (ncounts, counts, chunk_size, 0);
gomp_work_share_init_done ();
}
@@ -383,7 +570,7 @@ GOMP_loop_ull_doacross_runtime_start (unsigned ncounts, gomp_ull *counts,
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,
@@ -407,6 +594,51 @@ GOMP_loop_ull_doacross_runtime_start (unsigned ncounts, gomp_ull *counts,
}
}
+bool
+GOMP_loop_ull_doacross_start (unsigned ncounts, gomp_ull *counts,
+ long sched, gomp_ull chunk_size,
+ gomp_ull *istart, gomp_ull *iend,
+ uintptr_t *reductions, void **mem)
+{
+ struct gomp_thread *thr = gomp_thread ();
+
+ thr->ts.static_trip = 0;
+ if (reductions)
+ gomp_workshare_taskgroup_start ();
+ if (gomp_work_share_start (0))
+ {
+ size_t extra = 0;
+ if (mem)
+ extra = (uintptr_t) *mem;
+ sched = gomp_adjust_sched (sched, &chunk_size);
+ gomp_loop_ull_init (thr->ts.work_share, true, 0, counts[0], 1,
+ sched, chunk_size);
+ gomp_doacross_ull_init (ncounts, counts, chunk_size, extra);
+ if (reductions)
+ {
+ GOMP_taskgroup_reduction_register (reductions);
+ thr->task->taskgroup->workshare = true;
+ thr->ts.work_share->task_reductions = reductions;
+ }
+ gomp_work_share_init_done ();
+ }
+ else
+ {
+ if (reductions)
+ {
+ uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
+ gomp_workshare_task_reduction_register (reductions,
+ first_reductions);
+ }
+ sched = thr->ts.work_share->sched;
+ }
+
+ if (mem)
+ *mem = thr->ts.work_share->doacross->extra;
+
+ return ialias_call (GOMP_loop_ull_runtime_next) (istart, iend);
+}
+
/* 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
@@ -570,6 +802,10 @@ extern __typeof(gomp_loop_ull_dynamic_start) GOMP_loop_ull_nonmonotonic_dynamic_
__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")));
@@ -595,6 +831,10 @@ extern __typeof(gomp_loop_ull_dynamic_next) GOMP_loop_ull_nonmonotonic_dynamic_n
__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")));
@@ -650,6 +890,23 @@ GOMP_loop_ull_nonmonotonic_guided_start (bool up, gomp_ull start, gomp_ull end,
}
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,
gomp_ull *istart, gomp_ull *iend)
@@ -734,6 +991,19 @@ GOMP_loop_ull_nonmonotonic_guided_next (gomp_ull *istart, gomp_ull *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)
{
return gomp_loop_ull_ordered_static_next (istart, iend);
diff --git a/libgomp/oacc-async.c b/libgomp/oacc-async.c
index a4e186386df..2b24ae7adc2 100644
--- a/libgomp/oacc-async.c
+++ b/libgomp/oacc-async.c
@@ -1,6 +1,6 @@
/* OpenACC Runtime Library Definitions.
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -27,47 +27,199 @@
<http://www.gnu.org/licenses/>. */
#include <assert.h>
+#include <string.h>
#include "openacc.h"
#include "libgomp.h"
#include "oacc-int.h"
-int
-acc_async_test (int async)
+static struct goacc_thread *
+get_goacc_thread (void)
{
- if (!async_valid_p (async))
- gomp_fatal ("invalid async argument: %d", async);
-
struct goacc_thread *thr = goacc_thread ();
if (!thr || !thr->dev)
gomp_fatal ("no device active");
- return thr->dev->openacc.async_test_func (async);
+ return thr;
+}
+
+static int
+validate_async_val (int async)
+{
+ if (!async_valid_p (async))
+ gomp_fatal ("invalid async-argument: %d", async);
+
+ if (async == acc_async_sync)
+ return -1;
+
+ if (async == acc_async_noval)
+ return 0;
+
+ if (async >= 0)
+ /* TODO: we reserve 0 for acc_async_noval before we can clarify the
+ semantics of "default_async". */
+ return 1 + async;
+ else
+ __builtin_unreachable ();
+}
+
+/* Return the asyncqueue to be used for OpenACC async-argument ASYNC. This
+ might return NULL if no asyncqueue is to be used. Otherwise, if CREATE,
+ create the asyncqueue if it doesn't exist yet.
+
+ Unless CREATE, this will not generate any OpenACC Profiling Interface
+ events. */
+
+attribute_hidden struct goacc_asyncqueue *
+lookup_goacc_asyncqueue (struct goacc_thread *thr, bool create, int async)
+{
+ async = validate_async_val (async);
+ if (async < 0)
+ return NULL;
+
+ struct goacc_asyncqueue *ret_aq = NULL;
+ struct gomp_device_descr *dev = thr->dev;
+
+ gomp_mutex_lock (&dev->openacc.async.lock);
+
+ if (!create
+ && (async >= dev->openacc.async.nasyncqueue
+ || !dev->openacc.async.asyncqueue[async]))
+ goto end;
+
+ if (async >= dev->openacc.async.nasyncqueue)
+ {
+ int diff = async + 1 - dev->openacc.async.nasyncqueue;
+ dev->openacc.async.asyncqueue
+ = gomp_realloc (dev->openacc.async.asyncqueue,
+ sizeof (goacc_aq) * (async + 1));
+ memset (dev->openacc.async.asyncqueue + dev->openacc.async.nasyncqueue,
+ 0, sizeof (goacc_aq) * diff);
+ dev->openacc.async.nasyncqueue = async + 1;
+ }
+
+ if (!dev->openacc.async.asyncqueue[async])
+ {
+ dev->openacc.async.asyncqueue[async]
+ = dev->openacc.async.construct_func (dev->target_id);
+
+ if (!dev->openacc.async.asyncqueue[async])
+ {
+ gomp_mutex_unlock (&dev->openacc.async.lock);
+ gomp_fatal ("async %d creation failed", async);
+ }
+
+ /* Link new async queue into active list. */
+ goacc_aq_list n = gomp_malloc (sizeof (struct goacc_asyncqueue_list));
+ n->aq = dev->openacc.async.asyncqueue[async];
+ n->next = dev->openacc.async.active;
+ dev->openacc.async.active = n;
+ }
+
+ ret_aq = dev->openacc.async.asyncqueue[async];
+
+ end:
+ gomp_mutex_unlock (&dev->openacc.async.lock);
+ return ret_aq;
+}
+
+/* Return the asyncqueue to be used for OpenACC async-argument ASYNC. This
+ might return NULL if no asyncqueue is to be used. Otherwise, create the
+ asyncqueue if it doesn't exist yet. */
+
+attribute_hidden struct goacc_asyncqueue *
+get_goacc_asyncqueue (int async)
+{
+ struct goacc_thread *thr = get_goacc_thread ();
+ return lookup_goacc_asyncqueue (thr, true, async);
}
int
-acc_async_test_all (void)
+acc_async_test (int async)
{
struct goacc_thread *thr = goacc_thread ();
if (!thr || !thr->dev)
gomp_fatal ("no device active");
- return thr->dev->openacc.async_test_all_func ();
+ goacc_aq aq = lookup_goacc_asyncqueue (thr, false, async);
+ if (!aq)
+ return 1;
+
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
+
+ int res = thr->dev->openacc.async.test_func (aq);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+
+ return res;
+}
+
+int
+acc_async_test_all (void)
+{
+ struct goacc_thread *thr = get_goacc_thread ();
+
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+
+ int ret = 1;
+ gomp_mutex_lock (&thr->dev->openacc.async.lock);
+ for (goacc_aq_list l = thr->dev->openacc.async.active; l; l = l->next)
+ if (!thr->dev->openacc.async.test_func (l->aq))
+ {
+ ret = 0;
+ break;
+ }
+ gomp_mutex_unlock (&thr->dev->openacc.async.lock);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+
+ return ret;
}
void
acc_wait (int async)
{
- if (!async_valid_p (async))
- gomp_fatal ("invalid async argument: %d", async);
+ struct goacc_thread *thr = get_goacc_thread ();
- struct goacc_thread *thr = goacc_thread ();
+ goacc_aq aq = lookup_goacc_asyncqueue (thr, false, async);
+ if (!aq)
+ return;
- if (!thr || !thr->dev)
- gomp_fatal ("no device active");
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
+
+ if (!thr->dev->openacc.async.synchronize_func (aq))
+ gomp_fatal ("wait on %d failed", async);
- thr->dev->openacc.async_wait_func (async);
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
/* acc_async_wait is an OpenACC 1.0 compatibility name for acc_wait. */
@@ -84,12 +236,47 @@ acc_async_wait (int async)
void
acc_wait_async (int async1, int async2)
{
- struct goacc_thread *thr = goacc_thread ();
+ struct goacc_thread *thr = get_goacc_thread ();
- if (!thr || !thr->dev)
- gomp_fatal ("no device active");
+ goacc_aq aq1 = lookup_goacc_asyncqueue (thr, false, async1);
+ /* TODO: Is this also correct for acc_async_sync, assuming that in this case,
+ we'll always be synchronous anyways? */
+ if (!aq1)
+ return;
+
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async2;
+ prof_info.async_queue = prof_info.async;
+ }
+
+ goacc_aq aq2 = lookup_goacc_asyncqueue (thr, true, async2);
+ /* An async queue is always synchronized with itself. */
+ if (aq1 == aq2)
+ goto out_prof;
- thr->dev->openacc.async_wait_async_func (async1, async2);
+ if (aq2)
+ {
+ if (!thr->dev->openacc.async.serialize_func (aq1, aq2))
+ gomp_fatal ("ordering of async ids %d and %d failed", async1, async2);
+ }
+ else
+ {
+ /* TODO: Local thread synchronization.
+ Necessary for the "async2 == acc_async_sync" case, or can just skip? */
+ if (!thr->dev->openacc.async.synchronize_func (aq1))
+ gomp_fatal ("wait on %d failed", async1);
+ }
+
+ out_prof:
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
void
@@ -97,10 +284,24 @@ acc_wait_all (void)
{
struct goacc_thread *thr = goacc_thread ();
- if (!thr || !thr->dev)
- gomp_fatal ("no device active");
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+
+ bool ret = true;
+ gomp_mutex_lock (&thr->dev->openacc.async.lock);
+ for (goacc_aq_list l = thr->dev->openacc.async.active; l; l = l->next)
+ ret &= thr->dev->openacc.async.synchronize_func (l->aq);
+ gomp_mutex_unlock (&thr->dev->openacc.async.lock);
- thr->dev->openacc.async_wait_all_func ();
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+
+ if (!ret)
+ gomp_fatal ("wait all failed");
}
/* acc_async_wait_all is an OpenACC 1.0 compatibility name for acc_wait_all. */
@@ -117,13 +318,88 @@ acc_async_wait_all (void)
void
acc_wait_all_async (int async)
{
- if (!async_valid_p (async))
- gomp_fatal ("invalid async argument: %d", async);
+ struct goacc_thread *thr = get_goacc_thread ();
- struct goacc_thread *thr = goacc_thread ();
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
- if (!thr || !thr->dev)
- gomp_fatal ("no device active");
+ goacc_aq waiting_queue = lookup_goacc_asyncqueue (thr, true, async);
+
+ bool ret = true;
+ gomp_mutex_lock (&thr->dev->openacc.async.lock);
+ for (goacc_aq_list l = thr->dev->openacc.async.active; l; l = l->next)
+ {
+ if (waiting_queue)
+ ret &= thr->dev->openacc.async.serialize_func (l->aq, waiting_queue);
+ else
+ /* TODO: Local thread synchronization.
+ Necessary for the "async2 == acc_async_sync" case, or can just skip? */
+ ret &= thr->dev->openacc.async.synchronize_func (l->aq);
+ }
+ gomp_mutex_unlock (&thr->dev->openacc.async.lock);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+
+ if (!ret)
+ gomp_fatal ("wait all async(%d) failed", async);
+}
- thr->dev->openacc.async_wait_all_async_func (async);
+attribute_hidden void
+goacc_async_free (struct gomp_device_descr *devicep,
+ struct goacc_asyncqueue *aq, void *ptr)
+{
+ if (!aq)
+ free (ptr);
+ else
+ devicep->openacc.async.queue_callback_func (aq, free, ptr);
+}
+
+/* This function initializes the asyncqueues for the device specified by
+ DEVICEP. TODO DEVICEP must be locked on entry, and remains locked on
+ return. */
+
+attribute_hidden void
+goacc_init_asyncqueues (struct gomp_device_descr *devicep)
+{
+ devicep->openacc.async.nasyncqueue = 0;
+ devicep->openacc.async.asyncqueue = NULL;
+ devicep->openacc.async.active = NULL;
+ gomp_mutex_init (&devicep->openacc.async.lock);
+}
+
+/* This function finalizes the asyncqueues for the device specified by DEVICEP.
+ TODO DEVICEP must be locked on entry, and remains locked on return. */
+
+attribute_hidden bool
+goacc_fini_asyncqueues (struct gomp_device_descr *devicep)
+{
+ bool ret = true;
+ gomp_mutex_lock (&devicep->openacc.async.lock);
+ if (devicep->openacc.async.nasyncqueue > 0)
+ {
+ goacc_aq_list next;
+ for (goacc_aq_list l = devicep->openacc.async.active; l; l = next)
+ {
+ ret &= devicep->openacc.async.destruct_func (l->aq);
+ next = l->next;
+ free (l);
+ }
+ free (devicep->openacc.async.asyncqueue);
+ devicep->openacc.async.nasyncqueue = 0;
+ devicep->openacc.async.asyncqueue = NULL;
+ devicep->openacc.async.active = NULL;
+ }
+ gomp_mutex_unlock (&devicep->openacc.async.lock);
+ gomp_mutex_destroy (&devicep->openacc.async.lock);
+ return ret;
}
diff --git a/libgomp/oacc-cuda.c b/libgomp/oacc-cuda.c
index 20774c1b487..7a42085c877 100644
--- a/libgomp/oacc-cuda.c
+++ b/libgomp/oacc-cuda.c
@@ -1,6 +1,6 @@
/* OpenACC Runtime Library: CUDA support glue.
- Copyright (C) 2014-2018 Free Software Foundation, Inc.
+ Copyright (C) 2014-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -27,19 +27,32 @@
<http://www.gnu.org/licenses/>. */
#include "openacc.h"
-#include "config.h"
#include "libgomp.h"
#include "oacc-int.h"
+#include <assert.h>
void *
acc_get_current_cuda_device (void)
{
struct goacc_thread *thr = goacc_thread ();
+ void *ret = NULL;
if (thr && thr->dev && thr->dev->openacc.cuda.get_current_device_func)
- return thr->dev->openacc.cuda.get_current_device_func ();
+ {
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
- return NULL;
+ ret = thr->dev->openacc.cuda.get_current_device_func ();
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+ }
+
+ return ret;
}
void *
@@ -47,10 +60,23 @@ acc_get_current_cuda_context (void)
{
struct goacc_thread *thr = goacc_thread ();
+ void *ret = NULL;
if (thr && thr->dev && thr->dev->openacc.cuda.get_current_context_func)
- return thr->dev->openacc.cuda.get_current_context_func ();
-
- return NULL;
+ {
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+
+ ret = thr->dev->openacc.cuda.get_current_context_func ();
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+ }
+
+ return ret;
}
void *
@@ -58,13 +84,35 @@ acc_get_cuda_stream (int async)
{
struct goacc_thread *thr = goacc_thread ();
- if (!async_valid_stream_id_p (async))
+ if (!async_valid_p (async))
return NULL;
+ void *ret = NULL;
if (thr && thr->dev && thr->dev->openacc.cuda.get_stream_func)
- return thr->dev->openacc.cuda.get_stream_func (async);
-
- return NULL;
+ {
+ goacc_aq aq = lookup_goacc_asyncqueue (thr, false, async);
+ if (!aq)
+ return ret;
+
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
+
+ ret = thr->dev->openacc.cuda.get_stream_func (aq);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+ }
+
+ return ret;
}
int
@@ -72,15 +120,47 @@ acc_set_cuda_stream (int async, void *stream)
{
struct goacc_thread *thr;
- if (!async_valid_stream_id_p (async) || stream == NULL)
+ if (!async_valid_p (async) || stream == NULL)
return 0;
goacc_lazy_initialize ();
thr = goacc_thread ();
+ int ret = -1;
if (thr && thr->dev && thr->dev->openacc.cuda.set_stream_func)
- return thr->dev->openacc.cuda.set_stream_func (async, stream);
-
- return -1;
+ {
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
+
+ goacc_aq aq = get_goacc_asyncqueue (async);
+ /* Due to not using an asyncqueue for "acc_async_sync", this cannot be
+ used to change the CUDA stream associated with "acc_async_sync". */
+ if (!aq)
+ {
+ assert (async == acc_async_sync);
+ gomp_debug (0, "Refusing request to set CUDA stream associated"
+ " with \"acc_async_sync\"\n");
+ ret = 0;
+ goto out_prof;
+ }
+ gomp_mutex_lock (&thr->dev->openacc.async.lock);
+ ret = thr->dev->openacc.cuda.set_stream_func (aq, stream);
+ gomp_mutex_unlock (&thr->dev->openacc.async.lock);
+
+ out_prof:
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+ }
+
+ return ret;
}
diff --git a/libgomp/oacc-host.c b/libgomp/oacc-host.c
index 2de3c374da1..cbcac9bf7b3 100644
--- a/libgomp/oacc-host.c
+++ b/libgomp/oacc-host.c
@@ -1,6 +1,6 @@
/* OpenACC Runtime Library: acc_device_host.
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -32,7 +32,6 @@
#include <stdbool.h>
#include <stddef.h>
-#include <stdint.h>
static struct gomp_device_descr host_dispatch;
@@ -140,55 +139,89 @@ host_openacc_exec (void (*fn) (void *),
size_t mapnum __attribute__ ((unused)),
void **hostaddrs,
void **devaddrs __attribute__ ((unused)),
- int async __attribute__ ((unused)),
- unsigned *dims __attribute ((unused)),
+ unsigned *dims __attribute__ ((unused)),
void *targ_mem_desc __attribute__ ((unused)))
{
fn (hostaddrs);
}
static void
-host_openacc_register_async_cleanup (void *targ_mem_desc __attribute__ ((unused)),
- int async __attribute__ ((unused)))
+host_openacc_async_exec (void (*fn) (void *),
+ size_t mapnum __attribute__ ((unused)),
+ void **hostaddrs,
+ void **devaddrs __attribute__ ((unused)),
+ unsigned *dims __attribute__ ((unused)),
+ void *targ_mem_desc __attribute__ ((unused)),
+ struct goacc_asyncqueue *aq __attribute__ ((unused)))
{
+ fn (hostaddrs);
}
static int
-host_openacc_async_test (int async __attribute__ ((unused)))
+host_openacc_async_test (struct goacc_asyncqueue *aq __attribute__ ((unused)))
{
return 1;
}
-static int
-host_openacc_async_test_all (void)
+static bool
+host_openacc_async_synchronize (struct goacc_asyncqueue *aq
+ __attribute__ ((unused)))
{
- return 1;
+ return true;
}
-static void
-host_openacc_async_wait (int async __attribute__ ((unused)))
+static bool
+host_openacc_async_serialize (struct goacc_asyncqueue *aq1
+ __attribute__ ((unused)),
+ struct goacc_asyncqueue *aq2
+ __attribute__ ((unused)))
{
+ return true;
}
-static void
-host_openacc_async_wait_async (int async1 __attribute__ ((unused)),
- int async2 __attribute__ ((unused)))
+static bool
+host_openacc_async_host2dev (int ord __attribute__ ((unused)),
+ void *dst __attribute__ ((unused)),
+ const void *src __attribute__ ((unused)),
+ size_t n __attribute__ ((unused)),
+ struct goacc_asyncqueue *aq
+ __attribute__ ((unused)))
{
+ return true;
}
-static void
-host_openacc_async_wait_all (void)
+static bool
+host_openacc_async_dev2host (int ord __attribute__ ((unused)),
+ void *dst __attribute__ ((unused)),
+ const void *src __attribute__ ((unused)),
+ size_t n __attribute__ ((unused)),
+ struct goacc_asyncqueue *aq
+ __attribute__ ((unused)))
{
+ return true;
}
static void
-host_openacc_async_wait_all_async (int async __attribute__ ((unused)))
+host_openacc_async_queue_callback (struct goacc_asyncqueue *aq
+ __attribute__ ((unused)),
+ void (*callback_fn)(void *)
+ __attribute__ ((unused)),
+ void *userptr __attribute__ ((unused)))
{
}
-static void
-host_openacc_async_set_async (int async __attribute__ ((unused)))
+static struct goacc_asyncqueue *
+host_openacc_async_construct (int device __attribute__((unused)))
{
+ /* Non-NULL 0xffff... value as opaque dummy. */
+ return (struct goacc_asyncqueue *) -1;
+}
+
+static bool
+host_openacc_async_destruct (struct goacc_asyncqueue *aq
+ __attribute__ ((unused)))
+{
+ return true;
}
static void *
@@ -235,19 +268,21 @@ static struct gomp_device_descr host_dispatch =
.exec_func = host_openacc_exec,
- .register_async_cleanup_func = host_openacc_register_async_cleanup,
-
- .async_test_func = host_openacc_async_test,
- .async_test_all_func = host_openacc_async_test_all,
- .async_wait_func = host_openacc_async_wait,
- .async_wait_async_func = host_openacc_async_wait_async,
- .async_wait_all_func = host_openacc_async_wait_all,
- .async_wait_all_async_func = host_openacc_async_wait_all_async,
- .async_set_async_func = host_openacc_async_set_async,
-
.create_thread_data_func = host_openacc_create_thread_data,
.destroy_thread_data_func = host_openacc_destroy_thread_data,
+ .async = {
+ .construct_func = host_openacc_async_construct,
+ .destruct_func = host_openacc_async_destruct,
+ .test_func = host_openacc_async_test,
+ .synchronize_func = host_openacc_async_synchronize,
+ .serialize_func = host_openacc_async_serialize,
+ .queue_callback_func = host_openacc_async_queue_callback,
+ .exec_func = host_openacc_async_exec,
+ .dev2host_func = host_openacc_async_dev2host,
+ .host2dev_func = host_openacc_async_host2dev,
+ },
+
.cuda = {
.get_current_device_func = NULL,
.get_current_context_func = NULL,
diff --git a/libgomp/oacc-init.c b/libgomp/oacc-init.c
index 8db24b17d29..e1568c535b3 100644
--- a/libgomp/oacc-init.c
+++ b/libgomp/oacc-init.c
@@ -1,6 +1,6 @@
/* OpenACC Runtime initialization routines
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -210,8 +210,67 @@ acc_dev_num_out_of_range (acc_device_t d, int ord, int ndevs)
held before calling this function. */
static struct gomp_device_descr *
-acc_init_1 (acc_device_t d)
+acc_init_1 (acc_device_t d, acc_construct_t parent_construct, int implicit)
{
+ bool check_not_nested_p;
+ if (implicit)
+ {
+ /* In the implicit case, there should (TODO: must?) already be something
+ have been set up for an outer construct. */
+ check_not_nested_p = false;
+ }
+ else
+ {
+ check_not_nested_p = true;
+ /* TODO: should we set 'thr->prof_info' etc. in this case ('acc_init')?
+ The problem is, that we don't have 'thr' yet? (So,
+ 'check_not_nested_p = true' also is pointless actually.) */
+ }
+ bool profiling_p = GOACC_PROFILING_DISPATCH_P (check_not_nested_p);
+
+ acc_prof_info prof_info;
+ if (profiling_p)
+ {
+ prof_info.event_type = acc_ev_device_init_start;
+ prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
+ prof_info.version = _ACC_PROF_INFO_VERSION;
+ prof_info.device_type = d;
+ prof_info.device_number = goacc_device_num;
+ prof_info.thread_id = -1;
+ prof_info.async = acc_async_sync;
+ prof_info.async_queue = prof_info.async;
+ prof_info.src_file = NULL;
+ prof_info.func_name = NULL;
+ prof_info.line_no = -1;
+ prof_info.end_line_no = -1;
+ prof_info.func_line_no = -1;
+ prof_info.func_end_line_no = -1;
+ }
+ acc_event_info device_init_event_info;
+ if (profiling_p)
+ {
+ device_init_event_info.other_event.event_type = prof_info.event_type;
+ device_init_event_info.other_event.valid_bytes
+ = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
+ device_init_event_info.other_event.parent_construct = parent_construct;
+ device_init_event_info.other_event.implicit = implicit;
+ device_init_event_info.other_event.tool_info = NULL;
+ }
+ acc_api_info api_info;
+ if (profiling_p)
+ {
+ api_info.device_api = acc_device_api_none;
+ api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
+ api_info.device_type = prof_info.device_type;
+ api_info.vendor = -1;
+ api_info.device_handle = NULL;
+ api_info.context_handle = NULL;
+ api_info.async_handle = NULL;
+ }
+
+ if (profiling_p)
+ goacc_profiling_dispatch (&prof_info, &device_init_event_info, &api_info);
+
struct gomp_device_descr *base_dev, *acc_dev;
int ndevs;
@@ -234,6 +293,14 @@ acc_init_1 (acc_device_t d)
gomp_init_device (acc_dev);
gomp_mutex_unlock (&acc_dev->lock);
+ if (profiling_p)
+ {
+ prof_info.event_type = acc_ev_device_init_end;
+ device_init_event_info.other_event.event_type = prof_info.event_type;
+ goacc_profiling_dispatch (&prof_info, &device_init_event_info,
+ &api_info);
+ }
+
return base_dev;
}
@@ -309,7 +376,7 @@ acc_shutdown_1 (acc_device_t d)
if (acc_dev->state == GOMP_DEVICE_INITIALIZED)
{
devices_active = true;
- ret &= acc_dev->fini_device_func (acc_dev->target_id);
+ ret &= gomp_fini_device (acc_dev);
acc_dev->state = GOMP_DEVICE_UNINITIALIZED;
}
gomp_mutex_unlock (&acc_dev->lock);
@@ -423,11 +490,13 @@ goacc_attach_host_thread_to_device (int ord)
thr->dev = acc_dev = &base_dev[ord];
thr->saved_bound_dev = NULL;
thr->mapped_data = NULL;
-
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ /* Initially, all callbacks for all events are enabled. */
+ thr->prof_callbacks_enabled = true;
+
thr->target_tls
= acc_dev->openacc.create_thread_data_func (ord);
-
- acc_dev->openacc.async_set_async_func (acc_async_sync);
}
/* OpenACC 2.0a (3.2.12, 3.2.13) doesn't specify whether the serialization of
@@ -439,9 +508,7 @@ acc_init (acc_device_t d)
gomp_init_targets_once ();
gomp_mutex_lock (&acc_device_lock);
-
- cached_base_dev = acc_init_1 (d);
-
+ cached_base_dev = acc_init_1 (d, acc_construct_runtime_api, 0);
gomp_mutex_unlock (&acc_device_lock);
goacc_attach_host_thread_to_device (-1);
@@ -500,6 +567,12 @@ acc_set_device_type (acc_device_t d)
struct gomp_device_descr *base_dev, *acc_dev;
struct goacc_thread *thr = goacc_thread ();
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ prof_info.device_type = d;
+
gomp_init_targets_once ();
gomp_mutex_lock (&acc_device_lock);
@@ -524,6 +597,12 @@ acc_set_device_type (acc_device_t d)
}
goacc_attach_host_thread_to_device (-1);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
ialias (acc_set_device_type)
@@ -539,12 +618,22 @@ acc_get_device_type (void)
res = acc_device_type (thr->base_dev->type);
else
{
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+
gomp_init_targets_once ();
gomp_mutex_lock (&acc_device_lock);
dev = resolve_device (acc_device_default, true);
gomp_mutex_unlock (&acc_device_lock);
res = acc_device_type (dev->type);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
assert (res != acc_device_default
@@ -564,12 +653,24 @@ acc_get_device_num (acc_device_t d)
if (d >= _ACC_device_hwm)
gomp_fatal ("unknown device type %u", (unsigned) d);
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ prof_info.device_type = d;
+
gomp_init_targets_once ();
gomp_mutex_lock (&acc_device_lock);
dev = resolve_device (d, true);
gomp_mutex_unlock (&acc_device_lock);
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+
if (thr && thr->base_dev == dev && thr->dev)
return thr->dev->target_id;
@@ -691,8 +792,13 @@ goacc_lazy_initialize (void)
if (thr && thr->dev)
return;
+ gomp_init_targets_once ();
+
+ gomp_mutex_lock (&acc_device_lock);
if (!cached_base_dev)
- acc_init (acc_device_default);
- else
- goacc_attach_host_thread_to_device (-1);
+ cached_base_dev = acc_init_1 (acc_device_default,
+ acc_construct_parallel, 1);
+ gomp_mutex_unlock (&acc_device_lock);
+
+ goacc_attach_host_thread_to_device (-1);
}
diff --git a/libgomp/oacc-int.h b/libgomp/oacc-int.h
index cdd0f7f0f73..9dc6c8a5713 100644
--- a/libgomp/oacc-int.h
+++ b/libgomp/oacc-int.h
@@ -1,6 +1,6 @@
/* OpenACC Runtime - internal declarations
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -40,6 +40,7 @@
#include "openacc.h"
#include "config.h"
+#include "acc_prof.h"
#include <stddef.h>
#include <stdbool.h>
#include <stdarg.h>
@@ -68,6 +69,12 @@ struct goacc_thread
strictly push/pop semantics according to lexical scope. */
struct target_mem_desc *mapped_data;
+ /* Data of the OpenACC Profiling Interface. */
+ acc_prof_info *prof_info;
+ acc_api_info *api_info;
+ /* Per-thread toggle of OpenACC Profiling Interface callbacks. */
+ bool prof_callbacks_enabled;
+
/* These structures form a list: this is the next thread in that list. */
struct goacc_thread *next;
@@ -75,7 +82,14 @@ struct goacc_thread
void *target_tls;
};
-#if defined HAVE_TLS || defined USE_EMUTLS
+#ifdef __AMDGCN__
+static inline struct goacc_thread *
+goacc_thread (void)
+{
+ /* Unused in the offload libgomp for OpenACC: return a dummy value. */
+ return 0;
+}
+#elif defined HAVE_TLS || defined USE_EMUTLS
extern __thread struct goacc_thread *goacc_tls_data;
static inline struct goacc_thread *
goacc_thread (void)
@@ -99,6 +113,13 @@ void goacc_restore_bind (void);
void goacc_lazy_initialize (void);
void goacc_host_init (void);
+void goacc_init_asyncqueues (struct gomp_device_descr *);
+bool goacc_fini_asyncqueues (struct gomp_device_descr *);
+void goacc_async_free (struct gomp_device_descr *, struct goacc_asyncqueue *,
+ void *);
+struct goacc_asyncqueue *get_goacc_asyncqueue (int);
+struct goacc_asyncqueue *lookup_goacc_asyncqueue (struct goacc_thread *, bool,
+ int);
static inline bool
async_valid_stream_id_p (int async)
{
@@ -121,6 +142,28 @@ async_synchronous_p (int async)
return async == acc_async_sync;
}
+
+extern bool goacc_prof_enabled;
+/* Tune for the (very common) case that profiling is not enabled. */
+#define GOACC_PROF_ENABLED \
+ (__builtin_expect (__atomic_load_n (&goacc_prof_enabled, \
+ MEMMODEL_ACQUIRE) == true, false))
+
+void goacc_profiling_initialize (void);
+bool _goacc_profiling_dispatch_p (bool);
+/* Tune for the (very common) case that profiling is not enabled. */
+#define GOACC_PROFILING_DISPATCH_P(...) \
+ (GOACC_PROF_ENABLED \
+ && _goacc_profiling_dispatch_p (__VA_ARGS__))
+bool _goacc_profiling_setup_p (struct goacc_thread *,
+ acc_prof_info *, acc_api_info *);
+/* Tune for the (very common) case that profiling is not enabled. */
+#define GOACC_PROFILING_SETUP_P(...) \
+ (GOACC_PROFILING_DISPATCH_P (false) \
+ && _goacc_profiling_setup_p (__VA_ARGS__))
+void goacc_profiling_dispatch (acc_prof_info *, acc_event_info *,
+ acc_api_info *);
+
#ifdef HAVE_ATTRIBUTE_VISIBILITY
# pragma GCC visibility pop
#endif
diff --git a/libgomp/oacc-mem.c b/libgomp/oacc-mem.c
index 3787ce49e38..aafe88d3a14 100644
--- a/libgomp/oacc-mem.c
+++ b/libgomp/oacc-mem.c
@@ -1,6 +1,6 @@
/* OpenACC Runtime initialization routines
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -27,11 +27,9 @@
<http://www.gnu.org/licenses/>. */
#include "openacc.h"
-#include "config.h"
#include "libgomp.h"
#include "gomp-constants.h"
#include "oacc-int.h"
-#include <stdint.h>
#include <string.h>
#include <assert.h>
@@ -108,7 +106,19 @@ acc_malloc (size_t s)
if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
return malloc (s);
- return thr->dev->alloc_func (thr->dev->target_id, s);
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+
+ void *res = thr->dev->alloc_func (thr->dev->target_id, s);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+
+ return res;
}
/* OpenACC 2.0a (3.2.16) doesn't specify what to do in the event
@@ -131,6 +141,10 @@ acc_free (void *d)
if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
return free (d);
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+
gomp_mutex_lock (&acc_dev->lock);
/* We don't have to call lazy open here, as the ptr value must have
@@ -151,10 +165,17 @@ acc_free (void *d)
if (!acc_dev->free_func (acc_dev->target_id, d))
gomp_fatal ("error in freeing device memory in %s", __FUNCTION__);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
-void
-acc_memcpy_to_device (void *d, void *h, size_t s)
+static void
+memcpy_tofrom_device (bool from, void *d, void *h, size_t s, int async,
+ const char *libfnname)
{
/* No need to call lazy open here, as the device pointer must have
been obtained from a routine that did that. */
@@ -164,31 +185,57 @@ acc_memcpy_to_device (void *d, void *h, size_t s)
if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
{
- memmove (d, h, s);
+ if (from)
+ memmove (h, d, s);
+ else
+ memmove (d, h, s);
return;
}
- if (!thr->dev->host2dev_func (thr->dev->target_id, d, h, s))
- gomp_fatal ("error in %s", __FUNCTION__);
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
+
+ goacc_aq aq = get_goacc_asyncqueue (async);
+ if (from)
+ gomp_copy_dev2host (thr->dev, aq, h, d, s);
+ else
+ gomp_copy_host2dev (thr->dev, aq, d, h, s, /* TODO: cbuf? */ NULL);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
void
-acc_memcpy_from_device (void *h, void *d, size_t s)
+acc_memcpy_to_device (void *d, void *h, size_t s)
{
- /* No need to call lazy open here, as the device pointer must have
- been obtained from a routine that did that. */
- struct goacc_thread *thr = goacc_thread ();
+ memcpy_tofrom_device (false, d, h, s, acc_async_sync, __FUNCTION__);
+}
- assert (thr && thr->dev);
+void
+acc_memcpy_to_device_async (void *d, void *h, size_t s, int async)
+{
+ memcpy_tofrom_device (false, d, h, s, async, __FUNCTION__);
+}
- if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
- {
- memmove (h, d, s);
- return;
- }
+void
+acc_memcpy_from_device (void *h, void *d, size_t s)
+{
+ memcpy_tofrom_device (true, d, h, s, acc_async_sync, __FUNCTION__);
+}
- if (!thr->dev->dev2host_func (thr->dev->target_id, h, d, s))
- gomp_fatal ("error in %s", __FUNCTION__);
+void
+acc_memcpy_from_device_async (void *h, void *d, size_t s, int async)
+{
+ memcpy_tofrom_device (true, d, h, s, async, __FUNCTION__);
}
/* Return the device pointer that corresponds to host data H. Or NULL
@@ -209,6 +256,9 @@ acc_deviceptr (void *h)
if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
return h;
+ /* In the following, no OpenACC Profiling Interface events can possibly be
+ generated. */
+
gomp_mutex_lock (&dev->lock);
n = lookup_host (dev, h, 1);
@@ -246,6 +296,9 @@ acc_hostptr (void *d)
if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
return d;
+ /* In the following, no OpenACC Profiling Interface events can possibly be
+ generated. */
+
gomp_mutex_lock (&acc_dev->lock);
n = lookup_dev (acc_dev->openacc.data_environ, d, 1);
@@ -283,6 +336,9 @@ acc_is_present (void *h, size_t s)
if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
return h != NULL;
+ /* In the following, no OpenACC Profiling Interface events can possibly be
+ generated. */
+
gomp_mutex_lock (&acc_dev->lock);
n = lookup_host (acc_dev, h, s);
@@ -327,6 +383,10 @@ acc_map_data (void *h, void *d, size_t s)
gomp_fatal ("[%p,+%d]->[%p,+%d] is a bad map",
(void *)h, (int)s, (void *)d, (int)s);
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+
gomp_mutex_lock (&acc_dev->lock);
if (lookup_host (acc_dev, h, s))
@@ -348,6 +408,12 @@ acc_map_data (void *h, void *d, size_t s)
tgt = gomp_map_vars (acc_dev, mapnum, &hostaddrs, &devaddrs, &sizes,
&kinds, true, GOMP_MAP_VARS_OPENACC);
tgt->list[0].key->refcount = REFCOUNT_INFINITY;
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
gomp_mutex_lock (&acc_dev->lock);
@@ -368,6 +434,10 @@ acc_unmap_data (void *h)
if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
return;
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+
size_t host_size;
gomp_mutex_lock (&acc_dev->lock);
@@ -421,6 +491,12 @@ acc_unmap_data (void *h)
gomp_mutex_unlock (&acc_dev->lock);
gomp_unmap_vars (t, true);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
#define FLAG_PRESENT (1 << 0)
@@ -428,7 +504,7 @@ acc_unmap_data (void *h)
#define FLAG_COPY (1 << 2)
static void *
-present_create_copy (unsigned f, void *h, size_t s)
+present_create_copy (unsigned f, void *h, size_t s, int async)
{
void *d;
splay_tree_key n;
@@ -444,13 +520,22 @@ present_create_copy (unsigned f, void *h, size_t s)
if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
return h;
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
+
gomp_mutex_lock (&acc_dev->lock);
n = lookup_host (acc_dev, h, s);
if (n)
{
/* Present. */
- d = (void *) (n->tgt->tgt_start + n->tgt_offset);
+ d = (void *) (n->tgt->tgt_start + n->tgt_offset + h - n->host_start);
if (!(f & FLAG_PRESENT))
{
@@ -490,8 +575,10 @@ present_create_copy (unsigned f, void *h, size_t s)
gomp_mutex_unlock (&acc_dev->lock);
- tgt = gomp_map_vars (acc_dev, mapnum, &hostaddrs, NULL, &s, &kinds, true,
- GOMP_MAP_VARS_OPENACC);
+ goacc_aq aq = get_goacc_asyncqueue (async);
+
+ tgt = gomp_map_vars_async (acc_dev, aq, mapnum, &hostaddrs, NULL, &s,
+ &kinds, true, GOMP_MAP_VARS_OPENACC);
/* Initialize dynamic refcount. */
tgt->list[0].key->dynamic_refcount = 1;
@@ -504,52 +591,75 @@ present_create_copy (unsigned f, void *h, size_t s)
gomp_mutex_unlock (&acc_dev->lock);
}
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
+
return d;
}
void *
acc_create (void *h, size_t s)
{
- return present_create_copy (FLAG_PRESENT | FLAG_CREATE, h, s);
+ return present_create_copy (FLAG_PRESENT | FLAG_CREATE, h, s, acc_async_sync);
}
-void *
-acc_copyin (void *h, size_t s)
+void
+acc_create_async (void *h, size_t s, int async)
{
- return present_create_copy (FLAG_PRESENT | FLAG_CREATE | FLAG_COPY, h, s);
+ present_create_copy (FLAG_PRESENT | FLAG_CREATE, h, s, async);
}
+/* acc_present_or_create used to be what acc_create is now. */
+/* acc_pcreate is acc_present_or_create by a different name. */
+#ifdef HAVE_ATTRIBUTE_ALIAS
+strong_alias (acc_create, acc_present_or_create)
+strong_alias (acc_create, acc_pcreate)
+#else
void *
acc_present_or_create (void *h, size_t s)
{
- return present_create_copy (FLAG_PRESENT | FLAG_CREATE, h, s);
+ return acc_create (h, s);
}
-/* acc_pcreate is acc_present_or_create by a different name. */
-#ifdef HAVE_ATTRIBUTE_ALIAS
-strong_alias (acc_present_or_create, acc_pcreate)
-#else
void *
acc_pcreate (void *h, size_t s)
{
- return acc_present_or_create (h, s);
+ return acc_create (h, s);
}
#endif
void *
-acc_present_or_copyin (void *h, size_t s)
+acc_copyin (void *h, size_t s)
+{
+ return present_create_copy (FLAG_PRESENT | FLAG_CREATE | FLAG_COPY, h, s,
+ acc_async_sync);
+}
+
+void
+acc_copyin_async (void *h, size_t s, int async)
{
- return present_create_copy (FLAG_PRESENT | FLAG_CREATE | FLAG_COPY, h, s);
+ present_create_copy (FLAG_PRESENT | FLAG_CREATE | FLAG_COPY, h, s, async);
}
+/* acc_present_or_copyin used to be what acc_copyin is now. */
/* acc_pcopyin is acc_present_or_copyin by a different name. */
#ifdef HAVE_ATTRIBUTE_ALIAS
-strong_alias (acc_present_or_copyin, acc_pcopyin)
+strong_alias (acc_copyin, acc_present_or_copyin)
+strong_alias (acc_copyin, acc_pcopyin)
#else
void *
+acc_present_or_copyin (void *h, size_t s)
+{
+ return acc_copyin (h, s);
+}
+
+void *
acc_pcopyin (void *h, size_t s)
{
- return acc_present_or_copyin (h, s);
+ return acc_copyin (h, s);
}
#endif
@@ -557,9 +667,8 @@ acc_pcopyin (void *h, size_t s)
#define FLAG_FINALIZE (1 << 1)
static void
-delete_copyout (unsigned f, void *h, size_t s, const char *libfnname)
+delete_copyout (unsigned f, void *h, size_t s, int async, const char *libfnname)
{
- size_t host_size;
splay_tree_key n;
void *d;
struct goacc_thread *thr = goacc_thread ();
@@ -568,6 +677,15 @@ delete_copyout (unsigned f, void *h, size_t s, const char *libfnname)
if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
return;
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
+
gomp_mutex_lock (&acc_dev->lock);
n = lookup_host (acc_dev, h, s);
@@ -584,13 +702,12 @@ delete_copyout (unsigned f, void *h, size_t s, const char *libfnname)
d = (void *) (n->tgt->tgt_start + n->tgt_offset
+ (uintptr_t) h - n->host_start);
- host_size = n->host_end - n->host_start;
-
- if (n->host_start != (uintptr_t) h || host_size != s)
+ if ((uintptr_t) h < n->host_start || (uintptr_t) h + s > n->host_end)
{
+ size_t host_size = n->host_end - n->host_start;
gomp_mutex_unlock (&acc_dev->lock);
- gomp_fatal ("[%p,%d] surrounds2 [%p,+%d]",
- (void *) n->host_start, (int) host_size, (void *) h, (int) s);
+ gomp_fatal ("[%p,+%d] outside mapped block [%p,+%d]",
+ (void *) h, (int) s, (void *) n->host_start, (int) host_size);
}
if (n->refcount == REFCOUNT_INFINITY)
@@ -633,52 +750,73 @@ delete_copyout (unsigned f, void *h, size_t s, const char *libfnname)
}
if (f & FLAG_COPYOUT)
- acc_dev->dev2host_func (acc_dev->target_id, h, d, s);
-
+ {
+ goacc_aq aq = get_goacc_asyncqueue (async);
+ gomp_copy_dev2host (acc_dev, aq, h, d, s);
+ }
gomp_remove_var (acc_dev, n);
}
gomp_mutex_unlock (&acc_dev->lock);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
void
acc_delete (void *h , size_t s)
{
- delete_copyout (0, h, s, __FUNCTION__);
+ delete_copyout (0, h, s, acc_async_sync, __FUNCTION__);
+}
+
+void
+acc_delete_async (void *h , size_t s, int async)
+{
+ delete_copyout (0, h, s, async, __FUNCTION__);
}
void
acc_delete_finalize (void *h , size_t s)
{
- delete_copyout (FLAG_FINALIZE, h, s, __FUNCTION__);
+ delete_copyout (FLAG_FINALIZE, h, s, acc_async_sync, __FUNCTION__);
}
void
acc_delete_finalize_async (void *h , size_t s, int async)
{
- delete_copyout (FLAG_FINALIZE, h, s, __FUNCTION__);
+ delete_copyout (FLAG_FINALIZE, h, s, async, __FUNCTION__);
}
void
acc_copyout (void *h, size_t s)
{
- delete_copyout (FLAG_COPYOUT, h, s, __FUNCTION__);
+ delete_copyout (FLAG_COPYOUT, h, s, acc_async_sync, __FUNCTION__);
+}
+
+void
+acc_copyout_async (void *h, size_t s, int async)
+{
+ delete_copyout (FLAG_COPYOUT, h, s, async, __FUNCTION__);
}
void
acc_copyout_finalize (void *h, size_t s)
{
- delete_copyout (FLAG_COPYOUT | FLAG_FINALIZE, h, s, __FUNCTION__);
+ delete_copyout (FLAG_COPYOUT | FLAG_FINALIZE, h, s, acc_async_sync,
+ __FUNCTION__);
}
void
acc_copyout_finalize_async (void *h, size_t s, int async)
{
- delete_copyout (FLAG_COPYOUT | FLAG_FINALIZE, h, s, __FUNCTION__);
+ delete_copyout (FLAG_COPYOUT | FLAG_FINALIZE, h, s, async, __FUNCTION__);
}
static void
-update_dev_host (int is_dev, void *h, size_t s)
+update_dev_host (int is_dev, void *h, size_t s, int async)
{
splay_tree_key n;
void *d;
@@ -691,6 +829,15 @@ update_dev_host (int is_dev, void *h, size_t s)
if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
return;
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
+
gomp_mutex_lock (&acc_dev->lock);
n = lookup_host (acc_dev, h, s);
@@ -704,29 +851,49 @@ update_dev_host (int is_dev, void *h, size_t s)
d = (void *) (n->tgt->tgt_start + n->tgt_offset
+ (uintptr_t) h - n->host_start);
+ goacc_aq aq = get_goacc_asyncqueue (async);
+
if (is_dev)
- acc_dev->host2dev_func (acc_dev->target_id, d, h, s);
+ gomp_copy_host2dev (acc_dev, aq, d, h, s, /* TODO: cbuf? */ NULL);
else
- acc_dev->dev2host_func (acc_dev->target_id, h, d, s);
+ gomp_copy_dev2host (acc_dev, aq, h, d, s);
gomp_mutex_unlock (&acc_dev->lock);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
void
acc_update_device (void *h, size_t s)
{
- update_dev_host (1, h, s);
+ update_dev_host (1, h, s, acc_async_sync);
+}
+
+void
+acc_update_device_async (void *h, size_t s, int async)
+{
+ update_dev_host (1, h, s, async);
}
void
acc_update_self (void *h, size_t s)
{
- update_dev_host (0, h, s);
+ update_dev_host (0, h, s, acc_async_sync);
+}
+
+void
+acc_update_self_async (void *h, size_t s, int async)
+{
+ update_dev_host (0, h, s, async);
}
void
gomp_acc_insert_pointer (size_t mapnum, void **hostaddrs, size_t *sizes,
- void *kinds)
+ void *kinds, int async)
{
struct target_mem_desc *tgt;
struct goacc_thread *thr = goacc_thread ();
@@ -756,8 +923,9 @@ gomp_acc_insert_pointer (size_t mapnum, void **hostaddrs, size_t *sizes,
}
gomp_debug (0, " %s: prepare mappings\n", __FUNCTION__);
- tgt = gomp_map_vars (acc_dev, mapnum, hostaddrs,
- NULL, sizes, kinds, true, GOMP_MAP_VARS_OPENACC);
+ goacc_aq aq = get_goacc_asyncqueue (async);
+ tgt = gomp_map_vars_async (acc_dev, aq, mapnum, hostaddrs,
+ NULL, sizes, kinds, true, GOMP_MAP_VARS_OPENACC);
gomp_debug (0, " %s: mappings prepared\n", __FUNCTION__);
/* Initialize dynamic refcount. */
@@ -851,7 +1019,10 @@ gomp_acc_remove_pointer (void *h, size_t s, bool force_copyfrom, int async,
if (async < acc_async_noval)
gomp_unmap_vars (t, true);
else
- t->device_descr->openacc.register_async_cleanup_func (t, async);
+ {
+ goacc_aq aq = get_goacc_asyncqueue (async);
+ gomp_unmap_vars_async (t, true, aq);
+ }
}
gomp_mutex_unlock (&acc_dev->lock);
diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c
index b80ace58590..68a60de24fa 100644
--- a/libgomp/oacc-parallel.c
+++ b/libgomp/oacc-parallel.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -28,7 +28,6 @@
#include "openacc.h"
#include "libgomp.h"
-#include "libgomp_g.h"
#include "gomp-constants.h"
#include "oacc-int.h"
#ifdef HAVE_INTTYPES_H
@@ -38,6 +37,16 @@
#include <stdarg.h>
#include <assert.h>
+
+/* In the ABI, the GOACC_FLAGs are encoded as an inverted bitmask, so that we
+ continue to support the following two legacy values. */
+_Static_assert (GOACC_FLAGS_UNMARSHAL (GOMP_DEVICE_ICV) == 0,
+ "legacy GOMP_DEVICE_ICV broken");
+_Static_assert (GOACC_FLAGS_UNMARSHAL (GOMP_DEVICE_HOST_FALLBACK)
+ == GOACC_FLAG_HOST_FALLBACK,
+ "legacy GOMP_DEVICE_HOST_FALLBACK broken");
+
+
/* Returns the number of mappings associated with the pointer or pset. PSET
have three mappings, whereas pointer have two. */
@@ -105,17 +114,18 @@ handle_ftn_pointers (size_t mapnum, void **hostaddrs, size_t *sizes,
static void goacc_wait (int async, int num_waits, va_list *ap);
-/* Launch a possibly offloaded function on DEVICE. FN is the host fn
+/* Launch a possibly offloaded function with FLAGS. FN is the host fn
address. MAPNUM, HOSTADDRS, SIZES & KINDS describe the memory
blocks to be copied to/from the device. Varadic arguments are
keyed optional parameters terminated with a zero. */
void
-GOACC_parallel_keyed (int device, void (*fn) (void *),
+GOACC_parallel_keyed (int flags_m, void (*fn) (void *),
size_t mapnum, void **hostaddrs, size_t *sizes,
unsigned short *kinds, ...)
{
- bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
+ int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
+
va_list ap;
struct goacc_thread *thr;
struct gomp_device_descr *acc_dev;
@@ -141,21 +151,75 @@ GOACC_parallel_keyed (int device, void (*fn) (void *),
thr = goacc_thread ();
acc_dev = thr->dev;
+ bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
+
+ acc_prof_info prof_info;
+ if (profiling_p)
+ {
+ thr->prof_info = &prof_info;
+
+ prof_info.event_type = acc_ev_compute_construct_start;
+ prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
+ prof_info.version = _ACC_PROF_INFO_VERSION;
+ prof_info.device_type = acc_device_type (acc_dev->type);
+ prof_info.device_number = acc_dev->target_id;
+ prof_info.thread_id = -1;
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ prof_info.src_file = NULL;
+ prof_info.func_name = NULL;
+ prof_info.line_no = -1;
+ prof_info.end_line_no = -1;
+ prof_info.func_line_no = -1;
+ prof_info.func_end_line_no = -1;
+ }
+ acc_event_info compute_construct_event_info;
+ if (profiling_p)
+ {
+ compute_construct_event_info.other_event.event_type
+ = prof_info.event_type;
+ compute_construct_event_info.other_event.valid_bytes
+ = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
+ compute_construct_event_info.other_event.parent_construct
+ = acc_construct_parallel;
+ compute_construct_event_info.other_event.implicit = 0;
+ compute_construct_event_info.other_event.tool_info = NULL;
+ }
+ acc_api_info api_info;
+ if (profiling_p)
+ {
+ thr->api_info = &api_info;
+
+ api_info.device_api = acc_device_api_none;
+ api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
+ api_info.device_type = prof_info.device_type;
+ api_info.vendor = -1;
+ api_info.device_handle = NULL;
+ api_info.context_handle = NULL;
+ api_info.async_handle = NULL;
+ }
+
+ if (profiling_p)
+ goacc_profiling_dispatch (&prof_info, &compute_construct_event_info,
+ &api_info);
+
handle_ftn_pointers (mapnum, hostaddrs, sizes, kinds);
/* Host fallback if "if" clause is false or if the current device is set to
the host. */
- if (host_fallback)
+ if (flags & GOACC_FLAG_HOST_FALLBACK)
{
+ prof_info.device_type = acc_device_host;
+ api_info.device_type = prof_info.device_type;
goacc_save_and_set_bind (acc_device_host);
fn (hostaddrs);
goacc_restore_bind ();
- return;
+ goto out_prof;
}
else if (acc_device_type (acc_dev->type) == acc_device_host)
{
fn (hostaddrs);
- return;
+ goto out_prof;
}
/* Default: let the runtime choose. */
@@ -189,15 +253,20 @@ GOACC_parallel_keyed (int device, void (*fn) (void *),
if (async == GOMP_LAUNCH_OP_MAX)
async = va_arg (ap, unsigned);
+
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
+
break;
}
case GOMP_LAUNCH_WAIT:
{
unsigned num_waits = GOMP_LAUNCH_OP (tag);
-
- if (num_waits)
- goacc_wait (async, num_waits, &ap);
+ goacc_wait (async, num_waits, &ap);
break;
}
@@ -208,8 +277,6 @@ GOACC_parallel_keyed (int device, void (*fn) (void *),
}
va_end (ap);
- acc_dev->openacc.async_set_async_func (async);
-
if (!(acc_dev->capabilities & GOMP_OFFLOAD_CAP_NATIVE_EXEC))
{
k.host_start = (uintptr_t) fn;
@@ -226,49 +293,91 @@ GOACC_parallel_keyed (int device, void (*fn) (void *),
else
tgt_fn = (void (*)) fn;
- tgt = gomp_map_vars (acc_dev, mapnum, hostaddrs, NULL, sizes, kinds, true,
- GOMP_MAP_VARS_OPENACC);
+ acc_event_info enter_exit_data_event_info;
+ if (profiling_p)
+ {
+ prof_info.event_type = acc_ev_enter_data_start;
+ enter_exit_data_event_info.other_event.event_type
+ = prof_info.event_type;
+ enter_exit_data_event_info.other_event.valid_bytes
+ = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
+ enter_exit_data_event_info.other_event.parent_construct
+ = compute_construct_event_info.other_event.parent_construct;
+ enter_exit_data_event_info.other_event.implicit = 1;
+ enter_exit_data_event_info.other_event.tool_info = NULL;
+ goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
+ &api_info);
+ }
+
+ goacc_aq aq = get_goacc_asyncqueue (async);
+ tgt = gomp_map_vars_async (acc_dev, aq, mapnum, hostaddrs, NULL, sizes, kinds,
+ true, GOMP_MAP_VARS_OPENACC);
+ if (profiling_p)
+ {
+ prof_info.event_type = acc_ev_enter_data_end;
+ enter_exit_data_event_info.other_event.event_type
+ = prof_info.event_type;
+ goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
+ &api_info);
+ }
+
devaddrs = gomp_alloca (sizeof (void *) * mapnum);
for (i = 0; i < mapnum; i++)
- devaddrs[i] = (void *) (tgt->list[i].key->tgt->tgt_start
- + tgt->list[i].key->tgt_offset);
+ if (tgt->list[i].key != NULL)
+ devaddrs[i] = (void *) (tgt->list[i].key->tgt->tgt_start
+ + tgt->list[i].key->tgt_offset
+ + tgt->list[i].offset);
+ else
+ devaddrs[i] = NULL;
+ if (aq == NULL)
+ acc_dev->openacc.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs, dims,
+ tgt);
+ else
+ acc_dev->openacc.async.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs,
+ dims, tgt, aq);
- acc_dev->openacc.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs,
- async, dims, tgt);
+ if (profiling_p)
+ {
+ prof_info.event_type = acc_ev_exit_data_start;
+ enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
+ enter_exit_data_event_info.other_event.tool_info = NULL;
+ goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
+ &api_info);
+ }
/* If running synchronously, unmap immediately. */
- bool copyfrom = true;
- if (async_synchronous_p (async))
+ if (aq == NULL)
gomp_unmap_vars (tgt, true);
else
+ gomp_unmap_vars_async (tgt, true, aq);
+
+ if (profiling_p)
{
- bool async_unmap = false;
- for (size_t i = 0; i < tgt->list_count; i++)
- {
- splay_tree_key k = tgt->list[i].key;
- if (k && k->refcount == 1)
- {
- async_unmap = true;
- break;
- }
- }
- if (async_unmap)
- tgt->device_descr->openacc.register_async_cleanup_func (tgt, async);
- else
- {
- copyfrom = false;
- gomp_unmap_vars (tgt, copyfrom);
- }
+ prof_info.event_type = acc_ev_exit_data_end;
+ enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
+ goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
+ &api_info);
}
- acc_dev->openacc.async_set_async_func (acc_async_sync);
+ out_prof:
+ if (profiling_p)
+ {
+ prof_info.event_type = acc_ev_compute_construct_end;
+ compute_construct_event_info.other_event.event_type
+ = prof_info.event_type;
+ goacc_profiling_dispatch (&prof_info, &compute_construct_event_info,
+ &api_info);
+
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
-/* Legacy entry point, only provide host execution. */
+/* Legacy entry point (GCC 5). Only provide host fallback execution. */
void
-GOACC_parallel (int device, void (*fn) (void *),
+GOACC_parallel (int flags_m, void (*fn) (void *),
size_t mapnum, void **hostaddrs, size_t *sizes,
unsigned short *kinds,
int num_gangs, int num_workers, int vector_length,
@@ -280,10 +389,11 @@ GOACC_parallel (int device, void (*fn) (void *),
}
void
-GOACC_data_start (int device, size_t mapnum,
+GOACC_data_start (int flags_m, size_t mapnum,
void **hostaddrs, size_t *sizes, unsigned short *kinds)
{
- bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
+ int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
+
struct target_mem_desc *tgt;
#ifdef HAVE_INTTYPES_H
@@ -299,16 +409,83 @@ GOACC_data_start (int device, size_t mapnum,
struct goacc_thread *thr = goacc_thread ();
struct gomp_device_descr *acc_dev = thr->dev;
+ bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
+
+ acc_prof_info prof_info;
+ if (profiling_p)
+ {
+ thr->prof_info = &prof_info;
+
+ prof_info.event_type = acc_ev_enter_data_start;
+ prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
+ prof_info.version = _ACC_PROF_INFO_VERSION;
+ prof_info.device_type = acc_device_type (acc_dev->type);
+ prof_info.device_number = acc_dev->target_id;
+ prof_info.thread_id = -1;
+ prof_info.async = acc_async_sync; /* Always synchronous. */
+ prof_info.async_queue = prof_info.async;
+ prof_info.src_file = NULL;
+ prof_info.func_name = NULL;
+ prof_info.line_no = -1;
+ prof_info.end_line_no = -1;
+ prof_info.func_line_no = -1;
+ prof_info.func_end_line_no = -1;
+ }
+ acc_event_info enter_data_event_info;
+ if (profiling_p)
+ {
+ enter_data_event_info.other_event.event_type
+ = prof_info.event_type;
+ enter_data_event_info.other_event.valid_bytes
+ = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
+ enter_data_event_info.other_event.parent_construct = acc_construct_data;
+ for (int i = 0; i < mapnum; ++i)
+ if ((kinds[i] & 0xff) == GOMP_MAP_USE_DEVICE_PTR)
+ {
+ /* If there is one such data mapping kind, then this is actually an
+ OpenACC 'host_data' construct. (GCC maps the OpenACC
+ 'host_data' construct to the OpenACC 'data' construct.) Apart
+ from artificial test cases (such as an OpenACC 'host_data'
+ construct's (implicit) device initialization when there hasn't
+ been any device data be set up before...), there can't really
+ any meaningful events be generated from OpenACC 'host_data'
+ constructs, though. */
+ enter_data_event_info.other_event.parent_construct
+ = acc_construct_host_data;
+ break;
+ }
+ enter_data_event_info.other_event.implicit = 0;
+ enter_data_event_info.other_event.tool_info = NULL;
+ }
+ acc_api_info api_info;
+ if (profiling_p)
+ {
+ thr->api_info = &api_info;
+
+ api_info.device_api = acc_device_api_none;
+ api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
+ api_info.device_type = prof_info.device_type;
+ api_info.vendor = -1;
+ api_info.device_handle = NULL;
+ api_info.context_handle = NULL;
+ api_info.async_handle = NULL;
+ }
+
+ if (profiling_p)
+ goacc_profiling_dispatch (&prof_info, &enter_data_event_info, &api_info);
+
/* Host fallback or 'do nothing'. */
if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
- || host_fallback)
+ || (flags & GOACC_FLAG_HOST_FALLBACK))
{
+ prof_info.device_type = acc_device_host;
+ api_info.device_type = prof_info.device_type;
tgt = gomp_map_vars (NULL, 0, NULL, NULL, NULL, NULL, true,
GOMP_MAP_VARS_OPENACC);
tgt->prev = thr->mapped_data;
thr->mapped_data = tgt;
- return;
+ goto out_prof;
}
gomp_debug (0, " %s: prepare mappings\n", __FUNCTION__);
@@ -317,28 +494,101 @@ GOACC_data_start (int device, size_t mapnum,
gomp_debug (0, " %s: mappings prepared\n", __FUNCTION__);
tgt->prev = thr->mapped_data;
thr->mapped_data = tgt;
+
+ out_prof:
+ if (profiling_p)
+ {
+ prof_info.event_type = acc_ev_enter_data_end;
+ enter_data_event_info.other_event.event_type = prof_info.event_type;
+ goacc_profiling_dispatch (&prof_info, &enter_data_event_info, &api_info);
+
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
void
GOACC_data_end (void)
{
struct goacc_thread *thr = goacc_thread ();
+ struct gomp_device_descr *acc_dev = thr->dev;
struct target_mem_desc *tgt = thr->mapped_data;
+ bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
+
+ acc_prof_info prof_info;
+ if (profiling_p)
+ {
+ thr->prof_info = &prof_info;
+
+ prof_info.event_type = acc_ev_exit_data_start;
+ prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
+ prof_info.version = _ACC_PROF_INFO_VERSION;
+ prof_info.device_type = acc_device_type (acc_dev->type);
+ prof_info.device_number = acc_dev->target_id;
+ prof_info.thread_id = -1;
+ prof_info.async = acc_async_sync; /* Always synchronous. */
+ prof_info.async_queue = prof_info.async;
+ prof_info.src_file = NULL;
+ prof_info.func_name = NULL;
+ prof_info.line_no = -1;
+ prof_info.end_line_no = -1;
+ prof_info.func_line_no = -1;
+ prof_info.func_end_line_no = -1;
+ }
+ acc_event_info exit_data_event_info;
+ if (profiling_p)
+ {
+ exit_data_event_info.other_event.event_type
+ = prof_info.event_type;
+ exit_data_event_info.other_event.valid_bytes
+ = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
+ exit_data_event_info.other_event.parent_construct = acc_construct_data;
+ exit_data_event_info.other_event.implicit = 0;
+ exit_data_event_info.other_event.tool_info = NULL;
+ }
+ acc_api_info api_info;
+ if (profiling_p)
+ {
+ thr->api_info = &api_info;
+
+ api_info.device_api = acc_device_api_none;
+ api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
+ api_info.device_type = prof_info.device_type;
+ api_info.vendor = -1;
+ api_info.device_handle = NULL;
+ api_info.context_handle = NULL;
+ api_info.async_handle = NULL;
+ }
+
+ if (profiling_p)
+ goacc_profiling_dispatch (&prof_info, &exit_data_event_info, &api_info);
+
gomp_debug (0, " %s: restore mappings\n", __FUNCTION__);
thr->mapped_data = tgt->prev;
gomp_unmap_vars (tgt, true);
gomp_debug (0, " %s: mappings restored\n", __FUNCTION__);
+
+ if (profiling_p)
+ {
+ prof_info.event_type = acc_ev_exit_data_end;
+ exit_data_event_info.other_event.event_type = prof_info.event_type;
+ goacc_profiling_dispatch (&prof_info, &exit_data_event_info, &api_info);
+
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
void
-GOACC_enter_exit_data (int device, size_t mapnum,
+GOACC_enter_exit_data (int flags_m, size_t mapnum,
void **hostaddrs, size_t *sizes, unsigned short *kinds,
int async, int num_waits, ...)
{
+ int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
+
struct goacc_thread *thr;
struct gomp_device_descr *acc_dev;
- bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
bool data_enter = false;
size_t i;
@@ -347,19 +597,6 @@ GOACC_enter_exit_data (int device, size_t mapnum,
thr = goacc_thread ();
acc_dev = thr->dev;
- if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
- || host_fallback)
- return;
-
- if (num_waits)
- {
- va_list ap;
-
- va_start (ap, num_waits);
- goacc_wait (async, num_waits, &ap);
- va_end (ap);
- }
-
/* Determine whether "finalize" semantics apply to all mappings of this
OpenACC directive. */
bool finalize = false;
@@ -371,8 +608,6 @@ GOACC_enter_exit_data (int device, size_t mapnum,
finalize = true;
}
- acc_dev->openacc.async_set_async_func (async);
-
/* Determine if this is an "acc enter data". */
for (i = 0; i < mapnum; ++i)
{
@@ -401,6 +636,77 @@ GOACC_enter_exit_data (int device, size_t mapnum,
kind);
}
+ bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
+
+ acc_prof_info prof_info;
+ if (profiling_p)
+ {
+ thr->prof_info = &prof_info;
+
+ prof_info.event_type
+ = data_enter ? acc_ev_enter_data_start : acc_ev_exit_data_start;
+ prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
+ prof_info.version = _ACC_PROF_INFO_VERSION;
+ prof_info.device_type = acc_device_type (acc_dev->type);
+ prof_info.device_number = acc_dev->target_id;
+ prof_info.thread_id = -1;
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ prof_info.src_file = NULL;
+ prof_info.func_name = NULL;
+ prof_info.line_no = -1;
+ prof_info.end_line_no = -1;
+ prof_info.func_line_no = -1;
+ prof_info.func_end_line_no = -1;
+ }
+ acc_event_info enter_exit_data_event_info;
+ if (profiling_p)
+ {
+ enter_exit_data_event_info.other_event.event_type
+ = prof_info.event_type;
+ enter_exit_data_event_info.other_event.valid_bytes
+ = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
+ enter_exit_data_event_info.other_event.parent_construct
+ = data_enter ? acc_construct_enter_data : acc_construct_exit_data;
+ enter_exit_data_event_info.other_event.implicit = 0;
+ enter_exit_data_event_info.other_event.tool_info = NULL;
+ }
+ acc_api_info api_info;
+ if (profiling_p)
+ {
+ thr->api_info = &api_info;
+
+ api_info.device_api = acc_device_api_none;
+ api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
+ api_info.device_type = prof_info.device_type;
+ api_info.vendor = -1;
+ api_info.device_handle = NULL;
+ api_info.context_handle = NULL;
+ api_info.async_handle = NULL;
+ }
+
+ if (profiling_p)
+ goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
+ &api_info);
+
+ if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
+ || (flags & GOACC_FLAG_HOST_FALLBACK))
+ {
+ prof_info.device_type = acc_device_host;
+ api_info.device_type = prof_info.device_type;
+
+ goto out_prof;
+ }
+
+ if (num_waits)
+ {
+ va_list ap;
+
+ va_start (ap, num_waits);
+ goacc_wait (async, num_waits, &ap);
+ va_end (ap);
+ }
+
/* In c, non-pointers and arrays are represented by a single data clause.
Dynamically allocated arrays and subarrays are represented by a data
clause followed by an internal GOMP_MAP_POINTER.
@@ -424,16 +730,12 @@ GOACC_enter_exit_data (int device, size_t mapnum,
switch (kind)
{
case GOMP_MAP_ALLOC:
- acc_present_or_create (hostaddrs[i], sizes[i]);
- break;
case GOMP_MAP_FORCE_ALLOC:
- acc_create (hostaddrs[i], sizes[i]);
+ acc_create_async (hostaddrs[i], sizes[i], async);
break;
case GOMP_MAP_TO:
- acc_present_or_copyin (hostaddrs[i], sizes[i]);
- break;
case GOMP_MAP_FORCE_TO:
- acc_copyin (hostaddrs[i], sizes[i]);
+ acc_copyin_async (hostaddrs[i], sizes[i], async);
break;
default:
gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
@@ -444,7 +746,7 @@ GOACC_enter_exit_data (int device, size_t mapnum,
else
{
gomp_acc_insert_pointer (pointer, &hostaddrs[i],
- &sizes[i], &kinds[i]);
+ &sizes[i], &kinds[i], async);
/* Increment 'i' by two because OpenACC requires fortran
arrays to be contiguous, so each PSET is associated with
one of MAP_FORCE_ALLOC/MAP_FORCE_PRESET/MAP_FORCE_TO, and
@@ -469,17 +771,17 @@ GOACC_enter_exit_data (int device, size_t mapnum,
if (acc_is_present (hostaddrs[i], sizes[i]))
{
if (finalize)
- acc_delete_finalize (hostaddrs[i], sizes[i]);
+ acc_delete_finalize_async (hostaddrs[i], sizes[i], async);
else
- acc_delete (hostaddrs[i], sizes[i]);
+ acc_delete_async (hostaddrs[i], sizes[i], async);
}
break;
case GOMP_MAP_FROM:
case GOMP_MAP_FORCE_FROM:
if (finalize)
- acc_copyout_finalize (hostaddrs[i], sizes[i]);
+ acc_copyout_finalize_async (hostaddrs[i], sizes[i], async);
else
- acc_copyout (hostaddrs[i], sizes[i]);
+ acc_copyout_async (hostaddrs[i], sizes[i], async);
break;
default:
gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
@@ -498,39 +800,59 @@ GOACC_enter_exit_data (int device, size_t mapnum,
}
}
- acc_dev->openacc.async_set_async_func (acc_async_sync);
+ out_prof:
+ if (profiling_p)
+ {
+ prof_info.event_type
+ = data_enter ? acc_ev_enter_data_end : acc_ev_exit_data_end;
+ enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
+ goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
+ &api_info);
+
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
static void
goacc_wait (int async, int num_waits, va_list *ap)
{
- struct goacc_thread *thr = goacc_thread ();
- struct gomp_device_descr *acc_dev = thr->dev;
-
while (num_waits--)
{
int qid = va_arg (*ap, int);
-
+
+ /* Waiting on ACC_ASYNC_NOVAL maps to 'wait all'. */
+ if (qid == acc_async_noval)
+ {
+ if (async == acc_async_sync)
+ acc_wait_all ();
+ else
+ acc_wait_all_async (async);
+ break;
+ }
+
if (acc_async_test (qid))
continue;
if (async == acc_async_sync)
acc_wait (qid);
else if (qid == async)
- ;/* If we're waiting on the same asynchronous queue as we're
- launching on, the queue itself will order work as
- required, so there's no need to wait explicitly. */
+ /* If we're waiting on the same asynchronous queue as we're
+ launching on, the queue itself will order work as
+ required, so there's no need to wait explicitly. */
+ ;
else
- acc_dev->openacc.async_wait_async_func (qid, async);
+ acc_wait_async (qid, async);
}
}
void
-GOACC_update (int device, size_t mapnum,
+GOACC_update (int flags_m, size_t mapnum,
void **hostaddrs, size_t *sizes, unsigned short *kinds,
int async, int num_waits, ...)
{
- bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
+ int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
+
size_t i;
goacc_lazy_initialize ();
@@ -538,9 +860,64 @@ GOACC_update (int device, size_t mapnum,
struct goacc_thread *thr = goacc_thread ();
struct gomp_device_descr *acc_dev = thr->dev;
+ bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
+
+ acc_prof_info prof_info;
+ if (profiling_p)
+ {
+ thr->prof_info = &prof_info;
+
+ prof_info.event_type = acc_ev_update_start;
+ prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
+ prof_info.version = _ACC_PROF_INFO_VERSION;
+ prof_info.device_type = acc_device_type (acc_dev->type);
+ prof_info.device_number = acc_dev->target_id;
+ prof_info.thread_id = -1;
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ prof_info.src_file = NULL;
+ prof_info.func_name = NULL;
+ prof_info.line_no = -1;
+ prof_info.end_line_no = -1;
+ prof_info.func_line_no = -1;
+ prof_info.func_end_line_no = -1;
+ }
+ acc_event_info update_event_info;
+ if (profiling_p)
+ {
+ update_event_info.other_event.event_type
+ = prof_info.event_type;
+ update_event_info.other_event.valid_bytes
+ = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
+ update_event_info.other_event.parent_construct = acc_construct_update;
+ update_event_info.other_event.implicit = 0;
+ update_event_info.other_event.tool_info = NULL;
+ }
+ acc_api_info api_info;
+ if (profiling_p)
+ {
+ thr->api_info = &api_info;
+
+ api_info.device_api = acc_device_api_none;
+ api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
+ api_info.device_type = prof_info.device_type;
+ api_info.vendor = -1;
+ api_info.device_handle = NULL;
+ api_info.context_handle = NULL;
+ api_info.async_handle = NULL;
+ }
+
+ if (profiling_p)
+ goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
+
if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
- || host_fallback)
- return;
+ || (flags & GOACC_FLAG_HOST_FALLBACK))
+ {
+ prof_info.device_type = acc_device_host;
+ api_info.device_type = prof_info.device_type;
+
+ goto out_prof;
+ }
if (num_waits)
{
@@ -551,8 +928,6 @@ GOACC_update (int device, size_t mapnum,
va_end (ap);
}
- acc_dev->openacc.async_set_async_func (async);
-
bool update_device = false;
for (i = 0; i < mapnum; ++i)
{
@@ -575,6 +950,8 @@ GOACC_update (int device, size_t mapnum,
the value of the allocated device memory in the
previous pointer. */
*(uintptr_t *) hostaddrs[i] = (uintptr_t)dptr;
+ /* TODO: verify that we really cannot use acc_update_device_async
+ here. */
acc_update_device (hostaddrs[i], sizeof (uintptr_t));
/* Restore the host pointer. */
@@ -592,7 +969,7 @@ GOACC_update (int device, size_t mapnum,
/* Fallthru */
case GOMP_MAP_FORCE_TO:
update_device = true;
- acc_update_device (hostaddrs[i], sizes[i]);
+ acc_update_device_async (hostaddrs[i], sizes[i], async);
break;
case GOMP_MAP_FROM:
@@ -604,7 +981,7 @@ GOACC_update (int device, size_t mapnum,
/* Fallthru */
case GOMP_MAP_FORCE_FROM:
update_device = false;
- acc_update_self (hostaddrs[i], sizes[i]);
+ acc_update_self_async (hostaddrs[i], sizes[i], async);
break;
default:
@@ -613,12 +990,37 @@ GOACC_update (int device, size_t mapnum,
}
}
- acc_dev->openacc.async_set_async_func (acc_async_sync);
+ out_prof:
+ if (profiling_p)
+ {
+ prof_info.event_type = acc_ev_update_end;
+ update_event_info.other_event.event_type = prof_info.event_type;
+ goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
+
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
void
GOACC_wait (int async, int num_waits, ...)
{
+ goacc_lazy_initialize ();
+
+ struct goacc_thread *thr = goacc_thread ();
+
+ /* No nesting. */
+ assert (thr->prof_info == NULL);
+ assert (thr->api_info == NULL);
+ acc_prof_info prof_info;
+ acc_api_info api_info;
+ bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
+ if (profiling_p)
+ {
+ prof_info.async = async;
+ prof_info.async_queue = prof_info.async;
+ }
+
if (num_waits)
{
va_list ap;
@@ -629,16 +1031,26 @@ GOACC_wait (int async, int num_waits, ...)
}
else if (async == acc_async_sync)
acc_wait_all ();
- else if (async == acc_async_noval)
- goacc_thread ()->dev->openacc.async_wait_all_async_func (acc_async_noval);
+ else
+ acc_wait_all_async (async);
+
+ if (profiling_p)
+ {
+ thr->prof_info = NULL;
+ thr->api_info = NULL;
+ }
}
+/* Legacy entry point (GCC 5). */
+
int
GOACC_get_num_threads (void)
{
return 1;
}
+/* Legacy entry point (GCC 5). */
+
int
GOACC_get_thread_num (void)
{
@@ -646,7 +1058,7 @@ GOACC_get_thread_num (void)
}
void
-GOACC_declare (int device, size_t mapnum,
+GOACC_declare (int flags_m, size_t mapnum,
void **hostaddrs, size_t *sizes, unsigned short *kinds)
{
int i;
@@ -666,7 +1078,7 @@ GOACC_declare (int device, size_t mapnum,
case GOMP_MAP_POINTER:
case GOMP_MAP_RELEASE:
case GOMP_MAP_DELETE:
- GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
+ GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
&kinds[i], GOMP_ASYNC_SYNC, 0);
break;
@@ -675,18 +1087,18 @@ GOACC_declare (int device, size_t mapnum,
case GOMP_MAP_ALLOC:
if (!acc_is_present (hostaddrs[i], sizes[i]))
- GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
+ GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
&kinds[i], GOMP_ASYNC_SYNC, 0);
break;
case GOMP_MAP_TO:
- GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
+ GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
&kinds[i], GOMP_ASYNC_SYNC, 0);
break;
case GOMP_MAP_FROM:
- GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
+ GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
&kinds[i], GOMP_ASYNC_SYNC, 0);
break;
diff --git a/libgomp/oacc-plugin.c b/libgomp/oacc-plugin.c
index c04db90691a..b4f71a11c18 100644
--- a/libgomp/oacc-plugin.c
+++ b/libgomp/oacc-plugin.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2014-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -29,16 +29,22 @@
#include "libgomp.h"
#include "oacc-plugin.h"
#include "oacc-int.h"
+#include "acc_prof.h"
+/* This plugin function is now obsolete. */
void
-GOMP_PLUGIN_async_unmap_vars (void *ptr, int async)
+GOMP_PLUGIN_async_unmap_vars (void *ptr __attribute__((unused)),
+ int async __attribute__((unused)))
{
- struct target_mem_desc *tgt = ptr;
- struct gomp_device_descr *devicep = tgt->device_descr;
+ gomp_fatal ("invalid plugin function");
+}
+
+/* Return the TLS data for the current thread. */
- devicep->openacc.async_set_async_func (async);
- gomp_unmap_vars (tgt, true);
- devicep->openacc.async_set_async_func (acc_async_sync);
+struct goacc_thread *
+GOMP_PLUGIN_goacc_thread (void)
+{
+ return goacc_thread ();
}
/* Return the target-specific part of the TLS data for the current thread. */
@@ -60,3 +66,11 @@ GOMP_PLUGIN_acc_default_dim (unsigned int i)
}
return goacc_default_dims[i];
}
+
+void
+GOMP_PLUGIN_goacc_profiling_dispatch (acc_prof_info *prof_info,
+ acc_event_info *event_info,
+ acc_api_info *api_info)
+{
+ goacc_profiling_dispatch (prof_info, event_info, api_info);
+}
diff --git a/libgomp/oacc-plugin.h b/libgomp/oacc-plugin.h
index 0a183bb8834..887c6f60125 100644
--- a/libgomp/oacc-plugin.h
+++ b/libgomp/oacc-plugin.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2014-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -27,8 +27,15 @@
#ifndef OACC_PLUGIN_H
#define OACC_PLUGIN_H 1
+#include "oacc-int.h"
+#include "acc_prof.h"
+
extern void GOMP_PLUGIN_async_unmap_vars (void *, int);
+extern struct goacc_thread *GOMP_PLUGIN_goacc_thread (void);
extern void *GOMP_PLUGIN_acc_thread (void);
extern int GOMP_PLUGIN_acc_default_dim (unsigned int);
+extern void GOMP_PLUGIN_goacc_profiling_dispatch (acc_prof_info *,
+ acc_event_info *,
+ acc_api_info *);
#endif
diff --git a/libgomp/oacc-profiling.c b/libgomp/oacc-profiling.c
new file mode 100644
index 00000000000..eff28865089
--- /dev/null
+++ b/libgomp/oacc-profiling.c
@@ -0,0 +1,662 @@
+/* OpenACC Profiling Interface
+
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+ Contributed by Mentor, a Siemens Business.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#define _GNU_SOURCE
+#include "libgomp.h"
+#include "oacc-int.h"
+#include "secure_getenv.h"
+#include "acc_prof.h"
+#include <assert.h>
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#ifdef PLUGIN_SUPPORT
+# include <dlfcn.h>
+#endif
+
+#define STATIC_ASSERT(expr) _Static_assert (expr, "!(" #expr ")")
+
+/* Statically assert that the layout of the common fields in the
+ 'acc_event_info' variants matches. */
+/* 'event_type' */
+STATIC_ASSERT (offsetof (acc_event_info, event_type)
+ == offsetof (acc_event_info, data_event.event_type));
+STATIC_ASSERT (offsetof (acc_event_info, data_event.event_type)
+ == offsetof (acc_event_info, launch_event.event_type));
+STATIC_ASSERT (offsetof (acc_event_info, data_event.event_type)
+ == offsetof (acc_event_info, other_event.event_type));
+/* 'valid_bytes' */
+STATIC_ASSERT (offsetof (acc_event_info, data_event.valid_bytes)
+ == offsetof (acc_event_info, launch_event.valid_bytes));
+STATIC_ASSERT (offsetof (acc_event_info, data_event.valid_bytes)
+ == offsetof (acc_event_info, other_event.valid_bytes));
+/* 'parent_construct' */
+STATIC_ASSERT (offsetof (acc_event_info, data_event.parent_construct)
+ == offsetof (acc_event_info, launch_event.parent_construct));
+STATIC_ASSERT (offsetof (acc_event_info, data_event.parent_construct)
+ == offsetof (acc_event_info, other_event.parent_construct));
+/* 'implicit' */
+STATIC_ASSERT (offsetof (acc_event_info, data_event.implicit)
+ == offsetof (acc_event_info, launch_event.implicit));
+STATIC_ASSERT (offsetof (acc_event_info, data_event.implicit)
+ == offsetof (acc_event_info, other_event.implicit));
+/* 'tool_info' */
+STATIC_ASSERT (offsetof (acc_event_info, data_event.tool_info)
+ == offsetof (acc_event_info, launch_event.tool_info));
+STATIC_ASSERT (offsetof (acc_event_info, data_event.tool_info)
+ == offsetof (acc_event_info, other_event.tool_info));
+
+struct goacc_prof_callback_entry
+{
+ acc_prof_callback cb;
+ int ref;
+ bool enabled;
+ struct goacc_prof_callback_entry *next;
+};
+
+/* Use a separate flag to minimize run-time performance impact for the (very
+ common) case that profiling is not enabled.
+
+ Once enabled, we're not going to disable this anymore, anywhere. We
+ probably could, by adding appropriate logic to 'acc_prof_register',
+ 'acc_prof_unregister'. */
+bool goacc_prof_enabled = false;
+
+/* Global state for registered callbacks.
+ 'goacc_prof_callbacks_enabled[acc_ev_none]' acts as a global toggle. */
+static bool goacc_prof_callbacks_enabled[acc_ev_last];
+static struct goacc_prof_callback_entry *goacc_prof_callback_entries[acc_ev_last];
+/* Lock used to protect access to 'goacc_prof_callbacks_enabled', and
+ 'goacc_prof_callback_entries'. */
+static gomp_mutex_t goacc_prof_lock;
+
+void
+goacc_profiling_initialize (void)
+{
+ gomp_mutex_init (&goacc_prof_lock);
+
+ /* Initially, all callbacks for all events are enabled. */
+ for (int i = 0; i < acc_ev_last; ++i)
+ goacc_prof_callbacks_enabled[i] = true;
+
+
+#ifdef PLUGIN_SUPPORT
+ char *acc_proflibs = secure_getenv ("ACC_PROFLIB");
+ while (acc_proflibs != NULL && acc_proflibs[0] != '\0')
+ {
+ char *acc_proflibs_sep = strchr (acc_proflibs, ';');
+ char *acc_proflib;
+ if (acc_proflibs_sep == acc_proflibs)
+ {
+ /* Stray ';' separator: make sure we don't 'dlopen' the main
+ program. */
+ acc_proflib = NULL;
+ }
+ else
+ {
+ if (acc_proflibs_sep != NULL)
+ {
+ /* Single out the first library. */
+ acc_proflib = gomp_malloc (acc_proflibs_sep - acc_proflibs + 1);
+ memcpy (acc_proflib, acc_proflibs,
+ acc_proflibs_sep - acc_proflibs);
+ acc_proflib[acc_proflibs_sep - acc_proflibs] = '\0';
+ }
+ else
+ {
+ /* No ';' separator, so only one library. */
+ acc_proflib = acc_proflibs;
+ }
+
+ gomp_debug (0, "%s: dlopen (\"%s\")\n", __FUNCTION__, acc_proflib);
+ void *dl_handle = dlopen (acc_proflib, RTLD_LAZY);
+ if (dl_handle != NULL)
+ {
+ typeof (&acc_register_library) a_r_l
+ = dlsym (dl_handle, "acc_register_library");
+ if (a_r_l == NULL)
+ goto dl_fail;
+ gomp_debug (0, " %s: calling %s:acc_register_library\n",
+ __FUNCTION__, acc_proflib);
+ a_r_l (acc_prof_register, acc_prof_unregister,
+ acc_prof_lookup);
+ }
+ else
+ {
+ dl_fail:
+ gomp_error ("while loading ACC_PROFLIB \"%s\": %s",
+ acc_proflib, dlerror ());
+ if (dl_handle != NULL)
+ {
+ int err = dlclose (dl_handle);
+ dl_handle = NULL;
+ if (err != 0)
+ goto dl_fail;
+ }
+ }
+ }
+
+ if (acc_proflib != acc_proflibs)
+ {
+ free (acc_proflib);
+
+ acc_proflibs = acc_proflibs_sep + 1;
+ }
+ else
+ acc_proflibs = NULL;
+ }
+#endif /* PLUGIN_SUPPORT */
+}
+
+void
+acc_prof_register (acc_event_t ev, acc_prof_callback cb, acc_register_t reg)
+{
+ gomp_debug (0, "%s: ev=%d, cb=%p, reg=%d\n",
+ __FUNCTION__, (int) ev, (void *) cb, (int) reg);
+
+
+ /* For any events to be dispatched, the user first has to register a
+ callback, which makes this here a good place for enabling the whole
+ machinery. */
+ if (!GOACC_PROF_ENABLED)
+ __atomic_store_n (&goacc_prof_enabled, true, MEMMODEL_RELEASE);
+
+
+ enum
+ {
+ EVENT_KIND_BOGUS,
+ EVENT_KIND_NORMAL,
+ /* As end events invoke callbacks in the reverse order, we register these
+ in the reverse order here. */
+ EVENT_KIND_END,
+ } event_kind = EVENT_KIND_BOGUS;
+ switch (ev)
+ {
+ case acc_ev_none:
+ case acc_ev_device_init_start:
+ case acc_ev_device_shutdown_start:
+ case acc_ev_runtime_shutdown:
+ case acc_ev_create:
+ case acc_ev_delete:
+ case acc_ev_alloc:
+ case acc_ev_free:
+ case acc_ev_enter_data_start:
+ case acc_ev_exit_data_start:
+ case acc_ev_update_start:
+ case acc_ev_compute_construct_start:
+ case acc_ev_enqueue_launch_start:
+ case acc_ev_enqueue_upload_start:
+ case acc_ev_enqueue_download_start:
+ case acc_ev_wait_start:
+ event_kind = EVENT_KIND_NORMAL;
+ break;
+ case acc_ev_device_init_end:
+ case acc_ev_device_shutdown_end:
+ case acc_ev_enter_data_end:
+ case acc_ev_exit_data_end:
+ case acc_ev_update_end:
+ case acc_ev_compute_construct_end:
+ case acc_ev_enqueue_launch_end:
+ case acc_ev_enqueue_upload_end:
+ case acc_ev_enqueue_download_end:
+ case acc_ev_wait_end:
+ event_kind = EVENT_KIND_END;
+ break;
+ case acc_ev_last:
+ break;
+ }
+ if (event_kind == EVENT_KIND_BOGUS)
+ {
+ /* Silently ignore. */
+ gomp_debug (0, " ignoring request for bogus 'acc_event_t'\n");
+ return;
+ }
+
+ bool bogus = true;
+ switch (reg)
+ {
+ case acc_reg:
+ case acc_toggle:
+ case acc_toggle_per_thread:
+ bogus = false;
+ break;
+ }
+ if (bogus)
+ {
+ /* Silently ignore. */
+ gomp_debug (0, " ignoring request with bogus 'acc_register_t'\n");
+ return;
+ }
+
+ /* Special cases. */
+ if (reg == acc_toggle)
+ {
+ if (cb == NULL)
+ {
+ gomp_debug (0, " globally enabling callbacks\n");
+ gomp_mutex_lock (&goacc_prof_lock);
+ /* For 'acc_ev_none', this acts as a global toggle. */
+ goacc_prof_callbacks_enabled[ev] = true;
+ gomp_mutex_unlock (&goacc_prof_lock);
+ return;
+ }
+ else if (ev == acc_ev_none && cb != NULL)
+ {
+ gomp_debug (0, " ignoring request\n");
+ return;
+ }
+ }
+ else if (reg == acc_toggle_per_thread)
+ {
+ if (ev == acc_ev_none && cb == NULL)
+ {
+ gomp_debug (0, " thread: enabling callbacks\n");
+ goacc_lazy_initialize ();
+ struct goacc_thread *thr = goacc_thread ();
+ thr->prof_callbacks_enabled = true;
+ return;
+ }
+ /* Silently ignore. */
+ gomp_debug (0, " ignoring bogus request\n");
+ return;
+ }
+
+ gomp_mutex_lock (&goacc_prof_lock);
+
+ struct goacc_prof_callback_entry *it, *it_p;
+ it = goacc_prof_callback_entries[ev];
+ it_p = NULL;
+ while (it)
+ {
+ if (it->cb == cb)
+ break;
+ it_p = it;
+ it = it->next;
+ }
+
+ switch (reg)
+ {
+ case acc_reg:
+ /* If we already have this callback registered, just increment its
+ reference count. */
+ if (it != NULL)
+ {
+ it->ref++;
+ gomp_debug (0, " already registered;"
+ " incrementing reference count to: %d\n", it->ref);
+ }
+ else
+ {
+ struct goacc_prof_callback_entry *e
+ = gomp_malloc (sizeof (struct goacc_prof_callback_entry));
+ e->cb = cb;
+ e->ref = 1;
+ e->enabled = true;
+ bool prepend = (event_kind == EVENT_KIND_END);
+ /* If we don't have any callback registered yet, also use the
+ 'prepend' code path. */
+ if (it_p == NULL)
+ prepend = true;
+ if (prepend)
+ {
+ gomp_debug (0, " prepending\n");
+ e->next = goacc_prof_callback_entries[ev];
+ goacc_prof_callback_entries[ev] = e;
+ }
+ else
+ {
+ gomp_debug (0, " appending\n");
+ e->next = NULL;
+ it_p->next = e;
+ }
+ }
+ break;
+
+ case acc_toggle:
+ if (it == NULL)
+ {
+ gomp_debug (0, " ignoring request: is not registered\n");
+ break;
+ }
+ else
+ {
+ gomp_debug (0, " enabling\n");
+ it->enabled = true;
+ }
+ break;
+
+ case acc_toggle_per_thread:
+ __builtin_unreachable ();
+ }
+
+ gomp_mutex_unlock (&goacc_prof_lock);
+}
+
+void
+acc_prof_unregister (acc_event_t ev, acc_prof_callback cb, acc_register_t reg)
+{
+ gomp_debug (0, "%s: ev=%d, cb=%p, reg=%d\n",
+ __FUNCTION__, (int) ev, (void *) cb, (int) reg);
+
+ /* If profiling is not enabled, there cannot be anything to unregister. */
+ if (!GOACC_PROF_ENABLED)
+ return;
+
+ if (ev < acc_ev_none
+ || ev >= acc_ev_last)
+ {
+ /* Silently ignore. */
+ gomp_debug (0, " ignoring request for bogus 'acc_event_t'\n");
+ return;
+ }
+
+ bool bogus = true;
+ switch (reg)
+ {
+ case acc_reg:
+ case acc_toggle:
+ case acc_toggle_per_thread:
+ bogus = false;
+ break;
+ }
+ if (bogus)
+ {
+ /* Silently ignore. */
+ gomp_debug (0, " ignoring request with bogus 'acc_register_t'\n");
+ return;
+ }
+
+ /* Special cases. */
+ if (reg == acc_toggle)
+ {
+ if (cb == NULL)
+ {
+ gomp_debug (0, " globally disabling callbacks\n");
+ gomp_mutex_lock (&goacc_prof_lock);
+ /* For 'acc_ev_none', this acts as a global toggle. */
+ goacc_prof_callbacks_enabled[ev] = false;
+ gomp_mutex_unlock (&goacc_prof_lock);
+ return;
+ }
+ else if (ev == acc_ev_none && cb != NULL)
+ {
+ gomp_debug (0, " ignoring request\n");
+ return;
+ }
+ }
+ else if (reg == acc_toggle_per_thread)
+ {
+ if (ev == acc_ev_none && cb == NULL)
+ {
+ gomp_debug (0, " thread: disabling callbacks\n");
+ goacc_lazy_initialize ();
+ struct goacc_thread *thr = goacc_thread ();
+ thr->prof_callbacks_enabled = false;
+ return;
+ }
+ /* Silently ignore. */
+ gomp_debug (0, " ignoring bogus request\n");
+ return;
+ }
+
+ gomp_mutex_lock (&goacc_prof_lock);
+
+ struct goacc_prof_callback_entry *it, *it_p;
+ it = goacc_prof_callback_entries[ev];
+ it_p = NULL;
+ while (it)
+ {
+ if (it->cb == cb)
+ break;
+ it_p = it;
+ it = it->next;
+ }
+
+ switch (reg)
+ {
+ case acc_reg:
+ if (it == NULL)
+ {
+ /* Silently ignore. */
+ gomp_debug (0, " ignoring bogus request: is not registered\n");
+ break;
+ }
+ it->ref--;
+ gomp_debug (0, " decrementing reference count to: %d\n", it->ref);
+ if (it->ref == 0)
+ {
+ if (it_p == NULL)
+ goacc_prof_callback_entries[ev] = it->next;
+ else
+ it_p->next = it->next;
+ free (it);
+ }
+ break;
+
+ case acc_toggle:
+ if (it == NULL)
+ {
+ gomp_debug (0, " ignoring request: is not registered\n");
+ break;
+ }
+ else
+ {
+ gomp_debug (0, " disabling\n");
+ it->enabled = false;
+ }
+ break;
+
+ case acc_toggle_per_thread:
+ __builtin_unreachable ();
+ }
+
+ gomp_mutex_unlock (&goacc_prof_lock);
+}
+
+acc_query_fn
+acc_prof_lookup (const char *name)
+{
+ gomp_debug (0, "%s (%s)\n",
+ __FUNCTION__, name ?: "NULL");
+
+ return NULL;
+}
+
+void
+acc_register_library (acc_prof_reg reg, acc_prof_reg unreg,
+ acc_prof_lookup_func lookup)
+{
+ gomp_fatal ("TODO");
+}
+
+/* Prepare to dispatch events? */
+
+bool
+_goacc_profiling_dispatch_p (bool check_not_nested_p)
+{
+ gomp_debug (0, "%s\n", __FUNCTION__);
+
+ bool ret;
+
+ struct goacc_thread *thr = goacc_thread ();
+ if (__builtin_expect (thr == NULL, false))
+ {
+ /* If we don't have any per-thread state yet, that means that per-thread
+ callback dispatch has not been explicitly disabled (which only a call
+ to 'acc_prof_unregister' with 'acc_toggle_per_thread' would do, and
+ that would have allocated per-thread state via
+ 'goacc_lazy_initialize'); initially, all callbacks for all events are
+ enabled. */
+ gomp_debug (0, " %s: don't have any per-thread state yet\n", __FUNCTION__);
+ }
+ else
+ {
+ if (check_not_nested_p)
+ {
+ /* No nesting. */
+ assert (thr->prof_info == NULL);
+ assert (thr->api_info == NULL);
+ }
+
+ if (__builtin_expect (!thr->prof_callbacks_enabled, true))
+ {
+ gomp_debug (0, " %s: disabled for this thread\n", __FUNCTION__);
+ ret = false;
+ goto out;
+ }
+ }
+
+ gomp_mutex_lock (&goacc_prof_lock);
+
+ /* 'goacc_prof_callbacks_enabled[acc_ev_none]' acts as a global toggle. */
+ if (__builtin_expect (!goacc_prof_callbacks_enabled[acc_ev_none], true))
+ {
+ gomp_debug (0, " %s: disabled globally\n", __FUNCTION__);
+ ret = false;
+ goto out_unlock;
+ }
+ else
+ ret = true;
+
+ out_unlock:
+ gomp_mutex_unlock (&goacc_prof_lock);
+
+ out:
+ return ret;
+}
+
+/* Set up to dispatch events? */
+
+bool
+_goacc_profiling_setup_p (struct goacc_thread *thr,
+ acc_prof_info *prof_info, acc_api_info *api_info)
+{
+ gomp_debug (0, "%s (%p)\n", __FUNCTION__, thr);
+
+ /* If we don't have any per-thread state yet, we can't register 'prof_info'
+ and 'api_info'. */
+ if (__builtin_expect (thr == NULL, false))
+ {
+ gomp_debug (0, "Can't dispatch OpenACC Profiling Interface events for"
+ " the current call, construct, or directive\n");
+ return false;
+ }
+
+ if (thr->prof_info != NULL)
+ {
+ /* Profiling has already been set up for an outer construct. In this
+ case, we continue to use the existing information, and thus return
+ 'false' here.
+
+ This can happen, for example, for an 'enter data' directive, which
+ sets up profiling, then calls into 'acc_copyin', which should not
+ again set up profiling, should not overwrite the existing
+ information. */
+ return false;
+ }
+
+ thr->prof_info = prof_info;
+ thr->api_info = api_info;
+
+ /* Fill in some defaults. */
+
+ prof_info->event_type = -1; /* Must be set later. */
+ prof_info->valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
+ prof_info->version = _ACC_PROF_INFO_VERSION;
+ if (thr->dev)
+ {
+ prof_info->device_type = acc_device_type (thr->dev->type);
+ prof_info->device_number = thr->dev->target_id;
+ }
+ else
+ {
+ prof_info->device_type = -1;
+ prof_info->device_number = -1;
+ }
+ prof_info->thread_id = -1;
+ prof_info->async = acc_async_sync;
+ prof_info->async_queue = prof_info->async;
+ prof_info->src_file = NULL;
+ prof_info->func_name = NULL;
+ prof_info->line_no = -1;
+ prof_info->end_line_no = -1;
+ prof_info->func_line_no = -1;
+ prof_info->func_end_line_no = -1;
+
+ api_info->device_api = acc_device_api_none;
+ api_info->valid_bytes = _ACC_API_INFO_VALID_BYTES;
+ api_info->device_type = prof_info->device_type;
+ api_info->vendor = -1;
+ api_info->device_handle = NULL;
+ api_info->context_handle = NULL;
+ api_info->async_handle = NULL;
+
+ return true;
+}
+
+/* Dispatch events.
+
+ This must only be called if 'GOACC_PROFILING_DISPATCH_P' or
+ 'GOACC_PROFILING_SETUP_P' returned a true result. */
+
+void
+goacc_profiling_dispatch (acc_prof_info *prof_info, acc_event_info *event_info,
+ acc_api_info *apt_info)
+{
+ acc_event_t event_type = event_info->event_type;
+ gomp_debug (0, "%s: event_type=%d\n", __FUNCTION__, (int) event_type);
+ assert (event_type > acc_ev_none
+ && event_type < acc_ev_last);
+
+ gomp_mutex_lock (&goacc_prof_lock);
+
+ if (!goacc_prof_callbacks_enabled[event_type])
+ {
+ gomp_debug (0, " disabled for this event type\n");
+
+ goto out_unlock;
+ }
+
+ for (struct goacc_prof_callback_entry *e
+ = goacc_prof_callback_entries[event_type];
+ e != NULL;
+ e = e->next)
+ {
+ if (!e->enabled)
+ {
+ gomp_debug (0, " disabled for callback %p\n", e->cb);
+ continue;
+ }
+
+ gomp_debug (0, " calling callback %p\n", e->cb);
+ e->cb (prof_info, event_info, apt_info);
+ }
+
+ out_unlock:
+ gomp_mutex_unlock (&goacc_prof_lock);
+}
diff --git a/libgomp/oacc-target.c b/libgomp/oacc-target.c
new file mode 100644
index 00000000000..f2e79899030
--- /dev/null
+++ b/libgomp/oacc-target.c
@@ -0,0 +1 @@
+/* Nothing needed here. */
diff --git a/libgomp/omp.h.in b/libgomp/omp.h.in
index 654a4d5f42b..d7ac71400ad 100644
--- a/libgomp/omp.h.in
+++ b/libgomp/omp.h.in
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -50,7 +50,8 @@ typedef enum omp_sched_t
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
@@ -62,14 +63,32 @@ typedef enum omp_proc_bind_t
omp_proc_bind_spread = 4
} omp_proc_bind_t;
-typedef enum omp_lock_hint_t
+typedef enum omp_sync_hint_t
{
- omp_lock_hint_none = 0,
- omp_lock_hint_uncontended = 1,
- omp_lock_hint_contended = 2,
- omp_lock_hint_nonspeculative = 4,
- omp_lock_hint_speculative = 8,
-} omp_lock_hint_t;
+ omp_sync_hint_none = 0,
+ omp_lock_hint_none = omp_sync_hint_none,
+ omp_sync_hint_uncontended = 1,
+ omp_lock_hint_uncontended = omp_sync_hint_uncontended,
+ omp_sync_hint_contended = 2,
+ omp_lock_hint_contended = omp_sync_hint_contended,
+ omp_sync_hint_nonspeculative = 4,
+ omp_lock_hint_nonspeculative = omp_sync_hint_nonspeculative,
+ omp_sync_hint_speculative = 8,
+ omp_lock_hint_speculative = omp_sync_hint_speculative
+} omp_sync_hint_t;
+
+typedef omp_sync_hint_t omp_lock_hint_t;
+
+typedef struct __attribute__((__aligned__ (sizeof (void *)))) omp_depend_t
+{
+ char __omp_depend_t__[2 * sizeof (void *)];
+} omp_depend_t;
+
+typedef enum omp_pause_resource_t
+{
+ omp_pause_soft = 1,
+ omp_pause_hard = 2
+} omp_pause_resource_t;
#ifdef __cplusplus
extern "C" {
@@ -93,7 +112,7 @@ extern void omp_set_nested (int) __GOMP_NOTHROW;
extern int omp_get_nested (void) __GOMP_NOTHROW;
extern void omp_init_lock (omp_lock_t *) __GOMP_NOTHROW;
-extern void omp_init_lock_with_hint (omp_lock_t *, omp_lock_hint_t)
+extern void omp_init_lock_with_hint (omp_lock_t *, omp_sync_hint_t)
__GOMP_NOTHROW;
extern void omp_destroy_lock (omp_lock_t *) __GOMP_NOTHROW;
extern void omp_set_lock (omp_lock_t *) __GOMP_NOTHROW;
@@ -101,7 +120,7 @@ extern void omp_unset_lock (omp_lock_t *) __GOMP_NOTHROW;
extern int omp_test_lock (omp_lock_t *) __GOMP_NOTHROW;
extern void omp_init_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
-extern void omp_init_nest_lock_with_hint (omp_nest_lock_t *, omp_lock_hint_t)
+extern void omp_init_nest_lock_with_hint (omp_nest_lock_t *, omp_sync_hint_t)
__GOMP_NOTHROW;
extern void omp_destroy_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
extern void omp_set_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
@@ -144,19 +163,30 @@ extern int omp_get_max_task_priority (void) __GOMP_NOTHROW;
extern void *omp_target_alloc (__SIZE_TYPE__, int) __GOMP_NOTHROW;
extern void omp_target_free (void *, int) __GOMP_NOTHROW;
-extern int omp_target_is_present (void *, int) __GOMP_NOTHROW;
-extern int omp_target_memcpy (void *, void *, __SIZE_TYPE__, __SIZE_TYPE__,
- __SIZE_TYPE__, int, int) __GOMP_NOTHROW;
-extern int omp_target_memcpy_rect (void *, void *, __SIZE_TYPE__, int,
+extern int omp_target_is_present (const void *, int) __GOMP_NOTHROW;
+extern int omp_target_memcpy (void *, const void *, __SIZE_TYPE__,
+ __SIZE_TYPE__, __SIZE_TYPE__, int, int)
+ __GOMP_NOTHROW;
+extern int omp_target_memcpy_rect (void *, const void *, __SIZE_TYPE__, int,
const __SIZE_TYPE__ *,
const __SIZE_TYPE__ *,
const __SIZE_TYPE__ *,
const __SIZE_TYPE__ *,
const __SIZE_TYPE__ *, int, int)
__GOMP_NOTHROW;
-extern int omp_target_associate_ptr (void *, void *, __SIZE_TYPE__,
+extern int omp_target_associate_ptr (const void *, const void *, __SIZE_TYPE__,
__SIZE_TYPE__, int) __GOMP_NOTHROW;
-extern int omp_target_disassociate_ptr (void *, int) __GOMP_NOTHROW;
+extern int omp_target_disassociate_ptr (const void *, int) __GOMP_NOTHROW;
+
+extern void omp_set_affinity_format (const char *) __GOMP_NOTHROW;
+extern __SIZE_TYPE__ omp_get_affinity_format (char *, __SIZE_TYPE__)
+ __GOMP_NOTHROW;
+extern void omp_display_affinity (const char *) __GOMP_NOTHROW;
+extern __SIZE_TYPE__ omp_capture_affinity (char *, __SIZE_TYPE__, const char *)
+ __GOMP_NOTHROW;
+
+extern int omp_pause_resource (omp_pause_resource_t, int) __GOMP_NOTHROW;
+extern int omp_pause_resource_all (omp_pause_resource_t) __GOMP_NOTHROW;
#ifdef __cplusplus
}
diff --git a/libgomp/omp_lib.f90.in b/libgomp/omp_lib.f90.in
index eea33b893d6..c4e7c0dff4a 100644
--- a/libgomp/omp_lib.f90.in
+++ b/libgomp/omp_lib.f90.in
@@ -1,4 +1,4 @@
-! Copyright (C) 2005-2018 Free Software Foundation, Inc.
+! Copyright (C) 2005-2019 Free Software Foundation, Inc.
! Contributed by Jakub Jelinek <jakub@redhat.com>.
! This file is part of the GNU Offloading and Multi Processing Library
@@ -30,6 +30,7 @@
integer, parameter :: omp_sched_kind = 4
integer, parameter :: omp_proc_bind_kind = 4
integer, parameter :: omp_lock_hint_kind = 4
+ integer, parameter :: omp_pause_resource_kind = 4
integer (omp_sched_kind), parameter :: omp_sched_static = 1
integer (omp_sched_kind), parameter :: omp_sched_dynamic = 2
integer (omp_sched_kind), parameter :: omp_sched_guided = 3
@@ -54,6 +55,10 @@
parameter :: omp_lock_hint_nonspeculative = 4
integer (omp_lock_hint_kind), &
parameter :: omp_lock_hint_speculative = 8
+ integer (kind=omp_pause_resource_kind), &
+ parameter :: omp_pause_soft = 1
+ integer (kind=omp_pause_resource_kind), &
+ parameter :: omp_pause_hard = 2
end module
module omp_lib
@@ -433,4 +438,50 @@
end function omp_get_max_task_priority
end interface
+ interface
+ subroutine omp_set_affinity_format (format)
+ character(len=*), intent(in) :: format
+ end subroutine omp_set_affinity_format
+ end interface
+
+ interface
+ function omp_get_affinity_format (buffer)
+ integer (4) :: omp_get_affinity_format
+ character(len=*), intent(out) :: buffer
+ end function omp_get_affinity_format
+ end interface
+
+ interface
+ subroutine omp_display_affinity (format)
+ character(len=*), intent(in) :: format
+ end subroutine omp_display_affinity
+ end interface
+
+ interface
+ function omp_capture_affinity (buffer, format)
+ integer (4) :: omp_capture_affinity
+ character(len=*), intent(out) :: buffer
+ character(len=*), intent(in) :: format
+ end function omp_capture_affinity
+ end interface
+
+ interface
+ function omp_pause_resource (kind, device_num)
+ use omp_lib_kinds
+ integer (4) :: omp_pause_resource
+ integer (kind=omp_pause_resource_kind), &
+ intent(in) :: kind
+ integer (4) :: device_num
+ end function
+ end interface
+
+ interface
+ function omp_pause_resource_all (kind)
+ use omp_lib_kinds
+ integer (4) :: omp_pause_resource_all
+ integer (kind=omp_pause_resource_kind), &
+ intent(in) :: kind
+ end function
+ end interface
+
end module omp_lib
diff --git a/libgomp/omp_lib.h.in b/libgomp/omp_lib.h.in
index e57da94a2d5..a0fc04cc724 100644
--- a/libgomp/omp_lib.h.in
+++ b/libgomp/omp_lib.h.in
@@ -1,4 +1,4 @@
-! Copyright (C) 2005-2018 Free Software Foundation, Inc.
+! Copyright (C) 2005-2019 Free Software Foundation, Inc.
! Contributed by Jakub Jelinek <jakub@redhat.com>.
! This file is part of the GNU Offloading and Multi Processing Library
@@ -59,6 +59,12 @@
parameter (omp_lock_hint_nonspeculative = 4)
parameter (omp_lock_hint_speculative = 8)
parameter (openmp_version = 201511)
+ integer omp_pause_resource_kind
+ parameter (omp_pause_resource_kind = 4)
+ integer (omp_pause_resource_kind) omp_pause_soft
+ integer (omp_pause_resource_kind) omp_pause_hard
+ parameter (omp_pause_soft = 1)
+ parameter (omp_pause_hard = 2)
external omp_init_lock, omp_init_nest_lock
external omp_init_lock_with_hint
@@ -126,3 +132,12 @@
external omp_get_max_task_priority
integer(4) omp_get_max_task_priority
+
+ external omp_set_affinity_format, omp_get_affinity_format
+ external omp_display_affinity, omp_capture_affinity
+ integer(4) omp_get_affinity_format
+ integer(4) omp_capture_affinity
+
+ external omp_pause_resource, omp_pause_resource_all
+ integer(4) omp_pause_resource
+ integer(4) omp_pause_resource_all
diff --git a/libgomp/openacc.f90 b/libgomp/openacc.f90
index 84a8700f072..831a157e703 100644
--- a/libgomp/openacc.f90
+++ b/libgomp/openacc.f90
@@ -1,6 +1,6 @@
! OpenACC Runtime Library Definitions.
-! Copyright (C) 2014-2018 Free Software Foundation, Inc.
+! Copyright (C) 2014-2019 Free Software Foundation, Inc.
! Contributed by Tobias Burnus <burnus@net-b.de>
! and Mentor Embedded.
@@ -46,6 +46,7 @@ module openacc_kinds
! integer (acc_device_kind), parameter :: acc_device_host_nonshm = 3 removed.
integer (acc_device_kind), parameter :: acc_device_not_host = 4
integer (acc_device_kind), parameter :: acc_device_nvidia = 5
+ integer (acc_device_kind), parameter :: acc_device_gcn = 8
public :: acc_handle_kind
@@ -332,6 +333,150 @@ module openacc_internal
logical acc_is_present_array_h
type (*), dimension (..), contiguous :: a
end function
+
+ subroutine acc_copyin_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyin_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyin_async_array_h (a, async)
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_create_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_create_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_create_async_array_h (a, async)
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyout_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyout_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyout_async_array_h (a, async)
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_delete_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_delete_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_delete_async_array_h (a, async)
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_update_device_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_update_device_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_update_device_async_array_h (a, async)
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_update_self_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_update_self_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_update_self_async_array_h (a, async)
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ end subroutine
end interface
interface
@@ -510,6 +655,60 @@ module openacc_internal
type (*), dimension (*) :: a
integer (c_size_t), value :: len
end function
+
+ subroutine acc_copyin_async_l (a, len, async) &
+ bind (C, name = "acc_copyin_async")
+ use iso_c_binding, only: c_size_t, c_int
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_size_t), value :: len
+ integer (c_int), value :: async
+ end subroutine
+
+ subroutine acc_create_async_l (a, len, async) &
+ bind (C, name = "acc_create_async")
+ use iso_c_binding, only: c_size_t, c_int
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_size_t), value :: len
+ integer (c_int), value :: async
+ end subroutine
+
+ subroutine acc_copyout_async_l (a, len, async) &
+ bind (C, name = "acc_copyout_async")
+ use iso_c_binding, only: c_size_t, c_int
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_size_t), value :: len
+ integer (c_int), value :: async
+ end subroutine
+
+ subroutine acc_delete_async_l (a, len, async) &
+ bind (C, name = "acc_delete_async")
+ use iso_c_binding, only: c_size_t, c_int
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_size_t), value :: len
+ integer (c_int), value :: async
+ end subroutine
+
+ subroutine acc_update_device_async_l (a, len, async) &
+ bind (C, name = "acc_update_device_async")
+ use iso_c_binding, only: c_size_t, c_int
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_size_t), value :: len
+ integer (c_int), value :: async
+ end subroutine
+
+ subroutine acc_update_self_async_l (a, len, async) &
+ bind (C, name = "acc_update_self_async")
+ use iso_c_binding, only: c_size_t, c_int
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_size_t), value :: len
+ integer (c_int), value :: async
+ end subroutine
end interface
end module
@@ -529,6 +728,8 @@ module openacc
public :: acc_copyin, acc_present_or_copyin, acc_pcopyin, acc_create
public :: acc_present_or_create, acc_pcreate, acc_copyout, acc_delete
public :: acc_update_device, acc_update_self, acc_is_present
+ public :: acc_copyin_async, acc_create_async, acc_copyout_async
+ public :: acc_delete_async, acc_update_device_async, acc_update_self_async
integer, parameter :: openacc_version = 201306
@@ -694,6 +895,42 @@ module openacc
! acc_memcpy_to_device: Only available in C/C++
! acc_memcpy_from_device: Only available in C/C++
+ interface acc_copyin_async
+ procedure :: acc_copyin_async_32_h
+ procedure :: acc_copyin_async_64_h
+ procedure :: acc_copyin_async_array_h
+ end interface
+
+ interface acc_create_async
+ procedure :: acc_create_async_32_h
+ procedure :: acc_create_async_64_h
+ procedure :: acc_create_async_array_h
+ end interface
+
+ interface acc_copyout_async
+ procedure :: acc_copyout_async_32_h
+ procedure :: acc_copyout_async_64_h
+ procedure :: acc_copyout_async_array_h
+ end interface
+
+ interface acc_delete_async
+ procedure :: acc_delete_async_32_h
+ procedure :: acc_delete_async_64_h
+ procedure :: acc_delete_async_array_h
+ end interface
+
+ interface acc_update_device_async
+ procedure :: acc_update_device_async_32_h
+ procedure :: acc_update_device_async_64_h
+ procedure :: acc_update_device_async_array_h
+ end interface
+
+ interface acc_update_self_async
+ procedure :: acc_update_self_async_32_h
+ procedure :: acc_update_self_async_64_h
+ procedure :: acc_update_self_async_array_h
+ end interface
+
end module
function acc_get_num_devices_h (d)
@@ -1078,3 +1315,189 @@ function acc_is_present_array_h (a)
type (*), dimension (..), contiguous :: a
acc_is_present_array_h = acc_is_present_l (a, sizeof (a)) == 1
end function
+
+subroutine acc_copyin_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t, c_size_t, c_int
+ use openacc_internal, only: acc_copyin_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ call acc_copyin_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_copyin_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t, c_size_t, c_int
+ use openacc_internal, only: acc_copyin_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ call acc_copyin_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_copyin_async_array_h (a, async)
+ use iso_c_binding, only: c_int
+ use openacc_internal, only: acc_copyin_async_l
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ call acc_copyin_async_l (a, sizeof (a), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_create_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t, c_size_t, c_int
+ use openacc_internal, only: acc_create_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ call acc_create_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_create_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t, c_size_t, c_int
+ use openacc_internal, only: acc_create_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ call acc_create_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_create_async_array_h (a, async)
+ use iso_c_binding, only: c_int
+ use openacc_internal, only: acc_create_async_l
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ call acc_create_async_l (a, sizeof (a), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_copyout_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t, c_size_t, c_int
+ use openacc_internal, only: acc_copyout_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ call acc_copyout_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_copyout_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t, c_size_t, c_int
+ use openacc_internal, only: acc_copyout_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ call acc_copyout_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_copyout_async_array_h (a, async)
+ use iso_c_binding, only: c_int
+ use openacc_internal, only: acc_copyout_async_l
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ call acc_copyout_async_l (a, sizeof (a), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_delete_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t, c_size_t, c_int
+ use openacc_internal, only: acc_delete_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ call acc_delete_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_delete_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t, c_size_t, c_int
+ use openacc_internal, only: acc_delete_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ call acc_delete_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_delete_async_array_h (a, async)
+ use iso_c_binding, only: c_int
+ use openacc_internal, only: acc_delete_async_l
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ call acc_delete_async_l (a, sizeof (a), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_update_device_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t, c_size_t, c_int
+ use openacc_internal, only: acc_update_device_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ call acc_update_device_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_update_device_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t, c_size_t, c_int
+ use openacc_internal, only: acc_update_device_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ call acc_update_device_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_update_device_async_array_h (a, async)
+ use iso_c_binding, only: c_int
+ use openacc_internal, only: acc_update_device_async_l
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ call acc_update_device_async_l (a, sizeof (a), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_update_self_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t, c_size_t, c_int
+ use openacc_internal, only: acc_update_self_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ call acc_update_self_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_update_self_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t, c_size_t, c_int
+ use openacc_internal, only: acc_update_self_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ call acc_update_self_async_l (a, int (len, kind = c_size_t), int (async, kind = c_int))
+end subroutine
+
+subroutine acc_update_self_async_array_h (a, async)
+ use iso_c_binding, only: c_int
+ use openacc_internal, only: acc_update_self_async_l
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ call acc_update_self_async_l (a, sizeof (a), int (async, kind = c_int))
+end subroutine
diff --git a/libgomp/openacc.h b/libgomp/openacc.h
index 02a85a09ddb..42c861caabf 100644
--- a/libgomp/openacc.h
+++ b/libgomp/openacc.h
@@ -1,6 +1,6 @@
/* OpenACC Runtime Library User-facing Declarations
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -55,6 +55,7 @@ typedef enum acc_device_t {
/* acc_device_host_nonshm = 3 removed. */
acc_device_not_host = 4,
acc_device_nvidia = 5,
+ acc_device_gcn = 8,
_ACC_device_hwm,
/* Ensure enumeration is layout compatible with int. */
_ACC_highest = __INT_MAX__,
@@ -115,6 +116,16 @@ void acc_copyout_finalize_async (void *, size_t, int) __GOACC_NOTHROW;
void acc_delete_finalize (void *, size_t) __GOACC_NOTHROW;
void acc_delete_finalize_async (void *, size_t, int) __GOACC_NOTHROW;
+/* Async functions, specified in OpenACC 2.5. */
+void acc_copyin_async (void *, size_t, int) __GOACC_NOTHROW;
+void acc_create_async (void *, size_t, int) __GOACC_NOTHROW;
+void acc_copyout_async (void *, size_t, int) __GOACC_NOTHROW;
+void acc_delete_async (void *, size_t, int) __GOACC_NOTHROW;
+void acc_update_device_async (void *, size_t, int) __GOACC_NOTHROW;
+void acc_update_self_async (void *, size_t, int) __GOACC_NOTHROW;
+void acc_memcpy_to_device_async (void *, void *, size_t, int) __GOACC_NOTHROW;
+void acc_memcpy_from_device_async (void *, void *, size_t, int) __GOACC_NOTHROW;
+
/* CUDA-specific routines. */
void *acc_get_current_cuda_device (void) __GOACC_NOTHROW;
void *acc_get_current_cuda_context (void) __GOACC_NOTHROW;
diff --git a/libgomp/openacc_lib.h b/libgomp/openacc_lib.h
index 737c582041d..fbd8f5e3625 100644
--- a/libgomp/openacc_lib.h
+++ b/libgomp/openacc_lib.h
@@ -1,6 +1,6 @@
! OpenACC Runtime Library Definitions. -*- mode: fortran -*-
-! Copyright (C) 2014-2018 Free Software Foundation, Inc.
+! Copyright (C) 2014-2019 Free Software Foundation, Inc.
! Contributed by Tobias Burnus <burnus@net-b.de>
! and Mentor Embedded.
@@ -403,3 +403,159 @@
! acc_memcpy_to_device: Only available in C/C++
! acc_memcpy_from_device: Only available in C/C++
+
+ interface acc_copyin_async
+ subroutine acc_copyin_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyin_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyin_async_array_h (a, async_)
+ import acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async_
+ end subroutine
+ end interface
+
+ interface acc_create_async
+ subroutine acc_create_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_create_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_create_async_array_h (a, async_)
+ import acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async_
+ end subroutine
+ end interface
+
+ interface acc_copyout_async
+ subroutine acc_copyout_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyout_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyout_async_array_h (a, async_)
+ import acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async_
+ end subroutine
+ end interface
+
+ interface acc_delete_async
+ subroutine acc_delete_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_delete_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_delete_async_array_h (a, async_)
+ import acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async_
+ end subroutine
+ end interface
+
+ interface acc_update_device_async
+ subroutine acc_update_device_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_update_device_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_update_device_async_array_h (a, async_)
+ import acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async_
+ end subroutine
+ end interface
+
+ interface acc_update_self_async
+ subroutine acc_update_self_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_update_self_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ import acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_update_self_async_array_h (a, async_)
+ import acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async_
+ end subroutine
+ end interface
diff --git a/libgomp/ordered.c b/libgomp/ordered.c
index 1bdd5b2f25b..6d07fd445d3 100644
--- a/libgomp/ordered.c
+++ b/libgomp/ordered.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -259,7 +259,8 @@ GOMP_ordered_end (void)
#define MAX_COLLAPSED_BITS (__SIZEOF_LONG__ * __CHAR_BIT__)
void
-gomp_doacross_init (unsigned ncounts, long *counts, long chunk_size)
+gomp_doacross_init (unsigned ncounts, long *counts, long chunk_size,
+ size_t extra)
{
struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr->ts.team;
@@ -269,13 +270,24 @@ gomp_doacross_init (unsigned ncounts, long *counts, long chunk_size)
struct gomp_doacross_work_share *doacross;
if (team == NULL || team->nthreads == 1)
- return;
+ {
+ empty:
+ if (!extra)
+ ws->doacross = NULL;
+ else
+ {
+ doacross = gomp_malloc_cleared (sizeof (*doacross) + extra);
+ doacross->extra = (void *) (doacross + 1);
+ ws->doacross = doacross;
+ }
+ return;
+ }
for (i = 0; i < ncounts; i++)
{
/* If any count is 0, GOMP_doacross_{post,wait} can't be called. */
if (counts[i] == 0)
- return;
+ goto empty;
if (num_bits <= MAX_COLLAPSED_BITS)
{
@@ -314,7 +326,7 @@ gomp_doacross_init (unsigned ncounts, long *counts, long chunk_size)
elt_sz = (elt_sz + 63) & ~63UL;
doacross = gomp_malloc (sizeof (*doacross) + 63 + num_ents * elt_sz
- + shift_sz);
+ + shift_sz + extra);
doacross->chunk_size = chunk_size;
doacross->elt_sz = elt_sz;
doacross->ncounts = ncounts;
@@ -322,6 +334,13 @@ gomp_doacross_init (unsigned ncounts, long *counts, long chunk_size)
doacross->array = (unsigned char *)
((((uintptr_t) (doacross + 1)) + 63 + shift_sz)
& ~(uintptr_t) 63);
+ if (extra)
+ {
+ doacross->extra = doacross->array + num_ents * elt_sz;
+ memset (doacross->extra, '\0', extra);
+ }
+ else
+ doacross->extra = NULL;
if (num_bits <= MAX_COLLAPSED_BITS)
{
unsigned int shift_count = 0;
@@ -360,7 +379,8 @@ GOMP_doacross_post (long *counts)
unsigned long ent;
unsigned int i;
- if (__builtin_expect (doacross == NULL, 0))
+ if (__builtin_expect (doacross == NULL, 0)
+ || __builtin_expect (doacross->array == NULL, 0))
{
__sync_synchronize ();
return;
@@ -411,7 +431,8 @@ GOMP_doacross_wait (long first, ...)
unsigned long ent;
unsigned int i;
- if (__builtin_expect (doacross == NULL, 0))
+ if (__builtin_expect (doacross == NULL, 0)
+ || __builtin_expect (doacross->array == NULL, 0))
{
__sync_synchronize ();
return;
@@ -488,7 +509,8 @@ GOMP_doacross_wait (long first, ...)
typedef unsigned long long gomp_ull;
void
-gomp_doacross_ull_init (unsigned ncounts, gomp_ull *counts, gomp_ull chunk_size)
+gomp_doacross_ull_init (unsigned ncounts, gomp_ull *counts,
+ gomp_ull chunk_size, size_t extra)
{
struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr->ts.team;
@@ -498,13 +520,24 @@ gomp_doacross_ull_init (unsigned ncounts, gomp_ull *counts, gomp_ull chunk_size)
struct gomp_doacross_work_share *doacross;
if (team == NULL || team->nthreads == 1)
- return;
+ {
+ empty:
+ if (!extra)
+ ws->doacross = NULL;
+ else
+ {
+ doacross = gomp_malloc_cleared (sizeof (*doacross) + extra);
+ doacross->extra = (void *) (doacross + 1);
+ ws->doacross = doacross;
+ }
+ return;
+ }
for (i = 0; i < ncounts; i++)
{
/* If any count is 0, GOMP_doacross_{post,wait} can't be called. */
if (counts[i] == 0)
- return;
+ goto empty;
if (num_bits <= MAX_COLLAPSED_BITS)
{
@@ -557,6 +590,13 @@ gomp_doacross_ull_init (unsigned ncounts, gomp_ull *counts, gomp_ull chunk_size)
doacross->array = (unsigned char *)
((((uintptr_t) (doacross + 1)) + 63 + shift_sz)
& ~(uintptr_t) 63);
+ if (extra)
+ {
+ doacross->extra = doacross->array + num_ents * elt_sz;
+ memset (doacross->extra, '\0', extra);
+ }
+ else
+ doacross->extra = NULL;
if (num_bits <= MAX_COLLAPSED_BITS)
{
unsigned int shift_count = 0;
@@ -595,7 +635,8 @@ GOMP_doacross_ull_post (gomp_ull *counts)
unsigned long ent;
unsigned int i;
- if (__builtin_expect (doacross == NULL, 0))
+ if (__builtin_expect (doacross == NULL, 0)
+ || __builtin_expect (doacross->array == NULL, 0))
{
__sync_synchronize ();
return;
@@ -667,7 +708,8 @@ GOMP_doacross_ull_wait (gomp_ull first, ...)
unsigned long ent;
unsigned int i;
- if (__builtin_expect (doacross == NULL, 0))
+ if (__builtin_expect (doacross == NULL, 0)
+ || __builtin_expect (doacross->array == NULL, 0))
{
__sync_synchronize ();
return;
diff --git a/libgomp/parallel.c b/libgomp/parallel.c
index 803e8b770c8..7173883b2c1 100644
--- a/libgomp/parallel.c
+++ b/libgomp/parallel.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -123,7 +123,8 @@ void
GOMP_parallel_start (void (*fn) (void *), void *data, unsigned num_threads)
{
num_threads = gomp_resolve_num_threads (num_threads, 0);
- gomp_team_start (fn, data, num_threads, 0, gomp_new_team (num_threads));
+ gomp_team_start (fn, data, num_threads, 0, gomp_new_team (num_threads),
+ NULL);
}
void
@@ -161,14 +162,33 @@ GOMP_parallel_end (void)
ialias (GOMP_parallel_end)
void
-GOMP_parallel (void (*fn) (void *), void *data, unsigned num_threads, unsigned int flags)
+GOMP_parallel (void (*fn) (void *), void *data, unsigned num_threads,
+ unsigned int flags)
{
num_threads = gomp_resolve_num_threads (num_threads, 0);
- gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads));
+ gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads),
+ NULL);
fn (data);
ialias_call (GOMP_parallel_end) ();
}
+unsigned
+GOMP_parallel_reductions (void (*fn) (void *), void *data,
+ unsigned num_threads, unsigned int flags)
+{
+ struct gomp_taskgroup *taskgroup;
+ num_threads = gomp_resolve_num_threads (num_threads, 0);
+ uintptr_t *rdata = *(uintptr_t **)data;
+ taskgroup = gomp_parallel_reduction_register (rdata, num_threads);
+ gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads),
+ taskgroup);
+ fn (data);
+ ialias_call (GOMP_parallel_end) ();
+ gomp_sem_destroy (&taskgroup->taskgroup_sem);
+ free (taskgroup);
+ return num_threads;
+}
+
bool
GOMP_cancellation_point (int which)
{
@@ -185,8 +205,15 @@ GOMP_cancellation_point (int which)
}
else if (which & GOMP_CANCEL_TASKGROUP)
{
- if (thr->task->taskgroup && thr->task->taskgroup->cancelled)
- return true;
+ if (thr->task->taskgroup)
+ {
+ if (thr->task->taskgroup->cancelled)
+ return true;
+ if (thr->task->taskgroup->workshare
+ && thr->task->taskgroup->prev
+ && thr->task->taskgroup->prev->cancelled)
+ return true;
+ }
/* FALLTHRU into the GOMP_CANCEL_PARALLEL case,
as #pragma omp cancel parallel also cancels all explicit
tasks. */
@@ -218,11 +245,17 @@ GOMP_cancel (int which, bool do_cancel)
}
else if (which & GOMP_CANCEL_TASKGROUP)
{
- if (thr->task->taskgroup && !thr->task->taskgroup->cancelled)
+ if (thr->task->taskgroup)
{
- gomp_mutex_lock (&team->task_lock);
- thr->task->taskgroup->cancelled = true;
- gomp_mutex_unlock (&team->task_lock);
+ struct gomp_taskgroup *taskgroup = thr->task->taskgroup;
+ if (taskgroup->workshare && taskgroup->prev)
+ taskgroup = taskgroup->prev;
+ if (!taskgroup->cancelled)
+ {
+ gomp_mutex_lock (&team->task_lock);
+ taskgroup->cancelled = true;
+ gomp_mutex_unlock (&team->task_lock);
+ }
}
return true;
}
diff --git a/libgomp/plugin/Makefrag.am b/libgomp/plugin/Makefrag.am
index 5c8e8062987..45ed043e333 100644
--- a/libgomp/plugin/Makefrag.am
+++ b/libgomp/plugin/Makefrag.am
@@ -1,6 +1,6 @@
# Plugins for offload execution, Makefile.am fragment.
#
-# Copyright (C) 2014-2018 Free Software Foundation, Inc.
+# Copyright (C) 2014-2019 Free Software Foundation, Inc.
#
# Contributed by Mentor Embedded.
#
@@ -52,3 +52,17 @@ libgomp_plugin_hsa_la_LDFLAGS += $(PLUGIN_HSA_LDFLAGS)
libgomp_plugin_hsa_la_LIBADD = libgomp.la $(PLUGIN_HSA_LIBS)
libgomp_plugin_hsa_la_LIBTOOLFLAGS = --tag=disable-static
endif
+
+if PLUGIN_GCN
+# AMD GCN plugin
+libgomp_plugin_gcn_version_info = -version-info $(libtool_VERSION)
+toolexeclib_LTLIBRARIES += libgomp-plugin-gcn.la
+libgomp_plugin_gcn_la_SOURCES = plugin/plugin-gcn.c
+libgomp_plugin_gcn_la_CPPFLAGS = $(AM_CPPFLAGS) $(PLUGIN_GCN_CPPFLAGS) \
+ -D_GNU_SOURCE
+libgomp_plugin_gcn_la_LDFLAGS = $(libgomp_plugin_gcn_version_info) \
+ $(lt_host_flags)
+libgomp_plugin_gcn_la_LDFLAGS += $(PLUGIN_GCN_LDFLAGS)
+libgomp_plugin_gcn_la_LIBADD = libgomp.la $(PLUGIN_GCN_LIBS)
+libgomp_plugin_gcn_la_LIBTOOLFLAGS = --tag=disable-static
+endif
diff --git a/libgomp/plugin/configfrag.ac b/libgomp/plugin/configfrag.ac
index 864817d44d1..424ec6c96b2 100644
--- a/libgomp/plugin/configfrag.ac
+++ b/libgomp/plugin/configfrag.ac
@@ -1,6 +1,6 @@
# Plugins for offload execution, configure.ac fragment. -*- mode: autoconf -*-
#
-# Copyright (C) 2014-2018 Free Software Foundation, Inc.
+# Copyright (C) 2014-2019 Free Software Foundation, Inc.
#
# Contributed by Mentor Embedded.
#
@@ -26,8 +26,6 @@
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# <http://www.gnu.org/licenses/>.
-offload_targets=
-AC_SUBST(offload_targets)
plugin_support=yes
AC_CHECK_LIB(dl, dlsym, , [plugin_support=no])
if test x"$plugin_support" = xyes; then
@@ -59,7 +57,11 @@ AC_ARG_WITH(cuda-driver-lib,
[AS_HELP_STRING([--with-cuda-driver-lib=PATH],
[specify directory for the installed CUDA driver library])])
case "x$with_cuda_driver" in
- x | xno) ;;
+ x) ;;
+ xno)
+ CUDA_DRIVER_INCLUDE=no
+ CUDA_DRIVER_LIB=no
+ ;;
*) CUDA_DRIVER_INCLUDE=$with_cuda_driver/include
CUDA_DRIVER_LIB=$with_cuda_driver/lib
;;
@@ -70,10 +72,12 @@ fi
if test "x$with_cuda_driver_lib" != x; then
CUDA_DRIVER_LIB=$with_cuda_driver_lib
fi
-if test "x$CUDA_DRIVER_INCLUDE" != x; then
+if test "x$CUDA_DRIVER_INCLUDE" != x \
+ && test "x$CUDA_DRIVER_INCLUDE" != xno; then
CUDA_DRIVER_CPPFLAGS=-I$CUDA_DRIVER_INCLUDE
fi
-if test "x$CUDA_DRIVER_LIB" != x; then
+if test "x$CUDA_DRIVER_LIB" != x \
+ && test "x$CUDA_DRIVER_LIB" != xno; then
CUDA_DRIVER_LDFLAGS=-L$CUDA_DRIVER_LIB
fi
@@ -133,7 +137,22 @@ AC_SUBST(PLUGIN_HSA_CPPFLAGS)
AC_SUBST(PLUGIN_HSA_LDFLAGS)
AC_SUBST(PLUGIN_HSA_LIBS)
-# Get offload targets and path to install tree of offloading compiler.
+PLUGIN_GCN=0
+PLUGIN_GCN_CPPFLAGS=
+PLUGIN_GCN_LDFLAGS=
+PLUGIN_GCN_LIBS=
+AC_SUBST(PLUGIN_GCN)
+AC_SUBST(PLUGIN_GCN_CPPFLAGS)
+AC_SUBST(PLUGIN_GCN_LDFLAGS)
+AC_SUBST(PLUGIN_GCN_LIBS)
+
+# Parse '--enable-offload-targets', figure out the corresponding libgomp
+# plugins, and configure to find the corresponding offload compilers.
+# 'offload_plugins' and 'offload_targets' will be populated in the same order.
+offload_plugins=
+offload_targets=
+AC_SUBST(offload_plugins)
+AC_SUBST(offload_targets)
offload_additional_options=
offload_additional_lib_paths=
AC_SUBST(offload_additional_options)
@@ -142,36 +161,41 @@ if test x"$enable_offload_targets" != x; then
for tgt in `echo $enable_offload_targets | sed -e 's#,# #g'`; do
tgt_dir=`echo $tgt | grep '=' | sed 's/.*=//'`
tgt=`echo $tgt | sed 's/=.*//'`
- tgt_name=
+ tgt_plugin=
case $tgt in
*-intelmic-* | *-intelmicemul-*)
- tgt_name=intelmic
+ tgt_plugin=intelmic
;;
nvptx*)
- tgt_name=nvptx
+ tgt_plugin=nvptx
PLUGIN_NVPTX=$tgt
- PLUGIN_NVPTX_CPPFLAGS=$CUDA_DRIVER_CPPFLAGS
- PLUGIN_NVPTX_LDFLAGS=$CUDA_DRIVER_LDFLAGS
- PLUGIN_NVPTX_LIBS='-lcuda'
+ if test "x$CUDA_DRIVER_LIB" != xno \
+ && test "x$CUDA_DRIVER_LIB" != xno; then
+ PLUGIN_NVPTX_CPPFLAGS=$CUDA_DRIVER_CPPFLAGS
+ PLUGIN_NVPTX_LDFLAGS=$CUDA_DRIVER_LDFLAGS
+ PLUGIN_NVPTX_LIBS='-lcuda'
- PLUGIN_NVPTX_save_CPPFLAGS=$CPPFLAGS
- CPPFLAGS="$PLUGIN_NVPTX_CPPFLAGS $CPPFLAGS"
- PLUGIN_NVPTX_save_LDFLAGS=$LDFLAGS
- LDFLAGS="$PLUGIN_NVPTX_LDFLAGS $LDFLAGS"
- PLUGIN_NVPTX_save_LIBS=$LIBS
- LIBS="$PLUGIN_NVPTX_LIBS $LIBS"
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [#include "cuda.h"],
- [CUresult r = cuCtxPushCurrent (NULL);])],
- [PLUGIN_NVPTX=1])
- CPPFLAGS=$PLUGIN_NVPTX_save_CPPFLAGS
- LDFLAGS=$PLUGIN_NVPTX_save_LDFLAGS
- LIBS=$PLUGIN_NVPTX_save_LIBS
+ PLUGIN_NVPTX_save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$PLUGIN_NVPTX_CPPFLAGS $CPPFLAGS"
+ PLUGIN_NVPTX_save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$PLUGIN_NVPTX_LDFLAGS $LDFLAGS"
+ PLUGIN_NVPTX_save_LIBS=$LIBS
+ LIBS="$PLUGIN_NVPTX_LIBS $LIBS"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include "cuda.h"],
+ [CUresult r = cuCtxPushCurrent (NULL);])],
+ [PLUGIN_NVPTX=1])
+ CPPFLAGS=$PLUGIN_NVPTX_save_CPPFLAGS
+ LDFLAGS=$PLUGIN_NVPTX_save_LDFLAGS
+ LIBS=$PLUGIN_NVPTX_save_LIBS
+ fi
case $PLUGIN_NVPTX in
nvptx*)
- if test "x$CUDA_DRIVER_INCLUDE" = x \
- && test "x$CUDA_DRIVER_LIB" = x; then
+ if (test "x$CUDA_DRIVER_INCLUDE" = x \
+ || test "x$CUDA_DRIVER_INCLUDE" = xno) \
+ && (test "x$CUDA_DRIVER_LIB" = x \
+ || test "x$CUDA_DRIVER_LIB" = xno); then
PLUGIN_NVPTX=1
PLUGIN_NVPTX_CPPFLAGS='-I$(srcdir)/plugin/cuda'
PLUGIN_NVPTX_LIBS='-ldl'
@@ -191,7 +215,7 @@ if test x"$enable_offload_targets" != x; then
PLUGIN_HSA=0
;;
*)
- tgt_name=hsa
+ tgt_plugin=hsa
PLUGIN_HSA=$tgt
PLUGIN_HSA_CPPFLAGS=$HSA_RUNTIME_CPPFLAGS
PLUGIN_HSA_LDFLAGS="$HSA_RUNTIME_LDFLAGS"
@@ -209,7 +233,7 @@ if test x"$enable_offload_targets" != x; then
LDFLAGS=$PLUGIN_HSA_save_LDFLAGS
LIBS=$PLUGIN_HSA_save_LIBS
case $PLUGIN_HSA in
- hsa*)
+ hsa*)
HSA_PLUGIN=0
AC_MSG_ERROR([HSA run-time package required for HSA support])
;;
@@ -222,20 +246,46 @@ if test x"$enable_offload_targets" != x; then
;;
esac
;;
+
+ amdgcn*)
+ case "${target}" in
+ x86_64-*-*)
+ case " ${CC} ${CFLAGS} " in
+ *" -m32 "*)
+ PLUGIN_GCN=0
+ ;;
+ *)
+ tgt_plugin=gcn
+ PLUGIN_GCN=$tgt
+ PLUGIN_GCN_CPPFLAGS=$HSA_RUNTIME_CPPFLAGS
+ PLUGIN_GCN_LDFLAGS="$HSA_RUNTIME_LDFLAGS"
+ PLUGIN_GCN_LIBS="-ldl"
+ PLUGIN_GCN=1
+ ;;
+ esac
+ ;;
+ *-*-*)
+ PLUGIN_GCN=0
+ ;;
+ esac
+ ;;
*)
AC_MSG_ERROR([unknown offload target specified])
;;
esac
- if test x"$tgt_name" = x; then
- # Don't configure libgomp for this offloading target if we don't build
- # the corresponding plugin.
+ if test x"$tgt_plugin" = x; then
+ # Not configuring libgomp for this offload target if we're not building
+ # the corresponding offload plugin.
continue
- elif test x"$offload_targets" = x; then
- offload_targets=$tgt_name
+ elif test x"$offload_plugins" = x; then
+ offload_plugins=$tgt_plugin
+ offload_targets=$tgt
else
- offload_targets=$offload_targets,$tgt_name
+ offload_plugins=$offload_plugins,$tgt_plugin
+ offload_targets=$offload_targets,$tgt
fi
- if test "$tgt_name" = hsa; then
+ # Configure additional search paths.
+ if test "$tgt_plugin" = hsa; then
# Offloading compilation is all handled by the target compiler.
:
elif test x"$tgt_dir" != x; then
@@ -247,8 +297,8 @@ if test x"$enable_offload_targets" != x; then
fi
done
fi
-AC_DEFINE_UNQUOTED(OFFLOAD_TARGETS, "$offload_targets",
- [Define to offload targets, separated by commas.])
+AC_DEFINE_UNQUOTED(OFFLOAD_PLUGINS, "$offload_plugins",
+ [Define to offload plugins, separated by commas.])
AM_CONDITIONAL([PLUGIN_NVPTX], [test $PLUGIN_NVPTX = 1])
AC_DEFINE_UNQUOTED([PLUGIN_NVPTX], [$PLUGIN_NVPTX],
[Define to 1 if the NVIDIA plugin is built, 0 if not.])
@@ -257,6 +307,9 @@ AC_DEFINE_UNQUOTED([PLUGIN_NVPTX_DYNAMIC], [$PLUGIN_NVPTX_DYNAMIC],
AM_CONDITIONAL([PLUGIN_HSA], [test $PLUGIN_HSA = 1])
AC_DEFINE_UNQUOTED([PLUGIN_HSA], [$PLUGIN_HSA],
[Define to 1 if the HSA plugin is built, 0 if not.])
+AM_CONDITIONAL([PLUGIN_GCN], [test $PLUGIN_GCN = 1])
+AC_DEFINE_UNQUOTED([PLUGIN_GCN], [$PLUGIN_GCN],
+ [Define to 1 if the GCN plugin is built, 0 if not.])
if test "$HSA_RUNTIME_LIB" != ""; then
HSA_RUNTIME_LIB="$HSA_RUNTIME_LIB/"
diff --git a/libgomp/plugin/cuda-lib.def b/libgomp/plugin/cuda-lib.def
new file mode 100644
index 00000000000..a16badcfa9d
--- /dev/null
+++ b/libgomp/plugin/cuda-lib.def
@@ -0,0 +1,50 @@
+CUDA_ONE_CALL (cuCtxCreate)
+CUDA_ONE_CALL (cuCtxDestroy)
+CUDA_ONE_CALL (cuCtxGetCurrent)
+CUDA_ONE_CALL (cuCtxGetDevice)
+CUDA_ONE_CALL (cuCtxPopCurrent)
+CUDA_ONE_CALL (cuCtxPushCurrent)
+CUDA_ONE_CALL (cuCtxSynchronize)
+CUDA_ONE_CALL (cuDeviceGet)
+CUDA_ONE_CALL (cuDeviceGetAttribute)
+CUDA_ONE_CALL (cuDeviceGetCount)
+CUDA_ONE_CALL (cuEventCreate)
+CUDA_ONE_CALL (cuEventDestroy)
+CUDA_ONE_CALL (cuEventElapsedTime)
+CUDA_ONE_CALL (cuEventQuery)
+CUDA_ONE_CALL (cuEventRecord)
+CUDA_ONE_CALL (cuEventSynchronize)
+CUDA_ONE_CALL (cuFuncGetAttribute)
+CUDA_ONE_CALL_MAYBE_NULL (cuGetErrorString)
+CUDA_ONE_CALL (cuInit)
+CUDA_ONE_CALL (cuLaunchKernel)
+CUDA_ONE_CALL (cuLinkAddData)
+CUDA_ONE_CALL_MAYBE_NULL (cuLinkAddData_v2)
+CUDA_ONE_CALL (cuLinkComplete)
+CUDA_ONE_CALL (cuLinkCreate)
+CUDA_ONE_CALL_MAYBE_NULL (cuLinkCreate_v2)
+CUDA_ONE_CALL (cuLinkDestroy)
+CUDA_ONE_CALL (cuMemAlloc)
+CUDA_ONE_CALL (cuMemAllocHost)
+CUDA_ONE_CALL (cuMemcpy)
+CUDA_ONE_CALL (cuMemcpyDtoDAsync)
+CUDA_ONE_CALL (cuMemcpyDtoH)
+CUDA_ONE_CALL (cuMemcpyDtoHAsync)
+CUDA_ONE_CALL (cuMemcpyHtoD)
+CUDA_ONE_CALL (cuMemcpyHtoDAsync)
+CUDA_ONE_CALL (cuMemFree)
+CUDA_ONE_CALL (cuMemFreeHost)
+CUDA_ONE_CALL (cuMemGetAddressRange)
+CUDA_ONE_CALL (cuMemHostGetDevicePointer)
+CUDA_ONE_CALL (cuModuleGetFunction)
+CUDA_ONE_CALL (cuModuleGetGlobal)
+CUDA_ONE_CALL (cuModuleLoad)
+CUDA_ONE_CALL (cuModuleLoadData)
+CUDA_ONE_CALL (cuModuleUnload)
+CUDA_ONE_CALL_MAYBE_NULL (cuOccupancyMaxPotentialBlockSize)
+CUDA_ONE_CALL (cuStreamAddCallback)
+CUDA_ONE_CALL (cuStreamCreate)
+CUDA_ONE_CALL (cuStreamDestroy)
+CUDA_ONE_CALL (cuStreamQuery)
+CUDA_ONE_CALL (cuStreamSynchronize)
+CUDA_ONE_CALL (cuStreamWaitEvent)
diff --git a/libgomp/plugin/cuda/cuda.h b/libgomp/plugin/cuda/cuda.h
index 4799825bda2..e65f9725349 100644
--- a/libgomp/plugin/cuda/cuda.h
+++ b/libgomp/plugin/cuda/cuda.h
@@ -1,5 +1,5 @@
/* CUDA API description.
- Copyright (C) 2017-2018 Free Software Foundation, Inc.
+ Copyright (C) 2017-2019 Free Software Foundation, Inc.
This file is part of GCC.
@@ -44,6 +44,7 @@ typedef void *CUevent;
typedef void *CUfunction;
typedef void *CUlinkState;
typedef void *CUmodule;
+typedef size_t (*CUoccupancyB2DSize)(int);
typedef void *CUstream;
typedef enum {
@@ -53,7 +54,11 @@ typedef enum {
CUDA_ERROR_INVALID_CONTEXT = 201,
CUDA_ERROR_NOT_FOUND = 500,
CUDA_ERROR_NOT_READY = 600,
- CUDA_ERROR_LAUNCH_FAILED = 719
+ CUDA_ERROR_LAUNCH_FAILED = 719,
+ CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE = 720,
+ CUDA_ERROR_NOT_PERMITTED = 800,
+ CUDA_ERROR_NOT_SUPPORTED = 801,
+ CUDA_ERROR_UNKNOWN = 999
} CUresult;
typedef enum {
@@ -170,6 +175,10 @@ CUresult cuModuleGetGlobal (CUdeviceptr *, size_t *, CUmodule, const char *);
CUresult cuModuleLoad (CUmodule *, const char *);
CUresult cuModuleLoadData (CUmodule *, const void *);
CUresult cuModuleUnload (CUmodule);
+CUresult cuOccupancyMaxPotentialBlockSize(int *, int *, CUfunction,
+ CUoccupancyB2DSize, size_t, int);
+typedef void (*CUstreamCallback)(CUstream, CUresult, void *);
+CUresult cuStreamAddCallback(CUstream, CUstreamCallback, void *, unsigned int);
CUresult cuStreamCreate (CUstream *, unsigned);
#define cuStreamDestroy cuStreamDestroy_v2
CUresult cuStreamDestroy (CUstream);
diff --git a/libgomp/plugin/hsa_ext_finalize.h b/libgomp/plugin/hsa_ext_finalize.h
index 15cb2fa797c..0ab71024c73 100644
--- a/libgomp/plugin/hsa_ext_finalize.h
+++ b/libgomp/plugin/hsa_ext_finalize.h
@@ -1,5 +1,5 @@
/* HSA Extensions API 1.0.1 representation description.
- Copyright (C) 2016-2018 Free Software Foundation, Inc.
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/libgomp/plugin/plugin-gcn.c b/libgomp/plugin/plugin-gcn.c
new file mode 100644
index 00000000000..9287e27e022
--- /dev/null
+++ b/libgomp/plugin/plugin-gcn.c
@@ -0,0 +1,4012 @@
+/* Plugin for AMD GCN execution.
+
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
+
+ Contributed by Mentor Embedded
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* {{{ Includes and defines */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <limits.h>
+#include <hsa.h>
+#include <dlfcn.h>
+#include <signal.h>
+#include "libgomp-plugin.h"
+#include "gomp-constants.h"
+#include <elf.h>
+#include "oacc-plugin.h"
+#include "oacc-int.h"
+#include <assert.h>
+
+/* Additional definitions not in HSA 1.1.
+ FIXME: this needs to be updated in hsa.h for upstream, but the only source
+ right now is the ROCr source which may cause license issues. */
+#define HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT 0xA002
+
+/* These probably won't be in elf.h for a while. */
+#define R_AMDGPU_NONE 0
+#define R_AMDGPU_ABS32_LO 1 /* (S + A) & 0xFFFFFFFF */
+#define R_AMDGPU_ABS32_HI 2 /* (S + A) >> 32 */
+#define R_AMDGPU_ABS64 3 /* S + A */
+#define R_AMDGPU_REL32 4 /* S + A - P */
+#define R_AMDGPU_REL64 5 /* S + A - P */
+#define R_AMDGPU_ABS32 6 /* S + A */
+#define R_AMDGPU_GOTPCREL 7 /* G + GOT + A - P */
+#define R_AMDGPU_GOTPCREL32_LO 8 /* (G + GOT + A - P) & 0xFFFFFFFF */
+#define R_AMDGPU_GOTPCREL32_HI 9 /* (G + GOT + A - P) >> 32 */
+#define R_AMDGPU_REL32_LO 10 /* (S + A - P) & 0xFFFFFFFF */
+#define R_AMDGPU_REL32_HI 11 /* (S + A - P) >> 32 */
+#define reserved 12
+#define R_AMDGPU_RELATIVE64 13 /* B + A */
+
+/* GCN specific definitions for asynchronous queues. */
+
+#define ASYNC_QUEUE_SIZE 64
+#define DRAIN_QUEUE_SYNCHRONOUS_P false
+#define DEBUG_QUEUES 0
+#define DEBUG_THREAD_SLEEP 0
+#define DEBUG_THREAD_SIGNAL 0
+
+/* Defaults. */
+#define DEFAULT_GCN_HEAP_SIZE (100*1024*1024) /* 100MB. */
+
+/* Secure getenv() which returns NULL if running as SUID/SGID. */
+#ifndef HAVE_SECURE_GETENV
+#ifdef HAVE___SECURE_GETENV
+#define secure_getenv __secure_getenv
+#elif defined (HAVE_UNISTD_H) && defined(HAVE_GETUID) && defined(HAVE_GETEUID) \
+ && defined(HAVE_GETGID) && defined(HAVE_GETEGID)
+
+#include <unistd.h>
+
+/* Implementation of secure_getenv() for targets where it is not provided but
+ we have at least means to test real and effective IDs. */
+
+static char *
+secure_getenv (const char *name)
+{
+ if ((getuid () == geteuid ()) && (getgid () == getegid ()))
+ return getenv (name);
+ else
+ return NULL;
+}
+
+#else
+#define secure_getenv getenv
+#endif
+#endif
+
+/* }}} */
+/* {{{ Types */
+
+/* GCN-specific implmentation of the GOMP_PLUGIN_acc_thread data. */
+
+struct gcn_thread
+{
+ /* The thread number from the async clause, or GOMP_ASYNC_SYNC. */
+ int async;
+};
+
+/* As an HSA runtime is dlopened, following structure defines function
+ pointers utilized by the HSA plug-in. */
+
+struct hsa_runtime_fn_info
+{
+ /* HSA runtime. */
+ hsa_status_t (*hsa_status_string_fn) (hsa_status_t status,
+ const char **status_string);
+ hsa_status_t (*hsa_system_get_info_fn) (hsa_system_info_t attribute,
+ void *value);
+ hsa_status_t (*hsa_agent_get_info_fn) (hsa_agent_t agent,
+ hsa_agent_info_t attribute,
+ void *value);
+ hsa_status_t (*hsa_isa_get_info_fn)(hsa_isa_t isa,
+ hsa_isa_info_t attribute,
+ uint32_t index,
+ void *value);
+ hsa_status_t (*hsa_init_fn) (void);
+ hsa_status_t (*hsa_iterate_agents_fn)
+ (hsa_status_t (*callback)(hsa_agent_t agent, void *data), void *data);
+ hsa_status_t (*hsa_region_get_info_fn) (hsa_region_t region,
+ hsa_region_info_t attribute,
+ void *value);
+ hsa_status_t (*hsa_queue_create_fn)
+ (hsa_agent_t agent, uint32_t size, hsa_queue_type_t type,
+ void (*callback)(hsa_status_t status, hsa_queue_t *source, void *data),
+ void *data, uint32_t private_segment_size,
+ uint32_t group_segment_size, hsa_queue_t **queue);
+ hsa_status_t (*hsa_agent_iterate_regions_fn)
+ (hsa_agent_t agent,
+ hsa_status_t (*callback)(hsa_region_t region, void *data), void *data);
+ hsa_status_t (*hsa_executable_destroy_fn) (hsa_executable_t executable);
+ hsa_status_t (*hsa_executable_create_fn)
+ (hsa_profile_t profile, hsa_executable_state_t executable_state,
+ const char *options, hsa_executable_t *executable);
+ hsa_status_t (*hsa_executable_global_variable_define_fn)
+ (hsa_executable_t executable, const char *variable_name, void *address);
+ hsa_status_t (*hsa_executable_load_code_object_fn)
+ (hsa_executable_t executable, hsa_agent_t agent,
+ hsa_code_object_t code_object, const char *options);
+ hsa_status_t (*hsa_executable_freeze_fn)(hsa_executable_t executable,
+ const char *options);
+ hsa_status_t (*hsa_signal_create_fn) (hsa_signal_value_t initial_value,
+ uint32_t num_consumers,
+ const hsa_agent_t *consumers,
+ hsa_signal_t *signal);
+ hsa_status_t (*hsa_memory_allocate_fn) (hsa_region_t region, size_t size,
+ void **ptr);
+ hsa_status_t (*hsa_memory_assign_agent_fn) (void *ptr, hsa_agent_t agent,
+ hsa_access_permission_t access);
+ hsa_status_t (*hsa_memory_copy_fn)(void *dst, const void *src, size_t size);
+ hsa_status_t (*hsa_memory_free_fn) (void *ptr);
+ hsa_status_t (*hsa_signal_destroy_fn) (hsa_signal_t signal);
+ hsa_status_t (*hsa_executable_get_symbol_fn)
+ (hsa_executable_t executable, const char *module_name,
+ const char *symbol_name, hsa_agent_t agent, int32_t call_convention,
+ hsa_executable_symbol_t *symbol);
+ hsa_status_t (*hsa_executable_symbol_get_info_fn)
+ (hsa_executable_symbol_t executable_symbol,
+ hsa_executable_symbol_info_t attribute, void *value);
+ hsa_status_t (*hsa_executable_iterate_symbols_fn)
+ (hsa_executable_t executable,
+ hsa_status_t (*callback)(hsa_executable_t executable,
+ hsa_executable_symbol_t symbol, void *data),
+ void *data);
+ uint64_t (*hsa_queue_add_write_index_release_fn) (const hsa_queue_t *queue,
+ uint64_t value);
+ uint64_t (*hsa_queue_load_read_index_acquire_fn) (const hsa_queue_t *queue);
+ void (*hsa_signal_store_relaxed_fn) (hsa_signal_t signal,
+ hsa_signal_value_t value);
+ void (*hsa_signal_store_release_fn) (hsa_signal_t signal,
+ hsa_signal_value_t value);
+ hsa_signal_value_t (*hsa_signal_wait_acquire_fn)
+ (hsa_signal_t signal, hsa_signal_condition_t condition,
+ hsa_signal_value_t compare_value, uint64_t timeout_hint,
+ hsa_wait_state_t wait_state_hint);
+ hsa_signal_value_t (*hsa_signal_load_acquire_fn) (hsa_signal_t signal);
+ hsa_status_t (*hsa_queue_destroy_fn) (hsa_queue_t *queue);
+
+ hsa_status_t (*hsa_code_object_deserialize_fn)
+ (void *serialized_code_object, size_t serialized_code_object_size,
+ const char *options, hsa_code_object_t *code_object);
+};
+
+/* Structure describing the run-time and grid properties of an HSA kernel
+ lauch. This needs to match the format passed to GOMP_OFFLOAD_run. */
+
+struct GOMP_kernel_launch_attributes
+{
+ /* Number of dimensions the workload has. Maximum number is 3. */
+ uint32_t ndim;
+ /* Size of the grid in the three respective dimensions. */
+ uint32_t gdims[3];
+ /* Size of work-groups in the respective dimensions. */
+ uint32_t wdims[3];
+};
+
+/* Collection of information needed for a dispatch of a kernel from a
+ kernel. */
+
+struct kernel_dispatch
+{
+ struct agent_info *agent;
+ /* Pointer to a command queue associated with a kernel dispatch agent. */
+ void *queue;
+ /* Pointer to a memory space used for kernel arguments passing. */
+ void *kernarg_address;
+ /* Kernel object. */
+ uint64_t object;
+ /* Synchronization signal used for dispatch synchronization. */
+ uint64_t signal;
+ /* Private segment size. */
+ uint32_t private_segment_size;
+ /* Group segment size. */
+ uint32_t group_segment_size;
+};
+
+/* Structure of the kernargs segment, supporting console output.
+
+ This needs to match the definitions in Newlib, and the expectations
+ in libgomp target code. */
+
+struct kernargs {
+ /* Leave space for the real kernel arguments.
+ OpenACC and OpenMP only use one pointer. */
+ int64_t dummy1;
+ int64_t dummy2;
+
+ /* A pointer to struct output, below, for console output data. */
+ int64_t out_ptr;
+
+ /* A pointer to struct heap, below. */
+ int64_t heap_ptr;
+
+ /* A pointer to an ephemeral memory arena.
+ Only needed for OpenMP. */
+ int64_t arena_ptr;
+
+ /* Output data. */
+ struct output {
+ int return_value;
+ unsigned int next_output;
+ struct printf_data {
+ int written;
+ char msg[128];
+ int type;
+ union {
+ int64_t ivalue;
+ double dvalue;
+ char text[128];
+ };
+ } queue[1024];
+ unsigned int consumed;
+ } output_data;
+};
+
+/* A queue entry for a future asynchronous launch. */
+
+struct kernel_launch
+{
+ struct kernel_info *kernel;
+ void *vars;
+ struct GOMP_kernel_launch_attributes kla;
+};
+
+/* A queue entry for a future callback. */
+
+struct callback
+{
+ void (*fn)(void *);
+ void *data;
+};
+
+/* A data struct for the copy_data callback. */
+
+struct copy_data
+{
+ void *dst;
+ const void *src;
+ size_t len;
+ bool free_src;
+ struct goacc_asyncqueue *aq;
+};
+
+/* A queue entry for a placeholder. These correspond to a wait event. */
+
+struct placeholder
+{
+ int executed;
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+};
+
+/* A queue entry for a wait directive. */
+
+struct asyncwait_info
+{
+ struct placeholder *placeholderp;
+};
+
+/* Encode the type of an entry in an async queue. */
+
+enum entry_type
+{
+ KERNEL_LAUNCH,
+ CALLBACK,
+ ASYNC_WAIT,
+ ASYNC_PLACEHOLDER
+};
+
+/* An entry in an async queue. */
+
+struct queue_entry
+{
+ enum entry_type type;
+ union {
+ struct kernel_launch launch;
+ struct callback callback;
+ struct asyncwait_info asyncwait;
+ struct placeholder placeholder;
+ } u;
+};
+
+/* An async queue header.
+
+ OpenMP may create one of these.
+ OpenACC may create many. */
+
+struct goacc_asyncqueue
+{
+ struct agent_info *agent;
+ hsa_queue_t *hsa_queue;
+
+ pthread_t thread_drain_queue;
+ pthread_mutex_t mutex;
+ pthread_cond_t queue_cond_in;
+ pthread_cond_t queue_cond_out;
+ struct queue_entry queue[ASYNC_QUEUE_SIZE];
+ int queue_first;
+ int queue_n;
+ int drain_queue_stop;
+
+ int id;
+ struct goacc_asyncqueue *prev;
+ struct goacc_asyncqueue *next;
+};
+
+/* Mkoffload uses this structure to describe a kernel.
+
+ OpenMP kernel dimensions are passed at runtime.
+ OpenACC kernel dimensions are passed at compile time, here. */
+
+struct hsa_kernel_description
+{
+ const char *name;
+ int oacc_dims[3]; /* Only present for GCN kernels. */
+};
+
+/* Mkoffload uses this structure to describe an offload variable. */
+
+struct global_var_info
+{
+ const char *name;
+ void *address;
+};
+
+/* Mkoffload uses this structure to describe all the kernels in a
+ loadable module. These are passed the libgomp via static constructors. */
+
+struct gcn_image_desc
+{
+ struct gcn_image {
+ size_t size;
+ void *image;
+ } *gcn_image;
+ const unsigned kernel_count;
+ struct hsa_kernel_description *kernel_infos;
+ const unsigned global_variable_count;
+ struct global_var_info *global_variables;
+};
+
+/* Description of an HSA GPU agent (device) and the program associated with
+ it. */
+
+struct agent_info
+{
+ /* The HSA ID of the agent. Assigned when hsa_context is initialized. */
+ hsa_agent_t id;
+ /* The user-visible device number. */
+ int device_id;
+ /* Whether the agent has been initialized. The fields below are usable only
+ if it has been. */
+ bool initialized;
+ /* Precomuted check for problem architectures. */
+ bool gfx900_p;
+
+ /* Command queues of the agent. */
+ hsa_queue_t *sync_queue;
+ struct goacc_asyncqueue *async_queues, *omp_async_queue;
+ pthread_mutex_t async_queues_mutex;
+
+ /* The HSA memory region from which to allocate kernel arguments. */
+ hsa_region_t kernarg_region;
+
+ /* The HSA memory region from which to allocate device data. */
+ hsa_region_t data_region;
+
+ /* Allocated team arenas. */
+ struct team_arena_list *team_arena_list;
+ pthread_mutex_t team_arena_write_lock;
+
+ /* Read-write lock that protects kernels which are running or about to be run
+ from interference with loading and unloading of images. Needs to be
+ locked for reading while a kernel is being run, and for writing if the
+ list of modules is manipulated (and thus the HSA program invalidated). */
+ pthread_rwlock_t module_rwlock;
+
+ /* The module associated with this kernel. */
+ struct module_info *module;
+
+ /* Mutex enforcing that only one thread will finalize the HSA program. A
+ thread should have locked agent->module_rwlock for reading before
+ acquiring it. */
+ pthread_mutex_t prog_mutex;
+ /* Flag whether the HSA program that consists of all the modules has been
+ finalized. */
+ bool prog_finalized;
+ /* HSA executable - the finalized program that is used to locate kernels. */
+ hsa_executable_t executable;
+};
+
+/* Information required to identify, finalize and run any given kernel. */
+
+enum offload_kind {KIND_UNKNOWN, KIND_OPENMP, KIND_OPENACC};
+
+struct kernel_info
+{
+ /* Name of the kernel, required to locate it within the GCN object-code
+ module. */
+ const char *name;
+ /* The specific agent the kernel has been or will be finalized for and run
+ on. */
+ struct agent_info *agent;
+ /* The specific module where the kernel takes place. */
+ struct module_info *module;
+ /* Mutex enforcing that at most once thread ever initializes a kernel for
+ use. A thread should have locked agent->module_rwlock for reading before
+ acquiring it. */
+ pthread_mutex_t init_mutex;
+ /* Flag indicating whether the kernel has been initialized and all fields
+ below it contain valid data. */
+ bool initialized;
+ /* Flag indicating that the kernel has a problem that blocks an execution. */
+ bool initialization_failed;
+ /* The object to be put into the dispatch queue. */
+ uint64_t object;
+ /* Required size of kernel arguments. */
+ uint32_t kernarg_segment_size;
+ /* Required size of group segment. */
+ uint32_t group_segment_size;
+ /* Required size of private segment. */
+ uint32_t private_segment_size;
+ /* Set up for OpenMP or OpenACC? */
+ enum offload_kind kind;
+};
+
+/* Information about a particular GCN module, its image and kernels. */
+
+struct module_info
+{
+ /* The description with which the program has registered the image. */
+ struct gcn_image_desc *image_desc;
+ /* GCN heap allocation. */
+ struct heap *heap;
+ /* Physical boundaries of the loaded module. */
+ Elf64_Addr phys_address_start;
+ Elf64_Addr phys_address_end;
+
+ bool constructors_run_p;
+ struct kernel_info *init_array_func, *fini_array_func;
+
+ /* Number of kernels in this module. */
+ int kernel_count;
+ /* An array of kernel_info structures describing each kernel in this
+ module. */
+ struct kernel_info kernels[];
+};
+
+/* A linked list of memory arenas allocated on the device.
+ These are only used by OpenMP, as a means to optimize per-team malloc. */
+
+struct team_arena_list
+{
+ struct team_arena_list *next;
+
+ /* The number of teams determines the size of the allocation. */
+ int num_teams;
+ /* The device address of the arena itself. */
+ void *arena;
+ /* A flag to prevent two asynchronous kernels trying to use the same arena.
+ The mutex is locked until the kernel exits. */
+ pthread_mutex_t in_use;
+};
+
+/* Information about the whole HSA environment and all of its agents. */
+
+struct hsa_context_info
+{
+ /* Whether the structure has been initialized. */
+ bool initialized;
+ /* Number of usable GPU HSA agents in the system. */
+ int agent_count;
+ /* Array of agent_info structures describing the individual HSA agents. */
+ struct agent_info *agents;
+};
+
+/* Format of the on-device heap.
+
+ This must match the definition in Newlib and gcn-run. */
+
+struct heap {
+ int64_t size;
+ char data[0];
+};
+
+/* }}} */
+/* {{{ Global variables */
+
+/* Information about the whole HSA environment and all of its agents. */
+
+static struct hsa_context_info hsa_context;
+
+/* HSA runtime functions that are initialized in init_hsa_context. */
+
+static struct hsa_runtime_fn_info hsa_fns;
+
+/* Heap space, allocated target-side, provided for use of newlib malloc.
+ Each module should have it's own heap allocated.
+ Beware that heap usage increases with OpenMP teams. See also arenas. */
+
+static size_t gcn_kernel_heap_size = DEFAULT_GCN_HEAP_SIZE;
+
+/* Flag to decide whether print to stderr information about what is going on.
+ Set in init_debug depending on environment variables. */
+
+static bool debug;
+
+/* Flag to decide if the runtime should suppress a possible fallback to host
+ execution. */
+
+static bool suppress_host_fallback;
+
+/* Flag to locate HSA runtime shared library that is dlopened
+ by this plug-in. */
+
+static const char *hsa_runtime_lib;
+
+/* Flag to decide if the runtime should support also CPU devices (can be
+ a simulator). */
+
+static bool support_cpu_devices;
+
+/* Runtime dimension overrides. Zero indicates default. */
+
+static int override_x_dim = 0;
+static int override_z_dim = 0;
+
+/* }}} */
+/* {{{ Debug & Diagnostic */
+
+/* Print a message to stderr if GCN_DEBUG value is set to true. */
+
+#define DEBUG_PRINT(...) \
+ do \
+ { \
+ if (debug) \
+ { \
+ fprintf (stderr, __VA_ARGS__); \
+ } \
+ } \
+ while (false);
+
+/* Flush stderr if GCN_DEBUG value is set to true. */
+
+#define DEBUG_FLUSH() \
+ do { \
+ if (debug) \
+ fflush (stderr); \
+ } while (false)
+
+/* Print a logging message with PREFIX to stderr if GCN_DEBUG value
+ is set to true. */
+
+#define DEBUG_LOG(prefix, ...) \
+ do \
+ { \
+ DEBUG_PRINT (prefix); \
+ DEBUG_PRINT (__VA_ARGS__); \
+ DEBUG_FLUSH (); \
+ } while (false)
+
+/* Print a debugging message to stderr. */
+
+#define GCN_DEBUG(...) DEBUG_LOG ("GCN debug: ", __VA_ARGS__)
+
+/* Print a warning message to stderr. */
+
+#define GCN_WARNING(...) DEBUG_LOG ("GCN warning: ", __VA_ARGS__)
+
+/* Print HSA warning STR with an HSA STATUS code. */
+
+static void
+hsa_warn (const char *str, hsa_status_t status)
+{
+ if (!debug)
+ return;
+
+ const char *hsa_error_msg = "[unknown]";
+ hsa_fns.hsa_status_string_fn (status, &hsa_error_msg);
+
+ fprintf (stderr, "GCN warning: %s\nRuntime message: %s\n", str,
+ hsa_error_msg);
+}
+
+/* Report a fatal error STR together with the HSA error corresponding to STATUS
+ and terminate execution of the current process. */
+
+static void
+hsa_fatal (const char *str, hsa_status_t status)
+{
+ const char *hsa_error_msg = "[unknown]";
+ hsa_fns.hsa_status_string_fn (status, &hsa_error_msg);
+ GOMP_PLUGIN_fatal ("GCN fatal error: %s\nRuntime message: %s\n", str,
+ hsa_error_msg);
+}
+
+/* Like hsa_fatal, except only report error message, and return FALSE
+ for propagating error processing to outside of plugin. */
+
+static bool
+hsa_error (const char *str, hsa_status_t status)
+{
+ const char *hsa_error_msg = "[unknown]";
+ hsa_fns.hsa_status_string_fn (status, &hsa_error_msg);
+ GOMP_PLUGIN_error ("GCN fatal error: %s\nRuntime message: %s\n", str,
+ hsa_error_msg);
+ return false;
+}
+
+/* Dump information about the available hardware. */
+
+static void
+dump_hsa_system_info (void)
+{
+ hsa_status_t status;
+
+ hsa_endianness_t endianness;
+ status = hsa_fns.hsa_system_get_info_fn (HSA_SYSTEM_INFO_ENDIANNESS,
+ &endianness);
+ if (status == HSA_STATUS_SUCCESS)
+ switch (endianness)
+ {
+ case HSA_ENDIANNESS_LITTLE:
+ GCN_DEBUG ("HSA_SYSTEM_INFO_ENDIANNESS: LITTLE\n");
+ break;
+ case HSA_ENDIANNESS_BIG:
+ GCN_DEBUG ("HSA_SYSTEM_INFO_ENDIANNESS: BIG\n");
+ break;
+ default:
+ GCN_WARNING ("HSA_SYSTEM_INFO_ENDIANNESS: UNKNOWN\n");
+ }
+ else
+ GCN_WARNING ("HSA_SYSTEM_INFO_ENDIANNESS: FAILED\n");
+
+ uint8_t extensions[128];
+ status = hsa_fns.hsa_system_get_info_fn (HSA_SYSTEM_INFO_EXTENSIONS,
+ &extensions);
+ if (status == HSA_STATUS_SUCCESS)
+ {
+ if (extensions[0] & (1 << HSA_EXTENSION_IMAGES))
+ GCN_DEBUG ("HSA_SYSTEM_INFO_EXTENSIONS: IMAGES\n");
+ }
+ else
+ GCN_WARNING ("HSA_SYSTEM_INFO_EXTENSIONS: FAILED\n");
+}
+
+/* Dump information about the available hardware. */
+
+static void
+dump_machine_model (hsa_machine_model_t machine_model, const char *s)
+{
+ switch (machine_model)
+ {
+ case HSA_MACHINE_MODEL_SMALL:
+ GCN_DEBUG ("%s: SMALL\n", s);
+ break;
+ case HSA_MACHINE_MODEL_LARGE:
+ GCN_DEBUG ("%s: LARGE\n", s);
+ break;
+ default:
+ GCN_WARNING ("%s: UNKNOWN\n", s);
+ break;
+ }
+}
+
+/* Dump information about the available hardware. */
+
+static void
+dump_profile (hsa_profile_t profile, const char *s)
+{
+ switch (profile)
+ {
+ case HSA_PROFILE_FULL:
+ GCN_DEBUG ("%s: FULL\n", s);
+ break;
+ case HSA_PROFILE_BASE:
+ GCN_DEBUG ("%s: BASE\n", s);
+ break;
+ default:
+ GCN_WARNING ("%s: UNKNOWN\n", s);
+ break;
+ }
+}
+
+/* Dump information about a device memory region. */
+
+static hsa_status_t
+dump_hsa_region (hsa_region_t region, void *data __attribute__((unused)))
+{
+ hsa_status_t status;
+
+ hsa_region_segment_t segment;
+ status = hsa_fns.hsa_region_get_info_fn (region, HSA_REGION_INFO_SEGMENT,
+ &segment);
+ if (status == HSA_STATUS_SUCCESS)
+ {
+ if (segment == HSA_REGION_SEGMENT_GLOBAL)
+ GCN_DEBUG ("HSA_REGION_INFO_SEGMENT: GLOBAL\n");
+ else if (segment == HSA_REGION_SEGMENT_READONLY)
+ GCN_DEBUG ("HSA_REGION_INFO_SEGMENT: READONLY\n");
+ else if (segment == HSA_REGION_SEGMENT_PRIVATE)
+ GCN_DEBUG ("HSA_REGION_INFO_SEGMENT: PRIVATE\n");
+ else if (segment == HSA_REGION_SEGMENT_GROUP)
+ GCN_DEBUG ("HSA_REGION_INFO_SEGMENT: GROUP\n");
+ else
+ GCN_WARNING ("HSA_REGION_INFO_SEGMENT: UNKNOWN\n");
+ }
+ else
+ GCN_WARNING ("HSA_REGION_INFO_SEGMENT: FAILED\n");
+
+ if (segment == HSA_REGION_SEGMENT_GLOBAL)
+ {
+ uint32_t flags;
+ status
+ = hsa_fns.hsa_region_get_info_fn (region, HSA_REGION_INFO_GLOBAL_FLAGS,
+ &flags);
+ if (status == HSA_STATUS_SUCCESS)
+ {
+ if (flags & HSA_REGION_GLOBAL_FLAG_KERNARG)
+ GCN_DEBUG ("HSA_REGION_INFO_GLOBAL_FLAGS: KERNARG\n");
+ if (flags & HSA_REGION_GLOBAL_FLAG_FINE_GRAINED)
+ GCN_DEBUG ("HSA_REGION_INFO_GLOBAL_FLAGS: FINE_GRAINED\n");
+ if (flags & HSA_REGION_GLOBAL_FLAG_COARSE_GRAINED)
+ GCN_DEBUG ("HSA_REGION_INFO_GLOBAL_FLAGS: COARSE_GRAINED\n");
+ }
+ else
+ GCN_WARNING ("HSA_REGION_INFO_GLOBAL_FLAGS: FAILED\n");
+ }
+
+ size_t size;
+ status = hsa_fns.hsa_region_get_info_fn (region, HSA_REGION_INFO_SIZE, &size);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_REGION_INFO_SIZE: %zu\n", size);
+ else
+ GCN_WARNING ("HSA_REGION_INFO_SIZE: FAILED\n");
+
+ status
+ = hsa_fns.hsa_region_get_info_fn (region, HSA_REGION_INFO_ALLOC_MAX_SIZE,
+ &size);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_REGION_INFO_ALLOC_MAX_SIZE: %zu\n", size);
+ else
+ GCN_WARNING ("HSA_REGION_INFO_ALLOC_MAX_SIZE: FAILED\n");
+
+ bool alloc_allowed;
+ status
+ = hsa_fns.hsa_region_get_info_fn (region,
+ HSA_REGION_INFO_RUNTIME_ALLOC_ALLOWED,
+ &alloc_allowed);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_REGION_INFO_RUNTIME_ALLOC_ALLOWED: %u\n", alloc_allowed);
+ else
+ GCN_WARNING ("HSA_REGION_INFO_RUNTIME_ALLOC_ALLOWED: FAILED\n");
+
+ if (status != HSA_STATUS_SUCCESS || !alloc_allowed)
+ return HSA_STATUS_SUCCESS;
+
+ status
+ = hsa_fns.hsa_region_get_info_fn (region,
+ HSA_REGION_INFO_RUNTIME_ALLOC_GRANULE,
+ &size);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_REGION_INFO_RUNTIME_ALLOC_GRANULE: %zu\n", size);
+ else
+ GCN_WARNING ("HSA_REGION_INFO_RUNTIME_ALLOC_GRANULE: FAILED\n");
+
+ size_t align;
+ status
+ = hsa_fns.hsa_region_get_info_fn (region,
+ HSA_REGION_INFO_RUNTIME_ALLOC_ALIGNMENT,
+ &align);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_REGION_INFO_RUNTIME_ALLOC_ALIGNMENT: %zu\n", align);
+ else
+ GCN_WARNING ("HSA_REGION_INFO_RUNTIME_ALLOC_ALIGNMENT: FAILED\n");
+
+ return HSA_STATUS_SUCCESS;
+}
+
+/* Dump information about all the device memory regions. */
+
+static void
+dump_hsa_regions (hsa_agent_t agent)
+{
+ hsa_status_t status;
+ status = hsa_fns.hsa_agent_iterate_regions_fn (agent,
+ dump_hsa_region,
+ NULL);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_error ("Dumping hsa regions failed", status);
+}
+
+/* Dump information about the available devices. */
+
+static hsa_status_t
+dump_hsa_agent_info (hsa_agent_t agent, void *data __attribute__((unused)))
+{
+ hsa_status_t status;
+
+ char buf[64];
+ status = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_NAME,
+ &buf);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_AGENT_INFO_NAME: %s\n", buf);
+ else
+ GCN_WARNING ("HSA_AGENT_INFO_NAME: FAILED\n");
+
+ status = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_VENDOR_NAME,
+ &buf);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_AGENT_INFO_VENDOR_NAME: %s\n", buf);
+ else
+ GCN_WARNING ("HSA_AGENT_INFO_VENDOR_NAME: FAILED\n");
+
+ hsa_machine_model_t machine_model;
+ status
+ = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_MACHINE_MODEL,
+ &machine_model);
+ if (status == HSA_STATUS_SUCCESS)
+ dump_machine_model (machine_model, "HSA_AGENT_INFO_MACHINE_MODEL");
+ else
+ GCN_WARNING ("HSA_AGENT_INFO_MACHINE_MODEL: FAILED\n");
+
+ hsa_profile_t profile;
+ status = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_PROFILE,
+ &profile);
+ if (status == HSA_STATUS_SUCCESS)
+ dump_profile (profile, "HSA_AGENT_INFO_PROFILE");
+ else
+ GCN_WARNING ("HSA_AGENT_INFO_PROFILE: FAILED\n");
+
+ hsa_device_type_t device_type;
+ status = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_DEVICE,
+ &device_type);
+ if (status == HSA_STATUS_SUCCESS)
+ {
+ switch (device_type)
+ {
+ case HSA_DEVICE_TYPE_CPU:
+ GCN_DEBUG ("HSA_AGENT_INFO_DEVICE: CPU\n");
+ break;
+ case HSA_DEVICE_TYPE_GPU:
+ GCN_DEBUG ("HSA_AGENT_INFO_DEVICE: GPU\n");
+ break;
+ case HSA_DEVICE_TYPE_DSP:
+ GCN_DEBUG ("HSA_AGENT_INFO_DEVICE: DSP\n");
+ break;
+ default:
+ GCN_WARNING ("HSA_AGENT_INFO_DEVICE: UNKNOWN\n");
+ break;
+ }
+ }
+ else
+ GCN_WARNING ("HSA_AGENT_INFO_DEVICE: FAILED\n");
+
+ uint32_t cu_count;
+ status = hsa_fns.hsa_agent_get_info_fn
+ (agent, HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT, &cu_count);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT: %u\n", cu_count);
+ else
+ GCN_WARNING ("HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT: FAILED\n");
+
+ uint32_t size;
+ status = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_WAVEFRONT_SIZE,
+ &size);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_AGENT_INFO_WAVEFRONT_SIZE: %u\n", size);
+ else
+ GCN_WARNING ("HSA_AGENT_INFO_WAVEFRONT_SIZE: FAILED\n");
+
+ uint32_t max_dim;
+ status = hsa_fns.hsa_agent_get_info_fn (agent,
+ HSA_AGENT_INFO_WORKGROUP_MAX_DIM,
+ &max_dim);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_AGENT_INFO_WORKGROUP_MAX_DIM: %u\n", max_dim);
+ else
+ GCN_WARNING ("HSA_AGENT_INFO_WORKGROUP_MAX_DIM: FAILED\n");
+
+ uint32_t max_size;
+ status = hsa_fns.hsa_agent_get_info_fn (agent,
+ HSA_AGENT_INFO_WORKGROUP_MAX_SIZE,
+ &max_size);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_AGENT_INFO_WORKGROUP_MAX_SIZE: %u\n", max_size);
+ else
+ GCN_WARNING ("HSA_AGENT_INFO_WORKGROUP_MAX_SIZE: FAILED\n");
+
+ uint32_t grid_max_dim;
+ status = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_GRID_MAX_DIM,
+ &grid_max_dim);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_AGENT_INFO_GRID_MAX_DIM: %u\n", grid_max_dim);
+ else
+ GCN_WARNING ("HSA_AGENT_INFO_GRID_MAX_DIM: FAILED\n");
+
+ uint32_t grid_max_size;
+ status = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_GRID_MAX_SIZE,
+ &grid_max_size);
+ if (status == HSA_STATUS_SUCCESS)
+ GCN_DEBUG ("HSA_AGENT_INFO_GRID_MAX_SIZE: %u\n", grid_max_size);
+ else
+ GCN_WARNING ("HSA_AGENT_INFO_GRID_MAX_SIZE: FAILED\n");
+
+ dump_hsa_regions (agent);
+
+ return HSA_STATUS_SUCCESS;
+}
+
+/* Forward reference. */
+
+static char *get_executable_symbol_name (hsa_executable_symbol_t symbol);
+
+/* Helper function for dump_executable_symbols. */
+
+static hsa_status_t
+dump_executable_symbol (hsa_executable_t executable,
+ hsa_executable_symbol_t symbol,
+ void *data __attribute__((unused)))
+{
+ char *name = get_executable_symbol_name (symbol);
+
+ if (name)
+ {
+ GCN_DEBUG ("executable symbol: %s\n", name);
+ free (name);
+ }
+
+ return HSA_STATUS_SUCCESS;
+}
+
+/* Dump all global symbol in an executable. */
+
+static void
+dump_executable_symbols (hsa_executable_t executable)
+{
+ hsa_status_t status;
+ status
+ = hsa_fns.hsa_executable_iterate_symbols_fn (executable,
+ dump_executable_symbol,
+ NULL);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not dump HSA executable symbols", status);
+}
+
+/* Dump kernel DISPATCH data structure and indent it by INDENT spaces. */
+
+static void
+print_kernel_dispatch (struct kernel_dispatch *dispatch, unsigned indent)
+{
+ struct kernargs *kernargs = (struct kernargs *)dispatch->kernarg_address;
+
+ fprintf (stderr, "%*sthis: %p\n", indent, "", dispatch);
+ fprintf (stderr, "%*squeue: %p\n", indent, "", dispatch->queue);
+ fprintf (stderr, "%*skernarg_address: %p\n", indent, "", kernargs);
+ fprintf (stderr, "%*sheap address: %p\n", indent, "",
+ (void*)kernargs->heap_ptr);
+ fprintf (stderr, "%*sarena address: %p\n", indent, "",
+ (void*)kernargs->arena_ptr);
+ fprintf (stderr, "%*sobject: %lu\n", indent, "", dispatch->object);
+ fprintf (stderr, "%*sprivate_segment_size: %u\n", indent, "",
+ dispatch->private_segment_size);
+ fprintf (stderr, "%*sgroup_segment_size: %u\n", indent, "",
+ dispatch->group_segment_size);
+ fprintf (stderr, "\n");
+}
+
+/* }}} */
+/* {{{ Utility functions */
+
+/* Cast the thread local storage to gcn_thread. */
+
+static inline struct gcn_thread *
+gcn_thread (void)
+{
+ return (struct gcn_thread *) GOMP_PLUGIN_acc_thread ();
+}
+
+/* Initialize debug and suppress_host_fallback according to the environment. */
+
+static void
+init_environment_variables (void)
+{
+ if (secure_getenv ("GCN_DEBUG"))
+ debug = true;
+ else
+ debug = false;
+
+ if (secure_getenv ("GCN_SUPPRESS_HOST_FALLBACK"))
+ suppress_host_fallback = true;
+ else
+ suppress_host_fallback = false;
+
+ hsa_runtime_lib = secure_getenv ("HSA_RUNTIME_LIB");
+ if (hsa_runtime_lib == NULL)
+ hsa_runtime_lib = HSA_RUNTIME_LIB "libhsa-runtime64.so";
+
+ support_cpu_devices = secure_getenv ("GCN_SUPPORT_CPU_DEVICES");
+
+ const char *x = secure_getenv ("GCN_NUM_TEAMS");
+ if (!x)
+ x = secure_getenv ("GCN_NUM_GANGS");
+ if (x)
+ override_x_dim = atoi (x);
+
+ const char *z = secure_getenv ("GCN_NUM_THREADS");
+ if (!z)
+ z = secure_getenv ("GCN_NUM_WORKERS");
+ if (z)
+ override_z_dim = atoi (z);
+
+ const char *heap = secure_getenv ("GCN_HEAP_SIZE");
+ if (heap)
+ {
+ size_t tmp = atol (heap);
+ if (tmp)
+ gcn_kernel_heap_size = tmp;
+ }
+}
+
+/* Return malloc'd string with name of SYMBOL. */
+
+static char *
+get_executable_symbol_name (hsa_executable_symbol_t symbol)
+{
+ hsa_status_t status;
+ char *res;
+ uint32_t len;
+ const hsa_executable_symbol_info_t info_name_length
+ = HSA_EXECUTABLE_SYMBOL_INFO_NAME_LENGTH;
+
+ status = hsa_fns.hsa_executable_symbol_get_info_fn (symbol, info_name_length,
+ &len);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not get length of symbol name", status);
+ return NULL;
+ }
+
+ res = GOMP_PLUGIN_malloc (len + 1);
+
+ const hsa_executable_symbol_info_t info_name
+ = HSA_EXECUTABLE_SYMBOL_INFO_NAME;
+
+ status = hsa_fns.hsa_executable_symbol_get_info_fn (symbol, info_name, res);
+
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not get symbol name", status);
+ free (res);
+ return NULL;
+ }
+
+ res[len] = '\0';
+
+ return res;
+}
+
+/* Helper function for find_executable_symbol. */
+
+static hsa_status_t
+find_executable_symbol_1 (hsa_executable_t executable,
+ hsa_executable_symbol_t symbol,
+ void *data)
+{
+ hsa_executable_symbol_t *res = (hsa_executable_symbol_t *)data;
+ *res = symbol;
+ return HSA_STATUS_INFO_BREAK;
+}
+
+/* Find a global symbol in EXECUTABLE, save to *SYMBOL and return true. If not
+ found, return false. */
+
+static bool
+find_executable_symbol (hsa_executable_t executable,
+ hsa_executable_symbol_t *symbol)
+{
+ hsa_status_t status;
+
+ status
+ = hsa_fns.hsa_executable_iterate_symbols_fn (executable,
+ find_executable_symbol_1,
+ symbol);
+ if (status != HSA_STATUS_INFO_BREAK)
+ {
+ hsa_error ("Could not find executable symbol", status);
+ return false;
+ }
+
+ return true;
+}
+
+/* Get the number of GPU Compute Units. */
+
+static int
+get_cu_count (struct agent_info *agent)
+{
+ uint32_t cu_count;
+ hsa_status_t status = hsa_fns.hsa_agent_get_info_fn
+ (agent->id, HSA_AMD_AGENT_INFO_COMPUTE_UNIT_COUNT, &cu_count);
+ if (status == HSA_STATUS_SUCCESS)
+ return cu_count;
+ else
+ return 64; /* The usual number for older devices. */
+}
+
+/* Calculate the maximum grid size for OMP threads / OACC workers.
+ This depends on the kernel's resource usage levels. */
+
+static int
+limit_worker_threads (int threads)
+{
+ /* FIXME Do something more inteligent here.
+ GCN can always run 4 threads within a Compute Unit, but
+ more than that depends on register usage. */
+ if (threads > 16)
+ threads = 16;
+ return threads;
+}
+
+/* Parse the target attributes INPUT provided by the compiler and return true
+ if we should run anything all. If INPUT is NULL, fill DEF with default
+ values, then store INPUT or DEF into *RESULT.
+
+ This is used for OpenMP only. */
+
+static bool
+parse_target_attributes (void **input,
+ struct GOMP_kernel_launch_attributes *def,
+ struct GOMP_kernel_launch_attributes **result,
+ struct agent_info *agent)
+{
+ if (!input)
+ GOMP_PLUGIN_fatal ("No target arguments provided");
+
+ bool grid_attrs_found = false;
+ bool gcn_dims_found = false;
+ int gcn_teams = 0;
+ int gcn_threads = 0;
+ while (*input)
+ {
+ intptr_t id = (intptr_t) *input++, val;
+
+ if (id & GOMP_TARGET_ARG_SUBSEQUENT_PARAM)
+ val = (intptr_t) *input++;
+ else
+ val = id >> GOMP_TARGET_ARG_VALUE_SHIFT;
+
+ val = (val > INT_MAX) ? INT_MAX : val;
+
+ if ((id & GOMP_TARGET_ARG_DEVICE_MASK) == GOMP_DEVICE_GCN
+ && ((id & GOMP_TARGET_ARG_ID_MASK)
+ == GOMP_TARGET_ARG_HSA_KERNEL_ATTRIBUTES))
+ {
+ grid_attrs_found = true;
+ break;
+ }
+ else if ((id & GOMP_TARGET_ARG_DEVICE_ALL) == GOMP_TARGET_ARG_DEVICE_ALL)
+ {
+ gcn_dims_found = true;
+ switch (id & GOMP_TARGET_ARG_ID_MASK)
+ {
+ case GOMP_TARGET_ARG_NUM_TEAMS:
+ gcn_teams = val;
+ break;
+ case GOMP_TARGET_ARG_THREAD_LIMIT:
+ gcn_threads = limit_worker_threads (val);
+ break;
+ default:
+ ;
+ }
+ }
+ }
+
+ if (gcn_dims_found)
+ {
+ if (agent->gfx900_p && gcn_threads == 0 && override_z_dim == 0)
+ {
+ gcn_threads = 4;
+ GCN_WARNING ("VEGA BUG WORKAROUND: reducing default number of "
+ "threads to 4 per team.\n");
+ GCN_WARNING (" - If this is not a Vega 10 device, please use "
+ "GCN_NUM_THREADS=16\n");
+ }
+
+ def->ndim = 3;
+ /* Fiji has 64 CUs, but Vega20 has 60. */
+ def->gdims[0] = (gcn_teams > 0) ? gcn_teams : get_cu_count (agent);
+ /* Each thread is 64 work items wide. */
+ def->gdims[1] = 64;
+ /* A work group can have 16 wavefronts. */
+ def->gdims[2] = (gcn_threads > 0) ? gcn_threads : 16;
+ def->wdims[0] = 1; /* Single team per work-group. */
+ def->wdims[1] = 64;
+ def->wdims[2] = 16;
+ *result = def;
+ return true;
+ }
+ else if (!grid_attrs_found)
+ {
+ def->ndim = 1;
+ def->gdims[0] = 1;
+ def->gdims[1] = 1;
+ def->gdims[2] = 1;
+ def->wdims[0] = 1;
+ def->wdims[1] = 1;
+ def->wdims[2] = 1;
+ *result = def;
+ GCN_WARNING ("GOMP_OFFLOAD_run called with no launch attributes\n");
+ return true;
+ }
+
+ struct GOMP_kernel_launch_attributes *kla;
+ kla = (struct GOMP_kernel_launch_attributes *) *input;
+ *result = kla;
+ if (kla->ndim == 0 || kla->ndim > 3)
+ GOMP_PLUGIN_fatal ("Invalid number of dimensions (%u)", kla->ndim);
+
+ GCN_DEBUG ("GOMP_OFFLOAD_run called with %u dimensions:\n", kla->ndim);
+ unsigned i;
+ for (i = 0; i < kla->ndim; i++)
+ {
+ GCN_DEBUG (" Dimension %u: grid size %u and group size %u\n", i,
+ kla->gdims[i], kla->wdims[i]);
+ if (kla->gdims[i] == 0)
+ return false;
+ }
+ return true;
+}
+
+/* Return the group size given the requested GROUP size, GRID size and number
+ of grid dimensions NDIM. */
+
+static uint32_t
+get_group_size (uint32_t ndim, uint32_t grid, uint32_t group)
+{
+ if (group == 0)
+ {
+ /* TODO: Provide a default via environment or device characteristics. */
+ if (ndim == 1)
+ group = 64;
+ else if (ndim == 2)
+ group = 8;
+ else
+ group = 4;
+ }
+
+ if (group > grid)
+ group = grid;
+ return group;
+}
+
+/* Atomically store pair of uint16_t values (HEADER and REST) to a PACKET. */
+
+static void
+packet_store_release (uint32_t* packet, uint16_t header, uint16_t rest)
+{
+ __atomic_store_n (packet, header | (rest << 16), __ATOMIC_RELEASE);
+}
+
+/* A never-called callback for the HSA command queues. These signal events
+ that we don't use, so we trigger an error.
+
+ This "queue" is not to be confused with the async queues, below. */
+
+static void
+hsa_queue_callback (hsa_status_t status,
+ hsa_queue_t *queue __attribute__ ((unused)),
+ void *data __attribute__ ((unused)))
+{
+ hsa_fatal ("Asynchronous queue error", status);
+}
+
+/* }}} */
+/* {{{ HSA initialization */
+
+/* Populate hsa_fns with the function addresses from libhsa-runtime64.so. */
+
+static bool
+init_hsa_runtime_functions (void)
+{
+#define DLSYM_FN(function) \
+ hsa_fns.function##_fn = dlsym (handle, #function); \
+ if (hsa_fns.function##_fn == NULL) \
+ return false;
+ void *handle = dlopen (hsa_runtime_lib, RTLD_LAZY);
+ if (handle == NULL)
+ return false;
+
+ DLSYM_FN (hsa_status_string)
+ DLSYM_FN (hsa_system_get_info)
+ DLSYM_FN (hsa_agent_get_info)
+ DLSYM_FN (hsa_init)
+ DLSYM_FN (hsa_iterate_agents)
+ DLSYM_FN (hsa_region_get_info)
+ DLSYM_FN (hsa_queue_create)
+ DLSYM_FN (hsa_agent_iterate_regions)
+ DLSYM_FN (hsa_executable_destroy)
+ DLSYM_FN (hsa_executable_create)
+ DLSYM_FN (hsa_executable_global_variable_define)
+ DLSYM_FN (hsa_executable_load_code_object)
+ DLSYM_FN (hsa_executable_freeze)
+ DLSYM_FN (hsa_signal_create)
+ DLSYM_FN (hsa_memory_allocate)
+ DLSYM_FN (hsa_memory_assign_agent)
+ DLSYM_FN (hsa_memory_copy)
+ DLSYM_FN (hsa_memory_free)
+ DLSYM_FN (hsa_signal_destroy)
+ DLSYM_FN (hsa_executable_get_symbol)
+ DLSYM_FN (hsa_executable_symbol_get_info)
+ DLSYM_FN (hsa_executable_iterate_symbols)
+ DLSYM_FN (hsa_queue_add_write_index_release)
+ DLSYM_FN (hsa_queue_load_read_index_acquire)
+ DLSYM_FN (hsa_signal_wait_acquire)
+ DLSYM_FN (hsa_signal_store_relaxed)
+ DLSYM_FN (hsa_signal_store_release)
+ DLSYM_FN (hsa_signal_load_acquire)
+ DLSYM_FN (hsa_queue_destroy)
+ DLSYM_FN (hsa_code_object_deserialize)
+ return true;
+#undef DLSYM_FN
+}
+
+/* Return true if the agent is a GPU and can accept of concurrent submissions
+ from different threads. */
+
+static bool
+suitable_hsa_agent_p (hsa_agent_t agent)
+{
+ hsa_device_type_t device_type;
+ hsa_status_t status
+ = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_DEVICE,
+ &device_type);
+ if (status != HSA_STATUS_SUCCESS)
+ return false;
+
+ switch (device_type)
+ {
+ case HSA_DEVICE_TYPE_GPU:
+ break;
+ case HSA_DEVICE_TYPE_CPU:
+ if (!support_cpu_devices)
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ uint32_t features = 0;
+ status = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_FEATURE,
+ &features);
+ if (status != HSA_STATUS_SUCCESS
+ || !(features & HSA_AGENT_FEATURE_KERNEL_DISPATCH))
+ return false;
+ hsa_queue_type_t queue_type;
+ status = hsa_fns.hsa_agent_get_info_fn (agent, HSA_AGENT_INFO_QUEUE_TYPE,
+ &queue_type);
+ if (status != HSA_STATUS_SUCCESS
+ || (queue_type != HSA_QUEUE_TYPE_MULTI))
+ return false;
+
+ return true;
+}
+
+/* Callback of hsa_iterate_agents; if AGENT is a GPU device, increment
+ agent_count in hsa_context. */
+
+static hsa_status_t
+count_gpu_agents (hsa_agent_t agent, void *data __attribute__ ((unused)))
+{
+ if (suitable_hsa_agent_p (agent))
+ hsa_context.agent_count++;
+ return HSA_STATUS_SUCCESS;
+}
+
+/* Callback of hsa_iterate_agents; if AGENT is a GPU device, assign the agent
+ id to the describing structure in the hsa context. The index of the
+ structure is pointed to by DATA, increment it afterwards. */
+
+static hsa_status_t
+assign_agent_ids (hsa_agent_t agent, void *data)
+{
+ if (suitable_hsa_agent_p (agent))
+ {
+ int *agent_index = (int *) data;
+ hsa_context.agents[*agent_index].id = agent;
+ ++*agent_index;
+ }
+ return HSA_STATUS_SUCCESS;
+}
+
+/* Initialize hsa_context if it has not already been done.
+ Return TRUE on success. */
+
+static bool
+init_hsa_context (void)
+{
+ hsa_status_t status;
+ int agent_index = 0;
+
+ if (hsa_context.initialized)
+ return true;
+ init_environment_variables ();
+ if (!init_hsa_runtime_functions ())
+ {
+ GCN_WARNING ("Run-time could not be dynamically opened\n");
+ if (suppress_host_fallback)
+ GOMP_PLUGIN_fatal ("GCN host fallback has been suppressed");
+ return false;
+ }
+ status = hsa_fns.hsa_init_fn ();
+ if (status != HSA_STATUS_SUCCESS)
+ return hsa_error ("Run-time could not be initialized", status);
+ GCN_DEBUG ("HSA run-time initialized for GCN\n");
+
+ if (debug)
+ dump_hsa_system_info ();
+
+ status = hsa_fns.hsa_iterate_agents_fn (count_gpu_agents, NULL);
+ if (status != HSA_STATUS_SUCCESS)
+ return hsa_error ("GCN GPU devices could not be enumerated", status);
+ GCN_DEBUG ("There are %i GCN GPU devices.\n", hsa_context.agent_count);
+
+ hsa_context.agents
+ = GOMP_PLUGIN_malloc_cleared (hsa_context.agent_count
+ * sizeof (struct agent_info));
+ status = hsa_fns.hsa_iterate_agents_fn (assign_agent_ids, &agent_index);
+ if (agent_index != hsa_context.agent_count)
+ {
+ GOMP_PLUGIN_error ("Failed to assign IDs to all GCN agents");
+ return false;
+ }
+
+ if (debug)
+ {
+ status = hsa_fns.hsa_iterate_agents_fn (dump_hsa_agent_info, NULL);
+ if (status != HSA_STATUS_SUCCESS)
+ GOMP_PLUGIN_error ("Failed to list all HSA runtime agents");
+ }
+
+ hsa_context.initialized = true;
+ return true;
+}
+
+/* Verify that hsa_context has already been initialized and return the
+ agent_info structure describing device number N. Return NULL on error. */
+
+static struct agent_info *
+get_agent_info (int n)
+{
+ if (!hsa_context.initialized)
+ {
+ GOMP_PLUGIN_error ("Attempt to use uninitialized GCN context.");
+ return NULL;
+ }
+ if (n >= hsa_context.agent_count)
+ {
+ GOMP_PLUGIN_error ("Request to operate on non-existent GCN device %i", n);
+ return NULL;
+ }
+ if (!hsa_context.agents[n].initialized)
+ {
+ GOMP_PLUGIN_error ("Attempt to use an uninitialized GCN agent.");
+ return NULL;
+ }
+ return &hsa_context.agents[n];
+}
+
+/* Callback of hsa_agent_iterate_regions, via get_*_memory_region functions.
+
+ Selects (breaks at) a suitable region of type KIND. */
+
+static hsa_status_t
+get_memory_region (hsa_region_t region, hsa_region_t *retval,
+ hsa_region_global_flag_t kind)
+{
+ hsa_status_t status;
+ hsa_region_segment_t segment;
+
+ status = hsa_fns.hsa_region_get_info_fn (region, HSA_REGION_INFO_SEGMENT,
+ &segment);
+ if (status != HSA_STATUS_SUCCESS)
+ return status;
+ if (segment != HSA_REGION_SEGMENT_GLOBAL)
+ return HSA_STATUS_SUCCESS;
+
+ uint32_t flags;
+ status = hsa_fns.hsa_region_get_info_fn (region, HSA_REGION_INFO_GLOBAL_FLAGS,
+ &flags);
+ if (status != HSA_STATUS_SUCCESS)
+ return status;
+ if (flags & kind)
+ {
+ *retval = region;
+ return HSA_STATUS_INFO_BREAK;
+ }
+ return HSA_STATUS_SUCCESS;
+}
+
+/* Callback of hsa_agent_iterate_regions.
+
+ Selects a kernargs memory region. */
+
+static hsa_status_t
+get_kernarg_memory_region (hsa_region_t region, void *data)
+{
+ return get_memory_region (region, (hsa_region_t *)data,
+ HSA_REGION_GLOBAL_FLAG_KERNARG);
+}
+
+/* Callback of hsa_agent_iterate_regions.
+
+ Selects a coarse-grained memory region suitable for the heap and
+ offload data. */
+
+static hsa_status_t
+get_data_memory_region (hsa_region_t region, void *data)
+{
+ return get_memory_region (region, (hsa_region_t *)data,
+ HSA_REGION_GLOBAL_FLAG_COARSE_GRAINED);
+}
+
+/* }}} */
+/* {{{ Run */
+
+/* Create or reuse a team arena.
+
+ Team arenas are used by OpenMP to avoid calling malloc multiple times
+ while setting up each team. This is purely a performance optimization.
+
+ Allocating an arena also costs performance, albeit on the host side, so
+ this function will reuse an existing arena if a large enough one is idle.
+ The arena is released, but not deallocated, when the kernel exits. */
+
+static void *
+get_team_arena (struct agent_info *agent, int num_teams)
+{
+ struct team_arena_list **next_ptr = &agent->team_arena_list;
+ struct team_arena_list *item;
+
+ for (item = *next_ptr; item; next_ptr = &item->next, item = item->next)
+ {
+ if (item->num_teams < num_teams)
+ continue;
+
+ if (pthread_mutex_trylock (&item->in_use))
+ continue;
+
+ return item->arena;
+ }
+
+ GCN_DEBUG ("Creating a new arena for %d teams\n", num_teams);
+
+ if (pthread_mutex_lock (&agent->team_arena_write_lock))
+ {
+ GOMP_PLUGIN_error ("Could not lock a GCN agent program mutex");
+ return false;
+ }
+ item = malloc (sizeof (*item));
+ item->num_teams = num_teams;
+ item->next = NULL;
+ *next_ptr = item;
+
+ if (pthread_mutex_init (&item->in_use, NULL))
+ {
+ GOMP_PLUGIN_error ("Failed to initialize a GCN team arena write mutex");
+ return false;
+ }
+ if (pthread_mutex_lock (&item->in_use))
+ {
+ GOMP_PLUGIN_error ("Could not lock a GCN agent program mutex");
+ return false;
+ }
+ if (pthread_mutex_unlock (&agent->team_arena_write_lock))
+ {
+ GOMP_PLUGIN_error ("Could not unlock a GCN agent program mutex");
+ return false;
+ }
+
+ const int TEAM_ARENA_SIZE = 64*1024; /* Must match libgomp.h. */
+ hsa_status_t status;
+ status = hsa_fns.hsa_memory_allocate_fn (agent->data_region,
+ TEAM_ARENA_SIZE*num_teams,
+ &item->arena);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not allocate memory for GCN kernel arena", status);
+ status = hsa_fns.hsa_memory_assign_agent_fn (item->arena, agent->id,
+ HSA_ACCESS_PERMISSION_RW);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not assign arena memory to device", status);
+
+ return item->arena;
+}
+
+/* Mark a team arena available for reuse. */
+
+static void
+release_team_arena (struct agent_info* agent, void *arena)
+{
+ struct team_arena_list *item;
+
+ for (item = agent->team_arena_list; item; item = item->next)
+ {
+ if (item->arena == arena)
+ {
+ if (pthread_mutex_unlock (&item->in_use))
+ GOMP_PLUGIN_error ("Could not unlock a GCN agent program mutex");
+ return;
+ }
+ }
+ GOMP_PLUGIN_error ("Could not find a GCN arena to release.");
+}
+
+/* Clean up all the allocated team arenas. */
+
+static bool
+destroy_team_arenas (struct agent_info *agent)
+{
+ struct team_arena_list *item, *next;
+
+ for (item = agent->team_arena_list; item; item = next)
+ {
+ next = item->next;
+ hsa_fns.hsa_memory_free_fn (item->arena);
+ if (pthread_mutex_destroy (&item->in_use))
+ {
+ GOMP_PLUGIN_error ("Failed to destroy a GCN team arena mutex");
+ return false;
+ }
+ free (item);
+ }
+ agent->team_arena_list = NULL;
+
+ return true;
+}
+
+/* Allocate memory on a specified device. */
+
+static void *
+alloc_by_agent (struct agent_info *agent, size_t size)
+{
+ GCN_DEBUG ("Allocating %zu bytes on device %d\n", size, agent->device_id);
+
+ /* Zero-size allocations are invalid, so in order to return a valid pointer
+ we need to pass a valid size. One source of zero-size allocations is
+ kernargs for kernels that have no inputs or outputs (the kernel may
+ only use console output, for example). */
+ if (size == 0)
+ size = 4;
+
+ void *ptr;
+ hsa_status_t status = hsa_fns.hsa_memory_allocate_fn (agent->data_region,
+ size, &ptr);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not allocate device memory", status);
+ return NULL;
+ }
+
+ status = hsa_fns.hsa_memory_assign_agent_fn (ptr, agent->id,
+ HSA_ACCESS_PERMISSION_RW);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not assign data memory to device", status);
+ return NULL;
+ }
+
+ struct goacc_thread *thr = GOMP_PLUGIN_goacc_thread ();
+ bool profiling_dispatch_p
+ = __builtin_expect (thr != NULL && thr->prof_info != NULL, false);
+ if (profiling_dispatch_p)
+ {
+ acc_prof_info *prof_info = thr->prof_info;
+ acc_event_info data_event_info;
+ acc_api_info *api_info = thr->api_info;
+
+ prof_info->event_type = acc_ev_alloc;
+
+ data_event_info.data_event.event_type = prof_info->event_type;
+ data_event_info.data_event.valid_bytes
+ = _ACC_DATA_EVENT_INFO_VALID_BYTES;
+ data_event_info.data_event.parent_construct
+ = acc_construct_parallel;
+ data_event_info.data_event.implicit = 1;
+ data_event_info.data_event.tool_info = NULL;
+ data_event_info.data_event.var_name = NULL;
+ data_event_info.data_event.bytes = size;
+ data_event_info.data_event.host_ptr = NULL;
+ data_event_info.data_event.device_ptr = (void *) ptr;
+
+ api_info->device_api = acc_device_api_other;
+
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info, &data_event_info,
+ api_info);
+ }
+
+ return ptr;
+}
+
+/* Create kernel dispatch data structure for given KERNEL, along with
+ the necessary device signals and memory allocations. */
+
+static struct kernel_dispatch *
+create_kernel_dispatch (struct kernel_info *kernel, int num_teams)
+{
+ struct agent_info *agent = kernel->agent;
+ struct kernel_dispatch *shadow
+ = GOMP_PLUGIN_malloc_cleared (sizeof (struct kernel_dispatch));
+
+ shadow->agent = kernel->agent;
+ shadow->object = kernel->object;
+
+ hsa_signal_t sync_signal;
+ hsa_status_t status = hsa_fns.hsa_signal_create_fn (1, 0, NULL, &sync_signal);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Error creating the GCN sync signal", status);
+
+ shadow->signal = sync_signal.handle;
+ shadow->private_segment_size = kernel->private_segment_size;
+ shadow->group_segment_size = kernel->group_segment_size;
+
+ /* We expect kernels to request a single pointer, explicitly, and the
+ rest of struct kernargs, implicitly. If they request anything else
+ then something is wrong. */
+ if (kernel->kernarg_segment_size > 8)
+ {
+ GOMP_PLUGIN_fatal ("Unexpectedly large kernargs segment requested");
+ return NULL;
+ }
+
+ status = hsa_fns.hsa_memory_allocate_fn (agent->kernarg_region,
+ sizeof (struct kernargs),
+ &shadow->kernarg_address);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not allocate memory for GCN kernel arguments", status);
+ struct kernargs *kernargs = shadow->kernarg_address;
+
+ /* Zero-initialize the output_data (minimum needed). */
+ kernargs->out_ptr = (int64_t)&kernargs->output_data;
+ kernargs->output_data.next_output = 0;
+ for (unsigned i = 0;
+ i < (sizeof (kernargs->output_data.queue)
+ / sizeof (kernargs->output_data.queue[0]));
+ i++)
+ kernargs->output_data.queue[i].written = 0;
+ kernargs->output_data.consumed = 0;
+
+ /* Pass in the heap location. */
+ kernargs->heap_ptr = (int64_t)kernel->module->heap;
+
+ /* Create an arena. */
+ if (kernel->kind == KIND_OPENMP)
+ kernargs->arena_ptr = (int64_t)get_team_arena (agent, num_teams);
+ else
+ kernargs->arena_ptr = 0;
+
+ /* Ensure we can recognize unset return values. */
+ kernargs->output_data.return_value = 0xcafe0000;
+
+ return shadow;
+}
+
+/* Output any data written to console output from the kernel. It is expected
+ that this function is polled during kernel execution.
+
+ We print all entries from the last item printed to the next entry without
+ a "written" flag. If the "final" flag is set then it'll continue right to
+ the end.
+
+ The print buffer is circular, but the from and to locations don't wrap when
+ the buffer does, so the output limit is UINT_MAX. The target blocks on
+ output when the buffer is full. */
+
+static void
+console_output (struct kernel_info *kernel, struct kernargs *kernargs,
+ bool final)
+{
+ unsigned int limit = (sizeof (kernargs->output_data.queue)
+ / sizeof (kernargs->output_data.queue[0]));
+
+ unsigned int from = __atomic_load_n (&kernargs->output_data.consumed,
+ __ATOMIC_ACQUIRE);
+ unsigned int to = kernargs->output_data.next_output;
+
+ if (from > to)
+ {
+ /* Overflow. */
+ if (final)
+ printf ("GCN print buffer overflowed.\n");
+ return;
+ }
+
+ unsigned int i;
+ for (i = from; i < to; i++)
+ {
+ struct printf_data *data = &kernargs->output_data.queue[i%limit];
+
+ if (!data->written && !final)
+ break;
+
+ switch (data->type)
+ {
+ case 0: printf ("%.128s%ld\n", data->msg, data->ivalue); break;
+ case 1: printf ("%.128s%f\n", data->msg, data->dvalue); break;
+ case 2: printf ("%.128s%.128s\n", data->msg, data->text); break;
+ case 3: printf ("%.128s%.128s", data->msg, data->text); break;
+ default: printf ("GCN print buffer error!\n"); break;
+ }
+ data->written = 0;
+ __atomic_store_n (&kernargs->output_data.consumed, i+1,
+ __ATOMIC_RELEASE);
+ }
+ fflush (stdout);
+}
+
+/* Release data structure created for a kernel dispatch in SHADOW argument,
+ and clean up the signal and memory allocations. */
+
+static void
+release_kernel_dispatch (struct kernel_dispatch *shadow)
+{
+ GCN_DEBUG ("Released kernel dispatch: %p\n", shadow);
+
+ struct kernargs *kernargs = shadow->kernarg_address;
+ void *arena = (void *)kernargs->arena_ptr;
+ if (arena)
+ release_team_arena (shadow->agent, arena);
+
+ hsa_fns.hsa_memory_free_fn (shadow->kernarg_address);
+
+ hsa_signal_t s;
+ s.handle = shadow->signal;
+ hsa_fns.hsa_signal_destroy_fn (s);
+
+ free (shadow);
+}
+
+/* Extract the properties from a kernel binary. */
+
+static void
+init_kernel_properties (struct kernel_info *kernel)
+{
+ hsa_status_t status;
+ struct agent_info *agent = kernel->agent;
+ hsa_executable_symbol_t kernel_symbol;
+ status = hsa_fns.hsa_executable_get_symbol_fn (agent->executable, NULL,
+ kernel->name, agent->id,
+ 0, &kernel_symbol);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_warn ("Could not find symbol for kernel in the code object", status);
+ fprintf (stderr, "not found name: '%s'\n", kernel->name);
+ dump_executable_symbols (agent->executable);
+ goto failure;
+ }
+ GCN_DEBUG ("Located kernel %s\n", kernel->name);
+ status = hsa_fns.hsa_executable_symbol_get_info_fn
+ (kernel_symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &kernel->object);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not extract a kernel object from its symbol", status);
+ status = hsa_fns.hsa_executable_symbol_get_info_fn
+ (kernel_symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE,
+ &kernel->kernarg_segment_size);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not get info about kernel argument size", status);
+ status = hsa_fns.hsa_executable_symbol_get_info_fn
+ (kernel_symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_GROUP_SEGMENT_SIZE,
+ &kernel->group_segment_size);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not get info about kernel group segment size", status);
+ status = hsa_fns.hsa_executable_symbol_get_info_fn
+ (kernel_symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_PRIVATE_SEGMENT_SIZE,
+ &kernel->private_segment_size);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not get info about kernel private segment size",
+ status);
+
+ /* The kernel type is not known until something tries to launch it. */
+ kernel->kind = KIND_UNKNOWN;
+
+ GCN_DEBUG ("Kernel structure for %s fully initialized with "
+ "following segment sizes: \n", kernel->name);
+ GCN_DEBUG (" group_segment_size: %u\n",
+ (unsigned) kernel->group_segment_size);
+ GCN_DEBUG (" private_segment_size: %u\n",
+ (unsigned) kernel->private_segment_size);
+ GCN_DEBUG (" kernarg_segment_size: %u\n",
+ (unsigned) kernel->kernarg_segment_size);
+ return;
+
+failure:
+ kernel->initialization_failed = true;
+}
+
+/* Do all the work that is necessary before running KERNEL for the first time.
+ The function assumes the program has been created, finalized and frozen by
+ create_and_finalize_hsa_program. */
+
+static void
+init_kernel (struct kernel_info *kernel)
+{
+ if (pthread_mutex_lock (&kernel->init_mutex))
+ GOMP_PLUGIN_fatal ("Could not lock a GCN kernel initialization mutex");
+ if (kernel->initialized)
+ {
+ if (pthread_mutex_unlock (&kernel->init_mutex))
+ GOMP_PLUGIN_fatal ("Could not unlock a GCN kernel initialization "
+ "mutex");
+
+ return;
+ }
+
+ init_kernel_properties (kernel);
+
+ if (!kernel->initialization_failed)
+ {
+ GCN_DEBUG ("\n");
+
+ kernel->initialized = true;
+ }
+ if (pthread_mutex_unlock (&kernel->init_mutex))
+ GOMP_PLUGIN_fatal ("Could not unlock a GCN kernel initialization "
+ "mutex");
+}
+
+/* Run KERNEL on its agent, pass VARS to it as arguments and take
+ launch attributes from KLA.
+
+ MODULE_LOCKED indicates that the caller already holds the lock and
+ run_kernel need not lock it again.
+ If AQ is NULL then agent->sync_queue will be used. */
+
+static void
+run_kernel (struct kernel_info *kernel, void *vars,
+ struct GOMP_kernel_launch_attributes *kla,
+ struct goacc_asyncqueue *aq, bool module_locked)
+{
+ GCN_DEBUG ("GCN launch on queue: %d:%d\n", kernel->agent->device_id,
+ (aq ? aq->id : 0));
+ GCN_DEBUG ("GCN launch attribs: gdims:[");
+ int i;
+ for (i = 0; i < kla->ndim; ++i)
+ {
+ if (i)
+ DEBUG_PRINT (", ");
+ DEBUG_PRINT ("%u", kla->gdims[i]);
+ }
+ DEBUG_PRINT ("], normalized gdims:[");
+ for (i = 0; i < kla->ndim; ++i)
+ {
+ if (i)
+ DEBUG_PRINT (", ");
+ DEBUG_PRINT ("%u", kla->gdims[i] / kla->wdims[i]);
+ }
+ DEBUG_PRINT ("], wdims:[");
+ for (i = 0; i < kla->ndim; ++i)
+ {
+ if (i)
+ DEBUG_PRINT (", ");
+ DEBUG_PRINT ("%u", kla->wdims[i]);
+ }
+ DEBUG_PRINT ("]\n");
+ DEBUG_FLUSH ();
+
+ struct agent_info *agent = kernel->agent;
+ if (!module_locked && pthread_rwlock_rdlock (&agent->module_rwlock))
+ GOMP_PLUGIN_fatal ("Unable to read-lock a GCN agent rwlock");
+
+ if (!agent->initialized)
+ GOMP_PLUGIN_fatal ("Agent must be initialized");
+
+ if (!kernel->initialized)
+ GOMP_PLUGIN_fatal ("Called kernel must be initialized");
+
+ hsa_queue_t *command_q = (aq ? aq->hsa_queue : kernel->agent->sync_queue);
+
+ uint64_t index
+ = hsa_fns.hsa_queue_add_write_index_release_fn (command_q, 1);
+ GCN_DEBUG ("Got AQL index %llu\n", (long long int) index);
+
+ /* Wait until the queue is not full before writing the packet. */
+ while (index - hsa_fns.hsa_queue_load_read_index_acquire_fn (command_q)
+ >= command_q->size)
+ ;
+
+ /* Do not allow the dimensions to be overridden when running
+ constructors or destructors. */
+ int override_x = kernel->kind == KIND_UNKNOWN ? 0 : override_x_dim;
+ int override_z = kernel->kind == KIND_UNKNOWN ? 0 : override_z_dim;
+
+ hsa_kernel_dispatch_packet_t *packet;
+ packet = ((hsa_kernel_dispatch_packet_t *) command_q->base_address)
+ + index % command_q->size;
+
+ memset (((uint8_t *) packet) + 4, 0, sizeof (*packet) - 4);
+ packet->grid_size_x = override_x ? : kla->gdims[0];
+ packet->workgroup_size_x = get_group_size (kla->ndim,
+ packet->grid_size_x,
+ kla->wdims[0]);
+
+ if (kla->ndim >= 2)
+ {
+ packet->grid_size_y = kla->gdims[1];
+ packet->workgroup_size_y = get_group_size (kla->ndim, kla->gdims[1],
+ kla->wdims[1]);
+ }
+ else
+ {
+ packet->grid_size_y = 1;
+ packet->workgroup_size_y = 1;
+ }
+
+ if (kla->ndim == 3)
+ {
+ packet->grid_size_z = limit_worker_threads (override_z
+ ? : kla->gdims[2]);
+ packet->workgroup_size_z = get_group_size (kla->ndim,
+ packet->grid_size_z,
+ kla->wdims[2]);
+ }
+ else
+ {
+ packet->grid_size_z = 1;
+ packet->workgroup_size_z = 1;
+ }
+
+ GCN_DEBUG ("GCN launch actuals: grid:[%u, %u, %u],"
+ " normalized grid:[%u, %u, %u], workgroup:[%u, %u, %u]\n",
+ packet->grid_size_x, packet->grid_size_y, packet->grid_size_z,
+ packet->grid_size_x / packet->workgroup_size_x,
+ packet->grid_size_y / packet->workgroup_size_y,
+ packet->grid_size_z / packet->workgroup_size_z,
+ packet->workgroup_size_x, packet->workgroup_size_y,
+ packet->workgroup_size_z);
+
+ struct kernel_dispatch *shadow
+ = create_kernel_dispatch (kernel, packet->grid_size_x);
+ shadow->queue = command_q;
+
+ if (debug)
+ {
+ fprintf (stderr, "\nKernel has following dependencies:\n");
+ print_kernel_dispatch (shadow, 2);
+ }
+
+ packet->private_segment_size = kernel->private_segment_size;
+ packet->group_segment_size = kernel->group_segment_size;
+ packet->kernel_object = kernel->object;
+ packet->kernarg_address = shadow->kernarg_address;
+ hsa_signal_t s;
+ s.handle = shadow->signal;
+ packet->completion_signal = s;
+ hsa_fns.hsa_signal_store_relaxed_fn (s, 1);
+ memcpy (shadow->kernarg_address, &vars, sizeof (vars));
+
+ GCN_DEBUG ("Copying kernel runtime pointer to kernarg_address\n");
+
+ uint16_t header;
+ header = HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE;
+ header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE;
+ header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE;
+
+ GCN_DEBUG ("Going to dispatch kernel %s on device %d\n", kernel->name,
+ agent->device_id);
+
+ packet_store_release ((uint32_t *) packet, header,
+ (uint16_t) kla->ndim
+ << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS);
+
+ hsa_fns.hsa_signal_store_release_fn (command_q->doorbell_signal,
+ index);
+
+ GCN_DEBUG ("Kernel dispatched, waiting for completion\n");
+
+ /* Root signal waits with 1ms timeout. */
+ while (hsa_fns.hsa_signal_wait_acquire_fn (s, HSA_SIGNAL_CONDITION_LT, 1,
+ 1000 * 1000,
+ HSA_WAIT_STATE_BLOCKED) != 0)
+ {
+ console_output (kernel, shadow->kernarg_address, false);
+ }
+ console_output (kernel, shadow->kernarg_address, true);
+
+ struct kernargs *kernargs = shadow->kernarg_address;
+ unsigned int return_value = (unsigned int)kernargs->output_data.return_value;
+
+ release_kernel_dispatch (shadow);
+
+ if (!module_locked && pthread_rwlock_unlock (&agent->module_rwlock))
+ GOMP_PLUGIN_fatal ("Unable to unlock a GCN agent rwlock");
+
+ unsigned int upper = (return_value & ~0xffff) >> 16;
+ if (upper == 0xcafe)
+ ; // exit not called, normal termination.
+ else if (upper == 0xffff)
+ ; // exit called.
+ else
+ {
+ GOMP_PLUGIN_error ("Possible kernel exit value corruption, 2 most"
+ " significant bytes aren't 0xffff or 0xcafe: 0x%x\n",
+ return_value);
+ abort ();
+ }
+
+ if (upper == 0xffff)
+ {
+ unsigned int signal = (return_value >> 8) & 0xff;
+
+ if (signal == SIGABRT)
+ {
+ GCN_WARNING ("GCN Kernel aborted\n");
+ abort ();
+ }
+ else if (signal != 0)
+ {
+ GCN_WARNING ("GCN Kernel received unknown signal\n");
+ abort ();
+ }
+
+ GCN_DEBUG ("GCN Kernel exited with value: %d\n", return_value & 0xff);
+ exit (return_value & 0xff);
+ }
+}
+
+/* }}} */
+/* {{{ Load/Unload */
+
+/* Initialize KERNEL from D and other parameters. Return true on success. */
+
+static bool
+init_basic_kernel_info (struct kernel_info *kernel,
+ struct hsa_kernel_description *d,
+ struct agent_info *agent,
+ struct module_info *module)
+{
+ kernel->agent = agent;
+ kernel->module = module;
+ kernel->name = d->name;
+ if (pthread_mutex_init (&kernel->init_mutex, NULL))
+ {
+ GOMP_PLUGIN_error ("Failed to initialize a GCN kernel mutex");
+ return false;
+ }
+ return true;
+}
+
+/* Find the load_offset for MODULE, save to *LOAD_OFFSET, and return true. If
+ not found, return false. */
+
+static bool
+find_load_offset (Elf64_Addr *load_offset, struct agent_info *agent,
+ struct module_info *module, Elf64_Ehdr *image,
+ Elf64_Shdr *sections)
+{
+ bool res = false;
+
+ hsa_status_t status;
+
+ hsa_executable_symbol_t symbol;
+ if (!find_executable_symbol (agent->executable, &symbol))
+ return false;
+
+ status = hsa_fns.hsa_executable_symbol_get_info_fn
+ (symbol, HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_ADDRESS, load_offset);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not extract symbol address", status);
+ return false;
+ }
+
+ char *symbol_name = get_executable_symbol_name (symbol);
+ if (symbol_name == NULL)
+ return false;
+
+ /* Find the kernel function in ELF, and calculate actual load offset. */
+ for (int i = 0; i < image->e_shnum; i++)
+ if (sections[i].sh_type == SHT_SYMTAB)
+ {
+ Elf64_Shdr *strtab = &sections[sections[i].sh_link];
+ char *strings = (char *)image + strtab->sh_offset;
+
+ for (size_t offset = 0;
+ offset < sections[i].sh_size;
+ offset += sections[i].sh_entsize)
+ {
+ Elf64_Sym *sym = (Elf64_Sym*)((char*)image
+ + sections[i].sh_offset
+ + offset);
+ if (strcmp (symbol_name, strings + sym->st_name) == 0)
+ {
+ *load_offset -= sym->st_value;
+ res = true;
+ break;
+ }
+ }
+ }
+
+ free (symbol_name);
+ return res;
+}
+
+/* Create and finalize the program consisting of all loaded modules. */
+
+static bool
+create_and_finalize_hsa_program (struct agent_info *agent)
+{
+ hsa_status_t status;
+ int reloc_count = 0;
+ bool res = true;
+ if (pthread_mutex_lock (&agent->prog_mutex))
+ {
+ GOMP_PLUGIN_error ("Could not lock a GCN agent program mutex");
+ return false;
+ }
+ if (agent->prog_finalized)
+ goto final;
+
+ status
+ = hsa_fns.hsa_executable_create_fn (HSA_PROFILE_FULL,
+ HSA_EXECUTABLE_STATE_UNFROZEN,
+ "", &agent->executable);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not create GCN executable", status);
+ goto fail;
+ }
+
+ /* Load any GCN modules. */
+ struct module_info *module = agent->module;
+ if (module)
+ {
+ Elf64_Ehdr *image = (Elf64_Ehdr *)module->image_desc->gcn_image->image;
+
+ /* Hide relocations from the HSA runtime loader.
+ Keep a copy of the unmodified section headers to use later. */
+ Elf64_Shdr *image_sections = (Elf64_Shdr *)((char *)image
+ + image->e_shoff);
+ for (int i = image->e_shnum - 1; i >= 0; i--)
+ {
+ if (image_sections[i].sh_type == SHT_RELA
+ || image_sections[i].sh_type == SHT_REL)
+ /* Change section type to something harmless. */
+ image_sections[i].sh_type |= 0x80;
+ }
+
+ hsa_code_object_t co = { 0 };
+ status = hsa_fns.hsa_code_object_deserialize_fn
+ (module->image_desc->gcn_image->image,
+ module->image_desc->gcn_image->size,
+ NULL, &co);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not deserialize GCN code object", status);
+ goto fail;
+ }
+
+ status = hsa_fns.hsa_executable_load_code_object_fn
+ (agent->executable, agent->id, co, "");
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not load GCN code object", status);
+ goto fail;
+ }
+
+ if (!module->heap)
+ {
+ status = hsa_fns.hsa_memory_allocate_fn (agent->data_region,
+ gcn_kernel_heap_size,
+ (void**)&module->heap);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not allocate memory for GCN heap", status);
+ goto fail;
+ }
+
+ status = hsa_fns.hsa_memory_assign_agent_fn
+ (module->heap, agent->id, HSA_ACCESS_PERMISSION_RW);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not assign GCN heap memory to device", status);
+ goto fail;
+ }
+
+ hsa_fns.hsa_memory_copy_fn (&module->heap->size,
+ &gcn_kernel_heap_size,
+ sizeof (gcn_kernel_heap_size));
+ }
+
+ }
+
+ if (debug)
+ dump_executable_symbols (agent->executable);
+
+ status = hsa_fns.hsa_executable_freeze_fn (agent->executable, "");
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not freeze the GCN executable", status);
+ goto fail;
+ }
+
+ if (agent->module)
+ {
+ struct module_info *module = agent->module;
+ Elf64_Ehdr *image = (Elf64_Ehdr *)module->image_desc->gcn_image->image;
+ Elf64_Shdr *sections = (Elf64_Shdr *)((char *)image + image->e_shoff);
+
+ Elf64_Addr load_offset;
+ if (!find_load_offset (&load_offset, agent, module, image, sections))
+ goto fail;
+
+ /* Record the physical load address range.
+ We need this for data copies later. */
+ Elf64_Phdr *segments = (Elf64_Phdr *)((char*)image + image->e_phoff);
+ Elf64_Addr low = ~0, high = 0;
+ for (int i = 0; i < image->e_phnum; i++)
+ if (segments[i].p_memsz > 0)
+ {
+ if (segments[i].p_paddr < low)
+ low = segments[i].p_paddr;
+ if (segments[i].p_paddr > high)
+ high = segments[i].p_paddr + segments[i].p_memsz - 1;
+ }
+ module->phys_address_start = low + load_offset;
+ module->phys_address_end = high + load_offset;
+
+ // Find dynamic symbol table
+ Elf64_Shdr *dynsym = NULL;
+ for (int i = 0; i < image->e_shnum; i++)
+ if (sections[i].sh_type == SHT_DYNSYM)
+ {
+ dynsym = &sections[i];
+ break;
+ }
+
+ /* Fix up relocations. */
+ for (int i = 0; i < image->e_shnum; i++)
+ {
+ if (sections[i].sh_type == (SHT_RELA | 0x80))
+ for (size_t offset = 0;
+ offset < sections[i].sh_size;
+ offset += sections[i].sh_entsize)
+ {
+ Elf64_Rela *reloc = (Elf64_Rela*)((char*)image
+ + sections[i].sh_offset
+ + offset);
+ Elf64_Sym *sym =
+ (dynsym
+ ? (Elf64_Sym*)((char*)image
+ + dynsym->sh_offset
+ + (dynsym->sh_entsize
+ * ELF64_R_SYM (reloc->r_info)))
+ : NULL);
+
+ int64_t S = (sym ? sym->st_value : 0);
+ int64_t P = reloc->r_offset + load_offset;
+ int64_t A = reloc->r_addend;
+ int64_t B = load_offset;
+ int64_t V, size;
+ switch (ELF64_R_TYPE (reloc->r_info))
+ {
+ case R_AMDGPU_ABS32_LO:
+ V = (S + A) & 0xFFFFFFFF;
+ size = 4;
+ break;
+ case R_AMDGPU_ABS32_HI:
+ V = (S + A) >> 32;
+ size = 4;
+ break;
+ case R_AMDGPU_ABS64:
+ V = S + A;
+ size = 8;
+ break;
+ case R_AMDGPU_REL32:
+ V = S + A - P;
+ size = 4;
+ break;
+ case R_AMDGPU_REL64:
+ /* FIXME
+ LLD seems to emit REL64 where the the assembler has
+ ABS64. This is clearly wrong because it's not what the
+ compiler is expecting. Let's assume, for now, that
+ it's a bug. In any case, GCN kernels are always self
+ contained and therefore relative relocations will have
+ been resolved already, so this should be a safe
+ workaround. */
+ V = S + A/* - P*/;
+ size = 8;
+ break;
+ case R_AMDGPU_ABS32:
+ V = S + A;
+ size = 4;
+ break;
+ /* TODO R_AMDGPU_GOTPCREL */
+ /* TODO R_AMDGPU_GOTPCREL32_LO */
+ /* TODO R_AMDGPU_GOTPCREL32_HI */
+ case R_AMDGPU_REL32_LO:
+ V = (S + A - P) & 0xFFFFFFFF;
+ size = 4;
+ break;
+ case R_AMDGPU_REL32_HI:
+ V = (S + A - P) >> 32;
+ size = 4;
+ break;
+ case R_AMDGPU_RELATIVE64:
+ V = B + A;
+ size = 8;
+ break;
+ default:
+ fprintf (stderr, "Error: unsupported relocation type.\n");
+ exit (1);
+ }
+ status = hsa_fns.hsa_memory_copy_fn ((void*)P, &V, size);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Failed to fix up relocation", status);
+ goto fail;
+ }
+ reloc_count++;
+ }
+ }
+ }
+
+ GCN_DEBUG ("Loaded GCN kernels to device %d (%d relocations)\n",
+ agent->device_id, reloc_count);
+
+final:
+ agent->prog_finalized = true;
+
+ if (pthread_mutex_unlock (&agent->prog_mutex))
+ {
+ GOMP_PLUGIN_error ("Could not unlock a GCN agent program mutex");
+ res = false;
+ }
+
+ return res;
+
+fail:
+ res = false;
+ goto final;
+}
+
+/* Free the HSA program in agent and everything associated with it and set
+ agent->prog_finalized and the initialized flags of all kernels to false.
+ Return TRUE on success. */
+
+static bool
+destroy_hsa_program (struct agent_info *agent)
+{
+ if (!agent->prog_finalized)
+ return true;
+
+ hsa_status_t status;
+
+ GCN_DEBUG ("Destroying the current GCN program.\n");
+
+ status = hsa_fns.hsa_executable_destroy_fn (agent->executable);
+ if (status != HSA_STATUS_SUCCESS)
+ return hsa_error ("Could not destroy GCN executable", status);
+
+ if (agent->module)
+ {
+ int i;
+ for (i = 0; i < agent->module->kernel_count; i++)
+ agent->module->kernels[i].initialized = false;
+
+ if (agent->module->heap)
+ {
+ hsa_fns.hsa_memory_free_fn (agent->module->heap);
+ agent->module->heap = NULL;
+ }
+ }
+ agent->prog_finalized = false;
+ return true;
+}
+
+/* Deinitialize all information associated with MODULE and kernels within
+ it. Return TRUE on success. */
+
+static bool
+destroy_module (struct module_info *module, bool locked)
+{
+ /* Run destructors before destroying module. */
+ struct GOMP_kernel_launch_attributes kla =
+ { 3,
+ /* Grid size. */
+ { 1, 64, 1 },
+ /* Work-group size. */
+ { 1, 64, 1 }
+ };
+
+ if (module->fini_array_func)
+ {
+ init_kernel (module->fini_array_func);
+ run_kernel (module->fini_array_func, NULL, &kla, NULL, locked);
+ }
+ module->constructors_run_p = false;
+
+ int i;
+ for (i = 0; i < module->kernel_count; i++)
+ if (pthread_mutex_destroy (&module->kernels[i].init_mutex))
+ {
+ GOMP_PLUGIN_error ("Failed to destroy a GCN kernel initialization "
+ "mutex");
+ return false;
+ }
+
+ return true;
+}
+
+/* }}} */
+/* {{{ Async */
+
+/* Callback of dispatch queues to report errors. */
+
+static void
+execute_queue_entry (struct goacc_asyncqueue *aq, int index)
+{
+ struct queue_entry *entry = &aq->queue[index];
+
+ switch (entry->type)
+ {
+ case KERNEL_LAUNCH:
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("Async thread %d:%d: Executing launch entry (%d)\n",
+ aq->agent->device_id, aq->id, index);
+ run_kernel (entry->u.launch.kernel,
+ entry->u.launch.vars,
+ &entry->u.launch.kla, aq, false);
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("Async thread %d:%d: Executing launch entry (%d) done\n",
+ aq->agent->device_id, aq->id, index);
+ break;
+
+ case CALLBACK:
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("Async thread %d:%d: Executing callback entry (%d)\n",
+ aq->agent->device_id, aq->id, index);
+ entry->u.callback.fn (entry->u.callback.data);
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("Async thread %d:%d: Executing callback entry (%d) done\n",
+ aq->agent->device_id, aq->id, index);
+ break;
+
+ case ASYNC_WAIT:
+ {
+ /* FIXME: is it safe to access a placeholder that may already have
+ been executed? */
+ struct placeholder *placeholderp = entry->u.asyncwait.placeholderp;
+
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("Async thread %d:%d: Executing async wait entry (%d)\n",
+ aq->agent->device_id, aq->id, index);
+
+ pthread_mutex_lock (&placeholderp->mutex);
+
+ while (!placeholderp->executed)
+ pthread_cond_wait (&placeholderp->cond, &placeholderp->mutex);
+
+ pthread_mutex_unlock (&placeholderp->mutex);
+
+ if (pthread_cond_destroy (&placeholderp->cond))
+ GOMP_PLUGIN_error ("Failed to destroy serialization cond");
+
+ if (pthread_mutex_destroy (&placeholderp->mutex))
+ GOMP_PLUGIN_error ("Failed to destroy serialization mutex");
+
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("Async thread %d:%d: Executing async wait "
+ "entry (%d) done\n", aq->agent->device_id, aq->id, index);
+ }
+ break;
+
+ case ASYNC_PLACEHOLDER:
+ pthread_mutex_lock (&entry->u.placeholder.mutex);
+ entry->u.placeholder.executed = 1;
+ pthread_cond_signal (&entry->u.placeholder.cond);
+ pthread_mutex_unlock (&entry->u.placeholder.mutex);
+ break;
+
+ default:
+ GOMP_PLUGIN_fatal ("Unknown queue element");
+ }
+}
+
+/* This function is run as a thread to service an async queue in the
+ background. It runs continuously until the stop flag is set. */
+
+static void *
+drain_queue (void *thread_arg)
+{
+ struct goacc_asyncqueue *aq = thread_arg;
+
+ if (DRAIN_QUEUE_SYNCHRONOUS_P)
+ {
+ aq->drain_queue_stop = 2;
+ return NULL;
+ }
+
+ pthread_mutex_lock (&aq->mutex);
+
+ while (true)
+ {
+ if (aq->drain_queue_stop)
+ break;
+
+ if (aq->queue_n > 0)
+ {
+ pthread_mutex_unlock (&aq->mutex);
+ execute_queue_entry (aq, aq->queue_first);
+
+ pthread_mutex_lock (&aq->mutex);
+ aq->queue_first = ((aq->queue_first + 1)
+ % ASYNC_QUEUE_SIZE);
+ aq->queue_n--;
+
+ if (DEBUG_THREAD_SIGNAL)
+ GCN_DEBUG ("Async thread %d:%d: broadcasting queue out update\n",
+ aq->agent->device_id, aq->id);
+ pthread_cond_broadcast (&aq->queue_cond_out);
+ pthread_mutex_unlock (&aq->mutex);
+
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("Async thread %d:%d: continue\n", aq->agent->device_id,
+ aq->id);
+ pthread_mutex_lock (&aq->mutex);
+ }
+ else
+ {
+ if (DEBUG_THREAD_SLEEP)
+ GCN_DEBUG ("Async thread %d:%d: going to sleep\n",
+ aq->agent->device_id, aq->id);
+ pthread_cond_wait (&aq->queue_cond_in, &aq->mutex);
+ if (DEBUG_THREAD_SLEEP)
+ GCN_DEBUG ("Async thread %d:%d: woke up, rechecking\n",
+ aq->agent->device_id, aq->id);
+ }
+ }
+
+ aq->drain_queue_stop = 2;
+ if (DEBUG_THREAD_SIGNAL)
+ GCN_DEBUG ("Async thread %d:%d: broadcasting last queue out update\n",
+ aq->agent->device_id, aq->id);
+ pthread_cond_broadcast (&aq->queue_cond_out);
+ pthread_mutex_unlock (&aq->mutex);
+
+ GCN_DEBUG ("Async thread %d:%d: returning\n", aq->agent->device_id, aq->id);
+ return NULL;
+}
+
+/* This function is used only when DRAIN_QUEUE_SYNCHRONOUS_P is set, which
+ is not usually the case. This is just a debug tool. */
+
+static void
+drain_queue_synchronous (struct goacc_asyncqueue *aq)
+{
+ pthread_mutex_lock (&aq->mutex);
+
+ while (aq->queue_n > 0)
+ {
+ execute_queue_entry (aq, aq->queue_first);
+
+ aq->queue_first = ((aq->queue_first + 1)
+ % ASYNC_QUEUE_SIZE);
+ aq->queue_n--;
+ }
+
+ pthread_mutex_unlock (&aq->mutex);
+}
+
+/* Block the current thread until an async queue is writable. The aq->mutex
+ lock should be held on entry, and remains locked on exit. */
+
+static void
+wait_for_queue_nonfull (struct goacc_asyncqueue *aq)
+{
+ if (aq->queue_n == ASYNC_QUEUE_SIZE)
+ {
+ /* Queue is full. Wait for it to not be full. */
+ while (aq->queue_n == ASYNC_QUEUE_SIZE)
+ pthread_cond_wait (&aq->queue_cond_out, &aq->mutex);
+ }
+}
+
+/* Request an asynchronous kernel launch on the specified queue. This
+ may block if the queue is full, but returns without waiting for the
+ kernel to run. */
+
+static void
+queue_push_launch (struct goacc_asyncqueue *aq, struct kernel_info *kernel,
+ void *vars, struct GOMP_kernel_launch_attributes *kla)
+{
+ assert (aq->agent == kernel->agent);
+
+ pthread_mutex_lock (&aq->mutex);
+
+ wait_for_queue_nonfull (aq);
+
+ int queue_last = ((aq->queue_first + aq->queue_n)
+ % ASYNC_QUEUE_SIZE);
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("queue_push_launch %d:%d: at %i\n", aq->agent->device_id,
+ aq->id, queue_last);
+
+ aq->queue[queue_last].type = KERNEL_LAUNCH;
+ aq->queue[queue_last].u.launch.kernel = kernel;
+ aq->queue[queue_last].u.launch.vars = vars;
+ aq->queue[queue_last].u.launch.kla = *kla;
+
+ aq->queue_n++;
+
+ if (DEBUG_THREAD_SIGNAL)
+ GCN_DEBUG ("signalling async thread %d:%d: cond_in\n",
+ aq->agent->device_id, aq->id);
+ pthread_cond_signal (&aq->queue_cond_in);
+
+ pthread_mutex_unlock (&aq->mutex);
+}
+
+/* Request an asynchronous callback on the specified queue. The callback
+ function will be called, with the given opaque data, from the appropriate
+ async thread, when all previous items on that queue are complete. */
+
+static void
+queue_push_callback (struct goacc_asyncqueue *aq, void (*fn)(void *),
+ void *data)
+{
+ pthread_mutex_lock (&aq->mutex);
+
+ wait_for_queue_nonfull (aq);
+
+ int queue_last = ((aq->queue_first + aq->queue_n)
+ % ASYNC_QUEUE_SIZE);
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("queue_push_callback %d:%d: at %i\n", aq->agent->device_id,
+ aq->id, queue_last);
+
+ aq->queue[queue_last].type = CALLBACK;
+ aq->queue[queue_last].u.callback.fn = fn;
+ aq->queue[queue_last].u.callback.data = data;
+
+ aq->queue_n++;
+
+ if (DEBUG_THREAD_SIGNAL)
+ GCN_DEBUG ("signalling async thread %d:%d: cond_in\n",
+ aq->agent->device_id, aq->id);
+ pthread_cond_signal (&aq->queue_cond_in);
+
+ pthread_mutex_unlock (&aq->mutex);
+}
+
+/* Request that a given async thread wait for another thread (unspecified) to
+ reach the given placeholder. The wait will occur when all previous entries
+ on the queue are complete. A placeholder is effectively a kind of signal
+ which simply sets a flag when encountered in a queue. */
+
+static void
+queue_push_asyncwait (struct goacc_asyncqueue *aq,
+ struct placeholder *placeholderp)
+{
+ pthread_mutex_lock (&aq->mutex);
+
+ wait_for_queue_nonfull (aq);
+
+ int queue_last = ((aq->queue_first + aq->queue_n) % ASYNC_QUEUE_SIZE);
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("queue_push_asyncwait %d:%d: at %i\n", aq->agent->device_id,
+ aq->id, queue_last);
+
+ aq->queue[queue_last].type = ASYNC_WAIT;
+ aq->queue[queue_last].u.asyncwait.placeholderp = placeholderp;
+
+ aq->queue_n++;
+
+ if (DEBUG_THREAD_SIGNAL)
+ GCN_DEBUG ("signalling async thread %d:%d: cond_in\n",
+ aq->agent->device_id, aq->id);
+ pthread_cond_signal (&aq->queue_cond_in);
+
+ pthread_mutex_unlock (&aq->mutex);
+}
+
+/* Add a placeholder into an async queue. When the async thread reaches the
+ placeholder it will set the "executed" flag to true and continue.
+ Another thread may be waiting on this thread reaching the placeholder. */
+
+static struct placeholder *
+queue_push_placeholder (struct goacc_asyncqueue *aq)
+{
+ struct placeholder *placeholderp;
+
+ pthread_mutex_lock (&aq->mutex);
+
+ wait_for_queue_nonfull (aq);
+
+ int queue_last = ((aq->queue_first + aq->queue_n) % ASYNC_QUEUE_SIZE);
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("queue_push_placeholder %d:%d: at %i\n", aq->agent->device_id,
+ aq->id, queue_last);
+
+ aq->queue[queue_last].type = ASYNC_PLACEHOLDER;
+ placeholderp = &aq->queue[queue_last].u.placeholder;
+
+ if (pthread_mutex_init (&placeholderp->mutex, NULL))
+ {
+ pthread_mutex_unlock (&aq->mutex);
+ GOMP_PLUGIN_error ("Failed to initialize serialization mutex");
+ }
+
+ if (pthread_cond_init (&placeholderp->cond, NULL))
+ {
+ pthread_mutex_unlock (&aq->mutex);
+ GOMP_PLUGIN_error ("Failed to initialize serialization cond");
+ }
+
+ placeholderp->executed = 0;
+
+ aq->queue_n++;
+
+ if (DEBUG_THREAD_SIGNAL)
+ GCN_DEBUG ("signalling async thread %d:%d: cond_in\n",
+ aq->agent->device_id, aq->id);
+ pthread_cond_signal (&aq->queue_cond_in);
+
+ pthread_mutex_unlock (&aq->mutex);
+
+ return placeholderp;
+}
+
+/* Signal an asynchronous thread to terminate, and wait for it to do so. */
+
+static void
+finalize_async_thread (struct goacc_asyncqueue *aq)
+{
+ pthread_mutex_lock (&aq->mutex);
+ if (aq->drain_queue_stop == 2)
+ {
+ pthread_mutex_unlock (&aq->mutex);
+ return;
+ }
+
+ aq->drain_queue_stop = 1;
+
+ if (DEBUG_THREAD_SIGNAL)
+ GCN_DEBUG ("Signalling async thread %d:%d: cond_in\n",
+ aq->agent->device_id, aq->id);
+ pthread_cond_signal (&aq->queue_cond_in);
+
+ while (aq->drain_queue_stop != 2)
+ {
+ if (DEBUG_THREAD_SLEEP)
+ GCN_DEBUG ("Waiting for async thread %d:%d to finish, putting thread"
+ " to sleep\n", aq->agent->device_id, aq->id);
+ pthread_cond_wait (&aq->queue_cond_out, &aq->mutex);
+ if (DEBUG_THREAD_SLEEP)
+ GCN_DEBUG ("Waiting, woke up thread %d:%d. Rechecking\n",
+ aq->agent->device_id, aq->id);
+ }
+
+ GCN_DEBUG ("Done waiting for async thread %d:%d\n", aq->agent->device_id,
+ aq->id);
+ pthread_mutex_unlock (&aq->mutex);
+
+ int err = pthread_join (aq->thread_drain_queue, NULL);
+ if (err != 0)
+ GOMP_PLUGIN_fatal ("Join async thread %d:%d: failed: %s",
+ aq->agent->device_id, aq->id, strerror (err));
+ GCN_DEBUG ("Joined with async thread %d:%d\n", aq->agent->device_id, aq->id);
+}
+
+/* Set up an async queue for OpenMP. There will be only one. The
+ implementation simply uses an OpenACC async queue.
+ FIXME: is this thread-safe if two threads call this function? */
+
+static void
+maybe_init_omp_async (struct agent_info *agent)
+{
+ if (!agent->omp_async_queue)
+ agent->omp_async_queue
+ = GOMP_OFFLOAD_openacc_async_construct (agent->device_id);
+}
+
+/* A wrapper that works around an issue in the HSA runtime with host-to-device
+ copies from read-only pages. */
+
+static void
+hsa_memory_copy_wrapper (void *dst, const void *src, size_t len)
+{
+ hsa_status_t status = hsa_fns.hsa_memory_copy_fn (dst, src, len);
+
+ if (status == HSA_STATUS_SUCCESS)
+ return;
+
+ /* It appears that the copy fails if the source data is in a read-only page.
+ We can't detect that easily, so try copying the data to a temporary buffer
+ and doing the copy again if we got an error above. */
+
+ GCN_WARNING ("Read-only data transfer bug workaround triggered for "
+ "[%p:+%d]\n", (void *) src, (int) len);
+
+ void *src_copy = malloc (len);
+ memcpy (src_copy, src, len);
+ status = hsa_fns.hsa_memory_copy_fn (dst, (const void *) src_copy, len);
+ free (src_copy);
+ if (status != HSA_STATUS_SUCCESS)
+ GOMP_PLUGIN_error ("memory copy failed");
+}
+
+/* Copy data to or from a device. This is intended for use as an async
+ callback event. */
+
+static void
+copy_data (void *data_)
+{
+ struct copy_data *data = (struct copy_data *)data_;
+ GCN_DEBUG ("Async thread %d:%d: Copying %zu bytes from (%p) to (%p)\n",
+ data->aq->agent->device_id, data->aq->id, data->len, data->src,
+ data->dst);
+ hsa_memory_copy_wrapper (data->dst, data->src, data->len);
+ if (data->free_src)
+ free ((void *) data->src);
+ free (data);
+}
+
+/* Free device data. This is intended for use as an async callback event. */
+
+static void
+gomp_offload_free (void *ptr)
+{
+ GCN_DEBUG ("Async thread ?:?: Freeing %p\n", ptr);
+ GOMP_OFFLOAD_free (0, ptr);
+}
+
+/* Request an asynchronous data copy, to or from a device, on a given queue.
+ The event will be registered as a callback. If FREE_SRC is true
+ then the source data will be freed following the copy. */
+
+static void
+queue_push_copy (struct goacc_asyncqueue *aq, void *dst, const void *src,
+ size_t len, bool free_src)
+{
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("queue_push_copy %d:%d: %zu bytes from (%p) to (%p)\n",
+ aq->agent->device_id, aq->id, len, src, dst);
+ struct copy_data *data
+ = (struct copy_data *)GOMP_PLUGIN_malloc (sizeof (struct copy_data));
+ data->dst = dst;
+ data->src = src;
+ data->len = len;
+ data->free_src = free_src;
+ data->aq = aq;
+ queue_push_callback (aq, copy_data, data);
+}
+
+/* Return true if the given queue is currently empty. */
+
+static int
+queue_empty (struct goacc_asyncqueue *aq)
+{
+ pthread_mutex_lock (&aq->mutex);
+ int res = aq->queue_n == 0 ? 1 : 0;
+ pthread_mutex_unlock (&aq->mutex);
+
+ return res;
+}
+
+/* Wait for a given queue to become empty. This implements an OpenACC wait
+ directive. */
+
+static void
+wait_queue (struct goacc_asyncqueue *aq)
+{
+ if (DRAIN_QUEUE_SYNCHRONOUS_P)
+ {
+ drain_queue_synchronous (aq);
+ return;
+ }
+
+ pthread_mutex_lock (&aq->mutex);
+
+ while (aq->queue_n > 0)
+ {
+ if (DEBUG_THREAD_SLEEP)
+ GCN_DEBUG ("waiting for thread %d:%d, putting thread to sleep\n",
+ aq->agent->device_id, aq->id);
+ pthread_cond_wait (&aq->queue_cond_out, &aq->mutex);
+ if (DEBUG_THREAD_SLEEP)
+ GCN_DEBUG ("thread %d:%d woke up. Rechecking\n", aq->agent->device_id,
+ aq->id);
+ }
+
+ pthread_mutex_unlock (&aq->mutex);
+ GCN_DEBUG ("waiting for thread %d:%d, done\n", aq->agent->device_id, aq->id);
+}
+
+/* }}} */
+/* {{{ OpenACC support */
+
+/* Execute an OpenACC kernel, synchronously or asynchronously. */
+
+static void
+gcn_exec (struct kernel_info *kernel, size_t mapnum, void **hostaddrs,
+ void **devaddrs, unsigned *dims, void *targ_mem_desc, bool async,
+ struct goacc_asyncqueue *aq)
+{
+ if (!GOMP_OFFLOAD_can_run (kernel))
+ GOMP_PLUGIN_fatal ("OpenACC host fallback unimplemented.");
+
+ /* If we get here then this must be an OpenACC kernel. */
+ kernel->kind = KIND_OPENACC;
+
+ /* devaddrs must be double-indirect on the target. */
+ void **ind_da = alloc_by_agent (kernel->agent, sizeof (void*) * mapnum);
+ for (size_t i = 0; i < mapnum; i++)
+ hsa_fns.hsa_memory_copy_fn (&ind_da[i],
+ devaddrs[i] ? &devaddrs[i] : &hostaddrs[i],
+ sizeof (void *));
+
+ struct hsa_kernel_description *hsa_kernel_desc = NULL;
+ for (unsigned i = 0; i < kernel->module->image_desc->kernel_count; i++)
+ {
+ struct hsa_kernel_description *d
+ = &kernel->module->image_desc->kernel_infos[i];
+ if (d->name == kernel->name)
+ {
+ hsa_kernel_desc = d;
+ break;
+ }
+ }
+
+ /* We may have statically-determined dimensions in
+ hsa_kernel_desc->oacc_dims[] or dimensions passed to this offload kernel
+ invocation at runtime in dims[]. We allow static dimensions to take
+ priority over dynamic dimensions when present (non-zero). */
+ if (hsa_kernel_desc->oacc_dims[0] > 0)
+ dims[0] = hsa_kernel_desc->oacc_dims[0];
+ if (hsa_kernel_desc->oacc_dims[1] > 0)
+ dims[1] = hsa_kernel_desc->oacc_dims[1];
+ if (hsa_kernel_desc->oacc_dims[2] > 0)
+ dims[2] = hsa_kernel_desc->oacc_dims[2];
+
+ /* If any of the OpenACC dimensions remain 0 then we get to pick a number.
+ There isn't really a correct answer for this without a clue about the
+ problem size, so let's do a reasonable number of single-worker gangs.
+ 64 gangs matches a typical Fiji device. */
+
+ /* NOTE: Until support for middle-end worker partitioning is merged, use 1
+ for the default number of workers. */
+ if (dims[0] == 0) dims[0] = get_cu_count (kernel->agent); /* Gangs. */
+ if (dims[1] == 0) dims[1] = 1; /* Workers. */
+
+ /* The incoming dimensions are expressed in terms of gangs, workers, and
+ vectors. The HSA dimensions are expressed in terms of "work-items",
+ which means multiples of vector lanes.
+
+ The "grid size" specifies the size of the problem space, and the
+ "work-group size" specifies how much of that we want a single compute
+ unit to chew on at once.
+
+ The three dimensions do not really correspond to hardware, but the
+ important thing is that the HSA runtime will launch as many
+ work-groups as it takes to process the entire grid, and each
+ work-group will contain as many wave-fronts as it takes to process
+ the work-items in that group.
+
+ Essentially, as long as we set the Y dimension to 64 (the number of
+ vector lanes in hardware), and the Z group size to the maximum (16),
+ then we will get the gangs (X) and workers (Z) launched as we expect.
+
+ The reason for the apparent reversal of vector and worker dimension
+ order is to do with the way the run-time distributes work-items across
+ v1 and v2. */
+ struct GOMP_kernel_launch_attributes kla =
+ {3,
+ /* Grid size. */
+ {dims[0], 64, dims[1]},
+ /* Work-group size. */
+ {1, 64, 16}
+ };
+
+ struct goacc_thread *thr = GOMP_PLUGIN_goacc_thread ();
+ acc_prof_info *prof_info = thr->prof_info;
+ acc_event_info enqueue_launch_event_info;
+ acc_api_info *api_info = thr->api_info;
+ bool profiling_dispatch_p = __builtin_expect (prof_info != NULL, false);
+ if (profiling_dispatch_p)
+ {
+ prof_info->event_type = acc_ev_enqueue_launch_start;
+
+ enqueue_launch_event_info.launch_event.event_type
+ = prof_info->event_type;
+ enqueue_launch_event_info.launch_event.valid_bytes
+ = _ACC_LAUNCH_EVENT_INFO_VALID_BYTES;
+ enqueue_launch_event_info.launch_event.parent_construct
+ = acc_construct_parallel;
+ enqueue_launch_event_info.launch_event.implicit = 1;
+ enqueue_launch_event_info.launch_event.tool_info = NULL;
+ enqueue_launch_event_info.launch_event.kernel_name
+ = (char *) kernel->name;
+ enqueue_launch_event_info.launch_event.num_gangs = kla.gdims[0];
+ enqueue_launch_event_info.launch_event.num_workers = kla.gdims[2];
+ enqueue_launch_event_info.launch_event.vector_length = kla.gdims[1];
+
+ api_info->device_api = acc_device_api_other;
+
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info,
+ &enqueue_launch_event_info, api_info);
+ }
+
+ if (!async)
+ {
+ run_kernel (kernel, ind_da, &kla, NULL, false);
+ gomp_offload_free (ind_da);
+ }
+ else
+ {
+ queue_push_launch (aq, kernel, ind_da, &kla);
+ if (DEBUG_QUEUES)
+ GCN_DEBUG ("queue_push_callback %d:%d gomp_offload_free, %p\n",
+ aq->agent->device_id, aq->id, ind_da);
+ queue_push_callback (aq, gomp_offload_free, ind_da);
+ }
+
+ if (profiling_dispatch_p)
+ {
+ prof_info->event_type = acc_ev_enqueue_launch_end;
+ enqueue_launch_event_info.launch_event.event_type = prof_info->event_type;
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info,
+ &enqueue_launch_event_info,
+ api_info);
+ }
+}
+
+/* }}} */
+/* {{{ Generic Plugin API */
+
+/* Return the name of the accelerator, which is "gcn". */
+
+const char *
+GOMP_OFFLOAD_get_name (void)
+{
+ return "gcn";
+}
+
+/* Return the specific capabilities the HSA accelerator have. */
+
+unsigned int
+GOMP_OFFLOAD_get_caps (void)
+{
+ /* FIXME: Enable shared memory for APU, but not discrete GPU. */
+ return /*GOMP_OFFLOAD_CAP_SHARED_MEM |*/ GOMP_OFFLOAD_CAP_OPENMP_400
+ | GOMP_OFFLOAD_CAP_OPENACC_200;
+}
+
+/* Identify as GCN accelerator. */
+
+int
+GOMP_OFFLOAD_get_type (void)
+{
+ return OFFLOAD_TARGET_TYPE_GCN;
+}
+
+/* Return the libgomp version number we're compatible with. There is
+ no requirement for cross-version compatibility. */
+
+unsigned
+GOMP_OFFLOAD_version (void)
+{
+ return GOMP_VERSION;
+}
+
+/* Return the number of GCN devices on the system. */
+
+int
+GOMP_OFFLOAD_get_num_devices (void)
+{
+ if (!init_hsa_context ())
+ return 0;
+ return hsa_context.agent_count;
+}
+
+/* Initialize device (agent) number N so that it can be used for computation.
+ Return TRUE on success. */
+
+bool
+GOMP_OFFLOAD_init_device (int n)
+{
+ if (!init_hsa_context ())
+ return false;
+ if (n >= hsa_context.agent_count)
+ {
+ GOMP_PLUGIN_error ("Request to initialize non-existent GCN device %i", n);
+ return false;
+ }
+ struct agent_info *agent = &hsa_context.agents[n];
+
+ if (agent->initialized)
+ return true;
+
+ agent->device_id = n;
+
+ if (pthread_rwlock_init (&agent->module_rwlock, NULL))
+ {
+ GOMP_PLUGIN_error ("Failed to initialize a GCN agent rwlock");
+ return false;
+ }
+ if (pthread_mutex_init (&agent->prog_mutex, NULL))
+ {
+ GOMP_PLUGIN_error ("Failed to initialize a GCN agent program mutex");
+ return false;
+ }
+ if (pthread_mutex_init (&agent->async_queues_mutex, NULL))
+ {
+ GOMP_PLUGIN_error ("Failed to initialize a GCN agent queue mutex");
+ return false;
+ }
+ if (pthread_mutex_init (&agent->team_arena_write_lock, NULL))
+ {
+ GOMP_PLUGIN_error ("Failed to initialize a GCN team arena write mutex");
+ return false;
+ }
+ agent->async_queues = NULL;
+ agent->omp_async_queue = NULL;
+ agent->team_arena_list = NULL;
+
+ uint32_t queue_size;
+ hsa_status_t status;
+ status = hsa_fns.hsa_agent_get_info_fn (agent->id,
+ HSA_AGENT_INFO_QUEUE_MAX_SIZE,
+ &queue_size);
+ if (status != HSA_STATUS_SUCCESS)
+ return hsa_error ("Error requesting maximum queue size of the GCN agent",
+ status);
+
+ char buf[64];
+ status = hsa_fns.hsa_agent_get_info_fn (agent->id, HSA_AGENT_INFO_NAME,
+ &buf);
+ if (status != HSA_STATUS_SUCCESS)
+ return hsa_error ("Error querying the name of the agent", status);
+ agent->gfx900_p = (strncmp (buf, "gfx900", 6) == 0);
+
+ status = hsa_fns.hsa_queue_create_fn (agent->id, queue_size,
+ HSA_QUEUE_TYPE_MULTI,
+ hsa_queue_callback, NULL, UINT32_MAX,
+ UINT32_MAX, &agent->sync_queue);
+ if (status != HSA_STATUS_SUCCESS)
+ return hsa_error ("Error creating command queue", status);
+
+ agent->kernarg_region.handle = (uint64_t) -1;
+ status = hsa_fns.hsa_agent_iterate_regions_fn (agent->id,
+ get_kernarg_memory_region,
+ &agent->kernarg_region);
+ if (agent->kernarg_region.handle == (uint64_t) -1)
+ {
+ GOMP_PLUGIN_error ("Could not find suitable memory region for kernel "
+ "arguments");
+ return false;
+ }
+ GCN_DEBUG ("Selected kernel arguments memory region:\n");
+ dump_hsa_region (agent->kernarg_region, NULL);
+
+ agent->data_region.handle = (uint64_t) -1;
+ status = hsa_fns.hsa_agent_iterate_regions_fn (agent->id,
+ get_data_memory_region,
+ &agent->data_region);
+ if (agent->data_region.handle == (uint64_t) -1)
+ {
+ GOMP_PLUGIN_error ("Could not find suitable memory region for device "
+ "data");
+ return false;
+ }
+ GCN_DEBUG ("Selected device data memory region:\n");
+ dump_hsa_region (agent->data_region, NULL);
+
+ GCN_DEBUG ("GCN agent %d initialized\n", n);
+
+ agent->initialized = true;
+ return true;
+}
+
+/* Load GCN object-code module described by struct gcn_image_desc in
+ TARGET_DATA and return references to kernel descriptors in TARGET_TABLE.
+ If there are any constructors then run them. */
+
+int
+GOMP_OFFLOAD_load_image (int ord, unsigned version, const void *target_data,
+ struct addr_pair **target_table)
+{
+ if (GOMP_VERSION_DEV (version) != GOMP_VERSION_GCN)
+ {
+ GOMP_PLUGIN_error ("Offload data incompatible with GCN plugin"
+ " (expected %u, received %u)",
+ GOMP_VERSION_GCN, GOMP_VERSION_DEV (version));
+ return -1;
+ }
+
+ struct gcn_image_desc *image_desc = (struct gcn_image_desc *) target_data;
+ struct agent_info *agent;
+ struct addr_pair *pair;
+ struct module_info *module;
+ struct kernel_info *kernel;
+ int kernel_count = image_desc->kernel_count;
+ unsigned var_count = image_desc->global_variable_count;
+
+ agent = get_agent_info (ord);
+ if (!agent)
+ return -1;
+
+ if (pthread_rwlock_wrlock (&agent->module_rwlock))
+ {
+ GOMP_PLUGIN_error ("Unable to write-lock a GCN agent rwlock");
+ return -1;
+ }
+ if (agent->prog_finalized
+ && !destroy_hsa_program (agent))
+ return -1;
+
+ GCN_DEBUG ("Encountered %d kernels in an image\n", kernel_count);
+ GCN_DEBUG ("Encountered %u global variables in an image\n", var_count);
+ pair = GOMP_PLUGIN_malloc ((kernel_count + var_count - 2)
+ * sizeof (struct addr_pair));
+ *target_table = pair;
+ module = (struct module_info *)
+ GOMP_PLUGIN_malloc_cleared (sizeof (struct module_info)
+ + kernel_count * sizeof (struct kernel_info));
+ module->image_desc = image_desc;
+ module->kernel_count = kernel_count;
+ module->heap = NULL;
+ module->constructors_run_p = false;
+
+ kernel = &module->kernels[0];
+
+ /* Allocate memory for kernel dependencies. */
+ for (unsigned i = 0; i < kernel_count; i++)
+ {
+ struct hsa_kernel_description *d = &image_desc->kernel_infos[i];
+ if (!init_basic_kernel_info (kernel, d, agent, module))
+ return -1;
+ if (strcmp (d->name, "_init_array") == 0)
+ module->init_array_func = kernel;
+ else if (strcmp (d->name, "_fini_array") == 0)
+ module->fini_array_func = kernel;
+ else
+ {
+ pair->start = (uintptr_t) kernel;
+ pair->end = (uintptr_t) (kernel + 1);
+ pair++;
+ }
+ kernel++;
+ }
+
+ agent->module = module;
+ if (pthread_rwlock_unlock (&agent->module_rwlock))
+ {
+ GOMP_PLUGIN_error ("Unable to unlock a GCN agent rwlock");
+ return -1;
+ }
+
+ if (!create_and_finalize_hsa_program (agent))
+ return -1;
+
+ for (unsigned i = 0; i < var_count; i++)
+ {
+ struct global_var_info *v = &image_desc->global_variables[i];
+ GCN_DEBUG ("Looking for variable %s\n", v->name);
+
+ hsa_status_t status;
+ hsa_executable_symbol_t var_symbol;
+ status = hsa_fns.hsa_executable_get_symbol_fn (agent->executable, NULL,
+ v->name, agent->id,
+ 0, &var_symbol);
+
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not find symbol for variable in the code object",
+ status);
+
+ uint64_t var_addr;
+ uint32_t var_size;
+ status = hsa_fns.hsa_executable_symbol_get_info_fn
+ (var_symbol, HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_ADDRESS, &var_addr);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not extract a variable from its symbol", status);
+ status = hsa_fns.hsa_executable_symbol_get_info_fn
+ (var_symbol, HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_SIZE, &var_size);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Could not extract a variable size from its symbol", status);
+
+ pair->start = var_addr;
+ pair->end = var_addr + var_size;
+ GCN_DEBUG ("Found variable %s at %p with size %u\n", v->name,
+ (void *)var_addr, var_size);
+ pair++;
+ }
+
+ /* Ensure that constructors are run first. */
+ struct GOMP_kernel_launch_attributes kla =
+ { 3,
+ /* Grid size. */
+ { 1, 64, 1 },
+ /* Work-group size. */
+ { 1, 64, 1 }
+ };
+
+ if (module->init_array_func)
+ {
+ init_kernel (module->init_array_func);
+ run_kernel (module->init_array_func, NULL, &kla, NULL, false);
+ }
+ module->constructors_run_p = true;
+
+ /* Don't report kernels that libgomp need not know about. */
+ if (module->init_array_func)
+ kernel_count--;
+ if (module->fini_array_func)
+ kernel_count--;
+
+ return kernel_count + var_count;
+}
+
+/* Unload GCN object-code module described by struct gcn_image_desc in
+ TARGET_DATA from agent number N. Return TRUE on success. */
+
+bool
+GOMP_OFFLOAD_unload_image (int n, unsigned version, const void *target_data)
+{
+ if (GOMP_VERSION_DEV (version) != GOMP_VERSION_GCN)
+ {
+ GOMP_PLUGIN_error ("Offload data incompatible with GCN plugin"
+ " (expected %u, received %u)",
+ GOMP_VERSION_GCN, GOMP_VERSION_DEV (version));
+ return false;
+ }
+
+ struct agent_info *agent;
+ agent = get_agent_info (n);
+ if (!agent)
+ return false;
+
+ if (pthread_rwlock_wrlock (&agent->module_rwlock))
+ {
+ GOMP_PLUGIN_error ("Unable to write-lock a GCN agent rwlock");
+ return false;
+ }
+
+ if (!agent->module || agent->module->image_desc != target_data)
+ {
+ GOMP_PLUGIN_error ("Attempt to unload an image that has never been "
+ "loaded before");
+ return false;
+ }
+
+ if (!destroy_module (agent->module, true))
+ return false;
+ free (agent->module);
+ agent->module = NULL;
+ if (!destroy_hsa_program (agent))
+ return false;
+ if (pthread_rwlock_unlock (&agent->module_rwlock))
+ {
+ GOMP_PLUGIN_error ("Unable to unlock a GCN agent rwlock");
+ return false;
+ }
+ return true;
+}
+
+/* Deinitialize all information and status associated with agent number N. We
+ do not attempt any synchronization, assuming the user and libgomp will not
+ attempt deinitialization of a device that is in any way being used at the
+ same time. Return TRUE on success. */
+
+bool
+GOMP_OFFLOAD_fini_device (int n)
+{
+ struct agent_info *agent = get_agent_info (n);
+ if (!agent)
+ return false;
+
+ if (!agent->initialized)
+ return true;
+
+ if (agent->omp_async_queue)
+ {
+ GOMP_OFFLOAD_openacc_async_destruct (agent->omp_async_queue);
+ agent->omp_async_queue = NULL;
+ }
+
+ if (agent->module)
+ {
+ if (!destroy_module (agent->module, false))
+ return false;
+ free (agent->module);
+ agent->module = NULL;
+ }
+
+ if (!destroy_team_arenas (agent))
+ return false;
+
+ if (!destroy_hsa_program (agent))
+ return false;
+
+ hsa_status_t status = hsa_fns.hsa_queue_destroy_fn (agent->sync_queue);
+ if (status != HSA_STATUS_SUCCESS)
+ return hsa_error ("Error destroying command queue", status);
+
+ if (pthread_mutex_destroy (&agent->prog_mutex))
+ {
+ GOMP_PLUGIN_error ("Failed to destroy a GCN agent program mutex");
+ return false;
+ }
+ if (pthread_rwlock_destroy (&agent->module_rwlock))
+ {
+ GOMP_PLUGIN_error ("Failed to destroy a GCN agent rwlock");
+ return false;
+ }
+
+ if (pthread_mutex_destroy (&agent->async_queues_mutex))
+ {
+ GOMP_PLUGIN_error ("Failed to destroy a GCN agent queue mutex");
+ return false;
+ }
+ if (pthread_mutex_destroy (&agent->team_arena_write_lock))
+ {
+ GOMP_PLUGIN_error ("Failed to destroy a GCN team arena mutex");
+ return false;
+ }
+ agent->initialized = false;
+ return true;
+}
+
+/* Return true if the HSA runtime can run function FN_PTR. */
+
+bool
+GOMP_OFFLOAD_can_run (void *fn_ptr)
+{
+ struct kernel_info *kernel = (struct kernel_info *) fn_ptr;
+
+ init_kernel (kernel);
+ if (kernel->initialization_failed)
+ goto failure;
+
+ return true;
+
+failure:
+ if (suppress_host_fallback)
+ GOMP_PLUGIN_fatal ("GCN host fallback has been suppressed");
+ GCN_WARNING ("GCN target cannot be launched, doing a host fallback\n");
+ return false;
+}
+
+/* Allocate memory on device N. */
+
+void *
+GOMP_OFFLOAD_alloc (int n, size_t size)
+{
+ struct agent_info *agent = get_agent_info (n);
+ return alloc_by_agent (agent, size);
+}
+
+/* Free memory from device N. */
+
+bool
+GOMP_OFFLOAD_free (int device, void *ptr)
+{
+ GCN_DEBUG ("Freeing memory on device %d\n", device);
+
+ hsa_status_t status = hsa_fns.hsa_memory_free_fn (ptr);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Could not free device memory", status);
+ return false;
+ }
+
+ struct goacc_thread *thr = GOMP_PLUGIN_goacc_thread ();
+ bool profiling_dispatch_p
+ = __builtin_expect (thr != NULL && thr->prof_info != NULL, false);
+ if (profiling_dispatch_p)
+ {
+ acc_prof_info *prof_info = thr->prof_info;
+ acc_event_info data_event_info;
+ acc_api_info *api_info = thr->api_info;
+
+ prof_info->event_type = acc_ev_free;
+
+ data_event_info.data_event.event_type = prof_info->event_type;
+ data_event_info.data_event.valid_bytes
+ = _ACC_DATA_EVENT_INFO_VALID_BYTES;
+ data_event_info.data_event.parent_construct
+ = acc_construct_parallel;
+ data_event_info.data_event.implicit = 1;
+ data_event_info.data_event.tool_info = NULL;
+ data_event_info.data_event.var_name = NULL;
+ data_event_info.data_event.bytes = 0;
+ data_event_info.data_event.host_ptr = NULL;
+ data_event_info.data_event.device_ptr = (void *) ptr;
+
+ api_info->device_api = acc_device_api_other;
+
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info, &data_event_info,
+ api_info);
+ }
+
+ return true;
+}
+
+/* Copy data from DEVICE to host. */
+
+bool
+GOMP_OFFLOAD_dev2host (int device, void *dst, const void *src, size_t n)
+{
+ GCN_DEBUG ("Copying %zu bytes from device %d (%p) to host (%p)\n", n, device,
+ src, dst);
+ hsa_status_t status = hsa_fns.hsa_memory_copy_fn (dst, src, n);
+ if (status != HSA_STATUS_SUCCESS)
+ GOMP_PLUGIN_error ("memory copy failed");
+ return true;
+}
+
+/* Copy data from host to DEVICE. */
+
+bool
+GOMP_OFFLOAD_host2dev (int device, void *dst, const void *src, size_t n)
+{
+ GCN_DEBUG ("Copying %zu bytes from host (%p) to device %d (%p)\n", n, src,
+ device, dst);
+ hsa_memory_copy_wrapper (dst, src, n);
+ return true;
+}
+
+/* Copy data within DEVICE. Do the copy asynchronously, if appropriate. */
+
+bool
+GOMP_OFFLOAD_dev2dev (int device, void *dst, const void *src, size_t n)
+{
+ struct gcn_thread *thread_data = gcn_thread ();
+
+ if (thread_data && !async_synchronous_p (thread_data->async))
+ {
+ struct agent_info *agent = get_agent_info (device);
+ maybe_init_omp_async (agent);
+ queue_push_copy (agent->omp_async_queue, dst, src, n, false);
+ return true;
+ }
+
+ GCN_DEBUG ("Copying %zu bytes from device %d (%p) to device %d (%p)\n", n,
+ device, src, device, dst);
+ hsa_status_t status = hsa_fns.hsa_memory_copy_fn (dst, src, n);
+ if (status != HSA_STATUS_SUCCESS)
+ GOMP_PLUGIN_error ("memory copy failed");
+ return true;
+}
+
+/* }}} */
+/* {{{ OpenMP Plugin API */
+
+/* Run a synchronous OpenMP kernel on DEVICE and pass it an array of pointers
+ in VARS as a parameter. The kernel is identified by FN_PTR which must point
+ to a kernel_info structure, and must have previously been loaded to the
+ specified device. */
+
+void
+GOMP_OFFLOAD_run (int device, void *fn_ptr, void *vars, void **args)
+{
+ struct agent_info *agent = get_agent_info (device);
+ struct kernel_info *kernel = (struct kernel_info *) fn_ptr;
+ struct GOMP_kernel_launch_attributes def;
+ struct GOMP_kernel_launch_attributes *kla;
+ assert (agent == kernel->agent);
+
+ /* If we get here then the kernel must be OpenMP. */
+ kernel->kind = KIND_OPENMP;
+
+ if (!parse_target_attributes (args, &def, &kla, agent))
+ {
+ GCN_WARNING ("Will not run GCN kernel because the grid size is zero\n");
+ return;
+ }
+ run_kernel (kernel, vars, kla, NULL, false);
+}
+
+/* Run an asynchronous OpenMP kernel on DEVICE. This is similar to
+ GOMP_OFFLOAD_run except that the launch is queued and there is a call to
+ GOMP_PLUGIN_target_task_completion when it has finished. */
+
+void
+GOMP_OFFLOAD_async_run (int device, void *tgt_fn, void *tgt_vars,
+ void **args, void *async_data)
+{
+ GCN_DEBUG ("GOMP_OFFLOAD_async_run invoked\n");
+ struct agent_info *agent = get_agent_info (device);
+ struct kernel_info *kernel = (struct kernel_info *) tgt_fn;
+ struct GOMP_kernel_launch_attributes def;
+ struct GOMP_kernel_launch_attributes *kla;
+ assert (agent == kernel->agent);
+
+ /* If we get here then the kernel must be OpenMP. */
+ kernel->kind = KIND_OPENMP;
+
+ if (!parse_target_attributes (args, &def, &kla, agent))
+ {
+ GCN_WARNING ("Will not run GCN kernel because the grid size is zero\n");
+ return;
+ }
+
+ maybe_init_omp_async (agent);
+ queue_push_launch (agent->omp_async_queue, kernel, tgt_vars, kla);
+ queue_push_callback (agent->omp_async_queue,
+ GOMP_PLUGIN_target_task_completion, async_data);
+}
+
+/* }}} */
+/* {{{ OpenACC Plugin API */
+
+/* Run a synchronous OpenACC kernel. The device number is inferred from the
+ already-loaded KERNEL. */
+
+void
+GOMP_OFFLOAD_openacc_exec (void (*fn_ptr) (void *), size_t mapnum,
+ void **hostaddrs, void **devaddrs, unsigned *dims,
+ void *targ_mem_desc)
+{
+ struct kernel_info *kernel = (struct kernel_info *) fn_ptr;
+
+ gcn_exec (kernel, mapnum, hostaddrs, devaddrs, dims, targ_mem_desc, false,
+ NULL);
+}
+
+/* Run an asynchronous OpenACC kernel on the specified queue. */
+
+void
+GOMP_OFFLOAD_openacc_async_exec (void (*fn_ptr) (void *), size_t mapnum,
+ void **hostaddrs, void **devaddrs,
+ unsigned *dims, void *targ_mem_desc,
+ struct goacc_asyncqueue *aq)
+{
+ struct kernel_info *kernel = (struct kernel_info *) fn_ptr;
+
+ gcn_exec (kernel, mapnum, hostaddrs, devaddrs, dims, targ_mem_desc, true,
+ aq);
+}
+
+/* Create a new asynchronous thread and queue for running future kernels. */
+
+struct goacc_asyncqueue *
+GOMP_OFFLOAD_openacc_async_construct (int device)
+{
+ struct agent_info *agent = get_agent_info (device);
+
+ pthread_mutex_lock (&agent->async_queues_mutex);
+
+ struct goacc_asyncqueue *aq = GOMP_PLUGIN_malloc (sizeof (*aq));
+ aq->agent = get_agent_info (device);
+ aq->prev = NULL;
+ aq->next = agent->async_queues;
+ if (aq->next)
+ {
+ aq->next->prev = aq;
+ aq->id = aq->next->id + 1;
+ }
+ else
+ aq->id = 1;
+ agent->async_queues = aq;
+
+ aq->queue_first = 0;
+ aq->queue_n = 0;
+ aq->drain_queue_stop = 0;
+
+ if (pthread_mutex_init (&aq->mutex, NULL))
+ {
+ GOMP_PLUGIN_error ("Failed to initialize a GCN agent queue mutex");
+ return false;
+ }
+ if (pthread_cond_init (&aq->queue_cond_in, NULL))
+ {
+ GOMP_PLUGIN_error ("Failed to initialize a GCN agent queue cond");
+ return false;
+ }
+ if (pthread_cond_init (&aq->queue_cond_out, NULL))
+ {
+ GOMP_PLUGIN_error ("Failed to initialize a GCN agent queue cond");
+ return false;
+ }
+
+ hsa_status_t status = hsa_fns.hsa_queue_create_fn (agent->id,
+ ASYNC_QUEUE_SIZE,
+ HSA_QUEUE_TYPE_MULTI,
+ hsa_queue_callback, NULL,
+ UINT32_MAX, UINT32_MAX,
+ &aq->hsa_queue);
+ if (status != HSA_STATUS_SUCCESS)
+ hsa_fatal ("Error creating command queue", status);
+
+ int err = pthread_create (&aq->thread_drain_queue, NULL, &drain_queue, aq);
+ if (err != 0)
+ GOMP_PLUGIN_fatal ("GCN asynchronous thread creation failed: %s",
+ strerror (err));
+ GCN_DEBUG ("Async thread %d:%d: created\n", aq->agent->device_id,
+ aq->id);
+
+ pthread_mutex_unlock (&agent->async_queues_mutex);
+
+ return aq;
+}
+
+/* Destroy an exisiting asynchronous thread and queue. Waits for any
+ currently-running task to complete, but cancels any queued tasks. */
+
+bool
+GOMP_OFFLOAD_openacc_async_destruct (struct goacc_asyncqueue *aq)
+{
+ struct agent_info *agent = aq->agent;
+
+ finalize_async_thread (aq);
+
+ pthread_mutex_lock (&agent->async_queues_mutex);
+
+ int err;
+ if ((err = pthread_mutex_destroy (&aq->mutex)))
+ {
+ GOMP_PLUGIN_error ("Failed to destroy a GCN async queue mutex: %d", err);
+ goto fail;
+ }
+ if (pthread_cond_destroy (&aq->queue_cond_in))
+ {
+ GOMP_PLUGIN_error ("Failed to destroy a GCN async queue cond");
+ goto fail;
+ }
+ if (pthread_cond_destroy (&aq->queue_cond_out))
+ {
+ GOMP_PLUGIN_error ("Failed to destroy a GCN async queue cond");
+ goto fail;
+ }
+ hsa_status_t status = hsa_fns.hsa_queue_destroy_fn (aq->hsa_queue);
+ if (status != HSA_STATUS_SUCCESS)
+ {
+ hsa_error ("Error destroying command queue", status);
+ goto fail;
+ }
+
+ if (aq->prev)
+ aq->prev->next = aq->next;
+ if (aq->next)
+ aq->next->prev = aq->prev;
+ if (agent->async_queues == aq)
+ agent->async_queues = aq->next;
+
+ GCN_DEBUG ("Async thread %d:%d: destroyed\n", agent->device_id, aq->id);
+
+ free (aq);
+ pthread_mutex_unlock (&agent->async_queues_mutex);
+ return true;
+
+fail:
+ pthread_mutex_unlock (&agent->async_queues_mutex);
+ return false;
+}
+
+/* Return true if the specified async queue is currently empty. */
+
+int
+GOMP_OFFLOAD_openacc_async_test (struct goacc_asyncqueue *aq)
+{
+ return queue_empty (aq);
+}
+
+/* Block until the specified queue has executed all its tasks and the
+ queue is empty. */
+
+bool
+GOMP_OFFLOAD_openacc_async_synchronize (struct goacc_asyncqueue *aq)
+{
+ wait_queue (aq);
+ return true;
+}
+
+/* Add a serialization point across two async queues. Any new tasks added to
+ AQ2, after this call, will not run until all tasks on AQ1, at the time
+ of this call, have completed. */
+
+bool
+GOMP_OFFLOAD_openacc_async_serialize (struct goacc_asyncqueue *aq1,
+ struct goacc_asyncqueue *aq2)
+{
+ /* For serialize, stream aq2 waits for aq1 to complete work that has been
+ scheduled to run on it up to this point. */
+ if (aq1 != aq2)
+ {
+ struct placeholder *placeholderp = queue_push_placeholder (aq1);
+ queue_push_asyncwait (aq2, placeholderp);
+ }
+ return true;
+}
+
+/* Add an opaque callback to the given async queue. */
+
+void
+GOMP_OFFLOAD_openacc_async_queue_callback (struct goacc_asyncqueue *aq,
+ void (*fn) (void *), void *data)
+{
+ queue_push_callback (aq, fn, data);
+}
+
+/* Queue up an asynchronous data copy from host to DEVICE. */
+
+bool
+GOMP_OFFLOAD_openacc_async_host2dev (int device, void *dst, const void *src,
+ size_t n, struct goacc_asyncqueue *aq)
+{
+ struct agent_info *agent = get_agent_info (device);
+ assert (agent == aq->agent);
+ /* The source data does not necessarily remain live until the deferred
+ copy happens. Taking a snapshot of the data here avoids reading
+ uninitialised data later, but means that (a) data is copied twice and
+ (b) modifications to the copied data between the "spawning" point of
+ the asynchronous kernel and when it is executed will not be seen.
+ But, that is probably correct. */
+ void *src_copy = GOMP_PLUGIN_malloc (n);
+ memcpy (src_copy, src, n);
+ queue_push_copy (aq, dst, src_copy, n, true);
+ return true;
+}
+
+/* Queue up an asynchronous data copy from DEVICE to host. */
+
+bool
+GOMP_OFFLOAD_openacc_async_dev2host (int device, void *dst, const void *src,
+ size_t n, struct goacc_asyncqueue *aq)
+{
+ struct agent_info *agent = get_agent_info (device);
+ assert (agent == aq->agent);
+ queue_push_copy (aq, dst, src, n, false);
+ return true;
+}
+
+/* Set up plugin-specific thread-local-data (host-side). */
+
+void *
+GOMP_OFFLOAD_openacc_create_thread_data (int ord __attribute__((unused)))
+{
+ struct gcn_thread *thread_data
+ = GOMP_PLUGIN_malloc (sizeof (struct gcn_thread));
+
+ thread_data->async = GOMP_ASYNC_SYNC;
+
+ return (void *) thread_data;
+}
+
+/* Clean up plugin-specific thread-local-data. */
+
+void
+GOMP_OFFLOAD_openacc_destroy_thread_data (void *data)
+{
+ free (data);
+}
+
+/* }}} */
diff --git a/libgomp/plugin/plugin-hsa.c b/libgomp/plugin/plugin-hsa.c
index 1fd47694846..409e138aaca 100644
--- a/libgomp/plugin/plugin-hsa.c
+++ b/libgomp/plugin/plugin-hsa.c
@@ -1,6 +1,6 @@
/* Plugin for HSAIL execution.
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Martin Jambor <mjambor@suse.cz> and
Martin Liska <mliska@suse.cz>.
@@ -28,11 +28,14 @@
<http://www.gnu.org/licenses/>. */
#include "config.h"
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
+#endif
#include <stdbool.h>
#include <hsa.h>
#include <plugin/hsa_ext_finalize.h>
@@ -41,6 +44,13 @@
#include "gomp-constants.h"
#include "secure_getenv.h"
+#ifdef HAVE_INTTYPES_H
+typedef uint64_t print_uint64_t;
+#else
+#define PRIu64 "lu"
+typedef unsigned long print_uint64_t;
+#endif
+
/* As an HSA runtime is dlopened, following structure defines function
pointers utilized by the HSA plug-in. */
@@ -279,7 +289,7 @@ hsa_warn (const char *str, hsa_status_t status)
if (!debug)
return;
- const char *hsa_error_msg;
+ const char *hsa_error_msg = "[unknown]";
hsa_fns.hsa_status_string_fn (status, &hsa_error_msg);
fprintf (stderr, "HSA warning: %s\nRuntime message: %s", str, hsa_error_msg);
@@ -291,7 +301,7 @@ hsa_warn (const char *str, hsa_status_t status)
static void
hsa_fatal (const char *str, hsa_status_t status)
{
- const char *hsa_error_msg;
+ const char *hsa_error_msg = "[unknown]";
hsa_fns.hsa_status_string_fn (status, &hsa_error_msg);
GOMP_PLUGIN_fatal ("HSA fatal error: %s\nRuntime message: %s", str,
hsa_error_msg);
@@ -303,7 +313,7 @@ hsa_fatal (const char *str, hsa_status_t status)
static bool
hsa_error (const char *str, hsa_status_t status)
{
- const char *hsa_error_msg;
+ const char *hsa_error_msg = "[unknown]";
hsa_fns.hsa_status_string_fn (status, &hsa_error_msg);
GOMP_PLUGIN_error ("HSA fatal error: %s\nRuntime message: %s", str,
hsa_error_msg);
@@ -1154,8 +1164,9 @@ create_single_kernel_dispatch (struct kernel_info *kernel,
static void
release_kernel_dispatch (struct GOMP_hsa_kernel_dispatch *shadow)
{
- HSA_DEBUG ("Released kernel dispatch: %p has value: %lu (%p)\n", shadow,
- shadow->debug, (void *) shadow->debug);
+ HSA_DEBUG ("Released kernel dispatch: %p has value: %" PRIu64 " (%p)\n",
+ shadow, (print_uint64_t) shadow->debug,
+ (void *) (uintptr_t) shadow->debug);
hsa_fns.hsa_memory_free_fn (shadow->kernarg_address);
@@ -1276,9 +1287,9 @@ print_kernel_dispatch (struct GOMP_hsa_kernel_dispatch *dispatch, unsigned inden
indent_stream (stderr, indent);
fprintf (stderr, "kernarg_address: %p\n", dispatch->kernarg_address);
indent_stream (stderr, indent);
- fprintf (stderr, "object: %lu\n", dispatch->object);
+ fprintf (stderr, "object: %" PRIu64 "\n", (print_uint64_t) dispatch->object);
indent_stream (stderr, indent);
- fprintf (stderr, "signal: %lu\n", dispatch->signal);
+ fprintf (stderr, "signal: %" PRIu64 "\n", (print_uint64_t) dispatch->signal);
indent_stream (stderr, indent);
fprintf (stderr, "private_segment_size: %u\n",
dispatch->private_segment_size);
@@ -1286,8 +1297,8 @@ print_kernel_dispatch (struct GOMP_hsa_kernel_dispatch *dispatch, unsigned inden
fprintf (stderr, "group_segment_size: %u\n",
dispatch->group_segment_size);
indent_stream (stderr, indent);
- fprintf (stderr, "children dispatches: %lu\n",
- dispatch->kernel_dispatch_count);
+ fprintf (stderr, "children dispatches: %" PRIu64 "\n",
+ (print_uint64_t) dispatch->kernel_dispatch_count);
indent_stream (stderr, indent);
fprintf (stderr, "omp_num_threads: %u\n",
dispatch->omp_num_threads);
@@ -1594,8 +1605,8 @@ run_kernel (struct kernel_info *kernel, void *vars,
hsa_signal_t child_s;
child_s.handle = shadow->children_dispatches[i]->signal;
- HSA_DEBUG ("Waiting for children completion signal: %lu\n",
- shadow->children_dispatches[i]->signal);
+ HSA_DEBUG ("Waiting for children completion signal: %" PRIu64 "\n",
+ (print_uint64_t) shadow->children_dispatches[i]->signal);
hsa_fns.hsa_signal_load_acquire_fn (child_s);
}
diff --git a/libgomp/plugin/plugin-nvptx.c b/libgomp/plugin/plugin-nvptx.c
index 89326e57741..911d0f66a6e 100644
--- a/libgomp/plugin/plugin-nvptx.c
+++ b/libgomp/plugin/plugin-nvptx.c
@@ -1,6 +1,6 @@
/* Plugin for NVPTX execution.
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Mentor Embedded.
@@ -37,11 +37,11 @@
#include "libgomp-plugin.h"
#include "oacc-plugin.h"
#include "gomp-constants.h"
+#include "oacc-int.h"
#include <pthread.h>
#include <cuda.h>
#include <stdbool.h>
-#include <stdint.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>
@@ -49,60 +49,41 @@
#include <assert.h>
#include <errno.h>
+#if CUDA_VERSION < 6000
+extern CUresult cuGetErrorString (CUresult, const char **);
+#define CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_MULTIPROCESSOR 82
+#endif
+
+#if CUDA_VERSION >= 6050
+#undef cuLinkCreate
+#undef cuLinkAddData
+CUresult cuLinkAddData (CUlinkState, CUjitInputType, void *, size_t,
+ const char *, unsigned, CUjit_option *, void **);
+CUresult cuLinkCreate (unsigned, CUjit_option *, void **, CUlinkState *);
+#else
+typedef size_t (*CUoccupancyB2DSize)(int);
+CUresult cuLinkAddData_v2 (CUlinkState, CUjitInputType, void *, size_t,
+ const char *, unsigned, CUjit_option *, void **);
+CUresult cuLinkCreate_v2 (unsigned, CUjit_option *, void **, CUlinkState *);
+CUresult cuOccupancyMaxPotentialBlockSize(int *, int *, CUfunction,
+ CUoccupancyB2DSize, size_t, int);
+#endif
+
+#define DO_PRAGMA(x) _Pragma (#x)
+
#if PLUGIN_NVPTX_DYNAMIC
# include <dlfcn.h>
-# define CUDA_CALLS \
-CUDA_ONE_CALL (cuCtxCreate) \
-CUDA_ONE_CALL (cuCtxDestroy) \
-CUDA_ONE_CALL (cuCtxGetCurrent) \
-CUDA_ONE_CALL (cuCtxGetDevice) \
-CUDA_ONE_CALL (cuCtxPopCurrent) \
-CUDA_ONE_CALL (cuCtxPushCurrent) \
-CUDA_ONE_CALL (cuCtxSynchronize) \
-CUDA_ONE_CALL (cuDeviceGet) \
-CUDA_ONE_CALL (cuDeviceGetAttribute) \
-CUDA_ONE_CALL (cuDeviceGetCount) \
-CUDA_ONE_CALL (cuEventCreate) \
-CUDA_ONE_CALL (cuEventDestroy) \
-CUDA_ONE_CALL (cuEventElapsedTime) \
-CUDA_ONE_CALL (cuEventQuery) \
-CUDA_ONE_CALL (cuEventRecord) \
-CUDA_ONE_CALL (cuEventSynchronize) \
-CUDA_ONE_CALL (cuFuncGetAttribute) \
-CUDA_ONE_CALL (cuGetErrorString) \
-CUDA_ONE_CALL (cuInit) \
-CUDA_ONE_CALL (cuLaunchKernel) \
-CUDA_ONE_CALL (cuLinkAddData) \
-CUDA_ONE_CALL (cuLinkComplete) \
-CUDA_ONE_CALL (cuLinkCreate) \
-CUDA_ONE_CALL (cuLinkDestroy) \
-CUDA_ONE_CALL (cuMemAlloc) \
-CUDA_ONE_CALL (cuMemAllocHost) \
-CUDA_ONE_CALL (cuMemcpy) \
-CUDA_ONE_CALL (cuMemcpyDtoDAsync) \
-CUDA_ONE_CALL (cuMemcpyDtoH) \
-CUDA_ONE_CALL (cuMemcpyDtoHAsync) \
-CUDA_ONE_CALL (cuMemcpyHtoD) \
-CUDA_ONE_CALL (cuMemcpyHtoDAsync) \
-CUDA_ONE_CALL (cuMemFree) \
-CUDA_ONE_CALL (cuMemFreeHost) \
-CUDA_ONE_CALL (cuMemGetAddressRange) \
-CUDA_ONE_CALL (cuMemHostGetDevicePointer)\
-CUDA_ONE_CALL (cuModuleGetFunction) \
-CUDA_ONE_CALL (cuModuleGetGlobal) \
-CUDA_ONE_CALL (cuModuleLoad) \
-CUDA_ONE_CALL (cuModuleLoadData) \
-CUDA_ONE_CALL (cuModuleUnload) \
-CUDA_ONE_CALL (cuStreamCreate) \
-CUDA_ONE_CALL (cuStreamDestroy) \
-CUDA_ONE_CALL (cuStreamQuery) \
-CUDA_ONE_CALL (cuStreamSynchronize) \
-CUDA_ONE_CALL (cuStreamWaitEvent)
-# define CUDA_ONE_CALL(call) \
- __typeof (call) *call;
struct cuda_lib_s {
- CUDA_CALLS
+
+# define CUDA_ONE_CALL(call) \
+ __typeof (call) *call;
+# define CUDA_ONE_CALL_MAYBE_NULL(call) \
+ CUDA_ONE_CALL (call)
+#include "cuda-lib.def"
+# undef CUDA_ONE_CALL
+# undef CUDA_ONE_CALL_MAYBE_NULL
+
} cuda_lib;
/* -1 if init_cuda_lib has not been called yet, false
@@ -121,26 +102,41 @@ init_cuda_lib (void)
cuda_lib_inited = false;
if (h == NULL)
return false;
-# undef CUDA_ONE_CALL
-# define CUDA_ONE_CALL(call) CUDA_ONE_CALL_1 (call)
-# define CUDA_ONE_CALL_1(call) \
+
+# define CUDA_ONE_CALL(call) CUDA_ONE_CALL_1 (call, false)
+# define CUDA_ONE_CALL_MAYBE_NULL(call) CUDA_ONE_CALL_1 (call, true)
+# define CUDA_ONE_CALL_1(call, allow_null) \
cuda_lib.call = dlsym (h, #call); \
- if (cuda_lib.call == NULL) \
+ if (!allow_null && cuda_lib.call == NULL) \
return false;
- CUDA_CALLS
+#include "cuda-lib.def"
+# undef CUDA_ONE_CALL
+# undef CUDA_ONE_CALL_1
+# undef CUDA_ONE_CALL_MAYBE_NULL
+
cuda_lib_inited = true;
return true;
}
-# undef CUDA_ONE_CALL
-# undef CUDA_ONE_CALL_1
# define CUDA_CALL_PREFIX cuda_lib.
#else
+
+# define CUDA_ONE_CALL(call)
+# define CUDA_ONE_CALL_MAYBE_NULL(call) DO_PRAGMA (weak call)
+#include "cuda-lib.def"
+#undef CUDA_ONE_CALL_MAYBE_NULL
+#undef CUDA_ONE_CALL
+
# define CUDA_CALL_PREFIX
# define init_cuda_lib() true
#endif
#include "secure_getenv.h"
+#undef MIN
+#undef MAX
+#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
+#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
+
/* Convenience macros for the frequently used CUDA library call and
error handling sequence as well as CUDA library calls that
do the error checking themselves or don't do it at all. */
@@ -174,169 +170,52 @@ init_cuda_lib (void)
#define CUDA_CALL_NOCHECK(FN, ...) \
CUDA_CALL_PREFIX FN (__VA_ARGS__)
+#define CUDA_CALL_EXISTS(FN) \
+ CUDA_CALL_PREFIX FN
+
static const char *
cuda_error (CUresult r)
{
-#if CUDA_VERSION < 7000
- /* Specified in documentation and present in library from at least
- 5.5. Not declared in header file prior to 7.0. */
- extern CUresult cuGetErrorString (CUresult, const char **);
-#endif
+ const char *fallback = "unknown cuda error";
const char *desc;
+ if (!CUDA_CALL_EXISTS (cuGetErrorString))
+ return fallback;
+
r = CUDA_CALL_NOCHECK (cuGetErrorString, r, &desc);
- if (r != CUDA_SUCCESS)
- desc = "unknown cuda error";
+ if (r == CUDA_SUCCESS)
+ return desc;
- return desc;
+ return fallback;
}
static unsigned int instantiated_devices = 0;
static pthread_mutex_t ptx_dev_lock = PTHREAD_MUTEX_INITIALIZER;
-struct ptx_stream
+/* NVPTX/CUDA specific definition of asynchronous queues. */
+struct goacc_asyncqueue
{
- CUstream stream;
- pthread_t host_thread;
- bool multithreaded;
+ CUstream cuda_stream;
+};
- CUdeviceptr d;
- void *h;
- void *h_begin;
- void *h_end;
- void *h_next;
- void *h_prev;
- void *h_tail;
-
- struct ptx_stream *next;
+struct nvptx_callback
+{
+ void (*fn) (void *);
+ void *ptr;
+ struct goacc_asyncqueue *aq;
+ struct nvptx_callback *next;
};
/* Thread-specific data for PTX. */
struct nvptx_thread
{
- struct ptx_stream *current_stream;
+ /* We currently have this embedded inside the plugin because libgomp manages
+ devices through integer target_ids. This might be better if using an
+ opaque target-specific pointer directly from gomp_device_descr. */
struct ptx_device *ptx_dev;
};
-struct map
-{
- int async;
- size_t size;
- char mappings[0];
-};
-
-static bool
-map_init (struct ptx_stream *s)
-{
- int size = getpagesize ();
-
- assert (s);
- assert (!s->d);
- assert (!s->h);
-
- CUDA_CALL (cuMemAllocHost, &s->h, size);
- CUDA_CALL (cuMemHostGetDevicePointer, &s->d, s->h, 0);
-
- assert (s->h);
-
- s->h_begin = s->h;
- s->h_end = s->h_begin + size;
- s->h_next = s->h_prev = s->h_tail = s->h_begin;
-
- assert (s->h_next);
- assert (s->h_end);
- return true;
-}
-
-static bool
-map_fini (struct ptx_stream *s)
-{
- CUDA_CALL (cuMemFreeHost, s->h);
- return true;
-}
-
-static void
-map_pop (struct ptx_stream *s)
-{
- struct map *m;
-
- assert (s != NULL);
- assert (s->h_next);
- assert (s->h_prev);
- assert (s->h_tail);
-
- m = s->h_tail;
-
- s->h_tail += m->size;
-
- if (s->h_tail >= s->h_end)
- s->h_tail = s->h_begin + (int) (s->h_tail - s->h_end);
-
- if (s->h_next == s->h_tail)
- s->h_prev = s->h_next;
-
- assert (s->h_next >= s->h_begin);
- assert (s->h_tail >= s->h_begin);
- assert (s->h_prev >= s->h_begin);
-
- assert (s->h_next <= s->h_end);
- assert (s->h_tail <= s->h_end);
- assert (s->h_prev <= s->h_end);
-}
-
-static void
-map_push (struct ptx_stream *s, int async, size_t size, void **h, void **d)
-{
- int left;
- int offset;
- struct map *m;
-
- assert (s != NULL);
-
- left = s->h_end - s->h_next;
- size += sizeof (struct map);
-
- assert (s->h_prev);
- assert (s->h_next);
-
- if (size >= left)
- {
- m = s->h_prev;
- m->size += left;
- s->h_next = s->h_begin;
-
- if (s->h_next + size > s->h_end)
- GOMP_PLUGIN_fatal ("unable to push map");
- }
-
- assert (s->h_next);
-
- m = s->h_next;
- m->async = async;
- m->size = size;
-
- offset = (void *)&m->mappings[0] - s->h;
-
- *d = (void *)(s->d + offset);
- *h = (void *)(s->h + offset);
-
- s->h_prev = s->h_next;
- s->h_next += size;
-
- assert (s->h_prev);
- assert (s->h_next);
-
- assert (s->h_next >= s->h_begin);
- assert (s->h_tail >= s->h_begin);
- assert (s->h_prev >= s->h_begin);
- assert (s->h_next <= s->h_end);
- assert (s->h_tail <= s->h_end);
- assert (s->h_prev <= s->h_end);
-
- return;
-}
-
/* Target data function launch information. */
struct targ_fn_launch
@@ -388,22 +267,18 @@ struct ptx_image_data
struct ptx_image_data *next;
};
+struct ptx_free_block
+{
+ void *ptr;
+ struct ptx_free_block *next;
+};
+
struct ptx_device
{
CUcontext ctx;
bool ctx_shared;
CUdevice dev;
- struct ptx_stream *null_stream;
- /* All non-null streams associated with this device (actually context),
- either created implicitly or passed in from the user (via
- acc_set_cuda_stream). */
- struct ptx_stream *active_streams;
- struct {
- struct ptx_stream **arr;
- int size;
- } async_streams;
- /* A lock for use when manipulating the above stream list and array. */
- pthread_mutex_t stream_lock;
+
int ord;
bool overlap;
bool map;
@@ -414,35 +289,20 @@ struct ptx_device
int num_sms;
int regs_per_block;
int regs_per_sm;
+ int warp_size;
+ int max_threads_per_block;
+ int max_threads_per_multiprocessor;
+ int default_dims[GOMP_DIM_MAX];
struct ptx_image_data *images; /* Images loaded on device. */
pthread_mutex_t image_lock; /* Lock for above list. */
-
- struct ptx_device *next;
-};
-enum ptx_event_type
-{
- PTX_EVT_MEM,
- PTX_EVT_KNL,
- PTX_EVT_SYNC,
- PTX_EVT_ASYNC_CLEANUP
-};
+ struct ptx_free_block *free_blocks;
+ pthread_mutex_t free_blocks_lock;
-struct ptx_event
-{
- CUevent *evt;
- int type;
- void *addr;
- int ord;
- int val;
-
- struct ptx_event *next;
+ struct ptx_device *next;
};
-static pthread_mutex_t ptx_event_lock;
-static struct ptx_event *ptx_events;
-
static struct ptx_device **ptx_devices;
static inline struct nvptx_thread *
@@ -451,197 +311,6 @@ nvptx_thread (void)
return (struct nvptx_thread *) GOMP_PLUGIN_acc_thread ();
}
-static bool
-init_streams_for_device (struct ptx_device *ptx_dev, int concurrency)
-{
- int i;
- struct ptx_stream *null_stream
- = GOMP_PLUGIN_malloc (sizeof (struct ptx_stream));
-
- null_stream->stream = NULL;
- null_stream->host_thread = pthread_self ();
- null_stream->multithreaded = true;
- null_stream->d = (CUdeviceptr) NULL;
- null_stream->h = NULL;
- if (!map_init (null_stream))
- return false;
-
- ptx_dev->null_stream = null_stream;
- ptx_dev->active_streams = NULL;
- pthread_mutex_init (&ptx_dev->stream_lock, NULL);
-
- if (concurrency < 1)
- concurrency = 1;
-
- /* This is just a guess -- make space for as many async streams as the
- current device is capable of concurrently executing. This can grow
- later as necessary. No streams are created yet. */
- ptx_dev->async_streams.arr
- = GOMP_PLUGIN_malloc (concurrency * sizeof (struct ptx_stream *));
- ptx_dev->async_streams.size = concurrency;
-
- for (i = 0; i < concurrency; i++)
- ptx_dev->async_streams.arr[i] = NULL;
-
- return true;
-}
-
-static bool
-fini_streams_for_device (struct ptx_device *ptx_dev)
-{
- free (ptx_dev->async_streams.arr);
-
- bool ret = true;
- while (ptx_dev->active_streams != NULL)
- {
- struct ptx_stream *s = ptx_dev->active_streams;
- ptx_dev->active_streams = ptx_dev->active_streams->next;
-
- ret &= map_fini (s);
-
- CUresult r = CUDA_CALL_NOCHECK (cuStreamDestroy, s->stream);
- if (r != CUDA_SUCCESS)
- {
- GOMP_PLUGIN_error ("cuStreamDestroy error: %s", cuda_error (r));
- ret = false;
- }
- free (s);
- }
-
- ret &= map_fini (ptx_dev->null_stream);
- free (ptx_dev->null_stream);
- return ret;
-}
-
-/* Select a stream for (OpenACC-semantics) ASYNC argument for the current
- thread THREAD (and also current device/context). If CREATE is true, create
- the stream if it does not exist (or use EXISTING if it is non-NULL), and
- associate the stream with the same thread argument. Returns stream to use
- as result. */
-
-static struct ptx_stream *
-select_stream_for_async (int async, pthread_t thread, bool create,
- CUstream existing)
-{
- struct nvptx_thread *nvthd = nvptx_thread ();
- /* Local copy of TLS variable. */
- struct ptx_device *ptx_dev = nvthd->ptx_dev;
- struct ptx_stream *stream = NULL;
- int orig_async = async;
-
- /* The special value acc_async_noval (-1) maps (for now) to an
- implicitly-created stream, which is then handled the same as any other
- numbered async stream. Other options are available, e.g. using the null
- stream for anonymous async operations, or choosing an idle stream from an
- active set. But, stick with this for now. */
- if (async > acc_async_sync)
- async++;
-
- if (create)
- pthread_mutex_lock (&ptx_dev->stream_lock);
-
- /* NOTE: AFAICT there's no particular need for acc_async_sync to map to the
- null stream, and in fact better performance may be obtainable if it doesn't
- (because the null stream enforces overly-strict synchronisation with
- respect to other streams for legacy reasons, and that's probably not
- needed with OpenACC). Maybe investigate later. */
- if (async == acc_async_sync)
- stream = ptx_dev->null_stream;
- else if (async >= 0 && async < ptx_dev->async_streams.size
- && ptx_dev->async_streams.arr[async] && !(create && existing))
- stream = ptx_dev->async_streams.arr[async];
- else if (async >= 0 && create)
- {
- if (async >= ptx_dev->async_streams.size)
- {
- int i, newsize = ptx_dev->async_streams.size * 2;
-
- if (async >= newsize)
- newsize = async + 1;
-
- ptx_dev->async_streams.arr
- = GOMP_PLUGIN_realloc (ptx_dev->async_streams.arr,
- newsize * sizeof (struct ptx_stream *));
-
- for (i = ptx_dev->async_streams.size; i < newsize; i++)
- ptx_dev->async_streams.arr[i] = NULL;
-
- ptx_dev->async_streams.size = newsize;
- }
-
- /* Create a new stream on-demand if there isn't one already, or if we're
- setting a particular async value to an existing (externally-provided)
- stream. */
- if (!ptx_dev->async_streams.arr[async] || existing)
- {
- CUresult r;
- struct ptx_stream *s
- = GOMP_PLUGIN_malloc (sizeof (struct ptx_stream));
-
- if (existing)
- s->stream = existing;
- else
- {
- r = CUDA_CALL_NOCHECK (cuStreamCreate, &s->stream,
- CU_STREAM_DEFAULT);
- if (r != CUDA_SUCCESS)
- {
- pthread_mutex_unlock (&ptx_dev->stream_lock);
- GOMP_PLUGIN_fatal ("cuStreamCreate error: %s",
- cuda_error (r));
- }
- }
-
- /* If CREATE is true, we're going to be queueing some work on this
- stream. Associate it with the current host thread. */
- s->host_thread = thread;
- s->multithreaded = false;
-
- s->d = (CUdeviceptr) NULL;
- s->h = NULL;
- if (!map_init (s))
- {
- pthread_mutex_unlock (&ptx_dev->stream_lock);
- GOMP_PLUGIN_fatal ("map_init fail");
- }
-
- s->next = ptx_dev->active_streams;
- ptx_dev->active_streams = s;
- ptx_dev->async_streams.arr[async] = s;
- }
-
- stream = ptx_dev->async_streams.arr[async];
- }
- else if (async < 0)
- {
- if (create)
- pthread_mutex_unlock (&ptx_dev->stream_lock);
- GOMP_PLUGIN_fatal ("bad async %d", async);
- }
-
- if (create)
- {
- assert (stream != NULL);
-
- /* If we're trying to use the same stream from different threads
- simultaneously, set stream->multithreaded to true. This affects the
- behaviour of acc_async_test_all and acc_wait_all, which are supposed to
- only wait for asynchronous launches from the same host thread they are
- invoked on. If multiple threads use the same async value, we make note
- of that here and fall back to testing/waiting for all threads in those
- functions. */
- if (thread != stream->host_thread)
- stream->multithreaded = true;
-
- pthread_mutex_unlock (&ptx_dev->stream_lock);
- }
- else if (stream && !stream->multithreaded
- && !pthread_equal (stream->host_thread, thread))
- GOMP_PLUGIN_fatal ("async %d used on wrong thread", orig_async);
-
- return stream;
-}
-
/* Initialize the device. Return TRUE on success, else FALSE. PTX_DEV_LOCK
should be locked on entry and remains locked on exit. */
@@ -653,9 +322,6 @@ nvptx_init (void)
if (instantiated_devices != 0)
return true;
- ptx_events = NULL;
- pthread_mutex_init (&ptx_event_lock, NULL);
-
if (!init_cuda_lib ())
return false;
@@ -679,6 +345,11 @@ nvptx_attach_host_thread_to_device (int n)
CUcontext thd_ctx;
r = CUDA_CALL_NOCHECK (cuCtxGetDevice, &dev);
+ if (r == CUDA_ERROR_NOT_PERMITTED)
+ {
+ /* Assume we're in a CUDA callback, just return true. */
+ return true;
+ }
if (r != CUDA_SUCCESS && r != CUDA_ERROR_INVALID_CONTEXT)
{
GOMP_PLUGIN_error ("cuCtxGetDevice error: %s", cuda_error (r));
@@ -780,9 +451,11 @@ nvptx_open_device (int n)
&pi, CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK, dev);
ptx_dev->regs_per_block = pi;
- /* CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_MULTIPROCESSOR = 82 is defined only
+ /* CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_MULTIPROCESSOR is defined only
in CUDA 6.0 and newer. */
- r = CUDA_CALL_NOCHECK (cuDeviceGetAttribute, &pi, 82, dev);
+ r = CUDA_CALL_NOCHECK (cuDeviceGetAttribute, &pi,
+ CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_MULTIPROCESSOR,
+ dev);
/* Fallback: use limit of registers per block, which is usually equal. */
if (r == CUDA_ERROR_INVALID_VALUE)
pi = ptx_dev->regs_per_block;
@@ -800,17 +473,29 @@ nvptx_open_device (int n)
GOMP_PLUGIN_error ("Only warp size 32 is supported");
return NULL;
}
+ ptx_dev->warp_size = pi;
+
+ CUDA_CALL_ERET (NULL, cuDeviceGetAttribute, &pi,
+ CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK, dev);
+ ptx_dev->max_threads_per_block = pi;
+
+ CUDA_CALL_ERET (NULL, cuDeviceGetAttribute, &pi,
+ CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_MULTIPROCESSOR, dev);
+ ptx_dev->max_threads_per_multiprocessor = pi;
r = CUDA_CALL_NOCHECK (cuDeviceGetAttribute, &async_engines,
CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT, dev);
if (r != CUDA_SUCCESS)
async_engines = 1;
+ for (int i = 0; i != GOMP_DIM_MAX; i++)
+ ptx_dev->default_dims[i] = 0;
+
ptx_dev->images = NULL;
pthread_mutex_init (&ptx_dev->image_lock, NULL);
- if (!init_streams_for_device (ptx_dev, async_engines))
- return NULL;
+ ptx_dev->free_blocks = NULL;
+ pthread_mutex_init (&ptx_dev->free_blocks_lock, NULL);
return ptx_dev;
}
@@ -821,9 +506,15 @@ nvptx_close_device (struct ptx_device *ptx_dev)
if (!ptx_dev)
return true;
- if (!fini_streams_for_device (ptx_dev))
- return false;
-
+ for (struct ptx_free_block *b = ptx_dev->free_blocks; b;)
+ {
+ struct ptx_free_block *b_next = b->next;
+ CUDA_CALL (cuMemFree, (CUdeviceptr) b->ptr);
+ free (b);
+ b = b_next;
+ }
+
+ pthread_mutex_destroy (&ptx_dev->free_blocks_lock);
pthread_mutex_destroy (&ptx_dev->image_lock);
if (!ptx_dev->ctx_shared)
@@ -958,16 +649,24 @@ link_ptx (CUmodule *module, const struct targ_ptx_obj *ptx_objs,
nopts++;
}
- CUDA_CALL (cuLinkCreate, nopts, opts, optvals, &linkstate);
+ if (CUDA_CALL_EXISTS (cuLinkCreate_v2))
+ CUDA_CALL (cuLinkCreate_v2, nopts, opts, optvals, &linkstate);
+ else
+ CUDA_CALL (cuLinkCreate, nopts, opts, optvals, &linkstate);
for (; num_objs--; ptx_objs++)
{
/* cuLinkAddData's 'data' argument erroneously omits the const
qualifier. */
GOMP_PLUGIN_debug (0, "Loading:\n---\n%s\n---\n", ptx_objs->code);
- r = CUDA_CALL_NOCHECK (cuLinkAddData, linkstate, CU_JIT_INPUT_PTX,
- (char *) ptx_objs->code, ptx_objs->size,
- 0, 0, 0, 0);
+ if (CUDA_CALL_EXISTS (cuLinkAddData_v2))
+ r = CUDA_CALL_NOCHECK (cuLinkAddData_v2, linkstate, CU_JIT_INPUT_PTX,
+ (char *) ptx_objs->code, ptx_objs->size,
+ 0, 0, 0, 0);
+ else
+ r = CUDA_CALL_NOCHECK (cuLinkAddData, linkstate, CU_JIT_INPUT_PTX,
+ (char *) ptx_objs->code, ptx_objs->size,
+ 0, 0, 0, 0);
if (r != CUDA_SUCCESS)
{
GOMP_PLUGIN_error ("Link error log %s\n", &elog[0]);
@@ -995,137 +694,19 @@ link_ptx (CUmodule *module, const struct targ_ptx_obj *ptx_objs,
}
static void
-event_gc (bool memmap_lockable)
-{
- struct ptx_event *ptx_event = ptx_events;
- struct ptx_event *async_cleanups = NULL;
- struct nvptx_thread *nvthd = nvptx_thread ();
-
- pthread_mutex_lock (&ptx_event_lock);
-
- while (ptx_event != NULL)
- {
- CUresult r;
- struct ptx_event *e = ptx_event;
-
- ptx_event = ptx_event->next;
-
- if (e->ord != nvthd->ptx_dev->ord)
- continue;
-
- r = CUDA_CALL_NOCHECK (cuEventQuery, *e->evt);
- if (r == CUDA_SUCCESS)
- {
- bool append_async = false;
- CUevent *te;
-
- te = e->evt;
-
- switch (e->type)
- {
- case PTX_EVT_MEM:
- case PTX_EVT_SYNC:
- break;
-
- case PTX_EVT_KNL:
- map_pop (e->addr);
- break;
-
- case PTX_EVT_ASYNC_CLEANUP:
- {
- /* The function gomp_plugin_async_unmap_vars needs to claim the
- memory-map splay tree lock for the current device, so we
- can't call it when one of our callers has already claimed
- the lock. In that case, just delay the GC for this event
- until later. */
- if (!memmap_lockable)
- continue;
-
- append_async = true;
- }
- break;
- }
-
- CUDA_CALL_NOCHECK (cuEventDestroy, *te);
- free ((void *)te);
-
- /* Unlink 'e' from ptx_events list. */
- if (ptx_events == e)
- ptx_events = ptx_events->next;
- else
- {
- struct ptx_event *e_ = ptx_events;
- while (e_->next != e)
- e_ = e_->next;
- e_->next = e_->next->next;
- }
-
- if (append_async)
- {
- e->next = async_cleanups;
- async_cleanups = e;
- }
- else
- free (e);
- }
- }
-
- pthread_mutex_unlock (&ptx_event_lock);
-
- /* We have to do these here, after ptx_event_lock is released. */
- while (async_cleanups)
- {
- struct ptx_event *e = async_cleanups;
- async_cleanups = async_cleanups->next;
-
- GOMP_PLUGIN_async_unmap_vars (e->addr, e->val);
- free (e);
- }
-}
-
-static void
-event_add (enum ptx_event_type type, CUevent *e, void *h, int val)
-{
- struct ptx_event *ptx_event;
- struct nvptx_thread *nvthd = nvptx_thread ();
-
- assert (type == PTX_EVT_MEM || type == PTX_EVT_KNL || type == PTX_EVT_SYNC
- || type == PTX_EVT_ASYNC_CLEANUP);
-
- ptx_event = GOMP_PLUGIN_malloc (sizeof (struct ptx_event));
- ptx_event->type = type;
- ptx_event->evt = e;
- ptx_event->addr = h;
- ptx_event->ord = nvthd->ptx_dev->ord;
- ptx_event->val = val;
-
- pthread_mutex_lock (&ptx_event_lock);
-
- ptx_event->next = ptx_events;
- ptx_events = ptx_event;
-
- pthread_mutex_unlock (&ptx_event_lock);
-}
-
-static void
nvptx_exec (void (*fn), size_t mapnum, void **hostaddrs, void **devaddrs,
- int async, unsigned *dims, void *targ_mem_desc)
+ unsigned *dims, void *targ_mem_desc,
+ CUdeviceptr dp, CUstream stream)
{
struct targ_fn_descriptor *targ_fn = (struct targ_fn_descriptor *) fn;
CUfunction function;
- CUresult r;
int i;
- struct ptx_stream *dev_str;
void *kargs[1];
- void *hp, *dp;
struct nvptx_thread *nvthd = nvptx_thread ();
- const char *maybe_abort_msg = "(perhaps abort was called)";
+ int warp_size = nvthd->ptx_dev->warp_size;
function = targ_fn->fn;
- dev_str = select_stream_for_async (async, pthread_self (), false, NULL);
- assert (dev_str == nvthd->current_stream);
-
/* Initialize the launch dimensions. Typically this is constant,
provided by the device compiler, but we must permit runtime
values. */
@@ -1140,43 +721,36 @@ nvptx_exec (void (*fn), size_t mapnum, void **hostaddrs, void **devaddrs,
if (seen_zero)
{
- /* See if the user provided GOMP_OPENACC_DIM environment
- variable to specify runtime defaults. */
- static int default_dims[GOMP_DIM_MAX];
-
pthread_mutex_lock (&ptx_dev_lock);
- if (!default_dims[0])
+
+ static int gomp_openacc_dims[GOMP_DIM_MAX];
+ if (!gomp_openacc_dims[0])
+ {
+ /* See if the user provided GOMP_OPENACC_DIM environment
+ variable to specify runtime defaults. */
+ for (int i = 0; i < GOMP_DIM_MAX; ++i)
+ gomp_openacc_dims[i] = GOMP_PLUGIN_acc_default_dim (i);
+ }
+
+ if (!nvthd->ptx_dev->default_dims[0])
{
+ int default_dims[GOMP_DIM_MAX];
for (int i = 0; i < GOMP_DIM_MAX; ++i)
- default_dims[i] = GOMP_PLUGIN_acc_default_dim (i);
-
- int warp_size, block_size, dev_size, cpu_size;
- CUdevice dev = nvptx_thread()->ptx_dev->dev;
- /* 32 is the default for known hardware. */
- int gang = 0, worker = 32, vector = 32;
- CUdevice_attribute cu_tpb, cu_ws, cu_mpc, cu_tpm;
-
- cu_tpb = CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK;
- cu_ws = CU_DEVICE_ATTRIBUTE_WARP_SIZE;
- cu_mpc = CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT;
- cu_tpm = CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_MULTIPROCESSOR;
-
- if (CUDA_CALL_NOCHECK (cuDeviceGetAttribute, &block_size, cu_tpb,
- dev) == CUDA_SUCCESS
- && CUDA_CALL_NOCHECK (cuDeviceGetAttribute, &warp_size, cu_ws,
- dev) == CUDA_SUCCESS
- && CUDA_CALL_NOCHECK (cuDeviceGetAttribute, &dev_size, cu_mpc,
- dev) == CUDA_SUCCESS
- && CUDA_CALL_NOCHECK (cuDeviceGetAttribute, &cpu_size, cu_tpm,
- dev) == CUDA_SUCCESS)
- {
- GOMP_PLUGIN_debug (0, " warp_size=%d, block_size=%d,"
- " dev_size=%d, cpu_size=%d\n",
- warp_size, block_size, dev_size, cpu_size);
- gang = (cpu_size / block_size) * dev_size;
- worker = block_size / warp_size;
- vector = warp_size;
- }
+ default_dims[i] = gomp_openacc_dims[i];
+
+ int gang, worker, vector;
+ {
+ int block_size = nvthd->ptx_dev->max_threads_per_block;
+ int cpu_size = nvthd->ptx_dev->max_threads_per_multiprocessor;
+ int dev_size = nvthd->ptx_dev->num_sms;
+ GOMP_PLUGIN_debug (0, " warp_size=%d, block_size=%d,"
+ " dev_size=%d, cpu_size=%d\n",
+ warp_size, block_size, dev_size, cpu_size);
+
+ gang = (cpu_size / block_size) * dev_size;
+ worker = block_size / warp_size;
+ vector = warp_size;
+ }
/* There is no upper bound on the gang size. The best size
matches the hardware configuration. Logical gangs are
@@ -1197,29 +771,129 @@ nvptx_exec (void (*fn), size_t mapnum, void **hostaddrs, void **devaddrs,
default_dims[GOMP_DIM_GANG],
default_dims[GOMP_DIM_WORKER],
default_dims[GOMP_DIM_VECTOR]);
+
+ for (i = 0; i != GOMP_DIM_MAX; i++)
+ nvthd->ptx_dev->default_dims[i] = default_dims[i];
}
pthread_mutex_unlock (&ptx_dev_lock);
- for (i = 0; i != GOMP_DIM_MAX; i++)
- if (!dims[i])
- dims[i] = default_dims[i];
- }
+ {
+ bool default_dim_p[GOMP_DIM_MAX];
+ for (i = 0; i != GOMP_DIM_MAX; i++)
+ default_dim_p[i] = !dims[i];
+
+ if (!CUDA_CALL_EXISTS (cuOccupancyMaxPotentialBlockSize))
+ {
+ for (i = 0; i != GOMP_DIM_MAX; i++)
+ if (default_dim_p[i])
+ dims[i] = nvthd->ptx_dev->default_dims[i];
+
+ if (default_dim_p[GOMP_DIM_VECTOR])
+ dims[GOMP_DIM_VECTOR]
+ = MIN (dims[GOMP_DIM_VECTOR],
+ (targ_fn->max_threads_per_block / warp_size
+ * warp_size));
+
+ if (default_dim_p[GOMP_DIM_WORKER])
+ dims[GOMP_DIM_WORKER]
+ = MIN (dims[GOMP_DIM_WORKER],
+ targ_fn->max_threads_per_block / dims[GOMP_DIM_VECTOR]);
+ }
+ else
+ {
+ /* Handle the case that the compiler allows the runtime to choose
+ the vector-length conservatively, by ignoring
+ gomp_openacc_dims[GOMP_DIM_VECTOR]. TODO: actually handle
+ it. */
+ int vectors = 0;
+ /* TODO: limit gomp_openacc_dims[GOMP_DIM_WORKER] such that that
+ gomp_openacc_dims[GOMP_DIM_WORKER] * actual_vectors does not
+ exceed targ_fn->max_threads_per_block. */
+ int workers = gomp_openacc_dims[GOMP_DIM_WORKER];
+ int gangs = gomp_openacc_dims[GOMP_DIM_GANG];
+ int grids, blocks;
+
+ CUDA_CALL_ASSERT (cuOccupancyMaxPotentialBlockSize, &grids,
+ &blocks, function, NULL, 0,
+ dims[GOMP_DIM_WORKER] * dims[GOMP_DIM_VECTOR]);
+ GOMP_PLUGIN_debug (0, "cuOccupancyMaxPotentialBlockSize: "
+ "grid = %d, block = %d\n", grids, blocks);
+
+ /* Keep the num_gangs proportional to the block size. In
+ the case were a block size is limited by shared-memory
+ or the register file capacity, the runtime will not
+ excessively over assign gangs to the multiprocessor
+ units if their state is going to be swapped out even
+ more than necessary. The constant factor 2 is there to
+ prevent threads from idling when there is insufficient
+ work for them. */
+ if (gangs == 0)
+ gangs = 2 * grids * (blocks / warp_size);
+
+ if (vectors == 0)
+ vectors = warp_size;
+
+ if (workers == 0)
+ {
+ int actual_vectors = (default_dim_p[GOMP_DIM_VECTOR]
+ ? vectors
+ : dims[GOMP_DIM_VECTOR]);
+ workers = blocks / actual_vectors;
+ workers = MAX (workers, 1);
+ /* If we need a per-worker barrier ... . */
+ if (actual_vectors > 32)
+ /* Don't use more barriers than available. */
+ workers = MIN (workers, 15);
+ }
- /* This reserves a chunk of a pre-allocated page of memory mapped on both
- the host and the device. HP is a host pointer to the new chunk, and DP is
- the corresponding device pointer. */
- map_push (dev_str, async, mapnum * sizeof (void *), &hp, &dp);
+ for (i = 0; i != GOMP_DIM_MAX; i++)
+ if (default_dim_p[i])
+ switch (i)
+ {
+ case GOMP_DIM_GANG: dims[i] = gangs; break;
+ case GOMP_DIM_WORKER: dims[i] = workers; break;
+ case GOMP_DIM_VECTOR: dims[i] = vectors; break;
+ default: GOMP_PLUGIN_fatal ("invalid dim");
+ }
+ }
+ }
+ }
- GOMP_PLUGIN_debug (0, " %s: prepare mappings\n", __FUNCTION__);
+ /* Check if the accelerator has sufficient hardware resources to
+ launch the offloaded kernel. */
+ if (dims[GOMP_DIM_WORKER] * dims[GOMP_DIM_VECTOR]
+ > targ_fn->max_threads_per_block)
+ {
+ const char *msg
+ = ("The Nvidia accelerator has insufficient resources to launch '%s'"
+ " with num_workers = %d and vector_length = %d"
+ "; "
+ "recompile the program with 'num_workers = x and vector_length = y'"
+ " on that offloaded region or '-fopenacc-dim=:x:y' where"
+ " x * y <= %d"
+ ".\n");
+ GOMP_PLUGIN_fatal (msg, targ_fn->launch->fn, dims[GOMP_DIM_WORKER],
+ dims[GOMP_DIM_VECTOR], targ_fn->max_threads_per_block);
+ }
- /* Copy the array of arguments to the mapped page. */
- for (i = 0; i < mapnum; i++)
- ((void **) hp)[i] = devaddrs[i];
+ /* Check if the accelerator has sufficient barrier resources to
+ launch the offloaded kernel. */
+ if (dims[GOMP_DIM_WORKER] > 15 && dims[GOMP_DIM_VECTOR] > 32)
+ {
+ const char *msg
+ = ("The Nvidia accelerator has insufficient barrier resources to launch"
+ " '%s' with num_workers = %d and vector_length = %d"
+ "; "
+ "recompile the program with 'num_workers = x' on that offloaded"
+ " region or '-fopenacc-dim=:x:' where x <= 15"
+ "; "
+ "or, recompile the program with 'vector_length = 32' on that"
+ " offloaded region or '-fopenacc-dim=::32'"
+ ".\n");
+ GOMP_PLUGIN_fatal (msg, targ_fn->launch->fn, dims[GOMP_DIM_WORKER],
+ dims[GOMP_DIM_VECTOR]);
+ }
- /* Copy the (device) pointers to arguments to the device (dp and hp might in
- fact have the same value on a unified-memory system). */
- CUDA_CALL_ASSERT (cuMemcpy, (CUdeviceptr) dp, (CUdeviceptr) hp,
- mapnum * sizeof (void *));
GOMP_PLUGIN_debug (0, " %s: kernel %s: launch"
" gangs=%u, workers=%u, vectors=%u\n",
__FUNCTION__, targ_fn->launch->fn, dims[GOMP_DIM_GANG],
@@ -1231,386 +905,157 @@ nvptx_exec (void (*fn), size_t mapnum, void **hostaddrs, void **devaddrs,
// num_workers ntid.y
// vector length ntid.x
+ struct goacc_thread *thr = GOMP_PLUGIN_goacc_thread ();
+ acc_prof_info *prof_info = thr->prof_info;
+ acc_event_info enqueue_launch_event_info;
+ acc_api_info *api_info = thr->api_info;
+ bool profiling_p = __builtin_expect (prof_info != NULL, false);
+ if (profiling_p)
+ {
+ prof_info->event_type = acc_ev_enqueue_launch_start;
+
+ enqueue_launch_event_info.launch_event.event_type
+ = prof_info->event_type;
+ enqueue_launch_event_info.launch_event.valid_bytes
+ = _ACC_LAUNCH_EVENT_INFO_VALID_BYTES;
+ enqueue_launch_event_info.launch_event.parent_construct
+ = acc_construct_parallel;
+ enqueue_launch_event_info.launch_event.implicit = 1;
+ enqueue_launch_event_info.launch_event.tool_info = NULL;
+ enqueue_launch_event_info.launch_event.kernel_name = targ_fn->launch->fn;
+ enqueue_launch_event_info.launch_event.num_gangs
+ = dims[GOMP_DIM_GANG];
+ enqueue_launch_event_info.launch_event.num_workers
+ = dims[GOMP_DIM_WORKER];
+ enqueue_launch_event_info.launch_event.vector_length
+ = dims[GOMP_DIM_VECTOR];
+
+ api_info->device_api = acc_device_api_cuda;
+
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info, &enqueue_launch_event_info,
+ api_info);
+ }
+
kargs[0] = &dp;
CUDA_CALL_ASSERT (cuLaunchKernel, function,
dims[GOMP_DIM_GANG], 1, 1,
dims[GOMP_DIM_VECTOR], dims[GOMP_DIM_WORKER], 1,
- 0, dev_str->stream, kargs, 0);
+ 0, stream, kargs, 0);
-#ifndef DISABLE_ASYNC
- if (async < acc_async_noval)
+ if (profiling_p)
{
- r = CUDA_CALL_NOCHECK (cuStreamSynchronize, dev_str->stream);
- if (r == CUDA_ERROR_LAUNCH_FAILED)
- GOMP_PLUGIN_fatal ("cuStreamSynchronize error: %s %s\n", cuda_error (r),
- maybe_abort_msg);
- else if (r != CUDA_SUCCESS)
- GOMP_PLUGIN_fatal ("cuStreamSynchronize error: %s", cuda_error (r));
+ prof_info->event_type = acc_ev_enqueue_launch_end;
+ enqueue_launch_event_info.launch_event.event_type
+ = prof_info->event_type;
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info, &enqueue_launch_event_info,
+ api_info);
}
- else
- {
- CUevent *e;
- e = (CUevent *)GOMP_PLUGIN_malloc (sizeof (CUevent));
+ GOMP_PLUGIN_debug (0, " %s: kernel %s: finished\n", __FUNCTION__,
+ targ_fn->launch->fn);
+}
- r = CUDA_CALL_NOCHECK (cuEventCreate, e, CU_EVENT_DISABLE_TIMING);
- if (r == CUDA_ERROR_LAUNCH_FAILED)
- GOMP_PLUGIN_fatal ("cuEventCreate error: %s %s\n", cuda_error (r),
- maybe_abort_msg);
- else if (r != CUDA_SUCCESS)
- GOMP_PLUGIN_fatal ("cuEventCreate error: %s", cuda_error (r));
+void * openacc_get_current_cuda_context (void);
- event_gc (true);
+static void
+goacc_profiling_acc_ev_alloc (struct goacc_thread *thr, void *dp, size_t s)
+{
+ acc_prof_info *prof_info = thr->prof_info;
+ acc_event_info data_event_info;
+ acc_api_info *api_info = thr->api_info;
- CUDA_CALL_ASSERT (cuEventRecord, *e, dev_str->stream);
+ prof_info->event_type = acc_ev_alloc;
- event_add (PTX_EVT_KNL, e, (void *)dev_str, 0);
- }
-#else
- r = CUDA_CALL_NOCHECK (cuCtxSynchronize, );
- if (r == CUDA_ERROR_LAUNCH_FAILED)
- GOMP_PLUGIN_fatal ("cuCtxSynchronize error: %s %s\n", cuda_error (r),
- maybe_abort_msg);
- else if (r != CUDA_SUCCESS)
- GOMP_PLUGIN_fatal ("cuCtxSynchronize error: %s", cuda_error (r));
-#endif
+ data_event_info.data_event.event_type = prof_info->event_type;
+ data_event_info.data_event.valid_bytes = _ACC_DATA_EVENT_INFO_VALID_BYTES;
+ data_event_info.data_event.parent_construct = acc_construct_parallel;
+ data_event_info.data_event.implicit = 1;
+ data_event_info.data_event.tool_info = NULL;
+ data_event_info.data_event.var_name = NULL;
+ data_event_info.data_event.bytes = s;
+ data_event_info.data_event.host_ptr = NULL;
+ data_event_info.data_event.device_ptr = dp;
- GOMP_PLUGIN_debug (0, " %s: kernel %s: finished\n", __FUNCTION__,
- targ_fn->launch->fn);
+ api_info->device_api = acc_device_api_cuda;
-#ifndef DISABLE_ASYNC
- if (async < acc_async_noval)
-#endif
- map_pop (dev_str);
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info, &data_event_info, api_info);
}
-void * openacc_get_current_cuda_context (void);
-
static void *
nvptx_alloc (size_t s)
{
CUdeviceptr d;
CUDA_CALL_ERET (NULL, cuMemAlloc, &d, s);
+ struct goacc_thread *thr = GOMP_PLUGIN_goacc_thread ();
+ bool profiling_p
+ = __builtin_expect (thr != NULL && thr->prof_info != NULL, false);
+ if (profiling_p)
+ goacc_profiling_acc_ev_alloc (thr, (void *) d, s);
+
return (void *) d;
}
-static bool
-nvptx_free (void *p)
+static void
+goacc_profiling_acc_ev_free (struct goacc_thread *thr, void *p)
{
- CUdeviceptr pb;
- size_t ps;
+ acc_prof_info *prof_info = thr->prof_info;
+ acc_event_info data_event_info;
+ acc_api_info *api_info = thr->api_info;
- CUDA_CALL (cuMemGetAddressRange, &pb, &ps, (CUdeviceptr) p);
- if ((CUdeviceptr) p != pb)
- {
- GOMP_PLUGIN_error ("invalid device address");
- return false;
- }
+ prof_info->event_type = acc_ev_free;
- CUDA_CALL (cuMemFree, (CUdeviceptr) p);
- return true;
-}
+ data_event_info.data_event.event_type = prof_info->event_type;
+ data_event_info.data_event.valid_bytes = _ACC_DATA_EVENT_INFO_VALID_BYTES;
+ data_event_info.data_event.parent_construct = acc_construct_parallel;
+ data_event_info.data_event.implicit = 1;
+ data_event_info.data_event.tool_info = NULL;
+ data_event_info.data_event.var_name = NULL;
+ data_event_info.data_event.bytes = -1;
+ data_event_info.data_event.host_ptr = NULL;
+ data_event_info.data_event.device_ptr = p;
+ api_info->device_api = acc_device_api_cuda;
+
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info, &data_event_info, api_info);
+}
static bool
-nvptx_host2dev (void *d, const void *h, size_t s)
+nvptx_free (void *p, struct ptx_device *ptx_dev)
{
- CUdeviceptr pb;
- size_t ps;
- struct nvptx_thread *nvthd = nvptx_thread ();
-
- if (!s)
- return true;
- if (!d)
+ /* Assume callback context if this is null. */
+ if (GOMP_PLUGIN_acc_thread () == NULL)
{
- GOMP_PLUGIN_error ("invalid device address");
- return false;
+ struct ptx_free_block *n
+ = GOMP_PLUGIN_malloc (sizeof (struct ptx_free_block));
+ n->ptr = p;
+ pthread_mutex_lock (&ptx_dev->free_blocks_lock);
+ n->next = ptx_dev->free_blocks;
+ ptx_dev->free_blocks = n;
+ pthread_mutex_unlock (&ptx_dev->free_blocks_lock);
+ return true;
}
- CUDA_CALL (cuMemGetAddressRange, &pb, &ps, (CUdeviceptr) d);
-
- if (!pb)
- {
- GOMP_PLUGIN_error ("invalid device address");
- return false;
- }
- if (!h)
- {
- GOMP_PLUGIN_error ("invalid host address");
- return false;
- }
- if (d == h)
- {
- GOMP_PLUGIN_error ("invalid host or device address");
- return false;
- }
- if ((void *)(d + s) > (void *)(pb + ps))
- {
- GOMP_PLUGIN_error ("invalid size");
- return false;
- }
-
-#ifndef DISABLE_ASYNC
- if (nvthd && nvthd->current_stream != nvthd->ptx_dev->null_stream)
- {
- CUevent *e = (CUevent *)GOMP_PLUGIN_malloc (sizeof (CUevent));
- CUDA_CALL (cuEventCreate, e, CU_EVENT_DISABLE_TIMING);
- event_gc (false);
- CUDA_CALL (cuMemcpyHtoDAsync,
- (CUdeviceptr) d, h, s, nvthd->current_stream->stream);
- CUDA_CALL (cuEventRecord, *e, nvthd->current_stream->stream);
- event_add (PTX_EVT_MEM, e, (void *)h, 0);
- }
- else
-#endif
- CUDA_CALL (cuMemcpyHtoD, (CUdeviceptr) d, h, s);
-
- return true;
-}
-
-static bool
-nvptx_dev2host (void *h, const void *d, size_t s)
-{
CUdeviceptr pb;
size_t ps;
- struct nvptx_thread *nvthd = nvptx_thread ();
- if (!s)
- return true;
- if (!d)
+ CUDA_CALL (cuMemGetAddressRange, &pb, &ps, (CUdeviceptr) p);
+ if ((CUdeviceptr) p != pb)
{
GOMP_PLUGIN_error ("invalid device address");
return false;
}
- CUDA_CALL (cuMemGetAddressRange, &pb, &ps, (CUdeviceptr) d);
-
- if (!pb)
- {
- GOMP_PLUGIN_error ("invalid device address");
- return false;
- }
- if (!h)
- {
- GOMP_PLUGIN_error ("invalid host address");
- return false;
- }
- if (d == h)
- {
- GOMP_PLUGIN_error ("invalid host or device address");
- return false;
- }
- if ((void *)(d + s) > (void *)(pb + ps))
- {
- GOMP_PLUGIN_error ("invalid size");
- return false;
- }
-
-#ifndef DISABLE_ASYNC
- if (nvthd && nvthd->current_stream != nvthd->ptx_dev->null_stream)
- {
- CUevent *e = (CUevent *) GOMP_PLUGIN_malloc (sizeof (CUevent));
- CUDA_CALL (cuEventCreate, e, CU_EVENT_DISABLE_TIMING);
- event_gc (false);
- CUDA_CALL (cuMemcpyDtoHAsync,
- h, (CUdeviceptr) d, s, nvthd->current_stream->stream);
- CUDA_CALL (cuEventRecord, *e, nvthd->current_stream->stream);
- event_add (PTX_EVT_MEM, e, (void *)h, 0);
- }
- else
-#endif
- CUDA_CALL (cuMemcpyDtoH, h, (CUdeviceptr) d, s);
+ CUDA_CALL (cuMemFree, (CUdeviceptr) p);
+ struct goacc_thread *thr = GOMP_PLUGIN_goacc_thread ();
+ bool profiling_p
+ = __builtin_expect (thr != NULL && thr->prof_info != NULL, false);
+ if (profiling_p)
+ goacc_profiling_acc_ev_free (thr, p);
return true;
}
-static void
-nvptx_set_async (int async)
-{
- struct nvptx_thread *nvthd = nvptx_thread ();
- nvthd->current_stream
- = select_stream_for_async (async, pthread_self (), true, NULL);
-}
-
-static int
-nvptx_async_test (int async)
-{
- CUresult r;
- struct ptx_stream *s;
-
- s = select_stream_for_async (async, pthread_self (), false, NULL);
-
- if (!s)
- GOMP_PLUGIN_fatal ("unknown async %d", async);
-
- r = CUDA_CALL_NOCHECK (cuStreamQuery, s->stream);
- if (r == CUDA_SUCCESS)
- {
- /* The oacc-parallel.c:goacc_wait function calls this hook to determine
- whether all work has completed on this stream, and if so omits the call
- to the wait hook. If that happens, event_gc might not get called
- (which prevents variables from getting unmapped and their associated
- device storage freed), so call it here. */
- event_gc (true);
- return 1;
- }
- else if (r == CUDA_ERROR_NOT_READY)
- return 0;
-
- GOMP_PLUGIN_fatal ("cuStreamQuery error: %s", cuda_error (r));
-
- return 0;
-}
-
-static int
-nvptx_async_test_all (void)
-{
- struct ptx_stream *s;
- pthread_t self = pthread_self ();
- struct nvptx_thread *nvthd = nvptx_thread ();
-
- pthread_mutex_lock (&nvthd->ptx_dev->stream_lock);
-
- for (s = nvthd->ptx_dev->active_streams; s != NULL; s = s->next)
- {
- if ((s->multithreaded || pthread_equal (s->host_thread, self))
- && CUDA_CALL_NOCHECK (cuStreamQuery,
- s->stream) == CUDA_ERROR_NOT_READY)
- {
- pthread_mutex_unlock (&nvthd->ptx_dev->stream_lock);
- return 0;
- }
- }
-
- pthread_mutex_unlock (&nvthd->ptx_dev->stream_lock);
-
- event_gc (true);
-
- return 1;
-}
-
-static void
-nvptx_wait (int async)
-{
- struct ptx_stream *s;
-
- s = select_stream_for_async (async, pthread_self (), false, NULL);
- if (!s)
- GOMP_PLUGIN_fatal ("unknown async %d", async);
-
- CUDA_CALL_ASSERT (cuStreamSynchronize, s->stream);
-
- event_gc (true);
-}
-
-static void
-nvptx_wait_async (int async1, int async2)
-{
- CUevent *e;
- struct ptx_stream *s1, *s2;
- pthread_t self = pthread_self ();
-
- /* The stream that is waiting (rather than being waited for) doesn't
- necessarily have to exist already. */
- s2 = select_stream_for_async (async2, self, true, NULL);
-
- s1 = select_stream_for_async (async1, self, false, NULL);
- if (!s1)
- GOMP_PLUGIN_fatal ("invalid async 1\n");
-
- if (s1 == s2)
- GOMP_PLUGIN_fatal ("identical parameters");
-
- e = (CUevent *) GOMP_PLUGIN_malloc (sizeof (CUevent));
-
- CUDA_CALL_ASSERT (cuEventCreate, e, CU_EVENT_DISABLE_TIMING);
-
- event_gc (true);
-
- CUDA_CALL_ASSERT (cuEventRecord, *e, s1->stream);
-
- event_add (PTX_EVT_SYNC, e, NULL, 0);
-
- CUDA_CALL_ASSERT (cuStreamWaitEvent, s2->stream, *e, 0);
-}
-
-static void
-nvptx_wait_all (void)
-{
- CUresult r;
- struct ptx_stream *s;
- pthread_t self = pthread_self ();
- struct nvptx_thread *nvthd = nvptx_thread ();
-
- pthread_mutex_lock (&nvthd->ptx_dev->stream_lock);
-
- /* Wait for active streams initiated by this thread (or by multiple threads)
- to complete. */
- for (s = nvthd->ptx_dev->active_streams; s != NULL; s = s->next)
- {
- if (s->multithreaded || pthread_equal (s->host_thread, self))
- {
- r = CUDA_CALL_NOCHECK (cuStreamQuery, s->stream);
- if (r == CUDA_SUCCESS)
- continue;
- else if (r != CUDA_ERROR_NOT_READY)
- GOMP_PLUGIN_fatal ("cuStreamQuery error: %s", cuda_error (r));
-
- CUDA_CALL_ASSERT (cuStreamSynchronize, s->stream);
- }
- }
-
- pthread_mutex_unlock (&nvthd->ptx_dev->stream_lock);
-
- event_gc (true);
-}
-
-static void
-nvptx_wait_all_async (int async)
-{
- struct ptx_stream *waiting_stream, *other_stream;
- CUevent *e;
- struct nvptx_thread *nvthd = nvptx_thread ();
- pthread_t self = pthread_self ();
-
- /* The stream doing the waiting. This could be the first mention of the
- stream, so create it if necessary. */
- waiting_stream
- = select_stream_for_async (async, pthread_self (), true, NULL);
-
- /* Launches on the null stream already block on other streams in the
- context. */
- if (!waiting_stream || waiting_stream == nvthd->ptx_dev->null_stream)
- return;
-
- event_gc (true);
-
- pthread_mutex_lock (&nvthd->ptx_dev->stream_lock);
-
- for (other_stream = nvthd->ptx_dev->active_streams;
- other_stream != NULL;
- other_stream = other_stream->next)
- {
- if (!other_stream->multithreaded
- && !pthread_equal (other_stream->host_thread, self))
- continue;
-
- e = (CUevent *) GOMP_PLUGIN_malloc (sizeof (CUevent));
-
- CUDA_CALL_ASSERT (cuEventCreate, e, CU_EVENT_DISABLE_TIMING);
-
- /* Record an event on the waited-for stream. */
- CUDA_CALL_ASSERT (cuEventRecord, *e, other_stream->stream);
-
- event_add (PTX_EVT_SYNC, e, NULL, 0);
-
- CUDA_CALL_ASSERT (cuStreamWaitEvent, waiting_stream->stream, *e, 0);
- }
-
- pthread_mutex_unlock (&nvthd->ptx_dev->stream_lock);
-}
-
static void *
nvptx_get_current_cuda_device (void)
{
@@ -1633,69 +1078,6 @@ nvptx_get_current_cuda_context (void)
return nvthd->ptx_dev->ctx;
}
-static void *
-nvptx_get_cuda_stream (int async)
-{
- struct ptx_stream *s;
- struct nvptx_thread *nvthd = nvptx_thread ();
-
- if (!nvthd || !nvthd->ptx_dev)
- return NULL;
-
- s = select_stream_for_async (async, pthread_self (), false, NULL);
-
- return s ? s->stream : NULL;
-}
-
-static int
-nvptx_set_cuda_stream (int async, void *stream)
-{
- struct ptx_stream *oldstream;
- pthread_t self = pthread_self ();
- struct nvptx_thread *nvthd = nvptx_thread ();
-
- if (async < 0)
- GOMP_PLUGIN_fatal ("bad async %d", async);
-
- pthread_mutex_lock (&nvthd->ptx_dev->stream_lock);
-
- /* We have a list of active streams and an array mapping async values to
- entries of that list. We need to take "ownership" of the passed-in stream,
- and add it to our list, removing the previous entry also (if there was one)
- in order to prevent resource leaks. Note the potential for surprise
- here: maybe we should keep track of passed-in streams and leave it up to
- the user to tidy those up, but that doesn't work for stream handles
- returned from acc_get_cuda_stream above... */
-
- oldstream = select_stream_for_async (async, self, false, NULL);
-
- if (oldstream)
- {
- if (nvthd->ptx_dev->active_streams == oldstream)
- nvthd->ptx_dev->active_streams = nvthd->ptx_dev->active_streams->next;
- else
- {
- struct ptx_stream *s = nvthd->ptx_dev->active_streams;
- while (s->next != oldstream)
- s = s->next;
- s->next = s->next->next;
- }
-
- CUDA_CALL_ASSERT (cuStreamDestroy, oldstream->stream);
-
- if (!map_fini (oldstream))
- GOMP_PLUGIN_fatal ("error when freeing host memory");
-
- free (oldstream);
- }
-
- pthread_mutex_unlock (&nvthd->ptx_dev->stream_lock);
-
- (void) select_stream_for_async (async, self, true, (CUstream) stream);
-
- return 1;
-}
-
/* Plugin entry points. */
const char *
@@ -1764,6 +1146,12 @@ GOMP_OFFLOAD_fini_device (int n)
instantiated_devices--;
}
+ if (instantiated_devices == 0)
+ {
+ free (ptx_devices);
+ ptx_devices = NULL;
+ }
+
pthread_mutex_unlock (&ptx_dev_lock);
return true;
}
@@ -1929,6 +1317,23 @@ GOMP_OFFLOAD_alloc (int ord, size_t size)
{
if (!nvptx_attach_host_thread_to_device (ord))
return NULL;
+
+ struct ptx_device *ptx_dev = ptx_devices[ord];
+ struct ptx_free_block *blocks, *tmp;
+
+ pthread_mutex_lock (&ptx_dev->free_blocks_lock);
+ blocks = ptx_dev->free_blocks;
+ ptx_dev->free_blocks = NULL;
+ pthread_mutex_unlock (&ptx_dev->free_blocks_lock);
+
+ while (blocks)
+ {
+ tmp = blocks->next;
+ nvptx_free (blocks->ptr, ptx_dev);
+ free (blocks);
+ blocks = tmp;
+ }
+
return nvptx_alloc (size);
}
@@ -1936,93 +1341,174 @@ bool
GOMP_OFFLOAD_free (int ord, void *ptr)
{
return (nvptx_attach_host_thread_to_device (ord)
- && nvptx_free (ptr));
+ && nvptx_free (ptr, ptx_devices[ord]));
}
-bool
-GOMP_OFFLOAD_dev2host (int ord, void *dst, const void *src, size_t n)
+void
+GOMP_OFFLOAD_openacc_exec (void (*fn) (void *), size_t mapnum,
+ void **hostaddrs, void **devaddrs,
+ unsigned *dims, void *targ_mem_desc)
{
- return (nvptx_attach_host_thread_to_device (ord)
- && nvptx_dev2host (dst, src, n));
-}
+ GOMP_PLUGIN_debug (0, " %s: prepare mappings\n", __FUNCTION__);
-bool
-GOMP_OFFLOAD_host2dev (int ord, void *dst, const void *src, size_t n)
-{
- return (nvptx_attach_host_thread_to_device (ord)
- && nvptx_host2dev (dst, src, n));
-}
+ struct goacc_thread *thr = GOMP_PLUGIN_goacc_thread ();
+ acc_prof_info *prof_info = thr->prof_info;
+ acc_event_info data_event_info;
+ acc_api_info *api_info = thr->api_info;
+ bool profiling_p = __builtin_expect (prof_info != NULL, false);
-bool
-GOMP_OFFLOAD_dev2dev (int ord, void *dst, const void *src, size_t n)
-{
- struct ptx_device *ptx_dev = ptx_devices[ord];
- CUDA_CALL (cuMemcpyDtoDAsync, (CUdeviceptr) dst, (CUdeviceptr) src, n,
- ptx_dev->null_stream->stream);
- return true;
-}
+ void **hp = NULL;
+ CUdeviceptr dp = 0;
-void (*device_run) (int n, void *fn_ptr, void *vars) = NULL;
+ if (mapnum > 0)
+ {
+ size_t s = mapnum * sizeof (void *);
+ hp = alloca (s);
+ for (int i = 0; i < mapnum; i++)
+ hp[i] = (devaddrs[i] ? devaddrs[i] : hostaddrs[i]);
+ CUDA_CALL_ASSERT (cuMemAlloc, &dp, s);
+ if (profiling_p)
+ goacc_profiling_acc_ev_alloc (thr, (void *) dp, s);
+ }
-void
-GOMP_OFFLOAD_openacc_exec (void (*fn) (void *), size_t mapnum,
- void **hostaddrs, void **devaddrs,
- int async, unsigned *dims, void *targ_mem_desc)
-{
- nvptx_exec (fn, mapnum, hostaddrs, devaddrs, async, dims, targ_mem_desc);
-}
+ /* Copy the (device) pointers to arguments to the device (dp and hp might in
+ fact have the same value on a unified-memory system). */
+ if (mapnum > 0)
+ {
+ if (profiling_p)
+ {
+ prof_info->event_type = acc_ev_enqueue_upload_start;
+
+ data_event_info.data_event.event_type = prof_info->event_type;
+ data_event_info.data_event.valid_bytes
+ = _ACC_DATA_EVENT_INFO_VALID_BYTES;
+ data_event_info.data_event.parent_construct
+ = acc_construct_parallel;
+ data_event_info.data_event.implicit = 1; /* Always implicit. */
+ data_event_info.data_event.tool_info = NULL;
+ data_event_info.data_event.var_name = NULL;
+ data_event_info.data_event.bytes = mapnum * sizeof (void *);
+ data_event_info.data_event.host_ptr = hp;
+ data_event_info.data_event.device_ptr = (const void *) dp;
+
+ api_info->device_api = acc_device_api_cuda;
+
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info, &data_event_info,
+ api_info);
+ }
+ CUDA_CALL_ASSERT (cuMemcpyHtoD, dp, (void *) hp,
+ mapnum * sizeof (void *));
+ if (profiling_p)
+ {
+ prof_info->event_type = acc_ev_enqueue_upload_end;
+ data_event_info.data_event.event_type = prof_info->event_type;
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info, &data_event_info,
+ api_info);
+ }
+ }
-void
-GOMP_OFFLOAD_openacc_register_async_cleanup (void *targ_mem_desc, int async)
-{
- struct nvptx_thread *nvthd = nvptx_thread ();
- CUevent *e = (CUevent *) GOMP_PLUGIN_malloc (sizeof (CUevent));
+ nvptx_exec (fn, mapnum, hostaddrs, devaddrs, dims, targ_mem_desc,
+ dp, NULL);
- CUDA_CALL_ASSERT (cuEventCreate, e, CU_EVENT_DISABLE_TIMING);
- CUDA_CALL_ASSERT (cuEventRecord, *e, nvthd->current_stream->stream);
- event_add (PTX_EVT_ASYNC_CLEANUP, e, targ_mem_desc, async);
-}
+ CUresult r = CUDA_CALL_NOCHECK (cuStreamSynchronize, NULL);
+ const char *maybe_abort_msg = "(perhaps abort was called)";
+ if (r == CUDA_ERROR_LAUNCH_FAILED)
+ GOMP_PLUGIN_fatal ("cuStreamSynchronize error: %s %s\n", cuda_error (r),
+ maybe_abort_msg);
+ else if (r != CUDA_SUCCESS)
+ GOMP_PLUGIN_fatal ("cuStreamSynchronize error: %s", cuda_error (r));
-int
-GOMP_OFFLOAD_openacc_async_test (int async)
-{
- return nvptx_async_test (async);
+ CUDA_CALL_ASSERT (cuMemFree, dp);
+ if (profiling_p)
+ goacc_profiling_acc_ev_free (thr, (void *) dp);
}
-int
-GOMP_OFFLOAD_openacc_async_test_all (void)
+static void
+cuda_free_argmem (void *ptr)
{
- return nvptx_async_test_all ();
+ void **block = (void **) ptr;
+ nvptx_free (block[0], (struct ptx_device *) block[1]);
+ free (block);
}
void
-GOMP_OFFLOAD_openacc_async_wait (int async)
+GOMP_OFFLOAD_openacc_async_exec (void (*fn) (void *), size_t mapnum,
+ void **hostaddrs, void **devaddrs,
+ unsigned *dims, void *targ_mem_desc,
+ struct goacc_asyncqueue *aq)
{
- nvptx_wait (async);
-}
+ GOMP_PLUGIN_debug (0, " %s: prepare mappings\n", __FUNCTION__);
-void
-GOMP_OFFLOAD_openacc_async_wait_async (int async1, int async2)
-{
- nvptx_wait_async (async1, async2);
-}
+ struct goacc_thread *thr = GOMP_PLUGIN_goacc_thread ();
+ acc_prof_info *prof_info = thr->prof_info;
+ acc_event_info data_event_info;
+ acc_api_info *api_info = thr->api_info;
+ bool profiling_p = __builtin_expect (prof_info != NULL, false);
-void
-GOMP_OFFLOAD_openacc_async_wait_all (void)
-{
- nvptx_wait_all ();
-}
+ void **hp = NULL;
+ CUdeviceptr dp = 0;
+ void **block = NULL;
-void
-GOMP_OFFLOAD_openacc_async_wait_all_async (int async)
-{
- nvptx_wait_all_async (async);
-}
+ if (mapnum > 0)
+ {
+ size_t s = mapnum * sizeof (void *);
+ block = (void **) GOMP_PLUGIN_malloc (2 * sizeof (void *) + s);
+ hp = block + 2;
+ for (int i = 0; i < mapnum; i++)
+ hp[i] = (devaddrs[i] ? devaddrs[i] : hostaddrs[i]);
+ CUDA_CALL_ASSERT (cuMemAlloc, &dp, s);
+ if (profiling_p)
+ goacc_profiling_acc_ev_alloc (thr, (void *) dp, s);
+ }
-void
-GOMP_OFFLOAD_openacc_async_set_async (int async)
-{
- nvptx_set_async (async);
+ /* Copy the (device) pointers to arguments to the device (dp and hp might in
+ fact have the same value on a unified-memory system). */
+ if (mapnum > 0)
+ {
+ if (profiling_p)
+ {
+ prof_info->event_type = acc_ev_enqueue_upload_start;
+
+ data_event_info.data_event.event_type = prof_info->event_type;
+ data_event_info.data_event.valid_bytes
+ = _ACC_DATA_EVENT_INFO_VALID_BYTES;
+ data_event_info.data_event.parent_construct
+ = acc_construct_parallel;
+ data_event_info.data_event.implicit = 1; /* Always implicit. */
+ data_event_info.data_event.tool_info = NULL;
+ data_event_info.data_event.var_name = NULL;
+ data_event_info.data_event.bytes = mapnum * sizeof (void *);
+ data_event_info.data_event.host_ptr = hp;
+ data_event_info.data_event.device_ptr = (const void *) dp;
+
+ api_info->device_api = acc_device_api_cuda;
+
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info, &data_event_info,
+ api_info);
+ }
+
+ CUDA_CALL_ASSERT (cuMemcpyHtoDAsync, dp, (void *) hp,
+ mapnum * sizeof (void *), aq->cuda_stream);
+ block[0] = (void *) dp;
+
+ struct nvptx_thread *nvthd =
+ (struct nvptx_thread *) GOMP_PLUGIN_acc_thread ();
+ block[1] = (void *) nvthd->ptx_dev;
+
+ if (profiling_p)
+ {
+ prof_info->event_type = acc_ev_enqueue_upload_end;
+ data_event_info.data_event.event_type = prof_info->event_type;
+ GOMP_PLUGIN_goacc_profiling_dispatch (prof_info, &data_event_info,
+ api_info);
+ }
+ }
+
+ nvptx_exec (fn, mapnum, hostaddrs, devaddrs, dims, targ_mem_desc,
+ dp, aq->cuda_stream);
+
+ if (mapnum > 0)
+ GOMP_OFFLOAD_openacc_async_queue_callback (aq, cuda_free_argmem, block);
}
void *
@@ -2044,7 +1530,6 @@ GOMP_OFFLOAD_openacc_create_thread_data (int ord)
if (!thd_ctx)
CUDA_CALL_ASSERT (cuCtxPushCurrent, ptx_dev->ctx);
- nvthd->current_stream = ptx_dev->null_stream;
nvthd->ptx_dev = ptx_dev;
return (void *) nvthd;
@@ -2068,20 +1553,184 @@ GOMP_OFFLOAD_openacc_cuda_get_current_context (void)
return nvptx_get_current_cuda_context ();
}
-/* NOTE: This returns a CUstream, not a ptx_stream pointer. */
-
+/* This returns a CUstream. */
void *
-GOMP_OFFLOAD_openacc_cuda_get_stream (int async)
+GOMP_OFFLOAD_openacc_cuda_get_stream (struct goacc_asyncqueue *aq)
+{
+ return (void *) aq->cuda_stream;
+}
+
+/* This takes a CUstream. */
+int
+GOMP_OFFLOAD_openacc_cuda_set_stream (struct goacc_asyncqueue *aq, void *stream)
+{
+ if (aq->cuda_stream)
+ {
+ CUDA_CALL_ASSERT (cuStreamSynchronize, aq->cuda_stream);
+ CUDA_CALL_ASSERT (cuStreamDestroy, aq->cuda_stream);
+ }
+
+ aq->cuda_stream = (CUstream) stream;
+ return 1;
+}
+
+struct goacc_asyncqueue *
+GOMP_OFFLOAD_openacc_async_construct (int device __attribute__((unused)))
{
- return nvptx_get_cuda_stream (async);
+ CUstream stream = NULL;
+ CUDA_CALL_ERET (NULL, cuStreamCreate, &stream, CU_STREAM_DEFAULT);
+
+ struct goacc_asyncqueue *aq
+ = GOMP_PLUGIN_malloc (sizeof (struct goacc_asyncqueue));
+ aq->cuda_stream = stream;
+ return aq;
}
-/* NOTE: This takes a CUstream, not a ptx_stream pointer. */
+bool
+GOMP_OFFLOAD_openacc_async_destruct (struct goacc_asyncqueue *aq)
+{
+ CUDA_CALL_ERET (false, cuStreamDestroy, aq->cuda_stream);
+ free (aq);
+ return true;
+}
int
-GOMP_OFFLOAD_openacc_cuda_set_stream (int async, void *stream)
+GOMP_OFFLOAD_openacc_async_test (struct goacc_asyncqueue *aq)
+{
+ CUresult r = CUDA_CALL_NOCHECK (cuStreamQuery, aq->cuda_stream);
+ if (r == CUDA_SUCCESS)
+ return 1;
+ if (r == CUDA_ERROR_NOT_READY)
+ return 0;
+
+ GOMP_PLUGIN_error ("cuStreamQuery error: %s", cuda_error (r));
+ return -1;
+}
+
+bool
+GOMP_OFFLOAD_openacc_async_synchronize (struct goacc_asyncqueue *aq)
+{
+ CUDA_CALL_ERET (false, cuStreamSynchronize, aq->cuda_stream);
+ return true;
+}
+
+bool
+GOMP_OFFLOAD_openacc_async_serialize (struct goacc_asyncqueue *aq1,
+ struct goacc_asyncqueue *aq2)
+{
+ CUevent e;
+ CUDA_CALL_ERET (false, cuEventCreate, &e, CU_EVENT_DISABLE_TIMING);
+ CUDA_CALL_ERET (false, cuEventRecord, e, aq1->cuda_stream);
+ CUDA_CALL_ERET (false, cuStreamWaitEvent, aq2->cuda_stream, e, 0);
+ return true;
+}
+
+static void
+cuda_callback_wrapper (CUstream stream, CUresult res, void *ptr)
{
- return nvptx_set_cuda_stream (async, stream);
+ if (res != CUDA_SUCCESS)
+ GOMP_PLUGIN_fatal ("%s error: %s", __FUNCTION__, cuda_error (res));
+ struct nvptx_callback *cb = (struct nvptx_callback *) ptr;
+ cb->fn (cb->ptr);
+ free (ptr);
+}
+
+void
+GOMP_OFFLOAD_openacc_async_queue_callback (struct goacc_asyncqueue *aq,
+ void (*callback_fn)(void *),
+ void *userptr)
+{
+ struct nvptx_callback *b = GOMP_PLUGIN_malloc (sizeof (*b));
+ b->fn = callback_fn;
+ b->ptr = userptr;
+ b->aq = aq;
+ CUDA_CALL_ASSERT (cuStreamAddCallback, aq->cuda_stream,
+ cuda_callback_wrapper, (void *) b, 0);
+}
+
+static bool
+cuda_memcpy_sanity_check (const void *h, const void *d, size_t s)
+{
+ CUdeviceptr pb;
+ size_t ps;
+ if (!s)
+ return true;
+ if (!d)
+ {
+ GOMP_PLUGIN_error ("invalid device address");
+ return false;
+ }
+ CUDA_CALL (cuMemGetAddressRange, &pb, &ps, (CUdeviceptr) d);
+ if (!pb)
+ {
+ GOMP_PLUGIN_error ("invalid device address");
+ return false;
+ }
+ if (!h)
+ {
+ GOMP_PLUGIN_error ("invalid host address");
+ return false;
+ }
+ if (d == h)
+ {
+ GOMP_PLUGIN_error ("invalid host or device address");
+ return false;
+ }
+ if ((void *)(d + s) > (void *)(pb + ps))
+ {
+ GOMP_PLUGIN_error ("invalid size");
+ return false;
+ }
+ return true;
+}
+
+bool
+GOMP_OFFLOAD_host2dev (int ord, void *dst, const void *src, size_t n)
+{
+ if (!nvptx_attach_host_thread_to_device (ord)
+ || !cuda_memcpy_sanity_check (src, dst, n))
+ return false;
+ CUDA_CALL (cuMemcpyHtoD, (CUdeviceptr) dst, src, n);
+ return true;
+}
+
+bool
+GOMP_OFFLOAD_dev2host (int ord, void *dst, const void *src, size_t n)
+{
+ if (!nvptx_attach_host_thread_to_device (ord)
+ || !cuda_memcpy_sanity_check (dst, src, n))
+ return false;
+ CUDA_CALL (cuMemcpyDtoH, dst, (CUdeviceptr) src, n);
+ return true;
+}
+
+bool
+GOMP_OFFLOAD_dev2dev (int ord, void *dst, const void *src, size_t n)
+{
+ CUDA_CALL (cuMemcpyDtoDAsync, (CUdeviceptr) dst, (CUdeviceptr) src, n, NULL);
+ return true;
+}
+
+bool
+GOMP_OFFLOAD_openacc_async_host2dev (int ord, void *dst, const void *src,
+ size_t n, struct goacc_asyncqueue *aq)
+{
+ if (!nvptx_attach_host_thread_to_device (ord)
+ || !cuda_memcpy_sanity_check (src, dst, n))
+ return false;
+ CUDA_CALL (cuMemcpyHtoDAsync, (CUdeviceptr) dst, src, n, aq->cuda_stream);
+ return true;
+}
+
+bool
+GOMP_OFFLOAD_openacc_async_dev2host (int ord, void *dst, const void *src,
+ size_t n, struct goacc_asyncqueue *aq)
+{
+ if (!nvptx_attach_host_thread_to_device (ord)
+ || !cuda_memcpy_sanity_check (dst, src, n))
+ return false;
+ CUDA_CALL (cuMemcpyDtoHAsync, dst, (CUdeviceptr) src, n, aq->cuda_stream);
+ return true;
}
/* Adjust launch dimensions: pick good values for number of blocks and warps
@@ -2182,8 +1831,7 @@ GOMP_OFFLOAD_run (int ord, void *tgt_fn, void *tgt_vars, void **args)
CU_LAUNCH_PARAM_END
};
r = CUDA_CALL_NOCHECK (cuLaunchKernel, function, teams, 1, 1,
- 32, threads, 1, 0, ptx_dev->null_stream->stream,
- NULL, config);
+ 32, threads, 1, 0, NULL, NULL, config);
if (r != CUDA_SUCCESS)
GOMP_PLUGIN_fatal ("cuLaunchKernel error: %s", cuda_error (r));
diff --git a/libgomp/priority_queue.c b/libgomp/priority_queue.c
index dc96505c81a..94eeb7b2cc6 100644
--- a/libgomp/priority_queue.c
+++ b/libgomp/priority_queue.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Aldy Hernandez <aldyh@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/priority_queue.h b/libgomp/priority_queue.h
index 0b8225c8382..766c5e9b59e 100644
--- a/libgomp/priority_queue.h
+++ b/libgomp/priority_queue.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Aldy Hernandez <aldyh@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/sections.c b/libgomp/sections.c
index 65b53b45f73..887943670cc 100644
--- a/libgomp/sections.c
+++ b/libgomp/sections.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -26,8 +26,11 @@
/* This file handles the SECTIONS construct. */
#include "libgomp.h"
+#include <string.h>
+ialias_redirect (GOMP_taskgroup_reduction_register)
+
/* Initialize the given work share construct from the given arguments. */
static inline void
@@ -72,7 +75,7 @@ GOMP_sections_start (unsigned count)
struct gomp_thread *thr = gomp_thread ();
long s, e, ret;
- if (gomp_work_share_start (false))
+ if (gomp_work_share_start (0))
{
gomp_sections_init (thr->ts.work_share, count);
gomp_work_share_init_done ();
@@ -95,6 +98,80 @@ GOMP_sections_start (unsigned count)
return ret;
}
+unsigned
+GOMP_sections2_start (unsigned count, uintptr_t *reductions, void **mem)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ long s, e, ret;
+
+ if (reductions)
+ gomp_workshare_taskgroup_start ();
+ if (gomp_work_share_start (0))
+ {
+ gomp_sections_init (thr->ts.work_share, count);
+ if (reductions)
+ {
+ GOMP_taskgroup_reduction_register (reductions);
+ thr->task->taskgroup->workshare = true;
+ thr->ts.work_share->task_reductions = reductions;
+ }
+ if (mem)
+ {
+ uintptr_t size = (uintptr_t) *mem;
+#define INLINE_ORDERED_TEAM_IDS_OFF \
+ ((offsetof (struct gomp_work_share, inline_ordered_team_ids) \
+ + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
+ if (size > (sizeof (struct gomp_work_share)
+ - INLINE_ORDERED_TEAM_IDS_OFF))
+ *mem
+ = (void *) (thr->ts.work_share->ordered_team_ids
+ = gomp_malloc_cleared (size));
+ else
+ *mem = memset (((char *) thr->ts.work_share)
+ + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
+ }
+ gomp_work_share_init_done ();
+ }
+ else
+ {
+ if (reductions)
+ {
+ uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
+ gomp_workshare_task_reduction_register (reductions,
+ first_reductions);
+ }
+ if (mem)
+ {
+ if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+ & (__alignof__ (long long) - 1)) == 0)
+ *mem = (void *) thr->ts.work_share->ordered_team_ids;
+ else
+ {
+ uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
+ p += __alignof__ (long long) - 1;
+ p &= ~(__alignof__ (long long) - 1);
+ *mem = (void *) p;
+ }
+ }
+ }
+
+#ifdef HAVE_SYNC_BUILTINS
+ if (gomp_iter_dynamic_next (&s, &e))
+ ret = s;
+ else
+ ret = 0;
+#else
+ gomp_mutex_lock (&thr->ts.work_share->lock);
+ if (gomp_iter_dynamic_next_locked (&s, &e))
+ ret = s;
+ else
+ ret = 0;
+ gomp_mutex_unlock (&thr->ts.work_share->lock);
+#endif
+
+ return ret;
+}
+
/* This routine is called when the thread completes processing of the
section currently assigned to it. If the work-share construct is
bound directly to a parallel construct, then the construct may have
@@ -140,7 +217,7 @@ GOMP_parallel_sections_start (void (*fn) (void *), void *data,
num_threads = gomp_resolve_num_threads (num_threads, count);
team = gomp_new_team (num_threads);
gomp_sections_init (&team->work_shares[0], count);
- gomp_team_start (fn, data, num_threads, 0, team);
+ gomp_team_start (fn, data, num_threads, 0, team, NULL);
}
ialias_redirect (GOMP_parallel_end)
@@ -154,7 +231,7 @@ GOMP_parallel_sections (void (*fn) (void *), void *data,
num_threads = gomp_resolve_num_threads (num_threads, count);
team = gomp_new_team (num_threads);
gomp_sections_init (&team->work_shares[0], count);
- gomp_team_start (fn, data, num_threads, flags, team);
+ gomp_team_start (fn, data, num_threads, flags, team, NULL);
fn (data);
GOMP_parallel_end ();
}
diff --git a/libgomp/secure_getenv.h b/libgomp/secure_getenv.h
index 82b00aad71d..a11b23cee47 100644
--- a/libgomp/secure_getenv.h
+++ b/libgomp/secure_getenv.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2017-2019 Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/libgomp/single.c b/libgomp/single.c
index 24a7780ad93..4e1d894aa4a 100644
--- a/libgomp/single.c
+++ b/libgomp/single.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -47,7 +47,7 @@ GOMP_single_start (void)
return __sync_bool_compare_and_swap (&team->single_count, single_count,
single_count + 1L);
#else
- bool ret = gomp_work_share_start (false);
+ bool ret = gomp_work_share_start (0);
if (ret)
gomp_work_share_init_done ();
gomp_work_share_end_nowait ();
@@ -68,7 +68,7 @@ GOMP_single_copy_start (void)
bool first;
void *ret;
- first = gomp_work_share_start (false);
+ first = gomp_work_share_start (0);
if (first)
{
diff --git a/libgomp/splay-tree.c b/libgomp/splay-tree.c
index dce86b91038..fb12294021d 100644
--- a/libgomp/splay-tree.c
+++ b/libgomp/splay-tree.c
@@ -1,5 +1,5 @@
/* A splay-tree datatype.
- Copyright (C) 1998-2018 Free Software Foundation, Inc.
+ Copyright (C) 1998-2019 Free Software Foundation, Inc.
Contributed by Mark Mitchell (mark@markmitchell.com).
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/splay-tree.h b/libgomp/splay-tree.h
index 8743384b3bd..554e0c8704b 100644
--- a/libgomp/splay-tree.h
+++ b/libgomp/splay-tree.h
@@ -1,5 +1,5 @@
/* A splay-tree datatype.
- Copyright (C) 1998-2018 Free Software Foundation, Inc.
+ Copyright (C) 1998-2019 Free Software Foundation, Inc.
Contributed by Mark Mitchell (mark@markmitchell.com).
This file is part of the GNU Offloading and Multi Processing Library
diff --git a/libgomp/target.c b/libgomp/target.c
index dda041cdbef..84d6daa76ca 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2013-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -25,7 +25,6 @@
/* This file contains the support of offloading. */
-#include "config.h"
#include "libgomp.h"
#include "oacc-plugin.h"
#include "oacc-int.h"
@@ -45,6 +44,8 @@
#include "plugin-suffix.h"
#endif
+#define FIELD_TGT_EMPTY (~(size_t) 0)
+
static void gomp_target_init (void);
/* The whole initialization code for offloading plugins is only run one. */
@@ -177,19 +178,41 @@ gomp_device_copy (struct gomp_device_descr *devicep,
}
}
+static inline void
+goacc_device_copy_async (struct gomp_device_descr *devicep,
+ bool (*copy_func) (int, void *, const void *, size_t,
+ struct goacc_asyncqueue *),
+ const char *dst, void *dstaddr,
+ const char *src, const void *srcaddr,
+ size_t size, struct goacc_asyncqueue *aq)
+{
+ if (!copy_func (devicep->target_id, dstaddr, srcaddr, size, aq))
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ gomp_fatal ("Copying of %s object [%p..%p) to %s object [%p..%p) failed",
+ src, srcaddr, srcaddr + size, dst, dstaddr, dstaddr + size);
+ }
+}
+
/* Infrastructure for coalescing adjacent or nearly adjacent (in device addresses)
host to device memory transfers. */
+struct gomp_coalesce_chunk
+{
+ /* The starting and ending point of a coalesced chunk of memory. */
+ size_t start, end;
+};
+
struct gomp_coalesce_buf
{
/* Buffer into which gomp_copy_host2dev will memcpy data and from which
it will be copied to the device. */
void *buf;
struct target_mem_desc *tgt;
- /* Array with offsets, chunks[2 * i] is the starting offset and
- chunks[2 * i + 1] ending offset relative to tgt->tgt_start device address
+ /* Array with offsets, chunks[i].start is the starting offset and
+ chunks[i].end ending offset relative to tgt->tgt_start device address
of chunks which are to be copied to buf and later copied to device. */
- size_t *chunks;
+ struct gomp_coalesce_chunk *chunks;
/* Number of chunks in chunks array, or -1 if coalesce buffering should not
be performed. */
long chunk_cnt;
@@ -222,14 +245,14 @@ gomp_coalesce_buf_add (struct gomp_coalesce_buf *cbuf, size_t start, size_t len)
{
if (cbuf->chunk_cnt < 0)
return;
- if (start < cbuf->chunks[2 * cbuf->chunk_cnt - 1])
+ if (start < cbuf->chunks[cbuf->chunk_cnt - 1].end)
{
cbuf->chunk_cnt = -1;
return;
}
- if (start < cbuf->chunks[2 * cbuf->chunk_cnt - 1] + MAX_COALESCE_BUF_GAP)
+ if (start < cbuf->chunks[cbuf->chunk_cnt - 1].end + MAX_COALESCE_BUF_GAP)
{
- cbuf->chunks[2 * cbuf->chunk_cnt - 1] = start + len;
+ cbuf->chunks[cbuf->chunk_cnt - 1].end = start + len;
cbuf->use_cnt++;
return;
}
@@ -239,8 +262,8 @@ gomp_coalesce_buf_add (struct gomp_coalesce_buf *cbuf, size_t start, size_t len)
if (cbuf->use_cnt == 1)
cbuf->chunk_cnt--;
}
- cbuf->chunks[2 * cbuf->chunk_cnt] = start;
- cbuf->chunks[2 * cbuf->chunk_cnt + 1] = start + len;
+ cbuf->chunks[cbuf->chunk_cnt].start = start;
+ cbuf->chunks[cbuf->chunk_cnt].end = start + len;
cbuf->chunk_cnt++;
cbuf->use_cnt = 1;
}
@@ -263,28 +286,29 @@ gomp_to_device_kind_p (int kind)
}
}
-static void
+attribute_hidden void
gomp_copy_host2dev (struct gomp_device_descr *devicep,
+ struct goacc_asyncqueue *aq,
void *d, const void *h, size_t sz,
struct gomp_coalesce_buf *cbuf)
{
if (cbuf)
{
uintptr_t doff = (uintptr_t) d - cbuf->tgt->tgt_start;
- if (doff < cbuf->chunks[2 * cbuf->chunk_cnt - 1])
+ if (doff < cbuf->chunks[cbuf->chunk_cnt - 1].end)
{
long first = 0;
long last = cbuf->chunk_cnt - 1;
while (first <= last)
{
long middle = (first + last) >> 1;
- if (cbuf->chunks[2 * middle + 1] <= doff)
+ if (cbuf->chunks[middle].end <= doff)
first = middle + 1;
- else if (cbuf->chunks[2 * middle] <= doff)
+ else if (cbuf->chunks[middle].start <= doff)
{
- if (doff + sz > cbuf->chunks[2 * middle + 1])
+ if (doff + sz > cbuf->chunks[middle].end)
gomp_fatal ("internal libgomp cbuf error");
- memcpy ((char *) cbuf->buf + (doff - cbuf->chunks[0]),
+ memcpy ((char *) cbuf->buf + (doff - cbuf->chunks[0].start),
h, sz);
return;
}
@@ -293,14 +317,23 @@ gomp_copy_host2dev (struct gomp_device_descr *devicep,
}
}
}
- gomp_device_copy (devicep, devicep->host2dev_func, "dev", d, "host", h, sz);
+ if (__builtin_expect (aq != NULL, 0))
+ goacc_device_copy_async (devicep, devicep->openacc.async.host2dev_func,
+ "dev", d, "host", h, sz, aq);
+ else
+ gomp_device_copy (devicep, devicep->host2dev_func, "dev", d, "host", h, sz);
}
-static void
+attribute_hidden void
gomp_copy_dev2host (struct gomp_device_descr *devicep,
+ struct goacc_asyncqueue *aq,
void *h, const void *d, size_t sz)
{
- gomp_device_copy (devicep, devicep->dev2host_func, "host", h, "dev", d, sz);
+ if (__builtin_expect (aq != NULL, 0))
+ goacc_device_copy_async (devicep, devicep->openacc.async.dev2host_func,
+ "host", h, "dev", d, sz, aq);
+ else
+ gomp_device_copy (devicep, devicep->dev2host_func, "host", h, "dev", d, sz);
}
static void
@@ -318,7 +351,8 @@ gomp_free_device_memory (struct gomp_device_descr *devicep, void *devptr)
Helper function of gomp_map_vars. */
static inline void
-gomp_map_vars_existing (struct gomp_device_descr *devicep, splay_tree_key oldn,
+gomp_map_vars_existing (struct gomp_device_descr *devicep,
+ struct goacc_asyncqueue *aq, splay_tree_key oldn,
splay_tree_key newn, struct target_var_desc *tgt_var,
unsigned char kind, struct gomp_coalesce_buf *cbuf)
{
@@ -340,7 +374,7 @@ gomp_map_vars_existing (struct gomp_device_descr *devicep, splay_tree_key oldn,
}
if (GOMP_MAP_ALWAYS_TO_P (kind))
- gomp_copy_host2dev (devicep,
+ gomp_copy_host2dev (devicep, aq,
(void *) (oldn->tgt->tgt_start + oldn->tgt_offset
+ newn->host_start - oldn->host_start),
(void *) newn->host_start,
@@ -358,8 +392,8 @@ get_kind (bool short_mapkind, void *kinds, int idx)
}
static void
-gomp_map_pointer (struct target_mem_desc *tgt, uintptr_t host_ptr,
- uintptr_t target_offset, uintptr_t bias,
+gomp_map_pointer (struct target_mem_desc *tgt, struct goacc_asyncqueue *aq,
+ uintptr_t host_ptr, uintptr_t target_offset, uintptr_t bias,
struct gomp_coalesce_buf *cbuf)
{
struct gomp_device_descr *devicep = tgt->device_descr;
@@ -370,7 +404,7 @@ gomp_map_pointer (struct target_mem_desc *tgt, uintptr_t host_ptr,
if (cur_node.host_start == (uintptr_t) NULL)
{
cur_node.tgt_offset = (uintptr_t) NULL;
- gomp_copy_host2dev (devicep,
+ gomp_copy_host2dev (devicep, aq,
(void *) (tgt->tgt_start + target_offset),
(void *) &cur_node.tgt_offset,
sizeof (void *), cbuf);
@@ -392,12 +426,13 @@ gomp_map_pointer (struct target_mem_desc *tgt, uintptr_t host_ptr,
array section. Now subtract bias to get what we want
to initialize the pointer with. */
cur_node.tgt_offset -= bias;
- gomp_copy_host2dev (devicep, (void *) (tgt->tgt_start + target_offset),
+ gomp_copy_host2dev (devicep, aq, (void *) (tgt->tgt_start + target_offset),
(void *) &cur_node.tgt_offset, sizeof (void *), cbuf);
}
static void
-gomp_map_fields_existing (struct target_mem_desc *tgt, splay_tree_key n,
+gomp_map_fields_existing (struct target_mem_desc *tgt,
+ struct goacc_asyncqueue *aq, splay_tree_key n,
size_t first, size_t i, void **hostaddrs,
size_t *sizes, void *kinds,
struct gomp_coalesce_buf *cbuf)
@@ -417,7 +452,7 @@ gomp_map_fields_existing (struct target_mem_desc *tgt, splay_tree_key n,
&& n2->tgt == n->tgt
&& n2->host_start - n->host_start == n2->tgt_offset - n->tgt_offset)
{
- gomp_map_vars_existing (devicep, n2, &cur_node,
+ gomp_map_vars_existing (devicep, aq, n2, &cur_node,
&tgt->list[i], kind & typemask, cbuf);
return;
}
@@ -433,8 +468,8 @@ gomp_map_fields_existing (struct target_mem_desc *tgt, splay_tree_key n,
&& n2->host_start - n->host_start
== n2->tgt_offset - n->tgt_offset)
{
- gomp_map_vars_existing (devicep, n2, &cur_node, &tgt->list[i],
- kind & typemask, cbuf);
+ gomp_map_vars_existing (devicep, aq, n2, &cur_node,
+ &tgt->list[i], kind & typemask, cbuf);
return;
}
}
@@ -445,7 +480,7 @@ gomp_map_fields_existing (struct target_mem_desc *tgt, splay_tree_key n,
&& n2->tgt == n->tgt
&& n2->host_start - n->host_start == n2->tgt_offset - n->tgt_offset)
{
- gomp_map_vars_existing (devicep, n2, &cur_node, &tgt->list[i],
+ gomp_map_vars_existing (devicep, aq, n2, &cur_node, &tgt->list[i],
kind & typemask, cbuf);
return;
}
@@ -464,23 +499,33 @@ gomp_map_val (struct target_mem_desc *tgt, void **hostaddrs, size_t i)
return tgt->list[i].key->tgt->tgt_start
+ tgt->list[i].key->tgt_offset
+ tgt->list[i].offset;
- if (tgt->list[i].offset == ~(uintptr_t) 0)
- return (uintptr_t) hostaddrs[i];
- if (tgt->list[i].offset == ~(uintptr_t) 1)
- return 0;
- if (tgt->list[i].offset == ~(uintptr_t) 2)
- return tgt->list[i + 1].key->tgt->tgt_start
- + tgt->list[i + 1].key->tgt_offset
- + tgt->list[i + 1].offset
- + (uintptr_t) hostaddrs[i]
- - (uintptr_t) hostaddrs[i + 1];
- return tgt->tgt_start + tgt->list[i].offset;
+
+ switch (tgt->list[i].offset)
+ {
+ case OFFSET_INLINED:
+ return (uintptr_t) hostaddrs[i];
+
+ case OFFSET_POINTER:
+ return 0;
+
+ case OFFSET_STRUCT:
+ return tgt->list[i + 1].key->tgt->tgt_start
+ + tgt->list[i + 1].key->tgt_offset
+ + tgt->list[i + 1].offset
+ + (uintptr_t) hostaddrs[i]
+ - (uintptr_t) hostaddrs[i + 1];
+
+ default:
+ return tgt->tgt_start + tgt->list[i].offset;
+ }
}
-attribute_hidden struct target_mem_desc *
-gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
- void **hostaddrs, void **devaddrs, size_t *sizes, void *kinds,
- bool short_mapkind, enum gomp_map_vars_kind pragma_kind)
+static inline __attribute__((always_inline)) struct target_mem_desc *
+gomp_map_vars_internal (struct gomp_device_descr *devicep,
+ struct goacc_asyncqueue *aq, size_t mapnum,
+ void **hostaddrs, void **devaddrs, size_t *sizes,
+ void *kinds, bool short_mapkind,
+ enum gomp_map_vars_kind pragma_kind)
{
size_t i, tgt_align, tgt_size, not_found_cnt = 0;
bool has_firstprivate = false;
@@ -510,8 +555,8 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
cbuf.buf = NULL;
if (mapnum > 1 || pragma_kind == GOMP_MAP_VARS_TARGET)
{
- cbuf.chunks
- = (size_t *) gomp_alloca ((2 * mapnum + 2) * sizeof (size_t));
+ size_t chunks_size = (mapnum + 1) * sizeof (struct gomp_coalesce_chunk);
+ cbuf.chunks = (struct gomp_coalesce_chunk *) gomp_alloca (chunks_size);
cbuf.chunk_cnt = 0;
}
if (pragma_kind == GOMP_MAP_VARS_TARGET)
@@ -521,8 +566,8 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
tgt_size = mapnum * sizeof (void *);
cbuf.chunk_cnt = 1;
cbuf.use_cnt = 1 + (mapnum > 1);
- cbuf.chunks[0] = 0;
- cbuf.chunks[1] = tgt_size;
+ cbuf.chunks[0].start = 0;
+ cbuf.chunks[0].end = tgt_size;
}
gomp_mutex_lock (&devicep->lock);
@@ -540,25 +585,41 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
|| (kind & typemask) == GOMP_MAP_FIRSTPRIVATE_INT)
{
tgt->list[i].key = NULL;
- tgt->list[i].offset = ~(uintptr_t) 0;
+ tgt->list[i].offset = OFFSET_INLINED;
continue;
}
else if ((kind & typemask) == GOMP_MAP_USE_DEVICE_PTR)
{
- cur_node.host_start = (uintptr_t) hostaddrs[i];
- cur_node.host_end = cur_node.host_start;
- splay_tree_key n = gomp_map_lookup (mem_map, &cur_node);
- if (n == NULL)
+ tgt->list[i].key = NULL;
+ if (!not_found_cnt)
{
- gomp_mutex_unlock (&devicep->lock);
- gomp_fatal ("use_device_ptr pointer wasn't mapped");
+ /* In OpenMP < 5.0 and OpenACC the mapping has to be done
+ on a separate construct prior to using use_device_{addr,ptr}.
+ In OpenMP 5.0, map directives need to be ordered by the
+ middle-end before the use_device_* clauses. If
+ !not_found_cnt, all mappings requested (if any) are already
+ mapped, so use_device_{addr,ptr} can be resolved right away.
+ Otherwise, if not_found_cnt, gomp_map_lookup might fail
+ now but would succeed after performing the mappings in the
+ following loop. We can't defer this always to the second
+ loop, because it is not even invoked when !not_found_cnt
+ after the first loop. */
+ cur_node.host_start = (uintptr_t) hostaddrs[i];
+ cur_node.host_end = cur_node.host_start;
+ splay_tree_key n = gomp_map_lookup (mem_map, &cur_node);
+ if (n == NULL)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ gomp_fatal ("use_device_ptr pointer wasn't mapped");
+ }
+ cur_node.host_start -= n->host_start;
+ hostaddrs[i]
+ = (void *) (n->tgt->tgt_start + n->tgt_offset
+ + cur_node.host_start);
+ tgt->list[i].offset = ~(uintptr_t) 0;
}
- cur_node.host_start -= n->host_start;
- hostaddrs[i]
- = (void *) (n->tgt->tgt_start + n->tgt_offset
- + cur_node.host_start);
- tgt->list[i].key = NULL;
- tgt->list[i].offset = ~(uintptr_t) 0;
+ else
+ tgt->list[i].offset = 0;
continue;
}
else if ((kind & typemask) == GOMP_MAP_STRUCT)
@@ -569,7 +630,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
cur_node.host_end = (uintptr_t) hostaddrs[last]
+ sizes[last];
tgt->list[i].key = NULL;
- tgt->list[i].offset = ~(uintptr_t) 2;
+ tgt->list[i].offset = OFFSET_STRUCT;
splay_tree_key n = splay_tree_lookup (mem_map, &cur_node);
if (n == NULL)
{
@@ -594,7 +655,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
continue;
}
for (i = first; i <= last; i++)
- gomp_map_fields_existing (tgt, n, first, i, hostaddrs,
+ gomp_map_fields_existing (tgt, aq, n, first, i, hostaddrs,
sizes, kinds, NULL);
i--;
continue;
@@ -602,7 +663,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
else if ((kind & typemask) == GOMP_MAP_ALWAYS_POINTER)
{
tgt->list[i].key = NULL;
- tgt->list[i].offset = ~(uintptr_t) 1;
+ tgt->list[i].offset = OFFSET_POINTER;
has_firstprivate = true;
continue;
}
@@ -632,14 +693,14 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
if (!n)
{
tgt->list[i].key = NULL;
- tgt->list[i].offset = ~(uintptr_t) 1;
+ tgt->list[i].offset = OFFSET_POINTER;
continue;
}
}
else
n = splay_tree_lookup (mem_map, &cur_node);
if (n && n->refcount != REFCOUNT_LINK)
- gomp_map_vars_existing (devicep, n, &cur_node, &tgt->list[i],
+ gomp_map_vars_existing (devicep, aq, n, &cur_node, &tgt->list[i],
kind & typemask, NULL);
else
{
@@ -707,7 +768,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
if (cbuf.chunk_cnt > 0)
{
cbuf.buf
- = malloc (cbuf.chunks[2 * cbuf.chunk_cnt - 1] - cbuf.chunks[0]);
+ = malloc (cbuf.chunks[cbuf.chunk_cnt - 1].end - cbuf.chunks[0].start);
if (cbuf.buf)
{
cbuf.tgt = tgt;
@@ -750,15 +811,32 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
tgt_size = (tgt_size + align - 1) & ~(align - 1);
tgt->list[i].offset = tgt_size;
len = sizes[i];
- gomp_copy_host2dev (devicep,
+ gomp_copy_host2dev (devicep, aq,
(void *) (tgt->tgt_start + tgt_size),
(void *) hostaddrs[i], len, cbufp);
tgt_size += len;
continue;
case GOMP_MAP_FIRSTPRIVATE_INT:
- case GOMP_MAP_USE_DEVICE_PTR:
case GOMP_MAP_ZERO_LEN_ARRAY_SECTION:
continue;
+ case GOMP_MAP_USE_DEVICE_PTR:
+ if (tgt->list[i].offset == 0)
+ {
+ cur_node.host_start = (uintptr_t) hostaddrs[i];
+ cur_node.host_end = cur_node.host_start;
+ n = gomp_map_lookup (mem_map, &cur_node);
+ if (n == NULL)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ gomp_fatal ("use_device_ptr pointer wasn't mapped");
+ }
+ cur_node.host_start -= n->host_start;
+ hostaddrs[i]
+ = (void *) (n->tgt->tgt_start + n->tgt_offset
+ + cur_node.host_start);
+ tgt->list[i].offset = ~(uintptr_t) 0;
+ }
+ continue;
case GOMP_MAP_STRUCT:
first = i + 1;
last = i + sizes[i];
@@ -784,7 +862,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
continue;
}
for (i = first; i <= last; i++)
- gomp_map_fields_existing (tgt, n, first, i, hostaddrs,
+ gomp_map_fields_existing (tgt, aq, n, first, i, hostaddrs,
sizes, kinds, cbufp);
i--;
continue;
@@ -804,7 +882,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
cur_node.tgt_offset = gomp_map_val (tgt, hostaddrs, i - 1);
if (cur_node.tgt_offset)
cur_node.tgt_offset -= sizes[i];
- gomp_copy_host2dev (devicep,
+ gomp_copy_host2dev (devicep, aq,
(void *) (n->tgt->tgt_start
+ n->tgt_offset
+ cur_node.host_start
@@ -825,7 +903,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
k->host_end = k->host_start + sizeof (void *);
splay_tree_key n = splay_tree_lookup (mem_map, k);
if (n && n->refcount != REFCOUNT_LINK)
- gomp_map_vars_existing (devicep, n, k, &tgt->list[i],
+ gomp_map_vars_existing (devicep, aq, n, k, &tgt->list[i],
kind & typemask, cbufp);
else
{
@@ -840,12 +918,12 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
size_t align = (size_t) 1 << (kind >> rshift);
tgt->list[i].key = k;
k->tgt = tgt;
- if (field_tgt_clear != ~(size_t) 0)
+ if (field_tgt_clear != FIELD_TGT_EMPTY)
{
k->tgt_offset = k->host_start - field_tgt_base
+ field_tgt_offset;
if (i == field_tgt_clear)
- field_tgt_clear = ~(size_t) 0;
+ field_tgt_clear = FIELD_TGT_EMPTY;
}
else
{
@@ -878,18 +956,19 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
case GOMP_MAP_FORCE_TOFROM:
case GOMP_MAP_ALWAYS_TO:
case GOMP_MAP_ALWAYS_TOFROM:
- gomp_copy_host2dev (devicep,
+ gomp_copy_host2dev (devicep, aq,
(void *) (tgt->tgt_start
+ k->tgt_offset),
(void *) k->host_start,
k->host_end - k->host_start, cbufp);
break;
case GOMP_MAP_POINTER:
- gomp_map_pointer (tgt, (uintptr_t) *(void **) k->host_start,
+ gomp_map_pointer (tgt, aq,
+ (uintptr_t) *(void **) k->host_start,
k->tgt_offset, sizes[i], cbufp);
break;
case GOMP_MAP_TO_PSET:
- gomp_copy_host2dev (devicep,
+ gomp_copy_host2dev (devicep, aq,
(void *) (tgt->tgt_start
+ k->tgt_offset),
(void *) k->host_start,
@@ -911,7 +990,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
tgt->list[j].always_copy_from = false;
if (k->refcount != REFCOUNT_INFINITY)
k->refcount++;
- gomp_map_pointer (tgt,
+ gomp_map_pointer (tgt, aq,
(uintptr_t) *(void **) hostaddrs[j],
k->tgt_offset
+ ((uintptr_t) hostaddrs[j]
@@ -940,7 +1019,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
break;
case GOMP_MAP_FORCE_DEVICEPTR:
assert (k->host_end - k->host_start == sizeof (void *));
- gomp_copy_host2dev (devicep,
+ gomp_copy_host2dev (devicep, aq,
(void *) (tgt->tgt_start
+ k->tgt_offset),
(void *) k->host_start,
@@ -957,9 +1036,10 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
/* Set link pointer on target to the device address of the
mapped object. */
void *tgt_addr = (void *) (tgt->tgt_start + k->tgt_offset);
- devicep->host2dev_func (devicep->target_id,
- (void *) n->tgt_offset,
- &tgt_addr, sizeof (void *));
+ /* We intentionally do not use coalescing here, as it's not
+ data allocated by the current call to this function. */
+ gomp_copy_host2dev (devicep, aq, (void *) n->tgt_offset,
+ &tgt_addr, sizeof (void *), NULL);
}
array++;
}
@@ -971,7 +1051,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
for (i = 0; i < mapnum; i++)
{
cur_node.tgt_offset = gomp_map_val (tgt, hostaddrs, i);
- gomp_copy_host2dev (devicep,
+ gomp_copy_host2dev (devicep, aq,
(void *) (tgt->tgt_start + i * sizeof (void *)),
(void *) &cur_node.tgt_offset, sizeof (void *),
cbufp);
@@ -982,10 +1062,14 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
{
long c = 0;
for (c = 0; c < cbuf.chunk_cnt; ++c)
- gomp_copy_host2dev (devicep, (void *) (tgt->tgt_start + cbuf.chunks[2 * c]),
- (char *) cbuf.buf + (cbuf.chunks[2 * c] - cbuf.chunks[0]),
- cbuf.chunks[2 * c + 1] - cbuf.chunks[2 * c], NULL);
+ gomp_copy_host2dev (devicep, aq,
+ (void *) (tgt->tgt_start + cbuf.chunks[c].start),
+ (char *) cbuf.buf + (cbuf.chunks[c].start
+ - cbuf.chunks[0].start),
+ cbuf.chunks[c].end - cbuf.chunks[c].start, NULL);
free (cbuf.buf);
+ cbuf.buf = NULL;
+ cbufp = NULL;
}
/* If the variable from "omp target enter data" map-list was already mapped,
@@ -1001,7 +1085,27 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
return tgt;
}
-static void
+attribute_hidden struct target_mem_desc *
+gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
+ void **hostaddrs, void **devaddrs, size_t *sizes, void *kinds,
+ bool short_mapkind, enum gomp_map_vars_kind pragma_kind)
+{
+ return gomp_map_vars_internal (devicep, NULL, mapnum, hostaddrs, devaddrs,
+ sizes, kinds, short_mapkind, pragma_kind);
+}
+
+attribute_hidden struct target_mem_desc *
+gomp_map_vars_async (struct gomp_device_descr *devicep,
+ struct goacc_asyncqueue *aq, size_t mapnum,
+ void **hostaddrs, void **devaddrs, size_t *sizes,
+ void *kinds, bool short_mapkind,
+ enum gomp_map_vars_kind pragma_kind)
+{
+ return gomp_map_vars_internal (devicep, aq, mapnum, hostaddrs, devaddrs,
+ sizes, kinds, short_mapkind, pragma_kind);
+}
+
+attribute_hidden void
gomp_unmap_tgt (struct target_mem_desc *tgt)
{
/* Deallocate on target the tgt->tgt_start .. tgt->tgt_end region. */
@@ -1029,12 +1133,24 @@ gomp_remove_var (struct gomp_device_descr *devicep, splay_tree_key k)
return is_tgt_unmapped;
}
+static void
+gomp_unref_tgt (void *ptr)
+{
+ struct target_mem_desc *tgt = (struct target_mem_desc *) ptr;
+
+ if (tgt->refcount > 1)
+ tgt->refcount--;
+ else
+ gomp_unmap_tgt (tgt);
+}
+
/* Unmap variables described by TGT. If DO_COPYFROM is true, copy relevant
variables back from device to host: if it is false, it is assumed that this
has been done already. */
-attribute_hidden void
-gomp_unmap_vars (struct target_mem_desc *tgt, bool do_copyfrom)
+static inline __attribute__((always_inline)) void
+gomp_unmap_vars_internal (struct target_mem_desc *tgt, bool do_copyfrom,
+ struct goacc_asyncqueue *aq)
{
struct gomp_device_descr *devicep = tgt->device_descr;
@@ -1071,7 +1187,7 @@ gomp_unmap_vars (struct target_mem_desc *tgt, bool do_copyfrom)
if ((do_unmap && do_copyfrom && tgt->list[i].copy_from)
|| tgt->list[i].always_copy_from)
- gomp_copy_dev2host (devicep,
+ gomp_copy_dev2host (devicep, aq,
(void *) (k->host_start + tgt->list[i].offset),
(void *) (k->tgt->tgt_start + k->tgt_offset
+ tgt->list[i].offset),
@@ -1080,14 +1196,28 @@ gomp_unmap_vars (struct target_mem_desc *tgt, bool do_copyfrom)
gomp_remove_var (devicep, k);
}
- if (tgt->refcount > 1)
- tgt->refcount--;
+ if (aq)
+ devicep->openacc.async.queue_callback_func (aq, gomp_unref_tgt,
+ (void *) tgt);
else
- gomp_unmap_tgt (tgt);
+ gomp_unref_tgt ((void *) tgt);
gomp_mutex_unlock (&devicep->lock);
}
+attribute_hidden void
+gomp_unmap_vars (struct target_mem_desc *tgt, bool do_copyfrom)
+{
+ gomp_unmap_vars_internal (tgt, do_copyfrom, NULL);
+}
+
+attribute_hidden void
+gomp_unmap_vars_async (struct target_mem_desc *tgt, bool do_copyfrom,
+ struct goacc_asyncqueue *aq)
+{
+ gomp_unmap_vars_internal (tgt, do_copyfrom, aq);
+}
+
static void
gomp_update (struct gomp_device_descr *devicep, size_t mapnum, void **hostaddrs,
size_t *sizes, void *kinds, bool short_mapkind)
@@ -1137,9 +1267,10 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum, void **hostaddrs,
size_t size = cur_node.host_end - cur_node.host_start;
if (GOMP_MAP_COPY_TO_P (kind & typemask))
- gomp_copy_host2dev (devicep, devaddr, hostaddr, size, NULL);
+ gomp_copy_host2dev (devicep, NULL, devaddr, hostaddr, size,
+ NULL);
if (GOMP_MAP_COPY_FROM_P (kind & typemask))
- gomp_copy_dev2host (devicep, hostaddr, devaddr, size);
+ gomp_copy_dev2host (devicep, NULL, hostaddr, devaddr, size);
}
}
gomp_mutex_unlock (&devicep->lock);
@@ -1432,9 +1563,24 @@ gomp_init_device (struct gomp_device_descr *devicep)
false);
}
+ /* Initialize OpenACC asynchronous queues. */
+ goacc_init_asyncqueues (devicep);
+
devicep->state = GOMP_DEVICE_INITIALIZED;
}
+/* This function finalizes the target device, specified by DEVICEP. DEVICEP
+ must be locked on entry, and remains locked on return. */
+
+attribute_hidden bool
+gomp_fini_device (struct gomp_device_descr *devicep)
+{
+ bool ret = goacc_fini_asyncqueues (devicep);
+ ret &= devicep->fini_device_func (devicep->target_id);
+ devicep->state = GOMP_DEVICE_FINALIZED;
+ return ret;
+}
+
attribute_hidden void
gomp_unload_device (struct gomp_device_descr *devicep)
{
@@ -1854,11 +2000,20 @@ GOMP_target_update_ext (int device, size_t mapnum, void **hostaddrs,
struct gomp_team *team = thr->ts.team;
/* If parallel or taskgroup has been cancelled, don't start new
tasks. */
- if (team
- && (gomp_team_barrier_cancelled (&team->barrier)
- || (thr->task->taskgroup
- && thr->task->taskgroup->cancelled)))
- return;
+ if (__builtin_expect (gomp_cancel_var, 0) && team)
+ {
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ return;
+ if (thr->task->taskgroup)
+ {
+ if (thr->task->taskgroup->cancelled)
+ return;
+ if (thr->task->taskgroup->workshare
+ && thr->task->taskgroup->prev
+ && thr->task->taskgroup->prev->cancelled)
+ return;
+ }
+ }
gomp_task_maybe_wait_for_dependencies (depend);
}
@@ -1873,10 +2028,20 @@ GOMP_target_update_ext (int device, size_t mapnum, void **hostaddrs,
struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr->ts.team;
/* If parallel or taskgroup has been cancelled, don't start new tasks. */
- if (team
- && (gomp_team_barrier_cancelled (&team->barrier)
- || (thr->task->taskgroup && thr->task->taskgroup->cancelled)))
- return;
+ if (__builtin_expect (gomp_cancel_var, 0) && team)
+ {
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ return;
+ if (thr->task->taskgroup)
+ {
+ if (thr->task->taskgroup->cancelled)
+ return;
+ if (thr->task->taskgroup->workshare
+ && thr->task->taskgroup->prev
+ && thr->task->taskgroup->prev->cancelled)
+ return;
+ }
+ }
gomp_update (devicep, mapnum, hostaddrs, sizes, kinds, true);
}
@@ -1924,7 +2089,7 @@ gomp_exit_data (struct gomp_device_descr *devicep, size_t mapnum,
if ((kind == GOMP_MAP_FROM && k->refcount == 0)
|| kind == GOMP_MAP_ALWAYS_FROM)
- gomp_copy_dev2host (devicep, (void *) cur_node.host_start,
+ gomp_copy_dev2host (devicep, NULL, (void *) cur_node.host_start,
(void *) (k->tgt->tgt_start + k->tgt_offset
+ cur_node.host_start
- k->host_start),
@@ -1985,11 +2150,20 @@ GOMP_target_enter_exit_data (int device, size_t mapnum, void **hostaddrs,
struct gomp_team *team = thr->ts.team;
/* If parallel or taskgroup has been cancelled, don't start new
tasks. */
- if (team
- && (gomp_team_barrier_cancelled (&team->barrier)
- || (thr->task->taskgroup
- && thr->task->taskgroup->cancelled)))
- return;
+ if (__builtin_expect (gomp_cancel_var, 0) && team)
+ {
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ return;
+ if (thr->task->taskgroup)
+ {
+ if (thr->task->taskgroup->cancelled)
+ return;
+ if (thr->task->taskgroup->workshare
+ && thr->task->taskgroup->prev
+ && thr->task->taskgroup->prev->cancelled)
+ return;
+ }
+ }
gomp_task_maybe_wait_for_dependencies (depend);
}
@@ -2004,10 +2178,20 @@ GOMP_target_enter_exit_data (int device, size_t mapnum, void **hostaddrs,
struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr->ts.team;
/* If parallel or taskgroup has been cancelled, don't start new tasks. */
- if (team
- && (gomp_team_barrier_cancelled (&team->barrier)
- || (thr->task->taskgroup && thr->task->taskgroup->cancelled)))
- return;
+ if (__builtin_expect (gomp_cancel_var, 0) && team)
+ {
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ return;
+ if (thr->task->taskgroup)
+ {
+ if (thr->task->taskgroup->cancelled)
+ return;
+ if (thr->task->taskgroup->workshare
+ && thr->task->taskgroup->prev
+ && thr->task->taskgroup->prev->cancelled)
+ return;
+ }
+ }
size_t i;
if ((flags & GOMP_TARGET_FLAG_EXIT_DATA) == 0)
@@ -2164,7 +2348,7 @@ omp_target_free (void *device_ptr, int device_num)
}
int
-omp_target_is_present (void *ptr, int device_num)
+omp_target_is_present (const void *ptr, int device_num)
{
if (ptr == NULL)
return 1;
@@ -2196,8 +2380,9 @@ omp_target_is_present (void *ptr, int device_num)
}
int
-omp_target_memcpy (void *dst, void *src, size_t length, size_t dst_offset,
- size_t src_offset, int dst_device_num, int src_device_num)
+omp_target_memcpy (void *dst, const void *src, size_t length,
+ size_t dst_offset, size_t src_offset, int dst_device_num,
+ int src_device_num)
{
struct gomp_device_descr *dst_devicep = NULL, *src_devicep = NULL;
bool ret;
@@ -2264,7 +2449,7 @@ omp_target_memcpy (void *dst, void *src, size_t length, size_t dst_offset,
}
static int
-omp_target_memcpy_rect_worker (void *dst, void *src, size_t element_size,
+omp_target_memcpy_rect_worker (void *dst, const void *src, size_t element_size,
int num_dims, const size_t *volume,
const size_t *dst_offsets,
const size_t *src_offsets,
@@ -2286,21 +2471,25 @@ omp_target_memcpy_rect_worker (void *dst, void *src, size_t element_size,
return EINVAL;
if (dst_devicep == NULL && src_devicep == NULL)
{
- memcpy ((char *) dst + dst_off, (char *) src + src_off, length);
+ memcpy ((char *) dst + dst_off, (const char *) src + src_off,
+ length);
ret = 1;
}
else if (src_devicep == NULL)
ret = dst_devicep->host2dev_func (dst_devicep->target_id,
(char *) dst + dst_off,
- (char *) src + src_off, length);
+ (const char *) src + src_off,
+ length);
else if (dst_devicep == NULL)
ret = src_devicep->dev2host_func (src_devicep->target_id,
(char *) dst + dst_off,
- (char *) src + src_off, length);
+ (const char *) src + src_off,
+ length);
else if (src_devicep == dst_devicep)
ret = src_devicep->dev2dev_func (src_devicep->target_id,
(char *) dst + dst_off,
- (char *) src + src_off, length);
+ (const char *) src + src_off,
+ length);
else
ret = 0;
return ret ? 0 : EINVAL;
@@ -2321,7 +2510,7 @@ omp_target_memcpy_rect_worker (void *dst, void *src, size_t element_size,
for (j = 0; j < volume[0]; j++)
{
ret = omp_target_memcpy_rect_worker ((char *) dst + dst_off,
- (char *) src + src_off,
+ (const char *) src + src_off,
element_size, num_dims - 1,
volume + 1, dst_offsets + 1,
src_offsets + 1, dst_dimensions + 1,
@@ -2336,7 +2525,7 @@ omp_target_memcpy_rect_worker (void *dst, void *src, size_t element_size,
}
int
-omp_target_memcpy_rect (void *dst, void *src, size_t element_size,
+omp_target_memcpy_rect (void *dst, const void *src, size_t element_size,
int num_dims, const size_t *volume,
const size_t *dst_offsets,
const size_t *src_offsets,
@@ -2395,8 +2584,8 @@ omp_target_memcpy_rect (void *dst, void *src, size_t element_size,
}
int
-omp_target_associate_ptr (void *host_ptr, void *device_ptr, size_t size,
- size_t device_offset, int device_num)
+omp_target_associate_ptr (const void *host_ptr, const void *device_ptr,
+ size_t size, size_t device_offset, int device_num)
{
if (device_num == GOMP_DEVICE_HOST_FALLBACK)
return EINVAL;
@@ -2457,7 +2646,7 @@ omp_target_associate_ptr (void *host_ptr, void *device_ptr, size_t size,
}
int
-omp_target_disassociate_ptr (void *ptr, int device_num)
+omp_target_disassociate_ptr (const void *ptr, int device_num)
{
if (device_num == GOMP_DEVICE_HOST_FALLBACK)
return EINVAL;
@@ -2498,6 +2687,31 @@ omp_target_disassociate_ptr (void *ptr, int device_num)
return ret;
}
+int
+omp_pause_resource (omp_pause_resource_t kind, int device_num)
+{
+ (void) kind;
+ if (device_num == GOMP_DEVICE_HOST_FALLBACK)
+ return gomp_pause_host ();
+ if (device_num < 0 || device_num >= gomp_get_num_devices ())
+ return -1;
+ /* Do nothing for target devices for now. */
+ return 0;
+}
+
+int
+omp_pause_resource_all (omp_pause_resource_t kind)
+{
+ (void) kind;
+ if (gomp_pause_host ())
+ return -1;
+ /* Do nothing for target devices for now. */
+ return 0;
+}
+
+ialias (omp_pause_resource)
+ialias (omp_pause_resource_all)
+
#ifdef PLUGIN_SUPPORT
/* This function tries to load a plugin for DEVICE. Name of plugin is passed
@@ -2557,20 +2771,20 @@ gomp_load_plugin_for_device (struct gomp_device_descr *device,
if (device->capabilities & GOMP_OFFLOAD_CAP_OPENACC_200)
{
if (!DLSYM_OPT (openacc.exec, openacc_exec)
- || !DLSYM_OPT (openacc.register_async_cleanup,
- openacc_register_async_cleanup)
- || !DLSYM_OPT (openacc.async_test, openacc_async_test)
- || !DLSYM_OPT (openacc.async_test_all, openacc_async_test_all)
- || !DLSYM_OPT (openacc.async_wait, openacc_async_wait)
- || !DLSYM_OPT (openacc.async_wait_async, openacc_async_wait_async)
- || !DLSYM_OPT (openacc.async_wait_all, openacc_async_wait_all)
- || !DLSYM_OPT (openacc.async_wait_all_async,
- openacc_async_wait_all_async)
- || !DLSYM_OPT (openacc.async_set_async, openacc_async_set_async)
|| !DLSYM_OPT (openacc.create_thread_data,
openacc_create_thread_data)
|| !DLSYM_OPT (openacc.destroy_thread_data,
- openacc_destroy_thread_data))
+ openacc_destroy_thread_data)
+ || !DLSYM_OPT (openacc.async.construct, openacc_async_construct)
+ || !DLSYM_OPT (openacc.async.destruct, openacc_async_destruct)
+ || !DLSYM_OPT (openacc.async.test, openacc_async_test)
+ || !DLSYM_OPT (openacc.async.synchronize, openacc_async_synchronize)
+ || !DLSYM_OPT (openacc.async.serialize, openacc_async_serialize)
+ || !DLSYM_OPT (openacc.async.queue_callback,
+ openacc_async_queue_callback)
+ || !DLSYM_OPT (openacc.async.exec, openacc_async_exec)
+ || !DLSYM_OPT (openacc.async.dev2host, openacc_async_dev2host)
+ || !DLSYM_OPT (openacc.async.host2dev, openacc_async_host2dev))
{
/* Require all the OpenACC handlers if we have
GOMP_OFFLOAD_CAP_OPENACC_200. */
@@ -2621,19 +2835,16 @@ gomp_target_fini (void)
struct gomp_device_descr *devicep = &devices[i];
gomp_mutex_lock (&devicep->lock);
if (devicep->state == GOMP_DEVICE_INITIALIZED)
- {
- ret = devicep->fini_device_func (devicep->target_id);
- devicep->state = GOMP_DEVICE_FINALIZED;
- }
+ ret = gomp_fini_device (devicep);
gomp_mutex_unlock (&devicep->lock);
if (!ret)
gomp_fatal ("device finalization failed");
}
}
-/* This function initializes the runtime needed for offloading.
- It parses the list of offload targets and tries to load the plugins for
- these targets. On return, the variables NUM_DEVICES and NUM_DEVICES_OPENMP
+/* This function initializes the runtime for offloading.
+ It parses the list of offload plugins, and tries to load these.
+ On return, the variables NUM_DEVICES and NUM_DEVICES_OPENMP
will be set, and the array DEVICES initialized, containing descriptors for
corresponding devices, first the GOMP_OFFLOAD_CAP_OPENMP_400 ones, follows
by the others. */
@@ -2650,7 +2861,7 @@ gomp_target_init (void)
num_devices = 0;
devices = NULL;
- cur = OFFLOAD_TARGETS;
+ cur = OFFLOAD_PLUGINS;
if (*cur)
do
{
diff --git a/libgomp/task.c b/libgomp/task.c
index 80dcd902ab3..15177ac8824 100644
--- a/libgomp/task.c
+++ b/libgomp/task.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -166,21 +166,72 @@ gomp_task_handle_depend (struct gomp_task *task, struct gomp_task *parent,
void **depend)
{
size_t ndepend = (uintptr_t) depend[0];
- size_t nout = (uintptr_t) depend[1];
size_t i;
hash_entry_type ent;
+ if (ndepend)
+ {
+ /* depend[0] is total # */
+ size_t nout = (uintptr_t) depend[1]; /* # of out: and inout: */
+ /* ndepend - nout is # of in: */
+ for (i = 0; i < ndepend; i++)
+ {
+ task->depend[i].addr = depend[2 + i];
+ task->depend[i].is_in = i >= nout;
+ }
+ }
+ else
+ {
+ ndepend = (uintptr_t) depend[1]; /* total # */
+ size_t nout = (uintptr_t) depend[2]; /* # of out: and inout: */
+ size_t nmutexinoutset = (uintptr_t) depend[3]; /* # of mutexinoutset: */
+ /* For now we treat mutexinoutset like out, which is compliant, but
+ inefficient. */
+ size_t nin = (uintptr_t) depend[4]; /* # of in: */
+ /* ndepend - nout - nmutexinoutset - nin is # of depobjs */
+ size_t normal = nout + nmutexinoutset + nin;
+ size_t n = 0;
+ for (i = normal; i < ndepend; i++)
+ {
+ void **d = (void **) (uintptr_t) depend[5 + i];
+ switch ((uintptr_t) d[1])
+ {
+ case GOMP_DEPEND_OUT:
+ case GOMP_DEPEND_INOUT:
+ case GOMP_DEPEND_MUTEXINOUTSET:
+ break;
+ case GOMP_DEPEND_IN:
+ continue;
+ default:
+ gomp_fatal ("unknown omp_depend_t dependence type %d",
+ (int) (uintptr_t) d[1]);
+ }
+ task->depend[n].addr = d[0];
+ task->depend[n++].is_in = 0;
+ }
+ for (i = 0; i < normal; i++)
+ {
+ task->depend[n].addr = depend[5 + i];
+ task->depend[n++].is_in = i >= nout + nmutexinoutset;
+ }
+ for (i = normal; i < ndepend; i++)
+ {
+ void **d = (void **) (uintptr_t) depend[5 + i];
+ if ((uintptr_t) d[1] != GOMP_DEPEND_IN)
+ continue;
+ task->depend[n].addr = d[0];
+ task->depend[n++].is_in = 1;
+ }
+ }
task->depend_count = ndepend;
task->num_dependees = 0;
if (parent->depend_hash == NULL)
parent->depend_hash = htab_create (2 * ndepend > 12 ? 2 * ndepend : 12);
for (i = 0; i < ndepend; i++)
{
- task->depend[i].addr = depend[2 + i];
task->depend[i].next = NULL;
task->depend[i].prev = NULL;
task->depend[i].task = task;
- task->depend[i].is_in = i >= nout;
task->depend[i].redundant = false;
task->depend[i].redundant_out = false;
@@ -205,7 +256,7 @@ gomp_task_handle_depend (struct gomp_task *task, struct gomp_task *parent,
last = ent;
/* depend(in:...) doesn't depend on earlier depend(in:...). */
- if (i >= nout && ent->is_in)
+ if (task->depend[i].is_in && ent->is_in)
continue;
if (!ent->is_in)
@@ -280,9 +331,18 @@ gomp_task_handle_depend (struct gomp_task *task, struct gomp_task *parent,
then the task may be executed by any member of the team.
DEPEND is an array containing:
+ if depend[0] is non-zero, then:
depend[0]: number of depend elements.
- depend[1]: number of depend elements of type "out".
- depend[2..N+1]: address of [1..N]th depend element. */
+ depend[1]: number of depend elements of type "out/inout".
+ depend[2..N+1]: address of [1..N]th depend element.
+ otherwise, when depend[0] is zero, then:
+ depend[1]: number of depend elements.
+ depend[2]: number of depend elements of type "out/inout".
+ depend[3]: number of depend elements of type "mutexinoutset".
+ depend[4]: number of depend elements of type "in".
+ depend[5..4+depend[2]+depend[3]+depend[4]]: address of depend elements
+ depend[5+depend[2]+depend[3]+depend[4]..4+depend[1]]: address of
+ omp_depend_t objects. */
void
GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
@@ -303,10 +363,20 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
#endif
/* If parallel or taskgroup has been cancelled, don't start new tasks. */
- if (team
- && (gomp_team_barrier_cancelled (&team->barrier)
- || (thr->task->taskgroup && thr->task->taskgroup->cancelled)))
- return;
+ if (__builtin_expect (gomp_cancel_var, 0) && team)
+ {
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ return;
+ if (thr->task->taskgroup)
+ {
+ if (thr->task->taskgroup->cancelled)
+ return;
+ if (thr->task->taskgroup->workshare
+ && thr->task->taskgroup->prev
+ && thr->task->taskgroup->prev->cancelled)
+ return;
+ }
+ }
if ((flags & GOMP_TASK_FLAG_PRIORITY) == 0)
priority = 0;
@@ -377,7 +447,7 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
size_t depend_size = 0;
if (flags & GOMP_TASK_FLAG_DEPEND)
- depend_size = ((uintptr_t) depend[0]
+ depend_size = ((uintptr_t) (depend[0] ? depend[0] : depend[1])
* sizeof (struct gomp_task_depend_entry));
task = gomp_malloc (sizeof (*task) + depend_size
+ arg_size + arg_align - 1);
@@ -404,14 +474,26 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
gomp_mutex_lock (&team->task_lock);
/* If parallel or taskgroup has been cancelled, don't start new
tasks. */
- if (__builtin_expect ((gomp_team_barrier_cancelled (&team->barrier)
- || (taskgroup && taskgroup->cancelled))
- && !task->copy_ctors_done, 0))
+ if (__builtin_expect (gomp_cancel_var, 0)
+ && !task->copy_ctors_done)
{
- gomp_mutex_unlock (&team->task_lock);
- gomp_finish_task (task);
- free (task);
- return;
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ {
+ do_cancel:
+ gomp_mutex_unlock (&team->task_lock);
+ gomp_finish_task (task);
+ free (task);
+ return;
+ }
+ if (taskgroup)
+ {
+ if (taskgroup->cancelled)
+ goto do_cancel;
+ if (taskgroup->workshare
+ && taskgroup->prev
+ && taskgroup->prev->cancelled)
+ goto do_cancel;
+ }
}
if (taskgroup)
taskgroup->num_children++;
@@ -463,6 +545,7 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
ialias (GOMP_taskgroup_start)
ialias (GOMP_taskgroup_end)
+ialias (GOMP_taskgroup_reduction_register)
#define TYPE long
#define UTYPE unsigned long
@@ -601,10 +684,20 @@ gomp_create_target_task (struct gomp_device_descr *devicep,
struct gomp_team *team = thr->ts.team;
/* If parallel or taskgroup has been cancelled, don't start new tasks. */
- if (team
- && (gomp_team_barrier_cancelled (&team->barrier)
- || (thr->task->taskgroup && thr->task->taskgroup->cancelled)))
- return true;
+ if (__builtin_expect (gomp_cancel_var, 0) && team)
+ {
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ return true;
+ if (thr->task->taskgroup)
+ {
+ if (thr->task->taskgroup->cancelled)
+ return true;
+ if (thr->task->taskgroup->workshare
+ && thr->task->taskgroup->prev
+ && thr->task->taskgroup->prev->cancelled)
+ return true;
+ }
+ }
struct gomp_target_task *ttask;
struct gomp_task *task;
@@ -617,7 +710,7 @@ gomp_create_target_task (struct gomp_device_descr *devicep,
if (depend != NULL)
{
- depend_cnt = (uintptr_t) depend[0];
+ depend_cnt = (uintptr_t) (depend[0] ? depend[0] : depend[1]);
depend_size = depend_cnt * sizeof (struct gomp_task_depend_entry);
}
if (fn)
@@ -687,13 +780,25 @@ gomp_create_target_task (struct gomp_device_descr *devicep,
task->final_task = 0;
gomp_mutex_lock (&team->task_lock);
/* If parallel or taskgroup has been cancelled, don't start new tasks. */
- if (__builtin_expect (gomp_team_barrier_cancelled (&team->barrier)
- || (taskgroup && taskgroup->cancelled), 0))
+ if (__builtin_expect (gomp_cancel_var, 0))
{
- gomp_mutex_unlock (&team->task_lock);
- gomp_finish_task (task);
- free (task);
- return true;
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ {
+ do_cancel:
+ gomp_mutex_unlock (&team->task_lock);
+ gomp_finish_task (task);
+ free (task);
+ return true;
+ }
+ if (taskgroup)
+ {
+ if (taskgroup->cancelled)
+ goto do_cancel;
+ if (taskgroup->workshare
+ && taskgroup->prev
+ && taskgroup->prev->cancelled)
+ goto do_cancel;
+ }
}
if (depend_size)
{
@@ -986,10 +1091,21 @@ gomp_task_run_pre (struct gomp_task *child_task, struct gomp_task *parent,
if (--team->task_queued_count == 0)
gomp_team_barrier_clear_task_pending (&team->barrier);
- if ((gomp_team_barrier_cancelled (&team->barrier)
- || (taskgroup && taskgroup->cancelled))
+ if (__builtin_expect (gomp_cancel_var, 0)
&& !child_task->copy_ctors_done)
- return true;
+ {
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ return true;
+ if (taskgroup)
+ {
+ if (taskgroup->cancelled)
+ return true;
+ if (taskgroup->workshare
+ && taskgroup->prev
+ && taskgroup->prev->cancelled)
+ return true;
+ }
+ }
return false;
}
@@ -1456,6 +1572,35 @@ GOMP_taskwait (void)
}
}
+/* Called when encountering a taskwait directive with depend clause(s).
+ Wait as if it was an mergeable included task construct with empty body. */
+
+void
+GOMP_taskwait_depend (void **depend)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_team *team = thr->ts.team;
+
+ /* If parallel or taskgroup has been cancelled, return early. */
+ if (__builtin_expect (gomp_cancel_var, 0) && team)
+ {
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ return;
+ if (thr->task->taskgroup)
+ {
+ if (thr->task->taskgroup->cancelled)
+ return;
+ if (thr->task->taskgroup->workshare
+ && thr->task->taskgroup->prev
+ && thr->task->taskgroup->prev->cancelled)
+ return;
+ }
+ }
+
+ if (thr->task && thr->task->depend_hash)
+ gomp_task_maybe_wait_for_dependencies (depend);
+}
+
/* An undeferred task is about to run. Wait for all tasks that this
undeferred task depends on.
@@ -1464,7 +1609,7 @@ GOMP_taskwait (void)
the scheduling queues. Then we iterate through these imminently
ready tasks (and possibly other high priority tasks), and run them.
If we run out of ready dependencies to execute, we either wait for
- the reamining dependencies to finish, or wait for them to get
+ the remaining dependencies to finish, or wait for them to get
scheduled so we can run them.
DEPEND is as in GOMP_task. */
@@ -1477,21 +1622,50 @@ gomp_task_maybe_wait_for_dependencies (void **depend)
struct gomp_team *team = thr->ts.team;
struct gomp_task_depend_entry elem, *ent = NULL;
struct gomp_taskwait taskwait;
- size_t ndepend = (uintptr_t) depend[0];
+ size_t orig_ndepend = (uintptr_t) depend[0];
size_t nout = (uintptr_t) depend[1];
+ size_t ndepend = orig_ndepend;
+ size_t normal = ndepend;
+ size_t n = 2;
size_t i;
size_t num_awaited = 0;
struct gomp_task *child_task = NULL;
struct gomp_task *to_free = NULL;
int do_wake = 0;
+ if (ndepend == 0)
+ {
+ ndepend = nout;
+ nout = (uintptr_t) depend[2] + (uintptr_t) depend[3];
+ normal = nout + (uintptr_t) depend[4];
+ n = 5;
+ }
gomp_mutex_lock (&team->task_lock);
for (i = 0; i < ndepend; i++)
{
- elem.addr = depend[i + 2];
+ elem.addr = depend[i + n];
+ elem.is_in = i >= nout;
+ if (__builtin_expect (i >= normal, 0))
+ {
+ void **d = (void **) elem.addr;
+ switch ((uintptr_t) d[1])
+ {
+ case GOMP_DEPEND_IN:
+ break;
+ case GOMP_DEPEND_OUT:
+ case GOMP_DEPEND_INOUT:
+ case GOMP_DEPEND_MUTEXINOUTSET:
+ elem.is_in = 0;
+ break;
+ default:
+ gomp_fatal ("unknown omp_depend_t dependence type %d",
+ (int) (uintptr_t) d[1]);
+ }
+ elem.addr = d[0];
+ }
ent = htab_find (task->depend_hash, &elem);
for (; ent; ent = ent->next)
- if (i >= nout && ent->is_in)
+ if (elem.is_in && ent->is_in)
continue;
else
{
@@ -1654,13 +1828,28 @@ GOMP_taskyield (void)
/* Nothing at the moment. */
}
+static inline struct gomp_taskgroup *
+gomp_taskgroup_init (struct gomp_taskgroup *prev)
+{
+ struct gomp_taskgroup *taskgroup
+ = gomp_malloc (sizeof (struct gomp_taskgroup));
+ taskgroup->prev = prev;
+ priority_queue_init (&taskgroup->taskgroup_queue);
+ taskgroup->reductions = prev ? prev->reductions : NULL;
+ taskgroup->in_taskgroup_wait = false;
+ taskgroup->cancelled = false;
+ taskgroup->workshare = false;
+ taskgroup->num_children = 0;
+ gomp_sem_init (&taskgroup->taskgroup_sem, 0);
+ return taskgroup;
+}
+
void
GOMP_taskgroup_start (void)
{
struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr->ts.team;
struct gomp_task *task = thr->task;
- struct gomp_taskgroup *taskgroup;
/* If team is NULL, all tasks are executed as
GOMP_TASK_UNDEFERRED tasks and thus all children tasks of
@@ -1668,14 +1857,7 @@ GOMP_taskgroup_start (void)
by the time GOMP_taskgroup_end is called. */
if (team == NULL)
return;
- taskgroup = gomp_malloc (sizeof (struct gomp_taskgroup));
- taskgroup->prev = task->taskgroup;
- priority_queue_init (&taskgroup->taskgroup_queue);
- taskgroup->in_taskgroup_wait = false;
- taskgroup->cancelled = false;
- taskgroup->num_children = 0;
- gomp_sem_init (&taskgroup->taskgroup_sem, 0);
- task->taskgroup = taskgroup;
+ task->taskgroup = gomp_taskgroup_init (task->taskgroup);
}
void
@@ -1840,6 +2022,302 @@ GOMP_taskgroup_end (void)
free (taskgroup);
}
+static inline __attribute__((always_inline)) void
+gomp_reduction_register (uintptr_t *data, uintptr_t *old, uintptr_t *orig,
+ unsigned nthreads)
+{
+ size_t total_cnt = 0;
+ uintptr_t *d = data;
+ struct htab *old_htab = NULL, *new_htab;
+ do
+ {
+ if (__builtin_expect (orig != NULL, 0))
+ {
+ /* For worksharing task reductions, memory has been allocated
+ already by some other thread that encountered the construct
+ earlier. */
+ d[2] = orig[2];
+ d[6] = orig[6];
+ orig = (uintptr_t *) orig[4];
+ }
+ else
+ {
+ size_t sz = d[1] * nthreads;
+ /* Should use omp_alloc if d[3] is not -1. */
+ void *ptr = gomp_aligned_alloc (d[2], sz);
+ memset (ptr, '\0', sz);
+ d[2] = (uintptr_t) ptr;
+ d[6] = d[2] + sz;
+ }
+ d[5] = 0;
+ total_cnt += d[0];
+ if (d[4] == 0)
+ {
+ d[4] = (uintptr_t) old;
+ break;
+ }
+ else
+ d = (uintptr_t *) d[4];
+ }
+ while (1);
+ if (old && old[5])
+ {
+ old_htab = (struct htab *) old[5];
+ total_cnt += htab_elements (old_htab);
+ }
+ new_htab = htab_create (total_cnt);
+ if (old_htab)
+ {
+ /* Copy old hash table, like in htab_expand. */
+ hash_entry_type *p, *olimit;
+ new_htab->n_elements = htab_elements (old_htab);
+ olimit = old_htab->entries + old_htab->size;
+ p = old_htab->entries;
+ do
+ {
+ hash_entry_type x = *p;
+ if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
+ *find_empty_slot_for_expand (new_htab, htab_hash (x)) = x;
+ p++;
+ }
+ while (p < olimit);
+ }
+ d = data;
+ do
+ {
+ size_t j;
+ for (j = 0; j < d[0]; ++j)
+ {
+ uintptr_t *p = d + 7 + j * 3;
+ p[2] = (uintptr_t) d;
+ /* Ugly hack, hash_entry_type is defined for the task dependencies,
+ which hash on the first element which is a pointer. We need
+ to hash also on the first sizeof (uintptr_t) bytes which contain
+ a pointer. Hide the cast from the compiler. */
+ hash_entry_type n;
+ __asm ("" : "=g" (n) : "0" (p));
+ *htab_find_slot (&new_htab, n, INSERT) = n;
+ }
+ if (d[4] == (uintptr_t) old)
+ break;
+ else
+ d = (uintptr_t *) d[4];
+ }
+ while (1);
+ d[5] = (uintptr_t) new_htab;
+}
+
+static void
+gomp_create_artificial_team (void)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_task_icv *icv;
+ struct gomp_team *team = gomp_new_team (1);
+ struct gomp_task *task = thr->task;
+ icv = task ? &task->icv : &gomp_global_icv;
+ team->prev_ts = thr->ts;
+ thr->ts.team = team;
+ thr->ts.team_id = 0;
+ thr->ts.work_share = &team->work_shares[0];
+ thr->ts.last_work_share = NULL;
+#ifdef HAVE_SYNC_BUILTINS
+ thr->ts.single_count = 0;
+#endif
+ thr->ts.static_trip = 0;
+ thr->task = &team->implicit_task[0];
+ gomp_init_task (thr->task, NULL, icv);
+ if (task)
+ {
+ thr->task = task;
+ gomp_end_task ();
+ free (task);
+ thr->task = &team->implicit_task[0];
+ }
+#ifdef LIBGOMP_USE_PTHREADS
+ else
+ pthread_setspecific (gomp_thread_destructor, thr);
+#endif
+}
+
+/* The format of data is:
+ data[0] cnt
+ data[1] size
+ data[2] alignment (on output array pointer)
+ data[3] allocator (-1 if malloc allocator)
+ data[4] next pointer
+ data[5] used internally (htab pointer)
+ data[6] used internally (end of array)
+ cnt times
+ ent[0] address
+ ent[1] offset
+ ent[2] used internally (pointer to data[0])
+ The entries are sorted by increasing offset, so that a binary
+ search can be performed. Normally, data[8] is 0, exception is
+ for worksharing construct task reductions in cancellable parallel,
+ where at offset 0 there should be space for a pointer and an integer
+ which are used internally. */
+
+void
+GOMP_taskgroup_reduction_register (uintptr_t *data)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_team *team = thr->ts.team;
+ struct gomp_task *task;
+ unsigned nthreads;
+ if (__builtin_expect (team == NULL, 0))
+ {
+ /* The task reduction code needs a team and task, so for
+ orphaned taskgroups just create the implicit team. */
+ gomp_create_artificial_team ();
+ ialias_call (GOMP_taskgroup_start) ();
+ team = thr->ts.team;
+ }
+ nthreads = team->nthreads;
+ task = thr->task;
+ gomp_reduction_register (data, task->taskgroup->reductions, NULL, nthreads);
+ task->taskgroup->reductions = data;
+}
+
+void
+GOMP_taskgroup_reduction_unregister (uintptr_t *data)
+{
+ uintptr_t *d = data;
+ htab_free ((struct htab *) data[5]);
+ do
+ {
+ gomp_aligned_free ((void *) d[2]);
+ d = (uintptr_t *) d[4];
+ }
+ while (d && !d[5]);
+}
+ialias (GOMP_taskgroup_reduction_unregister)
+
+/* For i = 0 to cnt-1, remap ptrs[i] which is either address of the
+ original list item or address of previously remapped original list
+ item to address of the private copy, store that to ptrs[i].
+ For i < cntorig, additionally set ptrs[cnt+i] to the address of
+ the original list item. */
+
+void
+GOMP_task_reduction_remap (size_t cnt, size_t cntorig, void **ptrs)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_task *task = thr->task;
+ unsigned id = thr->ts.team_id;
+ uintptr_t *data = task->taskgroup->reductions;
+ uintptr_t *d;
+ struct htab *reduction_htab = (struct htab *) data[5];
+ size_t i;
+ for (i = 0; i < cnt; ++i)
+ {
+ hash_entry_type ent, n;
+ __asm ("" : "=g" (ent) : "0" (ptrs + i));
+ n = htab_find (reduction_htab, ent);
+ if (n)
+ {
+ uintptr_t *p;
+ __asm ("" : "=g" (p) : "0" (n));
+ /* At this point, p[0] should be equal to (uintptr_t) ptrs[i],
+ p[1] is the offset within the allocated chunk for each
+ thread, p[2] is the array registered with
+ GOMP_taskgroup_reduction_register, d[2] is the base of the
+ allocated memory and d[1] is the size of the allocated chunk
+ for one thread. */
+ d = (uintptr_t *) p[2];
+ ptrs[i] = (void *) (d[2] + id * d[1] + p[1]);
+ if (__builtin_expect (i < cntorig, 0))
+ ptrs[cnt + i] = (void *) p[0];
+ continue;
+ }
+ d = data;
+ while (d != NULL)
+ {
+ if ((uintptr_t) ptrs[i] >= d[2] && (uintptr_t) ptrs[i] < d[6])
+ break;
+ d = (uintptr_t *) d[4];
+ }
+ if (d == NULL)
+ gomp_fatal ("couldn't find matching task_reduction or reduction with "
+ "task modifier for %p", ptrs[i]);
+ uintptr_t off = ((uintptr_t) ptrs[i] - d[2]) % d[1];
+ ptrs[i] = (void *) (d[2] + id * d[1] + off);
+ if (__builtin_expect (i < cntorig, 0))
+ {
+ size_t lo = 0, hi = d[0] - 1;
+ while (lo <= hi)
+ {
+ size_t m = (lo + hi) / 2;
+ if (d[7 + 3 * m + 1] < off)
+ lo = m + 1;
+ else if (d[7 + 3 * m + 1] == off)
+ {
+ ptrs[cnt + i] = (void *) d[7 + 3 * m];
+ break;
+ }
+ else
+ hi = m - 1;
+ }
+ if (lo > hi)
+ gomp_fatal ("couldn't find matching task_reduction or reduction "
+ "with task modifier for %p", ptrs[i]);
+ }
+ }
+}
+
+struct gomp_taskgroup *
+gomp_parallel_reduction_register (uintptr_t *data, unsigned nthreads)
+{
+ struct gomp_taskgroup *taskgroup = gomp_taskgroup_init (NULL);
+ gomp_reduction_register (data, NULL, NULL, nthreads);
+ taskgroup->reductions = data;
+ return taskgroup;
+}
+
+void
+gomp_workshare_task_reduction_register (uintptr_t *data, uintptr_t *orig)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_team *team = thr->ts.team;
+ struct gomp_task *task = thr->task;
+ unsigned nthreads = team->nthreads;
+ gomp_reduction_register (data, task->taskgroup->reductions, orig, nthreads);
+ task->taskgroup->reductions = data;
+}
+
+void
+gomp_workshare_taskgroup_start (void)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_team *team = thr->ts.team;
+ struct gomp_task *task;
+
+ if (team == NULL)
+ {
+ gomp_create_artificial_team ();
+ team = thr->ts.team;
+ }
+ task = thr->task;
+ task->taskgroup = gomp_taskgroup_init (task->taskgroup);
+ task->taskgroup->workshare = true;
+}
+
+void
+GOMP_workshare_task_reduction_unregister (bool cancelled)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_task *task = thr->task;
+ struct gomp_team *team = thr->ts.team;
+ uintptr_t *data = task->taskgroup->reductions;
+ ialias_call (GOMP_taskgroup_end) ();
+ if (thr->ts.team_id == 0)
+ ialias_call (GOMP_taskgroup_reduction_unregister) (data);
+ else
+ htab_free ((struct htab *) data[5]);
+
+ if (!cancelled)
+ gomp_team_barrier_wait (&team->barrier);
+}
+
int
omp_in_final (void)
{
diff --git a/libgomp/taskloop.c b/libgomp/taskloop.c
index 5515b355f00..5d3f810a8f2 100644
--- a/libgomp/taskloop.c
+++ b/libgomp/taskloop.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2015-2019 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -149,11 +149,28 @@ GOMP_taskloop (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
if (flags & GOMP_TASK_FLAG_NOGROUP)
{
- if (thr->task && thr->task->taskgroup && thr->task->taskgroup->cancelled)
- return;
+ if (__builtin_expect (gomp_cancel_var, 0)
+ && thr->task
+ && thr->task->taskgroup)
+ {
+ if (thr->task->taskgroup->cancelled)
+ return;
+ if (thr->task->taskgroup->workshare
+ && thr->task->taskgroup->prev
+ && thr->task->taskgroup->prev->cancelled)
+ return;
+ }
}
else
- ialias_call (GOMP_taskgroup_start) ();
+ {
+ ialias_call (GOMP_taskgroup_start) ();
+ if (flags & GOMP_TASK_FLAG_REDUCTION)
+ {
+ struct gomp_data_head { TYPE t1, t2; uintptr_t *ptr; };
+ uintptr_t *ptr = ((struct gomp_data_head *) data)->ptr;
+ ialias_call (GOMP_taskgroup_reduction_register) (ptr);
+ }
+ }
if (priority > gomp_max_task_priority_var)
priority = gomp_max_task_priority_var;
@@ -284,19 +301,31 @@ GOMP_taskloop (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
gomp_mutex_lock (&team->task_lock);
/* If parallel or taskgroup has been cancelled, don't start new
tasks. */
- if (__builtin_expect ((gomp_team_barrier_cancelled (&team->barrier)
- || (taskgroup && taskgroup->cancelled))
- && cpyfn == NULL, 0))
+ if (__builtin_expect (gomp_cancel_var, 0)
+ && cpyfn == NULL)
{
- gomp_mutex_unlock (&team->task_lock);
- for (i = 0; i < num_tasks; i++)
+ if (gomp_team_barrier_cancelled (&team->barrier))
+ {
+ do_cancel:
+ gomp_mutex_unlock (&team->task_lock);
+ for (i = 0; i < num_tasks; i++)
+ {
+ gomp_finish_task (tasks[i]);
+ free (tasks[i]);
+ }
+ if ((flags & GOMP_TASK_FLAG_NOGROUP) == 0)
+ ialias_call (GOMP_taskgroup_end) ();
+ return;
+ }
+ if (taskgroup)
{
- gomp_finish_task (tasks[i]);
- free (tasks[i]);
+ if (taskgroup->cancelled)
+ goto do_cancel;
+ if (taskgroup->workshare
+ && taskgroup->prev
+ && taskgroup->prev->cancelled)
+ goto do_cancel;
}
- if ((flags & GOMP_TASK_FLAG_NOGROUP) == 0)
- ialias_call (GOMP_taskgroup_end) ();
- return;
}
if (taskgroup)
taskgroup->num_children += num_tasks;
diff --git a/libgomp/team.c b/libgomp/team.c
index 87cdcfd52a9..cdfb9ba6c98 100644
--- a/libgomp/team.c
+++ b/libgomp/team.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -32,7 +32,6 @@
#include <string.h>
#ifdef LIBGOMP_USE_PTHREADS
-/* This attribute contains PTHREAD_CREATE_DETACHED. */
pthread_attr_t gomp_thread_attr;
/* This key is for the thread destructor. */
@@ -58,6 +57,7 @@ struct gomp_thread_start_data
struct gomp_thread_pool *thread_pool;
unsigned int place;
bool nested;
+ pthread_t handle;
};
@@ -89,6 +89,9 @@ gomp_thread_start (void *xdata)
thr->ts = data->ts;
thr->task = data->task;
thr->place = data->place;
+#ifdef GOMP_NEEDS_THREAD_HANDLE
+ thr->handle = data->handle;
+#endif
thr->ts.team->ordered_release[thr->ts.team_id] = &thr->release;
@@ -131,6 +134,7 @@ gomp_thread_start (void *xdata)
}
gomp_sem_destroy (&thr->release);
+ pthread_detach (pthread_self ());
thr->thread_pool = NULL;
thr->task = NULL;
return NULL;
@@ -167,7 +171,7 @@ gomp_new_team (unsigned nthreads)
{
size_t extra = sizeof (team->ordered_release[0])
+ sizeof (team->implicit_task[0]);
- team = gomp_malloc (sizeof (*team) + nthreads * extra);
+ team = team_malloc (sizeof (*team) + nthreads * extra);
#ifndef HAVE_SYNC_BUILTINS
gomp_mutex_init (&team->work_share_list_free_lock);
@@ -183,7 +187,7 @@ gomp_new_team (unsigned nthreads)
team->single_count = 0;
#endif
team->work_shares_to_free = &team->work_shares[0];
- gomp_init_work_share (&team->work_shares[0], false, nthreads);
+ gomp_init_work_share (&team->work_shares[0], 0, nthreads);
team->work_shares[0].next_alloc = NULL;
team->work_share_list_free = NULL;
team->work_share_list_alloc = &team->work_shares[1];
@@ -217,7 +221,7 @@ free_team (struct gomp_team *team)
gomp_barrier_destroy (&team->barrier);
gomp_mutex_destroy (&team->task_lock);
priority_queue_free (&team->task_queue);
- free (team);
+ team_free (team);
}
static void
@@ -231,9 +235,13 @@ gomp_free_pool_helper (void *thread_pool)
thr->thread_pool = NULL;
thr->task = NULL;
#ifdef LIBGOMP_USE_PTHREADS
+ pthread_detach (pthread_self ());
pthread_exit (NULL);
#elif defined(__nvptx__)
asm ("exit;");
+#elif defined(__AMDGCN__)
+ asm ("s_dcache_wb\n\t"
+ "s_endpgm");
#else
#error gomp_free_pool_helper must terminate the thread
#endif
@@ -277,8 +285,8 @@ gomp_free_thread (void *arg __attribute__((unused)))
if (pool->last_team)
free_team (pool->last_team);
#ifndef __nvptx__
- free (pool->threads);
- free (pool);
+ team_free (pool->threads);
+ team_free (pool);
#endif
thr->thread_pool = NULL;
}
@@ -297,7 +305,8 @@ gomp_free_thread (void *arg __attribute__((unused)))
#ifdef LIBGOMP_USE_PTHREADS
void
gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
- unsigned flags, struct gomp_team *team)
+ unsigned flags, struct gomp_team *team,
+ struct gomp_taskgroup *taskgroup)
{
struct gomp_thread_start_data *start_data;
struct gomp_thread *thr, *nthr;
@@ -312,6 +321,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
unsigned int s = 0, rest = 0, p = 0, k = 0;
unsigned int affinity_count = 0;
struct gomp_thread **affinity_thr = NULL;
+ bool force_display = false;
thr = gomp_thread ();
nested = thr->ts.level;
@@ -319,7 +329,12 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
task = thr->task;
icv = task ? &task->icv : &gomp_global_icv;
if (__builtin_expect (gomp_places_list != NULL, 0) && thr->place == 0)
- gomp_init_affinity ();
+ {
+ gomp_init_affinity ();
+ if (__builtin_expect (gomp_display_affinity_var, 0) && nthreads == 1)
+ gomp_display_affinity_thread (gomp_thread_self (), &thr->ts,
+ thr->place);
+ }
/* Always save the previous state, even if this isn't a nested team.
In particular, we should save any work share state from an outer
@@ -338,6 +353,9 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
#endif
thr->ts.static_trip = 0;
thr->task = &team->implicit_task[0];
+#ifdef GOMP_NEEDS_THREAD_HANDLE
+ thr->handle = pthread_self ();
+#endif
nthreads_var = icv->nthreads_var;
if (__builtin_expect (gomp_nthreads_var_list != NULL, 0)
&& thr->ts.level < gomp_nthreads_var_list_len)
@@ -350,6 +368,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
&& thr->ts.level < gomp_bind_var_list_len)
bind_var = gomp_bind_var_list[thr->ts.level];
gomp_init_task (thr->task, task, icv);
+ thr->task->taskgroup = taskgroup;
team->implicit_task[0].icv.nthreads_var = nthreads_var;
team->implicit_task[0].icv.bind_var = bind_var;
@@ -465,7 +484,9 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
pool->threads
= gomp_realloc (pool->threads,
pool->threads_size
- * sizeof (struct gomp_thread_data *));
+ * sizeof (struct gomp_thread *));
+ /* Add current (master) thread to threads[]. */
+ pool->threads[0] = thr;
}
/* Release existing idle threads. */
@@ -540,6 +561,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
+ place_partition_len))
{
unsigned int l;
+ force_display = true;
if (affinity_thr == NULL)
{
unsigned int j;
@@ -623,6 +645,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
gomp_init_task (nthr->task, task, icv);
team->implicit_task[i].icv.nthreads_var = nthreads_var;
team->implicit_task[i].icv.bind_var = bind_var;
+ nthr->task->taskgroup = taskgroup;
nthr->fn = fn;
nthr->data = data;
team->ordered_release[i] = &nthr->release;
@@ -712,19 +735,17 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
{
size_t stacksize;
pthread_attr_init (&thread_attr);
- pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
if (! pthread_attr_getstacksize (&gomp_thread_attr, &stacksize))
pthread_attr_setstacksize (&thread_attr, stacksize);
attr = &thread_attr;
}
start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
- * (nthreads-i));
+ * (nthreads - i));
/* Launch new threads. */
for (; i < nthreads; ++i)
{
- pthread_t pt;
int err;
start_data->ts.place_partition_off = thr->ts.place_partition_off;
@@ -810,11 +831,14 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
gomp_init_task (start_data->task, task, icv);
team->implicit_task[i].icv.nthreads_var = nthreads_var;
team->implicit_task[i].icv.bind_var = bind_var;
+ start_data->task->taskgroup = taskgroup;
start_data->thread_pool = pool;
start_data->nested = nested;
attr = gomp_adjust_thread_attr (attr, &thread_attr);
- err = pthread_create (&pt, attr, gomp_thread_start, start_data++);
+ err = pthread_create (&start_data->handle, attr, gomp_thread_start,
+ start_data);
+ start_data++;
if (err != 0)
gomp_fatal ("Thread creation failed: %s", strerror (err));
}
@@ -854,6 +878,42 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
gomp_mutex_unlock (&gomp_managed_threads_lock);
#endif
}
+ if (__builtin_expect (gomp_display_affinity_var, 0))
+ {
+ if (nested
+ || nthreads != old_threads_used
+ || force_display)
+ {
+ gomp_display_affinity_thread (gomp_thread_self (), &thr->ts,
+ thr->place);
+ if (nested)
+ {
+ start_data -= nthreads - 1;
+ for (i = 1; i < nthreads; ++i)
+ {
+ gomp_display_affinity_thread (
+#ifdef LIBGOMP_USE_PTHREADS
+ start_data->handle,
+#else
+ gomp_thread_self (),
+#endif
+ &start_data->ts,
+ start_data->place);
+ start_data++;
+ }
+ }
+ else
+ {
+ for (i = 1; i < nthreads; ++i)
+ {
+ gomp_thread_handle handle
+ = gomp_thread_to_pthread_t (pool->threads[i]);
+ gomp_display_affinity_thread (handle, &pool->threads[i]->ts,
+ pool->threads[i]->place);
+ }
+ }
+ }
+ }
if (__builtin_expect (affinity_thr != NULL, 0)
&& team->prev_ts.place_partition_len > 64)
free (affinity_thr);
@@ -894,7 +954,7 @@ gomp_team_end (void)
gomp_end_task ();
thr->ts = team->prev_ts;
- if (__builtin_expect (thr->ts.team != NULL, 0))
+ if (__builtin_expect (thr->ts.level != 0, 0))
{
#ifdef HAVE_SYNC_BUILTINS
__sync_fetch_and_add (&gomp_managed_threads, 1L - team->nthreads);
@@ -959,6 +1019,76 @@ team_destructor (void)
crashes. */
pthread_key_delete (gomp_thread_destructor);
}
+
+/* Similar to gomp_free_pool_helper, but don't detach itself,
+ gomp_pause_host will pthread_join those threads. */
+
+static void
+gomp_pause_pool_helper (void *thread_pool)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_thread_pool *pool
+ = (struct gomp_thread_pool *) thread_pool;
+ gomp_simple_barrier_wait_last (&pool->threads_dock);
+ gomp_sem_destroy (&thr->release);
+ thr->thread_pool = NULL;
+ thr->task = NULL;
+ pthread_exit (NULL);
+}
+
+/* Free a thread pool and release its threads. Return non-zero on
+ failure. */
+
+int
+gomp_pause_host (void)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_thread_pool *pool = thr->thread_pool;
+ if (thr->ts.level)
+ return -1;
+ if (pool)
+ {
+ if (pool->threads_used > 0)
+ {
+ int i;
+ pthread_t *thrs
+ = gomp_alloca (sizeof (pthread_t) * pool->threads_used);
+ for (i = 1; i < pool->threads_used; i++)
+ {
+ struct gomp_thread *nthr = pool->threads[i];
+ nthr->fn = gomp_pause_pool_helper;
+ nthr->data = pool;
+ thrs[i] = gomp_thread_to_pthread_t (nthr);
+ }
+ /* This barrier undocks threads docked on pool->threads_dock. */
+ gomp_simple_barrier_wait (&pool->threads_dock);
+ /* And this waits till all threads have called gomp_barrier_wait_last
+ in gomp_pause_pool_helper. */
+ gomp_simple_barrier_wait (&pool->threads_dock);
+ /* Now it is safe to destroy the barrier and free the pool. */
+ gomp_simple_barrier_destroy (&pool->threads_dock);
+
+#ifdef HAVE_SYNC_BUILTINS
+ __sync_fetch_and_add (&gomp_managed_threads,
+ 1L - pool->threads_used);
+#else
+ gomp_mutex_lock (&gomp_managed_threads_lock);
+ gomp_managed_threads -= pool->threads_used - 1L;
+ gomp_mutex_unlock (&gomp_managed_threads_lock);
+#endif
+ for (i = 1; i < pool->threads_used; i++)
+ pthread_join (thrs[i], NULL);
+ }
+ if (pool->last_team)
+ free_team (pool->last_team);
+#ifndef __nvptx__
+ team_free (pool->threads);
+ team_free (pool);
+#endif
+ thr->thread_pool = NULL;
+ }
+ return 0;
+}
#endif
struct gomp_task_icv *
diff --git a/libgomp/teams.c b/libgomp/teams.c
new file mode 100644
index 00000000000..cc51faf7c6b
--- /dev/null
+++ b/libgomp/teams.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 2018-2019 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ This file is part of the GNU Offloading and Multi Processing Library
+ (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file handles the host TEAMS construct. */
+
+#include "libgomp.h"
+#include <limits.h>
+
+static unsigned gomp_num_teams = 1, gomp_team_num = 0;
+
+void
+GOMP_teams_reg (void (*fn) (void *), void *data, unsigned int num_teams,
+ unsigned int thread_limit, unsigned int flags)
+{
+ (void) flags;
+ (void) num_teams;
+ unsigned old_thread_limit_var = 0;
+ if (thread_limit)
+ {
+ struct gomp_task_icv *icv = gomp_icv (true);
+ old_thread_limit_var = icv->thread_limit_var;
+ icv->thread_limit_var
+ = thread_limit > INT_MAX ? UINT_MAX : thread_limit;
+ }
+ if (num_teams == 0)
+ num_teams = 3;
+ gomp_num_teams = num_teams;
+ for (gomp_team_num = 0; gomp_team_num < num_teams; gomp_team_num++)
+ fn (data);
+ gomp_num_teams = 1;
+ gomp_team_num = 0;
+ if (thread_limit)
+ {
+ struct gomp_task_icv *icv = gomp_icv (true);
+ icv->thread_limit_var = old_thread_limit_var;
+ }
+}
+
+int
+omp_get_num_teams (void)
+{
+ return gomp_num_teams;
+}
+
+int
+omp_get_team_num (void)
+{
+ return gomp_team_num;
+}
+
+ialias (omp_get_num_teams)
+ialias (omp_get_team_num)
diff --git a/libgomp/testsuite/Makefile.am b/libgomp/testsuite/Makefile.am
index e2a3f460eb0..62b1855695c 100644
--- a/libgomp/testsuite/Makefile.am
+++ b/libgomp/testsuite/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in.
-AUTOMAKE_OPTIONS = foreign dejagnu
+AUTOMAKE_OPTIONS = foreign
# May be used by various substitution variables.
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
@@ -10,8 +10,7 @@ EXPECT = $(shell if test -f $(top_builddir)/../expect/expect; then \
_RUNTEST = $(shell if test -f $(top_srcdir)/../dejagnu/runtest; then \
echo $(top_srcdir)/../dejagnu/runtest; else echo runtest; fi)
-RUNTEST = "$(_RUNTEST) $(AM_RUNTESTFLAGS)"
-
+RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
# Instead of directly in ../testsuite/libgomp-test-support.exp.in, the
# following variables have to be "routed through" this Makefile, for expansion
@@ -24,4 +23,65 @@ libgomp-test-support.exp: libgomp-test-support.pt.exp Makefile
'set offload_additional_lib_paths "$(offload_additional_lib_paths)"'
mv $@.tmp $@
+check-DEJAGNU: site.exp
+ srcdir='$(srcdir)'; export srcdir; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ if $(SHELL) -c "$(_RUNTEST) --version" > /dev/null 2>&1; then \
+ exit_status=0; l='$(PACKAGE)'; for tool in $$l; do \
+ if $(_RUNTEST) $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
+ then :; else exit_status=1; fi; \
+ done; \
+ else echo "WARNING: could not find '$(_RUNTEST)'" 1>&2; :;\
+ fi; \
+ exit $$exit_status
+site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG)
+ @echo 'Making a new site.exp file ...'
+ @echo '## these variables are automatically generated by make ##' >site.tmp
+ @echo '# Do not edit here. If you wish to override these values' >>site.tmp
+ @echo '# edit the last section' >>site.tmp
+ @echo 'set srcdir "$(srcdir)"' >>site.tmp
+ @echo "set objdir `pwd`" >>site.tmp
+ @echo 'set build_alias "$(build_alias)"' >>site.tmp
+ @echo 'set build_triplet $(build_triplet)' >>site.tmp
+ @echo 'set host_alias "$(host_alias)"' >>site.tmp
+ @echo 'set host_triplet $(host_triplet)' >>site.tmp
+ @echo 'set target_alias "$(target_alias)"' >>site.tmp
+ @echo 'set target_triplet $(target_triplet)' >>site.tmp
+ @list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \
+ echo "## Begin content included from file $$f. Do not modify. ##" \
+ && cat `test -f "$$f" || echo '$(srcdir)/'`$$f \
+ && echo "## End content included from file $$f. ##" \
+ || exit 1; \
+ done >> site.tmp
+ @echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp
+ @if test -f site.exp; then \
+ sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \
+ fi
+ @-rm -f site.bak
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv site.tmp site.exp
+
+distclean-DEJAGNU:
+ -rm -f site.exp site.bak
+ -l='$(PACKAGE)'; for tool in $$l; do \
+ rm -f $$tool.sum $$tool.log; \
+ done
+distclean-am: distclean-DEJAGNU
+check-am:
+ @if test -n "$(filter -j%, $(MFLAGS))"; then \
+ num_cpus=@CPU_COUNT@; \
+ if type -p getconf 2>/dev/null >/dev/null; then \
+ num_cpus=`getconf _NPROCESSORS_ONLN 2>/dev/null`; \
+ case "$$num_cpus" in \
+ '' | 0* | *[!0-9]*) num_cpus=@CPU_COUNT@;; \
+ esac; \
+ fi; \
+ if test $$num_cpus -gt 8 && test -z "$$OMP_NUM_THREADS"; then \
+ OMP_NUM_THREADS=8; export OMP_NUM_THREADS; \
+ echo @@@ libgomp OMP_NUM_THREADS adjusted to 8 because of parallel make check and too many CPUs; \
+ fi; \
+ fi; \
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
all-local: libgomp-test-support.exp
+
+.PHONY: check-DEJAGNU distclean-DEJAGNU
diff --git a/libgomp/testsuite/Makefile.in b/libgomp/testsuite/Makefile.in
index 9310138c32c..f0da16d3161 100644
--- a/libgomp/testsuite/Makefile.in
+++ b/libgomp/testsuite/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -15,23 +14,61 @@
@SET_MAKE@
VPATH = @srcdir@
-am__make_dryrun = \
- { \
- am__dry=no; \
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
- echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
- | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
- *) \
- for am__flg in $$MAKEFLAGS; do \
- case $$am__flg in \
- *=*|--*) ;; \
- *n*) am__dry=yes; break;; \
- esac; \
- done;; \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
esac; \
- test $$am__dry = yes; \
- }
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -52,10 +89,9 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = testsuite
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(srcdir)/libgomp-test-support.exp.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+ $(top_srcdir)/../config/ax_count_cpus.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/enable.m4 \
$(top_srcdir)/../config/futex.m4 \
@@ -63,7 +99,6 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/lthostflags.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/override.m4 \
- $(top_srcdir)/../config/stdint.m4 \
$(top_srcdir)/../config/tls.m4 $(top_srcdir)/../ltoptions.m4 \
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
@@ -71,20 +106,33 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/plugin/configfrag.ac $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am
mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES = libgomp-test-support.pt.exp
CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
-DEJATOOL = $(PACKAGE)
-RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
@@ -95,6 +143,7 @@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CPU_COUNT = @CPU_COUNT@
CUDA_DRIVER_INCLUDE = @CUDA_DRIVER_INCLUDE@
CUDA_DRIVER_LIB = @CUDA_DRIVER_LIB@
CYGPATH_W = @CYGPATH_W@
@@ -157,6 +206,10 @@ PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
+PLUGIN_GCN = @PLUGIN_GCN@
+PLUGIN_GCN_CPPFLAGS = @PLUGIN_GCN_CPPFLAGS@
+PLUGIN_GCN_LDFLAGS = @PLUGIN_GCN_LDFLAGS@
+PLUGIN_GCN_LIBS = @PLUGIN_GCN_LIBS@
PLUGIN_HSA = @PLUGIN_HSA@
PLUGIN_HSA_CPPFLAGS = @PLUGIN_HSA_CPPFLAGS@
PLUGIN_HSA_LDFLAGS = @PLUGIN_HSA_LDFLAGS@
@@ -223,6 +276,7 @@ mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
offload_additional_lib_paths = @offload_additional_lib_paths@
offload_additional_options = @offload_additional_options@
+offload_plugins = @offload_plugins@
offload_targets = @offload_targets@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
@@ -243,7 +297,7 @@ toolexeclibdir = @toolexeclibdir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-AUTOMAKE_OPTIONS = foreign dejagnu
+AUTOMAKE_OPTIONS = foreign
# May be used by various substitution variables.
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
@@ -253,7 +307,7 @@ EXPECT = $(shell if test -f $(top_builddir)/../expect/expect; then \
_RUNTEST = $(shell if test -f $(top_srcdir)/../dejagnu/runtest; then \
echo $(top_srcdir)/../dejagnu/runtest; else echo runtest; fi)
-RUNTEST = "$(_RUNTEST) $(AM_RUNTESTFLAGS)"
+RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
all: all-am
.SUFFIXES:
@@ -269,7 +323,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign testsuite/Makefile
-.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -295,59 +348,13 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
-tags: TAGS
-TAGS:
+tags TAGS:
-ctags: CTAGS
-CTAGS:
+ctags CTAGS:
+cscope cscopelist:
-check-DEJAGNU: site.exp
- srcdir='$(srcdir)'; export srcdir; \
- EXPECT=$(EXPECT); export EXPECT; \
- runtest=$(RUNTEST); \
- if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
- exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \
- if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
- then :; else exit_status=1; fi; \
- done; \
- else echo "WARNING: could not find \`runtest'" 1>&2; :;\
- fi; \
- exit $$exit_status
-site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG)
- @echo 'Making a new site.exp file...'
- @echo '## these variables are automatically generated by make ##' >site.tmp
- @echo '# Do not edit here. If you wish to override these values' >>site.tmp
- @echo '# edit the last section' >>site.tmp
- @echo 'set srcdir "$(srcdir)"' >>site.tmp
- @echo "set objdir `pwd`" >>site.tmp
- @echo 'set build_alias "$(build_alias)"' >>site.tmp
- @echo 'set build_triplet $(build_triplet)' >>site.tmp
- @echo 'set host_alias "$(host_alias)"' >>site.tmp
- @echo 'set host_triplet $(host_triplet)' >>site.tmp
- @echo 'set target_alias "$(target_alias)"' >>site.tmp
- @echo 'set target_triplet $(target_triplet)' >>site.tmp
- @list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \
- echo "## Begin content included from file $$f. Do not modify. ##" \
- && cat `test -f "$$f" || echo '$(srcdir)/'`$$f \
- && echo "## End content included from file $$f. ##" \
- || exit 1; \
- done >> site.tmp
- @echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp
- @if test -f site.exp; then \
- sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \
- fi
- @-rm -f site.bak
- @test ! -f site.exp || mv site.exp site.bak
- @mv site.tmp site.exp
-
-distclean-DEJAGNU:
- -rm -f site.exp site.bak
- -l='$(DEJATOOL)'; for tool in $$l; do \
- rm -f $$tool.sum $$tool.log; \
- done
check-am: all-am
- $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
check: check-am
all-am: Makefile all-local
installdirs:
@@ -387,8 +394,6 @@ clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
-distclean-am: clean-am distclean-DEJAGNU distclean-generic
-
dvi: dvi-am
dvi-am:
@@ -447,10 +452,10 @@ ps-am:
uninstall-am:
-.MAKE: check-am install-am install-strip
+.MAKE: install-am install-strip
-.PHONY: all all-am all-local check check-DEJAGNU check-am clean \
- clean-generic clean-libtool distclean distclean-DEJAGNU \
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags-am distclean \
distclean-generic distclean-libtool dvi dvi-am html html-am \
info info-am install install-am install-data install-data-am \
install-dvi install-dvi-am install-exec install-exec-am \
@@ -459,7 +464,9 @@ uninstall-am:
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
- ps ps-am uninstall uninstall-am
+ ps ps-am tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
# Instead of directly in ../testsuite/libgomp-test-support.exp.in, the
@@ -473,8 +480,69 @@ libgomp-test-support.exp: libgomp-test-support.pt.exp Makefile
'set offload_additional_lib_paths "$(offload_additional_lib_paths)"'
mv $@.tmp $@
+check-DEJAGNU: site.exp
+ srcdir='$(srcdir)'; export srcdir; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ if $(SHELL) -c "$(_RUNTEST) --version" > /dev/null 2>&1; then \
+ exit_status=0; l='$(PACKAGE)'; for tool in $$l; do \
+ if $(_RUNTEST) $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
+ then :; else exit_status=1; fi; \
+ done; \
+ else echo "WARNING: could not find '$(_RUNTEST)'" 1>&2; :;\
+ fi; \
+ exit $$exit_status
+site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG)
+ @echo 'Making a new site.exp file ...'
+ @echo '## these variables are automatically generated by make ##' >site.tmp
+ @echo '# Do not edit here. If you wish to override these values' >>site.tmp
+ @echo '# edit the last section' >>site.tmp
+ @echo 'set srcdir "$(srcdir)"' >>site.tmp
+ @echo "set objdir `pwd`" >>site.tmp
+ @echo 'set build_alias "$(build_alias)"' >>site.tmp
+ @echo 'set build_triplet $(build_triplet)' >>site.tmp
+ @echo 'set host_alias "$(host_alias)"' >>site.tmp
+ @echo 'set host_triplet $(host_triplet)' >>site.tmp
+ @echo 'set target_alias "$(target_alias)"' >>site.tmp
+ @echo 'set target_triplet $(target_triplet)' >>site.tmp
+ @list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \
+ echo "## Begin content included from file $$f. Do not modify. ##" \
+ && cat `test -f "$$f" || echo '$(srcdir)/'`$$f \
+ && echo "## End content included from file $$f. ##" \
+ || exit 1; \
+ done >> site.tmp
+ @echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp
+ @if test -f site.exp; then \
+ sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \
+ fi
+ @-rm -f site.bak
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv site.tmp site.exp
+
+distclean-DEJAGNU:
+ -rm -f site.exp site.bak
+ -l='$(PACKAGE)'; for tool in $$l; do \
+ rm -f $$tool.sum $$tool.log; \
+ done
+distclean-am: distclean-DEJAGNU
+check-am:
+ @if test -n "$(filter -j%, $(MFLAGS))"; then \
+ num_cpus=@CPU_COUNT@; \
+ if type -p getconf 2>/dev/null >/dev/null; then \
+ num_cpus=`getconf _NPROCESSORS_ONLN 2>/dev/null`; \
+ case "$$num_cpus" in \
+ '' | 0* | *[!0-9]*) num_cpus=@CPU_COUNT@;; \
+ esac; \
+ fi; \
+ if test $$num_cpus -gt 8 && test -z "$$OMP_NUM_THREADS"; then \
+ OMP_NUM_THREADS=8; export OMP_NUM_THREADS; \
+ echo @@@ libgomp OMP_NUM_THREADS adjusted to 8 because of parallel make check and too many CPUs; \
+ fi; \
+ fi; \
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
all-local: libgomp-test-support.exp
+.PHONY: check-DEJAGNU distclean-DEJAGNU
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/libgomp/testsuite/config/default.exp b/libgomp/testsuite/config/default.exp
index c976b986a5a..b3d3bba6f1e 100644
--- a/libgomp/testsuite/config/default.exp
+++ b/libgomp/testsuite/config/default.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2019 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libgomp/testsuite/lib/libgomp.exp b/libgomp/testsuite/lib/libgomp.exp
index c41b3e6dc18..74d032623c9 100644
--- a/libgomp/testsuite/lib/libgomp.exp
+++ b/libgomp/testsuite/lib/libgomp.exp
@@ -31,6 +31,7 @@ load_gcc_lib scanrtl.exp
load_gcc_lib scantree.exp
load_gcc_lib scanltranstree.exp
load_gcc_lib scanoffloadtree.exp
+load_gcc_lib scanoffloadrtl.exp
load_gcc_lib scanipa.exp
load_gcc_lib scanwpaipa.exp
load_gcc_lib timeout-dg.exp
@@ -40,28 +41,6 @@ load_gcc_lib fortran-modules.exp
# Try to load a test support file, built during libgomp configuration.
load_file libgomp-test-support.exp
-# Populate offload_targets_s (offloading targets separated by a space), and
-# offload_targets_s_openacc (the same, but with OpenACC names; OpenACC spells
-# some of them a little differently).
-set offload_targets_s [split $offload_targets ","]
-set offload_targets_s_openacc {}
-foreach offload_target_openacc $offload_targets_s {
- # Translate to OpenACC names, or skip if not yet supported.
- switch $offload_target_openacc {
- intelmic {
- continue
- }
- nvptx {
- set offload_target_openacc "nvidia"
- }
- hsa {
- continue
- }
- }
- lappend offload_targets_s_openacc "$offload_target_openacc"
-}
-lappend offload_targets_s_openacc "host"
-
set dg-do-what-default run
#
@@ -139,9 +118,9 @@ proc libgomp_init { args } {
set always_ld_library_path ".:${blddir}/.libs"
# Add liboffloadmic build directory in LD_LIBRARY_PATH to support
- # non-fallback testing for Intel MIC targets
- global offload_targets
- if { [string match "*,intelmic,*" ",$offload_targets,"] } {
+ # Intel MIC offloading testing.
+ global offload_plugins
+ if { [string match "*,intelmic,*" ",$offload_plugins,"] } {
append always_ld_library_path ":${blddir}/../liboffloadmic/.libs"
append always_ld_library_path ":${blddir}/../liboffloadmic/plugin/.libs"
# libstdc++ is required by liboffloadmic
@@ -195,6 +174,20 @@ proc libgomp_init { args } {
# For build-tree testing, also consider the library paths used for builing.
# For installed testing, we assume all that to be provided in the sysroot.
if { $blddir != "" } {
+ # The `-fopenacc' and `-fopenmp' options imply `-pthread', and
+ # that implies `-latomic' on some hosts, so wire in libatomic
+ # build directories.
+ if [ishost "riscv*-*-linux*"] {
+ set shlib_ext [get_shlib_extension]
+ set atomic_library_path "${blddir}/../libatomic/.libs"
+ if { [file exists "${atomic_library_path}/libatomic.a"]
+ || [file exists \
+ "${atomic_library_path}/libatomic.${shlib_ext}"] } {
+ lappend ALWAYS_CFLAGS \
+ "additional_flags=-L${atomic_library_path}"
+ append always_ld_library_path ":${atomic_library_path}"
+ }
+ }
global cuda_driver_include
global cuda_driver_lib
if { $cuda_driver_include != "" } {
@@ -245,8 +238,7 @@ proc libgomp_init { args } {
# Disable color diagnostics
lappend ALWAYS_CFLAGS "additional_flags=-fdiagnostics-color=never"
- # Used for support non-fallback offloading.
- # Help GCC to find target mkoffload.
+ # Help GCC to find offload compilers' 'mkoffload'.
global offload_additional_options
if { $offload_additional_options != "" } {
lappend ALWAYS_CFLAGS "additional_flags=${offload_additional_options}"
@@ -322,6 +314,28 @@ proc libgomp_option_proc { option } {
}
}
+# Translate offload target to OpenACC device type. Return the empty string if
+# not supported, and 'host' for offload target 'disable'.
+proc offload_target_to_openacc_device_type { offload_target } {
+ switch -glob $offload_target {
+ disable {
+ return "host"
+ }
+ hsa* {
+ return ""
+ }
+ *-intelmic* {
+ return ""
+ }
+ nvptx* {
+ return "nvidia"
+ }
+ default {
+ error "Unknown offload target: $offload_target"
+ }
+ }
+}
+
# Return 1 if offload device is available.
proc check_effective_target_offload_device { } {
return [check_runtime_nocache offload_device_available_ {
@@ -362,19 +376,7 @@ proc check_effective_target_offload_device_shared_as { } {
} ]
}
-# Return 1 if configured for nvptx offloading.
-
-proc check_effective_target_openacc_nvidia_accel_configured { } {
- global offload_targets
- if { ![string match "*,nvptx,*" ",$offload_targets,"] } {
- return 0
- }
- # PR libgomp/65099: Currently, we only support offloading in 64-bit
- # configurations.
- return [is-effective-target lp64]
-}
-
-# Return 1 if at least one nvidia board is present.
+# Return 1 if at least one Nvidia GPU is accessible.
proc check_effective_target_openacc_nvidia_accel_present { } {
return [check_runtime openacc_nvidia_accel_present {
@@ -385,29 +387,22 @@ proc check_effective_target_openacc_nvidia_accel_present { } {
} "" ]
}
-# Return 1 if at least one nvidia board is present, and the nvidia device type
-# is selected by default by means of setting the environment variable
-# ACC_DEVICE_TYPE.
+# Return 1 if at least one Nvidia GPU is accessible, and the OpenACC 'nvidia'
+# device type is selected.
proc check_effective_target_openacc_nvidia_accel_selected { } {
if { ![check_effective_target_openacc_nvidia_accel_present] } {
return 0;
}
- global offload_target_openacc
- if { $offload_target_openacc == "nvidia" } {
- return 1;
- }
- return 0;
+ global openacc_device_type
+ return [string match "nvidia" $openacc_device_type]
}
-# Return 1 if the host target is selected for offloaded
+# Return 1 if the OpenACC 'host' device type is selected.
proc check_effective_target_openacc_host_selected { } {
- global offload_target_openacc
- if { $offload_target_openacc == "host" } {
- return 1;
- }
- return 0;
+ global openacc_device_type
+ return [string match "host" $openacc_device_type]
}
# Return 1 if the selected OMP device is actually a HSA device
diff --git a/libgomp/testsuite/libgomp-test-support.exp.in b/libgomp/testsuite/libgomp-test-support.exp.in
index a5250a802c4..98fb442b537 100644
--- a/libgomp/testsuite/libgomp-test-support.exp.in
+++ b/libgomp/testsuite/libgomp-test-support.exp.in
@@ -2,4 +2,5 @@ set cuda_driver_include "@CUDA_DRIVER_INCLUDE@"
set cuda_driver_lib "@CUDA_DRIVER_LIB@"
set hsa_runtime_lib "@HSA_RUNTIME_LIB@"
+set offload_plugins "@offload_plugins@"
set offload_targets "@offload_targets@"
diff --git a/libgomp/testsuite/libgomp.c++/depend-1.C b/libgomp/testsuite/libgomp.c++/depend-1.C
new file mode 100644
index 00000000000..71a24d19f2a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/depend-1.C
@@ -0,0 +1,31 @@
+extern "C" void abort ();
+int a, b, c, d, e;
+
+void
+foo (int &x, bool y)
+{
+ #pragma omp task depend (out: x)
+ a = 1;
+ #pragma omp task depend (out: y ? b : c)
+ (y ? b : c) = 2;
+ #pragma omp task depend (inout: --d)
+ d += 4;
+ #pragma omp task depend (in : a, (y ? b : c), d)
+ e = a + b * 10 + c * 100 + d * 1000;
+}
+
+int
+main ()
+{
+ #pragma omp parallel
+ #pragma omp single
+ foo (a, true);
+ if (e != 1 + 20 + 0 + 3000)
+ abort ();
+ a = b = c = d = e = 0;
+ #pragma omp parallel
+ #pragma omp single
+ foo (a, false);
+ if (e != 1 + 0 + 200 + 3000)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/depend-iterator-1.C b/libgomp/testsuite/libgomp.c++/depend-iterator-1.C
new file mode 100644
index 00000000000..2cff5e84334
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/depend-iterator-1.C
@@ -0,0 +1,167 @@
+extern "C" void abort ();
+int arr[64], arr2[64], arr3[64];
+
+int *
+foo (int x, int y, long z)
+{
+ int v;
+ switch (x)
+ {
+ case 1:
+ if (z != 0 || y < 0 || y >= 64)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = arr2[y];
+ arr2[y]++;
+ }
+ if (v != 0) abort ();
+ return &arr[y];
+ case 2:
+ if (y < 0 || y > 60 || (y & 3) || z < 0 || z >= 4)
+ abort ();
+ #pragma omp atomic
+ arr2[y + z] = arr2[y + z] + 4;
+ return &arr[y + z];
+ case 3:
+ if (z < 0 || z > 60 || (z & 3) || y < 0 || y >= 4)
+ abort ();
+ #pragma omp atomic
+ arr2[y + z] = arr2[y + z] + 16;
+ return &arr[y + z];
+ case 4:
+ if (y != 0 || z > 64 || z <= 0)
+ abort ();
+ #pragma omp atomic
+ arr2[z - 1] = arr2[z - 1] + 64;
+ return &arr[z - 1];
+ case 5:
+ if ((y & 3) != 0 || y < 64 || y >= 96
+ || (z & 127) != 0 || z < 512 || z >= 1024)
+ abort ();
+ y = (y - 64) + (z - 512) / 128;
+ #pragma omp atomic
+ arr2[y] = arr2[y] + 256;
+ return &arr[y];
+ case 6:
+ if ((y & 3) != 0 || y <= 64 || y > 96
+ || (z & 127) != 1 || z <= 513 || z > 1025)
+ abort ();
+ y = (y - 68) + (z - 641) / 128;
+ #pragma omp atomic
+ arr2[y] = arr2[y] + 1024;
+ return &arr[y];
+ default:
+ abort ();
+ }
+}
+
+volatile int beg, end, step, step2;
+volatile unsigned int begu, endu;
+
+template <int N>
+void
+bar ()
+{
+ #pragma omp parallel
+ #pragma omp master
+ {
+ int i;
+ for (i = 0; i < 64; i++)
+ #pragma omp task depend (iterator (j=i:i+1) , out : foo (1, j, 0)[0])
+ arr[i] = i;
+ #pragma omp task depend (iterator (int k=beg:end:step,long int l=0:4:1) , inout : \
+ foo (2, k, l)[0], foo (3, l, k)[0]) private (i)
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i)
+ abort ();
+ else
+ arr[i] = arr[i] + 1;
+ #pragma omp task depend (iterator (int *p=&arr3[64]:&arr3[0]:-1), inout : \
+ foo (4, 0, p - &arr3[0])[0]) depend (in : beg)
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i + 1)
+ abort ();
+ else
+ arr[i] = arr[i] + 2;
+ #pragma omp task depend (iterator (unsigned n=begu:endu:step2, unsigned int o = 512: 1024U: (unsigned char) 128), inout : \
+ foo (5, n + 128, o)[0])
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i + 3)
+ abort ();
+ else
+ arr[i] = arr[i] + 4;
+ #pragma omp task depend (iterator (int unsigned p=endu:begu:step,unsigned q= 1025U:513U:(signed char) -128), in : \
+ foo (6, p + 128, q)[0])
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i + 7)
+ abort ();
+ else
+ arr[i] = arr[i] + 8;
+ }
+}
+
+template <typename A, typename B, typename C, typename D, typename E, typename F>
+void
+baz (A beg, A end, A step, D begu, D endu, A step2)
+{
+ #pragma omp parallel
+ #pragma omp master
+ {
+ int i;
+ for (i = 0; i < 64; i++)
+ #pragma omp task depend (iterator (A j=i:i+1),out : foo (1, j, 0)[0])
+ arr[i] = i;
+ #pragma omp task depend (iterator (A k=beg:end:step,B l=0:4:1), inout : \
+ foo (2, k, l)[0], foo (3, l, k)[0]) private (i)
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i)
+ abort ();
+ else
+ arr[i] = arr[i] + 1;
+ #pragma omp task depend (iterator (C p=&arr3[64]:&arr3[0]:-1), in : \
+ foo (4, 0, p - &arr3[0])[0]) depend (in : beg)
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i + 1)
+ abort ();
+ else
+ arr[i] = arr[i] + 2;
+ #pragma omp task depend (iterator (D n=begu:endu:step2, D o = 512: 1024U:(E) 128), inout : \
+ foo (5, n + 128, o)[0])
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i + 3)
+ abort ();
+ else
+ arr[i] = arr[i] + 4;
+ #pragma omp task depend (iterator (D p=endu:begu:step,D q= 1025U:513U:(F) -128), in : \
+ foo (6, p + 128, q)[0])
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i + 7)
+ abort ();
+ else
+ arr[i] = arr[i] + 8;
+ }
+}
+
+int
+main ()
+{
+ int m;
+ beg = 60;
+ end = -4;
+ step = -4;
+ step2 = 4;
+ begu = -64U;
+ endu = -32U;
+ bar<0> ();
+ for (m = 0; m < 64; m++)
+ if (arr[m] != m + 15 || arr2[m] != (m < 32 ? 1365 : 85))
+ abort ();
+ else
+ arr[m] = arr2[m] = 0;
+ baz<int, long int, int *, unsigned int, unsigned char, signed char> (beg, end, step, begu, endu, step2);
+ for (m = 0; m < 64; m++)
+ if (arr[m] != m + 15 || arr2[m] != (m < 32 ? 1365 : 85))
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/depobj-1.C b/libgomp/testsuite/libgomp.c++/depobj-1.C
new file mode 100644
index 00000000000..91edf8cc34b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/depobj-1.C
@@ -0,0 +1,103 @@
+#include <stdlib.h>
+#include <omp.h>
+
+void
+dep (omp_depend_t &d1, omp_depend_t *d2)
+{
+ int x = 1;
+ #pragma omp depobj (d1) depend(in: x)
+ #pragma omp depobj (*d2) depend(in: x)
+
+ #pragma omp depobj (d2[0]) update(out)
+ #pragma omp parallel
+ #pragma omp single
+ {
+ #pragma omp task shared (x) depend(depobj:*d2)
+ x = 2;
+ #pragma omp task shared (x) depend(depobj : d1)
+ if (x != 2)
+ abort ();
+ }
+ #pragma omp depobj (d2[0]) destroy
+ #pragma omp depobj (d1) destroy
+}
+
+template <typename T>
+void
+dep2 (T &d2)
+{
+ T d1;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ int x = 1;
+ #pragma omp depobj (d1) depend(out: x)
+ #pragma omp depobj (*&d2) depend (in:x)
+ #pragma omp depobj(d2)update(in)
+ #pragma omp task shared (x) depend(depobj :d1)
+ x = 2;
+ #pragma omp task shared (x) depend(depobj: d2)
+ if (x != 2)
+ abort ();
+ #pragma omp taskwait
+ #pragma omp depobj(d1)destroy
+ #pragma omp depobj((&d2)[0]) destroy
+ }
+}
+
+template <typename T>
+void
+dep3 (void)
+{
+ T d[2];
+ #pragma omp parallel
+ {
+ int x = 1;
+ #pragma omp single
+ {
+ #pragma omp depobj(d[0]) depend(out:x)
+ #pragma omp depobj(d[1]) depend(in: x)
+ #pragma omp task shared (x) depend(depobj:*d)
+ x = 2;
+ #pragma omp task shared (x) depend(depobj:*(d + 1))
+ if (x != 2)
+ abort ();
+ }
+ }
+ #pragma omp depobj(d[0]) destroy
+ #pragma omp depobj(d[1]) destroy
+}
+
+int xx;
+omp_depend_t dd1, dd2;
+
+template <int N>
+void
+antidep (void)
+{
+ xx = 1;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ #pragma omp task shared(xx) depend(depobj:dd2)
+ if (xx != 1)
+ abort ();
+ #pragma omp task shared(xx) depend(depobj:dd1)
+ xx = 2;
+ }
+}
+
+int
+main ()
+{
+ omp_depend_t d1, d2, d3;
+ dep (d1, &d2);
+ dep2 <omp_depend_t> (d3);
+ dep3 <omp_depend_t> ();
+ #pragma omp depobj (dd1) depend (inout: xx)
+ #pragma omp depobj (dd2) depend (in : xx)
+ antidep <0> ();
+ #pragma omp depobj (dd2) destroy
+ #pragma omp depobj (dd1) destroy
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/for-15.C b/libgomp/testsuite/libgomp.c++/for-15.C
index d48fa37beb0..ddb9ce629dd 100644
--- a/libgomp/testsuite/libgomp.c++/for-15.C
+++ b/libgomp/testsuite/libgomp.c++/for-15.C
@@ -88,11 +88,9 @@ private:
template <typename T> const I<T> &J<T>::begin () { return b; }
template <typename T> const I<T> &J<T>::end () { return e; }
-#pragma omp end declare target
int results[2000];
-#pragma omp declare target
template <typename T>
void
baz (I<T> &i)
@@ -186,37 +184,37 @@ main ()
a[i] = i;
#pragma omp target data map (to: a)
{
- #pragma omp target teams map (tofrom: results)
+ #pragma omp target teams map (always, tofrom: results)
{
J<int> j (&a[75], &a[1945]);
f1 (j);
}
check (i >= 75 && i < 1945 && (i - 75) % 3 == 0);
- #pragma omp target teams map (tofrom: results)
+ #pragma omp target teams map (always, tofrom: results)
{
J<int> j (&a[63], &a[1949]);
f2 (j);
}
check (i >= 63 && i < 1949);
- #pragma omp target teams map (tofrom: results)
+ #pragma omp target teams map (always, tofrom: results)
{
J<int> j (&a[58], &a[1979]);
f3 <2> (j);
}
check (i >= 58 && i < 1979 && (i - 58) % 6 == 0);
- #pragma omp target teams map (tofrom: results)
+ #pragma omp target teams map (always, tofrom: results)
{
J<int> j (&a[59], &a[1981]);
f4 <9> (j);
}
check (i >= 59 && i < 1981 && (i - 59) % 9 == 0);
- #pragma omp target teams map (tofrom: results)
+ #pragma omp target teams map (always, tofrom: results)
{
J<int> j (&a[52], &a[1972]);
f5 (j);
}
check (i >= 52 && i < 1972 && (i - 52) % 4 == 0);
- #pragma omp target teams map (tofrom: results)
+ #pragma omp target teams map (always, tofrom: results)
{
J<int> j (&a[31], &a[1827]);
f6 (j);
diff --git a/libgomp/testsuite/libgomp.c++/for-16.C b/libgomp/testsuite/libgomp.c++/for-16.C
new file mode 100644
index 00000000000..e7e5b857f23
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/for-16.C
@@ -0,0 +1,218 @@
+// PR c++/86443
+// { dg-do run }
+// { dg-additional-options "-std=c++17" }
+
+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
+baz (int i)
+{
+ if (i < 0 || i >= 2000)
+ abort ();
+ results[i]++;
+}
+
+void
+f1 (J<int> j)
+{
+#pragma omp distribute parallel for default(none)
+ for (I<int> i = j.begin (); i < j.end (); i += 3)
+ baz (*i);
+}
+
+void
+f2 (J<int> j)
+{
+ I<int> i;
+#pragma omp distribute parallel for default(none)
+ for (i = j.begin (); i < j.end (); ++i)
+ baz (*i);
+}
+
+template <int N>
+void
+f3 (J<int> j)
+{
+#pragma omp distribute parallel for default(none)
+ for (I<int> i = j.begin (); i < j.end (); i += 6)
+ baz (*i);
+}
+
+template <int N>
+void
+f4 (J<int> j)
+{
+ I<int> i;
+#pragma omp distribute parallel for default(none)
+ for (i = j.begin (); i < j.end (); i += 9)
+ baz (*i);
+}
+
+template <typename T>
+void
+f5 (J<T> j)
+{
+#pragma omp distribute parallel for default(none)
+ for (I<T> i = j.begin (); i < j.end (); i += 4)
+ baz (*i);
+}
+
+template <typename T>
+void
+f6 (J<T> j)
+{
+ I<T> i;
+#pragma omp distribute parallel for default(none)
+ for (i = j.begin (); i < j.end (); i += 7)
+ baz (*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];
+ for (int i = 0; i < 2000; i++)
+ a[i] = i;
+ #pragma omp teams
+ {
+ J<int> j (&a[75], &a[1945]);
+ f1 (j);
+ }
+ check (i >= 75 && i < 1945 && (i - 75) % 3 == 0);
+ #pragma omp teams
+ {
+ J<int> j (&a[63], &a[1949]);
+ f2 (j);
+ }
+ check (i >= 63 && i < 1949);
+ #pragma omp teams
+ {
+ J<int> j (&a[58], &a[1979]);
+ f3 <2> (j);
+ }
+ check (i >= 58 && i < 1979 && (i - 58) % 6 == 0);
+ #pragma omp teams
+ {
+ J<int> j (&a[59], &a[1981]);
+ f4 <9> (j);
+ }
+ check (i >= 59 && i < 1981 && (i - 59) % 9 == 0);
+ #pragma omp teams
+ {
+ J<int> j (&a[52], &a[1972]);
+ f5 (j);
+ }
+ check (i >= 52 && i < 1972 && (i - 52) % 4 == 0);
+ #pragma omp teams
+ {
+ J<int> j (&a[31], &a[1827]);
+ f6 (j);
+ }
+ check (i >= 31 && i < 1827 && (i - 31) % 7 == 0);
+}
diff --git a/libgomp/testsuite/libgomp.c++/for-21.C b/libgomp/testsuite/libgomp.c++/for-21.C
new file mode 100644
index 00000000000..fc0cb0ab672
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/for-21.C
@@ -0,0 +1,291 @@
+// { 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 for
+ for (I<int> i = x; i != y; i++)
+ baz (i);
+}
+
+void
+f2 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp parallel for private(i)
+ for (i = x; i != y - 1; i = 2 - 8 + 7 + i)
+ baz (i);
+}
+
+template <typename T>
+void
+f3 (const I<int> &x, const I<int> &y)
+{
+#pragma omp parallel for
+ 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 for 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 for
+ for (I<int> i = x + 2000 - 64; i != y + 10; i--)
+ baz (i);
+}
+
+template <int N>
+void
+f6 (const I<int> &x, const I<int> &y)
+{
+#pragma omp parallel for
+ for (I<int> i = x + 2000 - 64; i != y + 10; i = i - 12 + 11)
+ {
+ 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 for
+ 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 for
+ for (i = j.begin (); i != j.end () + N; i += 1)
+ baz (i);
+}
+
+template <typename T, int N>
+void
+f9 (const I<T> &x, const I<T> &y)
+{
+#pragma omp parallel for
+ 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 for
+ 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 for nowait
+ for (T i = x; i != y; i++)
+ baz (i);
+#pragma omp single
+ {
+ T j = y + 3;
+ baz (j);
+ }
+ }
+}
+
+template <typename T>
+void
+f12 (const T &x, const T &y)
+{
+ T i;
+#pragma omp parallel for
+ 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 for
+ for (T i = x; i != y + N; i += N)
+ baz (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);
+ f2 (&a[0], &a[1999]);
+ check (i < 1998);
+ 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 > 110 && i <= 2000 - 64);
+ f6<-10> (&a[10], &a[110]);
+ check (i > 110 && i <= 2000 - 64);
+ f7<1> (I<int> (), &a[12], &a[1800]);
+ check (i >= 2 && i < 1810);
+ f8<121> (J<int> (&a[14], &a[1803]));
+ check (i >= 14 && i < 1924);
+ f9<int, -1> (&a[33], &a[1967]);
+ check (i >= 33 && i < 1967);
+ f10<int, -1> (&a[1939], &a[17]);
+ check (i > 17 && i <= 1939);
+ f11<I<int> > (&a[16], &a[1981]);
+ check ((i >= 16 && i < 1981) || i == 1984);
+ f12<I<int> > (&a[1761], &a[37]);
+ check (i > 37 && i <= 1761);
+ K<1>::f13<I<int> > (&a[1], &a[1935]);
+ check (i >= 1 && i < 1936);
+ f9<long, 1 - 2> (&b[33], &b[1967]);
+ check (i >= 33 && i < 1967);
+ f10<long, -1> (&b[1939], &b[17]);
+ check (i > 17 && i <= 1939);
+ f11<I<long> > (&b[16], &b[1981]);
+ check ((i >= 16 && i < 1981) || i == 1984);
+ f12<I<long> > (&b[1761], &b[37]);
+ check (i > 37 && i <= 1761);
+ K<1>::f13<I<long> > (&b[1], &b[1935]);
+ check (i >= 1 && i < 1936);
+}
diff --git a/libgomp/testsuite/libgomp.c++/for-22.C b/libgomp/testsuite/libgomp.c++/for-22.C
new file mode 100644
index 00000000000..35fcf1f1dce
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/for-22.C
@@ -0,0 +1,314 @@
+// { 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 for lastprivate (i) schedule(runtime)
+ for (i = x; i != y; 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 for lastprivate(i)
+ for (i = x; i != y - 1; i = 2 - 8 + 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 for lastprivate (i)
+ for (i = x; i != y; i = i + 9 - 8)
+ baz (i);
+ return i;
+}
+
+template <typename T>
+I<int>
+f4 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp parallel for 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 for lastprivate(i)
+ for (i = x + 2000 - 64; i != y + T (10); 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 for lastprivate (i)
+ for (i = x + 2000 - 64; i != y + 10; i = i - T (12) + T (11))
+ {
+ I<int> j = i + -10;
+ baz (j);
+ }
+ return I<int> (i);
+}
+
+template <int N>
+I<int>
+f7 (I<int> i, const I<int> &x, const I<int> &y)
+{
+#pragma omp parallel for 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 for lastprivate (i)
+ for (i = j.begin (); i != j.end () + N; i += 1)
+ baz (i);
+ return i;
+}
+
+I<int> i9;
+
+template <long N>
+I<int> &
+f9 (J<int> j)
+{
+#pragma omp parallel for lastprivate(i9)
+ for (i9 = j.begin (); 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 for 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 for lastprivate (i)
+ for (i = x + U (0); i != y + U (2 - 2); i = U(3) + U(-2) + i)
+ baz (i);
+#pragma omp single
+ {
+ T j = y + 3;
+ baz (j);
+ }
+ }
+ return i;
+}
+
+template <typename T>
+T
+f12 (const T &x, const T &y)
+{
+ T i;
+#pragma omp parallel for 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[1990]) != 1993)
+ abort ();
+ check (i >= 10 && i < 1990);
+ if (*f2 (&a[0], &a[1999]) != 1998)
+ abort ();
+ check (i < 1998);
+ if (*f3<char> (&a[20], &a[1837]) != 1837)
+ abort ();
+ check (i >= 20 && i < 1837);
+ if (*f4<int> (&a[0], &a[30]) != 40)
+ abort ();
+ check (i > 40 && i <= 2000 - 64);
+ if (*f5<int> (&a[0], &a[100]) != 110)
+ abort ();
+ check (i > 110 && i <= 2000 - 64);
+ if (*f6<int> (&a[10], &a[110]) != 120)
+ abort ();
+ check (i > 110 && i <= 2000 - 64);
+ if (*f7<1> (I<int> (), &a[12], &a[1800]) != 1810)
+ abort ();
+ check (i >= 2 && i < 1810);
+ if (*f8<121> (J<int> (&a[14], &a[1803])) != 1924)
+ abort ();
+ check (i >= 14 && i < 1924);
+ if (*f9<-1> (J<int> (&a[33], &a[1967])) != 1968)
+ abort ();
+ check (i >= 33 && i <= 1967);
+ if (*f10<int, -1> (&a[1939], &a[17]) != 17)
+ abort ();
+ check (i > 17 && i <= 1939);
+ if (*f11<I<int>, int> (I<int> (), &a[16], &a[1981]) != 1981)
+ abort ();
+ check ((i >= 16 && i < 1981) || i == 1984);
+ if (*f12<I<int> > (&a[1761], &a[37]) != 37)
+ abort ();
+ check (i > 37 && i <= 1761);
+ if (*f10<long, -1> (&b[1939], &b[17]) != 17)
+ abort ();
+ check (i > 17 && i <= 1939);
+ if (*f11<I<long>, long> (I<long> (), &b[16], &b[1981]) != 1981)
+ abort ();
+ check ((i >= 16 && i < 1981) || i == 1984);
+ if (*f12<I<long> > (&b[1761], &b[37]) != 37)
+ abort ();
+ check (i > 37 && i <= 1761);
+}
diff --git a/libgomp/testsuite/libgomp.c++/for-23.C b/libgomp/testsuite/libgomp.c++/for-23.C
new file mode 100644
index 00000000000..e0d7b7afae4
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/for-23.C
@@ -0,0 +1,416 @@
+// { dg-do run }
+// { dg-additional-options "-std=c++17" }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+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; }
+
+template <typename T>
+class K
+{
+public:
+ K ();
+ ~K ();
+ template <int N> T &get () { if (N == 0) return c; else if (N == 1) return b; return a; }
+ T a, b, c;
+};
+
+template <typename T> K<T>::K () : a {}, b {}, c {} {}
+template <typename T> K<T>::~K () {}
+template <typename T> struct std::tuple_size<K<T>> { static constexpr int value = 3; };
+template <typename T, int N> struct std::tuple_element<N, K<T>> { using type = T; };
+
+template <typename T>
+class L
+{
+public:
+ L ();
+ ~L ();
+ T a, b, c;
+};
+
+template <typename T> L<T>::L () : a {}, b {}, c {} {}
+template <typename T> L<T>::~L () {}
+
+int a[2000];
+long b[40];
+short c[50];
+int d[1024];
+K<int> e[1089];
+L<int> f[1093];
+int results[2000];
+
+template <typename T>
+void
+baz (I<T> &i)
+{
+ if (*i < 0 || *i >= 2000)
+ abort ();
+ results[*i]++;
+}
+
+void
+baz (int i)
+{
+ if (i < 0 || i >= 2000)
+ abort ();
+ results[i]++;
+}
+
+void
+f1 ()
+{
+#pragma omp parallel for default(none) shared(a)
+ for (auto i : a)
+ baz (i);
+}
+
+void
+f2 ()
+{
+#pragma omp parallel for default(none) shared(a)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f3 ()
+{
+#pragma omp parallel for collapse(3) default(none) shared(b, c)
+ for (auto &i : b)
+ for (int j = 9; j < 10; j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+void
+f4 (J<int> j)
+{
+#pragma omp parallel for default(none) shared(j, a)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f5 ()
+{
+#pragma omp parallel for simd default(none) shared(d, results)
+ for (auto i : d)
+ results[i % 1024] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+void
+f6 (J<K<int>> j)
+{
+#pragma omp parallel for default(none) shared(j, e)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f7 (J<L<int>> j)
+{
+#pragma omp parallel for default(none) shared(j, f)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+void
+f8 (J<K<int>> j)
+{
+#pragma omp parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f9 (J<L<int>> j)
+{
+#pragma omp parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f10 ()
+{
+#pragma omp parallel for default(none) shared(a)
+ for (auto i : a)
+ baz (i);
+}
+
+template <int N>
+void
+f11 ()
+{
+#pragma omp parallel for default(none) shared(a)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f12 ()
+{
+#pragma omp parallel for collapse(3) default(none) shared(a, b, c)
+ for (auto &i : b)
+ for (I<int> j = I<int> (&a[9]); j < I<int> (&a[10]); j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || *j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+template <typename T>
+void
+f13 (J<T> j)
+{
+#pragma omp parallel for default(none) shared(j, a)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f14 ()
+{
+#pragma omp parallel for simd default(none) shared(d, results)
+ for (auto i : d)
+ results[i % N] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+template <typename T>
+void
+f15 (J<K<T>> j)
+{
+#pragma omp parallel for default(none) shared(j, e)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <typename T>
+void
+f16 (J<L<T>> j)
+{
+#pragma omp parallel for default(none) shared(j, f)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f17 (J<K<int>> j)
+{
+#pragma omp parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <int N>
+void
+f18 (J<L<int>> j)
+{
+#pragma omp parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+#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 ()
+{
+ for (int i = 0; i < 2000; i++)
+ a[i] = i;
+ for (int i = 0; i < 40; i++)
+ b[i] = i;
+ for (int i = 0; i < 50; i++)
+ c[i] = i;
+ for (int i = 0; i < 1024; i++)
+ d[i] = i;
+ for (int i = 0; i < 1089; i++)
+ {
+ e[i].a = i;
+ e[i].b = 2 * i;
+ e[i].c = 3 * i;
+ }
+ for (int i = 0; i < 1093; i++)
+ {
+ f[i].a = i;
+ f[i].b = 4 * i;
+ f[i].c = 5 * i;
+ }
+ f1 ();
+ check (1);
+ f2 ();
+ check (1);
+ f3 ();
+ check (1);
+ f4 (J<int> (&a[14], &a[1803]));
+ check (i >= 14 && i < 1803);
+ f5 ();
+ check (i >= 0 && i < 1024);
+ f6 (J<K<int>> (&e[19], &e[1029]));
+ check (i >= 19 && i < 1029);
+ f7 (J<L<int>> (&f[15], &f[1091]));
+ check (i >= 15 && i < 1091);
+ f8 (J<K<int>> (&e[27], &e[1037]));
+ check (i >= 27 && i < 1037);
+ f9 (J<L<int>> (&f[1], &f[1012]));
+ check (i >= 1 && i < 1012);
+ f10 <0> ();
+ check (1);
+ f11 <1> ();
+ check (1);
+ f12 <2> ();
+ check (1);
+ f13 (J<int> (&a[24], &a[1703]));
+ check (i >= 24 && i < 1703);
+ f14 <1024> ();
+ check (i >= 0 && i < 1024);
+ f15 (J<K<int>> (&e[39], &e[929]));
+ check (i >= 39 && i < 929);
+ f16 (J<L<int>> (&f[17], &f[1071]));
+ check (i >= 17 && i < 1071);
+ f17 <3> (J<K<int>> (&e[7], &e[1017]));
+ check (i >= 7 && i < 1017);
+ f18 <5> (J<L<int>> (&f[121], &f[1010]));
+ check (i >= 121 && i < 1010);
+}
diff --git a/libgomp/testsuite/libgomp.c++/for-24.C b/libgomp/testsuite/libgomp.c++/for-24.C
new file mode 100644
index 00000000000..99f74e46911
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/for-24.C
@@ -0,0 +1,425 @@
+// { dg-do run }
+// { dg-additional-options "-std=c++17" }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+#pragma omp declare target
+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; }
+
+struct K
+{
+ template <int N> int &get () { if (N == 0) return c; else if (N == 1) return b; return a; }
+ int a, b, c;
+};
+
+template <> struct std::tuple_size<K> { static constexpr int value = 3; };
+template <int N> struct std::tuple_element<N, K> { using type = int; };
+
+struct L
+{
+ int a, b, c;
+};
+
+int a[2000];
+long b[40];
+short c[50];
+int d[1024];
+K e[1089];
+L f[1093];
+
+int results[2000];
+
+template <typename T>
+void
+baz (I<T> &i)
+{
+ if (*i < 0 || *i >= 2000)
+ abort ();
+ results[*i]++;
+}
+
+void
+baz (int i)
+{
+ if (i < 0 || i >= 2000)
+ abort ();
+ results[i]++;
+}
+
+void
+f1 ()
+{
+#pragma omp distribute parallel for default(none) shared(a)
+ for (auto i : a)
+ baz (i);
+}
+
+void
+f2 ()
+{
+#pragma omp distribute parallel for default(none) shared(a)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f3 ()
+{
+#pragma omp distribute parallel for collapse(3) default(none) shared(b, c)
+ for (auto &i : b)
+ for (int j = 9; j < 10; j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+void
+f4 (J<int> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, a)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f5 ()
+{
+#pragma omp distribute parallel for simd default(none) shared(d, results)
+ for (auto i : d)
+ results[i % 1024] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+void
+f6 (J<K> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, e)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f7 (J<L> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, f)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+void
+f8 (J<K> j)
+{
+#pragma omp distribute parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f9 (J<L> j)
+{
+#pragma omp distribute parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f10 ()
+{
+#pragma omp distribute parallel for default(none) shared(a)
+ for (auto i : a)
+ baz (i);
+}
+
+template <int N>
+void
+f11 ()
+{
+#pragma omp distribute parallel for default(none) shared(a)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f12 ()
+{
+#pragma omp distribute parallel for collapse(3) default(none) shared(a, b, c)
+ for (auto &i : b)
+ for (I<int> j = I<int> (&a[9]); j < I<int> (&a[10]); j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || *j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+template <typename T>
+void
+f13 (J<T> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, a)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f14 ()
+{
+#pragma omp distribute parallel for simd default(none) shared(d, results)
+ for (auto i : d)
+ results[i % N] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+template <typename T>
+void
+f15 (J<T> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, e)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <typename T>
+void
+f16 (J<T> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, f)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f17 (J<K> j)
+{
+#pragma omp distribute parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <int N>
+void
+f18 (J<L> j)
+{
+#pragma omp distribute parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+#pragma omp end declare target
+
+#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 ()
+{
+ for (int i = 0; i < 2000; i++)
+ a[i] = i;
+ for (int i = 0; i < 40; i++)
+ b[i] = i;
+ for (int i = 0; i < 50; i++)
+ c[i] = i;
+ for (int i = 0; i < 1024; i++)
+ d[i] = i;
+ for (int i = 0; i < 1089; i++)
+ {
+ e[i].a = i;
+ e[i].b = 2 * i;
+ e[i].c = 3 * i;
+ }
+ for (int i = 0; i < 1093; i++)
+ {
+ f[i].a = i;
+ f[i].b = 4 * i;
+ f[i].c = 5 * i;
+ }
+ #pragma omp target update to (a, b, c, d, e, f)
+ #pragma omp target teams map (always, tofrom: results)
+ f1 ();
+ check (1);
+ #pragma omp target teams map (always, tofrom: results)
+ f2 ();
+ check (1);
+ #pragma omp target teams map (always, tofrom: results)
+ f3 ();
+ check (1);
+ #pragma omp target teams map (always, tofrom: results)
+ f4 (J<int> (&a[14], &a[1803]));
+ check (i >= 14 && i < 1803);
+ #pragma omp target teams map (always, tofrom: results)
+ f5 ();
+ check (i >= 0 && i < 1024);
+ #pragma omp target teams map (always, tofrom: results)
+ f6 (J<K> (&e[19], &e[1029]));
+ check (i >= 19 && i < 1029);
+ #pragma omp target teams map (always, tofrom: results)
+ f7 (J<L> (&f[15], &f[1091]));
+ check (i >= 15 && i < 1091);
+ #pragma omp target teams map (always, tofrom: results)
+ f8 (J<K> (&e[27], &e[1037]));
+ check (i >= 27 && i < 1037);
+ #pragma omp target teams map (always, tofrom: results)
+ f9 (J<L> (&f[1], &f[1012]));
+ check (i >= 1 && i < 1012);
+ #pragma omp target teams map (always, tofrom: results)
+ f10 <0> ();
+ check (1);
+ #pragma omp target teams map (always, tofrom: results)
+ f11 <1> ();
+ check (1);
+ #pragma omp target teams map (always, tofrom: results)
+ f12 <2> ();
+ check (1);
+ #pragma omp target teams map (always, tofrom: results)
+ f13 (J<int> (&a[24], &a[1703]));
+ check (i >= 24 && i < 1703);
+ #pragma omp target teams map (always, tofrom: results)
+ f14 <1024> ();
+ check (i >= 0 && i < 1024);
+ #pragma omp target teams map (always, tofrom: results)
+ f15 (J<K> (&e[39], &e[929]));
+ check (i >= 39 && i < 929);
+ #pragma omp target teams map (always, tofrom: results)
+ f16 (J<L> (&f[17], &f[1071]));
+ check (i >= 17 && i < 1071);
+ #pragma omp target teams map (always, tofrom: results)
+ f17 <3> (J<K> (&e[7], &e[1017]));
+ check (i >= 7 && i < 1017);
+ #pragma omp target teams map (always, tofrom: results)
+ f18 <5> (J<L> (&f[121], &f[1010]));
+ check (i >= 121 && i < 1010);
+}
diff --git a/libgomp/testsuite/libgomp.c++/for-25.C b/libgomp/testsuite/libgomp.c++/for-25.C
new file mode 100644
index 00000000000..3fecb488787
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/for-25.C
@@ -0,0 +1,420 @@
+// { dg-do run }
+// { dg-additional-options "-std=c++17" }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+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; }
+
+template <typename T>
+class K
+{
+public:
+ K ();
+ ~K ();
+ template <int N> T &get () { if (N == 0) return c; else if (N == 1) return b; return a; }
+ T a, b, c;
+};
+
+template <typename T> K<T>::K () : a {}, b {}, c {} {}
+template <typename T> K<T>::~K () {}
+template <typename T> struct std::tuple_size<K<T>> { static constexpr int value = 3; };
+template <typename T, int N> struct std::tuple_element<N, K<T>> { using type = T; };
+
+template <typename T>
+class L
+{
+public:
+ L ();
+ ~L ();
+ T a, b, c;
+};
+
+template <typename T> L<T>::L () : a {}, b {}, c {} {}
+template <typename T> L<T>::~L () {}
+
+int a[2000];
+long b[40];
+short c[50];
+int d[1024];
+K<int> e[1089];
+L<int> f[1093];
+int results[2000];
+
+template <typename T>
+void
+baz (I<T> &i)
+{
+ if (*i < 0 || *i >= 2000)
+ abort ();
+ results[*i]++;
+}
+
+void
+baz (int i)
+{
+ if (i < 0 || i >= 2000)
+ abort ();
+ results[i]++;
+}
+
+void
+f1 ()
+{
+#pragma omp taskloop default(none) shared(a)
+ for (auto i : a)
+ baz (i);
+}
+
+void
+f2 ()
+{
+#pragma omp taskloop default(none) shared(a)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f3 ()
+{
+#pragma omp taskloop collapse(3) default(none) shared(b, c)
+ for (auto &i : b)
+ for (int j = 9; j < 10; j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+void
+f4 (J<int> j)
+{
+#pragma omp taskloop default(none) shared(j, a)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f5 ()
+{
+#pragma omp taskloop simd default(none) shared(d, results)
+ for (auto i : d)
+ results[i % 1024] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+void
+f6 (J<K<int>> j)
+{
+#pragma omp taskloop default(none) shared(j, e)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f7 (J<L<int>> j)
+{
+#pragma omp taskloop default(none) shared(j, f)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+void
+f8 (J<K<int>> j)
+{
+#pragma omp taskloop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f9 (J<L<int>> j)
+{
+#pragma omp taskloop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f10 ()
+{
+#pragma omp taskloop default(none) shared(a)
+ for (auto i : a)
+ baz (i);
+}
+
+template <int N>
+void
+f11 ()
+{
+#pragma omp taskloop default(none) shared(a)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f12 ()
+{
+#pragma omp taskloop collapse(3) default(none) shared(a, b, c)
+ for (auto &i : b)
+ for (I<int> j = I<int> (&a[9]); j < I<int> (&a[10]); j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || *j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+template <typename T>
+void
+f13 (J<T> j)
+{
+#pragma omp taskloop default(none) shared(j, a)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f14 ()
+{
+#pragma omp taskloop simd default(none) shared(d, results)
+ for (auto i : d)
+ results[i % N] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+template <typename T>
+void
+f15 (J<K<T>> j)
+{
+#pragma omp taskloop default(none) shared(j, e)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <typename T>
+void
+f16 (J<L<T>> j)
+{
+#pragma omp taskloop default(none) shared(j, f)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f17 (J<K<int>> j)
+{
+#pragma omp taskloop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <int N>
+void
+f18 (J<L<int>> j)
+{
+#pragma omp taskloop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+#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 ()
+{
+ for (int i = 0; i < 2000; i++)
+ a[i] = i;
+ for (int i = 0; i < 40; i++)
+ b[i] = i;
+ for (int i = 0; i < 50; i++)
+ c[i] = i;
+ for (int i = 0; i < 1024; i++)
+ d[i] = i;
+ for (int i = 0; i < 1089; i++)
+ {
+ e[i].a = i;
+ e[i].b = 2 * i;
+ e[i].c = 3 * i;
+ }
+ for (int i = 0; i < 1093; i++)
+ {
+ f[i].a = i;
+ f[i].b = 4 * i;
+ f[i].c = 5 * i;
+ }
+ #pragma omp parallel
+ #pragma omp single
+ {
+ f1 ();
+ check (1);
+ f2 ();
+ check (1);
+ f3 ();
+ check (1);
+ f4 (J<int> (&a[14], &a[1803]));
+ check (i >= 14 && i < 1803);
+ f5 ();
+ check (i >= 0 && i < 1024);
+ f6 (J<K<int>> (&e[19], &e[1029]));
+ check (i >= 19 && i < 1029);
+ f7 (J<L<int>> (&f[15], &f[1091]));
+ check (i >= 15 && i < 1091);
+ f8 (J<K<int>> (&e[27], &e[1037]));
+ check (i >= 27 && i < 1037);
+ f9 (J<L<int>> (&f[1], &f[1012]));
+ check (i >= 1 && i < 1012);
+ f10 <0> ();
+ check (1);
+ f11 <1> ();
+ check (1);
+ f12 <2> ();
+ check (1);
+ f13 (J<int> (&a[24], &a[1703]));
+ check (i >= 24 && i < 1703);
+ f14 <1024> ();
+ check (i >= 0 && i < 1024);
+ f15 (J<K<int>> (&e[39], &e[929]));
+ check (i >= 39 && i < 929);
+ f16 (J<L<int>> (&f[17], &f[1071]));
+ check (i >= 17 && i < 1071);
+ f17 <3> (J<K<int>> (&e[7], &e[1017]));
+ check (i >= 7 && i < 1017);
+ f18 <5> (J<L<int>> (&f[121], &f[1010]));
+ check (i >= 121 && i < 1010);
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/for-26.C b/libgomp/testsuite/libgomp.c++/for-26.C
new file mode 100644
index 00000000000..bb7ae11d3cc
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/for-26.C
@@ -0,0 +1,422 @@
+// { dg-do run }
+// { dg-additional-options "-std=c++17" }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+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; }
+
+struct K
+{
+ template <int N> int &get () { if (N == 0) return c; else if (N == 1) return b; return a; }
+ int a, b, c;
+};
+
+template <> struct std::tuple_size<K> { static constexpr int value = 3; };
+template <int N> struct std::tuple_element<N, K> { using type = int; };
+
+struct L
+{
+ int a, b, c;
+};
+
+int a[2000];
+long b[40];
+short c[50];
+int d[1024];
+K e[1089];
+L f[1093];
+
+int results[2000];
+
+template <typename T>
+void
+baz (I<T> &i)
+{
+ if (*i < 0 || *i >= 2000)
+ abort ();
+ results[*i]++;
+}
+
+void
+baz (int i)
+{
+ if (i < 0 || i >= 2000)
+ abort ();
+ results[i]++;
+}
+
+void
+f1 ()
+{
+#pragma omp distribute parallel for default(none) shared(a)
+ for (auto i : a)
+ baz (i);
+}
+
+void
+f2 ()
+{
+#pragma omp distribute parallel for default(none) shared(a)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f3 ()
+{
+#pragma omp distribute parallel for collapse(3) default(none) shared(b, c)
+ for (auto &i : b)
+ for (int j = 9; j < 10; j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+void
+f4 (J<int> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, a)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f5 ()
+{
+#pragma omp distribute parallel for simd default(none) shared(d, results)
+ for (auto i : d)
+ results[i % 1024] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+void
+f6 (J<K> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, e)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f7 (J<L> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, f)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+void
+f8 (J<K> j)
+{
+#pragma omp distribute parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f9 (J<L> j)
+{
+#pragma omp distribute parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f10 ()
+{
+#pragma omp distribute parallel for default(none) shared(a)
+ for (auto i : a)
+ baz (i);
+}
+
+template <int N>
+void
+f11 ()
+{
+#pragma omp distribute parallel for default(none) shared(a)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f12 ()
+{
+#pragma omp distribute parallel for collapse(3) default(none) shared(a, b, c)
+ for (auto &i : b)
+ for (I<int> j = I<int> (&a[9]); j < I<int> (&a[10]); j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || *j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+template <typename T>
+void
+f13 (J<T> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, a)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f14 ()
+{
+#pragma omp distribute parallel for simd default(none) shared(d, results)
+ for (auto i : d)
+ results[i % N] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+template <typename T>
+void
+f15 (J<T> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, e)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <typename T>
+void
+f16 (J<T> j)
+{
+#pragma omp distribute parallel for default(none) shared(j, f)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f17 (J<K> j)
+{
+#pragma omp distribute parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <int N>
+void
+f18 (J<L> j)
+{
+#pragma omp distribute parallel for default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+#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 ()
+{
+ for (int i = 0; i < 2000; i++)
+ a[i] = i;
+ for (int i = 0; i < 40; i++)
+ b[i] = i;
+ for (int i = 0; i < 50; i++)
+ c[i] = i;
+ for (int i = 0; i < 1024; i++)
+ d[i] = i;
+ for (int i = 0; i < 1089; i++)
+ {
+ e[i].a = i;
+ e[i].b = 2 * i;
+ e[i].c = 3 * i;
+ }
+ for (int i = 0; i < 1093; i++)
+ {
+ f[i].a = i;
+ f[i].b = 4 * i;
+ f[i].c = 5 * i;
+ }
+ #pragma omp teams
+ f1 ();
+ check (1);
+ #pragma omp teams
+ f2 ();
+ check (1);
+ #pragma omp teams
+ f3 ();
+ check (1);
+ #pragma omp teams
+ f4 (J<int> (&a[14], &a[1803]));
+ check (i >= 14 && i < 1803);
+ #pragma omp teams
+ f5 ();
+ check (i >= 0 && i < 1024);
+ #pragma omp teams
+ f6 (J<K> (&e[19], &e[1029]));
+ check (i >= 19 && i < 1029);
+ #pragma omp teams
+ f7 (J<L> (&f[15], &f[1091]));
+ check (i >= 15 && i < 1091);
+ #pragma omp teams
+ f8 (J<K> (&e[27], &e[1037]));
+ check (i >= 27 && i < 1037);
+ #pragma omp teams
+ f9 (J<L> (&f[1], &f[1012]));
+ check (i >= 1 && i < 1012);
+ #pragma omp teams
+ f10 <0> ();
+ check (1);
+ #pragma omp teams
+ f11 <1> ();
+ check (1);
+ #pragma omp teams
+ f12 <2> ();
+ check (1);
+ #pragma omp teams
+ f13 (J<int> (&a[24], &a[1703]));
+ check (i >= 24 && i < 1703);
+ #pragma omp teams
+ f14 <1024> ();
+ check (i >= 0 && i < 1024);
+ #pragma omp teams
+ f15 (J<K> (&e[39], &e[929]));
+ check (i >= 39 && i < 929);
+ #pragma omp teams
+ f16 (J<L> (&f[17], &f[1071]));
+ check (i >= 17 && i < 1071);
+ #pragma omp teams
+ f17 <3> (J<K> (&e[7], &e[1017]));
+ check (i >= 7 && i < 1017);
+ #pragma omp teams
+ f18 <5> (J<L> (&f[121], &f[1010]));
+ check (i >= 121 && i < 1010);
+}
diff --git a/libgomp/testsuite/libgomp.c++/for-27.C b/libgomp/testsuite/libgomp.c++/for-27.C
new file mode 100644
index 00000000000..7dca4305f85
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/for-27.C
@@ -0,0 +1,169 @@
+// { dg-do run }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+int a[2000];
+
+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]++;
+}
+
+static inline void
+baz (int i)
+{
+ results[i]++;
+}
+
+void
+f1 ()
+{
+#pragma omp simd
+ for (auto i : a)
+ baz (i);
+}
+
+void
+f2 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp distribute parallel for
+ for (i = x; i <= y; i += 6)
+ baz (*i);
+}
+
+void
+f3 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp distribute parallel for private (i)
+ for (i = x; i < y - 1; i = 1 - 6 + 7 + i)
+ baz (*i);
+}
+
+void
+f4 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp teams distribute parallel for lastprivate (i)
+ for (i = x + 2000 - 64; i > y + 10; --i)
+ baz (*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 ()
+{
+ for (int i = 0; i < 2000; i++)
+ a[i] = i;
+ f1 ();
+ check (1);
+ #pragma omp teams
+ f2 (&a[10], &a[1990]);
+ check (i >= 10 && i <= 1990 && (i - 10) % 6 == 0);
+ #pragma omp teams
+ f3 (&a[0], &a[1999]);
+ check (i < 1998 && (i & 1) == 0);
+ f4 (&a[0], &a[30]);
+ check (i > 40 && i <= 2000 - 64);
+}
diff --git a/libgomp/testsuite/libgomp.c++/lastprivate-conditional-1.C b/libgomp/testsuite/libgomp.c++/lastprivate-conditional-1.C
new file mode 100644
index 00000000000..e0ec5d5209f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/lastprivate-conditional-1.C
@@ -0,0 +1,62 @@
+extern "C" void abort ();
+int w;
+struct S { int s, &t; S () : s (0), t (w) {}; void foo (short &); bool bar (int, int); void baz (short &); };
+
+bool
+S::bar (int i, int q)
+{
+ switch (q)
+ {
+ case 0: return (i % 17) == 7;
+ case 1: return (i % 19) == 2;
+ case 2: return (i % 23) == 5;
+ default: abort ();
+ }
+}
+
+void
+S::foo (short &x)
+{
+ #pragma omp for lastprivate (conditional: x, s, t)
+ for (int i = 0; i < 1025; ++i)
+ {
+ if (bar (i, 0))
+ x = i;
+ if (bar (i, 1))
+ s = i + 3;
+ if (bar (i, 2))
+ t = i + 6;
+ }
+}
+
+void
+S::baz (short &x)
+{
+ #pragma omp parallel for lastprivate (conditional: x, s, t) collapse (3)
+ for (int i = 0; i < 15; ++i)
+ for (int j = -4; j < 9; j++)
+ for (int k = 12; k > 7; --k)
+ {
+ int l = (k - 8) + (j + 4) * 5 + i * 13 * 5;
+ if (bar (l, 0))
+ x = l;
+ if (bar (l, 1))
+ s = l + 3;
+ if (bar (l, 2))
+ t = l + 6;
+ }
+}
+
+int
+main ()
+{
+ short x;
+ S s;
+ #pragma omp parallel
+ s.foo (x);
+ if (x != 1010 || s.s != 1012 || s.t != 1023)
+ abort ();
+ s.baz (x);
+ if (x != 959 || s.s != 974 || s.t != 977)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/lastprivate-conditional-2.C b/libgomp/testsuite/libgomp.c++/lastprivate-conditional-2.C
new file mode 100644
index 00000000000..742ef2151db
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/lastprivate-conditional-2.C
@@ -0,0 +1,104 @@
+extern "C" void abort ();
+int w;
+struct S {
+ int s, &t;
+ int *p;
+ S (int *x) : s (0), t (w), p(x) {};
+ void foo (short &);
+ void bar (short &);
+ void baz (short &);
+ void qux (short &);
+};
+
+void
+S::foo (short &x)
+{
+ #pragma omp simd lastprivate (conditional: x, s, t)
+ for (int i = 0; i < 1025; ++i)
+ {
+ if (p[i])
+ x = i;
+ if (p[i + 1025])
+ s = i + 3;
+ if (p[i + 2 * 1025])
+ t = i + 6;
+ }
+}
+
+void
+S::bar (short &x)
+{
+ #pragma omp simd lastprivate (conditional: x, s, t) collapse (3) if (0)
+ for (int i = 0; i < 15; ++i)
+ for (int j = -4; j < 9; j++)
+ for (int k = 12; k > 7; --k)
+ {
+ int l = (k - 8) + (j + 4) * 5 + i * 13 * 5;
+ if (p[l])
+ x = l;
+ if (p[l + 1025])
+ s = l + 3;
+ if (p[l + 1025 * 2])
+ t = l + 6;
+ }
+}
+
+void
+S::baz (short &x)
+{
+ #pragma omp parallel for simd lastprivate (conditional: x, s, t) if (simd: 0)
+ for (int i = 0; i < 1025; ++i)
+ {
+ if (p[i])
+ x = i;
+ if (p[i + 1025])
+ s = i + 3;
+ if (p[i + 2 * 1025])
+ t = i + 6;
+ }
+}
+
+void
+S::qux (short &x)
+{
+ #pragma omp for simd lastprivate (conditional: x, s, t) collapse (3) schedule (simd: guided, 8)
+ for (int i = 0; i < 15; ++i)
+ for (int j = -4; j < 9; j++)
+ for (int k = 12; k > 7; --k)
+ {
+ int l = (k - 8) + (j + 4) * 5 + i * 13 * 5;
+ if (p[l])
+ x = l;
+ if (p[l + 1025])
+ s = l + 3;
+ if (p[l + 1025 * 2])
+ t = l + 6;
+ }
+}
+
+int
+main ()
+{
+ short x;
+ int a[3 * 1025];
+ for (int i = 0; i < 1025; ++i)
+ {
+ a[i] = ((i % 17) == 7);
+ a[1025 + i] = ((i % 19) == 2);
+ a[2 * 1025 + i] = ((i % 23) == 5);
+ }
+ S s = a;
+ s.foo (x);
+ if (x != 1010 || s.s != 1012 || s.t != 1023)
+ abort ();
+ s.bar (x);
+ if (x != 959 || s.s != 974 || s.t != 977)
+ abort ();
+ #pragma omp parallel
+ s.baz (x);
+ if (x != 1010 || s.s != 1012 || s.t != 1023)
+ abort ();
+ s.qux (x);
+ if (x != 959 || s.s != 974 || s.t != 977)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/loop-13.C b/libgomp/testsuite/libgomp.c++/loop-13.C
new file mode 100644
index 00000000000..663212c1f74
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/loop-13.C
@@ -0,0 +1,298 @@
+// { 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>
+static inline void
+baz (I<T> &i)
+{
+ results[*i]++;
+}
+
+void
+f1 (const I<int> &x, const I<int> &y)
+{
+#pragma omp parallel loop order(concurrent)
+ 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 loop private(i) bind(parallel)
+ 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 loop bind(thread) order(concurrent)
+ 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 loop 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 loop bind(teams)
+ 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)
+{
+ I<int> i;
+#pragma omp teams loop order(concurrent)
+ for (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 master
+#pragma omp loop
+ 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 loop
+ 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)
+{
+ I<T> i;
+#pragma omp loop bind(teams) private(i)
+ for (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 loop bind(thread) private(i)
+ 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 loop
+ for (T i = x; i <= y; i += 3)
+ baz (i);
+#pragma omp single
+ {
+ T j = y + 3;
+ baz (j);
+ }
+ }
+}
+
+template <typename T>
+void
+f12 (const T &x, const T &y)
+{
+ T i;
+#pragma omp loop lastprivate(i) bind(thread)
+ 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)
+ {
+ T i;
+#pragma omp teams loop order(concurrent) bind(teams) lastprivate (i)
+ for (i = x; i <= y + N; i += N)
+ baz (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);
+ #pragma omp parallel
+ 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);
+ #pragma omp teams
+ 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);
+ #pragma omp parallel num_threads(2)
+ 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);
+ #pragma omp teams
+ 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);
+ #pragma omp teams
+ 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);
+}
diff --git a/libgomp/testsuite/libgomp.c++/loop-14.C b/libgomp/testsuite/libgomp.c++/loop-14.C
new file mode 100644
index 00000000000..191ab681b3c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/loop-14.C
@@ -0,0 +1,301 @@
+// { 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>
+static inline void
+baz (I<T> &i)
+{
+ results[*i]++;
+}
+
+I<int>
+f1 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp parallel shared (i)
+ {
+ #pragma omp loop lastprivate (i) order(concurrent)
+ 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 loop bind(parallel)
+ 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 teams
+ #pragma omp loop order(concurrent)
+ 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 teams loop 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 loop lastprivate (i) bind(thread)
+ 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 loop bind(thread)
+ 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 for 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 loop 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 loop bind(parallel)
+ 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 loop 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 loop bind(thread)
+ 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 teams loop
+ 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);
+ #pragma omp parallel
+ 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);
+}
diff --git a/libgomp/testsuite/libgomp.c++/loop-15.C b/libgomp/testsuite/libgomp.c++/loop-15.C
new file mode 100644
index 00000000000..b523b9bd2f9
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/loop-15.C
@@ -0,0 +1,417 @@
+// { dg-do run }
+// { dg-additional-options "-std=c++17" }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+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; }
+
+template <typename T>
+class K
+{
+public:
+ K ();
+ ~K ();
+ template <int N> T &get () { if (N == 0) return c; else if (N == 1) return b; return a; }
+ T a, b, c;
+};
+
+template <typename T> K<T>::K () : a {}, b {}, c {} {}
+template <typename T> K<T>::~K () {}
+template <typename T> struct std::tuple_size<K<T>> { static constexpr int value = 3; };
+template <typename T, int N> struct std::tuple_element<N, K<T>> { using type = T; };
+
+template <typename T>
+class L
+{
+public:
+ L ();
+ ~L ();
+ T a, b, c;
+};
+
+template <typename T> L<T>::L () : a {}, b {}, c {} {}
+template <typename T> L<T>::~L () {}
+
+int a[2000];
+long b[40];
+short c[50];
+int d[1024];
+K<int> e[1089];
+L<int> f[1093];
+int results[2000];
+
+template <typename T>
+static inline void
+baz (I<T> &i)
+{
+ results[*i]++;
+}
+
+static inline void
+baz (int i)
+{
+ results[i]++;
+}
+
+void
+f1 ()
+{
+#pragma omp parallel loop shared(a) default(none)
+ for (auto i : a)
+ baz (i);
+}
+
+void
+f2 ()
+{
+#pragma omp loop order(concurrent) bind(parallel)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f3 ()
+{
+#pragma omp teams loop collapse(3) default(none) shared(b, c)
+ for (auto &i : b)
+ for (int j = 9; j < 10; j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+void
+f4 (J<int> j)
+{
+#pragma omp loop bind(teams)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f5 ()
+{
+#pragma omp loop bind(thread)
+ for (auto i : d)
+ results[i % 1024] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+void
+f6 (J<K<int>> j)
+{
+#pragma omp loop bind(parallel)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f7 (J<L<int>> j)
+{
+#pragma omp parallel loop default(none) shared(j, f)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+void
+f8 (J<K<int>> j)
+{
+#pragma omp parallel loop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f9 (J<L<int>> j)
+{
+#pragma omp teams loop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f10 ()
+{
+#pragma omp loop bind(teams)
+ for (auto i : a)
+ baz (i);
+}
+
+template <int N>
+void
+f11 ()
+{
+#pragma omp loop bind(thread)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f12 ()
+{
+#pragma omp parallel loop collapse(3) default(none) shared(a, b, c) bind(parallel)
+ for (auto &i : b)
+ for (I<int> j = I<int> (&a[9]); j < I<int> (&a[10]); j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || *j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+template <typename T>
+void
+f13 (J<T> j)
+{
+#pragma omp loop bind(thread)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f14 ()
+{
+#pragma omp parallel loop default(none) shared(d, results)
+ for (auto i : d)
+ results[i % N] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+template <typename T>
+void
+f15 (J<K<T>> j)
+{
+#pragma omp parallel loop default(none) shared(j, e) bind(parallel)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <typename T>
+void
+f16 (J<L<T>> j)
+{
+#pragma omp loop bind(parallel)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f17 (J<K<int>> j)
+{
+#pragma omp parallel loop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <int N>
+void
+f18 (J<L<int>> j)
+{
+#pragma omp teams loop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+#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 ()
+{
+ for (int i = 0; i < 2000; i++)
+ a[i] = i;
+ for (int i = 0; i < 40; i++)
+ b[i] = i;
+ for (int i = 0; i < 50; i++)
+ c[i] = i;
+ for (int i = 0; i < 1024; i++)
+ d[i] = i;
+ for (int i = 0; i < 1089; i++)
+ {
+ e[i].a = i;
+ e[i].b = 2 * i;
+ e[i].c = 3 * i;
+ }
+ for (int i = 0; i < 1093; i++)
+ {
+ f[i].a = i;
+ f[i].b = 4 * i;
+ f[i].c = 5 * i;
+ }
+ f1 ();
+ check (1);
+ #pragma omp parallel
+ f2 ();
+ check (1);
+ f3 ();
+ check (1);
+ #pragma omp teams
+ f4 (J<int> (&a[14], &a[1803]));
+ check (i >= 14 && i < 1803);
+ f5 ();
+ check (i >= 0 && i < 1024);
+ #pragma omp parallel
+ f6 (J<K<int>> (&e[19], &e[1029]));
+ check (i >= 19 && i < 1029);
+ f7 (J<L<int>> (&f[15], &f[1091]));
+ check (i >= 15 && i < 1091);
+ f8 (J<K<int>> (&e[27], &e[1037]));
+ check (i >= 27 && i < 1037);
+ f9 (J<L<int>> (&f[1], &f[1012]));
+ check (i >= 1 && i < 1012);
+ #pragma omp teams
+ f10 <0> ();
+ check (1);
+ f11 <1> ();
+ check (1);
+ f12 <2> ();
+ check (1);
+ f13 (J<int> (&a[24], &a[1703]));
+ check (i >= 24 && i < 1703);
+ f14 <1024> ();
+ check (i >= 0 && i < 1024);
+ f15 (J<K<int>> (&e[39], &e[929]));
+ check (i >= 39 && i < 929);
+ #pragma omp parallel
+ f16 (J<L<int>> (&f[17], &f[1071]));
+ check (i >= 17 && i < 1071);
+ f17 <3> (J<K<int>> (&e[7], &e[1017]));
+ check (i >= 7 && i < 1017);
+ f18 <5> (J<L<int>> (&f[121], &f[1010]));
+ check (i >= 121 && i < 1010);
+}
diff --git a/libgomp/testsuite/libgomp.c++/pr88988.C b/libgomp/testsuite/libgomp.c++/pr88988.C
new file mode 100644
index 00000000000..9dea35d15fe
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/pr88988.C
@@ -0,0 +1,28 @@
+// PR c++/88988
+// { dg-do compile }
+// { dg-additional-options "-std=c++14" }
+
+extern "C" void abort ();
+
+template <typename T>
+struct A {
+ A () : a(), b()
+ {
+ [&] ()
+ {
+#pragma omp task firstprivate (a) shared (b)
+ b = ++a;
+#pragma omp taskwait
+ } ();
+ }
+
+ T a, b;
+};
+
+int
+main ()
+{
+ A<int> x;
+ if (x.a != 0 || x.b != 1)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-1.C b/libgomp/testsuite/libgomp.c++/scan-1.C
new file mode 100644
index 00000000000..d148dac924b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-1.C
@@ -0,0 +1,151 @@
+// { dg-require-effective-target size32plus }
+
+extern "C" void abort ();
+
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ int s;
+};
+
+S::S () : s (0)
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+ s = x.s;
+}
+
+S &
+S::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+static inline void
+ini (S &x)
+{
+ x.s = 0;
+}
+
+S r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+__attribute__((noipa)) void
+foo (S *a, S *b)
+{
+ #pragma omp for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+bar (void)
+{
+ S s;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return S (s);
+}
+
+__attribute__((noipa)) void
+baz (S *a, S *b)
+{
+ #pragma omp parallel for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+qux (void)
+{
+ S s;
+ #pragma omp parallel for reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return S (s);
+}
+
+int
+main ()
+{
+ S s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (bar ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+ r.s = 0;
+ baz (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-10.C b/libgomp/testsuite/libgomp.c++/scan-10.C
new file mode 100644
index 00000000000..04b8796a24e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-10.C
@@ -0,0 +1,120 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+ #pragma omp for simd if (0) reduction (inscan, +:r) nowait
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for simd simdlen(1) reduction (inscan, +:s) nowait
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel for simd reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-11.C b/libgomp/testsuite/libgomp.c++/scan-11.C
new file mode 100644
index 00000000000..9e83effd077
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-11.C
@@ -0,0 +1,123 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+ #pragma omp for simd reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, foo:s) if (0)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+ #pragma omp parallel for simd simdlen (1) reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel for simd reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-12.C b/libgomp/testsuite/libgomp.c++/scan-12.C
new file mode 100644
index 00000000000..ee911578520
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-12.C
@@ -0,0 +1,154 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ int s;
+};
+
+S::S () : s (0)
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+ s = x.s;
+}
+
+S &
+S::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+static inline void
+ini (S &x)
+{
+ x.s = 0;
+}
+
+S r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+__attribute__((noipa)) void
+foo (S *a, S *b, S &r)
+{
+ #pragma omp for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+bar ()
+{
+ S s;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (S *a, S *b, S &r)
+{
+ #pragma omp parallel for simd if (simd: 0) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+qux ()
+{
+ S s;
+ #pragma omp parallel for simd reduction (inscan, plus:s) simdlen(1)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ S s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (bar ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+ r.s = 0;
+ baz (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-13.C b/libgomp/testsuite/libgomp.c++/scan-13.C
new file mode 100644
index 00000000000..613045768e7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-13.C
@@ -0,0 +1,162 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+
+template <typename T>
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ T s;
+};
+
+template <typename T>
+S<T>::S () : s (0)
+{
+}
+
+template <typename T>
+S<T>::~S ()
+{
+}
+
+template <typename T>
+S<T>::S (const S &x)
+{
+ s = x.s;
+}
+
+template <typename T>
+S<T> &
+S<T>::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+template <typename T>
+static inline void
+ini (S<T> &x)
+{
+ x.s = 0;
+}
+
+S<int> r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S<int>: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S<int>: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+template <typename T>
+__attribute__((noipa)) void
+foo (S<T> *a, S<T> *b)
+{
+ #pragma omp for simd if (0) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+template <typename T>
+__attribute__((noipa)) S<T>
+bar (void)
+{
+ S<T> s;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return S<T> (s);
+}
+
+__attribute__((noipa)) void
+baz (S<int> *a, S<int> *b)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+__attribute__((noipa)) S<int>
+qux (void)
+{
+ S<int> s;
+ #pragma omp parallel for simd simdlen(1) reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return S<int> (s);
+}
+
+int
+main ()
+{
+ S<int> s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (bar<int> ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+ r.s = 0;
+ baz (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-14.C b/libgomp/testsuite/libgomp.c++/scan-14.C
new file mode 100644
index 00000000000..8ee4354c7fc
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-14.C
@@ -0,0 +1,124 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+template <typename T, typename U>
+__attribute__((noipa)) void
+foo (T a, T b, U r)
+{
+ #pragma omp for simd if (0) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+template <typename T>
+__attribute__((noipa)) T
+bar ()
+{
+ T &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s) simdlen(1)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+template <typename T>
+__attribute__((noipa)) void
+baz (T *a, T *b, T &r)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r)
+ for (T i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+template <typename T>
+__attribute__((noipa)) int
+qux ()
+{
+ T s = q;
+ q = 0;
+ #pragma omp parallel for simd reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo<int *, int &> (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar<int> () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz<int> (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux<int &> () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-15.C b/libgomp/testsuite/libgomp.c++/scan-15.C
new file mode 100644
index 00000000000..69550af9d62
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-15.C
@@ -0,0 +1,122 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+ #pragma omp for simd reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, foo:s) nowait
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+ #pragma omp parallel for simd reduction (inscan, foo:r) if (simd: 0)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel for simd reduction (inscan, foo:s)simdlen(1)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-16.C b/libgomp/testsuite/libgomp.c++/scan-16.C
new file mode 100644
index 00000000000..3fb6135c343
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-16.C
@@ -0,0 +1,154 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ int s;
+};
+
+S::S () : s (0)
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+ s = x.s;
+}
+
+S &
+S::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+static inline void
+ini (S &x)
+{
+ x.s = 0;
+}
+
+S r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+__attribute__((noipa)) void
+foo (S *a, S *b, S &r)
+{
+ #pragma omp for simd simdlen (1) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+__attribute__((noipa)) S
+bar (void)
+{
+ S s;
+ #pragma omp parallel
+ #pragma omp for simd if (0) reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (S *a, S *b, S &r)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+__attribute__((noipa)) S
+qux (void)
+{
+ S s;
+ #pragma omp parallel for simd reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ S s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (bar ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+ r.s = 0;
+ baz (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-2.C b/libgomp/testsuite/libgomp.c++/scan-2.C
new file mode 100644
index 00000000000..94555ccde30
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-2.C
@@ -0,0 +1,116 @@
+// { dg-require-effective-target size32plus }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+ #pragma omp for reduction (inscan, +:r) nowait
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s) nowait
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+ #pragma omp parallel for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel for reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-3.C b/libgomp/testsuite/libgomp.c++/scan-3.C
new file mode 100644
index 00000000000..5e83958bf77
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-3.C
@@ -0,0 +1,119 @@
+// { dg-require-effective-target size32plus }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+ #pragma omp for reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+ #pragma omp parallel for reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel for reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-4.C b/libgomp/testsuite/libgomp.c++/scan-4.C
new file mode 100644
index 00000000000..fc2c682849f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-4.C
@@ -0,0 +1,150 @@
+// { dg-require-effective-target size32plus }
+
+extern "C" void abort ();
+
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ int s;
+};
+
+S::S () : s (0)
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+ s = x.s;
+}
+
+S &
+S::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+static inline void
+ini (S &x)
+{
+ x.s = 0;
+}
+
+S r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+__attribute__((noipa)) void
+foo (S *a, S *b, S &r)
+{
+ #pragma omp for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+bar ()
+{
+ S s;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (S *a, S *b, S &r)
+{
+ #pragma omp parallel for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+qux ()
+{
+ S s;
+ #pragma omp parallel for reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ S s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (bar ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+ r.s = 0;
+ baz (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-5.C b/libgomp/testsuite/libgomp.c++/scan-5.C
new file mode 100644
index 00000000000..5931a7fe14e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-5.C
@@ -0,0 +1,158 @@
+// { dg-require-effective-target size32plus }
+
+extern "C" void abort ();
+
+template <typename T>
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ T s;
+};
+
+template <typename T>
+S<T>::S () : s (0)
+{
+}
+
+template <typename T>
+S<T>::~S ()
+{
+}
+
+template <typename T>
+S<T>::S (const S &x)
+{
+ s = x.s;
+}
+
+template <typename T>
+S<T> &
+S<T>::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+template <typename T>
+static inline void
+ini (S<T> &x)
+{
+ x.s = 0;
+}
+
+S<int> r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S<int>: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S<int>: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+template <typename T>
+__attribute__((noipa)) void
+foo (S<T> *a, S<T> *b)
+{
+ #pragma omp for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+template <typename T>
+__attribute__((noipa)) S<T>
+bar (void)
+{
+ S<T> s;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return S<T> (s);
+}
+
+__attribute__((noipa)) void
+baz (S<int> *a, S<int> *b)
+{
+ #pragma omp parallel for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+__attribute__((noipa)) S<int>
+qux (void)
+{
+ S<int> s;
+ #pragma omp parallel for reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return S<int> (s);
+}
+
+int
+main ()
+{
+ S<int> s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (bar<int> ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+ r.s = 0;
+ baz (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-6.C b/libgomp/testsuite/libgomp.c++/scan-6.C
new file mode 100644
index 00000000000..46674e7a243
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-6.C
@@ -0,0 +1,120 @@
+// { dg-require-effective-target size32plus }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+template <typename T, typename U>
+__attribute__((noipa)) void
+foo (T a, T b, U r)
+{
+ #pragma omp for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+template <typename T>
+__attribute__((noipa)) T
+bar ()
+{
+ T &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+template <typename T>
+__attribute__((noipa)) void
+baz (T *a, T *b, T &r)
+{
+ #pragma omp parallel for reduction (inscan, +:r)
+ for (T i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+template <typename T>
+__attribute__((noipa)) int
+qux ()
+{
+ T s = q;
+ q = 0;
+ #pragma omp parallel for reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo<int *, int &> (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar<int> () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz<int> (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux<int &> () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-7.C b/libgomp/testsuite/libgomp.c++/scan-7.C
new file mode 100644
index 00000000000..ebeb20302bf
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-7.C
@@ -0,0 +1,118 @@
+// { dg-require-effective-target size32plus }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+ #pragma omp for reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, foo:s) nowait
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+ #pragma omp parallel for reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel for reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-8.C b/libgomp/testsuite/libgomp.c++/scan-8.C
new file mode 100644
index 00000000000..cfdfb6b7624
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-8.C
@@ -0,0 +1,150 @@
+// { dg-require-effective-target size32plus }
+
+extern "C" void abort ();
+
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ int s;
+};
+
+S::S () : s (0)
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+ s = x.s;
+}
+
+S &
+S::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+static inline void
+ini (S &x)
+{
+ x.s = 0;
+}
+
+S r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+__attribute__((noipa)) void
+foo (S *a, S *b, S &r)
+{
+ #pragma omp for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+__attribute__((noipa)) S
+bar (void)
+{
+ S s;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (S *a, S *b, S &r)
+{
+ #pragma omp parallel for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+__attribute__((noipa)) S
+qux (void)
+{
+ S s;
+ #pragma omp parallel for reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ S s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (bar ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+ r.s = 0;
+ baz (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-9.C b/libgomp/testsuite/libgomp.c++/scan-9.C
new file mode 100644
index 00000000000..cd08f76895b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-9.C
@@ -0,0 +1,155 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ int s;
+};
+
+S::S () : s (0)
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+ s = x.s;
+}
+
+S &
+S::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+static inline void
+ini (S &x)
+{
+ x.s = 0;
+}
+
+S r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+__attribute__((noipa)) void
+foo (S *a, S *b)
+{
+ #pragma omp for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+bar (void)
+{
+ S s;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return S (s);
+}
+
+__attribute__((noipa)) void
+baz (S *a, S *b)
+{
+ #pragma omp parallel for simd simdlen (1) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+qux (void)
+{
+ S s;
+ #pragma omp parallel for simd if (simd: 0) reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return S (s);
+}
+
+int
+main ()
+{
+ S s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (bar ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+ r.s = 0;
+ baz (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/target-22.C b/libgomp/testsuite/libgomp.c++/target-22.C
new file mode 100644
index 00000000000..9d9dea01c75
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/target-22.C
@@ -0,0 +1,99 @@
+extern "C" void abort (void);
+struct S { int e, f; };
+
+void
+foo (int *&p, int (&s)[5], int &t, S &u, int n)
+{
+ int a[4] = { 7, 8, 9, 10 }, b[n], c[3] = { 20, 21, 22 };
+ int *r = a + 1, *q = p - 1, i, err;
+ int v = 27;
+ S w = { 28, 29 };
+ for (i = 0; i < n; i++)
+ b[i] = 9 + i;
+ #pragma omp target data map(to:a) use_device_ptr(r) map(from:err)
+ #pragma omp target is_device_ptr(r) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 4; i++)
+ if (r[i - 1] != 7 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data use_device_ptr(p) map(from:err) map(to:q[:4])
+ #pragma omp target is_device_ptr(p) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 4; i++)
+ if (p[i - 1] != i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to:b) use_device_addr(b) map(from:err)
+ #pragma omp target is_device_ptr(b) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < n; i++)
+ if (b[i] != 9 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data use_device_addr(c) map(to:c) map(from:err)
+ #pragma omp target is_device_ptr(c) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 3; i++)
+ if (c[i] != 20 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to:s[:5]) use_device_addr(s) map(from:err)
+ #pragma omp target is_device_ptr(s) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 5; i++)
+ if (s[i] != 17 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data use_device_addr (v) map(to: v) map(to:u) use_device_addr (u) map(from:err)
+ {
+ int *z = &v;
+ S *x = &u;
+ #pragma omp target is_device_ptr (z, x) map(from:err)
+ {
+ err = 0;
+ if (*z != 27 || x->e != 25 || x->f != 26)
+ err = 1;
+ }
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to: t) use_device_addr (t, w) map (to: w) map(from:err)
+ {
+ int *z = &t;
+ S *x = &w;
+ #pragma omp target is_device_ptr (z) is_device_ptr (x) map(from:err)
+ {
+ err = 0;
+ if (*z != 24 || x->e != 28 || x->f != 29)
+ err = 1;
+ }
+ }
+ if (err)
+ abort ();
+}
+
+int
+main ()
+{
+ int a[4] = { 0, 1, 2, 3 }, b[5] = { 17, 18, 19, 20, 21 };
+ int *p = a + 1;
+ int t = 24;
+ S u = { 25, 26 };
+ foo (p, b, t, u, 9);
+}
diff --git a/libgomp/testsuite/libgomp.c++/target-9.C b/libgomp/testsuite/libgomp.c++/target-9.C
index a5d171b0b3d..83a61cf599b 100644
--- a/libgomp/testsuite/libgomp.c++/target-9.C
+++ b/libgomp/testsuite/libgomp.c++/target-9.C
@@ -1,10 +1,13 @@
extern "C" void abort (void);
+struct S { int e, f; };
void
-foo (int *&p, int (&s)[5], int n)
+foo (int *&p, int (&s)[5], int &t, S &u, int n)
{
int a[4] = { 7, 8, 9, 10 }, b[n], c[3] = { 20, 21, 22 };
int *r = a + 1, *q = p - 1, i, err;
+ int v = 27;
+ S w = { 28, 29 };
for (i = 0; i < n; i++)
b[i] = 9 + i;
#pragma omp target data map(to:a)
@@ -30,7 +33,7 @@ foo (int *&p, int (&s)[5], int n)
if (err)
abort ();
#pragma omp target data map(to:b)
- #pragma omp target data use_device_ptr(b) map(from:err)
+ #pragma omp target data use_device_addr(b) map(from:err)
#pragma omp target is_device_ptr(b) private(i) map(from:err)
{
err = 0;
@@ -41,7 +44,7 @@ foo (int *&p, int (&s)[5], int n)
if (err)
abort ();
#pragma omp target data map(to:c)
- #pragma omp target data use_device_ptr(c) map(from:err)
+ #pragma omp target data use_device_addr(c) map(from:err)
#pragma omp target is_device_ptr(c) private(i) map(from:err)
{
err = 0;
@@ -52,7 +55,7 @@ foo (int *&p, int (&s)[5], int n)
if (err)
abort ();
#pragma omp target data map(to:s[:5])
- #pragma omp target data use_device_ptr(s) map(from:err)
+ #pragma omp target data use_device_addr(s) map(from:err)
#pragma omp target is_device_ptr(s) private(i) map(from:err)
{
err = 0;
@@ -62,6 +65,34 @@ foo (int *&p, int (&s)[5], int n)
}
if (err)
abort ();
+ #pragma omp target data map(to: v) map(to:u)
+ #pragma omp target data use_device_addr (v) use_device_addr (u) map(from:err)
+ {
+ int *z = &v;
+ S *x = &u;
+ #pragma omp target is_device_ptr (z, x) map(from:err)
+ {
+ err = 0;
+ if (*z != 27 || x->e != 25 || x->f != 26)
+ err = 1;
+ }
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to: t, w)
+ #pragma omp target data use_device_addr (t, w) map(from:err)
+ {
+ int *z = &t;
+ S *x = &w;
+ #pragma omp target is_device_ptr (z) is_device_ptr (x) map(from:err)
+ {
+ err = 0;
+ if (*z != 24 || x->e != 28 || x->f != 29)
+ err = 1;
+ }
+ }
+ if (err)
+ abort ();
}
int
@@ -69,5 +100,7 @@ main ()
{
int a[4] = { 0, 1, 2, 3 }, b[5] = { 17, 18, 19, 20, 21 };
int *p = a + 1;
- foo (p, b, 9);
+ int t = 24;
+ S u = { 25, 26 };
+ foo (p, b, t, u, 9);
}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-1.C b/libgomp/testsuite/libgomp.c++/task-reduction-1.C
new file mode 100644
index 00000000000..b3e228e5310
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-1.C
@@ -0,0 +1,63 @@
+extern "C" void abort ();
+
+int as;
+int &a = as;
+long int bs = 1;
+long int &b = bs;
+
+void
+foo (int &c, long long int &d)
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (*: d) in_reduction (+: c) \
+ in_reduction (+: a) in_reduction (*: b)
+ {
+ a += 7;
+ b *= 2;
+ c += 9;
+ d *= 3;
+ }
+}
+
+int
+main ()
+{
+ int cs = 0;
+ int &c = cs;
+ long long int ds = 1;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ long long int &d = ds;
+ #pragma omp taskgroup task_reduction (+: a, c) task_reduction (*: b, d)
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b, d)
+ {
+ int j;
+ a += 7;
+ b *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b, d)
+ {
+ a += 7;
+ b *= 2;
+ c += 9;
+ d *= 3;
+ foo (c, d);
+ }
+ c += 9;
+ d *= 3;
+ }
+ }
+#define THREEP4 (3LL * 3LL * 3LL * 3LL)
+ if (d != (THREEP4 * THREEP4 * THREEP4 * THREEP4 * THREEP4 * THREEP4
+ * THREEP4))
+ abort ();
+ }
+ if (a != 28 * 7 || b != (1L << 28) || c != 28 * 9)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-10.C b/libgomp/testsuite/libgomp.c++/task-reduction-10.C
new file mode 100644
index 00000000000..0eb94c121be
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-10.C
@@ -0,0 +1,125 @@
+extern "C" void abort ();
+
+struct S { S (); S (long long int, int); ~S (); static int cnt1, cnt2, cnt3; long long int s; int t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long long int x, int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S as = { 0LL, 7 };
+S &a = as;
+S bs (1LL, 5);
+S &b = bs;
+
+void
+foo (S &c, S &d)
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: c) in_reduction (*: b, d) in_reduction (+: a)
+ {
+ a.s += 7;
+ b.s *= 2;
+ c.s += 9;
+ d.s *= 3;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+}
+
+void
+test ()
+{
+ S cs = { 0LL, 7 };
+ S &c = cs;
+ S ds (1LL, 5);
+ #pragma omp parallel if (0)
+ {
+ S &d = ds;
+ #pragma omp parallel reduction (task, +: a, c) reduction (task, *: b, d)
+ {
+ #pragma omp for
+ for (int i = 0; i < 4; i++)
+ #pragma omp task in_reduction (*: b, d) in_reduction (+: a, c)
+ {
+ int j;
+ a.s += 7;
+ b.s *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a) in_reduction (*: b) \
+ in_reduction (+: c) in_reduction (*: d)
+ {
+ a.s += 7;
+ b.s *= 2;
+ c.s += 9;
+ d.s *= 3;
+ foo (c, d);
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ c.s += 9;
+ d.s *= 3;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ }
+#define THREEP7 (3LL * 3LL * 3LL * 3LL * 3LL * 3LL * 3LL)
+ if (d.s != (THREEP7 * THREEP7 * THREEP7 * THREEP7) || d.t != 5)
+ abort ();
+ }
+ if (a.s != 28 * 7 || a.t != 7 || b.s != (1L << 28) || b.t != 5
+ || c.s != 28 * 9 || c.t != 7)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test ();
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-11.C b/libgomp/testsuite/libgomp.c++/task-reduction-11.C
new file mode 100644
index 00000000000..542bdd64da1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-11.C
@@ -0,0 +1,237 @@
+extern "C" void abort ();
+
+int as[2];
+int (&a)[2] = as;
+long long int bs[7] = { 9, 11, 1, 1, 1, 13, 15 };
+long long int (&b)[7] = bs;
+int es[3] = { 5, 0, 5 };
+int (&e)[3] = es;
+int fs[5] = { 6, 7, 0, 0, 9 };
+int (&f)[5] = fs;
+int gs[4] = { 1, 0, 0, 2 };
+int (&g)[4] = gs;
+int hs[3] = { 0, 1, 4 };
+int (&h)[3] = hs;
+int ks[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+int (&k)[4][2] = ks;
+long long *ss;
+long long *&s = ss;
+long long (*ts)[2];
+long long (*&t)[2] = ts;
+
+template <typename T>
+void
+foo (T &n, T *&c, long long int *&d, T (&m)[3], T *&r, T (&o)[4], T *&p, T (&q)[4][2])
+{
+ T i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0] += 7;
+ a[1] += 17;
+ b[2] *= 2;
+ b[4] *= 2;
+ c[0] += 6;
+ d[1] *= 2;
+ e[1] += 19;
+ f[2] += 21;
+ f[3] += 23;
+ g[1] += 25;
+ g[2] += 27;
+ h[0] += 29;
+ k[1][0] += 31;
+ k[2][1] += 33;
+ m[1] += 19;
+ r[2] += 21;
+ r[3] += 23;
+ o[1] += 25;
+ o[2] += 27;
+ p[0] += 29;
+ q[1][0] += 31;
+ q[2][1] += 33;
+ s[1] *= 2;
+ t[2][0] *= 2;
+ t[3][1] *= 2;
+ }
+}
+
+template <typename T>
+void
+test (T &n)
+{
+ T cs[2] = { 0, 0 };
+ T (&c)[2] = cs;
+ T ps[3] = { 0, 1, 4 };
+ T (&p)[3] = ps;
+ T qs[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+ T (&q)[4][2] = qs;
+ long long sb[4] = { 5, 1, 1, 6 };
+ long long tb[5][2] = { { 9, 10 }, { 11, 12 }, { 1, 1 }, { 1, 1 }, { 13, 14 } };
+ T ms[3] = { 5, 0, 5 };
+ T os[4] = { 1, 0, 0, 2 };
+ s = sb;
+ t = tb;
+ #pragma omp parallel if (0)
+ {
+ long long int ds[] = { 1, 1 };
+ long long int (&d)[2] = ds;
+ T (&m)[3] = ms;
+ T rs[5] = { 6, 7, 0, 0, 9 };
+ T (&r)[5] = rs;
+ T (&o)[4] = os;
+ #pragma omp parallel reduction (task,+: a, c) reduction (task,*: b[2 * n:3 * n], d) \
+ reduction (task,+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (task,+: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (task,*: t[2:2][:], s[1:n + 1])
+ {
+ #pragma omp for
+ for (int i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ T j;
+ a[0] += 2;
+ a[1] += 3;
+ b[2] *= 2;
+ f[3] += 8;
+ g[1] += 9;
+ g[2] += 10;
+ h[0] += 11;
+ k[1][1] += 13;
+ k[2][1] += 15;
+ m[1] += 16;
+ r[2] += 8;
+ s[1] *= 2;
+ t[2][1] *= 2;
+ t[3][1] *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1] += 6;
+ r[2] += 7;
+ q[1][0] += 17;
+ q[2][0] += 19;
+ a[0] += 4;
+ a[1] += 5;
+ b[3] *= 2;
+ b[4] *= 2;
+ f[3] += 18;
+ g[1] += 29;
+ g[2] += 18;
+ h[0] += 19;
+ s[2] *= 2;
+ t[2][0] *= 2;
+ t[3][0] *= 2;
+ T *cp = c;
+ long long int *dp = d;
+ T *rp = r;
+ T *pp = p;
+ foo (n, cp, dp, m, rp, o, pp, q);
+ r[3] += 18;
+ o[1] += 29;
+ o[2] += 18;
+ p[0] += 19;
+ c[0] += 4;
+ c[1] += 5;
+ d[0] *= 2;
+ e[1] += 6;
+ f[2] += 7;
+ k[1][0] += 17;
+ k[2][0] += 19;
+ }
+ r[3] += 8;
+ o[1] += 9;
+ o[2] += 10;
+ p[0] += 11;
+ q[1][1] += 13;
+ q[2][1] += 15;
+ b[3] *= 2;
+ c[0] += 4;
+ c[1] += 9;
+ d[0] *= 2;
+ e[1] += 16;
+ f[2] += 8;
+ }
+ }
+ if (d[0] != 1LL << (8 + 4)
+ || d[1] != 1LL << 16
+ || m[0] != 5
+ || m[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2] != 5
+ || r[0] != 6
+ || r[1] != 7
+ || r[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4] != 9
+ || o[0] != 1
+ || o[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3] != 2)
+ abort ();
+ }
+ if (a[0] != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1] != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0] != 9 || b[1] != 11
+ || b[2] != 1LL << (16 + 4)
+ || b[3] != 1LL << (8 + 4)
+ || b[4] != 1LL << (16 + 8)
+ || b[5] != 13 || b[6] != 15
+ || c[0] != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1] != 5 * 8 + 9 * 4
+ || e[0] != 5
+ || e[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2] != 5
+ || f[0] != 6
+ || f[1] != 7
+ || f[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4] != 9
+ || g[0] != 1
+ || g[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3] != 2
+ || h[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1] != 1 || h[2] != 4
+ || k[0][0] != 5 || k[0][1] != 6
+ || k[1][0] != 31 * 16 + 17 * 8
+ || k[1][1] != 13 * 4
+ || k[2][0] != 19 * 8
+ || k[2][1] != 33 * 16 + 15 * 4
+ || k[3][0] != 7 || k[3][1] != 8
+ || p[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1] != 1 || p[2] != 4
+ || q[0][0] != 5 || q[0][1] != 6
+ || q[1][0] != 31 * 16 + 17 * 8
+ || q[1][1] != 13 * 4
+ || q[2][0] != 19 * 8
+ || q[2][1] != 33 * 16 + 15 * 4
+ || q[3][0] != 7 || q[3][1] != 8
+ || sb[0] != 5
+ || sb[1] != 1LL << (16 + 4)
+ || sb[2] != 1LL << 8
+ || sb[3] != 6
+ || tb[0][0] != 9 || tb[0][1] != 10 || tb[1][0] != 11 || tb[1][1] != 12
+ || tb[2][0] != 1LL << (16 + 8)
+ || tb[2][1] != 1LL << 4
+ || tb[3][0] != 1LL << 8
+ || tb[3][1] != 1LL << (16 + 4)
+ || tb[4][0] != 13 || tb[4][1] != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ int n = 1;
+ test (n);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-12.C b/libgomp/testsuite/libgomp.c++/task-reduction-12.C
new file mode 100644
index 00000000000..02c1a787cbf
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-12.C
@@ -0,0 +1,321 @@
+extern "C" void abort ();
+
+struct S { S (); S (long int, long int); ~S (); static int cnt1, cnt2, cnt3; long int s, t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long int x, long int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S a[2] = { { 0, 7 }, { 0, 7 } };
+S b[7] = { { 9, 5 }, { 11, 5 }, { 1, 5 }, { 1, 5 }, { 1, 5 }, { 13, 5 }, { 15, 5 } };
+S e[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+S f[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+S g[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+S h[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+S k[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+S *s;
+S (*t)[2];
+
+template <int N>
+void
+foo (int n, S *c, S *d, S m[3], S *r, S o[4], S *p, S q[4][2])
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0].s += 7;
+ a[1].s += 17;
+ b[2].s *= 2;
+ b[4].s *= 2;
+ c[0].s += 6;
+ d[1].s *= 2;
+ e[1].s += 19;
+ f[2].s += 21;
+ f[3].s += 23;
+ g[1].s += 25;
+ g[2].s += 27;
+ h[0].s += 29;
+ k[1][0].s += 31;
+ k[2][1].s += 33;
+ m[1].s += 19;
+ r[2].s += 21;
+ r[3].s += 23;
+ o[1].s += 25;
+ o[2].s += 27;
+ p[0].s += 29;
+ q[1][0].s += 31;
+ q[2][1].s += 33;
+ s[1].s *= 2;
+ t[2][0].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ }
+}
+
+template <int N>
+void
+test (int n)
+{
+ S c[2] = { { 0, 7 }, { 0, 7 } };
+ S p[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+ S q[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+ S ss[4] = { { 5, 5 }, { 1, 5 }, { 1, 5 }, { 6, 5 } };
+ S tt[5][2] = { { { 9, 5 }, { 10, 5 } }, { { 11, 5 }, { 12, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 13, 5 }, { 14, 5 } } };
+ s = ss;
+ t = tt;
+ #pragma omp parallel num_threads (1) if (0)
+ {
+ S d[] = { { 1, 5 }, { 1, 5 } };
+ S m[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+ S r[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+ S o[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+ #pragma omp parallel reduction (task, +: a, c) reduction (task, *: b[2 * n:3 * n], d) \
+ reduction (task, +: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (task, +: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (task, *: t[2:2][:], s[1:n + 1])
+ {
+ #pragma omp for
+ for (int i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ int j;
+ a[0].s += 2;
+ a[1].s += 3;
+ b[2].s *= 2;
+ f[3].s += 8;
+ g[1].s += 9;
+ g[2].s += 10;
+ h[0].s += 11;
+ k[1][1].s += 13;
+ k[2][1].s += 15;
+ m[1].s += 16;
+ r[2].s += 8;
+ s[1].s *= 2;
+ t[2][1].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1].s += 6;
+ r[2].s += 7;
+ q[1][0].s += 17;
+ q[2][0].s += 19;
+ a[0].s += 4;
+ a[1].s += 5;
+ b[3].s *= 2;
+ b[4].s *= 2;
+ f[3].s += 18;
+ g[1].s += 29;
+ g[2].s += 18;
+ h[0].s += 19;
+ s[2].s *= 2;
+ t[2][0].s *= 2;
+ t[3][0].s *= 2;
+ foo<N> (n, c, d, m, r, o, p, q);
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ r[3].s += 18;
+ o[1].s += 29;
+ o[2].s += 18;
+ p[0].s += 19;
+ c[0].s += 4;
+ c[1].s += 5;
+ d[0].s *= 2;
+ e[1].s += 6;
+ f[2].s += 7;
+ k[1][0].s += 17;
+ k[2][0].s += 19;
+ }
+ r[3].s += 8;
+ o[1].s += 9;
+ o[2].s += 10;
+ p[0].s += 11;
+ q[1][1].s += 13;
+ q[2][1].s += 15;
+ b[3].s *= 2;
+ c[0].s += 4;
+ c[1].s += 9;
+ d[0].s *= 2;
+ e[1].s += 16;
+ f[2].s += 8;
+ }
+ }
+ if (d[0].s != 1LL << (8 + 4)
+ || d[1].s != 1LL << 16
+ || m[0].s != 5
+ || m[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2].s != 5
+ || r[0].s != 6
+ || r[1].s != 7
+ || r[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4].s != 9
+ || o[0].s != 1
+ || o[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3].s != 2)
+ abort ();
+ if (e[1].t != 7 || h[0].t != 7 || m[1].t != 7 || p[0].t != 7)
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if (a[z].t != 7 || c[z].t != 7 || d[z].t != 5 || f[z + 2].t != 7
+ || g[z + 1].t != 7 || r[z + 2].t != 7 || s[z + 1].t != 5 || o[z + 1].t != 7
+ || k[z + 1][0].t != 7 || k[z + 1][1].t != 7 || q[z + 1][0].t != 7 || q[z + 1][1].t != 7
+ || t[z + 2][0].t != 5 || t[z + 2][1].t != 5)
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5)
+ abort ();
+ }
+ if (a[0].s != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1].s != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0].s != 9 || b[1].s != 11
+ || b[2].s != 1LL << (16 + 4)
+ || b[3].s != 1LL << (8 + 4)
+ || b[4].s != 1LL << (16 + 8)
+ || b[5].s != 13 || b[6].s != 15
+ || c[0].s != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1].s != 5 * 8 + 9 * 4
+ || e[0].s != 5
+ || e[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2].s != 5
+ || f[0].s != 6
+ || f[1].s != 7
+ || f[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4].s != 9
+ || g[0].s != 1
+ || g[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3].s != 2
+ || h[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1].s != 1 || h[2].s != 4
+ || k[0][0].s != 5 || k[0][1].s != 6
+ || k[1][0].s != 31 * 16 + 17 * 8
+ || k[1][1].s != 13 * 4
+ || k[2][0].s != 19 * 8
+ || k[2][1].s != 33 * 16 + 15 * 4
+ || k[3][0].s != 7 || k[3][1].s != 8
+ || p[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1].s != 1 || p[2].s != 4
+ || q[0][0].s != 5 || q[0][1].s != 6
+ || q[1][0].s != 31 * 16 + 17 * 8
+ || q[1][1].s != 13 * 4
+ || q[2][0].s != 19 * 8
+ || q[2][1].s != 33 * 16 + 15 * 4
+ || q[3][0].s != 7 || q[3][1].s != 8
+ || ss[0].s != 5
+ || ss[1].s != 1LL << (16 + 4)
+ || ss[2].s != 1LL << 8
+ || ss[3].s != 6
+ || tt[0][0].s != 9 || tt[0][1].s != 10 || tt[1][0].s != 11 || tt[1][1].s != 12
+ || tt[2][0].s != 1LL << (16 + 8)
+ || tt[2][1].s != 1LL << 4
+ || tt[3][0].s != 1LL << 8
+ || tt[3][1].s != 1LL << (16 + 4)
+ || tt[4][0].s != 13 || tt[4][1].s != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test<0> (1);
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-13.C b/libgomp/testsuite/libgomp.c++/task-reduction-13.C
new file mode 100644
index 00000000000..3d0165dfa92
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-13.C
@@ -0,0 +1,342 @@
+extern "C" void abort ();
+
+struct S { S (); S (long int, long int); ~S (); static int cnt1, cnt2, cnt3; long int s, t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long int x, long int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S as[2] = { { 0, 7 }, { 0, 7 } };
+S (&a)[2] = as;
+S bs[7] = { { 9, 5 }, { 11, 5 }, { 1, 5 }, { 1, 5 }, { 1, 5 }, { 13, 5 }, { 15, 5 } };
+S (&b)[7] = bs;
+S es[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+S (&e)[3] = es;
+S fs[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+S (&f)[5] = fs;
+S gs[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+S (&g)[4] = gs;
+S hs[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+S (&h)[3] = hs;
+S ks[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+S (&k)[4][2] = ks;
+S *ss;
+S *&s = ss;
+S (*ts)[2];
+S (*&t)[2] = ts;
+
+template <typename S, typename T>
+void
+foo (T &n, S *&c, S *&d, S (&m)[3], S *&r, S (&o)[4], S *&p, S (&q)[4][2])
+{
+ T i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0].s += 7;
+ a[1].s += 17;
+ b[2].s *= 2;
+ b[4].s *= 2;
+ c[0].s += 6;
+ d[1].s *= 2;
+ e[1].s += 19;
+ f[2].s += 21;
+ f[3].s += 23;
+ g[1].s += 25;
+ g[2].s += 27;
+ h[0].s += 29;
+ k[1][0].s += 31;
+ k[2][1].s += 33;
+ m[1].s += 19;
+ r[2].s += 21;
+ r[3].s += 23;
+ o[1].s += 25;
+ o[2].s += 27;
+ p[0].s += 29;
+ q[1][0].s += 31;
+ q[2][1].s += 33;
+ s[1].s *= 2;
+ t[2][0].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (T z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (T z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ }
+}
+
+template <typename S, typename T>
+void
+test (T &n)
+{
+ S cs[2] = { { 0, 7 }, { 0, 7 } };
+ S (&c)[2] = cs;
+ S ps[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+ S (&p)[3] = ps;
+ S qs[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+ S (&q)[4][2] = qs;
+ S sb[4] = { { 5, 5 }, { 1, 5 }, { 1, 5 }, { 6, 5 } };
+ S tb[5][2] = { { { 9, 5 }, { 10, 5 } }, { { 11, 5 }, { 12, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 13, 5 }, { 14, 5 } } };
+ S ms[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+ S os[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+ s = sb;
+ t = tb;
+ #pragma omp parallel if (0)
+ {
+ S ds[] = { { 1, 5 }, { 1, 5 } };
+ S (&d)[2] = ds;
+ S (&m)[3] = ms;
+ S rs[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+ S (&r)[5] = rs;
+ S (&o)[4] = os;
+ #pragma omp parallel reduction (task, +: a, c) reduction (task, *: b[2 * n:3 * n], d) \
+ reduction (task, +: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (task, +: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (task, *: t[2:2][:], s[1:n + 1])
+ {
+ #pragma omp for
+ for (T i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ T j;
+ a[0].s += 2;
+ a[1].s += 3;
+ b[2].s *= 2;
+ f[3].s += 8;
+ g[1].s += 9;
+ g[2].s += 10;
+ h[0].s += 11;
+ k[1][1].s += 13;
+ k[2][1].s += 15;
+ m[1].s += 16;
+ r[2].s += 8;
+ s[1].s *= 2;
+ t[2][1].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (T z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (T z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1].s += 6;
+ r[2].s += 7;
+ q[1][0].s += 17;
+ q[2][0].s += 19;
+ a[0].s += 4;
+ a[1].s += 5;
+ b[3].s *= 2;
+ b[4].s *= 2;
+ f[3].s += 18;
+ g[1].s += 29;
+ g[2].s += 18;
+ h[0].s += 19;
+ s[2].s *= 2;
+ t[2][0].s *= 2;
+ t[3][0].s *= 2;
+ S *cp = c;
+ S *dp = d;
+ S *rp = r;
+ S *pp = p;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (T z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (T z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ foo (n, cp, dp, m, rp, o, pp, q);
+ r[3].s += 18;
+ o[1].s += 29;
+ o[2].s += 18;
+ p[0].s += 19;
+ c[0].s += 4;
+ c[1].s += 5;
+ d[0].s *= 2;
+ e[1].s += 6;
+ f[2].s += 7;
+ k[1][0].s += 17;
+ k[2][0].s += 19;
+ }
+ r[3].s += 8;
+ o[1].s += 9;
+ o[2].s += 10;
+ p[0].s += 11;
+ q[1][1].s += 13;
+ q[2][1].s += 15;
+ b[3].s *= 2;
+ c[0].s += 4;
+ c[1].s += 9;
+ d[0].s *= 2;
+ e[1].s += 16;
+ f[2].s += 8;
+ }
+ }
+ if (d[0].s != 1LL << (8 + 4)
+ || d[1].s != 1LL << 16
+ || m[0].s != 5
+ || m[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2].s != 5
+ || r[0].s != 6
+ || r[1].s != 7
+ || r[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4].s != 9
+ || o[0].s != 1
+ || o[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3].s != 2)
+ abort ();
+ if (e[1].t != 7 || h[0].t != 7 || m[1].t != 7 || p[0].t != 7)
+ abort ();
+ for (T z = 0; z < 2; z++)
+ if (a[z].t != 7 || c[z].t != 7 || d[z].t != 5 || f[z + 2].t != 7
+ || g[z + 1].t != 7 || r[z + 2].t != 7 || s[z + 1].t != 5 || o[z + 1].t != 7
+ || k[z + 1][0].t != 7 || k[z + 1][1].t != 7 || q[z + 1][0].t != 7 || q[z + 1][1].t != 7
+ || t[z + 2][0].t != 5 || t[z + 2][1].t != 5)
+ abort ();
+ for (T z = 0; z < 3; z++)
+ if (b[z + 2].t != 5)
+ abort ();
+ }
+ if (a[0].s != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1].s != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0].s != 9 || b[1].s != 11
+ || b[2].s != 1LL << (16 + 4)
+ || b[3].s != 1LL << (8 + 4)
+ || b[4].s != 1LL << (16 + 8)
+ || b[5].s != 13 || b[6].s != 15
+ || c[0].s != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1].s != 5 * 8 + 9 * 4
+ || e[0].s != 5
+ || e[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2].s != 5
+ || f[0].s != 6
+ || f[1].s != 7
+ || f[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4].s != 9
+ || g[0].s != 1
+ || g[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3].s != 2
+ || h[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1].s != 1 || h[2].s != 4
+ || k[0][0].s != 5 || k[0][1].s != 6
+ || k[1][0].s != 31 * 16 + 17 * 8
+ || k[1][1].s != 13 * 4
+ || k[2][0].s != 19 * 8
+ || k[2][1].s != 33 * 16 + 15 * 4
+ || k[3][0].s != 7 || k[3][1].s != 8
+ || p[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1].s != 1 || p[2].s != 4
+ || q[0][0].s != 5 || q[0][1].s != 6
+ || q[1][0].s != 31 * 16 + 17 * 8
+ || q[1][1].s != 13 * 4
+ || q[2][0].s != 19 * 8
+ || q[2][1].s != 33 * 16 + 15 * 4
+ || q[3][0].s != 7 || q[3][1].s != 8
+ || sb[0].s != 5
+ || sb[1].s != 1LL << (16 + 4)
+ || sb[2].s != 1LL << 8
+ || sb[3].s != 6
+ || tb[0][0].s != 9 || tb[0][1].s != 10 || tb[1][0].s != 11 || tb[1][1].s != 12
+ || tb[2][0].s != 1LL << (16 + 8)
+ || tb[2][1].s != 1LL << 4
+ || tb[3][0].s != 1LL << 8
+ || tb[3][1].s != 1LL << (16 + 4)
+ || tb[4][0].s != 13 || tb[4][1].s != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ int n = 1;
+ test<S, int> (n);
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-14.C b/libgomp/testsuite/libgomp.c++/task-reduction-14.C
new file mode 100644
index 00000000000..3f4e79b16c5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-14.C
@@ -0,0 +1,72 @@
+#include <omp.h>
+#include <stdlib.h>
+
+struct A { A (); ~A (); A (const A &); static int cnt1, cnt2, cnt3; int a; };
+int A::cnt1;
+int A::cnt2;
+int A::cnt3;
+A::A () : a (0)
+{
+ #pragma omp atomic
+ cnt1++;
+}
+A::A (const A &x) : a (x.a)
+{
+ #pragma omp atomic
+ cnt2++;
+}
+A::~A ()
+{
+ #pragma omp atomic
+ cnt3++;
+}
+#pragma omp declare reduction (+: A: omp_out.a += omp_in.a)
+
+void
+foo (int x)
+{
+ A a, b[2];
+ int d = 1;
+ long int e[2] = { 1L, 1L };
+ int c = 0;
+ #pragma omp parallel
+ {
+ if (x && omp_get_thread_num () == 0)
+ {
+ for (int i = 0; i < 10000000; ++i)
+ asm volatile ("");
+ c = 1;
+ #pragma omp cancel parallel
+ }
+ #pragma omp for reduction (task, +: a, b) reduction (task, *: d, e)
+ for (int i = 0; i < 64; i++)
+ #pragma omp task in_reduction (+: a, b) in_reduction (*: d, e)
+ {
+ a.a++;
+ b[0].a += 2;
+ b[1].a += 3;
+ d *= ((i & 7) == 0) + 1;
+ e[0] *= ((i & 7) == 3) + 1;
+ e[1] *= ((i & 3) == 2) + 1;
+ }
+ if (x && omp_get_cancellation ())
+ abort ();
+ }
+ if (!c)
+ {
+ if (a.a != 64 || b[0].a != 128 || b[1].a != 192)
+ abort ();
+ if (d != 256 || e[0] != 256L || e[1] != 65536L)
+ abort ();
+ }
+}
+
+int
+main ()
+{
+ int c1 = A::cnt1, c2 = A::cnt2, c3 = A::cnt3;
+ volatile int zero = 0;
+ foo (zero);
+ if (A::cnt1 + A::cnt2 - c1 - c2 != A::cnt3 - c3)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-15.C b/libgomp/testsuite/libgomp.c++/task-reduction-15.C
new file mode 100644
index 00000000000..8a01e6b240a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-15.C
@@ -0,0 +1,75 @@
+extern "C" void abort ();
+
+int as;
+int &a = as;
+long int bs = 1;
+long int &b = bs;
+
+template <typename T, typename U>
+void
+foo (T &c, U &d)
+{
+ T i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (*: d) in_reduction (+: c) \
+ in_reduction (+: a) in_reduction (*: b)
+ {
+ a += 7;
+ b *= 2;
+ c += 9;
+ d *= 3;
+ }
+}
+
+template <typename T, typename U>
+void
+bar ()
+{
+ T cs = 0;
+ T &c = cs;
+ U ds = 1;
+ #pragma omp parallel if (0)
+ {
+ U &d = ds;
+ #pragma omp parallel
+ {
+ T i;
+ #pragma omp for reduction (task, +: a, c) reduction (task, *: b, d)
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b, d)
+ {
+ T j;
+ a += 7;
+ b *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b, d)
+ {
+ a += 7;
+ b *= 2;
+ c += 9;
+ d *= 3;
+ foo (c, d);
+ }
+ c += 9;
+ d *= 3;
+ }
+#define THREEP4 (3LL * 3LL * 3LL * 3LL)
+ if (d != (THREEP4 * THREEP4 * THREEP4 * THREEP4 * THREEP4 * THREEP4
+ * THREEP4))
+ abort ();
+ if (a != 28 * 7 || b != (1L << 28) || c != 28 * 9)
+ abort ();
+ }
+ }
+ if (a != 28 * 7 || b != (1L << 28) || c != 28 * 9)
+ abort ();
+ if (ds != (THREEP4 * THREEP4 * THREEP4 * THREEP4 * THREEP4 * THREEP4
+ * THREEP4))
+ abort ();
+}
+
+int
+main ()
+{
+ bar<int, long long int> ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-16.C b/libgomp/testsuite/libgomp.c++/task-reduction-16.C
new file mode 100644
index 00000000000..5835edcbd5b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-16.C
@@ -0,0 +1,130 @@
+extern "C" void abort ();
+
+struct S { S (); S (long long int, int); ~S (); static int cnt1, cnt2, cnt3; long long int s; int t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long long int x, int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S as = { 0LL, 7 };
+S &a = as;
+S bs (1LL, 5);
+S &b = bs;
+
+void
+foo (S &c, S &d)
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: c) in_reduction (*: b, d) in_reduction (+: a)
+ {
+ a.s += 7;
+ b.s *= 2;
+ c.s += 9;
+ d.s *= 3;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+}
+
+void
+test ()
+{
+ S cs = { 0LL, 7 };
+ S &c = cs;
+ S ds (1LL, 5);
+ #pragma omp parallel if (0)
+ {
+ S &d = ds;
+ #pragma omp parallel shared (a, b, c, d)
+ {
+ #pragma omp for schedule (static, 1) reduction (task, +: a, c) reduction (task, *: b, d)
+ for (int i = 0; i < 4; i++)
+ #pragma omp task in_reduction (*: b, d) in_reduction (+: a, c)
+ {
+ int j;
+ a.s += 7;
+ b.s *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a) in_reduction (*: b) \
+ in_reduction (+: c) in_reduction (*: d)
+ {
+ a.s += 7;
+ b.s *= 2;
+ c.s += 9;
+ d.s *= 3;
+ foo (c, d);
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ c.s += 9;
+ d.s *= 3;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+#define THREEP7 (3LL * 3LL * 3LL * 3LL * 3LL * 3LL * 3LL)
+ if (d.s != (THREEP7 * THREEP7 * THREEP7 * THREEP7) || d.t != 5)
+ abort ();
+ if (a.s != 28 * 7 || a.t != 7 || b.s != (1L << 28) || b.t != 5
+ || c.s != 28 * 9 || c.t != 7)
+ abort ();
+ }
+ }
+ if (a.s != 28 * 7 || a.t != 7 || b.s != (1L << 28) || b.t != 5
+ || c.s != 28 * 9 || c.t != 7)
+ abort ();
+ if (ds.s != (THREEP7 * THREEP7 * THREEP7 * THREEP7) || ds.t != 5)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test ();
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-17.C b/libgomp/testsuite/libgomp.c++/task-reduction-17.C
new file mode 100644
index 00000000000..c00c8e46542
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-17.C
@@ -0,0 +1,300 @@
+extern "C" void abort ();
+
+int as[2];
+int (&a)[2] = as;
+long long int bs[7] = { 9, 11, 1, 1, 1, 13, 15 };
+long long int (&b)[7] = bs;
+int es[3] = { 5, 0, 5 };
+int (&e)[3] = es;
+int fs[5] = { 6, 7, 0, 0, 9 };
+int (&f)[5] = fs;
+int gs[4] = { 1, 0, 0, 2 };
+int (&g)[4] = gs;
+int hs[3] = { 0, 1, 4 };
+int (&h)[3] = hs;
+int ks[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+int (&k)[4][2] = ks;
+long long *ss;
+long long *&s = ss;
+long long (*ts)[2];
+long long (*&t)[2] = ts;
+
+template <typename T>
+void
+foo (T &n, T *&c, long long int *&d, T (&m)[3], T *&r, T (&o)[4], T *&p, T (&q)[4][2])
+{
+ T i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0] += 7;
+ a[1] += 17;
+ b[2] *= 2;
+ b[4] *= 2;
+ c[0] += 6;
+ d[1] *= 2;
+ e[1] += 19;
+ f[2] += 21;
+ f[3] += 23;
+ g[1] += 25;
+ g[2] += 27;
+ h[0] += 29;
+ k[1][0] += 31;
+ k[2][1] += 33;
+ m[1] += 19;
+ r[2] += 21;
+ r[3] += 23;
+ o[1] += 25;
+ o[2] += 27;
+ p[0] += 29;
+ q[1][0] += 31;
+ q[2][1] += 33;
+ s[1] *= 2;
+ t[2][0] *= 2;
+ t[3][1] *= 2;
+ }
+}
+
+template <typename T, typename I>
+void
+test (T &n, I x, I y)
+{
+ T cs[2] = { 0, 0 };
+ T (&c)[2] = cs;
+ T ps[3] = { 0, 1, 4 };
+ T (&p)[3] = ps;
+ T qs[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+ T (&q)[4][2] = qs;
+ long long sb[4] = { 5, 1, 1, 6 };
+ long long tb[5][2] = { { 9, 10 }, { 11, 12 }, { 1, 1 }, { 1, 1 }, { 13, 14 } };
+ T ms[3] = { 5, 0, 5 };
+ T os[4] = { 1, 0, 0, 2 };
+ s = sb;
+ t = tb;
+ #pragma omp parallel if (0)
+ {
+ long long int ds[] = { 1, 1 };
+ long long int (&d)[2] = ds;
+ T (&m)[3] = ms;
+ T rs[5] = { 6, 7, 0, 0, 9 };
+ T (&r)[5] = rs;
+ T (&o)[4] = os;
+ #pragma omp parallel
+ {
+ #pragma omp for reduction (task,+: a, c) reduction (task,*: b[2 * n:3 * n], d) \
+ reduction (task,+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (task,+: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (task,*: t[2:2][:], s[1:n + 1]) schedule (dynamic)
+ for (I i = x; i != y; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ T j;
+ a[0] += 2;
+ a[1] += 3;
+ b[2] *= 2;
+ f[3] += 8;
+ g[1] += 9;
+ g[2] += 10;
+ h[0] += 11;
+ k[1][1] += 13;
+ k[2][1] += 15;
+ m[1] += 16;
+ r[2] += 8;
+ s[1] *= 2;
+ t[2][1] *= 2;
+ t[3][1] *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1] += 6;
+ r[2] += 7;
+ q[1][0] += 17;
+ q[2][0] += 19;
+ a[0] += 4;
+ a[1] += 5;
+ b[3] *= 2;
+ b[4] *= 2;
+ f[3] += 18;
+ g[1] += 29;
+ g[2] += 18;
+ h[0] += 19;
+ s[2] *= 2;
+ t[2][0] *= 2;
+ t[3][0] *= 2;
+ T *cp = c;
+ long long int *dp = d;
+ T *rp = r;
+ T *pp = p;
+ foo (n, cp, dp, m, rp, o, pp, q);
+ r[3] += 18;
+ o[1] += 29;
+ o[2] += 18;
+ p[0] += 19;
+ c[0] += 4;
+ c[1] += 5;
+ d[0] *= 2;
+ e[1] += 6;
+ f[2] += 7;
+ k[1][0] += 17;
+ k[2][0] += 19;
+ }
+ r[3] += 8;
+ o[1] += 9;
+ o[2] += 10;
+ p[0] += 11;
+ q[1][1] += 13;
+ q[2][1] += 15;
+ b[3] *= 2;
+ c[0] += 4;
+ c[1] += 9;
+ d[0] *= 2;
+ e[1] += 16;
+ f[2] += 8;
+ }
+ if (d[0] != 1LL << (8 + 4)
+ || d[1] != 1LL << 16
+ || m[0] != 5
+ || m[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2] != 5
+ || r[0] != 6
+ || r[1] != 7
+ || r[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4] != 9
+ || o[0] != 1
+ || o[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3] != 2)
+ abort ();
+ if (a[0] != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1] != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0] != 9 || b[1] != 11
+ || b[2] != 1LL << (16 + 4)
+ || b[3] != 1LL << (8 + 4)
+ || b[4] != 1LL << (16 + 8)
+ || b[5] != 13 || b[6] != 15
+ || c[0] != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1] != 5 * 8 + 9 * 4
+ || e[0] != 5
+ || e[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2] != 5
+ || f[0] != 6
+ || f[1] != 7
+ || f[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4] != 9
+ || g[0] != 1
+ || g[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3] != 2
+ || h[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1] != 1 || h[2] != 4
+ || k[0][0] != 5 || k[0][1] != 6
+ || k[1][0] != 31 * 16 + 17 * 8
+ || k[1][1] != 13 * 4
+ || k[2][0] != 19 * 8
+ || k[2][1] != 33 * 16 + 15 * 4
+ || k[3][0] != 7 || k[3][1] != 8
+ || p[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1] != 1 || p[2] != 4
+ || q[0][0] != 5 || q[0][1] != 6
+ || q[1][0] != 31 * 16 + 17 * 8
+ || q[1][1] != 13 * 4
+ || q[2][0] != 19 * 8
+ || q[2][1] != 33 * 16 + 15 * 4
+ || q[3][0] != 7 || q[3][1] != 8
+ || sb[0] != 5
+ || sb[1] != 1LL << (16 + 4)
+ || sb[2] != 1LL << 8
+ || sb[3] != 6
+ || tb[0][0] != 9 || tb[0][1] != 10 || tb[1][0] != 11 || tb[1][1] != 12
+ || tb[2][0] != 1LL << (16 + 8)
+ || tb[2][1] != 1LL << 4
+ || tb[3][0] != 1LL << 8
+ || tb[3][1] != 1LL << (16 + 4)
+ || tb[4][0] != 13 || tb[4][1] != 14)
+ abort ();
+ }
+ if (d[0] != 1LL << (8 + 4)
+ || d[1] != 1LL << 16
+ || m[0] != 5
+ || m[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2] != 5
+ || r[0] != 6
+ || r[1] != 7
+ || r[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4] != 9
+ || o[0] != 1
+ || o[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3] != 2)
+ abort ();
+ }
+ if (a[0] != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1] != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0] != 9 || b[1] != 11
+ || b[2] != 1LL << (16 + 4)
+ || b[3] != 1LL << (8 + 4)
+ || b[4] != 1LL << (16 + 8)
+ || b[5] != 13 || b[6] != 15
+ || c[0] != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1] != 5 * 8 + 9 * 4
+ || e[0] != 5
+ || e[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2] != 5
+ || f[0] != 6
+ || f[1] != 7
+ || f[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4] != 9
+ || g[0] != 1
+ || g[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3] != 2
+ || h[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1] != 1 || h[2] != 4
+ || k[0][0] != 5 || k[0][1] != 6
+ || k[1][0] != 31 * 16 + 17 * 8
+ || k[1][1] != 13 * 4
+ || k[2][0] != 19 * 8
+ || k[2][1] != 33 * 16 + 15 * 4
+ || k[3][0] != 7 || k[3][1] != 8
+ || p[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1] != 1 || p[2] != 4
+ || q[0][0] != 5 || q[0][1] != 6
+ || q[1][0] != 31 * 16 + 17 * 8
+ || q[1][1] != 13 * 4
+ || q[2][0] != 19 * 8
+ || q[2][1] != 33 * 16 + 15 * 4
+ || q[3][0] != 7 || q[3][1] != 8
+ || sb[0] != 5
+ || sb[1] != 1LL << (16 + 4)
+ || sb[2] != 1LL << 8
+ || sb[3] != 6
+ || tb[0][0] != 9 || tb[0][1] != 10 || tb[1][0] != 11 || tb[1][1] != 12
+ || tb[2][0] != 1LL << (16 + 8)
+ || tb[2][1] != 1LL << 4
+ || tb[3][0] != 1LL << 8
+ || tb[3][1] != 1LL << (16 + 4)
+ || tb[4][0] != 13 || tb[4][1] != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ int n = 1;
+ test (n, 0ULL, 4ULL);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-18.C b/libgomp/testsuite/libgomp.c++/task-reduction-18.C
new file mode 100644
index 00000000000..99c0e3727d4
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-18.C
@@ -0,0 +1,325 @@
+extern "C" void abort ();
+
+struct S { S (); S (long int, long int); ~S (); static int cnt1, cnt2, cnt3; long int s, t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long int x, long int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S a[2] = { { 0, 7 }, { 0, 7 } };
+S b[7] = { { 9, 5 }, { 11, 5 }, { 1, 5 }, { 1, 5 }, { 1, 5 }, { 13, 5 }, { 15, 5 } };
+S e[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+S f[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+S g[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+S h[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+S k[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+S *s;
+S (*t)[2];
+
+template <int N>
+void
+foo (int n, S *c, S *d, S m[3], S *r, S o[4], S *p, S q[4][2])
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0].s += 7;
+ a[1].s += 17;
+ b[2].s *= 2;
+ b[4].s *= 2;
+ c[0].s += 6;
+ d[1].s *= 2;
+ e[1].s += 19;
+ f[2].s += 21;
+ f[3].s += 23;
+ g[1].s += 25;
+ g[2].s += 27;
+ h[0].s += 29;
+ k[1][0].s += 31;
+ k[2][1].s += 33;
+ m[1].s += 19;
+ r[2].s += 21;
+ r[3].s += 23;
+ o[1].s += 25;
+ o[2].s += 27;
+ p[0].s += 29;
+ q[1][0].s += 31;
+ q[2][1].s += 33;
+ s[1].s *= 2;
+ t[2][0].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ }
+}
+
+template <int N>
+void
+test (int n)
+{
+ S c[2] = { { 0, 7 }, { 0, 7 } };
+ S p[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+ S q[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+ S ss[4] = { { 5, 5 }, { 1, 5 }, { 1, 5 }, { 6, 5 } };
+ S tt[5][2] = { { { 9, 5 }, { 10, 5 } }, { { 11, 5 }, { 12, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 13, 5 }, { 14, 5 } } };
+ s = ss;
+ t = tt;
+ #pragma omp parallel num_threads (1) if (0)
+ {
+ S d[] = { { 1, 5 }, { 1, 5 } };
+ S m[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+ S r[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+ S o[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+ volatile unsigned long long x = 0;
+ volatile unsigned long long y = 4;
+ volatile unsigned long long z = 1;
+ #pragma omp parallel
+ {
+ #pragma omp for reduction (task, +: a, c) reduction (task, *: b[2 * n:3 * n], d) \
+ reduction (task, +: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (task, +: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (task, *: t[2:2][:], s[1:n + 1]) \
+ schedule (nonmonotonic: guided, 1)
+ for (unsigned long long i = x; i < y; i += z)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ int j;
+ a[0].s += 2;
+ a[1].s += 3;
+ b[2].s *= 2;
+ f[3].s += 8;
+ g[1].s += 9;
+ g[2].s += 10;
+ h[0].s += 11;
+ k[1][1].s += 13;
+ k[2][1].s += 15;
+ m[1].s += 16;
+ r[2].s += 8;
+ s[1].s *= 2;
+ t[2][1].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1].s += 6;
+ r[2].s += 7;
+ q[1][0].s += 17;
+ q[2][0].s += 19;
+ a[0].s += 4;
+ a[1].s += 5;
+ b[3].s *= 2;
+ b[4].s *= 2;
+ f[3].s += 18;
+ g[1].s += 29;
+ g[2].s += 18;
+ h[0].s += 19;
+ s[2].s *= 2;
+ t[2][0].s *= 2;
+ t[3][0].s *= 2;
+ foo<N> (n, c, d, m, r, o, p, q);
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ r[3].s += 18;
+ o[1].s += 29;
+ o[2].s += 18;
+ p[0].s += 19;
+ c[0].s += 4;
+ c[1].s += 5;
+ d[0].s *= 2;
+ e[1].s += 6;
+ f[2].s += 7;
+ k[1][0].s += 17;
+ k[2][0].s += 19;
+ }
+ r[3].s += 8;
+ o[1].s += 9;
+ o[2].s += 10;
+ p[0].s += 11;
+ q[1][1].s += 13;
+ q[2][1].s += 15;
+ b[3].s *= 2;
+ c[0].s += 4;
+ c[1].s += 9;
+ d[0].s *= 2;
+ e[1].s += 16;
+ f[2].s += 8;
+ }
+ if (a[0].s != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1].s != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0].s != 9 || b[1].s != 11
+ || b[2].s != 1LL << (16 + 4)
+ || b[3].s != 1LL << (8 + 4)
+ || b[4].s != 1LL << (16 + 8)
+ || b[5].s != 13 || b[6].s != 15
+ || c[0].s != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1].s != 5 * 8 + 9 * 4
+ || e[0].s != 5
+ || e[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2].s != 5
+ || f[0].s != 6
+ || f[1].s != 7
+ || f[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4].s != 9
+ || g[0].s != 1
+ || g[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3].s != 2
+ || h[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1].s != 1 || h[2].s != 4
+ || k[0][0].s != 5 || k[0][1].s != 6
+ || k[1][0].s != 31 * 16 + 17 * 8
+ || k[1][1].s != 13 * 4
+ || k[2][0].s != 19 * 8
+ || k[2][1].s != 33 * 16 + 15 * 4
+ || k[3][0].s != 7 || k[3][1].s != 8
+ || p[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1].s != 1 || p[2].s != 4
+ || q[0][0].s != 5 || q[0][1].s != 6
+ || q[1][0].s != 31 * 16 + 17 * 8
+ || q[1][1].s != 13 * 4
+ || q[2][0].s != 19 * 8
+ || q[2][1].s != 33 * 16 + 15 * 4
+ || q[3][0].s != 7 || q[3][1].s != 8
+ || ss[0].s != 5
+ || ss[1].s != 1LL << (16 + 4)
+ || ss[2].s != 1LL << 8
+ || ss[3].s != 6
+ || tt[0][0].s != 9 || tt[0][1].s != 10 || tt[1][0].s != 11 || tt[1][1].s != 12
+ || tt[2][0].s != 1LL << (16 + 8)
+ || tt[2][1].s != 1LL << 4
+ || tt[3][0].s != 1LL << 8
+ || tt[3][1].s != 1LL << (16 + 4)
+ || tt[4][0].s != 13 || tt[4][1].s != 14)
+ abort ();
+ }
+ if (d[0].s != 1LL << (8 + 4)
+ || d[1].s != 1LL << 16
+ || m[0].s != 5
+ || m[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2].s != 5
+ || r[0].s != 6
+ || r[1].s != 7
+ || r[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4].s != 9
+ || o[0].s != 1
+ || o[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3].s != 2)
+ abort ();
+ if (e[1].t != 7 || h[0].t != 7 || m[1].t != 7 || p[0].t != 7)
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if (a[z].t != 7 || c[z].t != 7 || d[z].t != 5 || f[z + 2].t != 7
+ || g[z + 1].t != 7 || r[z + 2].t != 7 || s[z + 1].t != 5 || o[z + 1].t != 7
+ || k[z + 1][0].t != 7 || k[z + 1][1].t != 7 || q[z + 1][0].t != 7 || q[z + 1][1].t != 7
+ || t[z + 2][0].t != 5 || t[z + 2][1].t != 5)
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5)
+ abort ();
+ }
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test<0> (1);
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-19.C b/libgomp/testsuite/libgomp.c++/task-reduction-19.C
new file mode 100644
index 00000000000..15945c57cc2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-19.C
@@ -0,0 +1,343 @@
+extern "C" void abort ();
+
+struct S { S (); S (long int, long int); ~S (); static int cnt1, cnt2, cnt3; long int s, t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long int x, long int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S as[2] = { { 0, 7 }, { 0, 7 } };
+S (&a)[2] = as;
+S bs[7] = { { 9, 5 }, { 11, 5 }, { 1, 5 }, { 1, 5 }, { 1, 5 }, { 13, 5 }, { 15, 5 } };
+S (&b)[7] = bs;
+S es[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+S (&e)[3] = es;
+S fs[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+S (&f)[5] = fs;
+S gs[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+S (&g)[4] = gs;
+S hs[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+S (&h)[3] = hs;
+S ks[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+S (&k)[4][2] = ks;
+S *ss;
+S *&s = ss;
+S (*ts)[2];
+S (*&t)[2] = ts;
+
+template <typename S, typename T>
+void
+foo (T &n, S *&c, S *&d, S (&m)[3], S *&r, S (&o)[4], S *&p, S (&q)[4][2])
+{
+ T i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0].s += 7;
+ a[1].s += 17;
+ b[2].s *= 2;
+ b[4].s *= 2;
+ c[0].s += 6;
+ d[1].s *= 2;
+ e[1].s += 19;
+ f[2].s += 21;
+ f[3].s += 23;
+ g[1].s += 25;
+ g[2].s += 27;
+ h[0].s += 29;
+ k[1][0].s += 31;
+ k[2][1].s += 33;
+ m[1].s += 19;
+ r[2].s += 21;
+ r[3].s += 23;
+ o[1].s += 25;
+ o[2].s += 27;
+ p[0].s += 29;
+ q[1][0].s += 31;
+ q[2][1].s += 33;
+ s[1].s *= 2;
+ t[2][0].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (T z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (T z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ }
+}
+
+template <typename S, typename T>
+void
+test (T &n)
+{
+ S cs[2] = { { 0, 7 }, { 0, 7 } };
+ S (&c)[2] = cs;
+ S ps[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+ S (&p)[3] = ps;
+ S qs[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+ S (&q)[4][2] = qs;
+ S sb[4] = { { 5, 5 }, { 1, 5 }, { 1, 5 }, { 6, 5 } };
+ S tb[5][2] = { { { 9, 5 }, { 10, 5 } }, { { 11, 5 }, { 12, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 13, 5 }, { 14, 5 } } };
+ S ms[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+ S os[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+ s = sb;
+ t = tb;
+ #pragma omp parallel if (0)
+ {
+ S ds[] = { { 1, 5 }, { 1, 5 } };
+ S (&d)[2] = ds;
+ S (&m)[3] = ms;
+ S rs[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+ S (&r)[5] = rs;
+ S (&o)[4] = os;
+ #pragma omp parallel
+ {
+ #pragma omp for reduction (task, +: a, c) reduction (task, *: b[2 * n:3 * n], d) \
+ reduction (task, +: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (task, +: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (task, *: t[2:2][:], s[1:n + 1]) \
+ schedule (monotonic: runtime)
+ for (T i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ T j;
+ a[0].s += 2;
+ a[1].s += 3;
+ b[2].s *= 2;
+ f[3].s += 8;
+ g[1].s += 9;
+ g[2].s += 10;
+ h[0].s += 11;
+ k[1][1].s += 13;
+ k[2][1].s += 15;
+ m[1].s += 16;
+ r[2].s += 8;
+ s[1].s *= 2;
+ t[2][1].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (T z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (T z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1].s += 6;
+ r[2].s += 7;
+ q[1][0].s += 17;
+ q[2][0].s += 19;
+ a[0].s += 4;
+ a[1].s += 5;
+ b[3].s *= 2;
+ b[4].s *= 2;
+ f[3].s += 18;
+ g[1].s += 29;
+ g[2].s += 18;
+ h[0].s += 19;
+ s[2].s *= 2;
+ t[2][0].s *= 2;
+ t[3][0].s *= 2;
+ S *cp = c;
+ S *dp = d;
+ S *rp = r;
+ S *pp = p;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (T z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (T z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ foo (n, cp, dp, m, rp, o, pp, q);
+ r[3].s += 18;
+ o[1].s += 29;
+ o[2].s += 18;
+ p[0].s += 19;
+ c[0].s += 4;
+ c[1].s += 5;
+ d[0].s *= 2;
+ e[1].s += 6;
+ f[2].s += 7;
+ k[1][0].s += 17;
+ k[2][0].s += 19;
+ }
+ r[3].s += 8;
+ o[1].s += 9;
+ o[2].s += 10;
+ p[0].s += 11;
+ q[1][1].s += 13;
+ q[2][1].s += 15;
+ b[3].s *= 2;
+ c[0].s += 4;
+ c[1].s += 9;
+ d[0].s *= 2;
+ e[1].s += 16;
+ f[2].s += 8;
+ }
+ if (a[0].s != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1].s != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0].s != 9 || b[1].s != 11
+ || b[2].s != 1LL << (16 + 4)
+ || b[3].s != 1LL << (8 + 4)
+ || b[4].s != 1LL << (16 + 8)
+ || b[5].s != 13 || b[6].s != 15
+ || c[0].s != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1].s != 5 * 8 + 9 * 4
+ || e[0].s != 5
+ || e[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2].s != 5
+ || f[0].s != 6
+ || f[1].s != 7
+ || f[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4].s != 9
+ || g[0].s != 1
+ || g[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3].s != 2
+ || h[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1].s != 1 || h[2].s != 4
+ || k[0][0].s != 5 || k[0][1].s != 6
+ || k[1][0].s != 31 * 16 + 17 * 8
+ || k[1][1].s != 13 * 4
+ || k[2][0].s != 19 * 8
+ || k[2][1].s != 33 * 16 + 15 * 4
+ || k[3][0].s != 7 || k[3][1].s != 8
+ || p[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1].s != 1 || p[2].s != 4
+ || q[0][0].s != 5 || q[0][1].s != 6
+ || q[1][0].s != 31 * 16 + 17 * 8
+ || q[1][1].s != 13 * 4
+ || q[2][0].s != 19 * 8
+ || q[2][1].s != 33 * 16 + 15 * 4
+ || q[3][0].s != 7 || q[3][1].s != 8
+ || sb[0].s != 5
+ || sb[1].s != 1LL << (16 + 4)
+ || sb[2].s != 1LL << 8
+ || sb[3].s != 6
+ || tb[0][0].s != 9 || tb[0][1].s != 10 || tb[1][0].s != 11 || tb[1][1].s != 12
+ || tb[2][0].s != 1LL << (16 + 8)
+ || tb[2][1].s != 1LL << 4
+ || tb[3][0].s != 1LL << 8
+ || tb[3][1].s != 1LL << (16 + 4)
+ || tb[4][0].s != 13 || tb[4][1].s != 14)
+ abort ();
+ if (d[0].s != 1LL << (8 + 4)
+ || d[1].s != 1LL << 16
+ || m[0].s != 5
+ || m[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2].s != 5
+ || r[0].s != 6
+ || r[1].s != 7
+ || r[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4].s != 9
+ || o[0].s != 1
+ || o[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3].s != 2)
+ abort ();
+ if (e[1].t != 7 || h[0].t != 7 || m[1].t != 7 || p[0].t != 7)
+ abort ();
+ for (T z = 0; z < 2; z++)
+ if (a[z].t != 7 || c[z].t != 7 || d[z].t != 5 || f[z + 2].t != 7
+ || g[z + 1].t != 7 || r[z + 2].t != 7 || s[z + 1].t != 5 || o[z + 1].t != 7
+ || k[z + 1][0].t != 7 || k[z + 1][1].t != 7 || q[z + 1][0].t != 7 || q[z + 1][1].t != 7
+ || t[z + 2][0].t != 5 || t[z + 2][1].t != 5)
+ abort ();
+ for (T z = 0; z < 3; z++)
+ if (b[z + 2].t != 5)
+ abort ();
+ }
+ }
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ int n = 1;
+ test<S, int> (n);
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-2.C b/libgomp/testsuite/libgomp.c++/task-reduction-2.C
new file mode 100644
index 00000000000..75d2ee37e4f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-2.C
@@ -0,0 +1,119 @@
+extern "C" void abort ();
+
+struct S { S (); S (long int, long int); ~S (); static int cnt1, cnt2, cnt3; long int s, t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long int x, long int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S a = { 0, 7 };
+S b (1, 5);
+
+void
+foo ()
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (*: b) in_reduction (+: a)
+ {
+ a.s += 7;
+ b.s *= 2;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9))
+ abort ();
+ }
+}
+
+void
+test ()
+{
+ S c = { 0, 7 };
+ #pragma omp parallel
+ #pragma omp single
+ {
+ S d (1, 5);
+ #pragma omp taskgroup task_reduction (+: a, c) task_reduction (*: b, d)
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (*: b, d) in_reduction (+: a, c)
+ {
+ int j;
+ a.s += 7;
+ b.s *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a) in_reduction (*: b) \
+ in_reduction (+: c) in_reduction (*: d)
+ {
+ a.s += 7;
+ b.s *= 2;
+ c.s += 9;
+ d.s *= 3;
+ foo ();
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ c.s += 9;
+ d.s *= 3;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ }
+#define THREEP4 (3L * 3L * 3L * 3L)
+ if (d.s != (THREEP4 * THREEP4 * THREEP4) || d.t != 5)
+ abort ();
+ }
+ if (a.s != 28 * 7 || a.t != 7 || b.s != (1L << 28) || b.t != 5
+ || c.s != 12 * 9 || c.t != 7)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test ();
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-3.C b/libgomp/testsuite/libgomp.c++/task-reduction-3.C
new file mode 100644
index 00000000000..a6eccf6ced6
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-3.C
@@ -0,0 +1,126 @@
+extern "C" void abort ();
+
+struct S { S (); S (long long int, int); ~S (); static int cnt1, cnt2, cnt3; long long int s; int t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long long int x, int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S as = { 0LL, 7 };
+S &a = as;
+S bs (1LL, 5);
+S &b = bs;
+
+void
+foo (S &c, S &d)
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: c) in_reduction (*: b, d) in_reduction (+: a)
+ {
+ a.s += 7;
+ b.s *= 2;
+ c.s += 9;
+ d.s *= 3;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+}
+
+void
+test ()
+{
+ S cs = { 0LL, 7 };
+ S &c = cs;
+ S ds (1LL, 5);
+ #pragma omp parallel
+ #pragma omp single
+ {
+ S &d = ds;
+ #pragma omp taskgroup task_reduction (+: a, c) task_reduction (*: b, d)
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (*: b, d) in_reduction (+: a, c)
+ {
+ int j;
+ a.s += 7;
+ b.s *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a) in_reduction (*: b) \
+ in_reduction (+: c) in_reduction (*: d)
+ {
+ a.s += 7;
+ b.s *= 2;
+ c.s += 9;
+ d.s *= 3;
+ foo (c, d);
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ c.s += 9;
+ d.s *= 3;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ }
+#define THREEP7 (3LL * 3LL * 3LL * 3LL * 3LL * 3LL * 3LL)
+ if (d.s != (THREEP7 * THREEP7 * THREEP7 * THREEP7) || d.t != 5)
+ abort ();
+ }
+ if (a.s != 28 * 7 || a.t != 7 || b.s != (1L << 28) || b.t != 5
+ || c.s != 28 * 9 || c.t != 7)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test ();
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-4.C b/libgomp/testsuite/libgomp.c++/task-reduction-4.C
new file mode 100644
index 00000000000..1d4da79b3c1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-4.C
@@ -0,0 +1,238 @@
+extern "C" void abort ();
+
+int as[2];
+int (&a)[2] = as;
+long long int bs[7] = { 9, 11, 1, 1, 1, 13, 15 };
+long long int (&b)[7] = bs;
+int es[3] = { 5, 0, 5 };
+int (&e)[3] = es;
+int fs[5] = { 6, 7, 0, 0, 9 };
+int (&f)[5] = fs;
+int gs[4] = { 1, 0, 0, 2 };
+int (&g)[4] = gs;
+int hs[3] = { 0, 1, 4 };
+int (&h)[3] = hs;
+int ks[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+int (&k)[4][2] = ks;
+long long *ss;
+long long *&s = ss;
+long long (*ts)[2];
+long long (*&t)[2] = ts;
+
+template <typename T>
+void
+foo (T &n, T *&c, long long int *&d, T (&m)[3], T *&r, T (&o)[4], T *&p, T (&q)[4][2])
+{
+ T i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0] += 7;
+ a[1] += 17;
+ b[2] *= 2;
+ b[4] *= 2;
+ c[0] += 6;
+ d[1] *= 2;
+ e[1] += 19;
+ f[2] += 21;
+ f[3] += 23;
+ g[1] += 25;
+ g[2] += 27;
+ h[0] += 29;
+ k[1][0] += 31;
+ k[2][1] += 33;
+ m[1] += 19;
+ r[2] += 21;
+ r[3] += 23;
+ o[1] += 25;
+ o[2] += 27;
+ p[0] += 29;
+ q[1][0] += 31;
+ q[2][1] += 33;
+ s[1] *= 2;
+ t[2][0] *= 2;
+ t[3][1] *= 2;
+ }
+}
+
+template <typename T>
+void
+test (T &n)
+{
+ T cs[2] = { 0, 0 };
+ T (&c)[2] = cs;
+ T ps[3] = { 0, 1, 4 };
+ T (&p)[3] = ps;
+ T qs[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+ T (&q)[4][2] = qs;
+ long long sb[4] = { 5, 1, 1, 6 };
+ long long tb[5][2] = { { 9, 10 }, { 11, 12 }, { 1, 1 }, { 1, 1 }, { 13, 14 } };
+ T ms[3] = { 5, 0, 5 };
+ T os[4] = { 1, 0, 0, 2 };
+ s = sb;
+ t = tb;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ long long int ds[] = { 1, 1 };
+ long long int (&d)[2] = ds;
+ T (&m)[3] = ms;
+ T rs[5] = { 6, 7, 0, 0, 9 };
+ T (&r)[5] = rs;
+ T (&o)[4] = os;
+ #pragma omp taskgroup task_reduction (+: a, c) task_reduction (*: b[2 * n:3 * n], d) \
+ task_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ task_reduction (+: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ task_reduction (*: t[2:2][:], s[1:n + 1])
+ {
+ T i;
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ T j;
+ a[0] += 2;
+ a[1] += 3;
+ b[2] *= 2;
+ f[3] += 8;
+ g[1] += 9;
+ g[2] += 10;
+ h[0] += 11;
+ k[1][1] += 13;
+ k[2][1] += 15;
+ m[1] += 16;
+ r[2] += 8;
+ s[1] *= 2;
+ t[2][1] *= 2;
+ t[3][1] *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1] += 6;
+ r[2] += 7;
+ q[1][0] += 17;
+ q[2][0] += 19;
+ a[0] += 4;
+ a[1] += 5;
+ b[3] *= 2;
+ b[4] *= 2;
+ f[3] += 18;
+ g[1] += 29;
+ g[2] += 18;
+ h[0] += 19;
+ s[2] *= 2;
+ t[2][0] *= 2;
+ t[3][0] *= 2;
+ T *cp = c;
+ long long int *dp = d;
+ T *rp = r;
+ T *pp = p;
+ foo (n, cp, dp, m, rp, o, pp, q);
+ r[3] += 18;
+ o[1] += 29;
+ o[2] += 18;
+ p[0] += 19;
+ c[0] += 4;
+ c[1] += 5;
+ d[0] *= 2;
+ e[1] += 6;
+ f[2] += 7;
+ k[1][0] += 17;
+ k[2][0] += 19;
+ }
+ r[3] += 8;
+ o[1] += 9;
+ o[2] += 10;
+ p[0] += 11;
+ q[1][1] += 13;
+ q[2][1] += 15;
+ b[3] *= 2;
+ c[0] += 4;
+ c[1] += 9;
+ d[0] *= 2;
+ e[1] += 16;
+ f[2] += 8;
+ }
+ }
+ if (d[0] != 1LL << (8 + 4)
+ || d[1] != 1LL << 16
+ || m[0] != 5
+ || m[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2] != 5
+ || r[0] != 6
+ || r[1] != 7
+ || r[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4] != 9
+ || o[0] != 1
+ || o[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3] != 2)
+ abort ();
+ }
+ if (a[0] != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1] != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0] != 9 || b[1] != 11
+ || b[2] != 1LL << (16 + 4)
+ || b[3] != 1LL << (8 + 4)
+ || b[4] != 1LL << (16 + 8)
+ || b[5] != 13 || b[6] != 15
+ || c[0] != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1] != 5 * 8 + 9 * 4
+ || e[0] != 5
+ || e[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2] != 5
+ || f[0] != 6
+ || f[1] != 7
+ || f[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4] != 9
+ || g[0] != 1
+ || g[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3] != 2
+ || h[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1] != 1 || h[2] != 4
+ || k[0][0] != 5 || k[0][1] != 6
+ || k[1][0] != 31 * 16 + 17 * 8
+ || k[1][1] != 13 * 4
+ || k[2][0] != 19 * 8
+ || k[2][1] != 33 * 16 + 15 * 4
+ || k[3][0] != 7 || k[3][1] != 8
+ || p[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1] != 1 || p[2] != 4
+ || q[0][0] != 5 || q[0][1] != 6
+ || q[1][0] != 31 * 16 + 17 * 8
+ || q[1][1] != 13 * 4
+ || q[2][0] != 19 * 8
+ || q[2][1] != 33 * 16 + 15 * 4
+ || q[3][0] != 7 || q[3][1] != 8
+ || sb[0] != 5
+ || sb[1] != 1LL << (16 + 4)
+ || sb[2] != 1LL << 8
+ || sb[3] != 6
+ || tb[0][0] != 9 || tb[0][1] != 10 || tb[1][0] != 11 || tb[1][1] != 12
+ || tb[2][0] != 1LL << (16 + 8)
+ || tb[2][1] != 1LL << 4
+ || tb[3][0] != 1LL << 8
+ || tb[3][1] != 1LL << (16 + 4)
+ || tb[4][0] != 13 || tb[4][1] != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ int n = 1;
+ test (n);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-5.C b/libgomp/testsuite/libgomp.c++/task-reduction-5.C
new file mode 100644
index 00000000000..59583f15c82
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-5.C
@@ -0,0 +1,320 @@
+extern "C" void abort ();
+
+struct S { S (); S (long int, long int); ~S (); static int cnt1, cnt2, cnt3; long int s, t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long int x, long int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S a[2] = { { 0, 7 }, { 0, 7 } };
+S b[7] = { { 9, 5 }, { 11, 5 }, { 1, 5 }, { 1, 5 }, { 1, 5 }, { 13, 5 }, { 15, 5 } };
+S e[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+S f[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+S g[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+S h[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+S k[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+S *s;
+S (*t)[2];
+
+void
+foo (int n, S *c, S *d, S m[3], S *r, S o[4], S *p, S q[4][2])
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0].s += 7;
+ a[1].s += 17;
+ b[2].s *= 2;
+ b[4].s *= 2;
+ c[0].s += 6;
+ d[1].s *= 2;
+ e[1].s += 19;
+ f[2].s += 21;
+ f[3].s += 23;
+ g[1].s += 25;
+ g[2].s += 27;
+ h[0].s += 29;
+ k[1][0].s += 31;
+ k[2][1].s += 33;
+ m[1].s += 19;
+ r[2].s += 21;
+ r[3].s += 23;
+ o[1].s += 25;
+ o[2].s += 27;
+ p[0].s += 29;
+ q[1][0].s += 31;
+ q[2][1].s += 33;
+ s[1].s *= 2;
+ t[2][0].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ }
+}
+
+void
+test (int n)
+{
+ S c[2] = { { 0, 7 }, { 0, 7 } };
+ S p[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+ S q[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+ S ss[4] = { { 5, 5 }, { 1, 5 }, { 1, 5 }, { 6, 5 } };
+ S tt[5][2] = { { { 9, 5 }, { 10, 5 } }, { { 11, 5 }, { 12, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 13, 5 }, { 14, 5 } } };
+ s = ss;
+ t = tt;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ S d[] = { { 1, 5 }, { 1, 5 } };
+ S m[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+ S r[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+ S o[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+ #pragma omp taskgroup task_reduction (+: a, c) task_reduction (*: b[2 * n:3 * n], d) \
+ task_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ task_reduction (+: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ task_reduction (*: t[2:2][:], s[1:n + 1])
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ int j;
+ a[0].s += 2;
+ a[1].s += 3;
+ b[2].s *= 2;
+ f[3].s += 8;
+ g[1].s += 9;
+ g[2].s += 10;
+ h[0].s += 11;
+ k[1][1].s += 13;
+ k[2][1].s += 15;
+ m[1].s += 16;
+ r[2].s += 8;
+ s[1].s *= 2;
+ t[2][1].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1].s += 6;
+ r[2].s += 7;
+ q[1][0].s += 17;
+ q[2][0].s += 19;
+ a[0].s += 4;
+ a[1].s += 5;
+ b[3].s *= 2;
+ b[4].s *= 2;
+ f[3].s += 18;
+ g[1].s += 29;
+ g[2].s += 18;
+ h[0].s += 19;
+ s[2].s *= 2;
+ t[2][0].s *= 2;
+ t[3][0].s *= 2;
+ foo (n, c, d, m, r, o, p, q);
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ r[3].s += 18;
+ o[1].s += 29;
+ o[2].s += 18;
+ p[0].s += 19;
+ c[0].s += 4;
+ c[1].s += 5;
+ d[0].s *= 2;
+ e[1].s += 6;
+ f[2].s += 7;
+ k[1][0].s += 17;
+ k[2][0].s += 19;
+ }
+ r[3].s += 8;
+ o[1].s += 9;
+ o[2].s += 10;
+ p[0].s += 11;
+ q[1][1].s += 13;
+ q[2][1].s += 15;
+ b[3].s *= 2;
+ c[0].s += 4;
+ c[1].s += 9;
+ d[0].s *= 2;
+ e[1].s += 16;
+ f[2].s += 8;
+ }
+ }
+ if (d[0].s != 1LL << (8 + 4)
+ || d[1].s != 1LL << 16
+ || m[0].s != 5
+ || m[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2].s != 5
+ || r[0].s != 6
+ || r[1].s != 7
+ || r[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4].s != 9
+ || o[0].s != 1
+ || o[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3].s != 2)
+ abort ();
+ if (e[1].t != 7 || h[0].t != 7 || m[1].t != 7 || p[0].t != 7)
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if (a[z].t != 7 || c[z].t != 7 || d[z].t != 5 || f[z + 2].t != 7
+ || g[z + 1].t != 7 || r[z + 2].t != 7 || s[z + 1].t != 5 || o[z + 1].t != 7
+ || k[z + 1][0].t != 7 || k[z + 1][1].t != 7 || q[z + 1][0].t != 7 || q[z + 1][1].t != 7
+ || t[z + 2][0].t != 5 || t[z + 2][1].t != 5)
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5)
+ abort ();
+ }
+ if (a[0].s != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1].s != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0].s != 9 || b[1].s != 11
+ || b[2].s != 1LL << (16 + 4)
+ || b[3].s != 1LL << (8 + 4)
+ || b[4].s != 1LL << (16 + 8)
+ || b[5].s != 13 || b[6].s != 15
+ || c[0].s != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1].s != 5 * 8 + 9 * 4
+ || e[0].s != 5
+ || e[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2].s != 5
+ || f[0].s != 6
+ || f[1].s != 7
+ || f[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4].s != 9
+ || g[0].s != 1
+ || g[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3].s != 2
+ || h[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1].s != 1 || h[2].s != 4
+ || k[0][0].s != 5 || k[0][1].s != 6
+ || k[1][0].s != 31 * 16 + 17 * 8
+ || k[1][1].s != 13 * 4
+ || k[2][0].s != 19 * 8
+ || k[2][1].s != 33 * 16 + 15 * 4
+ || k[3][0].s != 7 || k[3][1].s != 8
+ || p[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1].s != 1 || p[2].s != 4
+ || q[0][0].s != 5 || q[0][1].s != 6
+ || q[1][0].s != 31 * 16 + 17 * 8
+ || q[1][1].s != 13 * 4
+ || q[2][0].s != 19 * 8
+ || q[2][1].s != 33 * 16 + 15 * 4
+ || q[3][0].s != 7 || q[3][1].s != 8
+ || ss[0].s != 5
+ || ss[1].s != 1LL << (16 + 4)
+ || ss[2].s != 1LL << 8
+ || ss[3].s != 6
+ || tt[0][0].s != 9 || tt[0][1].s != 10 || tt[1][0].s != 11 || tt[1][1].s != 12
+ || tt[2][0].s != 1LL << (16 + 8)
+ || tt[2][1].s != 1LL << 4
+ || tt[3][0].s != 1LL << 8
+ || tt[3][1].s != 1LL << (16 + 4)
+ || tt[4][0].s != 13 || tt[4][1].s != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test (1);
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-6.C b/libgomp/testsuite/libgomp.c++/task-reduction-6.C
new file mode 100644
index 00000000000..d7f69da219b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-6.C
@@ -0,0 +1,341 @@
+extern "C" void abort ();
+
+struct S { S (); S (long int, long int); ~S (); static int cnt1, cnt2, cnt3; long int s, t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long int x, long int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S as[2] = { { 0, 7 }, { 0, 7 } };
+S (&a)[2] = as;
+S bs[7] = { { 9, 5 }, { 11, 5 }, { 1, 5 }, { 1, 5 }, { 1, 5 }, { 13, 5 }, { 15, 5 } };
+S (&b)[7] = bs;
+S es[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+S (&e)[3] = es;
+S fs[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+S (&f)[5] = fs;
+S gs[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+S (&g)[4] = gs;
+S hs[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+S (&h)[3] = hs;
+S ks[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+S (&k)[4][2] = ks;
+S *ss;
+S *&s = ss;
+S (*ts)[2];
+S (*&t)[2] = ts;
+
+void
+foo (int &n, S *&c, S *&d, S (&m)[3], S *&r, S (&o)[4], S *&p, S (&q)[4][2])
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0].s += 7;
+ a[1].s += 17;
+ b[2].s *= 2;
+ b[4].s *= 2;
+ c[0].s += 6;
+ d[1].s *= 2;
+ e[1].s += 19;
+ f[2].s += 21;
+ f[3].s += 23;
+ g[1].s += 25;
+ g[2].s += 27;
+ h[0].s += 29;
+ k[1][0].s += 31;
+ k[2][1].s += 33;
+ m[1].s += 19;
+ r[2].s += 21;
+ r[3].s += 23;
+ o[1].s += 25;
+ o[2].s += 27;
+ p[0].s += 29;
+ q[1][0].s += 31;
+ q[2][1].s += 33;
+ s[1].s *= 2;
+ t[2][0].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ }
+}
+
+void
+test (int &n)
+{
+ S cs[2] = { { 0, 7 }, { 0, 7 } };
+ S (&c)[2] = cs;
+ S ps[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+ S (&p)[3] = ps;
+ S qs[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+ S (&q)[4][2] = qs;
+ S sb[4] = { { 5, 5 }, { 1, 5 }, { 1, 5 }, { 6, 5 } };
+ S tb[5][2] = { { { 9, 5 }, { 10, 5 } }, { { 11, 5 }, { 12, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 13, 5 }, { 14, 5 } } };
+ S ms[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+ S os[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+ s = sb;
+ t = tb;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ S ds[] = { { 1, 5 }, { 1, 5 } };
+ S (&d)[2] = ds;
+ S (&m)[3] = ms;
+ S rs[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+ S (&r)[5] = rs;
+ S (&o)[4] = os;
+ #pragma omp taskgroup task_reduction (+: a, c) task_reduction (*: b[2 * n:3 * n], d) \
+ task_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ task_reduction (+: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ task_reduction (*: t[2:2][:], s[1:n + 1])
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ int j;
+ a[0].s += 2;
+ a[1].s += 3;
+ b[2].s *= 2;
+ f[3].s += 8;
+ g[1].s += 9;
+ g[2].s += 10;
+ h[0].s += 11;
+ k[1][1].s += 13;
+ k[2][1].s += 15;
+ m[1].s += 16;
+ r[2].s += 8;
+ s[1].s *= 2;
+ t[2][1].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1].s += 6;
+ r[2].s += 7;
+ q[1][0].s += 17;
+ q[2][0].s += 19;
+ a[0].s += 4;
+ a[1].s += 5;
+ b[3].s *= 2;
+ b[4].s *= 2;
+ f[3].s += 18;
+ g[1].s += 29;
+ g[2].s += 18;
+ h[0].s += 19;
+ s[2].s *= 2;
+ t[2][0].s *= 2;
+ t[3][0].s *= 2;
+ S *cp = c;
+ S *dp = d;
+ S *rp = r;
+ S *pp = p;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ foo (n, cp, dp, m, rp, o, pp, q);
+ r[3].s += 18;
+ o[1].s += 29;
+ o[2].s += 18;
+ p[0].s += 19;
+ c[0].s += 4;
+ c[1].s += 5;
+ d[0].s *= 2;
+ e[1].s += 6;
+ f[2].s += 7;
+ k[1][0].s += 17;
+ k[2][0].s += 19;
+ }
+ r[3].s += 8;
+ o[1].s += 9;
+ o[2].s += 10;
+ p[0].s += 11;
+ q[1][1].s += 13;
+ q[2][1].s += 15;
+ b[3].s *= 2;
+ c[0].s += 4;
+ c[1].s += 9;
+ d[0].s *= 2;
+ e[1].s += 16;
+ f[2].s += 8;
+ }
+ }
+ if (d[0].s != 1LL << (8 + 4)
+ || d[1].s != 1LL << 16
+ || m[0].s != 5
+ || m[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2].s != 5
+ || r[0].s != 6
+ || r[1].s != 7
+ || r[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4].s != 9
+ || o[0].s != 1
+ || o[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3].s != 2)
+ abort ();
+ if (e[1].t != 7 || h[0].t != 7 || m[1].t != 7 || p[0].t != 7)
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if (a[z].t != 7 || c[z].t != 7 || d[z].t != 5 || f[z + 2].t != 7
+ || g[z + 1].t != 7 || r[z + 2].t != 7 || s[z + 1].t != 5 || o[z + 1].t != 7
+ || k[z + 1][0].t != 7 || k[z + 1][1].t != 7 || q[z + 1][0].t != 7 || q[z + 1][1].t != 7
+ || t[z + 2][0].t != 5 || t[z + 2][1].t != 5)
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5)
+ abort ();
+ }
+ if (a[0].s != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1].s != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0].s != 9 || b[1].s != 11
+ || b[2].s != 1LL << (16 + 4)
+ || b[3].s != 1LL << (8 + 4)
+ || b[4].s != 1LL << (16 + 8)
+ || b[5].s != 13 || b[6].s != 15
+ || c[0].s != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1].s != 5 * 8 + 9 * 4
+ || e[0].s != 5
+ || e[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2].s != 5
+ || f[0].s != 6
+ || f[1].s != 7
+ || f[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4].s != 9
+ || g[0].s != 1
+ || g[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3].s != 2
+ || h[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1].s != 1 || h[2].s != 4
+ || k[0][0].s != 5 || k[0][1].s != 6
+ || k[1][0].s != 31 * 16 + 17 * 8
+ || k[1][1].s != 13 * 4
+ || k[2][0].s != 19 * 8
+ || k[2][1].s != 33 * 16 + 15 * 4
+ || k[3][0].s != 7 || k[3][1].s != 8
+ || p[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1].s != 1 || p[2].s != 4
+ || q[0][0].s != 5 || q[0][1].s != 6
+ || q[1][0].s != 31 * 16 + 17 * 8
+ || q[1][1].s != 13 * 4
+ || q[2][0].s != 19 * 8
+ || q[2][1].s != 33 * 16 + 15 * 4
+ || q[3][0].s != 7 || q[3][1].s != 8
+ || sb[0].s != 5
+ || sb[1].s != 1LL << (16 + 4)
+ || sb[2].s != 1LL << 8
+ || sb[3].s != 6
+ || tb[0][0].s != 9 || tb[0][1].s != 10 || tb[1][0].s != 11 || tb[1][1].s != 12
+ || tb[2][0].s != 1LL << (16 + 8)
+ || tb[2][1].s != 1LL << 4
+ || tb[3][0].s != 1LL << 8
+ || tb[3][1].s != 1LL << (16 + 4)
+ || tb[4][0].s != 13 || tb[4][1].s != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ int n = 1;
+ test (n);
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-7.C b/libgomp/testsuite/libgomp.c++/task-reduction-7.C
new file mode 100644
index 00000000000..2a4d82ef77b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-7.C
@@ -0,0 +1,145 @@
+typedef __SIZE_TYPE__ size_t;
+extern "C" void abort ();
+
+void
+bar (int *a, int *b, int *c, int (*d)[2], int (*e)[4], int *f, int *g, size_t n)
+{
+ #pragma omp task in_reduction (*: a[:n], b[3:n], c[n:n], d[0][:n], e[0][1:n], f[:n], g[1:n])
+ {
+ a[0] *= 12;
+ a[1] *= 13;
+ b[3] *= 14;
+ b[4] *= 15;
+ c[n] *= 16;
+ c[n + 1] *= 17;
+ d[0][0] *= 18;
+ d[0][1] *= 19;
+ e[0][1] *= 20;
+ e[0][2] *= 21;
+ f[0] *= 22;
+ f[1] *= 23;
+ g[1] *= 24;
+ g[2] *= 25;
+ }
+}
+
+void
+foo (size_t n, void *x, void *y)
+{
+ int a[n], b[n + 3], c[2 * n];
+ int (*d)[n] = (int (*)[n]) x;
+ int (*e)[n * 2] = (int (*)[n * 2]) y;
+ int fb[n], gb[n * 2];
+ int (&f)[n] = fb;
+ int (&g)[n * 2] = gb;
+ int i;
+ for (i = 0; i < n; i++)
+ {
+ a[i] = 1;
+ b[i + 3] = 1;
+ c[i + n] = 1;
+ d[0][i] = 1;
+ e[0][i + 1] = 1;
+ f[i] = 1;
+ g[i + 1] = 1;
+ }
+ #pragma omp taskgroup task_reduction (*: a, b[3:n], c[n:n], d[0][:n], e[0][1:n], f, g[1:n])
+ {
+ bar (a, b, c, (int (*)[2]) d, (int (*)[4]) e, &f[0], &g[0], n);
+ #pragma omp task in_reduction (*: a, b[3:n], c[n:n], d[0][:n], e[0][1:n], f, g[1:n])
+ {
+ a[0] *= 2;
+ a[1] *= 3;
+ b[3] *= 4;
+ b[4] *= 5;
+ c[n] *= 6;
+ c[n + 1] *= 7;
+ d[0][0] *= 8;
+ d[0][1] *= 9;
+ e[0][1] *= 10;
+ e[0][2] *= 11;
+ f[0] *= 12;
+ f[1] *= 13;
+ g[1] *= 14;
+ g[2] *= 15;
+ }
+ n = 0;
+ }
+ if (a[0] != 24 || a[1] != 39 || b[3] != 56 || b[4] != 75)
+ abort ();
+ if (c[2] != 96 || c[3] != 119 || d[0][0] != 144 || d[0][1] != 171)
+ abort ();
+ if (e[0][1] != 200 || e[0][2] != 231 || f[0] != 264 || f[1] != 299)
+ abort ();
+ if (g[1] != 336 || g[2] != 375)
+ abort ();
+}
+
+void
+baz (size_t n, void *x, void *y)
+{
+ int a[n], b[n + 3], c[2 * n];
+ int (*d)[n] = (int (*)[n]) x;
+ int (*e)[n * 2] = (int (*)[n * 2]) y;
+ int fb[n], gb[n * 2];
+ int i;
+ for (i = 0; i < n; i++)
+ {
+ a[i] = 1;
+ b[i + 3] = 1;
+ c[i + n] = 1;
+ d[0][i] = 1;
+ e[0][i + 1] = 1;
+ fb[i] = 1;
+ gb[i + 1] = 1;
+ }
+ #pragma omp parallel num_threads(2)
+ #pragma omp master
+ {
+ int (&f)[n] = fb;
+ int (&g)[n * 2] = gb;
+ #pragma omp taskgroup task_reduction (*: a, b[3:n], c[n:n], d[0][:n], e[0][1:n], f, g[1:n])
+ {
+ bar (a, b, c, (int (*)[2]) d, (int (*)[4]) e, &f[0], &g[0], n);
+ #pragma omp task in_reduction (*: a, b[3:n], c[n:n], d[0][:n], e[0][1:n], f, g[1:n])
+ {
+ a[0] *= 2;
+ a[1] *= 3;
+ b[3] *= 4;
+ b[4] *= 5;
+ c[n] *= 6;
+ c[n + 1] *= 7;
+ d[0][0] *= 8;
+ d[0][1] *= 9;
+ e[0][1] *= 10;
+ e[0][2] *= 11;
+ f[0] *= 12;
+ f[1] *= 13;
+ g[1] *= 14;
+ g[2] *= 15;
+ }
+ n = 0;
+ }
+ }
+ if (a[0] != 24 || a[1] != 39 || b[3] != 56 || b[4] != 75)
+ abort ();
+ if (c[2] != 96 || c[3] != 119 || d[0][0] != 144 || d[0][1] != 171)
+ abort ();
+ if (e[0][1] != 200 || e[0][2] != 231 || fb[0] != 264 || fb[1] != 299)
+ abort ();
+ if (gb[1] != 336 || gb[2] != 375)
+ abort ();
+}
+
+int
+main ()
+{
+ int d[2], e[4];
+ volatile int two;
+ two = 2;
+ #pragma omp parallel num_threads (2)
+ #pragma omp master
+ foo (two, (void *) d, (void *) e);
+ baz (two, (void *) d, (void *) e);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-8.C b/libgomp/testsuite/libgomp.c++/task-reduction-8.C
new file mode 100644
index 00000000000..26737a32acb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-8.C
@@ -0,0 +1,70 @@
+extern "C" void abort ();
+
+int as;
+int &a = as;
+long int bs = 1;
+long int &b = bs;
+
+template <typename T, typename U>
+void
+foo (T &c, U &d)
+{
+ T i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (*: d) in_reduction (+: c) \
+ in_reduction (+: a) in_reduction (*: b)
+ {
+ a += 7;
+ b *= 2;
+ c += 9;
+ d *= 3;
+ }
+}
+
+template <typename T, typename U>
+void
+bar ()
+{
+ T cs = 0;
+ T &c = cs;
+ U ds = 1;
+ #pragma omp parallel if (0)
+ {
+ U &d = ds;
+ #pragma omp parallel reduction (task, +: a, c) reduction (task, *: b, d)
+ {
+ T i;
+ #pragma omp for
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b, d)
+ {
+ T j;
+ a += 7;
+ b *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b, d)
+ {
+ a += 7;
+ b *= 2;
+ c += 9;
+ d *= 3;
+ foo (c, d);
+ }
+ c += 9;
+ d *= 3;
+ }
+ }
+#define THREEP4 (3LL * 3LL * 3LL * 3LL)
+ if (d != (THREEP4 * THREEP4 * THREEP4 * THREEP4 * THREEP4 * THREEP4
+ * THREEP4))
+ abort ();
+ }
+ if (a != 28 * 7 || b != (1L << 28) || c != 28 * 9)
+ abort ();
+}
+
+int
+main ()
+{
+ bar<int, long long int> ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-reduction-9.C b/libgomp/testsuite/libgomp.c++/task-reduction-9.C
new file mode 100644
index 00000000000..068a7bb7b5d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-reduction-9.C
@@ -0,0 +1,128 @@
+#include <omp.h>
+#include <stdlib.h>
+
+struct S { S (); S (long int, long int); ~S (); static int cnt1, cnt2, cnt3; long int s, t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long int x, long int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S a = { 0, 7 };
+S b (1, 5);
+
+void
+foo ()
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (*: b) in_reduction (+: a)
+ {
+ a.s += 7;
+ b.s *= 2;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9))
+ abort ();
+ }
+}
+
+void
+test ()
+{
+ S c = { 0, 7 };
+ int t;
+ #pragma omp parallel num_threads (1)
+ {
+ S d (1, 5);
+ int r = 0;
+ #pragma omp parallel reduction (task, +: a, c) reduction (task, *: b, d) \
+ reduction (+: r)
+ {
+ int i;
+ #pragma omp master
+ t = omp_get_num_threads ();
+ r++;
+ a.s += 3;
+ c.s += 4;
+ #pragma omp for
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (*: b, d) in_reduction (+: a, c)
+ {
+ int j;
+ a.s += 7;
+ b.s *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a) in_reduction (*: b) \
+ in_reduction (+: c) in_reduction (*: d)
+ {
+ a.s += 7;
+ b.s *= 2;
+ c.s += 9;
+ d.s *= 3;
+ foo ();
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ c.s += 9;
+ d.s *= 3;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ }
+#define THREEP4 (3L * 3L * 3L * 3L)
+ if (d.s != (THREEP4 * THREEP4 * THREEP4) || d.t != 5 || r != t)
+ abort ();
+ }
+ if (a.s != 28 * 7 + 3 * t || a.t != 7 || b.s != (1L << 28) || b.t != 5
+ || c.s != 12 * 9 + 4 * t || c.t != 7)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test ();
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/taskloop-reduction-1.C b/libgomp/testsuite/libgomp.c++/taskloop-reduction-1.C
new file mode 100644
index 00000000000..f7fb9cac9e5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/taskloop-reduction-1.C
@@ -0,0 +1,153 @@
+extern "C" void abort ();
+
+struct S { S (); S (unsigned long long int, int); ~S (); static int cnt1, cnt2, cnt3; unsigned long long int s; int t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (unsigned long long int x, int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+rbar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+rbaz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) \
+ initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : rbaz (&omp_out, &omp_in)) \
+ initializer (rbar (&omp_priv, &omp_orig))
+
+S gs = { 0, 7 };
+S &g = gs;
+S hs (1, 5);
+S &h = hs;
+
+int
+foo (int *a, int &b)
+{
+ int xs = 0;
+ int &x = xs;
+ #pragma omp taskloop reduction (+:x) in_reduction (+:b)
+ for (int i = 0; i < 64; i++)
+ {
+ x += a[i];
+ b += a[i] * 2;
+ }
+ return x;
+}
+
+unsigned long long int
+bar (int *a, unsigned long long int &b)
+{
+ unsigned long long int xs = 1;
+ unsigned long long int &x = xs;
+ #pragma omp taskloop reduction (*:x) in_reduction (*:b)
+ for (int i = 0; i < 64; i++)
+ {
+ #pragma omp task in_reduction (*:x)
+ x *= a[i];
+ #pragma omp task in_reduction (*:b)
+ b *= (3 - a[i]);
+ }
+ return x;
+}
+
+void
+baz (int i, int *a, int *c)
+{
+ #pragma omp task in_reduction (*:h) in_reduction (+:g)
+ {
+ g.s += 7 * a[i];
+ h.s *= (3 - c[i]);
+ if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9))
+ abort ();
+ }
+}
+
+void
+test ()
+{
+ int i, j, a[64], b = 0, c[64];
+ unsigned long long int d = 1, e;
+ S ms (0, 7);
+ for (i = 0; i < 64; i++)
+ {
+ a[i] = 2 * i;
+ c[i] = 1 + ((i % 3) != 1);
+ }
+ #pragma omp parallel
+ #pragma omp master
+ {
+ S ns = { 1, 5 };
+ S &m = ms;
+ S &n = ns;
+ #pragma omp taskgroup task_reduction (+:b)
+ j = foo (a, b);
+ #pragma omp taskgroup task_reduction (*:d)
+ e = bar (c, d);
+ #pragma omp taskloop reduction (+: g, m) reduction (*: h, n)
+ for (i = 0; i < 64; ++i)
+ {
+ g.s += 3 * a[i];
+ h.s *= (3 - c[i]);
+ m.s += 4 * a[i];
+ n.s *= c[i];
+ if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9)
+ || (m.t != 7 && m.t != 3) || (n.t != 5 && n.t != 9))
+ abort ();
+ baz (i, a, c);
+ }
+ if (n.s != (1ULL << 43) || n.t != 5)
+ abort ();
+ }
+ if (j != 63 * 64 || b != 63 * 64 * 2)
+ abort ();
+ if (e != (1ULL << 43) || d != (1ULL << 21))
+ abort ();
+ if (g.s != 63 * 64 * 10 || g.t != 7)
+ abort ();
+ if (h.s != (1ULL << 42) || h.t != 5)
+ abort ();
+ if (ms.s != 63 * 64 * 4 || ms.t != 7)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test ();
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/taskloop-reduction-2.C b/libgomp/testsuite/libgomp.c++/taskloop-reduction-2.C
new file mode 100644
index 00000000000..f1de5dae2ea
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/taskloop-reduction-2.C
@@ -0,0 +1,253 @@
+extern "C" void abort ();
+
+int as[2];
+int (&a)[2] = as;
+long long int bs[7] = { 9, 11, 1, 1, 1, 13, 15 };
+long long int (&b)[7] = bs;
+int es[3] = { 5, 0, 5 };
+int (&e)[3] = es;
+int fs[5] = { 6, 7, 0, 0, 9 };
+int (&f)[5] = fs;
+int gs[4] = { 1, 0, 0, 2 };
+int (&g)[4] = gs;
+int hs[3] = { 0, 1, 4 };
+int (&h)[3] = hs;
+int ks[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+int (&k)[4][2] = ks;
+long long *ss;
+long long *&s = ss;
+long long (*ts)[2];
+long long (*&t)[2] = ts;
+struct U { U (); ~U () {}; U (const U &); int u[4]; };
+
+U::U
+()
+{
+ u[0] = 0; u[1] = 1; u[2] = 2; u[3] = 3;
+}
+
+U::U
+(const U &r)
+{
+ u[0] = r.u[0]; u[1] = r.u[1]; u[2] = r.u[2]; u[3] = r.u[3];
+}
+
+void
+foo (int &n, int *&c, long long int *&d, int (&m)[3], int *&r, int (&o)[4], int *&p, int (&q)[4][2])
+{
+ int i;
+ U u;
+ u.u[2] = 8;
+ #pragma omp taskloop in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:]) firstprivate (u) nogroup
+ for (i = 0; i < 2; i++)
+ {
+ a[0] += 7;
+ a[1] += 17;
+ b[2] *= 2;
+ b[4] *= 2;
+ c[0] += 6;
+ d[1] *= 2;
+ e[1] += 19;
+ f[2] += 21;
+ f[3] += 23;
+ g[1] += 25;
+ g[2] += 27;
+ h[0] += 29;
+ k[1][0] += 31;
+ k[2][1] += 33;
+ m[1] += 19;
+ r[2] += 21;
+ r[3] += 23;
+ o[1] += 25;
+ o[2] += 27;
+ p[0] += 29;
+ q[1][0] += 31;
+ q[2][1] += 33;
+ s[1] *= 2;
+ t[2][0] *= 2;
+ t[3][1] *= 2;
+ if (u.u[2] != 8)
+ abort ();
+ }
+}
+
+void
+test (int &n)
+{
+ int cs[2] = { 0, 0 };
+ int (&c)[2] = cs;
+ int ps[3] = { 0, 1, 4 };
+ int (&p)[3] = ps;
+ int qs[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+ int (&q)[4][2] = qs;
+ long long sb[4] = { 5, 1, 1, 6 };
+ long long tb[5][2] = { { 9, 10 }, { 11, 12 }, { 1, 1 }, { 1, 1 }, { 13, 14 } };
+ int ms[3] = { 5, 0, 5 };
+ int os[4] = { 1, 0, 0, 2 };
+ s = sb;
+ t = tb;
+ U u;
+ u.u[2] = 10;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ long long int ds[] = { 1, 1 };
+ long long int (&d)[2] = ds;
+ int (&m)[3] = ms;
+ int rs[5] = { 6, 7, 0, 0, 9 };
+ int (&r)[5] = rs;
+ int (&o)[4] = os;
+ int i;
+ #pragma omp taskloop reduction (+: a, c) reduction (*: b[2 * n:3 * n], d) \
+ reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (+: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (*: t[2:2][:], s[1:n + 1]) firstprivate (u)
+ for (i = 0; i < 4; i++)
+ {
+ int j;
+ a[0] += 2;
+ a[1] += 3;
+ b[2] *= 2;
+ f[3] += 8;
+ g[1] += 9;
+ g[2] += 10;
+ h[0] += 11;
+ k[1][1] += 13;
+ k[2][1] += 15;
+ m[1] += 16;
+ r[2] += 8;
+ s[1] *= 2;
+ t[2][1] *= 2;
+ t[3][1] *= 2;
+ if (u.u[2] != 10)
+ abort ();
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:]) firstprivate (u)
+ {
+ m[1] += 6;
+ r[2] += 7;
+ q[1][0] += 17;
+ q[2][0] += 19;
+ a[0] += 4;
+ a[1] += 5;
+ b[3] *= 2;
+ b[4] *= 2;
+ f[3] += 18;
+ g[1] += 29;
+ g[2] += 18;
+ h[0] += 19;
+ s[2] *= 2;
+ t[2][0] *= 2;
+ t[3][0] *= 2;
+ int *cp = c;
+ long long int *dp = d;
+ int *rp = r;
+ int *pp = p;
+ foo (n, cp, dp, m, rp, o, pp, q);
+ if (u.u[2] != 10)
+ abort ();
+ r[3] += 18;
+ o[1] += 29;
+ o[2] += 18;
+ p[0] += 19;
+ c[0] += 4;
+ c[1] += 5;
+ d[0] *= 2;
+ e[1] += 6;
+ f[2] += 7;
+ k[1][0] += 17;
+ k[2][0] += 19;
+ }
+ r[3] += 8;
+ o[1] += 9;
+ o[2] += 10;
+ p[0] += 11;
+ q[1][1] += 13;
+ q[2][1] += 15;
+ b[3] *= 2;
+ c[0] += 4;
+ c[1] += 9;
+ d[0] *= 2;
+ e[1] += 16;
+ f[2] += 8;
+ }
+ if (d[0] != 1LL << (8 + 4)
+ || d[1] != 1LL << 16
+ || m[0] != 5
+ || m[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2] != 5
+ || r[0] != 6
+ || r[1] != 7
+ || r[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4] != 9
+ || o[0] != 1
+ || o[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3] != 2)
+ abort ();
+ }
+ if (a[0] != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1] != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0] != 9 || b[1] != 11
+ || b[2] != 1LL << (16 + 4)
+ || b[3] != 1LL << (8 + 4)
+ || b[4] != 1LL << (16 + 8)
+ || b[5] != 13 || b[6] != 15
+ || c[0] != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1] != 5 * 8 + 9 * 4
+ || e[0] != 5
+ || e[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2] != 5
+ || f[0] != 6
+ || f[1] != 7
+ || f[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4] != 9
+ || g[0] != 1
+ || g[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3] != 2
+ || h[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1] != 1 || h[2] != 4
+ || k[0][0] != 5 || k[0][1] != 6
+ || k[1][0] != 31 * 16 + 17 * 8
+ || k[1][1] != 13 * 4
+ || k[2][0] != 19 * 8
+ || k[2][1] != 33 * 16 + 15 * 4
+ || k[3][0] != 7 || k[3][1] != 8
+ || p[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1] != 1 || p[2] != 4
+ || q[0][0] != 5 || q[0][1] != 6
+ || q[1][0] != 31 * 16 + 17 * 8
+ || q[1][1] != 13 * 4
+ || q[2][0] != 19 * 8
+ || q[2][1] != 33 * 16 + 15 * 4
+ || q[3][0] != 7 || q[3][1] != 8
+ || sb[0] != 5
+ || sb[1] != 1LL << (16 + 4)
+ || sb[2] != 1LL << 8
+ || sb[3] != 6
+ || tb[0][0] != 9 || tb[0][1] != 10 || tb[1][0] != 11 || tb[1][1] != 12
+ || tb[2][0] != 1LL << (16 + 8)
+ || tb[2][1] != 1LL << 4
+ || tb[3][0] != 1LL << 8
+ || tb[3][1] != 1LL << (16 + 4)
+ || tb[4][0] != 13 || tb[4][1] != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ int n = 1;
+ test (n);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/taskloop-reduction-3.C b/libgomp/testsuite/libgomp.c++/taskloop-reduction-3.C
new file mode 100644
index 00000000000..0588e4744f9
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/taskloop-reduction-3.C
@@ -0,0 +1,314 @@
+extern "C" void abort ();
+
+struct S { S (); S (long int, long int); ~S (); static int cnt1, cnt2, cnt3; long int s, t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long int x, long int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S a[2] = { { 0, 7 }, { 0, 7 } };
+S b[7] = { { 9, 5 }, { 11, 5 }, { 1, 5 }, { 1, 5 }, { 1, 5 }, { 13, 5 }, { 15, 5 } };
+S e[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+S f[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+S g[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+S h[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+S k[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+S *s;
+S (*t)[2];
+
+void
+foo (int n, S *c, S *d, S m[3], S *r, S o[4], S *p, S q[4][2])
+{
+ int i;
+ #pragma omp taskloop in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:]) nogroup
+ for (i = 0; i < 2; i++)
+ {
+ a[0].s += 7;
+ a[1].s += 17;
+ b[2].s *= 2;
+ b[4].s *= 2;
+ c[0].s += 6;
+ d[1].s *= 2;
+ e[1].s += 19;
+ f[2].s += 21;
+ f[3].s += 23;
+ g[1].s += 25;
+ g[2].s += 27;
+ h[0].s += 29;
+ k[1][0].s += 31;
+ k[2][1].s += 33;
+ m[1].s += 19;
+ r[2].s += 21;
+ r[3].s += 23;
+ o[1].s += 25;
+ o[2].s += 27;
+ p[0].s += 29;
+ q[1][0].s += 31;
+ q[2][1].s += 33;
+ s[1].s *= 2;
+ t[2][0].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ }
+}
+
+void
+test (int n)
+{
+ S c[2] = { { 0, 7 }, { 0, 7 } };
+ S p[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+ S q[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+ S ss[4] = { { 5, 5 }, { 1, 5 }, { 1, 5 }, { 6, 5 } };
+ S tt[5][2] = { { { 9, 5 }, { 10, 5 } }, { { 11, 5 }, { 12, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 13, 5 }, { 14, 5 } } };
+ s = ss;
+ t = tt;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ S d[] = { { 1, 5 }, { 1, 5 } };
+ S m[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+ S r[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+ S o[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+ int i;
+ #pragma omp taskloop reduction (+: a, c) reduction (*: b[2 * n:3 * n], d) \
+ reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (+: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (*: t[2:2][:], s[1:n + 1])
+ for (i = 0; i < 4; i++)
+ {
+ int j;
+ a[0].s += 2;
+ a[1].s += 3;
+ b[2].s *= 2;
+ f[3].s += 8;
+ g[1].s += 9;
+ g[2].s += 10;
+ h[0].s += 11;
+ k[1][1].s += 13;
+ k[2][1].s += 15;
+ m[1].s += 16;
+ r[2].s += 8;
+ s[1].s *= 2;
+ t[2][1].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ #pragma omp taskloop in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:]) nogroup
+ for (j = 0; j < 2; j++)
+ {
+ m[1].s += 6;
+ r[2].s += 7;
+ q[1][0].s += 17;
+ q[2][0].s += 19;
+ a[0].s += 4;
+ a[1].s += 5;
+ b[3].s *= 2;
+ b[4].s *= 2;
+ f[3].s += 18;
+ g[1].s += 29;
+ g[2].s += 18;
+ h[0].s += 19;
+ s[2].s *= 2;
+ t[2][0].s *= 2;
+ t[3][0].s *= 2;
+ foo (n, c, d, m, r, o, p, q);
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ r[3].s += 18;
+ o[1].s += 29;
+ o[2].s += 18;
+ p[0].s += 19;
+ c[0].s += 4;
+ c[1].s += 5;
+ d[0].s *= 2;
+ e[1].s += 6;
+ f[2].s += 7;
+ k[1][0].s += 17;
+ k[2][0].s += 19;
+ }
+ r[3].s += 8;
+ o[1].s += 9;
+ o[2].s += 10;
+ p[0].s += 11;
+ q[1][1].s += 13;
+ q[2][1].s += 15;
+ b[3].s *= 2;
+ c[0].s += 4;
+ c[1].s += 9;
+ d[0].s *= 2;
+ e[1].s += 16;
+ f[2].s += 8;
+ }
+ if (d[0].s != 1LL << (8 + 4)
+ || d[1].s != 1LL << 16
+ || m[0].s != 5
+ || m[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2].s != 5
+ || r[0].s != 6
+ || r[1].s != 7
+ || r[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4].s != 9
+ || o[0].s != 1
+ || o[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3].s != 2)
+ abort ();
+ if (e[1].t != 7 || h[0].t != 7 || m[1].t != 7 || p[0].t != 7)
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if (a[z].t != 7 || c[z].t != 7 || d[z].t != 5 || f[z + 2].t != 7
+ || g[z + 1].t != 7 || r[z + 2].t != 7 || s[z + 1].t != 5 || o[z + 1].t != 7
+ || k[z + 1][0].t != 7 || k[z + 1][1].t != 7 || q[z + 1][0].t != 7 || q[z + 1][1].t != 7
+ || t[z + 2][0].t != 5 || t[z + 2][1].t != 5)
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5)
+ abort ();
+ }
+ if (a[0].s != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1].s != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0].s != 9 || b[1].s != 11
+ || b[2].s != 1LL << (16 + 4)
+ || b[3].s != 1LL << (8 + 4)
+ || b[4].s != 1LL << (16 + 8)
+ || b[5].s != 13 || b[6].s != 15
+ || c[0].s != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1].s != 5 * 8 + 9 * 4
+ || e[0].s != 5
+ || e[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2].s != 5
+ || f[0].s != 6
+ || f[1].s != 7
+ || f[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4].s != 9
+ || g[0].s != 1
+ || g[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3].s != 2
+ || h[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1].s != 1 || h[2].s != 4
+ || k[0][0].s != 5 || k[0][1].s != 6
+ || k[1][0].s != 31 * 16 + 17 * 8
+ || k[1][1].s != 13 * 4
+ || k[2][0].s != 19 * 8
+ || k[2][1].s != 33 * 16 + 15 * 4
+ || k[3][0].s != 7 || k[3][1].s != 8
+ || p[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1].s != 1 || p[2].s != 4
+ || q[0][0].s != 5 || q[0][1].s != 6
+ || q[1][0].s != 31 * 16 + 17 * 8
+ || q[1][1].s != 13 * 4
+ || q[2][0].s != 19 * 8
+ || q[2][1].s != 33 * 16 + 15 * 4
+ || q[3][0].s != 7 || q[3][1].s != 8
+ || ss[0].s != 5
+ || ss[1].s != 1LL << (16 + 4)
+ || ss[2].s != 1LL << 8
+ || ss[3].s != 6
+ || tt[0][0].s != 9 || tt[0][1].s != 10 || tt[1][0].s != 11 || tt[1][1].s != 12
+ || tt[2][0].s != 1LL << (16 + 8)
+ || tt[2][1].s != 1LL << 4
+ || tt[3][0].s != 1LL << 8
+ || tt[3][1].s != 1LL << (16 + 4)
+ || tt[4][0].s != 13 || tt[4][1].s != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test (1);
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/taskloop-reduction-4.C b/libgomp/testsuite/libgomp.c++/taskloop-reduction-4.C
new file mode 100644
index 00000000000..41c7040ff1a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/taskloop-reduction-4.C
@@ -0,0 +1,315 @@
+extern "C" void abort ();
+
+struct S { S (); S (long int, long int); ~S (); static int cnt1, cnt2, cnt3; long int s, t; };
+
+int S::cnt1;
+int S::cnt2;
+int S::cnt3;
+
+S::S ()
+{
+ #pragma omp atomic
+ cnt1++;
+}
+
+S::S (long int x, long int y) : s (x), t (y)
+{
+ #pragma omp atomic update
+ ++cnt2;
+}
+
+S::~S ()
+{
+ #pragma omp atomic
+ cnt3 = cnt3 + 1;
+ if (t < 3 || t > 9 || (t & 1) == 0)
+ abort ();
+}
+
+void
+bar (S *p, S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (S *o, S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: S : omp_out.s += omp_in.s) initializer (omp_priv (0, 3))
+#pragma omp declare reduction (*: S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+S a[2] = { { 0, 7 }, { 0, 7 } };
+S b[7] = { { 9, 5 }, { 11, 5 }, { 1, 5 }, { 1, 5 }, { 1, 5 }, { 13, 5 }, { 15, 5 } };
+S e[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+S f[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+S g[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+S h[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+S k[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+S *s;
+S (*t)[2];
+
+template <int N>
+void
+foo (int n, S *c, S *d, S m[3], S *r, S o[4], S *p, S q[4][2])
+{
+ int i;
+ #pragma omp taskloop in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ reduction (default, +: o[n:n*2], m[1], p[0]) in_reduction (+: k[1:2][:], f[2:2]) \
+ reduction (+: q[1:2][:], r[2:2]) in_reduction (+: g[n:n*2], e[1], h[0]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ for (i = 0; i < 2; i++)
+ {
+ a[0].s += 7;
+ a[1].s += 17;
+ b[2].s *= 2;
+ b[4].s *= 2;
+ c[0].s += 6;
+ d[1].s *= 2;
+ e[1].s += 19;
+ f[2].s += 21;
+ f[3].s += 23;
+ g[1].s += 25;
+ g[2].s += 27;
+ h[0].s += 29;
+ k[1][0].s += 31;
+ k[2][1].s += 33;
+ m[1].s += 19;
+ r[2].s += 21;
+ r[3].s += 23;
+ o[1].s += 25;
+ o[2].s += 27;
+ p[0].s += 29;
+ q[1][0].s += 31;
+ q[2][1].s += 33;
+ s[1].s *= 2;
+ t[2][0].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ }
+}
+
+template <typename T>
+void
+test (int n)
+{
+ T c[2] = { { 0, 7 }, { 0, 7 } };
+ T p[3] = { { 0, 7 }, { 1, 7 }, { 4, 7 } };
+ T q[4][2] = { { { 5, 7 }, { 6, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 0, 7 }, { 0, 7 } }, { { 7, 7 }, { 8, 7 } } };
+ T ss[4] = { { 5, 5 }, { 1, 5 }, { 1, 5 }, { 6, 5 } };
+ T tt[5][2] = { { { 9, 5 }, { 10, 5 } }, { { 11, 5 }, { 12, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 1, 5 }, { 1, 5 } }, { { 13, 5 }, { 14, 5 } } };
+ s = ss;
+ t = tt;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ T d[] = { { 1, 5 }, { 1, 5 } };
+ T m[3] = { { 5, 7 }, { 0, 7 }, { 5, 7 } };
+ T r[5] = { { 6, 7 }, { 7, 7 }, { 0, 7 }, { 0, 7 }, { 9, 7 } };
+ T o[4] = { { 1, 7 }, { 0, 7 }, { 0, 7 }, { 2, 7 } };
+ int i;
+ #pragma omp taskloop reduction (+: a, c) reduction (default, *: b[2 * n:3 * n], d) \
+ reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (+: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (*: t[2:2][:], s[1:n + 1])
+ for (i = 0; i < 4; i++)
+ {
+ int j;
+ a[0].s += 2;
+ a[1].s += 3;
+ b[2].s *= 2;
+ f[3].s += 8;
+ g[1].s += 9;
+ g[2].s += 10;
+ h[0].s += 11;
+ k[1][1].s += 13;
+ k[2][1].s += 15;
+ m[1].s += 16;
+ r[2].s += 8;
+ s[1].s *= 2;
+ t[2][1].s *= 2;
+ t[3][1].s *= 2;
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ #pragma omp taskloop in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:]) nogroup
+ for (j = 0; j < 2; j++)
+ {
+ m[1].s += 6;
+ r[2].s += 7;
+ q[1][0].s += 17;
+ q[2][0].s += 19;
+ a[0].s += 4;
+ a[1].s += 5;
+ b[3].s *= 2;
+ b[4].s *= 2;
+ f[3].s += 18;
+ g[1].s += 29;
+ g[2].s += 18;
+ h[0].s += 19;
+ s[2].s *= 2;
+ t[2][0].s *= 2;
+ t[3][0].s *= 2;
+ foo<0> (n, c, d, m, r, o, p, q);
+ if ((e[1].t != 7 && e[1].t != 3) || (h[0].t != 7 && h[0].t != 3)
+ || (m[1].t != 7 && m[1].t != 3) || (p[0].t != 7 && p[0].t != 3))
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if ((a[z].t != 7 && a[z].t != 3) || (c[z].t != 7 && c[z].t != 3)
+ || (d[z].t != 5 && d[z].t != 9) || (f[z + 2].t != 7 && f[z + 2].t != 3)
+ || (g[z + 1].t != 7 && g[z + 1].t != 3) || (r[z + 2].t != 7 && r[z + 2].t != 3)
+ || (s[z + 1].t != 5 && s[z + 1].t != 9) || (o[z + 1].t != 7 && o[z + 1].t != 3)
+ || (k[z + 1][0].t != 7 && k[z + 1][0].t != 3) || (k[z + 1][1].t != 7 && k[z + 1][1].t != 3)
+ || (q[z + 1][0].t != 7 && q[z + 1][0].t != 3) || (q[z + 1][1].t != 7 && q[z + 1][1].t != 3)
+ || (t[z + 2][0].t != 5 && t[z + 2][0].t != 9) || (t[z + 2][1].t != 5 && t[z + 2][1].t != 9))
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5 && b[z + 2].t != 9)
+ abort ();
+ r[3].s += 18;
+ o[1].s += 29;
+ o[2].s += 18;
+ p[0].s += 19;
+ c[0].s += 4;
+ c[1].s += 5;
+ d[0].s *= 2;
+ e[1].s += 6;
+ f[2].s += 7;
+ k[1][0].s += 17;
+ k[2][0].s += 19;
+ }
+ r[3].s += 8;
+ o[1].s += 9;
+ o[2].s += 10;
+ p[0].s += 11;
+ q[1][1].s += 13;
+ q[2][1].s += 15;
+ b[3].s *= 2;
+ c[0].s += 4;
+ c[1].s += 9;
+ d[0].s *= 2;
+ e[1].s += 16;
+ f[2].s += 8;
+ }
+ if (d[0].s != 1LL << (8 + 4)
+ || d[1].s != 1LL << 16
+ || m[0].s != 5
+ || m[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2].s != 5
+ || r[0].s != 6
+ || r[1].s != 7
+ || r[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4].s != 9
+ || o[0].s != 1
+ || o[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3].s != 2)
+ abort ();
+ if (e[1].t != 7 || h[0].t != 7 || m[1].t != 7 || p[0].t != 7)
+ abort ();
+ for (int z = 0; z < 2; z++)
+ if (a[z].t != 7 || c[z].t != 7 || d[z].t != 5 || f[z + 2].t != 7
+ || g[z + 1].t != 7 || r[z + 2].t != 7 || s[z + 1].t != 5 || o[z + 1].t != 7
+ || k[z + 1][0].t != 7 || k[z + 1][1].t != 7 || q[z + 1][0].t != 7 || q[z + 1][1].t != 7
+ || t[z + 2][0].t != 5 || t[z + 2][1].t != 5)
+ abort ();
+ for (int z = 0; z < 3; z++)
+ if (b[z + 2].t != 5)
+ abort ();
+ }
+ if (a[0].s != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1].s != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0].s != 9 || b[1].s != 11
+ || b[2].s != 1LL << (16 + 4)
+ || b[3].s != 1LL << (8 + 4)
+ || b[4].s != 1LL << (16 + 8)
+ || b[5].s != 13 || b[6].s != 15
+ || c[0].s != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1].s != 5 * 8 + 9 * 4
+ || e[0].s != 5
+ || e[1].s != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2].s != 5
+ || f[0].s != 6
+ || f[1].s != 7
+ || f[2].s != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3].s != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4].s != 9
+ || g[0].s != 1
+ || g[1].s != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2].s != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3].s != 2
+ || h[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1].s != 1 || h[2].s != 4
+ || k[0][0].s != 5 || k[0][1].s != 6
+ || k[1][0].s != 31 * 16 + 17 * 8
+ || k[1][1].s != 13 * 4
+ || k[2][0].s != 19 * 8
+ || k[2][1].s != 33 * 16 + 15 * 4
+ || k[3][0].s != 7 || k[3][1].s != 8
+ || p[0].s != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1].s != 1 || p[2].s != 4
+ || q[0][0].s != 5 || q[0][1].s != 6
+ || q[1][0].s != 31 * 16 + 17 * 8
+ || q[1][1].s != 13 * 4
+ || q[2][0].s != 19 * 8
+ || q[2][1].s != 33 * 16 + 15 * 4
+ || q[3][0].s != 7 || q[3][1].s != 8
+ || ss[0].s != 5
+ || ss[1].s != 1LL << (16 + 4)
+ || ss[2].s != 1LL << 8
+ || ss[3].s != 6
+ || tt[0][0].s != 9 || tt[0][1].s != 10 || tt[1][0].s != 11 || tt[1][1].s != 12
+ || tt[2][0].s != 1LL << (16 + 8)
+ || tt[2][1].s != 1LL << 4
+ || tt[3][0].s != 1LL << 8
+ || tt[3][1].s != 1LL << (16 + 4)
+ || tt[4][0].s != 13 || tt[4][1].s != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ int c1 = S::cnt1, c2 = S::cnt2, c3 = S::cnt3;
+ test<S> (1);
+ if (S::cnt1 + S::cnt2 - c1 - c2 != S::cnt3 - c3)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/cancel-parallel-1.c b/libgomp/testsuite/libgomp.c-c++-common/cancel-parallel-1.c
new file mode 100644
index 00000000000..77395e2b0f3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/cancel-parallel-1.c
@@ -0,0 +1,42 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var OMP_CANCELLATION "true" } */
+
+#include <stdlib.h>
+#include <omp.h>
+
+int
+main ()
+{
+ int a[64];
+ #pragma omp parallel
+ {
+ #pragma omp barrier
+ if (omp_get_thread_num () == 0)
+ {
+ #pragma omp cancel parallel
+ }
+ #pragma omp for
+ for (int i = 0; i < 64; i++)
+ a[i] = i;
+ if (omp_get_cancellation ())
+ abort ();
+ }
+ #pragma omp parallel
+ {
+ #pragma omp barrier
+ if (omp_get_thread_num () == 0)
+ {
+ #pragma omp cancel parallel
+ }
+ #pragma omp taskgroup
+ {
+ #pragma omp for
+ for (int i = 0; i < 64; i++)
+ #pragma omp task
+ a[i] += i;
+ if (omp_get_cancellation ())
+ abort ();
+ }
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-3.c b/libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-3.c
new file mode 100644
index 00000000000..9e07cc10b65
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-3.c
@@ -0,0 +1,73 @@
+/* { dg-do run { target tls_runtime } } */
+/* { dg-set-target-env-var OMP_CANCELLATION "true" } */
+
+#include <stdlib.h>
+#include <omp.h>
+
+int t;
+#pragma omp threadprivate (t)
+
+int
+main ()
+{
+ int a = 0, i;
+ #pragma omp parallel
+ #pragma omp taskgroup
+ {
+ #pragma omp task
+ {
+ #pragma omp cancel taskgroup
+ if (omp_get_cancellation ())
+ abort ();
+ }
+ #pragma omp taskwait
+ #pragma omp for reduction (task, +: a)
+ for (i = 0; i < 64; ++i)
+ {
+ a++;
+ #pragma omp task in_reduction (+: a)
+ {
+ volatile int zero = 0;
+ a += zero;
+ if (omp_get_cancellation ())
+ abort ();
+ }
+ }
+ if (a != 64)
+ abort ();
+ #pragma omp task
+ {
+ if (omp_get_cancellation ())
+ abort ();
+ }
+ }
+ a = 0;
+ #pragma omp parallel
+ #pragma omp taskgroup
+ {
+ int p;
+ #pragma omp for reduction (task, +: a)
+ for (i = 0; i < 64; ++i)
+ {
+ a++;
+ t = 1;
+ #pragma omp task in_reduction (+: a)
+ {
+ volatile int zero = 0;
+ a += zero;
+ #pragma omp cancel taskgroup
+ if (omp_get_cancellation ())
+ abort ();
+ }
+ }
+ if (a != 64)
+ abort ();
+ p = t;
+ #pragma omp task firstprivate (p)
+ {
+ if (p && omp_get_cancellation ())
+ abort ();
+ }
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c b/libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c
new file mode 100644
index 00000000000..341bfb84ea8
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var OMP_CANCELLATION "true" } */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <omp.h>
+
+int
+main ()
+{
+ int i;
+ #pragma omp parallel
+ {
+ int c = 0;
+ #pragma omp barrier
+ #pragma omp master taskloop num_tasks (25) firstprivate (c)
+ for (i = 0; i < 50; i++)
+ {
+ if (c && omp_get_cancellation ())
+ abort ();
+ #pragma omp cancellation point taskgroup
+ usleep (30);
+ if (i > 10)
+ c = 1;
+ #pragma omp cancel taskgroup if (i > 10)
+ if (i > 10 && omp_get_cancellation ())
+ abort ();
+ }
+ usleep (10);
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/depend-iterator-1.c b/libgomp/testsuite/libgomp.c-c++-common/depend-iterator-1.c
new file mode 100644
index 00000000000..03cded42cbd
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/depend-iterator-1.c
@@ -0,0 +1,115 @@
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+int arr[64], arr2[64], arr3[64];
+
+int *
+foo (int x, int y, long z)
+{
+ int v;
+ switch (x)
+ {
+ case 1:
+ if (z != 0 || y < 0 || y >= 64)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = arr2[y];
+ arr2[y]++;
+ }
+ if (v != 0) abort ();
+ return &arr[y];
+ case 2:
+ if (y < 0 || y > 60 || (y & 3) || z < 0 || z >= 4)
+ abort ();
+ #pragma omp atomic
+ arr2[y + z] = arr2[y + z] + 4;
+ return &arr[y + z];
+ case 3:
+ if (z < 0 || z > 60 || (z & 3) || y < 0 || y >= 4)
+ abort ();
+ #pragma omp atomic
+ arr2[y + z] = arr2[y + z] + 16;
+ return &arr[y + z];
+ case 4:
+ if (y != 0 || z > 64 || z <= 0)
+ abort ();
+ #pragma omp atomic
+ arr2[z - 1] = arr2[z - 1] + 64;
+ return &arr[z - 1];
+ case 5:
+ if ((y & 3) != 0 || y < 64 || y >= 96
+ || (z & 127) != 0 || z < 512 || z >= 1024)
+ abort ();
+ y = (y - 64) + (z - 512) / 128;
+ #pragma omp atomic
+ arr2[y] = arr2[y] + 256;
+ return &arr[y];
+ case 6:
+ if ((y & 3) != 0 || y <= 64 || y > 96
+ || (z & 127) != 1 || z <= 513 || z > 1025)
+ abort ();
+ y = (y - 68) + (z - 641) / 128;
+ #pragma omp atomic
+ arr2[y] = arr2[y] + 1024;
+ return &arr[y];
+ default:
+ abort ();
+ }
+}
+
+volatile int beg, end, step, step2;
+volatile unsigned int begu, endu;
+
+int
+main ()
+{
+ int m;
+ beg = 60;
+ end = -4;
+ step = -4;
+ step2 = 4;
+ begu = -64U;
+ endu = -32U;
+ #pragma omp parallel
+ #pragma omp master
+ {
+ int i;
+ for (i = 0; i < 64; i++)
+ #pragma omp task depend (iterator (j=i:i+1) , out : foo (1, j, 0)[0])
+ arr[i] = i;
+ #pragma omp task depend (iterator (int k=beg:end:step,long int l=0:4:1) , inout : \
+ foo (2, k, l)[0], foo (3, l, k)[0]) private (i)
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i)
+ abort ();
+ else
+ arr[i] = arr[i] + 1;
+ #pragma omp task depend (iterator (int *p=&arr3[64]:&arr3[0]:-1) , inout : \
+ foo (4, 0, p - &arr3[0])[0]) depend (in : beg)
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i + 1)
+ abort ();
+ else
+ arr[i] = arr[i] + 2;
+ #pragma omp task depend (iterator (unsigned n=begu:endu:step2, unsigned int o = 512: 1024U: (unsigned char) 128), inout : \
+ foo (5, n + 128, o)[0])
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i + 3)
+ abort ();
+ else
+ arr[i] = arr[i] + 4;
+ #pragma omp task depend (iterator (int unsigned p=endu:begu:step,unsigned q= 1025U:513U:(signed char) -128), in : \
+ foo (6, p + 128, q)[0])
+ for (i = 0; i < 64; i++)
+ if (arr[i] != i + 7)
+ abort ();
+ else
+ arr[i] = arr[i] + 8;
+ }
+ for (m = 0; m < 64; m++)
+ if (arr[m] != m + 15 || arr2[m] != (m < 32 ? 1365 : 85))
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/depend-iterator-2.c b/libgomp/testsuite/libgomp.c-c++-common/depend-iterator-2.c
new file mode 100644
index 00000000000..d9cbfdcbe79
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/depend-iterator-2.c
@@ -0,0 +1,63 @@
+volatile int v;
+
+__attribute__((noipa)) void
+foo (int *p, int i)
+{
+ #pragma omp task depend (out: p[0])
+ v++;
+ #pragma omp task depend (in: p[0])
+ v++;
+ #pragma omp task depend (inout: p[0])
+ v++;
+ #pragma omp task depend (mutexinoutset: p[0])
+ v++;
+ #pragma omp task depend (out: p[0]) depend (in: p[1])
+ v++;
+ #pragma omp task depend (in: p[0]) depend (inout: p[1])
+ v++;
+ #pragma omp task depend (inout: p[0]) depend (mutexinoutset: p[1])
+ v++;
+ #pragma omp task depend (mutexinoutset: p[0]) depend (out: p[1])
+ v++;
+ #pragma omp task depend (iterator (j=0:2) , out : p[j])
+ v++;
+ #pragma omp task depend (iterator (j=0:2) , in : p[j])
+ v++;
+ #pragma omp task depend (iterator (j=0:2) , inout : p[j])
+ v++;
+ #pragma omp task depend (iterator (j=0:2) , mutexinoutset : p[j])
+ v++;
+ #pragma omp task depend (iterator (j=0:2) , out : p[j]) depend (iterator (j=0:2) , in : p[j + 2])
+ v++;
+ #pragma omp task depend (iterator (j=0:2) , in : p[j]) depend (iterator (j=0:2) , inout : p[j + 2])
+ v++;
+ #pragma omp task depend (iterator (j=0:2) , inout : p[j]) depend (iterator (j=0:2) , mutexinoutset : p[j + 2])
+ v++;
+ #pragma omp task depend (iterator (j=0:2) , mutexinoutset : p[j]) depend (iterator (j=0:2) , out : p[j + 2])
+ v++;
+ #pragma omp task depend (iterator (j=0:i) , out : p[j])
+ v++;
+ #pragma omp task depend (iterator (j=0:i) , in : p[j])
+ v++;
+ #pragma omp task depend (iterator (j=0:i) , inout : p[j])
+ v++;
+ #pragma omp task depend (iterator (j=0:i) , mutexinoutset : p[j])
+ v++;
+ #pragma omp task depend (iterator (j=0:i) , out : p[j]) depend (iterator (j=0:i) , in : p[j + 2])
+ v++;
+ #pragma omp task depend (iterator (j=0:i) , in : p[j]) depend (iterator (j=0:i) , inout : p[j + 2])
+ v++;
+ #pragma omp task depend (iterator (j=0:i) , inout : p[j]) depend (iterator (j=0:i) , mutexinoutset : p[j + 2])
+ v++;
+ #pragma omp task depend (iterator (j=0:i) , mutexinoutset : p[j]) depend (iterator (j=0:i) , out : p[j + 2])
+ v++;
+}
+
+int
+main ()
+{
+ int p[4];
+ foo (p, 2);
+ foo (p, -1);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-1.c b/libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-1.c
new file mode 100644
index 00000000000..86322eddbcc
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-1.c
@@ -0,0 +1,28 @@
+int
+main ()
+{
+ int a, b, c, d;
+ #pragma omp parallel num_threads (6)
+ #pragma omp single
+ {
+ #pragma omp task depend(out: c)
+ c = 1;
+ #pragma omp task depend(out: a)
+ a = 2;
+ #pragma omp task depend(out: b)
+ b = 3;
+ /* The above 3 tasks can be scheduled in any order. */
+ #pragma omp task depend(in: a) depend(mutexinoutset: c)
+ c += a;
+ #pragma omp task depend(in: b) depend(mutexinoutset: c)
+ c += b;
+ /* The above 2 tasks are mutually exclusive and need to wait
+ for the first and second or first and third tasks respectively. */
+ #pragma omp task depend(in: c)
+ d = c;
+ /* The above task needs to wait for the mutexinoutset tasks. */
+ }
+ if (d != 6)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-2.c b/libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-2.c
new file mode 100644
index 00000000000..ed92063e2c9
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/depend-mutexinout-2.c
@@ -0,0 +1,59 @@
+int
+main ()
+{
+ int a, b, c = 0;
+ #pragma omp parallel num_threads(2)
+ {
+ #pragma omp barrier
+ #pragma omp single
+ {
+ #pragma omp task depend(out: a)
+ {
+ int i;
+ a = 0;
+ for (i = 0; i < 524288; ++i)
+ {
+ asm volatile ("" : "+g" (a));
+ a++;
+ }
+ }
+ #pragma omp task depend(out: b)
+ {
+ int i;
+ b = 0;
+ for (i = 0; i < 64; ++i)
+ {
+ asm volatile ("" : "+g" (b));
+ b++;
+ }
+ }
+ #pragma omp task depend(in: a) depend(mutexinoutset: c)
+ {
+ int i;
+ int d = c;
+ for (i = 0; i < 524288 + 64 - a; ++i)
+ {
+ asm volatile ("" : "+g" (d) : "g" (&a) : "memory");
+ d++;
+ }
+ asm volatile ("" : "+g" (d), "+g" (c));
+ c = d;
+ }
+ #pragma omp task depend(in: b) depend(mutexinoutset: c)
+ {
+ int i;
+ int d = c;
+ for (i = 0; i < 524288 + 64 - b; ++i)
+ {
+ asm volatile ("" : "+g" (d) : "g" (&b) : "memory");
+ d++;
+ }
+ asm volatile ("" : "+g" (d), "+g" (c));
+ c = d;
+ }
+ }
+ }
+ if (c != 524288 + 64)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/depobj-1.c b/libgomp/testsuite/libgomp.c-c++-common/depobj-1.c
new file mode 100644
index 00000000000..a07a0c889c1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/depobj-1.c
@@ -0,0 +1,99 @@
+#include <stdlib.h>
+#include <omp.h>
+
+void
+dep (void)
+{
+ int x = 1;
+ omp_depend_t d1, d2;
+ #pragma omp depobj (d1) depend(in: x)
+ #pragma omp depobj (d2) depend(in: x)
+ #pragma omp depobj (d2) update(out)
+ #pragma omp parallel
+ #pragma omp single
+ {
+ #pragma omp task shared (x) depend(depobj: d2)
+ x = 2;
+ #pragma omp task shared (x) depend(depobj: d1)
+ if (x != 2)
+ abort ();
+ }
+ #pragma omp depobj (d2) destroy
+ #pragma omp depobj (d1) destroy
+}
+
+void
+dep2 (void)
+{
+ #pragma omp parallel
+ #pragma omp single
+ {
+ int x = 1;
+ omp_depend_t d1, d2;
+ #pragma omp depobj (d1) depend(out: x)
+ #pragma omp depobj (*&d2) depend (in:x)
+ #pragma omp depobj(d2)update(in)
+ #pragma omp task shared (x) depend(depobj:d1)
+ x = 2;
+ #pragma omp task shared (x) depend(depobj : d2)
+ if (x != 2)
+ abort ();
+ #pragma omp taskwait
+ #pragma omp depobj(d1)destroy
+ #pragma omp depobj((&d2)[0]) destroy
+ }
+}
+
+void
+dep3 (void)
+{
+ omp_depend_t d[2];
+ #pragma omp parallel
+ {
+ int x = 1;
+ #pragma omp single
+ {
+ #pragma omp depobj(d[0]) depend(out:x)
+ #pragma omp depobj(d[1]) depend(in: x)
+ #pragma omp task shared (x) depend(depobj: *d)
+ x = 2;
+ #pragma omp task shared (x) depend(depobj: *(d + 1))
+ if (x != 2)
+ abort ();
+ }
+ }
+ #pragma omp depobj(d[0]) destroy
+ #pragma omp depobj(d[1]) destroy
+}
+
+int xx;
+omp_depend_t dd1, dd2;
+
+void
+antidep (void)
+{
+ xx = 1;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ #pragma omp task shared(xx) depend(depobj:dd2)
+ if (xx != 1)
+ abort ();
+ #pragma omp task shared(xx) depend(depobj:dd1)
+ xx = 2;
+ }
+}
+
+int
+main ()
+{
+ dep ();
+ dep2 ();
+ dep3 ();
+ #pragma omp depobj (dd1) depend (inout: xx)
+ #pragma omp depobj (dd2) depend (in : xx)
+ antidep ();
+ #pragma omp depobj (dd2) destroy
+ #pragma omp depobj (dd1) destroy
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/display-affinity-1.c b/libgomp/testsuite/libgomp.c-c++-common/display-affinity-1.c
new file mode 100644
index 00000000000..a67bb37f1f0
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/display-affinity-1.c
@@ -0,0 +1,91 @@
+/* { dg-set-target-env-var OMP_PROC_BIND "spread,close" } */
+/* { dg-set-target-env-var OMP_PLACES "cores" } */
+/* { dg-set-target-env-var OMP_NUM_THREADS "4" } */
+/* { dg-set-target-env-var OMP_AFFINITY_FORMAT "hello" } */
+
+#include <omp.h>
+#include <string.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+#define FMT "L:%0.5L%%%n>%32H<!%.33{host}!%.6P_%i_%0.18i_%0.7{ancestor_tnum} %18A"
+ char buf[] = FMT, hostname[256], buf2[512 + 32], *q;
+ size_t l, l2, l3;
+ char *r = getenv ("OMP_AFFINITY_FORMAT");
+ if (r && strcmp (r, "hello") == 0)
+ {
+ if (omp_get_affinity_format (NULL, 0) != 5)
+ abort ();
+ if (omp_get_affinity_format (buf2, 3) != 5
+ || strcmp (buf2, "he") != 0)
+ abort ();
+ if (omp_get_affinity_format (buf2, 6) != 5
+ || strcmp (buf2, "hello") != 0)
+ abort ();
+ }
+ omp_set_affinity_format (buf);
+ memset (buf, '^', sizeof (buf));
+ if (omp_get_affinity_format (NULL, 0) != sizeof (buf) - 1)
+ abort ();
+ if (omp_get_affinity_format (buf, 3) != sizeof (buf) - 1
+ || buf[0] != FMT[0] || buf[1] != FMT[1] || buf[2] != '\0')
+ abort ();
+ memset (buf, ' ', sizeof (buf));
+ if (omp_get_affinity_format (buf, sizeof (buf) - 1) != sizeof (buf) - 1
+ || strncmp (buf, FMT, sizeof (buf) - 2) != 0
+ || buf[sizeof (buf) - 2] != '\0')
+ abort ();
+ memset (buf, '-', sizeof (buf));
+ if (omp_get_affinity_format (buf, sizeof (buf)) != sizeof (buf) - 1
+ || strcmp (buf, FMT) != 0)
+ abort ();
+ memset (buf, '0', sizeof (buf));
+ omp_display_affinity (NULL);
+ omp_display_affinity ("");
+ omp_display_affinity ("%%%0.9N");
+ omp_set_affinity_format ("%{host}");
+ l = omp_capture_affinity (hostname, sizeof hostname, NULL);
+ if (l < sizeof (hostname))
+ {
+ if (strlen (hostname) != l)
+ abort ();
+ l2 = omp_capture_affinity (NULL, 0,
+ "%0.5{nesting_level}%%%32{host}|||%.33H"
+ "%0.7a%3N!%N!");
+ if (l2 != (5 + 1 + (l > 32 ? l : 32) + 3 + (l > 33 ? l : 33)
+ + 7 + 3 + 1 + 1 + 1))
+ abort ();
+ omp_set_affinity_format ("%.5L%%%32H|||%.33{host}%0.7{ancestor_tnum}"
+ "%3{num_threads}!%{num_threads}!");
+ l3 = omp_capture_affinity (buf2, sizeof buf2, "");
+ if (l3 != l2)
+ abort ();
+ if (memcmp (buf2, " 0%", 5 + 1) != 0)
+ abort ();
+ q = buf2 + 6;
+ if (memcmp (q, hostname, l) != 0)
+ abort ();
+ q += l;
+ if (l < 32)
+ for (l3 = 32 - l; l3; l3--)
+ if (*q++ != ' ')
+ abort ();
+ if (memcmp (q, "|||", 3) != 0)
+ abort ();
+ q += 3;
+ if (l < 33)
+ for (l3 = 33 - l; l3; l3--)
+ if (*q++ != ' ')
+ abort ();
+ if (memcmp (q, hostname, l) != 0)
+ abort ();
+ q += l;
+ if (strcmp (q, "-0000011 !1!") != 0)
+ abort ();
+ }
+ #pragma omp parallel num_threads (4) proc_bind(spread)
+ omp_display_affinity ("%0.2a!%n!%.4L!%N;%.2t;%0.2T;%{team_num};%{num_teams};%A");
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-10.c b/libgomp/testsuite/libgomp.c-c++-common/for-10.c
new file mode 100644
index 00000000000..2b339a599ce
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-10.c
@@ -0,0 +1,4 @@
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#define CONDNE
+#include "for-4.c"
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-11.c b/libgomp/testsuite/libgomp.c-c++-common/for-11.c
new file mode 100644
index 00000000000..e46b4dd04c1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-11.c
@@ -0,0 +1,4 @@
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#define CONDNE
+#include "for-5.c"
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-12.c b/libgomp/testsuite/libgomp.c-c++-common/for-12.c
new file mode 100644
index 00000000000..e28ba93f8fe
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-12.c
@@ -0,0 +1,4 @@
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#define CONDNE
+#include "for-6.c"
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-13.c b/libgomp/testsuite/libgomp.c-c++-common/for-13.c
new file mode 100644
index 00000000000..a4767278fbb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-13.c
@@ -0,0 +1,99 @@
+unsigned short a[256];
+
+__attribute__((noinline, noclone)) void
+bar (void *x, unsigned short z)
+{
+ unsigned short *y = (unsigned short *) x;
+ if (y < &a[5] || y > &a[222] || y == &a[124])
+ __builtin_abort ();
+ *y += z;
+}
+
+__attribute__((noinline, noclone)) void
+foo (void *qx, void *rx, void *sx, int n)
+{
+ unsigned short (*q)[n], (*r)[n], (*s)[n], (*p)[n];
+ q = (typeof (q)) qx;
+ r = (typeof (r)) rx;
+ s = (typeof (s)) sx;
+ #pragma omp for
+ for (p = q; p != r; p++)
+ bar (p, 1);
+ #pragma omp for
+ for (p = s; p != r; p--)
+ bar (p, 2);
+ #pragma omp for
+ for (p = q; p != r; p = p + 1)
+ bar (p, 4);
+ #pragma omp for
+ for (p = s; p != r; p = p - 1)
+ bar (p, 8);
+ #pragma omp for
+ for (p = q; p != r; p = 1 + p)
+ bar (p, 16);
+ #pragma omp for
+ for (p = s; p != r; p = -1 + p)
+ bar (p, 32);
+ #pragma omp for
+ for (p = q; p != r; p += 1)
+ bar (p, 64);
+ #pragma omp for
+ for (p = s; p != r; p -= 1)
+ bar (p, 128);
+}
+
+__attribute__((noinline, noclone)) void
+baz (void *qx, void *rx, void *sx, int n)
+{
+ unsigned short (*q)[n], (*r)[n], (*s)[n], (*p)[n];
+ q = (typeof (q)) qx;
+ r = (typeof (r)) rx;
+ s = (typeof (s)) sx;
+ #pragma omp for
+ for (p = q; p < r; p++)
+ bar (p, 256);
+ #pragma omp for
+ for (p = s; p > r; p--)
+ bar (p, 512);
+ #pragma omp for
+ for (p = q; p < r; p = p + 1)
+ bar (p, 1024);
+ #pragma omp for
+ for (p = s; p > r; p = p - 1)
+ bar (p, 2048);
+ #pragma omp for
+ for (p = q; p < r; p = 1 + p)
+ bar (p, 4096);
+ #pragma omp for
+ for (p = s; p > r; p = -1 + p)
+ bar (p, 8192);
+ #pragma omp for
+ for (p = q; p < r; p += 1)
+ bar (p, 16384);
+ #pragma omp for
+ for (p = s; p > r; p -= 1)
+ bar (p, 32768U);
+}
+
+int
+main ()
+{
+ int i;
+ volatile int j = 7;
+#pragma omp parallel
+ {
+ foo (&a[5 + (j - 7)], &a[124 + (j - 7)], &a[222 + (j - 7)], j);
+ baz (&a[5 + (j - 7)], &a[124 + (j - 7)], &a[222 + (j - 7)], j);
+ }
+ for (i = 0; i < 256; i++)
+ if (i < 5 || i > 222 || i == 124 || ((i - 5) % 7) != 0)
+ {
+ if (a[i])
+ __builtin_abort ();
+ }
+ else if (i < 124 && a[i] != 1 + 4 + 16 + 64 + 256 + 1024 + 4096 + 16384)
+ __builtin_abort ();
+ else if (i > 124 && a[i] != 2 + 8 + 32 + 128 + 512 + 2048 + 8192 + 32768U)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-14.c b/libgomp/testsuite/libgomp.c-c++-common/for-14.c
new file mode 100644
index 00000000000..56440ab740f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-14.c
@@ -0,0 +1,110 @@
+/* { dg-additional-options "-std=gnu99" { target c } } */
+
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort ();
+
+#define M(x, y, z) O(x, y, z)
+#define O(x, y, z) x ## _ ## y ## _ ## z
+
+#define F distribute
+#define G d
+#define S
+#define N(x) M(x, G, normal)
+#include "for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+#define F distribute
+#define G d_ds128
+#define S dist_schedule(static, 128)
+#define N(x) M(x, G, normal)
+#include "for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+#define F distribute simd
+#define G ds
+#define S
+#define N(x) M(x, G, normal)
+#include "for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+#define F distribute simd
+#define G ds_ds128
+#define S dist_schedule(static, 128)
+#define N(x) M(x, G, normal)
+#include "for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+#define F distribute parallel for
+#define G dpf
+#include "for-1.h"
+#undef F
+#undef G
+
+#define F distribute parallel for dist_schedule(static, 128)
+#define G dpf_ds128
+#include "for-1.h"
+#undef F
+#undef G
+
+#define F distribute parallel for simd
+#define G dpfs
+#include "for-1.h"
+#undef F
+#undef G
+
+#define F distribute parallel for simd dist_schedule(static, 128)
+#define G dpfs_ds128
+#include "for-1.h"
+#undef F
+#undef G
+
+int
+main ()
+{
+ int err = 0;
+ #pragma omp teams reduction(|:err)
+ {
+ err |= test_d_normal ();
+ err |= test_d_ds128_normal ();
+ err |= test_ds_normal ();
+ err |= test_ds_ds128_normal ();
+ err |= test_dpf_static ();
+ err |= test_dpf_static32 ();
+ err |= test_dpf_auto ();
+ err |= test_dpf_guided32 ();
+ err |= test_dpf_runtime ();
+ err |= test_dpf_ds128_static ();
+ err |= test_dpf_ds128_static32 ();
+ err |= test_dpf_ds128_auto ();
+ err |= test_dpf_ds128_guided32 ();
+ err |= test_dpf_ds128_runtime ();
+ err |= test_dpfs_static ();
+ err |= test_dpfs_static32 ();
+ err |= test_dpfs_auto ();
+ err |= test_dpfs_guided32 ();
+ err |= test_dpfs_runtime ();
+ err |= test_dpfs_ds128_static ();
+ err |= test_dpfs_ds128_static32 ();
+ err |= test_dpfs_ds128_auto ();
+ err |= test_dpfs_ds128_guided32 ();
+ err |= test_dpfs_ds128_runtime ();
+ }
+ if (err)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-15.c b/libgomp/testsuite/libgomp.c-c++-common/for-15.c
new file mode 100644
index 00000000000..512b9725603
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-15.c
@@ -0,0 +1,115 @@
+/* { dg-additional-options "-std=gnu99" { target c } } */
+
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort ();
+
+#define M(x, y, z) O(x, y, z)
+#define O(x, y, z) x ## _ ## y ## _ ## z
+
+#define F for
+#define G f
+#define S
+#define N(x) M(x, G, normal)
+#include "for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+#define F teams distribute
+#define G td
+#define S
+#define N(x) M(x, G, normal)
+#include "for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+#define F teams distribute
+#define G td_ds128
+#define S dist_schedule(static, 128)
+#define N(x) M(x, G, normal)
+#include "for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+#define F teams distribute simd
+#define G tds
+#define S
+#define N(x) M(x, G, normal)
+#include "for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+#define F teams distribute simd
+#define G tds_ds128
+#define S dist_schedule(static, 128)
+#define N(x) M(x, G, normal)
+#include "for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+#define F teams distribute parallel for
+#define G tdpf
+#include "for-1.h"
+#undef F
+#undef G
+
+#define F teams distribute parallel for dist_schedule(static, 128)
+#define G tdpf_ds128
+#include "for-1.h"
+#undef F
+#undef G
+
+#define F teams distribute parallel for simd
+#define G tdpfs
+#include "for-1.h"
+#undef F
+#undef G
+
+#define F teams distribute parallel for simd dist_schedule(static, 128)
+#define G tdpfs_ds128
+#include "for-1.h"
+#undef F
+#undef G
+
+int
+main ()
+{
+ if (test_td_normal ()
+ || test_td_ds128_normal ()
+ || test_tds_normal ()
+ || test_tds_ds128_normal ()
+ || test_tdpf_static ()
+ || test_tdpf_static32 ()
+ || test_tdpf_auto ()
+ || test_tdpf_guided32 ()
+ || test_tdpf_runtime ()
+ || test_tdpf_ds128_static ()
+ || test_tdpf_ds128_static32 ()
+ || test_tdpf_ds128_auto ()
+ || test_tdpf_ds128_guided32 ()
+ || test_tdpf_ds128_runtime ()
+ || test_tdpfs_static ()
+ || test_tdpfs_static32 ()
+ || test_tdpfs_auto ()
+ || test_tdpfs_guided32 ()
+ || test_tdpfs_runtime ()
+ || test_tdpfs_ds128_static ()
+ || test_tdpfs_ds128_static32 ()
+ || test_tdpfs_ds128_auto ()
+ || test_tdpfs_ds128_guided32 ()
+ || test_tdpfs_ds128_runtime ())
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-16.c b/libgomp/testsuite/libgomp.c-c++-common/for-16.c
new file mode 100644
index 00000000000..5649ba9ee87
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-16.c
@@ -0,0 +1,114 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+
+unsigned long long int k = 16;
+#pragma omp declare target to (k)
+
+int
+main ()
+{
+ unsigned char a[144], b[144], c[144];
+ int l;
+ #pragma omp target map(from:a, b, c)
+ {
+ int i;
+ unsigned long long int j;
+ #pragma omp parallel for schedule (runtime)
+ for (i = 0; i < 16; i++)
+ a[i] = i;
+ #pragma omp parallel for schedule (monotonic: runtime)
+ for (i = 0; i < 16; i++)
+ a[i + 16] = i + 16;
+ #pragma omp parallel for schedule (nonmonotonic: runtime)
+ for (i = 0; i < 16; i++)
+ a[i + 32] = i + 32;
+ #pragma omp parallel
+ {
+ #pragma omp for schedule (runtime)
+ for (i = 0; i < 16; i++)
+ a[i + 48] = i + 48;
+ #pragma omp for schedule (monotonic: runtime)
+ for (i = 0; i < 16; i++)
+ a[i + 64] = i + 64;
+ #pragma omp for schedule (nonmonotonic: runtime)
+ for (i = 0; i < 16; i++)
+ a[i + 80] = i + 80;
+ #pragma omp for schedule (runtime)
+ for (j = 0; j < k; j++)
+ a[j + 96] = j + 96;
+ #pragma omp for schedule (monotonic: runtime)
+ for (j = 0; j < k; j++)
+ a[j + 112] = j + 112;
+ #pragma omp for schedule (nonmonotonic: runtime)
+ for (j = 0; j < k; j++)
+ a[j + 128] = j + 128;
+ }
+ #pragma omp parallel for schedule (dynamic)
+ for (i = 0; i < 16; i++)
+ b[i] = i;
+ #pragma omp parallel for schedule (monotonic: dynamic)
+ for (i = 0; i < 16; i++)
+ b[i + 16] = i + 16;
+ #pragma omp parallel for schedule (nonmonotonic: dynamic)
+ for (i = 0; i < 16; i++)
+ b[i + 32] = i + 32;
+ #pragma omp parallel
+ {
+ #pragma omp for schedule (dynamic)
+ for (i = 0; i < 16; i++)
+ b[i + 48] = i + 48;
+ #pragma omp for schedule (monotonic: dynamic)
+ for (i = 0; i < 16; i++)
+ b[i + 64] = i + 64;
+ #pragma omp for schedule (nonmonotonic: dynamic)
+ for (i = 0; i < 16; i++)
+ b[i + 80] = i + 80;
+ #pragma omp for schedule (dynamic)
+ for (j = 0; j < k; j++)
+ b[j + 96] = j + 96;
+ #pragma omp for schedule (monotonic: dynamic)
+ for (j = 0; j < k; j++)
+ b[j + 112] = j + 112;
+ #pragma omp for schedule (nonmonotonic: dynamic)
+ for (j = 0; j < k; j++)
+ b[j + 128] = j + 128;
+ }
+ #pragma omp parallel for schedule (guided)
+ for (i = 0; i < 16; i++)
+ c[i] = i;
+ #pragma omp parallel for schedule (monotonic: guided)
+ for (i = 0; i < 16; i++)
+ c[i + 16] = i + 16;
+ #pragma omp parallel for schedule (nonmonotonic: guided)
+ for (i = 0; i < 16; i++)
+ c[i + 32] = i + 32;
+ #pragma omp parallel
+ {
+ #pragma omp for schedule (guided)
+ for (i = 0; i < 16; i++)
+ c[i + 48] = i + 48;
+ #pragma omp for schedule (monotonic: guided)
+ for (i = 0; i < 16; i++)
+ c[i + 64] = i + 64;
+ #pragma omp for schedule (nonmonotonic: guided)
+ for (i = 0; i < 16; i++)
+ c[i + 80] = i + 80;
+ #pragma omp for schedule (guided)
+ for (j = 0; j < k; j++)
+ c[j + 96] = j + 96;
+ #pragma omp for schedule (monotonic: guided)
+ for (j = 0; j < k; j++)
+ c[j + 112] = j + 112;
+ #pragma omp for schedule (nonmonotonic: guided)
+ for (j = 0; j < k; j++)
+ c[j + 128] = j + 128;
+ }
+ }
+ for (l = 0; l < 144; ++l)
+ if (a[l] != l || b[l] != l || c[l] != l)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-2.h b/libgomp/testsuite/libgomp.c-c++-common/for-2.h
index 0bd116c5aec..91a604a6c25 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/for-2.h
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-2.h
@@ -21,6 +21,7 @@ noreturn (void)
#define OMPFROM(v) do {} while (0)
#endif
+#ifndef CONDNE
__attribute__((noinline, noclone)) void
N(f0) (void)
{
@@ -311,3 +312,292 @@ N(test) (void)
return 1;
return 0;
}
+
+#else
+
+__attribute__((noinline, noclone)) void
+N(f20) (void)
+{
+ int i;
+ OMPTGT
+#pragma omp F S
+ for (i = 0; i != 1500; i++)
+ a[i] += 2;
+}
+
+__attribute__((noinline, noclone)) void
+N(f21) (void)
+{
+ OMPTGT
+#pragma omp F S
+ for (unsigned int i = __INT_MAX__; i < 1500U + __INT_MAX__; i += 2 - 1)
+ a[(i - __INT_MAX__)] -= 2;
+}
+
+__attribute__((noinline, noclone)) void
+N(f22) (void)
+{
+ unsigned long long i;
+ OMPTGT
+#pragma omp F S
+ for (i = __LONG_LONG_MAX__ + 1500ULL - 27;
+ i != __LONG_LONG_MAX__ - 27ULL; i -= 3 - 2)
+ a[i + 26LL - __LONG_LONG_MAX__] -= 4;
+}
+
+__attribute__((noinline, noclone)) void
+N(f23) (long long n1, long long n2)
+{
+ OMPTGT
+#pragma omp F S
+ for (long long i = n1 + 23; i != n2 - 25; --i)
+ a[i + 48] += 7;
+}
+
+__attribute__((noinline, noclone)) void
+N(f24) (void)
+{
+ unsigned int i;
+ OMPTGT
+#pragma omp F S
+ for (i = 30; i != 30; i += 1)
+ a[i] += 10;
+}
+
+__attribute__((noinline, noclone)) void
+N(f25) (int n11, int n12, int n21, int n22, int n31, int n32,
+ int s2)
+{
+ SC int v1, v2, v3;
+ OMPTGT
+#pragma omp F S collapse(3)
+ for (v1 = n11; v1 != n12; v1 += 17 - 19 + 3)
+ for (v2 = n21; v2 < n22; v2 += s2)
+ for (v3 = n31; v3 != n32; ++v3)
+ b[v1][v2][v3] += 2.5;
+}
+
+__attribute__((noinline, noclone)) void
+N(f26) (int n11, int n12, int n21, int n22, long long n31, long long n32,
+ int s2)
+{
+ SC int v1, v2;
+ SC long long v3;
+ OMPTGT
+#pragma omp F S collapse(3)
+ for (v1 = n11; v1 != n12; v1 += -1)
+ for (v2 = n21; v2 > n22; v2 += s2)
+ for (v3 = n31; v3 != n32; v3 --)
+ b[v1][v2 / 2][v3] -= 4.5;
+}
+
+__attribute__((noinline, noclone)) void
+N(f27) (void)
+{
+ SC unsigned int v1, v3;
+ SC unsigned long long v2;
+ OMPTGT
+#pragma omp F S collapse(3)
+ for (v1 = 0; v1 < 20; v1 += 2)
+ for (v2 = __LONG_LONG_MAX__ + 11ULL;
+ v2 != __LONG_LONG_MAX__ - 4ULL; -- v2)
+ for (v3 = 10; v3 != 0; v3--)
+ b[v1 >> 1][v2 - __LONG_LONG_MAX__ + 3][v3 - 1] += 5.5;
+}
+
+__attribute__((noinline, noclone)) void
+N(f28) (void)
+{
+ SC long long v1, v2, v3;
+ OMPTGT
+#pragma omp F S collapse(3)
+ for (v1 = 0; v1 != 20; v1 -= 17 - 18)
+ for (v2 = 30; v2 < 20; v2++)
+ for (v3 = 10; v3 < 0; v3--)
+ b[v1][v2][v3] += 5.5;
+}
+
+__attribute__((noinline, noclone)) void
+N(f29) (void)
+{
+ int i;
+ OMPTGT
+#pragma omp F S
+ for (i = 20; i != 20; i++)
+ {
+ a[i] += 2;
+ noreturn ();
+ a[i] -= 4;
+ }
+}
+
+__attribute__((noinline, noclone)) void
+N(f30) (void)
+{
+ SC int i;
+ OMPTGT
+#pragma omp F S collapse(3)
+ for (i = 0; i != 10; i++)
+ for (int j = 10; j < 8; j++)
+ for (long k = -10; k != 10; k++)
+ {
+ b[i][j][k] += 4;
+ noreturn ();
+ b[i][j][k] -= 8;
+ }
+}
+
+__attribute__((noinline, noclone)) void
+N(f31) (int n)
+{
+ int i;
+ OMPTGT
+#pragma omp F S
+ for (i = 20; i != n; i++)
+ {
+ a[i] += 8;
+ noreturn ();
+ a[i] -= 16;
+ }
+}
+
+__attribute__((noinline, noclone)) void
+N(f32) (int n)
+{
+ SC int i;
+ OMPTGT
+#pragma omp F S collapse(3)
+ for (i = 0; i != 10; i++)
+ for (int j = n; j != 12; j++)
+ for (long k = -10; k != 10; k++)
+ {
+ b[i][j][k] += 16;
+ noreturn ();
+ b[i][j][k] -= 32;
+ }
+}
+
+__attribute__((noinline, noclone)) void
+N(f33) (void)
+{
+ int *i;
+ OMPTGT
+#pragma omp F S
+ for (i = a; i != &a[1500]; i++)
+ i[0] += 2;
+}
+
+__attribute__((noinline, noclone)) void
+N(f34) (void)
+{
+ SC float *i;
+ OMPTGT
+#pragma omp F S collapse(3)
+ for (i = &b[0][0][0]; i != &b[0][0][10]; i++)
+ for (float *j = &b[0][15][0]; j > &b[0][0][0]; j -= 10)
+ for (float *k = &b[0][0][10]; k != &b[0][0][0]; --k)
+ b[i - &b[0][0][0]][(j - &b[0][0][0]) / 10 - 1][(k - &b[0][0][0]) - 1]
+ -= 3.5;
+}
+
+__attribute__((noinline, noclone)) int
+N(test) (void)
+{
+ int i, j, k;
+ for (i = 0; i < 1500; i++)
+ a[i] = i - 25;
+ OMPTO (a);
+ N(f20) ();
+ OMPFROM (a);
+ for (i = 0; i < 1500; i++)
+ if (a[i] != i - 23)
+ return 1;
+ N(f21) ();
+ OMPFROM (a);
+ for (i = 0; i < 1500; i++)
+ if (a[i] != i - 25)
+ return 1;
+ N(f22) ();
+ OMPFROM (a);
+ for (i = 0; i < 1500; i++)
+ if (a[i] != i - 29)
+ return 1;
+ N(f23) (1500LL - 1 - 23 - 48, -1LL + 25 - 48);
+ OMPFROM (a);
+ for (i = 0; i < 1500; i++)
+ if (a[i] != i - 22)
+ return 1;
+ N(f24) ();
+ OMPFROM (a);
+ for (i = 0; i < 1500; i++)
+ if (a[i] != i - 22)
+ return 1;
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 15; j++)
+ for (k = 0; k < 10; k++)
+ b[i][j][k] = i - 2.5 + 1.5 * j - 1.5 * k;
+ OMPTO (b);
+ N(f25) (0, 10, 0, 15, 0, 10, 1);
+ OMPFROM (b);
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 15; j++)
+ for (k = 0; k < 10; k++)
+ if (b[i][j][k] != i + 1.5 * j - 1.5 * k)
+ return 1;
+ N(f25) (0, 10, 30, 15, 0, 10, 5);
+ OMPFROM (b);
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 15; j++)
+ for (k = 0; k < 10; k++)
+ if (b[i][j][k] != i + 1.5 * j - 1.5 * k)
+ return 1;
+ N(f26) (9, -1, 29, 0, 9, -1, -2);
+ OMPFROM (b);
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 15; j++)
+ for (k = 0; k < 10; k++)
+ if (b[i][j][k] != i - 4.5 + 1.5 * j - 1.5 * k)
+ return 1;
+ N(f27) ();
+ OMPFROM (b);
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 15; j++)
+ for (k = 0; k < 10; k++)
+ if (b[i][j][k] != i + 1.0 + 1.5 * j - 1.5 * k)
+ return 1;
+ N(f28) ();
+ OMPFROM (b);
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 15; j++)
+ for (k = 0; k < 10; k++)
+ if (b[i][j][k] != i + 1.0 + 1.5 * j - 1.5 * k)
+ return 1;
+ N(f29) ();
+ N(f30) ();
+ N(f31) (20);
+ N(f32) (12);
+ OMPFROM (a);
+ OMPFROM (b);
+ for (i = 0; i < 1500; i++)
+ if (a[i] != i - 22)
+ return 1;
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 15; j++)
+ for (k = 0; k < 10; k++)
+ if (b[i][j][k] != i + 1.0 + 1.5 * j - 1.5 * k)
+ return 1;
+ N(f33) ();
+ N(f34) ();
+ OMPFROM (a);
+ OMPFROM (b);
+ for (i = 0; i < 1500; i++)
+ if (a[i] != i - 20)
+ return 1;
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 15; j++)
+ for (k = 0; k < 10; k++)
+ if (b[i][j][k] != i - 2.5 + 1.5 * j - 1.5 * k)
+ return 1;
+ return 0;
+}
+#endif
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-7.c b/libgomp/testsuite/libgomp.c-c++-common/for-7.c
new file mode 100644
index 00000000000..43461bb5534
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-7.c
@@ -0,0 +1,4 @@
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#define CONDNE
+#include "for-1.c"
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-8.c b/libgomp/testsuite/libgomp.c-c++-common/for-8.c
new file mode 100644
index 00000000000..ed6bf7111b5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-8.c
@@ -0,0 +1,4 @@
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#define CONDNE
+#include "for-2.c"
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-9.c b/libgomp/testsuite/libgomp.c-c++-common/for-9.c
new file mode 100644
index 00000000000..dfd674fee56
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-9.c
@@ -0,0 +1,4 @@
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#define CONDNE
+#include "for-3.c"
diff --git a/libgomp/testsuite/libgomp.c-c++-common/function-not-offloaded-aux.c b/libgomp/testsuite/libgomp.c-c++-common/function-not-offloaded-aux.c
new file mode 100644
index 00000000000..b8aa3da48a1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/function-not-offloaded-aux.c
@@ -0,0 +1,12 @@
+/* { dg-skip-if "" { *-*-* } } */
+
+#pragma omp declare target
+extern int var;
+#pragma omp end declare target
+
+void __attribute__((noinline, noclone))
+foo (void)
+{
+ var++;
+}
+
diff --git a/libgomp/testsuite/libgomp.c-c++-common/function-not-offloaded.c b/libgomp/testsuite/libgomp.c-c++-common/function-not-offloaded.c
new file mode 100644
index 00000000000..9e59ef8864e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/function-not-offloaded.c
@@ -0,0 +1,16 @@
+/* { dg-do link } */
+/* { dg-excess-errors "unresolved symbol foo, lto1, mkoffload and lto-wrapper fatal errors" { target offload_device_nonshared_as } } */
+/* { dg-additional-sources "function-not-offloaded-aux.c" } */
+
+#pragma omp declare target
+int var;
+#pragma omp end declare target
+
+extern void foo ();
+
+int
+main ()
+{
+#pragma omp target
+ foo ();
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-1.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-1.c
new file mode 100644
index 00000000000..a7e9f90c5a8
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-1.c
@@ -0,0 +1,144 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+int r, s, u, v, r2, s2, u2, v2, r3, s3, u3, v3;
+long long w, w2, w3, p, p2, p3;
+int *x, *x2, *x3;
+short y, y2, y3;
+int z;
+int thr1, thr2;
+#pragma omp threadprivate (thr1, thr2)
+
+void
+foo (int *a, long long int b, long long int c)
+{
+ int i;
+ long long j;
+ #pragma omp for lastprivate (conditional: u, x) nowait
+ for (i = 15; i < 64; i++)
+ {
+ if ((a[i] % 5) == 3)
+ u = i;
+ if ((a[i] % 7) == 2)
+ x = &a[i];
+ }
+ #pragma omp for nowait lastprivate (conditional: v) reduction (+:r, s) schedule (nonmonotonic: static)
+ for (i = -3; i < 119; i += 2)
+ {
+ ++s;
+ if ((a[i + 4] % 11) == 9)
+ v = i;
+ else
+ ++r;
+ }
+ #pragma omp for schedule (monotonic: static) lastprivate (conditional: w) nowait
+ for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+ if ((a[j] % 13) == 5)
+ w = j * 2;
+ #pragma omp for schedule (auto) lastprivate (conditional: p) collapse(3)
+ for (i = -5; i < (int) (b + 5); i += 2)
+ for (j = b + 12 + c; j > b; --j)
+ for (int k = 0; k < 5; k += c)
+ if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+ p = i * 10000 + j * 100 + k;
+
+ #pragma omp for schedule (nonmonotonic: static, 2) nowait lastprivate (conditional: u2, x2)
+ for (i = 15; i < 64; i++)
+ {
+ if ((a[i] % 5) == 3)
+ u2 = i;
+ if ((a[i] % 7) == 2)
+ x2 = &a[i];
+ }
+ #pragma omp for schedule (static, 3) lastprivate (conditional: v2) reduction (+:r2, s2)
+ for (i = -3; i < 119; i += 2)
+ {
+ ++s2;
+ if ((a[i + 4] % 11) == 9)
+ v2 = i;
+ else
+ ++r2;
+ }
+ #pragma omp for lastprivate (conditional: w2) schedule (static, 1) nowait
+ for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+ if ((a[j] % 13) == 5)
+ w2 = j * 2;
+ #pragma omp for schedule (static, 3) collapse (3) lastprivate (conditional: p2)
+ for (i = -5; i < (int) (b + 5); i += 2)
+ for (j = b + 12 + c; j > b; --j)
+ for (int k = 0; k < 5; k += c)
+ if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+ p2 = i * 10000 + j * 100 + k;
+
+ #pragma omp for lastprivate (conditional: u3, x3) nowait schedule (runtime)
+ for (i = 15; i < 64; i++)
+ {
+ if ((a[i] % 5) == 3)
+ u3 = i;
+ if ((a[i] % 7) == 2)
+ x3 = &a[i];
+ }
+ #pragma omp for nowait lastprivate (conditional: v3) reduction (+:r3, s3) schedule (nonmonotonic: dynamic)
+ for (i = -3; i < 119; i += 2)
+ {
+ ++s3;
+ if ((a[i + 4] % 11) == 9)
+ v3 = i;
+ else
+ ++r3;
+ }
+ #pragma omp for schedule (monotonic: guided, 3) lastprivate (conditional: w3) nowait
+ for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+ if ((a[j] % 13) == 5)
+ w3 = j * 2;
+ #pragma omp for schedule (dynamic, 4) lastprivate (conditional: p3) collapse(3)
+ for (i = -5; i < (int) (b + 5); i += 2)
+ for (j = b + 12 + c; j > b; --j)
+ for (int k = 0; k < 5; k += c)
+ if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+ p3 = i * 10000 + j * 100 + k;
+
+ /* Nasty testcase, verify that even a no-op assignment is accounted
+ for in lastprivate(conditional:). */
+ #pragma omp for schedule (monotonic: static, 2) firstprivate (z) \
+ lastprivate (conditional: z)
+ for (int k = -2000; k < 8000; ++k)
+ {
+ if (k < 3000 && (k & 3) == 1)
+ {
+ z = k;
+ thr1 = k;
+ }
+ else if (k == 7931)
+ {
+ z = z;
+ thr2 = 1;
+ }
+ }
+
+ if (thr2 && z != thr1)
+ abort ();
+}
+
+int
+main ()
+{
+ int a[128], i;
+ volatile int j = 0;
+ for (i = 0; i < 128; i++)
+ a[i] = i;
+ w = 1234;
+ #pragma omp parallel
+ foo (a, j, j + 1);
+ if (u != 63 || v != 115 || w != 140 || x != &a[58] || r != 55 || s != 61 || p != 30104)
+ abort ();
+ if (u2 != 63 || v2 != 115 || w2 != 140 || x2 != &a[58] || r2 != 55 || s2 != 61 || p2 != 30104)
+ abort ();
+ if (u3 != 63 || v3 != 115 || w3 != 140 || x3 != &a[58] || r3 != 55 || s3 != 61 || p3 != 30104)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-10.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-10.c
new file mode 100644
index 00000000000..2f7503903fd
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-10.c
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+
+int v, x;
+
+__attribute__((noipa)) int
+foo (int *a)
+{
+ #pragma omp parallel for simd lastprivate (conditional: x) schedule(simd: static) if (simd: 0)
+ for (int i = 0; i < 128; i++)
+ if (a[i])
+ x = a[i];
+ return x;
+}
+
+__attribute__((noipa)) int
+bar (int *a, int *b)
+{
+ #pragma omp parallel
+ #pragma omp for simd lastprivate (conditional: x, v) schedule(static, 16) simdlen (1)
+ for (int i = 16; i < 128; ++i)
+ {
+ if (a[i])
+ x = a[i];
+ if (b[i])
+ v = b[i] + 10;
+ }
+ return x;
+}
+
+__attribute__((noipa)) int
+baz (int *a)
+{
+ #pragma omp parallel for simd if (simd: 0) lastprivate (conditional: x) schedule(simd: dynamic, 16)
+ for (int i = 0; i < 128; i++)
+ if (a[i])
+ x = a[i] + 5;
+ return x;
+}
+
+int
+main ()
+{
+ int a[128], b[128], i;
+ for (i = 0; i < 128; i++)
+ {
+ a[i] = ((i % 11) == 2) ? i + 10 : 0;
+ asm volatile ("" : "+g" (i));
+ b[i] = ((i % 13) == 5) ? i * 2 : 0;
+ }
+ if (foo (a) != 133)
+ __builtin_abort ();
+ if (bar (b, a) != 244 || v != 143)
+ __builtin_abort ();
+ if (baz (b) != 249)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-2.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-2.c
new file mode 100644
index 00000000000..f252206f5b3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-2.c
@@ -0,0 +1,171 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+int r, s, u, v, r2, s2, u2, v2, r3, s3, u3, v3, t;
+long long w, w2, w3, p, p2, p3;
+int *x, *x2, *x3;
+short y, y2, y3;
+int z;
+int thr1, thr2;
+#pragma omp threadprivate (thr1, thr2)
+
+void
+foo (int *a, long long int b, long long int c)
+{
+ int i;
+ long long j;
+ #pragma omp for lastprivate (conditional: u, x) reduction (task, +: t)
+ for (i = 15; i < 64; i++)
+ {
+ ++t;
+ if ((a[i] % 5) == 3)
+ u = i;
+ if ((a[i] % 7) == 2)
+ x = &a[i];
+ }
+ #pragma omp for lastprivate (conditional: v) reduction (+:r, s) schedule (nonmonotonic: static) reduction (task, +: t)
+ for (i = -3; i < 119; i += 2)
+ {
+ ++s;
+ ++t;
+ if ((a[i + 4] % 11) == 9)
+ v = i;
+ else
+ ++r;
+ }
+ #pragma omp for schedule (monotonic: static) lastprivate (conditional: w) reduction (task, +: t)
+ for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+ {
+ if ((a[j] % 13) == 5)
+ w = j * 2;
+ ++t;
+ }
+ #pragma omp for schedule (auto) lastprivate (conditional: p) collapse(3) reduction (task, +: t)
+ for (i = -5; i < (int) (b + 5); i += 2)
+ for (j = b + 12 + c; j > b; --j)
+ for (int k = 0; k < 5; k += c)
+ {
+ ++t;
+ if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+ p = i * 10000 + j * 100 + k;
+ }
+
+ #pragma omp for schedule (nonmonotonic: static, 2) reduction (task, +: t) lastprivate (conditional: u2, x2)
+ for (i = 15; i < 64; i++)
+ {
+ if ((a[i] % 5) == 3)
+ u2 = i;
+ if ((a[i] % 7) == 2)
+ x2 = &a[i];
+ t++;
+ }
+ #pragma omp for schedule (static, 3) lastprivate (conditional: v2) reduction (+:r2, s2) reduction (task, +: t)
+ for (i = -3; i < 119; i += 2)
+ {
+ ++s2;
+ if ((a[i + 4] % 11) == 9)
+ v2 = i;
+ else
+ ++r2;
+ t++;
+ }
+ #pragma omp for lastprivate (conditional: w2) schedule (static, 1) reduction (task, +: t)
+ for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+ {
+ if ((a[j] % 13) == 5)
+ w2 = j * 2;
+ t += 1;
+ }
+ #pragma omp for schedule (static, 3) collapse (3) reduction (task, +: t) lastprivate (conditional: p2)
+ for (i = -5; i < (int) (b + 5); i += 2)
+ for (j = b + 12 + c; j > b; --j)
+ for (int k = 0; k < 5; k += c)
+ {
+ ++t;
+ if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+ p2 = i * 10000 + j * 100 + k;
+ }
+
+ #pragma omp for lastprivate (conditional: u3, x3) reduction (task, +: t) schedule (runtime)
+ for (i = 15; i < 64; i++)
+ {
+ t = t + 1;
+ if ((a[i] % 5) == 3)
+ u3 = i;
+ if ((a[i] % 7) == 2)
+ x3 = &a[i];
+ }
+ #pragma omp for reduction (task, +: t) lastprivate (conditional: v3) reduction (+:r3, s3) schedule (nonmonotonic: dynamic)
+ for (i = -3; i < 119; i += 2)
+ {
+ ++s3;
+ if ((a[i + 4] % 11) == 9)
+ v3 = i;
+ else
+ ++r3;
+ ++t;
+ }
+ #pragma omp for schedule (monotonic: guided, 3) lastprivate (conditional: w3) reduction (task, +: t)
+ for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+ {
+ if ((a[j] % 13) == 5)
+ w3 = j * 2;
+ t++;
+ }
+ #pragma omp for schedule (dynamic, 4) lastprivate (conditional: p3) collapse(3) reduction (task, +: t)
+ for (i = -5; i < (int) (b + 5); i += 2)
+ for (j = b + 12 + c; j > b; --j)
+ for (int k = 0; k < 5; k += c)
+ {
+ ++t;
+ if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+ p3 = i * 10000 + j * 100 + k;
+ }
+
+ /* Nasty testcase, verify that even a no-op assignment is accounted
+ for in lastprivate(conditional:). */
+ #pragma omp for schedule (monotonic: static, 2) firstprivate (z) \
+ lastprivate (conditional: z) reduction (task, +: t)
+ for (int k = -2000; k < 8000; ++k)
+ {
+ t++;
+ if (k < 3000 && (k & 3) == 1)
+ {
+ z = k;
+ thr1 = k;
+ }
+ else if (k == 7931)
+ {
+ z = z;
+ thr2 = 1;
+ }
+ }
+
+ if (thr2 && z != thr1)
+ abort ();
+}
+
+int
+main ()
+{
+ int a[128], i;
+ volatile int j = 0;
+ for (i = 0; i < 128; i++)
+ a[i] = i;
+ w = 1234;
+ #pragma omp parallel
+ foo (a, j, j + 1);
+ if (u != 63 || v != 115 || w != 140 || x != &a[58] || r != 55 || s != 61 || p != 30104)
+ abort ();
+ if (u2 != 63 || v2 != 115 || w2 != 140 || x2 != &a[58] || r2 != 55 || s2 != 61 || p2 != 30104)
+ abort ();
+ if (u3 != 63 || v3 != 115 || w3 != 140 || x3 != &a[58] || r3 != 55 || s3 != 61 || p3 != 30104)
+ abort ();
+ if (t != 11356)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-3.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-3.c
new file mode 100644
index 00000000000..6c4370abaa3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-3.c
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+int r, s, u, v, t;
+int *x;
+
+void
+foo (int *a)
+{
+ int i;
+ long long j;
+ #pragma omp for lastprivate (conditional: u, x) ordered
+ for (i = 15; i < 64; i++)
+ {
+ #pragma omp critical
+ {
+ if ((a[i] % 5) == 3)
+ u = i;
+ }
+ #pragma omp ordered
+ {
+ if ((a[i] % 7) == 2)
+ x = &a[i];
+ }
+ }
+ #pragma omp for lastprivate (conditional: v) reduction (+:r, s) schedule (nonmonotonic: static) reduction (task, +: t)
+ for (i = -3; i < 119; i += 2)
+ {
+ ++s;
+ #pragma omp taskgroup
+ {
+ #pragma omp task in_reduction (+: t)
+ ++t;
+ if ((a[i + 4] % 11) == 9)
+ v = i;
+ else
+ ++r;
+ }
+ }
+}
+
+int
+main ()
+{
+ int a[128], i;
+ for (i = 0; i < 128; i++)
+ a[i] = i;
+ #pragma omp parallel
+ foo (a);
+ if (u != 63 || v != 115 || x != &a[58] || r != 55 || s != 61 || t != 61)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-4.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-4.c
new file mode 100644
index 00000000000..bc102a10cd1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-4.c
@@ -0,0 +1,161 @@
+#include <stdlib.h>
+
+int x;
+long long y;
+int r, s, t;
+
+void
+foo (const char *a)
+{
+ #pragma omp sections lastprivate (conditional: x, y)
+ {
+ if (a[0])
+ x = a[0];
+ #pragma omp section
+ {
+ if (a[1])
+ x = a[1];
+ if (a[2])
+ y = a[2];
+ }
+ #pragma omp section
+ if (a[3])
+ y = a[3];
+ #pragma omp section
+ if (a[4])
+ x = a[4];
+ #pragma omp section
+ {
+ if (a[5])
+ x = a[5];
+ if (a[6])
+ y = a[6];
+ }
+ }
+}
+
+void
+bar (const char *a)
+{
+ #pragma omp sections lastprivate (conditional: x, y) reduction (task, +: t)
+ {
+ if (a[0])
+ x = a[0];
+ #pragma omp section
+ {
+ if (a[1])
+ x = a[1];
+ if (a[2])
+ y = a[2];
+ #pragma omp task in_reduction (+: t)
+ t++;
+ }
+ #pragma omp section
+ if (a[3])
+ y = a[3];
+ #pragma omp section
+ if (a[4])
+ x = a[4];
+ #pragma omp section
+ {
+ #pragma omp task in_reduction (+: t)
+ ++t;
+ if (a[5])
+ x = a[5];
+ if (a[6])
+ y = a[6];
+ }
+ }
+}
+
+void
+baz (const char *a)
+{
+ #pragma omp sections lastprivate (conditional: x, y) reduction (+: r, s)
+ {
+ if (a[0])
+ x = a[0];
+ #pragma omp section
+ {
+ if (a[1])
+ x = a[1];
+ ++r;
+ ++s;
+ if (a[2])
+ y = a[2];
+ }
+ #pragma omp section
+ if (a[3])
+ y = a[3];
+ #pragma omp section
+ {
+ ++s;
+ if (a[4])
+ x = a[4];
+ }
+ #pragma omp section
+ {
+ if (a[5])
+ x = a[5];
+ if (a[6])
+ y = a[6];
+ ++s;
+ }
+ }
+}
+
+int
+main ()
+{
+ #pragma omp parallel
+ {
+ foo ("\0\1\2\3\0\5");
+ if (x != 5 || y != 3)
+ abort ();
+ #pragma omp barrier
+ foo ("\6\0\0\0\0\0\7");
+ if (x != 6 || y != 7)
+ abort ();
+ #pragma omp barrier
+ foo ("\7\6\5\4\3\2\1");
+ if (x != 2 || y != 1)
+ abort ();
+ #pragma omp barrier
+ foo ("\0\0\4\3\0\7");
+ if (x != 7 || y != 3)
+ abort ();
+ #pragma omp barrier
+ bar ("\0\1\2\4\0\5");
+ if (x != 5 || y != 4 || t != 2)
+ abort ();
+ #pragma omp barrier
+ bar ("\6\0\0\0\0\0\7");
+ if (x != 6 || y != 7 || t != 4)
+ abort ();
+ #pragma omp barrier
+ bar ("\7\6\5\4\3\2\1");
+ if (x != 2 || y != 1 || t != 6)
+ abort ();
+ #pragma omp barrier
+ bar ("\0\0\4\3\0\7");
+ if (x != 7 || y != 3 || t != 8)
+ abort ();
+ #pragma omp barrier
+ baz ("\0\1\2\4\0\5");
+ if (x != 5 || y != 4 || r != 1 || s != 3)
+ abort ();
+ #pragma omp barrier
+ baz ("\6\0\0\0\0\0\7");
+ if (x != 6 || y != 7 || r != 2 || s != 6)
+ abort ();
+ #pragma omp barrier
+ baz ("\7\6\5\4\3\2\1");
+ if (x != 2 || y != 1 || r != 3 || s != 9)
+ abort ();
+ #pragma omp barrier
+ baz ("\0\0\4\3\0\7");
+ if (x != 7 || y != 3 || r != 4 || s != 12)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c
new file mode 100644
index 00000000000..de6b9a87c1f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c
@@ -0,0 +1,143 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+int r, s, u, v, r2, s2, u2, v2, r3, s3, u3, v3;
+long long w, w2, w3, p, p2, p3;
+int *x, *x2, *x3;
+short y, y2, y3;
+int z;
+int thr1, thr2;
+#pragma omp threadprivate (thr1, thr2)
+
+void
+foo (int *a, long long int b, long long int c)
+{
+ int i;
+ long long j;
+ #pragma omp parallel for lastprivate (conditional: u, x)
+ for (i = 15; i < 64; i++)
+ {
+ if ((a[i] % 5) == 3)
+ u = i;
+ if ((a[i] % 7) == 2)
+ x = &a[i];
+ }
+ #pragma omp parallel for lastprivate (conditional: v) reduction (+:r, s) schedule (nonmonotonic: static)
+ for (i = -3; i < 119; i += 2)
+ {
+ ++s;
+ if ((a[i + 4] % 11) == 9)
+ v = i;
+ else
+ ++r;
+ }
+ #pragma omp parallel for schedule (monotonic: static) lastprivate (conditional: w)
+ for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+ if ((a[j] % 13) == 5)
+ w = j * 2;
+ #pragma omp parallel for schedule (auto) lastprivate (conditional: p) collapse(3)
+ for (i = -5; i < (int) (b + 5); i += 2)
+ for (j = b + 12 + c; j > b; --j)
+ for (int k = 0; k < 5; k += c)
+ if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+ p = i * 10000 + j * 100 + k;
+
+ #pragma omp parallel for schedule (nonmonotonic: static, 2) lastprivate (conditional: u2, x2)
+ for (i = 15; i < 64; i++)
+ {
+ if ((a[i] % 5) == 3)
+ u2 = i;
+ if ((a[i] % 7) == 2)
+ x2 = &a[i];
+ }
+ #pragma omp parallel for schedule (static, 3) lastprivate (conditional: v2) reduction (+:r2, s2)
+ for (i = -3; i < 119; i += 2)
+ {
+ ++s2;
+ if ((a[i + 4] % 11) == 9)
+ v2 = i;
+ else
+ ++r2;
+ }
+ #pragma omp parallel for lastprivate (conditional: w2) schedule (static, 1)
+ for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+ if ((a[j] % 13) == 5)
+ w2 = j * 2;
+ #pragma omp parallel for schedule (static, 3) collapse (3) lastprivate (conditional: p2)
+ for (i = -5; i < (int) (b + 5); i += 2)
+ for (j = b + 12 + c; j > b; --j)
+ for (int k = 0; k < 5; k += c)
+ if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+ p2 = i * 10000 + j * 100 + k;
+
+ #pragma omp parallel for lastprivate (conditional: u3, x3) schedule (runtime)
+ for (i = 15; i < 64; i++)
+ {
+ if ((a[i] % 5) == 3)
+ u3 = i;
+ if ((a[i] % 7) == 2)
+ x3 = &a[i];
+ }
+ #pragma omp parallel for lastprivate (conditional: v3) reduction (+:r3, s3) schedule (nonmonotonic: dynamic)
+ for (i = -3; i < 119; i += 2)
+ {
+ ++s3;
+ if ((a[i + 4] % 11) == 9)
+ v3 = i;
+ else
+ ++r3;
+ }
+ #pragma omp parallel for schedule (monotonic: guided, 3) lastprivate (conditional: w3)
+ for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+ if ((a[j] % 13) == 5)
+ w3 = j * 2;
+ #pragma omp parallel for schedule (dynamic, 4) lastprivate (conditional: p3) collapse(3)
+ for (i = -5; i < (int) (b + 5); i += 2)
+ for (j = b + 12 + c; j > b; --j)
+ for (int k = 0; k < 5; k += c)
+ if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+ p3 = i * 10000 + j * 100 + k;
+
+ /* Nasty testcase, verify that even a no-op assignment is accounted
+ for in lastprivate(conditional:). */
+ #pragma omp parallel for schedule (monotonic: static, 2) firstprivate (z) \
+ lastprivate (conditional: z)
+ for (int k = -2000; k < 8000; ++k)
+ {
+ if (k < 3000 && (k & 3) == 1)
+ {
+ z = k;
+ thr1 = k;
+ }
+ else if (k == 7931)
+ {
+ z = z;
+ thr2 = 1;
+ }
+ }
+
+ if (thr2 && z != thr1)
+ abort ();
+}
+
+int
+main ()
+{
+ int a[128], i;
+ volatile int j = 0;
+ for (i = 0; i < 128; i++)
+ a[i] = i;
+ w = 1234;
+ foo (a, j, j + 1);
+ if (u != 63 || v != 115 || w != 140 || x != &a[58] || r != 55 || s != 61 || p != 30104)
+ abort ();
+ if (u2 != 63 || v2 != 115 || w2 != 140 || x2 != &a[58] || r2 != 55 || s2 != 61 || p2 != 30104)
+ abort ();
+ if (u3 != 63 || v3 != 115 || w3 != 140 || x3 != &a[58] || r3 != 55 || s3 != 61 || p3 != 30104)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c
new file mode 100644
index 00000000000..d2137935859
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c
@@ -0,0 +1,159 @@
+#include <stdlib.h>
+
+int x;
+long long y;
+int r, s, t;
+
+void
+foo (const char *a)
+{
+ #pragma omp parallel sections lastprivate (conditional: x, y)
+ {
+ if (a[0])
+ x = a[0];
+ #pragma omp section
+ {
+ if (a[1])
+ x = a[1];
+ if (a[2])
+ y = a[2];
+ }
+ #pragma omp section
+ if (a[3])
+ y = a[3];
+ #pragma omp section
+ if (a[4])
+ x = a[4];
+ #pragma omp section
+ {
+ if (a[5])
+ x = a[5];
+ if (a[6])
+ y = a[6];
+ }
+ }
+}
+
+void
+bar (const char *a)
+{
+ #pragma omp parallel sections lastprivate (conditional: x, y) reduction (task, +: t)
+ {
+ if (a[0])
+ x = a[0];
+ #pragma omp section
+ {
+ if (a[1])
+ x = a[1];
+ if (a[2])
+ y = a[2];
+ #pragma omp task in_reduction (+: t)
+ t++;
+ }
+ #pragma omp section
+ if (a[3])
+ y = a[3];
+ #pragma omp section
+ if (a[4])
+ x = a[4];
+ #pragma omp section
+ {
+ #pragma omp task in_reduction (+: t)
+ ++t;
+ if (a[5])
+ x = a[5];
+ if (a[6])
+ y = a[6];
+ }
+ }
+}
+
+void
+baz (const char *a)
+{
+ #pragma omp parallel sections lastprivate (conditional: x, y) reduction (+: r, s)
+ {
+ if (a[0])
+ x = a[0];
+ #pragma omp section
+ {
+ if (a[1])
+ x = a[1];
+ ++r;
+ ++s;
+ if (a[2])
+ y = a[2];
+ }
+ #pragma omp section
+ if (a[3])
+ y = a[3];
+ #pragma omp section
+ {
+ ++s;
+ if (a[4])
+ x = a[4];
+ }
+ #pragma omp section
+ {
+ if (a[5])
+ x = a[5];
+ if (a[6])
+ y = a[6];
+ ++s;
+ }
+ }
+}
+
+int
+main ()
+{
+ foo ("\0\1\2\3\0\5");
+ if (x != 5 || y != 3)
+ abort ();
+
+ foo ("\6\0\0\0\0\0\7");
+ if (x != 6 || y != 7)
+ abort ();
+
+ foo ("\7\6\5\4\3\2\1");
+ if (x != 2 || y != 1)
+ abort ();
+
+ foo ("\0\0\4\3\0\7");
+ if (x != 7 || y != 3)
+ abort ();
+
+ bar ("\0\1\2\4\0\5");
+ if (x != 5 || y != 4 || t != 2)
+ abort ();
+
+ bar ("\6\0\0\0\0\0\7");
+ if (x != 6 || y != 7 || t != 4)
+ abort ();
+
+ bar ("\7\6\5\4\3\2\1");
+ if (x != 2 || y != 1 || t != 6)
+ abort ();
+
+ bar ("\0\0\4\3\0\7");
+ if (x != 7 || y != 3 || t != 8)
+ abort ();
+
+ baz ("\0\1\2\4\0\5");
+ if (x != 5 || y != 4 || r != 1 || s != 3)
+ abort ();
+
+ baz ("\6\0\0\0\0\0\7");
+ if (x != 6 || y != 7 || r != 2 || s != 6)
+ abort ();
+
+ baz ("\7\6\5\4\3\2\1");
+ if (x != 2 || y != 1 || r != 3 || s != 9)
+ abort ();
+
+ baz ("\0\0\4\3\0\7");
+ if (x != 7 || y != 3 || r != 4 || s != 12)
+ abort ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-7.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-7.c
new file mode 100644
index 00000000000..2d542d6d56c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-7.c
@@ -0,0 +1,63 @@
+/* { dg-do run } */
+/* { dg-additional-options "-O2 -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" { target avx_runtime } } } */
+
+int v, x;
+
+__attribute__((noipa)) void
+foo (int *a)
+{
+ #pragma omp for simd lastprivate (conditional: x) schedule(simd: static)
+ for (int i = 0; i < 128; i++)
+ if (a[i])
+ x = a[i];
+}
+
+__attribute__((noipa)) void
+bar (int *a, int *b)
+{
+ #pragma omp for simd lastprivate (conditional: x, v) schedule(static, 16)
+ for (int i = 16; i < 128; ++i)
+ {
+ if (a[i])
+ x = a[i];
+ if (b[i])
+ v = b[i] + 10;
+ }
+}
+
+__attribute__((noipa)) void
+baz (int *a)
+{
+ #pragma omp for simd lastprivate (conditional: x) schedule(simd: dynamic, 16)
+ for (int i = 0; i < 128; i++)
+ if (a[i])
+ x = a[i] + 5;
+}
+
+int
+main ()
+{
+ int a[128], b[128], i;
+ for (i = 0; i < 128; i++)
+ {
+ a[i] = ((i % 11) == 2) ? i + 10 : 0;
+ asm volatile ("" : "+g" (i));
+ b[i] = ((i % 13) == 5) ? i * 2 : 0;
+ }
+ #pragma omp parallel
+ foo (a);
+ if (x != 133)
+ __builtin_abort ();
+ x = -3;
+ #pragma omp parallel
+ bar (b, a);
+ if (x != 244 || v != 143)
+ __builtin_abort ();
+ #pragma omp parallel
+ baz (b);
+ if (x != 249)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-8.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-8.c
new file mode 100644
index 00000000000..b935a6c2dbf
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-8.c
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+/* { dg-additional-options "-O2 -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" { target avx_runtime } } } */
+
+int v, x;
+
+__attribute__((noipa)) int
+foo (int *a)
+{
+ #pragma omp parallel for simd lastprivate (conditional: x) schedule(simd: static)
+ for (int i = 0; i < 128; i++)
+ if (a[i])
+ x = a[i];
+ return x;
+}
+
+__attribute__((noipa)) int
+bar (int *a, int *b)
+{
+ #pragma omp parallel
+ #pragma omp for simd lastprivate (conditional: x, v) schedule(static, 16)
+ for (int i = 16; i < 128; ++i)
+ {
+ if (a[i])
+ x = a[i];
+ if (b[i])
+ v = b[i] + 10;
+ }
+ return x;
+}
+
+__attribute__((noipa)) int
+baz (int *a)
+{
+ #pragma omp parallel for simd lastprivate (conditional: x) schedule(simd: dynamic, 16)
+ for (int i = 0; i < 128; i++)
+ if (a[i])
+ x = a[i] + 5;
+ return x;
+}
+
+int
+main ()
+{
+ int a[128], b[128], i;
+ for (i = 0; i < 128; i++)
+ {
+ a[i] = ((i % 11) == 2) ? i + 10 : 0;
+ asm volatile ("" : "+g" (i));
+ b[i] = ((i % 13) == 5) ? i * 2 : 0;
+ }
+ if (foo (a) != 133)
+ __builtin_abort ();
+ if (bar (b, a) != 244 || v != 143)
+ __builtin_abort ();
+ if (baz (b) != 249)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-9.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-9.c
new file mode 100644
index 00000000000..746b2a74c97
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-9.c
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+
+int v, x;
+
+__attribute__((noipa)) void
+foo (int *a)
+{
+ #pragma omp for simd lastprivate (conditional: x) schedule(simd: static) if (simd: 0)
+ for (int i = 0; i < 128; i++)
+ if (a[i])
+ x = a[i];
+}
+
+__attribute__((noipa)) void
+bar (int *a, int *b)
+{
+ #pragma omp for simd lastprivate (conditional: x, v) schedule(static, 16) simdlen(1)
+ for (int i = 16; i < 128; ++i)
+ {
+ if (a[i])
+ x = a[i];
+ if (b[i])
+ v = b[i] + 10;
+ }
+}
+
+__attribute__((noipa)) void
+baz (int *a)
+{
+ #pragma omp for simd lastprivate (conditional: x) schedule(simd: dynamic, 16) if (0)
+ for (int i = 0; i < 128; i++)
+ if (a[i])
+ x = a[i] + 5;
+}
+
+int
+main ()
+{
+ int a[128], b[128], i;
+ for (i = 0; i < 128; i++)
+ {
+ a[i] = ((i % 11) == 2) ? i + 10 : 0;
+ asm volatile ("" : "+g" (i));
+ b[i] = ((i % 13) == 5) ? i * 2 : 0;
+ }
+ #pragma omp parallel
+ foo (a);
+ if (x != 133)
+ __builtin_abort ();
+ x = -3;
+ #pragma omp parallel
+ bar (b, a);
+ if (x != 244 || v != 143)
+ __builtin_abort ();
+ #pragma omp parallel
+ baz (b);
+ if (x != 249)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/loop-1.c b/libgomp/testsuite/libgomp.c-c++-common/loop-1.c
new file mode 100644
index 00000000000..de696081d16
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/loop-1.c
@@ -0,0 +1,127 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+#define N 256
+int r;
+
+void
+foo (int *a)
+{
+ int i, j;
+ #pragma omp loop bind(thread) order(concurrent) private (j) lastprivate (i) reduction(+:r) collapse(1)
+ for (i = 0; i < N; i++)
+ {
+ j = i - 2;
+ a[i] = j;
+ r += j;
+ }
+}
+
+void
+bar (int *a)
+{
+ int i, j;
+ #pragma omp loop bind(parallel) order(concurrent) private (j) lastprivate (i) reduction(+:r) collapse(1)
+ for (i = 0; i < N; i++)
+ {
+ j = i;
+ a[i] = j;
+ r += j;
+ }
+}
+
+void
+baz (int *a)
+{
+ int i, j;
+ #pragma omp loop bind(teams) order(concurrent) private (j) lastprivate (i) reduction(+:r)
+ for (i = 0; i < N; i++)
+ {
+ j = i + 2;
+ a[i] = j;
+ r += j;
+ }
+}
+
+int
+main ()
+{
+ int a[N], i, j;
+ foo (a);
+ for (i = 0; i < N; ++i)
+ if (a[i] != i - 2)
+ abort ();
+ else
+ a[i] = -35;
+ if (r != N * (N - 5) / 2)
+ abort ();
+ else
+ r = 0;
+ bar (a);
+ for (i = 0; i < N; ++i)
+ if (a[i] != i)
+ abort ();
+ else
+ a[i] = -35;
+ if (r != N * (N - 1) / 2)
+ abort ();
+ else
+ r = 0;
+ #pragma omp parallel loop private (j) lastprivate (i) reduction(+:r)
+ for (i = 0; i < N; i++)
+ {
+ j = i + 4;
+ a[i] = j;
+ r += j;
+ }
+ if (i != N)
+ abort ();
+ for (i = 0; i < N; ++i)
+ if (a[i] != i + 4)
+ abort ();
+ else
+ a[i] = -35;
+ if (r != N * (N + 7) / 2)
+ abort ();
+ else
+ r = 0;
+ #pragma omp parallel
+ bar (a);
+ for (i = 0; i < N; ++i)
+ if (a[i] != i)
+ abort ();
+ else
+ a[i] = -35;
+ if (r != N * (N - 1) / 2)
+ abort ();
+ else
+ r = 0;
+ #pragma omp teams
+ baz (a);
+ for (i = 0; i < N; ++i)
+ if (a[i] != i + 2)
+ abort ();
+ else
+ a[i] = -35;
+ if (r != N * (N + 3) / 2)
+ abort ();
+ else
+ r = 0;
+ #pragma omp teams loop order(concurrent) private (j) lastprivate (i) reduction(+:r) collapse(1)
+ for (i = 0; i < N; i++)
+ {
+ j = i - 4;
+ a[i] = j;
+ r += j;
+ }
+ if (i != N)
+ abort ();
+ for (i = 0; i < N; ++i)
+ if (a[i] != i - 4)
+ abort ();
+ if (r != N * (N - 9) / 2)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c b/libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c
new file mode 100644
index 00000000000..3e6da095122
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c
@@ -0,0 +1,66 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+#define N 64
+
+int
+main ()
+{
+ int p, *q, i, l;
+ int a[N];
+ q = a;
+ #pragma omp parallel master num_threads(4) private (p) shared(a)
+ {
+ int i;
+ p = omp_get_thread_num ();
+ if (p != 0)
+ abort ();
+ #pragma omp taskloop nogroup
+ for (i = 0; i < N; ++i)
+ {
+ if (omp_get_thread_num () >= 4)
+ abort ();
+ a[i] = i;
+ }
+ }
+ #pragma omp parallel num_threads(4)
+ {
+ #pragma omp master taskloop lastprivate (i, l) firstprivate (q)
+ for (i = 0; i != N; i = i + 1)
+ l = q[i];
+ }
+ if (i != N || l != N - 1)
+ abort ();
+ #pragma omp parallel master taskloop num_threads(4) \
+ lastprivate (i, l) firstprivate (q)
+ for (i = 0; i < N - 5; i += 2)
+ if (q[i] != i)
+ abort ();
+ else
+ l = q[i];
+ if (i != N - 4 || l != N - 6)
+ abort ();
+ #pragma omp parallel master taskloop simd num_threads(4)
+ for (i = 0; i < N; i++)
+ a[i] = 2 * a[i];
+ if (i != N)
+ abort ();
+ #pragma omp parallel num_threads(4)
+ {
+ int j;
+ #pragma omp master taskloop simd collapse(2)
+ for (i = 0; i < 2; i += 2)
+ for (j = 0; j < N; j++)
+ a[j] = a[j] + 1;
+ }
+ for (i = 0; i < N; i++)
+ if (a[i] != 2 * i + 1)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pause-1.c b/libgomp/testsuite/libgomp.c-c++-common/pause-1.c
new file mode 100644
index 00000000000..5367a72832e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/pause-1.c
@@ -0,0 +1,23 @@
+#include <omp.h>
+#include <stdlib.h>
+
+int a[64];
+
+int
+main ()
+{
+ int i;
+ #pragma omp parallel for
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ omp_pause_resource (omp_pause_soft, omp_get_initial_device ());
+ #pragma omp parallel for
+ for (i = 0; i < 64; i++)
+ a[i] += i;
+ omp_pause_resource_all (omp_pause_hard);
+ #pragma omp parallel for
+ for (i = 0; i < 64; i++)
+ if (a[i] != 2 * i)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pause-2.c b/libgomp/testsuite/libgomp.c-c++-common/pause-2.c
new file mode 100644
index 00000000000..e4781cdc707
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/pause-2.c
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+int t = 128;
+#pragma omp threadprivate (t)
+
+int
+main ()
+{
+ #pragma omp parallel
+ t = omp_get_thread_num () + 256;
+ #pragma omp parallel
+ if (t != omp_get_thread_num () + 256)
+ abort ();
+ omp_pause_resource (omp_pause_soft, omp_get_initial_device ());
+ /* This goes beyond what is required by the standard, we actually
+ check if the threads other than the initial one have been destroyed. */
+ #pragma omp parallel
+ {
+ if (omp_get_thread_num () != 0 && t != 128)
+ abort ();
+ t = omp_get_thread_num () + 384;
+ }
+ #pragma omp parallel
+ if (t != omp_get_thread_num () + 384)
+ abort ();
+ omp_pause_resource_all (omp_pause_hard);
+ #pragma omp parallel
+ {
+ if (omp_get_thread_num () != 0 && t != 128)
+ abort ();
+ t = omp_get_thread_num () + 512;
+ }
+ #pragma omp parallel
+ if (t != omp_get_thread_num () + 512)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pr66199-10.c b/libgomp/testsuite/libgomp.c-c++-common/pr66199-10.c
new file mode 100644
index 00000000000..301fa6c2551
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/pr66199-10.c
@@ -0,0 +1,60 @@
+/* PR middle-end/66199 */
+/* { dg-do run } */
+
+int u[1024], v[1024], w[1024];
+
+__attribute__((noinline, noclone)) long
+f1 (long a, long b)
+{
+ long d;
+ #pragma omp teams distribute parallel for simd default(none) firstprivate (a, b) shared(u, v, w)
+ for (d = a; d < b; d++)
+ u[d] = v[d] + w[d];
+ return d;
+}
+
+__attribute__((noinline, noclone)) long
+f2 (long a, long b, long c)
+{
+ long d, e;
+ #pragma omp teams distribute parallel for simd default(none) firstprivate (a, b, c) shared(u, v, w) linear(d) lastprivate(e)
+ for (d = a; d < b; d++)
+ {
+ u[d] = v[d] + w[d];
+ e = c + d * 5;
+ }
+ return d + e;
+}
+
+__attribute__((noinline, noclone)) long
+f3 (long a1, long b1, long a2, long b2)
+{
+ long d1, d2;
+ #pragma omp teams distribute parallel for simd default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) lastprivate(d1, d2) collapse(2)
+ for (d1 = a1; d1 < b1; d1++)
+ for (d2 = a2; d2 < b2; d2++)
+ u[d1 * 32 + d2] = v[d1 * 32 + d2] + w[d1 * 32 + d2];
+ return d1 + d2;
+}
+
+__attribute__((noinline, noclone)) long
+f4 (long a1, long b1, long a2, long b2)
+{
+ long d1, d2;
+ #pragma omp teams distribute parallel for simd default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) collapse(2)
+ for (d1 = a1; d1 < b1; d1++)
+ for (d2 = a2; d2 < b2; d2++)
+ u[d1 * 32 + d2] = v[d1 * 32 + d2] + w[d1 * 32 + d2];
+ return d1 + d2;
+}
+
+int
+main ()
+{
+ if (f1 (0, 1024) != 1024
+ || f2 (0, 1024, 17) != 1024 + (17 + 5 * 1023)
+ || f3 (0, 32, 0, 32) != 64
+ || f4 (0, 32, 0, 32) != 64)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pr66199-11.c b/libgomp/testsuite/libgomp.c-c++-common/pr66199-11.c
new file mode 100644
index 00000000000..bcb596eef5c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/pr66199-11.c
@@ -0,0 +1,38 @@
+/* PR middle-end/66199 */
+/* { dg-do run } */
+/* { dg-options "-O2" { target c } } */
+
+int u[1024], v[1024], w[1024];
+
+__attribute__((noinline, noclone)) long
+f2 (long a, long b, long c)
+{
+ long d, e;
+ #pragma omp teams distribute parallel for default(none) firstprivate (a, b, c) shared(u, v, w) lastprivate(d, e)
+ for (d = a; d < b; d++)
+ {
+ u[d] = v[d] + w[d];
+ e = c + d * 5;
+ }
+ return d + e;
+}
+
+__attribute__((noinline, noclone)) long
+f3 (long a1, long b1, long a2, long b2)
+{
+ long d1, d2;
+ #pragma omp teams distribute parallel for default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) lastprivate(d1, d2) collapse(2)
+ for (d1 = a1; d1 < b1; d1++)
+ for (d2 = a2; d2 < b2; d2++)
+ u[d1 * 32 + d2] = v[d1 * 32 + d2] + w[d1 * 32 + d2];
+ return d1 + d2;
+}
+
+int
+main ()
+{
+ if (f2 (0, 1024, 17) != 1024 + (17 + 5 * 1023)
+ || f3 (0, 32, 0, 32) != 64)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pr66199-12.c b/libgomp/testsuite/libgomp.c-c++-common/pr66199-12.c
new file mode 100644
index 00000000000..78eb12ac7aa
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/pr66199-12.c
@@ -0,0 +1,60 @@
+/* PR middle-end/66199 */
+/* { dg-do run } */
+
+int u[1024], v[1024], w[1024];
+
+__attribute__((noinline, noclone)) long
+f1 (long a, long b)
+{
+ long d;
+ #pragma omp teams distribute simd default(none) firstprivate (a, b) shared(u, v, w)
+ for (d = a; d < b; d++)
+ u[d] = v[d] + w[d];
+ return d;
+}
+
+__attribute__((noinline, noclone)) long
+f2 (long a, long b, long c)
+{
+ long d, e;
+ #pragma omp teams distribute simd default(none) firstprivate (a, b, c) shared(u, v, w) linear(d) lastprivate(e)
+ for (d = a; d < b; d++)
+ {
+ u[d] = v[d] + w[d];
+ e = c + d * 5;
+ }
+ return d + e;
+}
+
+__attribute__((noinline, noclone)) long
+f3 (long a1, long b1, long a2, long b2)
+{
+ long d1, d2;
+ #pragma omp teams distribute simd default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) lastprivate(d1, d2) collapse(2)
+ for (d1 = a1; d1 < b1; d1++)
+ for (d2 = a2; d2 < b2; d2++)
+ u[d1 * 32 + d2] = v[d1 * 32 + d2] + w[d1 * 32 + d2];
+ return d1 + d2;
+}
+
+__attribute__((noinline, noclone)) long
+f4 (long a1, long b1, long a2, long b2)
+{
+ long d1, d2;
+ #pragma omp teams distribute simd default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) collapse(2)
+ for (d1 = a1; d1 < b1; d1++)
+ for (d2 = a2; d2 < b2; d2++)
+ u[d1 * 32 + d2] = v[d1 * 32 + d2] + w[d1 * 32 + d2];
+ return d1 + d2;
+}
+
+int
+main ()
+{
+ if (f1 (0, 1024) != 1024
+ || f2 (0, 1024, 17) != 1024 + (17 + 5 * 1023)
+ || f3 (0, 32, 0, 32) != 64
+ || f4 (0, 32, 0, 32) != 64)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pr66199-13.c b/libgomp/testsuite/libgomp.c-c++-common/pr66199-13.c
new file mode 100644
index 00000000000..2f41a3860f4
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/pr66199-13.c
@@ -0,0 +1,64 @@
+/* PR middle-end/66199 */
+/* { dg-do run } */
+
+int u[1024], v[1024], w[1024];
+
+__attribute__((noinline, noclone)) long
+f1 (long a, long b)
+{
+ long d;
+ #pragma omp teams default(none) shared(a, b, d, u, v, w)
+ #pragma omp distribute simd firstprivate (a, b)
+ for (d = a; d < b; d++)
+ u[d] = v[d] + w[d];
+ return d;
+}
+
+__attribute__((noinline, noclone)) long
+f2 (long a, long b, long c)
+{
+ long d, e;
+ #pragma omp teams default(none) firstprivate (a, b, c) shared(d, e, u, v, w)
+ #pragma omp distribute simd linear(d) lastprivate(e)
+ for (d = a; d < b; d++)
+ {
+ u[d] = v[d] + w[d];
+ e = c + d * 5;
+ }
+ return d + e;
+}
+
+__attribute__((noinline, noclone)) long
+f3 (long a1, long b1, long a2, long b2)
+{
+ long d1, d2;
+ #pragma omp teams default(none) shared(a1, b1, a2, b2, d1, d2, u, v, w)
+ #pragma omp distribute simd firstprivate (a1, b1, a2, b2) lastprivate(d1, d2) collapse(2)
+ for (d1 = a1; d1 < b1; d1++)
+ for (d2 = a2; d2 < b2; d2++)
+ u[d1 * 32 + d2] = v[d1 * 32 + d2] + w[d1 * 32 + d2];
+ return d1 + d2;
+}
+
+__attribute__((noinline, noclone)) long
+f4 (long a1, long b1, long a2, long b2)
+{
+ long d1, d2;
+ #pragma omp teams default(none) firstprivate (a1, b1, a2, b2) shared(d1, d2, u, v, w)
+ #pragma omp distribute simd collapse(2)
+ for (d1 = a1; d1 < b1; d1++)
+ for (d2 = a2; d2 < b2; d2++)
+ u[d1 * 32 + d2] = v[d1 * 32 + d2] + w[d1 * 32 + d2];
+ return d1 + d2;
+}
+
+int
+main ()
+{
+ if (f1 (0, 1024) != 1024
+ || f2 (0, 1024, 17) != 1024 + (17 + 5 * 1023)
+ || f3 (0, 32, 0, 32) != 64
+ || f4 (0, 32, 0, 32) != 64)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/pr66199-14.c b/libgomp/testsuite/libgomp.c-c++-common/pr66199-14.c
new file mode 100644
index 00000000000..21936bfafaf
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/pr66199-14.c
@@ -0,0 +1,39 @@
+/* PR middle-end/66199 */
+/* { dg-do run } */
+
+int u[1024], v[1024], w[1024];
+
+__attribute__((noinline, noclone)) long
+f2 (long a, long b, long c)
+{
+ long d, e;
+ #pragma omp teams default(none) firstprivate (a, b, c) shared(d, e, u, v, w)
+ #pragma omp distribute lastprivate(d, e)
+ for (d = a; d < b; d++)
+ {
+ u[d] = v[d] + w[d];
+ e = c + d * 5;
+ }
+ return d + e;
+}
+
+__attribute__((noinline, noclone)) long
+f3 (long a1, long b1, long a2, long b2)
+{
+ long d1, d2;
+ #pragma omp teams default(none) shared(a1, b1, a2, b2, d1, d2, u, v, w)
+ #pragma omp distribute firstprivate (a1, b1, a2, b2) lastprivate(d1, d2) collapse(2)
+ for (d1 = a1; d1 < b1; d1++)
+ for (d2 = a2; d2 < b2; d2++)
+ u[d1 * 32 + d2] = v[d1 * 32 + d2] + w[d1 * 32 + d2];
+ return d1 + d2;
+}
+
+int
+main ()
+{
+ if (f2 (0, 1024, 17) != 1024 + (17 + 5 * 1023)
+ || f3 (0, 32, 0, 32) != 64)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/simd-1.c b/libgomp/testsuite/libgomp.c-c++-common/simd-1.c
new file mode 100644
index 00000000000..cce234d8171
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/simd-1.c
@@ -0,0 +1,71 @@
+// { dg-do run }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+#define N 1024
+int a[N], b[N];
+
+int
+f1 (void)
+{
+ int i;
+ #pragma omp simd private (i)
+ for (i = 0; i < N; i++)
+ a[i] = b[i] * 2;
+ #pragma omp simd lastprivate (i)
+ for (i = 0; i < N; i++)
+ a[i] += b[i] * 2;
+ return i;
+}
+
+int
+f2 (void)
+{
+ int i, j;
+ #pragma omp simd private (i), collapse (2), lastprivate (j)
+ for (i = 0; i < 32; i++)
+ for (j = 0; j < 32; ++j)
+ a[i * 32 + j] += b[i * 32 + j] * 2;
+ return j;
+}
+
+int
+f3 (void)
+{
+ static int i;
+ #pragma omp for simd private (i)
+ for (i = 0; i < N; ++i)
+ a[i] = b[i] * 2;
+ #pragma omp for simd lastprivate (i)
+ for (i = 0; i < N; ++i)
+ a[i] += b[i] * 2;
+ return i;
+}
+
+int
+f4 (void)
+{
+ static int i, j;
+ #pragma omp for simd private (i)collapse (2)lastprivate (j)
+ for (i = 0; i < 32; ++i)
+ for (j = 0; j < 32; j++)
+ a[i * 32 + j] += b[i * 32 + j] * 2;
+ return j;
+}
+
+int
+main ()
+{
+ int i;
+ for (i = 0; i < N; ++i)
+ a[i] = b[i] = i;
+ if (f1 () != 1024 || f2 () != 32)
+ __builtin_abort ();
+ #pragma omp parallel num_threads(4)
+ if (f3 () != 1024 || f4 () != 32)
+ __builtin_abort ();
+ for (i = 0; i < N; ++i)
+ if (a[i] != 6 * i || b[i] != i)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-1.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-1.c
new file mode 100644
index 00000000000..6c6191d96d5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-1.c
@@ -0,0 +1,58 @@
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int a;
+long int b = 1;
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a) in_reduction (*: b)
+ {
+ a += 7;
+ b *= 2;
+ }
+}
+
+int
+main ()
+{
+ int c = 0;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ long int d = 1;
+ #pragma omp taskgroup task_reduction (+: a, c) task_reduction (*: b, d)
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b, d)
+ {
+ int j;
+ a += 7;
+ b *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b, d)
+ {
+ a += 7;
+ b *= 2;
+ c += 9;
+ d *= 3;
+ foo ();
+ }
+ c += 9;
+ d *= 3;
+ }
+ }
+#define THREEP4 (3L * 3L * 3L * 3L)
+ if (d != (THREEP4 * THREEP4 * THREEP4))
+ abort ();
+ }
+ if (a != 28 * 7 || b != (1L << 28) || c != 12 * 9)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-11.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-11.c
new file mode 100644
index 00000000000..038b0e269e7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-11.c
@@ -0,0 +1,56 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+int a, b[3] = { 1, 1, 1 };
+unsigned long int c[2] = { ~0UL, ~0UL };
+
+void
+bar (int i)
+{
+ #pragma omp task in_reduction (*: b[:3]) in_reduction (&: c[1:]) \
+ in_reduction (+: a)
+ {
+ a += 4;
+ b[1] *= 4;
+ c[1] &= ~(1UL << (i + 16));
+ }
+}
+
+void
+foo (unsigned long long int x, unsigned long long int y, unsigned long long int z)
+{
+ unsigned long long int i;
+ #pragma omp for schedule(runtime) reduction (task, +: a) \
+ reduction (task, *: b) reduction (task, &: c[1:1])
+ for (i = x; i < y; i += z)
+ {
+ a++;
+ b[0] *= 2;
+ bar (i);
+ b[2] *= 3;
+ c[1] &= ~(1UL << i);
+ }
+}
+
+int
+main ()
+{
+ volatile int two = 2;
+ foo (two, 7 * two, two);
+ if (a != 30 || b[0] != 64 || b[1] != (1 << 12) || b[2] != 3 * 3 * 3 * 3 * 3 * 3
+ || c[0] != ~0UL || c[1] != ~0x15541554UL)
+ abort ();
+ a = 0;
+ b[0] = 1;
+ b[1] = 1;
+ b[2] = 1;
+ c[1] = ~0UL;
+ #pragma omp parallel
+ foo (two, 8 * two, two);
+ if (a != 35 || b[0] != 128 || b[1] != (1 << 14) || b[2] != 3 * 3 * 3 * 3 * 3 * 3 * 3
+ || c[0] != ~0UL || c[1] != ~0x55545554UL)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-12.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-12.c
new file mode 100644
index 00000000000..0ad92735ca7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-12.c
@@ -0,0 +1,67 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+int a, b[3] = { 1, 1, 1 };
+unsigned long int c[2] = { ~0UL, ~0UL };
+
+void
+bar (int i)
+{
+ #pragma omp task in_reduction (*: b[:3]) in_reduction (&: c[1:]) \
+ in_reduction (+: a)
+ {
+ a += 4;
+ b[1] *= 4;
+ c[1] &= ~(1UL << (i + 16));
+ }
+}
+
+void
+foo (int x)
+{
+ #pragma omp sections reduction (task, +: a) reduction (task, *: b) \
+ reduction (task, &: c[1:1])
+ {
+ {
+ a++; b[0] *= 2; bar (2); b[2] *= 3; c[1] &= ~(1UL << 2);
+ }
+ #pragma omp section
+ { b[0] *= 2; bar (4); b[2] *= 3; c[1] &= ~(1UL << 4); a++; }
+ #pragma omp section
+ { bar (6); b[2] *= 3; c[1] &= ~(1UL << 6); a++; b[0] *= 2; }
+ #pragma omp section
+ { b[2] *= 3; c[1] &= ~(1UL << 8); a++; b[0] *= 2; bar (8); }
+ #pragma omp section
+ { c[1] &= ~(1UL << 10); a++; b[0] *= 2; bar (10); b[2] *= 3; }
+ #pragma omp section
+ { a++; b[0] *= 2; b[2] *= 3; c[1] &= ~(1UL << 12); bar (12); }
+ #pragma omp section
+ if (x)
+ {
+ a++; b[0] *= 2; b[2] *= 3; bar (14); c[1] &= ~(1UL << 14);
+ }
+ }
+}
+
+int
+main ()
+{
+ volatile int one = 1;
+ foo (!one);
+ if (a != 30 || b[0] != 64 || b[1] != (1 << 12) || b[2] != 3 * 3 * 3 * 3 * 3 * 3
+ || c[0] != ~0UL || c[1] != ~0x15541554UL)
+ abort ();
+ a = 0;
+ b[0] = 1;
+ b[1] = 1;
+ b[2] = 1;
+ c[1] = ~0UL;
+ #pragma omp parallel
+ foo (one);
+ if (a != 35 || b[0] != 128 || b[1] != (1 << 14) || b[2] != 3 * 3 * 3 * 3 * 3 * 3 * 3
+ || c[0] != ~0UL || c[1] != ~0x55545554UL)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-13.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-13.c
new file mode 100644
index 00000000000..fc32216f407
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-13.c
@@ -0,0 +1,50 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+#pragma omp declare reduction (foo: int: omp_out += omp_in - 1) initializer (omp_priv = 1)
+
+int
+main ()
+{
+ int i, v = 0;
+ unsigned long long j;
+ volatile unsigned long long sixtyfour = 64;
+ int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0;
+ #pragma omp parallel
+ {
+#define P(str) _Pragma (#str)
+#define ONE_ORDERED_LOOP(var, i, max, n, clauses...) \
+ P (omp for ordered reduction (task, foo: var) clauses) \
+ for (i = 0; i < max; i++) \
+ { \
+ var++; \
+ P (omp task in_reduction (foo: var)) \
+ var++; \
+ _Pragma ("omp ordered") \
+ if (v++ != i + n) \
+ abort (); \
+ } \
+ if (var != 128 || v != 64 + n) \
+ abort (); \
+ _Pragma ("omp barrier")
+ ONE_ORDERED_LOOP (a, i, 64, 0, )
+ ONE_ORDERED_LOOP (b, i, 64, 64, schedule (monotonic: static))
+ ONE_ORDERED_LOOP (c, i, 64, 128, schedule (static, 1))
+ ONE_ORDERED_LOOP (d, i, 64, 192, schedule (monotonic: runtime))
+ ONE_ORDERED_LOOP (e, i, 64, 256, schedule (dynamic, 2))
+ ONE_ORDERED_LOOP (f, i, 64, 320, schedule (monotonic: guided, 3))
+ ONE_ORDERED_LOOP (g, i, 64, 384, schedule (auto))
+ #pragma omp single
+ { v = 0; a = 0; b = 0; c = 0; d = 0; e = 0; f = 0; g = 0; }
+ ONE_ORDERED_LOOP (a, j, sixtyfour, 0, )
+ ONE_ORDERED_LOOP (b, j, sixtyfour, 64, schedule (static))
+ ONE_ORDERED_LOOP (c, j, sixtyfour, 128, schedule (monotonic: static, 1))
+ ONE_ORDERED_LOOP (d, j, sixtyfour, 192, schedule (runtime))
+ ONE_ORDERED_LOOP (e, j, sixtyfour, 256, schedule (monotonic: dynamic, 2))
+ ONE_ORDERED_LOOP (f, j, sixtyfour, 320, schedule (guided, 3))
+ ONE_ORDERED_LOOP (g, j, sixtyfour, 384, schedule (monotonic: auto))
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-14.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-14.c
new file mode 100644
index 00000000000..37c00d4394a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-14.c
@@ -0,0 +1,51 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+#pragma omp declare reduction (foo: int: omp_out += omp_in - 1) initializer (omp_priv = 1)
+
+int
+main ()
+{
+ int i, v = 0;
+ unsigned long long j;
+ volatile unsigned long long sixtyfour = 64;
+ int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0;
+ #pragma omp parallel
+ {
+#define P(str) _Pragma (#str)
+#define ONE_ORDERED_LOOP(var, i, max, n, clauses...) \
+ P (omp for ordered(1) reduction (task, foo: var) clauses) \
+ for (i = 1; i <= max; i++) \
+ { \
+ P (omp task in_reduction (foo: var)) \
+ var++; \
+ P (omp ordered depend(sink: i - 1)) \
+ if (v++ != i + n - 1) \
+ abort (); \
+ _Pragma ("omp ordered depend(source)") \
+ var++; \
+ } \
+ if (var != 128 || v != 64 + n) \
+ abort (); \
+ _Pragma ("omp barrier")
+ ONE_ORDERED_LOOP (a, i, 64, 0, )
+ ONE_ORDERED_LOOP (b, i, 64, 64, schedule (monotonic: static))
+ ONE_ORDERED_LOOP (c, i, 64, 128, schedule (static, 1))
+ ONE_ORDERED_LOOP (d, i, 64, 192, schedule (monotonic: runtime))
+ ONE_ORDERED_LOOP (e, i, 64, 256, schedule (dynamic, 2))
+ ONE_ORDERED_LOOP (f, i, 64, 320, schedule (monotonic: guided, 3))
+ ONE_ORDERED_LOOP (g, i, 64, 384, schedule (auto))
+ #pragma omp single
+ { v = 0; a = 0; b = 0; c = 0; d = 0; e = 0; f = 0; g = 0; }
+ ONE_ORDERED_LOOP (a, j, sixtyfour, 0, )
+ ONE_ORDERED_LOOP (b, j, sixtyfour, 64, schedule (static))
+ ONE_ORDERED_LOOP (c, j, sixtyfour, 128, schedule (monotonic: static, 1))
+ ONE_ORDERED_LOOP (d, j, sixtyfour, 192, schedule (runtime))
+ ONE_ORDERED_LOOP (e, j, sixtyfour, 256, schedule (monotonic: dynamic, 2))
+ ONE_ORDERED_LOOP (f, j, sixtyfour, 320, schedule (guided, 3))
+ ONE_ORDERED_LOOP (g, j, sixtyfour, 384, schedule (monotonic: auto))
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-2.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-2.c
new file mode 100644
index 00000000000..aad725c29e3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-2.c
@@ -0,0 +1,90 @@
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+struct S { long int s, t; };
+
+void
+bar (struct S *p, struct S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+baz (struct S *o, struct S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: struct S : omp_out.s += omp_in.s) initializer (omp_priv = { 0, 3 })
+#pragma omp declare reduction (*: struct S : baz (&omp_out, &omp_in)) initializer (bar (&omp_priv, &omp_orig))
+
+struct S a = { 0, 7 };
+struct S b = { 1, 5 };
+
+void
+foo (void)
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (*: b) in_reduction (+: a)
+ {
+ a.s += 7;
+ b.s *= 2;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9))
+ abort ();
+ }
+}
+
+int
+main ()
+{
+ struct S c = { 0, 7 };
+ #pragma omp parallel
+ #pragma omp single
+ {
+ struct S d = { 1, 5 };
+ #pragma omp taskgroup task_reduction (+: a, c) task_reduction (*: b, d)
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (*: b, d) in_reduction (+: a, c)
+ {
+ int j;
+ a.s += 7;
+ b.s *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a) in_reduction (*: b) \
+ in_reduction (+: c) in_reduction (*: d)
+ {
+ a.s += 7;
+ b.s *= 2;
+ c.s += 9;
+ d.s *= 3;
+ foo ();
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ c.s += 9;
+ d.s *= 3;
+ if ((a.t != 7 && a.t != 3) || (b.t != 5 && b.t != 9)
+ || (c.t != 7 && c.t != 3) || (d.t != 5 && d.t != 9))
+ abort ();
+ }
+ }
+#define THREEP4 (3L * 3L * 3L * 3L)
+ if (d.s != (THREEP4 * THREEP4 * THREEP4) || d.t != 5)
+ abort ();
+ }
+ if (a.s != 28 * 7 || a.t != 7 || b.s != (1L << 28) || b.t != 5
+ || c.s != 12 * 9 || c.t != 7)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-3.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-3.c
new file mode 100644
index 00000000000..8a90e86e847
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-3.c
@@ -0,0 +1,218 @@
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int a[2];
+long long int b[7] = { 9, 11, 1, 1, 1, 13, 15 };
+int e[3] = { 5, 0, 5 };
+int f[5] = { 6, 7, 0, 0, 9 };
+int g[4] = { 1, 0, 0, 2 };
+int h[3] = { 0, 1, 4 };
+int k[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+long long *s;
+long long (*t)[2];
+
+void
+foo (int n, int *c, long long int *d, int m[3], int *r, int o[4], int *p, int q[4][2])
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0] += 7;
+ a[1] += 17;
+ b[2] *= 2;
+ b[4] *= 2;
+ c[0] += 6;
+ d[1] *= 2;
+ e[1] += 19;
+ f[2] += 21;
+ f[3] += 23;
+ g[1] += 25;
+ g[2] += 27;
+ h[0] += 29;
+ k[1][0] += 31;
+ k[2][1] += 33;
+ m[1] += 19;
+ r[2] += 21;
+ r[3] += 23;
+ o[1] += 25;
+ o[2] += 27;
+ p[0] += 29;
+ q[1][0] += 31;
+ q[2][1] += 33;
+ s[1] *= 2;
+ t[2][0] *= 2;
+ t[3][1] *= 2;
+ }
+}
+
+void
+test (int n)
+{
+ int c[2] = { 0, 0 };
+ int p[3] = { 0, 1, 4 };
+ int q[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+ long long ss[4] = { 5, 1, 1, 6 };
+ long long tt[5][2] = { { 9, 10 }, { 11, 12 }, { 1, 1 }, { 1, 1 }, { 13, 14 } };
+ s = ss;
+ t = tt;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ long long int d[] = { 1, 1 };
+ int m[3] = { 5, 0, 5 };
+ int r[5] = { 6, 7, 0, 0, 9 };
+ int o[4] = { 1, 0, 0, 2 };
+ #pragma omp taskgroup task_reduction (+: a, c) task_reduction (*: b[2 * n:3 * n], d) \
+ task_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ task_reduction (+: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ task_reduction (*: t[2:2][:], s[1:n + 1])
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ int j;
+ a[0] += 2;
+ a[1] += 3;
+ b[2] *= 2;
+ f[3] += 8;
+ g[1] += 9;
+ g[2] += 10;
+ h[0] += 11;
+ k[1][1] += 13;
+ k[2][1] += 15;
+ m[1] += 16;
+ r[2] += 8;
+ s[1] *= 2;
+ t[2][1] *= 2;
+ t[3][1] *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1] += 6;
+ r[2] += 7;
+ q[1][0] += 17;
+ q[2][0] += 19;
+ a[0] += 4;
+ a[1] += 5;
+ b[3] *= 2;
+ b[4] *= 2;
+ f[3] += 18;
+ g[1] += 29;
+ g[2] += 18;
+ h[0] += 19;
+ s[2] *= 2;
+ t[2][0] *= 2;
+ t[3][0] *= 2;
+ foo (n, c, d, m, r, o, p, q);
+ r[3] += 18;
+ o[1] += 29;
+ o[2] += 18;
+ p[0] += 19;
+ c[0] += 4;
+ c[1] += 5;
+ d[0] *= 2;
+ e[1] += 6;
+ f[2] += 7;
+ k[1][0] += 17;
+ k[2][0] += 19;
+ }
+ r[3] += 8;
+ o[1] += 9;
+ o[2] += 10;
+ p[0] += 11;
+ q[1][1] += 13;
+ q[2][1] += 15;
+ b[3] *= 2;
+ c[0] += 4;
+ c[1] += 9;
+ d[0] *= 2;
+ e[1] += 16;
+ f[2] += 8;
+ }
+ }
+ if (d[0] != 1LL << (8 + 4)
+ || d[1] != 1LL << 16
+ || m[0] != 5
+ || m[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2] != 5
+ || r[0] != 6
+ || r[1] != 7
+ || r[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4] != 9
+ || o[0] != 1
+ || o[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3] != 2)
+ abort ();
+ }
+ if (a[0] != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1] != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0] != 9 || b[1] != 11
+ || b[2] != 1LL << (16 + 4)
+ || b[3] != 1LL << (8 + 4)
+ || b[4] != 1LL << (16 + 8)
+ || b[5] != 13 || b[6] != 15
+ || c[0] != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1] != 5 * 8 + 9 * 4
+ || e[0] != 5
+ || e[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2] != 5
+ || f[0] != 6
+ || f[1] != 7
+ || f[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4] != 9
+ || g[0] != 1
+ || g[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3] != 2
+ || h[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1] != 1 || h[2] != 4
+ || k[0][0] != 5 || k[0][1] != 6
+ || k[1][0] != 31 * 16 + 17 * 8
+ || k[1][1] != 13 * 4
+ || k[2][0] != 19 * 8
+ || k[2][1] != 33 * 16 + 15 * 4
+ || k[3][0] != 7 || k[3][1] != 8
+ || p[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1] != 1 || p[2] != 4
+ || q[0][0] != 5 || q[0][1] != 6
+ || q[1][0] != 31 * 16 + 17 * 8
+ || q[1][1] != 13 * 4
+ || q[2][0] != 19 * 8
+ || q[2][1] != 33 * 16 + 15 * 4
+ || q[3][0] != 7 || q[3][1] != 8
+ || ss[0] != 5
+ || ss[1] != 1LL << (16 + 4)
+ || ss[2] != 1LL << 8
+ || ss[3] != 6
+ || tt[0][0] != 9 || tt[0][1] != 10 || tt[1][0] != 11 || tt[1][1] != 12
+ || tt[2][0] != 1LL << (16 + 8)
+ || tt[2][1] != 1LL << 4
+ || tt[3][0] != 1LL << 8
+ || tt[3][1] != 1LL << (16 + 4)
+ || tt[4][0] != 13 || tt[4][1] != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ test (1);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-4.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-4.c
new file mode 100644
index 00000000000..b0e5197623b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-4.c
@@ -0,0 +1,70 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+
+void
+bar (long long int *p)
+{
+ p[0] *= 2;
+ #pragma omp task in_reduction (*: p[0])
+ p[0] *= 3;
+}
+
+void
+foo (long long int *p, long long int *q)
+{
+ #pragma omp taskgroup task_reduction (*: p[0])
+ {
+ #pragma omp task in_reduction (*: p[0])
+ bar (p);
+ #pragma omp task in_reduction (*: p[0])
+ bar (p);
+ bar (p);
+ #pragma omp taskgroup task_reduction (*: q[0])
+ {
+ #pragma omp task in_reduction (*: q[0])
+ bar (q);
+ #pragma omp task in_reduction (*: q[0])
+ bar (q);
+ #pragma omp task in_reduction (*: q[0])
+ bar (q);
+ bar (q);
+ #pragma omp task in_reduction (*: p[0])
+ {
+ #pragma omp taskgroup task_reduction (*: p[0])
+ {
+ #pragma omp task in_reduction (*: p[0])
+ bar (p);
+ p[0] *= 2;
+ #pragma omp task in_reduction (*: p[0])
+ bar (p);
+ }
+ }
+ }
+ }
+}
+
+int
+main ()
+{
+ long long int p = 1LL, q = 1LL;
+ foo (&p, &q);
+ if (p != 6LL * 6LL * 6LL * 6LL * 6LL * 2LL || q != 6LL * 6LL * 6LL * 6LL)
+ abort ();
+ p = 1LL;
+ q = 1LL;
+ #pragma omp taskgroup
+ foo (&p, &q);
+ if (p != 6LL * 6LL * 6LL * 6LL * 6LL * 2LL || q != 6LL * 6LL * 6LL * 6LL)
+ abort ();
+ p = 1LL;
+ q = 1LL;
+ #pragma omp parallel
+ #pragma omp single
+ foo (&p, &q);
+ if (p != 6LL * 6LL * 6LL * 6LL * 6LL * 2LL || q != 6LL * 6LL * 6LL * 6LL)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-5.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-5.c
new file mode 100644
index 00000000000..018dc4fb28e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-5.c
@@ -0,0 +1,65 @@
+typedef __SIZE_TYPE__ size_t;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+
+int *q;
+
+void
+bar (int *p, int *r, int *t, int s, size_t u)
+{
+ #pragma omp task in_reduction (*: p[0], q[0], r[s - 1], t[0:u + 1])
+ {
+ *p *= 4;
+ *q *= 5;
+ r[s - 1] *= 6;
+ t[0] *= 8;
+ t[1] *= 9;
+ }
+}
+
+void
+foo (int *p, int *r, int *t, int s, size_t u)
+{
+ int *p2 = p;
+ #pragma omp taskgroup task_reduction (*: p[0], q[0], r[s], t[0:u + 1])
+ {
+ p = (int *) 0;
+ s++;
+ bar (p2, r, t, s, u);
+ r++;
+ #pragma omp taskwait
+ #pragma omp task in_reduction (*: p2[0], q[0], r[s - 2], t[0:u + 1])
+ {
+ *p2 *= 2;
+ *q *= 3;
+ r[s - 2] *= 7;
+ t[0] *= 10;
+ t[1] *= 11;
+ }
+ u = (~(size_t) 0) / 4;
+ s++;
+ p2 = (int *) 0;
+ q = (int *) 0;
+ r = (int *) 0;
+ t = (int *) 0;
+ }
+}
+
+int
+main ()
+{
+ int a = 1, b = 1, c[2] = { 1, 0 }, d[3] = { 1, 1, -1 };
+ volatile int zero;
+ zero = 0;
+ q = &b;
+ #pragma omp parallel num_threads (2)
+ #pragma omp master
+ foo (&a, &c[0], &d[0], zero, zero + 1);
+ if (a != 8 || b != 15 || c[0] != 42 || c[1] != 0
+ || d[0] != 80 || d[1] != 99 || d[2] != -1)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-6.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-6.c
new file mode 100644
index 00000000000..09cbea66542
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-6.c
@@ -0,0 +1,125 @@
+#include <omp.h>
+#include <stdlib.h>
+
+struct S { unsigned long long int s, t; };
+
+void
+rbar (struct S *p, struct S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+rbaz (struct S *o, struct S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: struct S : omp_out.s += omp_in.s) \
+ initializer (omp_priv = { 0, 3 })
+#pragma omp declare reduction (*: struct S : rbaz (&omp_out, &omp_in)) \
+ initializer (rbar (&omp_priv, &omp_orig))
+
+struct S g = { 0, 7 };
+struct S h = { 1, 5 };
+
+int
+foo (int *a, int *b)
+{
+ int x = 0;
+ #pragma omp taskloop reduction (+:x) in_reduction (+:b[0])
+ for (int i = 0; i < 64; i++)
+ {
+ x += a[i];
+ *b += a[i] * 2;
+ }
+ return x;
+}
+
+unsigned long long int
+bar (int *a, unsigned long long int *b)
+{
+ unsigned long long int x = 1;
+ #pragma omp taskloop reduction (*:x) in_reduction (*:b[0])
+ for (int i = 0; i < 64; i++)
+ {
+ #pragma omp task in_reduction (*:x)
+ x *= a[i];
+ #pragma omp task in_reduction (*:b[0])
+ *b *= (3 - a[i]);
+ }
+ return x;
+}
+
+void
+baz (int i, int *a, int *c)
+{
+ #pragma omp task in_reduction (*:h) in_reduction (+:g)
+ {
+ g.s += 7 * a[i];
+ h.s *= (3 - c[i]);
+ if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9))
+ abort ();
+ }
+}
+
+int
+main ()
+{
+ int i, j, a[64], b = 0, c[64];
+ unsigned long long int d = 1, e;
+ int r = 0, t;
+ struct S m = { 0, 7 };
+ struct S n = { 1, 5 };
+ for (i = 0; i < 64; i++)
+ {
+ a[i] = 2 * i;
+ c[i] = 1 + ((i % 3) != 1);
+ }
+ #pragma omp parallel reduction (task, +:b) reduction(+:r) \
+ reduction(task,*:d) reduction (task, +: g, m) \
+ reduction (task, *: h, n) shared(t)
+ {
+ #pragma omp master
+ {
+ j = foo (a, &b);
+ t = omp_get_num_threads ();
+ }
+ r++;
+ #pragma omp single nowait
+ e = bar (c, &d);
+ #pragma omp master
+ #pragma omp taskloop in_reduction (+: g, m) in_reduction (*: h, n)
+ for (i = 0; i < 64; ++i)
+ {
+ g.s += 3 * a[i];
+ h.s *= (3 - c[i]);
+ m.s += 4 * a[i];
+ n.s *= c[i];
+ if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9)
+ || (m.t != 7 && m.t != 3) || (n.t != 5 && n.t != 9))
+ abort ();
+ baz (i, a, c);
+ }
+ }
+ if (n.s != (1ULL << 43) || n.t != 5)
+ abort ();
+ if (j != 63 * 64 || b != 63 * 64 * 2)
+ abort ();
+ if (e != (1ULL << 43) || d != (1ULL << 21))
+ abort ();
+ if (g.s != 63 * 64 * 10 || g.t != 7)
+ abort ();
+ if (h.s != (1ULL << 42) || h.t != 5)
+ abort ();
+ if (m.s != 63 * 64 * 4 || m.t != 7)
+ abort ();
+ if (r != t)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-7.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-7.c
new file mode 100644
index 00000000000..c656f5ff00b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-7.c
@@ -0,0 +1,216 @@
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int a[2];
+long long int b[7] = { 9, 11, 1, 1, 1, 13, 15 };
+int e[3] = { 5, 0, 5 };
+int f[5] = { 6, 7, 0, 0, 9 };
+int g[4] = { 1, 0, 0, 2 };
+int h[3] = { 0, 1, 4 };
+int k[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+long long *s;
+long long (*t)[2];
+
+void
+foo (int n, int *c, long long int *d, int m[3], int *r, int o[4], int *p, int q[4][2])
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0] += 7;
+ a[1] += 17;
+ b[2] *= 2;
+ b[4] *= 2;
+ c[0] += 6;
+ d[1] *= 2;
+ e[1] += 19;
+ f[2] += 21;
+ f[3] += 23;
+ g[1] += 25;
+ g[2] += 27;
+ h[0] += 29;
+ k[1][0] += 31;
+ k[2][1] += 33;
+ m[1] += 19;
+ r[2] += 21;
+ r[3] += 23;
+ o[1] += 25;
+ o[2] += 27;
+ p[0] += 29;
+ q[1][0] += 31;
+ q[2][1] += 33;
+ s[1] *= 2;
+ t[2][0] *= 2;
+ t[3][1] *= 2;
+ }
+}
+
+void
+test (int n)
+{
+ int c[2] = { 0, 0 };
+ int p[3] = { 0, 1, 4 };
+ int q[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+ long long ss[4] = { 5, 1, 1, 6 };
+ long long tt[5][2] = { { 9, 10 }, { 11, 12 }, { 1, 1 }, { 1, 1 }, { 13, 14 } };
+ long long int d[] = { 1, 1 };
+ int m[3] = { 5, 0, 5 };
+ int r[5] = { 6, 7, 0, 0, 9 };
+ int o[4] = { 1, 0, 0, 2 };
+ s = ss;
+ t = tt;
+ #pragma omp parallel reduction (task, +: a, c) reduction (task, *: b[2 * n:3 * n], d) \
+ reduction (task, +: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (task, +: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (task, *: t[2:2][:], s[1:n + 1]) num_threads(4)
+ {
+ int i;
+ #pragma omp for
+ for (i = 0; i < 4; i++)
+ {
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ int j;
+ a[0] += 2;
+ a[1] += 3;
+ b[2] *= 2;
+ f[3] += 8;
+ g[1] += 9;
+ g[2] += 10;
+ h[0] += 11;
+ k[1][1] += 13;
+ k[2][1] += 15;
+ m[1] += 16;
+ r[2] += 8;
+ s[1] *= 2;
+ t[2][1] *= 2;
+ t[3][1] *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1] += 6;
+ r[2] += 7;
+ q[1][0] += 17;
+ q[2][0] += 19;
+ a[0] += 4;
+ a[1] += 5;
+ b[3] *= 2;
+ b[4] *= 2;
+ f[3] += 18;
+ g[1] += 29;
+ g[2] += 18;
+ h[0] += 19;
+ s[2] *= 2;
+ t[2][0] *= 2;
+ t[3][0] *= 2;
+ foo (n, c, d, m, r, o, p, q);
+ r[3] += 18;
+ o[1] += 29;
+ o[2] += 18;
+ p[0] += 19;
+ c[0] += 4;
+ c[1] += 5;
+ d[0] *= 2;
+ e[1] += 6;
+ f[2] += 7;
+ k[1][0] += 17;
+ k[2][0] += 19;
+ }
+ r[3] += 8;
+ o[1] += 9;
+ o[2] += 10;
+ p[0] += 11;
+ q[1][1] += 13;
+ q[2][1] += 15;
+ b[3] *= 2;
+ c[0] += 4;
+ c[1] += 9;
+ d[0] *= 2;
+ e[1] += 16;
+ f[2] += 8;
+ }
+ }
+ }
+ if (a[0] != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1] != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0] != 9 || b[1] != 11
+ || b[2] != 1LL << (16 + 4)
+ || b[3] != 1LL << (8 + 4)
+ || b[4] != 1LL << (16 + 8)
+ || b[5] != 13 || b[6] != 15
+ || c[0] != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1] != 5 * 8 + 9 * 4
+ || d[0] != 1LL << (8 + 4)
+ || d[1] != 1LL << 16
+ || e[0] != 5
+ || e[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2] != 5
+ || f[0] != 6
+ || f[1] != 7
+ || f[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4] != 9
+ || g[0] != 1
+ || g[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3] != 2
+ || h[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1] != 1 || h[2] != 4
+ || k[0][0] != 5 || k[0][1] != 6
+ || k[1][0] != 31 * 16 + 17 * 8
+ || k[1][1] != 13 * 4
+ || k[2][0] != 19 * 8
+ || k[2][1] != 33 * 16 + 15 * 4
+ || k[3][0] != 7 || k[3][1] != 8
+ || m[0] != 5
+ || m[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2] != 5
+ || o[0] != 1
+ || o[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3] != 2
+ || p[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1] != 1 || p[2] != 4
+ || q[0][0] != 5 || q[0][1] != 6
+ || q[1][0] != 31 * 16 + 17 * 8
+ || q[1][1] != 13 * 4
+ || q[2][0] != 19 * 8
+ || q[2][1] != 33 * 16 + 15 * 4
+ || q[3][0] != 7 || q[3][1] != 8
+ || r[0] != 6
+ || r[1] != 7
+ || r[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4] != 9
+ || ss[0] != 5
+ || ss[1] != 1LL << (16 + 4)
+ || ss[2] != 1LL << 8
+ || ss[3] != 6
+ || tt[0][0] != 9 || tt[0][1] != 10 || tt[1][0] != 11 || tt[1][1] != 12
+ || tt[2][0] != 1LL << (16 + 8)
+ || tt[2][1] != 1LL << 4
+ || tt[3][0] != 1LL << 8
+ || tt[3][1] != 1LL << (16 + 4)
+ || tt[4][0] != 13 || tt[4][1] != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ test (1);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-8.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-8.c
new file mode 100644
index 00000000000..52d238a5b15
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-8.c
@@ -0,0 +1,142 @@
+#include <omp.h>
+#include <stdlib.h>
+
+struct S { unsigned long long int s, t; };
+
+void
+rbar (struct S *p, struct S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+rbaz (struct S *o, struct S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: struct S : omp_out.s += omp_in.s) \
+ initializer (omp_priv = { 0, 3 })
+#pragma omp declare reduction (*: struct S : rbaz (&omp_out, &omp_in)) \
+ initializer (rbar (&omp_priv, &omp_orig))
+
+struct S g = { 0, 7 };
+struct S h = { 1, 5 };
+
+int
+foo (int z, int *a, int *b)
+{
+ int x = 0;
+ #pragma omp taskloop reduction (+:x) in_reduction (+:b[0])
+ for (int i = z; i < z + 8; i++)
+ {
+ x += a[i];
+ *b += a[i] * 2;
+ }
+ return x;
+}
+
+unsigned long long int
+bar (int z, int *a, unsigned long long int *b, int *s)
+{
+ unsigned long long int x = 1;
+ #pragma omp taskloop reduction (*:x) in_reduction (*:b[0]) \
+ in_reduction (+:s[0])
+ for (int i = z; i < z + 8; i++)
+ {
+ #pragma omp task in_reduction (*:x)
+ x *= a[i];
+ #pragma omp task in_reduction (*:b[0])
+ *b *= (3 - a[i]);
+ s[0]++;
+ }
+ return x;
+}
+
+void
+baz (int i, int *a, int *c)
+{
+ #pragma omp task in_reduction (*:h) in_reduction (+:g)
+ {
+ g.s += 7 * a[i];
+ h.s *= (3 - c[i]);
+ if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9))
+ abort ();
+ }
+}
+
+int
+main ()
+{
+ int i, j = 0, a[64], b = 0, c[64], f = 0;
+ unsigned long long int d = 1, e = 1;
+ volatile int one = 1;
+ int r = 0, s = 0, t;
+ struct S m = { 0, 7 };
+ struct S n = { 1, 5 };
+ for (i = 0; i < 64; i++)
+ {
+ a[i] = 2 * i;
+ c[i] = 1 + ((i % 3) != 1);
+ }
+ #pragma omp parallel reduction (task, +:b) shared(t) reduction(+:r, s)
+ {
+ int z, q1, q2, q3;
+ #pragma omp master
+ t = omp_get_num_threads ();
+ #pragma omp for schedule(static) reduction (task, +: f) reduction (+: j)
+ for (z = 0; z < 64; z += 8)
+ {
+ f++;
+ j += foo (z, a, &b);
+ j += foo (z, a, &f);
+ }
+ if (j != 63 * 64 * 2 || f != 63 * 64 * 2 + 8)
+ abort ();
+ r++;
+ #pragma omp taskgroup task_reduction (+: s)
+ {
+ #pragma omp for schedule(static, 1) reduction(task, *: d) reduction (*: e)
+ for (z = 0; z < 64; z += 8)
+ e *= bar (z, c, &d, &s);
+ }
+ if (e != (1ULL << 43) || d != (1ULL << 21))
+ abort ();
+ #pragma omp for schedule(monotonic: dynamic, 1) reduction (task, +: g, m) \
+ reduction (task, *: h, n) collapse(3)
+ for (q1 = 0; q1 < one; q1++)
+ for (q2 = 0; q2 < 64; q2 += 8)
+ for (q3 = 0; q3 < one; ++q3)
+ #pragma omp taskloop in_reduction (+: g, m) in_reduction (*: h, n) \
+ nogroup
+ for (i = q2; i < q2 + 8; ++i)
+ {
+ g.s += 3 * a[i];
+ h.s *= (3 - c[i]);
+ m.s += 4 * a[i];
+ n.s *= c[i];
+ if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9)
+ || (m.t != 7 && m.t != 3) || (n.t != 5 && n.t != 9))
+ abort ();
+ baz (i, a, c);
+ }
+ if (n.s != (1ULL << 43) || n.t != 5)
+ abort ();
+ if (g.s != 63 * 64 * 10 || g.t != 7)
+ abort ();
+ if (h.s != (1ULL << 42) || h.t != 5)
+ abort ();
+ if (m.s != 63 * 64 * 4 || m.t != 7)
+ abort ();
+ }
+ if (b != 63 * 64 * 2)
+ abort ();
+ if (r != t || s != 64)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-9.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-9.c
new file mode 100644
index 00000000000..3d71fef8670
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-9.c
@@ -0,0 +1,217 @@
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int a[2];
+long long int b[7] = { 9, 11, 1, 1, 1, 13, 15 };
+int e[3] = { 5, 0, 5 };
+int f[5] = { 6, 7, 0, 0, 9 };
+int g[4] = { 1, 0, 0, 2 };
+int h[3] = { 0, 1, 4 };
+int k[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+long long *s;
+long long (*t)[2];
+
+void
+foo (int n, int *c, long long int *d, int m[3], int *r, int o[4], int *p, int q[4][2])
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ #pragma omp task in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ a[0] += 7;
+ a[1] += 17;
+ b[2] *= 2;
+ b[4] *= 2;
+ c[0] += 6;
+ d[1] *= 2;
+ e[1] += 19;
+ f[2] += 21;
+ f[3] += 23;
+ g[1] += 25;
+ g[2] += 27;
+ h[0] += 29;
+ k[1][0] += 31;
+ k[2][1] += 33;
+ m[1] += 19;
+ r[2] += 21;
+ r[3] += 23;
+ o[1] += 25;
+ o[2] += 27;
+ p[0] += 29;
+ q[1][0] += 31;
+ q[2][1] += 33;
+ s[1] *= 2;
+ t[2][0] *= 2;
+ t[3][1] *= 2;
+ }
+}
+
+void
+test (int n)
+{
+ int c[2] = { 0, 0 };
+ int p[3] = { 0, 1, 4 };
+ int q[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+ long long ss[4] = { 5, 1, 1, 6 };
+ long long tt[5][2] = { { 9, 10 }, { 11, 12 }, { 1, 1 }, { 1, 1 }, { 13, 14 } };
+ long long int d[] = { 1, 1 };
+ int m[3] = { 5, 0, 5 };
+ int r[5] = { 6, 7, 0, 0, 9 };
+ int o[4] = { 1, 0, 0, 2 };
+ s = ss;
+ t = tt;
+ #pragma omp parallel num_threads(4)
+ {
+ int i;
+ #pragma omp for reduction (task, +: a, c) reduction (task, *: b[2 * n:3 * n], d) \
+ reduction (task, +: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (task, +: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (task, *: t[2:2][:], s[1:n + 1]) \
+ schedule(nonmonotonic: runtime)
+ for (i = 0; i < 4; i++)
+ {
+ #pragma omp task in_reduction (+: a, c) in_reduction (*: b[2 * n:3 * n], d) \
+ in_reduction (+: o[n:n*2], q[1:2][:], p[0], m[1], r[2:2]) \
+ in_reduction (+: g[n:n * 2], e[1], k[1:2][:], h[0], f[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:])
+ {
+ int j;
+ a[0] += 2;
+ a[1] += 3;
+ b[2] *= 2;
+ f[3] += 8;
+ g[1] += 9;
+ g[2] += 10;
+ h[0] += 11;
+ k[1][1] += 13;
+ k[2][1] += 15;
+ m[1] += 16;
+ r[2] += 8;
+ s[1] *= 2;
+ t[2][1] *= 2;
+ t[3][1] *= 2;
+ for (j = 0; j < 2; j++)
+ #pragma omp task in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:])
+ {
+ m[1] += 6;
+ r[2] += 7;
+ q[1][0] += 17;
+ q[2][0] += 19;
+ a[0] += 4;
+ a[1] += 5;
+ b[3] *= 2;
+ b[4] *= 2;
+ f[3] += 18;
+ g[1] += 29;
+ g[2] += 18;
+ h[0] += 19;
+ s[2] *= 2;
+ t[2][0] *= 2;
+ t[3][0] *= 2;
+ foo (n, c, d, m, r, o, p, q);
+ r[3] += 18;
+ o[1] += 29;
+ o[2] += 18;
+ p[0] += 19;
+ c[0] += 4;
+ c[1] += 5;
+ d[0] *= 2;
+ e[1] += 6;
+ f[2] += 7;
+ k[1][0] += 17;
+ k[2][0] += 19;
+ }
+ r[3] += 8;
+ o[1] += 9;
+ o[2] += 10;
+ p[0] += 11;
+ q[1][1] += 13;
+ q[2][1] += 15;
+ b[3] *= 2;
+ c[0] += 4;
+ c[1] += 9;
+ d[0] *= 2;
+ e[1] += 16;
+ f[2] += 8;
+ }
+ }
+ }
+ if (a[0] != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1] != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0] != 9 || b[1] != 11
+ || b[2] != 1LL << (16 + 4)
+ || b[3] != 1LL << (8 + 4)
+ || b[4] != 1LL << (16 + 8)
+ || b[5] != 13 || b[6] != 15
+ || c[0] != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1] != 5 * 8 + 9 * 4
+ || d[0] != 1LL << (8 + 4)
+ || d[1] != 1LL << 16
+ || e[0] != 5
+ || e[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2] != 5
+ || f[0] != 6
+ || f[1] != 7
+ || f[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4] != 9
+ || g[0] != 1
+ || g[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3] != 2
+ || h[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1] != 1 || h[2] != 4
+ || k[0][0] != 5 || k[0][1] != 6
+ || k[1][0] != 31 * 16 + 17 * 8
+ || k[1][1] != 13 * 4
+ || k[2][0] != 19 * 8
+ || k[2][1] != 33 * 16 + 15 * 4
+ || k[3][0] != 7 || k[3][1] != 8
+ || m[0] != 5
+ || m[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2] != 5
+ || o[0] != 1
+ || o[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3] != 2
+ || p[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1] != 1 || p[2] != 4
+ || q[0][0] != 5 || q[0][1] != 6
+ || q[1][0] != 31 * 16 + 17 * 8
+ || q[1][1] != 13 * 4
+ || q[2][0] != 19 * 8
+ || q[2][1] != 33 * 16 + 15 * 4
+ || q[3][0] != 7 || q[3][1] != 8
+ || r[0] != 6
+ || r[1] != 7
+ || r[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4] != 9
+ || ss[0] != 5
+ || ss[1] != 1LL << (16 + 4)
+ || ss[2] != 1LL << 8
+ || ss[3] != 6
+ || tt[0][0] != 9 || tt[0][1] != 10 || tt[1][0] != 11 || tt[1][1] != 12
+ || tt[2][0] != 1LL << (16 + 8)
+ || tt[2][1] != 1LL << 4
+ || tt[3][0] != 1LL << 8
+ || tt[3][1] != 1LL << (16 + 4)
+ || tt[4][0] != 13 || tt[4][1] != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ test (1);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-1.c b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-1.c
new file mode 100644
index 00000000000..d44b471a372
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-1.c
@@ -0,0 +1,119 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+
+struct S { unsigned long long int s, t; };
+
+void
+rbar (struct S *p, struct S *o)
+{
+ p->s = 1;
+ if (o->t != 5)
+ abort ();
+ p->t = 9;
+}
+
+static inline void
+rbaz (struct S *o, struct S *i)
+{
+ if (o->t != 5 || i->t != 9)
+ abort ();
+ o->s *= i->s;
+}
+
+#pragma omp declare reduction (+: struct S : omp_out.s += omp_in.s) \
+ initializer (omp_priv = { 0, 3 })
+#pragma omp declare reduction (*: struct S : rbaz (&omp_out, &omp_in)) \
+ initializer (rbar (&omp_priv, &omp_orig))
+
+struct S g = { 0, 7 };
+struct S h = { 1, 5 };
+
+int
+foo (int *a, int *b)
+{
+ int x = 0;
+ #pragma omp taskloop reduction (+:x) in_reduction (+:b[0])
+ for (int i = 0; i < 64; i++)
+ {
+ x += a[i];
+ *b += a[i] * 2;
+ }
+ return x;
+}
+
+unsigned long long int
+bar (int *a, unsigned long long int *b)
+{
+ unsigned long long int x = 1;
+ #pragma omp taskloop reduction (*:x) in_reduction (*:b[0])
+ for (int i = 0; i < 64; i++)
+ {
+ #pragma omp task in_reduction (*:x)
+ x *= a[i];
+ #pragma omp task in_reduction (*:b[0])
+ *b *= (3 - a[i]);
+ }
+ return x;
+}
+
+void
+baz (int i, int *a, int *c)
+{
+ #pragma omp task in_reduction (*:h) in_reduction (+:g)
+ {
+ g.s += 7 * a[i];
+ h.s *= (3 - c[i]);
+ if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9))
+ abort ();
+ }
+}
+
+int
+main ()
+{
+ int i, j, a[64], b = 0, c[64];
+ unsigned long long int d = 1, e;
+ struct S m = { 0, 7 };
+ for (i = 0; i < 64; i++)
+ {
+ a[i] = 2 * i;
+ c[i] = 1 + ((i % 3) != 1);
+ }
+ #pragma omp parallel
+ #pragma omp master
+ {
+ struct S n = { 1, 5 };
+ #pragma omp taskgroup task_reduction (+:b)
+ j = foo (a, &b);
+ #pragma omp taskgroup task_reduction (*:d)
+ e = bar (c, &d);
+ #pragma omp taskloop reduction (+: g, m) reduction (*: h, n)
+ for (i = 0; i < 64; ++i)
+ {
+ g.s += 3 * a[i];
+ h.s *= (3 - c[i]);
+ m.s += 4 * a[i];
+ n.s *= c[i];
+ if ((g.t != 7 && g.t != 3) || (h.t != 5 && h.t != 9)
+ || (m.t != 7 && m.t != 3) || (n.t != 5 && n.t != 9))
+ abort ();
+ baz (i, a, c);
+ }
+ if (n.s != (1ULL << 43) || n.t != 5)
+ abort ();
+ }
+ if (j != 63 * 64 || b != 63 * 64 * 2)
+ abort ();
+ if (e != (1ULL << 43) || d != (1ULL << 21))
+ abort ();
+ if (g.s != 63 * 64 * 10 || g.t != 7)
+ abort ();
+ if (h.s != (1ULL << 42) || h.t != 5)
+ abort ();
+ if (m.s != 63 * 64 * 4 || m.t != 7)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-2.c b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-2.c
new file mode 100644
index 00000000000..8fc05dc668e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-2.c
@@ -0,0 +1,212 @@
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int a[2];
+long long int b[7] = { 9, 11, 1, 1, 1, 13, 15 };
+int e[3] = { 5, 0, 5 };
+int f[5] = { 6, 7, 0, 0, 9 };
+int g[4] = { 1, 0, 0, 2 };
+int h[3] = { 0, 1, 4 };
+int k[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+long long *s;
+long long (*t)[2];
+
+void
+foo (int n, int *c, long long int *d, int m[3], int *r, int o[4], int *p, int q[4][2])
+{
+ int i;
+ #pragma omp taskloop in_reduction (+: a, c[:2]) in_reduction (*: b[2 * n:3 * n], d[0:2]) \
+ in_reduction (+: o[n:n*2], m[1], k[1:2][:], p[0], f[2:2]) \
+ in_reduction (+: q[1:2][:], g[n:n*2], e[1], h[0], r[2:2]) \
+ in_reduction (*: s[1:2], t[2:2][:]) nogroup
+ for (i = 0; i < 2; i++)
+ {
+ a[0] += 7;
+ a[1] += 17;
+ b[2] *= 2;
+ b[4] *= 2;
+ c[0] += 6;
+ d[1] *= 2;
+ e[1] += 19;
+ f[2] += 21;
+ f[3] += 23;
+ g[1] += 25;
+ g[2] += 27;
+ h[0] += 29;
+ k[1][0] += 31;
+ k[2][1] += 33;
+ m[1] += 19;
+ r[2] += 21;
+ r[3] += 23;
+ o[1] += 25;
+ o[2] += 27;
+ p[0] += 29;
+ q[1][0] += 31;
+ q[2][1] += 33;
+ s[1] *= 2;
+ t[2][0] *= 2;
+ t[3][1] *= 2;
+ }
+}
+
+void
+test (int n)
+{
+ int c[2] = { 0, 0 };
+ int p[3] = { 0, 1, 4 };
+ int q[4][2] = { { 5, 6 }, { 0, 0 }, { 0, 0 }, { 7, 8 } };
+ long long ss[4] = { 5, 1, 1, 6 };
+ long long tt[5][2] = { { 9, 10 }, { 11, 12 }, { 1, 1 }, { 1, 1 }, { 13, 14 } };
+ s = ss;
+ t = tt;
+ #pragma omp parallel
+ #pragma omp single
+ {
+ long long int d[] = { 1, 1 };
+ int m[3] = { 5, 0, 5 };
+ int r[5] = { 6, 7, 0, 0, 9 };
+ int o[4] = { 1, 0, 0, 2 };
+ int i;
+ #pragma omp taskloop reduction (+: a, c) reduction (default, *: b[2 * n:3 * n], d) \
+ reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][0:2]) \
+ reduction (default, +: o[n:n*2], m[1], q[1:2][:], p[0], r[2:2]) \
+ reduction (*: t[2:2][:], s[1:n + 1])
+ for (i = 0; i < 4; i++)
+ {
+ int j;
+ a[0] += 2;
+ a[1] += 3;
+ b[2] *= 2;
+ f[3] += 8;
+ g[1] += 9;
+ g[2] += 10;
+ h[0] += 11;
+ k[1][1] += 13;
+ k[2][1] += 15;
+ m[1] += 16;
+ r[2] += 8;
+ s[1] *= 2;
+ t[2][1] *= 2;
+ t[3][1] *= 2;
+ #pragma omp taskloop in_reduction (+: a, c[:2]) \
+ in_reduction (*: b[2 * n:3 * n], d[n - 1:n + 1]) \
+ in_reduction (+: e[1], f[2:2], g[n:n*2], h[0], k[1:2][:2]) \
+ in_reduction (+: m[1], r[2:2], o[n:n*2], p[0], q[1:2][:2]) \
+ in_reduction (*: s[n:2], t[2:2][:]) nogroup
+ for (j = 0; j < 2; j++)
+ {
+ m[1] += 6;
+ r[2] += 7;
+ q[1][0] += 17;
+ q[2][0] += 19;
+ a[0] += 4;
+ a[1] += 5;
+ b[3] *= 2;
+ b[4] *= 2;
+ f[3] += 18;
+ g[1] += 29;
+ g[2] += 18;
+ h[0] += 19;
+ s[2] *= 2;
+ t[2][0] *= 2;
+ t[3][0] *= 2;
+ foo (n, c, d, m, r, o, p, q);
+ r[3] += 18;
+ o[1] += 29;
+ o[2] += 18;
+ p[0] += 19;
+ c[0] += 4;
+ c[1] += 5;
+ d[0] *= 2;
+ e[1] += 6;
+ f[2] += 7;
+ k[1][0] += 17;
+ k[2][0] += 19;
+ }
+ r[3] += 8;
+ o[1] += 9;
+ o[2] += 10;
+ p[0] += 11;
+ q[1][1] += 13;
+ q[2][1] += 15;
+ b[3] *= 2;
+ c[0] += 4;
+ c[1] += 9;
+ d[0] *= 2;
+ e[1] += 16;
+ f[2] += 8;
+ }
+ if (d[0] != 1LL << (8 + 4)
+ || d[1] != 1LL << 16
+ || m[0] != 5
+ || m[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || m[2] != 5
+ || r[0] != 6
+ || r[1] != 7
+ || r[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || r[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || r[4] != 9
+ || o[0] != 1
+ || o[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || o[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || o[3] != 2)
+ abort ();
+ }
+ if (a[0] != 7 * 16 + 4 * 8 + 2 * 4
+ || a[1] != 17 * 16 + 5 * 8 + 3 * 4
+ || b[0] != 9 || b[1] != 11
+ || b[2] != 1LL << (16 + 4)
+ || b[3] != 1LL << (8 + 4)
+ || b[4] != 1LL << (16 + 8)
+ || b[5] != 13 || b[6] != 15
+ || c[0] != 6 * 16 + 4 * 8 + 4 * 4
+ || c[1] != 5 * 8 + 9 * 4
+ || e[0] != 5
+ || e[1] != 19 * 16 + 6 * 8 + 16 * 4
+ || e[2] != 5
+ || f[0] != 6
+ || f[1] != 7
+ || f[2] != 21 * 16 + 7 * 8 + 8 * 4
+ || f[3] != 23 * 16 + 18 * 8 + 8 * 4
+ || f[4] != 9
+ || g[0] != 1
+ || g[1] != 25 * 16 + 29 * 8 + 9 * 4
+ || g[2] != 27 * 16 + 18 * 8 + 10 * 4
+ || g[3] != 2
+ || h[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || h[1] != 1 || h[2] != 4
+ || k[0][0] != 5 || k[0][1] != 6
+ || k[1][0] != 31 * 16 + 17 * 8
+ || k[1][1] != 13 * 4
+ || k[2][0] != 19 * 8
+ || k[2][1] != 33 * 16 + 15 * 4
+ || k[3][0] != 7 || k[3][1] != 8
+ || p[0] != 29 * 16 + 19 * 8 + 11 * 4
+ || p[1] != 1 || p[2] != 4
+ || q[0][0] != 5 || q[0][1] != 6
+ || q[1][0] != 31 * 16 + 17 * 8
+ || q[1][1] != 13 * 4
+ || q[2][0] != 19 * 8
+ || q[2][1] != 33 * 16 + 15 * 4
+ || q[3][0] != 7 || q[3][1] != 8
+ || ss[0] != 5
+ || ss[1] != 1LL << (16 + 4)
+ || ss[2] != 1LL << 8
+ || ss[3] != 6
+ || tt[0][0] != 9 || tt[0][1] != 10 || tt[1][0] != 11 || tt[1][1] != 12
+ || tt[2][0] != 1LL << (16 + 8)
+ || tt[2][1] != 1LL << 4
+ || tt[3][0] != 1LL << 8
+ || tt[3][1] != 1LL << (16 + 4)
+ || tt[4][0] != 13 || tt[4][1] != 14)
+ abort ();
+}
+
+int
+main ()
+{
+ test (1);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c
new file mode 100644
index 00000000000..30a83249046
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#define N 1024
+long int u[N], m, n;
+
+__attribute__((noipa)) void
+foo (void)
+{
+ int i;
+ #pragma omp taskloop simd reduction (+:m) grainsize (64)
+ for (i = 0; i < N; ++i)
+ m += u[i];
+}
+
+__attribute__((noipa)) void
+bar (int x)
+{
+ #pragma omp taskloop simd in_reduction (+:n) grainsize (64) nogroup
+ for (int i = (x & 1) * (N / 2); i < (x & 1) * (N / 2) + (N / 2); i++)
+ n += 2 * u[i];
+}
+
+int
+main ()
+{
+ int i;
+ for (i = 0; i < N; ++i)
+ u[i] = i;
+ #pragma omp parallel master
+ {
+ foo ();
+ #pragma omp taskgroup task_reduction (+:n)
+ {
+ bar (0);
+ bar (1);
+ }
+ }
+ if (m != (long)(N - 1) * (N / 2) || n != (long)(N - 1) * N)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c
new file mode 100644
index 00000000000..c1c29b37414
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+#define N 1024
+long int u[N], m, n, o;
+
+__attribute__((noipa)) void
+foo (void)
+{
+ int i = -1;
+ #pragma omp master taskloop simd reduction (+:m) grainsize (64)
+ for (i = 0; i < N; ++i)
+ m += u[i];
+ if (i != (omp_get_thread_num () ? -1 : N))
+ abort ();
+}
+
+__attribute__((noipa)) void
+bar (int x)
+{
+ int i = -1;
+ #pragma omp master taskloop simd in_reduction (+:n) grainsize (64)
+ for (i = (x & 1) * (N / 2); i < (x & 1) * (N / 2) + (N / 2); i++)
+ n += 2 * u[i];
+ if (i != (omp_get_thread_num () ? -1 : (x & 1) * (N / 2) + (N / 2)))
+ abort ();
+}
+
+__attribute__((noipa)) void
+baz (void)
+{
+ int i;
+ #pragma omp parallel master taskloop simd reduction (+:o) grainsize (64)
+ for (i = 0; i < N; ++i)
+ o += u[i];
+ if (i != N)
+ abort ();
+}
+
+int
+main ()
+{
+ int i;
+ for (i = 0; i < N; ++i)
+ u[i] = i;
+ #pragma omp parallel
+ {
+ foo ();
+ #pragma omp taskgroup task_reduction (+:n)
+ {
+ bar (0);
+ bar (1);
+ }
+ }
+ baz ();
+ if (m != (long)(N - 1) * (N / 2) || n != (long)(N - 1) * N || o != m)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/taskwait-depend-1.c b/libgomp/testsuite/libgomp.c-c++-common/taskwait-depend-1.c
new file mode 100644
index 00000000000..094b4b3586a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/taskwait-depend-1.c
@@ -0,0 +1,29 @@
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int
+main ()
+{
+ int a, b, c, d;
+ #pragma omp parallel num_threads (4)
+ #pragma omp single
+ {
+ #pragma omp task depend(out : a)
+ a = 6;
+ #pragma omp task depend(out : b)
+ b = 7;
+ #pragma omp task depend(out : c)
+ c = 8;
+ #pragma omp taskwait depend(in : a, c)
+ d = a + c;
+ #pragma omp task depend(out : a)
+ a = 9;
+ #pragma omp task depend(out : c)
+ c = 10;
+ }
+ if (a != 9 || b != 7 || c != 10 || d != 6 + 8)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/variable-not-offloaded.c b/libgomp/testsuite/libgomp.c-c++-common/variable-not-offloaded.c
new file mode 100644
index 00000000000..bc4b916e9a4
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/variable-not-offloaded.c
@@ -0,0 +1,19 @@
+/* { dg-do link } */
+/* { dg-excess-errors "lto1, mkoffload and lto-wrapper fatal errors" { target offload_device_nonshared_as } } */
+
+int var; /* { dg-error "variable 'var' has been referenced in offloaded code but hasn't been marked to be included in the offloaded code" "" { target offload_device_nonshared_as } } */
+
+#pragma omp declare target
+void __attribute__((noinline, noclone))
+foo (void)
+{
+ var++;
+}
+#pragma omp end declare target
+
+int
+main ()
+{
+#pragma omp target
+ foo ();
+}
diff --git a/libgomp/testsuite/libgomp.c/affinity-1.c b/libgomp/testsuite/libgomp.c/affinity-1.c
index 1e71dd36148..a607dc35545 100644
--- a/libgomp/testsuite/libgomp.c/affinity-1.c
+++ b/libgomp/testsuite/libgomp.c/affinity-1.c
@@ -1,5 +1,5 @@
/* Affinity tests.
- Copyright (C) 2013-2018 Free Software Foundation, Inc.
+ Copyright (C) 2013-2019 Free Software Foundation, Inc.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
diff --git a/libgomp/testsuite/libgomp.c/cancel-for-2.c b/libgomp/testsuite/libgomp.c/cancel-for-2.c
index 30cfbb1c502..d1d6f86733d 100644
--- a/libgomp/testsuite/libgomp.c/cancel-for-2.c
+++ b/libgomp/testsuite/libgomp.c/cancel-for-2.c
@@ -20,7 +20,7 @@ foo (int *x)
#pragma omp for
for (i = 0; i < 1000; ++i)
{
- #pragma omp cancel for if (x[1])
+ #pragma omp cancel for if (cancel: x[1])
#pragma omp atomic
v++;
}
@@ -34,7 +34,7 @@ foo (int *x)
#pragma omp for
for (i = 0; i < 1000; ++i)
{
- #pragma omp cancel for if (x[3])
+ #pragma omp cancel for if ( cancel : x[3])
#pragma omp atomic
v += 2;
}
@@ -54,7 +54,7 @@ foo (int *x)
#pragma omp cancel for if (x[0])
abort ();
}
- #pragma omp cancel parallel if (omp_get_thread_num () == 2 && x[4])
+ #pragma omp cancel parallel if (cancel:omp_get_thread_num () == 2 && x[4])
#pragma omp for
for (i = 0; i < 1000; ++i)
{
diff --git a/libgomp/testsuite/libgomp.c/pr39591-1.c b/libgomp/testsuite/libgomp.c/pr39591-1.c
index df326f85424..a22bc337819 100644
--- a/libgomp/testsuite/libgomp.c/pr39591-1.c
+++ b/libgomp/testsuite/libgomp.c/pr39591-1.c
@@ -3,7 +3,7 @@
extern void abort (void);
-int err;
+int e;
int
main (void)
@@ -23,10 +23,10 @@ main (void)
for (j = 0; j < sizeof array / sizeof array[0]; j++)
if (array[j] != 0x55555555)
#pragma omp atomic
- err++;
+ e++;
}
}
- if (err)
+ if (e)
abort ();
return 0;
}
diff --git a/libgomp/testsuite/libgomp.c/pr39591-2.c b/libgomp/testsuite/libgomp.c/pr39591-2.c
index 2fe6421aef4..ba8b862f49c 100644
--- a/libgomp/testsuite/libgomp.c/pr39591-2.c
+++ b/libgomp/testsuite/libgomp.c/pr39591-2.c
@@ -3,7 +3,7 @@
extern void abort (void);
-int err;
+int e;
void __attribute__((noinline))
foo (int *array)
@@ -14,7 +14,7 @@ foo (int *array)
for (j = 0; j < 40; j++)
if (array[j] != 0x55555555)
#pragma omp atomic
- err++;
+ e++;
}
}
@@ -32,7 +32,7 @@ main (void)
for (i = 0; i < 50; i++)
foo (array);
}
- if (err)
+ if (e)
abort ();
return 0;
}
diff --git a/libgomp/testsuite/libgomp.c/pr39591-3.c b/libgomp/testsuite/libgomp.c/pr39591-3.c
index 81e8ca8e497..590553437ea 100644
--- a/libgomp/testsuite/libgomp.c/pr39591-3.c
+++ b/libgomp/testsuite/libgomp.c/pr39591-3.c
@@ -3,7 +3,7 @@
extern void abort (void);
-int err, a[40];
+int e, a[40];
void __attribute__((noinline))
foo (int *array)
@@ -14,7 +14,7 @@ foo (int *array)
for (j = 0; j < 40; j++)
if (array[j] != 0x55555555)
#pragma omp atomic
- err++;
+ e++;
}
}
@@ -33,7 +33,7 @@ main (void)
for (i = 0; i < 50; i++)
foo (a);
}
- if (err)
+ if (e)
abort ();
return 0;
}
diff --git a/libgomp/testsuite/libgomp.c/pr86660.c b/libgomp/testsuite/libgomp.c/pr86660.c
new file mode 100644
index 00000000000..bea6b15270b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pr86660.c
@@ -0,0 +1,28 @@
+/* PR middle-end/86660 */
+
+#pragma omp declare target
+int v[20];
+
+void
+foo (void)
+{
+ if (v[7] != 2)
+ __builtin_abort ();
+ v[7] = 1;
+}
+#pragma omp end declare target
+
+int
+main ()
+{
+ v[5] = 8;
+ v[7] = 2;
+ #pragma omp target map (always, tofrom: v)
+ {
+ foo ();
+ v[5] = 3;
+ }
+ if (v[7] != 1 || v[5] != 3)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pr89002.c b/libgomp/testsuite/libgomp.c/pr89002.c
new file mode 100644
index 00000000000..6d1b16405f2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pr89002.c
@@ -0,0 +1,43 @@
+/* PR middle-end/89002 */
+
+extern void abort (void);
+
+int
+foo (int x)
+{
+ int a;
+ int *p = &a;
+
+#pragma omp taskloop lastprivate (a)
+ for (a = 0; a < x; ++a)
+ ;
+ return *p;
+}
+
+int
+bar (int x)
+{
+ int a;
+ int *p = &a;
+
+#pragma omp parallel
+#pragma omp single
+#pragma omp taskloop lastprivate (a)
+ for (a = 0; a < x; ++a)
+ ;
+ return *p;
+}
+
+int
+main ()
+{
+#pragma omp parallel
+#pragma omp single
+ {
+ if (foo (4) != 4)
+ abort ();
+ }
+ if (bar (6) != 6)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pr90779.c b/libgomp/testsuite/libgomp.c/pr90779.c
new file mode 100644
index 00000000000..0dd1c105a38
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pr90779.c
@@ -0,0 +1,18 @@
+/* PR middle-end/90779 */
+
+extern void abort (void);
+
+int
+main ()
+{
+ int i, j;
+ for (i = 0; i < 2; ++i)
+ #pragma omp target map(from: j)
+ {
+ static int k = 5;
+ j = ++k;
+ }
+ if (j != 7)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pr90811.c b/libgomp/testsuite/libgomp.c/pr90811.c
new file mode 100644
index 00000000000..25b7d78c0ea
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pr90811.c
@@ -0,0 +1,29 @@
+/* PR target/90811 */
+
+int
+main ()
+{
+ long long a[100], b[100];
+ int i;
+ for (i = 0; i < 100; i++)
+ {
+ a[i] = i;
+ b[i] = i % 10;
+ }
+ #pragma omp target teams distribute parallel for simd map(tofrom: a[:100], b[:100])
+ for (i = 0; i < 100; i++)
+ {
+ long long c = 0;
+ const long long d[] = { 1, 3, 5, 7, 9 };
+ for (int j = 4; j >= 0; j--)
+ c = d[j] + b[i] * c;
+ a[i] += c;
+ }
+ for (i = 0; i < 100; i++)
+ {
+ const long long r[] = { 1, 26, 229, 976, 2849, 6646, 13381, 24284, 40801, 64594 };
+ if (a[i] != r[i % 10] + (i / 10 * 10))
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/private-1.c b/libgomp/testsuite/libgomp.c/private-1.c
index 1d3659b25fa..10c092a12c6 100644
--- a/libgomp/testsuite/libgomp.c/private-1.c
+++ b/libgomp/testsuite/libgomp.c/private-1.c
@@ -20,7 +20,7 @@ f1 (int i, int j, int k)
}
int v1 = 1, v2 = 2, v5 = 5;
-int err;
+int e;
void
f2 (void)
@@ -35,11 +35,11 @@ f2 (void)
#pragma omp parallel num_threads(1) firstprivate(v1, v2, v3, v4)
{
if (++v1 != 8 || ++v2 != 3 || ++v3 != 4 || ++v4 != 5 || ++v5 != 6)
- err = 1;
+ e = 1;
}
if (v1 != 7 || v2 != 2 || v3 != 3 || v4 != 4 || v5 != 6)
abort ();
- if (err)
+ if (e)
abort ();
}
}
diff --git a/libgomp/testsuite/libgomp.c/scan-1.c b/libgomp/testsuite/libgomp.c/scan-1.c
new file mode 100644
index 00000000000..dd34f33a694
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-1.c
@@ -0,0 +1,115 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-10.c b/libgomp/testsuite/libgomp.c/scan-10.c
new file mode 100644
index 00000000000..0005ce109b2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-10.c
@@ -0,0 +1,116 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+int r, a[1024], b[1024], x, y, z;
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for reduction (inscan, +:r) lastprivate (conditional: z) firstprivate (x) private (y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = r; if ((i & 1) == 0 && i < 937) z = r; }
+ #pragma omp scan exclusive(r)
+ { y = a[i]; r += y + x + 12; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s) firstprivate (x) private (y) lastprivate (z)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = s; b[i] = y + x + 12; }
+ #pragma omp scan exclusive(s)
+ { y = 2 * a[i]; s += y; z = y; }
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for reduction (inscan, +:r) firstprivate (x) lastprivate (x)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ { r += a[i] + x + 12; if (i == 1023) x = 29; }
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for reduction (inscan, +:s) lastprivate (conditional: x, y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = s; if ((a[i] & 1) == 0 && i < 829) y = a[i]; }
+ #pragma omp scan exclusive(s)
+ { s += 2 * a[i]; if ((a[i] & 1) == 1 && i < 825) x = a[i]; }
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ x = -12;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2 || x != -12 || z != b[936])
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023 || x != -12 || z != 2 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2 || x != 29)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023 || x != 823 || y != 828)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-11.c b/libgomp/testsuite/libgomp.c/scan-11.c
new file mode 100644
index 00000000000..3bc2d3a1d7c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-11.c
@@ -0,0 +1,119 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s) if (0)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r) simdlen(1)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-12.c b/libgomp/testsuite/libgomp.c/scan-12.c
new file mode 100644
index 00000000000..f769d17e8ca
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-12.c
@@ -0,0 +1,121 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, foo:r) simdlen (1)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd if (simd: 0) reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-13.c b/libgomp/testsuite/libgomp.c/scan-13.c
new file mode 100644
index 00000000000..9cf1623d262
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-13.c
@@ -0,0 +1,92 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+float r = 1.0f, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (float *a, float *b)
+{
+ #pragma omp for simd reduction (inscan, *:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r *= a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) float
+bar (void)
+{
+ float s = -__builtin_inff ();
+ #pragma omp parallel for simd reduction (inscan, max:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s = s > a[i] ? s : a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ float s = 1.0f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (i < 80)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 200)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else if (i < 280)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 380)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else
+ switch (i % 6)
+ {
+ case 0: a[i] = 0.25f; break;
+ case 1: a[i] = 2.0f; break;
+ case 2: a[i] = -1.0f; break;
+ case 3: a[i] = -4.0f; break;
+ case 4: a[i] = 0.5f; break;
+ case 5: a[i] = 1.0f; break;
+ default: a[i] = 0.0f; break;
+ }
+ b[i] = -19.0f;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r * 16384.0f != 0.125f)
+ abort ();
+ float m = -175.25f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s *= a[i];
+ if (b[i] != s)
+ abort ();
+ else
+ {
+ a[i] = m - ((i % 3) == 1 ? 2.0f : (i % 3) == 2 ? 4.0f : 0.0f);
+ b[i] = -231.75f;
+ m += 0.75f;
+ }
+ }
+ if (bar () != 592.0f)
+ abort ();
+ s = -__builtin_inff ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (s < a[i])
+ s = a[i];
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-14.c b/libgomp/testsuite/libgomp.c/scan-14.c
new file mode 100644
index 00000000000..3a20a75b2e9
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-14.c
@@ -0,0 +1,183 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+unsigned short r2, b2[1024];
+unsigned char r3, b3[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp for simd reduction (inscan, +:r, r2, r3) if (simd:0)
+ for (int i = 0; i < 1024; i++)
+ {
+ { r += a[i]; r2 += a[i]; r3 += a[i]; }
+ #pragma omp scan inclusive(r, r2, r3)
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ }
+}
+
+__attribute__((noipa)) int
+bar (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s, s2, s3) simdlen (1)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ s += 2 * a[i];
+ s2 += 2 * a[i];
+ s3 += 2 * a[i];
+ }
+ #pragma omp scan inclusive(s, s2, s3)
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r, r2, r3)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ r += a[i];
+ r2 += a[i];
+ r3 += a[i];
+ }
+ #pragma omp scan inclusive(r, r2, r3)
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ }
+}
+
+__attribute__((noipa)) int
+qux (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel for simd reduction (inscan, +:s, s2, s3)
+ for (int i = 0; i < 1024; i++)
+ {
+ { s += 2 * a[i]; s2 += 2 * a[i]; s3 += 2 * a[i]; }
+ #pragma omp scan inclusive(s, s2, s3)
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ unsigned short s2;
+ unsigned char s3;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ }
+ if (bar (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ }
+ }
+ r = 0;
+ r2 = 0;
+ r3 = 0;
+ baz (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ }
+ s2 = 0;
+ s3 = 0;
+ if (qux (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-15.c b/libgomp/testsuite/libgomp.c/scan-15.c
new file mode 100644
index 00000000000..c0c6dfd3b99
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-15.c
@@ -0,0 +1,119 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd simdlen (1) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd if (simd: 0) reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-16.c b/libgomp/testsuite/libgomp.c/scan-16.c
new file mode 100644
index 00000000000..8b816781dd8
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-16.c
@@ -0,0 +1,121 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd simdlen (1) reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd if (simd: 0) reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-17.c b/libgomp/testsuite/libgomp.c/scan-17.c
new file mode 100644
index 00000000000..57e4390462a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-17.c
@@ -0,0 +1,90 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+float r = 1.0f, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (float *a, float *b)
+{
+ #pragma omp for simd reduction (inscan, *:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r *= a[i];
+ }
+}
+
+__attribute__((noipa)) float
+bar (void)
+{
+ float s = -__builtin_inff ();
+ #pragma omp parallel for simd reduction (inscan, max:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s = s > a[i] ? s : a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ float s = 1.0f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (i < 80)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 200)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else if (i < 280)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 380)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else
+ switch (i % 6)
+ {
+ case 0: a[i] = 0.25f; break;
+ case 1: a[i] = 2.0f; break;
+ case 2: a[i] = -1.0f; break;
+ case 3: a[i] = -4.0f; break;
+ case 4: a[i] = 0.5f; break;
+ case 5: a[i] = 1.0f; break;
+ default: a[i] = 0.0f; break;
+ }
+ b[i] = -19.0f;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r * 16384.0f != 0.125f)
+ abort ();
+ float m = -175.25f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -231.75f;
+ s *= a[i];
+ a[i] = m - ((i % 3) == 1 ? 2.0f : (i % 3) == 2 ? 4.0f : 0.0f);
+ m += 0.75f;
+ }
+ if (bar () != 592.0f)
+ abort ();
+ s = -__builtin_inff ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ if (s < a[i])
+ s = a[i];
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-18.c b/libgomp/testsuite/libgomp.c/scan-18.c
new file mode 100644
index 00000000000..ae467fc7bdb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-18.c
@@ -0,0 +1,183 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+unsigned short r2, b2[1024];
+unsigned char r3, b3[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp for simd reduction (inscan, +:r, r2, r3)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ #pragma omp scan exclusive(r, r2, r3)
+ { r += a[i]; r2 += a[i]; r3 += a[i]; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s, s2, s3)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ #pragma omp scan exclusive(s, s2, s3)
+ {
+ s += 2 * a[i];
+ s2 += 2 * a[i];
+ s3 += 2 * a[i];
+ }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r, r2, r3) if (simd: 0)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ #pragma omp scan exclusive(r, r2, r3)
+ {
+ r += a[i];
+ r2 += a[i];
+ r3 += a[i];
+ }
+ }
+}
+
+__attribute__((noipa)) int
+qux (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel for simd simdlen (1) reduction (inscan, +:s, s2, s3)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ #pragma omp scan exclusive(s, s2, s3)
+ { s += 2 * a[i]; s2 += 2 * a[i]; s3 += 2 * a[i]; }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ unsigned short s2;
+ unsigned char s3;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ s += i;
+ }
+ if (bar (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ }
+ s += 2 * i;
+ }
+ r = 0;
+ r2 = 0;
+ r3 = 0;
+ baz (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ s += i;
+ }
+ s2 = 0;
+ s3 = 0;
+ if (qux (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-19.c b/libgomp/testsuite/libgomp.c/scan-19.c
new file mode 100644
index 00000000000..b4205012902
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-19.c
@@ -0,0 +1,120 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024], x, y, z;
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, +:r) lastprivate (conditional: z) firstprivate (x) private (y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = a[i]; r += y + x + 12; }
+ #pragma omp scan inclusive(r)
+ { b[i] = r; if ((i & 1) == 0 && i < 937) z = r; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s) firstprivate (x) private (y) lastprivate (z)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = 2 * a[i]; s += y; z = y; }
+ #pragma omp scan inclusive(s)
+ { y = s; b[i] = y + x + 12; }
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r) firstprivate (x) lastprivate (x) if (simd: 0)
+ for (int i = 0; i < 1024; i++)
+ {
+ { r += a[i]; if (i == 1023) x = 29; }
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd simdlen (1) reduction (inscan, +:s) lastprivate (conditional: x, y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { s += 2 * a[i]; if ((a[i] & 1) == 1 && i < 825) x = a[i]; }
+ #pragma omp scan inclusive(s)
+ { b[i] = s; if ((a[i] & 1) == 0 && i < 829) y = a[i]; }
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ x = -12;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2 || x != -12 || z != b[936])
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023 || x != -12 || z != 2 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2 || x != 29)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023 || x != 823 || y != 828)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-2.c b/libgomp/testsuite/libgomp.c/scan-2.c
new file mode 100644
index 00000000000..476bbedfd60
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-2.c
@@ -0,0 +1,117 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-20.c b/libgomp/testsuite/libgomp.c/scan-20.c
new file mode 100644
index 00000000000..3ef88d78d9d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-20.c
@@ -0,0 +1,120 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024], x, y, z;
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, +:r) lastprivate (conditional: z) firstprivate (x) private (y) simdlen(1)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = r; if ((i & 1) == 0 && i < 937) z = r; }
+ #pragma omp scan exclusive(r)
+ { y = a[i]; r += y + x + 12; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s) firstprivate (x) private (y) lastprivate (z) if (0)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = s; b[i] = y + x + 12; }
+ #pragma omp scan exclusive(s)
+ { y = 2 * a[i]; s += y; z = y; }
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r) firstprivate (x) lastprivate (x)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ { r += a[i]; if (i == 1023) x = 29; }
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd reduction (inscan, +:s) lastprivate (conditional: x, y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = s; if ((a[i] & 1) == 0 && i < 829) y = a[i]; }
+ #pragma omp scan exclusive(s)
+ { s += 2 * a[i]; if ((a[i] & 1) == 1 && i < 825) x = a[i]; }
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ x = -12;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2 || x != -12 || z != b[936])
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023 || x != -12 || z != 2 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2 || x != 29)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023 || x != 823 || y != 828)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-21.c b/libgomp/testsuite/libgomp.c/scan-21.c
new file mode 100644
index 00000000000..c531961ffe4
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-21.c
@@ -0,0 +1,6 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-require-effective-target avx_runtime } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details -msse2 -mno-sse3" } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" } } */
+
+#include "scan-13.c"
diff --git a/libgomp/testsuite/libgomp.c/scan-22.c b/libgomp/testsuite/libgomp.c/scan-22.c
new file mode 100644
index 00000000000..96fead7d54d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-22.c
@@ -0,0 +1,6 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-require-effective-target avx_runtime } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details -msse2 -mno-sse3" } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" } } */
+
+#include "scan-17.c"
diff --git a/libgomp/testsuite/libgomp.c/scan-3.c b/libgomp/testsuite/libgomp.c/scan-3.c
new file mode 100644
index 00000000000..2e1fcadba04
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-3.c
@@ -0,0 +1,88 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+float r = 1.0f, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (float *a, float *b)
+{
+ #pragma omp for reduction (inscan, *:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r *= a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) float
+bar (void)
+{
+ float s = -__builtin_inff ();
+ #pragma omp parallel for reduction (inscan, max:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s = s > a[i] ? s : a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ float s = 1.0f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (i < 80)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 200)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else if (i < 280)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 380)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else
+ switch (i % 6)
+ {
+ case 0: a[i] = 0.25f; break;
+ case 1: a[i] = 2.0f; break;
+ case 2: a[i] = -1.0f; break;
+ case 3: a[i] = -4.0f; break;
+ case 4: a[i] = 0.5f; break;
+ case 5: a[i] = 1.0f; break;
+ default: a[i] = 0.0f; break;
+ }
+ b[i] = -19.0f;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r * 16384.0f != 0.125f)
+ abort ();
+ float m = -175.25f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s *= a[i];
+ if (b[i] != s)
+ abort ();
+ else
+ {
+ a[i] = m - ((i % 3) == 1 ? 2.0f : (i % 3) == 2 ? 4.0f : 0.0f);
+ b[i] = -231.75f;
+ m += 0.75f;
+ }
+ }
+ if (bar () != 592.0f)
+ abort ();
+ s = -__builtin_inff ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (s < a[i])
+ s = a[i];
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-4.c b/libgomp/testsuite/libgomp.c/scan-4.c
new file mode 100644
index 00000000000..b1e999352fa
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-4.c
@@ -0,0 +1,179 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+unsigned short r2, b2[1024];
+unsigned char r3, b3[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp for reduction (inscan, +:r, r2, r3)
+ for (int i = 0; i < 1024; i++)
+ {
+ { r += a[i]; r2 += a[i]; r3 += a[i]; }
+ #pragma omp scan inclusive(r, r2, r3)
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ }
+}
+
+__attribute__((noipa)) int
+bar (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s, s2, s3)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ s += 2 * a[i];
+ s2 += 2 * a[i];
+ s3 += 2 * a[i];
+ }
+ #pragma omp scan inclusive(s, s2, s3)
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp parallel for reduction (inscan, +:r, r2, r3)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ r += a[i];
+ r2 += a[i];
+ r3 += a[i];
+ }
+ #pragma omp scan inclusive(r, r2, r3)
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ }
+}
+
+__attribute__((noipa)) int
+qux (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel for reduction (inscan, +:s, s2, s3)
+ for (int i = 0; i < 1024; i++)
+ {
+ { s += 2 * a[i]; s2 += 2 * a[i]; s3 += 2 * a[i]; }
+ #pragma omp scan inclusive(s, s2, s3)
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ unsigned short s2;
+ unsigned char s3;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ }
+ if (bar (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ }
+ }
+ r = 0;
+ r2 = 0;
+ r3 = 0;
+ baz (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ }
+ s2 = 0;
+ s3 = 0;
+ if (qux (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-5.c b/libgomp/testsuite/libgomp.c/scan-5.c
new file mode 100644
index 00000000000..c50418264ef
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-5.c
@@ -0,0 +1,115 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-6.c b/libgomp/testsuite/libgomp.c/scan-6.c
new file mode 100644
index 00000000000..9434ebb2b5a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-6.c
@@ -0,0 +1,117 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-7.c b/libgomp/testsuite/libgomp.c/scan-7.c
new file mode 100644
index 00000000000..20b7071e8f6
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-7.c
@@ -0,0 +1,86 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+float r = 1.0f, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (float *a, float *b)
+{
+ #pragma omp for reduction (inscan, *:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r *= a[i];
+ }
+}
+
+__attribute__((noipa)) float
+bar (void)
+{
+ float s = -__builtin_inff ();
+ #pragma omp parallel for reduction (inscan, max:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s = s > a[i] ? s : a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ float s = 1.0f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (i < 80)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 200)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else if (i < 280)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 380)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else
+ switch (i % 6)
+ {
+ case 0: a[i] = 0.25f; break;
+ case 1: a[i] = 2.0f; break;
+ case 2: a[i] = -1.0f; break;
+ case 3: a[i] = -4.0f; break;
+ case 4: a[i] = 0.5f; break;
+ case 5: a[i] = 1.0f; break;
+ default: a[i] = 0.0f; break;
+ }
+ b[i] = -19.0f;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r * 16384.0f != 0.125f)
+ abort ();
+ float m = -175.25f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -231.75f;
+ s *= a[i];
+ a[i] = m - ((i % 3) == 1 ? 2.0f : (i % 3) == 2 ? 4.0f : 0.0f);
+ m += 0.75f;
+ }
+ if (bar () != 592.0f)
+ abort ();
+ s = -__builtin_inff ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ if (s < a[i])
+ s = a[i];
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-8.c b/libgomp/testsuite/libgomp.c/scan-8.c
new file mode 100644
index 00000000000..f09c85c36e7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-8.c
@@ -0,0 +1,179 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+unsigned short r2, b2[1024];
+unsigned char r3, b3[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp for reduction (inscan, +:r, r2, r3)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ #pragma omp scan exclusive(r, r2, r3)
+ { r += a[i]; r2 += a[i]; r3 += a[i]; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s, s2, s3)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ #pragma omp scan exclusive(s, s2, s3)
+ {
+ s += 2 * a[i];
+ s2 += 2 * a[i];
+ s3 += 2 * a[i];
+ }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp parallel for reduction (inscan, +:r, r2, r3)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ #pragma omp scan exclusive(r, r2, r3)
+ {
+ r += a[i];
+ r2 += a[i];
+ r3 += a[i];
+ }
+ }
+}
+
+__attribute__((noipa)) int
+qux (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel for reduction (inscan, +:s, s2, s3)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ #pragma omp scan exclusive(s, s2, s3)
+ { s += 2 * a[i]; s2 += 2 * a[i]; s3 += 2 * a[i]; }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ unsigned short s2;
+ unsigned char s3;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ s += i;
+ }
+ if (bar (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ }
+ s += 2 * i;
+ }
+ r = 0;
+ r2 = 0;
+ r3 = 0;
+ baz (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ s += i;
+ }
+ s2 = 0;
+ s3 = 0;
+ if (qux (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-9.c b/libgomp/testsuite/libgomp.c/scan-9.c
new file mode 100644
index 00000000000..822752306ae
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-9.c
@@ -0,0 +1,116 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+int r, a[1024], b[1024], x, y, z;
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for reduction (inscan, +:r) lastprivate (conditional: z) firstprivate (x) private (y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = a[i]; r += y + x + 12; }
+ #pragma omp scan inclusive(r)
+ { b[i] = r; if ((i & 1) == 0 && i < 937) z = r; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s) firstprivate (x) private (y) lastprivate (z)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = 2 * a[i]; s += y; z = y; }
+ #pragma omp scan inclusive(s)
+ { y = s; b[i] = y + x + 12; }
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for reduction (inscan, +:r) firstprivate (x) lastprivate (x)
+ for (int i = 0; i < 1024; i++)
+ {
+ { r += a[i] + x + 12; if (i == 1023) x = 29; }
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for reduction (inscan, +:s) lastprivate (conditional: x, y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { s += 2 * a[i]; if ((a[i] & 1) == 1 && i < 825) x = a[i]; }
+ #pragma omp scan inclusive(s)
+ { b[i] = s; if ((a[i] & 1) == 0 && i < 829) y = a[i]; }
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ x = -12;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2 || x != -12 || z != b[936])
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023 || x != -12 || z != 2 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2 || x != 29)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023 || x != 823 || y != 828)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/sort-1.c b/libgomp/testsuite/libgomp.c/sort-1.c
index c24b1c73c79..3ef53d061cd 100644
--- a/libgomp/testsuite/libgomp.c/sort-1.c
+++ b/libgomp/testsuite/libgomp.c/sort-1.c
@@ -1,5 +1,5 @@
/* Test and benchmark of a couple of parallel sorting algorithms.
- Copyright (C) 2008-2018 Free Software Foundation, Inc.
+ Copyright (C) 2008-2019 Free Software Foundation, Inc.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
diff --git a/libgomp/testsuite/libgomp.c/target-18.c b/libgomp/testsuite/libgomp.c/target-18.c
index cbacaf6a77a..dd511fb98cb 100644
--- a/libgomp/testsuite/libgomp.c/target-18.c
+++ b/libgomp/testsuite/libgomp.c/target-18.c
@@ -1,9 +1,11 @@
extern void abort (void);
+struct S { int e, f; };
void
foo (int n)
{
- int a[4] = { 0, 1, 2, 3 }, b[n];
+ int a[4] = { 0, 1, 2, 3 }, b[n], c = 4;
+ struct S d = { 5, 6 };
int *p = a + 1, i, err;
for (i = 0; i < n; i++)
b[i] = 9 + i;
@@ -21,7 +23,7 @@ foo (int n)
for (i = 0; i < 4; i++)
a[i] = 23 + i;
#pragma omp target data map(to:a)
- #pragma omp target data use_device_ptr(a) map(from:err)
+ #pragma omp target data use_device_addr(a) map(from:err)
#pragma omp target is_device_ptr(a) private(i) map(from:err)
{
err = 0;
@@ -32,7 +34,7 @@ foo (int n)
if (err)
abort ();
#pragma omp target data map(to:b)
- #pragma omp target data use_device_ptr(b) map(from:err)
+ #pragma omp target data use_device_addr(b) map(from:err)
#pragma omp target is_device_ptr(b) private(i) map(from:err)
{
err = 0;
@@ -42,6 +44,28 @@ foo (int n)
}
if (err)
abort ();
+ #pragma omp target data map(to:c)
+ #pragma omp target data use_device_addr(c) map(from:err)
+ {
+ int *q = &c;
+ #pragma omp target is_device_ptr(q) map(from:err)
+ {
+ err = *q != 4;
+ }
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to:d)
+ #pragma omp target data use_device_addr(d) map(from:err)
+ {
+ struct S *r = &d;
+ #pragma omp target is_device_ptr(r) map(from:err)
+ {
+ err = r->e != 5 || r->f != 6;
+ }
+ }
+ if (err)
+ abort ();
}
int
diff --git a/libgomp/testsuite/libgomp.c/target-37.c b/libgomp/testsuite/libgomp.c/target-37.c
new file mode 100644
index 00000000000..b3cc6a25215
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/target-37.c
@@ -0,0 +1,71 @@
+extern void abort (void);
+struct S { int e, f; };
+
+void
+foo (int n)
+{
+ int a[4] = { 0, 1, 2, 3 }, b[n], c = 4;
+ struct S d = { 5, 6 };
+ int *p = a + 1, i, err;
+ for (i = 0; i < n; i++)
+ b[i] = 9 + i;
+ #pragma omp target data use_device_ptr(p) map(from:err) map(to:a)
+ #pragma omp target is_device_ptr(p) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 4; i++)
+ if (p[i - 1] != i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ for (i = 0; i < 4; i++)
+ a[i] = 23 + i;
+ #pragma omp target data map(to:a) use_device_addr(a) map(from:err)
+ #pragma omp target is_device_ptr(a) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 4; i++)
+ if (a[i] != 23 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data use_device_addr(b) map(from:err) map(to:b)
+ #pragma omp target is_device_ptr(b) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 4; i++)
+ if (b[i] != 9 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to:c) use_device_addr(c) map(from:err)
+ {
+ int *q = &c;
+ #pragma omp target is_device_ptr(q) map(from:err)
+ {
+ err = *q != 4;
+ }
+ }
+ if (err)
+ abort ();
+ #pragma omp target data use_device_addr(d) map(to:d) map(from:err)
+ {
+ struct S *r = &d;
+ #pragma omp target is_device_ptr(r) map(from:err)
+ {
+ err = r->e != 5 || r->f != 6;
+ }
+ }
+ if (err)
+ abort ();
+}
+
+int
+main ()
+{
+ foo (9);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/target-print-1.c b/libgomp/testsuite/libgomp.c/target-print-1.c
new file mode 100644
index 00000000000..5857b875ced
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/target-print-1.c
@@ -0,0 +1,17 @@
+/* Ensure that printf on the offload device works. */
+
+/* { dg-do run } */
+/* { dg-output "The answer is 42(\n|\r\n|\r)+" } */
+
+#include <stdio.h>
+
+int var = 42;
+
+int
+main ()
+{
+#pragma omp target
+ {
+ printf ("The answer is %d\n", var);
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c/task-1.c b/libgomp/testsuite/libgomp.c/task-1.c
index 66f58a29b87..d17c3c61c2f 100644
--- a/libgomp/testsuite/libgomp.c/task-1.c
+++ b/libgomp/testsuite/libgomp.c/task-1.c
@@ -20,7 +20,7 @@ f1 (int i, int j, int k)
}
int v1 = 1, v2 = 2, v5 = 5;
-int err;
+int e;
void
f2 (void)
@@ -35,12 +35,12 @@ f2 (void)
#pragma omp task
{
if (++v1 != 8 || ++v2 != 3 || ++v3 != 4 || ++v4 != 5 || ++v5 != 6)
- err = 1;
+ e = 1;
}
#pragma omp taskwait
if (v1 != 7 || v2 != 2 || v3 != 3 || v4 != 4 || v5 != 6)
abort ();
- if (err)
+ if (e)
abort ();
}
}
diff --git a/libgomp/testsuite/libgomp.c/task-5.c b/libgomp/testsuite/libgomp.c/task-5.c
index b1523712760..bf44ddd012b 100644
--- a/libgomp/testsuite/libgomp.c/task-5.c
+++ b/libgomp/testsuite/libgomp.c/task-5.c
@@ -3,42 +3,42 @@
#include <omp.h>
#include <stdlib.h>
-int err;
+int serr;
int
main ()
{
int e;
-#pragma omp parallel shared(err)
+#pragma omp parallel shared(serr)
{
if (omp_in_final ())
#pragma omp atomic write
- err = 1;
- #pragma omp task if (0) shared(err)
+ serr = 1;
+ #pragma omp task if (0) shared(serr)
{
if (omp_in_final ())
#pragma omp atomic write
- err = 1;
- #pragma omp task if (0) shared(err)
+ serr = 1;
+ #pragma omp task if (0) shared(serr)
if (omp_in_final ())
#pragma omp atomic write
- err = 1;
+ serr = 1;
}
- #pragma omp task final (1) shared(err)
+ #pragma omp task final (1) shared(serr)
{
if (!omp_in_final ())
#pragma omp atomic write
- err = 1;
+ serr = 1;
#pragma omp taskyield
#pragma omp taskwait
- #pragma omp task shared(err)
+ #pragma omp task shared(serr)
if (!omp_in_final ())
#pragma omp atomic write
- err = 1;
+ serr = 1;
}
}
#pragma omp atomic read
- e = err;
+ e = serr;
if (e)
abort ();
return 0;
diff --git a/libgomp/testsuite/libgomp.c/task-reduction-1.c b/libgomp/testsuite/libgomp.c/task-reduction-1.c
new file mode 100644
index 00000000000..224d995bd13
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/task-reduction-1.c
@@ -0,0 +1,137 @@
+typedef __SIZE_TYPE__ size_t;
+extern void abort (void);
+
+void
+bar (int *a, int *b, int *c, int (*d)[2], int (*e)[4], size_t n, int f[1][n], int g[1][n * 2])
+{
+ #pragma omp task in_reduction (*: a[:n], b[3:n], c[n:n], d[0][:n], e[0][1:n], f[0][:], g[0][1:n])
+ {
+ a[0] *= 12;
+ a[1] *= 13;
+ b[3] *= 14;
+ b[4] *= 15;
+ c[n] *= 16;
+ c[n + 1] *= 17;
+ d[0][0] *= 18;
+ d[0][1] *= 19;
+ e[0][1] *= 20;
+ e[0][2] *= 21;
+ f[0][0] *= 22;
+ f[0][1] *= 23;
+ g[0][1] *= 24;
+ g[0][2] *= 25;
+ }
+}
+
+void
+foo (size_t n, void *x, void *y, int f[1][n], int g[1][n * 2])
+{
+ int a[n], b[n + 3], c[2 * n];
+ int (*d)[n] = (int (*)[n]) x;
+ int (*e)[n * 2] = (int (*)[n * 2]) y;
+ int i;
+ for (i = 0; i < n; i++)
+ {
+ a[i] = 1;
+ b[i + 3] = 1;
+ c[i + n] = 1;
+ d[0][i] = 1;
+ e[0][i + 1] = 1;
+ f[0][i] = 1;
+ g[0][i + 1] = 1;
+ }
+ #pragma omp taskgroup task_reduction (*: a, b[3:n], c[n:n], d[0][:n], e[0][1:n], f[0][:], g[0][1:n])
+ {
+ bar (a, b, c, (int (*)[2]) d, (int (*)[4]) e, n, f, g);
+ #pragma omp task in_reduction (*: a, b[3:n], c[n:n], d[0][:n], e[0][1:n], f[0][:], g[0][1:n])
+ {
+ a[0] *= 2;
+ a[1] *= 3;
+ b[3] *= 4;
+ b[4] *= 5;
+ c[n] *= 6;
+ c[n + 1] *= 7;
+ d[0][0] *= 8;
+ d[0][1] *= 9;
+ e[0][1] *= 10;
+ e[0][2] *= 11;
+ f[0][0] *= 12;
+ f[0][1] *= 13;
+ g[0][1] *= 14;
+ g[0][2] *= 15;
+ }
+ n = 0;
+ }
+ if (a[0] != 24 || a[1] != 39 || b[3] != 56 || b[4] != 75)
+ abort ();
+ if (c[2] != 96 || c[3] != 119 || d[0][0] != 144 || d[0][1] != 171)
+ abort ();
+ if (e[0][1] != 200 || e[0][2] != 231 || f[0][0] != 264 || f[0][1] != 299)
+ abort ();
+ if (g[0][1] != 336 || g[0][2] != 375)
+ abort ();
+}
+
+void
+baz (size_t n, void *x, void *y, int f[1][n], int g[1][n * 2])
+{
+ int a[n], b[n + 3], c[2 * n];
+ int (*d)[n] = (int (*)[n]) x;
+ int (*e)[n * 2] = (int (*)[n * 2]) y;
+ int i;
+ for (i = 0; i < n; i++)
+ {
+ a[i] = 1;
+ b[i + 3] = 1;
+ c[i + n] = 1;
+ d[0][i] = 1;
+ e[0][i + 1] = 1;
+ f[0][i] = 1;
+ g[0][i + 1] = 1;
+ }
+ #pragma omp parallel num_threads(2)
+ #pragma omp master
+ #pragma omp taskgroup task_reduction (*: a, b[3:n], c[n:n], d[0][:n], e[0][1:n], f[0][:], g[0][1:n])
+ {
+ bar (a, b, c, (int (*)[2]) d, (int (*)[4]) e, n, f, g);
+ #pragma omp task in_reduction (*: a, b[3:n], c[n:n], d[0][:n], e[0][1:n], f[0][:], g[0][1:n])
+ {
+ a[0] *= 2;
+ a[1] *= 3;
+ b[3] *= 4;
+ b[4] *= 5;
+ c[n] *= 6;
+ c[n + 1] *= 7;
+ d[0][0] *= 8;
+ d[0][1] *= 9;
+ e[0][1] *= 10;
+ e[0][2] *= 11;
+ f[0][0] *= 12;
+ f[0][1] *= 13;
+ g[0][1] *= 14;
+ g[0][2] *= 15;
+ }
+ n = 0;
+ }
+ if (a[0] != 24 || a[1] != 39 || b[3] != 56 || b[4] != 75)
+ abort ();
+ if (c[2] != 96 || c[3] != 119 || d[0][0] != 144 || d[0][1] != 171)
+ abort ();
+ if (e[0][1] != 200 || e[0][2] != 231 || f[0][0] != 264 || f[0][1] != 299)
+ abort ();
+ if (g[0][1] != 336 || g[0][2] != 375)
+ abort ();
+}
+
+int
+main ()
+{
+ int d[1][2], e[1][4], f[1][2], g[1][4];
+ volatile int two;
+ two = 2;
+ #pragma omp parallel num_threads (2)
+ #pragma omp master
+ foo (two, (void *) d, (void *) e, f, g);
+ baz (two, (void *) d, (void *) e, f, g);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/task-reduction-2.c b/libgomp/testsuite/libgomp.c/task-reduction-2.c
new file mode 100644
index 00000000000..f5d48c36873
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/task-reduction-2.c
@@ -0,0 +1,86 @@
+typedef __SIZE_TYPE__ size_t;
+extern void abort (void);
+
+void
+bar (int *a, int *b, int *c, int (*d)[2], int (*e)[4], size_t n, int f[1][n], int g[1][n * 2])
+{
+ #pragma omp task in_reduction (*: a[:n], b[3:n], c[n:n], d[0][:n], e[0][1:n], f[0][:], g[0][1:n])
+ {
+ a[0] *= 12;
+ a[1] *= 13;
+ b[3] *= 14;
+ b[4] *= 15;
+ c[n] *= 16;
+ c[n + 1] *= 17;
+ d[0][0] *= 18;
+ d[0][1] *= 19;
+ e[0][1] *= 20;
+ e[0][2] *= 21;
+ f[0][0] *= 22;
+ f[0][1] *= 23;
+ g[0][1] *= 24;
+ g[0][2] *= 25;
+ }
+}
+
+void
+baz (size_t n, void *x, void *y, int f[1][n], int g[1][n * 2])
+{
+ int a[n], b[n + 3], c[2 * n];
+ int (*d)[n] = (int (*)[n]) x;
+ int (*e)[n * 2] = (int (*)[n * 2]) y;
+ int i;
+ for (i = 0; i < n; i++)
+ {
+ a[i] = 1;
+ b[i + 3] = 1;
+ c[i + n] = 1;
+ d[0][i] = 1;
+ e[0][i + 1] = 1;
+ f[0][i] = 1;
+ g[0][i + 1] = 1;
+ }
+ #pragma omp parallel num_threads(2) firstprivate (n) \
+ reduction (task, *: a, b[3:n], c[n:n], d[0][:n], e[0][1:n], f[0][:], g[0][1:n])
+ {
+ #pragma omp master
+ bar (a, b, c, (int (*)[2]) d, (int (*)[4]) e, n, f, g);
+ #pragma omp master
+ #pragma omp task in_reduction (*: a, b[3:n], c[n:n], d[0][:n], e[0][1:n], f[0][:], g[0][1:n])
+ {
+ a[0] *= 2;
+ a[1] *= 3;
+ b[3] *= 4;
+ b[4] *= 5;
+ c[n] *= 6;
+ c[n + 1] *= 7;
+ d[0][0] *= 8;
+ d[0][1] *= 9;
+ e[0][1] *= 10;
+ e[0][2] *= 11;
+ f[0][0] *= 12;
+ f[0][1] *= 13;
+ g[0][1] *= 14;
+ g[0][2] *= 15;
+ }
+ n = 0;
+ }
+ if (a[0] != 24 || a[1] != 39 || b[3] != 56 || b[4] != 75)
+ abort ();
+ if (c[2] != 96 || c[3] != 119 || d[0][0] != 144 || d[0][1] != 171)
+ abort ();
+ if (e[0][1] != 200 || e[0][2] != 231 || f[0][0] != 264 || f[0][1] != 299)
+ abort ();
+ if (g[0][1] != 336 || g[0][2] != 375)
+ abort ();
+}
+
+int
+main ()
+{
+ int d[1][2], e[1][4], f[1][2], g[1][4];
+ volatile int two;
+ two = 2;
+ baz (two, (void *) d, (void *) e, f, g);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/task-reduction-3.c b/libgomp/testsuite/libgomp.c/task-reduction-3.c
new file mode 100644
index 00000000000..f912bd9569b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/task-reduction-3.c
@@ -0,0 +1,60 @@
+extern void abort (void);
+
+int
+foo (void)
+{
+ int i = -1, j = -1, k;
+ void nested (void) { i++; j++; }
+ nested ();
+ #pragma omp taskgroup task_reduction (+: i)
+ {
+ #pragma omp task in_reduction (+: i)
+ i++;
+ #pragma omp task in_reduction (+: i)
+ i += 6;
+ }
+ #pragma omp taskloop reduction (+: j)
+ for (k = 0; k < 2; k++)
+ {
+ j += 5;
+ #pragma omp task in_reduction (+: j)
+ j += 31;
+ }
+ return i + j;
+}
+
+int
+bar (void)
+{
+ int i = 0, j = 0;
+ void nested (void)
+ {
+ int k;
+ #pragma omp taskgroup task_reduction (+: i)
+ {
+ #pragma omp task in_reduction (+: i)
+ i++;
+ #pragma omp task in_reduction (+: i)
+ i += 7;
+ }
+ #pragma omp taskloop reduction (+: j)
+ for (k = 0; k < 2; k++)
+ {
+ j += 21;
+ #pragma omp task in_reduction (+: j)
+ j += 8;
+ }
+ }
+ nested ();
+ return i + j;
+}
+
+int
+main ()
+{
+ if (foo () != (1 + 6 + (5 + 31) * 2))
+ abort ();
+ if (bar () != (1 + 7 + (21 + 8) * 2))
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/teams-1.c b/libgomp/testsuite/libgomp.c/teams-1.c
new file mode 100644
index 00000000000..c5df8371b9e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/teams-1.c
@@ -0,0 +1,27 @@
+#include <omp.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+ #pragma omp teams thread_limit (2)
+ {
+ if (omp_in_parallel ()
+ || omp_get_level () != 0
+ || omp_get_ancestor_thread_num (0) != 0
+ || omp_get_ancestor_thread_num (1) != -1)
+ abort ();
+ omp_set_dynamic (0);
+ omp_set_nested (1);
+ #pragma omp parallel num_threads (2)
+ {
+ if (!omp_in_parallel ()
+ || omp_get_level () != 1
+ || omp_get_ancestor_thread_num (0) != 0
+ || omp_get_ancestor_thread_num (1) != omp_get_thread_num ()
+ || omp_get_ancestor_thread_num (2) != -1)
+ abort ();
+ }
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/teams-2.c b/libgomp/testsuite/libgomp.c/teams-2.c
new file mode 100644
index 00000000000..2ddf50875c5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/teams-2.c
@@ -0,0 +1,123 @@
+#include <omp.h>
+#include <stdlib.h>
+
+__attribute__((noinline))
+void
+foo (int x, int y, int z, int *a, int *b)
+{
+ if (x == 0)
+ {
+ int i, j;
+ for (i = 0; i < 64; i++)
+ #pragma omp parallel for shared (a, b)
+ for (j = 0; j < 32; j++)
+ foo (3, i, j, a, b);
+ }
+ else if (x == 1)
+ {
+ int i, j;
+ #pragma omp distribute dist_schedule (static, 1)
+ for (i = 0; i < 64; i++)
+ #pragma omp parallel for shared (a, b)
+ for (j = 0; j < 32; j++)
+ foo (3, i, j, a, b);
+ }
+ else if (x == 2)
+ {
+ int j;
+ #pragma omp parallel for shared (a, b)
+ for (j = 0; j < 32; j++)
+ foo (3, y, j, a, b);
+ }
+ else
+ {
+ #pragma omp atomic
+ b[y] += z;
+ #pragma omp atomic
+ *a += 1;
+ }
+}
+
+__attribute__((noinline))
+int
+bar (int x, int y, int z)
+{
+ int a, b[64], i;
+ a = 8;
+ for (i = 0; i < 64; i++)
+ b[i] = i;
+ foo (x, y, z, &a, b);
+ if (x == 0)
+ {
+ if (a != 8 + 64 * 32)
+ return 1;
+ for (i = 0; i < 64; i++)
+ if (b[i] != i + 31 * 32 / 2)
+ return 1;
+ }
+ else if (x == 1)
+ {
+ int c = omp_get_num_teams ();
+ int d = omp_get_team_num ();
+ int e = d;
+ int f = 0;
+ for (i = 0; i < 64; i++)
+ if (i == e)
+ {
+ if (b[i] != i + 31 * 32 / 2)
+ return 1;
+ f++;
+ e = e + c;
+ }
+ else if (b[i] != i)
+ return 1;
+ if (a < 8 || a > 8 + f * 32)
+ return 1;
+ }
+ else if (x == 2)
+ {
+ if (a != 8 + 32)
+ return 1;
+ for (i = 0; i < 64; i++)
+ if (b[i] != i + (i == y ? 31 * 32 / 2 : 0))
+ return 1;
+ }
+ else if (x == 3)
+ {
+ if (a != 8 + 1)
+ return 1;
+ for (i = 0; i < 64; i++)
+ if (b[i] != i + (i == y ? z : 0))
+ return 1;
+ }
+ return 0;
+}
+
+int
+main ()
+{
+ int i, j, err = 0;
+ #pragma omp teams reduction(+:err)
+ err += bar (0, 0, 0);
+ if (err)
+ abort ();
+ #pragma omp teams reduction(+:err)
+ err += bar (1, 0, 0);
+ if (err)
+ abort ();
+ #pragma omp teams reduction(+:err)
+ #pragma omp distribute
+ for (i = 0; i < 64; i++)
+ err += bar (2, i, 0);
+ if (err)
+ abort ();
+ #pragma omp teams reduction(+:err)
+ #pragma omp distribute
+ for (i = 0; i < 64; i++)
+ #pragma omp parallel for reduction(+:err)
+ for (j = 0; j < 32; j++)
+ err += bar (3, i, j);
+ if (err)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/thread-limit-4.c b/libgomp/testsuite/libgomp.c/thread-limit-4.c
new file mode 100644
index 00000000000..5642e6a87ba
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/thread-limit-4.c
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var OMP_THREAD_LIMIT "9" } */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <omp.h>
+
+int
+main ()
+{
+ if (omp_get_thread_limit () != 9)
+ return 0;
+ omp_set_dynamic (0);
+ #pragma omp parallel num_threads (8)
+ if (omp_get_num_threads () != 8)
+ abort ();
+ #pragma omp parallel num_threads (16)
+ if (omp_get_num_threads () > 9)
+ abort ();
+ #pragma omp teams thread_limit (6)
+ {
+ if (omp_get_thread_limit () > 6)
+ abort ();
+ if (omp_get_thread_limit () == 6)
+ {
+ omp_set_dynamic (0);
+ omp_set_nested (1);
+ #pragma omp parallel num_threads (3)
+ if (omp_get_num_threads () != 3)
+ abort ();
+ #pragma omp parallel num_threads (3)
+ if (omp_get_num_threads () != 3)
+ abort ();
+ #pragma omp parallel num_threads (8)
+ if (omp_get_num_threads () > 6)
+ abort ();
+ #pragma omp parallel num_threads (6)
+ if (omp_get_num_threads () != 6)
+ abort ();
+ int cnt = 0;
+ #pragma omp parallel num_threads (5)
+ #pragma omp parallel num_threads (5)
+ #pragma omp parallel num_threads (2)
+ {
+ int v;
+ #pragma omp atomic capture
+ v = ++cnt;
+ if (v > 6)
+ abort ();
+ usleep (10000);
+ #pragma omp atomic
+ --cnt;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/thread-limit-5.c b/libgomp/testsuite/libgomp.c/thread-limit-5.c
new file mode 100644
index 00000000000..d3d22b1e1a6
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/thread-limit-5.c
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <omp.h>
+
+int
+main ()
+{
+ #pragma omp teams thread_limit (1)
+ if (omp_get_thread_limit () != 1)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.fortran/aligned1.f03 b/libgomp/testsuite/libgomp.fortran/aligned1.f03
index 582ea03c029..a0b80d4555f 100644
--- a/libgomp/testsuite/libgomp.fortran/aligned1.f03
+++ b/libgomp/testsuite/libgomp.fortran/aligned1.f03
@@ -42,21 +42,21 @@
end do
call foo (p, q, c_loc (r(1)), s)
do i = 1, 1024
- if (p(i) /= i * i + 3 * i + 2) STOP 1
+ if (p(i) /= i * i + 3 * i + 2) stop 1
p(i) = i
end do
call bar (p, q, c_loc (r(1)), s)
do i = 1, 1024
- if (p(i) /= i * i + 3 * i + 2) STOP 2
+ if (p(i) /= i * i + 3 * i + 2) stop 2
end do
! Attempt to create 64-byte aligned allocatable
do i = 1, 64
allocate (c(1023 + i))
- if (iand (loc (c(1)), 63) == 0) exit
+ if (iand (int(loc(c(1)),8), 63_8) == 0) exit
deallocate (c)
allocate (b(i)%a(1023 + i))
allocate (c(1023 + i))
- if (iand (loc (c(1)), 63) == 0) exit
+ if (iand (int(loc(c(1)),8), 63_8) == 0) exit
deallocate (c)
end do
if (allocated (c)) then
@@ -65,7 +65,7 @@
end do
call baz (p, c)
do i = 1, 1024
- if (p(i) /= i * i + 5 * i + 2) STOP 3
+ if (p(i) /= i * i + 5 * i + 2) stop 3
end do
end if
end
diff --git a/libgomp/testsuite/libgomp.fortran/alloc-comp-1.f90 b/libgomp/testsuite/libgomp.fortran/alloc-comp-1.f90
index fac03653da0..ea76bc1e7e8 100644
--- a/libgomp/testsuite/libgomp.fortran/alloc-comp-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/alloc-comp-1.f90
@@ -22,19 +22,19 @@ contains
type (dl), intent (in) :: obj
integer, intent (in) :: val, cl1, cu1, cl2, cu2
logical, intent (in) :: c, f
- if ((c .neqv. allocated (obj%c)) .or. (f .neqv. allocated (obj%f))) STOP 1
+ if ((c .neqv. allocated (obj%c)) .or. (f .neqv. allocated (obj%f))) stop 1
if (c) then
- if (lbound (obj%c, 1) /= cl1 .or. ubound (obj%c, 1) /= cu1) STOP 2
- if (lbound (obj%c, 2) /= cl2 .or. ubound (obj%c, 2) /= cu2) STOP 3
+ if (lbound (obj%c, 1) /= cl1 .or. ubound (obj%c, 1) /= cu1) stop 2
+ if (lbound (obj%c, 2) /= cl2 .or. ubound (obj%c, 2) /= cu2) stop 3
end if
if (val /= 0) then
- if (obj%a /= val .or. obj%b /= val) STOP 4
- if (obj%d /= val .or. obj%e /= val) STOP 5
+ if (obj%a /= val .or. obj%b /= val) stop 4
+ if (obj%d /= val .or. obj%e /= val) stop 5
if (c) then
- if (any (obj%c /= val)) STOP 6
+ if (any (obj%c /= val)) stop 6
end if
if (f) then
- if (obj%f /= val) STOP 7
+ if (obj%f /= val) stop 7
end if
end if
end subroutine ver_dl
@@ -43,9 +43,9 @@ contains
integer, intent (in) :: val, hl, hu, cl1, cu1, cl2, cu2
logical, intent (in) :: h, k, c, f
integer :: i, j
- if ((h .neqv. allocated (obj%h)) .or. (k .neqv. allocated (obj%k))) STOP 8
+ if ((h .neqv. allocated (obj%h)) .or. (k .neqv. allocated (obj%k))) stop 8
if (h) then
- if (lbound (obj%h, 1) /= hl .or. ubound (obj%h, 1) /= hu) STOP 9
+ if (lbound (obj%h, 1) /= hl .or. ubound (obj%h, 1) /= hu) stop 9
do i = hl, hu
call ver_dl (obj%h(i), val, c, cl1, cu1, cl2, cu2, f)
end do
@@ -57,7 +57,7 @@ contains
end do
if (k) call ver_dl (obj%k, val, c, cl1, cu1, cl2, cu2, f)
if (val /= 0) then
- if (obj%g /= val .or. obj%i /= val) STOP 10
+ if (obj%g /= val .or. obj%i /= val) stop 10
end if
end subroutine ver_dt
subroutine alloc_dl (obj, val, c, cl1, cu1, cl2, cu2, f)
diff --git a/libgomp/testsuite/libgomp.fortran/alloc-comp-2.f90 b/libgomp/testsuite/libgomp.fortran/alloc-comp-2.f90
index 7d035387a3e..111005e1879 100644
--- a/libgomp/testsuite/libgomp.fortran/alloc-comp-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/alloc-comp-2.f90
@@ -22,19 +22,19 @@ contains
type (dl), intent (in) :: obj
integer, intent (in) :: val, cl1, cu1, cl2, cu2
logical, intent (in) :: c, f
- if ((c .neqv. allocated (obj%c)) .or. (f .neqv. allocated (obj%f))) STOP 1
+ if ((c .neqv. allocated (obj%c)) .or. (f .neqv. allocated (obj%f))) stop 1
if (c) then
- if (lbound (obj%c, 1) /= cl1 .or. ubound (obj%c, 1) /= cu1) STOP 2
- if (lbound (obj%c, 2) /= cl2 .or. ubound (obj%c, 2) /= cu2) STOP 3
+ if (lbound (obj%c, 1) /= cl1 .or. ubound (obj%c, 1) /= cu1) stop 2
+ if (lbound (obj%c, 2) /= cl2 .or. ubound (obj%c, 2) /= cu2) stop 3
end if
if (val /= 0) then
- if (obj%a /= val .or. obj%b /= val) STOP 4
- if (obj%d /= val .or. obj%e /= val) STOP 5
+ if (obj%a /= val .or. obj%b /= val) stop 4
+ if (obj%d /= val .or. obj%e /= val) stop 5
if (c) then
- if (any (obj%c /= val)) STOP 6
+ if (any (obj%c /= val)) stop 6
end if
if (f) then
- if (obj%f /= val) STOP 7
+ if (obj%f /= val) stop 7
end if
end if
end subroutine ver_dl
@@ -43,9 +43,9 @@ contains
integer, intent (in) :: val, hl, hu, cl1, cu1, cl2, cu2
logical, intent (in) :: h, k, c, f
integer :: i, j
- if ((h .neqv. allocated (obj%h)) .or. (k .neqv. allocated (obj%k))) STOP 8
+ if ((h .neqv. allocated (obj%h)) .or. (k .neqv. allocated (obj%k))) stop 8
if (h) then
- if (lbound (obj%h, 1) /= hl .or. ubound (obj%h, 1) /= hu) STOP 9
+ if (lbound (obj%h, 1) /= hl .or. ubound (obj%h, 1) /= hu) stop 9
do i = hl, hu
call ver_dl (obj%h(i), val, c, cl1, cu1, cl2, cu2, f)
end do
@@ -57,7 +57,7 @@ contains
end do
if (k) call ver_dl (obj%k, val, c, cl1, cu1, cl2, cu2, f)
if (val /= 0) then
- if (obj%g /= val .or. obj%i /= val) STOP 10
+ if (obj%g /= val .or. obj%i /= val) stop 10
end if
end subroutine ver_dt
subroutine alloc_dl (obj, val, c, cl1, cu1, cl2, cu2, f)
@@ -122,20 +122,20 @@ contains
logical, parameter :: T = .true.
logical :: l
!$omp parallel private (x, y, z)
- if (allocated (x) .or. allocated (y) .or. allocated (z)) STOP 11
+ if (allocated (x) .or. allocated (y) .or. allocated (z)) stop 11
!$omp end parallel
!$omp parallel firstprivate (x, y, z)
- if (allocated (x) .or. allocated (y) .or. allocated (z)) STOP 12
+ if (allocated (x) .or. allocated (y) .or. allocated (z)) stop 12
!$omp end parallel
l = F
!$omp parallel sections lastprivate (x, y, z) firstprivate (l)
!$omp section
if (.not. l) then
- if (allocated (x) .or. allocated (y) .or. allocated (z)) STOP 13
+ if (allocated (x) .or. allocated (y) .or. allocated (z)) stop 13
end if
!$omp section
if (.not. l) then
- if (allocated (x) .or. allocated (y) .or. allocated (z)) STOP 14
+ if (allocated (x) .or. allocated (y) .or. allocated (z)) stop 14
end if
allocate (x, y, z(-3:-3,2:3))
call alloc_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
@@ -148,10 +148,10 @@ contains
call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
!$omp section
!$omp end parallel sections
- if (.not.allocated (x) .or. .not.allocated (y)) STOP 15
- if (.not.allocated (z)) STOP 16
- if (lbound (z, 1) /= -3 .or. ubound (z, 1) /= -3) STOP 17
- if (lbound (z, 2) /= 2 .or. ubound (z, 2) /= 3) STOP 18
+ if (.not.allocated (x) .or. .not.allocated (y)) stop 15
+ if (.not.allocated (z)) stop 16
+ if (lbound (z, 1) /= -3 .or. ubound (z, 1) /= -3) stop 17
+ if (lbound (z, 2) /= 2 .or. ubound (z, 2) /= 3) stop 18
call ver_dt (x, 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
call ver_dt (y, 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
diff --git a/libgomp/testsuite/libgomp.fortran/alloc-comp-3.f90 b/libgomp/testsuite/libgomp.fortran/alloc-comp-3.f90
index 42ba7b4b7e2..0185859cb26 100644
--- a/libgomp/testsuite/libgomp.fortran/alloc-comp-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/alloc-comp-3.f90
@@ -22,19 +22,19 @@ contains
type (dl), intent (in) :: obj
integer, intent (in) :: val, cl1, cu1, cl2, cu2
logical, intent (in) :: c, f
- if ((c .neqv. allocated (obj%c)) .or. (f .neqv. allocated (obj%f))) STOP 1
+ if ((c .neqv. allocated (obj%c)) .or. (f .neqv. allocated (obj%f))) stop 1
if (c) then
- if (lbound (obj%c, 1) /= cl1 .or. ubound (obj%c, 1) /= cu1) STOP 2
- if (lbound (obj%c, 2) /= cl2 .or. ubound (obj%c, 2) /= cu2) STOP 3
+ if (lbound (obj%c, 1) /= cl1 .or. ubound (obj%c, 1) /= cu1) stop 2
+ if (lbound (obj%c, 2) /= cl2 .or. ubound (obj%c, 2) /= cu2) stop 3
end if
if (val /= 0) then
- if (obj%a /= val .or. obj%b /= val) STOP 4
- if (obj%d /= val .or. obj%e /= val) STOP 5
+ if (obj%a /= val .or. obj%b /= val) stop 4
+ if (obj%d /= val .or. obj%e /= val) stop 5
if (c) then
- if (any (obj%c /= val)) STOP 6
+ if (any (obj%c /= val)) stop 6
end if
if (f) then
- if (obj%f /= val) STOP 7
+ if (obj%f /= val) stop 7
end if
end if
end subroutine ver_dl
@@ -43,9 +43,9 @@ contains
integer, intent (in) :: val, hl, hu, cl1, cu1, cl2, cu2
logical, intent (in) :: h, k, c, f
integer :: i, j
- if ((h .neqv. allocated (obj%h)) .or. (k .neqv. allocated (obj%k))) STOP 8
+ if ((h .neqv. allocated (obj%h)) .or. (k .neqv. allocated (obj%k))) stop 8
if (h) then
- if (lbound (obj%h, 1) /= hl .or. ubound (obj%h, 1) /= hu) STOP 9
+ if (lbound (obj%h, 1) /= hl .or. ubound (obj%h, 1) /= hu) stop 9
do i = hl, hu
call ver_dl (obj%h(i), val, c, cl1, cu1, cl2, cu2, f)
end do
@@ -57,7 +57,7 @@ contains
end do
if (k) call ver_dl (obj%k, val, c, cl1, cu1, cl2, cu2, f)
if (val /= 0) then
- if (obj%g /= val .or. obj%i /= val) STOP 10
+ if (obj%g /= val .or. obj%i /= val) stop 10
end if
end subroutine ver_dt
subroutine alloc_dl (obj, val, c, cl1, cu1, cl2, cu2, f)
@@ -124,27 +124,27 @@ contains
logical, parameter :: F = .false.
logical, parameter :: T = .true.
logical :: l
- if (lbound (x, 1) /= 2 .or. ubound (x, 1) /= 4) STOP 11
- if (lbound (y, 1) /= 3 .or. ubound (y, 1) /= 4) STOP 12
+ if (lbound (x, 1) /= 2 .or. ubound (x, 1) /= 4) stop 11
+ if (lbound (y, 1) /= 3 .or. ubound (y, 1) /= 4) stop 12
call ver_dt (x(2), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
call ver_dt (x(n), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
call ver_dt (y(3), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
call ver_dt (y(4), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
!$omp parallel private (z)
- if (allocated (z)) STOP 13
+ if (allocated (z)) stop 13
!$omp end parallel
!$omp parallel firstprivate (z)
- if (allocated (z)) STOP 14
+ if (allocated (z)) stop 14
!$omp end parallel
l = F
!$omp parallel sections lastprivate (z) firstprivate (l)
!$omp section
if (.not. l) then
- if (allocated (z)) STOP 15
+ if (allocated (z)) stop 15
end if
!$omp section
if (.not. l) then
- if (allocated (z)) STOP 16
+ if (allocated (z)) stop 16
end if
allocate (z(-3:-3,2:3))
call alloc_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
@@ -153,9 +153,9 @@ contains
call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
!$omp section
!$omp end parallel sections
- if (.not.allocated (z)) STOP 17
- if (lbound (z, 1) /= -3 .or. ubound (z, 1) /= -3) STOP 18
- if (lbound (z, 2) /= 2 .or. ubound (z, 2) /= 3) STOP 19
+ if (.not.allocated (z)) stop 17
+ if (lbound (z, 1) /= -3 .or. ubound (z, 1) /= -3) stop 18
+ if (lbound (z, 2) /= 2 .or. ubound (z, 2) /= 3) stop 19
call ver_dt (z(-3,2), 5, F, 0, 0, T, T, -1, -1, -1, -1, T)
call ver_dt (z(-3,3), 23, T, 0, 1, T, T, 2, 2, 2, 2, F)
call ver_dt (x(n - 1), 0, F, 0, 0, F, F, 0, 0, 0, 0, F)
@@ -203,8 +203,8 @@ contains
call alloc_dt (z(-3,2), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
call alloc_dt (z(-3,3), 15, F, 0, 0, T, T, 2, 2, 2, 2, T)
!$omp parallel firstprivate (x, y, z)
- if (lbound (x, 1) /= 2 .or. ubound (x, 1) /= 4) STOP 20
- if (lbound (y, 1) /= 3 .or. ubound (y, 1) /= 4) STOP 21
+ if (lbound (x, 1) /= 2 .or. ubound (x, 1) /= 4) stop 20
+ if (lbound (y, 1) /= 3 .or. ubound (y, 1) /= 4) stop 21
call ver_dt (x(n - 1), 5, T, 1, 2, F, T, 2, 3, -2, -2, F)
call alloc_dt (x(n - 1), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
call ver_dt (x(n - 1), 4, T, -3, -1, T, T, -1, -1, 2, 3, T)
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable1.f90 b/libgomp/testsuite/libgomp.fortran/allocatable1.f90
index b9fd2ee6dbc..59e14406082 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable1.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable1.f90
@@ -7,7 +7,7 @@
logical :: k, l
b(:, :) = 16
l = .false.
- if (allocated (a)) STOP 1
+ if (allocated (a)) stop 1
!$omp parallel private (a, b) reduction (.or.:l)
l = l.or.allocated (a)
allocate (a(3, 6))
@@ -18,18 +18,18 @@
deallocate (a)
l = l.or.allocated (a)
!$omp end parallel
- if (allocated (a).or.l) STOP 2
+ if (allocated (a).or.l) stop 2
allocate (a(6, 3))
a(:, :) = 3
- if (.not.allocated (a)) STOP 3
+ if (.not.allocated (a)) stop 3
l = l.or.size(a).ne.18.or.size(a,1).ne.6.or.size(a,2).ne.3
- if (l) STOP 4
+ if (l) stop 4
!$omp parallel private (a, b) reduction (.or.:l)
l = l.or..not.allocated (a)
a(3, 2) = 1
b(3, 2) = 1
!$omp end parallel
- if (l.or..not.allocated (a)) STOP 5
+ if (l.or..not.allocated (a)) stop 5
!$omp parallel firstprivate (a, b) reduction (.or.:l)
l = l.or..not.allocated (a)
l = l.or.size(a).ne.18.or.size(a,1).ne.6.or.size(a,2).ne.3
@@ -41,7 +41,7 @@
a(:, :) = omp_get_thread_num ()
b(:, :) = omp_get_thread_num ()
!$omp end parallel
- if (any (a.ne.3).or.any (b.ne.16).or.l) STOP 6
+ if (any (a.ne.3).or.any (b.ne.16).or.l) stop 6
k = .true.
!$omp parallel do firstprivate (a, b, k) lastprivate (a, b) &
!$omp & reduction (.or.:l)
@@ -59,9 +59,9 @@
a(:, :) = i + 2
b(:, :) = i
end do
- if (any (a.ne.38).or.any (b.ne.36).or.l) STOP 7
+ if (any (a.ne.38).or.any (b.ne.36).or.l) stop 7
deallocate (a)
- if (allocated (a)) STOP 8
+ if (allocated (a)) stop 8
allocate (a (0:1, 0:3))
a(:, :) = 0
!$omp parallel do reduction (+:a) reduction (.or.:l) &
@@ -72,10 +72,10 @@
a(modulo (i, 2), i / 2) = a(modulo (i, 2), i / 2) + i
a(i / 4, modulo (i, 4)) = a(i / 4, modulo (i, 4)) + i
end do
- if (l) STOP 9
+ if (l) stop 9
do i = 0, 1
do j = 0, 3
- if (a(i, j) .ne. (5*i + 3*j)) STOP 10
+ if (a(i, j) .ne. (5*i + 3*j)) stop 10
end do
end do
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable10.f90 b/libgomp/testsuite/libgomp.fortran/allocatable10.f90
index 9b05dc74143..9ebceb814da 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable10.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable10.f90
@@ -4,109 +4,109 @@
integer :: i
!$omp declare reduction (foo : integer : omp_out = omp_out + omp_in) &
!$omp & initializer (omp_priv = 0)
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 1
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 1
allocate (a, b(6:9), c(3, 8:9))
a = 0
b = 0
c = 0
- if (.not.allocated (a)) STOP 2
- if (.not.allocated (b) .or. size (b) /= 4) STOP 3
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 4
- if (.not.allocated (c) .or. size (c) /= 6) STOP 5
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 6
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 7
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 8
+ if (.not.allocated (a)) stop 2
+ if (.not.allocated (b) .or. size (b) /= 4) stop 3
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 4
+ if (.not.allocated (c) .or. size (c) /= 6) stop 5
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 6
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 7
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 8
!$omp parallel do reduction (+:a, b, c)
do i = 1, 10
- if (.not.allocated (a)) STOP 9
- if (.not.allocated (b) .or. size (b) /= 4) STOP 10
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 11
- if (.not.allocated (c) .or. size (c) /= 6) STOP 12
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 13
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 14
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 15
+ if (.not.allocated (a)) stop 9
+ if (.not.allocated (b) .or. size (b) /= 4) stop 10
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 11
+ if (.not.allocated (c) .or. size (c) /= 6) stop 12
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 13
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 14
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 15
a = a + i
b = b + 2 * i
c = c + 3 * i
end do
- if (.not.allocated (a)) STOP 16
- if (.not.allocated (b) .or. size (b) /= 4) STOP 17
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 18
- if (.not.allocated (c) .or. size (c) /= 6) STOP 19
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 20
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 21
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 22
- if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) STOP 23
+ if (.not.allocated (a)) stop 16
+ if (.not.allocated (b) .or. size (b) /= 4) stop 17
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 18
+ if (.not.allocated (c) .or. size (c) /= 6) stop 19
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 20
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 21
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 22
+ if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) stop 23
a = 0
b = 0
c = 0
!$omp parallel do reduction (foo : a, b, c)
do i = 1, 10
- if (.not.allocated (a)) STOP 24
- if (.not.allocated (b) .or. size (b) /= 4) STOP 25
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 26
- if (.not.allocated (c) .or. size (c) /= 6) STOP 27
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 28
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 29
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 30
+ if (.not.allocated (a)) stop 24
+ if (.not.allocated (b) .or. size (b) /= 4) stop 25
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 26
+ if (.not.allocated (c) .or. size (c) /= 6) stop 27
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 28
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 29
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 30
a = a + i
b = b + 2 * i
c = c + 3 * i
end do
- if (.not.allocated (a)) STOP 31
- if (.not.allocated (b) .or. size (b) /= 4) STOP 32
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 33
- if (.not.allocated (c) .or. size (c) /= 6) STOP 34
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 35
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 36
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 37
- if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) STOP 38
+ if (.not.allocated (a)) stop 31
+ if (.not.allocated (b) .or. size (b) /= 4) stop 32
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 33
+ if (.not.allocated (c) .or. size (c) /= 6) stop 34
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 35
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 36
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 37
+ if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) stop 38
a = 0
b = 0
c = 0
!$omp simd reduction (+:a, b, c)
do i = 1, 10
- if (.not.allocated (a)) STOP 39
- if (.not.allocated (b) .or. size (b) /= 4) STOP 40
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 41
- if (.not.allocated (c) .or. size (c) /= 6) STOP 42
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 43
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 44
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 45
+ if (.not.allocated (a)) stop 39
+ if (.not.allocated (b) .or. size (b) /= 4) stop 40
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 41
+ if (.not.allocated (c) .or. size (c) /= 6) stop 42
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 43
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 44
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 45
a = a + i
b = b + 2 * i
c = c + 3 * i
end do
- if (.not.allocated (a)) STOP 46
- if (.not.allocated (b) .or. size (b) /= 4) STOP 47
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 48
- if (.not.allocated (c) .or. size (c) /= 6) STOP 49
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 50
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 51
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 52
- if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) STOP 53
+ if (.not.allocated (a)) stop 46
+ if (.not.allocated (b) .or. size (b) /= 4) stop 47
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 48
+ if (.not.allocated (c) .or. size (c) /= 6) stop 49
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 50
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 51
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 52
+ if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) stop 53
a = 0
b = 0
c = 0
!$omp simd reduction (foo : a, b, c)
do i = 1, 10
- if (.not.allocated (a)) STOP 54
- if (.not.allocated (b) .or. size (b) /= 4) STOP 55
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 56
- if (.not.allocated (c) .or. size (c) /= 6) STOP 57
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 58
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 59
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 60
+ if (.not.allocated (a)) stop 54
+ if (.not.allocated (b) .or. size (b) /= 4) stop 55
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 56
+ if (.not.allocated (c) .or. size (c) /= 6) stop 57
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 58
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 59
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 60
a = a + i
b = b + 2 * i
c = c + 3 * i
end do
- if (.not.allocated (a)) STOP 61
- if (.not.allocated (b) .or. size (b) /= 4) STOP 62
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 63
- if (.not.allocated (c) .or. size (c) /= 6) STOP 64
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 65
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 66
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 67
- if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) STOP 68
+ if (.not.allocated (a)) stop 61
+ if (.not.allocated (b) .or. size (b) /= 4) stop 62
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 63
+ if (.not.allocated (c) .or. size (c) /= 6) stop 64
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 65
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 66
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 67
+ if (a /= 55 .or. any (b /= 110) .or. any (c /= 165)) stop 68
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable11.f90 b/libgomp/testsuite/libgomp.fortran/allocatable11.f90
index 916dc6e596e..c3b82942f30 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable11.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable11.f90
@@ -5,68 +5,68 @@
integer, allocatable, save :: a, b(:), c(:,:)
integer :: p
!$omp threadprivate (a, b, c)
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 1
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 1
call omp_set_dynamic (.false.)
call omp_set_num_threads (4)
!$omp parallel num_threads (4)
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 2
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 2
!$omp end parallel
allocate (a, b(6:9), c(3, 8:9))
a = 4
b = 5
c = 6
- if (.not.allocated (a)) STOP 3
- if (.not.allocated (b) .or. size (b) /= 4) STOP 4
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 5
- if (.not.allocated (c) .or. size (c) /= 6) STOP 6
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 7
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 8
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 9
+ if (.not.allocated (a)) stop 3
+ if (.not.allocated (b) .or. size (b) /= 4) stop 4
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 5
+ if (.not.allocated (c) .or. size (c) /= 6) stop 6
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 7
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 8
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 9
!$omp parallel num_threads (4) copyin (a, b, c) private (p)
p = omp_get_thread_num ()
- if (.not.allocated (a)) STOP 10
- if (.not.allocated (b) .or. size (b) /= 4) STOP 11
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 12
- if (.not.allocated (c) .or. size (c) /= 6) STOP 13
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 14
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 15
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 16
- if (a /= 4 .or. any (b /= 5) .or. any (c /= 6)) STOP 17
+ if (.not.allocated (a)) stop 10
+ if (.not.allocated (b) .or. size (b) /= 4) stop 11
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 12
+ if (.not.allocated (c) .or. size (c) /= 6) stop 13
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 14
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 15
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 16
+ if (a /= 4 .or. any (b /= 5) .or. any (c /= 6)) stop 17
deallocate (a, b, c)
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 18
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 18
allocate (a, b(p:9), c(3, p:7))
a = p
b = p
c = p
- if (.not.allocated (a)) STOP 19
- if (.not.allocated (b) .or. size (b) /= (10 - p)) STOP 20
- if (lbound (b, 1) /= p .or. ubound (b, 1) /= 9) STOP 21
- if (.not.allocated (c) .or. size (c) /= (3 * (8 - p))) STOP 22
- if (size (c, 1) /= 3 .or. size (c, 2) /= (8 - p)) STOP 23
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 24
- if (lbound (c, 2) /= p .or. ubound (c, 2) /= 7) STOP 25
- if (a /= p .or. any (b /= p) .or. any (c /= p)) STOP 26
+ if (.not.allocated (a)) stop 19
+ if (.not.allocated (b) .or. size (b) /= (10 - p)) stop 20
+ if (lbound (b, 1) /= p .or. ubound (b, 1) /= 9) stop 21
+ if (.not.allocated (c) .or. size (c) /= (3 * (8 - p))) stop 22
+ if (size (c, 1) /= 3 .or. size (c, 2) /= (8 - p)) stop 23
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 24
+ if (lbound (c, 2) /= p .or. ubound (c, 2) /= 7) stop 25
+ if (a /= p .or. any (b /= p) .or. any (c /= p)) stop 26
!$omp end parallel
!$omp parallel num_threads (4) copyin (a, b, c)
- if (.not.allocated (a)) STOP 27
- if (.not.allocated (b) .or. size (b) /= 10) STOP 28
- if (lbound (b, 1) /= 0 .or. ubound (b, 1) /= 9) STOP 29
- if (.not.allocated (c) .or. size (c) /= 24) STOP 30
- if (size (c, 1) /= 3 .or. size (c, 2) /= 8) STOP 31
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 32
- if (lbound (c, 2) /= 0 .or. ubound (c, 2) /= 7) STOP 33
- if (a /= 0 .or. any (b /= 0) .or. any (c /= 0)) STOP 34
+ if (.not.allocated (a)) stop 27
+ if (.not.allocated (b) .or. size (b) /= 10) stop 28
+ if (lbound (b, 1) /= 0 .or. ubound (b, 1) /= 9) stop 29
+ if (.not.allocated (c) .or. size (c) /= 24) stop 30
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 8) stop 31
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 32
+ if (lbound (c, 2) /= 0 .or. ubound (c, 2) /= 7) stop 33
+ if (a /= 0 .or. any (b /= 0) .or. any (c /= 0)) stop 34
!$omp end parallel
deallocate (a, b, c)
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 35
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 35
!$omp parallel num_threads (4) copyin (a, b, c)
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 36
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 36
!$omp end parallel
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable12.f90 b/libgomp/testsuite/libgomp.fortran/allocatable12.f90
index 6ccf1c0323c..8ce4dd2f3fe 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable12.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable12.f90
@@ -2,11 +2,11 @@
integer, allocatable :: a, b(:), c(:,:)
logical :: l
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 1
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 1
!$omp parallel private (a, b, c, l)
l = .false.
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 2
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 2
!$omp single
allocate (a, b(6:9), c(3, 8:9))
@@ -15,60 +15,60 @@
c = 6
!$omp end single copyprivate (a, b, c)
- if (.not.allocated (a)) STOP 3
- if (.not.allocated (b) .or. size (b) /= 4) STOP 4
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 5
- if (.not.allocated (c) .or. size (c) /= 6) STOP 6
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 7
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 8
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 9
- if (a /= 4 .or. any (b /= 5) .or. any (c /= 6)) STOP 10
+ if (.not.allocated (a)) stop 3
+ if (.not.allocated (b) .or. size (b) /= 4) stop 4
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 5
+ if (.not.allocated (c) .or. size (c) /= 6) stop 6
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 7
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 8
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 9
+ if (a /= 4 .or. any (b /= 5) .or. any (c /= 6)) stop 10
!$omp single
deallocate (a, b, c)
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 11
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 11
allocate (a, b(0:4), c(3, 2:7))
a = 1
b = 2
c = 3
!$omp end single copyprivate (a, b, c)
- if (.not.allocated (a)) STOP 12
- if (.not.allocated (b) .or. size (b) /= 5) STOP 13
- if (lbound (b, 1) /= 0 .or. ubound (b, 1) /= 4) STOP 14
- if (.not.allocated (c) .or. size (c) /= 18) STOP 15
- if (size (c, 1) /= 3 .or. size (c, 2) /= 6) STOP 16
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 17
- if (lbound (c, 2) /= 2 .or. ubound (c, 2) /= 7) STOP 18
- if (a /= 1 .or. any (b /= 2) .or. any (c /= 3)) STOP 19
+ if (.not.allocated (a)) stop 12
+ if (.not.allocated (b) .or. size (b) /= 5) stop 13
+ if (lbound (b, 1) /= 0 .or. ubound (b, 1) /= 4) stop 14
+ if (.not.allocated (c) .or. size (c) /= 18) stop 15
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 6) stop 16
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 17
+ if (lbound (c, 2) /= 2 .or. ubound (c, 2) /= 7) stop 18
+ if (a /= 1 .or. any (b /= 2) .or. any (c /= 3)) stop 19
!$omp single
l = .true.
deallocate (a, b, c)
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 20
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 20
allocate (a, b(2:6), c(3:5, 3:8))
a = 7
b = 8
c = 9
!$omp end single copyprivate (a, b, c)
- if (.not.allocated (a)) STOP 21
- if (.not.allocated (b) .or. size (b) /= 5) STOP 22
+ if (.not.allocated (a)) stop 21
+ if (.not.allocated (b) .or. size (b) /= 5) stop 22
if (l) then
- if (lbound (b, 1) /= 2 .or. ubound (b, 1) /= 6) STOP 23
+ if (lbound (b, 1) /= 2 .or. ubound (b, 1) /= 6) stop 23
else
- if (lbound (b, 1) /= 0 .or. ubound (b, 1) /= 4) STOP 24
+ if (lbound (b, 1) /= 0 .or. ubound (b, 1) /= 4) stop 24
end if
- if (.not.allocated (c) .or. size (c) /= 18) STOP 25
- if (size (c, 1) /= 3 .or. size (c, 2) /= 6) STOP 26
+ if (.not.allocated (c) .or. size (c) /= 18) stop 25
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 6) stop 26
if (l) then
- if (lbound (c, 1) /= 3 .or. ubound (c, 1) /= 5) STOP 27
- if (lbound (c, 2) /= 3 .or. ubound (c, 2) /= 8) STOP 28
+ if (lbound (c, 1) /= 3 .or. ubound (c, 1) /= 5) stop 27
+ if (lbound (c, 2) /= 3 .or. ubound (c, 2) /= 8) stop 28
else
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 29
- if (lbound (c, 2) /= 2 .or. ubound (c, 2) /= 7) STOP 30
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 29
+ if (lbound (c, 2) /= 2 .or. ubound (c, 2) /= 7) stop 30
end if
- if (a /= 7 .or. any (b /= 8) .or. any (c /= 9)) STOP 31
+ if (a /= 7 .or. any (b /= 8) .or. any (c /= 9)) stop 31
!$omp end parallel
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable2.f90 b/libgomp/testsuite/libgomp.fortran/allocatable2.f90
index 1361e6d1a91..fbf81c214b8 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable2.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable2.f90
@@ -7,7 +7,7 @@
integer :: n
logical :: l
!$omp threadprivate (a)
- if (allocated (a)) STOP 1
+ if (allocated (a)) stop 1
call omp_set_dynamic (.false.)
l = .false.
!$omp parallel num_threads (4) reduction(.or.:l)
@@ -16,7 +16,7 @@
l = l.or..not.allocated (a)
l = l.or.size(a).ne.12.or.size(a,1).ne.3.or.size(a,2).ne.4
!$omp end parallel
- if (l.or.any(a.ne.6)) STOP 1
+ if (l.or.any(a.ne.6)) stop 2
!$omp parallel num_threads (4) copyin (a) reduction(.or.:l) private (b)
l = l.or.allocated (b)
l = l.or..not.allocated (a)
@@ -37,11 +37,11 @@
deallocate (b)
l = l.or.allocated (b)
!$omp end parallel
- if (n.lt.0 .or. n.ge.4) STOP 2
- if (l.or.any(a.ne.(n + 36))) STOP 3
+ if (n.lt.0 .or. n.ge.4) stop 3
+ if (l.or.any(a.ne.(n + 36))) stop 4
!$omp parallel num_threads (4) reduction(.or.:l)
deallocate (a)
l = l.or.allocated (a)
!$omp end parallel
- if (l.or.allocated (a)) STOP 4
+ if (l.or.allocated (a)) stop 5
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable3.f90 b/libgomp/testsuite/libgomp.fortran/allocatable3.f90
index 03ed1ac3f1a..4663b15988f 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable3.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable3.f90
@@ -4,7 +4,7 @@
integer :: i
logical :: l
l = .false.
- if (allocated (a)) STOP 1
+ if (allocated (a)) stop 1
!$omp parallel private (a) reduction (.or.:l)
allocate (a (-7:-5))
l = l.or..not.allocated (a)
@@ -18,4 +18,5 @@
l = l.or.any (a.ne.0)
deallocate (a)
!$omp end parallel
+ if (l.or.allocated (a)) stop 2
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable4.f90 b/libgomp/testsuite/libgomp.fortran/allocatable4.f90
index 0b0ac174fad..2a8cf22901d 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable4.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable4.f90
@@ -6,7 +6,7 @@
logical :: k, l
b(:, :) = 16
l = .false.
- if (allocated (a)) STOP 1
+ if (allocated (a)) stop 1
!$omp task private (a, b) shared (l)
l = l.or.allocated (a)
allocate (a(3, 6))
@@ -18,19 +18,19 @@
l = l.or.allocated (a)
!$omp end task
!$omp taskwait
- if (allocated (a).or.l) STOP 2
+ if (allocated (a).or.l) stop 2
allocate (a(6, 3))
a(:, :) = 3
- if (.not.allocated (a)) STOP 3
+ if (.not.allocated (a)) stop 3
l = l.or.size(a).ne.18.or.size(a,1).ne.6.or.size(a,2).ne.3
- if (l) STOP 4
+ if (l) stop 4
!$omp task private (a, b) shared (l)
l = l.or..not.allocated (a)
a(3, 2) = 1
b(3, 2) = 1
!$omp end task
!$omp taskwait
- if (l.or..not.allocated (a)) STOP 5
+ if (l.or..not.allocated (a)) stop 5
!$omp task firstprivate (a, b) shared (l)
l = l.or..not.allocated (a)
l = l.or.size(a).ne.18.or.size(a,1).ne.6.or.size(a,2).ne.3
@@ -43,5 +43,5 @@
b(:, :) = 8
!$omp end task
!$omp taskwait
- if (any (a.ne.3).or.any (b.ne.16).or.l) STOP 6
+ if (any (a.ne.3).or.any (b.ne.16).or.l) stop 6
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable5.f90 b/libgomp/testsuite/libgomp.fortran/allocatable5.f90
index 20ac6012ebd..73027e7082c 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable5.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable5.f90
@@ -12,6 +12,6 @@ program pr42866
a = a + 2
!$omp end sections
!$omp end parallel
- if (any (a.ne.3)) STOP 1
+ if (any (a.ne.3)) stop 1
deallocate (a)
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable6.f90 b/libgomp/testsuite/libgomp.fortran/allocatable6.f90
index 444af1dd713..b7bfba9c53d 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable6.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable6.f90
@@ -25,10 +25,10 @@
else if (i .gt. 1 .and. i .lt. 9) then
j = 7
end if
- if (c(i) .ne. j) STOP 1
+ if (c(i) .ne. j) stop 1
j = 179 - modulo (i, 11)
if (i .gt. 1 .and. i .lt. 9) j = i
- if (d(i) .ne. j) STOP 2
+ if (d(i) .ne. j) stop 2
end do
deallocate (a, b, c, d)
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable7.f90 b/libgomp/testsuite/libgomp.fortran/allocatable7.f90
index 787b03559e2..77cd5be6c82 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable7.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable7.f90
@@ -12,5 +12,5 @@
deallocate (a)
l = l .or. allocated (a)
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable8.f90 b/libgomp/testsuite/libgomp.fortran/allocatable8.f90
index 84b18f34940..d1a216a9f46 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable8.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable8.f90
@@ -5,10 +5,10 @@
integer, save, allocatable :: a(:, :)
logical :: l
!$omp threadprivate (a)
- if (allocated (a)) STOP 1
+ if (allocated (a)) stop 1
l = .false.
!$omp parallel copyin (a) num_threads (4) reduction(.or.:l)
l = l.or.allocated (a)
!$omp end parallel
- if (l.or.allocated (a)) STOP 2
+ if (l.or.allocated (a)) stop 2
end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable9.f90 b/libgomp/testsuite/libgomp.fortran/allocatable9.f90
index c7decfb4b33..a9929f7506a 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable9.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable9.f90
@@ -2,155 +2,155 @@
integer, allocatable :: a, b(:), c(:,:)
logical :: l
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 1
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 1
!$omp parallel private (a, b, c)
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 2
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 2
allocate (a, b(-7:-1), c(2:3, 3:5))
- if (.not.allocated (a)) STOP 3
- if (.not.allocated (b) .or. size (b) /= 7) STOP 4
- if (lbound (b, 1) /= -7 .or. ubound (b, 1) /= -1) STOP 5
- if (.not.allocated (c) .or. size (c) /= 6) STOP 6
- if (size (c, 1) /= 2 .or. size (c, 2) /= 3) STOP 7
- if (lbound (c, 1) /= 2 .or. ubound (c, 1) /= 3) STOP 8
- if (lbound (c, 2) /= 3 .or. ubound (c, 2) /= 5) STOP 9
+ if (.not.allocated (a)) stop 3
+ if (.not.allocated (b) .or. size (b) /= 7) stop 4
+ if (lbound (b, 1) /= -7 .or. ubound (b, 1) /= -1) stop 5
+ if (.not.allocated (c) .or. size (c) /= 6) stop 6
+ if (size (c, 1) /= 2 .or. size (c, 2) /= 3) stop 7
+ if (lbound (c, 1) /= 2 .or. ubound (c, 1) /= 3) stop 8
+ if (lbound (c, 2) /= 3 .or. ubound (c, 2) /= 5) stop 9
a = 4
b = 3
c = 2
!$omp end parallel
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 10
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 10
!$omp parallel firstprivate (a, b, c)
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 11
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 11
allocate (a, b(-7:-1), c(2:3, 3:5))
- if (.not.allocated (a)) STOP 12
- if (.not.allocated (b) .or. size (b) /= 7) STOP 13
- if (lbound (b, 1) /= -7 .or. ubound (b, 1) /= -1) STOP 14
- if (.not.allocated (c) .or. size (c) /= 6) STOP 15
- if (size (c, 1) /= 2 .or. size (c, 2) /= 3) STOP 16
- if (lbound (c, 1) /= 2 .or. ubound (c, 1) /= 3) STOP 17
- if (lbound (c, 2) /= 3 .or. ubound (c, 2) /= 5) STOP 18
+ if (.not.allocated (a)) stop 12
+ if (.not.allocated (b) .or. size (b) /= 7) stop 13
+ if (lbound (b, 1) /= -7 .or. ubound (b, 1) /= -1) stop 14
+ if (.not.allocated (c) .or. size (c) /= 6) stop 15
+ if (size (c, 1) /= 2 .or. size (c, 2) /= 3) stop 16
+ if (lbound (c, 1) /= 2 .or. ubound (c, 1) /= 3) stop 17
+ if (lbound (c, 2) /= 3 .or. ubound (c, 2) /= 5) stop 18
a = 4
b = 3
c = 2
!$omp end parallel
- if (allocated (a) .or. allocated (b) .or. allocated (c)) STOP 19
+ if (allocated (a) .or. allocated (b) .or. allocated (c)) stop 19
allocate (a, b(6:9), c(3, 8:9))
a = 2
b = 4
c = 5
- if (.not.allocated (a)) STOP 20
- if (.not.allocated (b) .or. size (b) /= 4) STOP 21
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 22
- if (.not.allocated (c) .or. size (c) /= 6) STOP 23
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 24
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 25
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 26
+ if (.not.allocated (a)) stop 20
+ if (.not.allocated (b) .or. size (b) /= 4) stop 21
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 22
+ if (.not.allocated (c) .or. size (c) /= 6) stop 23
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 24
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 25
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 26
!$omp parallel firstprivate (a, b, c)
- if (.not.allocated (a)) STOP 27
- if (.not.allocated (b) .or. size (b) /= 4) STOP 28
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 29
- if (.not.allocated (c) .or. size (c) /= 6) STOP 30
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 31
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 32
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 33
- if (a /= 2 .or. any (b .ne. 4) .or. any (c .ne. 5)) STOP 34
+ if (.not.allocated (a)) stop 27
+ if (.not.allocated (b) .or. size (b) /= 4) stop 28
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 29
+ if (.not.allocated (c) .or. size (c) /= 6) stop 30
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 31
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 32
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 33
+ if (a /= 2 .or. any (b .ne. 4) .or. any (c .ne. 5)) stop 34
deallocate (a)
- if (allocated (a)) STOP 35
+ if (allocated (a)) stop 35
allocate (a)
a = 8
b = (/ 1, 2, 3 /)
c = reshape ((/ 1, 2, 3, 4, 5, 6, 7, 8 /), (/ 2, 4 /))
- if (.not.allocated (a)) STOP 36
- if (.not.allocated (b) .or. size (b) /= 3) STOP 37
- if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 3) STOP 38
- if (.not.allocated (c) .or. size (c) /= 8) STOP 39
- if (size (c, 1) /= 2 .or. size (c, 2) /= 4) STOP 40
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 2) STOP 41
- if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 4) STOP 42
- if (a /= 8 .or. b(2) /= 2 .or. c(1, 2) /= 3) STOP 43
+ if (.not.allocated (a)) stop 36
+ if (.not.allocated (b) .or. size (b) /= 3) stop 37
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 3) stop 38
+ if (.not.allocated (c) .or. size (c) /= 8) stop 39
+ if (size (c, 1) /= 2 .or. size (c, 2) /= 4) stop 40
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 2) stop 41
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 4) stop 42
+ if (a /= 8 .or. b(2) /= 2 .or. c(1, 2) /= 3) stop 43
!$omp end parallel
- if (.not.allocated (a)) STOP 44
- if (.not.allocated (b) .or. size (b) /= 4) STOP 45
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 46
- if (.not.allocated (c) .or. size (c) /= 6) STOP 47
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 48
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 49
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 50
- if (a /= 2 .or. any (b .ne. 4) .or. any (c .ne. 5)) STOP 51
+ if (.not.allocated (a)) stop 44
+ if (.not.allocated (b) .or. size (b) /= 4) stop 45
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 46
+ if (.not.allocated (c) .or. size (c) /= 6) stop 47
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 48
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 49
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 50
+ if (a /= 2 .or. any (b .ne. 4) .or. any (c .ne. 5)) stop 51
l = .false.
!$omp parallel sections lastprivate (a, b, c) firstprivate (l)
!$omp section
- if (.not.allocated (a)) STOP 52
+ if (.not.allocated (a)) stop 52
if (l) then
- if (.not.allocated (b) .or. size (b) /= 6) STOP 53
- if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 6) STOP 54
- if (.not.allocated (c) .or. size (c) /= 8) STOP 55
- if (size (c, 1) /= 4 .or. size (c, 2) /= 2) STOP 56
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 4) STOP 57
- if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 2) STOP 58
- if (a /= 12 .or. b(2) /= 8 .or. c(1, 2) /= 5) STOP 59
+ if (.not.allocated (b) .or. size (b) /= 6) stop 53
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 6) stop 54
+ if (.not.allocated (c) .or. size (c) /= 8) stop 55
+ if (size (c, 1) /= 4 .or. size (c, 2) /= 2) stop 56
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 4) stop 57
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 2) stop 58
+ if (a /= 12 .or. b(2) /= 8 .or. c(1, 2) /= 5) stop 59
else
- if (.not.allocated (b) .or. size (b) /= 4) STOP 60
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 61
- if (.not.allocated (c) .or. size (c) /= 6) STOP 62
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 63
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 64
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 65
+ if (.not.allocated (b) .or. size (b) /= 4) stop 60
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 61
+ if (.not.allocated (c) .or. size (c) /= 6) stop 62
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 63
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 64
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 65
end if
l = .true.
deallocate (a)
- if (allocated (a)) STOP 66
+ if (allocated (a)) stop 66
allocate (a)
a = 8
b = (/ 1, 2, 3 /)
c = reshape ((/ 1, 2, 3, 4, 5, 6, 7, 8 /), (/ 2, 4 /))
- if (.not.allocated (a)) STOP 67
- if (.not.allocated (b) .or. size (b) /= 3) STOP 68
- if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 3) STOP 69
- if (.not.allocated (c) .or. size (c) /= 8) STOP 70
- if (size (c, 1) /= 2 .or. size (c, 2) /= 4) STOP 71
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 2) STOP 72
- if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 4) STOP 73
- if (a /= 8 .or. b(2) /= 2 .or. c(1, 2) /= 3) STOP 74
+ if (.not.allocated (a)) stop 67
+ if (.not.allocated (b) .or. size (b) /= 3) stop 68
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 3) stop 69
+ if (.not.allocated (c) .or. size (c) /= 8) stop 70
+ if (size (c, 1) /= 2 .or. size (c, 2) /= 4) stop 71
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 2) stop 72
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 4) stop 73
+ if (a /= 8 .or. b(2) /= 2 .or. c(1, 2) /= 3) stop 74
!$omp section
- if (.not.allocated (a)) STOP 75
+ if (.not.allocated (a)) stop 75
if (l) then
- if (.not.allocated (b) .or. size (b) /= 3) STOP 76
- if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 3) STOP 77
- if (.not.allocated (c) .or. size (c) /= 8) STOP 78
- if (size (c, 1) /= 2 .or. size (c, 2) /= 4) STOP 79
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 2) STOP 80
- if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 4) STOP 81
- if (a /= 8 .or. b(2) /= 2 .or. c(1, 2) /= 3) STOP 82
+ if (.not.allocated (b) .or. size (b) /= 3) stop 76
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 3) stop 77
+ if (.not.allocated (c) .or. size (c) /= 8) stop 78
+ if (size (c, 1) /= 2 .or. size (c, 2) /= 4) stop 79
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 2) stop 80
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 4) stop 81
+ if (a /= 8 .or. b(2) /= 2 .or. c(1, 2) /= 3) stop 82
else
- if (.not.allocated (b) .or. size (b) /= 4) STOP 83
- if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) STOP 84
- if (.not.allocated (c) .or. size (c) /= 6) STOP 85
- if (size (c, 1) /= 3 .or. size (c, 2) /= 2) STOP 86
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) STOP 87
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) STOP 88
+ if (.not.allocated (b) .or. size (b) /= 4) stop 83
+ if (lbound (b, 1) /= 6 .or. ubound (b, 1) /= 9) stop 84
+ if (.not.allocated (c) .or. size (c) /= 6) stop 85
+ if (size (c, 1) /= 3 .or. size (c, 2) /= 2) stop 86
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 3) stop 87
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 9) stop 88
end if
l = .true.
deallocate (a)
- if (allocated (a)) STOP 89
+ if (allocated (a)) stop 89
allocate (a)
a = 12
b = (/ 9, 8, 7, 6, 5, 4 /)
c = reshape ((/ 1, 2, 3, 4, 5, 6, 7, 8 /), (/ 4, 2 /))
- if (.not.allocated (a)) STOP 90
- if (.not.allocated (b) .or. size (b) /= 6) STOP 91
- if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 6) STOP 92
- if (.not.allocated (c) .or. size (c) /= 8) STOP 93
- if (size (c, 1) /= 4 .or. size (c, 2) /= 2) STOP 94
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 4) STOP 95
- if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 2) STOP 96
- if (a /= 12 .or. b(2) /= 8 .or. c(1, 2) /= 5) STOP 97
+ if (.not.allocated (a)) stop 90
+ if (.not.allocated (b) .or. size (b) /= 6) stop 91
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 6) stop 92
+ if (.not.allocated (c) .or. size (c) /= 8) stop 93
+ if (size (c, 1) /= 4 .or. size (c, 2) /= 2) stop 94
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 4) stop 95
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 2) stop 96
+ if (a /= 12 .or. b(2) /= 8 .or. c(1, 2) /= 5) stop 97
!$omp end parallel sections
- if (.not.allocated (a)) STOP 98
- if (.not.allocated (b) .or. size (b) /= 6) STOP 99
- if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 6) STOP 100
- if (.not.allocated (c) .or. size (c) /= 8) STOP 101
- if (size (c, 1) /= 4 .or. size (c, 2) /= 2) STOP 102
- if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 4) STOP 103
- if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 2) STOP 104
- if (a /= 12 .or. b(2) /= 8 .or. c(1, 2) /= 5) STOP 105
+ if (.not.allocated (a)) stop 98
+ if (.not.allocated (b) .or. size (b) /= 6) stop 99
+ if (lbound (b, 1) /= 1 .or. ubound (b, 1) /= 6) stop 100
+ if (.not.allocated (c) .or. size (c) /= 8) stop 101
+ if (size (c, 1) /= 4 .or. size (c, 2) /= 2) stop 102
+ if (lbound (c, 1) /= 1 .or. ubound (c, 1) /= 4) stop 103
+ if (lbound (c, 2) /= 1 .or. ubound (c, 2) /= 2) stop 104
+ if (a /= 12 .or. b(2) /= 8 .or. c(1, 2) /= 5) stop 105
end
diff --git a/libgomp/testsuite/libgomp.fortran/appendix-a/a.28.5.f90 b/libgomp/testsuite/libgomp.fortran/appendix-a/a.28.5.f90
index 08de997f8c4..a3f56dd4757 100644
--- a/libgomp/testsuite/libgomp.fortran/appendix-a/a.28.5.f90
+++ b/libgomp/testsuite/libgomp.fortran/appendix-a/a.28.5.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-w" }
+! { dg-options "-w -std=legacy" }
!
! "-w" added as libgomp/testsuite seemingly cannot parse with
! dg-warning Fortran's output. Fortran warns for "call sub1(a)"
diff --git a/libgomp/testsuite/libgomp.fortran/associate1.f90 b/libgomp/testsuite/libgomp.fortran/associate1.f90
index c7930c7644a..31ecaf04200 100644
--- a/libgomp/testsuite/libgomp.fortran/associate1.f90
+++ b/libgomp/testsuite/libgomp.fortran/associate1.f90
@@ -12,12 +12,12 @@ program associate1
!$omp parallel private(v, a) default(none)
v = -1
a = 2.5
- if (v /= -1 .or. u /= 15) STOP 1
- if (a(2,1) /= 2.5 .or. b /= 3.5) STOP 2
+ if (v /= -1 .or. u /= 15) stop 1
+ if (a(2,1) /= 2.5 .or. b /= 3.5) stop 2
associate(u => v, b => a(2, 1))
- if (u /= -1 .or. b /= 2.5) STOP 3
+ if (u /= -1 .or. b /= 2.5) stop 3
end associate
- if (u /= 15 .or. b /= 3.5) STOP 4
+ if (u /= 15 .or. b /= 3.5) stop 4
!$omp end parallel
end associate
end program
diff --git a/libgomp/testsuite/libgomp.fortran/associate2.f90 b/libgomp/testsuite/libgomp.fortran/associate2.f90
index fbeae95b18f..63d172b476c 100644
--- a/libgomp/testsuite/libgomp.fortran/associate2.f90
+++ b/libgomp/testsuite/libgomp.fortran/associate2.f90
@@ -20,12 +20,12 @@ program associate2
!$omp parallel private(v, a) default(none)
v = -1
forall (k = 1:3, l = 1:3) a(k, l)%a(:,:) = 2.5
- if (v(3) /= -1 .or. u(3) /= 15) STOP 1
- if (a(2,1)%a(1,2) /= 2.5 .or. b(1,2) /= 3.5) STOP 2
+ if (v(3) /= -1 .or. u(3) /= 15) stop 1
+ if (a(2,1)%a(1,2) /= 2.5 .or. b(1,2) /= 3.5) stop 2
associate(u => v, b => a(2, 1)%a)
- if (u(3) /= -1 .or. b(1,2) /= 2.5) STOP 3
+ if (u(3) /= -1 .or. b(1,2) /= 2.5) stop 3
end associate
- if (u(3) /= 15 .or. b(1,2) /= 3.5) STOP 4
+ if (u(3) /= 15 .or. b(1,2) /= 3.5) stop 4
!$omp end parallel
end associate
forall (k = 1:3, l = 1:3) a(k, l)%c(:,:)%i = 7
@@ -35,12 +35,12 @@ program associate2
associate(d => a(i, j)%c(2,:)%i)
!$omp parallel private(a) default(none)
forall (k = 1:3, l = 1:3) a(k, l)%c(:,:)%i = 15
- if (a(1,2)%c(2,1)%i /= 15 .or. d(1) /= 9) STOP 5
- if (a(1,2)%c(2,2)%i /= 15 .or. d(2) /= 7) STOP 6
+ if (a(1,2)%c(2,1)%i /= 15 .or. d(1) /= 9) stop 5
+ if (a(1,2)%c(2,2)%i /= 15 .or. d(2) /= 7) stop 6
associate(d => a(2,1)%c(2,:)%i)
- if (d(1) /= 15 .or. d(2) /= 15) STOP 7
+ if (d(1) /= 15 .or. d(2) /= 15) stop 7
end associate
- if (d(1) /= 9 .or. d(2) /= 7) STOP 8
+ if (d(1) /= 9 .or. d(2) /= 7) stop 8
!$omp end parallel
end associate
end program
diff --git a/libgomp/testsuite/libgomp.fortran/associate3.f90 b/libgomp/testsuite/libgomp.fortran/associate3.f90
index da788a467ea..29c2dd3fc1d 100644
--- a/libgomp/testsuite/libgomp.fortran/associate3.f90
+++ b/libgomp/testsuite/libgomp.fortran/associate3.f90
@@ -16,5 +16,5 @@
if (j.eq.1) k = 7
end do
end associate
- if (any (v%f(:).ne.21.) .or. i.ne.7) STOP 1
+ if (any (v%f(:).ne.21.) .or. i.ne.7) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/async_io_1.f90 b/libgomp/testsuite/libgomp.fortran/async_io_1.f90
new file mode 100644
index 00000000000..07721bb230a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/async_io_1.f90
@@ -0,0 +1,48 @@
+! { dg-do run }
+!TODO: Move these testcases to gfortran testsuite
+! once compilation with pthreads is supported there
+! Check basic functionality of async I/O
+program main
+ implicit none
+ integer:: i=1, j=2, k, l
+ real :: a, b, c, d
+ character(3), parameter:: yes="yes"
+ character(4) :: str
+ complex :: cc, dd
+ integer, dimension(4):: is = [0, 1, 2, 3]
+ integer, dimension(4):: res
+ character(10) :: inq
+
+ open (10, file='a.dat', asynchronous=yes)
+ cc = (1.5, 0.5)
+ inquire (10,asynchronous=inq)
+ if (inq /= "YES") stop 1
+ write (10,*,asynchronous=yes) 4, 3
+ write (10,*,asynchronous=yes) 2, 1
+ write (10,*,asynchronous=yes) 1.0, 3.0
+ write (10,'(A)', asynchronous=yes) 'asdf'
+ write (10,*, asynchronous=yes) cc
+ close (10)
+ open (20, file='a.dat', asynchronous=yes)
+ read (20, *, asynchronous=yes) i, j
+ read (20, *, asynchronous=yes) k, l
+ read (20, *, asynchronous=yes) a, b
+ read (20,'(A4)',asynchronous=yes) str
+ read (20,*, asynchronous=yes) dd
+ wait (20)
+ if (i /= 4 .or. j /= 3) stop 2
+ if (k /= 2 .or. l /= 1) stop 3
+ if (a /= 1.0 .or. b /= 3.0) stop 4
+ if (str /= 'asdf') stop 5
+ if (cc /= dd) stop 6
+ close (20,status="delete")
+
+ open(10, file='c.dat', asynchronous=yes)
+ write(10, *, asynchronous=yes) is
+ close(10)
+ open(20, file='c.dat', asynchronous=yes)
+ read(20, *, asynchronous=yes) res
+ wait (20)
+ if (any(res /= is)) stop 7
+ close (20,status="delete")
+end program
diff --git a/libgomp/testsuite/libgomp.fortran/async_io_2.f90 b/libgomp/testsuite/libgomp.fortran/async_io_2.f90
new file mode 100644
index 00000000000..440d46e9463
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/async_io_2.f90
@@ -0,0 +1,18 @@
+! { dg-do run }
+!TODO: Move these testcases to gfortran testsuite
+! once compilation with pthreads is supported there
+program main
+ implicit none
+ integer :: i, ios
+ character(len=100) :: iom
+ open (10,file="tst.dat")
+ write (10,'(A4)') 'asdf'
+ close(10)
+ i = 234
+ open(10,file="tst.dat", asynchronous="yes")
+ read (10,'(I4)',asynchronous="yes") i
+ iom = ' '
+ wait (10,iostat=ios,iomsg=iom)
+ if (iom == ' ') stop 1
+ close(10,status="delete")
+end program main
diff --git a/libgomp/testsuite/libgomp.fortran/async_io_3.f90 b/libgomp/testsuite/libgomp.fortran/async_io_3.f90
new file mode 100644
index 00000000000..7d5124868cf
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/async_io_3.f90
@@ -0,0 +1,16 @@
+
+!TODO: Move these testcases to gfortran testsuite
+! once compilation with pthreads is supported there
+! { dg-do run }
+program main
+ integer :: i
+ open (10,file="tst.dat")
+ write (10,'(A4)') 'asdf'
+ close(10)
+ i = 234
+ open(10,file="tst.dat", asynchronous="yes")
+ read (10,'(I4)',asynchronous="yes") i
+ wait(10)
+end program main
+! { dg-output "Fortran runtime error: Bad value during integer read" }
+! { dg-final { remote_file build delete "tst.dat" } }
diff --git a/libgomp/testsuite/libgomp.fortran/async_io_4.f90 b/libgomp/testsuite/libgomp.fortran/async_io_4.f90
new file mode 100644
index 00000000000..1ff76b4f162
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/async_io_4.f90
@@ -0,0 +1,90 @@
+! { dg-do run { target fd_truncate } }
+!TODO: Move these testcases to gfortran testsuite
+! once compilation with pthreads is supported there
+
+! Test BACKSPACE for synchronous and asynchronous I/O
+program main
+
+ integer i, n, nr
+ real x(10), y(10)
+
+ ! PR libfortran/20068
+ open (20, status='scratch', asynchronous="yes")
+ write (20,*, asynchronous="yes" ) 1
+ write (20,*, asynchronous="yes") 2
+ write (20,*, asynchronous="yes") 3
+ rewind (20)
+ i = 41
+ read (20,*, asynchronous="yes") i
+ wait (20)
+ if (i .ne. 1) stop 1
+ write (*,*) ' '
+ backspace (20)
+ i = 42
+ read (20,*, asynchronous="yes") i
+ close (20)
+ if (i .ne. 1) stop 2
+
+ ! PR libfortran/20125
+ open (20, status='scratch', asynchronous="yes")
+ write (20,*, asynchronous="yes") 7
+ backspace (20)
+ read (20,*, asynchronous="yes") i
+ wait (20)
+ if (i .ne. 7) stop 3
+ close (20)
+
+ open (20, status='scratch', form='unformatted')
+ write (20) 8
+ backspace (20)
+ read (20) i
+ if (i .ne. 8) stop 4
+ close (20)
+
+ ! PR libfortran/20471
+ do n = 1, 10
+ x(n) = sqrt(real(n))
+ end do
+ open (3, form='unformatted', status='scratch')
+ write (3) (x(n),n=1,10)
+ backspace (3)
+ rewind (3)
+ read (3) (y(n),n=1,10)
+
+ do n = 1, 10
+ if (abs(x(n)-y(n)) > 0.00001) stop 5
+ end do
+ close (3)
+
+ ! PR libfortran/20156
+ open (3, form='unformatted', status='scratch')
+ do i = 1, 5
+ x(1) = i
+ write (3) n, (x(n),n=1,10)
+ end do
+ nr = 0
+ rewind (3)
+20 continue
+ read (3,end=30,err=90) n, (x(n),n=1,10)
+ nr = nr + 1
+ goto 20
+30 continue
+ if (nr .ne. 5) stop 6
+
+ do i = 1, nr+1
+ backspace (3)
+ end do
+
+ do i = 1, nr
+ read(3,end=70,err=90) n, (x(n),n=1,10)
+ if (abs(x(1) - i) .gt. 0.001) stop 7
+ end do
+ close (3)
+ stop
+
+70 continue
+ stop 8
+90 continue
+ stop 9
+
+end program
diff --git a/libgomp/testsuite/libgomp.fortran/async_io_5.f90 b/libgomp/testsuite/libgomp.fortran/async_io_5.f90
new file mode 100644
index 00000000000..56487bbd3fa
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/async_io_5.f90
@@ -0,0 +1,132 @@
+! { dg-do run }
+!TODO: Move these testcases to gfortran testsuite
+! once compilation with pthreads is supported there
+! PR55818 Reading a REAL from a file which doesn't end in a new line fails
+! Test case from PR reporter.
+implicit none
+integer :: stat
+!integer :: var ! << works
+real :: var ! << fails
+character(len=10) :: cvar ! << fails
+complex :: cval
+logical :: lvar
+
+open(99, file="test.dat", access="stream", form="unformatted", status="new")
+write(99) "1", new_line("")
+write(99) "2", new_line("")
+write(99) "3"
+close(99)
+
+! Test character kind
+open(99, file="test.dat")
+read (99,*, iostat=stat) cvar
+if (stat /= 0 .or. cvar /= "1") stop 1
+read (99,*, iostat=stat) cvar
+if (stat /= 0 .or. cvar /= "2") stop 2
+read (99,*, iostat=stat) cvar ! << FAILS: stat /= 0
+if (stat /= 0 .or. cvar /= "3") stop 3 ! << aborts here
+
+! Test real kind
+rewind(99)
+read (99,*, iostat=stat) var
+if (stat /= 0 .or. var /= 1.0) stop 4
+read (99,*, iostat=stat) var
+if (stat /= 0 .or. var /= 2.0) stop 5
+read (99,*, iostat=stat) var ! << FAILS: stat /= 0
+if (stat /= 0 .or. var /= 3.0) stop 6
+close(99, status="delete")
+
+! Test real kind with exponents
+open(99, file="test.dat", access="stream", form="unformatted", status="new")
+write(99) "1.0e3", new_line("")
+write(99) "2.0e-03", new_line("")
+write(99) "3.0e2"
+close(99)
+
+open(99, file="test.dat")
+read (99,*, iostat=stat) var
+if (stat /= 0) stop 7
+read (99,*, iostat=stat) var
+if (stat /= 0) stop 8
+read (99,*) var ! << FAILS: stat /= 0
+if (stat /= 0) stop 9
+close(99, status="delete")
+
+! Test logical kind
+open(99, file="test.dat", access="stream", form="unformatted", status="new")
+write(99) "Tru", new_line("")
+write(99) "fal", new_line("")
+write(99) "t"
+close(99)
+
+open(99, file="test.dat")
+read (99,*, iostat=stat) lvar
+if (stat /= 0 .or. (.not.lvar)) stop 10
+read (99,*, iostat=stat) lvar
+if (stat /= 0 .or. lvar) stop 11
+read (99,*) lvar ! << FAILS: stat /= 0
+if (stat /= 0 .or. (.not.lvar)) stop 12
+close(99, status="delete")
+
+! Test combinations of Inf and Nan
+open(99, file="test.dat", access="stream", form="unformatted", status="new")
+write(99) "infinity", new_line("")
+write(99) "nan", new_line("")
+write(99) "infinity"
+close(99)
+
+open(99, file="test.dat")
+read (99,*, iostat=stat) var
+if (stat /= 0) stop 13
+read (99,*, iostat=stat) var
+if (stat /= 0) stop 14
+read (99,*) var ! << FAILS: stat /= 0
+if (stat /= 0) stop 1! << aborts here
+close(99, status="delete")
+
+open(99, file="test.dat", access="stream", form="unformatted", status="new")
+write(99) "infinity", new_line("")
+write(99) "inf", new_line("")
+write(99) "nan"
+close(99)
+
+open(99, file="test.dat")
+read (99,*, iostat=stat) var
+if (stat /= 0) stop 15
+read (99,*, iostat=stat) var
+if (stat /= 0) stop 16
+read (99,*) var ! << FAILS: stat /= 0
+if (stat /= 0) stop 2! << aborts here
+close(99, status="delete")
+
+open(99, file="test.dat", access="stream", form="unformatted", status="new")
+write(99) "infinity", new_line("")
+write(99) "nan", new_line("")
+write(99) "inf"
+close(99)
+
+open(99, file="test.dat")
+read (99,*, iostat=stat) var
+if (stat /= 0) stop 17
+read (99,*, iostat=stat) var
+if (stat /= 0) stop 18
+read (99,*) var ! << FAILS: stat /= 0
+if (stat /= 0) stop 3! << aborts here
+close(99, status="delete")
+
+! Test complex kind
+open(99, file="test.dat", access="stream", form="unformatted", status="new")
+write(99) "(1,2)", new_line("")
+write(99) "(2,3)", new_line("")
+write(99) "(4,5)"
+close(99)
+
+open(99, file="test.dat")
+read (99,*, iostat=stat) cval
+if (stat /= 0 .or. cval /= cmplx(1,2)) stop 19
+read (99,*, iostat=stat) cval
+if (stat /= 0 .or. cval /= cmplx(2,3)) stop 20
+read (99,*, iostat=stat) cval ! << FAILS: stat /= 0, value is okay
+if (stat /= 0 .or. cval /= cmplx(4,5)) stop 21
+close(99, status="delete")
+end
diff --git a/libgomp/testsuite/libgomp.fortran/async_io_6.f90 b/libgomp/testsuite/libgomp.fortran/async_io_6.f90
new file mode 100644
index 00000000000..75f5ca7a2af
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/async_io_6.f90
@@ -0,0 +1,30 @@
+! { dg-do run }
+!TODO: Move these testcases to gfortran testsuite
+! once compilation with pthreads is supported there
+! PR 22390 Implement flush statement
+program flush_1
+
+ character(len=256) msg
+ integer ios
+
+ open (unit=10, access='SEQUENTIAL', status='SCRATCH')
+
+ write (10, *) 42
+ flush 10
+
+ write (10, *) 42
+ flush(10)
+
+ write (10, *) 42
+ flush(unit=10, iostat=ios)
+ if (ios /= 0) stop 1
+
+ write (10, *) 42
+ flush (unit=10, err=20)
+ goto 30
+20 stop 2
+30 continue
+
+ call flush(10)
+
+end program flush_1
diff --git a/libgomp/testsuite/libgomp.fortran/async_io_7.f90 b/libgomp/testsuite/libgomp.fortran/async_io_7.f90
new file mode 100644
index 00000000000..0c8dd1b8056
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/async_io_7.f90
@@ -0,0 +1,22 @@
+! { dg-do run }
+!TODO: Move these testcases to gfortran testsuite
+! once compilation with pthreads is supported there
+! PR40008 F2008: Add NEWUNIT= for OPEN statement
+! Contributed by Jerry DeLisle <jvdelisle@gcc.gnu.org>
+program newunit_1
+ character(len=25) :: str
+ integer(1) :: myunit, myunit2
+ myunit = 25
+ str = "bad"
+ open(newunit=myunit, status="scratch")
+ open(newunit = myunit2, file="newunit_1file")
+ write(myunit,'(e24.15e2)') 1.0d0
+ write(myunit2,*) "abcdefghijklmnop"
+ flush(myunit)
+ rewind(myunit)
+ rewind(myunit2)
+ read(myunit2,'(a)') str
+ if (str.ne." abcdefghijklmnop") stop 1
+ close(myunit)
+ close(myunit2, status="delete")
+end program newunit_1
diff --git a/libgomp/testsuite/libgomp.fortran/async_io_8.f90 b/libgomp/testsuite/libgomp.fortran/async_io_8.f90
new file mode 100644
index 00000000000..f5ae93dc3a8
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/async_io_8.f90
@@ -0,0 +1,30 @@
+! { dg-do run }
+! PR libfortran/88411
+! This used to generate errors due to a mixup of
+! synchronous and asynchronous execution.
+! Test case by Harald Anlauf.
+program gfcbug153
+ implicit none
+ integer :: iu, irecl
+ real :: a(100,20), b(1,3000)
+ iu = 10
+ a = 0.
+ b = 0.
+ inquire (iolength = irecl) a
+ open (iu, file="file1.dat", access='direct', &
+ asynchronous='yes', &
+ recl=irecl)
+ write(iu, rec=1) a(:,:)
+ write(iu, rec=2) a(:,:)
+ write(iu, rec=3) a(:,:)
+ close (iu,status="delete")
+
+ inquire (iolength = irecl) b
+ open (iu, file="file2.dat", access='direct', &
+ asynchronous='yes', &
+ recl=irecl)
+ write(iu, rec=1) b(:,:)
+ write(iu, rec=2) b(:,:)
+ write(iu, rec=3) b(:,:)
+ close (iu,status="delete")
+end program
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-do-1.f90 b/libgomp/testsuite/libgomp.fortran/cancel-do-1.f90
index 84009ec2ac9..1c44e25d77d 100644
--- a/libgomp/testsuite/libgomp.fortran/cancel-do-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/cancel-do-1.f90
@@ -8,7 +8,7 @@
!$omp do
do i = 0, 999
!$omp cancel do
- if (omp_get_cancellation ()) STOP 1
+ if (omp_get_cancellation ()) stop 1
enddo
!$omp endparallel
end
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-do-2.f90 b/libgomp/testsuite/libgomp.fortran/cancel-do-2.f90
index 9d8e91cec98..b5cca934291 100644
--- a/libgomp/testsuite/libgomp.fortran/cancel-do-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/cancel-do-2.f90
@@ -22,7 +22,7 @@ contains
!$omp do
do i = 0, 999
!$omp cancel do if (x(1))
- STOP 1
+ stop 1
end do
!$omp do
do i = 0, 999
@@ -47,7 +47,7 @@ contains
end do
!$omp end do
!$omp end parallel
- if (v.ne.3000.or.w.ne.0) STOP 2
+ if (v.ne.3000.or.w.ne.0) stop 2
!$omp parallel num_threads (32) shared (v, w)
! None of these cancel directives should actually cancel anything,
! but the compiler shouldn't know that and thus should use cancellable
@@ -56,7 +56,7 @@ contains
!$omp do
do i = 0, 999
!$omp cancel do if (x(1))
- STOP 3
+ stop 3
end do
!$omp cancel parallel if (omp_get_thread_num ().eq.2.and.x(5))
!$omp do
@@ -85,6 +85,6 @@ contains
!$omp end do
!$omp cancel parallel if (omp_get_thread_num ().eq.5.and.x(5))
!$omp end parallel
- if (v.ne.6000.or.w.ne.0) STOP 4
+ if (v.ne.6000.or.w.ne.0) stop 4
end subroutine
end
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-parallel-1.f90 b/libgomp/testsuite/libgomp.fortran/cancel-parallel-1.f90
index dc0f69b13ed..759870189ef 100644
--- a/libgomp/testsuite/libgomp.fortran/cancel-parallel-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/cancel-parallel-1.f90
@@ -5,6 +5,6 @@
!$omp parallel num_threads(32)
!$omp cancel parallel
- if (omp_get_cancellation ()) STOP 1
+ if (omp_get_cancellation ()) stop 1
!$omp end parallel
end
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-sections-1.f90 b/libgomp/testsuite/libgomp.fortran/cancel-sections-1.f90
index 7e1d4b37534..cfc3903592f 100644
--- a/libgomp/testsuite/libgomp.fortran/cancel-sections-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/cancel-sections-1.f90
@@ -7,16 +7,16 @@
!$omp parallel num_threads(32)
!$omp sections
!$omp cancel sections
- STOP 1
+ stop 1
!$omp section
!$omp cancel sections
- STOP 2
+ stop 2
!$omp section
!$omp cancel sections
- STOP 3
+ stop 3
!$omp section
!$omp cancel sections
- STOP 4
+ stop 4
!$omp end sections
!$omp end parallel
end if
diff --git a/libgomp/testsuite/libgomp.fortran/cancel-taskgroup-2.f90 b/libgomp/testsuite/libgomp.fortran/cancel-taskgroup-2.f90
index 54c52208b97..693241ef71c 100644
--- a/libgomp/testsuite/libgomp.fortran/cancel-taskgroup-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/cancel-taskgroup-2.f90
@@ -8,7 +8,7 @@
!$omp taskgroup
!$omp task
!$omp cancel taskgroup
- STOP 1
+ stop 1
!$omp endtask
!$omp endtaskgroup
!$omp endparallel
diff --git a/libgomp/testsuite/libgomp.fortran/character1.f90 b/libgomp/testsuite/libgomp.fortran/character1.f90
index a672b7d2fdc..eb3c21d068d 100644
--- a/libgomp/testsuite/libgomp.fortran/character1.f90
+++ b/libgomp/testsuite/libgomp.fortran/character1.f90
@@ -67,6 +67,6 @@ contains
l = l .or. f .ne. 'YY' .or. p .ne. 'm3' .or. r .ne. 'M3'
end if
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end subroutine test
end
diff --git a/libgomp/testsuite/libgomp.fortran/character2.f90 b/libgomp/testsuite/libgomp.fortran/character2.f90
index 20a3f07c4b3..67ce63ac624 100644
--- a/libgomp/testsuite/libgomp.fortran/character2.f90
+++ b/libgomp/testsuite/libgomp.fortran/character2.f90
@@ -56,6 +56,6 @@ contains
l = l .or. t .ne. '456'
end if
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end subroutine test
end
diff --git a/libgomp/testsuite/libgomp.fortran/collapse1.f90 b/libgomp/testsuite/libgomp.fortran/collapse1.f90
index 3777b520245..c22085599c2 100644
--- a/libgomp/testsuite/libgomp.fortran/collapse1.f90
+++ b/libgomp/testsuite/libgomp.fortran/collapse1.f90
@@ -22,5 +22,5 @@ program collapse1
end do
end do
!$omp end parallel do
- if (l) STOP 1
+ if (l) stop 1
end program collapse1
diff --git a/libgomp/testsuite/libgomp.fortran/collapse2.f90 b/libgomp/testsuite/libgomp.fortran/collapse2.f90
index 32d9fdd816f..47cd7c9e580 100644
--- a/libgomp/testsuite/libgomp.fortran/collapse2.f90
+++ b/libgomp/testsuite/libgomp.fortran/collapse2.f90
@@ -25,7 +25,7 @@ firstdo: do i = 1, 3
end do
end do firstdo
!$omp end parallel do
- if (l) STOP 1
+ if (l) stop 1
end subroutine test1
subroutine test2
@@ -38,7 +38,7 @@ firstdo: do i = 1, 3
enddo
enddo dokk
115 continue
- if (any(a(1:3,1:3,1:3).ne.1)) STOP 2
+ if (any(a(1:3,1:3,1:3).ne.1)) stop 2
!$omp do collapse(3)
dol: do 120 l=1,3
@@ -48,7 +48,7 @@ firstdo: do i = 1, 3
enddo
enddo doll
120 end do dol
- if (any(a(1:3,1:3,1:3).ne.2)) STOP 3
+ if (any(a(1:3,1:3,1:3).ne.2)) stop 3
end subroutine test2
end program collapse2
diff --git a/libgomp/testsuite/libgomp.fortran/collapse3.f90 b/libgomp/testsuite/libgomp.fortran/collapse3.f90
index 001dc2ac630..d463b4f39cc 100644
--- a/libgomp/testsuite/libgomp.fortran/collapse3.f90
+++ b/libgomp/testsuite/libgomp.fortran/collapse3.f90
@@ -24,8 +24,8 @@ contains
end do
end do
end do
- if (i.ne.7.or.j.ne.5.or.k.ne.19) STOP 1
- if (m.ne.(600+40+18)) STOP 2
+ if (i.ne.7.or.j.ne.5.or.k.ne.19) stop 1
+ if (m.ne.(600+40+18)) stop 2
do i = 1, 7
do j = -3, 5
do k = 12, 19
@@ -56,8 +56,8 @@ contains
end do
end do
end do
- if (i.ne.7.or.j.ne.5.or.k.ne.19) STOP 3
- if (m.ne.(600+40+18)) STOP 4
+ if (i.ne.7.or.j.ne.5.or.k.ne.19) stop 3
+ if (m.ne.(600+40+18)) stop 4
do i = 1, 7
do j = -3, 5
do k = 12, 19
@@ -88,8 +88,8 @@ contains
end do
end do
end do
- if (i.ne.7.or.j.ne.5.or.k.ne.19) STOP 5
- if (m.ne.(600+40+18)) STOP 6
+ if (i.ne.7.or.j.ne.5.or.k.ne.19) stop 5
+ if (m.ne.(600+40+18)) stop 6
do i = 1, 7
do j = -3, 5
do k = 12, 19
@@ -120,8 +120,8 @@ contains
end do
end do
end do
- if (i.ne.7.or.j.ne.5.or.k.ne.19) STOP 7
- if (m.ne.(600+40+18)) STOP 8
+ if (i.ne.7.or.j.ne.5.or.k.ne.19) stop 7
+ if (m.ne.(600+40+18)) stop 8
do i = 1, 7
do j = -3, 5
do k = 12, 19
@@ -153,8 +153,8 @@ contains
end do
end do
end do
- if (i.ne.7.or.j.ne.5.or.k.ne.19) STOP 9
- if (m.ne.(600+40+18)) STOP 10
+ if (i.ne.7.or.j.ne.5.or.k.ne.19) stop 9
+ if (m.ne.(600+40+18)) stop 10
do i = 1, 7
do j = -3, 5
do k = 12, 19
@@ -186,8 +186,8 @@ contains
end do
end do
end do
- if (i.ne.7.or.j.ne.5.or.k.ne.19) STOP 11
- if (m.ne.(600+40+18)) STOP 12
+ if (i.ne.7.or.j.ne.5.or.k.ne.19) stop 11
+ if (m.ne.(600+40+18)) stop 12
do i = 1, 7
do j = -3, 5
do k = 12, 19
diff --git a/libgomp/testsuite/libgomp.fortran/collapse4.f90 b/libgomp/testsuite/libgomp.fortran/collapse4.f90
index 2019d8dcccd..8c28571975b 100644
--- a/libgomp/testsuite/libgomp.fortran/collapse4.f90
+++ b/libgomp/testsuite/libgomp.fortran/collapse4.f90
@@ -8,5 +8,5 @@
end do
end do
end do
- if (i .ne. 18 .or. j .ne. 7 .or. k .ne. 6) STOP 1
+ if (i .ne. 18 .or. j .ne. 7 .or. k .ne. 6) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/crayptr1.f90 b/libgomp/testsuite/libgomp.fortran/crayptr1.f90
index 28e2aa62d80..2340257f3f6 100644
--- a/libgomp/testsuite/libgomp.fortran/crayptr1.f90
+++ b/libgomp/testsuite/libgomp.fortran/crayptr1.f90
@@ -26,7 +26,7 @@
l = l .or. p .ne. 3
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
l = .false.
!$omp parallel num_threads (2) reduction (.or.:l) default (private)
@@ -41,6 +41,6 @@
l = l .or. p .ne. 3 * omp_get_thread_num () + 5
!$omp end parallel
- if (l) STOP 2
+ if (l) stop 2
end
diff --git a/libgomp/testsuite/libgomp.fortran/crayptr2.f90 b/libgomp/testsuite/libgomp.fortran/crayptr2.f90
index 2847de92e37..3014be832a3 100644
--- a/libgomp/testsuite/libgomp.fortran/crayptr2.f90
+++ b/libgomp/testsuite/libgomp.fortran/crayptr2.f90
@@ -27,5 +27,5 @@
l = l .or. (p .ne. d + 1)
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/crayptr3.f90 b/libgomp/testsuite/libgomp.fortran/crayptr3.f90
index bb48f9e7371..2d360fa5a8b 100644
--- a/libgomp/testsuite/libgomp.fortran/crayptr3.f90
+++ b/libgomp/testsuite/libgomp.fortran/crayptr3.f90
@@ -18,7 +18,7 @@
l = l .or. (p .ne. (2 + omp_get_thread_num ()))
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
l = .false.
ip = loc (a)
@@ -31,6 +31,6 @@
l = l .or. (p .ne. (2 + i))
end do
- if (l) STOP 2
- if (p .ne. 3) STOP 3
+ if (l) stop 2
+ if (p .ne. 3) stop 3
end
diff --git a/libgomp/testsuite/libgomp.fortran/declare-simd-1.f90 b/libgomp/testsuite/libgomp.fortran/declare-simd-1.f90
index c5b021dd951..cb8f4df8d62 100644
--- a/libgomp/testsuite/libgomp.fortran/declare-simd-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/declare-simd-1.f90
@@ -61,7 +61,7 @@ end module declare_simd_1_mod
do i = 1, 128
b(i) = bar (a(i), 2 * i, b(i))
end do
- if (any (b.ne.d)) STOP 1
+ if (any (b.ne.d)) stop 1
!$omp simd
do i = 1, 128
b(i) = i * 2.0
@@ -71,7 +71,7 @@ end module declare_simd_1_mod
b(i) = baz (7.0_8, 2, b(i))
end do
do i = 1, 128
- if (b(i).ne.(7.0 + 4.0 * i)) STOP 2
+ if (b(i).ne.(7.0 + 4.0 * i)) stop 2
end do
contains
function baz (x, y, z)
diff --git a/libgomp/testsuite/libgomp.fortran/declare-simd-3.f90 b/libgomp/testsuite/libgomp.fortran/declare-simd-3.f90
index 85cea9cab0a..3a20e0aad70 100644
--- a/libgomp/testsuite/libgomp.fortran/declare-simd-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/declare-simd-3.f90
@@ -17,6 +17,6 @@ subroutine bar
b(i) = foo (7.0_8, 5 * i, b(i))
end do
do i = 1, 128
- if (b(i).ne.(7.0 + 10.0 * i * i)) STOP 1
+ if (b(i).ne.(7.0 + 10.0 * i * i)) stop 1
end do
end subroutine bar
diff --git a/libgomp/testsuite/libgomp.fortran/declare-target-2.f90 b/libgomp/testsuite/libgomp.fortran/declare-target-2.f90
index 1fbc0dc0cb7..85fc68c6ede 100644
--- a/libgomp/testsuite/libgomp.fortran/declare-target-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/declare-target-2.f90
@@ -14,5 +14,5 @@ subroutine foo
!$omp end target
!$omp target update from(var_x)
- if (var_x /= 20) STOP 1
+ if (var_x /= 20) stop 1
end subroutine foo
diff --git a/libgomp/testsuite/libgomp.fortran/depend-1.f90 b/libgomp/testsuite/libgomp.fortran/depend-1.f90
index 5f7bb5faf21..85792fa9b4b 100644
--- a/libgomp/testsuite/libgomp.fortran/depend-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/depend-1.f90
@@ -21,7 +21,7 @@ contains
x = 2
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 1
+ if (x.ne.2) stop 1
!$omp end task
!$omp end single
!$omp end parallel
@@ -36,7 +36,7 @@ contains
x = 2
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 2
+ if (x.ne.2) stop 2
!$omp end task
!$omp taskwait
!$omp end single
@@ -52,7 +52,7 @@ contains
x = 2
!$omp endtask
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 3
+ if (x.ne.2) stop 3
!$omp endtask
!$omp endsingle
!$omp endparallel
@@ -67,7 +67,7 @@ contains
x = 2
!$omp end task
!$omp task depend(in: x)
- if (x.ne.1) STOP 4
+ if (x.ne.1) stop 4
!$omp end task
!$omp end single
!$omp end parallel
@@ -79,7 +79,7 @@ contains
!$omp parallel
!$omp single
!$omp task shared(x) depend(in: x)
- if (x.ne.1) STOP 5
+ if (x.ne.1) stop 5
!$omp end task
!$omp task shared(x) depend(out: x)
x = 2
@@ -95,7 +95,7 @@ contains
x = 1
!$omp taskgroup
!$omp task shared(x) depend(in: x)
- if (x.ne.1) STOP 6
+ if (x.ne.1) stop 6
!$omp end task
!$omp task shared(x) depend(out: x)
x = 2
@@ -111,7 +111,7 @@ contains
x = 1
!$omp single
!$omp task shared(x) depend(in: x)
- if (x.ne.1) STOP 7
+ if (x.ne.1) stop 7
!$omp end task
!$omp task shared(x) depend(out: x)
x = 2
@@ -132,7 +132,7 @@ contains
x = 2
!$omp end task
!$omp taskwait
- if (x.ne.2) STOP 8
+ if (x.ne.2) stop 8
!$omp end single
!$omp end parallel
end subroutine outdep
@@ -146,13 +146,13 @@ contains
x = 2
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 9
+ if (x.ne.2) stop 9
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 10
+ if (x.ne.2) stop 10
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 11
+ if (x.ne.2) stop 11
!$omp end task
!$omp end single
!$omp end parallel
@@ -167,13 +167,13 @@ contains
x = 2;
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 12
+ if (x.ne.2) stop 12
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 13
+ if (x.ne.2) stop 13
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 14
+ if (x.ne.2) stop 14
!$omp end task
!$omp taskwait
!$omp end single
@@ -189,13 +189,13 @@ contains
x = 2
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 15
+ if (x.ne.2) stop 15
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 16
+ if (x.ne.2) stop 16
!$omp end task
!$omp task shared (x) depend(in: x)
- if (x.ne.2) STOP 17
+ if (x.ne.2) stop 17
!$omp end task
!$omp end single
!$omp end parallel
diff --git a/libgomp/testsuite/libgomp.fortran/depend-2.f90 b/libgomp/testsuite/libgomp.fortran/depend-2.f90
index b53ba0795e6..4384c1f760e 100644
--- a/libgomp/testsuite/libgomp.fortran/depend-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/depend-2.f90
@@ -6,7 +6,7 @@
!$omp single
!$omp taskgroup
!$omp task depend(in: x(:, :))
- if (y.ne.1) STOP 1
+ if (y.ne.1) stop 1
!$omp end task
!$omp task depend(out: x(:, :))
y = 2
@@ -14,7 +14,7 @@
!$omp end taskgroup
!$omp taskgroup
!$omp task depend(in: x(4, 7))
- if (y.ne.2) STOP 2
+ if (y.ne.2) stop 2
!$omp end task
!$omp task depend(out: x(4:4, 7:7))
y = 3
@@ -22,7 +22,7 @@
!$omp end taskgroup
!$omp taskgroup
!$omp task depend(in: x(4:, 8:))
- if (y.ne.3) STOP 3
+ if (y.ne.3) stop 3
!$omp end task
!$omp task depend(out: x(4:6, 8:12))
y = 4
@@ -30,5 +30,5 @@
!$omp end taskgroup
!$omp end single
!$omp end parallel
- if (y.ne.4) STOP 4
+ if (y.ne.4) stop 4
end
diff --git a/libgomp/testsuite/libgomp.fortran/depend-3.f90 b/libgomp/testsuite/libgomp.fortran/depend-3.f90
index 09478da4134..aa948edd916 100644
--- a/libgomp/testsuite/libgomp.fortran/depend-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/depend-3.f90
@@ -13,7 +13,7 @@ contains
!$omp single
!$omp taskgroup
!$omp task depend(in: x)
- if (y.ne.1) STOP 1
+ if (y.ne.1) stop 1
!$omp end task
!$omp task depend(out: x(1:2, 1:3))
y = 2
@@ -21,7 +21,7 @@ contains
!$omp end taskgroup
!$omp taskgroup
!$omp task depend(in: z)
- if (y.ne.2) STOP 2
+ if (y.ne.2) stop 2
!$omp end task
!$omp task depend(out: z(-2:3, 2:4))
y = 3
@@ -29,7 +29,7 @@ contains
!$omp end taskgroup
!$omp taskgroup
!$omp task depend(in: x)
- if (y.ne.3) STOP 3
+ if (y.ne.3) stop 3
!$omp end task
!$omp task depend(out: x(1:, 1:))
y = 4
@@ -37,6 +37,6 @@ contains
!$omp end taskgroup
!$omp end single
!$omp end parallel
- if (y.ne.4) STOP 4
+ if (y.ne.4) stop 4
end subroutine
end
diff --git a/libgomp/testsuite/libgomp.fortran/display-affinity-1.f90 b/libgomp/testsuite/libgomp.fortran/display-affinity-1.f90
new file mode 100644
index 00000000000..4811b6f801b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/display-affinity-1.f90
@@ -0,0 +1,34 @@
+! { dg-set-target-env-var OMP_PROC_BIND "spread,close" }
+! { dg-set-target-env-var OMP_PLACES "cores" }
+! { dg-set-target-env-var OMP_NUM_THREADS "4" }
+! { dg-set-target-env-var OMP_AFFINITY_FORMAT "hello" }
+
+ use omp_lib
+ character(len=68) :: buf, buf2
+ character(len=8) :: buf3
+ character(len=1) :: buf4
+ integer :: l1, l2
+
+ buf = 'L:%0.5L%%%n>%32H<!%.33{host}!%.6P_%i_%0.18i_%0.7{ancestor_tnum} %18A'
+ call omp_set_affinity_format (format = buf)
+ if (omp_get_affinity_format (buf4) /= 68) stop 1
+ if (buf4 /= 'L') stop 2
+ if (omp_get_affinity_format (buf2) /= 68) stop 3
+ if (buf2 /= buf) stop 4
+ if (omp_get_affinity_format (buf3) /= 68) stop 5
+ if (buf3 /= 'L:%0.5L%') stop 6
+ call omp_display_affinity ('')
+ call omp_display_affinity ('%%%0.9N')
+ l1 = omp_capture_affinity (buf4, '%0.5{nesting_level}%%|||%0.7a%3N!%N!')
+ buf = '%.5L%%|||%0.7{ancestor_tnum}%3{num_threads}!%{num_threads}!'
+ call omp_set_affinity_format (trim (buf))
+ l2 = omp_capture_affinity (buf2, '')
+ if (l1 /= l2) stop 7
+ if (l1 /= 22) stop 8
+ if (buf2 /= ' 0%|||-0000011 !1!') stop 9
+ if (buf4 /= '0') stop 10
+!$omp parallel num_threads (4) proc_bind(spread)
+ call omp_display_affinity ('%0.2a!%n!%.4L!%N;%.2t;%0.2T;&
+ &%{team_num};%{num_teams};%A')
+!$omp end parallel
+end
diff --git a/libgomp/testsuite/libgomp.fortran/do1.f90 b/libgomp/testsuite/libgomp.fortran/do1.f90
index bb7b6d83e14..e85f6371a9b 100644
--- a/libgomp/testsuite/libgomp.fortran/do1.f90
+++ b/libgomp/testsuite/libgomp.fortran/do1.f90
@@ -47,7 +47,7 @@
!$omp end parallel
- if (any (a .ne. b)) STOP 1
+ if (any (a .ne. b)) stop 1
a = -1
!$omp parallel num_threads (4)
@@ -79,7 +79,7 @@
!$omp end parallel
- if (any (a .ne. b)) STOP 2
+ if (any (a .ne. b)) stop 2
a = -1
!$omp parallel num_threads (4)
@@ -111,7 +111,7 @@
!$omp end parallel
- if (any (a .ne. b)) STOP 3
+ if (any (a .ne. b)) stop 3
a = -1
!$omp parallel num_threads (4)
@@ -143,7 +143,7 @@
!$omp end parallel
- if (any (a .ne. b)) STOP 4
+ if (any (a .ne. b)) stop 4
a = -1
!$omp parallel num_threads (4)
@@ -175,5 +175,5 @@
!$omp end parallel
- if (any (a .ne. b)) STOP 5
+ if (any (a .ne. b)) stop 5
end
diff --git a/libgomp/testsuite/libgomp.fortran/do2.f90 b/libgomp/testsuite/libgomp.fortran/do2.f90
index 11e3b8cec11..b6081831b1f 100644
--- a/libgomp/testsuite/libgomp.fortran/do2.f90
+++ b/libgomp/testsuite/libgomp.fortran/do2.f90
@@ -86,7 +86,7 @@
!$omp end parallel
- if (any (a .ne. b) .or. k) STOP 1
+ if (any (a .ne. b) .or. k) stop 1
a = -1
k = .false.
j = 8
@@ -155,7 +155,7 @@
!$omp end parallel
- if (any (a .ne. b) .or. k) STOP 2
+ if (any (a .ne. b) .or. k) stop 2
a = -1
k = .false.
j = 8
@@ -224,7 +224,7 @@
!$omp end parallel
- if (any (a .ne. b) .or. k) STOP 3
+ if (any (a .ne. b) .or. k) stop 3
a = -1
k = .false.
j = 8
@@ -293,7 +293,7 @@
!$omp end parallel
- if (any (a .ne. b) .or. k) STOP 4
+ if (any (a .ne. b) .or. k) stop 4
a = -1
k = .false.
j = 8
@@ -362,5 +362,5 @@
!$omp end parallel
- if (any (a .ne. b) .or. k) STOP 5
+ if (any (a .ne. b) .or. k) stop 5
end
diff --git a/libgomp/testsuite/libgomp.fortran/do_concurrent_5.f90 b/libgomp/testsuite/libgomp.fortran/do_concurrent_5.f90
index 6fb9d1e8d96..971cd634a5f 100644
--- a/libgomp/testsuite/libgomp.fortran/do_concurrent_5.f90
+++ b/libgomp/testsuite/libgomp.fortran/do_concurrent_5.f90
@@ -33,7 +33,7 @@ program main
do concurrent (i = 1:nsplit)
pi(i) = sum(compute( low(i), high(i) ))
end do
- if (abs (sum(pi) - atan(1.0d0)) > 1e-5) STOP 1
+ if (abs (sum(pi) - atan(1.0d0)) > 1e-5) stop 1
contains
diff --git a/libgomp/testsuite/libgomp.fortran/doacross1.f90 b/libgomp/testsuite/libgomp.fortran/doacross1.f90
index e3beda05e89..2b15e7d7d11 100644
--- a/libgomp/testsuite/libgomp.fortran/doacross1.f90
+++ b/libgomp/testsuite/libgomp.fortran/doacross1.f90
@@ -17,14 +17,14 @@
if (i.gt.1) then
!$omp atomic read
l = a(i - 1)
- if (l.lt.2) STOP 1
+ if (l.lt.2) stop 1
end if
!$omp atomic write
a(i) = 2
if (i.lt.N) then
!$omp atomic read
l = a(i + 1)
- if (l.eq.3) STOP 2
+ if (l.eq.3) stop 2
end if
!$omp ordered depend(source)
!$omp atomic write
@@ -43,19 +43,19 @@
if (j.gt.2.and.k.gt.2) then
!$omp atomic read
l = b(i,j-2,k-1)
- if (l.lt.2) STOP 3
+ if (l.lt.2) stop 3
end if
!$omp atomic write
b(i,j,k) = 2
if (i.gt.4.and.j.gt.2.and.k.lt.4) then
!$omp atomic read
l = b(i-2,j-2, k+1)
- if (l.lt.2) STOP 4
+ if (l.lt.2) stop 4
end if
if (i.gt.5.and.j.le.N/16-3.and.k.eq.4) then
!$omp atomic read
l = b( i - 3, j+2, k-2)
- if (l.lt.2) STOP 5
+ if (l.lt.2) stop 5
end if
!$omp ordered depend(source)
!$omp atomic write
@@ -94,19 +94,19 @@
if (k.le.5) then
!$omp atomic read
l = c(i, j, k + 2)
- if (l.lt.2) STOP 6
+ if (l.lt.2) stop 6
end if
!$omp atomic write
c(i, j, k) = 2
if (i.ge.3.and.j.lt.8.and.k.ge.5) then
!$omp atomic read
l = c(i - 2, j + 1, k - 4)
- if (l.lt.2) STOP 7
+ if (l.lt.2) stop 7
end if
if (i.ge.2.and.j.ge.5.and.k.ge.3) then
!$omp atomic read
l = c(i - 1, j - 2, k - 2)
- if (l.lt.2) STOP 8
+ if (l.lt.2) stop 8
end if
!$omp ordered depend ( source )
!$omp atomic write
@@ -137,13 +137,13 @@
do l = 0, d + 1
!$omp ordered depend(source)
!$omp ordered depend(sink: i-2,j+2,k-2,l)
- if (e.eq.0) STOP 9
+ if (e.eq.0) stop 9
end do
end do
end do
end do
!$omp single
- if (i.ne.1.or.j.ne.-1.or.k.ne.0) STOP 10
+ if (i.ne.1.or.j.ne.-1.or.k.ne.0) stop 10
i = 8; j = 9; k = 10
!$omp end single
!$omp do ordered(4) collapse(2) lastprivate (i, j, k, m)
@@ -153,13 +153,13 @@
do m = 0, d-1
!$omp ordered depend(source)
!$omp ordered depend(sink: i - 2, j + 2, k - 2, m)
- STOP 11
+ stop 11
end do
end do
end do
end do
!$omp single
- if (i.ne.1.or.j.ne.-1.or.k.ne.2.or.m.ne.0) STOP 12
+ if (i.ne.1.or.j.ne.-1.or.k.ne.2.or.m.ne.0) stop 12
!$omp end single
!$omp do collapse(2) ordered(4) lastprivate (i,j,k)
do i = 0, d
@@ -168,7 +168,7 @@
do l = 0, d + 3
!$omp ordered depend(source)
!$omp ordered depend(sink: i-2,j+2,k-2,l)
- if (e.eq.0) STOP 13
+ if (e.eq.0) stop 13
end do
end do
end do
@@ -176,7 +176,7 @@
!$omp end do nowait
!$omp do
do i = 1, N
- if (a(i) .ne. 3) STOP 14
+ if (a(i) .ne. 3) stop 14
end do
!$omp end do nowait
!$omp do collapse(2) private(k)
@@ -184,9 +184,9 @@
do j = 1, 8
do k = 1, 4
if (i.ge.3.and.i.lt.N/16.and.iand(j,1).ne.0.and.k.ge.2) then
- if (b(i,j,k).ne.3) STOP 15
+ if (b(i,j,k).ne.3) stop 15
else
- if (b(i,j,k).ne.0) STOP 16
+ if (b(i,j,k).ne.0) stop 16
end if
end do
end do
@@ -197,9 +197,9 @@
do j = 1, 8
do k = 1, 4
if (j.ge.3.and.iand(k,1).ne.0) then
- if (c(i,j,k).ne.3) STOP 17
+ if (c(i,j,k).ne.3) stop 17
else
- if (c(i,j,k).ne.0) STOP 18
+ if (c(i,j,k).ne.0) stop 18
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.fortran/doacross2.f90 b/libgomp/testsuite/libgomp.fortran/doacross2.f90
index 226dbe2c14e..213ac715f9e 100644
--- a/libgomp/testsuite/libgomp.fortran/doacross2.f90
+++ b/libgomp/testsuite/libgomp.fortran/doacross2.f90
@@ -20,14 +20,14 @@
if (i.gt.2) then
!$omp atomic read
l = a(i - 1)
- if (l.lt.2) STOP 1
+ if (l.lt.2) stop 1
end if
!$omp atomic write
a(i) = 2
if (i.lt.N) then
!$omp atomic read
l = a(i + 1)
- if (l.eq.3) STOP 2
+ if (l.eq.3) stop 2
end if
!$omp ordered depend(source)
!$omp atomic write
@@ -46,19 +46,19 @@
if (j.gt.2.and.k.gt.2) then
!$omp atomic read
l = b(i,j-2,k-1)
- if (l.lt.2) STOP 3
+ if (l.lt.2) stop 3
end if
!$omp atomic write
b(i,j,k) = 2
if (i.gt.5.and.j.gt.2.and.k.lt.4) then
!$omp atomic read
l = b(i-2,j-2, k+1)
- if (l.lt.2) STOP 4
+ if (l.lt.2) stop 4
end if
if (i.gt.6.and.j.le.N/16-3.and.k.eq.4) then
!$omp atomic read
l = b( i - 3, j+2, k-2)
- if (l.lt.2) STOP 5
+ if (l.lt.2) stop 5
end if
!$omp ordered depend(source)
!$omp atomic write
@@ -97,19 +97,19 @@
if (k.le.5) then
!$omp atomic read
l = c(i, j, k + 2)
- if (l.lt.2) STOP 6
+ if (l.lt.2) stop 6
end if
!$omp atomic write
c(i, j, k) = 2
if (i.ge.5.and.j.lt.8.and.k.ge.5) then
!$omp atomic read
l = c(i - 2, j + 1, k - 4)
- if (l.lt.2) STOP 7
+ if (l.lt.2) stop 7
end if
if (i.ge.4.and.j.ge.5.and.k.ge.3) then
!$omp atomic read
l = c(i - 1, j - 2, k - 2)
- if (l.lt.2) STOP 8
+ if (l.lt.2) stop 8
end if
!$omp ordered depend ( source )
!$omp atomic write
@@ -145,19 +145,19 @@
if (k.gt.2.and.i.gt.4) then
!$omp atomic read
l = g(j,k-2,i-1)
- if (l.lt.2) STOP 9
+ if (l.lt.2) stop 9
end if
!$omp atomic write
g(j,k,i) = 2
if (j.gt.2.and.k.gt.2.and.i.lt.6) then
!$omp atomic read
l = g(j-2,k-2, i+1)
- if (l.lt.2) STOP 10
+ if (l.lt.2) stop 10
end if
if (j.gt.3.and.k.le.N/16-3.and.i.eq.6) then
!$omp atomic read
l = g( j - 3, k+2, i-2)
- if (l.lt.2) STOP 11
+ if (l.lt.2) stop 11
end if
!$omp ordered depend(source)
!$omp atomic write
@@ -173,13 +173,13 @@
do l = 0, d + 1
!$omp ordered depend(source)
!$omp ordered depend(sink: i-2,j+2,k-2,l)
- if (e.eq.0) STOP 12
+ if (e.eq.0) stop 12
end do
end do
end do
end do
!$omp single
- if (i.ne.3.or.j.ne.-1.or.k.ne.0) STOP 13
+ if (i.ne.3.or.j.ne.-1.or.k.ne.0) stop 13
i = 8; j = 9; k = 10
!$omp end single
!$omp do ordered(4) collapse(2) lastprivate (i, j, k, m)
@@ -189,13 +189,13 @@
do m = 0, d-1
!$omp ordered depend(source)
!$omp ordered depend(sink: i - 2, j + 2, k - 2, m)
- STOP 14
+ stop 14
end do
end do
end do
end do
!$omp single
- if (i.ne.3.or.j.ne.-1.or.k.ne.2.or.m.ne.0) STOP 15
+ if (i.ne.3.or.j.ne.-1.or.k.ne.2.or.m.ne.0) stop 15
!$omp end single
!$omp do collapse(2) ordered(4) lastprivate (i,j,k)
do i = 2, f + 2
@@ -204,18 +204,18 @@
do l = 0, d + 3
!$omp ordered depend(source)
!$omp ordered depend(sink: i-2,j+2,k-2,l)
- if (e.eq.0) STOP 16
+ if (e.eq.0) stop 16
end do
end do
end do
end do
!$omp end do nowait
!$omp single
- if (a(1) .ne. 0) STOP 17
+ if (a(1) .ne. 0) stop 17
!$omp end single nowait
!$omp do
do i = 2, N
- if (a(i) .ne. 3) STOP 18
+ if (a(i) .ne. 3) stop 18
end do
!$omp end do nowait
!$omp do collapse(2) private(k)
@@ -223,9 +223,9 @@
do j = 1, 8
do k = 1, 4
if (i.ge.4.and.i.lt.N/16.and.iand(j,1).ne.0.and.k.ge.2) then
- if (b(i,j,k).ne.3) STOP 19
+ if (b(i,j,k).ne.3) stop 19
else
- if (b(i,j,k).ne.0) STOP 20
+ if (b(i,j,k).ne.0) stop 20
end if
end do
end do
@@ -236,9 +236,9 @@
do j = 1, 8
do k = 1, 4
if (i.ge.3.and.j.ge.3.and.iand(k,1).ne.0) then
- if (c(i,j,k).ne.3) STOP 21
+ if (c(i,j,k).ne.3) stop 21
else
- if (c(i,j,k).ne.0) STOP 22
+ if (c(i,j,k).ne.0) stop 22
end if
end do
end do
@@ -249,9 +249,9 @@
do j = 1, 8
do k = 1, 6
if (i.lt.N/16.and.iand(j,1).ne.0.and.k.ge.4) then
- if (g(i,j,k).ne.3) STOP 23
+ if (g(i,j,k).ne.3) stop 23
else
- if (g(i,j,k).ne.0) STOP 24
+ if (g(i,j,k).ne.0) stop 24
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.fortran/doacross3.f90 b/libgomp/testsuite/libgomp.fortran/doacross3.f90
index 6649894a8fe..5ba57008c6f 100644
--- a/libgomp/testsuite/libgomp.fortran/doacross3.f90
+++ b/libgomp/testsuite/libgomp.fortran/doacross3.f90
@@ -20,14 +20,14 @@
if (i.gt.2) then
!$omp atomic read
l = a(i - 1)
- if (l.lt.2) STOP 1
+ if (l.lt.2) stop 1
end if
!$omp atomic write
a(i) = 2
if (i.lt.N) then
!$omp atomic read
l = a(i + 1)
- if (l.eq.3) STOP 2
+ if (l.eq.3) stop 2
end if
!$omp ordered depend(source)
!$omp atomic write
@@ -46,19 +46,19 @@
if (j.gt.2.and.k.gt.2) then
!$omp atomic read
l = b(i,j-2,k-1)
- if (l.lt.2) STOP 3
+ if (l.lt.2) stop 3
end if
!$omp atomic write
b(i,j,k) = 2
if (i.gt.5.and.j.gt.2.and.k.lt.4) then
!$omp atomic read
l = b(i-2,j-2, k+1)
- if (l.lt.2) STOP 4
+ if (l.lt.2) stop 4
end if
if (i.gt.6.and.j.le.N/16-3.and.k.eq.4) then
!$omp atomic read
l = b( i - 3, j+2, k-2)
- if (l.lt.2) STOP 5
+ if (l.lt.2) stop 5
end if
!$omp ordered depend(source)
!$omp atomic write
@@ -97,19 +97,19 @@
if (k.le.5) then
!$omp atomic read
l = c(i, j, k + 2)
- if (l.lt.2) STOP 6
+ if (l.lt.2) stop 6
end if
!$omp atomic write
c(i, j, k) = 2
if (i.ge.5.and.j.lt.8.and.k.ge.5) then
!$omp atomic read
l = c(i - 2, j + 1, k - 4)
- if (l.lt.2) STOP 7
+ if (l.lt.2) stop 7
end if
if (i.ge.4.and.j.ge.5.and.k.ge.3) then
!$omp atomic read
l = c(i - 1, j - 2, k - 2)
- if (l.lt.2) STOP 8
+ if (l.lt.2) stop 8
end if
!$omp ordered depend ( source )
!$omp atomic write
@@ -145,19 +145,19 @@
if (k.gt.2.and.i.gt.4) then
!$omp atomic read
l = g(j,k-2,i-1)
- if (l.lt.2) STOP 9
+ if (l.lt.2) stop 9
end if
!$omp atomic write
g(j,k,i) = 2
if (j.gt.2.and.k.gt.2.and.i.lt.6) then
!$omp atomic read
l = g(j-2,k-2, i+1)
- if (l.lt.2) STOP 10
+ if (l.lt.2) stop 10
end if
if (j.gt.3.and.k.le.N/16-3.and.i.eq.6) then
!$omp atomic read
l = g( j - 3, k+2, i-2)
- if (l.lt.2) STOP 11
+ if (l.lt.2) stop 11
end if
!$omp ordered depend(source)
!$omp atomic write
@@ -173,13 +173,13 @@
do l = 0, d + 1, 1 + d
!$omp ordered depend(source)
!$omp ordered depend(sink: i-2,j+2,k-2,l)
- if (e.eq.0) STOP 12
+ if (e.eq.0) stop 12
end do
end do
end do
end do
!$omp single
- if (i.ne.3.or.j.ne.-1.or.k.ne.0) STOP 13
+ if (i.ne.3.or.j.ne.-1.or.k.ne.0) stop 13
i = 8; j = 9; k = 10
!$omp end single
!$omp do ordered(4) collapse(2) lastprivate (i, j, k, m)
@@ -189,13 +189,13 @@
do m = 0, d-1, d+1
!$omp ordered depend(source)
!$omp ordered depend(sink: i - 2, j + 2, k - 2, m)
- STOP 14
+ stop 14
end do
end do
end do
end do
!$omp single
- if (i.ne.3.or.j.ne.-1.or.k.ne.2.or.m.ne.0) STOP 15
+ if (i.ne.3.or.j.ne.-1.or.k.ne.2.or.m.ne.0) stop 15
!$omp end single
!$omp do collapse(2) ordered(4) lastprivate (i,j,k)
do i = 2, f + 2, 1 + f
@@ -204,18 +204,18 @@
do l = 0, d + 3, d + 1
!$omp ordered depend(source)
!$omp ordered depend(sink: i-2,j+2,k-2,l)
- if (e.eq.0) STOP 16
+ if (e.eq.0) stop 16
end do
end do
end do
end do
!$omp end do nowait
!$omp single
- if (a(1) .ne. 0) STOP 17
+ if (a(1) .ne. 0) stop 17
!$omp end single nowait
!$omp do
do i = 2, N
- if (a(i) .ne. 3) STOP 18
+ if (a(i) .ne. 3) stop 18
end do
!$omp end do nowait
!$omp do collapse(2) private(k)
@@ -223,9 +223,9 @@
do j = 1, 8
do k = 1, 4
if (i.ge.4.and.i.lt.N/16.and.iand(j,1).ne.0.and.k.ge.2) then
- if (b(i,j,k).ne.3) STOP 19
+ if (b(i,j,k).ne.3) stop 19
else
- if (b(i,j,k).ne.0) STOP 20
+ if (b(i,j,k).ne.0) stop 20
end if
end do
end do
@@ -236,9 +236,9 @@
do j = 1, 8
do k = 1, 4
if (i.ge.3.and.j.ge.3.and.iand(k,1).ne.0) then
- if (c(i,j,k).ne.3) STOP 21
+ if (c(i,j,k).ne.3) stop 21
else
- if (c(i,j,k).ne.0) STOP 22
+ if (c(i,j,k).ne.0) stop 22
end if
end do
end do
@@ -249,9 +249,9 @@
do j = 1, 8
do k = 1, 6
if (i.lt.N/16.and.iand(j,1).ne.0.and.k.ge.4) then
- if (g(i,j,k).ne.3) STOP 23
+ if (g(i,j,k).ne.3) stop 23
else
- if (g(i,j,k).ne.0) STOP 24
+ if (g(i,j,k).ne.0) stop 24
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/array_sections-3.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/array_sections-3.f90
index 08091b83fcb..50c71300fb6 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/array_sections-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/array_sections-3.f90
@@ -12,6 +12,6 @@ contains
p(9) = 777
!$omp end target
!$omp end target data
- if (A(3) /= 777 .or. A(9) /= 777) STOP 1
+ if (A(3) /= 777 .or. A(9) /= 777) stop 1
end subroutine
end
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/array_sections-4.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/array_sections-4.f90
index f730894bd95..e6715e37532 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/array_sections-4.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/array_sections-4.f90
@@ -13,6 +13,6 @@ contains
A(9) = 999
!$omp end target
!$omp end target data
- if (A(3) /= 777 .or. A(9) /= 999) STOP 1
+ if (A(3) /= 777 .or. A(9) /= 999) stop 1
end subroutine
end
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/async_target-1.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/async_target-1.f90
index dd6f7f5a791..6d1fc98cb74 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/async_target-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/async_target-1.f90
@@ -27,7 +27,7 @@ subroutine check ()
else
err = (Y(i) - Z(i)) / Z(i)
end if
- if (err > EPS .or. err < -EPS) STOP 1
+ if (err > EPS .or. err < -EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/async_target-2.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/async_target-2.f90
index 2380f3a01f0..ad35539aa44 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/async_target-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/async_target-2.f90
@@ -17,7 +17,7 @@ subroutine check (p, N)
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
@@ -30,14 +30,14 @@ subroutine vec_mult (p, N)
!$omp target data map(to: v1, v2, N) map(from: p)
!$omp task shared(v1, v2, p) depend(out: v1, v2)
!$omp target map(to: v1, v2, N)
- if (omp_is_initial_device ()) STOP 2
+ if (omp_is_initial_device ()) stop 2
allocate (v1(N), v2(N))
call init (v1, v2, N)
!$omp end target
!$omp end task
!$omp task shared(v1, v2, p) depend(in: v1, v2)
!$omp target map(to: v1, v2, N) map(from: p)
- if (omp_is_initial_device ()) STOP 3
+ if (omp_is_initial_device ()) stop 3
!$omp parallel do
do i = 1, N
p(i) = v1(i) * v2(i)
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-1.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-1.f90
index 51de6b26b36..e439fe1b738 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-1.f90
@@ -26,8 +26,8 @@ end module
program e_53_1
use e_53_1_mod, only : fib, fib_wrapper
- if (fib (15) /= fib_wrapper (15)) STOP 1
+ if (fib (15) /= fib_wrapper (15)) stop 1
! Reduced from 25 to 23, otherwise execution runs out of thread stack on
! Nvidia Titan V.
- if (fib (23) /= fib_wrapper (23)) STOP 2
+ if (fib (23) /= fib_wrapper (23)) stop 2
end program
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-2.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-2.f90
index 76cce01a658..ee582b21632 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-2.f90
@@ -8,7 +8,7 @@ program e_53_2
! Nvidia Titan V.
x = fib (23)
!$omp end target
- if (x /= fib (23)) STOP 1
+ if (x /= fib (23)) stop 1
end program
integer recursive function fib (n) result (f)
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-3.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-3.f90
index 1405ea71793..1d332496ce5 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-3.f90
@@ -21,7 +21,7 @@ subroutine check (p, N)
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-4.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-4.f90
index 47d6cd87d5f..a1f6478388f 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-4.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-4.f90
@@ -53,7 +53,7 @@ subroutine check (a, b)
else
err = (a - b) / b
end if
- if (err > EPS .or. err < -EPS) STOP 1
+ if (err > EPS .or. err < -EPS) stop 1
end subroutine
program e_53_4
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-5.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-5.f90
index 8fd6af7d738..5b334514a4d 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-5.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/declare_target-5.f90
@@ -68,7 +68,7 @@ subroutine check (a, b)
else
err = (a - b) / b
end if
- if (err > EPS .or. err < -EPS) STOP 1
+ if (err > EPS .or. err < -EPS) stop 1
end subroutine
program e_53_5
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/device-1.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/device-1.f90
index a141e058e52..f7db7bdb505 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/device-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/device-1.f90
@@ -20,7 +20,7 @@ program e_57_1
!$omp end target
!$omp end target data
- if (b /= 100 .or. .not. c .or. d) STOP 1
+ if (b /= 100 .or. .not. c .or. d) stop 1
a = a + 200
b = 0
@@ -36,7 +36,7 @@ program e_57_1
!$omp end target
!$omp end target data
- if (b /= 0 .or. c .or. d) STOP 2
+ if (b /= 0 .or. c .or. d) stop 2
a = a + 200
b = 0
@@ -52,5 +52,5 @@ program e_57_1
!$omp end target
!$omp end target data
- if (b /= 100 .or. .not. c .or. d) STOP 3
+ if (b /= 100 .or. .not. c .or. d) stop 3
end program
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/device-2.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/device-2.f90
index a7d4f24611f..a63162198d4 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/device-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/device-2.f90
@@ -15,10 +15,10 @@ program e_57_2
end do
do i = 1, num
- if (offload(i)) STOP 1
+ if (offload(i)) stop 1
end do
do i = num+1, N
- if (.not. offload(i)) STOP 2
+ if (.not. offload(i)) stop 2
end do
end program
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/device-3.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/device-3.f90
index d6bc042d6c2..50c75c03f14 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/device-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/device-3.f90
@@ -11,11 +11,11 @@ program e_57_3
!$omp target map(from: res)
res = omp_is_initial_device ()
!$omp end target
- if (res) STOP 1
+ if (res) stop 1
call omp_set_default_device (omp_get_num_devices ())
!$omp target map(from: res)
res = omp_is_initial_device ()
!$omp end target
- if (.not. res) STOP 2
+ if (.not. res) stop 2
end program
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/simd-1.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/simd-1.f90
index 1d705535cfd..04f659a84f5 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/simd-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/simd-1.f90
@@ -28,7 +28,7 @@ contains
double precision :: diff, a(*), b(*)
do i = 1, n
diff = a(i) - b(i)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/simd-2.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/simd-2.f90
index c9c162fef0d..3bb88388ad2 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/simd-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/simd-2.f90
@@ -49,7 +49,7 @@ contains
double precision :: diff, a(*), b(*)
do i = 1, n
diff = a(i) - b(i)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
end module
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/simd-3.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/simd-3.f90
index eb8497053bf..5e376f604b9 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/simd-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/simd-3.f90
@@ -57,6 +57,6 @@ program SIMD3
diff = sum - sum_ref
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end program
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/simd-4.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/simd-4.f90
index cb78e2c7765..551b8396f13 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/simd-4.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/simd-4.f90
@@ -47,7 +47,7 @@ contains
real :: diff, a(*), b(*)
do i = 1, n
diff = a(i) - b(i)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/simd-5.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/simd-5.f90
index 561deb786c4..d2c266cba55 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/simd-5.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/simd-5.f90
@@ -56,7 +56,7 @@ contains
do j = 1, n
do i = 1, n
diff = a(i,j) - b(i,j)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/simd-6.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/simd-6.f90
index 7f7c5101475..7540a945628 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/simd-6.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/simd-6.f90
@@ -109,14 +109,14 @@ contains
real :: diff, a(*), b(*)
do i = 1, n
diff = a(i) - b(i)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
subroutine checkint (a, b, n)
integer :: i, n, a(*), b(*)
do i = 1, n
- if (a(i) .ne. b(i)) STOP 2
+ if (a(i) .ne. b(i)) stop 2
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/simd-7.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/simd-7.f90
index e6af9c8224b..1e2233ee869 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/simd-7.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/simd-7.f90
@@ -23,7 +23,7 @@ program fibonacci
call fib_ref (a_ref, N)
do i = 0, N-1
- if (a(i) .ne. a_ref(i)) STOP 1
+ if (a(i) .ne. a_ref(i)) stop 1
end do
end program
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/simd-8.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/simd-8.f90
index 722d9824c5f..5fa4db5cf5a 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/simd-8.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/simd-8.f90
@@ -47,6 +47,6 @@ program simd_8f
diff = pri - 8237.25
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end program
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target-1.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target-1.f90
index 2ec4f68f309..b5dfd09dd75 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target-1.f90
@@ -17,7 +17,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target-2.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target-2.f90
index e995ef5a3ac..7e01c57bf80 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target-2.f90
@@ -17,7 +17,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target-3.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target-3.f90
index 338189f6952..76eb6d17bd7 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target-3.f90
@@ -17,7 +17,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target-4.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target-4.f90
index 856ccdb536a..71f0f69e046 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target-4.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target-4.f90
@@ -17,7 +17,7 @@ contains
real, pointer, dimension(:) :: p
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target-5.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target-5.f90
index bae30414234..b4fd99efa74 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target-5.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target-5.f90
@@ -19,7 +19,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
@@ -29,7 +29,7 @@ contains
real :: p(N), v1(N), v2(N)
call init (v1, v2, N)
!$omp target if(N > THRESHOLD1) map(to: v1,v2) map(from: p)
- if (omp_is_initial_device ()) STOP 2
+ if (omp_is_initial_device ()) stop 2
!$omp parallel do if(N > THRESHOLD2)
do i = 1, N
p(i) = v1(i) * v2(i)
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-1.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-1.f90
index f9cceb94050..b3b2a48ca5a 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-1.f90
@@ -17,7 +17,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-2.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-2.f90
index 219b450c005..217cc73061a 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-2.f90
@@ -26,7 +26,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - 2 * (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-3.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-3.f90
index b48dbe29836..6d470cfd9e9 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-3.f90
@@ -19,7 +19,7 @@ contains
do k = 1, cols
do i = 1, rows
diff = P(i,k) - Q(i,k)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-4.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-4.f90
index 7499e3b70a5..24554aa5f89 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-4.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-4.f90
@@ -17,7 +17,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-5.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-5.f90
index 8057d058a21..364e2f36a96 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-5.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-5.f90
@@ -17,7 +17,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-6.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-6.f90
index ba6d879ca8b..c578eba4dc1 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-6.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-6.f90
@@ -28,7 +28,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - 2 * (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
@@ -39,7 +39,7 @@ contains
call init (v1, v2, N)
!$omp target data if(N > THRESHOLD) map(from: p)
!$omp target if(N > THRESHOLD) map(to: v1, v2)
- if (omp_is_initial_device ()) STOP 2
+ if (omp_is_initial_device ()) stop 2
!$omp parallel do
do i = 1, N
p(i) = v1(i) * v2(i)
@@ -47,7 +47,7 @@ contains
!$omp end target
call init_again (v1, v2, N)
!$omp target if(N > THRESHOLD) map(to: v1, v2)
- if (omp_is_initial_device ()) STOP 3
+ if (omp_is_initial_device ()) stop 3
!$omp parallel do
do i = 1, N
p(i) = p(i) + v1(i) * v2(i)
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-7.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-7.f90
index 629ef2c6c4d..ec8ef07d3d3 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target_data-7.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target_data-7.f90
@@ -19,7 +19,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
@@ -30,7 +30,7 @@ contains
call init (v1, v2, N)
!$omp target data if(N > THRESHOLD) map(to: v1, v2) map(from: p)
!$omp target
- if (omp_is_initial_device ()) STOP 2
+ if (omp_is_initial_device ()) stop 2
!$omp parallel do
do i = 1, N
p(i) = v1(i) * v2(i)
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target_update-1.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target_update-1.f90
index 1861d4405a5..8a6b23014fa 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target_update-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target_update-1.f90
@@ -26,7 +26,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - 2 * (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/target_update-2.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/target_update-2.f90
index 7734a6adb96..149449239ba 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/target_update-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/target_update-2.f90
@@ -26,7 +26,7 @@ contains
real :: diff, p(N)
do i = 1, N
diff = p(i) - (i * i + (i + 2.0) * (i - 3.0))
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-1.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-1.f90
index f40e36f3bca..1e24a4067d8 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-1.f90
@@ -9,7 +9,7 @@ program example
x = 2
!$omp end task
!$omp task shared(x) depend(in: x)
- if (x .ne. 2) STOP 1
+ if (x .ne. 2) stop 1
!$omp end task
!$omp end single
!$omp end parallel
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-2.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-2.f90
index 7debb607ff4..e13b3d69a4b 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-2.f90
@@ -6,7 +6,7 @@ program example
!$omp parallel
!$omp single
!$omp task shared(x) depend(in: x)
- if (x .ne. 1) STOP 1
+ if (x .ne. 1) stop 1
!$omp end task
!$omp task shared(x) depend(out: x)
x = 2
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-3.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-3.f90
index 34cd2c74970..a12998db1e4 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-3.f90
@@ -12,7 +12,7 @@ program example
x = 2
!$omp end task
!$omp taskwait
- if ((x .ne. 1) .and. (x .ne. 2)) STOP 1
+ if ((x .ne. 1) .and. (x .ne. 2)) stop 1
!$omp end single
!$omp end parallel
end program
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-4.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-4.f90
index 47e93f9213b..ab78626dd3b 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-4.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-4.f90
@@ -9,10 +9,10 @@ program example
x = 2
!$omp end task
!$omp task shared(x) depend(in: x)
- if (x .ne. 2) STOP 1
+ if (x .ne. 2) stop 1
!$omp end task
!$omp task shared(x) depend(in: x)
- if (x .ne. 2) STOP 2
+ if (x .ne. 2) stop 2
!$omp end task
!$omp end single
!$omp end parallel
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-5.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-5.f90
index 9e12db3386c..45054dfba9e 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-5.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/task_dep-5.f90
@@ -51,7 +51,7 @@ contains
do j = 1, N
diff = A(i, j) - B(i, j)
if (diff > EPS .or. -diff > EPS) then
- STOP 1
+ stop 1
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/teams-2.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/teams-2.f90
index 794c907e975..a288c3a9f6e 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/teams-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/teams-2.f90
@@ -49,7 +49,7 @@ subroutine check (a, b)
else
err = (a - b) / b
end if
- if (err > EPS .or. err < -EPS) STOP 1
+ if (err > EPS .or. err < -EPS) stop 1
end subroutine
program e_54_1
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/teams-3.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/teams-3.f90
index 1c8f7d8a43d..f4d95853acc 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/teams-3.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/teams-3.f90
@@ -42,7 +42,7 @@ subroutine check (a, b)
else
err = (a - b) / b
end if
- if (err > EPS .or. err < -EPS) STOP 1
+ if (err > EPS .or. err < -EPS) stop 1
end subroutine
program e_54_3
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/teams-4.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/teams-4.f90
index 94de777c71c..4911ea4df75 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/teams-4.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/teams-4.f90
@@ -44,7 +44,7 @@ subroutine check (a, b)
else
err = (a - b) / b
end if
- if (err > EPS .or. err < -EPS) STOP 1
+ if (err > EPS .or. err < -EPS) stop 1
end subroutine
program e_54_4
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/teams-5.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/teams-5.f90
index 7e380ad2658..243164ec785 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/teams-5.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/teams-5.f90
@@ -18,7 +18,7 @@ contains
real :: diff
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/examples-4/teams-6.f90 b/libgomp/testsuite/libgomp.fortran/examples-4/teams-6.f90
index 8121fba67d7..677ce0179a9 100644
--- a/libgomp/testsuite/libgomp.fortran/examples-4/teams-6.f90
+++ b/libgomp/testsuite/libgomp.fortran/examples-4/teams-6.f90
@@ -18,7 +18,7 @@ contains
real :: diff
do i = 1, N
diff = p(i) - (i + 2.0) * (i - 3.0)
- if (diff > EPS .or. -diff > EPS) STOP 1
+ if (diff > EPS .or. -diff > EPS) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.fortran/fortran.exp b/libgomp/testsuite/libgomp.fortran/fortran.exp
index d848ed4d47f..eb701311b6a 100644
--- a/libgomp/testsuite/libgomp.fortran/fortran.exp
+++ b/libgomp/testsuite/libgomp.fortran/fortran.exp
@@ -54,11 +54,17 @@ if { $lang_test_file_found } {
# Allow for spec subsitution.
lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/${quadmath_library_path}/"
set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}:${blddir}/${quadmath_library_path}"
+ append lang_link_flags " -lquadmath"
} else {
set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}"
}
} else {
set ld_library_path "$always_ld_library_path"
+ if { [check_no_compiler_messages has_libquadmath executable {
+ int main() {return 0;}
+ } "-lgfortran -lquadmath"] } then {
+ append lang_link_flags " -lquadmath"
+ }
}
append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
set_ld_library_path_env_vars
diff --git a/libgomp/testsuite/libgomp.fortran/lastprivate1.f90 b/libgomp/testsuite/libgomp.fortran/lastprivate1.f90
index 132617b5c27..4eae92b39e8 100644
--- a/libgomp/testsuite/libgomp.fortran/lastprivate1.f90
+++ b/libgomp/testsuite/libgomp.fortran/lastprivate1.f90
@@ -1,18 +1,19 @@
+! { dg-do run }
program lastprivate
integer :: i
common /c/ i
!$omp parallel num_threads (4)
call test1
!$omp end parallel
- if (i .ne. 21) STOP 1
+ if (i .ne. 21) stop 1
!$omp parallel num_threads (4)
call test2
!$omp end parallel
- if (i .ne. 64) STOP 2
+ if (i .ne. 64) stop 2
!$omp parallel num_threads (4)
call test3
!$omp end parallel
- if (i .ne. 14) STOP 3
+ if (i .ne. 14) stop 3
call test4
call test5
call test6
@@ -53,21 +54,21 @@ contains
!$omp parallel do lastprivate (j) num_threads (4) default (none)
do j = 1, 20
end do
- if (j .ne. 21) STOP 4
+ if (j .ne. 21) stop 4
end subroutine test4
subroutine test5
integer :: j
!$omp parallel do lastprivate (j) num_threads (4) default (none)
do j = 7, 61, 3
end do
- if (j .ne. 64) STOP 5
+ if (j .ne. 64) stop 5
end subroutine test5
subroutine test6
integer :: j
!$omp parallel do lastprivate (j) num_threads (4) default (none)
do j = -10, 11, ret3 ()
end do
- if (j .ne. 14) STOP 6
+ if (j .ne. 14) stop 6
end subroutine test6
subroutine test7
integer :: i
@@ -75,7 +76,7 @@ contains
!$omp parallel do lastprivate (i) num_threads (4) default (none)
do i = 1, 20
end do
- if (i .ne. 21) STOP 7
+ if (i .ne. 21) stop 7
end subroutine test7
subroutine test8
integer :: i
@@ -83,7 +84,7 @@ contains
!$omp parallel do lastprivate (i) num_threads (4) default (none)
do i = 7, 61, 3
end do
- if (i .ne. 64) STOP 8
+ if (i .ne. 64) stop 8
end subroutine test8
subroutine test9
integer :: i
@@ -91,7 +92,7 @@ contains
!$omp parallel do lastprivate (i) num_threads (4) default (none)
do i = -10, 11, ret3 ()
end do
- if (i .ne. 14) STOP 9
+ if (i .ne. 14) stop 9
end subroutine test9
subroutine test10
integer :: i
@@ -101,7 +102,7 @@ contains
do i = 1, 20
end do
!$omp end parallel
- if (i .ne. 21) STOP 10
+ if (i .ne. 21) stop 10
end subroutine test10
subroutine test11
integer :: i
@@ -111,7 +112,7 @@ contains
do i = 7, 61, 3
end do
!$omp end parallel
- if (i .ne. 64) STOP 11
+ if (i .ne. 64) stop 11
end subroutine test11
subroutine test12
integer :: i
@@ -121,6 +122,6 @@ contains
do i = -10, 11, ret3 ()
end do
!$omp end parallel
- if (i .ne. 14) STOP 12
+ if (i .ne. 14) stop 12
end subroutine test12
end program lastprivate
diff --git a/libgomp/testsuite/libgomp.fortran/lastprivate2.f90 b/libgomp/testsuite/libgomp.fortran/lastprivate2.f90
index 6cd5760206c..edaf82325a8 100644
--- a/libgomp/testsuite/libgomp.fortran/lastprivate2.f90
+++ b/libgomp/testsuite/libgomp.fortran/lastprivate2.f90
@@ -1,18 +1,19 @@
+! { dg-do run }
program lastprivate
integer :: i, k
common /c/ i, k
!$omp parallel num_threads (4)
call test1
!$omp end parallel
- if (i .ne. 21 .or. k .ne. 20) STOP 1
+ if (i .ne. 21 .or. k .ne. 20) stop 1
!$omp parallel num_threads (4)
call test2
!$omp end parallel
- if (i .ne. 64 .or. k .ne. 61) STOP 2
+ if (i .ne. 64 .or. k .ne. 61) stop 2
!$omp parallel num_threads (4)
call test3
!$omp end parallel
- if (i .ne. 14 .or. k .ne. 11) STOP 3
+ if (i .ne. 14 .or. k .ne. 11) stop 3
call test4
call test5
call test6
@@ -57,7 +58,7 @@ contains
do j = 1, 20
l = j
end do
- if (j .ne. 21 .or. l .ne. 20) STOP 4
+ if (j .ne. 21 .or. l .ne. 20) stop 4
end subroutine test4
subroutine test5
integer :: j, l
@@ -66,7 +67,7 @@ contains
do j = 7, 61, 3
l = j
end do
- if (j .ne. 64 .or. l .ne. 61) STOP 5
+ if (j .ne. 64 .or. l .ne. 61) stop 5
end subroutine test5
subroutine test6
integer :: j, l
@@ -74,7 +75,7 @@ contains
do j = -10, 11, ret3 ()
l = j
end do
- if (j .ne. 14 .or. l .ne. 11) STOP 6
+ if (j .ne. 14 .or. l .ne. 11) stop 6
end subroutine test6
subroutine test7
integer :: i, k
@@ -83,7 +84,7 @@ contains
do i = 1, 20
k = i
end do
- if (i .ne. 21 .or. k .ne. 20) STOP 7
+ if (i .ne. 21 .or. k .ne. 20) stop 7
end subroutine test7
subroutine test8
integer :: i, k
@@ -92,7 +93,7 @@ contains
do i = 7, 61, 3
k = i
end do
- if (i .ne. 64 .or. k .ne. 61) STOP 8
+ if (i .ne. 64 .or. k .ne. 61) stop 8
end subroutine test8
subroutine test9
integer :: i, k
@@ -102,7 +103,7 @@ contains
do i = -10, 11, ret3 ()
k = i
end do
- if (i .ne. 14 .or. k .ne. 11) STOP 9
+ if (i .ne. 14 .or. k .ne. 11) stop 9
end subroutine test9
subroutine test10
integer :: i, k
@@ -113,7 +114,7 @@ contains
k = i
end do
!$omp end parallel
- if (i .ne. 21 .or. k .ne. 20) STOP 10
+ if (i .ne. 21 .or. k .ne. 20) stop 10
end subroutine test10
subroutine test11
integer :: i, k
@@ -124,7 +125,7 @@ contains
k = i
end do
!$omp end parallel
- if (i .ne. 64 .or. k .ne. 61) STOP 11
+ if (i .ne. 64 .or. k .ne. 61) stop 11
end subroutine test11
subroutine test12
integer :: i, k
@@ -136,6 +137,6 @@ contains
k = i
end do
!$omp end parallel
- if (i .ne. 14 .or. k .ne. 11) STOP 12
+ if (i .ne. 14 .or. k .ne. 11) stop 12
end subroutine test12
end program lastprivate
diff --git a/libgomp/testsuite/libgomp.fortran/lib1.f90 b/libgomp/testsuite/libgomp.fortran/lib1.f90
index 92c32508491..4e7f9b24bd5 100644
--- a/libgomp/testsuite/libgomp.fortran/lib1.f90
+++ b/libgomp/testsuite/libgomp.fortran/lib1.f90
@@ -11,42 +11,42 @@
call omp_init_lock (lck)
call omp_set_lock (lck)
- if (omp_test_lock (lck)) STOP 1
+ if (omp_test_lock (lck)) stop 1
call omp_unset_lock (lck)
- if (.not. omp_test_lock (lck)) STOP 2
- if (omp_test_lock (lck)) STOP 3
+ if (.not. omp_test_lock (lck)) stop 2
+ if (omp_test_lock (lck)) stop 3
call omp_unset_lock (lck)
call omp_destroy_lock (lck)
call omp_init_nest_lock (nlck)
- if (omp_test_nest_lock (nlck) .ne. 1) STOP 4
+ if (omp_test_nest_lock (nlck) .ne. 1) stop 4
call omp_set_nest_lock (nlck)
- if (omp_test_nest_lock (nlck) .ne. 3) STOP 5
+ if (omp_test_nest_lock (nlck) .ne. 3) stop 5
call omp_unset_nest_lock (nlck)
call omp_unset_nest_lock (nlck)
- if (omp_test_nest_lock (nlck) .ne. 2) STOP 6
+ if (omp_test_nest_lock (nlck) .ne. 2) stop 6
call omp_unset_nest_lock (nlck)
call omp_unset_nest_lock (nlck)
call omp_destroy_nest_lock (nlck)
call omp_set_dynamic (.true.)
- if (.not. omp_get_dynamic ()) STOP 7
+ if (.not. omp_get_dynamic ()) stop 7
call omp_set_dynamic (.false.)
- if (omp_get_dynamic ()) STOP 8
+ if (omp_get_dynamic ()) stop 8
call omp_set_nested (.true.)
- if (.not. omp_get_nested ()) STOP 9
+ if (.not. omp_get_nested ()) stop 9
call omp_set_nested (.false.)
- if (omp_get_nested ()) STOP 10
+ if (omp_get_nested ()) stop 10
call omp_set_num_threads (5)
- if (omp_get_num_threads () .ne. 1) STOP 11
- if (omp_get_max_threads () .ne. 5) STOP 12
- if (omp_get_thread_num () .ne. 0) STOP 13
+ if (omp_get_num_threads () .ne. 1) stop 11
+ if (omp_get_max_threads () .ne. 5) stop 12
+ if (omp_get_thread_num () .ne. 0) stop 13
call omp_set_num_threads (3)
- if (omp_get_num_threads () .ne. 1) STOP 14
- if (omp_get_max_threads () .ne. 3) STOP 15
- if (omp_get_thread_num () .ne. 0) STOP 16
+ if (omp_get_num_threads () .ne. 1) stop 14
+ if (omp_get_max_threads () .ne. 3) stop 15
+ if (omp_get_thread_num () .ne. 0) stop 16
l = .false.
!$omp parallel reduction (.or.:l)
l = omp_get_num_threads () .ne. 3
@@ -56,22 +56,22 @@
l = l .or. (omp_get_thread_num () .ne. 0)
!$omp end master
!$omp end parallel
- if (l) STOP 17
+ if (l) stop 17
- if (omp_get_num_procs () .le. 0) STOP 18
- if (omp_in_parallel ()) STOP 19
+ if (omp_get_num_procs () .le. 0) stop 18
+ if (omp_in_parallel ()) stop 19
!$omp parallel reduction (.or.:l)
l = .not. omp_in_parallel ()
!$omp end parallel
!$omp parallel reduction (.or.:l) if (.true.)
l = .not. omp_in_parallel ()
!$omp end parallel
- if (l) STOP 20
+ if (l) stop 20
e = omp_get_wtime ()
- if (d .gt. e) STOP 21
+ if (d .gt. e) stop 21
d = omp_get_wtick ()
! Negative precision is definitely wrong,
! bigger than 1s clock resolution is also strange
- if (d .le. 0 .or. d .gt. 1.) STOP 22
+ if (d .le. 0 .or. d .gt. 1.) stop 22
end
diff --git a/libgomp/testsuite/libgomp.fortran/lib4.f90 b/libgomp/testsuite/libgomp.fortran/lib4.f90
index ce6aa00e521..d551cde35c6 100644
--- a/libgomp/testsuite/libgomp.fortran/lib4.f90
+++ b/libgomp/testsuite/libgomp.fortran/lib4.f90
@@ -6,11 +6,11 @@ program lib4
integer :: modifier
call omp_set_schedule (omp_sched_static, 32)
call omp_get_schedule (kind, modifier)
- if (kind.ne.omp_sched_static.or.modifier.ne.32) STOP 1
+ if (kind.ne.omp_sched_static.or.modifier.ne.32) stop 1
call omp_set_schedule (omp_sched_dynamic, 4)
call omp_get_schedule (kind, modifier)
- if (kind.ne.omp_sched_dynamic.or.modifier.ne.4) STOP 2
- if (omp_get_thread_limit ().lt.0) STOP 3
+ if (kind.ne.omp_sched_dynamic.or.modifier.ne.4) stop 2
+ if (omp_get_thread_limit ().lt.0) stop 3
call omp_set_max_active_levels (6)
- if (omp_get_max_active_levels ().ne.6) STOP 4
+ if (omp_get_max_active_levels ().ne.6) stop 4
end program lib4
diff --git a/libgomp/testsuite/libgomp.fortran/lock-1.f90 b/libgomp/testsuite/libgomp.fortran/lock-1.f90
index b3408388c5d..21116078049 100644
--- a/libgomp/testsuite/libgomp.fortran/lock-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/lock-1.f90
@@ -7,16 +7,16 @@
l = .false.
call omp_init_nest_lock (lock)
- if (omp_test_nest_lock (lock) .ne. 1) STOP 1
- if (omp_test_nest_lock (lock) .ne. 2) STOP 2
+ if (omp_test_nest_lock (lock) .ne. 1) stop 1
+ if (omp_test_nest_lock (lock) .ne. 2) stop 2
!$omp parallel if (.false.) reduction (.or.:l)
! In OpenMP 2.5 this was supposed to return 3,
! but in OpenMP 3.0 the parallel region has a different
! task and omp_*_lock_t are owned by tasks, not by threads.
if (omp_test_nest_lock (lock) .ne. 0) l = .true.
!$omp end parallel
- if (l) STOP 3
- if (omp_test_nest_lock (lock) .ne. 3) STOP 4
+ if (l) stop 3
+ if (omp_test_nest_lock (lock) .ne. 3) stop 4
call omp_unset_nest_lock (lock)
call omp_unset_nest_lock (lock)
call omp_unset_nest_lock (lock)
diff --git a/libgomp/testsuite/libgomp.fortran/lock-2.f90 b/libgomp/testsuite/libgomp.fortran/lock-2.f90
index 8608027ef54..ddf53c1b70e 100644
--- a/libgomp/testsuite/libgomp.fortran/lock-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/lock-2.f90
@@ -8,8 +8,8 @@
l = .false.
call omp_init_nest_lock (lock)
!$omp parallel num_threads (1) reduction (.or.:l)
- if (omp_test_nest_lock (lock) .ne. 1) STOP 1
- if (omp_test_nest_lock (lock) .ne. 2) STOP 2
+ if (omp_test_nest_lock (lock) .ne. 1) stop 1
+ if (omp_test_nest_lock (lock) .ne. 2) stop 2
!$omp task if (.false.) shared (lock, l)
if (omp_test_nest_lock (lock) .ne. 0) l = .true.
!$omp end task
@@ -19,6 +19,6 @@
call omp_unset_nest_lock (lock)
call omp_unset_nest_lock (lock)
!$omp end parallel
- if (l) STOP 3
+ if (l) stop 3
call omp_destroy_nest_lock (lock)
end
diff --git a/libgomp/testsuite/libgomp.fortran/nested1.f90 b/libgomp/testsuite/libgomp.fortran/nested1.f90
index ed1e832ee6e..f521b7bf820 100644
--- a/libgomp/testsuite/libgomp.fortran/nested1.f90
+++ b/libgomp/testsuite/libgomp.fortran/nested1.f90
@@ -8,16 +8,16 @@ program nested1
e3 = 0
call omp_set_nested (.true.)
call omp_set_dynamic (.false.)
- if (omp_in_parallel ()) STOP 1
- if (omp_get_num_threads ().ne.1) STOP 2
- if (omp_get_level ().ne.0) STOP 3
- if (omp_get_ancestor_thread_num (0).ne.0) STOP 4
- if (omp_get_ancestor_thread_num (-1).ne.-1) STOP 5
- if (omp_get_ancestor_thread_num (1).ne.-1) STOP 6
- if (omp_get_team_size (0).ne.1) STOP 7
- if (omp_get_team_size (-1).ne.-1) STOP 8
- if (omp_get_team_size (1).ne.-1) STOP 9
- if (omp_get_active_level ().ne.0) STOP 10
+ if (omp_in_parallel ()) stop 1
+ if (omp_get_num_threads ().ne.1) stop 2
+ if (omp_get_level ().ne.0) stop 3
+ if (omp_get_ancestor_thread_num (0).ne.0) stop 4
+ if (omp_get_ancestor_thread_num (-1).ne.-1) stop 5
+ if (omp_get_ancestor_thread_num (1).ne.-1) stop 6
+ if (omp_get_team_size (0).ne.1) stop 7
+ if (omp_get_team_size (-1).ne.-1) stop 8
+ if (omp_get_team_size (1).ne.-1) stop 9
+ if (omp_get_active_level ().ne.0) stop 10
!$omp parallel num_threads (4) private (e, tn1)
e = 0
tn1 = omp_get_thread_num ()
@@ -83,5 +83,5 @@ program nested1
!$omp end parallel
!$omp end parallel
!$omp end parallel
- if (e1.ne.0.or.e2.ne.0.or.e3.ne.0) STOP 11
+ if (e1.ne.0.or.e2.ne.0.or.e3.ne.0) stop 11
end program nested1
diff --git a/libgomp/testsuite/libgomp.fortran/nestedfn1.f90 b/libgomp/testsuite/libgomp.fortran/nestedfn1.f90
index 833cb9a0884..9949071b4b9 100644
--- a/libgomp/testsuite/libgomp.fortran/nestedfn1.f90
+++ b/libgomp/testsuite/libgomp.fortran/nestedfn1.f90
@@ -5,7 +5,7 @@
b = 2
c = 3
call foo
- if (a .ne. 7) STOP 1
+ if (a .ne. 7) stop 1
contains
subroutine foo
use omp_lib
@@ -38,6 +38,6 @@ contains
if (a .ne. 7 .or. b .ne. 8 .or. c .ne. 9) l = .true.
end if
!$omp end parallel
- if (l) STOP 2
+ if (l) stop 2
end subroutine foo
end
diff --git a/libgomp/testsuite/libgomp.fortran/nestedfn2.f90 b/libgomp/testsuite/libgomp.fortran/nestedfn2.f90
index 34054ad4937..cd2e505a6e6 100644
--- a/libgomp/testsuite/libgomp.fortran/nestedfn2.f90
+++ b/libgomp/testsuite/libgomp.fortran/nestedfn2.f90
@@ -24,8 +24,8 @@ contains
subroutine test3
integer :: i
common /c/ i
- if (i .lt. 0 .or. i .ge. 4) STOP 1
- if (i + 10 .ne. vari) STOP 2
+ if (i .lt. 0 .or. i .ge. 4) stop 1
+ if (i + 10 .ne. vari) stop 2
end subroutine test3
subroutine test4
use omp_lib
diff --git a/libgomp/testsuite/libgomp.fortran/nestedfn3.f90 b/libgomp/testsuite/libgomp.fortran/nestedfn3.f90
index 4e8a18a63ac..fa82d2f23b0 100644
--- a/libgomp/testsuite/libgomp.fortran/nestedfn3.f90
+++ b/libgomp/testsuite/libgomp.fortran/nestedfn3.f90
@@ -5,7 +5,7 @@ program nestomp
integer :: j
j = 8
call bar
- if (j.ne.10) STOP 1
+ if (j.ne.10) stop 1
contains
subroutine foo (i)
integer :: i
diff --git a/libgomp/testsuite/libgomp.fortran/nestedfn4.f90 b/libgomp/testsuite/libgomp.fortran/nestedfn4.f90
index bc8614a340a..6e4126888c1 100644
--- a/libgomp/testsuite/libgomp.fortran/nestedfn4.f90
+++ b/libgomp/testsuite/libgomp.fortran/nestedfn4.f90
@@ -1,3 +1,4 @@
+! { dg-do run }
program foo
integer :: i, j, k
integer :: a(10), c(10)
@@ -6,19 +7,19 @@ program foo
call test1
call test2
do i = 1, 10
- if (a(i) .ne. 10 * i) STOP 1
+ if (a(i) .ne. 10 * i) stop 1
end do
!$omp parallel do reduction (+:c)
do i = 1, 10
c = c + a
end do
do i = 1, 10
- if (c(i) .ne. 10 * a(i)) STOP 2
+ if (c(i) .ne. 10 * a(i)) stop 2
end do
!$omp parallel do lastprivate (j)
do j = 1, 10, k
end do
- if (j .ne. 11) STOP 3
+ if (j .ne. 11) stop 3
contains
subroutine test1
integer :: i
@@ -36,6 +37,6 @@ contains
!$omp parallel do lastprivate (j)
do j = 1, 10, k
end do
- if (j .ne. 11) STOP 4
+ if (j .ne. 11) stop 4
end subroutine test2
end program foo
diff --git a/libgomp/testsuite/libgomp.fortran/nestedfn5.f90 b/libgomp/testsuite/libgomp.fortran/nestedfn5.f90
index e65019e2666..28c9b00da67 100644
--- a/libgomp/testsuite/libgomp.fortran/nestedfn5.f90
+++ b/libgomp/testsuite/libgomp.fortran/nestedfn5.f90
@@ -30,7 +30,7 @@ contains
b = b + 1
end do
!$omp end simd
- if (a /= 21 .or. b /= 12) STOP 1
+ if (a /= 21 .or. b /= 12) stop 1
!$omp simd aligned(f : c_sizeof (e(1)))
do b = 1, 64
g(b) = f
@@ -44,8 +44,8 @@ contains
d(2:2,4:5) = d(2:2,4:5) + 1
!$omp end task
!$omp task depend(in : a, d(2:2,4:5))
- if (a /= 22) STOP 2
- if (any (d(2:2,4:5) /= 5)) STOP 3
+ if (a /= 22) stop 2
+ if (any (d(2:2,4:5) /= 5)) stop 3
!$omp end task
!$omp end taskgroup
!$omp end single
@@ -64,8 +64,8 @@ contains
d(2:3,4:4) = 9
!$omp end target
!$omp target update from (a, q, d(2:3,4:4), l)
- if (a /= 6 .or. l .or. b /= 11 .or. any (q /= 8)) STOP 4
- if (any (d(2:3,4:4) /= 9) .or. d(2,5) /= 5 .or. d(3,5) /= 4) STOP 5
+ if (a /= 6 .or. l .or. b /= 11 .or. any (q /= 8)) stop 4
+ if (any (d(2:3,4:4) /= 9) .or. d(2,5) /= 5 .or. d(3,5) /= 4) stop 5
a = 12
b = 13
q = 14
@@ -82,7 +82,7 @@ contains
m = 0
n = 64
o = 16
- if (l) STOP 6
+ if (l) stop 6
!$omp target teams distribute parallel do simd if (.not.l) device(a) &
!$omp & num_teams(b) dist_schedule(static, c) num_threads (h) &
!$omp & reduction (+: m) safelen (n) schedule(static, o) &
@@ -91,7 +91,7 @@ contains
m = m + 1
end do
!$omp end target teams distribute parallel do simd
- if (m /= 64) STOP 7
+ if (m /= 64) stop 7
!$omp end target data
end subroutine foo
end subroutine bar
diff --git a/libgomp/testsuite/libgomp.fortran/omp_atomic1.f90 b/libgomp/testsuite/libgomp.fortran/omp_atomic1.f90
index cec05287fc2..57b7c0051f7 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_atomic1.f90
+++ b/libgomp/testsuite/libgomp.fortran/omp_atomic1.f90
@@ -18,22 +18,22 @@
c = c * 2
!$omp atomic
d = 2 / d
- if (a .ne. 5 .or. b .ne. 2 .or. c .ne. 6 .or. d .ne. 0.5) STOP 1
+ if (a .ne. 5 .or. b .ne. 2 .or. c .ne. 6 .or. d .ne. 0.5) stop 1
d = 1.2
!$omp atomic
a = a + c + d
!$omp atomic
b = b - (a + c + d)
- if (a .ne. 12 .or. b .ne. -17) STOP 2
+ if (a .ne. 12 .or. b .ne. -17) stop 2
!$omp atomic
a = c + d + a
!$omp atomic
b = a + c + d - b
- if (a .ne. 19 .or. b .ne. 43) STOP 3
+ if (a .ne. 19 .or. b .ne. 43) stop 3
!$omp atomic
b = (a + c + d) - b
a = 32
!$omp atomic
a = a / 3.4
- if (a .ne. 9 .or. b .ne. -16) STOP 4
+ if (a .ne. 9 .or. b .ne. -16) stop 4
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_atomic2.f90 b/libgomp/testsuite/libgomp.fortran/omp_atomic2.f90
index 68df316c85d..3748e30bc26 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_atomic2.f90
+++ b/libgomp/testsuite/libgomp.fortran/omp_atomic2.f90
@@ -13,28 +13,28 @@
n = 20
call foo (r, d, n)
- if (n .ne. 22) STOP 1
- if (any (r .ne. 33)) STOP 2
+ if (n .ne. 22) stop 1
+ if (any (r .ne. 33)) stop 2
i = 1
j = 18
k = 23
!$omp atomic
i = min (i, j, k, n)
- if (i .ne. 1) STOP 3
+ if (i .ne. 1) stop 3
!$omp atomic
i = max (j, n, k, i)
- if (i .ne. 23) STOP 4
+ if (i .ne. 23) stop 4
a = 1
b = 18
c = 23
!$omp atomic
a = min (a, b, c)
- if (a .ne. 1) STOP 5
+ if (a .ne. 1) stop 5
!$omp atomic
a = max (a, b, c)
- if (a .ne. 23) STOP 6
+ if (a .ne. 23) stop 6
contains
function bar (i)
diff --git a/libgomp/testsuite/libgomp.fortran/omp_atomic3.f90 b/libgomp/testsuite/libgomp.fortran/omp_atomic3.f90
index e4a1a6e460d..454b167157f 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_atomic3.f90
+++ b/libgomp/testsuite/libgomp.fortran/omp_atomic3.f90
@@ -36,23 +36,23 @@
c2 = c
!$omp atomic read
d2 = d
- if (a2 .ne. 5 .or. b2 .ne. 2 .or. c2 .ne. 6 .or. d2 .ne. 0.5) STOP 1
+ if (a2 .ne. 5 .or. b2 .ne. 2 .or. c2 .ne. 6 .or. d2 .ne. 0.5) stop 1
!$omp atomic write
d = 1.2
!$omp atomic
a = a + c + d
!$omp atomic
b = b - (a + c + d)
- if (a .ne. 12 .or. b .ne. -17) STOP 2
+ if (a .ne. 12 .or. b .ne. -17) stop 2
!$omp atomic
a = c + d + a
!$omp atomic
b = a + c + d - b
- if (a .ne. 19 .or. b .ne. 43) STOP 3
+ if (a .ne. 19 .or. b .ne. 43) stop 3
!$omp atomic
b = (a + c + d) - b
a = 32
!$omp atomic
a = a / 3.4
- if (a .ne. 9 .or. b .ne. -16) STOP 4
+ if (a .ne. 9 .or. b .ne. -16) stop 4
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_atomic4.f90 b/libgomp/testsuite/libgomp.fortran/omp_atomic4.f90
index c4cb5cf9de9..75da9f39400 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_atomic4.f90
+++ b/libgomp/testsuite/libgomp.fortran/omp_atomic4.f90
@@ -28,10 +28,10 @@
d = d / 2.0
d2 = d
!$omp end atomic
- if (a2 .ne. 1 .or. b2 .ne. -16 .or. c2 .ne. 3 .or. d2 .ne. 2) STOP 1
+ if (a2 .ne. 1 .or. b2 .ne. -16 .or. c2 .ne. 3 .or. d2 .ne. 2) stop 1
!$omp atomic read
a2 = a
!$omp atomic read
c2 = c
- if (a2 .ne. 5 .or. b2 .ne. -16 .or. c2 .ne. 6 .or. d2 .ne. 2) STOP 2
+ if (a2 .ne. 5 .or. b2 .ne. -16 .or. c2 .ne. 6 .or. d2 .ne. 2) stop 2
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_atomic5.f90 b/libgomp/testsuite/libgomp.fortran/omp_atomic5.f90
index 1303ba4b51c..292a7f62a2f 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_atomic5.f90
+++ b/libgomp/testsuite/libgomp.fortran/omp_atomic5.f90
@@ -30,30 +30,30 @@
d = d / 2.0
d2 = d
!$omp end atomic
- if (a2 .ne. 1 .or. b2 .ne. -16 .or. c2 .ne. 3 .or. d2 .ne. 2) STOP 1
+ if (a2 .ne. 1 .or. b2 .ne. -16 .or. c2 .ne. 3 .or. d2 .ne. 2) stop 1
!$omp atomic read seq_cst
a2 = a
!$omp atomic seq_cst, read
c2 = c
- if (a2 .ne. 5 .or. b2 .ne. -16 .or. c2 .ne. 6 .or. d2 .ne. 2) STOP 2
+ if (a2 .ne. 5 .or. b2 .ne. -16 .or. c2 .ne. 6 .or. d2 .ne. 2) stop 2
a2 = 10
- if (a2 .ne. 10) STOP 3
+ if (a2 .ne. 10) stop 3
!$omp atomic capture
a2 = a
a = e(1) + e(6) + e(7) * 2
!$omp endatomic
- if (a2 .ne. 5) STOP 4
+ if (a2 .ne. 5) stop 4
!$omp atomic read
a2 = a
!$omp end atomic
- if (a2 .ne. 28) STOP 5
+ if (a2 .ne. 28) stop 5
!$omp atomic capture seq_cst
b2 = b
b = e(1) + e(7) + e(5) * 2
!$omp end atomic
- if (b2 .ne. -16) STOP 6
+ if (b2 .ne. -16) stop 6
!$omp atomic seq_cst, read
b2 = b
!$omp end atomic
- if (b2 .ne. 24) STOP 7
+ if (b2 .ne. 24) stop 7
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_cond1.f b/libgomp/testsuite/libgomp.fortran/omp_cond1.f
index f050f5101be..d98e6cc2848 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_cond1.f
+++ b/libgomp/testsuite/libgomp.fortran/omp_cond1.f
@@ -1,13 +1,13 @@
C Test conditional compilation in fixed form if -fopenmp
10 foo = 2
&56
- if (foo.ne.256) STOP 1
+ if (foo.ne.256) stop 1
bar = 26
!$2 0 ba
c$ +r = 42
!$ bar = 62
!$ bar = bar + 1
- if (bar.ne.43) STOP 2
+ if (bar.ne.43) stop 2
baz = bar
*$ 0baz = 5
C$ +12! Comment
@@ -17,5 +17,5 @@ c$ !4
!$ X baz = 0 ! Not valid OpenMP conditional compilation lines
! $ baz = 1
c$ 10&baz = 2
- if (baz.ne.51242) STOP 3
+ if (baz.ne.51242) stop 3
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_cond2.f b/libgomp/testsuite/libgomp.fortran/omp_cond2.f
index 83e79dc36eb..e54edeaf55e 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_cond2.f
+++ b/libgomp/testsuite/libgomp.fortran/omp_cond2.f
@@ -2,13 +2,13 @@ c Test conditional compilation in fixed form if -fno-openmp
! { dg-options "-fno-openmp" }
10 foo = 2
&56
- if (foo.ne.256) STOP 1
+ if (foo.ne.256) stop 1
bar = 26
!$2 0 ba
c$ +r = 42
!$ bar = 62
!$ bar = bar + 1
- if (bar.ne.26) STOP 2
+ if (bar.ne.26) stop 2
baz = bar
*$ 0baz = 5
C$ +12! Comment
@@ -18,5 +18,5 @@ c$ !4
!$ X baz = 0 ! Not valid OpenMP conditional compilation lines
! $ baz = 1
c$ 10&baz = 2
- if (baz.ne.26) STOP 3
+ if (baz.ne.26) stop 3
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_cond3.F90 b/libgomp/testsuite/libgomp.fortran/omp_cond3.F90
index 3db2fd1163e..6a8ce52d326 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_cond3.F90
+++ b/libgomp/testsuite/libgomp.fortran/omp_cond3.F90
@@ -1,7 +1,7 @@
! Test conditional compilation in free form if -fopenmp
10 foo = 2&
&56
- if (foo.ne.256) STOP 1
+ if (foo.ne.256) stop 1
bar = 26
!$ 20 ba&
!$ &r = 4&
@@ -11,7 +11,7 @@
#ifdef _OPENMP
bar = bar - 1
#endif
- if (bar.ne.43) STOP 2
+ if (bar.ne.43) stop 2
baz = bar
!$ 30 baz = 5& ! Comment
!$12 &
@@ -19,5 +19,5 @@ bar = bar - 1
!$X baz = 0 ! Not valid OpenMP conditional compilation lines
! $ baz = 1
baz = baz + 1 !$ baz = 2
- if (baz.ne.515) STOP 3
+ if (baz.ne.515) stop 3
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_cond4.F90 b/libgomp/testsuite/libgomp.fortran/omp_cond4.F90
index ae2e93253aa..644f7e302a2 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_cond4.F90
+++ b/libgomp/testsuite/libgomp.fortran/omp_cond4.F90
@@ -2,7 +2,7 @@
! { dg-options "-fno-openmp" }
10 foo = 2&
&56
- if (foo.ne.256) STOP 1
+ if (foo.ne.256) stop 1
bar = 26
!$ 20 ba&
!$ &r = 4&
@@ -12,7 +12,7 @@
#ifdef _OPENMP
bar = bar - 1
#endif
- if (bar.ne.26) STOP 2
+ if (bar.ne.26) stop 2
baz = bar
!$ 30 baz = 5& ! Comment
!$12 &
@@ -20,5 +20,5 @@ bar = bar - 1
!$X baz = 0 ! Not valid OpenMP conditional compilation lines
! $ baz = 1
baz = baz + 1 !$ baz = 2
- if (baz.ne.27) STOP 3
+ if (baz.ne.27) stop 3
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_parse1.f90 b/libgomp/testsuite/libgomp.fortran/omp_parse1.f90
index db89401f839..f3b4bc579cf 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_parse1.f90
+++ b/libgomp/testsuite/libgomp.fortran/omp_parse1.f90
@@ -43,16 +43,16 @@ contains
d(b + 1) = c
if (f .ne. g .or. f .ne. b) h = .true.
!$omp endparallel
- if (h) STOP 1
- if (a .ne. 6) STOP 2
- if (j .ne. 24) STOP 3
- if (d(1) .eq. -1) STOP 4
+ if (h) stop 1
+ if (a .ne. 6) stop 2
+ if (j .ne. 24) stop 3
+ if (d(1) .eq. -1) stop 4
e = 1
do g = 1, d(1)
- if (d(g) .ne. d(1)) STOP 5
+ if (d(g) .ne. d(1)) stop 5
e = e * 2
end do
- if (e .ne. i) STOP 6
+ if (e .ne. i) stop 6
end subroutine test_parallel
subroutine test_do_orphan
@@ -79,7 +79,7 @@ contains
call test_do_orphan
!$omp do schedule (static) firstprivate (n)
do 200 i = 1, j
- if (i .eq. 1 .and. n .ne. 24) STOP 7
+ if (i .eq. 1 .and. n .ne. 24) stop 7
n = i
200 d(n) = omp_get_thread_num ()
!$omp enddo nowait
@@ -103,11 +103,11 @@ contains
end do
! Implied omp end do here
!$omp end parallel
- if (.not. m) STOP 8
+ if (.not. m) stop 8
j = 0
do i = 1, 64
- if (d(i) .lt. j .or. d(i) .ge. j + k) STOP 9
+ if (d(i) .lt. j .or. d(i) .ge. j + k) stop 9
if (i .eq. 16) j = 1024
if (i .eq. 32) j = 2048
if (i .eq. 48) j = 4096
@@ -152,9 +152,9 @@ contains
n = 7
!$omp endsections
!$omp end parallel
- if (j .ne. 271 .or. l .ne. 0) STOP 10
- if (m .ne. 4 + 6 + 8 + 10) STOP 11
- if (n .ne. 7) STOP 12
+ if (j .ne. 271 .or. l .ne. 0) stop 10
+ if (m .ne. 4 + 6 + 8 + 10) stop 11
+ if (n .ne. 7) stop 12
end subroutine test_sections
subroutine test_single
@@ -182,6 +182,6 @@ contains
!$omp end single copyprivate (j)
if (i .ne. omp_get_thread_num () .or. j .ne. -2) m = .true.
!$omp endparallel
- if (m) STOP 13
+ if (m) stop 13
end subroutine test_single
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_parse2.f90 b/libgomp/testsuite/libgomp.fortran/omp_parse2.f90
index e63f55f7c31..3de6968bae2 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_parse2.f90
+++ b/libgomp/testsuite/libgomp.fortran/omp_parse2.f90
@@ -16,7 +16,7 @@ contains
j = omp_get_thread_num () .eq. 0
!$omp endmaster
!$omp end parallel
- if (.not. (i .or. j)) STOP 1
+ if (.not. (i .or. j)) stop 1
end subroutine test_master
subroutine test_critical_1 (i, j)
@@ -45,7 +45,7 @@ contains
i = i + 1
!$omp endcritical (critical_foo)
!$omp end parallel
- if (n .lt. 1 .or. i .ne. n * 3 .or. j .ne. n * 3) STOP 2
+ if (n .lt. 1 .or. i .ne. n * 3 .or. j .ne. n * 3) stop 2
end subroutine test_critical
subroutine test_barrier
@@ -62,7 +62,7 @@ contains
j = j .or. .true.
end if
!$omp end parallel
- if (i .ne. 5 .or. j) STOP 3
+ if (i .ne. 5 .or. j) stop 3
end subroutine test_barrier
subroutine test_atomic
@@ -89,14 +89,14 @@ contains
f = max (omp_get_thread_num (), f)
if (omp_get_thread_num () .eq. 0) g = omp_get_num_threads ()
!$omp end parallel
- if (g .le. 0 .or. g .gt. 8) STOP 4
- if (a .ne. 6 * g .or. b .ne. 3 ** g) STOP 5
+ if (g .le. 0 .or. g .gt. 8) stop 4
+ if (a .ne. 6 * g .or. b .ne. 3 ** g) stop 5
if (iand (g, 1) .eq. 1) then
- if (c .ne. 8) STOP 6
+ if (c .ne. 8) stop 6
else if (c .ne. 0) then
- STOP 7
+ stop 7
end if
- if (d .ne. 1024 / (2 ** g)) STOP 8
- if (e .ne. 0 .or. f .ne. g - 1) STOP 9
+ if (d .ne. 1024 / (2 ** g)) stop 8
+ if (e .ne. 0 .or. f .ne. g - 1) stop 9
end subroutine test_atomic
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_parse3.f90 b/libgomp/testsuite/libgomp.fortran/omp_parse3.f90
index a61d54615d2..6076c7aad3c 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_parse3.f90
+++ b/libgomp/testsuite/libgomp.fortran/omp_parse3.f90
@@ -45,10 +45,10 @@ contains
j = 1
do 100 i = 1, 100
if (i .eq. j) then
- if (d(i) .ne. i) STOP 1
+ if (d(i) .ne. i) stop 1
j = i + 5
else
- if (d(i) .ne. -1) STOP 2
+ if (d(i) .ne. -1) stop 2
end if
100 d(i) = -1
end subroutine test_ordered
@@ -69,17 +69,17 @@ contains
!$omp parallel copyin (/tlsblock/, z) reduction (.or.:m) &
!$omp& num_threads (4)
if (omp_get_thread_num () .eq. 0) i = omp_get_num_threads ()
- if (x .ne. 6 .or. y .ne. 7 .or. z .ne. 8) STOP 3
+ if (x .ne. 6 .or. y .ne. 7 .or. z .ne. 8) stop 3
x = omp_get_thread_num ()
y = omp_get_thread_num () + 1024
z = omp_get_thread_num () + 4096
!$omp end parallel
- if (x .ne. 0 .or. y .ne. 1024 .or. z .ne. 4096) STOP 4
+ if (x .ne. 0 .or. y .ne. 1024 .or. z .ne. 4096) stop 4
!$omp parallel num_threads (4), private (j) reduction (.or.:n)
if (omp_get_num_threads () .eq. i) then
j = omp_get_thread_num ()
if (x .ne. j .or. y .ne. j + 1024 .or. z .ne. j + 4096) &
-& STOP 5
+& stop 5
end if
!$omp end parallel
m = m .or. n
@@ -89,9 +89,9 @@ contains
if (z .ne. 4096) n = .true.
if (omp_get_num_threads () .eq. i) then
j = omp_get_thread_num ()
- if (x .ne. j .or. y .ne. j + 1024) STOP 6
+ if (x .ne. j .or. y .ne. j + 1024) stop 6
end if
!$omp end parallel
- if (m .or. n) STOP 7
+ if (m .or. n) stop 7
end subroutine test_threadprivate
end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_parse4.f90 b/libgomp/testsuite/libgomp.fortran/omp_parse4.f90
index 273ce53075b..09b0fa24269 100644
--- a/libgomp/testsuite/libgomp.fortran/omp_parse4.f90
+++ b/libgomp/testsuite/libgomp.fortran/omp_parse4.f90
@@ -59,14 +59,14 @@ contains
!$omp end parallel
if (any (f .ne. (/100, 100, 100, 210, 210, 210, 310, 310, 337, 337/))) &
-& STOP 1
- if (any (g .ne. (/-1, -1, -1, 0, 0, 0, 0, 0, 0, 0/))) STOP 2
- if (i .ne. 20) STOP 3
-!$ if (l .ne. 128 + m) STOP 4
- if (any (d .ne. 1 .or. e .ne. 1)) STOP 5
- if (any (b .ne. transpose (a))) STOP 6
- if (any (c .ne. b)) STOP 7
+& stop 1
+ if (any (g .ne. (/-1, -1, -1, 0, 0, 0, 0, 0, 0, 0/))) stop 2
+ if (i .ne. 20) stop 3
+!$ if (l .ne. 128 + m) stop 4
+ if (any (d .ne. 1 .or. e .ne. 1)) stop 5
+ if (any (b .ne. transpose (a))) stop 6
+ if (any (c .ne. b)) stop 7
if (any (n .ne. (/1, 2, 6, 12, 5, 30, 42, 56, 9, 90, &
-& 110, 132, 13, 182, 210, 240/))) STOP 8
+& 110, 132, 13, 182, 210, 240/))) stop 8
end subroutine test_workshare
end
diff --git a/libgomp/testsuite/libgomp.fortran/openmp_version-1.f b/libgomp/testsuite/libgomp.fortran/openmp_version-1.f
index de16933f9e5..78d4b981f6b 100644
--- a/libgomp/testsuite/libgomp.fortran/openmp_version-1.f
+++ b/libgomp/testsuite/libgomp.fortran/openmp_version-1.f
@@ -4,6 +4,6 @@
implicit none
include "omp_lib.h"
- if (openmp_version .ne. 201511) STOP 1;
+ if (openmp_version .ne. 201511) stop 1;
end program main
diff --git a/libgomp/testsuite/libgomp.fortran/openmp_version-2.f90 b/libgomp/testsuite/libgomp.fortran/openmp_version-2.f90
index b2e0d3a7064..693dba0b3f5 100644
--- a/libgomp/testsuite/libgomp.fortran/openmp_version-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/openmp_version-2.f90
@@ -4,6 +4,6 @@ program main
use omp_lib
implicit none
- if (openmp_version .ne. 201511) STOP 1;
+ if (openmp_version .ne. 201511) stop 1;
end program main
diff --git a/libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt-2.f95 b/libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt-2.f95
index bb165cdfaca..0f800e64523 100644
--- a/libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt-2.f95
+++ b/libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt-2.f95
@@ -34,7 +34,7 @@ program main
call foo ()
do i = 0, n - 1
- if (c(i) .ne. (i + MODULO ((i * 3), 7))) STOP 1
+ if (c(i) .ne. (i + MODULO ((i * 3), 7))) stop 1
end do
end program
diff --git a/libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt.f95 b/libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt.f95
index 5ed4a382a08..1485683467c 100644
--- a/libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt.f95
+++ b/libgomp/testsuite/libgomp.fortran/parloops-exit-first-loop-alt.f95
@@ -35,7 +35,7 @@ program main
call foo (n)
do i = 0, n - 1
- if (c(i) .ne. (i + MODULO ((i * 3), 7))) STOP 1
+ if (c(i) .ne. (i + MODULO ((i * 3), 7))) stop 1
end do
end program
diff --git a/libgomp/testsuite/libgomp.fortran/pointer1.f90 b/libgomp/testsuite/libgomp.fortran/pointer1.f90
index 817006a2d20..3332000dc61 100644
--- a/libgomp/testsuite/libgomp.fortran/pointer1.f90
+++ b/libgomp/testsuite/libgomp.fortran/pointer1.f90
@@ -21,7 +21,7 @@ contains
c(1) = c(1) + 1
r = r + 1
!$omp end parallel
- if (a.ne.r.or.c(1).ne.r) STOP 1
+ if (a.ne.r.or.c(1).ne.r) stop 1
r2 = r
b => a
d => c
@@ -33,7 +33,7 @@ contains
d(1) = d(1) + 1
r = r + 1
!$omp end parallel
- if (b.ne.r+r2.or.d(1).ne.r+r2) STOP 2
+ if (b.ne.r+r2.or.d(1).ne.r+r2) stop 2
end subroutine foo
subroutine bar (a, c)
integer, pointer :: a, c(:), b, d(:)
@@ -55,8 +55,8 @@ contains
end if
end do
!$omp end parallel do
- if (b.ne.100.or.any(d.ne.10)) STOP 3
- if (a.ne.17.or.any(c.ne.21)) STOP 4
+ if (b.ne.100.or.any(d.ne.10)) stop 3
+ if (a.ne.17.or.any(c.ne.21)) stop 4
a => b
c => d
!$omp parallel do firstprivate (b, d) lastprivate (b, d)
@@ -71,7 +71,7 @@ contains
end if
end do
!$omp end parallel do
- if (a.ne.200.or.any(c.ne.20)) STOP 5
- if (b.ne.17.or.any(d.ne.21)) STOP 6
+ if (a.ne.200.or.any(c.ne.20)) stop 5
+ if (b.ne.17.or.any(d.ne.21)) stop 6
end subroutine bar
end
diff --git a/libgomp/testsuite/libgomp.fortran/pointer2.f90 b/libgomp/testsuite/libgomp.fortran/pointer2.f90
index 859c0e4c36b..3db052e72aa 100644
--- a/libgomp/testsuite/libgomp.fortran/pointer2.f90
+++ b/libgomp/testsuite/libgomp.fortran/pointer2.f90
@@ -21,8 +21,8 @@
thr(1) = thr(1) + 1
i = i + 1
!$omp end parallel
- if (l) STOP 1
- if (thr(1).ne.14) STOP 2
- if (s(1).ne.1+i) STOP 3
- if (u(1).ne.14) STOP 4
+ if (l) stop 1
+ if (thr(1).ne.14) stop 2
+ if (s(1).ne.1+i) stop 3
+ if (u(1).ne.14) stop 4
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr25219.f90 b/libgomp/testsuite/libgomp.fortran/pr25219.f90
index 61dd1bc04e6..6795efa4e85 100644
--- a/libgomp/testsuite/libgomp.fortran/pr25219.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr25219.f90
@@ -1,3 +1,4 @@
+! { dg-do run }
! PR fortran/25219
implicit none
@@ -11,5 +12,5 @@
end do
!$omp end do
!$omp end parallel
- if (k .ne. 100) STOP 1
+ if (k .ne. 100) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr27395-1.f90 b/libgomp/testsuite/libgomp.fortran/pr27395-1.f90
index 8930c780ff2..855a346c865 100644
--- a/libgomp/testsuite/libgomp.fortran/pr27395-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr27395-1.f90
@@ -8,7 +8,7 @@ program pr27395_1
integer, dimension(n) :: sumarray
call foo(n,m,sumarray)
do i=1,n
- if (sumarray(i).ne.m*i) STOP 1
+ if (sumarray(i).ne.m*i) stop 1
end do
end program pr27395_1
diff --git a/libgomp/testsuite/libgomp.fortran/pr27395-2.f90 b/libgomp/testsuite/libgomp.fortran/pr27395-2.f90
index f55b701cdb4..55229cc4b39 100644
--- a/libgomp/testsuite/libgomp.fortran/pr27395-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr27395-2.f90
@@ -25,6 +25,6 @@ subroutine foo(n,m)
!$OMP END DO
!$OMP END PARALLEL
do i=1,n
- if (sumarray(i).ne.m*i) STOP 1
+ if (sumarray(i).ne.m*i) stop 1
end do
end subroutine foo
diff --git a/libgomp/testsuite/libgomp.fortran/pr27416-1.f90 b/libgomp/testsuite/libgomp.fortran/pr27416-1.f90
index 7bc5d3e78c8..e62a784b5a8 100644
--- a/libgomp/testsuite/libgomp.fortran/pr27416-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr27416-1.f90
@@ -6,7 +6,7 @@
!$omp parallel num_threads (4)
call foo (j)
!$omp end parallel
- if (j.ne.6+16) STOP 1
+ if (j.ne.6+16) stop 1
end
subroutine foo (j)
diff --git a/libgomp/testsuite/libgomp.fortran/pr27916-1.f90 b/libgomp/testsuite/libgomp.fortran/pr27916-1.f90
index bb75af9c15c..1a1b0c34144 100644
--- a/libgomp/testsuite/libgomp.fortran/pr27916-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr27916-1.f90
@@ -22,5 +22,5 @@ program pr27916
r = r .or. allocated (a)
end do
!$omp end parallel do
- if (r) STOP 1
+ if (r) stop 1
end program pr27916
diff --git a/libgomp/testsuite/libgomp.fortran/pr27916-2.f90 b/libgomp/testsuite/libgomp.fortran/pr27916-2.f90
index 7973726cb57..c0bc6668f36 100644
--- a/libgomp/testsuite/libgomp.fortran/pr27916-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr27916-2.f90
@@ -22,5 +22,5 @@ program pr27916
r = r .or. allocated (a)
end do
!$omp end parallel do
- if (r) STOP 1
+ if (r) stop 1
end program pr27916
diff --git a/libgomp/testsuite/libgomp.fortran/pr28390.f b/libgomp/testsuite/libgomp.fortran/pr28390.f
index a667e08f73e..9a0832a59bb 100644
--- a/libgomp/testsuite/libgomp.fortran/pr28390.f
+++ b/libgomp/testsuite/libgomp.fortran/pr28390.f
@@ -1,8 +1,9 @@
+! { dg-do run }
! PR fortran/28390
program pr28390
integer i
!$omp parallel do lastprivate(i)
do i=1,100
end do
- if (i.ne.101) STOP 1
+ if (i.ne.101) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr29629.f90 b/libgomp/testsuite/libgomp.fortran/pr29629.f90
index 4b802c56310..1920ac0b4a3 100644
--- a/libgomp/testsuite/libgomp.fortran/pr29629.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr29629.f90
@@ -4,7 +4,7 @@
program pr29629
integer :: n
n = 10000
- if (any (func(n).ne.10000)) STOP 1
+ if (any (func(n).ne.10000)) stop 1
contains
function func(n)
integer, intent(in) :: n
diff --git a/libgomp/testsuite/libgomp.fortran/pr32550.f90 b/libgomp/testsuite/libgomp.fortran/pr32550.f90
index ce496cacd23..99852df3296 100644
--- a/libgomp/testsuite/libgomp.fortran/pr32550.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr32550.f90
@@ -17,5 +17,5 @@
e = e + 1
end if
!$omp end parallel
- if (e.ne.0) STOP 1
+ if (e.ne.0) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr33880.f90 b/libgomp/testsuite/libgomp.fortran/pr33880.f90
index e6a26f42d82..ec00dd86d8b 100644
--- a/libgomp/testsuite/libgomp.fortran/pr33880.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr33880.f90
@@ -9,7 +9,7 @@ program pr33880
!$omp atomic
j = j + 1
end do
- if (j .ne. 1000) STOP 1
+ if (j .ne. 1000) stop 1
contains
subroutine something()
i = 0
diff --git a/libgomp/testsuite/libgomp.fortran/pr34020.f90 b/libgomp/testsuite/libgomp.fortran/pr34020.f90
index 6d2316472d8..31aaecda180 100644
--- a/libgomp/testsuite/libgomp.fortran/pr34020.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr34020.f90
@@ -16,5 +16,5 @@
do i = 1, 300000
call atomic_add(lhs, rhs)
enddo
- if (lhs .ne. 300000) STOP 1
+ if (lhs .ne. 300000) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr35130.f90 b/libgomp/testsuite/libgomp.fortran/pr35130.f90
index e6be64f15f5..05d00a67ee1 100644
--- a/libgomp/testsuite/libgomp.fortran/pr35130.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr35130.f90
@@ -1,3 +1,4 @@
+! { dg-do run }
! PR middle-end/35130
program pr35130
@@ -10,7 +11,7 @@ program pr35130
call inner(k)
end do
!$omp end parallel do
- if (any (a.ne.42)) STOP 1
+ if (any (a.ne.42)) stop 1
contains
subroutine inner(i)
implicit none
diff --git a/libgomp/testsuite/libgomp.fortran/pr42162.f90 b/libgomp/testsuite/libgomp.fortran/pr42162.f90
index 3792a33fe9f..fd75f554ea4 100644
--- a/libgomp/testsuite/libgomp.fortran/pr42162.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr42162.f90
@@ -49,5 +49,5 @@ program pr42162
!$omp parallel num_threads(3)
call sub3 (k, c)
!$omp end parallel
- if (k.ne.4.or.any(a.ne.2).or.any(b.ne.3).or.any(c.ne.4)) STOP 1
+ if (k.ne.4.or.any(a.ne.2).or.any(b.ne.3).or.any(c.ne.4)) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr46753.f90 b/libgomp/testsuite/libgomp.fortran/pr46753.f90
index 0d9debce196..5caa4d7e86b 100644
--- a/libgomp/testsuite/libgomp.fortran/pr46753.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr46753.f90
@@ -7,11 +7,11 @@
do i = 2147483636, 2147483646
j = j + 1
end do
- if (j.ne.11) STOP 1
+ if (j.ne.11) stop 1
j = 0
!$omp parallel do reduction(+:j)
do i = -2147483637, -2147483647, -1
j = j + 1
end do
- if (j.ne.11) STOP 2
+ if (j.ne.11) stop 2
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr48894.f90 b/libgomp/testsuite/libgomp.fortran/pr48894.f90
index 0f7bfad4cae..e906f45e27f 100644
--- a/libgomp/testsuite/libgomp.fortran/pr48894.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr48894.f90
@@ -19,5 +19,5 @@
endif
!$omp end parallel
!$omp end parallel
- if (err .ne. 0) STOP 1
+ if (err .ne. 0) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr49792-1.f90 b/libgomp/testsuite/libgomp.fortran/pr49792-1.f90
index 18643ac5a50..5a9d470b5e9 100644
--- a/libgomp/testsuite/libgomp.fortran/pr49792-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr49792-1.f90
@@ -14,5 +14,5 @@ program pr49792
real(kind=8) :: b(16)
b(:) = a(16:1:-1)
call reverse (16,a)
- if (any (a.ne.b)) STOP 1
+ if (any (a.ne.b)) stop 1
end program pr49792
diff --git a/libgomp/testsuite/libgomp.fortran/pr49792-2.f90 b/libgomp/testsuite/libgomp.fortran/pr49792-2.f90
index 689f7decacb..570901d5559 100644
--- a/libgomp/testsuite/libgomp.fortran/pr49792-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr49792-2.f90
@@ -17,6 +17,6 @@ program pr49792
!$omp parallel workshare
a = b
!$omp end parallel workshare
- if (size(a).ne.size(b)) STOP 1
- if (any (a.ne.b)) STOP 2
+ if (size(a).ne.size(b)) stop 1
+ if (any (a.ne.b)) stop 2
end program pr49792
diff --git a/libgomp/testsuite/libgomp.fortran/pr63938-1.f90 b/libgomp/testsuite/libgomp.fortran/pr63938-1.f90
index eb85500ea4c..4cc8be7ec1e 100644
--- a/libgomp/testsuite/libgomp.fortran/pr63938-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr63938-1.f90
@@ -10,5 +10,5 @@ program pr63938_1
x(1) = x(1) + 1
end do
!$omp end parallel do
- if (x(1) .ne. 1000) STOP 1
+ if (x(1) .ne. 1000) stop 1
end program pr63938_1
diff --git a/libgomp/testsuite/libgomp.fortran/pr63938-2.f90 b/libgomp/testsuite/libgomp.fortran/pr63938-2.f90
index 934e800648e..d0a17ac4fea 100644
--- a/libgomp/testsuite/libgomp.fortran/pr63938-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr63938-2.f90
@@ -14,5 +14,5 @@ program pr63938_2
x%x = x%x + 1
end do
!$omp end parallel do
- if (x%x .ne. 1000) STOP 1
+ if (x%x .ne. 1000) stop 1
end program pr63938_2
diff --git a/libgomp/testsuite/libgomp.fortran/pr65597.f90 b/libgomp/testsuite/libgomp.fortran/pr65597.f90
index 25754314766..29d1c9e80bc 100644
--- a/libgomp/testsuite/libgomp.fortran/pr65597.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr65597.f90
@@ -13,9 +13,9 @@
end do
do i = 1, 151
if (mod (i, 31) .eq. 1) then
- if (a(i) .ne. 2) STOP 1
+ if (a(i) .ne. 2) stop 1
else
- if (a(i) .ne. 0) STOP 2
+ if (a(i) .ne. 0) stop 2
end if
end do
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr66199-1.f90 b/libgomp/testsuite/libgomp.fortran/pr66199-1.f90
index ecf62458340..6c9e566cf86 100644
--- a/libgomp/testsuite/libgomp.fortran/pr66199-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr66199-1.f90
@@ -1,5 +1,4 @@
! PR middle-end/66199
-! { dg-do run }
! { dg-options "-O2" }
integer :: u(1024), v(1024), w(1024), a, b, c, d, e, a1, b1, a2, b2, d1, d2
@@ -10,7 +9,7 @@
do d = a, b
u(d) = v(d) + w(d)
end do
- if (d .ne. 1025) STOP 1
+ if (d .ne. 1025) stop 1
c = 17
d = 75
!$omp parallel do simd default(none) firstprivate (a, b) shared(u, v, w) &
@@ -20,8 +19,8 @@
c = c + 5
e = c
end do
- if (d .ne. 1025 .or. c .ne. (17 + 5 * 1024)) STOP 2
- if (e .ne. (17 + 5 * 1024)) STOP 3
+ if (d .ne. 1025 .or. c .ne. (17 + 5 * 1024)) stop 2
+ if (e .ne. (17 + 5 * 1024)) stop 3
a1 = 0
a2 = 0
b1 = 31
@@ -35,7 +34,7 @@
u(d1 * 32 + d2 + 1) = v(d1 * 32 + d2 + 1) + w(d1 * 32 + d2 + 1)
end do
end do
- if (d1 .ne. 32 .or. d2 .ne. 32) STOP 4
+ if (d1 .ne. 32 .or. d2 .ne. 32) stop 4
d1 = 7
d2 = 9
!$omp parallel do simd default(none) firstprivate (a1, b1, a2, b2) &
@@ -45,5 +44,5 @@
u(d1 * 32 + d2 + 1) = v(d1 * 32 + d2 + 1) + w(d1 * 32 + d2 + 1)
end do
end do
- if (d1 .ne. 32 .or. d2 .ne. 32) STOP 5
+ if (d1 .ne. 32 .or. d2 .ne. 32) stop 5
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr66199-2.f90 b/libgomp/testsuite/libgomp.fortran/pr66199-2.f90
index 0cc0fa5097f..fef15b2bb57 100644
--- a/libgomp/testsuite/libgomp.fortran/pr66199-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr66199-2.f90
@@ -1,5 +1,4 @@
! PR middle-end/66199
-! { dg-do run }
! { dg-options "-O2" }
integer :: u(1024), v(1024), w(1024), a, b, c, d, e, a1, b1, a2, b2, d1, d2
diff --git a/libgomp/testsuite/libgomp.fortran/pr71014.f90 b/libgomp/testsuite/libgomp.fortran/pr71014.f90
index 7fcbf73862d..518df1024aa 100644
--- a/libgomp/testsuite/libgomp.fortran/pr71014.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr71014.f90
@@ -16,5 +16,5 @@ program pr71014
end do
end associate
end do
- if (any(s /= t)) STOP 1
+ if (any(s /= t)) stop 1
end program pr71014
diff --git a/libgomp/testsuite/libgomp.fortran/pr81304.f90 b/libgomp/testsuite/libgomp.fortran/pr81304.f90
index c7419342ca6..3f7406aeaf5 100644
--- a/libgomp/testsuite/libgomp.fortran/pr81304.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr81304.f90
@@ -13,5 +13,5 @@ program pr81304
a = min (a, c)
b = max (b, c)
end do
- if (any (a /= (/ 1, -4, 6 /)) .or. any (b /= (/ 16, 11, 21 /))) STOP 1
+ if (any (a /= (/ 1, -4, 6 /)) .or. any (b /= (/ 16, 11, 21 /))) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr81841.f90 b/libgomp/testsuite/libgomp.fortran/pr81841.f90
index ed75837c37b..9ddc95af69f 100644
--- a/libgomp/testsuite/libgomp.fortran/pr81841.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr81841.f90
@@ -17,10 +17,10 @@ program pr81841
common /c/ e, f
!$omp threadprivate (/c/)
!$omp parallel num_threads(8)
- if ((e /= 32) .or. any(f /= 1.)) STOP 1
+ if ((e /= 32) .or. any(f /= 1.)) stop 1
e = omp_get_thread_num ()
f = e + 19.
!$omp barrier
- if ((e /= omp_get_thread_num ()) .or. any(f /= e + 19.)) STOP 2
+ if ((e /= omp_get_thread_num ()) .or. any(f /= e + 19.)) stop 2
!$omp end parallel
end
diff --git a/libgomp/testsuite/libgomp.fortran/pr84418-1.f90 b/libgomp/testsuite/libgomp.fortran/pr84418-1.f90
index 59391211a74..8547fceb79e 100644
--- a/libgomp/testsuite/libgomp.fortran/pr84418-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr84418-1.f90
@@ -15,7 +15,7 @@
c(i) = foo (a(i), b(i))
end do
do i = 1, 1024
- if (c(i).ne.(2 * i)) STOP 1
+ if (c(i).ne.(2 * i)) stop 1
end do
contains
real function foo (x, y)
diff --git a/libgomp/testsuite/libgomp.fortran/pr84418-2.f90 b/libgomp/testsuite/libgomp.fortran/pr84418-2.f90
index f85fbf2ba87..481e24e5d8a 100644
--- a/libgomp/testsuite/libgomp.fortran/pr84418-2.f90
+++ b/libgomp/testsuite/libgomp.fortran/pr84418-2.f90
@@ -23,7 +23,7 @@
c(i) = foo (a(i), b(:,i))
end do
do i = 1, 1024
- if (c(i).ne.(6 * i)) STOP 1
+ if (c(i).ne.(6 * i)) stop 1
end do
contains
function foo (x, y)
diff --git a/libgomp/testsuite/libgomp.fortran/pr88463-1.f90 b/libgomp/testsuite/libgomp.fortran/pr88463-1.f90
new file mode 100644
index 00000000000..53a99ee7c7f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/pr88463-1.f90
@@ -0,0 +1,19 @@
+! PR fortran/88463
+! { dg-do compile { target { ! *-*-* } } }
+
+module pr88463_1
+ integer, parameter :: c = 1
+ real, parameter :: d(4) = (/ 2, 3, 4, 5 /)
+end module pr88463_1
+
+program pr88463
+ use pr88463_1
+ use pr88463_2
+ integer :: i
+ real :: j(4)
+ !$omp parallel default(none) private (i, j)
+ i = a + b(1) + b(4) + c + d(1) + d(4)
+ j(1:4) = b(1:4)
+ j(1:4) = d(1:4)
+ !$omp end parallel
+end program pr88463
diff --git a/libgomp/testsuite/libgomp.fortran/pr88463-2.f90 b/libgomp/testsuite/libgomp.fortran/pr88463-2.f90
new file mode 100644
index 00000000000..8b2b98ddda1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/pr88463-2.f90
@@ -0,0 +1,9 @@
+! PR fortran/88463
+! { dg-do link }
+! { dg-options "-fopenmp" }
+! { dg-additional-sources pr88463-1.f90 }
+
+module pr88463_2
+ integer, parameter :: a = 1
+ real, parameter :: b(4) = (/ 2., 3., 4., 5. /)
+end module pr88463_2
diff --git a/libgomp/testsuite/libgomp.fortran/pr90779.f90 b/libgomp/testsuite/libgomp.fortran/pr90779.f90
new file mode 100644
index 00000000000..c14dc87dd00
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/pr90779.f90
@@ -0,0 +1,13 @@
+! { dg-do run }
+! PR middle-end/90779
+
+program pr90779
+ implicit none
+ integer :: v(4), i
+
+ !$omp target map(from:v)
+ v(:) = (/ (i, i=1,4) /)
+ !$omp end target
+
+ if (any (v .ne. (/ (i, i=1,4) /))) stop 1
+end program
diff --git a/libgomp/testsuite/libgomp.fortran/procptr1.f90 b/libgomp/testsuite/libgomp.fortran/procptr1.f90
index 560d0da4216..44410d47b53 100644
--- a/libgomp/testsuite/libgomp.fortran/procptr1.f90
+++ b/libgomp/testsuite/libgomp.fortran/procptr1.f90
@@ -11,25 +11,25 @@
integer :: i
ptr => foo
!$omp parallel shared (ptr)
- if (ptr () /= 1) STOP 1
+ if (ptr () /= 1) stop 1
!$omp end parallel
ptr => bar
!$omp parallel firstprivate (ptr)
- if (ptr () /= 2) STOP 2
+ if (ptr () /= 2) stop 2
!$omp end parallel
!$omp parallel sections lastprivate (ptr)
!$omp section
ptr => foo
- if (ptr () /= 1) STOP 3
+ if (ptr () /= 1) stop 3
!$omp section
ptr => bar
- if (ptr () /= 2) STOP 4
+ if (ptr () /= 2) stop 4
!$omp section
ptr => baz
- if (ptr () /= 3) STOP 5
+ if (ptr () /= 3) stop 5
!$omp end parallel sections
- if (ptr () /= 3) STOP 6
- if (.not.associated (ptr, baz)) STOP 7
+ if (ptr () /= 3) stop 6
+ if (.not.associated (ptr, baz)) stop 7
end
integer function foo ()
foo = 1
diff --git a/libgomp/testsuite/libgomp.fortran/recursion1.f90 b/libgomp/testsuite/libgomp.fortran/recursion1.f90
index c9aec7e4159..2546d09d11e 100644
--- a/libgomp/testsuite/libgomp.fortran/recursion1.f90
+++ b/libgomp/testsuite/libgomp.fortran/recursion1.f90
@@ -14,7 +14,7 @@ do i=1,10
call sub(i)
end do
!$omp end parallel do
-if (s/=55) STOP 1
+if (s/=55) stop 1
contains
diff --git a/libgomp/testsuite/libgomp.fortran/reduction1.f90 b/libgomp/testsuite/libgomp.fortran/reduction1.f90
index bc036b057ea..622a7059d6c 100644
--- a/libgomp/testsuite/libgomp.fortran/reduction1.f90
+++ b/libgomp/testsuite/libgomp.fortran/reduction1.f90
@@ -55,14 +55,14 @@
ca = cmplx (-1, 0)
end if
!$omp end parallel
- if (v) STOP 1
+ if (v) stop 1
if (cnt .eq. 3) then
- if (i .ne. 8 .or. any (ia .ne. (/3, 3, 1, 6, 6, 8/))) STOP 2
- if (r .ne. 8 .or. any (ra .ne. (/9.5, 8.0, 1.5, 1.5/))) STOP 3
- if (d .ne. 12.5 .or. any (da .ne. (/8.0, 16.5, 16.5, 14.0, 5.5/))) STOP 4
- if (c .ne. cmplx (11.5, -5)) STOP 5
- if (ca(1) .ne. cmplx (12, 2)) STOP 6
- if (ca(2) .ne. cmplx (6.5, 3) .or. ca(2) .ne. ca(3)) STOP 7
+ if (i .ne. 8 .or. any (ia .ne. (/3, 3, 1, 6, 6, 8/))) stop 2
+ if (r .ne. 8 .or. any (ra .ne. (/9.5, 8.0, 1.5, 1.5/))) stop 3
+ if (d .ne. 12.5 .or. any (da .ne. (/8.0, 16.5, 16.5, 14.0, 5.5/))) stop 4
+ if (c .ne. cmplx (11.5, -5)) stop 5
+ if (ca(1) .ne. cmplx (12, 2)) stop 6
+ if (ca(2) .ne. cmplx (6.5, 3) .or. ca(2) .ne. ca(3)) stop 7
end if
i = 1
@@ -113,14 +113,14 @@
ca = cmplx (-1, 0)
end if
!$omp end parallel
- if (v) STOP 8
+ if (v) stop 8
if (cnt .eq. 3) then
- if (i .ne. 8 .or. any (ia .ne. (/3, 3, 1, 6, 6, 8/))) STOP 9
- if (r .ne. 8 .or. any (ra .ne. (/9.5, 8.0, 1.5, 1.5/))) STOP 10
- if (d .ne. 12.5 .or. any (da .ne. (/8.0, 16.5, 16.5, 14.0, 5.5/))) STOP 11
- if (c .ne. cmplx (11.5, -5)) STOP 12
- if (ca(1) .ne. cmplx (12, 2)) STOP 13
- if (ca(2) .ne. cmplx (6.5, 3) .or. ca(2) .ne. ca(3)) STOP 14
+ if (i .ne. 8 .or. any (ia .ne. (/3, 3, 1, 6, 6, 8/))) stop 9
+ if (r .ne. 8 .or. any (ra .ne. (/9.5, 8.0, 1.5, 1.5/))) stop 10
+ if (d .ne. 12.5 .or. any (da .ne. (/8.0, 16.5, 16.5, 14.0, 5.5/))) stop 11
+ if (c .ne. cmplx (11.5, -5)) stop 12
+ if (ca(1) .ne. cmplx (12, 2)) stop 13
+ if (ca(2) .ne. cmplx (6.5, 3) .or. ca(2) .ne. ca(3)) stop 14
end if
i = 1
@@ -169,13 +169,13 @@
ca = cmplx (-1, 0)
end if
!$omp end parallel
- if (v) STOP 15
+ if (v) stop 15
if (cnt .eq. 3) then
- if (i .ne. 6 .or. any (ia .ne. (/4, 4, 8, -16, -16, -8/))) STOP 16
- if (r .ne. 8 .or. any (ra .ne. (/4., -2., -1., -1./))) STOP 17
- if (d .ne. -40 .or. any (da .ne. (/32., -64., -64., 64., -32./))) STOP 18
- if (c .ne. cmplx (0, 15)) STOP 19
- if (ca(1) .ne. cmplx (0, 10)) STOP 20
- if (ca(2) .ne. cmplx (-2, 0) .or. ca(2) .ne. ca(3)) STOP 21
+ if (i .ne. 6 .or. any (ia .ne. (/4, 4, 8, -16, -16, -8/))) stop 16
+ if (r .ne. 8 .or. any (ra .ne. (/4., -2., -1., -1./))) stop 17
+ if (d .ne. -40 .or. any (da .ne. (/32., -64., -64., 64., -32./))) stop 18
+ if (c .ne. cmplx (0, 15)) stop 19
+ if (ca(1) .ne. cmplx (0, 10)) stop 20
+ if (ca(2) .ne. cmplx (-2, 0) .or. ca(2) .ne. ca(3)) stop 21
end if
end
diff --git a/libgomp/testsuite/libgomp.fortran/reduction2.f90 b/libgomp/testsuite/libgomp.fortran/reduction2.f90
index 6af173d2397..75c2e0cf239 100644
--- a/libgomp/testsuite/libgomp.fortran/reduction2.f90
+++ b/libgomp/testsuite/libgomp.fortran/reduction2.f90
@@ -31,10 +31,10 @@
ma(1) = .true.
end if
!$omp end parallel
- if (v) STOP 1
+ if (v) stop 1
if (cnt .eq. 3) then
- if (l .or. any (la .neqv. (/.true., .false., .false., .false./))) STOP 2
- if (.not. m .or. any (ma .neqv. (/.true., .true., .false., .true./))) STOP 3
+ if (l .or. any (la .neqv. (/.true., .false., .false., .false./))) stop 2
+ if (.not. m .or. any (ma .neqv. (/.true., .true., .false., .true./))) stop 3
end if
l = .true.
@@ -64,10 +64,10 @@
ma(1) = .true.
end if
!$omp end parallel
- if (v) STOP 4
+ if (v) stop 4
if (cnt .eq. 3) then
- if (.not. l .or. any (la .neqv. (/.true., .false., .true., .false./))) STOP 5
- if (.not. m .or. any (ma .neqv. (/.false., .true., .false., .true./))) STOP 6
+ if (.not. l .or. any (la .neqv. (/.true., .false., .true., .false./))) stop 5
+ if (.not. m .or. any (ma .neqv. (/.false., .true., .false., .true./))) stop 6
end if
end
diff --git a/libgomp/testsuite/libgomp.fortran/reduction3.f90 b/libgomp/testsuite/libgomp.fortran/reduction3.f90
index b0a858b54f0..e19bac6f57e 100644
--- a/libgomp/testsuite/libgomp.fortran/reduction3.f90
+++ b/libgomp/testsuite/libgomp.fortran/reduction3.f90
@@ -46,11 +46,11 @@
da = -1
end if
!$omp end parallel
- if (v) STOP 1
+ if (v) stop 1
if (cnt .eq. 3) then
- if (i .ne. 4 .or. any (ia .ne. (/7, 2, 2, 5, 5, 5/))) STOP 2
- if (r .ne. 5 .or. any (ra .ne. (/6.5, 6.5, 4., 4./))) STOP 3
- if (d .ne. 8.5 .or. any (da .ne. (/6.5, 8.5, 8.5, 8.5, 6.5/))) STOP 4
+ if (i .ne. 4 .or. any (ia .ne. (/7, 2, 2, 5, 5, 5/))) stop 2
+ if (r .ne. 5 .or. any (ra .ne. (/6.5, 6.5, 4., 4./))) stop 3
+ if (d .ne. 8.5 .or. any (da .ne. (/6.5, 8.5, 8.5, 8.5, 6.5/))) stop 4
end if
i = 1
@@ -94,10 +94,10 @@
da(1:4) = 6
end if
!$omp end parallel
- if (v) STOP 5
+ if (v) stop 5
if (cnt .eq. 3) then
- if (i .ne. 1 .or. any (ia .ne. (/1, 1, -2, -2, -2, 1/))) STOP 6
- if (r .ne. -1 .or. any (ra .ne. (/4., -1.5, -8.5, -1.5/))) STOP 7
- if (d .ne. -2.5 .or. any (da .ne. (/2.5, 2.5, 2.5, 6., 6.5/))) STOP 8
+ if (i .ne. 1 .or. any (ia .ne. (/1, 1, -2, -2, -2, 1/))) stop 6
+ if (r .ne. -1 .or. any (ra .ne. (/4., -1.5, -8.5, -1.5/))) stop 7
+ if (d .ne. -2.5 .or. any (da .ne. (/2.5, 2.5, 2.5, 6., 6.5/))) stop 8
end if
end
diff --git a/libgomp/testsuite/libgomp.fortran/reduction4.f90 b/libgomp/testsuite/libgomp.fortran/reduction4.f90
index 91c7fc89bf2..2de903c05a1 100644
--- a/libgomp/testsuite/libgomp.fortran/reduction4.f90
+++ b/libgomp/testsuite/libgomp.fortran/reduction4.f90
@@ -4,12 +4,12 @@
integer (kind = 4) :: i, ia (6), j, ja (6), k, ka (6), ta (6), n, cnt, x
logical :: v
- i = Z'ffff0f'
- ia = Z'f0ff0f'
- j = Z'0f0000'
- ja = Z'0f5a00'
- k = Z'055aa0'
- ka = Z'05a5a5'
+ i = int(Z'ffff0f')
+ ia = int(Z'f0ff0f')
+ j = int(Z'0f0000')
+ ja = int(Z'0f5a00')
+ k = int(Z'055aa0')
+ ka = int(Z'05a5a5')
v = .false.
cnt = -1
x = not(0)
@@ -22,35 +22,35 @@
n = omp_get_thread_num ()
if (n .eq. 0) then
cnt = omp_get_num_threads ()
- i = Z'ff7fff'
- ia(3:5) = Z'fffff1'
- j = Z'078000'
+ i = int(Z'ff7fff')
+ ia(3:5) = int(Z'fffff1')
+ j = int(Z'078000')
ja(1:3) = 1
- k = Z'78'
- ka(3:6) = Z'f0f'
+ k = int(Z'78')
+ ka(3:6) = int(Z'f0f')
else if (n .eq. 1) then
- i = Z'ffff77'
- ia(2:5) = Z'ffafff'
- j = Z'007800'
+ i = int(Z'ffff77')
+ ia(2:5) = int(Z'ffafff')
+ j = int(Z'007800')
ja(2:5) = 8
- k = Z'57'
- ka(3:4) = Z'f0108'
+ k = int(Z'57')
+ ka(3:4) = int(Z'f0108')
else
- i = Z'777fff'
- ia(1:2) = Z'fffff3'
- j = Z'000780'
- ja(5:6) = Z'f00'
- k = Z'1000'
- ka(6:6) = Z'777'
+ i = int(Z'777fff')
+ ia(1:2) = int(Z'fffff3')
+ j = int(Z'000780')
+ ja(5:6) = int(Z'f00')
+ k = int(Z'1000')
+ ka(6:6) = int(Z'777')
end if
!$omp end parallel
- if (v) STOP 1
+ if (v) stop 1
if (cnt .eq. 3) then
- ta = (/Z'f0ff03', Z'f0af03', Z'f0af01', Z'f0af01', Z'f0af01', Z'f0ff0f'/)
- if (i .ne. Z'777f07' .or. any (ia .ne. ta)) STOP 2
- ta = (/Z'f5a01', Z'f5a09', Z'f5a09', Z'f5a08', Z'f5f08', Z'f5f00'/)
- if (j .ne. Z'fff80' .or. any (ja .ne. ta)) STOP 3
- ta = (/Z'5a5a5', Z'5a5a5', Z'aaba2', Z'aaba2', Z'5aaaa', Z'5addd'/)
- if (k .ne. Z'54a8f' .or. any (ka .ne. ta)) STOP 4
+ ta = (/int(Z'f0ff03'), int(Z'f0af03'), int(Z'f0af01'), int(Z'f0af01'), int(Z'f0af01'), int(Z'f0ff0f')/)
+ if (i .ne. int(Z'777f07') .or. any (ia .ne. ta)) stop 2
+ ta = (/int(Z'f5a01'), int(Z'f5a09'), int(Z'f5a09'), int(Z'f5a08'), int(Z'f5f08'), int(Z'f5f00')/)
+ if (j .ne. int(Z'fff80') .or. any (ja .ne. ta)) stop 3
+ ta = (/int(Z'5a5a5'), int(Z'5a5a5'), int(Z'aaba2'), int(Z'aaba2'), int(Z'5aaaa'), int(Z'5addd')/)
+ if (k .ne. int(Z'54a8f') .or. any (ka .ne. ta)) stop 4
end if
end
diff --git a/libgomp/testsuite/libgomp.fortran/reduction5.f90 b/libgomp/testsuite/libgomp.fortran/reduction5.f90
index f8fdcb471fe..e2a17a93a1f 100644
--- a/libgomp/testsuite/libgomp.fortran/reduction5.f90
+++ b/libgomp/testsuite/libgomp.fortran/reduction5.f90
@@ -10,15 +10,15 @@ contains
subroutine test1
use reduction5, bitwise_or => ior
integer :: n
- n = Z'f'
+ n = int(Z'f')
!$omp parallel sections num_threads (3) reduction (bitwise_or: n)
- n = ior (n, Z'20')
+ n = ior (n, int(Z'20'))
!$omp section
- n = bitwise_or (Z'410', n)
+ n = bitwise_or (int(Z'410'), n)
!$omp section
- n = bitwise_or (n, Z'2000')
+ n = bitwise_or (n, int(Z'2000'))
!$omp end parallel sections
- if (n .ne. Z'243f') STOP 1
+ if (n .ne. int(Z'243f')) stop 1
end subroutine
subroutine test2
use reduction5, min => max, max => min
@@ -36,7 +36,7 @@ contains
if (m .gt. 3) m = 3
if (n .lt. -1) n = -1
!$omp end parallel sections
- if (m .ne. 3 .or. n .ne. 15) STOP 2
+ if (m .ne. 3 .or. n .ne. 15) stop 2
end subroutine test2
end
diff --git a/libgomp/testsuite/libgomp.fortran/reduction6.f90 b/libgomp/testsuite/libgomp.fortran/reduction6.f90
index 99fb8d16bc0..24d849cc60f 100644
--- a/libgomp/testsuite/libgomp.fortran/reduction6.f90
+++ b/libgomp/testsuite/libgomp.fortran/reduction6.f90
@@ -8,7 +8,7 @@
call foo (a (2:4, 3:5), nthreads)
if (nthreads .eq. 3) then
write (c, '(36i1)') a
- if (c .ne. '999999999999966699966699966699999999') STOP 1
+ if (c .ne. '999999999999966699966699966699999999') stop 1
end if
contains
subroutine foo (b, nthreads)
@@ -27,6 +27,6 @@ contains
!$omp end master
b = 2
!$omp end parallel
- if (err .gt. 0) STOP 2
+ if (err .gt. 0) stop 2
end subroutine foo
end
diff --git a/libgomp/testsuite/libgomp.fortran/reference1.f90 b/libgomp/testsuite/libgomp.fortran/reference1.f90
index 8c9631b49d2..1d52c2fcdaa 100644
--- a/libgomp/testsuite/libgomp.fortran/reference1.f90
+++ b/libgomp/testsuite/libgomp.fortran/reference1.f90
@@ -8,10 +8,10 @@
k = 0
d = 24.5
call test (i, j, k, d)
- if (i .ne. 38) STOP 1
- if (iand (k, 255) .ne. 0) STOP 2
+ if (i .ne. 38) stop 1
+ if (iand (k, 255) .ne. 0) stop 2
if (iand (k, 65280) .eq. 0) then
- if (k .ne. 65536 * 4) STOP 3
+ if (k .ne. 65536 * 4) stop 3
end if
contains
subroutine test (i, j, k, d)
diff --git a/libgomp/testsuite/libgomp.fortran/reference2.f90 b/libgomp/testsuite/libgomp.fortran/reference2.f90
index 87efab255e1..6fcd05dca4b 100644
--- a/libgomp/testsuite/libgomp.fortran/reference2.f90
+++ b/libgomp/testsuite/libgomp.fortran/reference2.f90
@@ -11,7 +11,7 @@ contains
a = 15
l = bar (a)
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end subroutine
function bar (a)
real, dimension (5) :: a
diff --git a/libgomp/testsuite/libgomp.fortran/retval1.f90 b/libgomp/testsuite/libgomp.fortran/retval1.f90
index db49a0da8a0..604e14e2e84 100644
--- a/libgomp/testsuite/libgomp.fortran/retval1.f90
+++ b/libgomp/testsuite/libgomp.fortran/retval1.f90
@@ -14,7 +14,7 @@ function f1 ()
l = l .or. (omp_get_thread_num () .eq. 0 .and. f1 .ne. 8.5)
l = l .or. (omp_get_thread_num () .eq. 1 .and. f1 .ne. 14.5)
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
f1 = -2.5
end function f1
function f2 ()
@@ -32,7 +32,7 @@ entry e2 ()
l = l .or. (omp_get_thread_num () .eq. 0 .and. e2 .ne. 8.5)
l = l .or. (omp_get_thread_num () .eq. 1 .and. e2 .ne. 14.5)
!$omp end parallel
- if (l) STOP 2
+ if (l) stop 2
e2 = 7.5
end function f2
function f3 ()
@@ -53,7 +53,7 @@ entry e3 ()
l = l .or. (omp_get_thread_num () .eq. 1 .and. e3 .ne. 14.5)
l = l .or. f3 .ne. e3 - 4.5
!$omp end parallel
- if (l) STOP 3
+ if (l) stop 3
e3 = 0.5
end function f3
function f4 () result (r4)
@@ -74,7 +74,7 @@ entry e4 () result (s4)
l = l .or. (omp_get_thread_num () .eq. 1 .and. s4 .ne. 14.5)
l = l .or. r4 .ne. s4 - 4.5
!$omp end parallel
- if (l) STOP 4
+ if (l) stop 4
s4 = -0.5
end function f4
function f5 (is_f5)
@@ -101,20 +101,20 @@ entry e5 (is_f5)
l = l .or. (omp_get_thread_num () .eq. 1 .and. e5 .ne. 14)
l = l .or. f5 .ne. e5 - 4.5
!$omp end parallel
- if (l) STOP 5
+ if (l) stop 5
if (is_f5) f5 = -2.5
if (.not. is_f5) e5 = 8
end function f5
real :: f1, f2, e2, f3, e3, f4, e4, f5
integer :: e5
- if (f1 () .ne. -2.5) STOP 6
- if (f2 () .ne. 7.5) STOP 7
- if (e2 () .ne. 7.5) STOP 8
- if (f3 () .ne. 0.5) STOP 9
- if (e3 () .ne. 0.5) STOP 10
- if (f4 () .ne. -0.5) STOP 11
- if (e4 () .ne. -0.5) STOP 12
- if (f5 (.true.) .ne. -2.5) STOP 13
- if (e5 (.false.) .ne. 8) STOP 14
+ if (f1 () .ne. -2.5) stop 6
+ if (f2 () .ne. 7.5) stop 7
+ if (e2 () .ne. 7.5) stop 8
+ if (f3 () .ne. 0.5) stop 9
+ if (e3 () .ne. 0.5) stop 10
+ if (f4 () .ne. -0.5) stop 11
+ if (e4 () .ne. -0.5) stop 12
+ if (f5 (.true.) .ne. -2.5) stop 13
+ if (e5 (.false.) .ne. 8) stop 14
end
diff --git a/libgomp/testsuite/libgomp.fortran/retval2.f90 b/libgomp/testsuite/libgomp.fortran/retval2.f90
index a2fd5b99117..2851e056eb8 100644
--- a/libgomp/testsuite/libgomp.fortran/retval2.f90
+++ b/libgomp/testsuite/libgomp.fortran/retval2.f90
@@ -17,11 +17,11 @@ contains
l = l .or. (omp_get_thread_num () .eq. 0 .and. f1 .ne. 8.5)
l = l .or. (omp_get_thread_num () .eq. 1 .and. f1 .ne. 14.5)
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
f1 = -2.5
end subroutine sub1
end function f1
real :: f1
- if (f1 () .ne. -2.5) STOP 2
+ if (f1 () .ne. -2.5) stop 2
end
diff --git a/libgomp/testsuite/libgomp.fortran/sharing1.f90 b/libgomp/testsuite/libgomp.fortran/sharing1.f90
index 03633e9a78c..48c21aae429 100644
--- a/libgomp/testsuite/libgomp.fortran/sharing1.f90
+++ b/libgomp/testsuite/libgomp.fortran/sharing1.f90
@@ -25,5 +25,5 @@
!$omp barrier
if (j .ne. 25 .or. i .ne. (k * 10 + 14)) l = .true.
!$omp end parallel
- if (l .or. j .ne. 25) STOP 1
+ if (l .or. j .ne. 25) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/sharing2.f90 b/libgomp/testsuite/libgomp.fortran/sharing2.f90
index 0b01059ee1d..3f76475f68e 100644
--- a/libgomp/testsuite/libgomp.fortran/sharing2.f90
+++ b/libgomp/testsuite/libgomp.fortran/sharing2.f90
@@ -27,6 +27,6 @@
!$omp barrier
if (j .ne. 25 .or. i .ne. (k * 10 + 14)) l = .true.
!$omp end parallel
- if (l) STOP 1
- if (j .ne. 25) STOP 2
+ if (l) stop 1
+ if (j .ne. 25) stop 2
end
diff --git a/libgomp/testsuite/libgomp.fortran/simd1.f90 b/libgomp/testsuite/libgomp.fortran/simd1.f90
index 558e141e1d1..353f16d04bc 100644
--- a/libgomp/testsuite/libgomp.fortran/simd1.f90
+++ b/libgomp/testsuite/libgomp.fortran/simd1.f90
@@ -30,6 +30,6 @@
s = s + l
t%x = t%x + l
end do
- if (r.ne.2700.or.j.ne.70.or.k.ne.80.or.s.ne.2700) STOP 1
- if (t%x.ne.2700) STOP 2
+ if (r.ne.2700.or.j.ne.70.or.k.ne.80.or.s.ne.2700) stop 1
+ if (t%x.ne.2700) stop 2
end
diff --git a/libgomp/testsuite/libgomp.fortran/simd2.f90 b/libgomp/testsuite/libgomp.fortran/simd2.f90
index 0062d5e6e60..415ad9c965d 100644
--- a/libgomp/testsuite/libgomp.fortran/simd2.f90
+++ b/libgomp/testsuite/libgomp.fortran/simd2.f90
@@ -13,42 +13,42 @@
end do
s = foo (b)
do i = 1, 1024
- if (a(i).ne.((i - 513) * b(i))) STOP 1
+ if (a(i).ne.((i - 513) * b(i))) stop 1
if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
- if (b(i).ne.(modulo (i - 52, 39) - 39)) STOP 2
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) stop 2
else
- if (b(i).ne.(modulo (i - 52, 39))) STOP 3
+ if (b(i).ne.(modulo (i - 52, 39))) stop 3
end if
a(i) = i - 513
end do
- if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) STOP 4
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) stop 4
k = 4
m = 2
t = 1
s = bar (b)
do i = 1, 1024
- if (a(i).ne.((i - 513) * b(i))) STOP 5
+ if (a(i).ne.((i - 513) * b(i))) stop 5
if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
- if (b(i).ne.(modulo (i - 52, 39) - 39)) STOP 6
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) stop 6
else
- if (b(i).ne.(modulo (i - 52, 39))) STOP 7
+ if (b(i).ne.(modulo (i - 52, 39))) stop 7
end if
a(i) = i - 513
end do
- if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) STOP 8
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) stop 8
k = 4
m = 2
t = 1
s = baz (b)
do i = 1, 1024
- if (a(i).ne.((i - 513) * b(i))) STOP 9
+ if (a(i).ne.((i - 513) * b(i))) stop 9
if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
- if (b(i).ne.(modulo (i - 52, 39) - 39)) STOP 10
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) stop 10
else
- if (b(i).ne.(modulo (i - 52, 39))) STOP 11
+ if (b(i).ne.(modulo (i - 52, 39))) stop 11
end if
end do
- if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) STOP 12
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) stop 12
contains
function foo (p)
integer :: p(1024), u, v, i, s, foo
@@ -62,8 +62,8 @@ contains
s = s + p(i) + k
end do
!$omp end simd
- if (i.ne.1025) STOP 13
- if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) STOP 14
+ if (i.ne.1025) stop 13
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) stop 14
foo = s
end function foo
function bar (p)
@@ -78,8 +78,8 @@ contains
s = s + p(i) + k
end do
!$omp end simd
- if (i.ne.1025) STOP 15
- if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) STOP 16
+ if (i.ne.1025) stop 15
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) stop 16
bar = s
end function bar
function baz (p)
@@ -94,8 +94,8 @@ contains
v = p(i) + k
s = s + p(i) + k
end do
- if (i.ne.1025) STOP 17
- if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) STOP 18
+ if (i.ne.1025) stop 17
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) stop 18
baz = s
end function baz
end
diff --git a/libgomp/testsuite/libgomp.fortran/simd3.f90 b/libgomp/testsuite/libgomp.fortran/simd3.f90
index 22ff564bd06..29b98e1895a 100644
--- a/libgomp/testsuite/libgomp.fortran/simd3.f90
+++ b/libgomp/testsuite/libgomp.fortran/simd3.f90
@@ -13,42 +13,42 @@
end do
s = foo (b)
do i = 1, 1024
- if (a(i).ne.((i - 513) * b(i))) STOP 1
+ if (a(i).ne.((i - 513) * b(i))) stop 1
if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
- if (b(i).ne.(modulo (i - 52, 39) - 39)) STOP 2
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) stop 2
else
- if (b(i).ne.(modulo (i - 52, 39))) STOP 3
+ if (b(i).ne.(modulo (i - 52, 39))) stop 3
end if
a(i) = i - 513
end do
- if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) STOP 4
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) stop 4
k = 4
m = 2
t = 1
s = bar (b)
do i = 1, 1024
- if (a(i).ne.((i - 513) * b(i))) STOP 5
+ if (a(i).ne.((i - 513) * b(i))) stop 5
if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
- if (b(i).ne.(modulo (i - 52, 39) - 39)) STOP 6
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) stop 6
else
- if (b(i).ne.(modulo (i - 52, 39))) STOP 7
+ if (b(i).ne.(modulo (i - 52, 39))) stop 7
end if
a(i) = i - 513
end do
- if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) STOP 8
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) stop 8
k = 4
m = 2
t = 1
s = baz (b)
do i = 1, 1024
- if (a(i).ne.((i - 513) * b(i))) STOP 9
+ if (a(i).ne.((i - 513) * b(i))) stop 9
if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
- if (b(i).ne.(modulo (i - 52, 39) - 39)) STOP 10
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) stop 10
else
- if (b(i).ne.(modulo (i - 52, 39))) STOP 11
+ if (b(i).ne.(modulo (i - 52, 39))) stop 11
end if
end do
- if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) STOP 12
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) stop 12
contains
function foo (p)
integer :: p(1024), u, v, i, s, foo
@@ -65,8 +65,8 @@ contains
end do
!$omp end do simd
!$omp end parallel
- if (i.ne.1025) STOP 13
- if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) STOP 14
+ if (i.ne.1025) stop 13
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) stop 14
foo = s
end function foo
function bar (p)
@@ -84,8 +84,8 @@ contains
end do
!$omp end do simd
!$omp endparallel
- if (i.ne.1025) STOP 15
- if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) STOP 16
+ if (i.ne.1025) stop 15
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) stop 16
bar = s
end function bar
function baz (p)
@@ -102,8 +102,8 @@ contains
s = s + p(i) + k
end do
!$omp end parallel
- if (i.ne.1025) STOP 17
- if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) STOP 18
+ if (i.ne.1025) stop 17
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) stop 18
baz = s
end function baz
end
diff --git a/libgomp/testsuite/libgomp.fortran/simd4.f90 b/libgomp/testsuite/libgomp.fortran/simd4.f90
index ceb1611bd38..a81bc5e3472 100644
--- a/libgomp/testsuite/libgomp.fortran/simd4.f90
+++ b/libgomp/testsuite/libgomp.fortran/simd4.f90
@@ -13,42 +13,42 @@
end do
s = foo (b)
do i = 1, 1024
- if (a(i).ne.((i - 513) * b(i))) STOP 1
+ if (a(i).ne.((i - 513) * b(i))) stop 1
if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
- if (b(i).ne.(modulo (i - 52, 39) - 39)) STOP 2
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) stop 2
else
- if (b(i).ne.(modulo (i - 52, 39))) STOP 3
+ if (b(i).ne.(modulo (i - 52, 39))) stop 3
end if
a(i) = i - 513
end do
- if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) STOP 4
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) stop 4
k = 4
m = 2
t = 1
s = bar (b)
do i = 1, 1024
- if (a(i).ne.((i - 513) * b(i))) STOP 5
+ if (a(i).ne.((i - 513) * b(i))) stop 5
if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
- if (b(i).ne.(modulo (i - 52, 39) - 39)) STOP 6
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) stop 6
else
- if (b(i).ne.(modulo (i - 52, 39))) STOP 7
+ if (b(i).ne.(modulo (i - 52, 39))) stop 7
end if
a(i) = i - 513
end do
- if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) STOP 8
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) stop 8
k = 4
m = 2
t = 1
s = baz (b)
do i = 1, 1024
- if (a(i).ne.((i - 513) * b(i))) STOP 9
+ if (a(i).ne.((i - 513) * b(i))) stop 9
if (i.lt.52.and.modulo (i - 52, 39).ne.0) then
- if (b(i).ne.(modulo (i - 52, 39) - 39)) STOP 10
+ if (b(i).ne.(modulo (i - 52, 39) - 39)) stop 10
else
- if (b(i).ne.(modulo (i - 52, 39))) STOP 11
+ if (b(i).ne.(modulo (i - 52, 39))) stop 11
end if
end do
- if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) STOP 12
+ if (k.ne.(4 + 3 * 1024).or.s.ne.1596127) stop 12
contains
function foo (p)
integer :: p(1024), u, v, i, s, foo
@@ -63,8 +63,8 @@ contains
s = s + p(i) + k
end do
!$omp end parallel do simd
- if (i.ne.1025) STOP 13
- if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) STOP 14
+ if (i.ne.1025) stop 13
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) stop 14
foo = s
end function foo
function bar (p)
@@ -80,8 +80,8 @@ contains
s = s + p(i) + k
end do
!$omp endparalleldosimd
- if (i.ne.1025) STOP 15
- if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) STOP 16
+ if (i.ne.1025) stop 15
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) stop 16
bar = s
end function bar
function baz (p)
@@ -96,8 +96,8 @@ contains
v = p(i) + k
s = s + p(i) + k
end do
- if (i.ne.1025) STOP 17
- if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) STOP 18
+ if (i.ne.1025) stop 17
+ if (u.ne.(36 + 4 + 3 * 1023).or.v.ne.(36 + 4 + 3 * 1024)) stop 18
baz = s
end function baz
end
diff --git a/libgomp/testsuite/libgomp.fortran/simd5.f90 b/libgomp/testsuite/libgomp.fortran/simd5.f90
index e1383d20d30..099fec55cb9 100644
--- a/libgomp/testsuite/libgomp.fortran/simd5.f90
+++ b/libgomp/testsuite/libgomp.fortran/simd5.f90
@@ -12,7 +12,7 @@
c = c + b - (7 + 2 * i)
b = b + 2
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) STOP 1
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) stop 1
i = 4
j = 4
b = 7
@@ -21,7 +21,7 @@
c = c + b - (7 + i / 4 * 3)
b = b + 3
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) STOP 2
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) stop 2
i = 4
j = 4
b = 7
@@ -30,7 +30,7 @@
c = c + b - (7 + 2 * i)
b = b + 2
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) STOP 3
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) stop 3
i = 4
j = 4
b = 7
@@ -39,7 +39,7 @@
c = c + b - (7 + i / 4 * 3)
b = b + 3
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) STOP 4
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) stop 4
i = 4
j = 4
b = 7
@@ -50,7 +50,7 @@
b = b + 2
end do
end do
- if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) STOP 5
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) stop 5
i = 4
j = 4
b = 7
@@ -61,7 +61,7 @@
b = b + 2
end do
end do
- if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) STOP 6
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) stop 6
i = 4
j = 4
b = 7
@@ -70,7 +70,7 @@
c = c + b - (7 + 2 * i)
b = b + 2
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) STOP 7
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) stop 7
i = 4
j = 4
b = 7
@@ -79,7 +79,7 @@
c = c + b - (7 + i / 4 * 3)
b = b + 3
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) STOP 8
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) stop 8
i = 4
j = 4
b = 7
@@ -88,7 +88,7 @@
c = c + b - (7 + 2 * i)
b = b + 2
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) STOP 9
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) stop 9
i = 4
j = 4
b = 7
@@ -97,7 +97,7 @@
c = c + b - (7 + i / 4 * 3)
b = b + 3
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) STOP 10
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) stop 10
i = 4
j = 4
b = 7
@@ -108,7 +108,7 @@
b = b + 2
end do
end do
- if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) STOP 11
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) stop 11
i = 4
j = 4
b = 7
@@ -120,5 +120,5 @@
b = b + 2
end do
end do
- if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) STOP 12
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) stop 12
end
diff --git a/libgomp/testsuite/libgomp.fortran/simd6.f90 b/libgomp/testsuite/libgomp.fortran/simd6.f90
index b78bb4b6886..445ac4de4c4 100644
--- a/libgomp/testsuite/libgomp.fortran/simd6.f90
+++ b/libgomp/testsuite/libgomp.fortran/simd6.f90
@@ -18,7 +18,7 @@
c = c + b - (7 + 2 * i)
call foo (b, i, j, 2)
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) STOP 1
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) stop 1
i = 4
j = 4
b = 7
@@ -27,7 +27,7 @@
c = c + b - (7 + i / 4 * 3)
call foo (b, i, j, 3)
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) STOP 2
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) stop 2
i = 4
j = 4
b = 7
@@ -36,7 +36,7 @@
c = c + b - (7 + 2 * i)
call foo (b, i, j, 2)
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) STOP 3
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) stop 3
i = 4
j = 4
b = 7
@@ -45,7 +45,7 @@
c = c + b - (7 + i / 4 * 3)
call foo (b, i, j, 3)
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) STOP 4
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) stop 4
i = 4
j = 4
b = 7
@@ -56,7 +56,7 @@
call foo (b, i, j, 2)
end do
end do
- if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) STOP 5
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) stop 5
i = 4
j = 4
b = 7
@@ -67,7 +67,7 @@
call foo (b, i, j, 2)
end do
end do
- if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) STOP 6
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) stop 6
i = 4
j = 4
b = 7
@@ -76,7 +76,7 @@
c = c + b - (7 + 2 * i)
call foo (b, i, j, 2)
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) STOP 7
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) stop 7
i = 4
j = 4
b = 7
@@ -85,7 +85,7 @@
c = c + b - (7 + i / 4 * 3)
call foo (b, i, j, 3)
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) STOP 8
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) stop 8
i = 4
j = 4
b = 7
@@ -94,7 +94,7 @@
c = c + b - (7 + 2 * i)
call foo (b, i, j, 2)
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) STOP 9
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 64 * 2) stop 9
i = 4
j = 4
b = 7
@@ -103,7 +103,7 @@
c = c + b - (7 + i / 4 * 3)
call foo (b, i, j, 3)
end do
- if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) STOP 10
+ if (c /= 0 .or. i /= 64 .or. b /= 7 + 16 * 3) stop 10
i = 4
j = 4
b = 7
@@ -114,7 +114,7 @@
call foo (b, i, j, 2)
end do
end do
- if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) STOP 11
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) stop 11
i = 4
j = 4
b = 7
@@ -126,7 +126,7 @@
call foo (b, i, j, 2)
end do
end do
- if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) STOP 12
+ if (c /= 0 .or. i /= 8 .or. j /= 8 .or. b /= 7 + 64 * 2) stop 12
end
subroutine foo (b, i, j, x)
integer, intent (inout) :: b
diff --git a/libgomp/testsuite/libgomp.fortran/simd7.f90 b/libgomp/testsuite/libgomp.fortran/simd7.f90
index 4b5633e902b..28b2f251c55 100644
--- a/libgomp/testsuite/libgomp.fortran/simd7.f90
+++ b/libgomp/testsuite/libgomp.fortran/simd7.f90
@@ -30,20 +30,20 @@ subroutine foo (d, e, f, g, m, n)
b = b + 1; c = c + 2; d = d + 3; e = e + 4; f = f + 5; g = g + 6
h = h + 7; k = k + 8; m = m + 9
end do
- if (l .or. i /= 64) STOP 1
- if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) STOP 2
- if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) STOP 3
- if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) STOP 4
- if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) STOP 5
- if (m /= 15 + 9 * 64) STOP 6
- if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) STOP 7
- if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) STOP 8
- if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) STOP 9
- if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) STOP 10
- if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) STOP 11
- if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) STOP 12
- if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) STOP 13
- if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) STOP 14
+ if (l .or. i /= 64) stop 1
+ if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) stop 2
+ if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) stop 3
+ if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) stop 4
+ if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) stop 5
+ if (m /= 15 + 9 * 64) stop 6
+ if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) stop 7
+ if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) stop 8
+ if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) stop 9
+ if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) stop 10
+ if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) stop 11
+ if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) stop 12
+ if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) stop 13
+ if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) stop 14
i = 4; j = 4; b = 7; c = 8; d = 9; e = 10; f = 11; g = 12; h = 13; k = 14; m = 15
!$omp simd linear(b)linear(c:2)linear(d:3)linear(e:4)linear(f:5)linear(g:6) &
!$omp & linear(h:7)linear(k:8)linear(m:9) reduction(.or.:l) collapse(2)
@@ -68,20 +68,20 @@ subroutine foo (d, e, f, g, m, n)
h = h + 7; k = k + 8; m = m + 9
end do
end do
- if (l .or. i /= 8 .or. j /= 8) STOP 15
- if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) STOP 16
- if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) STOP 17
- if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) STOP 18
- if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) STOP 19
- if (m /= 15 + 9 * 64) STOP 20
- if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) STOP 21
- if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) STOP 22
- if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) STOP 23
- if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) STOP 24
- if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) STOP 25
- if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) STOP 26
- if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) STOP 27
- if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) STOP 28
+ if (l .or. i /= 8 .or. j /= 8) stop 15
+ if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) stop 16
+ if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) stop 17
+ if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) stop 18
+ if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) stop 19
+ if (m /= 15 + 9 * 64) stop 20
+ if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) stop 21
+ if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) stop 22
+ if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) stop 23
+ if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) stop 24
+ if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) stop 25
+ if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) stop 26
+ if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) stop 27
+ if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) stop 28
i = 4; j = 4; b = 7; c = 8; d = 9; e = 10; f = 11; g = 12; h = 13; k = 14; m = 15
!$omp parallel do simd linear(b)linear(c:2)linear(d:3)linear(e:4)linear(f:5) &
!$omp & linear(g:6)linear(h:7)linear(k:8)linear(m:9) reduction(.or.:l)
@@ -104,20 +104,20 @@ subroutine foo (d, e, f, g, m, n)
b = b + 1; c = c + 2; d = d + 3; e = e + 4; f = f + 5; g = g + 6
h = h + 7; k = k + 8; m = m + 9
end do
- if (l .or. i /= 64) STOP 29
- if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) STOP 30
- if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) STOP 31
- if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) STOP 32
- if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) STOP 33
- if (m /= 15 + 9 * 64) STOP 34
- if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) STOP 35
- if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) STOP 36
- if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) STOP 37
- if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) STOP 38
- if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) STOP 39
- if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) STOP 40
- if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) STOP 41
- if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) STOP 42
+ if (l .or. i /= 64) stop 29
+ if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) stop 30
+ if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) stop 31
+ if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) stop 32
+ if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) stop 33
+ if (m /= 15 + 9 * 64) stop 34
+ if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) stop 35
+ if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) stop 36
+ if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) stop 37
+ if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) stop 38
+ if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) stop 39
+ if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) stop 40
+ if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) stop 41
+ if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) stop 42
i = 4; j = 4; b = 7; c = 8; d = 9; e = 10; f = 11; g = 12; h = 13; k = 14; m = 15
!$omp parallel do simd linear(b)linear(c:2)linear(d:3)linear(e:4)linear(f:5) &
!$omp & linear(g:6)linear(h:7)linear(k:8)linear(m:9) reduction(.or.:l) collapse(2)
@@ -142,20 +142,20 @@ subroutine foo (d, e, f, g, m, n)
h = h + 7; k = k + 8; m = m + 9
end do
end do
- if (l .or. i /= 8 .or. j /= 8) STOP 43
- if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) STOP 44
- if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) STOP 45
- if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) STOP 46
- if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) STOP 47
- if (m /= 15 + 9 * 64) STOP 48
- if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) STOP 49
- if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) STOP 50
- if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) STOP 51
- if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) STOP 52
- if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) STOP 53
- if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) STOP 54
- if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) STOP 55
- if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) STOP 56
+ if (l .or. i /= 8 .or. j /= 8) stop 43
+ if (any (b /= 7 + 64) .or. any (c /= 8 + 2 * 64)) stop 44
+ if (any (d /= 9 + 3 * 64) .or. any (e /= 10 + 4 * 64)) stop 45
+ if (any (f /= 11 + 5 * 64) .or. any (g /= 12 + 6 * 64)) stop 46
+ if (any (h /= 13 + 7 * 64) .or. (k /= 14 + 8 * 64)) stop 47
+ if (m /= 15 + 9 * 64) stop 48
+ if ((lbound (b, 1) /= 2) .or. (ubound (b, 1) /= 9)) stop 49
+ if ((lbound (c, 1) /= 3) .or. (ubound (c, 1) /= n)) stop 50
+ if ((lbound (d, 1) /= 1) .or. (ubound (d, 1) /= 17)) stop 51
+ if ((lbound (e, 1) /= 2) .or. (ubound (e, 1) /= n)) stop 52
+ if ((lbound (f, 1) /= 2) .or. (ubound (f, 1) /= 3)) stop 53
+ if ((lbound (f, 2) /= 3) .or. (ubound (f, 2) /= 5)) stop 54
+ if ((lbound (g, 1) /= 7) .or. (ubound (g, 1) /= 10)) stop 55
+ if ((lbound (h, 1) /= 2) .or. (ubound (h, 1) /= 7)) stop 56
end subroutine
interface
diff --git a/libgomp/testsuite/libgomp.fortran/stack.f90 b/libgomp/testsuite/libgomp.fortran/stack.f90
index f0babdd059a..da0ff744f17 100644
--- a/libgomp/testsuite/libgomp.fortran/stack.f90
+++ b/libgomp/testsuite/libgomp.fortran/stack.f90
@@ -11,7 +11,7 @@ program stack
!$omp end parallel
! Check that the two threads are not sharing a location for
! the array x in foo()
- if (ilocs(1) .eq. ilocs(2)) STOP 1
+ if (ilocs(1) .eq. ilocs(2)) stop 1
end program stack
integer function foo ()
diff --git a/libgomp/testsuite/libgomp.fortran/strassen.f90 b/libgomp/testsuite/libgomp.fortran/strassen.f90
index 84faced494a..e0dc0c8eef9 100644
--- a/libgomp/testsuite/libgomp.fortran/strassen.f90
+++ b/libgomp/testsuite/libgomp.fortran/strassen.f90
@@ -19,7 +19,7 @@ program strassen_matmul
call strassen (A, B, D, N)
end = omp_get_wtime ()
write(*,'(a, f10.6)') ' Time for Strassen = ', end - start
- if (sqrt (sum ((C - D) ** 2)) / N .gt. 0.1) STOP 1
+ if (sqrt (sum ((C - D) ** 2)) / N .gt. 0.1) stop 1
D = 0
start = omp_get_wtime ()
!$omp parallel
@@ -29,7 +29,7 @@ program strassen_matmul
!$omp end parallel
end = omp_get_wtime ()
write(*,'(a, f10.6)') ' Time for Strassen MP = ', end - start
- if (sqrt (sum ((C - D) ** 2)) / N .gt. 0.1) STOP 2
+ if (sqrt (sum ((C - D) ** 2)) / N .gt. 0.1) stop 2
contains
diff --git a/libgomp/testsuite/libgomp.fortran/tabs1.f90 b/libgomp/testsuite/libgomp.fortran/tabs1.f90
index 68dba38c9ad..da334dc419e 100644
--- a/libgomp/testsuite/libgomp.fortran/tabs1.f90
+++ b/libgomp/testsuite/libgomp.fortran/tabs1.f90
@@ -1,4 +1,4 @@
- if (b().ne.2) STOP 1
+ if (b().ne.2) stop 1
contains
subroutine a
!$omp parallel
diff --git a/libgomp/testsuite/libgomp.fortran/tabs2.f b/libgomp/testsuite/libgomp.fortran/tabs2.f
index 07fca22cac3..a018dd53f60 100644
--- a/libgomp/testsuite/libgomp.fortran/tabs2.f
+++ b/libgomp/testsuite/libgomp.fortran/tabs2.f
@@ -1,5 +1,5 @@
! { dg-options "-ffixed-form" }
- if (b().ne.2) STOP 1
+ if (b().ne.2) stop 1
contains
subroutine a
!$omp parallel
diff --git a/libgomp/testsuite/libgomp.fortran/target-allocatable-1-1.f90 b/libgomp/testsuite/libgomp.fortran/target-allocatable-1-1.f90
new file mode 100644
index 00000000000..429a855a20b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-allocatable-1-1.f90
@@ -0,0 +1,69 @@
+! Test 'allocatable' with OpenMP 'target' 'map' clauses.
+
+! See also '../libgomp.oacc-fortran/allocatable-1-1.f90'.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+! { dg-additional-options "-DMEM_SHARED" { target offload_device_shared_as } }
+
+program main
+ implicit none
+ integer, allocatable :: a, b, c, d, e
+
+ allocate (a)
+ a = 11
+
+ b = 25 ! Implicit allocation.
+
+ c = 52 ! Implicit allocation.
+
+ !No 'allocate (d)' here.
+
+ !No 'allocate (e)' here.
+
+ !$omp target map(to: a) map(tofrom: b, c, d) map(from: e)
+
+ if (.not. allocated (a)) stop 1
+ if (a .ne. 11) stop 2
+ a = 33
+
+ if (.not. allocated (b)) stop 3
+ if (b .ne. 25) stop 4
+
+ if (.not. allocated (c)) stop 5
+ if (c .ne. 52) stop 6
+ c = 10
+
+ if (allocated (d)) stop 7
+ d = 42 ! Implicit allocation, but on device only.
+ if (.not. allocated (d)) stop 8
+ deallocate (d) ! OpenMP requires must be "unallocated upon exit from the region".
+
+ if (allocated (e)) stop 9
+ e = 24 ! Implicit allocation, but on device only.
+ if (.not. allocated (e)) stop 10
+ deallocate (e) ! OpenMP requires must be "unallocated upon exit from the region".
+
+ !$omp end target
+
+ if (.not. allocated (a)) stop 20
+#ifdef MEM_SHARED
+ if (a .ne. 33) stop 21
+#else
+ if (a .ne. 11) stop 22
+#endif
+ deallocate (a)
+
+ if (.not. allocated (b)) stop 23
+ if (b .ne. 25) stop 24
+ deallocate (b)
+
+ if (.not. allocated (c)) stop 25
+ if (c .ne. 10) stop 26
+ deallocate (c)
+
+ if (allocated (d)) stop 27
+
+ if (allocated (e)) stop 28
+
+end program main
diff --git a/libgomp/testsuite/libgomp.fortran/target-allocatable-1-2.f90 b/libgomp/testsuite/libgomp.fortran/target-allocatable-1-2.f90
new file mode 100644
index 00000000000..5301c8eeffb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-allocatable-1-2.f90
@@ -0,0 +1,82 @@
+! Test 'allocatable' with OpenMP 'target' 'map' clauses, subroutine in module,
+! pass by reference.
+
+! See also '../libgomp.oacc-fortran/allocatable-1-2.f90'.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+! { dg-additional-options "-DMEM_SHARED" { target offload_device_shared_as } }
+
+module m
+contains
+ subroutine r (a, b, c, d, e)
+ implicit none
+ integer, allocatable :: a, b, c, d, e
+
+ !$omp target map(to: a) map(tofrom: b, c, d) map(from: e)
+
+ if (.not. allocated (a)) stop 1
+ if (a .ne. 11) stop 2
+ a = 33
+
+ if (.not. allocated (b)) stop 3
+ if (b .ne. 25) stop 4
+
+ if (.not. allocated (c)) stop 5
+ if (c .ne. 52) stop 6
+ c = 10
+
+ if (allocated (d)) stop 7
+ d = 42 ! Implicit allocation, but on device only.
+ if (.not. allocated (d)) stop 8
+ deallocate (d) ! OpenMP requires must be "unallocated upon exit from the region".
+
+ if (allocated (e)) stop 9
+ e = 24 ! Implicit allocation, but on device only.
+ if (.not. allocated (e)) stop 10
+ deallocate (e) ! OpenMP requires must be "unallocated upon exit from the region".
+
+ !$omp end target
+
+ end subroutine r
+end module m
+
+program main
+ use m
+ implicit none
+ integer, allocatable :: a, b, c, d, e
+
+ allocate (a)
+ a = 11
+
+ b = 25 ! Implicit allocation.
+
+ c = 52 ! Implicit allocation.
+
+ !No 'allocate (d)' here.
+
+ !No 'allocate (e)' here.
+
+ call r(a, b, c, d, e)
+
+ if (.not. allocated (a)) stop 20
+#ifdef MEM_SHARED
+ if (a .ne. 33) stop 21
+#else
+ if (a .ne. 11) stop 22
+#endif
+ deallocate (a)
+
+ if (.not. allocated (b)) stop 23
+ if (b .ne. 25) stop 24
+ deallocate (b)
+
+ if (.not. allocated (c)) stop 25
+ if (c .ne. 10) stop 26
+ deallocate (c)
+
+ if (allocated (d)) stop 27
+
+ if (allocated (e)) stop 28
+
+end program main
diff --git a/libgomp/testsuite/libgomp.fortran/target-print-1.f90 b/libgomp/testsuite/libgomp.fortran/target-print-1.f90
new file mode 100644
index 00000000000..c71a0952483
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-print-1.f90
@@ -0,0 +1,15 @@
+! Ensure that printf on the offload device works.
+
+! { dg-do run }
+! { dg-output "The answer is 42(\n|\r\n|\r)+" }
+! { dg-xfail-if "no write for nvidia" { openacc_nvidia_accel_selected } }
+
+program main
+ implicit none
+ integer :: var = 42
+
+!$omp target
+ write (0, '("The answer is ", I2)') var
+!$omp end target
+
+end program main
diff --git a/libgomp/testsuite/libgomp.fortran/target-simd.f90 b/libgomp/testsuite/libgomp.fortran/target-simd.f90
new file mode 100644
index 00000000000..158347b59dc
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-simd.f90
@@ -0,0 +1,26 @@
+! { dg-do run }
+
+program test
+ implicit none
+ real, allocatable :: a(:), b(:)
+ integer :: i
+
+ a = [(i, i = 1, 100)]
+ allocate(b, mold=a)
+ b = 0
+
+ !$omp target simd map(to:a) map(from:b)
+ do i = 1, size(a)
+ b(i) = 5.0 * a(i)
+ end do
+
+ if (any (b - 5.0 *a > 10.0*epsilon(a))) stop 1
+
+ !$omp target simd map(to:a) map(from:b)
+ do i = 1, size(a)
+ b(i) = 2.0 * a(i)
+ end do
+ !$omp end target simd
+
+ if (any (b - 2.0 *a > 10.0*epsilon(a))) stop 2
+end program test
diff --git a/libgomp/testsuite/libgomp.fortran/target1.f90 b/libgomp/testsuite/libgomp.fortran/target1.f90
index 99c5087ca97..36b12591344 100644
--- a/libgomp/testsuite/libgomp.fortran/target1.f90
+++ b/libgomp/testsuite/libgomp.fortran/target1.f90
@@ -13,9 +13,9 @@ contains
q(i) = p(i)
end do
!$omp end target
- if (any (p /= q)) STOP 1
+ if (any (p /= q)) stop 1
do i = 1, n
- if (p(i) /= i * iand (i, 63)) STOP 2
+ if (p(i) /= i * iand (i, 63)) stop 2
end do
!$omp target data if (n > 256) map (to: v(1:n), w) map (from: p, q)
!$omp target if (n > 256)
@@ -38,7 +38,7 @@ contains
end do
!$omp end target
!$omp end target data
- if (any (p + 2.0 /= q)) STOP 3
+ if (any (p + 2.0 /= q)) stop 3
end subroutine
end module target1
use target1, only : foo
@@ -52,7 +52,7 @@ end module target1
end do
call foo (p, v, w, n)
do i = 1, n
- if (p(i) /= i * iand (i, 63) + 3) STOP 4
+ if (p(i) /= i * iand (i, 63) + 3) stop 4
end do
deallocate (p, v, w)
end
diff --git a/libgomp/testsuite/libgomp.fortran/target2.f90 b/libgomp/testsuite/libgomp.fortran/target2.f90
index 0595ed192d5..11b8af737e3 100644
--- a/libgomp/testsuite/libgomp.fortran/target2.f90
+++ b/libgomp/testsuite/libgomp.fortran/target2.f90
@@ -29,7 +29,7 @@ contains
r = r .or. (j /= 16)
r = r .or. (any (k /= 17)) .or. (lbound (k, 1) /= 4) .or. (ubound (k, 1) /= n)
!$omp end target
- if (r) STOP 1
+ if (r) stop 1
!$omp target map (to: b(3:n), c(5:n+4), d(2:n+1), e(1:,:2), g(3:n), i(3:n), k(4:n), n) map (from: r)
r = (any (b /= 8)) .or. (lbound (b, 1) /= 3) .or. (ubound (b, 1) /= n)
r = r .or. (any (c /= 9)) .or. (lbound (c, 1) /= 5) .or. (ubound (c, 1) /= n + 4)
@@ -40,7 +40,7 @@ contains
r = r .or. (any (i /= 15)) .or. (lbound (i, 1) /= 3) .or. (ubound (i, 1) /= n)
r = r .or. (any (k /= 17)) .or. (lbound (k, 1) /= 4) .or. (ubound (k, 1) /= n)
!$omp end target
- if (r) STOP 2
+ if (r) stop 2
!$omp target map (to: b(5:n-2), c(7:n), d(4:n-2), e(1:,2:), g(5:n-3), i(6:n-4), k(5:n-5), n) map (from: r)
r = (any (b(5:n-2) /= 8)) .or. (lbound (b, 1) /= 3) .or. (ubound (b, 1) /= n)
r = r .or. (any (c(7:n) /= 9)) .or. (lbound (c, 1) /= 5) .or. (ubound (c, 1) /= n + 4)
@@ -62,7 +62,7 @@ contains
r = r .or. (any (i(6:n-4) /= 15)) .or. (lbound (i, 1) /= 3) .or. (ubound (i, 1) /= n)
r = r .or. (any (k(5:n-5) /= 17)) .or. (lbound (k, 1) /= 4) .or. (ubound (k, 1) /= n)
!$omp end target
- if (r) STOP 3
+ if (r) stop 3
!$omp target map (to: d(2:n+1), n)
r = a /= 7
r = r .or. (any (b /= 8)) .or. (lbound (b, 1) /= 3) .or. (ubound (b, 1) /= n)
@@ -77,7 +77,7 @@ contains
r = r .or. (j /= 16)
r = r .or. (any (k /= 17)) .or. (lbound (k, 1) /= 4) .or. (ubound (k, 1) /= n)
!$omp end target
- if (r) STOP 4
+ if (r) stop 4
end subroutine foo
end module target2
use target2, only : foo
diff --git a/libgomp/testsuite/libgomp.fortran/target3.f90 b/libgomp/testsuite/libgomp.fortran/target3.f90
index 6c45d119e6e..d9b9ccf63be 100644
--- a/libgomp/testsuite/libgomp.fortran/target3.f90
+++ b/libgomp/testsuite/libgomp.fortran/target3.f90
@@ -13,12 +13,12 @@ contains
r = associated (f) .or. associated (g)
r = r .or. associated (j) .or. associated (k)
!$omp end target
- if (r) STOP 1
+ if (r) stop 1
!$omp target
r = associated (f) .or. associated (g)
r = r .or. associated (j) .or. associated (k)
!$omp end target
- if (r) STOP 2
+ if (r) stop 2
end subroutine foo
end module target3
use target3, only : foo
diff --git a/libgomp/testsuite/libgomp.fortran/target4.f90 b/libgomp/testsuite/libgomp.fortran/target4.f90
index 52575af07f4..5dac76cffd1 100644
--- a/libgomp/testsuite/libgomp.fortran/target4.f90
+++ b/libgomp/testsuite/libgomp.fortran/target4.f90
@@ -44,5 +44,5 @@ end module target4
& 30800.0d0, 33000.0d0, 23256.0d0, 25840.0d0, 28424.0d0, 31008.0d0, 33592.0d0, 36176.0d0, &
& 38760.0d0, 41344.0d0, 30000.0d0, 33000.0d0, 36000.0d0, 39000.0d0, 42000.0d0, 45000.0d0, &
& 48000.0d0, 51000.0d0 /), (/ 8, 9 /))
- if (any (a /= res)) STOP 1
+ if (any (a /= res)) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/target5.f90 b/libgomp/testsuite/libgomp.fortran/target5.f90
index b03cb58c544..9d4662a18eb 100644
--- a/libgomp/testsuite/libgomp.fortran/target5.f90
+++ b/libgomp/testsuite/libgomp.fortran/target5.f90
@@ -3,7 +3,7 @@
integer :: r
r = 0
call foo (r)
- if (r /= 11) STOP 1
+ if (r /= 11) stop 1
contains
subroutine foo (r)
integer :: i, r
diff --git a/libgomp/testsuite/libgomp.fortran/target6.f90 b/libgomp/testsuite/libgomp.fortran/target6.f90
index 82f49e2b9c8..c4105d73082 100644
--- a/libgomp/testsuite/libgomp.fortran/target6.f90
+++ b/libgomp/testsuite/libgomp.fortran/target6.f90
@@ -16,7 +16,7 @@ contains
!$omp end target
!$omp target update if (n > 256) from (p)
do i = 1, n
- if (p(i) /= i * iand (i, 63)) STOP 1
+ if (p(i) /= i * iand (i, 63)) stop 1
v(i) = v(i) + 1
end do
!$omp target update if (n > 256) to (v(1:n))
@@ -28,8 +28,8 @@ contains
!$omp end target
!$omp end target data
do i = 1, n
- if (q(i) /= (v(i) - 1) * w(i)) STOP 2
- if (p(i) /= q(i) + w(i)) STOP 3
+ if (q(i) /= (v(i) - 1) * w(i)) stop 2
+ if (p(i) /= q(i) + w(i)) stop 3
end do
end subroutine
end module target6
@@ -44,7 +44,7 @@ end module target6
end do
call foo (p, v, w, n)
do i = 1, n
- if (p(i) /= (i + 1) * iand (i, 63)) STOP 4
+ if (p(i) /= (i + 1) * iand (i, 63)) stop 4
end do
deallocate (p, v, w)
end
diff --git a/libgomp/testsuite/libgomp.fortran/target7.f90 b/libgomp/testsuite/libgomp.fortran/target7.f90
index 49ebb97618e..73a7485a638 100644
--- a/libgomp/testsuite/libgomp.fortran/target7.f90
+++ b/libgomp/testsuite/libgomp.fortran/target7.f90
@@ -28,7 +28,7 @@
!$omp end single
!$omp end parallel
do i = 1, n
- if (a(i) /= i + 1) STOP 1
+ if (a(i) /= i + 1) stop 1
end do
end
real function foo (x)
diff --git a/libgomp/testsuite/libgomp.fortran/target8.f90 b/libgomp/testsuite/libgomp.fortran/target8.f90
index e4874ae275c..5e7b1a4951f 100644
--- a/libgomp/testsuite/libgomp.fortran/target8.f90
+++ b/libgomp/testsuite/libgomp.fortran/target8.f90
@@ -22,7 +22,7 @@
!$omp end single
!$omp end parallel
do i = 1, n
- if (a(i) /= i + 1) STOP 1
+ if (a(i) /= i + 1) stop 1
end do
contains
real function foo (x)
diff --git a/libgomp/testsuite/libgomp.fortran/target9.f90 b/libgomp/testsuite/libgomp.fortran/target9.f90
new file mode 100644
index 00000000000..30adc1bd70a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target9.f90
@@ -0,0 +1,124 @@
+! { dg-do run }
+! { dg-require-effective-target offload_device_nonshared_as } */
+
+module target_test
+ implicit none (type, external)
+ integer, parameter :: N = 40
+ integer :: sum
+ integer :: var1 = 1
+ integer :: var2 = 2
+
+ !$omp declare target to(D)
+ integer :: D(N) = 0
+contains
+ subroutine enter_data (X)
+ integer :: X(:)
+ !$omp target enter data map(to: var1, var2, X) map(alloc: sum)
+ end subroutine enter_data
+
+ subroutine exit_data_0 (D)
+ integer :: D(N)
+ !$omp target exit data map(delete: D)
+ end subroutine exit_data_0
+
+ subroutine exit_data_1 ()
+ !$omp target exit data map(from: var1)
+ end subroutine exit_data_1
+
+ subroutine exit_data_2 (X)
+ integer :: X(N)
+ !$omp target exit data map(from: var2) map(release: X, sum)
+ end subroutine exit_data_2
+
+ subroutine exit_data_3 (p, idx)
+ integer :: p(:)
+ integer, value :: idx
+ !$omp target exit data map(from: p(idx))
+ end subroutine exit_data_3
+
+ subroutine test_nested ()
+ integer :: X, Y, Z
+ X = 0
+ Y = 0
+ Z = 0
+
+ !$omp target data map(from: X, Y, Z)
+ !$omp target data map(from: X, Y, Z)
+ !$omp target map(from: X, Y, Z)
+ X = 1337
+ Y = 1337
+ Z = 1337
+ !$omp end target
+ if (X /= 0) stop 11
+ if (Y /= 0) stop 12
+ if (Z /= 0) stop 13
+
+ !$omp target exit data map(from: X) map(release: Y)
+ if (X /= 0) stop 14
+ if (Y /= 0) stop 15
+
+ !$omp target exit data map(release: Y) map(delete: Z)
+ if (Y /= 0) stop 16
+ if (Z /= 0) stop 17
+ !$omp end target data
+ if (X /= 1337) stop 18
+ if (Y /= 0) stop 19
+ if (Z /= 0) stop 20
+
+ !$omp target map(from: X)
+ X = 2448
+ !$omp end target
+ if (X /= 2448) stop 21
+ if (Y /= 0) stop 22
+ if (Z /= 0) stop 23
+
+ X = 4896
+ !$omp end target data
+ if (X /= 4896) stop 24
+ if (Y /= 0) stop 25
+ if (Z /= 0) stop 26
+ end subroutine test_nested
+end module target_test
+
+program main
+ use target_test
+ implicit none (type, external)
+
+ integer, allocatable :: X(:)
+ integer, pointer, contiguous :: Y(:)
+
+
+ allocate(X(N), Y(N))
+ X(10) = 10
+ Y(20) = 20
+ call enter_data (X)
+
+ call exit_data_0 (D) ! This should have no effect on D.
+
+ !$omp target map(alloc: var1, var2, X) map(to: Y) map(always, from: sum)
+ var1 = var1 + X(10)
+ var2 = var2 + Y(20)
+ sum = var1 + var2
+ D(sum) = D(sum) + 1
+ !$omp end target
+
+ if (var1 /= 1) stop 1
+ if (var2 /= 2) stop 2
+ if (sum /= 33) stop 3
+
+ call exit_data_1 ()
+ if (var1 /= 11) stop 4
+ if (var2 /= 2) stop 5
+
+ ! Increase refcount of already mapped X(1:N).
+ !$omp target enter data map(alloc: X(16:17))
+
+ call exit_data_2 (X)
+ if (var2 /= 22) stop 6
+
+ call exit_data_3 (X, 5) ! Unmap X(1:N).
+
+ deallocate (X, Y)
+
+ call test_nested ()
+end program main
diff --git a/libgomp/testsuite/libgomp.fortran/task1.f90 b/libgomp/testsuite/libgomp.fortran/task1.f90
index 761226cd854..4eb6c106ea2 100644
--- a/libgomp/testsuite/libgomp.fortran/task1.f90
+++ b/libgomp/testsuite/libgomp.fortran/task1.f90
@@ -13,7 +13,7 @@ program tasktest
!$omp end task
end if
!$omp end parallel
- if (j.gt.0) STOP 1
+ if (j.gt.0) stop 1
contains
subroutine subr (i)
use omp_lib
diff --git a/libgomp/testsuite/libgomp.fortran/task2.f90 b/libgomp/testsuite/libgomp.fortran/task2.f90
index 27151415043..623c7179293 100644
--- a/libgomp/testsuite/libgomp.fortran/task2.f90
+++ b/libgomp/testsuite/libgomp.fortran/task2.f90
@@ -1,3 +1,4 @@
+! { dg-do run }
! { dg-options "-std=legacy" }
integer :: err
@@ -7,7 +8,7 @@
call test
!$omp end single
!$omp end parallel
- if (err.ne.0) STOP 1
+ if (err.ne.0) stop 1
contains
subroutine check (x, y, l)
integer :: x, y
diff --git a/libgomp/testsuite/libgomp.fortran/task3.f90 b/libgomp/testsuite/libgomp.fortran/task3.f90
index fcff52ad016..a7b90d4c990 100644
--- a/libgomp/testsuite/libgomp.fortran/task3.f90
+++ b/libgomp/testsuite/libgomp.fortran/task3.f90
@@ -21,6 +21,6 @@ program F03_2_7_1d
!$omp end parallel
if (sum /= NT) then
print *, "FAIL - sum == ", sum, " (expected ", NT, ")"
- STOP 1
+ stop 1
end if
end program F03_2_7_1d
diff --git a/libgomp/testsuite/libgomp.fortran/task4.f90 b/libgomp/testsuite/libgomp.fortran/task4.f90
index 6430f2914a4..918bb1f97a7 100644
--- a/libgomp/testsuite/libgomp.fortran/task4.f90
+++ b/libgomp/testsuite/libgomp.fortran/task4.f90
@@ -41,5 +41,5 @@
!$omp end parallel
!$omp atomic read
e = err
- if (e .ne. 0) STOP 1
+ if (e .ne. 0) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/taskgroup1.f90 b/libgomp/testsuite/libgomp.fortran/taskgroup1.f90
index 3f6b38a35f9..a32d4440c16 100644
--- a/libgomp/testsuite/libgomp.fortran/taskgroup1.f90
+++ b/libgomp/testsuite/libgomp.fortran/taskgroup1.f90
@@ -1,3 +1,4 @@
+! { dg-do run }
integer :: v(16), i
do i = 1, 16
v(i) = i
@@ -18,7 +19,7 @@
end do
!$omp end taskgroup
do i = 1, 16
- if (v(i).ne.(i + 1)) STOP 1
+ if (v(i).ne.(i + 1)) stop 1
end do
!$omp taskgroup
do i = 1, 16, 2
@@ -34,7 +35,7 @@
end do
!$omp endtaskgroup
do i = 1, 16
- if (v(i).ne.(i + 2)) STOP 2
+ if (v(i).ne.(i + 2)) stop 2
end do
!$omp taskgroup
do i = 1, 16, 2
@@ -53,8 +54,8 @@
end do
!$omp end taskgroup
do i = 1, 16, 2
- if (v(i).ne.(i + 3)) STOP 3
- if (v(i + 1).ne.(i + 5)) STOP 4
+ if (v(i).ne.(i + 3)) stop 3
+ if (v(i + 1).ne.(i + 5)) stop 4
end do
!$omp taskgroup
do i = 1, 16, 2
@@ -66,14 +67,14 @@
v(i + 1) = v(i + 1) + 1
!$omp end task
!$omp end taskgroup
- if (v(i).ne.(i + 4).or.v(i + 1).ne.(i + 6)) STOP 5
+ if (v(i).ne.(i + 4).or.v(i + 1).ne.(i + 6)) stop 5
!$omp task
v(i) = v(i) + 1
!$omp end task
end do
!$omp end taskgroup
do i = 1, 16
- if (v(i).ne.(i + 5)) STOP 6
+ if (v(i).ne.(i + 5)) stop 6
end do
!$omp end single
!$omp end parallel
diff --git a/libgomp/testsuite/libgomp.fortran/taskloop1.f90 b/libgomp/testsuite/libgomp.fortran/taskloop1.f90
index 48904b145bd..616d16a6a26 100644
--- a/libgomp/testsuite/libgomp.fortran/taskloop1.f90
+++ b/libgomp/testsuite/libgomp.fortran/taskloop1.f90
@@ -1,3 +1,4 @@
+! { dg-do run }
common /blk/ q, e
integer :: q, r
logical :: e
@@ -7,7 +8,7 @@
r = bar (12, 18)
!$omp end single
!$omp end parallel
- if (q .ne. 6 .or. r .ne. 17 .or. e) STOP 1
+ if (q .ne. 6 .or. r .ne. 17 .or. e) stop 1
contains
subroutine foo (a, b)
integer, intent (in) :: a, b
diff --git a/libgomp/testsuite/libgomp.fortran/taskloop2.f90 b/libgomp/testsuite/libgomp.fortran/taskloop2.f90
index 0e92fcb6f89..a20242f9774 100644
--- a/libgomp/testsuite/libgomp.fortran/taskloop2.f90
+++ b/libgomp/testsuite/libgomp.fortran/taskloop2.f90
@@ -1,4 +1,3 @@
-! { dg-do run }
! { dg-options "-O2" }
! { dg-additional-options "-msse2" { target sse2_runtime } }
! { dg-additional-options "-mavx" { target avx_runtime } }
@@ -13,7 +12,7 @@
!$omp end single
!$omp end parallel
do i = 1, 1024
- if (u(i) .ne. 2 * i + 1) STOP 1
+ if (u(i) .ne. 2 * i + 1) stop 1
v(i) = 1024 - i
w(i) = 512 - i
end do
@@ -24,45 +23,45 @@
!$omp end parallel
do i = 1, 1024
if (i .lt. 2 .or. i .gt. 1022) then
- if (u(i) .ne. 2 * i + 1) STOP 2
+ if (u(i) .ne. 2 * i + 1) stop 2
else
- if (u(i) .ne. 1536 - 2 * i) STOP 3
+ if (u(i) .ne. 1536 - 2 * i) stop 3
end if
v(i) = i
w(i) = i + 1
end do
- if (m .ne. (1023 + 2 * (1021 * 5 + 17) + 9)) STOP 4
+ if (m .ne. (1023 + 2 * (1021 * 5 + 17) + 9)) stop 4
!$omp parallel
!$omp single
call f3 (1, 1024)
!$omp end single
!$omp end parallel
do i = 1, 1024
- if (u(i) .ne. 2 * i + 1) STOP 5
+ if (u(i) .ne. 2 * i + 1) stop 5
v(i) = 1024 - i
w(i) = 512 - i
end do
- if (m .ne. 1025) STOP 6
+ if (m .ne. 1025) stop 6
!$omp parallel
!$omp single
call f4 (0, 31, 1, 32)
!$omp end single
!$omp end parallel
do i = 1, 1024
- if (u(i) .ne. 1536 - 2 * i) STOP 7
+ if (u(i) .ne. 1536 - 2 * i) stop 7
v(i) = i
w(i) = i + 1
end do
- if (m .ne. 32 + 33 + 1024) STOP 8
+ if (m .ne. 32 + 33 + 1024) stop 8
!$omp parallel
!$omp single
call f5 (0, 31, 1, 32)
!$omp end single
!$omp end parallel
do i = 1, 1024
- if (u(i) .ne. 2 * i + 1) STOP 9
+ if (u(i) .ne. 2 * i + 1) stop 9
end do
- if (m .ne. 32 + 33) STOP 10
+ if (m .ne. 32 + 33) stop 10
contains
subroutine f1 (a, b)
integer, intent(in) :: a, b
diff --git a/libgomp/testsuite/libgomp.fortran/taskloop3.f90 b/libgomp/testsuite/libgomp.fortran/taskloop3.f90
index 75f48229211..c4e57ddd451 100644
--- a/libgomp/testsuite/libgomp.fortran/taskloop3.f90
+++ b/libgomp/testsuite/libgomp.fortran/taskloop3.f90
@@ -1,18 +1,17 @@
-! { dg-do run }
! { dg-options "-O2" }
integer, save :: g
integer :: i
!$omp parallel
!$omp single
- if (f1 (74) .ne. 63 + 4) STOP 1
+ if (f1 (74) .ne. 63 + 4) stop 1
g = 77
call f2
!$omp taskwait
- if (g .ne. 63 + 9) STOP 2
- if (f3 (7_8, 11_8, 2_8) .ne. 11 * 7 + 13) STOP 3
+ if (g .ne. 63 + 9) stop 2
+ if (f3 (7_8, 11_8, 2_8) .ne. 11 * 7 + 13) stop 3
if (f4 (0_8, 31_8, 16_8, 46_8, 1_8, 2_8, 73) .ne. 32 + 5 * 48 &
-& + 11 * 31 + 17 * 46) STOP 4
+& + 11 * 31 + 17 * 46) stop 4
!$omp end single
!$omp end parallel
contains
@@ -22,7 +21,7 @@ contains
x = y
!$omp taskloop firstprivate(x)lastprivate(x)
do i = 0, 63
- if (x .ne. 74) STOP 5
+ if (x .ne. 74) stop 5
if (i .eq. 63) then
x = i + 4
end if
@@ -33,7 +32,7 @@ contains
integer :: i
!$omp taskloop firstprivate(g)lastprivate(g)nogroup
do i = 0, 63
- if (g .ne. 77) STOP 6
+ if (g .ne. 77) stop 6
if (i .eq. 63) then
g = i + 9
end if
@@ -60,7 +59,7 @@ contains
!$omp & lastprivate (i, j, k, l)
do i = a, b, e
do j = c, d, f
- if (k .ne. 73) STOP 7
+ if (k .ne. 73) stop 7
if (i .eq. 31 .and. j .eq. 46) then
k = i
end if
diff --git a/libgomp/testsuite/libgomp.fortran/taskloop4.f90 b/libgomp/testsuite/libgomp.fortran/taskloop4.f90
index 23067a3e48d..4f7a25b88ca 100644
--- a/libgomp/testsuite/libgomp.fortran/taskloop4.f90
+++ b/libgomp/testsuite/libgomp.fortran/taskloop4.f90
@@ -1,4 +1,3 @@
-! { dg-do run }
! { dg-options "-O2" }
integer, save :: u(64), v
@@ -11,22 +10,22 @@
! >= grainsize && < 2 * grainsize,
! unless # of loop iterations is smaller than grainsize.
call test (0, 79, 1, 17, fn, ntasks, min_iters, max_iters, cnt)
- if (cnt .ne. 79) STOP 1
- if (min_iters .lt. 17 .or. max_iters .ge. 17 * 2) STOP 2
+ if (cnt .ne. 79) stop 1
+ if (min_iters .lt. 17 .or. max_iters .ge. 17 * 2) stop 2
call test (-49, 2541, 7, 28, fn, ntasks, min_iters, max_iters, cnt)
- if (cnt .ne. 370) STOP 3
- if (min_iters .lt. 28 .or. max_iters .ge. 28 * 2) STOP 4
+ if (cnt .ne. 370) stop 3
+ if (min_iters .lt. 28 .or. max_iters .ge. 28 * 2) stop 4
call test (7, 21, 2, 15, fn, ntasks, min_iters, max_iters, cnt)
- if (cnt .ne. 7) STOP 5
- if (min_iters .ne. 7 .or. max_iters .ne. 7) STOP 6
- if (ntasks .ne. 1) STOP 7
+ if (cnt .ne. 7) stop 5
+ if (min_iters .ne. 7 .or. max_iters .ne. 7) stop 6
+ if (ntasks .ne. 1) stop 7
fn => num_tasks
! If num_tasks is present, # of task loop iters is
! min (# of loop iters, num_tasks).
call test (-51, 2500, 48, 9, fn, ntasks, min_iters, max_iters, cnt)
- if (cnt .ne. 54 .or. ntasks .ne. 9) STOP 8
+ if (cnt .ne. 54 .or. ntasks .ne. 9) stop 8
call test (0, 25, 2, 17, fn, ntasks, min_iters, max_iters, cnt)
- if (cnt .ne. 13 .or. ntasks .ne. 13) STOP 9
+ if (cnt .ne. 13 .or. ntasks .ne. 13) stop 9
!$omp end single
!$omp end parallel
contains
@@ -42,7 +41,7 @@ contains
k = v
v = v + 1
!$omp end atomic
- if (k .ge. 64) STOP 10
+ if (k .ge. 64) stop 10
end if
j = j + 1
u(k + 1) = j
@@ -60,7 +59,7 @@ contains
k = v
v = v + 1
!$omp end atomic
- if (k .ge. 64) STOP 11
+ if (k .ge. 64) stop 11
end if
j = j + 1
u(k + 1) = j
diff --git a/libgomp/testsuite/libgomp.fortran/threadprivate1.f90 b/libgomp/testsuite/libgomp.fortran/threadprivate1.f90
index 4867cc2cdbc..4ee56448aa0 100644
--- a/libgomp/testsuite/libgomp.fortran/threadprivate1.f90
+++ b/libgomp/testsuite/libgomp.fortran/threadprivate1.f90
@@ -15,7 +15,7 @@ end module threadprivate1
!$omp barrier
if (d .ne. omp_get_thread_num () + 6.5) l = .true.
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end
! { dg-final { cleanup-modules "threadprivate1" } }
diff --git a/libgomp/testsuite/libgomp.fortran/threadprivate2.f90 b/libgomp/testsuite/libgomp.fortran/threadprivate2.f90
index c0aa5be8a94..f1428d8bef9 100644
--- a/libgomp/testsuite/libgomp.fortran/threadprivate2.f90
+++ b/libgomp/testsuite/libgomp.fortran/threadprivate2.f90
@@ -53,16 +53,16 @@ end module threadprivate2
baz%b = omp_get_thread_num () * 2 + 1
!$omp end parallel
- if (l) STOP 1
- if (.not.allocated (foo)) STOP 2
- if (size (foo).ne.18) STOP 3
- if (any (foo.ne.1)) STOP 4
-
- if (associated (bar1)) STOP 5
- if (.not.associated (bar3)) STOP 6
- if (any (bar3 .ne. -2)) STOP 7
+ if (l) stop 1
+ if (.not.allocated (foo)) stop 2
+ if (size (foo).ne.18) stop 3
+ if (any (foo.ne.1)) stop 4
+
+ if (associated (bar1)) stop 5
+ if (.not.associated (bar3)) stop 6
+ if (any (bar3 .ne. -2)) stop 7
deallocate (bar3)
- if (associated (bar3)) STOP 8
+ if (associated (bar3)) stop 8
!$omp parallel num_threads (4) reduction (.or.:l)
l = l.or..not.allocated (foo)
@@ -85,12 +85,12 @@ end module threadprivate2
l = l.or.(baz%b.ne.(omp_get_thread_num () * 2 + 1))
!$omp end parallel
- if (l) STOP 9
- if (.not.allocated (foo)) STOP 10
- if (size (foo).ne.18) STOP 11
- if (any (foo.ne.1)) STOP 12
+ if (l) stop 9
+ if (.not.allocated (foo)) stop 10
+ if (size (foo).ne.18) stop 11
+ if (any (foo.ne.1)) stop 12
deallocate (foo)
- if (allocated (foo)) STOP 13
+ if (allocated (foo)) stop 13
end
! { dg-final { cleanup-modules "threadprivate2" } }
diff --git a/libgomp/testsuite/libgomp.fortran/threadprivate3.f90 b/libgomp/testsuite/libgomp.fortran/threadprivate3.f90
index 5bb6b290e48..e82cc8a5ce4 100644
--- a/libgomp/testsuite/libgomp.fortran/threadprivate3.f90
+++ b/libgomp/testsuite/libgomp.fortran/threadprivate3.f90
@@ -44,7 +44,7 @@ end module threadprivate3
bar3 = omp_get_thread_num () - 2
if (omp_get_thread_num () .ne. 0) then
deallocate (bar3)
- if (associated (bar3)) STOP 1
+ if (associated (bar3)) stop 1
else
bar1 => var
end if
@@ -55,13 +55,13 @@ end module threadprivate3
baz%b = omp_get_thread_num () * 2 + 1
!$omp end parallel
- if (l) STOP 2
- if (.not.associated (bar1)) STOP 3
- if (any (bar1.ne.6)) STOP 4
- if (.not.associated (bar3)) STOP 5
- if (any (bar3 .ne. -2)) STOP 6
+ if (l) stop 2
+ if (.not.associated (bar1)) stop 3
+ if (any (bar1.ne.6)) stop 4
+ if (.not.associated (bar3)) stop 5
+ if (any (bar3 .ne. -2)) stop 6
deallocate (bar3)
- if (associated (bar3)) STOP 7
+ if (associated (bar3)) stop 7
allocate (bar3 (10))
bar3 = 17
@@ -102,7 +102,7 @@ end module threadprivate3
l = l.or.(baz%b .ne. omp_get_thread_num () * 3 + 5)
!$omp end parallel
- if (l) STOP 8
+ if (l) stop 8
end
! { dg-final { cleanup-modules "threadprivate3" } }
diff --git a/libgomp/testsuite/libgomp.fortran/threadprivate4.f90 b/libgomp/testsuite/libgomp.fortran/threadprivate4.f90
index 2e7a438dd7b..a428ed94b15 100644
--- a/libgomp/testsuite/libgomp.fortran/threadprivate4.f90
+++ b/libgomp/testsuite/libgomp.fortran/threadprivate4.f90
@@ -72,7 +72,7 @@ end module threadprivate4
vi = -1
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/udr1.f90 b/libgomp/testsuite/libgomp.fortran/udr1.f90
index 138bd587232..a12016d8864 100644
--- a/libgomp/testsuite/libgomp.fortran/udr1.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr1.f90
@@ -28,24 +28,24 @@ end module udr1
do i = 1, 100
j = j + i
end do
- if (j .ne. 5050) STOP 1
+ if (j .ne. 5050) stop 1
j = 3
!$omp parallel do reduction (bar : j)
do i = 1, 100
j = j + 4 * i
end do
- if (j .ne. (5050 * 4 + 3)) STOP 2
+ if (j .ne. (5050 * 4 + 3)) stop 2
!$omp parallel do reduction (+ : d)
do i = 1, 100
- if (d%y .ne. 9) STOP 3
+ if (d%y .ne. 9) stop 3
d%x = d%x + 8 * i
end do
- if (d%x .ne. (5050 * 8 + 7) .or. d%y .ne. 9) STOP 4
+ if (d%x .ne. (5050 * 8 + 7) .or. d%y .ne. 9) stop 4
d = dt (5, 21)
!$omp parallel do reduction (foo : d)
do i = 1, 100
- if (d%y .ne. 21) STOP 5
+ if (d%y .ne. 21) stop 5
d%x = d%x + 8 * i
end do
- if (d%x .ne. (5050 * 8 + 5) .or. d%y .ne. 21) STOP 6
+ if (d%x .ne. (5050 * 8 + 5) .or. d%y .ne. 21) stop 6
end
diff --git a/libgomp/testsuite/libgomp.fortran/udr10.f90 b/libgomp/testsuite/libgomp.fortran/udr10.f90
index a855c0b15c9..15e0f869bee 100644
--- a/libgomp/testsuite/libgomp.fortran/udr10.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr10.f90
@@ -28,5 +28,5 @@ program udr10
j = j .localadd. dl(i)
k = k + dl(i * 2)
end do
- if (j%x /= 5050 .or. k%x /= 10100) STOP 1
+ if (j%x /= 5050 .or. k%x /= 10100) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/udr11.f90 b/libgomp/testsuite/libgomp.fortran/udr11.f90
index d69dd72bac3..57989be4a01 100644
--- a/libgomp/testsuite/libgomp.fortran/udr11.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr11.f90
@@ -88,8 +88,8 @@ end module udr11
t%x = t%x + 2 * i
u%x = u%x + 3 * i
end do
- if (j%x /= 5050 .or. k%x /= 30300 .or. l%x /= 15150) STOP 1
- if (m%x /= 5050 .or. n%x /= 10100 .or. o%x /= 15150) STOP 2
- if (p%x /= 5050 .or. q%x /= 10100 .or. r%x /= 15150) STOP 3
- if (s%x /= 5050 .or. t%x /= 10100 .or. u%x /= 15150) STOP 4
+ if (j%x /= 5050 .or. k%x /= 30300 .or. l%x /= 15150) stop 1
+ if (m%x /= 5050 .or. n%x /= 10100 .or. o%x /= 15150) stop 2
+ if (p%x /= 5050 .or. q%x /= 10100 .or. r%x /= 15150) stop 3
+ if (s%x /= 5050 .or. t%x /= 10100 .or. u%x /= 15150) stop 4
end
diff --git a/libgomp/testsuite/libgomp.fortran/udr12.f90 b/libgomp/testsuite/libgomp.fortran/udr12.f90
index c39f0ebc90a..d1ae1aad909 100644
--- a/libgomp/testsuite/libgomp.fortran/udr12.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr12.f90
@@ -34,7 +34,7 @@
b = b + 3
r = r + 1
!$omp end parallel
- if (any (a /= 2 * r) .or. b /= 3 * r) STOP 1
+ if (any (a /= 2 * r) .or. b /= 3 * r) stop 1
a(:) = 0
b = 0
r = 0
@@ -43,7 +43,7 @@
b = b + 3
r = r + 1
!$omp end parallel
- if (any (a /= 4 * r) .or. b /= 6 * r) STOP 2
+ if (any (a /= 4 * r) .or. b /= 6 * r) stop 2
a(:) = 0
b = 0
r = 0
@@ -52,7 +52,7 @@
b = b + 3
r = r + 1
!$omp end parallel
- if (any (a /= 2 * r) .or. b /= 3 * r) STOP 3
+ if (any (a /= 2 * r) .or. b /= 3 * r) stop 3
end
elemental function fn1 (x, y)
integer, intent(in) :: x, y
diff --git a/libgomp/testsuite/libgomp.fortran/udr13.f90 b/libgomp/testsuite/libgomp.fortran/udr13.f90
index 0ff53adf0ca..d29e498e6bb 100644
--- a/libgomp/testsuite/libgomp.fortran/udr13.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr13.f90
@@ -41,38 +41,38 @@
a(:) = 0
r = 0
!$omp parallel reduction (bar : a) reduction (+: r)
- if (lbound (a, 1) /= 1 .or. ubound (a, 1) /= 10) STOP 1
+ if (lbound (a, 1) /= 1 .or. ubound (a, 1) /= 10) stop 1
a = a + 2
r = r + 1
!$omp end parallel
- if (any (a /= 4 * r) ) STOP 2
+ if (any (a /= 4 * r) ) stop 2
b(:,:) = 0
allocate (c (4:6,8:10))
c(:,:) = 0
r = 0
!$omp parallel reduction (baz : b, c) reduction (+: r)
- if (lbound (b, 1) /= 3 .or. ubound (b, 1) /= 5) STOP 3
- if (lbound (b, 2) /= 7 .or. ubound (b, 2) /= 9) STOP 4
- if (.not. allocated (c)) STOP 5
- if (lbound (c, 1) /= 4 .or. ubound (c, 1) /= 6) STOP 6
- if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 10) STOP 7
+ if (lbound (b, 1) /= 3 .or. ubound (b, 1) /= 5) stop 3
+ if (lbound (b, 2) /= 7 .or. ubound (b, 2) /= 9) stop 4
+ if (.not. allocated (c)) stop 5
+ if (lbound (c, 1) /= 4 .or. ubound (c, 1) /= 6) stop 6
+ if (lbound (c, 2) /= 8 .or. ubound (c, 2) /= 10) stop 7
b = b + 3
c = c + 4
r = r + 1
!$omp end parallel
- if (any (b /= 3 * r) .or. any (c /= 4 * r)) STOP 8
+ if (any (b /= 3 * r) .or. any (c /= 4 * r)) stop 8
deallocate (c)
allocate (c (0:1,7:11))
c(:,:) = 0
r = 0
!$omp parallel reduction (foo : c) reduction (+: r)
- if (.not. allocated (c)) STOP 9
- if (lbound (c, 1) /= 0 .or. ubound (c, 1) /= 1) STOP 10
- if (lbound (c, 2) /= 7 .or. ubound (c, 2) /= 11) STOP 11
+ if (.not. allocated (c)) stop 9
+ if (lbound (c, 1) /= 0 .or. ubound (c, 1) /= 1) stop 10
+ if (lbound (c, 2) /= 7 .or. ubound (c, 2) /= 11) stop 11
c = c + 5
r = r + 1
!$omp end parallel
- if (any (c /= 10 * r)) STOP 12
+ if (any (c /= 10 * r)) stop 12
end
function fn1 (x, y, m1, m2)
integer, intent(in) :: x(:), y(:), m1, m2
diff --git a/libgomp/testsuite/libgomp.fortran/udr14.f90 b/libgomp/testsuite/libgomp.fortran/udr14.f90
index cb54f4350b9..eed57e9afaf 100644
--- a/libgomp/testsuite/libgomp.fortran/udr14.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr14.f90
@@ -13,31 +13,31 @@
a(7)%h = (/ 0, 0, 0 /)
r = 0
!$omp parallel reduction(+:r) reduction (baz:a)
- if (.not.allocated (a)) STOP 1
- if (lbound (a, 1) /= 7 .or. ubound (a, 1) /= 8) STOP 2
- if (.not.allocated (a(7)%h)) STOP 3
- if (allocated (a(8)%h)) STOP 4
- if (lbound (a(7)%h, 1) /= 1 .or. ubound (a(7)%h, 1) /= 3) STOP 5
+ if (.not.allocated (a)) stop 1
+ if (lbound (a, 1) /= 7 .or. ubound (a, 1) /= 8) stop 2
+ if (.not.allocated (a(7)%h)) stop 3
+ if (allocated (a(8)%h)) stop 4
+ if (lbound (a(7)%h, 1) /= 1 .or. ubound (a(7)%h, 1) /= 3) stop 5
a(:)%g = a(:)%g + 2
a(7)%h = a(7)%h + 3
r = r + 1
!$omp end parallel
- if (.not.allocated (a)) STOP 6
- if (lbound (a, 1) /= 7 .or. ubound (a, 1) /= 8) STOP 7
- if (.not.allocated (a(7)%h)) STOP 8
- if (allocated (a(8)%h)) STOP 9
- if (lbound (a(7)%h, 1) /= 1 .or. ubound (a(7)%h, 1) /= 3) STOP 10
- if (any (a(:)%g /= 2 * r) .or. any (a(7)%h(:) /= 3 * r)) STOP 11
+ if (.not.allocated (a)) stop 6
+ if (lbound (a, 1) /= 7 .or. ubound (a, 1) /= 8) stop 7
+ if (.not.allocated (a(7)%h)) stop 8
+ if (allocated (a(8)%h)) stop 9
+ if (lbound (a(7)%h, 1) /= 1 .or. ubound (a(7)%h, 1) /= 3) stop 10
+ if (any (a(:)%g /= 2 * r) .or. any (a(7)%h(:) /= 3 * r)) stop 11
contains
subroutine foo (x, y)
type (dt), allocatable :: x(:), y(:)
- if (allocated (x) .neqv. allocated (y)) STOP 12
- if (lbound (x, 1) /= lbound (y, 1)) STOP 13
- if (ubound (x, 1) /= ubound (y, 1)) STOP 14
- if (allocated (x(7)%h) .neqv. allocated (y(7)%h)) STOP 15
- if (allocated (x(8)%h) .neqv. allocated (y(8)%h)) STOP 16
- if (lbound (x(7)%h, 1) /= lbound (y(7)%h, 1)) STOP 17
- if (ubound (x(7)%h, 1) /= ubound (y(7)%h, 1)) STOP 18
+ if (allocated (x) .neqv. allocated (y)) stop 12
+ if (lbound (x, 1) /= lbound (y, 1)) stop 13
+ if (ubound (x, 1) /= ubound (y, 1)) stop 14
+ if (allocated (x(7)%h) .neqv. allocated (y(7)%h)) stop 15
+ if (allocated (x(8)%h) .neqv. allocated (y(8)%h)) stop 16
+ if (lbound (x(7)%h, 1) /= lbound (y(7)%h, 1)) stop 17
+ if (ubound (x(7)%h, 1) /= ubound (y(7)%h, 1)) stop 18
x(7)%g = 0
x(7)%h = 0
x(8)%g = 0
diff --git a/libgomp/testsuite/libgomp.fortran/udr15.f90 b/libgomp/testsuite/libgomp.fortran/udr15.f90
index ffdb9a783bc..f5f3139d084 100644
--- a/libgomp/testsuite/libgomp.fortran/udr15.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr15.f90
@@ -60,5 +60,5 @@ end module udr15m2
j = j.addthree.iand (i, -4)
d = d + dt(i)
end do
- if (d%x /= 5050 .or. j /= 4903) STOP 1
+ if (d%x /= 5050 .or. j /= 4903) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/udr2.f90 b/libgomp/testsuite/libgomp.fortran/udr2.f90
index 5b7d87b33eb..81fc6519257 100644
--- a/libgomp/testsuite/libgomp.fortran/udr2.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr2.f90
@@ -28,24 +28,24 @@ end module udr2
do i = 1, 100
j = j + i
end do
- if (any(j .ne. 5050)) STOP 1
+ if (any(j .ne. 5050)) stop 1
j = 3
!$omp parallel do reduction (bar : j)
do i = 1, 100
j = j + 4 * i
end do
- if (any(j .ne. (5050 * 4 + 3))) STOP 2
+ if (any(j .ne. (5050 * 4 + 3))) stop 2
!$omp parallel do reduction (+ : d)
do i = 1, 100
- if (any(d%y .ne. 9)) STOP 3
+ if (any(d%y .ne. 9)) stop 3
d%x = d%x + 8 * i
end do
- if (any(d%x .ne. (5050 * 8 + 7)) .or. any(d%y .ne. 9)) STOP 4
+ if (any(d%x .ne. (5050 * 8 + 7)) .or. any(d%y .ne. 9)) stop 4
d = dt (5, 21)
!$omp parallel do reduction (foo : d)
do i = 1, 100
- if (any(d%y .ne. 21)) STOP 5
+ if (any(d%y .ne. 21)) stop 5
d%x = d%x + 8 * i
end do
- if (any(d%x .ne. (5050 * 8 + 5)) .or. any(d%y .ne. 21)) STOP 6
+ if (any(d%x .ne. (5050 * 8 + 5)) .or. any(d%y .ne. 21)) stop 6
end
diff --git a/libgomp/testsuite/libgomp.fortran/udr3.f90 b/libgomp/testsuite/libgomp.fortran/udr3.f90
index 50cecec1f5a..a54f8ba2b2f 100644
--- a/libgomp/testsuite/libgomp.fortran/udr3.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr3.f90
@@ -29,10 +29,10 @@
& // char (ichar (f(2:2)) + mod (i, 3))
end do
do i = 1, 64
- if (index (c, char (ichar ('0') + i)) .eq. 0) STOP 1
- if (index (d, char (ichar ('0') + i)) .eq. 0) STOP 2
+ if (index (c, char (ichar ('0') + i)) .eq. 0) stop 1
+ if (index (d, char (ichar ('0') + i)) .eq. 0) stop 2
end do
- if (e.ne.char (ichar ('0') + 64)) STOP 3
- if (f(1:1).ne.char (ichar ('0') + 32)) STOP 4
- if (f(2:2).ne.char (ichar ('0') + 64)) STOP 5
+ if (e.ne.char (ichar ('0') + 64)) stop 3
+ if (f(1:1).ne.char (ichar ('0') + 32)) stop 4
+ if (f(2:2).ne.char (ichar ('0') + 64)) stop 5
end
diff --git a/libgomp/testsuite/libgomp.fortran/udr4.f90 b/libgomp/testsuite/libgomp.fortran/udr4.f90
index 86d9515c70a..5d70b6b2830 100644
--- a/libgomp/testsuite/libgomp.fortran/udr4.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr4.f90
@@ -36,12 +36,12 @@
& // char (ichar (f(:,:)(2:2)) + mod (i, 3))
end do
do i = 1, 64
- if (any (index (c, char (ichar ('0') + i)) .eq. 0)) STOP 1
- if (any (index (d, char (ichar ('0') + i)) .eq. 0)) STOP 2
+ if (any (index (c, char (ichar ('0') + i)) .eq. 0)) stop 1
+ if (any (index (d, char (ichar ('0') + i)) .eq. 0)) stop 2
end do
- if (any (e.ne.char (ichar ('0') + 64))) STOP 3
- if (any (f(:,:)(1:1).ne.char (ichar ('0') + 32))) STOP 4
- if (any (f(:,:)(2:2).ne.char (ichar ('0') + 64))) STOP 5
+ if (any (e.ne.char (ichar ('0') + 64))) stop 3
+ if (any (f(:,:)(1:1).ne.char (ichar ('0') + 32))) stop 4
+ if (any (f(:,:)(2:2).ne.char (ichar ('0') + 64))) stop 5
end
elemental function fn (x, y)
character (len=64), intent (in) :: x, y
diff --git a/libgomp/testsuite/libgomp.fortran/udr5.f90 b/libgomp/testsuite/libgomp.fortran/udr5.f90
index 8c6c525742a..725d0bfc905 100644
--- a/libgomp/testsuite/libgomp.fortran/udr5.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr5.f90
@@ -52,6 +52,6 @@ program udr5
r4 = r4 + 1.0
call dp_add (dp, 1.0d0)
!$omp end parallel
- if (xdt%r .ne. r) STOP 1
- if (i4.ne.r.or.i8.ne.r.or.r4.ne.r.or.dp.ne.r) STOP 2
+ if (xdt%r .ne. r) stop 1
+ if (i4.ne.r.or.i8.ne.r.or.r4.ne.r.or.dp.ne.r) stop 2
end program udr5
diff --git a/libgomp/testsuite/libgomp.fortran/udr6.f90 b/libgomp/testsuite/libgomp.fortran/udr6.f90
index 159f6a40ffb..7c7556b5f24 100644
--- a/libgomp/testsuite/libgomp.fortran/udr6.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr6.f90
@@ -62,8 +62,8 @@ program udr6
call dp_add (dp(i), 1.0d0)
end do
!$omp end parallel
- if (any (xdt%r .ne. r)) STOP 1
- if (any (i4.ne.r).or.any(i8.ne.r)) STOP 2
- if (any(r4.ne.r).or.any(dp.ne.r)) STOP 3
+ if (any (xdt%r .ne. r)) stop 1
+ if (any (i4.ne.r).or.any(i8.ne.r)) stop 2
+ if (any(r4.ne.r).or.any(dp.ne.r)) stop 3
deallocate (xdt, i4, i8, r4, dp)
end program udr6
diff --git a/libgomp/testsuite/libgomp.fortran/udr7.f90 b/libgomp/testsuite/libgomp.fortran/udr7.f90
index 92b24a196f4..9e60ac1eb0d 100644
--- a/libgomp/testsuite/libgomp.fortran/udr7.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr7.f90
@@ -22,7 +22,7 @@ program udr7
do i = 1, 64
x = x + i
end do
- if (any (x /= 2080.0)) STOP 1
+ if (any (x /= 2080.0)) stop 1
contains
elemental subroutine omp_out (x, y)
real, intent (out) :: x
diff --git a/libgomp/testsuite/libgomp.fortran/udr8.f90 b/libgomp/testsuite/libgomp.fortran/udr8.f90
index 6b8eac22a7f..fb1fc2e9373 100644
--- a/libgomp/testsuite/libgomp.fortran/udr8.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr8.f90
@@ -42,5 +42,5 @@ end module udr8m2
j = j.add.iand (i, -4)
d = d + dt(i)
end do
- if (d%x /= 5050 .or. j /= 4903) STOP 1
+ if (d%x /= 5050 .or. j /= 4903) stop 1
end
diff --git a/libgomp/testsuite/libgomp.fortran/udr9.f90 b/libgomp/testsuite/libgomp.fortran/udr9.f90
index a8ba78d924d..7b96f88fcbb 100644
--- a/libgomp/testsuite/libgomp.fortran/udr9.f90
+++ b/libgomp/testsuite/libgomp.fortran/udr9.f90
@@ -23,7 +23,7 @@ contains
end subroutine
subroutine initializer1 (x, y)
integer :: x, y
- if (y .ne. 3) STOP 1
+ if (y .ne. 3) stop 1
x = y
end subroutine
end module udr9m1
@@ -61,5 +61,5 @@ end module udr9m2
j = j.add.iand (i, -4)
d = d + dt(i)
end do
- if (d%x /= 5050 .or. j /= 4903) STOP 2
+ if (d%x /= 5050 .or. j /= 4903) stop 2
end
diff --git a/libgomp/testsuite/libgomp.fortran/use_device_addr-1.f90 b/libgomp/testsuite/libgomp.fortran/use_device_addr-1.f90
new file mode 100644
index 00000000000..94ac76f5700
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/use_device_addr-1.f90
@@ -0,0 +1,1233 @@
+! { dg-do run }
+! Comprehensive run-time test for use_device_addr
+!
+! Differs from use_device_addr-2.f90 by using a 8-byte variable (c_double)
+!
+! This test case assumes that a 'var' appearing in 'use_device_addr' is
+! only used as 'c_loc(var)' - such that only the actual data is used/usable
+! on the device - and not meta data ((dynamic) type information, 'present()'
+! status, array shape).
+!
+! Untested in this test case are:
+! - arrays with array descriptor
+! - polymorphic variables
+! - absent optional arguments
+!
+module target_procs
+ use iso_c_binding
+ implicit none (type, external)
+ private
+ public :: copy3_array, copy3_scalar
+contains
+ subroutine copy3_array_int(from_ptr, to_ptr, N)
+ !$omp declare target
+ real(c_double) :: from_ptr(:)
+ real(c_double) :: to_ptr(:)
+ integer, value :: N
+ integer :: i
+
+ !$omp parallel do
+ do i = 1, N
+ to_ptr(i) = 3 * from_ptr(i)
+ end do
+ !$omp end parallel do
+ end subroutine copy3_array_int
+
+ subroutine copy3_scalar_int(from, to)
+ !$omp declare target
+ real(c_double) :: from, to
+
+ to = 3 * from
+ end subroutine copy3_scalar_int
+
+
+ subroutine copy3_array(from, to, N)
+ type(c_ptr), value :: from, to
+ integer, value :: N
+ real(c_double), pointer :: from_ptr(:), to_ptr(:)
+
+ call c_f_pointer(from, from_ptr, shape=[N])
+ call c_f_pointer(to, to_ptr, shape=[N])
+
+ call do_offload_scalar(from_ptr,to_ptr)
+ contains
+ subroutine do_offload_scalar(from_r, to_r)
+ real(c_double), target :: from_r(:), to_r(:)
+ ! The extra function is needed as is_device_ptr
+ ! requires non-value, non-pointer dummy arguments
+
+ !$omp target is_device_ptr(from_r, to_r)
+ call copy3_array_int(from_r, to_r, N)
+ !$omp end target
+ end subroutine do_offload_scalar
+ end subroutine copy3_array
+
+ subroutine copy3_scalar(from, to)
+ type(c_ptr), value, target :: from, to
+ real(c_double), pointer :: from_ptr(:), to_ptr(:)
+
+ ! Standard-conform detour of using an array as at time of writing
+ ! is_device_ptr below does not handle scalars
+ call c_f_pointer(from, from_ptr, shape=[1])
+ call c_f_pointer(to, to_ptr, shape=[1])
+
+ call do_offload_scalar(from_ptr,to_ptr)
+ contains
+ subroutine do_offload_scalar(from_r, to_r)
+ real(c_double), target :: from_r(:), to_r(:)
+ ! The extra function is needed as is_device_ptr
+ ! requires non-value, non-pointer dummy arguments
+
+ !$omp target is_device_ptr(from_r, to_r)
+ call copy3_scalar_int(from_r(1), to_r(1))
+ !$omp end target
+ end subroutine do_offload_scalar
+ end subroutine copy3_scalar
+end module target_procs
+
+
+
+! Test local dummy arguments (w/o optional)
+module test_dummies
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_call_1, test_dummy_call_2
+contains
+ subroutine test_dummy_call_1()
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_double), target :: aa, bb
+ real(c_double), target, allocatable :: cc, dd
+ real(c_double), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_double), target :: gg(N), hh(N)
+
+ allocate(cc, dd, ee, ff)
+
+ aa = 11.0_c_double
+ bb = 22.0_c_double
+ cc = 33.0_c_double
+ dd = 44.0_c_double
+ ee = 55.0_c_double
+ ff = 66.0_c_double
+ gg = 77.0_c_double
+ hh = 88.0_c_double
+
+ call test_dummy_callee_1(aa, bb, cc, dd, ee, ff, gg, hh, N)
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_dummy_call_1
+
+ subroutine test_dummy_callee_1(aa, bb, cc, dd, ee, ff, gg, hh, N)
+ ! scalars
+ real(c_double), target :: aa, bb
+ real(c_double), target, allocatable :: cc, dd
+ real(c_double), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_double), target :: gg(N), hh(N)
+ integer, value :: N
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ call copy3_scalar(c_loc(aa), c_loc(bb))
+ !$omp end target data
+ if (abs(aa - 11.0_c_double) > 10.0_c_double * epsilon(aa)) stop 1
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 2
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ call copy3_scalar(c_loc(cc), c_loc(dd))
+ !$omp end target data
+ if (abs(cc - 33.0_c_double) > 10.0_c_double * epsilon(cc)) stop 3
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 4
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ call copy3_scalar(c_loc(ee), c_loc(ff))
+ !$omp end target data
+ if (abs(ee - 55.0_c_double) > 10.0_c_double * epsilon(ee)) stop 5
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 6
+
+
+ !$omp target data map(to:gg) map(from:hh) use_device_addr(gg,hh)
+ call copy3_array(c_loc(gg), c_loc(hh), N)
+ !$omp end target data
+ if (any(abs(gg - 77.0_c_double) > 10.0_c_double * epsilon(gg))) stop 7
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 8
+ end subroutine test_dummy_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_call_2()
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_double), target :: aa, bb
+ real(c_double), target, allocatable :: cc, dd
+ real(c_double), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_double), target :: gg(N), hh(N)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_double), pointer :: aptr, bptr, cptr, dptr, eptr, fptr
+ real(c_double), pointer :: gptr(:), hptr(:)
+
+ allocate(cc, dd, ee, ff)
+ call test_dummy_callee_2(aa, bb, cc, dd, ee, ff, gg, hh, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, gptr, hptr, &
+ N)
+ deallocate(ee, ff)
+ end subroutine test_dummy_call_2
+
+ subroutine test_dummy_callee_2(aa, bb, cc, dd, ee, ff, gg, hh, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, gptr, hptr, &
+ N)
+ ! scalars
+ real(c_double), target :: aa, bb
+ real(c_double), target, allocatable :: cc, dd
+ real(c_double), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_double), target :: gg(N), hh(N)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_double), pointer :: aptr, bptr, cptr, dptr, eptr, fptr
+ real(c_double), pointer :: gptr(:), hptr(:)
+
+ integer, value :: N
+
+ real(c_double) :: dummy
+
+ aa = 111.0_c_double
+ bb = 222.0_c_double
+ cc = 333.0_c_double
+ dd = 444.0_c_double
+ ee = 555.0_c_double
+ ff = 666.0_c_double
+ gg = 777.0_c_double
+ hh = 888.0_c_double
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 9
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 10
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_double
+ !$omp target update to(aa)
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 1111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 11
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 12
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_double
+ !$omp target update to(aa)
+ call copy3_scalar(c_loc(aptr), c_loc(bptr))
+ !$omp target update from(bb)
+ if (abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 13
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 14
+ !$omp end target data
+
+ if (abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 15
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 16
+
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 333.0_c_double) > 10.0_c_double * epsilon(cc)) stop 17
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 18
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_double
+ !$omp target update to(cc)
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 3333.0_c_double) > 10.0_c_double * epsilon(cc)) stop 19
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 20
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_double
+ !$omp target update to(cc)
+ call copy3_scalar(c_loc(cptr), c_loc(dptr))
+ !$omp target update from(dd)
+ if (abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(cc)) stop 21
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 22
+ !$omp end target data
+
+ if (abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(dd)) stop 23
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(dd)) stop 24
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 25
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 26
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_double
+ !$omp target update to(ee)
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 5555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 27
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 28
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_double
+ !$omp target update to(ee)
+ call copy3_scalar(c_loc(eptr), c_loc(fptr))
+ !$omp target update from(ff)
+ if (abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 29
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ff)) stop 30
+ !$omp end target data
+
+ if (abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 31
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 32
+
+
+ !$omp target data map(to:gg) map(from:hh)
+ !$omp target data map(alloc:dummy) use_device_addr(gg,hh)
+ c_gptr = c_loc(gg)
+ c_hptr = c_loc(hh)
+ gptr => gg
+ hptr => hh
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 33
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(hh))) stop 34
+
+ ! check c_loc ptr again after target-value modification
+ gg = 7777.0_c_double
+ !$omp target update to(gg)
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 7777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 35
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 36
+
+ ! check Fortran pointer after target-value modification
+ gg = 77777.0_c_double
+ !$omp target update to(gg)
+ call copy3_array(c_loc(gptr), c_loc(hptr), N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 77777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 37
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 38
+ !$omp end target data
+
+ if (any(abs(gg - 77777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 39
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 40
+ end subroutine test_dummy_callee_2
+end module test_dummies
+
+
+
+! Test local dummy arguments + VALUE (w/o optional)
+module test_dummies_value
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_val_call_1, test_dummy_val_call_2
+contains
+ subroutine test_dummy_val_call_1()
+ ! scalars - with value, neither allocatable nor pointer no dimension permitted
+ real(c_double), target :: aa, bb
+
+ aa = 11.0_c_double
+ bb = 22.0_c_double
+
+ call test_dummy_val_callee_1(aa, bb)
+ end subroutine test_dummy_val_call_1
+
+ subroutine test_dummy_val_callee_1(aa, bb)
+ ! scalars
+ real(c_double), value, target :: aa, bb
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ call copy3_scalar(c_loc(aa), c_loc(bb))
+ !$omp end target data
+ if (abs(aa - 11.0_c_double) > 10.0_c_double * epsilon(aa)) stop 41
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 42
+ end subroutine test_dummy_val_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_val_call_2()
+ ! scalars - with value, neither allocatable nor pointer no dimension permitted
+ real(c_double), target :: aa, bb
+ type(c_ptr) :: c_aptr, c_bptr
+ real(c_double), pointer :: aptr, bptr
+
+ call test_dummy_val_callee_2(aa, bb, c_aptr, c_bptr, aptr, bptr)
+ end subroutine test_dummy_val_call_2
+
+ subroutine test_dummy_val_callee_2(aa, bb, c_aptr, c_bptr, aptr, bptr)
+ real(c_double), value, target :: aa, bb
+ type(c_ptr), value :: c_aptr, c_bptr
+ real(c_double), pointer :: aptr, bptr
+
+ real(c_double) :: dummy
+
+ aa = 111.0_c_double
+ bb = 222.0_c_double
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 43
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 44
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_double
+ !$omp target update to(aa)
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 1111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 45
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 46
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_double
+ !$omp target update to(aa)
+ call copy3_scalar(c_loc(aptr), c_loc(bptr))
+ !$omp target update from(bb)
+ if (abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 47
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 48
+ !$omp end target data
+
+ if (abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 49
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 50
+ end subroutine test_dummy_val_callee_2
+end module test_dummies_value
+
+
+
+! Test local dummy arguments + OPTIONAL
+! Values present and ptr associated to nonzero
+module test_dummies_opt
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_opt_call_1, test_dummy_opt_call_2
+contains
+ subroutine test_dummy_opt_call_1()
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_double), target :: aa, bb
+ real(c_double), target, allocatable :: cc, dd
+ real(c_double), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_double), target :: gg(N), hh(N)
+
+ allocate(cc, dd, ee, ff)
+
+ aa = 11.0_c_double
+ bb = 22.0_c_double
+ cc = 33.0_c_double
+ dd = 44.0_c_double
+ ee = 55.0_c_double
+ ff = 66.0_c_double
+ gg = 77.0_c_double
+ hh = 88.0_c_double
+
+ call test_dummy_opt_callee_1(aa, bb, cc, dd, ee, ff, gg, hh, N)
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_dummy_opt_call_1
+
+ subroutine test_dummy_opt_callee_1(aa, bb, cc, dd, ee, ff, gg, hh, N)
+ ! scalars
+ real(c_double), optional, target :: aa, bb
+ real(c_double), optional, target, allocatable :: cc, dd
+ real(c_double), optional, pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_double), optional, target :: gg(N), hh(N)
+ integer, value :: N
+
+ ! All shall be present - and pointing to non-NULL
+ if (.not.present(aa) .or. .not.present(bb)) stop 51
+ if (.not.present(cc) .or. .not.present(dd)) stop 52
+ if (.not.present(ee) .or. .not.present(ff)) stop 53
+ if (.not.present(gg) .or. .not.present(hh)) stop 54
+
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 55
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 56
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 57
+ call copy3_scalar(c_loc(aa), c_loc(bb))
+ !$omp end target data
+ if (abs(aa - 11.0_c_double) > 10.0_c_double * epsilon(aa)) stop 58
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 59
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ if (.not.present(cc) .or. .not.present(dd)) stop 60
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 61
+ call copy3_scalar(c_loc(cc), c_loc(dd))
+ !$omp end target data
+ if (abs(cc - 33.0_c_double) > 10.0_c_double * epsilon(cc)) stop 62
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 63
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 64
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 65
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 66
+ call copy3_scalar(c_loc(ee), c_loc(ff))
+ !$omp end target data
+ if (abs(ee - 55.0_c_double) > 10.0_c_double * epsilon(ee)) stop 67
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 68
+
+ !$omp target data map(to:gg) map(from:hh) use_device_addr(gg,hh)
+ if (.not.present(gg) .or. .not.present(hh)) stop 69
+ if (.not.c_associated(c_loc(gg)) .or. .not.c_associated(c_loc(hh))) stop 70
+ call copy3_array(c_loc(gg), c_loc(hh), N)
+ !$omp end target data
+ if (any(abs(gg - 77.0_c_double) > 10.0_c_double * epsilon(gg))) stop 71
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 72
+ end subroutine test_dummy_opt_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_opt_call_2()
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_double), target :: aa, bb
+ real(c_double), target, allocatable :: cc, dd
+ real(c_double), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_double), target :: gg(N), hh(N)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_double), pointer :: aptr, bptr, cptr, dptr, eptr, fptr
+ real(c_double), pointer :: gptr(:), hptr(:)
+
+ allocate(cc, dd, ee, ff)
+ call test_dummy_opt_callee_2(aa, bb, cc, dd, ee, ff, gg, hh, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, gptr, hptr, &
+ N)
+ deallocate(ee, ff)
+ end subroutine test_dummy_opt_call_2
+
+ subroutine test_dummy_opt_callee_2(aa, bb, cc, dd, ee, ff, gg, hh, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, gptr, hptr, &
+ N)
+ ! scalars
+ real(c_double), optional, target :: aa, bb
+ real(c_double), optional, target, allocatable :: cc, dd
+ real(c_double), optional, pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_double), optional, target :: gg(N), hh(N)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_double), optional, pointer :: aptr, bptr, cptr, dptr, eptr, fptr
+ real(c_double), optional, pointer :: gptr(:), hptr(:)
+
+ integer, value :: N
+
+ real(c_double) :: dummy
+
+ ! All shall be present - and pointing to non-NULL
+ if (.not.present(aa) .or. .not.present(bb)) stop 73
+ if (.not.present(cc) .or. .not.present(dd)) stop 74
+ if (.not.present(ee) .or. .not.present(ff)) stop 75
+ if (.not.present(gg) .or. .not.present(hh)) stop 76
+
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 77
+
+ aa = 111.0_c_double
+ bb = 222.0_c_double
+ cc = 333.0_c_double
+ dd = 444.0_c_double
+ ee = 555.0_c_double
+ ff = 666.0_c_double
+ gg = 777.0_c_double
+ hh = 888.0_c_double
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 78
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 79
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ if (.not.c_associated(c_aptr) .or. .not.c_associated(c_bptr)) stop 80
+ if (.not.associated(aptr) .or. .not.associated(bptr)) stop 81
+ !$omp end target data
+
+ if (.not.present(aa) .or. .not.present(bb)) stop 82
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 83
+ if (.not.c_associated(c_aptr) .or. .not.c_associated(c_bptr)) stop 84
+ if (.not.associated(aptr) .or. .not.associated(bptr)) stop 85
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 86
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 87
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_double
+ !$omp target update to(aa)
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 1111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 88
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 89
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_double
+ !$omp target update to(aa)
+ call copy3_scalar(c_loc(aptr), c_loc(bptr))
+ !$omp target update from(bb)
+ if (abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 90
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 91
+ !$omp end target data
+
+ if (abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 92
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 93
+
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ if (.not.present(cc) .or. .not.present(dd)) stop 94
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 95
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ if (.not.c_associated(c_cptr) .or. .not.c_associated(c_dptr)) stop 96
+ if (.not.associated(cptr) .or. .not.associated(dptr)) stop 97
+ !$omp end target data
+ if (.not.present(cc) .or. .not.present(dd)) stop 98
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 99
+ if (.not.c_associated(c_cptr) .or. .not.c_associated(c_dptr)) stop 100
+ if (.not.associated(cptr) .or. .not.associated(dptr)) stop 101
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 333.0_c_double) > 10.0_c_double * epsilon(cc)) stop 102
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 103
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_double
+ !$omp target update to(cc)
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 3333.0_c_double) > 10.0_c_double * epsilon(cc)) stop 104
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 105
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_double
+ !$omp target update to(cc)
+ call copy3_scalar(c_loc(cptr), c_loc(dptr))
+ !$omp target update from(dd)
+ if (abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(cc)) stop 106
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 107
+ !$omp end target data
+
+ if (abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(dd)) stop 108
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(dd)) stop 109
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 110
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 111
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 112
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ if (.not.c_associated(c_eptr) .or. .not.c_associated(c_fptr)) stop 113
+ if (.not.associated(eptr) .or. .not.associated(fptr)) stop 114
+ !$omp end target data
+ if (.not.present(ee) .or. .not.present(ff)) stop 115
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 116
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 117
+ if (.not.c_associated(c_eptr) .or. .not.c_associated(c_fptr)) stop 118
+ if (.not.associated(eptr) .or. .not.associated(fptr)) stop 119
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 120
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 121
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_double
+ !$omp target update to(ee)
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 5555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 122
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 123
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_double
+ !$omp target update to(ee)
+ call copy3_scalar(c_loc(eptr), c_loc(fptr))
+ !$omp target update from(ff)
+ if (abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 124
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ff)) stop 125
+ !$omp end target data
+
+ if (abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 126
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 127
+
+
+ !$omp target data map(to:gg) map(from:hh)
+ !$omp target data map(alloc:dummy) use_device_addr(gg,hh)
+ if (.not.present(gg) .or. .not.present(hh)) stop 128
+ if (.not.c_associated(c_loc(gg)) .or. .not.c_associated(c_loc(hh))) stop 129
+ c_gptr = c_loc(gg)
+ c_hptr = c_loc(hh)
+ gptr => gg
+ hptr => hh
+ if (.not.c_associated(c_gptr) .or. .not.c_associated(c_hptr)) stop 130
+ if (.not.associated(gptr) .or. .not.associated(hptr)) stop 131
+ !$omp end target data
+ if (.not.present(gg) .or. .not.present(hh)) stop 132
+ if (.not.c_associated(c_loc(gg)) .or. .not.c_associated(c_loc(hh))) stop 133
+ if (.not.c_associated(c_gptr) .or. .not.c_associated(c_hptr)) stop 134
+ if (.not.associated(gptr) .or. .not.associated(hptr)) stop 135
+
+ ! check c_loc ptr once
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 136
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(hh))) stop 137
+
+ ! check c_loc ptr again after target-value modification
+ gg = 7777.0_c_double
+ !$omp target update to(gg)
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 7777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 138
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 139
+
+ ! check Fortran pointer after target-value modification
+ gg = 77777.0_c_double
+ !$omp target update to(gg)
+ call copy3_array(c_loc(gptr), c_loc(hptr), N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 77777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 140
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 141
+ !$omp end target data
+
+ if (any(abs(gg - 77777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 142
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 143
+ end subroutine test_dummy_opt_callee_2
+end module test_dummies_opt
+
+
+
+! Test local dummy arguments + OPTIONAL + VALUE
+! Values present
+module test_dummies_opt_value
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_opt_val_call_1, test_dummy_opt_val_call_2
+contains
+ subroutine test_dummy_opt_val_call_1()
+ ! scalars - with value, neither allocatable nor pointer no dimension permitted
+ real(c_double), target :: aa, bb
+
+ aa = 11.0_c_double
+ bb = 22.0_c_double
+
+ call test_dummy_opt_val_callee_1(aa, bb)
+ end subroutine test_dummy_opt_val_call_1
+
+ subroutine test_dummy_opt_val_callee_1(aa, bb)
+ ! scalars
+ real(c_double), optional, value, target :: aa, bb
+
+ if (.not.present(aa) .or. .not.present(bb)) stop 144
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 145
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 146
+ call copy3_scalar(c_loc(aa), c_loc(bb))
+ !$omp end target data
+ if (abs(aa - 11.0_c_double) > 10.0_c_double * epsilon(aa)) stop 147
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 148
+ end subroutine test_dummy_opt_val_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_opt_val_call_2()
+ ! scalars - with value, neither allocatable nor pointer no dimension permitted
+ real(c_double), target :: aa, bb
+ type(c_ptr) :: c_aptr, c_bptr
+ real(c_double), pointer :: aptr, bptr
+
+ call test_dummy_opt_val_callee_2(aa, bb, c_aptr, c_bptr, aptr, bptr)
+ end subroutine test_dummy_opt_val_call_2
+
+ subroutine test_dummy_opt_val_callee_2(aa, bb, c_aptr, c_bptr, aptr, bptr)
+ real(c_double), optional, value, target :: aa, bb
+ type(c_ptr), optional, value :: c_aptr, c_bptr
+ real(c_double), optional, pointer :: aptr, bptr
+
+ real(c_double) :: dummy
+
+ if (.not.present(aa) .or. .not.present(bb)) stop 149
+ if (.not.present(c_aptr) .or. .not.present(c_bptr)) stop 150
+ if (.not.present(aptr) .or. .not.present(bptr)) stop 151
+
+ aa = 111.0_c_double
+ bb = 222.0_c_double
+
+ !$omp target data map(to:aa) map(from:bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 152
+ if (.not.present(c_aptr) .or. .not.present(c_bptr)) stop 153
+ if (.not.present(aptr) .or. .not.present(bptr)) stop 154
+
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 155
+ if (.not.present(c_aptr) .or. .not.present(c_bptr)) stop 156
+ if (.not.present(aptr) .or. .not.present(bptr)) stop 157
+
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ if (.not.c_associated(c_aptr) .or. .not.c_associated(c_bptr)) stop 158
+ if (.not.associated(aptr) .or. .not.associated(bptr)) stop 159
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 160
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 161
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_double
+ !$omp target update to(aa)
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 1111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 162
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 163
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_double
+ !$omp target update to(aa)
+ call copy3_scalar(c_loc(aptr), c_loc(bptr))
+ !$omp target update from(bb)
+ if (abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 164
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 165
+ !$omp end target data
+
+ if (abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 166
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 167
+ end subroutine test_dummy_opt_val_callee_2
+end module test_dummies_opt_value
+
+
+
+! Test nullptr
+module test_nullptr
+ use iso_c_binding
+ implicit none (type, external)
+ private
+ public :: test_nullptr_1
+contains
+ subroutine test_nullptr_1()
+ ! scalars
+ real(c_double), pointer :: aa, bb
+ real(c_double), pointer :: ee, ff
+
+ real(c_double), allocatable, target :: gg, hh
+
+ type(c_ptr) :: c_aptr, c_bptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_double), pointer :: aptr, bptr, eptr, fptr, gptr, hptr
+
+ aa => null()
+ bb => null()
+ ee => null()
+ ff => null()
+
+ if (associated(aa) .or. associated(bb)) stop 168
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ if (c_associated(c_loc(aa)) .or. c_associated(c_loc(bb))) stop 169
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ if (c_associated(c_aptr) .or. c_associated(c_bptr)) stop 170
+ if (associated(aptr) .or. associated(bptr, bb)) stop 171
+ !$omp end target data
+ if (c_associated(c_aptr) .or. c_associated(c_bptr)) stop 172
+ if (associated(aptr) .or. associated(bptr, bb)) stop 173
+
+ if (allocated(gg)) stop 174
+ !$omp target data map(tofrom:gg) use_device_addr(gg)
+ if (c_associated(c_loc(gg))) stop 175
+ c_gptr = c_loc(gg)
+ gptr => gg
+ if (c_associated(c_gptr)) stop 176
+ if (associated(gptr)) stop 177
+ if (allocated(gg)) stop 178
+ !$omp end target data
+ if (c_associated(c_gptr)) stop 179
+ if (associated(gptr)) stop 180
+ if (allocated(gg)) stop 181
+
+ call test_dummy_opt_nullptr_callee_1(ee, ff, hh, c_eptr, c_fptr, c_hptr, eptr, fptr, hptr)
+ end subroutine test_nullptr_1
+
+ subroutine test_dummy_opt_nullptr_callee_1(ee, ff, hh, c_eptr, c_fptr, c_hptr, eptr, fptr, hptr)
+ ! scalars
+ real(c_double), optional, pointer :: ee, ff
+ real(c_double), optional, allocatable, target :: hh
+
+ type(c_ptr), optional :: c_eptr, c_fptr, c_hptr
+ real(c_double), optional, pointer :: eptr, fptr, hptr
+
+ if (.not.present(ee) .or. .not.present(ff)) stop 182
+ if (associated(ee) .or. associated(ff)) stop 183
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 184
+ if (associated(ee) .or. associated(ff)) stop 185
+ if (c_associated(c_loc(ee)) .or. c_associated(c_loc(ff))) stop 186
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ if (c_associated(c_eptr) .or. c_associated(c_fptr)) stop 187
+ if (associated(eptr) .or. associated(fptr)) stop 188
+ !$omp end target data
+
+ if (c_associated(c_eptr) .or. c_associated(c_fptr)) stop 189
+ if (associated(eptr) .or. associated(fptr)) stop 190
+ if (associated(ee) .or. associated(ff)) stop 191
+
+
+ if (.not.present(hh)) stop 192
+ if (allocated(hh)) stop 193
+
+ !$omp target data map(tofrom:hh) use_device_addr(hh)
+ if (.not.present(hh)) stop 194
+ if (allocated(hh)) stop 195
+ if (c_associated(c_loc(hh))) stop 196
+ c_hptr = c_loc(hh)
+ hptr => hh
+ if (c_associated(c_hptr)) stop 197
+ if (associated(hptr)) stop 198
+ if (allocated(hh)) stop 199
+ !$omp end target data
+
+ if (c_associated(c_hptr)) stop 200
+ if (associated(hptr)) stop 201
+ if (allocated(hh)) stop 202
+ end subroutine test_dummy_opt_nullptr_callee_1
+end module test_nullptr
+
+
+
+! Test local variables
+module tests
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_main_1, test_main_2
+contains
+ ! map + use_device_addr + c_loc
+ subroutine test_main_1()
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_double), target :: aa, bb
+ real(c_double), target, allocatable :: cc, dd
+ real(c_double), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_double), target :: gg(N), hh(N)
+
+ allocate(cc, dd, ee, ff)
+
+
+ aa = 11.0_c_double
+ bb = 22.0_c_double
+ cc = 33.0_c_double
+ dd = 44.0_c_double
+ ee = 55.0_c_double
+ ff = 66.0_c_double
+ gg = 77.0_c_double
+ hh = 88.0_c_double
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ call copy3_scalar(c_loc(aa), c_loc(bb))
+ !$omp end target data
+ if (abs(aa - 11.0_c_double) > 10.0_c_double * epsilon(aa)) stop 203
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 204
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ call copy3_scalar(c_loc(cc), c_loc(dd))
+ !$omp end target data
+ if (abs(cc - 33.0_c_double) > 10.0_c_double * epsilon(cc)) stop 205
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 206
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ call copy3_scalar(c_loc(ee), c_loc(ff))
+ !$omp end target data
+ if (abs(ee - 55.0_c_double) > 10.0_c_double * epsilon(ee)) stop 207
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 208
+
+
+ !$omp target data map(to:gg) map(from:hh) use_device_addr(gg,hh)
+ call copy3_array(c_loc(gg), c_loc(hh), N)
+ !$omp end target data
+ if (any(abs(gg - 77.0_c_double) > 10.0_c_double * epsilon(gg))) stop 209
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 210
+
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_main_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_main_2
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_double), target :: aa, bb
+ real(c_double), target, allocatable :: cc, dd
+ real(c_double), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_double), target :: gg(N), hh(N)
+
+ real(c_double) :: dummy
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_double), pointer :: aptr, bptr, cptr, dptr, eptr, fptr
+ real(c_double), pointer :: gptr(:), hptr(:)
+
+ allocate(cc, dd, ee, ff)
+
+ aa = 111.0_c_double
+ bb = 222.0_c_double
+ cc = 333.0_c_double
+ dd = 444.0_c_double
+ ee = 555.0_c_double
+ ff = 666.0_c_double
+ gg = 777.0_c_double
+ hh = 888.0_c_double
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 211
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 212
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_double
+ !$omp target update to(aa)
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 1111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 213
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 214
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_double
+ !$omp target update to(aa)
+ call copy3_scalar(c_loc(aptr), c_loc(bptr))
+ !$omp target update from(bb)
+ if (abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 215
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 216
+ !$omp end target data
+
+ if (abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa)) stop 217
+ if (abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa)) stop 218
+
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 333.0_c_double) > 10.0_c_double * epsilon(cc)) stop 219
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 220
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_double
+ !$omp target update to(cc)
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 3333.0_c_double) > 10.0_c_double * epsilon(cc)) stop 221
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 222
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_double
+ !$omp target update to(cc)
+ call copy3_scalar(c_loc(cptr), c_loc(dptr))
+ !$omp target update from(dd)
+ if (abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(cc)) stop 223
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc)) stop 224
+ !$omp end target data
+
+ if (abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(dd)) stop 225
+ if (abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(dd)) stop 226
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 227
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 228
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_double
+ !$omp target update to(ee)
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 5555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 229
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 230
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_double
+ !$omp target update to(ee)
+ call copy3_scalar(c_loc(eptr), c_loc(fptr))
+ !$omp target update from(ff)
+ if (abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 231
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ff)) stop 232
+ !$omp end target data
+
+ if (abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee)) stop 233
+ if (abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee)) stop 234
+
+
+ !$omp target data map(to:gg) map(from:hh)
+ !$omp target data map(alloc:dummy) use_device_addr(gg,hh)
+ c_gptr = c_loc(gg)
+ c_hptr = c_loc(hh)
+ gptr => gg
+ hptr => hh
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 235
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(hh))) stop 236
+
+ ! check c_loc ptr again after target-value modification
+ gg = 7777.0_c_double
+ !$omp target update to(gg)
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 7777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 237
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 238
+
+ ! check Fortran pointer after target-value modification
+ gg = 77777.0_c_double
+ !$omp target update to(gg)
+ call copy3_array(c_loc(gptr), c_loc(hptr), N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 77777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 239
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 240
+ !$omp end target data
+
+ if (any(abs(gg - 77777.0_c_double) > 10.0_c_double * epsilon(gg))) stop 241
+ if (any(abs(3.0_c_double * gg - hh) > 10.0_c_double * epsilon(gg))) stop 242
+
+ deallocate(ee, ff)
+ end subroutine test_main_2
+end module tests
+
+
+program omp_device_addr
+ use tests
+ use test_dummies
+ use test_dummies_value
+ use test_dummies_opt
+ use test_dummies_opt_value
+ use test_nullptr
+ implicit none (type, external)
+
+ call test_main_1()
+ call test_main_2()
+
+ call test_dummy_call_1()
+ call test_dummy_call_2()
+
+ call test_dummy_val_call_1()
+ call test_dummy_val_call_2()
+
+ call test_dummy_opt_call_1()
+ call test_dummy_opt_call_2()
+
+ call test_dummy_opt_val_call_1()
+ call test_dummy_opt_val_call_2()
+
+ call test_nullptr_1()
+end program omp_device_addr
diff --git a/libgomp/testsuite/libgomp.fortran/use_device_addr-2.f90 b/libgomp/testsuite/libgomp.fortran/use_device_addr-2.f90
new file mode 100644
index 00000000000..d6c5a672370
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/use_device_addr-2.f90
@@ -0,0 +1,1233 @@
+! { dg-do run }
+! Comprehensive run-time test for use_device_addr
+!
+! Differs from use_device_addr-1.f90 by using a 4-byte variable (c_float)
+!
+! This test case assumes that a 'var' appearing in 'use_device_addr' is
+! only used as 'c_loc(var)' - such that only the actual data is used/usable
+! on the device - and not meta data ((dynamic) type information, 'present()'
+! status, array shape).
+!
+! Untested in this test case are:
+! - arrays with array descriptor
+! - polymorphic variables
+! - absent optional arguments
+!
+module target_procs
+ use iso_c_binding
+ implicit none (type, external)
+ private
+ public :: copy3_array, copy3_scalar
+contains
+ subroutine copy3_array_int(from_ptr, to_ptr, N)
+ !$omp declare target
+ real(c_float) :: from_ptr(:)
+ real(c_float) :: to_ptr(:)
+ integer, value :: N
+ integer :: i
+
+ !$omp parallel do
+ do i = 1, N
+ to_ptr(i) = 3 * from_ptr(i)
+ end do
+ !$omp end parallel do
+ end subroutine copy3_array_int
+
+ subroutine copy3_scalar_int(from, to)
+ !$omp declare target
+ real(c_float) :: from, to
+
+ to = 3 * from
+ end subroutine copy3_scalar_int
+
+
+ subroutine copy3_array(from, to, N)
+ type(c_ptr), value :: from, to
+ integer, value :: N
+ real(c_float), pointer :: from_ptr(:), to_ptr(:)
+
+ call c_f_pointer(from, from_ptr, shape=[N])
+ call c_f_pointer(to, to_ptr, shape=[N])
+
+ call do_offload_scalar(from_ptr,to_ptr)
+ contains
+ subroutine do_offload_scalar(from_r, to_r)
+ real(c_float), target :: from_r(:), to_r(:)
+ ! The extra function is needed as is_device_ptr
+ ! requires non-value, non-pointer dummy arguments
+
+ !$omp target is_device_ptr(from_r, to_r)
+ call copy3_array_int(from_r, to_r, N)
+ !$omp end target
+ end subroutine do_offload_scalar
+ end subroutine copy3_array
+
+ subroutine copy3_scalar(from, to)
+ type(c_ptr), value, target :: from, to
+ real(c_float), pointer :: from_ptr(:), to_ptr(:)
+
+ ! Standard-conform detour of using an array as at time of writing
+ ! is_device_ptr below does not handle scalars
+ call c_f_pointer(from, from_ptr, shape=[1])
+ call c_f_pointer(to, to_ptr, shape=[1])
+
+ call do_offload_scalar(from_ptr,to_ptr)
+ contains
+ subroutine do_offload_scalar(from_r, to_r)
+ real(c_float), target :: from_r(:), to_r(:)
+ ! The extra function is needed as is_device_ptr
+ ! requires non-value, non-pointer dummy arguments
+
+ !$omp target is_device_ptr(from_r, to_r)
+ call copy3_scalar_int(from_r(1), to_r(1))
+ !$omp end target
+ end subroutine do_offload_scalar
+ end subroutine copy3_scalar
+end module target_procs
+
+
+
+! Test local dummy arguments (w/o optional)
+module test_dummies
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_call_1, test_dummy_call_2
+contains
+ subroutine test_dummy_call_1()
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_float), target :: aa, bb
+ real(c_float), target, allocatable :: cc, dd
+ real(c_float), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_float), target :: gg(N), hh(N)
+
+ allocate(cc, dd, ee, ff)
+
+ aa = 11.0_c_float
+ bb = 22.0_c_float
+ cc = 33.0_c_float
+ dd = 44.0_c_float
+ ee = 55.0_c_float
+ ff = 66.0_c_float
+ gg = 77.0_c_float
+ hh = 88.0_c_float
+
+ call test_dummy_callee_1(aa, bb, cc, dd, ee, ff, gg, hh, N)
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_dummy_call_1
+
+ subroutine test_dummy_callee_1(aa, bb, cc, dd, ee, ff, gg, hh, N)
+ ! scalars
+ real(c_float), target :: aa, bb
+ real(c_float), target, allocatable :: cc, dd
+ real(c_float), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_float), target :: gg(N), hh(N)
+ integer, value :: N
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ call copy3_scalar(c_loc(aa), c_loc(bb))
+ !$omp end target data
+ if (abs(aa - 11.0_c_float) > 10.0_c_float * epsilon(aa)) stop 1
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 2
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ call copy3_scalar(c_loc(cc), c_loc(dd))
+ !$omp end target data
+ if (abs(cc - 33.0_c_float) > 10.0_c_float * epsilon(cc)) stop 3
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 4
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ call copy3_scalar(c_loc(ee), c_loc(ff))
+ !$omp end target data
+ if (abs(ee - 55.0_c_float) > 10.0_c_float * epsilon(ee)) stop 5
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 6
+
+
+ !$omp target data map(to:gg) map(from:hh) use_device_addr(gg,hh)
+ call copy3_array(c_loc(gg), c_loc(hh), N)
+ !$omp end target data
+ if (any(abs(gg - 77.0_c_float) > 10.0_c_float * epsilon(gg))) stop 7
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 8
+ end subroutine test_dummy_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_call_2()
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_float), target :: aa, bb
+ real(c_float), target, allocatable :: cc, dd
+ real(c_float), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_float), target :: gg(N), hh(N)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_float), pointer :: aptr, bptr, cptr, dptr, eptr, fptr
+ real(c_float), pointer :: gptr(:), hptr(:)
+
+ allocate(cc, dd, ee, ff)
+ call test_dummy_callee_2(aa, bb, cc, dd, ee, ff, gg, hh, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, gptr, hptr, &
+ N)
+ deallocate(ee, ff)
+ end subroutine test_dummy_call_2
+
+ subroutine test_dummy_callee_2(aa, bb, cc, dd, ee, ff, gg, hh, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, gptr, hptr, &
+ N)
+ ! scalars
+ real(c_float), target :: aa, bb
+ real(c_float), target, allocatable :: cc, dd
+ real(c_float), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_float), target :: gg(N), hh(N)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_float), pointer :: aptr, bptr, cptr, dptr, eptr, fptr
+ real(c_float), pointer :: gptr(:), hptr(:)
+
+ integer, value :: N
+
+ real(c_float) :: dummy
+
+ aa = 111.0_c_float
+ bb = 222.0_c_float
+ cc = 333.0_c_float
+ dd = 444.0_c_float
+ ee = 555.0_c_float
+ ff = 666.0_c_float
+ gg = 777.0_c_float
+ hh = 888.0_c_float
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 9
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 10
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_float
+ !$omp target update to(aa)
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 1111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 11
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 12
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_float
+ !$omp target update to(aa)
+ call copy3_scalar(c_loc(aptr), c_loc(bptr))
+ !$omp target update from(bb)
+ if (abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 13
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 14
+ !$omp end target data
+
+ if (abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 15
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 16
+
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 333.0_c_float) > 10.0_c_float * epsilon(cc)) stop 17
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 18
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_float
+ !$omp target update to(cc)
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 3333.0_c_float) > 10.0_c_float * epsilon(cc)) stop 19
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 20
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_float
+ !$omp target update to(cc)
+ call copy3_scalar(c_loc(cptr), c_loc(dptr))
+ !$omp target update from(dd)
+ if (abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(cc)) stop 21
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 22
+ !$omp end target data
+
+ if (abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(dd)) stop 23
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(dd)) stop 24
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 25
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 26
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_float
+ !$omp target update to(ee)
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 5555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 27
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 28
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_float
+ !$omp target update to(ee)
+ call copy3_scalar(c_loc(eptr), c_loc(fptr))
+ !$omp target update from(ff)
+ if (abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 29
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ff)) stop 30
+ !$omp end target data
+
+ if (abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 31
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 32
+
+
+ !$omp target data map(to:gg) map(from:hh)
+ !$omp target data map(alloc:dummy) use_device_addr(gg,hh)
+ c_gptr = c_loc(gg)
+ c_hptr = c_loc(hh)
+ gptr => gg
+ hptr => hh
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 33
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(hh))) stop 34
+
+ ! check c_loc ptr again after target-value modification
+ gg = 7777.0_c_float
+ !$omp target update to(gg)
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 7777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 35
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 36
+
+ ! check Fortran pointer after target-value modification
+ gg = 77777.0_c_float
+ !$omp target update to(gg)
+ call copy3_array(c_loc(gptr), c_loc(hptr), N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 77777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 37
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 38
+ !$omp end target data
+
+ if (any(abs(gg - 77777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 39
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 40
+ end subroutine test_dummy_callee_2
+end module test_dummies
+
+
+
+! Test local dummy arguments + VALUE (w/o optional)
+module test_dummies_value
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_val_call_1, test_dummy_val_call_2
+contains
+ subroutine test_dummy_val_call_1()
+ ! scalars - with value, neither allocatable nor pointer no dimension permitted
+ real(c_float), target :: aa, bb
+
+ aa = 11.0_c_float
+ bb = 22.0_c_float
+
+ call test_dummy_val_callee_1(aa, bb)
+ end subroutine test_dummy_val_call_1
+
+ subroutine test_dummy_val_callee_1(aa, bb)
+ ! scalars
+ real(c_float), value, target :: aa, bb
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ call copy3_scalar(c_loc(aa), c_loc(bb))
+ !$omp end target data
+ if (abs(aa - 11.0_c_float) > 10.0_c_float * epsilon(aa)) stop 41
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 42
+ end subroutine test_dummy_val_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_val_call_2()
+ ! scalars - with value, neither allocatable nor pointer no dimension permitted
+ real(c_float), target :: aa, bb
+ type(c_ptr) :: c_aptr, c_bptr
+ real(c_float), pointer :: aptr, bptr
+
+ call test_dummy_val_callee_2(aa, bb, c_aptr, c_bptr, aptr, bptr)
+ end subroutine test_dummy_val_call_2
+
+ subroutine test_dummy_val_callee_2(aa, bb, c_aptr, c_bptr, aptr, bptr)
+ real(c_float), value, target :: aa, bb
+ type(c_ptr), value :: c_aptr, c_bptr
+ real(c_float), pointer :: aptr, bptr
+
+ real(c_float) :: dummy
+
+ aa = 111.0_c_float
+ bb = 222.0_c_float
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 43
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 44
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_float
+ !$omp target update to(aa)
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 1111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 45
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 46
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_float
+ !$omp target update to(aa)
+ call copy3_scalar(c_loc(aptr), c_loc(bptr))
+ !$omp target update from(bb)
+ if (abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 47
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 48
+ !$omp end target data
+
+ if (abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 49
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 50
+ end subroutine test_dummy_val_callee_2
+end module test_dummies_value
+
+
+
+! Test local dummy arguments + OPTIONAL
+! Values present and ptr associated to nonzero
+module test_dummies_opt
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_opt_call_1, test_dummy_opt_call_2
+contains
+ subroutine test_dummy_opt_call_1()
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_float), target :: aa, bb
+ real(c_float), target, allocatable :: cc, dd
+ real(c_float), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_float), target :: gg(N), hh(N)
+
+ allocate(cc, dd, ee, ff)
+
+ aa = 11.0_c_float
+ bb = 22.0_c_float
+ cc = 33.0_c_float
+ dd = 44.0_c_float
+ ee = 55.0_c_float
+ ff = 66.0_c_float
+ gg = 77.0_c_float
+ hh = 88.0_c_float
+
+ call test_dummy_opt_callee_1(aa, bb, cc, dd, ee, ff, gg, hh, N)
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_dummy_opt_call_1
+
+ subroutine test_dummy_opt_callee_1(aa, bb, cc, dd, ee, ff, gg, hh, N)
+ ! scalars
+ real(c_float), optional, target :: aa, bb
+ real(c_float), optional, target, allocatable :: cc, dd
+ real(c_float), optional, pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_float), optional, target :: gg(N), hh(N)
+ integer, value :: N
+
+ ! All shall be present - and pointing to non-NULL
+ if (.not.present(aa) .or. .not.present(bb)) stop 51
+ if (.not.present(cc) .or. .not.present(dd)) stop 52
+ if (.not.present(ee) .or. .not.present(ff)) stop 53
+ if (.not.present(gg) .or. .not.present(hh)) stop 54
+
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 55
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 56
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 57
+ call copy3_scalar(c_loc(aa), c_loc(bb))
+ !$omp end target data
+ if (abs(aa - 11.0_c_float) > 10.0_c_float * epsilon(aa)) stop 58
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 59
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ if (.not.present(cc) .or. .not.present(dd)) stop 60
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 61
+ call copy3_scalar(c_loc(cc), c_loc(dd))
+ !$omp end target data
+ if (abs(cc - 33.0_c_float) > 10.0_c_float * epsilon(cc)) stop 62
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 63
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 64
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 65
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 66
+ call copy3_scalar(c_loc(ee), c_loc(ff))
+ !$omp end target data
+ if (abs(ee - 55.0_c_float) > 10.0_c_float * epsilon(ee)) stop 67
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 68
+
+ !$omp target data map(to:gg) map(from:hh) use_device_addr(gg,hh)
+ if (.not.present(gg) .or. .not.present(hh)) stop 69
+ if (.not.c_associated(c_loc(gg)) .or. .not.c_associated(c_loc(hh))) stop 70
+ call copy3_array(c_loc(gg), c_loc(hh), N)
+ !$omp end target data
+ if (any(abs(gg - 77.0_c_float) > 10.0_c_float * epsilon(gg))) stop 71
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 72
+ end subroutine test_dummy_opt_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_opt_call_2()
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_float), target :: aa, bb
+ real(c_float), target, allocatable :: cc, dd
+ real(c_float), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_float), target :: gg(N), hh(N)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_float), pointer :: aptr, bptr, cptr, dptr, eptr, fptr
+ real(c_float), pointer :: gptr(:), hptr(:)
+
+ allocate(cc, dd, ee, ff)
+ call test_dummy_opt_callee_2(aa, bb, cc, dd, ee, ff, gg, hh, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, gptr, hptr, &
+ N)
+ deallocate(ee, ff)
+ end subroutine test_dummy_opt_call_2
+
+ subroutine test_dummy_opt_callee_2(aa, bb, cc, dd, ee, ff, gg, hh, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, gptr, hptr, &
+ N)
+ ! scalars
+ real(c_float), optional, target :: aa, bb
+ real(c_float), optional, target, allocatable :: cc, dd
+ real(c_float), optional, pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_float), optional, target :: gg(N), hh(N)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_float), optional, pointer :: aptr, bptr, cptr, dptr, eptr, fptr
+ real(c_float), optional, pointer :: gptr(:), hptr(:)
+
+ integer, value :: N
+
+ real(c_float) :: dummy
+
+ ! All shall be present - and pointing to non-NULL
+ if (.not.present(aa) .or. .not.present(bb)) stop 73
+ if (.not.present(cc) .or. .not.present(dd)) stop 74
+ if (.not.present(ee) .or. .not.present(ff)) stop 75
+ if (.not.present(gg) .or. .not.present(hh)) stop 76
+
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 77
+
+ aa = 111.0_c_float
+ bb = 222.0_c_float
+ cc = 333.0_c_float
+ dd = 444.0_c_float
+ ee = 555.0_c_float
+ ff = 666.0_c_float
+ gg = 777.0_c_float
+ hh = 888.0_c_float
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 78
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 79
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ if (.not.c_associated(c_aptr) .or. .not.c_associated(c_bptr)) stop 80
+ if (.not.associated(aptr) .or. .not.associated(bptr)) stop 81
+ !$omp end target data
+
+ if (.not.present(aa) .or. .not.present(bb)) stop 82
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 83
+ if (.not.c_associated(c_aptr) .or. .not.c_associated(c_bptr)) stop 84
+ if (.not.associated(aptr) .or. .not.associated(bptr)) stop 85
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 86
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 87
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_float
+ !$omp target update to(aa)
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 1111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 88
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 89
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_float
+ !$omp target update to(aa)
+ call copy3_scalar(c_loc(aptr), c_loc(bptr))
+ !$omp target update from(bb)
+ if (abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 90
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 91
+ !$omp end target data
+
+ if (abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 92
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 93
+
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ if (.not.present(cc) .or. .not.present(dd)) stop 94
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 95
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ if (.not.c_associated(c_cptr) .or. .not.c_associated(c_dptr)) stop 96
+ if (.not.associated(cptr) .or. .not.associated(dptr)) stop 97
+ !$omp end target data
+ if (.not.present(cc) .or. .not.present(dd)) stop 98
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 99
+ if (.not.c_associated(c_cptr) .or. .not.c_associated(c_dptr)) stop 100
+ if (.not.associated(cptr) .or. .not.associated(dptr)) stop 101
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 333.0_c_float) > 10.0_c_float * epsilon(cc)) stop 102
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 103
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_float
+ !$omp target update to(cc)
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 3333.0_c_float) > 10.0_c_float * epsilon(cc)) stop 104
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 105
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_float
+ !$omp target update to(cc)
+ call copy3_scalar(c_loc(cptr), c_loc(dptr))
+ !$omp target update from(dd)
+ if (abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(cc)) stop 106
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 107
+ !$omp end target data
+
+ if (abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(dd)) stop 108
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(dd)) stop 109
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 110
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 111
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 112
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ if (.not.c_associated(c_eptr) .or. .not.c_associated(c_fptr)) stop 113
+ if (.not.associated(eptr) .or. .not.associated(fptr)) stop 114
+ !$omp end target data
+ if (.not.present(ee) .or. .not.present(ff)) stop 115
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 116
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 117
+ if (.not.c_associated(c_eptr) .or. .not.c_associated(c_fptr)) stop 118
+ if (.not.associated(eptr) .or. .not.associated(fptr)) stop 119
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 120
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 121
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_float
+ !$omp target update to(ee)
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 5555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 122
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 123
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_float
+ !$omp target update to(ee)
+ call copy3_scalar(c_loc(eptr), c_loc(fptr))
+ !$omp target update from(ff)
+ if (abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 124
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ff)) stop 125
+ !$omp end target data
+
+ if (abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 126
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 127
+
+
+ !$omp target data map(to:gg) map(from:hh)
+ !$omp target data map(alloc:dummy) use_device_addr(gg,hh)
+ if (.not.present(gg) .or. .not.present(hh)) stop 128
+ if (.not.c_associated(c_loc(gg)) .or. .not.c_associated(c_loc(hh))) stop 129
+ c_gptr = c_loc(gg)
+ c_hptr = c_loc(hh)
+ gptr => gg
+ hptr => hh
+ if (.not.c_associated(c_gptr) .or. .not.c_associated(c_hptr)) stop 130
+ if (.not.associated(gptr) .or. .not.associated(hptr)) stop 131
+ !$omp end target data
+ if (.not.present(gg) .or. .not.present(hh)) stop 132
+ if (.not.c_associated(c_loc(gg)) .or. .not.c_associated(c_loc(hh))) stop 133
+ if (.not.c_associated(c_gptr) .or. .not.c_associated(c_hptr)) stop 134
+ if (.not.associated(gptr) .or. .not.associated(hptr)) stop 135
+
+ ! check c_loc ptr once
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 136
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(hh))) stop 137
+
+ ! check c_loc ptr again after target-value modification
+ gg = 7777.0_c_float
+ !$omp target update to(gg)
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 7777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 138
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 139
+
+ ! check Fortran pointer after target-value modification
+ gg = 77777.0_c_float
+ !$omp target update to(gg)
+ call copy3_array(c_loc(gptr), c_loc(hptr), N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 77777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 140
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 141
+ !$omp end target data
+
+ if (any(abs(gg - 77777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 142
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 143
+ end subroutine test_dummy_opt_callee_2
+end module test_dummies_opt
+
+
+
+! Test local dummy arguments + OPTIONAL + VALUE
+! Values present
+module test_dummies_opt_value
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_opt_val_call_1, test_dummy_opt_val_call_2
+contains
+ subroutine test_dummy_opt_val_call_1()
+ ! scalars - with value, neither allocatable nor pointer no dimension permitted
+ real(c_float), target :: aa, bb
+
+ aa = 11.0_c_float
+ bb = 22.0_c_float
+
+ call test_dummy_opt_val_callee_1(aa, bb)
+ end subroutine test_dummy_opt_val_call_1
+
+ subroutine test_dummy_opt_val_callee_1(aa, bb)
+ ! scalars
+ real(c_float), optional, value, target :: aa, bb
+
+ if (.not.present(aa) .or. .not.present(bb)) stop 144
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 145
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 146
+ call copy3_scalar(c_loc(aa), c_loc(bb))
+ !$omp end target data
+ if (abs(aa - 11.0_c_float) > 10.0_c_float * epsilon(aa)) stop 147
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 148
+ end subroutine test_dummy_opt_val_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_opt_val_call_2()
+ ! scalars - with value, neither allocatable nor pointer no dimension permitted
+ real(c_float), target :: aa, bb
+ type(c_ptr) :: c_aptr, c_bptr
+ real(c_float), pointer :: aptr, bptr
+
+ call test_dummy_opt_val_callee_2(aa, bb, c_aptr, c_bptr, aptr, bptr)
+ end subroutine test_dummy_opt_val_call_2
+
+ subroutine test_dummy_opt_val_callee_2(aa, bb, c_aptr, c_bptr, aptr, bptr)
+ real(c_float), optional, value, target :: aa, bb
+ type(c_ptr), optional, value :: c_aptr, c_bptr
+ real(c_float), optional, pointer :: aptr, bptr
+
+ real(c_float) :: dummy
+
+ if (.not.present(aa) .or. .not.present(bb)) stop 149
+ if (.not.present(c_aptr) .or. .not.present(c_bptr)) stop 150
+ if (.not.present(aptr) .or. .not.present(bptr)) stop 151
+
+ aa = 111.0_c_float
+ bb = 222.0_c_float
+
+ !$omp target data map(to:aa) map(from:bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 152
+ if (.not.present(c_aptr) .or. .not.present(c_bptr)) stop 153
+ if (.not.present(aptr) .or. .not.present(bptr)) stop 154
+
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 155
+ if (.not.present(c_aptr) .or. .not.present(c_bptr)) stop 156
+ if (.not.present(aptr) .or. .not.present(bptr)) stop 157
+
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ if (.not.c_associated(c_aptr) .or. .not.c_associated(c_bptr)) stop 158
+ if (.not.associated(aptr) .or. .not.associated(bptr)) stop 159
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 160
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 161
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_float
+ !$omp target update to(aa)
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 1111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 162
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 163
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_float
+ !$omp target update to(aa)
+ call copy3_scalar(c_loc(aptr), c_loc(bptr))
+ !$omp target update from(bb)
+ if (abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 164
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 165
+ !$omp end target data
+
+ if (abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 166
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 167
+ end subroutine test_dummy_opt_val_callee_2
+end module test_dummies_opt_value
+
+
+
+! Test nullptr
+module test_nullptr
+ use iso_c_binding
+ implicit none (type, external)
+ private
+ public :: test_nullptr_1
+contains
+ subroutine test_nullptr_1()
+ ! scalars
+ real(c_float), pointer :: aa, bb
+ real(c_float), pointer :: ee, ff
+
+ real(c_float), allocatable, target :: gg, hh
+
+ type(c_ptr) :: c_aptr, c_bptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_float), pointer :: aptr, bptr, eptr, fptr, gptr, hptr
+
+ aa => null()
+ bb => null()
+ ee => null()
+ ff => null()
+
+ if (associated(aa) .or. associated(bb)) stop 168
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ if (c_associated(c_loc(aa)) .or. c_associated(c_loc(bb))) stop 169
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ if (c_associated(c_aptr) .or. c_associated(c_bptr)) stop 170
+ if (associated(aptr) .or. associated(bptr, bb)) stop 171
+ !$omp end target data
+ if (c_associated(c_aptr) .or. c_associated(c_bptr)) stop 172
+ if (associated(aptr) .or. associated(bptr, bb)) stop 173
+
+ if (allocated(gg)) stop 174
+ !$omp target data map(tofrom:gg) use_device_addr(gg)
+ if (c_associated(c_loc(gg))) stop 175
+ c_gptr = c_loc(gg)
+ gptr => gg
+ if (c_associated(c_gptr)) stop 176
+ if (associated(gptr)) stop 177
+ if (allocated(gg)) stop 178
+ !$omp end target data
+ if (c_associated(c_gptr)) stop 179
+ if (associated(gptr)) stop 180
+ if (allocated(gg)) stop 181
+
+ call test_dummy_opt_nullptr_callee_1(ee, ff, hh, c_eptr, c_fptr, c_hptr, eptr, fptr, hptr)
+ end subroutine test_nullptr_1
+
+ subroutine test_dummy_opt_nullptr_callee_1(ee, ff, hh, c_eptr, c_fptr, c_hptr, eptr, fptr, hptr)
+ ! scalars
+ real(c_float), optional, pointer :: ee, ff
+ real(c_float), optional, allocatable, target :: hh
+
+ type(c_ptr), optional :: c_eptr, c_fptr, c_hptr
+ real(c_float), optional, pointer :: eptr, fptr, hptr
+
+ if (.not.present(ee) .or. .not.present(ff)) stop 182
+ if (associated(ee) .or. associated(ff)) stop 183
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 184
+ if (associated(ee) .or. associated(ff)) stop 185
+ if (c_associated(c_loc(ee)) .or. c_associated(c_loc(ff))) stop 186
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ if (c_associated(c_eptr) .or. c_associated(c_fptr)) stop 187
+ if (associated(eptr) .or. associated(fptr)) stop 188
+ !$omp end target data
+
+ if (c_associated(c_eptr) .or. c_associated(c_fptr)) stop 189
+ if (associated(eptr) .or. associated(fptr)) stop 190
+ if (associated(ee) .or. associated(ff)) stop 191
+
+
+ if (.not.present(hh)) stop 192
+ if (allocated(hh)) stop 193
+
+ !$omp target data map(tofrom:hh) use_device_addr(hh)
+ if (.not.present(hh)) stop 194
+ if (allocated(hh)) stop 195
+ if (c_associated(c_loc(hh))) stop 196
+ c_hptr = c_loc(hh)
+ hptr => hh
+ if (c_associated(c_hptr)) stop 197
+ if (associated(hptr)) stop 198
+ if (allocated(hh)) stop 199
+ !$omp end target data
+
+ if (c_associated(c_hptr)) stop 200
+ if (associated(hptr)) stop 201
+ if (allocated(hh)) stop 202
+ end subroutine test_dummy_opt_nullptr_callee_1
+end module test_nullptr
+
+
+
+! Test local variables
+module tests
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_main_1, test_main_2
+contains
+ ! map + use_device_addr + c_loc
+ subroutine test_main_1()
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_float), target :: aa, bb
+ real(c_float), target, allocatable :: cc, dd
+ real(c_float), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_float), target :: gg(N), hh(N)
+
+ allocate(cc, dd, ee, ff)
+
+
+ aa = 11.0_c_float
+ bb = 22.0_c_float
+ cc = 33.0_c_float
+ dd = 44.0_c_float
+ ee = 55.0_c_float
+ ff = 66.0_c_float
+ gg = 77.0_c_float
+ hh = 88.0_c_float
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ call copy3_scalar(c_loc(aa), c_loc(bb))
+ !$omp end target data
+ if (abs(aa - 11.0_c_float) > 10.0_c_float * epsilon(aa)) stop 203
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 204
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ call copy3_scalar(c_loc(cc), c_loc(dd))
+ !$omp end target data
+ if (abs(cc - 33.0_c_float) > 10.0_c_float * epsilon(cc)) stop 205
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 206
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ call copy3_scalar(c_loc(ee), c_loc(ff))
+ !$omp end target data
+ if (abs(ee - 55.0_c_float) > 10.0_c_float * epsilon(ee)) stop 207
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 208
+
+
+ !$omp target data map(to:gg) map(from:hh) use_device_addr(gg,hh)
+ call copy3_array(c_loc(gg), c_loc(hh), N)
+ !$omp end target data
+ if (any(abs(gg - 77.0_c_float) > 10.0_c_float * epsilon(gg))) stop 209
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 210
+
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_main_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_main_2
+ integer, parameter :: N = 1000
+
+ ! scalars
+ real(c_float), target :: aa, bb
+ real(c_float), target, allocatable :: cc, dd
+ real(c_float), pointer :: ee, ff
+
+ ! non-descriptor arrays
+ real(c_float), target :: gg(N), hh(N)
+
+ real(c_float) :: dummy
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_float), pointer :: aptr, bptr, cptr, dptr, eptr, fptr
+ real(c_float), pointer :: gptr(:), hptr(:)
+
+ allocate(cc, dd, ee, ff)
+
+ aa = 111.0_c_float
+ bb = 222.0_c_float
+ cc = 333.0_c_float
+ dd = 444.0_c_float
+ ee = 555.0_c_float
+ ff = 666.0_c_float
+ gg = 777.0_c_float
+ hh = 888.0_c_float
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 211
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 212
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_float
+ !$omp target update to(aa)
+ call copy3_scalar(c_aptr, c_bptr)
+ !$omp target update from(bb)
+ if (abs(aa - 1111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 213
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 214
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_float
+ !$omp target update to(aa)
+ call copy3_scalar(c_loc(aptr), c_loc(bptr))
+ !$omp target update from(bb)
+ if (abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 215
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 216
+ !$omp end target data
+
+ if (abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa)) stop 217
+ if (abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa)) stop 218
+
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 333.0_c_float) > 10.0_c_float * epsilon(cc)) stop 219
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 220
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_float
+ !$omp target update to(cc)
+ call copy3_scalar(c_cptr, c_dptr)
+ !$omp target update from(dd)
+ if (abs(cc - 3333.0_c_float) > 10.0_c_float * epsilon(cc)) stop 221
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 222
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_float
+ !$omp target update to(cc)
+ call copy3_scalar(c_loc(cptr), c_loc(dptr))
+ !$omp target update from(dd)
+ if (abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(cc)) stop 223
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc)) stop 224
+ !$omp end target data
+
+ if (abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(dd)) stop 225
+ if (abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(dd)) stop 226
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 227
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 228
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_float
+ !$omp target update to(ee)
+ call copy3_scalar(c_eptr, c_fptr)
+ !$omp target update from(ff)
+ if (abs(ee - 5555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 229
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 230
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_float
+ !$omp target update to(ee)
+ call copy3_scalar(c_loc(eptr), c_loc(fptr))
+ !$omp target update from(ff)
+ if (abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 231
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ff)) stop 232
+ !$omp end target data
+
+ if (abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee)) stop 233
+ if (abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee)) stop 234
+
+
+ !$omp target data map(to:gg) map(from:hh)
+ !$omp target data map(alloc:dummy) use_device_addr(gg,hh)
+ c_gptr = c_loc(gg)
+ c_hptr = c_loc(hh)
+ gptr => gg
+ hptr => hh
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 235
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(hh))) stop 236
+
+ ! check c_loc ptr again after target-value modification
+ gg = 7777.0_c_float
+ !$omp target update to(gg)
+ call copy3_array(c_gptr, c_hptr, N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 7777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 237
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 238
+
+ ! check Fortran pointer after target-value modification
+ gg = 77777.0_c_float
+ !$omp target update to(gg)
+ call copy3_array(c_loc(gptr), c_loc(hptr), N)
+ !$omp target update from(hh)
+ if (any(abs(gg - 77777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 239
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 240
+ !$omp end target data
+
+ if (any(abs(gg - 77777.0_c_float) > 10.0_c_float * epsilon(gg))) stop 241
+ if (any(abs(3.0_c_float * gg - hh) > 10.0_c_float * epsilon(gg))) stop 242
+
+ deallocate(ee, ff)
+ end subroutine test_main_2
+end module tests
+
+
+program omp_device_addr
+ use tests
+ use test_dummies
+ use test_dummies_value
+ use test_dummies_opt
+ use test_dummies_opt_value
+ use test_nullptr
+ implicit none (type, external)
+
+ call test_main_1()
+ call test_main_2()
+
+ call test_dummy_call_1()
+ call test_dummy_call_2()
+
+ call test_dummy_val_call_1()
+ call test_dummy_val_call_2()
+
+ call test_dummy_opt_call_1()
+ call test_dummy_opt_call_2()
+
+ call test_dummy_opt_val_call_1()
+ call test_dummy_opt_val_call_2()
+
+ call test_nullptr_1()
+end program omp_device_addr
diff --git a/libgomp/testsuite/libgomp.fortran/use_device_addr-3.f90 b/libgomp/testsuite/libgomp.fortran/use_device_addr-3.f90
new file mode 100644
index 00000000000..5c42bee718c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/use_device_addr-3.f90
@@ -0,0 +1,765 @@
+! { dg-do run }
+
+! Comprehensive run-time test for use_device_addr
+!
+! Tests array with array descriptor
+!
+! Differs from use_device_addr-4.f90 by using a 8-byte variable (c_double)
+!
+! This test case assumes that a 'var' appearing in 'use_device_addr' is
+! only used as 'c_loc(var)' - such that only the actual data is used/usable
+! on the device - and not meta data ((dynamic) type information, 'present()'
+! status, array shape).
+!
+! Untested in this test case are:
+! - scalars
+! - polymorphic variables
+! - absent optional arguments
+!
+module target_procs
+ use iso_c_binding
+ implicit none (type, external)
+ private
+ public :: copy3_array
+contains
+ subroutine copy3_array_int(from_ptr, to_ptr, N)
+ !$omp declare target
+ real(c_double) :: from_ptr(:)
+ real(c_double) :: to_ptr(:)
+ integer, value :: N
+ integer :: i
+
+ !$omp parallel do
+ do i = 1, N
+ to_ptr(i) = 3 * from_ptr(i)
+ end do
+ !$omp end parallel do
+ end subroutine copy3_array_int
+
+ subroutine copy3_array(from, to, N)
+ type(c_ptr), value :: from, to
+ integer, value :: N
+ real(c_double), pointer :: from_ptr(:), to_ptr(:)
+
+ call c_f_pointer(from, from_ptr, shape=[N])
+ call c_f_pointer(to, to_ptr, shape=[N])
+
+ call do_offload_scalar(from_ptr,to_ptr)
+ contains
+ subroutine do_offload_scalar(from_r, to_r)
+ real(c_double), target :: from_r(:), to_r(:)
+ ! The extra function is needed as is_device_ptr
+ ! requires non-value, non-pointer dummy arguments
+
+ !$omp target is_device_ptr(from_r, to_r)
+ call copy3_array_int(from_r, to_r, N)
+ !$omp end target
+ end subroutine do_offload_scalar
+ end subroutine copy3_array
+end module target_procs
+
+
+
+! Test local dummy arguments (w/o optional)
+module test_dummies
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_call_1, test_dummy_call_2
+contains
+ subroutine test_dummy_call_1()
+ integer, parameter :: N = 1000
+
+ real(c_double), target :: aa(N), bb(N)
+ real(c_double), target, allocatable :: cc(:), dd(:)
+ real(c_double), pointer :: ee(:), ff(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+
+ aa = 11.0_c_double
+ bb = 22.0_c_double
+ cc = 33.0_c_double
+ dd = 44.0_c_double
+ ee = 55.0_c_double
+ ff = 66.0_c_double
+
+ call test_dummy_callee_1(aa, bb, cc, dd, ee, ff, N)
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_dummy_call_1
+
+ subroutine test_dummy_callee_1(aa, bb, cc, dd, ee, ff, N)
+ real(c_double), target :: aa(:), bb(:)
+ real(c_double), target, allocatable :: cc(:), dd(:)
+ real(c_double), pointer :: ee(:), ff(:)
+
+ integer, value :: N
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ call copy3_array(c_loc(aa), c_loc(bb), N)
+ !$omp end target data
+ if (any(abs(aa - 11.0_c_double) > 10.0_c_double * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa))) stop 1
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ call copy3_array(c_loc(cc), c_loc(dd), N)
+ !$omp end target data
+ if (any(abs(cc - 33.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ call copy3_array(c_loc(ee), c_loc(ff), N)
+ !$omp end target data
+ if (any(abs(ee - 55.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+ end subroutine test_dummy_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_call_2()
+ integer, parameter :: N = 1000
+
+ real(c_double), target :: aa(N), bb(N)
+ real(c_double), target, allocatable :: cc(:), dd(:)
+ real(c_double), pointer :: ee(:), ff(:)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr
+ real(c_double), pointer :: aptr(:), bptr(:), cptr(:), dptr(:), eptr(:), fptr(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+
+ call test_dummy_callee_2(aa, bb, cc, dd, ee, ff, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, &
+ N)
+ deallocate(ee, ff)
+ end subroutine test_dummy_call_2
+
+ subroutine test_dummy_callee_2(aa, bb, cc, dd, ee, ff, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, &
+ N)
+ real(c_double), target :: aa(:), bb(:)
+ real(c_double), target, allocatable :: cc(:), dd(:)
+ real(c_double), pointer :: ee(:), ff(:)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr
+ real(c_double), pointer :: aptr(:), bptr(:), cptr(:), dptr(:), eptr(:), fptr(:)
+
+ integer, value :: N
+
+ real(c_double) :: dummy
+
+ aa = 111.0_c_double
+ bb = 222.0_c_double
+ cc = 333.0_c_double
+ dd = 444.0_c_double
+ ee = 555.0_c_double
+ ff = 666.0_c_double
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_aptr, c_bptr, N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 111.0_c_double) > 10.0_c_double * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_double
+ !$omp target update to(aa)
+ call copy3_array(c_aptr, c_bptr, N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 1111.0_c_double) > 10.0_c_double * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_double
+ !$omp target update to(aa)
+ call copy3_array(c_loc(aptr), c_loc(bptr), N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa))) stop 1
+ !$omp end target data
+
+ if (any(abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa))) stop 1
+
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 333.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_double
+ !$omp target update to(cc)
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 3333.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_double
+ !$omp target update to(cc)
+ call copy3_array(c_loc(cptr), c_loc(dptr), N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+ !$omp end target data
+
+ if (any(abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(dd))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(dd))) stop 1
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_double
+ !$omp target update to(ee)
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 5555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_double
+ !$omp target update to(ee)
+ call copy3_array(c_loc(eptr), c_loc(fptr), N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ff))) stop 1
+ !$omp end target data
+
+ if (any(abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+ end subroutine test_dummy_callee_2
+end module test_dummies
+
+
+
+! Test local dummy arguments + OPTIONAL
+! Values present and ptr associated to nonzero
+module test_dummies_opt
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_opt_call_1, test_dummy_opt_call_2
+contains
+ subroutine test_dummy_opt_call_1()
+ integer, parameter :: N = 1000
+
+ real(c_double), target :: aa(N), bb(N)
+ real(c_double), target, allocatable :: cc(:), dd(:)
+ real(c_double), pointer :: ee(:), ff(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+
+ aa = 11.0_c_double
+ bb = 22.0_c_double
+ cc = 33.0_c_double
+ dd = 44.0_c_double
+ ee = 55.0_c_double
+ ff = 66.0_c_double
+
+ call test_dummy_opt_callee_1(aa, bb, cc, dd, ee, ff, N)
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_dummy_opt_call_1
+
+ subroutine test_dummy_opt_callee_1(aa, bb, cc, dd, ee, ff, N)
+ ! scalars
+ real(c_double), optional, target :: aa(:), bb(:)
+ real(c_double), optional, target, allocatable :: cc(:), dd(:)
+ real(c_double), optional, pointer :: ee(:), ff(:)
+
+ integer, value :: N
+
+ ! All shall be present - and pointing to non-NULL
+ if (.not.present(aa) .or. .not.present(bb)) stop 1
+ if (.not.present(cc) .or. .not.present(dd)) stop 1
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+
+ if (.not.allocated(cc) .or. .not.allocated(dd)) stop 1
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 1
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 1
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 1
+ call copy3_array(c_loc(aa), c_loc(bb), N)
+ !$omp end target data
+ if (any(abs(aa - 11.0_c_double) > 10.0_c_double * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa))) stop 1
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ if (.not.present(cc) .or. .not.present(dd)) stop 1
+ if (.not.allocated(cc) .or. .not.allocated(dd)) stop 1
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 1
+ call copy3_array(c_loc(cc), c_loc(dd), N)
+ !$omp end target data
+ if (any(abs(cc - 33.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 1
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 1
+ call copy3_array(c_loc(ee), c_loc(ff), N)
+ !$omp end target data
+ if (any(abs(ee - 55.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+ end subroutine test_dummy_opt_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_opt_call_2()
+ integer, parameter :: N = 1000
+
+ real(c_double), target :: aa(N), bb(N)
+ real(c_double), target, allocatable :: cc(:), dd(:)
+ real(c_double), pointer :: ee(:), ff(:)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr
+ real(c_double), pointer :: aptr(:), bptr(:), cptr(:), dptr(:), eptr(:), fptr(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+ call test_dummy_opt_callee_2(aa, bb, cc, dd, ee, ff, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, &
+ N)
+ deallocate(ee, ff)
+ end subroutine test_dummy_opt_call_2
+
+ subroutine test_dummy_opt_callee_2(aa, bb, cc, dd, ee, ff, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, &
+ N)
+ ! scalars
+ real(c_double), optional, target :: aa(:), bb(:)
+ real(c_double), optional, target, allocatable :: cc(:), dd(:)
+ real(c_double), optional, pointer :: ee(:), ff(:)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr
+ real(c_double), optional, pointer :: aptr(:), bptr(:), cptr(:), dptr(:), eptr(:), fptr(:)
+
+ integer, value :: N
+
+ real(c_double) :: dummy
+
+ ! All shall be present - and pointing to non-NULL
+ if (.not.present(aa) .or. .not.present(bb)) stop 1
+ if (.not.present(cc) .or. .not.present(dd)) stop 1
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+
+ if (.not.allocated(cc) .or. .not.allocated(dd)) stop 1
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 1
+
+ aa = 111.0_c_double
+ bb = 222.0_c_double
+ cc = 333.0_c_double
+ dd = 444.0_c_double
+ ee = 555.0_c_double
+ ff = 666.0_c_double
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 1
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 1
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ if (.not.c_associated(c_aptr) .or. .not.c_associated(c_bptr)) stop 1
+ if (.not.associated(aptr) .or. .not.associated(bptr)) stop 1
+ !$omp end target data
+
+ if (.not.present(aa) .or. .not.present(bb)) stop 1
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 1
+ if (.not.c_associated(c_aptr) .or. .not.c_associated(c_bptr)) stop 1
+ if (.not.associated(aptr) .or. .not.associated(bptr)) stop 1
+
+ ! check c_loc ptr once
+ call copy3_array(c_aptr, c_bptr, N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 111.0_c_double) > 10.0_c_double * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_double
+ !$omp target update to(aa)
+ call copy3_array(c_aptr, c_bptr, N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 1111.0_c_double) > 10.0_c_double * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_double
+ !$omp target update to(aa)
+ call copy3_array(c_loc(aptr), c_loc(bptr), N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa))) stop 1
+ !$omp end target data
+
+ if (any(abs(aa - 11111.0_c_double) > 10.0_c_double * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_double * aa - bb) > 10.0_c_double * epsilon(aa))) stop 1
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ if (.not.present(cc) .or. .not.present(dd)) stop 1
+ if (.not.allocated(cc) .or. .not.allocated(dd)) stop 1
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 1
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ if (.not.c_associated(c_cptr) .or. .not.c_associated(c_dptr)) stop 1
+ if (.not.associated(cptr) .or. .not.associated(dptr)) stop 1
+ !$omp end target data
+ if (.not.present(cc) .or. .not.present(dd)) stop 1
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 1
+ if (.not.c_associated(c_cptr) .or. .not.c_associated(c_dptr)) stop 1
+ if (.not.associated(cptr) .or. .not.associated(dptr)) stop 1
+
+ ! check c_loc ptr once
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 333.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_double
+ !$omp target update to(cc)
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 3333.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_double
+ !$omp target update to(cc)
+ call copy3_array(c_loc(cptr), c_loc(dptr), N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+ !$omp end target data
+
+ if (any(abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(dd))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(dd))) stop 1
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 1
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 1
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ if (.not.c_associated(c_eptr) .or. .not.c_associated(c_fptr)) stop 1
+ if (.not.associated(eptr) .or. .not.associated(fptr)) stop 1
+ !$omp end target data
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 1
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 1
+ if (.not.c_associated(c_eptr) .or. .not.c_associated(c_fptr)) stop 1
+ if (.not.associated(eptr) .or. .not.associated(fptr)) stop 1
+
+ ! check c_loc ptr once
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_double
+ !$omp target update to(ee)
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 5555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_double
+ !$omp target update to(ee)
+ call copy3_array(c_loc(eptr), c_loc(fptr), N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ff))) stop 1
+ !$omp end target data
+
+ if (any(abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+ end subroutine test_dummy_opt_callee_2
+end module test_dummies_opt
+
+
+
+! Test nullptr
+module test_nullptr
+ use iso_c_binding
+ implicit none (type, external)
+ private
+ public :: test_nullptr_1
+contains
+ subroutine test_nullptr_1()
+ real(c_double), pointer :: aa(:), bb(:)
+ real(c_double), pointer :: ee(:), ff(:)
+
+ real(c_double), allocatable, target :: gg(:), hh(:)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_double), pointer :: aptr(:), bptr(:), eptr(:), fptr(:), gptr(:), hptr(:)
+
+ aa => null()
+ bb => null()
+ ee => null()
+ ff => null()
+
+ if (associated(aa) .or. associated(bb)) stop 1
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ if (c_associated(c_loc(aa)) .or. c_associated(c_loc(bb))) stop 1
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ if (c_associated(c_aptr) .or. c_associated(c_bptr)) stop 1
+ if (associated(aptr) .or. associated(bptr, bb)) stop 1
+ if (associated(aa) .or. associated(bb)) stop 1
+ !$omp end target data
+ if (c_associated(c_aptr) .or. c_associated(c_bptr)) stop 1
+ if (associated(aptr) .or. associated(bptr, bb)) stop 1
+ if (associated(aa) .or. associated(bb)) stop 1
+
+ if (allocated(gg)) stop 1
+ !$omp target data map(tofrom:gg) use_device_addr(gg)
+ if (c_associated(c_loc(gg))) stop 1
+ c_gptr = c_loc(gg)
+ gptr => gg
+ if (c_associated(c_gptr)) stop 1
+ if (associated(gptr)) stop 1
+ if (allocated(gg)) stop 1
+ !$omp end target data
+ if (c_associated(c_gptr)) stop 1
+ if (associated(gptr)) stop 1
+ if (allocated(gg)) stop 1
+
+ call test_dummy_opt_nullptr_callee_1(ee, ff, hh, c_eptr, c_fptr, c_hptr, eptr, fptr, hptr)
+ end subroutine test_nullptr_1
+
+ subroutine test_dummy_opt_nullptr_callee_1(ee, ff, hh, c_eptr, c_fptr, c_hptr, eptr, fptr, hptr)
+ ! scalars
+ real(c_double), optional, pointer :: ee(:), ff(:)
+ real(c_double), optional, allocatable, target :: hh(:)
+
+ type(c_ptr), optional :: c_eptr, c_fptr, c_hptr
+ real(c_double), optional, pointer :: eptr(:), fptr(:), hptr(:)
+
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+ if (associated(ee) .or. associated(ff)) stop 1
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+ if (associated(ee) .or. associated(ff)) stop 1
+ if (c_associated(c_loc(ee)) .or. c_associated(c_loc(ff))) stop 1
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ if (c_associated(c_eptr) .or. c_associated(c_fptr)) stop 1
+ if (associated(eptr) .or. associated(fptr)) stop 1
+ !$omp end target data
+
+ if (c_associated(c_eptr) .or. c_associated(c_fptr)) stop 1
+ if (associated(eptr) .or. associated(fptr)) stop 1
+
+ if (allocated(hh)) stop 1
+ !$omp target data map(tofrom:hh) use_device_addr(hh)
+ if (c_associated(c_loc(hh))) stop 1
+ c_hptr = c_loc(hh)
+ hptr => hh
+ if (c_associated(c_hptr)) stop 1
+ if (associated(hptr)) stop 1
+ if (allocated(hh)) stop 1
+ !$omp end target data
+ if (c_associated(c_hptr)) stop 1
+ if (associated(hptr)) stop 1
+ if (allocated(hh)) stop 1
+ end subroutine test_dummy_opt_nullptr_callee_1
+end module test_nullptr
+
+
+
+! Test local variables
+module tests
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_main_1, test_main_2
+contains
+ ! map + use_device_addr + c_loc
+ subroutine test_main_1()
+ integer, parameter :: N = 1000
+
+ real(c_double), target, allocatable :: cc(:), dd(:)
+ real(c_double), pointer :: ee(:), ff(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+
+ cc = 33.0_c_double
+ dd = 44.0_c_double
+ ee = 55.0_c_double
+ ff = 66.0_c_double
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ call copy3_array(c_loc(cc), c_loc(dd), N)
+ !$omp end target data
+ if (any(abs(cc - 33.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ call copy3_array(c_loc(ee), c_loc(ff), N)
+ !$omp end target data
+ if (any(abs(ee - 55.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_main_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_main_2
+ integer, parameter :: N = 1000
+
+ real(c_double), target, allocatable :: cc(:), dd(:)
+ real(c_double), pointer :: ee(:), ff(:)
+
+ real(c_double) :: dummy
+ type(c_ptr) :: c_cptr, c_dptr, c_eptr, c_fptr
+ real(c_double), pointer :: cptr(:), dptr(:), eptr(:), fptr(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+
+ cc = 333.0_c_double
+ dd = 444.0_c_double
+ ee = 555.0_c_double
+ ff = 666.0_c_double
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 333.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_double
+ !$omp target update to(cc)
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 3333.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_double
+ !$omp target update to(cc)
+ call copy3_array(c_loc(cptr), c_loc(dptr), N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(cc))) stop 1
+ !$omp end target data
+
+ if (any(abs(cc - 33333.0_c_double) > 10.0_c_double * epsilon(dd))) stop 1
+ if (any(abs(3.0_c_double * cc - dd) > 10.0_c_double * epsilon(dd))) stop 1
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_double
+ !$omp target update to(ee)
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 5555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_double
+ !$omp target update to(ee)
+ call copy3_array(c_loc(eptr), c_loc(fptr), N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ff))) stop 1
+ !$omp end target data
+
+ if (any(abs(ee - 55555.0_c_double) > 10.0_c_double * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_double * ee - ff) > 10.0_c_double * epsilon(ee))) stop 1
+
+ deallocate(ee, ff)
+ end subroutine test_main_2
+end module tests
+
+
+program omp_device_addr
+ use tests
+ use test_dummies
+ use test_dummies_opt
+ use test_nullptr
+ implicit none (type, external)
+
+ call test_main_1()
+ call test_main_2()
+
+ call test_dummy_call_1()
+ call test_dummy_call_2()
+
+ call test_dummy_opt_call_1()
+ call test_dummy_opt_call_2()
+
+ call test_nullptr_1()
+end program omp_device_addr
diff --git a/libgomp/testsuite/libgomp.fortran/use_device_addr-4.f90 b/libgomp/testsuite/libgomp.fortran/use_device_addr-4.f90
new file mode 100644
index 00000000000..5e66a79da90
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/use_device_addr-4.f90
@@ -0,0 +1,765 @@
+! { dg-do run }
+
+! Comprehensive run-time test for use_device_addr
+!
+! Tests array with array descriptor
+!
+! Differs from use_device_addr-3.f90 by using a 4-byte variable (c_float)
+!
+! This test case assumes that a 'var' appearing in 'use_device_addr' is
+! only used as 'c_loc(var)' - such that only the actual data is used/usable
+! on the device - and not meta data ((dynamic) type information, 'present()'
+! status, array shape).
+!
+! Untested in this test case are:
+! - scalars
+! - polymorphic variables
+! - absent optional arguments
+!
+module target_procs
+ use iso_c_binding
+ implicit none (type, external)
+ private
+ public :: copy3_array
+contains
+ subroutine copy3_array_int(from_ptr, to_ptr, N)
+ !$omp declare target
+ real(c_float) :: from_ptr(:)
+ real(c_float) :: to_ptr(:)
+ integer, value :: N
+ integer :: i
+
+ !$omp parallel do
+ do i = 1, N
+ to_ptr(i) = 3 * from_ptr(i)
+ end do
+ !$omp end parallel do
+ end subroutine copy3_array_int
+
+ subroutine copy3_array(from, to, N)
+ type(c_ptr), value :: from, to
+ integer, value :: N
+ real(c_float), pointer :: from_ptr(:), to_ptr(:)
+
+ call c_f_pointer(from, from_ptr, shape=[N])
+ call c_f_pointer(to, to_ptr, shape=[N])
+
+ call do_offload_scalar(from_ptr,to_ptr)
+ contains
+ subroutine do_offload_scalar(from_r, to_r)
+ real(c_float), target :: from_r(:), to_r(:)
+ ! The extra function is needed as is_device_ptr
+ ! requires non-value, non-pointer dummy arguments
+
+ !$omp target is_device_ptr(from_r, to_r)
+ call copy3_array_int(from_r, to_r, N)
+ !$omp end target
+ end subroutine do_offload_scalar
+ end subroutine copy3_array
+end module target_procs
+
+
+
+! Test local dummy arguments (w/o optional)
+module test_dummies
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_call_1, test_dummy_call_2
+contains
+ subroutine test_dummy_call_1()
+ integer, parameter :: N = 1000
+
+ real(c_float), target :: aa(N), bb(N)
+ real(c_float), target, allocatable :: cc(:), dd(:)
+ real(c_float), pointer :: ee(:), ff(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+
+ aa = 11.0_c_float
+ bb = 22.0_c_float
+ cc = 33.0_c_float
+ dd = 44.0_c_float
+ ee = 55.0_c_float
+ ff = 66.0_c_float
+
+ call test_dummy_callee_1(aa, bb, cc, dd, ee, ff, N)
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_dummy_call_1
+
+ subroutine test_dummy_callee_1(aa, bb, cc, dd, ee, ff, N)
+ real(c_float), target :: aa(:), bb(:)
+ real(c_float), target, allocatable :: cc(:), dd(:)
+ real(c_float), pointer :: ee(:), ff(:)
+
+ integer, value :: N
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ call copy3_array(c_loc(aa), c_loc(bb), N)
+ !$omp end target data
+ if (any(abs(aa - 11.0_c_float) > 10.0_c_float * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa))) stop 1
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ call copy3_array(c_loc(cc), c_loc(dd), N)
+ !$omp end target data
+ if (any(abs(cc - 33.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ call copy3_array(c_loc(ee), c_loc(ff), N)
+ !$omp end target data
+ if (any(abs(ee - 55.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+ end subroutine test_dummy_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_call_2()
+ integer, parameter :: N = 1000
+
+ real(c_float), target :: aa(N), bb(N)
+ real(c_float), target, allocatable :: cc(:), dd(:)
+ real(c_float), pointer :: ee(:), ff(:)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr
+ real(c_float), pointer :: aptr(:), bptr(:), cptr(:), dptr(:), eptr(:), fptr(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+
+ call test_dummy_callee_2(aa, bb, cc, dd, ee, ff, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, &
+ N)
+ deallocate(ee, ff)
+ end subroutine test_dummy_call_2
+
+ subroutine test_dummy_callee_2(aa, bb, cc, dd, ee, ff, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, &
+ N)
+ real(c_float), target :: aa(:), bb(:)
+ real(c_float), target, allocatable :: cc(:), dd(:)
+ real(c_float), pointer :: ee(:), ff(:)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr
+ real(c_float), pointer :: aptr(:), bptr(:), cptr(:), dptr(:), eptr(:), fptr(:)
+
+ integer, value :: N
+
+ real(c_float) :: dummy
+
+ aa = 111.0_c_float
+ bb = 222.0_c_float
+ cc = 333.0_c_float
+ dd = 444.0_c_float
+ ee = 555.0_c_float
+ ff = 666.0_c_float
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_aptr, c_bptr, N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 111.0_c_float) > 10.0_c_float * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_float
+ !$omp target update to(aa)
+ call copy3_array(c_aptr, c_bptr, N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 1111.0_c_float) > 10.0_c_float * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_float
+ !$omp target update to(aa)
+ call copy3_array(c_loc(aptr), c_loc(bptr), N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa))) stop 1
+ !$omp end target data
+
+ if (any(abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa))) stop 1
+
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 333.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_float
+ !$omp target update to(cc)
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 3333.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_float
+ !$omp target update to(cc)
+ call copy3_array(c_loc(cptr), c_loc(dptr), N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+ !$omp end target data
+
+ if (any(abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(dd))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(dd))) stop 1
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_float
+ !$omp target update to(ee)
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 5555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_float
+ !$omp target update to(ee)
+ call copy3_array(c_loc(eptr), c_loc(fptr), N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ff))) stop 1
+ !$omp end target data
+
+ if (any(abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+ end subroutine test_dummy_callee_2
+end module test_dummies
+
+
+
+! Test local dummy arguments + OPTIONAL
+! Values present and ptr associated to nonzero
+module test_dummies_opt
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_dummy_opt_call_1, test_dummy_opt_call_2
+contains
+ subroutine test_dummy_opt_call_1()
+ integer, parameter :: N = 1000
+
+ real(c_float), target :: aa(N), bb(N)
+ real(c_float), target, allocatable :: cc(:), dd(:)
+ real(c_float), pointer :: ee(:), ff(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+
+ aa = 11.0_c_float
+ bb = 22.0_c_float
+ cc = 33.0_c_float
+ dd = 44.0_c_float
+ ee = 55.0_c_float
+ ff = 66.0_c_float
+
+ call test_dummy_opt_callee_1(aa, bb, cc, dd, ee, ff, N)
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_dummy_opt_call_1
+
+ subroutine test_dummy_opt_callee_1(aa, bb, cc, dd, ee, ff, N)
+ ! scalars
+ real(c_float), optional, target :: aa(:), bb(:)
+ real(c_float), optional, target, allocatable :: cc(:), dd(:)
+ real(c_float), optional, pointer :: ee(:), ff(:)
+
+ integer, value :: N
+
+ ! All shall be present - and pointing to non-NULL
+ if (.not.present(aa) .or. .not.present(bb)) stop 1
+ if (.not.present(cc) .or. .not.present(dd)) stop 1
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+
+ if (.not.allocated(cc) .or. .not.allocated(dd)) stop 1
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 1
+
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 1
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 1
+ call copy3_array(c_loc(aa), c_loc(bb), N)
+ !$omp end target data
+ if (any(abs(aa - 11.0_c_float) > 10.0_c_float * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa))) stop 1
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ if (.not.present(cc) .or. .not.present(dd)) stop 1
+ if (.not.allocated(cc) .or. .not.allocated(dd)) stop 1
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 1
+ call copy3_array(c_loc(cc), c_loc(dd), N)
+ !$omp end target data
+ if (any(abs(cc - 33.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 1
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 1
+ call copy3_array(c_loc(ee), c_loc(ff), N)
+ !$omp end target data
+ if (any(abs(ee - 55.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+ end subroutine test_dummy_opt_callee_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_dummy_opt_call_2()
+ integer, parameter :: N = 1000
+
+ real(c_float), target :: aa(N), bb(N)
+ real(c_float), target, allocatable :: cc(:), dd(:)
+ real(c_float), pointer :: ee(:), ff(:)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr
+ real(c_float), pointer :: aptr(:), bptr(:), cptr(:), dptr(:), eptr(:), fptr(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+ call test_dummy_opt_callee_2(aa, bb, cc, dd, ee, ff, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, &
+ N)
+ deallocate(ee, ff)
+ end subroutine test_dummy_opt_call_2
+
+ subroutine test_dummy_opt_callee_2(aa, bb, cc, dd, ee, ff, &
+ c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr, &
+ aptr, bptr, cptr, dptr, eptr, fptr, &
+ N)
+ ! scalars
+ real(c_float), optional, target :: aa(:), bb(:)
+ real(c_float), optional, target, allocatable :: cc(:), dd(:)
+ real(c_float), optional, pointer :: ee(:), ff(:)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_cptr, c_dptr, c_eptr, c_fptr
+ real(c_float), optional, pointer :: aptr(:), bptr(:), cptr(:), dptr(:), eptr(:), fptr(:)
+
+ integer, value :: N
+
+ real(c_float) :: dummy
+
+ ! All shall be present - and pointing to non-NULL
+ if (.not.present(aa) .or. .not.present(bb)) stop 1
+ if (.not.present(cc) .or. .not.present(dd)) stop 1
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+
+ if (.not.allocated(cc) .or. .not.allocated(dd)) stop 1
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 1
+
+ aa = 111.0_c_float
+ bb = 222.0_c_float
+ cc = 333.0_c_float
+ dd = 444.0_c_float
+ ee = 555.0_c_float
+ ff = 666.0_c_float
+
+ !$omp target data map(to:aa) map(from:bb)
+ !$omp target data map(alloc:dummy) use_device_addr(aa,bb)
+ if (.not.present(aa) .or. .not.present(bb)) stop 1
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 1
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ if (.not.c_associated(c_aptr) .or. .not.c_associated(c_bptr)) stop 1
+ if (.not.associated(aptr) .or. .not.associated(bptr)) stop 1
+ !$omp end target data
+
+ if (.not.present(aa) .or. .not.present(bb)) stop 1
+ if (.not.c_associated(c_loc(aa)) .or. .not.c_associated(c_loc(bb))) stop 1
+ if (.not.c_associated(c_aptr) .or. .not.c_associated(c_bptr)) stop 1
+ if (.not.associated(aptr) .or. .not.associated(bptr)) stop 1
+
+ ! check c_loc ptr once
+ call copy3_array(c_aptr, c_bptr, N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 111.0_c_float) > 10.0_c_float * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ aa = 1111.0_c_float
+ !$omp target update to(aa)
+ call copy3_array(c_aptr, c_bptr, N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 1111.0_c_float) > 10.0_c_float * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ aa = 11111.0_c_float
+ !$omp target update to(aa)
+ call copy3_array(c_loc(aptr), c_loc(bptr), N)
+ !$omp target update from(bb)
+ if (any(abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa))) stop 1
+ !$omp end target data
+
+ if (any(abs(aa - 11111.0_c_float) > 10.0_c_float * epsilon(aa))) stop 1
+ if (any(abs(3.0_c_float * aa - bb) > 10.0_c_float * epsilon(aa))) stop 1
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ if (.not.present(cc) .or. .not.present(dd)) stop 1
+ if (.not.allocated(cc) .or. .not.allocated(dd)) stop 1
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 1
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ if (.not.c_associated(c_cptr) .or. .not.c_associated(c_dptr)) stop 1
+ if (.not.associated(cptr) .or. .not.associated(dptr)) stop 1
+ !$omp end target data
+ if (.not.present(cc) .or. .not.present(dd)) stop 1
+ if (.not.c_associated(c_loc(cc)) .or. .not.c_associated(c_loc(dd))) stop 1
+ if (.not.c_associated(c_cptr) .or. .not.c_associated(c_dptr)) stop 1
+ if (.not.associated(cptr) .or. .not.associated(dptr)) stop 1
+
+ ! check c_loc ptr once
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 333.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_float
+ !$omp target update to(cc)
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 3333.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_float
+ !$omp target update to(cc)
+ call copy3_array(c_loc(cptr), c_loc(dptr), N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+ !$omp end target data
+
+ if (any(abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(dd))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(dd))) stop 1
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 1
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 1
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ if (.not.c_associated(c_eptr) .or. .not.c_associated(c_fptr)) stop 1
+ if (.not.associated(eptr) .or. .not.associated(fptr)) stop 1
+ !$omp end target data
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+ if (.not.associated(ee) .or. .not.associated(ff)) stop 1
+ if (.not.c_associated(c_loc(ee)) .or. .not.c_associated(c_loc(ff))) stop 1
+ if (.not.c_associated(c_eptr) .or. .not.c_associated(c_fptr)) stop 1
+ if (.not.associated(eptr) .or. .not.associated(fptr)) stop 1
+
+ ! check c_loc ptr once
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_float
+ !$omp target update to(ee)
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 5555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_float
+ !$omp target update to(ee)
+ call copy3_array(c_loc(eptr), c_loc(fptr), N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ff))) stop 1
+ !$omp end target data
+
+ if (any(abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+ end subroutine test_dummy_opt_callee_2
+end module test_dummies_opt
+
+
+
+! Test nullptr
+module test_nullptr
+ use iso_c_binding
+ implicit none (type, external)
+ private
+ public :: test_nullptr_1
+contains
+ subroutine test_nullptr_1()
+ real(c_float), pointer :: aa(:), bb(:)
+ real(c_float), pointer :: ee(:), ff(:)
+
+ real(c_float), allocatable, target :: gg(:), hh(:)
+
+ type(c_ptr) :: c_aptr, c_bptr, c_eptr, c_fptr, c_gptr, c_hptr
+ real(c_float), pointer :: aptr(:), bptr(:), eptr(:), fptr(:), gptr(:), hptr(:)
+
+ aa => null()
+ bb => null()
+ ee => null()
+ ff => null()
+
+ if (associated(aa) .or. associated(bb)) stop 1
+ !$omp target data map(to:aa) map(from:bb) use_device_addr(aa,bb)
+ if (c_associated(c_loc(aa)) .or. c_associated(c_loc(bb))) stop 1
+ c_aptr = c_loc(aa)
+ c_bptr = c_loc(bb)
+ aptr => aa
+ bptr => bb
+ if (c_associated(c_aptr) .or. c_associated(c_bptr)) stop 1
+ if (associated(aptr) .or. associated(bptr, bb)) stop 1
+ if (associated(aa) .or. associated(bb)) stop 1
+ !$omp end target data
+ if (c_associated(c_aptr) .or. c_associated(c_bptr)) stop 1
+ if (associated(aptr) .or. associated(bptr, bb)) stop 1
+ if (associated(aa) .or. associated(bb)) stop 1
+
+ if (allocated(gg)) stop 1
+ !$omp target data map(tofrom:gg) use_device_addr(gg)
+ if (c_associated(c_loc(gg))) stop 1
+ c_gptr = c_loc(gg)
+ gptr => gg
+ if (c_associated(c_gptr)) stop 1
+ if (associated(gptr)) stop 1
+ if (allocated(gg)) stop 1
+ !$omp end target data
+ if (c_associated(c_gptr)) stop 1
+ if (associated(gptr)) stop 1
+ if (allocated(gg)) stop 1
+
+ call test_dummy_opt_nullptr_callee_1(ee, ff, hh, c_eptr, c_fptr, c_hptr, eptr, fptr, hptr)
+ end subroutine test_nullptr_1
+
+ subroutine test_dummy_opt_nullptr_callee_1(ee, ff, hh, c_eptr, c_fptr, c_hptr, eptr, fptr, hptr)
+ ! scalars
+ real(c_float), optional, pointer :: ee(:), ff(:)
+ real(c_float), optional, allocatable, target :: hh(:)
+
+ type(c_ptr), optional :: c_eptr, c_fptr, c_hptr
+ real(c_float), optional, pointer :: eptr(:), fptr(:), hptr(:)
+
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+ if (associated(ee) .or. associated(ff)) stop 1
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ if (.not.present(ee) .or. .not.present(ff)) stop 1
+ if (associated(ee) .or. associated(ff)) stop 1
+ if (c_associated(c_loc(ee)) .or. c_associated(c_loc(ff))) stop 1
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ if (c_associated(c_eptr) .or. c_associated(c_fptr)) stop 1
+ if (associated(eptr) .or. associated(fptr)) stop 1
+ !$omp end target data
+
+ if (c_associated(c_eptr) .or. c_associated(c_fptr)) stop 1
+ if (associated(eptr) .or. associated(fptr)) stop 1
+
+ if (allocated(hh)) stop 1
+ !$omp target data map(tofrom:hh) use_device_addr(hh)
+ if (c_associated(c_loc(hh))) stop 1
+ c_hptr = c_loc(hh)
+ hptr => hh
+ if (c_associated(c_hptr)) stop 1
+ if (associated(hptr)) stop 1
+ if (allocated(hh)) stop 1
+ !$omp end target data
+ if (c_associated(c_hptr)) stop 1
+ if (associated(hptr)) stop 1
+ if (allocated(hh)) stop 1
+ end subroutine test_dummy_opt_nullptr_callee_1
+end module test_nullptr
+
+
+
+! Test local variables
+module tests
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+ private
+ public :: test_main_1, test_main_2
+contains
+ ! map + use_device_addr + c_loc
+ subroutine test_main_1()
+ integer, parameter :: N = 1000
+
+ real(c_float), target, allocatable :: cc(:), dd(:)
+ real(c_float), pointer :: ee(:), ff(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+
+ cc = 33.0_c_float
+ dd = 44.0_c_float
+ ee = 55.0_c_float
+ ff = 66.0_c_float
+
+ !$omp target data map(to:cc) map(from:dd) use_device_addr(cc,dd)
+ call copy3_array(c_loc(cc), c_loc(dd), N)
+ !$omp end target data
+ if (any(abs(cc - 33.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+
+ !$omp target data map(to:ee) map(from:ff) use_device_addr(ee,ff)
+ call copy3_array(c_loc(ee), c_loc(ff), N)
+ !$omp end target data
+ if (any(abs(ee - 55.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+
+ deallocate(ee, ff) ! pointers, only
+ end subroutine test_main_1
+
+ ! Save device ptr - and recall pointer
+ subroutine test_main_2
+ integer, parameter :: N = 1000
+
+ real(c_float), target, allocatable :: cc(:), dd(:)
+ real(c_float), pointer :: ee(:), ff(:)
+
+ real(c_float) :: dummy
+ type(c_ptr) :: c_cptr, c_dptr, c_eptr, c_fptr
+ real(c_float), pointer :: cptr(:), dptr(:), eptr(:), fptr(:)
+
+ allocate(cc(N), dd(N), ee(N), ff(N))
+
+ cc = 333.0_c_float
+ dd = 444.0_c_float
+ ee = 555.0_c_float
+ ff = 666.0_c_float
+
+ !$omp target data map(to:cc) map(from:dd)
+ !$omp target data map(alloc:dummy) use_device_addr(cc,dd)
+ c_cptr = c_loc(cc)
+ c_dptr = c_loc(dd)
+ cptr => cc
+ dptr => dd
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 333.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ cc = 3333.0_c_float
+ !$omp target update to(cc)
+ call copy3_array(c_cptr, c_dptr, N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 3333.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ cc = 33333.0_c_float
+ !$omp target update to(cc)
+ call copy3_array(c_loc(cptr), c_loc(dptr), N)
+ !$omp target update from(dd)
+ if (any(abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(cc))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(cc))) stop 1
+ !$omp end target data
+
+ if (any(abs(cc - 33333.0_c_float) > 10.0_c_float * epsilon(dd))) stop 1
+ if (any(abs(3.0_c_float * cc - dd) > 10.0_c_float * epsilon(dd))) stop 1
+
+
+ !$omp target data map(to:ee) map(from:ff)
+ !$omp target data map(alloc:dummy) use_device_addr(ee,ff)
+ c_eptr = c_loc(ee)
+ c_fptr = c_loc(ff)
+ eptr => ee
+ fptr => ff
+ !$omp end target data
+
+ ! check c_loc ptr once
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+
+ ! check c_loc ptr again after target-value modification
+ ee = 5555.0_c_float
+ !$omp target update to(ee)
+ call copy3_array(c_eptr, c_fptr, N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 5555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+
+ ! check Fortran pointer after target-value modification
+ ee = 55555.0_c_float
+ !$omp target update to(ee)
+ call copy3_array(c_loc(eptr), c_loc(fptr), N)
+ !$omp target update from(ff)
+ if (any(abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ff))) stop 1
+ !$omp end target data
+
+ if (any(abs(ee - 55555.0_c_float) > 10.0_c_float * epsilon(ee))) stop 1
+ if (any(abs(3.0_c_float * ee - ff) > 10.0_c_float * epsilon(ee))) stop 1
+
+ deallocate(ee, ff)
+ end subroutine test_main_2
+end module tests
+
+
+program omp_device_addr
+ use tests
+ use test_dummies
+ use test_dummies_opt
+ use test_nullptr
+ implicit none (type, external)
+
+ call test_main_1()
+ call test_main_2()
+
+ call test_dummy_call_1()
+ call test_dummy_call_2()
+
+ call test_dummy_opt_call_1()
+ call test_dummy_opt_call_2()
+
+ call test_nullptr_1()
+end program omp_device_addr
diff --git a/libgomp/testsuite/libgomp.fortran/use_device_ptr-1.f90 b/libgomp/testsuite/libgomp.fortran/use_device_ptr-1.f90
new file mode 100644
index 00000000000..e5390e27a51
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/use_device_ptr-1.f90
@@ -0,0 +1,597 @@
+! { dg-do run }
+
+module target_procs
+ use iso_c_binding
+ implicit none (type, external)
+ private
+ public :: copy3_array, copy3_scalar, copy3_array1, copy3_array3
+contains
+ subroutine copy3_array_int(from_ptr, to_ptr, N)
+ !$omp declare target
+ real(c_double) :: from_ptr(:)
+ real(c_double) :: to_ptr(:)
+ integer, value :: N
+ integer :: i
+
+ !$omp parallel do
+ do i = 1, N
+ to_ptr(i) = 3 * from_ptr(i)
+ end do
+ !$omp end parallel do
+ end subroutine copy3_array_int
+
+ subroutine copy3_scalar_int(from, to)
+ !$omp declare target
+ real(c_double) :: from, to
+
+ to = 3 * from
+ end subroutine copy3_scalar_int
+
+
+ subroutine copy3_array(from, to, N)
+ type(c_ptr), value :: from, to
+ integer, value :: N
+ real(c_double), pointer :: from_ptr(:), to_ptr(:)
+
+ call c_f_pointer(from, from_ptr, shape=[N])
+ call c_f_pointer(to, to_ptr, shape=[N])
+
+ call do_offload_scalar(from_ptr,to_ptr)
+ contains
+ subroutine do_offload_scalar(from_r, to_r)
+ real(c_double), target :: from_r(:), to_r(:)
+ ! The extra function is needed as is_device_ptr
+ ! requires non-value, non-pointer dummy arguments
+
+ !$omp target is_device_ptr(from_r, to_r)
+ call copy3_array_int(from_r, to_r, N)
+ !$omp end target
+ end subroutine do_offload_scalar
+ end subroutine copy3_array
+
+ subroutine copy3_scalar(from, to)
+ type(c_ptr), value, target :: from, to
+ real(c_double), pointer :: from_ptr(:), to_ptr(:)
+
+ ! Standard-conform detour of using an array as at time of writing
+ ! is_device_ptr below does not handle scalars
+ call c_f_pointer(from, from_ptr, shape=[1])
+ call c_f_pointer(to, to_ptr, shape=[1])
+
+ call do_offload_scalar(from_ptr,to_ptr)
+ contains
+ subroutine do_offload_scalar(from_r, to_r)
+ real(c_double), target :: from_r(:), to_r(:)
+ ! The extra function is needed as is_device_ptr
+ ! requires non-value, non-pointer dummy arguments
+
+ !$omp target is_device_ptr(from_r, to_r)
+ call copy3_scalar_int(from_r(1), to_r(1))
+ !$omp end target
+ end subroutine do_offload_scalar
+ end subroutine copy3_scalar
+
+ subroutine copy3_array1(from, to)
+ real(c_double), target :: from(:), to(:)
+ integer :: N
+ N = size(from)
+
+ !!$omp target is_device_ptr(from, to)
+ call copy3_array(c_loc(from), c_loc(to), N)
+ !!$omp end target
+ end subroutine copy3_array1
+
+ subroutine copy3_array3(from, to)
+ real(c_double), optional, target :: from(:), to(:)
+ integer :: N
+ N = size(from)
+
+! !$omp target is_device_ptr(from, to)
+ call copy3_array(c_loc(from), c_loc(to), N)
+! !$omp end target
+ end subroutine copy3_array3
+end module target_procs
+
+
+
+module offloading2
+ use iso_c_binding
+ use target_procs
+ implicit none (type, external)
+contains
+ ! Same as main program but uses dummy *nonoptional* arguments
+ subroutine use_device_ptr_sub(AA, BB, CC, DD, EE, FF, AptrA, BptrB, N)
+ real(c_double), pointer :: AA(:), BB(:)
+ real(c_double), allocatable, target :: CC(:), DD(:)
+ real(c_double), target :: EE(N), FF(N), dummy(1)
+ real(c_double), pointer :: AptrA(:), BptrB(:)
+ intent(inout) :: AA, BB, CC, DD, EE, FF
+ integer, value :: N
+
+ type(c_ptr) :: tgt_aptr, tgt_bptr, tgt_cptr, tgt_dptr, tgt_eptr, tgt_fptr
+
+ AA = 11.0_c_double
+ BB = 22.0_c_double
+ CC = 33.0_c_double
+ DD = 44.0_c_double
+ EE = 55.0_c_double
+ FF = 66.0_c_double
+
+ ! pointer-type array to use_device_ptr
+ !$omp target data map(to:AA) map(from:BB) use_device_ptr(AA,BB)
+ call copy3_array(c_loc(AA), c_loc(BB), N)
+ !$omp end target data
+
+ if (any(abs(AA - 11.0_c_double) > 10.0_c_double * epsilon(AA))) stop 1
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 2
+
+ ! allocatable array to use_device_ptr
+ !$omp target data map(to:CC) map(from:DD) use_device_ptr(CC,DD)
+ call copy3_array(c_loc(CC), c_loc(DD), N)
+ !$omp end target data
+
+ if (any(abs(CC - 33.0_c_double) > 10.0_c_double * epsilon(CC))) stop 3
+ if (any(abs(3.0_c_double * CC - DD) > 10.0_c_double * epsilon(CC))) stop 4
+
+ ! fixed-size decriptorless array to use_device_ptr
+ !$omp target data map(to:EE) map(from:FF) use_device_ptr(EE,FF)
+ call copy3_array(c_loc(EE), c_loc(FF), N)
+ !$omp end target data
+
+ if (any(abs(EE - 55.0_c_double) > 10.0_c_double * epsilon(EE))) stop 5
+ if (any(abs(3.0_c_double * EE - FF) > 10.0_c_double * epsilon(EE))) stop 6
+
+
+
+ AA = 111.0_c_double
+ BB = 222.0_c_double
+ CC = 333.0_c_double
+ DD = 444.0_c_double
+ EE = 555.0_c_double
+ FF = 666.0_c_double
+
+ ! pointer-type array to use_device_ptr
+ !$omp target data map(to:AA) map(from:BB)
+ !$omp target data map(alloc:dummy) use_device_ptr(AA,BB)
+ tgt_aptr = c_loc(AA)
+ tgt_bptr = c_loc(BB)
+ AptrA => AA
+ BptrB => BB
+ !$omp end target data
+
+ call copy3_array(tgt_aptr, tgt_bptr, N)
+ !$omp target update from(BB)
+ if (any(abs(AA - 111.0_c_double) > 10.0_c_double * epsilon(AA))) stop 7
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 8
+
+ AA = 1111.0_c_double
+ !$omp target update to(AA)
+ call copy3_array(tgt_aptr, tgt_bptr, N)
+ !$omp target update from(BB)
+ if (any(abs(AA - 1111.0_c_double) > 10.0_c_double * epsilon(AA))) stop 9
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 10
+
+ ! AprtA tests
+ AA = 7.0_c_double
+ !$omp target update to(AA)
+ call copy3_array(c_loc(AptrA), c_loc(BptrB), N)
+ !$omp target update from(BB)
+ if (any(abs(AA - 7.0_c_double) > 10.0_c_double * epsilon(AA))) stop 11
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 12
+
+ AA = 77.0_c_double
+ !$omp target update to(AA)
+ call copy3_array1(AptrA, BptrB)
+ !$omp target update from(BB)
+ if (any(abs(AA - 77.0_c_double) > 10.0_c_double * epsilon(AA))) stop 13
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 14
+
+! AA = 777.0_c_double
+! !$omp target update to(AA)
+! call copy3_array2(AptrA, BptrB)
+! !$omp target update from(BB)
+! if (any(abs(AA - 777.0_c_double) > 10.0_c_double * epsilon(AA))) stop 15
+! if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 16
+
+ AA = 7777.0_c_double
+ !$omp target update to(AA)
+ call copy3_array3(AptrA, BptrB)
+ !$omp target update from(BB)
+ if (any(abs(AA - 7777.0_c_double) > 10.0_c_double * epsilon(AA))) stop 17
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 18
+
+! AA = 77777.0_c_double
+! !$omp target update to(AA)
+! call copy3_array4(AptrA, BptrB)
+! !$omp target update from(BB)
+ !$omp end target data
+!
+! if (any(abs(AA - 77777.0_c_double) > 10.0_c_double * epsilon(AA))) stop 19
+! if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 20
+
+
+
+ ! allocatable array to use_device_ptr
+ !$omp target data map(to:CC) map(from:DD)
+ !$omp target data map(alloc:dummy) use_device_ptr(CC,DD)
+ tgt_cptr = c_loc(CC)
+ tgt_dptr = c_loc(DD)
+ !$omp end target data
+
+ call copy3_array(tgt_cptr, tgt_dptr, N)
+ !$omp target update from(DD)
+ if (any(abs(CC - 333.0_c_double) > 10.0_c_double * epsilon(CC))) stop 21
+ if (any(abs(3.0_c_double * CC - DD) > 10.0_c_double * epsilon(CC))) stop 22
+
+ CC = 3333.0_c_double
+ !$omp target update to(CC)
+ call copy3_array(tgt_cptr, tgt_dptr, N)
+ !$omp target update from(DD)
+ !$omp end target data
+
+ if (any(abs(CC - 3333.0_c_double) > 10.0_c_double * epsilon(CC))) stop 23
+ if (any(abs(3.0_c_double * CC - DD) > 10.0_c_double * epsilon(CC))) stop 24
+
+
+
+ ! fixed-size decriptorless array to use_device_ptr
+ !$omp target data map(to:EE) map(from:FF)
+ !$omp target data map(alloc:dummy) use_device_ptr(EE,FF)
+ tgt_eptr = c_loc(EE)
+ tgt_fptr = c_loc(FF)
+ !$omp end target data
+
+ call copy3_array(tgt_eptr, tgt_fptr, N)
+ !$omp target update from(FF)
+ if (any(abs(EE - 555.0_c_double) > 10.0_c_double * epsilon(EE))) stop 25
+ if (any(abs(3.0_c_double * EE - FF) > 10.0_c_double * epsilon(EE))) stop 26
+
+ EE = 5555.0_c_double
+ !$omp target update to(EE)
+ call copy3_array(tgt_eptr, tgt_fptr, N)
+ !$omp target update from(FF)
+ !$omp end target data
+
+ if (any(abs(EE - 5555.0_c_double) > 10.0_c_double * epsilon(EE))) stop 27
+ if (any(abs(3.0_c_double * EE - FF) > 10.0_c_double * epsilon(EE))) stop 28
+ end subroutine use_device_ptr_sub
+
+
+
+ ! Same as main program but uses dummy *optional* arguments
+ subroutine use_device_ptr_sub2(AA, BB, CC, DD, EE, FF, AptrA, BptrB, N)
+ real(c_double), optional, pointer :: AA(:), BB(:)
+ real(c_double), optional, allocatable, target :: CC(:), DD(:)
+ real(c_double), optional, target :: EE(N), FF(N)
+ real(c_double), pointer :: AptrA(:), BptrB(:)
+ intent(inout) :: AA, BB, CC, DD, EE, FF
+ real(c_double), target :: dummy(1)
+ integer, value :: N
+
+ type(c_ptr) :: tgt_aptr, tgt_bptr, tgt_cptr, tgt_dptr, tgt_eptr, tgt_fptr
+
+ AA = 11.0_c_double
+ BB = 22.0_c_double
+ CC = 33.0_c_double
+ DD = 44.0_c_double
+ EE = 55.0_c_double
+ FF = 66.0_c_double
+
+ ! pointer-type array to use_device_ptr
+ !$omp target data map(to:AA) map(from:BB) use_device_ptr(AA,BB)
+ call copy3_array(c_loc(AA), c_loc(BB), N)
+ !$omp end target data
+
+ if (any(abs(AA - 11.0_c_double) > 10.0_c_double * epsilon(AA))) stop 29
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 30
+
+ ! allocatable array to use_device_ptr
+ !$omp target data map(to:CC) map(from:DD) use_device_ptr(CC,DD)
+ call copy3_array(c_loc(CC), c_loc(DD), N)
+ !$omp end target data
+
+ if (any(abs(CC - 33.0_c_double) > 10.0_c_double * epsilon(CC))) stop 31
+ if (any(abs(3.0_c_double * CC - DD) > 10.0_c_double * epsilon(CC))) stop 32
+
+ ! fixed-size decriptorless array to use_device_ptr
+ !$omp target data map(to:EE) map(from:FF) use_device_ptr(EE,FF)
+ call copy3_array(c_loc(EE), c_loc(FF), N)
+ !$omp end target data
+
+ if (any(abs(EE - 55.0_c_double) > 10.0_c_double * epsilon(EE))) stop 33
+ if (any(abs(3.0_c_double * EE - FF) > 10.0_c_double * epsilon(EE))) stop 34
+
+
+
+ AA = 111.0_c_double
+ BB = 222.0_c_double
+ CC = 333.0_c_double
+ DD = 444.0_c_double
+ EE = 555.0_c_double
+ FF = 666.0_c_double
+
+ ! pointer-type array to use_device_ptr
+ !$omp target data map(to:AA) map(from:BB)
+ !$omp target data map(alloc:dummy) use_device_ptr(AA,BB)
+ tgt_aptr = c_loc(AA)
+ tgt_bptr = c_loc(BB)
+ AptrA => AA
+ BptrB => BB
+ !$omp end target data
+
+ call copy3_array(tgt_aptr, tgt_bptr, N)
+ !$omp target update from(BB)
+ if (any(abs(AA - 111.0_c_double) > 10.0_c_double * epsilon(AA))) stop 35
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 36
+
+ AA = 1111.0_c_double
+ !$omp target update to(AA)
+ call copy3_array(tgt_aptr, tgt_bptr, N)
+ !$omp target update from(BB)
+ if (any(abs(AA - 1111.0_c_double) > 10.0_c_double * epsilon(AA))) stop 37
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 38
+
+ ! AprtA tests
+ AA = 7.0_c_double
+ !$omp target update to(AA)
+ call copy3_array(c_loc(AptrA), c_loc(BptrB), N)
+ !$omp target update from(BB)
+ if (any(abs(AA - 7.0_c_double) > 10.0_c_double * epsilon(AA))) stop 39
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 40
+
+ AA = 77.0_c_double
+ !$omp target update to(AA)
+ call copy3_array1(AptrA, BptrB)
+ !$omp target update from(BB)
+ if (any(abs(AA - 77.0_c_double) > 10.0_c_double * epsilon(AA))) stop 41
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 42
+
+! AA = 777.0_c_double
+! !$omp target update to(AA)
+! call copy3_array2(AptrA, BptrB)
+! !$omp target update from(BB)
+! if (any(abs(AA - 777.0_c_double) > 10.0_c_double * epsilon(AA))) stop 43
+! if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 44
+
+ AA = 7777.0_c_double
+ !$omp target update to(AA)
+ call copy3_array3(AptrA, BptrB)
+ !$omp target update from(BB)
+ if (any(abs(AA - 7777.0_c_double) > 10.0_c_double * epsilon(AA))) stop 45
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 46
+
+! AA = 77777.0_c_double
+! !$omp target update to(AA)
+! call copy3_array4(AptrA, BptrB)
+! !$omp target update from(BB)
+ !$omp end target data
+!
+! if (any(abs(AA - 77777.0_c_double) > 10.0_c_double * epsilon(AA))) stop 47
+! if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 48
+
+
+
+ ! allocatable array to use_device_ptr
+ !$omp target data map(to:CC) map(from:DD)
+ !$omp target data map(alloc:dummy) use_device_ptr(CC,DD)
+ tgt_cptr = c_loc(CC)
+ tgt_dptr = c_loc(DD)
+ !$omp end target data
+
+ call copy3_array(tgt_cptr, tgt_dptr, N)
+ !$omp target update from(DD)
+ if (any(abs(CC - 333.0_c_double) > 10.0_c_double * epsilon(CC))) stop 49
+ if (any(abs(3.0_c_double * CC - DD) > 10.0_c_double * epsilon(CC))) stop 50
+
+ CC = 3333.0_c_double
+ !$omp target update to(CC)
+ call copy3_array(tgt_cptr, tgt_dptr, N)
+ !$omp target update from(DD)
+ !$omp end target data
+
+ if (any(abs(CC - 3333.0_c_double) > 10.0_c_double * epsilon(CC))) stop 51
+ if (any(abs(3.0_c_double * CC - DD) > 10.0_c_double * epsilon(CC))) stop 52
+
+
+
+ ! fixed-size decriptorless array to use_device_ptr
+ !$omp target data map(to:EE) map(from:FF)
+ !$omp target data map(alloc:dummy) use_device_ptr(EE,FF)
+ tgt_eptr = c_loc(EE)
+ tgt_fptr = c_loc(FF)
+ !$omp end target data
+
+ call copy3_array(tgt_eptr, tgt_fptr, N)
+ !$omp target update from(FF)
+ if (any(abs(EE - 555.0_c_double) > 10.0_c_double * epsilon(EE))) stop 53
+ if (any(abs(3.0_c_double * EE - FF) > 10.0_c_double * epsilon(EE))) stop 54
+
+ EE = 5555.0_c_double
+ !$omp target update to(EE)
+ call copy3_array(tgt_eptr, tgt_fptr, N)
+ !$omp end target data
+
+ if (any(abs(EE - 5555.0_c_double) > 10.0_c_double * epsilon(EE))) stop 55
+ if (any(abs(3.0_c_double * EE - FF) > 10.0_c_double * epsilon(EE))) stop 56
+ end subroutine use_device_ptr_sub2
+end module offloading2
+
+
+
+program omp_device_ptr
+ use iso_c_binding
+ use target_procs
+ use offloading2
+ implicit none (type, external)
+
+ integer, parameter :: N = 1000
+ real(c_double), pointer :: AA(:), BB(:), arg_AA(:), arg_BB(:), arg2_AA(:), arg2_BB(:)
+ real(c_double), allocatable, target :: CC(:), DD(:), arg_CC(:), arg_DD(:), arg2_CC(:), arg2_DD(:)
+ real(c_double), target :: EE(N), FF(N), dummy(1), arg_EE(N), arg_FF(N), arg2_EE(N), arg2_FF(N)
+
+ real(c_double), pointer :: AptrA(:), BptrB(:)
+ type(c_ptr) :: tgt_aptr, tgt_bptr, tgt_cptr, tgt_dptr, tgt_eptr, tgt_fptr
+
+ allocate(AA(N), BB(N), CC(N), DD(N))
+
+ AA = 11.0_c_double
+ BB = 22.0_c_double
+ CC = 33.0_c_double
+ DD = 44.0_c_double
+ EE = 55.0_c_double
+ FF = 66.0_c_double
+
+ ! pointer-type array to use_device_ptr
+ !$omp target data map(to:AA) map(from:BB) use_device_ptr(AA,BB)
+ call copy3_array(c_loc(AA), c_loc(BB), N)
+ !$omp end target data
+
+ if (any(abs(AA - 11.0_c_double) > 10.0_c_double * epsilon(AA))) stop 57
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 58
+
+ ! allocatable array to use_device_ptr
+ !$omp target data map(to:CC) map(from:DD) use_device_ptr(CC,DD)
+ call copy3_array(c_loc(CC), c_loc(DD), N)
+ !$omp end target data
+
+ if (any(abs(CC - 33.0_c_double) > 10.0_c_double * epsilon(CC))) stop 59
+ if (any(abs(3.0_c_double * CC - DD) > 10.0_c_double * epsilon(CC))) stop 60
+
+ ! fixed-size decriptorless array to use_device_ptr
+ !$omp target data map(to:EE) map(from:FF) use_device_ptr(EE,FF)
+ call copy3_array(c_loc(EE), c_loc(FF), N)
+ !$omp end target data
+
+ if (any(abs(EE - 55.0_c_double) > 10.0_c_double * epsilon(EE))) stop 61
+ if (any(abs(3.0_c_double * EE - FF) > 10.0_c_double * epsilon(EE))) stop 62
+
+
+
+ AA = 111.0_c_double
+ BB = 222.0_c_double
+ CC = 333.0_c_double
+ DD = 444.0_c_double
+ EE = 555.0_c_double
+ FF = 666.0_c_double
+
+ ! pointer-type array to use_device_ptr
+ !$omp target data map(to:AA) map(from:BB)
+ !$omp target data map(alloc:dummy) use_device_ptr(AA,BB)
+ tgt_aptr = c_loc(AA)
+ tgt_bptr = c_loc(BB)
+ AptrA => AA
+ BptrB => BB
+ !$omp end target data
+
+ call copy3_array(tgt_aptr, tgt_bptr, N)
+ !$omp target update from(BB)
+ if (any(abs(AA - 111.0_c_double) > 10.0_c_double * epsilon(AA))) stop 63
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 64
+
+ AA = 1111.0_c_double
+ !$omp target update to(AA)
+ call copy3_array(tgt_aptr, tgt_bptr, N)
+ !$omp target update from(BB)
+ if (any(abs(AA - 1111.0_c_double) > 10.0_c_double * epsilon(AA))) stop 65
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 66
+
+ ! AprtA tests
+ AA = 7.0_c_double
+ !$omp target update to(AA)
+ call copy3_array(c_loc(AptrA), c_loc(BptrB), N)
+ !$omp target update from(BB)
+ if (any(abs(AA - 7.0_c_double) > 10.0_c_double * epsilon(AA))) stop 67
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 68
+
+ AA = 77.0_c_double
+ !$omp target update to(AA)
+ call copy3_array1(AptrA, BptrB)
+ !$omp target update from(BB)
+ if (any(abs(AA - 77.0_c_double) > 10.0_c_double * epsilon(AA))) stop 69
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 70
+
+! AA = 777.0_c_double
+! !$omp target update to(AA)
+! call copy3_array2(AptrA, BptrB)
+! !$omp target update from(BB)
+! if (any(abs(AA - 777.0_c_double) > 10.0_c_double * epsilon(AA))) stop 71
+! if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 72
+
+ AA = 7777.0_c_double
+ !$omp target update to(AA)
+ call copy3_array3(AptrA, BptrB)
+ !$omp target update from(BB)
+ if (any(abs(AA - 7777.0_c_double) > 10.0_c_double * epsilon(AA))) stop 73
+ if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 74
+
+! AA = 77777.0_c_double
+! !$omp target update to(AA)
+! call copy3_array4(AptrA, BptrB)
+! !$omp target update from(BB)
+ !$omp end target data
+!
+! if (any(abs(AA - 77777.0_c_double) > 10.0_c_double * epsilon(AA))) stop 75
+! if (any(abs(3.0_c_double * AA - BB) > 10.0_c_double * epsilon(AA))) stop 76
+
+
+
+ ! allocatable array to use_device_ptr
+ !$omp target data map(to:CC) map(from:DD)
+ !$omp target data map(alloc:dummy) use_device_ptr(CC,DD)
+ tgt_cptr = c_loc(CC)
+ tgt_dptr = c_loc(DD)
+ !$omp end target data
+
+ call copy3_array(tgt_cptr, tgt_dptr, N)
+ !$omp target update from(DD)
+ if (any(abs(CC - 333.0_c_double) > 10.0_c_double * epsilon(CC))) stop 77
+ if (any(abs(3.0_c_double * CC - DD) > 10.0_c_double * epsilon(CC))) stop 78
+
+ CC = 3333.0_c_double
+ !$omp target update to(CC)
+ call copy3_array(tgt_cptr, tgt_dptr, N)
+ !$omp target update from(DD)
+ !$omp end target data
+
+ if (any(abs(CC - 3333.0_c_double) > 10.0_c_double * epsilon(CC))) stop 79
+ if (any(abs(3.0_c_double * CC - DD) > 10.0_c_double * epsilon(CC))) stop 80
+
+
+
+ ! fixed-size decriptorless array to use_device_ptr
+ !$omp target data map(to:EE) map(from:FF)
+ !$omp target data map(alloc:dummy) use_device_ptr(EE,FF)
+ tgt_eptr = c_loc(EE)
+ tgt_fptr = c_loc(FF)
+ !$omp end target data
+
+ call copy3_array(tgt_eptr, tgt_fptr, N)
+ !$omp target update from(FF)
+ if (any(abs(EE - 555.0_c_double) > 10.0_c_double * epsilon(EE))) stop 81
+ if (any(abs(3.0_c_double * EE - FF) > 10.0_c_double * epsilon(EE))) stop 82
+
+ EE = 5555.0_c_double
+ !$omp target update to(EE)
+ call copy3_array(tgt_eptr, tgt_fptr, N)
+ !$omp target update from(FF)
+ !$omp end target data
+
+ if (any(abs(EE - 5555.0_c_double) > 10.0_c_double * epsilon(EE))) stop 83
+ if (any(abs(3.0_c_double * EE - FF) > 10.0_c_double * epsilon(EE))) stop 84
+
+
+
+ deallocate(AA, BB) ! Free pointers only
+
+ AptrA => null()
+ BptrB => null()
+ allocate(arg_AA(N), arg_BB(N), arg_CC(N), arg_DD(N))
+ call use_device_ptr_sub(arg_AA, arg_BB, arg_CC, arg_DD, arg_EE, arg_FF, AptrA, BptrB, N)
+ deallocate(arg_AA, arg_BB)
+
+ AptrA => null()
+ BptrB => null()
+ allocate(arg2_AA(N), arg2_BB(N), arg2_CC(N), arg2_DD(N))
+ call use_device_ptr_sub2(arg2_AA, arg2_BB, arg2_CC, arg2_DD, arg2_EE, arg2_FF, AptrA, BptrB, N)
+ deallocate(arg2_AA, arg2_BB)
+end program omp_device_ptr
diff --git a/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-1.f90 b/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-1.f90
new file mode 100644
index 00000000000..e92ee8bf573
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-1.f90
@@ -0,0 +1,59 @@
+! { dg-do run }
+! Test whether use_device_ptr properly handles OPTIONAL arguments
+! (Only case of present arguments is tested)
+program test_it
+ implicit none
+ integer, target :: ixx
+ integer, pointer :: ptr_i, ptr_null
+
+ ptr_i => ixx
+ call foo(ptr_i)
+
+ ptr_null => null()
+ call bar(ptr_null)
+
+ call foo_absent()
+ call bar_absent()
+contains
+ subroutine foo(ii)
+ integer, pointer, optional :: ii
+
+ if (.not.present(ii)) stop 1
+ if (.not.associated(ii, ixx)) stop 2
+ !$omp target data map(to:ixx) use_device_ptr(ii)
+ if (.not.present(ii)) stop 3
+ if (.not.associated(ii)) stop 4
+ !$omp end target data
+ end subroutine foo
+
+ ! For bar, it is assumed that a NULL ptr on the host maps to NULL on the device
+ subroutine bar(jj)
+ integer, pointer, optional :: jj
+
+ if (.not.present(jj)) stop 5
+ if (associated(jj)) stop 6
+ !$omp target data map(to:ixx) use_device_ptr(jj)
+ if (.not.present(jj)) stop 7
+ if (associated(jj)) stop 8
+ !$omp end target data
+ end subroutine bar
+
+ subroutine foo_absent(ii)
+ integer, pointer, optional :: ii
+
+ if (present(ii)) STOP 31
+ !$omp target data map(to:ixx) use_device_ptr(ii)
+ if (present(ii)) STOP 32
+ !$omp end target data
+ end subroutine foo_absent
+
+ ! For bar, it is assumed that a NULL ptr on the host maps to NULL on the device
+ subroutine bar_absent(jj)
+ integer, pointer, optional :: jj
+
+ if (present(jj)) STOP 41
+ !$omp target data map(to:ixx) use_device_ptr(jj)
+ if (present(jj)) STOP 42
+ !$omp end target data
+ end subroutine bar_absent
+end program test_it
diff --git a/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f90 b/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f90
new file mode 100644
index 00000000000..41abf17eede
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/use_device_ptr-optional-2.f90
@@ -0,0 +1,33 @@
+! Check whether absent optional arguments are properly
+! handled with use_device_{addr,ptr}.
+program main
+ implicit none (type, external)
+ call foo()
+contains
+ subroutine foo(v, w, x, y, z)
+ integer, target, optional, value :: v
+ integer, target, optional :: w
+ integer, target, optional :: x(:)
+ integer, target, optional, allocatable :: y
+ integer, target, optional, allocatable :: z(:)
+ integer :: d
+
+ !$omp target data map(d) use_device_addr(v, w, x, y, z)
+ if(present(v)) stop 1
+ if(present(w)) stop 2
+ if(present(x)) stop 3
+ if(present(y)) stop 4
+ if(present(z)) stop 5
+ !$omp end target data
+
+! Using 'v' in use_device_ptr gives an ICE
+! TODO: Find out what the OpenMP spec permits for use_device_ptr
+
+ !$omp target data map(d) use_device_ptr(w, x, y, z)
+ if(present(w)) stop 6
+ if(present(x)) stop 7
+ if(present(y)) stop 8
+ if(present(z)) stop 9
+ !$omp end target data
+ end subroutine foo
+end program main
diff --git a/libgomp/testsuite/libgomp.fortran/vla1.f90 b/libgomp/testsuite/libgomp.fortran/vla1.f90
index bf25e89a54a..63d17e7d47b 100644
--- a/libgomp/testsuite/libgomp.fortran/vla1.f90
+++ b/libgomp/testsuite/libgomp.fortran/vla1.f90
@@ -156,7 +156,7 @@ contains
call check (size (k, 3), 3, l)
call check (size (k), 15, l)
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end subroutine foo
subroutine test
diff --git a/libgomp/testsuite/libgomp.fortran/vla2.f90 b/libgomp/testsuite/libgomp.fortran/vla2.f90
index 1bda078a8f1..ef337d4753e 100644
--- a/libgomp/testsuite/libgomp.fortran/vla2.f90
+++ b/libgomp/testsuite/libgomp.fortran/vla2.f90
@@ -124,7 +124,7 @@ contains
call check (size (k, 3), 3, l)
call check (size (k), 15, l)
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end subroutine foo
subroutine test
diff --git a/libgomp/testsuite/libgomp.fortran/vla3.f90 b/libgomp/testsuite/libgomp.fortran/vla3.f90
index e31aaaf6b15..c21048370bc 100644
--- a/libgomp/testsuite/libgomp.fortran/vla3.f90
+++ b/libgomp/testsuite/libgomp.fortran/vla3.f90
@@ -162,7 +162,7 @@ contains
call check (size (k, 3), 3, l)
call check (size (k), 15, l)
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end subroutine foo
subroutine test
diff --git a/libgomp/testsuite/libgomp.fortran/vla4.f90 b/libgomp/testsuite/libgomp.fortran/vla4.f90
index 3388e872288..2d1a940778f 100644
--- a/libgomp/testsuite/libgomp.fortran/vla4.f90
+++ b/libgomp/testsuite/libgomp.fortran/vla4.f90
@@ -166,7 +166,7 @@ contains
call check (size (k), 15, l)
110 continue
!$omp end parallel do
- if (l) STOP 1
+ if (l) stop 1
if (z2 == 6) then
x = 5
w = 'thread5thr_number_5THREAD5THR_NUMBER_5'
@@ -202,7 +202,7 @@ contains
do 115, q = 4, 6
l = l .or. k(p, 1, q - 3) .ne. 19 + x + p + 7 + 3 * q
115 continue
- if (l) STOP 2
+ if (l) stop 2
end if
end subroutine foo
diff --git a/libgomp/testsuite/libgomp.fortran/vla5.f90 b/libgomp/testsuite/libgomp.fortran/vla5.f90
index 3b040c737ff..3b28c5108fe 100644
--- a/libgomp/testsuite/libgomp.fortran/vla5.f90
+++ b/libgomp/testsuite/libgomp.fortran/vla5.f90
@@ -138,7 +138,7 @@ contains
call check (size (k), 15, l)
110 continue
!$omp end parallel do
- if (l) STOP 1
+ if (l) stop 1
if (z2 == 6) then
x = 5
w = 'thread5thr_number_5THREAD5THR_NUMBER_5'
@@ -174,7 +174,7 @@ contains
do 115, q = 4, 6
l = l .or. k(p, 1, q - 3) .ne. 19 + x + p + 7 + 3 * q
115 continue
- if (l) STOP 2
+ if (l) stop 2
end if
end subroutine foo
diff --git a/libgomp/testsuite/libgomp.fortran/vla6.f90 b/libgomp/testsuite/libgomp.fortran/vla6.f90
index ccc91ec85d3..c2ea7f38ac4 100644
--- a/libgomp/testsuite/libgomp.fortran/vla6.f90
+++ b/libgomp/testsuite/libgomp.fortran/vla6.f90
@@ -173,7 +173,7 @@ contains
l = l .or. k(p, 1, q - 3) .ne. 19 + x + p + 7 + 3 * q
115 continue
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end subroutine foo
subroutine test
diff --git a/libgomp/testsuite/libgomp.fortran/vla7.f90 b/libgomp/testsuite/libgomp.fortran/vla7.f90
index a97132dc0a4..1e27a2e3f4a 100644
--- a/libgomp/testsuite/libgomp.fortran/vla7.f90
+++ b/libgomp/testsuite/libgomp.fortran/vla7.f90
@@ -4,13 +4,13 @@
character (6) :: c, f2
character (6) :: d(2)
c = f1 (6)
- if (c .ne. 'opqrst') STOP 1
+ if (c .ne. 'opqrst') stop 1
c = f2 (6)
- if (c .ne. '_/!!/_') STOP 2
+ if (c .ne. '_/!!/_') stop 2
d = f3 (6)
- if (d(1) .ne. 'opqrst' .or. d(2) .ne. 'a') STOP 3
+ if (d(1) .ne. 'opqrst' .or. d(2) .ne. 'a') stop 3
d = f4 (6)
- if (d(1) .ne. 'Opqrst' .or. d(2) .ne. 'A') STOP 4
+ if (d(1) .ne. 'Opqrst' .or. d(2) .ne. 'A') stop 4
contains
function f1 (n)
use omp_lib
@@ -40,7 +40,7 @@ contains
!$omp barrier
l = l .or. f1 .ne. 'def'
!$omp end parallel
- if (l) STOP 5
+ if (l) stop 5
f1 = 'opqrst'
end function f1
function f3 (n)
@@ -71,7 +71,7 @@ contains
!$omp barrier
l = l .or. any (f3 .ne. 'def')
!$omp end parallel
- if (l) STOP 6
+ if (l) stop 6
f3(1) = 'opqrst'
f3(2) = 'a'
end function f3
@@ -105,7 +105,7 @@ contains
l = l .or. any (f4 .ne. 'def')
l = l .or. size (f4) .ne. 2
!$omp end parallel
- if (l) STOP 7
+ if (l) stop 7
f4(1) = 'Opqrst'
f4(2) = 'A'
end function f4
@@ -138,6 +138,6 @@ function f2 (n)
!$omp barrier
l = l .or. f2 .ne. 'def'
!$omp end parallel
- if (l) STOP 8
+ if (l) stop 8
f2 = '_/!!/_'
end function f2
diff --git a/libgomp/testsuite/libgomp.fortran/vla8.f90 b/libgomp/testsuite/libgomp.fortran/vla8.f90
index ee756d4fe6e..fbf3308d747 100644
--- a/libgomp/testsuite/libgomp.fortran/vla8.f90
+++ b/libgomp/testsuite/libgomp.fortran/vla8.f90
@@ -237,7 +237,7 @@ contains
l = l .or. k(p, 1, q - 3) .ne. 19 + x + p + 7 + 3 * q
125 continue
!$omp end parallel
- if (l) STOP 1
+ if (l) stop 1
end subroutine foo
subroutine test
diff --git a/libgomp/testsuite/libgomp.fortran/workshare1.f90 b/libgomp/testsuite/libgomp.fortran/workshare1.f90
index 1d2ba7d3ee2..a9baef40979 100644
--- a/libgomp/testsuite/libgomp.fortran/workshare1.f90
+++ b/libgomp/testsuite/libgomp.fortran/workshare1.f90
@@ -1,3 +1,4 @@
+! { dg-do run }
function foo ()
integer :: foo
logical :: foo_seen
@@ -24,7 +25,7 @@ end
b = 20
a(1:5) = max (a(1:5), b(1:5))
!$omp end parallel workshare
- if (any (a(1:5) .ne. 20)) STOP 1
- if (any (a(6:10) .ne. 10)) STOP 2
- if (.not. foo_seen .or. .not. bar_seen) STOP 3
+ if (any (a(1:5) .ne. 20)) stop 1
+ if (any (a(6:10) .ne. 10)) stop 2
+ if (.not. foo_seen .or. .not. bar_seen) stop 3
end
diff --git a/libgomp/testsuite/libgomp.fortran/workshare2.f90 b/libgomp/testsuite/libgomp.fortran/workshare2.f90
index 655a450885e..299e577732b 100644
--- a/libgomp/testsuite/libgomp.fortran/workshare2.f90
+++ b/libgomp/testsuite/libgomp.fortran/workshare2.f90
@@ -1,9 +1,10 @@
+! { dg-do run }
subroutine f1
integer a(20:50,70:90)
!$omp parallel workshare
a(:,:) = 17
!$omp end parallel workshare
- if (any (a.ne.17)) STOP 1
+ if (any (a.ne.17)) stop 1
end subroutine f1
subroutine f2
integer a(20:50,70:90),d(15),e(15),f(15)
@@ -20,14 +21,14 @@ subroutine f2
f = 7
where (e.ge.5) f = f + 1
!$omp end parallel workshare
- if (any (a.ne.17)) STOP 2
- if (c.ne.5.or.b.ne.4) STOP 3
- if (any(d.ne.0)) STOP 4
+ if (any (a.ne.17)) stop 2
+ if (c.ne.5.or.b.ne.4) stop 3
+ if (any(d.ne.0)) stop 4
do i = 1, 15
if (e(i).ge.5) then
- if (f(i).ne.8) STOP 5
+ if (f(i).ne.8) stop 5
else
- if (f(i).ne.7) STOP 6
+ if (f(i).ne.7) stop 6
end if
end do
end subroutine f2
diff --git a/libgomp/testsuite/libgomp.graphite/force-parallel-5.c b/libgomp/testsuite/libgomp.graphite/force-parallel-5.c
index de31d6436f5..b83ca79dfae 100644
--- a/libgomp/testsuite/libgomp.graphite/force-parallel-5.c
+++ b/libgomp/testsuite/libgomp.graphite/force-parallel-5.c
@@ -31,6 +31,6 @@ int main(void)
}
/* Check that parallel code generation part make the right answer. */
-/* { dg-final { scan-tree-dump-times "2 loops carried no dependency" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "2 loops carried no dependency" 1 "graphite" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "loopfn.0" 4 "optimized" } } */
/* { dg-final { scan-tree-dump-times "loopfn.1" 4 "optimized" } } */
diff --git a/libgomp/testsuite/libgomp.graphite/graphite.exp b/libgomp/testsuite/libgomp.graphite/graphite.exp
index 398ba5df91e..9d9de02abbe 100644
--- a/libgomp/testsuite/libgomp.graphite/graphite.exp
+++ b/libgomp/testsuite/libgomp.graphite/graphite.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2018 Free Software Foundation, Inc.
+# Copyright (C) 2009-2019 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libgomp/testsuite/libgomp.oacc-c++/c++.exp b/libgomp/testsuite/libgomp.oacc-c++/c++.exp
index 9beadd6fc1e..dcefa792ca4 100644
--- a/libgomp/testsuite/libgomp.oacc-c++/c++.exp
+++ b/libgomp/testsuite/libgomp.oacc-c++/c++.exp
@@ -77,18 +77,24 @@ if { $lang_test_file_found } {
set libstdcxx_includes ""
}
- # Test OpenACC with available accelerators.
- foreach offload_target_openacc $offload_targets_s_openacc {
- set tagopt "-DACC_DEVICE_TYPE_$offload_target_openacc=1"
-
- switch $offload_target_openacc {
+ # Test with all available offload targets, and with offloading disabled.
+ foreach offload_target [concat [split $offload_targets ","] "disable"] {
+ global openacc_device_type
+ set openacc_device_type [offload_target_to_openacc_device_type $offload_target]
+ set tagopt "-DACC_DEVICE_TYPE_$openacc_device_type=1"
+
+ switch $openacc_device_type {
+ "" {
+ unsupported "$subdir $offload_target offloading"
+ continue
+ }
host {
set acc_mem_shared 1
}
nvidia {
if { ![check_effective_target_openacc_nvidia_accel_present] } {
# Don't bother; execution testing is going to FAIL.
- untested "$subdir $offload_target_openacc offloading"
+ untested "$subdir $offload_target offloading: supported, but hardware not accessible"
continue
}
@@ -101,12 +107,17 @@ if { $lang_test_file_found } {
set acc_mem_shared 0
}
default {
- set acc_mem_shared 0
+ error "Unknown OpenACC device type: $openacc_device_type (offload target: $offload_target)"
}
}
set tagopt "$tagopt -DACC_MEM_SHARED=$acc_mem_shared"
- setenv ACC_DEVICE_TYPE $offload_target_openacc
+ # To avoid compilation overhead, and to keep simple '-foffload=[...]'
+ # handling in test cases, by default only build for the offload target
+ # that we're actually going to test.
+ set tagopt "$tagopt -foffload=$offload_target"
+ # Force usage of the corresponding OpenACC device type.
+ setenv ACC_DEVICE_TYPE $openacc_device_type
# To get better test coverage for device-specific code that is only
# ever used in offloading configurations, we'd like more thorough
@@ -115,8 +126,8 @@ if { $lang_test_file_found } {
# -O0 and -O2 only, to avoid testing times exploding too much, under
# the assumption that between -O0 and -O[something] there is the
# biggest difference in the overall structure of the generated code.
- switch $offload_target_openacc {
- host {
+ switch -glob $offload_target {
+ disable {
set-torture-options [list \
{ -O2 } ]
}
diff --git a/libgomp/testsuite/libgomp.oacc-c++/firstprivate-mappings-1.C b/libgomp/testsuite/libgomp.oacc-c++/firstprivate-mappings-1.C
new file mode 100644
index 00000000000..c8dba9e5d1c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c++/firstprivate-mappings-1.C
@@ -0,0 +1,3 @@
+/* Verify OpenACC 'firstprivate' mappings for C++ reference types. */
+
+#include "../../../gcc/testsuite/g++.dg/goacc/firstprivate-mappings-1.C"
diff --git a/libgomp/testsuite/libgomp.oacc-c++/non-scalar-data.C b/libgomp/testsuite/libgomp.oacc-c++/non-scalar-data.C
index 8e4b296382b..e5f8707c249 100644
--- a/libgomp/testsuite/libgomp.oacc-c++/non-scalar-data.C
+++ b/libgomp/testsuite/libgomp.oacc-c++/non-scalar-data.C
@@ -1,8 +1,7 @@
// Ensure that a non-scalar dummy arguments which are implicitly used inside
// offloaded regions are properly mapped using present_or_copy semantics.
-// { dg-xfail-if "TODO" { *-*-* } }
-// { dg-excess-errors "ICE" }
+// { dg-do run }
#include <cassert>
diff --git a/libgomp/testsuite/libgomp.oacc-c++/pr71959-aux.cc b/libgomp/testsuite/libgomp.oacc-c++/pr71959-aux.cc
new file mode 100644
index 00000000000..10a6eeb644c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c++/pr71959-aux.cc
@@ -0,0 +1,35 @@
+// { dg-do compile }
+
+#define STR1(X) #X
+#define STR2(X) STR1(X)
+#define LABEL(X) STR2(__USER_LABEL_PREFIX__) X
+
+struct Iter
+{
+ int *cursor;
+
+ void ctor (int *cursor_) asm (LABEL ("_ZN4IterC1EPi"));
+ int *point () const asm (LABEL ("_ZNK4Iter5pointEv"));
+};
+
+#pragma acc routine
+void Iter::ctor (int *cursor_)
+{
+ cursor = cursor_;
+}
+
+#pragma acc routine
+int *Iter::point () const
+{
+ return cursor;
+}
+
+void apply (int (*fn)(), Iter out) asm (LABEL ("_ZN5Apply5applyEPFivE4Iter"));
+
+#pragma acc routine
+void apply (int (*fn)(), struct Iter out)
+{ *out.point() = fn (); }
+
+extern "C" void __gxx_personality_v0 ()
+{
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c++/pr71959.C b/libgomp/testsuite/libgomp.oacc-c++/pr71959.C
new file mode 100644
index 00000000000..bf27a75c784
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c++/pr71959.C
@@ -0,0 +1,31 @@
+// { dg-additional-sources "pr71959-aux.cc" }
+
+// PR lto/71959 ICEd LTO due to mismatch between writing & reading behaviour
+
+struct Iter
+{
+ int *cursor;
+
+ Iter(int *cursor_) : cursor(cursor_) {}
+
+ int *point() const { return cursor; }
+};
+
+#pragma acc routine seq
+int one () { return 1; }
+
+struct Apply
+{
+ static void apply (int (*fn)(), Iter out)
+ { *out.point() = fn (); }
+};
+
+int main ()
+{
+ int x;
+
+#pragma acc parallel copyout(x)
+ Apply::apply (one, Iter (&x));
+
+ return x != 1;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c++/routine-1-auto.C b/libgomp/testsuite/libgomp.oacc-c++/routine-1-auto.C
index f4b54e55fa7..771a2734306 100644
--- a/libgomp/testsuite/libgomp.oacc-c++/routine-1-auto.C
+++ b/libgomp/testsuite/libgomp.oacc-c++/routine-1-auto.C
@@ -1,7 +1,5 @@
// Routine with "auto" return type.
-// { dg-additional-options "-fno-exceptions" }
-
#define TEMPLATE
#define TYPE int
#define RETURN_1 auto
diff --git a/libgomp/testsuite/libgomp.oacc-c++/routine-1-template-auto.C b/libgomp/testsuite/libgomp.oacc-c++/routine-1-template-auto.C
index 444f1f32a76..17bdaa0c1c1 100644
--- a/libgomp/testsuite/libgomp.oacc-c++/routine-1-template-auto.C
+++ b/libgomp/testsuite/libgomp.oacc-c++/routine-1-template-auto.C
@@ -1,7 +1,5 @@
// Templated routine with "auto" return type.
-// { dg-additional-options "-fno-exceptions" }
-
#define TEMPLATE template<typename TYPE>
#define RETURN_1 auto
#define RETURN_2
diff --git a/libgomp/testsuite/libgomp.oacc-c++/routine-1-template-trailing-return-type.C b/libgomp/testsuite/libgomp.oacc-c++/routine-1-template-trailing-return-type.C
index bfe2787d931..99faa865041 100644
--- a/libgomp/testsuite/libgomp.oacc-c++/routine-1-template-trailing-return-type.C
+++ b/libgomp/testsuite/libgomp.oacc-c++/routine-1-template-trailing-return-type.C
@@ -1,7 +1,5 @@
// Templated routine using trailing return type syntax.
-// { dg-additional-options "-fno-exceptions" }
-
#define TEMPLATE template<typename TYPE>
#define RETURN_1 auto
#define RETURN_2 -> TYPE
diff --git a/libgomp/testsuite/libgomp.oacc-c++/routine-1-template.C b/libgomp/testsuite/libgomp.oacc-c++/routine-1-template.C
index a7e0323d44f..89defb196b1 100644
--- a/libgomp/testsuite/libgomp.oacc-c++/routine-1-template.C
+++ b/libgomp/testsuite/libgomp.oacc-c++/routine-1-template.C
@@ -1,7 +1,5 @@
// Templated routine.
-// { dg-additional-options "-fno-exceptions" }
-
#define TEMPLATE template<typename TYPE>
#define RETURN_1 TYPE
#define RETURN_2
diff --git a/libgomp/testsuite/libgomp.oacc-c++/routine-1-trailing-return-type.C b/libgomp/testsuite/libgomp.oacc-c++/routine-1-trailing-return-type.C
index 3074ba47c2a..767e0ce4666 100644
--- a/libgomp/testsuite/libgomp.oacc-c++/routine-1-trailing-return-type.C
+++ b/libgomp/testsuite/libgomp.oacc-c++/routine-1-trailing-return-type.C
@@ -1,7 +1,5 @@
// Routine using trailing return type syntax.
-// { dg-additional-options "-fno-exceptions" }
-
#define TEMPLATE
#define TYPE int
#define RETURN_1 auto
diff --git a/libgomp/testsuite/libgomp.oacc-c++/this.C b/libgomp/testsuite/libgomp.oacc-c++/this.C
new file mode 100644
index 00000000000..510c690cf87
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c++/this.C
@@ -0,0 +1,43 @@
+#include <cstdlib>
+#include <iostream>
+using namespace std;
+
+class test {
+ public:
+ int a;
+
+ test ()
+ {
+ a = -1;
+#pragma acc enter data copyin (this[0:1])
+ }
+
+ ~test ()
+ {
+#pragma acc exit data delete (this[0:1])
+ }
+
+ void set (int i)
+ {
+ a = i;
+#pragma acc update device (this[0:1])
+ }
+
+ int get ()
+ {
+#pragma acc update host (this[0:1])
+ return a;
+ }
+};
+
+int
+main ()
+{
+ test t;
+
+ t.set (4);
+ if (t.get () != 4)
+ abort ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-dispatch-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-dispatch-1.c
new file mode 100644
index 00000000000..d929bfd80a4
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-dispatch-1.c
@@ -0,0 +1,353 @@
+/* Test dispatch of events to callbacks. */
+
+#undef NDEBUG
+#include <assert.h>
+
+#include <acc_prof.h>
+
+
+/* Use explicit 'copyin' clauses, to work around "'firstprivate'
+ optimizations", which will cause the value at the point of call to be used
+ (*before* any potential modifications done in callbacks), as opposed to its
+ address being taken, which then later gets dereferenced (*after* any
+ modifications done in callbacks). */
+#define COPYIN(...) copyin(__VA_ARGS__)
+
+
+#define DEBUG_printf(...) //__builtin_printf (__VA_ARGS__)
+
+
+static int state = -1;
+
+#define STATE_OP(state, op) \
+ do \
+ { \
+ typeof (state) state_o = (state); \
+ (void) state_o; \
+ (state)op; \
+ DEBUG_printf("state: %d -> %d\n", state_o, (state)); \
+ } \
+ while (0)
+
+
+static void cb_compute_construct_start_1 (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 0
+ || state == 10
+ || state == 30
+ || state == 41
+ || state == 51
+ || state == 91
+ || state == 101
+ || state == 151);
+ STATE_OP (state, ++);
+}
+
+static void cb_compute_construct_start_2 (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 1
+ || state == 11
+ || state == 40
+ || state == 50
+ || state == 90
+ || state == 100
+ || state == 150);
+ STATE_OP (state, ++);
+}
+
+static void cb_compute_construct_end_1 (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 14
+ || state == 21
+ || state == 32
+ || state == 42
+ || state == 80
+ || state == 103
+ || state == 152);
+ STATE_OP (state, ++);
+}
+
+static void cb_compute_construct_end_2 (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 13
+ || state == 43
+ || state == 102
+ || state == 154);
+ STATE_OP (state, ++);
+}
+
+static void cb_compute_construct_end_3 (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 12
+ || state == 20
+ || state == 31
+ || state == 44
+ || state == 81
+ || state == 104
+ || state == 153);
+ STATE_OP (state, ++);
+}
+
+
+static acc_prof_reg reg;
+static acc_prof_reg unreg;
+static acc_prof_lookup_func lookup;
+void acc_register_library (acc_prof_reg reg_, acc_prof_reg unreg_, acc_prof_lookup_func lookup_)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ reg = reg_;
+ unreg = unreg_;
+ lookup = lookup_;
+}
+
+
+int main()
+{
+ acc_register_library (acc_prof_register, acc_prof_unregister, acc_prof_lookup);
+
+ STATE_OP (state, = 0);
+ reg (acc_ev_compute_construct_start, cb_compute_construct_start_1, acc_reg);
+ reg (acc_ev_compute_construct_start, cb_compute_construct_start_1, acc_reg);
+ reg (acc_ev_compute_construct_start, cb_compute_construct_start_2, acc_reg);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 2);
+ }
+ assert (state == 2);
+
+ STATE_OP (state, = 10);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_1, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_3, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_3, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_3, acc_reg);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 12);
+ }
+ assert (state == 15);
+
+ STATE_OP (state, = 20);
+ unreg (acc_ev_compute_construct_start, cb_compute_construct_start_1, acc_toggle);
+ unreg (acc_ev_compute_construct_start, cb_compute_construct_start_2, acc_toggle);
+ unreg (acc_ev_compute_construct_start, cb_compute_construct_start_1, acc_reg);
+ unreg (acc_ev_compute_construct_start, cb_compute_construct_start_2, acc_reg);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_1, acc_toggle);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_toggle);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_3, acc_toggle);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_reg);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_reg);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_toggle);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_toggle);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 20);
+ }
+ assert (state == 20);
+
+ STATE_OP (state, = 30);
+ reg (acc_ev_compute_construct_start, cb_compute_construct_start_1, acc_toggle);
+ reg (acc_ev_compute_construct_start, cb_compute_construct_start_2, acc_toggle);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_1, acc_toggle);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_toggle);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_3, acc_toggle);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 31);
+ }
+ assert (state == 33);
+
+ STATE_OP (state, = 40);
+ reg (acc_ev_compute_construct_start, cb_compute_construct_start_2, acc_reg);
+ unreg (acc_ev_compute_construct_start, cb_compute_construct_start_1, acc_reg);
+ reg (acc_ev_compute_construct_start, cb_compute_construct_start_1, acc_reg);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_3, acc_reg);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_3, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_reg);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_1, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_1, acc_reg);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 42);
+ }
+ assert (state == 45);
+
+ STATE_OP (state, = 50);
+ unreg (acc_ev_compute_construct_end, NULL, acc_toggle);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 52);
+ }
+ assert (state == 52);
+
+ STATE_OP (state, = 60);
+ unreg (acc_ev_compute_construct_end, NULL, acc_toggle);
+ unreg (/* TODO */ (acc_event_t) 0, NULL, acc_toggle_per_thread);
+ unreg (/* TODO */ (acc_event_t) 0, NULL, acc_toggle_per_thread);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 60);
+ }
+ assert (state == 60);
+
+ STATE_OP (state, = 70);
+ unreg (acc_ev_compute_construct_start, NULL, acc_toggle);
+ reg (/* TODO */ (acc_event_t) 0, NULL, acc_toggle_per_thread);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 70);
+ }
+ assert (state == 70);
+
+ STATE_OP (state, = 80);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_reg);
+ reg (acc_ev_compute_construct_end, NULL, acc_toggle);
+ reg (/* TODO */ (acc_event_t) 0, NULL, acc_toggle_per_thread);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 80);
+ }
+ assert (state == 82);
+
+ STATE_OP (state, = 90);
+ reg (acc_ev_compute_construct_start, NULL, acc_toggle);
+ unreg (acc_ev_compute_construct_end, NULL, acc_toggle);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_2, acc_reg);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 92);
+ }
+ assert (state == 92);
+
+ STATE_OP (state, = 100);
+ reg (acc_ev_compute_construct_end, NULL, acc_toggle);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 102);
+ }
+ assert (state == 105);
+
+ STATE_OP (state, = 110);
+ unreg (/* TODO */ (acc_event_t) 0, NULL, acc_toggle);
+ unreg (/* TODO */ (acc_event_t) 0, NULL, acc_toggle);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 110);
+ }
+ assert (state == 110);
+
+ STATE_OP (state, = 120);
+ unreg (/* TODO */ (acc_event_t) 0, NULL, acc_toggle_per_thread);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 120);
+ }
+ assert (state == 120);
+
+ STATE_OP (state, = 130);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_3, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_3, acc_reg);
+ reg (/* TODO */ (acc_event_t) 0, NULL, acc_toggle);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 130);
+ }
+ assert (state == 130);
+
+ STATE_OP (state, = 140);
+ unreg (acc_ev_compute_construct_start, cb_compute_construct_start_1, acc_reg);
+ reg (acc_ev_compute_construct_start, cb_compute_construct_start_1, acc_reg);
+ unreg (acc_ev_compute_construct_end, cb_compute_construct_end_1, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end_1, acc_reg);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 140);
+ }
+ assert (state == 140);
+
+ STATE_OP (state, = 150);
+ reg (/* TODO */ (acc_event_t) 0, NULL, acc_toggle_per_thread);
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+ assert (state_init == 152);
+ }
+ assert (state == 155);
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-init-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-init-1.c
new file mode 100644
index 00000000000..b356feb8108
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-init-1.c
@@ -0,0 +1,316 @@
+/* Test dispatch of events to callbacks. */
+
+#undef NDEBUG
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <acc_prof.h>
+
+
+/* Use explicit 'copyin' clauses, to work around "'firstprivate'
+ optimizations", which will cause the value at the point of call to be used
+ (*before* any potential modifications done in callbacks), as opposed to its
+ address being taken, which then later gets dereferenced (*after* any
+ modifications done in callbacks). */
+#define COPYIN(...) copyin(__VA_ARGS__)
+
+
+#define DEBUG_printf(...) //__builtin_printf (__VA_ARGS__)
+
+
+static int state = -1;
+
+#define STATE_OP(state, op) \
+ do \
+ { \
+ typeof (state) state_o = (state); \
+ (void) state_o; \
+ (state)op; \
+ DEBUG_printf("state: %d -> %d\n", state_o, (state)); \
+ } \
+ while (0)
+
+
+static acc_device_t acc_device_type;
+static int acc_device_num;
+static int acc_async;
+
+
+struct tool_info
+{
+ acc_event_info event_info;
+ struct tool_info *nested;
+};
+struct tool_info *tool_info;
+
+static void cb_device_init_start (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 0
+ || state == 100);
+ STATE_OP (state, ++);
+
+ assert (tool_info == NULL);
+ tool_info = (struct tool_info *) malloc(sizeof *tool_info);
+ assert (tool_info != NULL);
+ tool_info->nested = NULL;
+
+ assert (prof_info->event_type == acc_ev_device_init_start);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ if (state == 1)
+ assert (prof_info->device_type == acc_device_host);
+ else
+ assert (prof_info->device_type == acc_device_default);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async_sync);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_runtime_api);
+ assert (event_info->other_event.implicit == 0);
+ assert (event_info->other_event.tool_info == NULL);
+
+ assert (api_info->device_api == acc_device_api_none);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ tool_info->event_info.other_event.event_type = event_info->other_event.event_type;
+ event_info->other_event.tool_info = tool_info;
+}
+
+static void cb_device_init_end (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 1
+ || state == 101);
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_device_init_start);
+
+ assert (prof_info->event_type == acc_ev_device_init_end);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ if (state == 2)
+ assert (prof_info->device_type == acc_device_host);
+ else
+ assert (prof_info->device_type == acc_device_default);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async_sync);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_runtime_api);
+ assert (event_info->other_event.implicit == 0);
+ assert (event_info->other_event.tool_info == tool_info);
+
+ assert (api_info->device_api == acc_device_api_none);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ free (tool_info);
+ tool_info = NULL;
+}
+
+static void cb_compute_construct_start (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 10
+ || state == 110);
+ STATE_OP (state, ++);
+
+ assert (tool_info == NULL);
+ tool_info = (struct tool_info *) malloc(sizeof *tool_info);
+ assert (tool_info != NULL);
+ tool_info->nested = NULL;
+
+ assert (prof_info->event_type == acc_ev_compute_construct_start);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == /* TODO acc_async */ acc_async_sync);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_parallel);
+ assert (event_info->other_event.implicit == 0);
+ assert (event_info->other_event.tool_info == NULL);
+
+ assert (api_info->device_api == acc_device_api_none);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ tool_info->event_info.other_event.event_type = event_info->other_event.event_type;
+ event_info->other_event.tool_info = tool_info;
+}
+
+static void cb_compute_construct_end (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 11
+ || state == 111);
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_compute_construct_start);
+ assert (tool_info->nested == NULL);
+
+ assert (prof_info->event_type == acc_ev_compute_construct_end);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ if (acc_device_type == acc_device_host)
+ assert (prof_info->async == acc_async_sync);
+ else
+ assert (prof_info->async == acc_async);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_parallel);
+ assert (event_info->other_event.implicit == 0);
+ assert (event_info->other_event.tool_info == tool_info);
+
+ if (acc_device_type == acc_device_host)
+ assert (api_info->device_api == acc_device_api_none);
+ else
+ assert (api_info->device_api == acc_device_api_cuda);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ free (tool_info);
+ tool_info = NULL;
+}
+
+
+static acc_prof_reg reg;
+static acc_prof_reg unreg;
+static acc_prof_lookup_func lookup;
+void acc_register_library (acc_prof_reg reg_, acc_prof_reg unreg_, acc_prof_lookup_func lookup_)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ reg = reg_;
+ unreg = unreg_;
+ lookup = lookup_;
+}
+
+
+int main()
+{
+ acc_register_library (acc_prof_register, acc_prof_unregister, acc_prof_lookup);
+
+ STATE_OP (state, = 0);
+ reg (acc_ev_device_init_start, cb_device_init_start, acc_reg);
+ reg (acc_ev_device_init_end, cb_device_init_end, acc_reg);
+ reg (acc_ev_compute_construct_start, cb_compute_construct_start, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end, acc_reg);
+ assert (state == 0);
+
+ acc_init (acc_device_host);
+ assert (state == 2);
+
+ STATE_OP (state, = 10);
+
+ acc_device_type = acc_get_device_type ();
+ acc_device_num = acc_get_device_num (acc_device_type);
+ acc_async = 12;
+
+ {
+ int state_init;
+#pragma acc parallel async(acc_async) COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+#pragma acc wait
+ assert (state_init == 11);
+ }
+ assert (state == 12);
+
+ STATE_OP (state, = 90);
+ acc_shutdown (acc_device_host);
+ assert (state == 90);
+
+
+ STATE_OP (state, = 100);
+ acc_init (acc_device_default);
+ assert (state == 102);
+
+ STATE_OP (state, = 110);
+
+ acc_device_type = acc_get_device_type ();
+ acc_device_num = acc_get_device_num (acc_device_type);
+ acc_async = 12;
+
+ {
+ int state_init;
+#pragma acc parallel async(acc_async) COPYIN(state) copyout(state_init)
+ {
+ state_init = state;
+ }
+#pragma acc wait
+ assert (state_init == 111);
+ }
+ assert (state == 112);
+
+ STATE_OP (state, = 190);
+ acc_shutdown (acc_device_default);
+ assert (state == 190);
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c
new file mode 100644
index 00000000000..7cfc364e411
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-kernels-1.c
@@ -0,0 +1,229 @@
+/* Test dispatch of events to callbacks. */
+
+#undef NDEBUG
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <acc_prof.h>
+
+
+/* Use explicit 'copyin' clauses, to work around "'firstprivate'
+ optimizations", which will cause the value at the point of call to be used
+ (*before* any potential modifications done in callbacks), as opposed to its
+ address being taken, which then later gets dereferenced (*after* any
+ modifications done in callbacks). */
+#define COPYIN(...) copyin(__VA_ARGS__)
+
+
+/* See the 'DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT' reference in
+ 'libgomp.texi'. */
+#define DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT 0
+
+
+#define DEBUG_printf(...) //__builtin_printf (__VA_ARGS__)
+
+
+volatile // TODO PR90488
+static int state = -1;
+
+#define STATE_OP(state, op) \
+ do \
+ { \
+ typeof (state) state_o = (state); \
+ (void) state_o; \
+ (state)op; \
+ DEBUG_printf("state: %d -> %d\n", state_o, (state)); \
+ } \
+ while (0)
+
+
+static acc_device_t acc_device_type;
+static int acc_device_num;
+static int num_gangs, num_workers, vector_length;
+
+
+static void cb_enqueue_launch_start (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (acc_device_type != acc_device_host);
+
+ assert (state == 0);
+ STATE_OP (state, = 1);
+
+ assert (prof_info->event_type == acc_ev_enqueue_launch_start);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async_sync);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->launch_event.event_type == prof_info->event_type);
+ assert (event_info->launch_event.valid_bytes == _ACC_LAUNCH_EVENT_INFO_VALID_BYTES);
+ assert (event_info->launch_event.parent_construct == acc_construct_parallel);
+ assert (event_info->launch_event.implicit == 1);
+ assert (event_info->launch_event.tool_info == NULL);
+ assert (event_info->launch_event.kernel_name != NULL);
+ {
+ const char *s = strstr (event_info->launch_event.kernel_name, "main");
+ assert (s != NULL);
+ s = strstr (s, "omp_fn");
+ assert (s != NULL);
+ }
+ if (num_gangs < 1)
+ assert (event_info->launch_event.num_gangs >= 1);
+ else
+ {
+#ifdef __OPTIMIZE__
+ assert (event_info->launch_event.num_gangs == num_gangs);
+#else
+ /* No parallelized OpenACC 'kernels' constructs. Unparallelized OpenACC
+ 'kernels' constructs must get launched as 1 x 1 x 1 GPU kernels. */
+ assert (event_info->launch_event.num_gangs == 1);
+#endif
+ }
+ if (num_workers < 1)
+ assert (event_info->launch_event.num_workers >= 1);
+ else
+ {
+#ifdef __OPTIMIZE__
+ assert (event_info->launch_event.num_workers == num_workers);
+#else
+ /* See 'num_gangs' above. */
+ assert (event_info->launch_event.num_workers == 1);
+#endif
+ }
+ if (vector_length < 1)
+ assert (event_info->launch_event.vector_length >= 1);
+ else if (acc_device_type == acc_device_nvidia) /* ... is special. */
+ assert (event_info->launch_event.vector_length == 32);
+ else
+ {
+#ifdef __OPTIMIZE__
+ assert (event_info->launch_event.vector_length == vector_length);
+#else
+ /* See 'num_gangs' above. */
+ assert (event_info->launch_event.vector_length == 1);
+#endif
+ }
+
+ if (acc_device_type == acc_device_host)
+ assert (api_info->device_api == acc_device_api_none);
+ else
+ assert (api_info->device_api == acc_device_api_cuda);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+}
+
+
+static acc_prof_reg reg;
+static acc_prof_reg unreg;
+static acc_prof_lookup_func lookup;
+void acc_register_library (acc_prof_reg reg_, acc_prof_reg unreg_, acc_prof_lookup_func lookup_)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ reg = reg_;
+ unreg = unreg_;
+ lookup = lookup_;
+}
+
+
+int main()
+{
+ acc_register_library (acc_prof_register, acc_prof_unregister, acc_prof_lookup);
+
+ STATE_OP (state, = 0);
+ reg (acc_ev_enqueue_launch_start, cb_enqueue_launch_start, acc_reg);
+ assert (state == 0);
+
+ acc_device_type = acc_get_device_type ();
+ acc_device_num = acc_get_device_num (acc_device_type);
+ assert (state == 0);
+
+ /* Parallelism dimensions: compiler/runtime decides. */
+ STATE_OP (state, = 0);
+ num_gangs = num_workers = vector_length = 0;
+ {
+#define N 100
+ int x[N];
+#pragma acc kernels
+ {
+ for (int i = 0; i < N; ++i)
+ x[i] = i * i;
+ }
+ if (acc_device_type == acc_device_host)
+ assert (state == 0); /* No 'acc_ev_enqueue_launch_start'. */
+ else
+ assert (state == 1);
+ for (int i = 0; i < N; ++i)
+ if (x[i] != i * i)
+ __builtin_abort ();
+#undef N
+ }
+
+ /* Parallelism dimensions: literal. */
+ STATE_OP (state, = 0);
+ num_gangs = 30;
+ num_workers = 3;
+ vector_length = 5;
+ {
+#define N 100
+ int x[N];
+#pragma acc kernels \
+ num_gangs (30) num_workers (3) vector_length (5)
+ /* { dg-prune-output "using vector_length \\(32\\), ignoring 5" } */
+ {
+ for (int i = 0; i < N; ++i)
+ x[i] = i * i;
+ }
+ if (acc_device_type == acc_device_host)
+ assert (state == 0); /* No 'acc_ev_enqueue_launch_start'. */
+ else
+ assert (state == 1);
+ for (int i = 0; i < N; ++i)
+ if (x[i] != i * i)
+ __builtin_abort ();
+#undef N
+ }
+
+ /* Parallelism dimensions: variable. */
+ STATE_OP (state, = 0);
+ num_gangs = 22;
+ num_workers = 5;
+ vector_length = 7;
+ {
+#define N 100
+ int x[N];
+#pragma acc kernels \
+ num_gangs (num_gangs) num_workers (num_workers) vector_length (vector_length)
+ /* { dg-prune-output "using vector_length \\(32\\), ignoring runtime setting" } */
+ {
+ for (int i = 0; i < N; ++i)
+ x[i] = i * i;
+ }
+ if (acc_device_type == acc_device_host)
+ assert (state == 0); /* No 'acc_ev_enqueue_launch_start'. */
+ else
+ assert (state == 1);
+ for (int i = 0; i < N; ++i)
+ if (x[i] != i * i)
+ __builtin_abort ();
+#undef N
+ }
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-parallel-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-parallel-1.c
new file mode 100644
index 00000000000..ac6eb48cbbe
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-parallel-1.c
@@ -0,0 +1,719 @@
+/* Test dispatch of events to callbacks. */
+
+#undef NDEBUG
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <acc_prof.h>
+
+
+/* Use explicit 'copyin' clauses, to work around "'firstprivate'
+ optimizations", which will cause the value at the point of call to be used
+ (*before* any potential modifications done in callbacks), as opposed to its
+ address being taken, which then later gets dereferenced (*after* any
+ modifications done in callbacks). */
+#define COPYIN(...) copyin(__VA_ARGS__)
+
+
+/* See the 'DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT' reference in
+ libgomp.texi. */
+#define DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT 0
+
+
+/* Do we expect to see 'acc_ev_exit_data_start' and 'acc_ev_exit_data_end'
+ after a compute construct with an 'async' clause? */
+#define ASYNC_EXIT_DATA 1
+
+
+#define DEBUG_printf(...) //__builtin_printf (__VA_ARGS__)
+
+
+static int state = -1;
+
+#define STATE_OP(state, op) \
+ do \
+ { \
+ typeof (state) state_o = (state); \
+ (void) state_o; \
+ (state)op; \
+ DEBUG_printf("state: %d -> %d\n", state_o, (state)); \
+ } \
+ while (0)
+
+
+static acc_device_t acc_device_type;
+static int acc_device_num;
+static int acc_async;
+
+
+struct tool_info
+{
+ acc_event_info event_info;
+ struct tool_info *nested;
+};
+struct tool_info *tool_info;
+
+static void cb_device_init_start (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+#if DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT
+ assert (state == 1
+ || state == 101);
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_compute_construct_start);
+ assert (tool_info->nested == NULL);
+ tool_info->nested = (struct tool_info *) malloc(sizeof *tool_info);
+ assert (tool_info->nested != NULL);
+ tool_info->nested->nested = NULL;
+#else
+ assert (state == 0
+ || state == 100);
+ STATE_OP (state, ++);
+
+ assert (tool_info == NULL);
+ tool_info = (struct tool_info *) malloc(sizeof *tool_info);
+ assert (tool_info != NULL);
+ tool_info->nested = NULL;
+#endif
+
+ assert (prof_info->event_type == acc_ev_device_init_start);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_default);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async_sync);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_parallel);
+ assert (event_info->other_event.implicit == 1);
+ assert (event_info->other_event.tool_info == NULL);
+
+ assert (api_info->device_api == acc_device_api_none);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+#if DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT
+ tool_info->nested->event_info.other_event.event_type = event_info->other_event.event_type;
+ event_info->other_event.tool_info = tool_info->nested;
+#else
+ tool_info->event_info.other_event.event_type = event_info->other_event.event_type;
+ event_info->other_event.tool_info = tool_info;
+#endif
+}
+
+static void cb_device_init_end (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+#if DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT
+ assert (state == 2
+ || state == 102);
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_compute_construct_start);
+ assert (tool_info->nested != NULL);
+ assert (tool_info->nested->event_info.other_event.event_type == acc_ev_device_init_start);
+#else
+ assert (state == 1
+ || state == 101);
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_device_init_start);
+#endif
+
+ assert (prof_info->event_type == acc_ev_device_init_end);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_default);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async_sync);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_parallel);
+ assert (event_info->other_event.implicit == 1);
+#if DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT
+ assert (event_info->other_event.tool_info == tool_info->nested);
+#else
+ assert (event_info->other_event.tool_info == tool_info);
+#endif
+
+ assert (api_info->device_api == acc_device_api_none);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+#if DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT
+ free (tool_info->nested);
+ tool_info->nested = NULL;
+#else
+ free (tool_info);
+ tool_info = NULL;
+#endif
+}
+
+static void cb_enter_data_start (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 3
+ || state == 103);
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_compute_construct_start);
+ assert (tool_info->nested == NULL);
+ tool_info->nested = (struct tool_info *) malloc(sizeof *tool_info);
+ assert (tool_info->nested != NULL);
+ tool_info->nested->nested = NULL;
+
+ assert (prof_info->event_type == acc_ev_enter_data_start);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_parallel);
+ assert (event_info->other_event.implicit == 1);
+ assert (event_info->other_event.tool_info == NULL);
+
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ tool_info->nested->event_info.other_event.event_type = event_info->other_event.event_type;
+ event_info->other_event.tool_info = tool_info->nested;
+}
+
+static void cb_enter_data_end (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 4
+ || state == 104);
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_compute_construct_start);
+ assert (tool_info->nested != NULL);
+ assert (tool_info->nested->event_info.other_event.event_type == acc_ev_enter_data_start);
+
+ assert (prof_info->event_type == acc_ev_enter_data_end);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_parallel);
+ assert (event_info->other_event.implicit == 1);
+ assert (event_info->other_event.tool_info == tool_info->nested);
+
+ if (acc_device_type == acc_device_host)
+ assert (api_info->device_api == acc_device_api_none);
+ else
+ assert (api_info->device_api == acc_device_api_cuda);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ free (tool_info->nested);
+ tool_info->nested = NULL;
+}
+
+static void cb_exit_data_start (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 7
+#if ASYNC_EXIT_DATA
+ || state == 107
+#endif
+ );
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_compute_construct_start);
+ assert (tool_info->nested == NULL);
+ tool_info->nested = (struct tool_info *) malloc(sizeof *tool_info);
+ assert (tool_info->nested != NULL);
+ tool_info->nested->nested = NULL;
+
+ assert (prof_info->event_type == acc_ev_exit_data_start);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_parallel);
+ assert (event_info->other_event.implicit == 1);
+ assert (event_info->other_event.tool_info == NULL);
+
+ if (acc_device_type == acc_device_host)
+ assert (api_info->device_api == acc_device_api_none);
+ else
+ assert (api_info->device_api == acc_device_api_cuda);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ tool_info->nested->event_info.other_event.event_type = event_info->other_event.event_type;
+ event_info->other_event.tool_info = tool_info->nested;
+}
+
+static void cb_exit_data_end (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (state == 8
+#if ASYNC_EXIT_DATA
+ || state == 108
+#endif
+ );
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_compute_construct_start);
+ assert (tool_info->nested != NULL);
+ assert (tool_info->nested->event_info.other_event.event_type == acc_ev_exit_data_start);
+
+ assert (prof_info->event_type == acc_ev_exit_data_end);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_parallel);
+ assert (event_info->other_event.implicit == 1);
+ assert (event_info->other_event.tool_info == tool_info->nested);
+
+ if (acc_device_type == acc_device_host)
+ assert (api_info->device_api == acc_device_api_none);
+ else
+ assert (api_info->device_api == acc_device_api_cuda);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ free (tool_info->nested);
+ tool_info->nested = NULL;
+}
+
+static void cb_compute_construct_start (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+#if DEVICE_INIT_INSIDE_COMPUTE_CONSTRUCT
+ assert (state == 0
+ || state == 100);
+ if (state == 100)
+ {
+ /* Compensate for the missing 'acc_ev_device_init_start' and
+ 'acc_ev_device_init_end'. */
+ state += 2;
+ }
+#else
+ if (state == 100)
+ {
+ /* Compensate for the missing 'acc_ev_device_init_start' and
+ 'acc_ev_device_init_end'. */
+ state += 2;
+ }
+ assert (state == 2
+ || state == 102);
+#endif
+ STATE_OP (state, ++);
+
+ assert (tool_info == NULL);
+ tool_info = (struct tool_info *) malloc(sizeof *tool_info);
+ assert (tool_info != NULL);
+ tool_info->nested = NULL;
+
+ assert (prof_info->event_type == acc_ev_compute_construct_start);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == /* TODO acc_async */ acc_async_sync);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_parallel);
+ assert (event_info->other_event.implicit == 0);
+ assert (event_info->other_event.tool_info == NULL);
+
+ assert (api_info->device_api == acc_device_api_none);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ tool_info->event_info.other_event.event_type = event_info->other_event.event_type;
+ event_info->other_event.tool_info = tool_info;
+
+ if (acc_device_type == acc_device_host)
+ {
+ /* Compensate for the missing 'acc_ev_enter_data_start'. */
+ state += 1;
+ }
+}
+
+static void cb_compute_construct_end (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ if (acc_device_type == acc_device_host)
+ {
+ /* Compensate for the missing 'acc_ev_enter_data_end'. */
+ state += 1;
+ /* Compensate for the missing 'acc_ev_enqueue_launch_start' and
+ 'acc_ev_enqueue_launch_end'. */
+ state += 2;
+ /* Compensate for the missing 'acc_ev_exit_data_start' and
+ 'acc_ev_exit_data_end'. */
+ state += 2;
+ }
+#if !ASYNC_EXIT_DATA
+ else if (acc_async != acc_async_sync)
+ {
+ /* Compensate for the missing 'acc_ev_exit_data_start' and
+ 'acc_ev_exit_data_end'. */
+ state += 2;
+ }
+#endif
+ assert (state == 9
+ || state == 109);
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_compute_construct_start);
+ assert (tool_info->nested == NULL);
+
+ assert (prof_info->event_type == acc_ev_compute_construct_end);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ if (acc_device_type == acc_device_host)
+ assert (prof_info->async == acc_async_sync);
+ else
+ assert (prof_info->async == acc_async);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->other_event.event_type == prof_info->event_type);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (event_info->other_event.parent_construct == acc_construct_parallel);
+ assert (event_info->other_event.implicit == 0);
+ assert (event_info->other_event.tool_info == tool_info);
+
+ if (acc_device_type == acc_device_host)
+ assert (api_info->device_api == acc_device_api_none);
+ else
+ assert (api_info->device_api == acc_device_api_cuda);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ free (tool_info);
+ tool_info = NULL;
+}
+
+static void cb_enqueue_launch_start (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (acc_device_type != acc_device_host);
+
+ assert (state == 5
+ || state == 105);
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_compute_construct_start);
+ assert (tool_info->nested == NULL);
+ tool_info->nested = (struct tool_info *) malloc(sizeof *tool_info);
+ assert (tool_info->nested != NULL);
+ tool_info->nested->nested = NULL;
+
+ assert (prof_info->event_type == acc_ev_enqueue_launch_start);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->launch_event.event_type == prof_info->event_type);
+ assert (event_info->launch_event.valid_bytes == _ACC_LAUNCH_EVENT_INFO_VALID_BYTES);
+ assert (event_info->launch_event.parent_construct == acc_construct_parallel);
+ assert (event_info->launch_event.implicit == 1);
+ assert (event_info->launch_event.tool_info == NULL);
+ assert (event_info->launch_event.kernel_name != NULL);
+ {
+ const char *s = strstr (event_info->launch_event.kernel_name, "main");
+ assert (s != NULL);
+ s = strstr (s, "omp_fn");
+ assert (s != NULL);
+ }
+ assert (event_info->launch_event.num_gangs >= 1);
+ assert (event_info->launch_event.num_workers >= 1);
+ assert (event_info->launch_event.vector_length >= 1);
+
+ if (acc_device_type == acc_device_host)
+ assert (api_info->device_api == acc_device_api_none);
+ else
+ assert (api_info->device_api == acc_device_api_cuda);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ tool_info->nested->event_info.launch_event.event_type = event_info->launch_event.event_type;
+ tool_info->nested->event_info.launch_event.kernel_name = strdup (event_info->launch_event.kernel_name);
+ tool_info->nested->event_info.launch_event.num_gangs = event_info->launch_event.num_gangs;
+ tool_info->nested->event_info.launch_event.num_workers = event_info->launch_event.num_workers;
+ tool_info->nested->event_info.launch_event.vector_length = event_info->launch_event.vector_length;
+ event_info->other_event.tool_info = tool_info->nested;
+}
+
+static void cb_enqueue_launch_end (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ assert (acc_device_type != acc_device_host);
+
+ assert (state == 6
+ || state == 106);
+ STATE_OP (state, ++);
+
+ assert (tool_info != NULL);
+ assert (tool_info->event_info.other_event.event_type == acc_ev_compute_construct_start);
+ assert (tool_info->nested != NULL);
+ assert (tool_info->nested->event_info.launch_event.event_type == acc_ev_enqueue_launch_start);
+ assert (tool_info->nested->event_info.launch_event.kernel_name != NULL);
+ assert (tool_info->nested->event_info.launch_event.num_gangs >= 1);
+ assert (tool_info->nested->event_info.launch_event.num_workers >= 1);
+ assert (tool_info->nested->event_info.launch_event.vector_length >= 1);
+
+ assert (prof_info->event_type == acc_ev_enqueue_launch_end);
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (prof_info->version == _ACC_PROF_INFO_VERSION);
+ assert (prof_info->device_type == acc_device_type);
+ assert (prof_info->device_number == acc_device_num);
+ assert (prof_info->thread_id == -1);
+ assert (prof_info->async == acc_async);
+ assert (prof_info->async_queue == prof_info->async);
+ assert (prof_info->src_file == NULL);
+ assert (prof_info->func_name == NULL);
+ assert (prof_info->line_no == -1);
+ assert (prof_info->end_line_no == -1);
+ assert (prof_info->func_line_no == -1);
+ assert (prof_info->func_end_line_no == -1);
+
+ assert (event_info->launch_event.event_type == prof_info->event_type);
+ assert (event_info->launch_event.valid_bytes == _ACC_LAUNCH_EVENT_INFO_VALID_BYTES);
+ assert (event_info->launch_event.parent_construct == acc_construct_parallel);
+ assert (event_info->launch_event.implicit == 1);
+ assert (event_info->launch_event.tool_info == tool_info->nested);
+ assert (event_info->launch_event.kernel_name != NULL);
+ assert (strcmp (event_info->launch_event.kernel_name, tool_info->nested->event_info.launch_event.kernel_name) == 0);
+ assert (event_info->launch_event.num_gangs == tool_info->nested->event_info.launch_event.num_gangs);
+ assert (event_info->launch_event.num_workers == tool_info->nested->event_info.launch_event.num_workers);
+ assert (event_info->launch_event.vector_length == tool_info->nested->event_info.launch_event.vector_length);
+
+ if (acc_device_type == acc_device_host)
+ assert (api_info->device_api == acc_device_api_none);
+ else
+ assert (api_info->device_api == acc_device_api_cuda);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+ assert (api_info->device_type == prof_info->device_type);
+ assert (api_info->vendor == -1);
+ assert (api_info->device_handle == NULL);
+ assert (api_info->context_handle == NULL);
+ assert (api_info->async_handle == NULL);
+
+ free ((void *) tool_info->nested->event_info.launch_event.kernel_name);
+ free (tool_info->nested);
+ tool_info->nested = NULL;
+}
+
+
+static acc_prof_reg reg;
+static acc_prof_reg unreg;
+static acc_prof_lookup_func lookup;
+void acc_register_library (acc_prof_reg reg_, acc_prof_reg unreg_, acc_prof_lookup_func lookup_)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ reg = reg_;
+ unreg = unreg_;
+ lookup = lookup_;
+}
+
+
+int main()
+{
+ acc_register_library (acc_prof_register, acc_prof_unregister, acc_prof_lookup);
+
+ STATE_OP (state, = 0);
+ reg (acc_ev_device_init_start, cb_device_init_start, acc_reg);
+ reg (acc_ev_device_init_end, cb_device_init_end, acc_reg);
+ reg (acc_ev_enter_data_start, cb_enter_data_start, acc_reg);
+ reg (acc_ev_enter_data_end, cb_enter_data_end, acc_reg);
+ reg (acc_ev_exit_data_start, cb_exit_data_start, acc_reg);
+ reg (acc_ev_exit_data_end, cb_exit_data_end, acc_reg);
+ reg (acc_ev_compute_construct_start, cb_compute_construct_start, acc_reg);
+ reg (acc_ev_compute_construct_end, cb_compute_construct_end, acc_reg);
+ reg (acc_ev_enqueue_launch_start, cb_enqueue_launch_start, acc_reg);
+ reg (acc_ev_enqueue_launch_end, cb_enqueue_launch_end, acc_reg);
+ assert (state == 0);
+
+ acc_device_type = acc_get_device_type ();
+ acc_device_num = acc_get_device_num (acc_device_type);
+ acc_async = acc_async_sync;
+ assert (state == 0);
+
+ {
+ int state_init;
+#pragma acc parallel COPYIN(state) copyout(state_init)
+ {
+ asm volatile ("" : : : "memory"); // TODO PR90488
+
+ state_init = state;
+ }
+ assert (state_init == 4);
+ }
+ assert (state == 10);
+
+ STATE_OP (state, = 100);
+
+ acc_async = 12;
+ {
+ int state_init;
+#pragma acc parallel async(acc_async) COPYIN(state) copyout(state_init)
+ {
+ asm volatile ("" : : : "memory"); // TODO PR90488
+
+ state_init = state;
+ }
+#pragma acc wait
+ assert (state_init == 104);
+ }
+ assert (state == 110);
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-valid_bytes-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-valid_bytes-1.c
new file mode 100644
index 00000000000..5b58c51d4c4
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-valid_bytes-1.c
@@ -0,0 +1,226 @@
+/* Test the 'valid_bytes' magic. */
+
+#undef NDEBUG
+#include <assert.h>
+
+#include <acc_prof.h>
+
+
+#define DEBUG_printf(...) //__builtin_printf (__VA_ARGS__)
+
+
+static int ev_count_data;
+
+static void cb_data_event (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s %d\n", __FUNCTION__, prof_info->event_type);
+
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (event_info->data_event.valid_bytes == _ACC_DATA_EVENT_INFO_VALID_BYTES);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+
+ ++ev_count_data;
+}
+
+static int ev_count_launch;
+
+static void cb_launch_event (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s %d\n", __FUNCTION__, prof_info->event_type);
+
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (event_info->launch_event.valid_bytes == _ACC_LAUNCH_EVENT_INFO_VALID_BYTES);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+
+ ++ev_count_launch;
+}
+
+static int ev_count_other;
+
+static void cb_other_event (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s %d\n", __FUNCTION__, prof_info->event_type);
+
+ assert (prof_info->valid_bytes == _ACC_PROF_INFO_VALID_BYTES);
+ assert (event_info->other_event.valid_bytes == _ACC_OTHER_EVENT_INFO_VALID_BYTES);
+ assert (api_info->valid_bytes == _ACC_API_INFO_VALID_BYTES);
+
+ ++ev_count_other;
+}
+
+
+void acc_register_library (acc_prof_reg reg_, acc_prof_reg unreg_, acc_prof_lookup_func lookup_)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ reg_ (acc_ev_device_init_start, cb_other_event, acc_reg);
+ reg_ (acc_ev_device_init_end, cb_other_event, acc_reg);
+ reg_ (acc_ev_device_shutdown_start, cb_other_event, acc_reg);
+ reg_ (acc_ev_device_shutdown_end, cb_other_event, acc_reg);
+ reg_ (acc_ev_runtime_shutdown, cb_other_event, acc_reg);
+ reg_ (acc_ev_create, cb_data_event, acc_reg);
+ reg_ (acc_ev_delete, cb_data_event, acc_reg);
+ reg_ (acc_ev_alloc, cb_data_event, acc_reg);
+ reg_ (acc_ev_free, cb_data_event, acc_reg);
+ reg_ (acc_ev_enter_data_start, cb_other_event, acc_reg);
+ reg_ (acc_ev_enter_data_end, cb_other_event, acc_reg);
+ reg_ (acc_ev_exit_data_start, cb_other_event, acc_reg);
+ reg_ (acc_ev_exit_data_end, cb_other_event, acc_reg);
+ reg_ (acc_ev_update_start, cb_other_event, acc_reg);
+ reg_ (acc_ev_update_end, cb_other_event, acc_reg);
+ reg_ (acc_ev_compute_construct_start, cb_other_event, acc_reg);
+ reg_ (acc_ev_compute_construct_end, cb_other_event, acc_reg);
+ reg_ (acc_ev_enqueue_launch_start, cb_launch_event, acc_reg);
+ reg_ (acc_ev_enqueue_launch_end, cb_launch_event, acc_reg);
+ reg_ (acc_ev_enqueue_upload_start, cb_data_event, acc_reg);
+ reg_ (acc_ev_enqueue_upload_end, cb_data_event, acc_reg);
+ reg_ (acc_ev_enqueue_download_start, cb_data_event, acc_reg);
+ reg_ (acc_ev_enqueue_download_end, cb_data_event, acc_reg);
+ reg_ (acc_ev_wait_start, cb_other_event, acc_reg);
+ reg_ (acc_ev_wait_end, cb_other_event, acc_reg);
+}
+
+
+/* Basic struct. */
+typedef struct A
+{
+ int a;
+ int b;
+#define VALID_BYTES_A \
+ _ACC_PROF_VALID_BYTES_STRUCT (A, b, \
+ _ACC_PROF_VALID_BYTES_BASICTYPE (int))
+} A;
+
+/* Add a 'char' field. */
+typedef struct B
+{
+ int a;
+ int b;
+ char c;
+#define VALID_BYTES_B \
+ _ACC_PROF_VALID_BYTES_STRUCT (B, c, \
+ _ACC_PROF_VALID_BYTES_BASICTYPE (char))
+} B;
+
+/* Add another 'char' field. */
+typedef struct C
+{
+ int a;
+ int b;
+ char c, d;
+#define VALID_BYTES_C \
+ _ACC_PROF_VALID_BYTES_STRUCT (C, d, \
+ _ACC_PROF_VALID_BYTES_BASICTYPE (char))
+} C;
+
+/* Add two 'void *' fields. */
+typedef struct D
+{
+ int a;
+ int b;
+ char c, d;
+ void *e;
+ void *f;
+#define VALID_BYTES_D \
+ _ACC_PROF_VALID_BYTES_STRUCT (D, f, \
+ _ACC_PROF_VALID_BYTES_BASICTYPE (void *))
+} D;
+
+/* Add another three 'char' fields. */
+typedef struct E
+{
+ int a;
+ int b;
+ char c, d;
+ void *e;
+ void *f;
+ char g, h, i;
+#define VALID_BYTES_E \
+ _ACC_PROF_VALID_BYTES_STRUCT (E, i, \
+ _ACC_PROF_VALID_BYTES_BASICTYPE (char))
+} E;
+
+
+int main()
+{
+ acc_register_library (acc_prof_register, acc_prof_unregister, acc_prof_lookup);
+
+ A A1;
+ DEBUG_printf ("s=%zd, vb=%zd\n", sizeof A1, VALID_BYTES_A);
+ assert (VALID_BYTES_A <= sizeof A1);
+ DEBUG_printf ("&A1=%p, &A1.b=%p\n", &A1, &A1.b);
+ assert (((char *) &A1) + VALID_BYTES_A == (char *) (&A1.b + 1));
+
+ B B1;
+ DEBUG_printf ("s=%zd, vb=%zd\n", sizeof B1, VALID_BYTES_B);
+ assert (VALID_BYTES_B <= sizeof B1);
+ DEBUG_printf ("&B1=%p, &B1.c=%p\n", &B1, &B1.c);
+ assert (((char *) &B1) + VALID_BYTES_B == (char *) (&B1.c + 1));
+
+ assert (VALID_BYTES_B == VALID_BYTES_A + 1 * sizeof (char));
+
+ C C1;
+ DEBUG_printf ("s=%zd, vb=%zd\n", sizeof C1, VALID_BYTES_C);
+ assert (VALID_BYTES_C <= sizeof C1);
+ DEBUG_printf ("&C1=%p, &C1.d=%p\n", &C1, &C1.d);
+ assert (((char *) &C1) + VALID_BYTES_C == (char *) (&C1.d + 1));
+
+ assert (VALID_BYTES_C == VALID_BYTES_B + 1 * sizeof (char));
+
+ D D1;
+ DEBUG_printf ("s=%zd, vb=%zd\n", sizeof D1, VALID_BYTES_D);
+ assert (VALID_BYTES_D <= sizeof D1);
+ DEBUG_printf ("&D1=%p, &D1.f=%p\n", &D1, &D1.f);
+ assert (((char *) &D1) + VALID_BYTES_D == (char *) (&D1.f + 1));
+
+ assert (VALID_BYTES_D > VALID_BYTES_C);
+
+ E E1;
+ DEBUG_printf ("s=%zd, vb=%zd\n", sizeof E1, VALID_BYTES_E);
+ assert (VALID_BYTES_E <= sizeof E1);
+ DEBUG_printf ("&E1=%p, &E1.i=%p\n", &E1, &E1.i);
+ assert (((char *) &E1) + VALID_BYTES_E == (char *) (&E1.i + 1));
+
+ assert (VALID_BYTES_E == VALID_BYTES_D + 3 * sizeof (char));
+
+ ev_count_data = 0;
+ ev_count_launch = 0;
+ ev_count_other = 0;
+
+ /* Trigger tests done in 'cb_*' functions. */
+ int host;
+#pragma acc parallel copyout (host)
+ {
+ asm volatile ("" : : : "memory"); // TODO PR90488
+
+ host = acc_on_device (acc_device_host);
+ }
+
+ DEBUG_printf ("ev_count_data = %d\n", ev_count_data);
+ if (host)
+ assert (ev_count_data == 0);
+ else
+ {
+ /* We don't know exactly how many data events to expect, but we at least
+ expect some. */
+ assert (ev_count_data > 0);
+ }
+
+ DEBUG_printf ("ev_count_launch = %d\n", ev_count_launch);
+ if (host)
+ assert (ev_count_data == 0);
+ else
+ {
+ /* We expect two launch events, 'acc_ev_enqueue_launch_start',
+ 'acc_ev_enqueue_launch_end'. */
+ assert (ev_count_launch == 2);
+ }
+
+ DEBUG_printf ("ev_count_other = %d\n", ev_count_other);
+ /* We don't know exactly how many other events to expect, but we at least
+ expect 'acc_ev_device_init_start', 'acc_ev_device_init_end',
+ 'acc_ev_compute_construct_start', 'acc_ev_compute_construct_end'. */
+ assert (ev_count_other >= 4);
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-version-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-version-1.c
new file mode 100644
index 00000000000..f5378687167
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_prof-version-1.c
@@ -0,0 +1,76 @@
+/* Test the 'version' field of 'acc_prof_info'. */
+
+#undef NDEBUG
+#include <assert.h>
+
+#include <acc_prof.h>
+
+
+#define DEBUG_printf(...) //__builtin_printf (__VA_ARGS__)
+
+
+static int ev_count;
+
+
+static void cb_any_event (acc_prof_info *prof_info, acc_event_info *event_info, acc_api_info *api_info)
+{
+ DEBUG_printf ("%s %d\n", __FUNCTION__, prof_info->event_type);
+
+ assert (prof_info->version == 201711);
+
+ ++ev_count;
+}
+
+
+void acc_register_library (acc_prof_reg reg_, acc_prof_reg unreg_, acc_prof_lookup_func lookup_)
+{
+ DEBUG_printf ("%s\n", __FUNCTION__);
+
+ reg_ (acc_ev_device_init_start, cb_any_event, acc_reg);
+ reg_ (acc_ev_device_init_end, cb_any_event, acc_reg);
+ reg_ (acc_ev_device_shutdown_start, cb_any_event, acc_reg);
+ reg_ (acc_ev_device_shutdown_end, cb_any_event, acc_reg);
+ reg_ (acc_ev_runtime_shutdown, cb_any_event, acc_reg);
+ reg_ (acc_ev_create, cb_any_event, acc_reg);
+ reg_ (acc_ev_delete, cb_any_event, acc_reg);
+ reg_ (acc_ev_alloc, cb_any_event, acc_reg);
+ reg_ (acc_ev_free, cb_any_event, acc_reg);
+ reg_ (acc_ev_enter_data_start, cb_any_event, acc_reg);
+ reg_ (acc_ev_enter_data_end, cb_any_event, acc_reg);
+ reg_ (acc_ev_exit_data_start, cb_any_event, acc_reg);
+ reg_ (acc_ev_exit_data_end, cb_any_event, acc_reg);
+ reg_ (acc_ev_update_start, cb_any_event, acc_reg);
+ reg_ (acc_ev_update_end, cb_any_event, acc_reg);
+ reg_ (acc_ev_compute_construct_start, cb_any_event, acc_reg);
+ reg_ (acc_ev_compute_construct_end, cb_any_event, acc_reg);
+ reg_ (acc_ev_enqueue_launch_start, cb_any_event, acc_reg);
+ reg_ (acc_ev_enqueue_launch_end, cb_any_event, acc_reg);
+ reg_ (acc_ev_enqueue_upload_start, cb_any_event, acc_reg);
+ reg_ (acc_ev_enqueue_upload_end, cb_any_event, acc_reg);
+ reg_ (acc_ev_enqueue_download_start, cb_any_event, acc_reg);
+ reg_ (acc_ev_enqueue_download_end, cb_any_event, acc_reg);
+ reg_ (acc_ev_wait_start, cb_any_event, acc_reg);
+ reg_ (acc_ev_wait_end, cb_any_event, acc_reg);
+}
+
+
+int main()
+{
+ acc_register_library (acc_prof_register, acc_prof_unregister, acc_prof_lookup);
+
+ ev_count = 0;
+
+ /* Trigger tests done in 'cb_*' functions. */
+#pragma acc parallel
+ {
+ asm volatile ("" : : : "memory"); // TODO PR90488
+ }
+
+ DEBUG_printf ("ev_count = %d\n", ev_count);
+ /* We don't know exactly how many events to expect, but we at least expect
+ 'acc_ev_device_init_start', 'acc_ev_device_init_end',
+ 'acc_ev_compute_construct_start', 'acc_ev_compute_construct_end'. */
+ assert (ev_count >= 4);
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_set_cuda_stream-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_set_cuda_stream-1.c
new file mode 100644
index 00000000000..93981ff5cb7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_set_cuda_stream-1.c
@@ -0,0 +1,42 @@
+/* Verify expected nvptx plugin behavior for "acc_set_cuda_stream" for
+ "acc_async_sync". */
+
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-set-target-env-var GOMP_DEBUG "1" } */
+
+#undef NDEBUG
+#include <assert.h>
+#include <openacc.h>
+
+int main(void)
+{
+ int async = 42;
+
+ /* Initialize. */
+#pragma acc parallel async(acc_async_sync)
+ ;
+#pragma acc parallel async(async)
+ ;
+#pragma acc wait
+
+ void *cuda_stream_sync = acc_get_cuda_stream (acc_async_sync);
+ assert (cuda_stream_sync == NULL);
+ void *cuda_stream_async = acc_get_cuda_stream (async);
+ assert (cuda_stream_async != NULL);
+ int ret = acc_set_cuda_stream (acc_async_sync, cuda_stream_async);
+ assert (ret == 0);
+ void *cuda_stream_sync_ = acc_get_cuda_stream (acc_async_sync);
+ assert (cuda_stream_sync_ == cuda_stream_sync);
+ void *cuda_stream_async_ = acc_get_cuda_stream (async);
+ assert (cuda_stream_async_ == cuda_stream_async);
+
+#pragma acc parallel async(acc_async_sync)
+ ;
+#pragma acc parallel async(async)
+ ;
+#pragma acc wait
+
+ return 0;
+}
+
+/* { dg-output "Refusing request to set CUDA stream associated with \"acc_async_sync\"" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/async_queue-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/async_queue-1.c
new file mode 100644
index 00000000000..544b19fe663
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/async_queue-1.c
@@ -0,0 +1,127 @@
+/* Test mapping of async values to specific underlying queues. */
+
+#undef NDEBUG
+#include <assert.h>
+#include <openacc.h>
+
+/* This is implemented in terms of the "acc_get_cuda_stream" interface. */
+
+struct
+{
+ int async;
+ void *cuda_stream;
+} queues[] = { { acc_async_sync, NULL },
+ { acc_async_noval, NULL },
+ { 0, NULL },
+ { 1, NULL },
+ { 2, NULL },
+ { 36, NULL },
+ { 1982, NULL } };
+const size_t queues_n = sizeof queues / sizeof queues[0];
+
+int main(void)
+{
+ /* Explicitly initialize: it's not clear whether the following OpenACC
+ runtime library calls implicitly initialize;
+ <https://github.com/OpenACC/openacc-spec/issues/102>. */
+ acc_device_t d;
+#if defined ACC_DEVICE_TYPE_nvidia
+ d = acc_device_nvidia;
+#elif defined ACC_DEVICE_TYPE_host
+ d = acc_device_host;
+#else
+# error Not ported to this ACC_DEVICE_TYPE
+#endif
+ acc_init (d);
+
+ for (size_t i = 0; i < queues_n; ++i)
+ {
+ /* Before actually being used, there are all NULL. */
+ queues[i].cuda_stream = acc_get_cuda_stream (queues[i].async);
+ assert (queues[i].cuda_stream == NULL);
+ }
+
+ /* No-ops still don't initialize them. */
+ {
+ size_t i = 0;
+ /* Find the first non-special async-argument. */
+ while (queues[i].async < 0)
+ ++i;
+ assert (i < queues_n);
+
+#pragma acc wait(queues[i].async) // no-op
+
+ ++i;
+ assert (i < queues_n);
+#pragma acc parallel wait(queues[i].async) // no-op
+ ;
+
+ ++i;
+ assert (i < queues_n);
+ acc_wait(queues[i].async); // no-op
+
+ i += 2;
+ assert (i < queues_n);
+ acc_wait_async(queues[i - 1].async, queues[i].async); // no-op, and async queue "i" does not get set up
+
+ for (size_t i = 0; i < queues_n; ++i)
+ {
+ queues[i].cuda_stream = acc_get_cuda_stream (queues[i].async);
+ assert (queues[i].cuda_stream == NULL);
+ }
+ }
+
+ for (size_t i = 0; i < queues_n; ++i)
+ {
+ /* Use the queue to initialize it. */
+#pragma acc parallel async(queues[i].async)
+ ;
+#pragma acc wait
+
+ /* Verify CUDA stream used. */
+ queues[i].cuda_stream = acc_get_cuda_stream (queues[i].async);
+#if defined ACC_DEVICE_TYPE_nvidia
+ /* "acc_async_sync" maps to the NULL CUDA default stream. */
+ if (queues[i].async == acc_async_sync)
+ assert (queues[i].cuda_stream == NULL);
+ else
+ assert (queues[i].cuda_stream != NULL);
+#elif defined ACC_DEVICE_TYPE_host
+ /* For "acc_device_host" there are no CUDA streams. */
+ assert (queues[i].cuda_stream == NULL);
+#else
+# error Not ported to this ACC_DEVICE_TYPE
+#endif
+ }
+
+ /* Verify same results. */
+ for (size_t i = 0; i < queues_n; ++i)
+ {
+ void *cuda_stream;
+
+ cuda_stream = acc_get_cuda_stream (queues[i].async);
+ assert (cuda_stream == queues[i].cuda_stream);
+
+#pragma acc parallel async(queues[i].async)
+ ;
+#pragma acc wait
+
+ cuda_stream = acc_get_cuda_stream (queues[i].async);
+ assert (cuda_stream == queues[i].cuda_stream);
+ }
+
+ /* Verify individual underlying queues are all different. */
+ for (size_t i = 0; i < queues_n; ++i)
+ {
+ if (queues[i].cuda_stream == NULL)
+ continue;
+ for (size_t j = i + 1; j < queues_n; ++j)
+ {
+ if (queues[j].cuda_stream == NULL)
+ continue;
+ assert (queues[j].cuda_stream != queues[i].cuda_stream);
+ }
+ }
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/asyncwait-nop-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/asyncwait-nop-1.c
new file mode 100644
index 00000000000..4ab67363ba6
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/asyncwait-nop-1.c
@@ -0,0 +1,75 @@
+/* Several of the async/wait combinations invoked here are no-ops -- they don't
+ effect anything, but are still valid.
+
+ This doesn't verify that the asynchronous operations synchronize correctly,
+ but just verifies that we don't refuse any variants. */
+
+#undef NDEBUG
+#include <assert.h>
+#include <openacc.h>
+
+int values[] = { acc_async_sync,
+ acc_async_noval,
+ 0,
+ 1,
+ 2,
+ 36,
+ 1982, };
+const size_t values_n = sizeof values / sizeof values[0];
+
+int
+main ()
+{
+ /* Explicitly initialize: it's not clear whether the following OpenACC
+ runtime library calls implicitly initialize;
+ <https://github.com/OpenACC/openacc-spec/issues/102>. */
+ acc_device_t d;
+#if defined ACC_DEVICE_TYPE_nvidia
+ d = acc_device_nvidia;
+#elif defined ACC_DEVICE_TYPE_host
+ d = acc_device_host;
+#else
+# error Not ported to this ACC_DEVICE_TYPE
+#endif
+ acc_init (d);
+
+
+ for (size_t i = 0; i < values_n; ++i)
+ assert (acc_async_test (values[i]) == 1);
+
+
+ for (size_t i = 0; i < values_n; ++i)
+ {
+#pragma acc parallel wait (values[i])
+ ;
+#pragma acc wait (values[i])
+ acc_wait (values[i]);
+ }
+
+
+ for (size_t i = 0; i < values_n; ++i)
+ {
+ for (size_t j = 0; j < values_n; ++j)
+ {
+#pragma acc parallel wait (values[i]) async (values[j])
+ ;
+#pragma acc wait (values[i]) async (values[j])
+ acc_wait_async (values[i], values[j]);
+ }
+ }
+
+
+ for (size_t i = 0; i < values_n; ++i)
+ {
+#pragma acc parallel wait async (values[i])
+ ;
+#pragma acc wait async (values[i])
+ acc_wait_all_async (values[i]);
+ }
+
+
+ /* Clean up. */
+ acc_wait_all ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c
new file mode 100644
index 00000000000..7e50f3b892e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-1.c
@@ -0,0 +1,28 @@
+/* { dg-skip-if "" { *-*-* } { "-DACC_MEM_SHARED=1" } } */
+
+#include <openacc.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdint.h>
+
+int main (int argc, char* argv[])
+{
+ char *myblock = (char *) malloc (1024);
+ int i;
+ void *dst;
+ for (i = 0; i < 1024; i++)
+ myblock[i] = i;
+ dst = acc_copyin (myblock, 1024);
+ for (i = 0; i < 1024; i += 256)
+ {
+ void *partdst = acc_pcopyin (&myblock[i], 256);
+ assert ((uintptr_t) partdst == (uintptr_t) dst + i);
+ }
+ for (i = 0; i < 1024; i += 256)
+ acc_delete (&myblock[i], 256);
+ assert (acc_is_present (myblock, 1024));
+ acc_delete (myblock, 1024);
+ assert (!acc_is_present (myblock, 1024));
+ free (myblock);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c
new file mode 100644
index 00000000000..00e7da1f128
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/copyin-devptr-2.c
@@ -0,0 +1,35 @@
+/* { dg-skip-if "" { *-*-* } { "-DACC_MEM_SHARED=1" } } */
+
+#include <openacc.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdint.h>
+
+int main (int argc, char* argv[])
+{
+ char *block1 = (char *) malloc (1024);
+ char *block2 = (char *) malloc (1024);
+ char *block3 = (char *) malloc (1024);
+ int i;
+ void *dst;
+ for (i = 0; i < 1024; i++)
+ block1[i] = block2[i] = block3[i] = i;
+ #pragma acc data copyin(block1[0:1024]) copyin(block2[0:1024]) \
+ copyin(block3[0:1024])
+ {
+ dst = acc_deviceptr (block2);
+ for (i = 0; i < 1024; i += 256)
+ {
+ void *partdst = acc_pcopyin (&block2[i], 256);
+ assert ((uintptr_t) partdst == (uintptr_t) dst + i);
+ }
+ }
+ assert (acc_is_present (block2, 1024));
+ for (i = 0; i < 1024; i += 256)
+ acc_delete (&block2[i], 256);
+ assert (!acc_is_present (block2, 1024));
+ free (block1);
+ free (block2);
+ free (block3);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-2-lib.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-2-lib.c
index 2ddfa7d4a01..e9d1edaba7f 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-2-lib.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-2-lib.c
@@ -1,16 +1,15 @@
-/* This test is similar to data-2.c, but it uses acc_* library functions
- to move data. */
-
-/* { dg-do run } */
+/* Test asynchronous, unstructed data regions, runtime library variant. */
+/* See also data-2.c. */
#include <stdlib.h>
+#undef NDEBUG
#include <assert.h>
#include <openacc.h>
int
main (int argc, char **argv)
{
- int N = 128; //1024 * 1024;
+ int N = 12345;
float *a, *b, *c, *d, *e;
void *d_a, *d_b, *d_c, *d_d;
int i;
@@ -30,19 +29,21 @@ main (int argc, char **argv)
b[i] = 0.0;
}
- d_a = acc_copyin (a, nbytes);
- d_b = acc_copyin (b, nbytes);
- acc_copyin (&N, sizeof (int));
+ acc_copyin_async (a, nbytes, acc_async_noval);
+ acc_copyin_async (b, nbytes, acc_async_noval);
+ acc_copyin_async (&N, sizeof (int), acc_async_noval);
-#pragma acc parallel present (a[0:N], b[0:N], N) async wait
+#pragma acc parallel present (a[0:N], b[0:N], N) async
#pragma acc loop
for (i = 0; i < N; i++)
b[i] = a[i];
- acc_wait_all ();
+ d_a = acc_deviceptr (a);
+ acc_memcpy_from_device_async (a, d_a, nbytes, acc_async_noval);
+ d_b = acc_deviceptr (b);
+ acc_memcpy_from_device_async (b, d_b, nbytes, acc_async_noval);
- acc_memcpy_from_device (a, d_a, nbytes);
- acc_memcpy_from_device (b, d_b, nbytes);
+ acc_wait (acc_async_noval);
for (i = 0; i < N; i++)
{
@@ -56,19 +57,21 @@ main (int argc, char **argv)
b[i] = 0.0;
}
- acc_update_device (a, nbytes);
- acc_update_device (b, nbytes);
+ acc_update_device_async (a, nbytes, 1);
+ acc_update_device_async (b, nbytes, 1);
-#pragma acc parallel present (a[0:N], b[0:N], N) async (1)
+#pragma acc parallel present (a[0:N], b[0:N], N) async (1)
#pragma acc loop
for (i = 0; i < N; i++)
b[i] = a[i];
+ acc_memcpy_from_device_async (a, d_a, nbytes, 1);
+ acc_memcpy_from_device_async (b, d_b, nbytes, 1);
+
acc_wait (1);
+ /* Test unseen async-argument. */
+ acc_wait (10);
- acc_memcpy_from_device (a, d_a, nbytes);
- acc_memcpy_from_device (b, d_b, nbytes);
-
for (i = 0; i < N; i++)
{
assert (a[i] == 2.0);
@@ -83,46 +86,42 @@ main (int argc, char **argv)
d[i] = 0.0;
}
- acc_update_device (a, nbytes);
- acc_update_device (b, nbytes);
- d_c = acc_copyin (c, nbytes);
- d_d = acc_copyin (d, nbytes);
+ acc_update_device_async (a, nbytes, 0);
+ acc_update_device_async (b, nbytes, 1);
+ acc_copyin_async (c, nbytes, 2);
+ acc_copyin_async (d, nbytes, 3);
-#pragma acc parallel present (a[0:N], b[0:N], N) async (1)
+#pragma acc parallel present (a[0:N], b[0:N], N) wait (0) async (1)
#pragma acc loop
for (i = 0; i < N; i++)
b[i] = (a[i] * a[i] * a[i]) / a[i];
-#pragma acc parallel present (a[0:N], c[0:N], N) async (2)
+#pragma acc parallel present (a[0:N], c[0:N], N) wait (0) async (2)
#pragma acc loop
for (i = 0; i < N; i++)
c[i] = (a[i] + a[i] + a[i] + a[i]) / a[i];
-#pragma acc parallel present (a[0:N], d[0:N], N) async (3)
+#pragma acc parallel present (a[0:N], d[0:N], N) wait (0) async (3)
#pragma acc loop
for (i = 0; i < N; i++)
d[i] = ((a[i] * a[i] + a[i]) / a[i]) - a[i];
- acc_wait_all ();
+ acc_memcpy_from_device_async (a, d_a, nbytes, 0);
+ acc_memcpy_from_device_async (b, d_b, nbytes, 1);
+ d_c = acc_deviceptr (c);
+ acc_memcpy_from_device_async (c, d_c, nbytes, 2);
+ d_d = acc_deviceptr (d);
+ acc_memcpy_from_device_async (d, d_d, nbytes, 3);
- acc_memcpy_from_device (a, d_a, nbytes);
- acc_memcpy_from_device (b, d_b, nbytes);
- acc_memcpy_from_device (c, d_c, nbytes);
- acc_memcpy_from_device (d, d_d, nbytes);
+ acc_wait_all_async (0);
+ acc_wait (0);
for (i = 0; i < N; i++)
{
- if (a[i] != 3.0)
- abort ();
-
- if (b[i] != 9.0)
- abort ();
-
- if (c[i] != 4.0)
- abort ();
-
- if (d[i] != 1.0)
- abort ();
+ assert (a[i] == 3.0);
+ assert (b[i] == 9.0);
+ assert (c[i] == 4.0);
+ assert (d[i] == 1.0);
}
for (i = 0; i < N; i++)
@@ -134,53 +133,43 @@ main (int argc, char **argv)
e[i] = 0.0;
}
- acc_update_device (a, nbytes);
- acc_update_device (b, nbytes);
- acc_update_device (c, nbytes);
- acc_update_device (d, nbytes);
- acc_copyin (e, nbytes);
+ acc_update_device_async (a, nbytes, 10);
+ acc_update_device_async (b, nbytes, 11);
+ acc_update_device_async (c, nbytes, 12);
+ acc_update_device_async (d, nbytes, 13);
+ acc_copyin_async (e, nbytes, 14);
-#pragma acc parallel present (a[0:N], b[0:N], N) async (1)
+#pragma acc parallel present (a[0:N], b[0:N], N) wait (10) async (11)
for (int ii = 0; ii < N; ii++)
b[ii] = (a[ii] * a[ii] * a[ii]) / a[ii];
-#pragma acc parallel present (a[0:N], c[0:N], N) async (2)
+#pragma acc parallel present (a[0:N], c[0:N], N) wait (10) async (12)
for (int ii = 0; ii < N; ii++)
c[ii] = (a[ii] + a[ii] + a[ii] + a[ii]) / a[ii];
-#pragma acc parallel present (a[0:N], d[0:N], N) async (3)
+#pragma acc parallel present (a[0:N], d[0:N], N) wait (10) async (13)
for (int ii = 0; ii < N; ii++)
d[ii] = ((a[ii] * a[ii] + a[ii]) / a[ii]) - a[ii];
-#pragma acc parallel present (a[0:N], b[0:N], c[0:N], d[0:N], e[0:N], N) \
- async (4)
+#pragma acc parallel present (a[0:N], b[0:N], c[0:N], d[0:N], e[0:N], N) wait (11) wait (12) wait (13) async (14)
for (int ii = 0; ii < N; ii++)
e[ii] = a[ii] + b[ii] + c[ii] + d[ii];
+ acc_copyout_async (a, nbytes, 10);
+ acc_copyout_async (b, nbytes, 11);
+ acc_copyout_async (c, nbytes, 12);
+ acc_copyout_async (d, nbytes, 13);
+ acc_copyout_async (e, nbytes, 14);
+ acc_delete_async (&N, sizeof (int), 15);
acc_wait_all ();
- acc_copyout (a, nbytes);
- acc_copyout (b, nbytes);
- acc_copyout (c, nbytes);
- acc_copyout (d, nbytes);
- acc_copyout (e, nbytes);
- acc_delete (&N, sizeof (int));
for (i = 0; i < N; i++)
{
- if (a[i] != 2.0)
- abort ();
-
- if (b[i] != 4.0)
- abort ();
-
- if (c[i] != 4.0)
- abort ();
-
- if (d[i] != 1.0)
- abort ();
-
- if (e[i] != 11.0)
- abort ();
+ assert (a[i] == 2.0);
+ assert (b[i] == 4.0);
+ assert (c[i] == 4.0);
+ assert (d[i] == 1.0);
+ assert (e[i] == 11.0);
}
return 0;
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-2.c
index 0c6abe69dc1..2fc4a598e8f 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-2.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-2.c
@@ -1,14 +1,14 @@
-/* Test 'acc enter/exit data' regions. */
-
-/* { dg-do run } */
-/* { dg-xfail-run-if "TODO" { openacc_nvidia_accel_selected } } */
+/* Test asynchronous, unstructed data regions, directives variant. */
+/* See also data-2-lib.c. */
#include <stdlib.h>
+#undef NDEBUG
+#include <assert.h>
int
main (int argc, char **argv)
{
- int N = 128; //1024 * 1024;
+ int N = 12345;
float *a, *b, *c, *d, *e;
int i;
int nbytes;
@@ -27,48 +27,24 @@ main (int argc, char **argv)
b[i] = 0.0;
}
-#pragma acc enter data copyin (a[0:N]) copyin (b[0:N]) copyin (N) async
-#pragma acc parallel present (a[0:N], b[0:N]) async wait
-#pragma acc loop
- for (i = 0; i < N; i++)
- b[i] = a[i];
-
-#pragma acc exit data copyout (a[0:N]) copyout (b[0:N]) wait async
-#pragma acc wait
-
- for (i = 0; i < N; i++)
- {
- if (a[i] != 3.0)
- abort ();
-
- if (b[i] != 3.0)
- abort ();
- }
-
- for (i = 0; i < N; i++)
- {
- a[i] = 3.0;
- b[i] = 0.0;
- }
+#pragma acc enter data copyin (a[0:N]) async
+#pragma acc enter data copyin (b[0:N]) async
+#pragma acc enter data copyin (N) async
-#pragma acc enter data copyin (a[0:N]) async
-#pragma acc enter data copyin (b[0:N]) async wait
-#pragma acc enter data copyin (N) async wait
-#pragma acc parallel async wait
+#pragma acc parallel present (a[0:N], b[0:N], N) async
#pragma acc loop
for (i = 0; i < N; i++)
b[i] = a[i];
-#pragma acc exit data copyout (a[0:N]) copyout (b[0:N]) delete (N) wait async
+#pragma acc update self (a[0:N]) async
+#pragma acc update self (b[0:N]) async
+
#pragma acc wait
for (i = 0; i < N; i++)
{
- if (a[i] != 3.0)
- abort ();
-
- if (b[i] != 3.0)
- abort ();
+ assert (a[i] == 3.0);
+ assert (b[i] == 3.0);
}
for (i = 0; i < N; i++)
@@ -77,22 +53,25 @@ main (int argc, char **argv)
b[i] = 0.0;
}
-#pragma acc enter data copyin (a[0:N]) copyin (b[0:N]) copyin (N) async (1)
-#pragma acc parallel present (a[0:N], b[0:N]) async (1)
+#pragma acc update device (a[0:N]) async (1)
+#pragma acc update device (b[0:N]) async (1)
+
+#pragma acc parallel present (a[0:N], b[0:N], N) async (1)
#pragma acc loop
for (i = 0; i < N; i++)
b[i] = a[i];
-#pragma acc exit data copyout (a[0:N]) copyout (b[0:N]) wait (1) async (1)
+#pragma acc update self (a[0:N]) async (1)
+#pragma acc update self (b[0:N]) async (1)
+
#pragma acc wait (1)
+ /* Test unseen async-argument. */
+#pragma acc wait (10)
for (i = 0; i < N; i++)
{
- if (a[i] != 2.0)
- abort ();
-
- if (b[i] != 2.0)
- abort ();
+ assert (a[i] == 2.0);
+ assert (b[i] == 2.0);
}
for (i = 0; i < N; i++)
@@ -103,39 +82,40 @@ main (int argc, char **argv)
d[i] = 0.0;
}
-#pragma acc enter data copyin (a[0:N]) copyin (b[0:N]) copyin (c[0:N]) copyin (d[0:N]) copyin (N) async (1)
+#pragma acc update device (a[0:N]) async (0)
+#pragma acc update device (b[0:N]) async (1)
+#pragma acc enter data copyin (c[0:N]) async (2)
+#pragma acc enter data copyin (d[0:N]) async (3)
-#pragma acc parallel present (a[0:N], b[0:N]) async (1) wait (1)
+#pragma acc parallel present (a[0:N], b[0:N], N) wait (0) async (1)
#pragma acc loop
for (i = 0; i < N; i++)
b[i] = (a[i] * a[i] * a[i]) / a[i];
-#pragma acc parallel present (a[0:N], c[0:N]) async (2) wait (1)
+#pragma acc parallel present (a[0:N], c[0:N], N) wait (0) async (2)
#pragma acc loop
for (i = 0; i < N; i++)
c[i] = (a[i] + a[i] + a[i] + a[i]) / a[i];
-#pragma acc parallel present (a[0:N], d[0:N]) async (3) wait (1)
+#pragma acc parallel present (a[0:N], d[0:N], N) wait (0) async (3)
#pragma acc loop
for (i = 0; i < N; i++)
d[i] = ((a[i] * a[i] + a[i]) / a[i]) - a[i];
-#pragma acc exit data copyout (a[0:N]) copyout (b[0:N]) copyout (c[0:N]) copyout (d[0:N]) wait (1, 2, 3) async (1)
-#pragma acc wait (1)
+#pragma acc update self (a[0:N]) async (0)
+#pragma acc update self (b[0:N]) async (1)
+#pragma acc update self (c[0:N]) async (2)
+#pragma acc update self (d[0:N]) async (3)
+
+#pragma acc wait async (0)
+#pragma acc wait (0)
for (i = 0; i < N; i++)
{
- if (a[i] != 3.0)
- abort ();
-
- if (b[i] != 9.0)
- abort ();
-
- if (c[i] != 4.0)
- abort ();
-
- if (d[i] != 1.0)
- abort ();
+ assert (a[i] == 3.0);
+ assert (b[i] == 9.0);
+ assert (c[i] == 4.0);
+ assert (d[i] == 1.0);
}
for (i = 0; i < N; i++)
@@ -147,45 +127,43 @@ main (int argc, char **argv)
e[i] = 0.0;
}
-#pragma acc enter data copyin (a[0:N]) copyin (b[0:N]) copyin (c[0:N]) copyin (d[0:N]) copyin (e[0:N]) copyin (N) async (1)
+#pragma acc update device (a[0:N]) async (10)
+#pragma acc update device (b[0:N]) async (11)
+#pragma acc update device (c[0:N]) async (12)
+#pragma acc update device (d[0:N]) async (13)
+#pragma acc enter data copyin (e[0:N]) async (14)
-#pragma acc parallel present (a[0:N], b[0:N]) async (1) wait (1)
+#pragma acc parallel present (a[0:N], b[0:N], N) wait (10) async (11)
for (int ii = 0; ii < N; ii++)
b[ii] = (a[ii] * a[ii] * a[ii]) / a[ii];
-#pragma acc parallel present (a[0:N], c[0:N]) async (2) wait (1)
+#pragma acc parallel present (a[0:N], c[0:N], N) wait (10) async (12)
for (int ii = 0; ii < N; ii++)
c[ii] = (a[ii] + a[ii] + a[ii] + a[ii]) / a[ii];
-#pragma acc parallel present (a[0:N], d[0:N]) async (3) wait (1)
+#pragma acc parallel present (a[0:N], d[0:N], N) wait (10) async (13)
for (int ii = 0; ii < N; ii++)
d[ii] = ((a[ii] * a[ii] + a[ii]) / a[ii]) - a[ii];
-#pragma acc parallel present (a[0:N], b[0:N], c[0:N], d[0:N], e[0:N]) \
- wait (1) async (4)
+#pragma acc parallel present (a[0:N], b[0:N], c[0:N], d[0:N], e[0:N], N) wait (11) wait (12) wait (13) async (14)
for (int ii = 0; ii < N; ii++)
e[ii] = a[ii] + b[ii] + c[ii] + d[ii];
-#pragma acc exit data copyout (a[0:N]) copyout (b[0:N]) copyout (c[0:N]) \
- copyout (d[0:N]) copyout (e[0:N]) wait (1, 2, 3, 4) async (1)
-#pragma acc wait (1)
+#pragma acc exit data copyout (a[0:N]) async (10)
+#pragma acc exit data copyout (b[0:N]) async (11)
+#pragma acc exit data copyout (c[0:N]) async (12)
+#pragma acc exit data copyout (d[0:N]) async (13)
+#pragma acc exit data copyout (e[0:N]) async (14)
+#pragma acc exit data delete (N) async (15)
+#pragma acc wait
for (i = 0; i < N; i++)
{
- if (a[i] != 2.0)
- abort ();
-
- if (b[i] != 4.0)
- abort ();
-
- if (c[i] != 4.0)
- abort ();
-
- if (d[i] != 1.0)
- abort ();
-
- if (e[i] != 11.0)
- abort ();
+ assert (a[i] == 2.0);
+ assert (b[i] == 4.0);
+ assert (c[i] == 4.0);
+ assert (d[i] == 1.0);
+ assert (e[i] == 11.0);
}
return 0;
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-3.c
index 0bf706a1b5d..5ec50b808a7 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-3.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-3.c
@@ -138,7 +138,7 @@ main (int argc, char **argv)
d[ii] = ((a[ii] * a[ii] + a[ii]) / a[ii]) - a[ii];
#pragma acc parallel present (a[0:N], b[0:N], c[0:N], d[0:N], e[0:N]) \
- wait (1,5) async (4)
+ wait (1, 2, 3, 5) async (4)
for (int ii = 0; ii < N; ii++)
e[ii] = a[ii] + b[ii] + c[ii] + d[ii];
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-1.c
deleted file mode 100644
index fd3b77dcff5..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-1.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
-
-#include <stdio.h>
-#include <openacc.h>
-
-int
-main (int argc, char *argv[])
-{
- int i;
-
- acc_copyin (&i, sizeof i);
-
- fprintf (stderr, "CheCKpOInT\n");
-#pragma acc data copy (i)
- ++i;
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-2.c
deleted file mode 100644
index 0118b2568e2..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-2.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
-
-#include <stdio.h>
-
-int
-main (int argc, char *argv[])
-{
- int i;
-
-#pragma acc data present_or_copy (i)
- {
- fprintf (stderr, "CheCKpOInT\n");
-#pragma acc data copyout (i)
- ++i;
- }
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-3.c
deleted file mode 100644
index b346c69826f..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-3.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
-
-#include <stdio.h>
-#include <openacc.h>
-
-int
-main (int argc, char *argv[])
-{
- int i;
-
-#pragma acc data present_or_copy (i)
- {
- fprintf (stderr, "CheCKpOInT\n");
- acc_copyin (&i, sizeof i);
- }
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-4.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-4.c
deleted file mode 100644
index e99ad33d9be..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-4.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
-
-#include <stdio.h>
-#include <openacc.h>
-
-int
-main (int argc, char *argv[])
-{
- int i;
-
- acc_present_or_copyin (&i, sizeof i);
- fprintf (stderr, "CheCKpOInT\n");
- acc_copyin (&i, sizeof i);
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-5.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-5.c
deleted file mode 100644
index f8370c006df..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-5.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
-
-#include <stdio.h>
-#include <openacc.h>
-
-int
-main (int argc, char *argv[])
-{
- int i;
-
-#pragma acc enter data create (i)
- fprintf (stderr, "CheCKpOInT\n");
- acc_copyin (&i, sizeof i);
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-6.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-6.c
deleted file mode 100644
index d7f4deb18e4..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-6.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
-
-#include <stdio.h>
-#include <openacc.h>
-
-int
-main (int argc, char *argv[])
-{
- int i;
-
- acc_present_or_copyin (&i, sizeof i);
- fprintf (stderr, "CheCKpOInT\n");
-#pragma acc enter data create (i)
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-7.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-7.c
deleted file mode 100644
index 54be59507ca..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-7.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
-
-#include <stdio.h>
-#include <openacc.h>
-
-int
-main (int argc, char *argv[])
-{
- int i;
-
-#pragma acc enter data create (i)
- fprintf (stderr, "CheCKpOInT\n");
- acc_create (&i, sizeof i);
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-8.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-8.c
deleted file mode 100644
index e5c0f9cfb32..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-already-8.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
-
-#include <stdio.h>
-
-int
-main (int argc, char *argv[])
-{
- int i;
-
-#pragma acc data create (i)
- {
- fprintf (stderr, "CheCKpOInT\n");
-#pragma acc parallel copyin (i)
- ++i;
- }
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/data-firstprivate-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-firstprivate-1.c
new file mode 100644
index 00000000000..8900a4e070d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/data-firstprivate-1.c
@@ -0,0 +1,165 @@
+/* Test behavior of 'firstprivate' lexically vs. dynamically nested inside a
+ 'data' region. */
+
+#include <stdlib.h>
+
+
+#define VERIFY(x) \
+ do { \
+ if (!(x)) \
+ abort (); \
+ } while (0);
+
+
+/* This is basically and extended version of 't2' from 'firstprivate-1.c'. */
+
+int lexically_nested_val = 2;
+
+static void
+lexically_nested ()
+{
+#pragma acc data \
+ copy (lexically_nested_val)
+ {
+ VERIFY (lexically_nested_val == 2);
+
+#pragma acc parallel \
+ present (lexically_nested_val)
+ {
+ VERIFY (lexically_nested_val == 2);
+
+ /* This updates the device copy, or shared variable. */
+ lexically_nested_val = 7;
+ }
+
+#if ACC_MEM_SHARED
+ VERIFY (lexically_nested_val == 7);
+#else
+ VERIFY (lexically_nested_val == 2);
+#endif
+
+ /* This only updates the local/shared variable, but not the device
+ copy. */
+ lexically_nested_val = 5;
+
+#pragma acc parallel \
+ firstprivate (lexically_nested_val)
+ {
+#if 1 /* Current behavior. */
+ /* The 'firstprivate' copy is initialized from the device copy, or
+ shared variable. */
+# if ACC_MEM_SHARED
+ VERIFY (lexically_nested_val == 5);
+# else
+ VERIFY (lexically_nested_val == 7);
+# endif
+#else /* Expected behavior per PR92036. */
+ /* The 'firstprivate' copy is initialized from the local thread. */
+ VERIFY (lexically_nested_val == 5);
+#endif
+
+ /* This updates the 'firstprivate' copy only, but not the shared
+ variable. */
+ lexically_nested_val = 9;
+ }
+
+ VERIFY (lexically_nested_val == 5);
+ }
+ /* If not shared, the device copy has now been copied back. */
+
+#if ACC_MEM_SHARED
+ VERIFY (lexically_nested_val == 5);
+#else
+ VERIFY (lexically_nested_val == 7);
+#endif
+}
+
+
+int dynamically_nested_val = 2;
+
+/* Same as above, but compute construct 1 broken out, so no longer lexically
+ nested inside 'data' region. */
+
+static void
+dynamically_nested_compute_1 ()
+{
+#pragma acc parallel \
+ present (dynamically_nested_val)
+ {
+ VERIFY (dynamically_nested_val == 2);
+
+ /* This updates the device copy, or shared variable. */
+ dynamically_nested_val = 7;
+ }
+}
+
+/* Same as above, but compute construct 2 broken out, so no longer lexically
+ nested inside 'data' region. */
+
+static void
+dynamically_nested_compute_2 ()
+{
+#pragma acc parallel \
+ firstprivate (dynamically_nested_val)
+ {
+#if 1 /* Current behavior. */
+ /* The 'firstprivate' copy is initialized from the device copy, or shared
+ variable. */
+# if ACC_MEM_SHARED
+ VERIFY (dynamically_nested_val == 5);
+# else
+ VERIFY (dynamically_nested_val == 7);
+# endif
+#else /* Expected behavior per PR92036. */
+ /* The 'firstprivate' copy is initialized from the local thread. */
+ VERIFY (dynamically_nested_val == 5);
+#endif
+
+ /* This updates the 'firstprivate' copy only, but not the shared
+ variable. */
+ dynamically_nested_val = 9;
+ }
+}
+
+static void
+dynamically_nested ()
+{
+#pragma acc data \
+ copy (dynamically_nested_val)
+ {
+ VERIFY (dynamically_nested_val == 2);
+
+ dynamically_nested_compute_1 ();
+
+#if ACC_MEM_SHARED
+ VERIFY (dynamically_nested_val == 7);
+#else
+ VERIFY (dynamically_nested_val == 2);
+#endif
+
+ /* This only updates the local/shared variable, but not the device
+ copy. */
+ dynamically_nested_val = 5;
+
+ dynamically_nested_compute_2 ();
+
+ VERIFY (dynamically_nested_val == 5);
+ }
+ /* If not shared, the device copy has now been copied back. */
+
+#if ACC_MEM_SHARED
+ VERIFY (dynamically_nested_val == 5);
+#else
+ VERIFY (dynamically_nested_val == 7);
+#endif
+}
+
+
+int
+main()
+{
+ lexically_nested ();
+ dynamically_nested ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-1.c
index bc726174252..087b9545692 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-1.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-1.c
@@ -1,6 +1,5 @@
#include <openacc.h>
#include <stdlib.h>
-#include <stdio.h>
#define N 8
@@ -39,14 +38,14 @@ subr1 (int *a)
}
}
-int b[8];
+int b[N];
#pragma acc declare create (b)
-int d[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+int d[N] = { 1, 2, 3, 4, 5, 6, 7, 8 };
#pragma acc declare copyin (d)
-int
-main (int argc, char **argv)
+static void
+f (void)
{
int a[N];
int e[N];
@@ -110,11 +109,98 @@ main (int argc, char **argv)
subr2 (&a[0]);
- for (i = 0; i < 1; i++)
+ for (i = 0; i < N; i++)
{
if (a[i] != 1234 * 6)
abort ();
}
+}
+
+
+/* The same as 'f' but everything contained in an OpenACC 'data' construct. */
+
+static void
+f_data (void)
+{
+#pragma acc data
+ {
+ int a[N];
+ int e[N];
+# pragma acc declare create (e)
+ int i;
+
+ for (i = 0; i < N; i++)
+ a[i] = i + 1;
+
+ if (!acc_is_present (&b, sizeof (b)))
+ abort ();
+
+ if (!acc_is_present (&d, sizeof (d)))
+ abort ();
+
+ if (!acc_is_present (&e, sizeof (e)))
+ abort ();
+
+# pragma acc parallel copyin (a[0:N])
+ {
+ for (i = 0; i < N; i++)
+ {
+ b[i] = a[i];
+ a[i] = b[i];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (a[i] != i + 1)
+ abort ();
+ }
+
+# pragma acc parallel copy (a[0:N])
+ {
+ for (i = 0; i < N; i++)
+ {
+ e[i] = a[i] + d[i];
+ a[i] = e[i];
+ }
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ if (a[i] != (i + 1) * 2)
+ abort ();
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ a[i] = 1234;
+ }
+
+ subr1 (&a[0]);
+
+ for (i = 0; i < N; i++)
+ {
+ if (a[i] != 1234 * 2)
+ abort ();
+ }
+
+ subr2 (&a[0]);
+
+ for (i = 0; i < N; i++)
+ {
+ if (a[i] != 1234 * 6)
+ abort ();
+ }
+ }
+}
+
+
+int
+main (int argc, char **argv)
+{
+ f ();
+
+ f_data ();
return 0;
}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla.c
index 3ea148ed40d..0f51badca42 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/declare-vla.c
@@ -1,9 +1,10 @@
-/* Verify that acc declare accept VLA variables. */
+/* Verify OpenACC 'declare' with VLAs. */
#include <assert.h>
-int
-main ()
+
+void
+f (void)
{
int N = 1000;
int i, A[N];
@@ -20,6 +21,46 @@ main ()
for (i = 0; i < N; i++)
assert (A[i] == i);
+}
+
+
+/* The same as 'f' but everything contained in an OpenACC 'data' construct. */
+
+void
+f_data (void)
+{
+#pragma acc data
+ {
+ int N = 1000;
+ int i, A[N];
+# pragma acc declare copy(A)
+
+ for (i = 0; i < N; i++)
+ A[i] = -i;
+
+# pragma acc kernels
+ for (i = 0; i < N; i++)
+ A[i] = i;
+
+# pragma acc update host(A)
+
+ for (i = 0; i < N; i++)
+ assert (A[i] == i);
+ }
+}
+
+
+int
+main ()
+{
+ f ();
+
+ f_data ();
return 0;
}
+
+
+/* { dg-xfail-run-if "TODO PR90861" { *-*-* } { "-DACC_MEM_SHARED=0" } }
+ This might XPASS if the compiler happens to put the two 'A' VLAs at the same
+ address. */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/firstprivate-mappings-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/firstprivate-mappings-1.c
new file mode 100644
index 00000000000..4a8b310414c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/firstprivate-mappings-1.c
@@ -0,0 +1,6 @@
+/* Verify OpenACC 'firstprivate' mappings. */
+
+/* { dg-additional-options "-Wno-psabi" } as apparently we're doing funny
+ things with vector arguments. */
+
+#include "../../../gcc/testsuite/c-c++-common/goacc/firstprivate-mappings-1.c"
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/function-not-offloaded.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/function-not-offloaded.c
new file mode 100644
index 00000000000..fdf4eb08f8a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/function-not-offloaded.c
@@ -0,0 +1,18 @@
+/* { dg-do link } */
+/* { dg-excess-errors "lto1, mkoffload and lto-wrapper fatal errors" { target openacc_nvidia_accel_selected } } */
+
+int var;
+#pragma acc declare create (var)
+
+void __attribute__((noinline, noclone))
+foo () /* { dg-error "function 'foo' has been referenced in offloaded code but hasn't been marked to be included in the offloaded code" "" { target openacc_nvidia_accel_selected } } */
+{
+ var++;
+}
+
+int
+main ()
+{
+#pragma acc parallel
+ foo ();
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/gang-reduction-var-assignment.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/gang-reduction-var-assignment.c
new file mode 100644
index 00000000000..05f58a4bddf
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/gang-reduction-var-assignment.c
@@ -0,0 +1,16 @@
+/* { dg-xfail-run-if "PR88852" { openacc_host_selected } } */
+
+int
+main (void)
+{
+ int x = 123;
+
+#pragma acc parallel num_gangs(1) reduction (+: x)
+ {
+ x = 23;
+ }
+ if (x != 146)
+ __builtin_abort();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/insufficient-resources.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/insufficient-resources.c
new file mode 100644
index 00000000000..b59cd420785
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/insufficient-resources.c
@@ -0,0 +1,21 @@
+/* { dg-set-target-env-var "GOMP_OPENACC_DIM" ":33:" } */
+/* { dg-shouldfail "" { openacc_nvidia_accel_selected } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+#pragma acc parallel vector_length (32)
+ {
+#pragma acc loop worker
+ for (unsigned int i = 0; i < 32; i++)
+#pragma acc loop vector
+ for (unsigned int j = 0; j < 64; j++)
+ ;
+ }
+
+ return 0;
+}
+/* { dg-output "The Nvidia accelerator has insufficient resources" { target openacc_nvidia_accel_selected } } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-20.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-20.c
index 25ceb3a26af..10d3cbc5cc6 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-20.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-20.c
@@ -31,5 +31,5 @@ main (int argc, char **argv)
}
/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
-/* { dg-output "\\\[\[0-9a-fA-FxX\]+,256\\\] surrounds2 \\\[\[0-9a-fA-FxX\]+,\\\+257\\\]" } */
+/* { dg-output "\\\[\[0-9a-fA-FxX\]+,\\\+257\\\] outside mapped block \\\[\[0-9a-fA-FxX\]+,\\\+256\\\]" } */
/* { dg-shouldfail "" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-22.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-22.c
index 65ff440a528..cb32bbcb652 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-22.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-22.c
@@ -31,5 +31,3 @@ main (int argc, char **argv)
}
/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
-/* { dg-output "\\\[\[0-9a-fA-FxX\]+,256\\\] surrounds2 \\\[\[0-9a-fA-FxX\]+,\\\+255\\\]" } */
-/* { dg-shouldfail "" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-23.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-23.c
index fd4dc5971a1..b1f3e71f278 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-23.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-23.c
@@ -41,5 +41,5 @@ main (int argc, char **argv)
}
/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
-/* { dg-output "\\\[\[0-9a-fA-FxX\]+,256\\\] surrounds2 \\\[\[0-9a-fA-FxX\]+,\\\+512\\\]" } */
+/* { dg-output "\\\[\[0-9a-fA-FxX\]+,\\\+512\\\] outside mapped block \\\[\[0-9a-fA-FxX\]+,\\\+256\\\]" } */
/* { dg-shouldfail "" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-30.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-30.c
index 9bc9ecc1068..d0e5ffb0691 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-30.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-30.c
@@ -28,5 +28,3 @@ main (int argc, char **argv)
}
/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
-/* { dg-output "\\\[\[0-9a-fA-FxX\]+,256\\\] surrounds2 \\\[\[0-9a-fA-FxX\]+,\\\+254\\\]" } */
-/* { dg-shouldfail "" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-69.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-69.c
index 5462f125352..c10bebaab13 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-69.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-69.c
@@ -103,6 +103,13 @@ main (int argc, char **argv)
abort ();
}
+ /* Test unseen async-argument. */
+ if (acc_async_test (1) != 1)
+ {
+ fprintf (stderr, "acc_async_test failed on unseen async-argument\n");
+ abort ();
+ }
+
sleep (1);
if (acc_async_test (0) != 1)
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-71.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-71.c
deleted file mode 100644
index c85e8245955..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-71.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* { dg-do run { target openacc_nvidia_accel_selected } } */
-/* { dg-additional-options "-lcuda" } */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <openacc.h>
-#include <cuda.h>
-
-int
-main (int argc, char **argv)
-{
- CUdevice dev;
- CUfunction delay;
- CUmodule module;
- CUresult r;
- CUstream stream;
- unsigned long *a, *d_a, dticks;
- int nbytes;
- float dtime;
- void *kargs[2];
- int clkrate;
- int devnum, nprocs;
-
- acc_init (acc_device_nvidia);
-
- devnum = acc_get_device_num (acc_device_nvidia);
-
- r = cuDeviceGet (&dev, devnum);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuDeviceGet failed: %d\n", r);
- abort ();
- }
-
- r =
- cuDeviceGetAttribute (&nprocs, CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT,
- dev);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuDeviceGetAttribute failed: %d\n", r);
- abort ();
- }
-
- r = cuDeviceGetAttribute (&clkrate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, dev);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuDeviceGetAttribute failed: %d\n", r);
- abort ();
- }
-
- r = cuModuleLoad (&module, "subr.ptx");
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuModuleLoad failed: %d\n", r);
- abort ();
- }
-
- r = cuModuleGetFunction (&delay, module, "delay");
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuModuleGetFunction failed: %d\n", r);
- abort ();
- }
-
- nbytes = nprocs * sizeof (unsigned long);
-
- dtime = 200.0;
-
- dticks = (unsigned long) (dtime * clkrate);
-
- a = (unsigned long *) malloc (nbytes);
- d_a = (unsigned long *) acc_malloc (nbytes);
-
- acc_map_data (a, d_a, nbytes);
-
- kargs[0] = (void *) &d_a;
- kargs[1] = (void *) &dticks;
-
- r = cuStreamCreate (&stream, CU_STREAM_DEFAULT);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuStreamCreate failed: %d\n", r);
- abort ();
- }
-
- acc_set_cuda_stream (0, stream);
-
- r = cuLaunchKernel (delay, 1, 1, 1, 1, 1, 1, 0, stream, kargs, 0);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuLaunchKernel failed: %d\n", r);
- abort ();
- }
-
- fprintf (stderr, "CheCKpOInT\n");
- if (acc_async_test (1) != 0)
- {
- fprintf (stderr, "asynchronous operation not running\n");
- abort ();
- }
-
- sleep ((int) (dtime / 1000.0f) + 1);
-
- if (acc_async_test (1) != 1)
- {
- fprintf (stderr, "found asynchronous operation still running\n");
- abort ();
- }
-
- acc_unmap_data (a);
-
- free (a);
- acc_free (d_a);
-
- acc_shutdown (acc_device_nvidia);
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
-/* { dg-output "unknown async \[0-9\]+" } */
-/* { dg-shouldfail "" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-74.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-74.c
index 0726ee420c3..0efcf0d5222 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-74.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-74.c
@@ -103,6 +103,8 @@ main (int argc, char **argv)
}
acc_wait (0);
+ /* Test unseen async-argument. */
+ acc_wait (1);
atime = stop_timer (0);
@@ -115,6 +117,8 @@ main (int argc, char **argv)
start_timer (0);
acc_wait (0);
+ /* Test unseen async-argument. */
+ acc_wait (1);
atime = stop_timer (0);
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-77.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-77.c
deleted file mode 100644
index f4f196def3b..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-77.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/* { dg-do run { target openacc_nvidia_accel_selected } } */
-/* { dg-additional-options "-lcuda" } */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <openacc.h>
-#include <cuda.h>
-#include "timer.h"
-
-int
-main (int argc, char **argv)
-{
- CUdevice dev;
- CUfunction delay;
- CUmodule module;
- CUresult r;
- CUstream stream;
- unsigned long *a, *d_a, dticks;
- int nbytes;
- float atime, dtime;
- void *kargs[2];
- int clkrate;
- int devnum, nprocs;
-
- acc_init (acc_device_nvidia);
-
- devnum = acc_get_device_num (acc_device_nvidia);
-
- r = cuDeviceGet (&dev, devnum);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuDeviceGet failed: %d\n", r);
- abort ();
- }
-
- r =
- cuDeviceGetAttribute (&nprocs, CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT,
- dev);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuDeviceGetAttribute failed: %d\n", r);
- abort ();
- }
-
- r = cuDeviceGetAttribute (&clkrate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, dev);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuDeviceGetAttribute failed: %d\n", r);
- abort ();
- }
-
- r = cuModuleLoad (&module, "subr.ptx");
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuModuleLoad failed: %d\n", r);
- abort ();
- }
-
- r = cuModuleGetFunction (&delay, module, "delay");
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuModuleGetFunction failed: %d\n", r);
- abort ();
- }
-
- nbytes = nprocs * sizeof (unsigned long);
-
- dtime = 200.0;
-
- dticks = (unsigned long) (dtime * clkrate);
-
- a = (unsigned long *) malloc (nbytes);
- d_a = (unsigned long *) acc_malloc (nbytes);
-
- acc_map_data (a, d_a, nbytes);
-
- kargs[0] = (void *) &d_a;
- kargs[1] = (void *) &dticks;
-
- r = cuStreamCreate (&stream, CU_STREAM_DEFAULT);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuStreamCreate failed: %d\n", r);
- abort ();
- }
-
- acc_set_cuda_stream (0, stream);
-
- init_timers (1);
-
- start_timer (0);
-
- r = cuLaunchKernel (delay, 1, 1, 1, 1, 1, 1, 0, stream, kargs, 0);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuLaunchKernel failed: %d\n", r);
- abort ();
- }
-
- fprintf (stderr, "CheCKpOInT\n");
- acc_wait (1);
-
- atime = stop_timer (0);
-
- if (atime < dtime)
- {
- fprintf (stderr, "actual time < delay time\n");
- abort ();
- }
-
- start_timer (0);
-
- acc_wait (1);
-
- atime = stop_timer (0);
-
- if (0.010 < atime)
- {
- fprintf (stderr, "actual time < delay time\n");
- abort ();
- }
-
- acc_unmap_data (a);
-
- fini_timers ();
-
- free (a);
- acc_free (d_a);
-
- acc_shutdown (acc_device_nvidia);
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
-/* { dg-output "unknown async \[0-9\]+" } */
-/* { dg-shouldfail "" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-79.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-79.c
index ef3df13ebc9..b2e2687e4e7 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-79.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-79.c
@@ -122,6 +122,13 @@ main (int argc, char **argv)
}
}
+ if (acc_async_test (0) != 0)
+ abort ();
+
+ /* Test unseen async-argument. */
+ if (acc_async_test (1) != 1)
+ abort ();
+
acc_wait_async (0, 1);
if (acc_async_test (0) != 0)
@@ -130,6 +137,23 @@ main (int argc, char **argv)
if (acc_async_test (1) != 0)
abort ();
+ /* Test unseen async-argument. */
+ {
+ if (acc_async_test (2) != 1)
+ abort ();
+
+ acc_wait_async (2, 1);
+
+ if (acc_async_test (0) != 0)
+ abort ();
+
+ if (acc_async_test (1) != 0)
+ abort ();
+
+ if (acc_async_test (2) != 1)
+ abort ();
+ }
+
acc_wait (1);
atime = stop_timer (0);
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-80.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-80.c
deleted file mode 100644
index 9a9a837fa4f..00000000000
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-80.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* { dg-do run { target openacc_nvidia_accel_selected } } */
-/* { dg-additional-options "-lcuda" } */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <openacc.h>
-#include <cuda.h>
-#include "timer.h"
-
-int
-main (int argc, char **argv)
-{
- CUdevice dev;
- CUfunction delay;
- CUmodule module;
- CUresult r;
- CUstream stream;
- int N;
- int i;
- unsigned long *a, *d_a, dticks;
- int nbytes;
- float atime, dtime;
- void *kargs[2];
- int clkrate;
- int devnum, nprocs;
-
- acc_init (acc_device_nvidia);
-
- devnum = acc_get_device_num (acc_device_nvidia);
-
- r = cuDeviceGet (&dev, devnum);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuDeviceGet failed: %d\n", r);
- abort ();
- }
-
- r =
- cuDeviceGetAttribute (&nprocs, CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT,
- dev);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuDeviceGetAttribute failed: %d\n", r);
- abort ();
- }
-
- r = cuDeviceGetAttribute (&clkrate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, dev);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuDeviceGetAttribute failed: %d\n", r);
- abort ();
- }
-
- r = cuModuleLoad (&module, "subr.ptx");
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuModuleLoad failed: %d\n", r);
- abort ();
- }
-
- r = cuModuleGetFunction (&delay, module, "delay");
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuModuleGetFunction failed: %d\n", r);
- abort ();
- }
-
- nbytes = nprocs * sizeof (unsigned long);
-
- dtime = 200.0;
-
- dticks = (unsigned long) (dtime * clkrate);
-
- N = nprocs;
-
- a = (unsigned long *) malloc (nbytes);
- d_a = (unsigned long *) acc_malloc (nbytes);
-
- acc_map_data (a, d_a, nbytes);
-
- r = cuStreamCreate (&stream, CU_STREAM_DEFAULT);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuStreamCreate failed: %d\n", r);
- abort ();
- }
-
- acc_set_cuda_stream (1, stream);
-
- init_timers (1);
-
- kargs[0] = (void *) &d_a;
- kargs[1] = (void *) &dticks;
-
- start_timer (0);
-
- for (i = 0; i < N; i++)
- {
- r = cuLaunchKernel (delay, 1, 1, 1, 1, 1, 1, 0, stream, kargs, 0);
- if (r != CUDA_SUCCESS)
- {
- fprintf (stderr, "cuLaunchKernel failed: %d\n", r);
- abort ();
- }
- }
-
- fprintf (stderr, "CheCKpOInT\n");
- acc_wait_async (1, 1);
-
- acc_wait (1);
-
- atime = stop_timer (0);
-
- if (atime < dtime)
- {
- fprintf (stderr, "actual time < delay time\n");
- abort ();
- }
-
- acc_unmap_data (a);
-
- fini_timers ();
-
- free (a);
- acc_free (d_a);
-
- acc_shutdown (acc_device_nvidia);
-
- return 0;
-}
-
-/* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
-/* { dg-output "identical parameters" } */
-/* { dg-shouldfail "" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-84.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-84.c
index 786b908f755..d793c743630 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-84.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-84.c
@@ -7,6 +7,14 @@
#include <openacc.h>
#include <cuda.h>
+#if !defined __cplusplus
+# undef static_assert
+# define static_assert _Static_assert
+#endif
+
+static_assert (acc_async_sync == -2, "acc_async_sync?");
+static_assert (acc_async_noval == -1, "acc_async_noval?");
+
int
main (int argc, char **argv)
{
@@ -20,9 +28,11 @@ main (int argc, char **argv)
(void) acc_get_device_num (acc_device_nvidia);
- streams = (CUstream *) malloc (N * sizeof (void *));
+ streams = (CUstream *) malloc ((2 + N) * sizeof (void *));
+ streams += 2;
+ /* "streams[i]" is valid for i in [acc_async_sync..N). */
- for (i = 0; i < N; i++)
+ for (i = acc_async_sync; i < N; i++)
{
streams[i] = (CUstream) acc_get_cuda_stream (i);
if (streams[i] != NULL)
@@ -35,11 +45,20 @@ main (int argc, char **argv)
abort ();
}
- if (!acc_set_cuda_stream (i, streams[i]))
- abort ();
+ int ret = acc_set_cuda_stream (i, streams[i]);
+ if (i == acc_async_sync)
+ {
+ if (ret == 1)
+ abort ();
+ }
+ else
+ {
+ if (ret != 1)
+ abort ();
+ }
}
- for (i = 0; i < N; i++)
+ for (i = acc_async_sync; i < N; i++)
{
int j;
int cnt;
@@ -48,7 +67,7 @@ main (int argc, char **argv)
s = streams[i];
- for (j = 0; j < N; j++)
+ for (j = acc_async_sync; j < N; j++)
{
if (s == streams[j])
cnt++;
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-85.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-85.c
index cf925a7b002..141c83b53dd 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-85.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-85.c
@@ -7,6 +7,14 @@
#include <stdio.h>
#include <cuda.h>
+#if !defined __cplusplus
+# undef static_assert
+# define static_assert _Static_assert
+#endif
+
+static_assert (acc_async_sync == -2, "acc_async_sync?");
+static_assert (acc_async_noval == -1, "acc_async_noval?");
+
int
main (int argc, char **argv)
{
@@ -20,9 +28,11 @@ main (int argc, char **argv)
(void) acc_get_device_num (acc_device_nvidia);
- streams = (CUstream *) malloc (N * sizeof (void *));
+ streams = (CUstream *) malloc ((2 + N) * sizeof (void *));
+ streams += 2;
+ /* "streams[i]" is valid for i in [acc_async_sync..N). */
- for (i = 0; i < N; i++)
+ for (i = acc_async_sync; i < N; i++)
{
streams[i] = (CUstream) acc_get_cuda_stream (i);
if (streams[i] != NULL)
@@ -35,8 +45,17 @@ main (int argc, char **argv)
abort ();
}
- if (!acc_set_cuda_stream (i, streams[i]))
- abort ();
+ int ret = acc_set_cuda_stream (i, streams[i]);
+ if (i == acc_async_sync)
+ {
+ if (ret == 1)
+ abort ();
+ }
+ else
+ {
+ if (ret != 1)
+ abort ();
+ }
}
s = NULL;
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-94.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-94.c
new file mode 100644
index 00000000000..54497237b0c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-94.c
@@ -0,0 +1,42 @@
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <openacc.h>
+
+int
+main (int argc, char **argv)
+{
+ const int N = 256;
+ int i;
+ int async = 8;
+ unsigned char *h;
+
+ h = (unsigned char *) malloc (N);
+
+ for (i = 0; i < N; i++)
+ {
+ h[i] = i;
+ }
+
+ acc_copyin_async (h, N, async);
+
+ memset (h, 0, N);
+
+ acc_wait (async);
+
+ acc_copyout_async (h, N, async + 1);
+
+ acc_wait (async + 1);
+
+ for (i = 0; i < N; i++)
+ {
+ if (h[i] != i)
+ abort ();
+ }
+
+ free (h);
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-95.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-95.c
new file mode 100644
index 00000000000..85b238d78c8
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-95.c
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <openacc.h>
+
+int
+main (int argc, char **argv)
+{
+ const int N = 256;
+ int i, q = 5;
+ unsigned char *h, *g;
+ void *d;
+
+ h = (unsigned char *) malloc (N);
+ g = (unsigned char *) malloc (N);
+ for (i = 0; i < N; i++)
+ {
+ g[i] = i;
+ }
+
+ acc_create_async (h, N, q);
+
+ acc_memcpy_to_device_async (acc_deviceptr (h), g, N, q);
+ memset (&h[0], 0, N);
+
+ acc_wait (q);
+
+ acc_update_self_async (h, N, q + 1);
+ acc_delete_async (h, N, q + 1);
+
+ acc_wait (q + 1);
+
+ for (i = 0; i < N; i++)
+ {
+ if (h[i] != i)
+ abort ();
+ }
+
+ free (h);
+ free (g);
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-default.h b/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-default.h
index a9e26939cf2..8c71249687c 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-default.h
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-default.h
@@ -1,5 +1,4 @@
#include <openacc.h>
-#include <alloca.h>
#include <string.h>
#include <stdio.h>
#include <gomp-constants.h>
@@ -28,9 +27,9 @@ check (const int *ary, int size, int gp, int wp, int vp)
{
int exit = 0;
int ix;
- int *gangs = (int *)alloca (gp * sizeof (int));
- int *workers = (int *)alloca (wp * sizeof (int));
- int *vectors = (int *)alloca (vp * sizeof (int));
+ int *gangs = (int *)__builtin_alloca (gp * sizeof (int));
+ int *workers = (int *)__builtin_alloca (wp * sizeof (int));
+ int *vectors = (int *)__builtin_alloca (vp * sizeof (int));
int offloaded = 0;
memset (gangs, 0, gp * sizeof (int));
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-dim-default.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-dim-default.c
index dd8107c1acc..04387d36174 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-dim-default.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/loop-dim-default.c
@@ -1,7 +1,6 @@
/* { dg-additional-options "-fopenacc-dim=16:16" } */
#include <openacc.h>
-#include <alloca.h>
#include <string.h>
#include <stdio.h>
#include <gomp-constants.h>
@@ -28,9 +27,9 @@ int check (const int *ary, int size, int gp, int wp, int vp)
{
int exit = 0;
int ix;
- int *gangs = (int *)alloca (gp * sizeof (int));
- int *workers = (int *)alloca (wp * sizeof (int));
- int *vectors = (int *)alloca (vp * sizeof (int));
+ int *gangs = (int *)__builtin_alloca (gp * sizeof (int));
+ int *workers = (int *)__builtin_alloca (wp * sizeof (int));
+ int *vectors = (int *)__builtin_alloca (vp * sizeof (int));
int offloaded = 0;
memset (gangs, 0, gp * sizeof (int));
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/mapping-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/mapping-1.c
new file mode 100644
index 00000000000..593e7d4d553
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/mapping-1.c
@@ -0,0 +1,63 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Exercise the kernel launch argument mapping. */
+
+int
+main (int argc, char **argv)
+{
+ int a[256], b[256], c[256], d[256], e[256], f[256];
+ int i;
+ int n;
+
+ /* 48 is the size of the mappings for the first parallel construct. */
+ n = sysconf (_SC_PAGESIZE) / 48 - 1;
+
+ i = 0;
+
+ for (i = 0; i < n; i++)
+ {
+ #pragma acc parallel copy (a, b, c, d)
+ {
+ int j;
+
+ for (j = 0; j < 256; j++)
+ {
+ a[j] = j;
+ b[j] = j;
+ c[j] = j;
+ d[j] = j;
+ }
+ }
+ }
+
+#pragma acc parallel copy (a, b, c, d, e, f)
+ {
+ int j;
+
+ for (j = 0; j < 256; j++)
+ {
+ a[j] = j;
+ b[j] = j;
+ c[j] = j;
+ d[j] = j;
+ e[j] = j;
+ f[j] = j;
+ }
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ if (a[i] != i) abort();
+ if (b[i] != i) abort();
+ if (c[i] != i) abort();
+ if (d[i] != i) abort();
+ if (e[i] != i) abort();
+ if (f[i] != i) abort();
+ }
+
+ exit (0);
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/nvptx-merged-loop.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/nvptx-merged-loop.c
new file mode 100644
index 00000000000..8a2117e1624
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/nvptx-merged-loop.c
@@ -0,0 +1,30 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-options "-foffload=-fdump-rtl-mach" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+
+#define N (32*32*32+17)
+void __attribute__ ((noinline)) Foo (int *ary)
+{
+ int ix;
+
+#pragma acc parallel num_workers(32) vector_length(32) copyout(ary[0:N])
+ {
+ /* Loop partitioning should be merged. */
+#pragma acc loop worker vector
+ for (unsigned ix = 0; ix < N; ix++)
+ {
+ ary[ix] = ix;
+ }
+ }
+}
+
+int main ()
+{
+ int ary[N];
+
+ Foo (ary);
+
+ return 0;
+}
+
+/* { dg-final { scan-offload-rtl-dump "Merging loop .* into " "mach" } } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/nvptx-sese-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/nvptx-sese-1.c
new file mode 100644
index 00000000000..9583265c775
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/nvptx-sese-1.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-options "-foffload=-fdump-rtl-mach" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+
+#pragma acc routine seq
+int __attribute__((noinline)) foo (int x)
+{
+ return x & 2;
+}
+
+int main ()
+{
+ int r = 0;
+
+#pragma acc parallel copy(r) vector_length(32)
+ {
+#pragma acc loop vector reduction (+:r)
+ for (int i = 00; i < 40; i++)
+ r += i;
+
+ /* This piece is a multi-block SESE region */
+ if (foo (r))
+ r *= 2;
+
+ if (r & 1) /* to here. */
+#pragma acc loop vector reduction (+:r)
+ for (int i = 00; i < 40; i++)
+ r += i;
+ }
+
+ return 0;
+}
+
+/* Match {N->N(.N)+} */
+/* { dg-final { scan-offload-rtl-dump "SESE regions:.* \[0-9\]+{\[0-9\]+->\[0-9\]+(\\.\[0-9\]+)+}" "mach" } } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-1.c
index 5e82e1d350c..8c08717fdf2 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-1.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-1.c
@@ -15,7 +15,7 @@ main (int argc, char *argv[])
#pragma acc parallel num_gangs(32) num_workers(32) vector_length(32) \
reduction(+:res) copy(res)
{
- #pragma acc loop gang
+ #pragma acc loop gang /* { dg-warning "nested loop in reduction needs reduction clause for 'res'" "TODO" } */
for (j = 0; j < 32; j++)
{
#pragma acc loop worker reduction(+:res)
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-2.c
index a339f327956..41042accbde 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-2.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-2.c
@@ -14,7 +14,7 @@ main (int argc, char *argv[])
#pragma acc parallel num_gangs(32) num_workers(32) vector_length(32) \
reduction(^:res)
{
- #pragma acc loop gang
+ #pragma acc loop gang /* { dg-warning "nested loop in reduction needs reduction clause for 'res'" "TODO" } */
for (j = 0; j < 32; j++)
{
#pragma acc loop worker vector reduction(^:res)
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-3.c
index 6369d7fbb33..ace1e005e2e 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-3.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-3.c
@@ -16,7 +16,7 @@ main (int argc, char *argv[])
#pragma acc parallel num_gangs(32) num_workers(32) vector_length(32) \
reduction(+:res) copy(res)
{
- #pragma acc loop gang
+ #pragma acc loop gang /* { dg-warning "nested loop in reduction needs reduction clause for 'res'" "TODO" } */
for (j = 0; j < 32; j++)
{
#pragma acc loop worker vector reduction(+:res)
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-4.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-4.c
index 140c3226327..c3cc12fa953 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-4.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-4.c
@@ -16,7 +16,7 @@ main (int argc, char *argv[])
#pragma acc parallel num_gangs(32) num_workers(32) vector_length(32) \
reduction(+:res) reduction(max:mres) copy(res, mres)
{
- #pragma acc loop gang
+ #pragma acc loop gang /* { dg-warning "nested loop in reduction needs reduction clause for 'm\?res'" "TODO" } */
for (j = 0; j < 32; j++)
{
#pragma acc loop worker vector reduction(+:res) reduction(max:mres)
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/parallel-dims.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/parallel-dims.c
index 4a9854662cc..a5edfc6ca16 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/parallel-dims.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/parallel-dims.c
@@ -1,6 +1,8 @@
/* OpenACC parallelism dimensions clauses: num_gangs, num_workers,
vector_length. */
+/* See also '../libgomp.oacc-fortran/parallel-dims.f90'. */
+
#include <limits.h>
#include <openacc.h>
#include <gomp-constants.h>
@@ -45,6 +47,8 @@ int main ()
{
acc_init (acc_device_default);
+ /* OpenACC parallel construct. */
+
/* Non-positive value. */
/* GR, WS, VS. */
@@ -154,7 +158,7 @@ int main ()
int gangs_min, gangs_max, workers_min, workers_max, vectors_min, vectors_max;
gangs_min = workers_min = vectors_min = INT_MAX;
gangs_max = workers_max = vectors_max = INT_MIN;
-#pragma acc parallel copy (vectors_actual) /* { dg-warning "using vector_length \\(32\\), ignoring 1" "" { target openacc_nvidia_accel_configured } } */ \
+#pragma acc parallel copy (vectors_actual) /* { dg-warning "using vector_length \\(32\\), ignoring 1" "" { target openacc_nvidia_accel_selected } } */ \
vector_length (VECTORS) /* { dg-warning "'vector_length' value must be positive" "" { target c++ } } */
{
/* We're actually executing with vector_length (1), just the GCC nvptx
@@ -265,7 +269,7 @@ int main ()
int gangs_min, gangs_max, workers_min, workers_max, vectors_min, vectors_max;
gangs_min = workers_min = vectors_min = INT_MAX;
gangs_max = workers_max = vectors_max = INT_MIN;
-#pragma acc parallel copy (workers_actual) /* { dg-warning "using num_workers \\(32\\), ignoring 2097152" "" { target openacc_nvidia_accel_configured } } */ \
+#pragma acc parallel copy (workers_actual) /* { dg-warning "using num_workers \\(32\\), ignoring 2097152" "" { target openacc_nvidia_accel_selected } } */ \
num_workers (WORKERS)
{
if (acc_on_device (acc_device_host))
@@ -350,7 +354,7 @@ int main ()
int gangs_min, gangs_max, workers_min, workers_max, vectors_min, vectors_max;
gangs_min = workers_min = vectors_min = INT_MAX;
gangs_max = workers_max = vectors_max = INT_MIN;
-#pragma acc parallel copy (vectors_actual) /* { dg-warning "using vector_length \\(32\\), ignoring 2097152" "" { target openacc_nvidia_accel_configured } } */ \
+#pragma acc parallel copy (vectors_actual) /* { dg-warning "using vector_length \\(1024\\), ignoring 2097152" "" { target openacc_nvidia_accel_selected } } */ \
vector_length (VECTORS)
{
if (acc_on_device (acc_device_host))
@@ -361,7 +365,7 @@ int main ()
else if (acc_on_device (acc_device_nvidia))
{
/* The GCC nvptx back end enforces vector_length (32). */
- vectors_actual = 32;
+ vectors_actual = 1024;
}
else
__builtin_abort ();
@@ -390,7 +394,7 @@ int main ()
int gangs_min, gangs_max, workers_min, workers_max, vectors_min, vectors_max;
gangs_min = workers_min = vectors_min = INT_MAX;
gangs_max = workers_max = vectors_max = INT_MIN;
-#pragma acc parallel copy (vectors_actual) /* { dg-warning "using vector_length \\(32\\), ignoring runtime setting" "" { target openacc_nvidia_accel_configured } } */ \
+#pragma acc parallel copy (vectors_actual) /* { dg-warning "using vector_length \\(32\\), ignoring runtime setting" "" { target openacc_nvidia_accel_selected } } */ \
vector_length (vectors)
{
if (acc_on_device (acc_device_host))
@@ -437,7 +441,7 @@ int main ()
int gangs_min, gangs_max, workers_min, workers_max, vectors_min, vectors_max;
gangs_min = workers_min = vectors_min = INT_MAX;
gangs_max = workers_max = vectors_max = INT_MIN;
-#pragma acc parallel copy (gangs_actual, workers_actual, vectors_actual) /* { dg-warning "using vector_length \\(32\\), ignoring 11" "" { target openacc_nvidia_accel_configured } } */ \
+#pragma acc parallel copy (gangs_actual, workers_actual, vectors_actual) /* { dg-warning "using vector_length \\(32\\), ignoring 11" "" { target openacc_nvidia_accel_selected } } */ \
num_gangs (gangs) \
num_workers (WORKERS) \
vector_length (VECTORS)
@@ -478,6 +482,8 @@ int main ()
}
+ /* OpenACC kernels construct. */
+
/* We can't test parallelized OpenACC kernels constructs in this way: use of
the acc_gang, acc_worker, acc_vector functions will make the construct
unparallelizable. */
@@ -544,5 +550,72 @@ int main ()
}
+ /* OpenACC serial construct. */
+
+ /* GR, WS, VS. */
+ {
+ int gangs_min, gangs_max, workers_min, workers_max, vectors_min, vectors_max;
+ gangs_min = workers_min = vectors_min = INT_MAX;
+ gangs_max = workers_max = vectors_max = INT_MIN;
+#pragma acc serial /* { dg-warning "using vector_length \\(32\\), ignoring 1" "" { target openacc_nvidia_accel_selected } } */ \
+ reduction (min: gangs_min, workers_min, vectors_min) reduction (max: gangs_max, workers_max, vectors_max)
+ {
+ for (int i = 100; i > -100; i--)
+ {
+ gangs_min = gangs_max = acc_gang ();
+ workers_min = workers_max = acc_worker ();
+ vectors_min = vectors_max = acc_vector ();
+ }
+ }
+ if (gangs_min != 0 || gangs_max != 1 - 1
+ || workers_min != 0 || workers_max != 1 - 1
+ || vectors_min != 0 || vectors_max != 1 - 1)
+ __builtin_abort ();
+ }
+
+ /* Composition of GP, WP, VP. */
+ {
+ int vectors_actual = 1; /* Implicit 'vector_length (1)' clause. */
+ int gangs_min, gangs_max, workers_min, workers_max, vectors_min, vectors_max;
+ gangs_min = workers_min = vectors_min = INT_MAX;
+ gangs_max = workers_max = vectors_max = INT_MIN;
+#pragma acc serial copy (vectors_actual) /* { dg-warning "using vector_length \\(32\\), ignoring 1" "" { target openacc_nvidia_accel_selected } } */ \
+ copy (gangs_min, gangs_max, workers_min, workers_max, vectors_min, vectors_max)
+ {
+ if (acc_on_device (acc_device_nvidia))
+ {
+ /* The GCC nvptx back end enforces vector_length (32). */
+ /* It's unclear if that's actually permissible here;
+ <https://github.com/OpenACC/openacc-spec/issues/238> "OpenACC
+ 'serial' construct might not actually be serial". */
+ vectors_actual = 32;
+ }
+#pragma acc loop gang reduction (min: gangs_min, workers_min, vectors_min) reduction (max: gangs_max, workers_max, vectors_max)
+ for (int i = 100; i > -100; i--)
+#pragma acc loop worker reduction (min: gangs_min, workers_min, vectors_min) reduction (max: gangs_max, workers_max, vectors_max)
+ for (int j = 100; j > -100; j--)
+#pragma acc loop vector reduction (min: gangs_min, workers_min, vectors_min) reduction (max: gangs_max, workers_max, vectors_max)
+ for (int k = 100 * vectors_actual; k > -100 * vectors_actual; k--)
+ {
+ gangs_min = gangs_max = acc_gang ();
+ workers_min = workers_max = acc_worker ();
+ vectors_min = vectors_max = acc_vector ();
+ }
+ }
+ if (acc_get_device_type () == acc_device_nvidia)
+ {
+ if (vectors_actual != 32)
+ __builtin_abort ();
+ }
+ else
+ if (vectors_actual != 1)
+ __builtin_abort ();
+ if (gangs_min != 0 || gangs_max != 1 - 1
+ || workers_min != 0 || workers_max != 1 - 1
+ || vectors_min != 0 || vectors_max != vectors_actual - 1)
+ __builtin_abort ();
+ }
+
+
return 0;
}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr84955-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr84955-1.c
new file mode 100644
index 00000000000..44767cd27c3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr84955-1.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cddce2 -ffinite-loops" } */
+
+int
+f1 (void)
+{
+ int i, j;
+
+#pragma acc parallel loop tile(2,3)
+ for (i = 1; i < 10; i++)
+ for (j = 1; j < 10; j++)
+ for (;;)
+ ;
+
+ return i + j;
+}
+
+int
+f2 (void)
+{
+ int i, j, k;
+
+#pragma acc parallel loop tile(2,3)
+ for (i = 1; i < 10; i++)
+ for (j = 1; j < 10; j++)
+ for (k = 1; k < 10; k++)
+ ;
+
+ return i + j;
+}
+/* { dg-final { scan-tree-dump-not "if" "cddce2"} } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-2.c
new file mode 100644
index 00000000000..2cb5b95949d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-2.c
@@ -0,0 +1,18 @@
+/* { dg-additional-options "-save-temps" } */
+/* { dg-do run { target openacc_nvidia_accel_selected } }
+ { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+
+int
+main (void)
+{
+ int v1;
+
+ #pragma acc parallel
+ #pragma acc loop worker
+ for (v1 = 0; v1 < 20; v1 += 2)
+ ;
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "bar.sync" 0 } } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-3.c
new file mode 100644
index 00000000000..c5d1c5add68
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-3.c
@@ -0,0 +1,35 @@
+/* { dg-additional-options "-save-temps -w" } */
+/* { dg-do run { target openacc_nvidia_accel_selected } }
+ { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+
+int a;
+#pragma acc declare create(a)
+
+#pragma acc routine vector
+void __attribute__((noinline, noclone))
+foo_v (void)
+{
+ a = 1;
+}
+
+#pragma acc routine worker
+void __attribute__((noinline, noclone))
+foo_w (void)
+{
+ a = 2;
+}
+
+int
+main (void)
+{
+
+ #pragma acc parallel
+ foo_v ();
+
+ #pragma acc parallel
+ foo_w ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "bar.sync" } } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-4.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-4.c
new file mode 100644
index 00000000000..e8a433ffc0a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-4.c
@@ -0,0 +1,24 @@
+/* { dg-additional-options "-save-temps -w" } */
+/* { dg-do run { target openacc_nvidia_accel_selected } }
+ { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+
+#define n 1024
+
+int
+main (void)
+{
+ #pragma acc parallel
+ {
+ #pragma acc loop worker
+ for (int i = 0; i < n; i++)
+ ;
+
+ #pragma acc loop worker
+ for (int i = 0; i < n; i++)
+ ;
+ }
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "bar.sync" 0 } } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-5.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-5.c
new file mode 100644
index 00000000000..61e7e48f0c9
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381-5.c
@@ -0,0 +1,24 @@
+/* { dg-additional-options "-save-temps" } */
+/* { dg-do run { target openacc_nvidia_accel_selected } }
+ { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+
+#define n 1024
+
+int
+main (void)
+{
+ #pragma acc parallel vector_length(128)
+ {
+ #pragma acc loop vector
+ for (int i = 0; i < n; i++)
+ ;
+
+ #pragma acc loop vector
+ for (int i = 0; i < n; i++)
+ ;
+ }
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "bar.sync" } } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381.c
new file mode 100644
index 00000000000..2864dfcf3cb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85381.c
@@ -0,0 +1,18 @@
+/* { dg-additional-options "-save-temps" } */
+/* { dg-do run { target openacc_nvidia_accel_selected } }
+ { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
+
+int
+main (void)
+{
+ int v1;
+
+ #pragma acc parallel vector_length (128)
+ #pragma acc loop vector
+ for (v1 = 0; v1 < 20; v1 += 2)
+ ;
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "bar.sync" } } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486-2.c
new file mode 100644
index 00000000000..f6ca263166d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486-2.c
@@ -0,0 +1,52 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-additional-options "-fopenacc-dim=::128" } */
+
+/* Minimized from ref-1.C. */
+
+#include <stdio.h>
+
+#pragma acc routine vector
+void __attribute__((noinline, noclone))
+Vector (int *ptr, int n, const int inc)
+{
+ #pragma acc loop vector
+ for (unsigned ix = 0; ix < n; ix++)
+ ptr[ix] += inc;
+}
+
+int
+main (void)
+{
+ const int n = 32, m=32;
+
+ int ary[m][n];
+ unsigned ix, iy;
+
+ for (ix = m; ix--;)
+ for (iy = n; iy--;)
+ ary[ix][iy] = (1 << 16) + (ix << 8) + iy;
+
+ int err = 0;
+
+#pragma acc parallel copy (ary)
+ {
+ Vector (&ary[0][0], m * n, (1 << 24) - (1 << 16));
+ }
+
+ for (ix = m; ix--;)
+ for (iy = n; iy--;)
+ if (ary[ix][iy] != ((1 << 24) + (ix << 8) + iy))
+ {
+ printf ("ary[%u][%u] = %x expected %x\n",
+ ix, iy, ary[ix][iy], ((1 << 24) + (ix << 8) + iy));
+ err++;
+ }
+
+ if (err)
+ {
+ printf ("%d failed\n", err);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486-3.c
new file mode 100644
index 00000000000..a959b90c29a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486-3.c
@@ -0,0 +1,54 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-set-target-env-var "GOMP_OPENACC_DIM" "::128" } */
+
+/* Minimized from ref-1.C. */
+
+#include <stdio.h>
+
+#pragma acc routine vector
+void __attribute__((noinline, noclone))
+Vector (int *ptr, int n, const int inc)
+{
+ #pragma acc loop vector
+ for (unsigned ix = 0; ix < n; ix++)
+ ptr[ix] += inc;
+}
+
+int
+main (void)
+{
+ const int n = 32, m=32;
+
+ int ary[m][n];
+ unsigned ix, iy;
+
+ for (ix = m; ix--;)
+ for (iy = n; iy--;)
+ ary[ix][iy] = (1 << 16) + (ix << 8) + iy;
+
+ int err = 0;
+
+#pragma acc parallel copy (ary)
+ {
+ Vector (&ary[0][0], m * n, (1 << 24) - (1 << 16));
+ }
+
+ for (ix = m; ix--;)
+ for (iy = n; iy--;)
+ if (ary[ix][iy] != ((1 << 24) + (ix << 8) + iy))
+ {
+ printf ("ary[%u][%u] = %x expected %x\n",
+ ix, iy, ary[ix][iy], ((1 << 24) + (ix << 8) + iy));
+ err++;
+ }
+
+ if (err)
+ {
+ printf ("%d failed\n", err);
+ return 1;
+ }
+
+ return 0;
+}
+
+/* { dg-prune-output "using vector_length \\(32\\), ignoring runtime setting" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486.c
new file mode 100644
index 00000000000..99c08059d37
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr85486.c
@@ -0,0 +1,51 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+
+/* Minimized from ref-1.C. */
+
+#include <stdio.h>
+
+#pragma acc routine vector
+void __attribute__((noinline, noclone))
+Vector (int *ptr, int n, const int inc)
+{
+ #pragma acc loop vector
+ for (unsigned ix = 0; ix < n; ix++)
+ ptr[ix] += inc;
+}
+
+int
+main (void)
+{
+ const int n = 32, m=32;
+
+ int ary[m][n];
+ unsigned ix, iy;
+
+ for (ix = m; ix--;)
+ for (iy = n; iy--;)
+ ary[ix][iy] = (1 << 16) + (ix << 8) + iy;
+
+ int err = 0;
+
+#pragma acc parallel copy (ary) vector_length (128) /* { dg-warning "using vector_length \\(32\\) due to call to vector-partitionable routine, ignoring 128" } */
+ {
+ Vector (&ary[0][0], m * n, (1 << 24) - (1 << 16));
+ }
+
+ for (ix = m; ix--;)
+ for (iy = n; iy--;)
+ if (ary[ix][iy] != ((1 << 24) + (ix << 8) + iy))
+ {
+ printf ("ary[%u][%u] = %x expected %x\n",
+ ix, iy, ary[ix][iy], ((1 << 24) + (ix << 8) + iy));
+ err++;
+ }
+
+ if (err)
+ {
+ printf ("%d failed\n", err);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr87835.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr87835.c
new file mode 100644
index 00000000000..88c2c7763cc
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr87835.c
@@ -0,0 +1,61 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-additional-options "-lcuda" } */
+
+#include <openacc.h>
+#include <stdlib.h>
+#include "cuda.h"
+
+#include <stdio.h>
+
+#define n 128
+
+int
+main (void)
+{
+ CUresult r;
+ CUstream stream1;
+ int N = n;
+ int a[n];
+ int c[n];
+
+ acc_init (acc_device_nvidia);
+
+ r = cuStreamCreate (&stream1, CU_STREAM_NON_BLOCKING);
+ if (r != CUDA_SUCCESS)
+ {
+ fprintf (stderr, "cuStreamCreate failed: %d\n", r);
+ abort ();
+ }
+
+ acc_set_cuda_stream (1, stream1);
+
+ for (int i = 0; i < n; i++)
+ {
+ a[i] = 3;
+ c[i] = 0;
+ }
+
+#pragma acc data copy (a, c) copyin (N)
+ {
+#pragma acc parallel async (1)
+ ;
+
+#pragma acc parallel async (1) num_gangs (320)
+ #pragma acc loop gang
+ for (int ii = 0; ii < N; ii++)
+ c[ii] = (a[ii] + a[N - ii - 1]);
+
+#pragma acc parallel async (1)
+ #pragma acc loop seq
+ for (int ii = 0; ii < n; ii++)
+ a[ii] = 6;
+
+#pragma acc wait (1)
+ }
+
+ for (int i = 0; i < n; i++)
+ if (c[i] != 6)
+ abort ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr88288.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr88288.c
new file mode 100644
index 00000000000..d13e3359a3e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr88288.c
@@ -0,0 +1,41 @@
+/* Test present data clauses in acc offloaded regions when the
+ subarray inside the present clause does not have the same base
+ offset value as the subarray in the enclosing acc data or acc enter
+ data variable. */
+
+#include <assert.h>
+
+void
+offset (int *data, int n)
+{
+ int i;
+
+#pragma acc parallel loop present (data[0:n])
+ for (i = 0; i < n; i++)
+ data[i] = n;
+}
+
+int
+main ()
+{
+ const int n = 30;
+ int data[n], i;
+
+ for (i = 0; i < n; i++)
+ data[i] = -1;
+
+#pragma acc data copy(data[0:n])
+ {
+ offset (data + 10, 10);
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ if (i < 10 || i >= 20)
+ assert (data[i] == -1);
+ else
+ assert (data[i] == 10);
+ }
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr88941.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr88941.c
new file mode 100644
index 00000000000..e31bb527df3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr88941.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+
+#include <stdlib.h>
+
+int
+main (void)
+{
+
+#pragma acc parallel async
+ ;
+
+ /* no #pragma acc wait */
+ return 0;
+}
+
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr88946.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr88946.c
new file mode 100644
index 00000000000..ad56ded1d2b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr88946.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+
+int
+main (void)
+{
+ #pragma acc parallel async
+ ;
+
+ #pragma acc parallel async
+ ;
+
+ #pragma acc wait
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr89376.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr89376.c
new file mode 100644
index 00000000000..7f6c83254d5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr89376.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fno-tree-ch -fno-tree-dce -fno-tree-vrp" } */
+
+int
+main (void)
+{
+ int fa;
+
+ #pragma acc kernels
+ for (int rw = 0; rw < 1; ++rw)
+ fa = 0;
+
+ return 0;
+}
+
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr90009.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr90009.c
new file mode 100644
index 00000000000..58d1039dd8d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr90009.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+
+#include <stdlib.h>
+
+#define N 100
+
+int data[N];
+
+int
+main (void)
+{
+ int n = N, b = 3;
+#pragma acc parallel num_workers(2)
+ {
+ int c;
+ if (n)
+ c = 0;
+ else
+ c = b;
+
+#pragma acc loop worker
+ for (int i = 0; i < n; i++)
+ data[i] = 1;
+
+ if (c)
+ data[0] = 2;
+ }
+
+ for (int i = 0; i < n; i++)
+ if (data[i] != 1)
+ abort ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-1.c
index e8a8911faeb..4e76ccd5b5c 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-1.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-1.c
@@ -1,16 +1,13 @@
/* { dg-do run } */
-/* Ignore vector_length warnings for offloaded (nvptx) targets. */
-/* { dg-additional-options "-foffload=-w" } */
-
/* Integer reductions. */
#include <stdlib.h>
#include "reduction.h"
-const int ng = 8;
-const int nw = 4;
-const int vl = 32;
+#define ng 8
+#define nw 4
+#define vl 32
static void
test_reductions (void)
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-2.c
index d19b1c825ca..96e6c079ef3 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-2.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-2.c
@@ -1,16 +1,13 @@
/* { dg-do run } */
-/* Ignore vector_length warnings for offloaded (nvptx) targets. */
-/* { dg-additional-options "-foffload=-w" } */
-
/* float reductions. */
#include <stdlib.h>
#include "reduction.h"
-const int ng = 8;
-const int nw = 4;
-const int vl = 32;
+#define ng 8
+#define nw 4
+#define vl 32
static void
test_reductions (void)
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-3.c
index 1b948bef5a0..dc18426d748 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-3.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-3.c
@@ -1,16 +1,13 @@
/* { dg-do run } */
-/* Ignore vector_length warnings for offloaded (nvptx) targets. */
-/* { dg-additional-options "-foffload=-w" } */
-
/* double reductions. */
#include <stdlib.h>
#include "reduction.h"
-const int ng = 8;
-const int nw = 4;
-const int vl = 32;
+#define ng 8
+#define nw 4
+#define vl 32
static void
test_reductions (void)
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-4.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-4.c
index 79355eded80..d152674be45 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-4.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-4.c
@@ -1,17 +1,14 @@
/* { dg-do run { target { ! { hppa*-*-hpux* } } } } */
-/* Ignore vector_length warnings for offloaded (nvptx) targets. */
-/* { dg-additional-options "-foffload=-w" } */
-
/* complex reductions. */
#include <stdlib.h>
#include <complex.h>
#include "reduction.h"
-const int ng = 8;
-const int nw = 4;
-const int vl = 32;
+#define ng 8
+#define nw 4
+#define vl 32
static void
test_reductions (void)
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-5.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-5.c
index 46b553a61ff..6f5d29316a0 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-5.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/reduction-5.c
@@ -1,17 +1,14 @@
/* { dg-do run } */
/* { dg-additional-options "-w" } */
-/* Ignore vector_length warnings for offloaded (nvptx) targets. */
-/* { dg-additional-options "-foffload=-w" } */
-
/* Multiple reductions. */
#include <stdio.h>
#include <stdlib.h>
-const int ng = 8;
-const int nw = 4;
-const int vl = 32;
+#define ng 8
+#define nw 4
+#define vl 32
const int n = 100;
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-1.c
index 2a36b3b1fac..0f70e264240 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-1.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/routine-1.c
@@ -1,5 +1,3 @@
-// { dg-additional-options "-fno-exceptions" }
-
// Defaults, if not "#include"d from ../libgomp.oacc-c++/routine-1-*.C.
#ifndef TEMPLATE
# define TEMPLATE
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/variable-not-offloaded.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/variable-not-offloaded.c
new file mode 100644
index 00000000000..8e10271b97f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/variable-not-offloaded.c
@@ -0,0 +1,17 @@
+/* { dg-do link } */
+
+int var; /* { dg-error "'var' requires a 'declare' directive for use in a 'routine' function" } */
+
+#pragma acc routine
+void __attribute__((noinline, noclone))
+foo (void)
+{
+ var++;
+}
+
+int
+main ()
+{
+#pragma acc parallel
+ foo ();
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-1.c
new file mode 100644
index 00000000000..18d77cc5ecb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-1.c
@@ -0,0 +1,38 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-additional-options "-foffload=-fdump-tree-oaccdevlow" } */
+/* { dg-set-target-env-var "GOMP_DEBUG" "1" } */
+
+#include <stdlib.h>
+
+#define N 1024
+
+unsigned int a[N];
+unsigned int b[N];
+unsigned int c[N];
+unsigned int n = N;
+
+int
+main (void)
+{
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ a[i] = i % 3;
+ b[i] = i % 5;
+ }
+
+#pragma acc parallel vector_length (128) copyin (a,b) copyout (c)
+ {
+#pragma acc loop vector
+ for (unsigned int i = 0; i < n; i++)
+ c[i] = a[i] + b[i];
+ }
+
+ for (unsigned int i = 0; i < n; ++i)
+ if (c[i] != (i % 3) + (i % 5))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-offload-tree-dump "__attribute__\\(\\(oacc function \\(1, 1, 128\\)" "oaccdevlow" } } */
+/* { dg-output "nvptx_exec: kernel main\\\$_omp_fn\\\$0: launch gangs=1, workers=1, vectors=128" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-10.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-10.c
new file mode 100644
index 00000000000..0658cfde7ad
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-10.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+
+#include <stdlib.h>
+
+#define N 1024
+
+unsigned int a[N];
+unsigned int b[N];
+unsigned int c[N];
+unsigned int n = N;
+
+int
+main (void)
+{
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ a[i] = i % 3;
+ b[i] = i % 5;
+ }
+
+ unsigned int res = 1;
+ unsigned long long res2 = 1;
+#pragma acc parallel vector_length (128) copyin (a,b) reduction (+:res, res2) copy (res, res2)
+ {
+#pragma acc loop vector reduction (+:res, res2)
+ for (unsigned int i = 0; i < n; i++)
+ {
+ res += ((a[i] + b[i]) % 2);
+ res2 += ((a[i] + b[i]) % 2);
+ }
+ }
+
+ if (res != 478)
+ abort ();
+ if (res2 != 478)
+ abort ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-2.c
new file mode 100644
index 00000000000..8b5b2a4a92d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-2.c
@@ -0,0 +1,39 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-additional-options "-fopenacc-dim=::128" } */
+/* { dg-additional-options "-foffload=-fdump-tree-oaccdevlow" } */
+/* { dg-set-target-env-var "GOMP_DEBUG" "1" } */
+
+#include <stdlib.h>
+
+#define N 1024
+
+unsigned int a[N];
+unsigned int b[N];
+unsigned int c[N];
+unsigned int n = N;
+
+int
+main (void)
+{
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ a[i] = i % 3;
+ b[i] = i % 5;
+ }
+
+#pragma acc parallel copyin (a,b) copyout (c)
+ {
+#pragma acc loop vector
+ for (unsigned int i = 0; i < n; i++)
+ c[i] = a[i] + b[i];
+ }
+
+ for (unsigned int i = 0; i < n; ++i)
+ if (c[i] != (i % 3) + (i % 5))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-offload-tree-dump "__attribute__\\(\\(oacc function \\(1, 1, 128\\)" "oaccdevlow" } } */
+/* { dg-output "nvptx_exec: kernel main\\\$_omp_fn\\\$0: launch gangs=1, workers=1, vectors=128" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-3.c
new file mode 100644
index 00000000000..59be37a7c27
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-3.c
@@ -0,0 +1,42 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-additional-options "-foffload=-fdump-tree-oaccdevlow" } */
+/* We default to warp size 32 for the vector length, so the GOMP_OPENACC_DIM has
+ no effect. */
+/* { dg-set-target-env-var "GOMP_OPENACC_DIM" "::128" } */
+/* { dg-set-target-env-var "GOMP_DEBUG" "1" } */
+
+
+#include <stdlib.h>
+
+#define N 1024
+
+unsigned int a[N];
+unsigned int b[N];
+unsigned int c[N];
+unsigned int n = N;
+
+int
+main (void)
+{
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ a[i] = i % 3;
+ b[i] = i % 5;
+ }
+
+#pragma acc parallel copyin (a,b) copyout (c)
+ {
+#pragma acc loop vector
+ for (unsigned int i = 0; i < n; i++)
+ c[i] = a[i] + b[i];
+ }
+
+ for (unsigned int i = 0; i < n; ++i)
+ if (c[i] != (i % 3) + (i % 5))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-offload-tree-dump "__attribute__\\(\\(oacc function \\(1, 1, 32\\)" "oaccdevlow" } } */
+/* { dg-output "nvptx_exec: kernel main\\\$_omp_fn\\\$0: launch gangs=1, workers=1, vectors=32" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-4.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-4.c
new file mode 100644
index 00000000000..e5d1df09b8a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-4.c
@@ -0,0 +1,40 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-additional-options "-foffload=-fdump-tree-oaccdevlow" } */
+/* { dg-set-target-env-var "GOMP_DEBUG" "1" } */
+
+#include <stdlib.h>
+
+#define N 1024
+
+unsigned int a[N];
+unsigned int b[N];
+unsigned int c[N];
+unsigned int n = N;
+
+int
+main (void)
+{
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ a[i] = i % 3;
+ b[i] = i % 5;
+ }
+
+#pragma acc parallel num_workers (2) vector_length (128) copyin (a,b) copyout (c)
+ {
+#pragma acc loop worker
+ for (unsigned int i = 0; i < 4; i++)
+#pragma acc loop vector
+ for (unsigned int j = 0; j < n / 4; j++)
+ c[(i * N / 4) + j] = a[(i * N / 4) + j] + b[(i * N / 4) + j];
+ }
+
+ for (unsigned int i = 0; i < n; ++i)
+ if (c[i] != (i % 3) + (i % 5))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-offload-tree-dump "__attribute__\\(\\(oacc function \\(1, 2, 128\\)" "oaccdevlow" } } */
+/* { dg-output "nvptx_exec: kernel main\\\$_omp_fn\\\$0: launch gangs=1, workers=2, vectors=128" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-5.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-5.c
new file mode 100644
index 00000000000..e60f1c28db4
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-5.c
@@ -0,0 +1,41 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-additional-options "-fopenacc-dim=:2:128" } */
+/* { dg-additional-options "-foffload=-fdump-tree-oaccdevlow" } */
+/* { dg-set-target-env-var "GOMP_DEBUG" "1" } */
+
+#include <stdlib.h>
+
+#define N 1024
+
+unsigned int a[N];
+unsigned int b[N];
+unsigned int c[N];
+unsigned int n = N;
+
+int
+main (void)
+{
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ a[i] = i % 3;
+ b[i] = i % 5;
+ }
+
+#pragma acc parallel copyin (a,b) copyout (c)
+ {
+#pragma acc loop worker
+ for (unsigned int i = 0; i < 4; i++)
+#pragma acc loop vector
+ for (unsigned int j = 0; j < n / 4; j++)
+ c[(i * N / 4) + j] = a[(i * N / 4) + j] + b[(i * N / 4) + j];
+ }
+
+ for (unsigned int i = 0; i < n; ++i)
+ if (c[i] != (i % 3) + (i % 5))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-offload-tree-dump "__attribute__\\(\\(oacc function \\(1, 2, 128\\)" "oaccdevlow" } } */
+/* { dg-output "nvptx_exec: kernel main\\\$_omp_fn\\\$0: launch gangs=1, workers=2, vectors=128" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-6.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-6.c
new file mode 100644
index 00000000000..a1f67622f84
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-6.c
@@ -0,0 +1,41 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-set-target-env-var "GOMP_OPENACC_DIM" ":2:" } */
+/* { dg-additional-options "-foffload=-fdump-tree-oaccdevlow" } */
+/* { dg-set-target-env-var "GOMP_DEBUG" "1" } */
+
+#include <stdlib.h>
+
+#define N 1024
+
+unsigned int a[N];
+unsigned int b[N];
+unsigned int c[N];
+unsigned int n = N;
+
+int
+main (void)
+{
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ a[i] = i % 3;
+ b[i] = i % 5;
+ }
+
+#pragma acc parallel vector_length (128) copyin (a,b) copyout (c)
+ {
+#pragma acc loop worker
+ for (unsigned int i = 0; i < 4; i++)
+#pragma acc loop vector
+ for (unsigned int j = 0; j < n / 4; j++)
+ c[(i * N / 4) + j] = a[(i * N / 4) + j] + b[(i * N / 4) + j];
+ }
+
+ for (unsigned int i = 0; i < n; ++i)
+ if (c[i] != (i % 3) + (i % 5))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-offload-tree-dump "__attribute__\\(\\(oacc function \\(1, 0, 128\\)" "oaccdevlow" } } */
+/* { dg-output "nvptx_exec: kernel main\\\$_omp_fn\\\$0: launch gangs=1, workers=2, vectors=128" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-7.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-7.c
new file mode 100644
index 00000000000..c419f6499b5
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-128-7.c
@@ -0,0 +1,40 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
+/* { dg-additional-options "-foffload=-fdump-tree-oaccdevlow" } */
+/* { dg-set-target-env-var "GOMP_DEBUG" "1" } */
+
+#include <stdlib.h>
+
+#define N 1024
+
+unsigned int a[N];
+unsigned int b[N];
+unsigned int c[N];
+unsigned int n = N;
+
+int
+main (void)
+{
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ a[i] = i % 3;
+ b[i] = i % 5;
+ }
+
+#pragma acc parallel vector_length (128) copyin (a,b) copyout (c)
+ {
+#pragma acc loop worker
+ for (unsigned int i = 0; i < 4; i++)
+#pragma acc loop vector
+ for (unsigned int j = 0; j < n / 4; j++)
+ c[(i * N / 4) + j] = a[(i * N / 4) + j] + b[(i * N / 4) + j];
+ }
+
+ for (unsigned int i = 0; i < n; ++i)
+ if (c[i] != (i % 3) + (i % 5))
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-offload-tree-dump "__attribute__\\(\\(oacc function \\(1, 0, 128\\)" "oaccdevlow" } } */
+/* { dg-output "nvptx_exec: kernel main\\\$_omp_fn\\\$0: launch gangs=1, workers=8, vectors=128" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-1.c
new file mode 100644
index 00000000000..2d57ad4464a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-1.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+#pragma acc parallel vector_length (64) num_workers (16) /* { dg-warning "using num_workers \\(15\\), ignoring 16" "" { target openacc_nvidia_accel_selected } } */
+ {
+#pragma acc loop worker
+ for (unsigned int i = 0; i < 32; i++)
+#pragma acc loop vector
+ for (unsigned int j = 0; j < 64; j++)
+ ;
+ }
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-2.c
new file mode 100644
index 00000000000..4dfbae8de91
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-2.c
@@ -0,0 +1,21 @@
+/* { dg-set-target-env-var "GOMP_OPENACC_DIM" ":16:" } */
+/* { dg-shouldfail "" { openacc_nvidia_accel_selected } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+#pragma acc parallel vector_length (64)
+ {
+#pragma acc loop worker
+ for (unsigned int i = 0; i < 32; i++)
+#pragma acc loop vector
+ for (unsigned int j = 0; j < 64; j++)
+ ;
+ }
+
+ return 0;
+}
+/* { dg-output "The Nvidia accelerator has insufficient barrier resources" { target openacc_nvidia_accel_selected } } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-3.c
new file mode 100644
index 00000000000..1acb40e8357
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vector-length-64-3.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main (void)
+{
+#pragma acc parallel vector_length (64)
+ {
+#pragma acc loop worker
+ for (unsigned int i = 0; i < 32; i++)
+#pragma acc loop vector
+ for (unsigned int j = 0; j < 64; j++)
+ ;
+ }
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/vred2d-128.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/vred2d-128.c
new file mode 100644
index 00000000000..86171d456e0
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/vred2d-128.c
@@ -0,0 +1,55 @@
+/* Test large vector lengths. */
+
+#include <assert.h>
+
+#define n 10000
+int a1[n], a2[n];
+
+#define gentest(name, outer, inner) \
+ void name () \
+ { \
+ long i, j, t1, t2, t3; \
+ _Pragma(outer) \
+ for (i = 0; i < n; i++) \
+ { \
+ t1 = 0; \
+ t2 = 0; \
+ _Pragma(inner) \
+ for (j = i; j < n; j++) \
+ { \
+ t1++; \
+ t2--; \
+ } \
+ a1[i] = t1; \
+ a2[i] = t2; \
+ } \
+ for (i = 0; i < n; i++) \
+ { \
+ assert (a1[i] == n-i); \
+ assert (a2[i] == -(n-i)); \
+ } \
+ } \
+
+gentest (test1, "acc parallel loop gang vector_length (128) firstprivate (t1, t2)",
+ "acc loop vector reduction(+:t1) reduction(-:t2)")
+
+gentest (test2, "acc parallel loop gang vector_length (128) firstprivate (t1, t2)",
+ "acc loop worker vector reduction(+:t1) reduction(-:t2)")
+
+gentest (test3, "acc parallel loop gang worker vector_length (128) firstprivate (t1, t2)",
+ "acc loop vector reduction(+:t1) reduction(-:t2)")
+
+gentest (test4, "acc parallel loop firstprivate (t1, t2)",
+ "acc loop reduction(+:t1) reduction(-:t2)")
+
+
+int
+main ()
+{
+ test1 ();
+ test2 ();
+ test3 ();
+ test4 ();
+
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.oacc-c/c.exp b/libgomp/testsuite/libgomp.oacc-c/c.exp
index 4475bf5341f..55cd40f1e99 100644
--- a/libgomp/testsuite/libgomp.oacc-c/c.exp
+++ b/libgomp/testsuite/libgomp.oacc-c/c.exp
@@ -38,20 +38,26 @@ set ld_library_path $always_ld_library_path
append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
set_ld_library_path_env_vars
-# Test OpenACC with available accelerators.
+# Test with all available offload targets, and with offloading disabled.
set SAVE_ALWAYS_CFLAGS "$ALWAYS_CFLAGS"
-foreach offload_target_openacc $offload_targets_s_openacc {
+foreach offload_target [concat [split $offload_targets ","] "disable"] {
set ALWAYS_CFLAGS "$SAVE_ALWAYS_CFLAGS"
- set tagopt "-DACC_DEVICE_TYPE_$offload_target_openacc=1"
-
- switch $offload_target_openacc {
+ global openacc_device_type
+ set openacc_device_type [offload_target_to_openacc_device_type $offload_target]
+ set tagopt "-DACC_DEVICE_TYPE_$openacc_device_type=1"
+
+ switch $openacc_device_type {
+ "" {
+ unsupported "$subdir $offload_target offloading"
+ continue
+ }
host {
set acc_mem_shared 1
}
nvidia {
if { ![check_effective_target_openacc_nvidia_accel_present] } {
# Don't bother; execution testing is going to FAIL.
- untested "$subdir $offload_target_openacc offloading"
+ untested "$subdir $offload_target offloading: supported, but hardware not accessible"
continue
}
@@ -64,12 +70,17 @@ foreach offload_target_openacc $offload_targets_s_openacc {
set acc_mem_shared 0
}
default {
- set acc_mem_shared 0
+ error "Unknown OpenACC device type: $openacc_device_type (offload target: $offload_target)"
}
}
set tagopt "$tagopt -DACC_MEM_SHARED=$acc_mem_shared"
- setenv ACC_DEVICE_TYPE $offload_target_openacc
+ # To avoid compilation overhead, and to keep simple '-foffload=[...]'
+ # handling in test cases, by default only build for the offload target
+ # that we're actually going to test.
+ set tagopt "$tagopt -foffload=$offload_target"
+ # Force usage of the corresponding OpenACC device type.
+ setenv ACC_DEVICE_TYPE $openacc_device_type
# To get better test coverage for device-specific code that is only
# ever used in offloading configurations, we'd like more thorough
@@ -78,8 +89,8 @@ foreach offload_target_openacc $offload_targets_s_openacc {
# -O0 and -O2 only, to avoid testing times exploding too much, under
# the assumption that between -O0 and -O[something] there is the
# biggest difference in the overall structure of the generated code.
- switch $offload_target_openacc {
- host {
+ switch -glob $offload_target {
+ disable {
set-torture-options [list \
{ -O2 } ]
}
diff --git a/libgomp/testsuite/libgomp.oacc-c/print-1.c b/libgomp/testsuite/libgomp.oacc-c/print-1.c
new file mode 100644
index 00000000000..593885b5c2c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c/print-1.c
@@ -0,0 +1,17 @@
+/* Ensure that printf on the offload device works. */
+
+/* { dg-do run } */
+/* { dg-output "The answer is 42(\n|\r\n|\r)+" } */
+
+#include <stdio.h>
+
+int var = 42;
+
+int
+main ()
+{
+#pragma acc parallel
+ {
+ printf ("The answer is %d\n", var);
+ }
+}
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90
index fc0af7ff7d8..70c05d7d3c1 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/abort-1.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
! Verify that an unconditional "call abort" inside an OpenACC parallel region
! does the right thing.
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/abort-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/abort-2.f90
index 97a692ba667..6671d46d8b8 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/abort-2.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/abort-2.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
! Verify that a conditional "call abort" inside an OpenACC parallel region does
! the right thing.
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90
index d6c67a0c31a..1a8432cfa86 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-1.f90
@@ -1,4 +1,6 @@
+! { dg-do run }
! { dg-additional-options "-cpp" }
+!
! TODO: Have to disable the acc_on_device builtin for we want to test the
! libgomp library function? The command line option
! '-fno-builtin-acc_on_device' is valid for C/C++/ObjC/ObjC++ but not for
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f
index 75e24509ce9..56f99d4f99b 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f
+++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-2.f
@@ -1,4 +1,6 @@
+! { dg-do run }
! { dg-additional-options "-cpp" }
+!
! TODO: Have to disable the acc_on_device builtin for we want to test
! the libgomp library function? The command line option
! '-fno-builtin-acc_on_device' is valid for C/C++/ObjC/ObjC++ but not
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f
index 908d185f40c..565723851b1 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f
+++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_on_device-1-3.f
@@ -1,4 +1,6 @@
+! { dg-do run }
! { dg-additional-options "-cpp" }
+!
! TODO: Have to disable the acc_on_device builtin for we want to test
! the libgomp library function? The command line option
! '-fno-builtin-acc_on_device' is valid for C/C++/ObjC/ObjC++ but not
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-1.f90
new file mode 100644
index 00000000000..e5981312f14
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-1.f90
@@ -0,0 +1,68 @@
+! Test 'allocatable' with OpenACC data clauses.
+
+! See also '../libgomp.fortran/target-allocatable-1-1.f90'.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+
+program main
+ implicit none
+ integer, allocatable :: a, b, c, d, e
+
+ allocate (a)
+ a = 11
+
+ b = 25 ! Implicit allocation.
+
+ c = 52 ! Implicit allocation.
+
+ !No 'allocate (d)' here.
+
+ !No 'allocate (e)' here.
+
+ !$acc parallel copyin(a) copy(b, c, d) copyout(e)
+
+ if (.not. allocated (a)) stop 1
+ if (a .ne. 11) stop 2
+ a = 33
+
+ if (.not. allocated (b)) stop 3
+ if (b .ne. 25) stop 4
+
+ if (.not. allocated (c)) stop 5
+ if (c .ne. 52) stop 6
+ c = 10
+
+ if (allocated (d)) stop 7
+ d = 42 ! Implicit allocation, but on device only.
+ if (.not. allocated (d)) stop 8
+ deallocate (d) ! OpenMP requires must be "unallocated upon exit from the region".
+
+ if (allocated (e)) stop 9
+ e = 24 ! Implicit allocation, but on device only.
+ if (.not. allocated (e)) stop 10
+ deallocate (e) ! OpenMP requires must be "unallocated upon exit from the region".
+
+ !$acc end parallel
+
+ if (.not. allocated (a)) stop 20
+#if ACC_MEM_SHARED
+ if (a .ne. 33) stop 21
+#else
+ if (a .ne. 11) stop 22
+#endif
+ deallocate (a)
+
+ if (.not. allocated (b)) stop 23
+ if (b .ne. 25) stop 24
+ deallocate (b)
+
+ if (.not. allocated (c)) stop 25
+ if (c .ne. 10) stop 26
+ deallocate (c)
+
+ if (allocated (d)) stop 27
+
+ if (allocated (e)) stop 28
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-2.f90
new file mode 100644
index 00000000000..2faf0f8078f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-1-2.f90
@@ -0,0 +1,81 @@
+! Test 'allocatable' with OpenACC data clauses, subroutine in module, pass by
+! reference.
+
+! See also '../libgomp.fortran/target-allocatable-1-2.f90'.
+
+! { dg-do run }
+! { dg-additional-options "-cpp" }
+
+module m
+contains
+ subroutine r (a, b, c, d, e)
+ implicit none
+ integer, allocatable :: a, b, c, d, e
+
+ !$acc parallel copyin(a) copy(b, c, d) copyout(e)
+
+ if (.not. allocated (a)) stop 1
+ if (a .ne. 11) stop 2
+ a = 33
+
+ if (.not. allocated (b)) stop 3
+ if (b .ne. 25) stop 4
+
+ if (.not. allocated (c)) stop 5
+ if (c .ne. 52) stop 6
+ c = 10
+
+ if (allocated (d)) stop 7
+ d = 42 ! Implicit allocation, but on device only.
+ if (.not. allocated (d)) stop 8
+ deallocate (d) ! OpenMP requires must be "unallocated upon exit from the region".
+
+ if (allocated (e)) stop 9
+ e = 24 ! Implicit allocation, but on device only.
+ if (.not. allocated (e)) stop 10
+ deallocate (e) ! OpenMP requires must be "unallocated upon exit from the region".
+
+ !$acc end parallel
+
+ end subroutine r
+end module m
+
+program main
+ use m
+ implicit none
+ integer, allocatable :: a, b, c, d, e
+
+ allocate (a)
+ a = 11
+
+ b = 25 ! Implicit allocation.
+
+ c = 52 ! Implicit allocation.
+
+ !No 'allocate (d)' here.
+
+ !No 'allocate (e)' here.
+
+ call r(a, b, c, d, e)
+
+ if (.not. allocated (a)) stop 20
+#if ACC_MEM_SHARED
+ if (a .ne. 33) stop 21
+#else
+ if (a .ne. 11) stop 22
+#endif
+ deallocate (a)
+
+ if (.not. allocated (b)) stop 23
+ if (b .ne. 25) stop 24
+ deallocate (b)
+
+ if (.not. allocated (c)) stop 25
+ if (c .ne. 10) stop 26
+ deallocate (c)
+
+ if (allocated (d)) stop 27
+
+ if (allocated (e)) stop 28
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/allocatable-array-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-array-1.f90
new file mode 100644
index 00000000000..c9a76385d9f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/allocatable-array-1.f90
@@ -0,0 +1,27 @@
+! { dg-do run }
+
+program main
+ integer, parameter :: n = 40
+ integer, allocatable :: ar(:,:,:)
+ integer :: i
+
+ allocate (ar(1:n,0:n-1,0:n-1))
+ !$acc enter data copyin (ar)
+
+ !$acc update host (ar)
+
+ !$acc update device (ar)
+
+ call update_ar (ar, n)
+
+ !$acc exit data copyout (ar)
+end program main
+
+subroutine update_ar (ar, n)
+ integer :: n
+ integer, dimension (1:n,0:n-1,0:n-1) :: ar
+
+ !$acc update host (ar)
+
+ !$acc update device (ar)
+end subroutine update_ar
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/common-block-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/common-block-1.f90
new file mode 100644
index 00000000000..d77878ede39
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/common-block-1.f90
@@ -0,0 +1,107 @@
+! { dg-do run }
+!
+! Test data located inside common blocks. This test does not exercise
+! ACC DECLARE.
+
+module const
+ integer, parameter :: n = 100
+end module const
+
+subroutine check
+ use const
+
+ implicit none
+ integer i, x(n), y
+ common /BLOCK/ x, y
+
+ do i = 1, n
+ if (x(i) .ne. y) stop 1
+ end do
+end subroutine check
+
+module m
+ use const
+ integer a(n), b
+ common /BLOCK/ a, b
+
+contains
+ subroutine mod_implicit_incr
+ implicit none
+ integer i
+
+ !$acc parallel loop
+ do i = 1, n
+ a(i) = b
+ end do
+ !$acc end parallel loop
+
+ call check
+ end subroutine mod_implicit_incr
+
+ subroutine mod_explicit_incr
+ implicit none
+ integer i
+
+ !$acc parallel loop copy(a(1:n)) copyin(b)
+ do i = 1, n
+ a(i) = b
+ end do
+ !$acc end parallel loop
+
+ call check
+ end subroutine mod_explicit_incr
+end module m
+
+subroutine sub_implicit_incr
+ use const
+
+ implicit none
+ integer i, x(n), y
+ common /BLOCK/ x, y
+
+ !$acc parallel loop
+ do i = 1, n
+ x(i) = y
+ end do
+ !$acc end parallel loop
+
+ call check
+end subroutine sub_implicit_incr
+
+subroutine sub_explicit_incr
+ use const
+
+ implicit none
+ integer i, x(n), y
+ common /BLOCK/ x, y
+
+ !$acc parallel loop copy(x(1:n)) copyin(y)
+ do i = 1, n
+ x(i) = y
+ end do
+ !$acc end parallel loop
+
+ call check
+end subroutine sub_explicit_incr
+
+program main
+ use m
+
+ implicit none
+
+ a(:) = -1
+ b = 5
+ call mod_implicit_incr
+
+ a(:) = -2
+ b = 6
+ call mod_explicit_incr
+
+ a(:) = -3
+ b = 7
+ call sub_implicit_incr
+
+ a(:) = -4
+ b = 8
+ call sub_explicit_incr
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/common-block-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/common-block-2.f90
new file mode 100644
index 00000000000..018b37d00bb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/common-block-2.f90
@@ -0,0 +1,152 @@
+! { dg-do run }
+!
+! Test data located inside common blocks. This test does not exercise
+! ACC DECLARE. All data clauses are explicit.
+
+module consts
+ integer, parameter :: n = 100
+end module consts
+
+subroutine validate
+ use consts
+
+ implicit none
+ integer i, j
+ real*4 x(n), y(n), z
+ common /BLOCK/ x, y, z, j
+
+ do i = 1, n
+ if (abs(x(i) - i - z) .ge. 0.0001) stop 1
+ end do
+end subroutine validate
+
+subroutine incr
+ use consts
+
+ implicit none
+ integer i, j
+ real*4 x(n), y(n), z
+ common /BLOCK/ x, y, z, j
+
+ !$acc parallel loop pcopy(/BLOCK/)
+ do i = 1, n
+ x(i) = x(i) + z
+ end do
+ !$acc end parallel loop
+end subroutine incr
+
+program main
+ use consts
+
+ implicit none
+ integer i, j
+ real*4 a(n), b(n), c
+ common /BLOCK/ a, b, c, j
+
+ ! Test copyout, pcopy, device
+
+ !$acc data copyout(a, c)
+
+ c = 1.0
+
+ !$acc update device(c)
+
+ !$acc parallel loop pcopy(a)
+ do i = 1, n
+ a(i) = i
+ end do
+ !$acc end parallel loop
+
+ call incr
+ call incr
+ call incr
+ !$acc end data
+
+ c = 3.0
+ call validate
+
+ ! Test pcopy without copyout
+
+ c = 2.0
+ call incr
+ c = 5.0
+ call validate
+
+ ! Test create, delete, host, copyout, copyin
+
+ !$acc enter data create(b)
+
+ !$acc parallel loop pcopy(b)
+ do i = 1, n
+ b(i) = i
+ end do
+ !$acc end parallel loop
+
+ !$acc update host (b)
+
+ !$acc parallel loop pcopy(b) copyout(a) copyin(c)
+ do i = 1, n
+ a(i) = b(i) + c
+ end do
+ !$acc end parallel loop
+
+ !$acc exit data delete(b)
+
+ call validate
+
+ a(:) = b(:)
+ c = 0.0
+ call validate
+
+ ! Test copy
+
+ c = 1.0
+ !$acc parallel loop copy(/BLOCK/)
+ do i = 1, n
+ a(i) = b(i) + c
+ end do
+ !$acc end parallel loop
+
+ call validate
+
+ ! Test pcopyin, pcopyout FIXME
+
+ c = 2.0
+ !$acc data copyin(b, c) copyout(a)
+
+ !$acc parallel loop pcopyin(b, c) pcopyout(a)
+ do i = 1, n
+ a(i) = b(i) + c
+ end do
+ !$acc end parallel loop
+
+ !$acc end data
+
+ call validate
+
+ ! Test reduction, private
+
+ j = 0
+
+ !$acc parallel private(i) copy(j)
+ !$acc loop reduction(+:j)
+ do i = 1, n
+ j = j + 1
+ end do
+ !$acc end parallel
+
+ if (j .ne. n) stop 2
+
+ ! Test firstprivate, copy
+
+ a(:) = 0
+ c = j
+
+ !$acc parallel loop firstprivate(c) copyout(a)
+ do i = 1, n
+ a(i) = i + c
+ end do
+ !$acc end parallel loop
+
+ call validate
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/common-block-3.f90 b/libgomp/testsuite/libgomp.oacc-fortran/common-block-3.f90
new file mode 100644
index 00000000000..3c59b66246b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/common-block-3.f90
@@ -0,0 +1,139 @@
+! { dg-do run }
+!
+! Test data located inside common blocks. This test does not exercise
+! ACC DECLARE. Most of the data clauses are implicit.
+
+module consts
+ integer, parameter :: n = 100
+end module consts
+
+subroutine validate
+ use consts
+
+ implicit none
+ integer i, j
+ real*4 x(n), y(n), z
+ common /BLOCK/ x, y, z, j
+
+ do i = 1, n
+ if (abs(x(i) - i - z) .ge. 0.0001) stop 1
+ end do
+end subroutine validate
+
+subroutine incr_parallel
+ use consts
+
+ implicit none
+ integer i, j
+ real*4 x(n), y(n), z
+ common /BLOCK/ x, y, z, j
+
+ !$acc parallel loop
+ do i = 1, n
+ x(i) = x(i) + z
+ end do
+ !$acc end parallel loop
+end subroutine incr_parallel
+
+subroutine incr_kernels
+ use consts
+
+ implicit none
+ integer i, j
+ real*4 x(n), y(n), z
+ common /BLOCK/ x, y, z, j
+
+ !$acc kernels
+ do i = 1, n
+ x(i) = x(i) + z
+ end do
+ !$acc end kernels
+end subroutine incr_kernels
+
+program main
+ use consts
+
+ implicit none
+ integer i, j
+ real*4 a(n), b(n), c
+ common /BLOCK/ a, b, c, j
+
+ !$acc data copyout(a, c)
+
+ c = 1.0
+
+ !$acc update device(c)
+
+ !$acc parallel loop
+ do i = 1, n
+ a(i) = i
+ end do
+ !$acc end parallel loop
+
+ call incr_parallel
+ call incr_parallel
+ call incr_parallel
+ !$acc end data
+
+ c = 3.0
+ call validate
+
+ ! Test pcopy without copyout
+
+ c = 2.0
+ call incr_kernels
+ c = 5.0
+ call validate
+
+ !$acc kernels
+ do i = 1, n
+ b(i) = i
+ end do
+ !$acc end kernels
+
+ !$acc parallel loop
+ do i = 1, n
+ a(i) = b(i) + c
+ end do
+ !$acc end parallel loop
+
+ call validate
+
+ a(:) = b(:)
+ c = 0.0
+ call validate
+
+ ! Test copy
+
+ c = 1.0
+ !$acc parallel loop
+ do i = 1, n
+ a(i) = b(i) + c
+ end do
+ !$acc end parallel loop
+
+ call validate
+
+ c = 2.0
+ !$acc data copyin(b, c) copyout(a)
+
+ !$acc kernels
+ do i = 1, n
+ a(i) = b(i) + c
+ end do
+ !$acc end kernels
+
+ !$acc end data
+
+ call validate
+
+ j = 0
+
+ !$acc parallel loop reduction(+:j)
+ do i = 1, n
+ j = j + 1
+ end do
+ !$acc end parallel loop
+
+ if (j .ne. n) stop 2
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/data-1.f90
index bf323b3f540..eeb06f3c84f 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/data-1.f90
@@ -26,32 +26,32 @@ program main
j = -2
!$acc data copyin (i, j)
- if (is_mapped (i) .eqv. .FALSE.) call abort
- if (is_mapped (j) .eqv. .FALSE.) call abort
+ if (is_mapped (i) .eqv. .FALSE.) stop 1
+ if (is_mapped (j) .eqv. .FALSE.) stop 2
- if (i .ne. -1 .or. j .ne. -2) call abort
+ if (i .ne. -1 .or. j .ne. -2) stop 3
i = 2
j = 1
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 4
!$acc end data
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 5
i = -1
j = -2
!$acc data copyout (i, j)
- if (is_mapped (i) .eqv. .FALSE.) call abort
- if (is_mapped (j) .eqv. .FALSE.) call abort
+ if (is_mapped (i) .eqv. .FALSE.) stop 6
+ if (is_mapped (j) .eqv. .FALSE.) stop 7
- if (i .ne. -1 .or. j .ne. -2) call abort
+ if (i .ne. -1 .or. j .ne. -2) stop 8
i = 2
j = 1
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 9
!$acc parallel present (i, j)
i = 4
@@ -59,55 +59,55 @@ program main
!$acc end parallel
!$acc end data
- if (i .ne. 4 .or. j .ne. 2) call abort
+ if (i .ne. 4 .or. j .ne. 2) stop 10
i = -1
j = -2
!$acc data create (i, j)
- if (is_mapped (i) .eqv. .FALSE.) call abort
- if (is_mapped (j) .eqv. .FALSE.) call abort
+ if (is_mapped (i) .eqv. .FALSE.) stop 11
+ if (is_mapped (j) .eqv. .FALSE.) stop 12
- if (i .ne. -1 .or. j .ne. -2) call abort
+ if (i .ne. -1 .or. j .ne. -2) stop 13
i = 2
j = 1
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 14
!$acc end data
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 15
i = -1
j = -2
!$acc data present_or_copyin (i, j)
- if (is_mapped (i) .eqv. .FALSE.) call abort
- if (is_mapped (j) .eqv. .FALSE.) call abort
+ if (is_mapped (i) .eqv. .FALSE.) stop 16
+ if (is_mapped (j) .eqv. .FALSE.) stop 17
- if (i .ne. -1 .or. j .ne. -2) call abort
+ if (i .ne. -1 .or. j .ne. -2) stop 18
i = 2
j = 1
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 19
!$acc end data
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 20
i = -1
j = -2
!$acc data present_or_copyout (i, j)
- if (is_mapped (i) .eqv. .FALSE.) call abort
- if (is_mapped (j) .eqv. .FALSE.) call abort
+ if (is_mapped (i) .eqv. .FALSE.) stop 21
+ if (is_mapped (j) .eqv. .FALSE.) stop 22
- if (i .ne. -1 .or. j .ne. -2) call abort
+ if (i .ne. -1 .or. j .ne. -2) stop 23
i = 2
j = 1
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 24
!$acc parallel present (i, j)
i = 4
@@ -115,98 +115,98 @@ program main
!$acc end parallel
!$acc end data
- if (i .ne. 4 .or. j .ne. 2) call abort
+ if (i .ne. 4 .or. j .ne. 2) stop 25
i = -1
j = -2
!$acc data present_or_copy (i, j)
- if (is_mapped (i) .eqv. .FALSE.) call abort
- if (is_mapped (j) .eqv. .FALSE.) call abort
+ if (is_mapped (i) .eqv. .FALSE.) stop 26
+ if (is_mapped (j) .eqv. .FALSE.) stop 27
- if (i .ne. -1 .or. j .ne. -2) call abort
+ if (i .ne. -1 .or. j .ne. -2) stop 28
i = 2
j = 1
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 29
!$acc end data
#if ACC_MEM_SHARED
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 30
#else
- if (i .ne. -1 .or. j .ne. -2) call abort
+ if (i .ne. -1 .or. j .ne. -2) stop 31
#endif
i = -1
j = -2
!$acc data present_or_create (i, j)
- if (is_mapped (i) .eqv. .FALSE.) call abort
- if (is_mapped (j) .eqv. .FALSE.) call abort
+ if (is_mapped (i) .eqv. .FALSE.) stop 32
+ if (is_mapped (j) .eqv. .FALSE.) stop 33
i = 2
j = 1
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 34
!$acc end data
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 35
i = -1
j = -2
!$acc data copyin (i, j)
!$acc data present (i, j)
- if (is_mapped (i) .eqv. .FALSE.) call abort
- if (is_mapped (j) .eqv. .FALSE.) call abort
+ if (is_mapped (i) .eqv. .FALSE.) stop 36
+ if (is_mapped (j) .eqv. .FALSE.) stop 37
- if (i .ne. -1 .or. j .ne. -2) call abort
+ if (i .ne. -1 .or. j .ne. -2) stop 38
i = 2
j = 1
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 39
!$acc end data
!$acc end data
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 40
i = -1
j = -2
!$acc data copyin (i, j)
!$acc data present (i, j)
- if (is_mapped (i) .eqv. .FALSE.) call abort
- if (is_mapped (j) .eqv. .FALSE.) call abort
+ if (is_mapped (i) .eqv. .FALSE.) stop 41
+ if (is_mapped (j) .eqv. .FALSE.) stop 42
- if (i .ne. -1 .or. j .ne. -2) call abort
+ if (i .ne. -1 .or. j .ne. -2) stop 43
i = 2
j = 1
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 44
!$acc end data
!$acc end data
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 45
i = -1
j = -2
!$acc data
#if !ACC_MEM_SHARED
- if (is_mapped (i) .eqv. .TRUE.) call abort
- if (is_mapped (j) .eqv. .TRUE.) call abort
+ if (is_mapped (i) .eqv. .TRUE.) stop 46
+ if (is_mapped (j) .eqv. .TRUE.) stop 47
#endif
- if (i .ne. -1 .or. j .ne. -2) call abort
+ if (i .ne. -1 .or. j .ne. -2) stop 48
i = 2
j = 1
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 49
!$acc end data
- if (i .ne. 2 .or. j .ne. 1) call abort
+ if (i .ne. 2 .or. j .ne. 1) stop 50
end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/data-2.f90
index 83a540070e6..ec206958e23 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-2.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/data-2.f90
@@ -54,7 +54,7 @@ program test
!$acc wait
do i = 1, N
- if (d(i) .ne. 4.0) call abort
+ if (d(i) .ne. 4.0) STOP 3
end do
c(:) = 3.0
@@ -75,7 +75,7 @@ program test
!$acc wait
do i = 1, N
- if (d(i) .ne. 4.0) call abort
+ if (d(i) .ne. 4.0) STOP 4
end do
end program test
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-5.f90 b/libgomp/testsuite/libgomp.oacc-fortran/data-5.f90
index a8843dedc22..c68a2795900 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-5.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/data-5.f90
@@ -23,8 +23,8 @@ program refcount_test
if (h(i) .eq. i) c = c + 1
end do
! h[] should be filled with uninitialized device values,
- ! abort if it's not.
- if (c .eq. N) call abort
+ ! 'stop' if it's not.
+ if (c .eq. N) stop 1
h(:) = 0
@@ -37,20 +37,20 @@ program refcount_test
! No actual copyout should happen.
call acc_copyout (h)
do i = 1, N
- if (h(i) .ne. 0) call abort
+ if (h(i) .ne. 0) stop 2
end do
!$acc exit data delete (h(1:N))
! This should not actually be deleted yet.
- if (acc_is_present (h) .eqv. .FALSE.) call abort
+ if (acc_is_present (h) .eqv. .FALSE.) stop 3
!$acc exit data copyout (h(1:N)) finalize
do i = 1, N
- if (h(i) .ne. 111) call abort
+ if (h(i) .ne. 111) stop 4
end do
- if (acc_is_present (h) .eqv. .TRUE.) call abort
+ if (acc_is_present (h) .eqv. .TRUE.) stop 5
end program refcount_test
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-already-1.f b/libgomp/testsuite/libgomp.oacc-fortran/data-already-1.f
deleted file mode 100644
index fab0ffc99cc..00000000000
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-already-1.f
+++ /dev/null
@@ -1,16 +0,0 @@
-! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
-
- IMPLICIT NONE
- INCLUDE "openacc_lib.h"
-
- INTEGER I
-
- CALL ACC_COPYIN (I)
- WRITE(0, *) "CheCKpOInT"
-!$ACC DATA COPY (I)
- I = 0
-!$ACC END DATA
-
- END
-
-! { dg-output "CheCKpOInT(\n|\r\n|\r).*" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-already-2.f b/libgomp/testsuite/libgomp.oacc-fortran/data-already-2.f
deleted file mode 100644
index bd03062670f..00000000000
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-already-2.f
+++ /dev/null
@@ -1,16 +0,0 @@
-! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
-
- IMPLICIT NONE
-
- INTEGER I
-
-!$ACC DATA PRESENT_OR_COPY (I)
- WRITE(0, *) "CheCKpOInT"
-!$ACC DATA COPYOUT (I)
- I = 0
-!$ACC END DATA
-!$ACC END DATA
-
- END
-
-! { dg-output "CheCKpOInT(\n|\r\n|\r).*" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-already-3.f b/libgomp/testsuite/libgomp.oacc-fortran/data-already-3.f
deleted file mode 100644
index 60ea3864e4e..00000000000
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-already-3.f
+++ /dev/null
@@ -1,15 +0,0 @@
-! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
-
- IMPLICIT NONE
- INCLUDE "openacc_lib.h"
-
- INTEGER I
-
-!$ACC DATA PRESENT_OR_COPY (I)
- WRITE(0, *) "CheCKpOInT"
- CALL ACC_COPYIN (I)
-!$ACC END DATA
-
- END
-
-! { dg-output "CheCKpOInT(\n|\r\n|\r).*" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-already-4.f b/libgomp/testsuite/libgomp.oacc-fortran/data-already-4.f
deleted file mode 100644
index 2abdbf0f868..00000000000
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-already-4.f
+++ /dev/null
@@ -1,14 +0,0 @@
-! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
-
- IMPLICIT NONE
- INCLUDE "openacc_lib.h"
-
- INTEGER I
-
- CALL ACC_PRESENT_OR_COPYIN (I)
- WRITE(0, *) "CheCKpOInT"
- CALL ACC_COPYIN (I)
-
- END
-
-! { dg-output "CheCKpOInT(\n|\r\n|\r).*" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-already-5.f b/libgomp/testsuite/libgomp.oacc-fortran/data-already-5.f
deleted file mode 100644
index f361d8c1772..00000000000
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-already-5.f
+++ /dev/null
@@ -1,14 +0,0 @@
-! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
-
- IMPLICIT NONE
- INCLUDE "openacc_lib.h"
-
- INTEGER I
-
-!$ACC ENTER DATA CREATE (I)
- WRITE(0, *) "CheCKpOInT"
- CALL ACC_COPYIN (I)
-
- END
-
-! { dg-output "CheCKpOInT(\n|\r\n|\r).*" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-already-6.f b/libgomp/testsuite/libgomp.oacc-fortran/data-already-6.f
deleted file mode 100644
index a864737c692..00000000000
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-already-6.f
+++ /dev/null
@@ -1,14 +0,0 @@
-! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
-
- IMPLICIT NONE
- INCLUDE "openacc_lib.h"
-
- INTEGER I
-
- CALL ACC_PRESENT_OR_COPYIN (I)
- WRITE(0, *) "CheCKpOInT"
-!$ACC ENTER DATA CREATE (I)
-
- END
-
-! { dg-output "CheCKpOInT(\n|\r\n|\r).*" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-already-7.f b/libgomp/testsuite/libgomp.oacc-fortran/data-already-7.f
deleted file mode 100644
index 0d893280e40..00000000000
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-already-7.f
+++ /dev/null
@@ -1,14 +0,0 @@
-! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
-
- IMPLICIT NONE
- INCLUDE "openacc_lib.h"
-
- INTEGER I
-
-!$ACC ENTER DATA CREATE (I)
- WRITE(0, *) "CheCKpOInT"
- CALL ACC_CREATE (I)
-
- END
-
-! { dg-output "CheCKpOInT(\n|\r\n|\r).*" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/data-already-8.f b/libgomp/testsuite/libgomp.oacc-fortran/data-already-8.f
deleted file mode 100644
index 7a41f67225a..00000000000
--- a/libgomp/testsuite/libgomp.oacc-fortran/data-already-8.f
+++ /dev/null
@@ -1,16 +0,0 @@
-! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
-
- IMPLICIT NONE
-
- INTEGER I
-
-!$ACC DATA CREATE (I)
- WRITE(0, *) "CheCKpOInT"
-!$ACC PARALLEL COPYIN (I)
- I = 0
-!$ACC END PARALLEL
-!$ACC END DATA
-
- END
-
-! { dg-output "CheCKpOInT(\n|\r\n|\r).*" }
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/dummy-array.f90 b/libgomp/testsuite/libgomp.oacc-fortran/dummy-array.f90
index e95563cd406..697d94d52aa 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/dummy-array.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/dummy-array.f90
@@ -13,7 +13,7 @@ program main
call dummy_array (a, n)
do i = 1, n
- if (a(i) .ne. i) call abort
+ if (a(i) .ne. i) stop 1
end do
end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/fortran.exp b/libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
index 663c9323b72..852f372b319 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
+++ b/libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
@@ -56,39 +56,56 @@ if { $lang_test_file_found } {
# Allow for spec subsitution.
lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/${quadmath_library_path}/"
set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}:${blddir}/${quadmath_library_path}"
+ append lang_link_flags " -lquadmath"
} else {
set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}"
}
} else {
set ld_library_path "$always_ld_library_path"
+ if { [check_no_compiler_messages has_libquadmath executable {
+ int main() {return 0;}
+ } "-lgfortran -lquadmath"] } then {
+ append lang_link_flags " -lquadmath"
+ }
}
append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
set_ld_library_path_env_vars
- # Test OpenACC with available accelerators.
- foreach offload_target_openacc $offload_targets_s_openacc {
- set tagopt "-DACC_DEVICE_TYPE_$offload_target_openacc=1"
+ # Test with all available offload targets, and with offloading disabled.
+ foreach offload_target [concat [split $offload_targets ","] "disable"] {
+ global openacc_device_type
+ set openacc_device_type [offload_target_to_openacc_device_type $offload_target]
+ set tagopt "-DACC_DEVICE_TYPE_$openacc_device_type=1"
- switch $offload_target_openacc {
+ switch $openacc_device_type {
+ "" {
+ unsupported "$subdir $offload_target offloading"
+ continue
+ }
host {
set acc_mem_shared 1
}
nvidia {
if { ![check_effective_target_openacc_nvidia_accel_present] } {
# Don't bother; execution testing is going to FAIL.
- untested "$subdir $offload_target_openacc offloading"
+ untested "$subdir $offload_target offloading: supported, but hardware not accessible"
continue
}
set acc_mem_shared 0
}
default {
- set acc_mem_shared 0
+ error "Unknown OpenACC device type: $openacc_device_type (offload target: $offload_target)"
}
}
set tagopt "$tagopt -DACC_MEM_SHARED=$acc_mem_shared"
- setenv ACC_DEVICE_TYPE $offload_target_openacc
+ # To avoid compilation overhead, and to keep simple '-foffload=[...]'
+ # handling in test cases, by default only build for the offload target
+ # that we're actually going to test.
+ set tagopt "$tagopt -foffload=$offload_target"
+ # Force usage of the corresponding OpenACC device type.
+ setenv ACC_DEVICE_TYPE $openacc_device_type
# For Fortran we're doing torture testing, as Fortran has far more tests
# with arrays etc. that testing just -O0 or -O2 is insufficient, that is
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/gemm-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/gemm-2.f90
new file mode 100644
index 00000000000..5fa93642477
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/gemm-2.f90
@@ -0,0 +1,80 @@
+! Exercise three levels of parallelism using SGEMM from BLAS.
+
+! { dg-do run }
+! { dg-additional-options "-fopenacc-dim=::128" }
+
+! Implicitly set vector_length to 128 using -fopenacc-dim.
+subroutine openacc_sgemm (m, n, k, alpha, a, b, beta, c)
+ integer :: m, n, k
+ real :: alpha, beta
+ real :: a(k,*), b(k,*), c(m,*)
+
+ integer :: i, j, l
+ real :: temp
+
+ !$acc parallel loop copy(c(1:m,1:n)) copyin(a(1:k,1:m),b(1:k,1:n)) firstprivate (temp)
+ do j = 1, n
+ !$acc loop
+ do i = 1, m
+ temp = 0.0
+ !$acc loop reduction(+:temp)
+ do l = 1, k
+ temp = temp + a(l,i)*b(l,j)
+ end do
+ if(beta == 0.0) then
+ c(i,j) = alpha*temp
+ else
+ c(i,j) = alpha*temp + beta*c(i,j)
+ end if
+ end do
+ end do
+end subroutine openacc_sgemm
+
+subroutine host_sgemm (m, n, k, alpha, a, b, beta, c)
+ integer :: m, n, k
+ real :: alpha, beta
+ real :: a(k,*), b(k,*), c(m,*)
+
+ integer :: i, j, l
+ real :: temp
+
+ do j = 1, n
+ do i = 1, m
+ temp = 0.0
+ do l = 1, k
+ temp = temp + a(l,i)*b(l,j)
+ end do
+ if(beta == 0.0) then
+ c(i,j) = alpha*temp
+ else
+ c(i,j) = alpha*temp + beta*c(i,j)
+ end if
+ end do
+ end do
+end subroutine host_sgemm
+
+program main
+ integer, parameter :: M = 100, N = 50, K = 2000
+ real :: a(K, M), b(K, N), c(M, N), d (M, N), e (M, N)
+ real alpha, beta
+ integer i, j
+
+ a(:,:) = 1.0
+ b(:,:) = 0.25
+
+ c(:,:) = 0.0
+ d(:,:) = 0.0
+ e(:,:) = 0.0
+
+ alpha = 1.05
+ beta = 1.25
+
+ call openacc_sgemm (M, N, K, alpha, a, b, beta, c)
+ call host_sgemm (M, N, K, alpha, a, b, beta, e)
+
+ do i = 1, m
+ do j = 1, n
+ if (c(i,j) /= e(i,j)) stop 1
+ end do
+ end do
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/gemm.f90 b/libgomp/testsuite/libgomp.oacc-fortran/gemm.f90
new file mode 100644
index 00000000000..9e8915fbb88
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/gemm.f90
@@ -0,0 +1,79 @@
+! Exercise three levels of parallelism using SGEMM from BLAS.
+
+! { dg-do run }
+
+! Explicitly set vector_length to 128 using a vector_length clause.
+subroutine openacc_sgemm_128 (m, n, k, alpha, a, b, beta, c)
+ integer :: m, n, k
+ real :: alpha, beta
+ real :: a(k,*), b(k,*), c(m,*)
+
+ integer :: i, j, l
+ real :: temp
+
+ !$acc parallel loop copy(c(1:m,1:n)) copyin(a(1:k,1:m),b(1:k,1:n)) vector_length (128) firstprivate (temp)
+ do j = 1, n
+ !$acc loop
+ do i = 1, m
+ temp = 0.0
+ !$acc loop reduction(+:temp)
+ do l = 1, k
+ temp = temp + a(l,i)*b(l,j)
+ end do
+ if(beta == 0.0) then
+ c(i,j) = alpha*temp
+ else
+ c(i,j) = alpha*temp + beta*c(i,j)
+ end if
+ end do
+ end do
+end subroutine openacc_sgemm_128
+
+subroutine host_sgemm (m, n, k, alpha, a, b, beta, c)
+ integer :: m, n, k
+ real :: alpha, beta
+ real :: a(k,*), b(k,*), c(m,*)
+
+ integer :: i, j, l
+ real :: temp
+
+ do j = 1, n
+ do i = 1, m
+ temp = 0.0
+ do l = 1, k
+ temp = temp + a(l,i)*b(l,j)
+ end do
+ if(beta == 0.0) then
+ c(i,j) = alpha*temp
+ else
+ c(i,j) = alpha*temp + beta*c(i,j)
+ end if
+ end do
+ end do
+end subroutine host_sgemm
+
+program main
+ integer, parameter :: M = 100, N = 50, K = 2000
+ real :: a(K, M), b(K, N), c(M, N), d (M, N), e (M, N)
+ real alpha, beta
+ integer i, j
+
+ a(:,:) = 1.0
+ b(:,:) = 0.25
+
+ c(:,:) = 0.0
+ d(:,:) = 0.0
+ e(:,:) = 0.0
+
+ alpha = 1.05
+ beta = 1.25
+
+ call openacc_sgemm_128 (M, N, K, alpha, a, b, beta, d)
+ call host_sgemm (M, N, K, alpha, a, b, beta, e)
+
+ do i = 1, m
+ do j = 1, n
+ if (d(i,j) /= e(i,j)) stop 1
+ end do
+ end do
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/host_data-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/host_data-2.f90
index ff0921863f6..ab70e4e8dea 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/host_data-2.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/host_data-2.f90
@@ -93,6 +93,6 @@ subroutine validate_results (n, a, b)
real*4 :: a(n), b(n)
do i = 1, N
- if (abs(a(i) - b(i)) > 0.0001) call abort
+ if (abs(a(i) - b(i)) > 0.0001) stop 1
end do
end subroutine validate_results
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/host_data-3.f b/libgomp/testsuite/libgomp.oacc-fortran/host_data-3.f
index 05ed949ee5c..434c18c9889 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/host_data-3.f
+++ b/libgomp/testsuite/libgomp.oacc-fortran/host_data-3.f
@@ -79,7 +79,7 @@
real*4 :: a(n), b(n)
do i = 1, N
- if (abs(a(i) - b(i)) > 0.0001) call abort
+ if (abs(a(i) - b(i)) > 0.0001) stop 1
end do
end subroutine validate_results
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/host_data-4.f90 b/libgomp/testsuite/libgomp.oacc-fortran/host_data-4.f90
index 6e379b5485b..e81a8b292c1 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/host_data-4.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/host_data-4.f90
@@ -33,7 +33,7 @@ contains
real*4 :: a(n), b(n)
do i = 1, N
- if (abs(a(i) - b(i)) > 0.0001) call abort
+ if (abs(a(i) - b(i)) > 0.0001) stop 1
end do
end subroutine validate_results
end module cublas
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction-2.f90
index fdf9409bde4..0a612a57964 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction-2.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction-2.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
program foo
IMPLICIT NONE
@@ -5,7 +7,7 @@ program foo
call bar (vol)
- if (vol .ne. 4) call abort
+ if (vol .ne. 4) stop 1
end program foo
subroutine bar(vol)
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction.f90
index 912a22b5153..0b939c04fbb 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-acc-loop-reduction.f90
@@ -1,10 +1,12 @@
+! { dg-do run }
+!
program foo
IMPLICIT NONE
INTEGER :: vol = 0
call bar (vol)
- if (vol .ne. 2) call abort
+ if (vol .ne. 2) stop 1
end program foo
subroutine bar(vol)
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-collapse-3.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-collapse-3.f90
index 4ef99cd3475..03b3a115d7b 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-collapse-3.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-collapse-3.f90
@@ -14,7 +14,7 @@ dokk: do kk=1,3
enddo dokk
115 continue
!$acc end kernels
- if (any(a(1:3,1:3,1:3).ne.1)) call abort
+ if (any(a(1:3,1:3,1:3).ne.1)) stop 1
!$acc kernels
!$acc loop collapse(3)
@@ -26,5 +26,5 @@ doll: do ll=1,3
enddo doll
120 end do dol
!$acc end kernels
- if (any(a(1:3,1:3,1:3).ne.2)) call abort
+ if (any(a(1:3,1:3,1:3).ne.2)) stop 2
end program collapse3
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-collapse-4.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-collapse-4.f90
index db382a7deb6..15e33603adb 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-collapse-4.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-collapse-4.f90
@@ -30,11 +30,11 @@ program collapse4
end do
end do
end do
- if (l .neqv. r) call abort
+ if (l .neqv. r) stop 1
do i = 2, 6
do j = -2, 4
do k = 13, 18
- if (a(i, j, k) .ne. b(i, j, k)) call abort
+ if (a(i, j, k) .ne. b(i, j, k)) stop 2
end do
end do
end do
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-independent.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-independent.f90
index a881fbbe5cc..5a47aca2dba 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-independent.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-independent.f90
@@ -26,7 +26,7 @@ subroutine foo (a, b, c)
!$acc end kernels
do i = 1, n
- if (c(i) .ne. a(i) + b(i)) call abort
+ if (c(i) .ne. a(i) + b(i)) stop 1
end do
end subroutine
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-loop-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-loop-1.f90
index edcdc56ec1c..37aa0ac4f63 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-loop-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-loop-1.f90
@@ -37,7 +37,7 @@ program loops
!$acc end kernels
do i = 1, n
- if (a(i) .ne. b(i)) call abort
+ if (a(i) .ne. b(i)) stop 1
end do
call check (a, b, n)
@@ -61,6 +61,6 @@ subroutine check (a, b, n)
integer :: i
do i = 1, n
- if (a(i) .ne. b(i)) call abort
+ if (a(i) .ne. b(i)) stop 2
end do
end subroutine check
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-map-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-map-1.f90
index 704ff622854..736ce1791ae 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-map-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-map-1.f90
@@ -37,7 +37,7 @@ program map
!$acc end kernels
do i = 1, n
- if (a(i) .ne. b(i)) call abort
+ if (a(i) .ne. b(i)) stop 1
end do
call check (a, b, n)
@@ -111,6 +111,6 @@ subroutine check (a, b, n)
integer :: i
do i = 1, n
- if (a(i) .ne. b(i)) call abort
+ if (a(i) .ne. b(i)) stop 2
end do
end subroutine check
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-parallel-loop-data-enter-exit.f95 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-parallel-loop-data-enter-exit.f95
index fe1088c0d04..0d353e80131 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-parallel-loop-data-enter-exit.f95
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-parallel-loop-data-enter-exit.f95
@@ -30,7 +30,7 @@ program main
!$acc exit data copyout (a(0:n-1), b(0:n-1), c(0:n-1))
do i = 0, n - 1
- if (c(i) .ne. a(i) + b(i)) call abort
+ if (c(i) .ne. a(i) + b(i)) stop 1
end do
end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-1.f90
index 5119fabadaf..bcc0476d665 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-1.f90
@@ -18,6 +18,6 @@ program main
!$acc end kernels
do i = 1, 32
- if (arr(i) .ne. i * 3) call abort
+ if (arr(i) .ne. i * 3) stop 1
end do
end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-2.f90
index 5e46287497d..5571059588f 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-2.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-2.f90
@@ -23,6 +23,6 @@ program main
!$acc end kernels
do i = 0, 32 * 32 - 1
- if (arr(i) .ne. i + (i / 32) * 2) call abort
+ if (arr(i) .ne. i + (i / 32) * 2) stop 1
end do
end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-3.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-3.f90
index 5cc3378f459..6abbed7f489 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-3.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-3.f90
@@ -23,6 +23,6 @@ program main
!$acc end kernels
do i = 0, 32 * 32 - 1
- if (arr(i) .ne. i + (i / 32) * 2) call abort
+ if (arr(i) .ne. i + (i / 32) * 2) stop 1
end do
end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-6.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-6.f90
index 1e41555aa1c..d92be2d4f0e 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-6.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-gang-6.f90
@@ -31,6 +31,6 @@ program main
!$acc end kernels
do i = 0, 32 * 32 - 1
- if (arr(i) .ne. i + (i / 32) * 13) call abort
+ if (arr(i) .ne. i + (i / 32) * 13) stop 1
end do
end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-vector-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-vector-1.f90
index 3efd9fe473b..e9c0fb3f130 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-vector-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-vector-1.f90
@@ -33,7 +33,7 @@ program main
do k = 0, 32 - 1
idx = i * 1024 + j * 32 + k
if (arr(idx) .ne. idx + ieor(i, j * 3) * k + ior(i, j * 5) * k) then
- call abort
+ stop 1
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-vector-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-vector-2.f90
index 1cf3b9818ef..13badb51919 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-vector-2.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-vector-2.f90
@@ -30,7 +30,7 @@ program main
do k = 0, 32 - 1
idx = i * 1024 + j * 32 + k
if (arr(idx) .ne. idx + ieor(i, j * 3) * k + ior(i, j * 5) * k) then
- call abort
+ stop 1
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-1.f90
index 55e98e05c03..04d732ef410 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-1.f90
@@ -22,6 +22,6 @@ program main
!$acc end kernels
do i = 0, 32 * 32 - 1
- if (arr(i) .ne. i + ieor(i / 32, mod(i, 32) * 3)) call abort
+ if (arr(i) .ne. i + ieor(i / 32, mod(i, 32) * 3)) stop 1
end do
end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-2.f90
index 7924e7f13a6..6c9a6b81c8a 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-2.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-2.f90
@@ -29,7 +29,7 @@ program main
do j = 0, 32 -1
do k = 0, 32 - 1
idx = i * 1024 + j * 32 + k
- if (arr(idx) .ne. idx + ieor(i, j * 3) * k) call abort
+ if (arr(idx) .ne. idx + ieor(i, j * 3) * k) stop 1
end do
end do
end do
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-3.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-3.f90
index 598c6fd7226..fab14c3a953 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-3.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-3.f90
@@ -40,7 +40,7 @@ program main
do k = 0, 32 - 1
idx = i * 1024 + j * 32 + k
if (arr(idx) .ne. idx + ieor(i, j * 3) * k + ior(i, j * 5) * k) then
- call abort
+ stop 1
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-4.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-4.f90
index 8512d7c3966..71f4a110acb 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-4.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-4.f90
@@ -37,7 +37,7 @@ program main
do k = 0, 32 - 1
idx = i * 1024 + j * 32 + k
if (arr(idx) .ne. idx + ieor(i, j * 3) * k + ior(i, j * 5) * k) then
- call abort
+ stop 1
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-5.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-5.f90
index c3ebf744578..bb457555a42 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-5.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-5.f90
@@ -40,7 +40,7 @@ program main
do k = 0, 32 - 1
idx = i * 1024 + j * 32 + k
if (arr(idx) .ne. idx + ieor(i, j * 3) * k + ior(i, j * 5) * k) then
- call abort
+ stop 1
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-6.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-6.f90
index 2a8a5905895..e169714dd51 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-6.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-6.f90
@@ -41,7 +41,7 @@ program main
do k = 0, 32 - 1
idx = i * 1024 + j * 32 + k
if (arr(idx) .ne. idx + ieor(i, j * 3) * k + ior(i, j * 5) * k) then
- call abort
+ stop 1
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-7.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-7.f90
index 7dd1d3da7be..e262c02ac00 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-7.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-private-vars-loop-worker-7.f90
@@ -36,7 +36,7 @@ program main
do k = 0, 32 - 1
idx = i * 1024 + j * 32 + k
if (arr(idx) .ne. idx + ieor(i, j * 3) * k + ior(i, j * 5) * k) then
- call abort
+ stop 1
end if
end do
end do
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-reduction-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-reduction-1.f90
index c7a52ed98f6..4b85608f0de 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/kernels-reduction-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-reduction-1.f90
@@ -15,5 +15,5 @@ program reduction
end do
!$acc end kernels
- if (red .ne. n) call abort
+ if (red .ne. n) stop 1
end program reduction
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-1.f90
index 901169aa119..760e21f916f 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/lib-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-1.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
use openacc
if (acc_get_num_devices (acc_device_host) .ne. 1) STOP 1
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-12.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-12.f90
index e307dfde374..efb921065ac 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/lib-12.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-12.f90
@@ -1,5 +1,4 @@
! { dg-do run }
-! { dg-xfail-run-if "TODO" { openacc_nvidia_accel_selected } { "-O0" "-O1" } { "" } }
program main
use openacc
@@ -18,10 +17,14 @@ program main
call acc_wait_async (0, 1)
- if (acc_async_test (0) .neqv. .TRUE.) call abort
-
- if (acc_async_test (1) .neqv. .TRUE.) call abort
+ ! Test unseen async-argument.
+ if (acc_async_test (2) .neqv. .TRUE.) stop 1
+ call acc_wait_async (2, 1)
call acc_wait (1)
+ if (acc_async_test (0) .neqv. .TRUE.) stop 2
+ if (acc_async_test (1) .neqv. .TRUE.) stop 3
+ if (acc_async_test (2) .neqv. .TRUE.) stop 4
+
end program
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-13.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-13.f90
index 6d713b1cd95..deb2c288604 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/lib-13.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-13.f90
@@ -1,5 +1,4 @@
! { dg-do run }
-! { dg-xfail-run-if "TODO" { openacc_nvidia_accel_selected } { "-O0" "-O1" } { "" } }
program main
use openacc
@@ -22,13 +21,12 @@ program main
end do
!$acc end data
- if (acc_async_test (1) .neqv. .TRUE.) call abort
- if (acc_async_test (2) .neqv. .TRUE.) call abort
-
call acc_wait_all_async (nprocs + 1)
- if (acc_async_test (nprocs + 1) .neqv. .TRUE.) call abort
+ call acc_wait (nprocs + 1)
- call acc_wait_all ()
+ if (acc_async_test (1) .neqv. .TRUE.) stop 1
+ if (acc_async_test (2) .neqv. .TRUE.) stop 2
+ if (acc_async_test (nprocs + 1) .neqv. .TRUE.) stop 3
end program
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-14.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-14.f90
index eb0206ccce1..bf35631c96b 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/lib-14.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-14.f90
@@ -19,14 +19,14 @@ program main
call acc_present_or_copyin (h)
- if (acc_is_present (h) .neqv. .TRUE.) call abort
+ if (acc_is_present (h) .neqv. .TRUE.) stop 1
call acc_copyout (h)
- if (acc_is_present (h) .neqv. .FALSE.) call abort
+ if (acc_is_present (h) .neqv. .FALSE.) stop 1
do i = 1, N
- if (h(i) /= i) call abort
+ if (h(i) /= i) stop 1
end do
do i = 1, N
@@ -35,19 +35,19 @@ program main
call acc_pcopyin (h, sizeof (h))
- if (acc_is_present (h) .neqv. .TRUE.) call abort
+ if (acc_is_present (h) .neqv. .TRUE.) stop 1
call acc_copyout (h)
- if (acc_is_present (h) .neqv. .FALSE.) call abort
+ if (acc_is_present (h) .neqv. .FALSE.) stop 1
do i = 1, N
- if (h(i) /= i + i) call abort
+ if (h(i) /= i + i) stop 1
end do
call acc_create (h)
- if (acc_is_present (h) .neqv. .TRUE.) call abort
+ if (acc_is_present (h) .neqv. .TRUE.) stop 1
!$acc parallel loop
do i = 1, N
@@ -57,26 +57,26 @@ program main
call acc_copyout (h)
- if (acc_is_present (h) .neqv. .FALSE.) call abort
+ if (acc_is_present (h) .neqv. .FALSE.) stop 1
do i = 1, N
- if (h(i) /= i) call abort
+ if (h(i) /= i) stop 1
end do
call acc_present_or_create (h, sizeof (h))
- if (acc_is_present (h) .neqv. .TRUE.) call abort
+ if (acc_is_present (h) .neqv. .TRUE.) stop 1
call acc_delete (h)
- if (acc_is_present (h) .neqv. .FALSE.) call abort
+ if (acc_is_present (h) .neqv. .FALSE.) stop 1
call acc_pcreate (h)
- if (acc_is_present (h) .neqv. .TRUE.) call abort
+ if (acc_is_present (h) .neqv. .TRUE.) stop 1
call acc_delete (h)
- if (acc_is_present (h) .neqv. .FALSE.) call abort
+ if (acc_is_present (h) .neqv. .FALSE.) stop 1
end program
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-15.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-15.f90
index 3a834dbb22a..8b9bbd94cbc 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/lib-15.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-15.f90
@@ -23,14 +23,14 @@ program main
call acc_update_device (h, sizeof (h))
- if (acc_is_present (h) .neqv. .TRUE.) call abort
+ if (acc_is_present (h) .neqv. .TRUE.) stop 1
h(:) = 0
call acc_copyout (h, sizeof (h))
do i = 1, N
- if (h(i) /= i + i) call abort
+ if (h(i) /= i + i) stop 2
end do
call acc_copyin (h, sizeof (h))
@@ -39,14 +39,14 @@ program main
call acc_update_self (h, sizeof (h))
- if (acc_is_present (h) .neqv. .TRUE.) call abort
+ if (acc_is_present (h) .neqv. .TRUE.) stop 3
do i = 1, N
- if (h(i) /= i + i) call abort
+ if (h(i) /= i + i) stop 4
end do
call acc_delete (h)
- if (acc_is_present (h) .neqv. .FALSE.) call abort
+ if (acc_is_present (h) .neqv. .FALSE.) stop 5
end program
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-16-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-16-2.f90
new file mode 100644
index 00000000000..ddd557d3be0
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-16-2.f90
@@ -0,0 +1,58 @@
+! See also "lib-16.f90".
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+program main
+ implicit none
+ include "openacc_lib.h"
+
+ integer, parameter :: N = 256
+ integer, allocatable :: h(:)
+ integer :: i
+ integer :: async = 5
+
+ allocate (h(N))
+
+ do i = 1, N
+ h(i) = i
+ end do
+
+ call acc_copyin (h)
+
+ do i = 1, N
+ h(i) = i + i
+ end do
+
+ call acc_update_device_async (h, sizeof (h), async)
+
+ if (acc_is_present (h) .neqv. .TRUE.) stop 1
+
+ h(:) = 0
+
+ call acc_copyout_async (h, sizeof (h), async)
+
+ call acc_wait (async)
+
+ do i = 1, N
+ if (h(i) /= i + i) stop 2
+ end do
+
+ call acc_copyin (h, sizeof (h))
+
+ h(:) = 0
+
+ call acc_update_self_async (h, sizeof (h), async)
+
+ if (acc_is_present (h) .neqv. .TRUE.) stop 3
+
+ do i = 1, N
+ if (h(i) /= i + i) stop 4
+ end do
+
+ call acc_delete_async (h, async)
+
+ call acc_wait (async)
+
+ if (acc_is_present (h) .neqv. .FALSE.) stop 5
+
+end program
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-16.f90 b/libgomp/testsuite/libgomp.oacc-fortran/lib-16.f90
new file mode 100644
index 00000000000..ccd1ce6ee18
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-16.f90
@@ -0,0 +1,58 @@
+! See also "lib-16-2.f90".
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+
+program main
+ use openacc
+ implicit none
+
+ integer, parameter :: N = 256
+ integer, allocatable :: h(:)
+ integer :: i
+ integer :: async = 5
+
+ allocate (h(N))
+
+ do i = 1, N
+ h(i) = i
+ end do
+
+ call acc_copyin (h)
+
+ do i = 1, N
+ h(i) = i + i
+ end do
+
+ call acc_update_device_async (h, sizeof (h), async)
+
+ if (acc_is_present (h) .neqv. .TRUE.) stop 1
+
+ h(:) = 0
+
+ call acc_copyout_async (h, sizeof (h), async)
+
+ call acc_wait (async)
+
+ do i = 1, N
+ if (h(i) /= i + i) stop 2
+ end do
+
+ call acc_copyin (h, sizeof (h))
+
+ h(:) = 0
+
+ call acc_update_self_async (h, sizeof (h), async)
+
+ if (acc_is_present (h) .neqv. .TRUE.) stop 3
+
+ do i = 1, N
+ if (h(i) /= i + i) stop 4
+ end do
+
+ call acc_delete_async (h, async)
+
+ call acc_wait (async)
+
+ if (acc_is_present (h) .neqv. .FALSE.) stop 5
+
+end program
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-2.f b/libgomp/testsuite/libgomp.oacc-fortran/lib-2.f
index 069e07ec035..3c8d8dba3e7 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/lib-2.f
+++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-2.f
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
USE OPENACC
IF (ACC_GET_NUM_DEVICES (ACC_DEVICE_HOST) .NE. 1) STOP 1
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/lib-3.f b/libgomp/testsuite/libgomp.oacc-fortran/lib-3.f
index 47424f14a15..54a781eae69 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/lib-3.f
+++ b/libgomp/testsuite/libgomp.oacc-fortran/lib-3.f
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
INCLUDE "openacc_lib.h"
IF (ACC_GET_NUM_DEVICES (ACC_DEVICE_HOST) .NE. 1) STOP 1
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/map-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/map-1.f90
index 47859508c8f..c0e8f8f540c 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/map-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/map-1.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
program map
integer, parameter :: n = 20, c = 10
integer :: i, a(n), b(n)
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/parallel-dims-aux.c b/libgomp/testsuite/libgomp.oacc-fortran/parallel-dims-aux.c
new file mode 100644
index 00000000000..b5986f4afef
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/parallel-dims-aux.c
@@ -0,0 +1,45 @@
+/* OpenACC parallelism dimensions clauses: num_gangs, num_workers,
+ vector_length. */
+
+/* Copied from '../libgomp.oacc-c-c++-common/parallel-dims.c'. */
+
+/* Used by 'parallel-dims.f90'. */
+
+#include <limits.h>
+#include <openacc.h>
+#include <gomp-constants.h>
+
+/* TODO: "(int) acc_device_*" casts because of the C++ acc_on_device wrapper
+ not behaving as expected for -O0. */
+#pragma acc routine seq
+/* static */ unsigned int __attribute__ ((optimize ("O2"))) acc_gang ()
+{
+ if (acc_on_device ((int) acc_device_host))
+ return 0;
+ else if (acc_on_device ((int) acc_device_nvidia))
+ return __builtin_goacc_parlevel_id (GOMP_DIM_GANG);
+ else
+ __builtin_abort ();
+}
+
+#pragma acc routine seq
+/* static */ unsigned int __attribute__ ((optimize ("O2"))) acc_worker ()
+{
+ if (acc_on_device ((int) acc_device_host))
+ return 0;
+ else if (acc_on_device ((int) acc_device_nvidia))
+ return __builtin_goacc_parlevel_id (GOMP_DIM_WORKER);
+ else
+ __builtin_abort ();
+}
+
+#pragma acc routine seq
+/* static */ unsigned int __attribute__ ((optimize ("O2"))) acc_vector ()
+{
+ if (acc_on_device ((int) acc_device_host))
+ return 0;
+ else if (acc_on_device ((int) acc_device_nvidia))
+ return __builtin_goacc_parlevel_id (GOMP_DIM_VECTOR);
+ else
+ __builtin_abort ();
+}
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/parallel-dims.f90 b/libgomp/testsuite/libgomp.oacc-fortran/parallel-dims.f90
new file mode 100644
index 00000000000..1bfcd6ce099
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/parallel-dims.f90
@@ -0,0 +1,120 @@
+! OpenACC parallelism dimensions clauses: num_gangs, num_workers,
+! vector_length.
+
+! { dg-additional-sources parallel-dims-aux.c }
+! { dg-do run }
+! { dg-prune-output "command-line option '-fintrinsic-modules-path=.*' is valid for Fortran but not for C" }
+
+! See also '../libgomp.oacc-c-c++-common/parallel-dims.c'.
+
+module acc_routines
+ implicit none (type, external)
+
+ interface
+ integer function acc_gang() bind(C)
+ !$acc routine seq
+ end function acc_gang
+
+ integer function acc_worker() bind(C)
+ !$acc routine seq
+ end function acc_worker
+
+ integer function acc_vector() bind(C)
+ !$acc routine seq
+ end function acc_vector
+ end interface
+end module acc_routines
+
+program main
+ use iso_c_binding
+ use openacc
+ use acc_routines
+ implicit none (type, external)
+
+ integer :: gangs_min, gangs_max, workers_min, workers_max, vectors_min, vectors_max
+ integer :: vectors_actual
+ integer :: i, j, k
+
+ call acc_init (acc_device_default)
+
+ ! OpenACC parallel construct.
+
+ !TODO
+
+
+ ! OpenACC kernels construct.
+
+ !TODO
+
+
+ ! OpenACC serial construct.
+
+ ! GR, WS, VS.
+
+ gangs_min = huge(gangs_min) ! INT_MAX
+ workers_min = huge(workers_min) ! INT_MAX
+ vectors_min = huge(vectors_min) ! INT_MAX
+ gangs_max = -huge(gangs_max) - 1 ! INT_MIN
+ workers_max = -huge(gangs_max) - 1 ! INT_MIN
+ vectors_max = -huge(gangs_max) - 1 ! INT_MIN
+ !$acc serial &
+ !$acc reduction (min: gangs_min, workers_min, vectors_min) reduction (max: gangs_max, workers_max, vectors_max) ! { dg-warning "using vector_length \\(32\\), ignoring 1" "" { target openacc_nvidia_accel_selected } }
+ do i = 100, -99, -1
+ gangs_min = acc_gang ();
+ gangs_max = acc_gang ();
+ workers_min = acc_worker ();
+ workers_max = acc_worker ();
+ vectors_min = acc_vector ();
+ vectors_max = acc_vector ();
+ end do
+ !$acc end serial
+ if (gangs_min /= 0 .or. gangs_max /= 1 - 1 &
+ .or. workers_min /= 0 .or. workers_max /= 1 - 1 &
+ .or. vectors_min /= 0 .or. vectors_max /= 1 - 1) &
+ stop 1
+
+ ! Composition of GP, WP, VP.
+
+ vectors_actual = 1 ! Implicit 'vector_length (1)' clause.
+ gangs_min = huge(gangs_min) ! INT_MAX
+ workers_min = huge(workers_min) ! INT_MAX
+ vectors_min = huge(vectors_min) ! INT_MAX
+ gangs_max = -huge(gangs_max) - 1 ! INT_MIN
+ workers_max = -huge(gangs_max) - 1 ! INT_MIN
+ vectors_max = -huge(gangs_max) - 1 ! INT_MIN
+ !$acc serial copy (vectors_actual) &
+ !$acc copy (gangs_min, gangs_max, workers_min, workers_max, vectors_min, vectors_max) ! { dg-warning "using vector_length \\(32\\), ignoring 1" "" { target openacc_nvidia_accel_selected } }
+ if (acc_on_device (acc_device_nvidia)) then
+ ! The GCC nvptx back end enforces vector_length (32).
+ ! It's unclear if that's actually permissible here;
+ ! <https://github.com/OpenACC/openacc-spec/issues/238> "OpenACC 'serial'
+ ! construct might not actually be serial".
+ vectors_actual = 32
+ end if
+ !$acc loop gang reduction (min: gangs_min, workers_min, vectors_min) reduction (max: gangs_max, workers_max, vectors_max)
+ do i = 100, -99, -1
+ !$acc loop worker reduction (min: gangs_min, workers_min, vectors_min) reduction (max: gangs_max, workers_max, vectors_max)
+ do j = 100, -99, -1
+ !$acc loop vector reduction (min: gangs_min, workers_min, vectors_min) reduction (max: gangs_max, workers_max, vectors_max)
+ do k = 100 * vectors_actual, -99 * vectors_actual, -1
+ gangs_min = acc_gang ();
+ gangs_max = acc_gang ();
+ workers_min = acc_worker ();
+ workers_max = acc_worker ();
+ vectors_min = acc_vector ();
+ vectors_max = acc_vector ();
+ end do
+ end do
+ end do
+ !$acc end serial
+ if (acc_get_device_type () .eq. acc_device_nvidia) then
+ if (vectors_actual /= 32) stop 2
+ else
+ if (vectors_actual /= 1) stop 3
+ end if
+ if (gangs_min /= 0 .or. gangs_max /= 1 - 1 &
+ .or. workers_min /= 0 .or. workers_max /= 1 - 1 &
+ .or. vectors_min /= 0 .or. vectors_max /= vectors_actual - 1) &
+ stop 4
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/parallel-loop-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/parallel-loop-1.f90
index 754b833a4ba..676417cfecf 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/parallel-loop-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/parallel-loop-1.f90
@@ -37,7 +37,7 @@ program loops
!$acc end parallel
do i = 1, n
- if (a(i) .ne. b(i)) call abort
+ if (a(i) .ne. b(i)) stop 1
end do
call check (a, b, n)
@@ -72,6 +72,6 @@ subroutine check (a, b, n)
integer :: i
do i = 1, n
- if (a(i) .ne. b(i)) call abort
+ if (a(i) .ne. b(i)) stop 2
end do
end subroutine check
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/pointer-align-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/pointer-align-1.f90
index 3f4b9fe070e..d0e7aa1c81b 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/pointer-align-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/pointer-align-1.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
! PR middle-end/63247
program test
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/pr68813.f90 b/libgomp/testsuite/libgomp.oacc-fortran/pr68813.f90
index 735350f6aac..c4552053e28 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/pr68813.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/pr68813.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
program foo
implicit none
integer, parameter :: n = 100
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/pr70289.f90 b/libgomp/testsuite/libgomp.oacc-fortran/pr70289.f90
index 63bde44100d..a516f9f32f6 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/pr70289.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/pr70289.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
program foo
implicit none
integer :: i
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/pr70643.f90 b/libgomp/testsuite/libgomp.oacc-fortran/pr70643.f90
index c8a7922a415..42dc3193546 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/pr70643.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/pr70643.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
MODULE reduction_test
CONTAINS
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/print-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/print-1.f90
new file mode 100644
index 00000000000..a83280d1edb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/print-1.f90
@@ -0,0 +1,15 @@
+! Ensure that printf on the offload device works.
+
+! { dg-do run }
+! { dg-output "The answer is 42(\n|\r\n|\r)+" }
+! { dg-xfail-if "no write for nvidia" { openacc_nvidia_accel_selected } }
+
+program main
+ implicit none
+ integer :: var = 42
+
+!$acc parallel
+ write (0, '("The answer is ", I2)') var
+!$acc end parallel
+
+end program main
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/pset-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/pset-1.f90
index c3a8a9cac1c..3cf7eb5987d 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/pset-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/pset-1.f90
@@ -9,7 +9,7 @@ program test
integer, allocatable :: c3(:,:,:)
allocate (a1(5))
- if (.not.allocated (a1)) STOP 1
+ if (.not.allocated (a1)) STOP 49
a1 = 10
@@ -30,7 +30,7 @@ program test
deallocate(a1)
allocate (a1(0:4))
- if (.not.allocated (a1)) STOP 2
+ if (.not.allocated (a1)) STOP 50
a1 = 10
@@ -51,7 +51,7 @@ program test
deallocate(a1)
allocate (b2(5,5))
- if (.not.allocated (b2)) STOP 3
+ if (.not.allocated (b2)) STOP 51
b2 = 11
@@ -72,7 +72,7 @@ program test
deallocate(b2)
allocate (b2(0:4,0:4))
- if (.not.allocated (b2)) STOP 4
+ if (.not.allocated (b2)) STOP 52
b2 = 11
@@ -93,7 +93,7 @@ program test
deallocate(b2)
allocate (c3(5,5,5))
- if (.not.allocated (c3)) STOP 5
+ if (.not.allocated (c3)) STOP 53
c3 = 12
@@ -114,7 +114,7 @@ program test
deallocate(c3)
allocate (c3(0:4,0:4,0:4))
- if (.not.allocated (c3)) STOP 6
+ if (.not.allocated (c3)) STOP 54
c3 = 12
@@ -135,13 +135,13 @@ program test
deallocate(c3)
allocate (a1(5))
- if (.not.allocated (a1)) STOP 7
+ if (.not.allocated (a1)) STOP 55
allocate (b1(5))
- if (.not.allocated (b1)) STOP 8
+ if (.not.allocated (b1)) STOP 56
allocate (c1(5))
- if (.not.allocated (c1)) STOP 9
+ if (.not.allocated (c1)) STOP 57
a1 = 10
b1 = 3
@@ -172,13 +172,13 @@ program test
deallocate(c1)
allocate (a1(0:4))
- if (.not.allocated (a1)) STOP 10
+ if (.not.allocated (a1)) STOP 58
allocate (b1(0:4))
- if (.not.allocated (b1)) STOP 11
+ if (.not.allocated (b1)) STOP 59
allocate (c1(0:4))
- if (.not.allocated (c1)) STOP 12
+ if (.not.allocated (c1)) STOP 60
a1 = 10
b1 = 3
@@ -209,7 +209,7 @@ program test
deallocate(c1)
allocate (a1(5))
- if (.not.allocated (a1)) STOP 13
+ if (.not.allocated (a1)) STOP 61
a1 = 10
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/reference-reductions.f90 b/libgomp/testsuite/libgomp.oacc-fortran/reference-reductions.f90
index a684d07977c..b25430e59ed 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/reference-reductions.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/reference-reductions.f90
@@ -34,5 +34,5 @@ program test
r=10.0
call param_reduction (r)
- if (r .ne. 1010) call abort ()
+ if (r .ne. 1010) stop 1
end program test
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/routine-7.f90 b/libgomp/testsuite/libgomp.oacc-fortran/routine-7.f90
index f58a95fe670..1009f4a81e5 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/routine-7.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/routine-7.f90
@@ -109,7 +109,7 @@ end subroutine gang
subroutine seq (a)
!$acc routine seq
- integer, intent (inout) :: a(M)
+ integer, intent (inout) :: a(N)
integer :: i
do i = 1, N
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/subarrays-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/subarrays-1.f90
index 8a2ec2cc97e..b67a8f482f4 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/subarrays-1.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/subarrays-1.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
program subarrays
integer, parameter :: n = 20, c = 10
integer :: i, a(n), b(n)
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/subarrays-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/subarrays-2.f90
index 914da5b4062..1cc6dd68820 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/subarrays-2.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/subarrays-2.f90
@@ -1,3 +1,5 @@
+! { dg-do run }
+!
program subarrays
integer, parameter :: n = 20, c = 10, low = 5, high = 10
integer :: i, a(n), b(n)
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/vector-routine.f90 b/libgomp/testsuite/libgomp.oacc-fortran/vector-routine.f90
index 1edcee48677..88b9ab411d4 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/vector-routine.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/vector-routine.f90
@@ -21,7 +21,7 @@ program main
!$acc end parallel
do i = 1, N
- if (a(i) .ne. 0) call abort
+ if (a(i) .ne. 0) stop 1
end do
contains
diff --git a/libgomp/work.c b/libgomp/work.c
index b2b34145289..28bb0c11255 100644
--- a/libgomp/work.c
+++ b/libgomp/work.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005-2018 Free Software Foundation, Inc.
+/* Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
@@ -76,7 +76,15 @@ alloc_work_share (struct gomp_team *team)
#endif
team->work_share_chunk *= 2;
+ /* Allocating gomp_work_share structures aligned is just an
+ optimization, don't do it when using the fallback method. */
+#ifdef GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC
+ ws = gomp_aligned_alloc (__alignof (struct gomp_work_share),
+ team->work_share_chunk
+ * sizeof (struct gomp_work_share));
+#else
ws = gomp_malloc (team->work_share_chunk * sizeof (struct gomp_work_share));
+#endif
ws->next_alloc = team->work_shares[0].next_alloc;
team->work_shares[0].next_alloc = ws;
team->work_share_list_alloc = &ws[1];
@@ -90,30 +98,38 @@ alloc_work_share (struct gomp_team *team)
This shouldn't touch the next_alloc field. */
void
-gomp_init_work_share (struct gomp_work_share *ws, bool ordered,
+gomp_init_work_share (struct gomp_work_share *ws, size_t ordered,
unsigned nthreads)
{
gomp_mutex_init (&ws->lock);
if (__builtin_expect (ordered, 0))
{
-#define INLINE_ORDERED_TEAM_IDS_CNT \
- ((sizeof (struct gomp_work_share) \
- - offsetof (struct gomp_work_share, inline_ordered_team_ids)) \
- / sizeof (((struct gomp_work_share *) 0)->inline_ordered_team_ids[0]))
-
- if (nthreads > INLINE_ORDERED_TEAM_IDS_CNT)
- ws->ordered_team_ids
- = gomp_malloc (nthreads * sizeof (*ws->ordered_team_ids));
+#define INLINE_ORDERED_TEAM_IDS_SIZE \
+ (sizeof (struct gomp_work_share) \
+ - offsetof (struct gomp_work_share, inline_ordered_team_ids))
+
+ if (__builtin_expect (ordered != 1, 0))
+ {
+ size_t o = nthreads * sizeof (*ws->ordered_team_ids);
+ o += __alignof__ (long long) - 1;
+ if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+ & (__alignof__ (long long) - 1)) == 0)
+ o &= ~(__alignof__ (long long) - 1);
+ ordered += o - 1;
+ }
+ else
+ ordered = nthreads * sizeof (*ws->ordered_team_ids);
+ if (ordered > INLINE_ORDERED_TEAM_IDS_SIZE)
+ ws->ordered_team_ids = team_malloc (ordered);
else
ws->ordered_team_ids = ws->inline_ordered_team_ids;
- memset (ws->ordered_team_ids, '\0',
- nthreads * sizeof (*ws->ordered_team_ids));
+ memset (ws->ordered_team_ids, '\0', ordered);
ws->ordered_num_used = 0;
ws->ordered_owner = -1;
ws->ordered_cur = 0;
}
else
- ws->ordered_team_ids = NULL;
+ ws->ordered_team_ids = ws->inline_ordered_team_ids;
gomp_ptrlock_init (&ws->next_ws, NULL);
ws->threads_completed = 0;
}
@@ -126,7 +142,7 @@ gomp_fini_work_share (struct gomp_work_share *ws)
{
gomp_mutex_destroy (&ws->lock);
if (ws->ordered_team_ids != ws->inline_ordered_team_ids)
- free (ws->ordered_team_ids);
+ team_free (ws->ordered_team_ids);
gomp_ptrlock_destroy (&ws->next_ws);
}
@@ -166,7 +182,7 @@ free_work_share (struct gomp_team *team, struct gomp_work_share *ws)
if this was the first thread to reach this point. */
bool
-gomp_work_share_start (bool ordered)
+gomp_work_share_start (size_t ordered)
{
struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr->ts.team;
@@ -178,7 +194,7 @@ gomp_work_share_start (bool ordered)
ws = gomp_malloc (sizeof (*ws));
gomp_init_work_share (ws, ordered, 1);
thr->ts.work_share = ws;
- return ws;
+ return true;
}
ws = thr->ts.work_share;