2015-11-30 Cesar Philippidis <cesar@codesourcery.com>
gcc/
* tree-nested.c (convert_nonlocal_omp_clauses): Handle optional
arguments for OMP_CLAUSE_{GANG,WORKER,VECTOR}.
(convert_local_omp_clauses): Likewise
gcc/testsuite/
* gfortran.dg/goacc/subroutines.f90: New test.
new file mode 100644
@@ -0,0 +1,73 @@
+! Exercise how tree-nested.c handles gang, worker vector and seq.
+
+! { dg-do compile }
+
+program main
+ integer, parameter :: N = 100
+ integer :: nonlocal_arg
+ integer :: nonlocal_a(N)
+ integer :: nonlocal_i
+ integer :: nonlocal_j
+
+ nonlocal_a (:) = 5
+ nonlocal_arg = 5
+
+ call local ()
+ call nonlocal ()
+
+contains
+
+ subroutine local ()
+ integer :: local_i
+ integer :: local_arg
+ integer :: local_a(N)
+ integer :: local_j
+
+ local_a (:) = 5
+ local_arg = 5
+
+ !$acc kernels loop gang(num:local_arg) worker(local_arg) vector(local_arg)
+ do local_i = 1, N
+ local_a(local_i) = 100
+ !$acc loop seq
+ do local_j = 1, N
+ enddo
+ enddo
+ !$acc end kernels loop
+
+ !$acc kernels loop gang(static:local_arg) worker(local_arg) &
+ !$acc vector(local_arg)
+ do local_i = 1, N
+ local_a(local_i) = 100
+ !$acc loop seq
+ do local_j = 1, N
+ enddo
+ enddo
+ !$acc end kernels loop
+ end subroutine local
+
+ subroutine nonlocal ()
+ nonlocal_a (:) = 5
+ nonlocal_arg = 5
+
+ !$acc kernels loop gang(num:nonlocal_arg) worker(nonlocal_arg) &
+ !$acc vector(nonlocal_arg)
+ do nonlocal_i = 1, N
+ nonlocal_a(nonlocal_i) = 100
+ !$acc loop seq
+ do nonlocal_j = 1, N
+ enddo
+ enddo
+ !$acc end kernels loop
+
+ !$acc kernels loop gang(static:nonlocal_arg) worker(nonlocal_arg) &
+ !$acc vector(nonlocal_arg)
+ do nonlocal_i = 1, N
+ nonlocal_a(nonlocal_i) = 100
+ !$acc loop seq
+ do nonlocal_j = 1, N
+ enddo
+ enddo
+ !$acc end kernels loop
+ end subroutine nonlocal
+end program main
@@ -1109,10 +1109,28 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_NUM_GANGS:
case OMP_CLAUSE_NUM_WORKERS:
case OMP_CLAUSE_VECTOR_LENGTH:
- wi->val_only = true;
- wi->is_lhs = false;
- convert_nonlocal_reference_op (&OMP_CLAUSE_OPERAND (clause, 0),
- &dummy, wi);
+ case OMP_CLAUSE_GANG:
+ case OMP_CLAUSE_WORKER:
+ case OMP_CLAUSE_VECTOR:
+ /* Several OpenACC clauses have optional arguments. Check if they
+ are present. */
+ if (OMP_CLAUSE_OPERAND (clause, 0))
+ {
+ wi->val_only = true;
+ wi->is_lhs = false;
+ convert_nonlocal_reference_op (&OMP_CLAUSE_OPERAND (clause, 0),
+ &dummy, wi);
+ }
+
+ /* The gang clause accepts two arguments. */
+ if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_GANG
+ && OMP_CLAUSE_GANG_STATIC_EXPR (clause))
+ {
+ wi->val_only = true;
+ wi->is_lhs = false;
+ convert_nonlocal_reference_op
+ (&OMP_CLAUSE_GANG_STATIC_EXPR (clause), &dummy, wi);
+ }
break;
case OMP_CLAUSE_DIST_SCHEDULE:
@@ -1176,9 +1194,6 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
- case OMP_CLAUSE_GANG:
- case OMP_CLAUSE_WORKER:
- case OMP_CLAUSE_VECTOR:
case OMP_CLAUSE_SEQ:
break;
@@ -1768,10 +1783,28 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_NUM_GANGS:
case OMP_CLAUSE_NUM_WORKERS:
case OMP_CLAUSE_VECTOR_LENGTH:
- wi->val_only = true;
- wi->is_lhs = false;
- convert_local_reference_op (&OMP_CLAUSE_OPERAND (clause, 0), &dummy,
- wi);
+ case OMP_CLAUSE_GANG:
+ case OMP_CLAUSE_WORKER:
+ case OMP_CLAUSE_VECTOR:
+ /* Several OpenACC clauses have optional arguments. Check if they
+ are present. */
+ if (OMP_CLAUSE_OPERAND (clause, 0))
+ {
+ wi->val_only = true;
+ wi->is_lhs = false;
+ convert_local_reference_op (&OMP_CLAUSE_OPERAND (clause, 0),
+ &dummy, wi);
+ }
+
+ /* The gang clause accepts two arguments. */
+ if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_GANG
+ && OMP_CLAUSE_GANG_STATIC_EXPR (clause))
+ {
+ wi->val_only = true;
+ wi->is_lhs = false;
+ convert_nonlocal_reference_op
+ (&OMP_CLAUSE_GANG_STATIC_EXPR (clause), &dummy, wi);
+ }
break;
case OMP_CLAUSE_DIST_SCHEDULE:
@@ -1840,9 +1873,6 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
- case OMP_CLAUSE_GANG:
- case OMP_CLAUSE_WORKER:
- case OMP_CLAUSE_VECTOR:
case OMP_CLAUSE_SEQ:
break;