gfc_omp_map_op map_op;
gfc_omp_linear_op linear_op;
struct gfc_common_head *common;
+ bool lastprivate_conditional;
} u;
struct gfc_omp_namelist_udr *udr;
struct gfc_omp_namelist *next;
break;
case 'l':
if ((mask & OMP_CLAUSE_LASTPRIVATE)
- && gfc_match_omp_variable_list ("lastprivate (",
- &c->lists[OMP_LIST_LASTPRIVATE],
- true) == MATCH_YES)
- continue;
+ && gfc_match ("lastprivate ( ") == MATCH_YES)
+ {
+ bool conditional = gfc_match ("conditional : ") == MATCH_YES;
+ head = NULL;
+ if (gfc_match_omp_variable_list ("",
+ &c->lists[OMP_LIST_LASTPRIVATE],
+ false, NULL, &head) == MATCH_YES)
+ {
+ gfc_omp_namelist *n;
+ for (n = *head; n; n = n->next)
+ n->u.lastprivate_conditional = conditional;
+ continue;
+ }
+ gfc_current_locus = old_loc;
+ break;
+ }
end_colon = false;
head = NULL;
if ((mask & OMP_CLAUSE_LINEAR)
tree type = TREE_TYPE (decl), size, ptr, cond, then_b, else_b;
stmtblock_t block, cond_block;
- gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_PRIVATE
- || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LASTPRIVATE
- || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR
- || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION);
+ switch (OMP_CLAUSE_CODE (clause))
+ {
+ case OMP_CLAUSE__LOOPTEMP_:
+ case OMP_CLAUSE__REDUCTEMP_:
+ case OMP_CLAUSE__CONDTEMP_:
+ case OMP_CLAUSE__SCANTEMP_:
+ return NULL;
+ case OMP_CLAUSE_PRIVATE:
+ case OMP_CLAUSE_LASTPRIVATE:
+ case OMP_CLAUSE_LINEAR:
+ case OMP_CLAUSE_REDUCTION:
+ break;
+ default:
+ gcc_unreachable ();
+ }
if ((! GFC_DESCRIPTOR_TYPE_P (type)
|| GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
tree node = build_omp_clause (input_location, code);
OMP_CLAUSE_DECL (node) = t;
list = gfc_trans_add_clause (node, list);
+
+ if (code == OMP_CLAUSE_LASTPRIVATE
+ && namelist->u.lastprivate_conditional)
+ OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (node) = 1;
}
}
return list;
--- /dev/null
+subroutine foo (p)
+ implicit none
+ logical :: p(:)
+ integer a, b, c, d, e, f, g, h;
+ integer :: i
+ a = -1; b = -1; c = -1; d = -1; e = -1; f = -1; g = -1; h = -1
+ !$omp teams
+ !$omp distribute lastprivate (conditional: a) ! { dg-error "conditional 'lastprivate' clause on 'distribute' construct" }
+ do i = 1, 32
+ if (p(i)) &
+ a = i
+ end do
+ !$omp distribute simd lastprivate (conditional: b) ! { dg-error "conditional 'lastprivate' clause on 'distribute' construct" }
+ do i = 1, 32
+ if (p(i)) &
+ b = i
+ end do
+ !$omp distribute parallel do lastprivate (conditional: c) ! { dg-error "conditional 'lastprivate' clause on 'distribute' construct" }
+ do i = 1, 32
+ if (p(i)) &
+ c = i
+ end do
+ !$omp distribute parallel do simd lastprivate (conditional: d) ! { dg-error "conditional 'lastprivate' clause on 'distribute' construct" }
+ do i = 1, 32
+ if (p(i)) &
+ d = i
+ end do
+ !$omp end teams
+
+ !$omp teams distribute parallel do lastprivate (conditional: e) ! { dg-error "conditional 'lastprivate' clause on 'distribute' construct" }
+ do i = 1, 32
+ if (p(i)) &
+ e = i
+ end do
+
+ !$omp parallel
+ !$omp master
+ !$omp taskloop lastprivate (conditional: f) ! { dg-error "conditional 'lastprivate' clause on 'taskloop' construct" }
+ do i = 1, 32
+ if (p(i)) &
+ f = i
+ end do
+! !$omp master taskloop simd lastprivate (conditional: g) ! { dg!error "conditional 'lastprivate' clause on 'taskloop' construct" }
+! do i = 1, 32
+! if (p(i)) &
+! g = i
+! end do
+ !$omp end master
+ !$omp end parallel
+
+! !$omp parallel master taskloop simd lastprivate (conditional: h) ! { dg!error "conditional 'lastprivate' clause on 'taskloop' construct" }
+! do i = 1, 32
+! if (p(i)) &
+! h = i
+! end do
+! !$omp end parallel master taskloop simd
+end subroutine
+
+!struct S { int a, b; };
+
+subroutine bar (p)
+ implicit none
+ logical :: p(:)
+ type s_t
+ integer :: a, b
+ end type s_t
+ type(s_t) s, t
+ integer i
+ s = s_t(-1, -1)
+ t = s_t( 1, 2)
+ !$omp parallel do lastprivate (conditional: s) ! { dg-error "non-scalar variable 's' in conditional 'lastprivate' clause" }
+ do i = 1, 32
+ if (p(i)) then
+ block
+ type(s_t) u
+ u = t
+ u%b = i
+ s = u
+ end block
+ end if
+ end do
+end subroutine
--- /dev/null
+! { dg-additional-options "-fdump-tree-original" }
+subroutine foo (p)
+ logical :: p(:)
+ integer i
+ integer a, b, c, d, e, f, g, h
+ a = -1; b = -1; c = -1; d = -1; e = -1; f = -1; g = -1; h = -1
+ !$omp parallel
+ !$omp do lastprivate (conditional: a)
+ do i = 1, 32
+ if (p(i)) &
+ a = i
+ end do
+ !$omp end parallel
+ !$omp simd lastprivate (conditional: b)
+ do i = 1, 32
+ if (p(i)) &
+ b = i
+ end do
+ !$omp parallel
+ !$omp do simd lastprivate (conditional: c)
+ do i = 1, 32
+ if (p(i)) &
+ c = i
+ end do
+ !$omp end parallel
+ !$omp parallel do lastprivate (conditional: d)
+ do i = 1, 32
+ if (p(i)) &
+ d = i
+ end do
+ !$omp end parallel do
+ !$omp parallel do simd lastprivate (conditional: e)
+ do i = 1, 32
+ if (p(i)) &
+ e = i
+ end do
+ !$omp end parallel do simd
+end subroutine
+
+! { dg-final { scan-tree-dump-times "#pragma omp for lastprivate\\(conditional:a\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) lastprivate\\(conditional:b\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp for lastprivate\\(conditional:c\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) lastprivate\\(conditional:c\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel lastprivate\\(conditional:d\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel lastprivate\\(conditional:e\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) lastprivate\\(conditional:e\\)" 1 "original" } }
--- /dev/null
+subroutine foo
+ integer i, j, k
+ !$omp parallel
+ !$omp do lastprivate (conditional: i) ! { dg-warning "conditional 'lastprivate' on loop iterator 'i' ignored" }
+ do i = 1, 32
+ end do
+ !$omp do collapse (3) lastprivate (conditional: i) ! { dg-warning "conditional 'lastprivate' on loop iterator 'i' ignored" }
+ do i = 1, 32
+ do j = 1, 32
+ do k = 1, 32
+ end do
+ end do
+ end do
+ !$omp do collapse (3) lastprivate (conditional: j) ! { dg-warning "conditional 'lastprivate' on loop iterator 'j' ignored" }
+ do i = 1, 32
+ do j = 1, 32
+ do k = 1, 32
+ end do
+ end do
+ end do
+ !$omp do collapse (3) lastprivate (conditional: k) ! { dg-warning "conditional 'lastprivate' on loop iterator 'k' ignored" }
+ do i = 1, 32
+ do j = 1, 32
+ do k = 1, 32
+ end do
+ end do
+ end do
+ !$omp end parallel
+
+ ! Error in eqiv. C code: "conditional 'lastprivate' on loop iterator 'i' ignored"
+ !$omp parallel do lastprivate (conditional: i)
+ do i = 1, 32
+ end do
+ !$omp end parallel do
+
+ ! Error in eqiv. C code: "conditional 'lastprivate' on loop iterator 'i' ignored"
+ !$omp parallel do collapse (3) lastprivate (conditional: i)
+ do i = 1, 32
+ do j = 1, 32
+ do k = 1, 32
+ end do
+ end do
+ end do
+ !$omp end parallel do
+
+ ! Error in eqiv. C code: "conditional 'lastprivate' on loop iterator 'j' ignored"
+ !$omp parallel do collapse (3) lastprivate (conditional: j)
+ do i = 1, 32
+ do j = 1, 32
+ do k = 1, 32
+ end do
+ end do
+ end do
+ !$omp end parallel do
+
+ ! Error in eqiv. C code: "conditional 'lastprivate' on loop iterator 'k' ignored"
+ !$omp parallel do collapse (3) lastprivate (conditional: k)
+ do i = 1, 32
+ do j = 1, 32
+ do k = 1, 32
+ end do
+ end do
+ end do
+ !$omp end parallel do
+end subroutine
--- /dev/null
+module m
+integer x, w
+end module m
+
+subroutine foo
+ use m
+ interface
+ logical function bar(i)
+ integer i
+ end function
+ end interface
+ integer y, i, z
+ logical tmp
+ y = 5
+ !$omp teams num_teams(1) firstprivate (x) shared (y) shared (w)
+ !$omp parallel do firstprivate (x, y, z, w) lastprivate (conditional: x, y, z, w)
+ do i = 1, 64
+ if (bar (i)) then
+ x = i;
+ y = i + 1;
+ z = i + 2;
+ w = i + 3;
+ end if
+ tmp = bar (y);
+ tmp = bar (z);
+ end do
+ !$omp end teams
+end
--- /dev/null
+! { dg-do compile }
+! { dg-options "-O2 -fopenmp -fdump-tree-ompexp" }
+! { dg-final { scan-tree-dump-times "GOMP_loop_start " 3 "ompexp" } }
+! { dg-final { scan-tree-dump-times "GOMP_loop_end_nowait " 3 "ompexp" } }
+
+module m
+ logical r
+end module m
+
+subroutine foo (a)
+ use m
+ implicit none
+ logical a(:)
+ integer :: i
+ !$omp do lastprivate(conditional: r)
+ do i = 1, 64
+ if (a(i)) &
+ r = a(i)
+ end do
+ !$omp end do nowait
+end
+
+subroutine bar (a)
+ use m
+ implicit none
+ logical a(:)
+ integer :: i
+ !$omp do lastprivate(conditional: r) schedule (static, 4)
+ do i = 1, 64
+ if (a(i)) &
+ r = a(i)
+ end do
+ !$omp end do nowait
+end
+
+subroutine baz (a)
+ use m
+ implicit none
+ logical a(:)
+ integer :: i
+ !$omp do lastprivate(conditional: r) schedule (runtime)
+ do i = 1, 64
+ if (a(i)) &
+ r = a(i)
+ end do
+ !$omp end do nowait
+end