From ea3534b385a713639953fb5dfd287af87b52bead Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 24 Oct 2024 05:54:35 -0500 Subject: [PATCH] [flang][OpenMP] Parse AFFINITY clause, lowering not supported yet (#113485) Implement parsing of the AFFINITY clause on TASK construct, conversion from the parser class to omp::Clause. Lowering to HLFIR is unsupported, a TODO message is displayed. --- flang/include/flang/Parser/dump-parse-tree.h | 1 + flang/include/flang/Parser/parse-tree.h | 7 ++ flang/lib/Lower/OpenMP/Clauses.cpp | 11 ++- flang/lib/Lower/OpenMP/OpenMP.cpp | 3 +- flang/lib/Parser/openmp-parsers.cpp | 7 ++ flang/lib/Parser/unparse.cpp | 4 + .../Lower/OpenMP/Todo/affinity-clause.f90 | 10 +++ flang/test/Parser/OpenMP/affinity-clause.f90 | 79 +++++++++++++++++++ .../test/Semantics/OpenMP/affinity-clause.f90 | 9 +++ llvm/include/llvm/Frontend/OpenMP/OMP.td | 1 + 10 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 flang/test/Lower/OpenMP/Todo/affinity-clause.f90 create mode 100644 flang/test/Parser/OpenMP/affinity-clause.f90 create mode 100644 flang/test/Semantics/OpenMP/affinity-clause.f90 diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 040065c0cbc029..76d2f164fc4bf0 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -476,6 +476,7 @@ class ParseTreeDumper { NODE(parser, OldParameterStmt) NODE(parser, OmpIteratorSpecifier) NODE(parser, OmpIteratorModifier) + NODE(parser, OmpAffinityClause) NODE(parser, OmpAlignedClause) NODE(parser, OmpAtomic) NODE(parser, OmpAtomicCapture) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index f727525a759e64..c1884f6e88d1ec 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3458,6 +3458,13 @@ struct OmpReductionOperator { // --- Clauses +// OMP 5.0 2.10.1 affinity([aff-modifier:] locator-list) +// aff-modifier: interator-modifier +struct OmpAffinityClause { + TUPLE_CLASS_BOILERPLATE(OmpAffinityClause); + std::tuple, OmpObjectList> t; +}; + // 2.8.1 aligned-clause -> ALIGNED (variable-name-list[ : scalar-constant]) struct OmpAlignedClause { TUPLE_CLASS_BOILERPLATE(OmpAlignedClause); diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 8974b4211b9684..ee3d74a7c631af 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -352,8 +352,15 @@ Absent make(const parser::OmpClause::Absent &inp, Affinity make(const parser::OmpClause::Affinity &inp, semantics::SemanticsContext &semaCtx) { - // inp -> empty - llvm_unreachable("Empty: affinity"); + // inp.v -> parser::OmpAffinityClause + auto &t0 = std::get>(inp.v.t); + auto &t1 = std::get(inp.v.t); + + auto &&maybeIter = + maybeApply([&](auto &&s) { return makeIterator(s, semaCtx); }, t0); + + return Affinity{{/*Iterator=*/std::move(maybeIter), + /*LocatorList=*/makeObjects(t1, semaCtx)}}; } Align make(const parser::OmpClause::Align &inp, diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 52a077cd5a797a..fc54da8babe63e 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -2769,7 +2769,8 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, for (const Clause &clause : clauses) { mlir::Location clauseLocation = converter.genLocation(clause.source); - if (!std::holds_alternative(clause.u) && + if (!std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 4a1daed04f3e9d..59a8757e58e8cc 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -177,6 +177,11 @@ TYPE_PARSER(construct( TYPE_PARSER(construct("ITERATOR" >> parenthesized(nonemptyList(sourced(Parser{}))))) +// [5.0] 2.10.1 affinity([aff-modifier:] locator-list) +// aff-modifier: interator-modifier +TYPE_PARSER(construct( + maybe(Parser{} / ":"), Parser{})) + // 2.15.3.1 DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE) TYPE_PARSER(construct( "PRIVATE" >> pure(OmpDefaultClause::Type::Private) || @@ -415,6 +420,8 @@ TYPE_PARSER(construct( TYPE_PARSER( "ACQUIRE" >> construct(construct()) || "ACQ_REL" >> construct(construct()) || + "AFFINITY" >> construct(construct( + parenthesized(Parser{}))) || "ALIGNED" >> construct(construct( parenthesized(Parser{}))) || "ALLOCATE" >> construct(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 5870aba0132c88..04df988223e8f8 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2129,6 +2129,10 @@ class UnparseVisitor { Walk(std::get>(x.t), ":"); Walk(std::get(x.t)); } + void Unparse(const OmpAffinityClause &x) { + Walk(std::get>(x.t), ":"); + Walk(std::get(x.t)); + } void Unparse(const OmpAlignedClause &x) { Walk(std::get(x.t)); Put(","); diff --git a/flang/test/Lower/OpenMP/Todo/affinity-clause.f90 b/flang/test/Lower/OpenMP/Todo/affinity-clause.f90 new file mode 100644 index 00000000000000..3459dd219e4257 --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/affinity-clause.f90 @@ -0,0 +1,10 @@ +!RUN: %not_todo_cmd bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s +!RUN: %not_todo_cmd %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s + +!CHECK: not yet implemented: Unhandled clause AFFINITY in TASK construct +subroutine f00(x) + integer :: x(10) +!$omp task affinity(x) + x = x + 1 +!$omp end task +end diff --git a/flang/test/Parser/OpenMP/affinity-clause.f90 b/flang/test/Parser/OpenMP/affinity-clause.f90 new file mode 100644 index 00000000000000..804723cad7b2b3 --- /dev/null +++ b/flang/test/Parser/OpenMP/affinity-clause.f90 @@ -0,0 +1,79 @@ +!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=50 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s +!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=50 %s | FileCheck --check-prefix="PARSE-TREE" %s + +subroutine f00(x) + integer :: x(10) +!$omp task affinity(x) + x = x + 1 +!$omp end task +end + +!UNPARSE: SUBROUTINE f00 (x) +!UNPARSE: INTEGER x(10_4) +!UNPARSE: !$OMP TASK AFFINITY(x) +!UNPARSE: x=x+1_4 +!UNPARSE: !$OMP END TASK +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginBlockDirective +!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = task +!PARSE-TREE: | OmpClauseList -> OmpClause -> Affinity -> OmpAffinityClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' + +subroutine f01(x) + integer :: x(10) +!$omp task affinity(x(1), x(3)) + x = x + 1 +!$omp end task +end + +!UNPARSE: SUBROUTINE f01 (x) +!UNPARSE: INTEGER x(10_4) +!UNPARSE: !$OMP TASK AFFINITY(x(1_4),x(3_4)) +!UNPARSE: x=x+1_4 +!UNPARSE: !$OMP END TASK +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginBlockDirective +!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = task +!PARSE-TREE: | OmpClauseList -> OmpClause -> Affinity -> OmpAffinityClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> ArrayElement +!PARSE-TREE: | | | DataRef -> Name = 'x' +!PARSE-TREE: | | | SectionSubscript -> Integer -> Expr = '1_4' +!PARSE-TREE: | | | | LiteralConstant -> IntLiteralConstant = '1' +!PARSE-TREE: | | OmpObject -> Designator -> DataRef -> ArrayElement +!PARSE-TREE: | | | DataRef -> Name = 'x' +!PARSE-TREE: | | | SectionSubscript -> Integer -> Expr = '3_4' +!PARSE-TREE: | | | | LiteralConstant -> IntLiteralConstant = '3' + +subroutine f02(x) + integer :: x(10) +!$omp task affinity(iterator(i = 1:3): x(i)) + x = x + 1 +!$omp end task +end + +!UNPARSE: SUBROUTINE f02 (x) +!UNPARSE: INTEGER x(10_4) +!UNPARSE: !$OMP TASK AFFINITY(ITERATOR(INTEGER i = 1_4:3_4):x(i)) +!UNPARSE: x=x+1_4 +!UNPARSE: !$OMP END TASK +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginBlockDirective +!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = task +!PARSE-TREE: | OmpClauseList -> OmpClause -> Affinity -> OmpAffinityClause +!PARSE-TREE: | | OmpIteratorModifier -> OmpIteratorSpecifier +!PARSE-TREE: | | | TypeDeclarationStmt +!PARSE-TREE: | | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> +!PARSE-TREE: | | | | EntityDecl +!PARSE-TREE: | | | | | Name = 'i' +!PARSE-TREE: | | | SubscriptTriplet +!PARSE-TREE: | | | | Scalar -> Integer -> Expr = '1_4' +!PARSE-TREE: | | | | | LiteralConstant -> IntLiteralConstant = '1' +!PARSE-TREE: | | | | Scalar -> Integer -> Expr = '3_4' +!PARSE-TREE: | | | | | LiteralConstant -> IntLiteralConstant = '3' +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> ArrayElement +!PARSE-TREE: | | | DataRef -> Name = 'x' +!PARSE-TREE: | | | SectionSubscript -> Integer -> Expr = 'i' +!PARSE-TREE: | | | | Designator -> DataRef -> Name = 'i' diff --git a/flang/test/Semantics/OpenMP/affinity-clause.f90 b/flang/test/Semantics/OpenMP/affinity-clause.f90 new file mode 100644 index 00000000000000..53b2c4fc56677f --- /dev/null +++ b/flang/test/Semantics/OpenMP/affinity-clause.f90 @@ -0,0 +1,9 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=45 + +subroutine f00(x) + integer :: x(10) +!ERROR: AFFINITY clause is not allowed on directive TASK in OpenMP v4.5, try -fopenmp-version=50 +!$omp task affinity(x) + x = x + 1 +!$omp end task +end diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index f784c37cbe955d..1834ad4d037f3d 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -45,6 +45,7 @@ def OMPC_AdjustArgs : Clause<"adjust_args"> { } def OMPC_Affinity : Clause<"affinity"> { let clangClass = "OMPAffinityClause"; + let flangClass = "OmpAffinityClause"; } def OMPC_Align : Clause<"align"> { let clangClass = "OMPAlignClause";