Skip to content

Commit 4df366c

Browse files
[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.
1 parent 599c739 commit 4df366c

File tree

10 files changed

+105
-1
lines changed

10 files changed

+105
-1
lines changed

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ class ParseTreeDumper {
486486
NODE(parser, OmpAffinityClause)
487487
NODE(OmpAffinityClause, Modifier)
488488
NODE(parser, OmpAlignment)
489+
NODE(parser, OmpAlignClause)
489490
NODE(parser, OmpAlignedClause)
490491
NODE(OmpAlignedClause, Modifier)
491492
NODE(parser, OmpAtClause)

flang/include/flang/Parser/parse-tree.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3760,6 +3760,11 @@ struct OmpAffinityClause {
37603760
std::tuple<MODIFIERS(), OmpObjectList> t;
37613761
};
37623762

3763+
// Ref: 5.2: [174]
3764+
struct OmpAlignClause {
3765+
WRAPPER_CLASS_BOILERPLATE(OmpAlignClause, ScalarIntExpr);
3766+
};
3767+
37633768
// Ref: [4.5:72-81], [5.0:110-119], [5.1:134-143], [5.2:169-170]
37643769
//
37653770
// aligned-clause ->

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ TYPE_PARSER(construct<OmpBindClause>(
567567
"TEAMS" >> pure(OmpBindClause::Binding::Teams) ||
568568
"THREAD" >> pure(OmpBindClause::Binding::Thread)))
569569

570+
TYPE_PARSER(construct<OmpAlignClause>(scalarIntExpr))
571+
570572
TYPE_PARSER(construct<OmpAtClause>(
571573
"EXECUTION" >> pure(OmpAtClause::ActionTime::Execution) ||
572574
"COMPILATION" >> pure(OmpAtClause::ActionTime::Compilation)))
@@ -582,6 +584,8 @@ TYPE_PARSER(
582584
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
583585
"AFFINITY" >> construct<OmpClause>(construct<OmpClause::Affinity>(
584586
parenthesized(Parser<OmpAffinityClause>{}))) ||
587+
"ALIGN" >> construct<OmpClause>(construct<OmpClause::Align>(
588+
parenthesized(Parser<OmpAlignClause>{}))) ||
585589
"ALIGNED" >> construct<OmpClause>(construct<OmpClause::Aligned>(
586590
parenthesized(Parser<OmpAlignedClause>{}))) ||
587591
"ALLOCATE" >> construct<OmpClause>(construct<OmpClause::Allocate>(

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,11 +1489,24 @@ void OmpStructureChecker::Leave(const parser::OpenMPRequiresConstruct &) {
14891489
dirContext_.pop_back();
14901490
}
14911491

1492+
void OmpStructureChecker::CheckAlignValue(const parser::OmpClause &clause) {
1493+
if (auto *align{std::get_if<parser::OmpClause::Align>(&clause.u)}) {
1494+
if (const auto &v{GetIntValue(align->v)}; !v || *v <= 0) {
1495+
context_.Say(clause.source,
1496+
"The alignment value should be a constant positive integer"_err_en_US);
1497+
}
1498+
}
1499+
}
1500+
14921501
void OmpStructureChecker::Enter(const parser::OpenMPDeclarativeAllocate &x) {
14931502
isPredefinedAllocator = true;
14941503
const auto &dir{std::get<parser::Verbatim>(x.t)};
14951504
const auto &objectList{std::get<parser::OmpObjectList>(x.t)};
14961505
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate);
1506+
const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
1507+
for (const auto &clause : clauseList.v) {
1508+
CheckAlignValue(clause);
1509+
}
14971510
CheckIsVarPartOfAnotherVar(dir.source, objectList);
14981511
}
14991512

@@ -1720,6 +1733,10 @@ void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &x) {
17201733
const auto &dir{std::get<parser::Verbatim>(x.t)};
17211734
const auto &objectList{std::get<std::optional<parser::OmpObjectList>>(x.t)};
17221735
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate);
1736+
const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
1737+
for (const auto &clause : clauseList.v) {
1738+
CheckAlignValue(clause);
1739+
}
17231740
if (objectList) {
17241741
CheckIsVarPartOfAnotherVar(dir.source, *objectList);
17251742
}

flang/lib/Semantics/check-omp-structure.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ class OmpStructureChecker
264264
void CheckAllowedRequiresClause(llvmOmpClause clause);
265265
bool deviceConstructFound_{false};
266266

267+
void CheckAlignValue(const parser::OmpClause &);
268+
267269
void EnterDirectiveNest(const int index) { directiveNest_[index]++; }
268270
void ExitDirectiveNest(const int index) { directiveNest_[index]--; }
269271
int GetDirectiveNest(const int index) { return directiveNest_[index]; }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
! This test checks lowering of OpenMP allocate Directive with align clause.
2+
3+
// RUN: not flang -fc1 -emit-fir -fopenmp %s 2>&1 | FileCheck %s
4+
5+
program main
6+
integer :: x
7+
8+
// CHECK: not yet implemented: OpenMPDeclarativeAllocate
9+
!$omp allocate(x) align(32)
10+
end
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
! REQUIRES: openmp_runtime
2+
3+
! RUN: %flang_fc1 %openmp_flags -fopenmp-version=51 -fdebug-dump-parse-tree %s | FileCheck %s
4+
! RUN: %flang_fc1 %openmp_flags -fdebug-unparse -fopenmp-version=51 %s | FileCheck %s --check-prefix="UNPARSE"
5+
! Ensures associated declarative OMP allocations are nested in their
6+
! corresponding executable allocate directive
7+
8+
program allocate_align_tree
9+
use omp_lib
10+
integer, allocatable :: j(:), xarray(:)
11+
integer :: z, t
12+
t = 2
13+
z = 3
14+
!$omp allocate(j) align(16)
15+
!$omp allocate(xarray) align(32) allocator(omp_large_cap_mem_alloc)
16+
allocate(j(z), xarray(t))
17+
end program allocate_align_tree
18+
19+
!CHECK: | | DeclarationConstruct -> SpecificationConstruct -> TypeDeclarationStmt
20+
!CHECK-NEXT: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
21+
!CHECK-NEXT: | | | AttrSpec -> Allocatable
22+
!CHECK-NEXT: | | | EntityDecl
23+
!CHECK-NEXT: | | | | Name = 'j'
24+
25+
26+
!CHECK: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPExecutableAllocate
27+
!CHECK-NEXT: | | | Verbatim
28+
!CHECK-NEXT: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'xarray'
29+
!CHECK-NEXT: | | | OmpClauseList -> OmpClause -> Align -> OmpAlignClause -> Scalar -> Integer -> Expr = '32_4'
30+
!CHECK-NEXT: | | | | LiteralConstant -> IntLiteralConstant = '32'
31+
!CHECK-NEXT: | | | OmpClause -> Allocator -> Scalar -> Integer -> Expr = '2_8'
32+
!CHECK-NEXT: | | | | Designator -> DataRef -> Name = 'omp_large_cap_mem_alloc'
33+
!CHECK-NEXT: | | | OpenMPDeclarativeAllocate
34+
!CHECK-NEXT: | | | | Verbatim
35+
!CHECK-NEXT: | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'j'
36+
!CHECK-NEXT: | | | | OmpClauseList -> OmpClause -> Align -> OmpAlignClause -> Scalar -> Integer -> Expr = '16_4'
37+
!CHECK-NEXT: | | | | | LiteralConstant -> IntLiteralConstant = '16'
38+
!CHECK-NEXT: | | | AllocateStmt
39+
40+
!UNPARSE: !$OMP ALLOCATE (j) ALIGN(16_4)
41+
!UNPARSE: !$OMP ALLOCATE (xarray) ALIGN(32_4) ALLOCATOR(2_8)
42+
!UNPARSE-NEXT: ALLOCATE(j(z), xarray(t))

flang/test/Parser/OpenMP/allocate-unparse.f90

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ program allocate_unparse
55
use omp_lib
66

77
real, dimension (:,:), allocatable :: darray
8-
integer :: a, b, m, n, t, x, y, z
8+
integer :: a, b, j, m, n, t, x, y, z
99

1010
! 2.11.3 declarative allocate
1111

@@ -25,6 +25,7 @@ program allocate_unparse
2525
!$omp allocate(z) allocator(omp_default_mem_alloc)
2626
!$omp allocate(m) allocator(omp_default_mem_alloc)
2727
!$omp allocate(n)
28+
!$omp allocate(j) align(16)
2829
allocate ( darray(z, t) )
2930

3031
end program allocate_unparse
@@ -41,4 +42,5 @@ end program allocate_unparse
4142
!CHECK:!$OMP ALLOCATE (z) ALLOCATOR(omp_default_mem_alloc)
4243
!CHECK:!$OMP ALLOCATE (m) ALLOCATOR(omp_default_mem_alloc)
4344
!CHECK:!$OMP ALLOCATE (n)
45+
!CHECK:!$OMP ALLOCATE (j) ALIGN(16)
4446
!CHECK:ALLOCATE(darray(z,t))
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
! REQUIRES: openmp_runtime
2+
3+
! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=51
4+
! OpenMP Version 5.2
5+
! The allocate clause's allocator modifier must be of type allocator_handle
6+
! and the align modifier must be constant, positive integer expression
7+
8+
program allocate_align_tree
9+
use omp_lib
10+
integer, allocatable :: j(:), xarray(:)
11+
integer :: z, t, xx
12+
t = 2
13+
z = 3
14+
!ERROR: The alignment value should be a constant positive integer
15+
!$omp allocate(j) align(xx)
16+
!ERROR: The alignment value should be a constant positive integer
17+
!$omp allocate(xarray) align(-32) allocator(omp_large_cap_mem_alloc)
18+
allocate(j(z), xarray(t))
19+
end program allocate_align_tree
20+

llvm/include/llvm/Frontend/OpenMP/OMP.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def OMPC_Affinity : Clause<"affinity"> {
4949
}
5050
def OMPC_Align : Clause<"align"> {
5151
let clangClass = "OMPAlignClause";
52+
let flangClass = "OmpAlignClause";
5253
}
5354
def OMPC_Aligned : Clause<"aligned"> {
5455
let clangClass = "OMPAlignedClause";

0 commit comments

Comments
 (0)