This patch creates the `OmpRewriteMutator` pass that runs at the end of `RewriteParseTree()`. This pass is intended to make OpenMP-specific mutations to the PFT after name resolution. In the case of the `atomic_default_mem_order` clause of the REQUIRES directive, name resolution results in populating global symbols with information about the REQUIRES clauses that apply to that scope. The new rewrite pass is then able to use this information in order to explicitly set the memory order of ATOMIC constructs for which that is not already specified. Given that this rewrite happens before semantics checks, the check of the order in which ATOMIC constructs without explicit memory order and REQUIRES directives with `atomic_default_mem_order` appear is moved earlier into the rewrite pass. Otherwise, these problems would not be caught by semantics checks, since the PFT would be modified by that stage. This is patch 4/5 of a series splitting D149337 to simplify review. Depends on D157983. Differential Revision: https://reviews.llvm.org/D158096
110 lines
3.7 KiB
Fortran
110 lines
3.7 KiB
Fortran
! RUN: %flang_fc1 -fopenmp -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s
|
|
! Ensure that requires atomic_default_mem_order is used to update atomic
|
|
! operations with no explicit memory order set. ACQ_REL clause tested here.
|
|
program requires
|
|
implicit none
|
|
!$omp requires atomic_default_mem_order(acq_rel)
|
|
integer :: i, j
|
|
|
|
! ----------------------------------------------------------------------------
|
|
! READ
|
|
! ----------------------------------------------------------------------------
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Acquire
|
|
!$omp atomic read
|
|
i = j
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead
|
|
! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Acquire
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
|
|
!$omp atomic relaxed read
|
|
i = j
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead
|
|
! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Acquire
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
|
|
!$omp atomic read relaxed
|
|
i = j
|
|
|
|
! ----------------------------------------------------------------------------
|
|
! WRITE
|
|
! ----------------------------------------------------------------------------
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Release
|
|
!$omp atomic write
|
|
i = j
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite
|
|
! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
|
|
!$omp atomic relaxed write
|
|
i = j
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite
|
|
! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
|
|
!$omp atomic write relaxed
|
|
i = j
|
|
|
|
! ----------------------------------------------------------------------------
|
|
! UPDATE
|
|
! ----------------------------------------------------------------------------
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Release
|
|
!$omp atomic update
|
|
i = i + j
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate
|
|
! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
|
|
!$omp atomic relaxed update
|
|
i = i + j
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate
|
|
! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
|
|
!$omp atomic update relaxed
|
|
i = i + j
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomic
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Release
|
|
!$omp atomic
|
|
i = i + j
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomic
|
|
! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
|
|
!$omp atomic relaxed
|
|
i = i + j
|
|
|
|
! ----------------------------------------------------------------------------
|
|
! CAPTURE
|
|
! ----------------------------------------------------------------------------
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> AcqRel
|
|
!$omp atomic capture
|
|
i = j
|
|
i = j
|
|
!$omp end atomic
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture
|
|
! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> AcqRel
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
|
|
!$omp atomic relaxed capture
|
|
i = j
|
|
i = j
|
|
!$omp end atomic
|
|
|
|
! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture
|
|
! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> AcqRel
|
|
! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
|
|
!$omp atomic capture relaxed
|
|
i = j
|
|
i = j
|
|
!$omp end atomic
|
|
end program requires
|