[FLANG][OpenMP]Add support for ALIGN clause on OMP ALLOCATE (#120791)
This is trivially additional support for the existing ALLOCATE directive, which allows an ALIGN clause. The ALLOCATE directive is currently not implemented, so this is just addding the necessary parser parts to allow the compiler to not say "Huh? I don't get this" [or "Expected OpenMP construct"] when it encounters the ALIGN clause. Some parser testing is updated and a new todo test, just in case the feature of align clause is not supported by the initial support for ALLOCATE.
This commit is contained in:
@@ -486,6 +486,7 @@ public:
|
||||
NODE(parser, OmpAffinityClause)
|
||||
NODE(OmpAffinityClause, Modifier)
|
||||
NODE(parser, OmpAlignment)
|
||||
NODE(parser, OmpAlignClause)
|
||||
NODE(parser, OmpAlignedClause)
|
||||
NODE(OmpAlignedClause, Modifier)
|
||||
NODE(parser, OmpAtClause)
|
||||
|
||||
@@ -3760,6 +3760,11 @@ struct OmpAffinityClause {
|
||||
std::tuple<MODIFIERS(), OmpObjectList> t;
|
||||
};
|
||||
|
||||
// Ref: 5.2: [174]
|
||||
struct OmpAlignClause {
|
||||
WRAPPER_CLASS_BOILERPLATE(OmpAlignClause, ScalarIntExpr);
|
||||
};
|
||||
|
||||
// Ref: [4.5:72-81], [5.0:110-119], [5.1:134-143], [5.2:169-170]
|
||||
//
|
||||
// aligned-clause ->
|
||||
|
||||
@@ -567,6 +567,8 @@ TYPE_PARSER(construct<OmpBindClause>(
|
||||
"TEAMS" >> pure(OmpBindClause::Binding::Teams) ||
|
||||
"THREAD" >> pure(OmpBindClause::Binding::Thread)))
|
||||
|
||||
TYPE_PARSER(construct<OmpAlignClause>(scalarIntExpr))
|
||||
|
||||
TYPE_PARSER(construct<OmpAtClause>(
|
||||
"EXECUTION" >> pure(OmpAtClause::ActionTime::Execution) ||
|
||||
"COMPILATION" >> pure(OmpAtClause::ActionTime::Compilation)))
|
||||
@@ -582,6 +584,8 @@ TYPE_PARSER(
|
||||
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
|
||||
"AFFINITY" >> construct<OmpClause>(construct<OmpClause::Affinity>(
|
||||
parenthesized(Parser<OmpAffinityClause>{}))) ||
|
||||
"ALIGN" >> construct<OmpClause>(construct<OmpClause::Align>(
|
||||
parenthesized(Parser<OmpAlignClause>{}))) ||
|
||||
"ALIGNED" >> construct<OmpClause>(construct<OmpClause::Aligned>(
|
||||
parenthesized(Parser<OmpAlignedClause>{}))) ||
|
||||
"ALLOCATE" >> construct<OmpClause>(construct<OmpClause::Allocate>(
|
||||
|
||||
@@ -1489,11 +1489,24 @@ void OmpStructureChecker::Leave(const parser::OpenMPRequiresConstruct &) {
|
||||
dirContext_.pop_back();
|
||||
}
|
||||
|
||||
void OmpStructureChecker::CheckAlignValue(const parser::OmpClause &clause) {
|
||||
if (auto *align{std::get_if<parser::OmpClause::Align>(&clause.u)}) {
|
||||
if (const auto &v{GetIntValue(align->v)}; !v || *v <= 0) {
|
||||
context_.Say(clause.source,
|
||||
"The alignment value should be a constant positive integer"_err_en_US);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OmpStructureChecker::Enter(const parser::OpenMPDeclarativeAllocate &x) {
|
||||
isPredefinedAllocator = true;
|
||||
const auto &dir{std::get<parser::Verbatim>(x.t)};
|
||||
const auto &objectList{std::get<parser::OmpObjectList>(x.t)};
|
||||
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate);
|
||||
const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
|
||||
for (const auto &clause : clauseList.v) {
|
||||
CheckAlignValue(clause);
|
||||
}
|
||||
CheckIsVarPartOfAnotherVar(dir.source, objectList);
|
||||
}
|
||||
|
||||
@@ -1720,6 +1733,10 @@ void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &x) {
|
||||
const auto &dir{std::get<parser::Verbatim>(x.t)};
|
||||
const auto &objectList{std::get<std::optional<parser::OmpObjectList>>(x.t)};
|
||||
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate);
|
||||
const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
|
||||
for (const auto &clause : clauseList.v) {
|
||||
CheckAlignValue(clause);
|
||||
}
|
||||
if (objectList) {
|
||||
CheckIsVarPartOfAnotherVar(dir.source, *objectList);
|
||||
}
|
||||
|
||||
@@ -264,6 +264,8 @@ private:
|
||||
void CheckAllowedRequiresClause(llvmOmpClause clause);
|
||||
bool deviceConstructFound_{false};
|
||||
|
||||
void CheckAlignValue(const parser::OmpClause &);
|
||||
|
||||
void EnterDirectiveNest(const int index) { directiveNest_[index]++; }
|
||||
void ExitDirectiveNest(const int index) { directiveNest_[index]--; }
|
||||
int GetDirectiveNest(const int index) { return directiveNest_[index]; }
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
! This test checks lowering of OpenMP allocate Directive with align clause.
|
||||
|
||||
// RUN: not flang -fc1 -emit-fir -fopenmp %s 2>&1 | FileCheck %s
|
||||
|
||||
program main
|
||||
integer :: x
|
||||
|
||||
// CHECK: not yet implemented: OpenMPDeclarativeAllocate
|
||||
!$omp allocate(x) align(32)
|
||||
end
|
||||
42
flang/test/Parser/OpenMP/allocate-align-tree.f90
Normal file
42
flang/test/Parser/OpenMP/allocate-align-tree.f90
Normal file
@@ -0,0 +1,42 @@
|
||||
! REQUIRES: openmp_runtime
|
||||
|
||||
! RUN: %flang_fc1 %openmp_flags -fopenmp-version=51 -fdebug-dump-parse-tree %s | FileCheck %s
|
||||
! RUN: %flang_fc1 %openmp_flags -fdebug-unparse -fopenmp-version=51 %s | FileCheck %s --check-prefix="UNPARSE"
|
||||
! Ensures associated declarative OMP allocations are nested in their
|
||||
! corresponding executable allocate directive
|
||||
|
||||
program allocate_align_tree
|
||||
use omp_lib
|
||||
integer, allocatable :: j(:), xarray(:)
|
||||
integer :: z, t
|
||||
t = 2
|
||||
z = 3
|
||||
!$omp allocate(j) align(16)
|
||||
!$omp allocate(xarray) align(32) allocator(omp_large_cap_mem_alloc)
|
||||
allocate(j(z), xarray(t))
|
||||
end program allocate_align_tree
|
||||
|
||||
!CHECK: | | DeclarationConstruct -> SpecificationConstruct -> TypeDeclarationStmt
|
||||
!CHECK-NEXT: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
|
||||
!CHECK-NEXT: | | | AttrSpec -> Allocatable
|
||||
!CHECK-NEXT: | | | EntityDecl
|
||||
!CHECK-NEXT: | | | | Name = 'j'
|
||||
|
||||
|
||||
!CHECK: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPExecutableAllocate
|
||||
!CHECK-NEXT: | | | Verbatim
|
||||
!CHECK-NEXT: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'xarray'
|
||||
!CHECK-NEXT: | | | OmpClauseList -> OmpClause -> Align -> OmpAlignClause -> Scalar -> Integer -> Expr = '32_4'
|
||||
!CHECK-NEXT: | | | | LiteralConstant -> IntLiteralConstant = '32'
|
||||
!CHECK-NEXT: | | | OmpClause -> Allocator -> Scalar -> Integer -> Expr = '2_8'
|
||||
!CHECK-NEXT: | | | | Designator -> DataRef -> Name = 'omp_large_cap_mem_alloc'
|
||||
!CHECK-NEXT: | | | OpenMPDeclarativeAllocate
|
||||
!CHECK-NEXT: | | | | Verbatim
|
||||
!CHECK-NEXT: | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'j'
|
||||
!CHECK-NEXT: | | | | OmpClauseList -> OmpClause -> Align -> OmpAlignClause -> Scalar -> Integer -> Expr = '16_4'
|
||||
!CHECK-NEXT: | | | | | LiteralConstant -> IntLiteralConstant = '16'
|
||||
!CHECK-NEXT: | | | AllocateStmt
|
||||
|
||||
!UNPARSE: !$OMP ALLOCATE (j) ALIGN(16_4)
|
||||
!UNPARSE: !$OMP ALLOCATE (xarray) ALIGN(32_4) ALLOCATOR(2_8)
|
||||
!UNPARSE-NEXT: ALLOCATE(j(z), xarray(t))
|
||||
@@ -5,7 +5,7 @@ program allocate_unparse
|
||||
use omp_lib
|
||||
|
||||
real, dimension (:,:), allocatable :: darray
|
||||
integer :: a, b, m, n, t, x, y, z
|
||||
integer :: a, b, j, m, n, t, x, y, z
|
||||
|
||||
! 2.11.3 declarative allocate
|
||||
|
||||
@@ -25,6 +25,7 @@ integer :: a, b, m, n, t, x, y, z
|
||||
!$omp allocate(z) allocator(omp_default_mem_alloc)
|
||||
!$omp allocate(m) allocator(omp_default_mem_alloc)
|
||||
!$omp allocate(n)
|
||||
!$omp allocate(j) align(16)
|
||||
allocate ( darray(z, t) )
|
||||
|
||||
end program allocate_unparse
|
||||
@@ -41,4 +42,5 @@ end program allocate_unparse
|
||||
!CHECK:!$OMP ALLOCATE (z) ALLOCATOR(omp_default_mem_alloc)
|
||||
!CHECK:!$OMP ALLOCATE (m) ALLOCATOR(omp_default_mem_alloc)
|
||||
!CHECK:!$OMP ALLOCATE (n)
|
||||
!CHECK:!$OMP ALLOCATE (j) ALIGN(16)
|
||||
!CHECK:ALLOCATE(darray(z,t))
|
||||
|
||||
20
flang/test/Semantics/OpenMP/allocate-align01.f90
Normal file
20
flang/test/Semantics/OpenMP/allocate-align01.f90
Normal file
@@ -0,0 +1,20 @@
|
||||
! REQUIRES: openmp_runtime
|
||||
|
||||
! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=51
|
||||
! OpenMP Version 5.2
|
||||
! The allocate clause's allocator modifier must be of type allocator_handle
|
||||
! and the align modifier must be constant, positive integer expression
|
||||
|
||||
program allocate_align_tree
|
||||
use omp_lib
|
||||
integer, allocatable :: j(:), xarray(:)
|
||||
integer :: z, t, xx
|
||||
t = 2
|
||||
z = 3
|
||||
!ERROR: The alignment value should be a constant positive integer
|
||||
!$omp allocate(j) align(xx)
|
||||
!ERROR: The alignment value should be a constant positive integer
|
||||
!$omp allocate(xarray) align(-32) allocator(omp_large_cap_mem_alloc)
|
||||
allocate(j(z), xarray(t))
|
||||
end program allocate_align_tree
|
||||
|
||||
@@ -49,6 +49,7 @@ def OMPC_Affinity : Clause<"affinity"> {
|
||||
}
|
||||
def OMPC_Align : Clause<"align"> {
|
||||
let clangClass = "OMPAlignClause";
|
||||
let flangClass = "OmpAlignClause";
|
||||
}
|
||||
def OMPC_Aligned : Clause<"aligned"> {
|
||||
let clangClass = "OMPAlignedClause";
|
||||
|
||||
Reference in New Issue
Block a user