Author: Irina Dobrescu Date: 2020-12-10T16:21:19Z New Revision: c9e967af3fc7ce824cd811379c5e99a998819779
URL: https://github.com/llvm/llvm-project/commit/c9e967af3fc7ce824cd811379c5e99a998819779 DIFF: https://github.com/llvm/llvm-project/commit/c9e967af3fc7ce824cd811379c5e99a998819779.diff LOG: [flang]Add Parser Support for Allocate Directive Differential Revision: https://reviews.llvm.org/D89562 Added: flang/test/Parser/omp-allocate-unparse.f90 flang/test/Semantics/omp-allocate-directive.f90 Modified: flang/include/flang/Parser/dump-parse-tree.h flang/include/flang/Parser/parse-tree.h flang/lib/Lower/OpenMP.cpp flang/lib/Parser/openmp-parsers.cpp flang/lib/Parser/type-parsers.h flang/lib/Parser/unparse.cpp flang/lib/Semantics/check-omp-structure.cpp flang/lib/Semantics/check-omp-structure.h llvm/include/llvm/Frontend/OpenMP/OMP.td Removed: ################################################################################ diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index c86c2ec6e66b..791e21fa4b62 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -545,6 +545,7 @@ class ParseTreeDumper { NODE(parser, OpenMPCancellationPointConstruct) NODE(parser, OpenMPConstruct) NODE(parser, OpenMPCriticalConstruct) + NODE(parser, OpenMPDeclarativeAllocate) NODE(parser, OpenMPDeclarativeConstruct) NODE(parser, OpenMPDeclareReductionConstruct) NODE(parser, OpenMPDeclareSimdConstruct) @@ -552,6 +553,7 @@ class ParseTreeDumper { NODE(parser, OmpMemoryOrderClause) NODE(parser, OpenMPFlushConstruct) NODE(parser, OpenMPLoopConstruct) + NODE(parser, OpenMPExecutableAllocate) NODE(parser, OpenMPSimpleStandaloneConstruct) NODE(parser, OpenMPStandaloneConstruct) NODE(parser, OpenMPSectionsConstruct) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 6bed37c2b871..ca73af210c15 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3583,11 +3583,19 @@ struct OpenMPThreadprivate { std::tuple<Verbatim, OmpObjectList> t; }; +// 2.11.3 allocate -> ALLOCATE (variable-name-list) [clause] +struct OpenMPDeclarativeAllocate { + TUPLE_CLASS_BOILERPLATE(OpenMPDeclarativeAllocate); + CharBlock source; + std::tuple<Verbatim, OmpObjectList, OmpClauseList> t; +}; + struct OpenMPDeclarativeConstruct { UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct); CharBlock source; - std::variant<OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct, - OpenMPDeclareTargetConstruct, OpenMPThreadprivate> + std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareReductionConstruct, + OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct, + OpenMPThreadprivate> u; }; @@ -3607,6 +3615,19 @@ struct OpenMPCriticalConstruct { std::tuple<OmpCriticalDirective, Block, OmpEndCriticalDirective> t; }; +// 2.11.3 allocate -> ALLOCATE [(variable-name-list)] [clause] +// [ALLOCATE (variable-name-list) [clause] [...]] +// allocate-statement +// clause -> allocator-clause +struct OpenMPExecutableAllocate { + TUPLE_CLASS_BOILERPLATE(OpenMPExecutableAllocate); + CharBlock source; + std::tuple<Verbatim, std::optional<OmpObjectList>, OmpClauseList, + std::optional<std::list<OpenMPDeclarativeAllocate>>, + Statement<AllocateStmt>> + t; +}; + // 2.17.7 atomic -> ATOMIC [clause[,]] atomic-clause [[,]clause] | // ATOMIC [clause] // clause -> memory-order-clause | HINT(hint-expression) @@ -3777,6 +3798,7 @@ struct OpenMPConstruct { UNION_CLASS_BOILERPLATE(OpenMPConstruct); std::variant<OpenMPStandaloneConstruct, OpenMPSectionsConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct, OpenMPAtomicConstruct, + OpenMPExecutableAllocate, OpenMPDeclarativeAllocate, OpenMPCriticalConstruct> u; }; diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 780aea9664fc..cfe4b0b86b67 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -256,6 +256,10 @@ void Fortran::lower::genOpenMPConstruct( [&](const Fortran::parser::OpenMPLoopConstruct &loopConstruct) { TODO(""); }, + [&](const Fortran::parser::OpenMPDeclarativeAllocate + &execAllocConstruct) { TODO(""); }, + [&](const Fortran::parser::OpenMPExecutableAllocate + &execAllocConstruct) { TODO(""); }, [&](const Fortran::parser::OpenMPBlockConstruct &blockConstruct) { genOMP(converter, eval, blockConstruct); }, diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index da10f9ffb0a8..69fc4f0e67ee 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -159,6 +159,8 @@ TYPE_PARSER( construct<OmpClause>(parenthesized(Parser<OmpAlignedClause>{})) || "ALLOCATE" >> construct<OmpClause>(parenthesized(Parser<OmpAllocateClause>{})) || + "ALLOCATOR" >> construct<OmpClause>(construct<OmpClause::Allocator>( + parenthesized(scalarIntExpr))) || "COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>( parenthesized(scalarIntConstantExpr))) || "COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>( @@ -454,6 +456,13 @@ TYPE_PARSER(sourced(construct<OmpCriticalDirective>(verbatim("CRITICAL"_tok), TYPE_PARSER(construct<OpenMPCriticalConstruct>( Parser<OmpCriticalDirective>{}, block, Parser<OmpEndCriticalDirective>{})) +// 2.11.3 Executable Allocate directive +TYPE_PARSER( + sourced(construct<OpenMPExecutableAllocate>(verbatim("ALLOCATE"_tok), + maybe(parenthesized(Parser<OmpObjectList>{})), Parser<OmpClauseList>{}, + maybe(nonemptyList(Parser<OpenMPDeclarativeAllocate>{})) / endOmpLine, + statement(allocateStmt)))) + // 2.8.2 Declare Simd construct TYPE_PARSER( sourced(construct<OpenMPDeclareSimdConstruct>(verbatim("DECLARE SIMD"_tok), @@ -463,6 +472,12 @@ TYPE_PARSER( TYPE_PARSER(sourced(construct<OpenMPThreadprivate>( verbatim("THREADPRIVATE"_tok), parenthesized(Parser<OmpObjectList>{})))) +// 2.11.3 Declarative Allocate directive +TYPE_PARSER( + sourced(construct<OpenMPDeclarativeAllocate>(verbatim("ALLOCATE"_tok), + parenthesized(Parser<OmpObjectList>{}), Parser<OmpClauseList>{})) / + lookAhead(endOmpLine / !statement(allocateStmt))) + // Declarative constructs TYPE_PARSER(startOmpLine >> sourced(construct<OpenMPDeclarativeConstruct>( @@ -471,6 +486,8 @@ TYPE_PARSER(startOmpLine >> Parser<OpenMPDeclareSimdConstruct>{}) || construct<OpenMPDeclarativeConstruct>( Parser<OpenMPDeclareTargetConstruct>{}) || + construct<OpenMPDeclarativeConstruct>( + Parser<OpenMPDeclarativeAllocate>{}) || construct<OpenMPDeclarativeConstruct>(Parser<OpenMPThreadprivate>{})) / endOmpLine) @@ -511,6 +528,8 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US, // OpenMPStandaloneConstruct to resolve !$OMP ORDERED construct<OpenMPConstruct>(Parser<OpenMPStandaloneConstruct>{}), construct<OpenMPConstruct>(Parser<OpenMPAtomicConstruct>{}), + construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}), + construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}), construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))) // END OMP Block directives diff --git a/flang/lib/Parser/type-parsers.h b/flang/lib/Parser/type-parsers.h index d6269cbdc715..b5f6e34d3a72 100644 --- a/flang/lib/Parser/type-parsers.h +++ b/flang/lib/Parser/type-parsers.h @@ -85,6 +85,7 @@ constexpr Parser<Variable> variable; // R902 constexpr Parser<Substring> substring; // R908 constexpr Parser<DataRef> dataRef; // R911, R914, R917 constexpr Parser<StructureComponent> structureComponent; // R913 +constexpr Parser<AllocateStmt> allocateStmt; // R927 constexpr Parser<StatVariable> statVariable; // R929 constexpr Parser<StatOrErrmsg> statOrErrmsg; // R942 & R1165 constexpr Parser<DefinedOpName> definedOpName; // R1003, R1023, R1414, & R1415 diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 56f09f97d98e..cf843ffb3c9d 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2287,6 +2287,25 @@ class UnparseVisitor { Walk(std::get<std::optional<OmpEndAtomic>>(x.t), "!$OMP END ATOMIC\n"); EndOpenMP(); } + void Unparse(const OpenMPExecutableAllocate &x) { + BeginOpenMP(); + Word("!$OMP ALLOCATE"); + Walk(" (", std::get<std::optional<OmpObjectList>>(x.t), ")"); + Walk(std::get<OmpClauseList>(x.t)); + Put("\n"); + EndOpenMP(); + Walk(std::get<Statement<AllocateStmt>>(x.t)); + } + void Unparse(const OpenMPDeclarativeAllocate &x) { + BeginOpenMP(); + Word("!$OMP ALLOCATE"); + Put(" ("); + Walk(std::get<OmpObjectList>(x.t)); + Put(")"); + Walk(std::get<OmpClauseList>(x.t)); + Put("\n"); + EndOpenMP(); + } void Unparse(const OmpCriticalDirective &x) { BeginOpenMP(); Word("!$OMP CRITICAL"); @@ -2339,6 +2358,15 @@ class UnparseVisitor { BeginOpenMP(); Word("!$OMP "); return std::visit(common::visitors{ + [&](const OpenMPDeclarativeAllocate &z) { + Word("ALLOCATE ("); + Walk(std::get<OmpObjectList>(z.t)); + Put(")"); + Walk(std::get<OmpClauseList>(z.t)); + Put("\n"); + EndOpenMP(); + return false; + }, [&](const OpenMPDeclareReductionConstruct &) { Word("DECLARE REDUCTION "); return true; diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 9ed73e65e57c..af76ca5a0a5a 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -179,6 +179,15 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) { dirContext_.pop_back(); } +void OmpStructureChecker::Enter(const parser::OpenMPDeclarativeAllocate &x) { + const auto &dir{std::get<parser::Verbatim>(x.t)}; + PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate); +} + +void OmpStructureChecker::Leave(const parser::OpenMPDeclarativeAllocate &) { + dirContext_.pop_back(); +} + void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) { const auto &dir{std::get<parser::Verbatim>(x.t)}; PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target); @@ -192,6 +201,15 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &) { dirContext_.pop_back(); } +void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &x) { + const auto &dir{std::get<parser::Verbatim>(x.t)}; + PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate); +} + +void OmpStructureChecker::Leave(const parser::OpenMPExecutableAllocate &) { + dirContext_.pop_back(); +} + void OmpStructureChecker::Enter( const parser::OpenMPSimpleStandaloneConstruct &x) { const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(x.t)}; @@ -382,6 +400,7 @@ CHECK_SIMPLE_CLAUSE(SeqCst, OMPC_seq_cst) CHECK_SIMPLE_CLAUSE(Release, OMPC_release) CHECK_SIMPLE_CLAUSE(Relaxed, OMPC_relaxed) +CHECK_REQ_SCALAR_INT_CLAUSE(Allocator, OMPC_allocator) CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize) CHECK_REQ_SCALAR_INT_CLAUSE(NumTasks, OMPC_num_tasks) CHECK_REQ_SCALAR_INT_CLAUSE(NumTeams, OMPC_num_teams) diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index bb1509b4bdfb..e2233a1094c9 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -104,8 +104,12 @@ class OmpStructureChecker void Enter(const parser::OpenMPDeclareSimdConstruct &); void Leave(const parser::OpenMPDeclareSimdConstruct &); + void Enter(const parser::OpenMPDeclarativeAllocate &); + void Leave(const parser::OpenMPDeclarativeAllocate &); void Enter(const parser::OpenMPDeclareTargetConstruct &); void Leave(const parser::OpenMPDeclareTargetConstruct &); + void Enter(const parser::OpenMPExecutableAllocate &); + void Leave(const parser::OpenMPExecutableAllocate &); void Enter(const parser::OpenMPSimpleStandaloneConstruct &); void Leave(const parser::OpenMPSimpleStandaloneConstruct &); @@ -121,6 +125,7 @@ class OmpStructureChecker void Leave(const parser::OmpClauseList &); void Enter(const parser::OmpClause &); void Enter(const parser::OmpNowait &); + void Enter(const parser::OmpClause::Allocator &); void Enter(const parser::OmpClause::Inbranch &); void Enter(const parser::OmpClause::Mergeable &); void Enter(const parser::OmpClause::Nogroup &); diff --git a/flang/test/Parser/omp-allocate-unparse.f90 b/flang/test/Parser/omp-allocate-unparse.f90 new file mode 100644 index 000000000000..3f517c1e2d04 --- /dev/null +++ b/flang/test/Parser/omp-allocate-unparse.f90 @@ -0,0 +1,44 @@ +! RUN: %f18 -fdebug-no-semantics -funparse -fopenmp %s | FileCheck %s +! Check Unparsing of OpenMP Allocate directive + +program allocate_unparse +use omp_lib + +real, dimension (:,:), allocatable :: darray +integer :: a, b, m, n, t, x, y, z + +! 2.11.3 declarative allocate + +!$omp allocate(x, y) +!$omp allocate(x, y) allocator(omp_default_mem_alloc) + +! 2.11.3 executable allocate + +!$omp allocate(a, b) + allocate ( darray(a, b) ) +!$omp allocate allocator(omp_default_mem_alloc) + allocate ( darray(a, b) ) +!$omp allocate(a, b) allocator(omp_default_mem_alloc) + allocate ( darray(a, b) ) + +!$omp allocate(t) allocator(omp_const_mem_alloc) +!$omp allocate(z) allocator(omp_default_mem_alloc) +!$omp allocate(m) allocator(omp_default_mem_alloc) +!$omp allocate(n) + allocate ( darray(z, t) ) + +end program allocate_unparse + +!CHECK:!$OMP ALLOCATE (x,y) +!CHECK:!$OMP ALLOCATE (x,y) ALLOCATOR(omp_default_mem_alloc) +!CHECK:!$OMP ALLOCATE (a,b) +!CHECK:ALLOCATE(darray(a,b)) +!CHECK:!$OMP ALLOCATE ALLOCATOR(omp_default_mem_alloc) +!CHECK:ALLOCATE(darray(a,b)) +!CHECK:!$OMP ALLOCATE (a,b) ALLOCATOR(omp_default_mem_alloc) +!CHECK:ALLOCATE(darray(a,b)) +!CHECK:!$OMP ALLOCATE (t) ALLOCATOR(omp_const_mem_alloc) +!CHECK:!$OMP ALLOCATE (z) ALLOCATOR(omp_default_mem_alloc) +!CHECK:!$OMP ALLOCATE (m) ALLOCATOR(omp_default_mem_alloc) +!CHECK:!$OMP ALLOCATE (n) +!CHECK:ALLOCATE(darray(z,t)) diff --git a/flang/test/Semantics/omp-allocate-directive.f90 b/flang/test/Semantics/omp-allocate-directive.f90 new file mode 100644 index 000000000000..62f85ce4ed1e --- /dev/null +++ b/flang/test/Semantics/omp-allocate-directive.f90 @@ -0,0 +1,25 @@ +! RUN: %S/test_errors.sh %s %t %f18 -fopenmp +! Check OpenMP Allocate directive +use omp_lib + +! 2.11.3 declarative allocate +! 2.11.3 executable allocate + +real, dimension (:,:), allocatable :: darray +integer :: a, b, x, y, m, n, t, z +!$omp allocate(x, y) +!$omp allocate(x, y) allocator(omp_default_mem_alloc) + +!$omp allocate(a, b) + allocate ( darray(a, b) ) + +!$omp allocate(a, b) allocator(omp_default_mem_alloc) + allocate ( darray(a, b) ) + +!$omp allocate(t) allocator(omp_const_mem_alloc) +!$omp allocate(z) allocator(omp_default_mem_alloc) +!$omp allocate(m) allocator(omp_default_mem_alloc) +!$omp allocate(n) + allocate ( darray(z, t) ) + +end diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index 3a93dd73edeb..6f16cfe730b7 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -34,6 +34,7 @@ def OpenMP : DirectiveLanguage { def OMPC_Allocator : Clause<"allocator"> { let clangClass = "OMPAllocatorClause"; + let flangClassValue = "ScalarIntExpr"; } def OMPC_If : Clause<"if"> { let clangClass = "OMPIfClause"; _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits