This patch backports the recent fortran routine support changes I've made in trunk to gomp-4_0-branch. Nothing changed in the fortran front end, but I corrected a couple of problems with the way that gang, worker and vector were handled in tree-nested.c. And there's a new test case to exercise those changes.
This patch has been applied to gomp-4_0-branch. Cesar
2015-11-30 Cesar Philippidis <ce...@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. diff --git a/gcc/testsuite/gfortran.dg/goacc/subroutines.f90 b/gcc/testsuite/gfortran.dg/goacc/subroutines.f90 new file mode 100644 index 0000000..6cab798 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/subroutines.f90 @@ -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 diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index e321072..1c9849b 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -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;