[llvm-branch-commits] [flang] [flang][OpenMP] Make object identity more precise (PR #94495)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/94495 Derived type components may use a given `Symbol` regardless of what parent objects they are a part of. Because of that, simply using a symbol address is not sufficient to determine object identity. Make the designator a part of the IdTy. To compare identities, when symbols are equal (and non-null), compare the designators. >From 1c266fa056044e2baa6cd4262fdf9a4cd74fd14d Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 5 Jun 2024 10:09:09 -0500 Subject: [PATCH] [flang][OpenMP] Make object identity more precise Derived type components may use a given `Symbol` regardless of what parent objects they are a part of. Because of that, simply using a symbol address is not sufficient to determine object identity. Make the designator a part of the IdTy. To compare identities, when symbols are equal (and non-null), compare the designators. --- flang/lib/Lower/OpenMP/Clauses.h | 50 --- flang/lib/Lower/OpenMP/Utils.cpp | 2 +- flang/test/Lower/OpenMP/map-component-ref.f90 | 41 +++ 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h index f7cd0ea83ad12..98fb5dcf7722e 100644 --- a/flang/lib/Lower/OpenMP/Clauses.h +++ b/flang/lib/Lower/OpenMP/Clauses.h @@ -36,30 +36,64 @@ struct TypeTy : public evaluate::SomeType { bool operator==(const TypeTy &t) const { return true; } }; -using IdTy = semantics::Symbol *; +template +struct IdTyTemplate { + // "symbol" is always non-null for id's of actual objects. + Fortran::semantics::Symbol *symbol; + std::optional designator; + + bool operator==(const IdTyTemplate &other) const { +// If symbols are different, then the objects are different. +if (symbol != other.symbol) + return false; +if (symbol == nullptr) + return true; +// Equal symbols don't necessarily indicate identical objects, +// for example, a derived object component may use a single symbol, +// which will refer to different objects for different designators, +// e.g. a%c and b%c. +return designator == other.designator; + } + + operator bool() const { return symbol != nullptr; } +}; + using ExprTy = SomeExpr; template using List = tomp::ListT; } // namespace Fortran::lower::omp +// Specialization of the ObjectT template namespace tomp::type { template <> -struct ObjectT { - using IdTy = Fortran::lower::omp::IdTy; +struct ObjectT, + Fortran::lower::omp::ExprTy> { + using IdTy = Fortran::lower::omp::IdTyTemplate; using ExprTy = Fortran::lower::omp::ExprTy; - IdTy id() const { return symbol; } - Fortran::semantics::Symbol *sym() const { return symbol; } - const std::optional &ref() const { return designator; } + IdTy id() const { return identity; } + Fortran::semantics::Symbol *sym() const { return identity.symbol; } + const std::optional &ref() const { return identity.designator; } - IdTy symbol; - std::optional designator; + IdTy identity; }; } // namespace tomp::type namespace Fortran::lower::omp { +using IdTy = IdTyTemplate; +} +namespace std { +template <> +struct hash { + size_t operator()(const Fortran::lower::omp::IdTy &id) const { +return static_cast(reinterpret_cast(id.symbol)); + } +}; +} // namespace std + +namespace Fortran::lower::omp { using Object = tomp::ObjectT; using ObjectList = tomp::ObjectListT; diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp index eff915f569f27..da94352a84a7c 100644 --- a/flang/lib/Lower/OpenMP/Utils.cpp +++ b/flang/lib/Lower/OpenMP/Utils.cpp @@ -188,7 +188,7 @@ void addChildIndexAndMapToParent( std::map> &parentMemberIndices, mlir::omp::MapInfoOp &mapOp, semantics::SemanticsContext &semaCtx) { - std::optional dataRef = ExtractDataRef(object.designator); + std::optional dataRef = ExtractDataRef(object.ref()); assert(dataRef.has_value() && "DataRef could not be extracted during mapping of derived type " "cannot proceed"); diff --git a/flang/test/Lower/OpenMP/map-component-ref.f90 b/flang/test/Lower/OpenMP/map-component-ref.f90 index 2c582667f38d3..21b56ab303acd 100644 --- a/flang/test/Lower/OpenMP/map-component-ref.f90 +++ b/flang/test/Lower/OpenMP/map-component-ref.f90 @@ -1,21 +1,22 @@ ! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s ! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s -! CHECK: %[[V0:[0-9]+]] = fir.alloca !fir.type<_QFfooTt0{a0:i32,a1:i32}> {bindc_name = "a", uniq_name = "_QFfooEa"} -! CHECK: %[[V1:[0-9]+]]:2 = hlfir.declare %[[V0]] {uniq_name = "_QFfooEa"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[V2:[0-9]+]] = hlfir.designate %[[V1]]#0{"a1"} : (!fir.ref>) -> !fir.ref +! CHECK-LABEL: func.func @_QPfoo1 +! CHECK: %[[V0:[0-9]+]] = fir.alloca !fir.type<_QFfoo1Tt0{a0:i32,a1:i32}> {bindc_name = "a", uniq_name = "
[llvm-branch-commits] [llvm] [Frontend] Introduce `getDirectiveCategory` for ACC/OMP directives (PR #94689)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/94689 The categories are primarily meant for OpenMP, where the spec assigns a category to each directive. It's one of declarative, executable, informational, meta, subsidiary, and utility. These will be used in clang to avoid listing directives belonging to certain categories by hand. >From 64fcf25e2158de44bccf725a0f91d8228b7cb7a5 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 6 Jun 2024 15:10:13 -0500 Subject: [PATCH] [Frontend] Introduce `getDirectiveCategory` for ACC/OMP directives The categories are primarily meant for OpenMP, where the spec assigns a category to each directive. It's one of declarative, executable, informational, meta, subsidiary, and utility. These will be used in clang to avoid listing directives belonging to certain categories by hand. --- .../llvm/Frontend/Directive/DirectiveBase.td | 15 +++ llvm/include/llvm/Frontend/OpenACC/ACC.td | 21 llvm/include/llvm/Frontend/OpenMP/OMP.td | 109 ++ llvm/include/llvm/TableGen/DirectiveEmitter.h | 6 + llvm/test/TableGen/directive1.td | 23 +++- llvm/test/TableGen/directive2.td | 23 +++- llvm/utils/TableGen/DirectiveEmitter.cpp | 31 - 7 files changed, 225 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td index ce532e0cfae29..6889c7e642ec6 100644 --- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td +++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td @@ -156,6 +156,18 @@ def AS_FromLeaves : Association<"FromLeaves"> {}// See below // The name "AS_FromLeaves" is recognized by TableGen, and there is no enum // generated for it. +// Kinds of directive categories. +class Category { + string name = n; // Name of the enum value in enum class Category. +} + +def CA_Declarative: Category<"Declarative"> {} +def CA_Executable: Category<"Executable"> {} +def CA_Informational: Category<"Informational"> {} +def CA_Meta: Category<"Meta"> {} +def CA_Subsidiary: Category<"Subsidiary"> {} +def CA_Utility: Category<"Utility"> {} + // Information about a specific directive. class Directive { // Name of the directive. Can be composite directive sepearted by whitespace. @@ -190,4 +202,7 @@ class Directive { // What the directive is associated with. Association association = AS_FromLeaves; + + // The category if the directive. + Category category = ?; } diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td index dfa6a222e9f77..30a81efe7f8a6 100644 --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -268,6 +268,7 @@ def ACCC_Unknown : Clause<"unknown"> { // 2.12 def ACC_Atomic : Directive<"atomic"> { let association = AS_Block; + let category = CA_Executable; } // 2.6.5 @@ -293,6 +294,7 @@ def ACC_Data : Directive<"data"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.13 @@ -308,6 +310,7 @@ def ACC_Declare : Directive<"declare"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.5.3 @@ -334,6 +337,7 @@ def ACC_Kernels : Directive<"kernels"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.5.1 @@ -363,6 +367,7 @@ def ACC_Parallel : Directive<"parallel"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.5.2 @@ -391,6 +396,7 @@ def ACC_Serial : Directive<"serial"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.9 @@ -411,11 +417,13 @@ def ACC_Loop : Directive<"loop"> { VersionedClause ]; let association = AS_Loop; + let category = CA_Executable; } // 2.10 def ACC_Cache : Directive<"cache"> { let association = AS_None; + let category = CA_Executable; } // 2.14.1 @@ -426,6 +434,7 @@ def ACC_Init : Directive<"init"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.15.1 @@ -442,6 +451,7 @@ def ACC_Routine : Directive<"routine"> { VersionedClause ]; let association = AS_Declaration; + let category = CA_Declarative; } // 2.14.3 @@ -461,6 +471,7 @@ def ACC_Set : Directive<"set"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.2 @@ -471,6 +482,7 @@ def ACC_Shutdown : Directive<"shutdown"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.4 @@ -490,6 +502,7 @@ def ACC_Update : Directive<"update"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.16.3 @@ -499,6 +512,7 @@ def ACC_Wait : Directive<"wait"> { VersionedClause ];
[llvm-branch-commits] [clang] [clang][OpenMP] Shorten directive classification in ParseOpenMP (PR #94691)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/94691 Use directive categories to simplify long lists of `case` statements in the OpenMP parser. This is a step towards avoiding dependence on explicitly specified sets of directives that can be expressed more generically. The upcoming OpenMP 6.0 will introduce many new combined directives, and the more generically we handle directives, the easier the introduction of the new standard will be. >From 950ad6a14687f5eab41bf8cc8ed64d07d8ad0a3d Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 6 Jun 2024 15:52:31 -0500 Subject: [PATCH] [clang][OpenMP] Shorten directive classification in ParseOpenMP Use directive categories to simplify long lists of `case` statements in the OpenMP parser. This is a step towards avoiding dependence on explicitly specified sets of directives that can be expressed more generically. The upcoming OpenMP 6.0 will introduce many new combined directives, and the more generically we handle directives, the easier the introduction of the new standard will be. --- clang/include/clang/Parse/Parser.h | 13 + clang/lib/Parse/ParseOpenMP.cpp| 526 - 2 files changed, 230 insertions(+), 309 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index d054b8cf0d240..88571a4a46f2c 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3509,6 +3509,19 @@ class Parser : public CodeCompletionHandler { /// metadirective and therefore ends on the closing paren. StmtResult ParseOpenMPDeclarativeOrExecutableDirective( ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective = false); + + /// Parses executable directive. + /// + /// \param StmtCtx The context in which we're parsing the directive. + /// \param DKind The kind of the executable directive. + /// \param Loc Source location of the beginning of the directive. + /// \param ReadDirectiveWithinMetadirective true if directive is within a + /// metadirective and therefore ends on the closing paren. + StmtResult + ParseOpenMPExecutableDirective(ParsedStmtContext StmtCtx, + OpenMPDirectiveKind DKind, SourceLocation Loc, + bool ReadDirectiveWithinMetadirective); + /// Parses clause of kind \a CKind for directive of a kind \a Kind. /// /// \param DKind Kind of current directive. diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 50a872fedebf7..a10bb009ec835 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -2374,86 +2374,209 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_unknown: Diag(Tok, diag::err_omp_unknown_directive); break; - case OMPD_parallel: - case OMPD_simd: - case OMPD_tile: - case OMPD_unroll: - case OMPD_task: - case OMPD_taskyield: + default: +switch (getDirectiveCategory(DKind)) { +case Category::Executable: +case Category::Meta: +case Category::Subsidiary: +case Category::Utility: + Diag(Tok, diag::err_omp_unexpected_directive) + << 1 << getOpenMPDirectiveName(DKind); + break; +default: + break; +} + } + while (Tok.isNot(tok::annot_pragma_openmp_end)) +ConsumeAnyToken(); + ConsumeAnyToken(); + return nullptr; +} + +StmtResult +Parser::ParseOpenMPExecutableDirective(ParsedStmtContext StmtCtx, + OpenMPDirectiveKind DKind, + SourceLocation Loc, + bool ReadDirectiveWithinMetadirective) { + bool HasAssociatedStatement = true; + + switch (DKind) { case OMPD_barrier: - case OMPD_taskwait: - case OMPD_taskgroup: - case OMPD_flush: + case OMPD_cancel: + case OMPD_cancellation_point: case OMPD_depobj: + case OMPD_error: + case OMPD_flush: + case OMPD_interop: case OMPD_scan: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_section: - case OMPD_single: - case OMPD_master: - case OMPD_ordered: - case OMPD_critical: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_parallel_sections: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_atomic: - case OMPD_target: - case OMPD_teams: - case OMPD_cancellation_point: - case OMPD_cancel: - case OMPD_target_data: case OMPD_target_enter_data: case OMPD_target_exit_data: - case OMPD_target_parallel: - case OMPD_target_parallel_for: - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_master_taskloop_simd: - case OMPD_masked_taskloop: - case OMPD_masked_taskloop_simd: - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_distr
[llvm-branch-commits] [llvm] [Frontend] Introduce `getDirectiveCategory` for ACC/OMP directives (PR #94689)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/94689 >From 64fcf25e2158de44bccf725a0f91d8228b7cb7a5 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 6 Jun 2024 15:10:13 -0500 Subject: [PATCH 1/2] [Frontend] Introduce `getDirectiveCategory` for ACC/OMP directives The categories are primarily meant for OpenMP, where the spec assigns a category to each directive. It's one of declarative, executable, informational, meta, subsidiary, and utility. These will be used in clang to avoid listing directives belonging to certain categories by hand. --- .../llvm/Frontend/Directive/DirectiveBase.td | 15 +++ llvm/include/llvm/Frontend/OpenACC/ACC.td | 21 llvm/include/llvm/Frontend/OpenMP/OMP.td | 109 ++ llvm/include/llvm/TableGen/DirectiveEmitter.h | 6 + llvm/test/TableGen/directive1.td | 23 +++- llvm/test/TableGen/directive2.td | 23 +++- llvm/utils/TableGen/DirectiveEmitter.cpp | 31 - 7 files changed, 225 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td index ce532e0cfae29..6889c7e642ec6 100644 --- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td +++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td @@ -156,6 +156,18 @@ def AS_FromLeaves : Association<"FromLeaves"> {}// See below // The name "AS_FromLeaves" is recognized by TableGen, and there is no enum // generated for it. +// Kinds of directive categories. +class Category { + string name = n; // Name of the enum value in enum class Category. +} + +def CA_Declarative: Category<"Declarative"> {} +def CA_Executable: Category<"Executable"> {} +def CA_Informational: Category<"Informational"> {} +def CA_Meta: Category<"Meta"> {} +def CA_Subsidiary: Category<"Subsidiary"> {} +def CA_Utility: Category<"Utility"> {} + // Information about a specific directive. class Directive { // Name of the directive. Can be composite directive sepearted by whitespace. @@ -190,4 +202,7 @@ class Directive { // What the directive is associated with. Association association = AS_FromLeaves; + + // The category if the directive. + Category category = ?; } diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td index dfa6a222e9f77..30a81efe7f8a6 100644 --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -268,6 +268,7 @@ def ACCC_Unknown : Clause<"unknown"> { // 2.12 def ACC_Atomic : Directive<"atomic"> { let association = AS_Block; + let category = CA_Executable; } // 2.6.5 @@ -293,6 +294,7 @@ def ACC_Data : Directive<"data"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.13 @@ -308,6 +310,7 @@ def ACC_Declare : Directive<"declare"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.5.3 @@ -334,6 +337,7 @@ def ACC_Kernels : Directive<"kernels"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.5.1 @@ -363,6 +367,7 @@ def ACC_Parallel : Directive<"parallel"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.5.2 @@ -391,6 +396,7 @@ def ACC_Serial : Directive<"serial"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.9 @@ -411,11 +417,13 @@ def ACC_Loop : Directive<"loop"> { VersionedClause ]; let association = AS_Loop; + let category = CA_Executable; } // 2.10 def ACC_Cache : Directive<"cache"> { let association = AS_None; + let category = CA_Executable; } // 2.14.1 @@ -426,6 +434,7 @@ def ACC_Init : Directive<"init"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.15.1 @@ -442,6 +451,7 @@ def ACC_Routine : Directive<"routine"> { VersionedClause ]; let association = AS_Declaration; + let category = CA_Declarative; } // 2.14.3 @@ -461,6 +471,7 @@ def ACC_Set : Directive<"set"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.2 @@ -471,6 +482,7 @@ def ACC_Shutdown : Directive<"shutdown"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.4 @@ -490,6 +502,7 @@ def ACC_Update : Directive<"update"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.16.3 @@ -499,6 +512,7 @@ def ACC_Wait : Directive<"wait"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.6 @@ -516,6 +530,7 @@ def ACC_EnterData : Directive<"enter data"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.7 @@ -534,6 +549,7 @@ def ACC_E
[llvm-branch-commits] [llvm] [Frontend] Introduce `getDirectiveCategory` for ACC/OMP directives (PR #94689)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/94689 >From 64fcf25e2158de44bccf725a0f91d8228b7cb7a5 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 6 Jun 2024 15:10:13 -0500 Subject: [PATCH 1/3] [Frontend] Introduce `getDirectiveCategory` for ACC/OMP directives The categories are primarily meant for OpenMP, where the spec assigns a category to each directive. It's one of declarative, executable, informational, meta, subsidiary, and utility. These will be used in clang to avoid listing directives belonging to certain categories by hand. --- .../llvm/Frontend/Directive/DirectiveBase.td | 15 +++ llvm/include/llvm/Frontend/OpenACC/ACC.td | 21 llvm/include/llvm/Frontend/OpenMP/OMP.td | 109 ++ llvm/include/llvm/TableGen/DirectiveEmitter.h | 6 + llvm/test/TableGen/directive1.td | 23 +++- llvm/test/TableGen/directive2.td | 23 +++- llvm/utils/TableGen/DirectiveEmitter.cpp | 31 - 7 files changed, 225 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td index ce532e0cfae29..6889c7e642ec6 100644 --- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td +++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td @@ -156,6 +156,18 @@ def AS_FromLeaves : Association<"FromLeaves"> {}// See below // The name "AS_FromLeaves" is recognized by TableGen, and there is no enum // generated for it. +// Kinds of directive categories. +class Category { + string name = n; // Name of the enum value in enum class Category. +} + +def CA_Declarative: Category<"Declarative"> {} +def CA_Executable: Category<"Executable"> {} +def CA_Informational: Category<"Informational"> {} +def CA_Meta: Category<"Meta"> {} +def CA_Subsidiary: Category<"Subsidiary"> {} +def CA_Utility: Category<"Utility"> {} + // Information about a specific directive. class Directive { // Name of the directive. Can be composite directive sepearted by whitespace. @@ -190,4 +202,7 @@ class Directive { // What the directive is associated with. Association association = AS_FromLeaves; + + // The category if the directive. + Category category = ?; } diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td index dfa6a222e9f77..30a81efe7f8a6 100644 --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -268,6 +268,7 @@ def ACCC_Unknown : Clause<"unknown"> { // 2.12 def ACC_Atomic : Directive<"atomic"> { let association = AS_Block; + let category = CA_Executable; } // 2.6.5 @@ -293,6 +294,7 @@ def ACC_Data : Directive<"data"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.13 @@ -308,6 +310,7 @@ def ACC_Declare : Directive<"declare"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.5.3 @@ -334,6 +337,7 @@ def ACC_Kernels : Directive<"kernels"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.5.1 @@ -363,6 +367,7 @@ def ACC_Parallel : Directive<"parallel"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.5.2 @@ -391,6 +396,7 @@ def ACC_Serial : Directive<"serial"> { VersionedClause ]; let association = AS_Block; + let category = CA_Executable; } // 2.9 @@ -411,11 +417,13 @@ def ACC_Loop : Directive<"loop"> { VersionedClause ]; let association = AS_Loop; + let category = CA_Executable; } // 2.10 def ACC_Cache : Directive<"cache"> { let association = AS_None; + let category = CA_Executable; } // 2.14.1 @@ -426,6 +434,7 @@ def ACC_Init : Directive<"init"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.15.1 @@ -442,6 +451,7 @@ def ACC_Routine : Directive<"routine"> { VersionedClause ]; let association = AS_Declaration; + let category = CA_Declarative; } // 2.14.3 @@ -461,6 +471,7 @@ def ACC_Set : Directive<"set"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.2 @@ -471,6 +482,7 @@ def ACC_Shutdown : Directive<"shutdown"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.4 @@ -490,6 +502,7 @@ def ACC_Update : Directive<"update"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.16.3 @@ -499,6 +512,7 @@ def ACC_Wait : Directive<"wait"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.6 @@ -516,6 +530,7 @@ def ACC_EnterData : Directive<"enter data"> { VersionedClause ]; let association = AS_None; + let category = CA_Executable; } // 2.14.7 @@ -534,6 +549,7 @@ def ACC_E
[llvm-branch-commits] [clang] [clang][OpenMP] Implement `isOpenMPCapturingDirective` (PR #97090)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/97090 Check if the given directive can capture variables, and thus needs a captured statement. Simplify some code using this function. >From 0ee7c0154dee86e25c05f09828637eaf9bb8ec27 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 28 Jun 2024 12:31:35 -0500 Subject: [PATCH] [clang][OpenMP] Implement `isOpenMPCapturingDirective` Check if the given directive can capture variables, and thus needs a captured statement. Simplify some code using this function. --- clang/include/clang/Basic/OpenMPKinds.h | 6 +++ clang/lib/Basic/OpenMPKinds.cpp | 66 + clang/lib/Sema/SemaOpenMP.cpp | 14 +- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 6d9d6ebc58e2c..3f21766f392cf 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -376,6 +376,12 @@ bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter); /// \return true - if the above condition is met for this directive /// otherwise - false. bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind); + +/// Checks if the specified directive need to capture variables. +/// \param DKind Specified directive. +/// \return true - if the above condition is met for this directive +/// otherwise - false. +bool isOpenMPCapturingDirective(OpenMPDirectiveKind DKind); } #endif diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 7c8990880fae3..30c34c207ae23 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -709,10 +709,44 @@ bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind) { return Cat == Category::Executable || Cat == Category::Subsidiary; } +bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) { + if (isOpenMPExecutableDirective(DKind)) { +switch (DKind) { +case OMPD_atomic: +case OMPD_barrier: +case OMPD_cancel: +case OMPD_cancellation_point: +case OMPD_critical: +case OMPD_depobj: +case OMPD_error: +case OMPD_flush: +case OMPD_masked: +case OMPD_master: +case OMPD_section: +case OMPD_taskwait: +case OMPD_taskyield: + return false; +default: + return !isOpenMPLoopTransformationDirective(DKind); +} + } + // Non-executable directives. + switch (DKind) { + case OMPD_metadirective: + case OMPD_nothing: +return true; + default: +break; + } + return false; +} + void clang::getOpenMPCaptureRegions( SmallVectorImpl &CaptureRegions, OpenMPDirectiveKind DKind) { assert(unsigned(DKind) < llvm::omp::Directive_enumSize); + assert(isOpenMPCapturingDirective(DKind)); + switch (DKind) { case OMPD_metadirective: CaptureRegions.push_back(OMPD_metadirective); @@ -799,48 +833,18 @@ void clang::getOpenMPCaptureRegions( case OMPD_for: case OMPD_for_simd: case OMPD_sections: - case OMPD_section: case OMPD_single: - case OMPD_master: - case OMPD_critical: case OMPD_taskgroup: case OMPD_distribute: case OMPD_ordered: - case OMPD_atomic: case OMPD_target_data: case OMPD_distribute_simd: case OMPD_scope: case OMPD_dispatch: CaptureRegions.push_back(OMPD_unknown); break; - case OMPD_tile: - case OMPD_unroll: -// loop transformations do not introduce captures. -break; - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_barrier: - case OMPD_error: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_cancel: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_requires: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: -llvm_unreachable("OpenMP Directive is not allowed"); - case OMPD_unknown: default: -llvm_unreachable("Unknown OpenMP directive"); +llvm_unreachable("Unhandled OpenMP directive"); } } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index b17c7e2be968e..a741339a7d669 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4862,11 +4862,7 @@ StmtResult SemaOpenMP::ActOnOpenMPRegionEnd(StmtResult S, ArrayRef Clauses) { handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(), /* ScopeEntry */ false); - if (DSAStack->getCurrentDirective() == OMPD_atomic || - DSAStack->getCurrentDirective() == OMPD_critical || - DSAStack->getCurrentDirective() == OMPD_section || - DSAStack->getCurrentDirective() == OMPD_master || - DSAStack->getCurrentDirective
[llvm-branch-commits] [clang] [clang][OpenMP] Implement `isOpenMPCapturingDirective` (PR #97090)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/97090 >From 0ee7c0154dee86e25c05f09828637eaf9bb8ec27 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 28 Jun 2024 12:31:35 -0500 Subject: [PATCH 1/2] [clang][OpenMP] Implement `isOpenMPCapturingDirective` Check if the given directive can capture variables, and thus needs a captured statement. Simplify some code using this function. --- clang/include/clang/Basic/OpenMPKinds.h | 6 +++ clang/lib/Basic/OpenMPKinds.cpp | 66 + clang/lib/Sema/SemaOpenMP.cpp | 14 +- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 6d9d6ebc58e2c..3f21766f392cf 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -376,6 +376,12 @@ bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter); /// \return true - if the above condition is met for this directive /// otherwise - false. bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind); + +/// Checks if the specified directive need to capture variables. +/// \param DKind Specified directive. +/// \return true - if the above condition is met for this directive +/// otherwise - false. +bool isOpenMPCapturingDirective(OpenMPDirectiveKind DKind); } #endif diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 7c8990880fae3..30c34c207ae23 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -709,10 +709,44 @@ bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind) { return Cat == Category::Executable || Cat == Category::Subsidiary; } +bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) { + if (isOpenMPExecutableDirective(DKind)) { +switch (DKind) { +case OMPD_atomic: +case OMPD_barrier: +case OMPD_cancel: +case OMPD_cancellation_point: +case OMPD_critical: +case OMPD_depobj: +case OMPD_error: +case OMPD_flush: +case OMPD_masked: +case OMPD_master: +case OMPD_section: +case OMPD_taskwait: +case OMPD_taskyield: + return false; +default: + return !isOpenMPLoopTransformationDirective(DKind); +} + } + // Non-executable directives. + switch (DKind) { + case OMPD_metadirective: + case OMPD_nothing: +return true; + default: +break; + } + return false; +} + void clang::getOpenMPCaptureRegions( SmallVectorImpl &CaptureRegions, OpenMPDirectiveKind DKind) { assert(unsigned(DKind) < llvm::omp::Directive_enumSize); + assert(isOpenMPCapturingDirective(DKind)); + switch (DKind) { case OMPD_metadirective: CaptureRegions.push_back(OMPD_metadirective); @@ -799,48 +833,18 @@ void clang::getOpenMPCaptureRegions( case OMPD_for: case OMPD_for_simd: case OMPD_sections: - case OMPD_section: case OMPD_single: - case OMPD_master: - case OMPD_critical: case OMPD_taskgroup: case OMPD_distribute: case OMPD_ordered: - case OMPD_atomic: case OMPD_target_data: case OMPD_distribute_simd: case OMPD_scope: case OMPD_dispatch: CaptureRegions.push_back(OMPD_unknown); break; - case OMPD_tile: - case OMPD_unroll: -// loop transformations do not introduce captures. -break; - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_barrier: - case OMPD_error: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_cancel: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_requires: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: -llvm_unreachable("OpenMP Directive is not allowed"); - case OMPD_unknown: default: -llvm_unreachable("Unknown OpenMP directive"); +llvm_unreachable("Unhandled OpenMP directive"); } } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index b17c7e2be968e..a741339a7d669 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4862,11 +4862,7 @@ StmtResult SemaOpenMP::ActOnOpenMPRegionEnd(StmtResult S, ArrayRef Clauses) { handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(), /* ScopeEntry */ false); - if (DSAStack->getCurrentDirective() == OMPD_atomic || - DSAStack->getCurrentDirective() == OMPD_critical || - DSAStack->getCurrentDirective() == OMPD_section || - DSAStack->getCurrentDirective() == OMPD_master || - DSAStack->getCurrentDirective() == OMPD_masked) + if (!isOpenMPCapturingDirective(DSAStack->getCurrentDirective())) return S; bool ErrorFound = fa
[llvm-branch-commits] [clang] [clang][OpenMP] Implement `isOpenMPCapturingDirective` (PR #97090)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/97090 >From 0ee7c0154dee86e25c05f09828637eaf9bb8ec27 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 28 Jun 2024 12:31:35 -0500 Subject: [PATCH 1/2] [clang][OpenMP] Implement `isOpenMPCapturingDirective` Check if the given directive can capture variables, and thus needs a captured statement. Simplify some code using this function. --- clang/include/clang/Basic/OpenMPKinds.h | 6 +++ clang/lib/Basic/OpenMPKinds.cpp | 66 + clang/lib/Sema/SemaOpenMP.cpp | 14 +- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 6d9d6ebc58e2c..3f21766f392cf 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -376,6 +376,12 @@ bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter); /// \return true - if the above condition is met for this directive /// otherwise - false. bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind); + +/// Checks if the specified directive need to capture variables. +/// \param DKind Specified directive. +/// \return true - if the above condition is met for this directive +/// otherwise - false. +bool isOpenMPCapturingDirective(OpenMPDirectiveKind DKind); } #endif diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 7c8990880fae3..30c34c207ae23 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -709,10 +709,44 @@ bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind) { return Cat == Category::Executable || Cat == Category::Subsidiary; } +bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) { + if (isOpenMPExecutableDirective(DKind)) { +switch (DKind) { +case OMPD_atomic: +case OMPD_barrier: +case OMPD_cancel: +case OMPD_cancellation_point: +case OMPD_critical: +case OMPD_depobj: +case OMPD_error: +case OMPD_flush: +case OMPD_masked: +case OMPD_master: +case OMPD_section: +case OMPD_taskwait: +case OMPD_taskyield: + return false; +default: + return !isOpenMPLoopTransformationDirective(DKind); +} + } + // Non-executable directives. + switch (DKind) { + case OMPD_metadirective: + case OMPD_nothing: +return true; + default: +break; + } + return false; +} + void clang::getOpenMPCaptureRegions( SmallVectorImpl &CaptureRegions, OpenMPDirectiveKind DKind) { assert(unsigned(DKind) < llvm::omp::Directive_enumSize); + assert(isOpenMPCapturingDirective(DKind)); + switch (DKind) { case OMPD_metadirective: CaptureRegions.push_back(OMPD_metadirective); @@ -799,48 +833,18 @@ void clang::getOpenMPCaptureRegions( case OMPD_for: case OMPD_for_simd: case OMPD_sections: - case OMPD_section: case OMPD_single: - case OMPD_master: - case OMPD_critical: case OMPD_taskgroup: case OMPD_distribute: case OMPD_ordered: - case OMPD_atomic: case OMPD_target_data: case OMPD_distribute_simd: case OMPD_scope: case OMPD_dispatch: CaptureRegions.push_back(OMPD_unknown); break; - case OMPD_tile: - case OMPD_unroll: -// loop transformations do not introduce captures. -break; - case OMPD_threadprivate: - case OMPD_allocate: - case OMPD_taskyield: - case OMPD_barrier: - case OMPD_error: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_cancel: - case OMPD_flush: - case OMPD_depobj: - case OMPD_scan: - case OMPD_declare_reduction: - case OMPD_declare_mapper: - case OMPD_declare_simd: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_requires: - case OMPD_declare_variant: - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: -llvm_unreachable("OpenMP Directive is not allowed"); - case OMPD_unknown: default: -llvm_unreachable("Unknown OpenMP directive"); +llvm_unreachable("Unhandled OpenMP directive"); } } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index b17c7e2be968e..a741339a7d669 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4862,11 +4862,7 @@ StmtResult SemaOpenMP::ActOnOpenMPRegionEnd(StmtResult S, ArrayRef Clauses) { handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(), /* ScopeEntry */ false); - if (DSAStack->getCurrentDirective() == OMPD_atomic || - DSAStack->getCurrentDirective() == OMPD_critical || - DSAStack->getCurrentDirective() == OMPD_section || - DSAStack->getCurrentDirective() == OMPD_master || - DSAStack->getCurrentDirective() == OMPD_masked) + if (!isOpenMPCapturingDirective(DSAStack->getCurrentDirective())) return S; bool ErrorFound = fa
[llvm-branch-commits] [clang] [clang][OpenMP] Rewrite `getOpenMPCaptureRegions` in term of leafs (PR #97110)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/97110 Replace the switch in `getOpenMPCaptureRegions` with a loop collecting capture regions based on the constituent directives. >From 2d25e0d32672ecae3dc3ad42c50446e651eceb06 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 28 Jun 2024 15:27:42 -0500 Subject: [PATCH] [clang][OpenMP] Rewrite `getOpenMPCaptureRegions` in term of leafs Replace the switch in `getOpenMPCaptureRegions` with a loop collecting capture regions based on the constituent directives. --- clang/lib/Basic/OpenMPKinds.cpp | 170 ++-- 1 file changed, 72 insertions(+), 98 deletions(-) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 30c34c207ae23..152891dfa27dc 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -747,105 +747,79 @@ void clang::getOpenMPCaptureRegions( assert(unsigned(DKind) < llvm::omp::Directive_enumSize); assert(isOpenMPCapturingDirective(DKind)); - switch (DKind) { - case OMPD_metadirective: -CaptureRegions.push_back(OMPD_metadirective); -break; - case OMPD_parallel: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_parallel_loop: -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_target_teams: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_teams); -break; - case OMPD_teams: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: -CaptureRegions.push_back(OMPD_teams); -break; - case OMPD_target: - case OMPD_target_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -break; - case OMPD_teams_loop: - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: -CaptureRegions.push_back(OMPD_teams); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_target_parallel: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_loop: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_task: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target_update: -CaptureRegions.push_back(OMPD_task); -break; - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop: - case OMPD_masked_taskloop_simd: -CaptureRegions.push_back(OMPD_taskloop); -break; - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_master_taskloop_simd: -CaptureRegions.push_back(OMPD_parallel); -CaptureRegions.push_back(OMPD_taskloop); -break; - case OMPD_target_teams_loop: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_teams); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_nothing: -CaptureRegions.push_back(OMPD_nothing); -break; - case OMPD_loop: -// TODO: 'loop' may require different capture regions depending on the bind -// clause or the parent directive when there is no bind clause. Use -// OMPD_unknown for now. - case OMPD_simd: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_single: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_target_data: - case OMPD_distribute_simd: - case OMPD_scope: - case OMPD_dispatch: + auto getRegionsForLeaf = [&](OpenMPDirectiveKind LKind) { +assert(isLeafConstruct(LKind) && "Epecting leaf directive"); +switch (LKind) { +case OMPD_metadirective: + CaptureRegions.push_back(OMPD_metadirective); + break; +case OMPD_nothing: + CaptureRegions.push_back(OMPD_nothing); + break; +case OMPD_parallel: + CaptureRegions.push_back(OMPD_parallel); + break; +case OMPD_target: + CaptureRegions.push_back(OMPD_task); + CaptureRegions.push_back(OMPD_target); + break; +case OMPD_task: +case OMPD_target_enter_data: +case OMPD_target_exit_data: +case OMPD_target_update: + CaptureRegions.push_back(OMPD_task); + break; +case OMPD_teams: + CaptureRegions.push_back(OMPD_teams); + break; +case OMPD_taskloop: + CaptureRegions.push_back(OMPD_taskloop); + break; +case OMP
[llvm-branch-commits] [clang] [clang][OpenMP] Rewrite `getOpenMPCaptureRegions` in terms of leafs (PR #97110)
https://github.com/kparzysz edited https://github.com/llvm/llvm-project/pull/97110 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang][OpenMP] Rewrite `getOpenMPCaptureRegions` in terms of leafs (PR #97110)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/97110 >From 2d25e0d32672ecae3dc3ad42c50446e651eceb06 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 28 Jun 2024 15:27:42 -0500 Subject: [PATCH] [clang][OpenMP] Rewrite `getOpenMPCaptureRegions` in term of leafs Replace the switch in `getOpenMPCaptureRegions` with a loop collecting capture regions based on the constituent directives. --- clang/lib/Basic/OpenMPKinds.cpp | 170 ++-- 1 file changed, 72 insertions(+), 98 deletions(-) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 30c34c207ae23..152891dfa27dc 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -747,105 +747,79 @@ void clang::getOpenMPCaptureRegions( assert(unsigned(DKind) < llvm::omp::Directive_enumSize); assert(isOpenMPCapturingDirective(DKind)); - switch (DKind) { - case OMPD_metadirective: -CaptureRegions.push_back(OMPD_metadirective); -break; - case OMPD_parallel: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_parallel_loop: -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_target_teams: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_teams); -break; - case OMPD_teams: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: -CaptureRegions.push_back(OMPD_teams); -break; - case OMPD_target: - case OMPD_target_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -break; - case OMPD_teams_loop: - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: -CaptureRegions.push_back(OMPD_teams); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_target_parallel: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_loop: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_task: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target_update: -CaptureRegions.push_back(OMPD_task); -break; - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop: - case OMPD_masked_taskloop_simd: -CaptureRegions.push_back(OMPD_taskloop); -break; - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_master_taskloop_simd: -CaptureRegions.push_back(OMPD_parallel); -CaptureRegions.push_back(OMPD_taskloop); -break; - case OMPD_target_teams_loop: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_teams); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_nothing: -CaptureRegions.push_back(OMPD_nothing); -break; - case OMPD_loop: -// TODO: 'loop' may require different capture regions depending on the bind -// clause or the parent directive when there is no bind clause. Use -// OMPD_unknown for now. - case OMPD_simd: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_single: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_target_data: - case OMPD_distribute_simd: - case OMPD_scope: - case OMPD_dispatch: + auto getRegionsForLeaf = [&](OpenMPDirectiveKind LKind) { +assert(isLeafConstruct(LKind) && "Epecting leaf directive"); +switch (LKind) { +case OMPD_metadirective: + CaptureRegions.push_back(OMPD_metadirective); + break; +case OMPD_nothing: + CaptureRegions.push_back(OMPD_nothing); + break; +case OMPD_parallel: + CaptureRegions.push_back(OMPD_parallel); + break; +case OMPD_target: + CaptureRegions.push_back(OMPD_task); + CaptureRegions.push_back(OMPD_target); + break; +case OMPD_task: +case OMPD_target_enter_data: +case OMPD_target_exit_data: +case OMPD_target_update: + CaptureRegions.push_back(OMPD_task); + break; +case OMPD_teams: + CaptureRegions.push_back(OMPD_teams); + break; +case OMPD_taskloop: + CaptureRegions.push_back(OMPD_taskloop); + break; +case OMPD_loop: + // TODO: 'loop' may require different capture regions depending on the + // bind clause or the parent dire
[llvm-branch-commits] [clang] [clang][OpenMP] Rewrite `getOpenMPCaptureRegions` in terms of leafs (PR #97110)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/97110 >From 2d25e0d32672ecae3dc3ad42c50446e651eceb06 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 28 Jun 2024 15:27:42 -0500 Subject: [PATCH 1/2] [clang][OpenMP] Rewrite `getOpenMPCaptureRegions` in term of leafs Replace the switch in `getOpenMPCaptureRegions` with a loop collecting capture regions based on the constituent directives. --- clang/lib/Basic/OpenMPKinds.cpp | 170 ++-- 1 file changed, 72 insertions(+), 98 deletions(-) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 30c34c207ae23..152891dfa27dc 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -747,105 +747,79 @@ void clang::getOpenMPCaptureRegions( assert(unsigned(DKind) < llvm::omp::Directive_enumSize); assert(isOpenMPCapturingDirective(DKind)); - switch (DKind) { - case OMPD_metadirective: -CaptureRegions.push_back(OMPD_metadirective); -break; - case OMPD_parallel: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_parallel_loop: -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_target_teams: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_teams); -break; - case OMPD_teams: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: -CaptureRegions.push_back(OMPD_teams); -break; - case OMPD_target: - case OMPD_target_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -break; - case OMPD_teams_loop: - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: -CaptureRegions.push_back(OMPD_teams); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_target_parallel: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_loop: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_task: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target_update: -CaptureRegions.push_back(OMPD_task); -break; - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop: - case OMPD_masked_taskloop_simd: -CaptureRegions.push_back(OMPD_taskloop); -break; - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_master_taskloop_simd: -CaptureRegions.push_back(OMPD_parallel); -CaptureRegions.push_back(OMPD_taskloop); -break; - case OMPD_target_teams_loop: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_teams); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_nothing: -CaptureRegions.push_back(OMPD_nothing); -break; - case OMPD_loop: -// TODO: 'loop' may require different capture regions depending on the bind -// clause or the parent directive when there is no bind clause. Use -// OMPD_unknown for now. - case OMPD_simd: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_single: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_target_data: - case OMPD_distribute_simd: - case OMPD_scope: - case OMPD_dispatch: + auto getRegionsForLeaf = [&](OpenMPDirectiveKind LKind) { +assert(isLeafConstruct(LKind) && "Epecting leaf directive"); +switch (LKind) { +case OMPD_metadirective: + CaptureRegions.push_back(OMPD_metadirective); + break; +case OMPD_nothing: + CaptureRegions.push_back(OMPD_nothing); + break; +case OMPD_parallel: + CaptureRegions.push_back(OMPD_parallel); + break; +case OMPD_target: + CaptureRegions.push_back(OMPD_task); + CaptureRegions.push_back(OMPD_target); + break; +case OMPD_task: +case OMPD_target_enter_data: +case OMPD_target_exit_data: +case OMPD_target_update: + CaptureRegions.push_back(OMPD_task); + break; +case OMPD_teams: + CaptureRegions.push_back(OMPD_teams); + break; +case OMPD_taskloop: + CaptureRegions.push_back(OMPD_taskloop); + break; +case OMPD_loop: + // TODO: 'loop' may require different capture regions depending on the + // bind clause or the parent
[llvm-branch-commits] [clang] [clang][OpenMP] Rewrite `getOpenMPCaptureRegions` in terms of leafs (PR #97110)
@@ -747,105 +747,79 @@ void clang::getOpenMPCaptureRegions( assert(unsigned(DKind) < llvm::omp::Directive_enumSize); assert(isOpenMPCapturingDirective(DKind) && "Expecting capturing directive"); - switch (DKind) { - case OMPD_metadirective: -CaptureRegions.push_back(OMPD_metadirective); -break; - case OMPD_parallel: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_parallel_loop: -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_target_teams: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_teams); -break; - case OMPD_teams: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: -CaptureRegions.push_back(OMPD_teams); -break; - case OMPD_target: - case OMPD_target_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -break; - case OMPD_teams_loop: - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: -CaptureRegions.push_back(OMPD_teams); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_target_parallel: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_loop: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_task: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target_update: -CaptureRegions.push_back(OMPD_task); -break; - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop: - case OMPD_masked_taskloop_simd: -CaptureRegions.push_back(OMPD_taskloop); -break; - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_master_taskloop_simd: -CaptureRegions.push_back(OMPD_parallel); -CaptureRegions.push_back(OMPD_taskloop); -break; - case OMPD_target_teams_loop: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_teams); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_nothing: -CaptureRegions.push_back(OMPD_nothing); -break; - case OMPD_loop: -// TODO: 'loop' may require different capture regions depending on the bind -// clause or the parent directive when there is no bind clause. Use -// OMPD_unknown for now. - case OMPD_simd: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_single: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_target_data: - case OMPD_distribute_simd: - case OMPD_scope: - case OMPD_dispatch: + auto getRegionsForLeaf = [&](OpenMPDirectiveKind LKind) { kparzysz wrote: Done https://github.com/llvm/llvm-project/pull/97110 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang][OpenMP] Rewrite `getOpenMPCaptureRegions` in terms of leafs (PR #97110)
@@ -747,105 +747,79 @@ void clang::getOpenMPCaptureRegions( assert(unsigned(DKind) < llvm::omp::Directive_enumSize); assert(isOpenMPCapturingDirective(DKind) && "Expecting capturing directive"); - switch (DKind) { - case OMPD_metadirective: -CaptureRegions.push_back(OMPD_metadirective); -break; - case OMPD_parallel: - case OMPD_parallel_for: - case OMPD_parallel_for_simd: - case OMPD_parallel_master: - case OMPD_parallel_masked: - case OMPD_parallel_sections: - case OMPD_distribute_parallel_for: - case OMPD_distribute_parallel_for_simd: - case OMPD_parallel_loop: -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_target_teams: - case OMPD_target_teams_distribute: - case OMPD_target_teams_distribute_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_teams); -break; - case OMPD_teams: - case OMPD_teams_distribute: - case OMPD_teams_distribute_simd: -CaptureRegions.push_back(OMPD_teams); -break; - case OMPD_target: - case OMPD_target_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -break; - case OMPD_teams_loop: - case OMPD_teams_distribute_parallel_for: - case OMPD_teams_distribute_parallel_for_simd: -CaptureRegions.push_back(OMPD_teams); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_target_parallel: - case OMPD_target_parallel_for: - case OMPD_target_parallel_for_simd: - case OMPD_target_parallel_loop: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_task: - case OMPD_target_enter_data: - case OMPD_target_exit_data: - case OMPD_target_update: -CaptureRegions.push_back(OMPD_task); -break; - case OMPD_taskloop: - case OMPD_taskloop_simd: - case OMPD_master_taskloop: - case OMPD_master_taskloop_simd: - case OMPD_masked_taskloop: - case OMPD_masked_taskloop_simd: -CaptureRegions.push_back(OMPD_taskloop); -break; - case OMPD_parallel_masked_taskloop: - case OMPD_parallel_masked_taskloop_simd: - case OMPD_parallel_master_taskloop: - case OMPD_parallel_master_taskloop_simd: -CaptureRegions.push_back(OMPD_parallel); -CaptureRegions.push_back(OMPD_taskloop); -break; - case OMPD_target_teams_loop: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: -CaptureRegions.push_back(OMPD_task); -CaptureRegions.push_back(OMPD_target); -CaptureRegions.push_back(OMPD_teams); -CaptureRegions.push_back(OMPD_parallel); -break; - case OMPD_nothing: -CaptureRegions.push_back(OMPD_nothing); -break; - case OMPD_loop: -// TODO: 'loop' may require different capture regions depending on the bind -// clause or the parent directive when there is no bind clause. Use -// OMPD_unknown for now. - case OMPD_simd: - case OMPD_for: - case OMPD_for_simd: - case OMPD_sections: - case OMPD_single: - case OMPD_taskgroup: - case OMPD_distribute: - case OMPD_ordered: - case OMPD_target_data: - case OMPD_distribute_simd: - case OMPD_scope: - case OMPD_dispatch: + auto getRegionsForLeaf = [&](OpenMPDirectiveKind LKind) { +assert(isLeafConstruct(LKind) && "Epecting leaf directive"); +switch (LKind) { +case OMPD_metadirective: + CaptureRegions.push_back(OMPD_metadirective); + break; +case OMPD_nothing: + CaptureRegions.push_back(OMPD_nothing); + break; +case OMPD_parallel: + CaptureRegions.push_back(OMPD_parallel); + break; +case OMPD_target: + CaptureRegions.push_back(OMPD_task); + CaptureRegions.push_back(OMPD_target); + break; +case OMPD_task: +case OMPD_target_enter_data: +case OMPD_target_exit_data: +case OMPD_target_update: + CaptureRegions.push_back(OMPD_task); + break; +case OMPD_teams: + CaptureRegions.push_back(OMPD_teams); + break; +case OMPD_taskloop: + CaptureRegions.push_back(OMPD_taskloop); + break; +case OMPD_loop: + // TODO: 'loop' may require different capture regions depending on the + // bind clause or the parent directive when there is no bind clause. + // If any of the directives that push regions here are parents of 'loop', + // assume 'parallel'. Otherwise do nothing. + if (!CaptureRegions.empty() && + !llvm::is_contained(CaptureRegions, OMPD_parallel)) +CaptureRegions.push_back(OMPD_parallel); + break; +case OMPD_dispatch: +case OMPD_distribute: +case OMPD_for: +case OMPD_masked: +case OMPD_master: +case OMPD_ordered: +case OMPD_scope: +case OMPD_sections: +case OMPD_simd: +case OMPD_single: +case OMPD_target_data: +case OMPD_taskgroup: + // These directives (when standalone) use OMPD_unknown as the region, + //
[llvm-branch-commits] [flang] [Flang][OpenMP] Prevent allocas from being inserted into loop wrappers (PR #97563)
https://github.com/kparzysz approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/97563 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [Flang][OpenMP] NFC: Remove unused argument for omp.target lowering (PR #97564)
https://github.com/kparzysz approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/97564 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang][OpenMP] Remove compound directives from `checkNestingOfRegions` (PR #98387)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/98387 Express the constraints via constituent directives. >From 263c2357cd686e63b5b78985d3c8c6f3635e69cc Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 10 Jul 2024 09:35:56 -0500 Subject: [PATCH] [clang][OpenMP] Remove compound directives from `checkNestingOfRegions` Express the constraints via constituent directives. --- clang/lib/Sema/SemaOpenMP.cpp | 107 +- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index ef09e53077f47..5861923582eb1 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4797,6 +4797,12 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, ShouldBeInTeamsRegion, ShouldBeInLoopSimdRegion, } Recommend = NoRecommend; + + SmallVector LeafOrComposite; + ArrayRef ParentLOC = + getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite); + OpenMPDirectiveKind EnclosingConstruct = ParentLOC.back(); + if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() && CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop && CurrentRegion != OMPD_parallel && @@ -4805,6 +4811,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, << getOpenMPDirectiveName(CurrentRegion); return true; } + if (isOpenMPSimdDirective(ParentRegion) && ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && @@ -4828,19 +4835,20 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); return CurrentRegion != OMPD_simd; } - if (ParentRegion == OMPD_atomic) { + + if (EnclosingConstruct == OMPD_atomic) { // OpenMP [2.16, Nesting of Regions] // OpenMP constructs may not be nested inside an atomic region. SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); return true; } + if (CurrentRegion == OMPD_section) { // OpenMP [2.7.2, sections Construct, Restrictions] // Orphaned section directives are prohibited. That is, the section // directives must appear within the sections construct and must not be // encountered elsewhere in the sections region. -if (ParentRegion != OMPD_sections && -ParentRegion != OMPD_parallel_sections) { +if (EnclosingConstruct != OMPD_sections) { SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) << (ParentRegion != OMPD_unknown) << getOpenMPDirectiveName(ParentRegion); @@ -4848,6 +4856,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, } return false; } + // Allow some constructs (except teams and cancellation constructs) to be // orphaned (they could be used in functions, called from OpenMP regions // with the required preconditions). @@ -4856,18 +4865,20 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, CurrentRegion != OMPD_cancellation_point && CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) return false; + // Checks needed for mapping "loop" construct. Please check mapLoopConstruct // for a detailed explanation if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop && (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) && (isOpenMPWorksharingDirective(ParentRegion) || - ParentRegion == OMPD_loop)) { + EnclosingConstruct == OMPD_loop)) { int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4; SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) << true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber << getOpenMPDirectiveName(CurrentRegion); return true; } + if (CurrentRegion == OMPD_cancellation_point || CurrentRegion == OMPD_cancel) { // OpenMP [2.16, Nesting of Regions] @@ -4881,27 +4892,17 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, // construct-type-clause is not taskgroup must be closely nested inside an // OpenMP construct that matches the type specified in // construct-type-clause. -NestingProhibited = -!((CancelRegion == OMPD_parallel && - (ParentRegion == OMPD_parallel || -ParentRegion == OMPD_target_parallel)) || - (CancelRegion == OMPD_for && - (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || -ParentRegion == OMPD_target_parallel_for || -ParentRegion == OMPD_distribute_parallel_for || -ParentRegion == OMPD_teams_distribute_parallel_for || -ParentRegion == OMPD_target_teams_distribute_parallel_for)) || - (CancelRegion == OMPD_taskgroup && -
[llvm-branch-commits] [clang] [clang][OpenMP] Remove compound directives from `checkNestingOfRegions` (PR #98387)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/98387 >From 263c2357cd686e63b5b78985d3c8c6f3635e69cc Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 10 Jul 2024 09:35:56 -0500 Subject: [PATCH 1/2] [clang][OpenMP] Remove compound directives from `checkNestingOfRegions` Express the constraints via constituent directives. --- clang/lib/Sema/SemaOpenMP.cpp | 107 +- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index ef09e53077f47..5861923582eb1 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4797,6 +4797,12 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, ShouldBeInTeamsRegion, ShouldBeInLoopSimdRegion, } Recommend = NoRecommend; + + SmallVector LeafOrComposite; + ArrayRef ParentLOC = + getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite); + OpenMPDirectiveKind EnclosingConstruct = ParentLOC.back(); + if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() && CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop && CurrentRegion != OMPD_parallel && @@ -4805,6 +4811,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, << getOpenMPDirectiveName(CurrentRegion); return true; } + if (isOpenMPSimdDirective(ParentRegion) && ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && @@ -4828,19 +4835,20 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); return CurrentRegion != OMPD_simd; } - if (ParentRegion == OMPD_atomic) { + + if (EnclosingConstruct == OMPD_atomic) { // OpenMP [2.16, Nesting of Regions] // OpenMP constructs may not be nested inside an atomic region. SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); return true; } + if (CurrentRegion == OMPD_section) { // OpenMP [2.7.2, sections Construct, Restrictions] // Orphaned section directives are prohibited. That is, the section // directives must appear within the sections construct and must not be // encountered elsewhere in the sections region. -if (ParentRegion != OMPD_sections && -ParentRegion != OMPD_parallel_sections) { +if (EnclosingConstruct != OMPD_sections) { SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) << (ParentRegion != OMPD_unknown) << getOpenMPDirectiveName(ParentRegion); @@ -4848,6 +4856,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, } return false; } + // Allow some constructs (except teams and cancellation constructs) to be // orphaned (they could be used in functions, called from OpenMP regions // with the required preconditions). @@ -4856,18 +4865,20 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, CurrentRegion != OMPD_cancellation_point && CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) return false; + // Checks needed for mapping "loop" construct. Please check mapLoopConstruct // for a detailed explanation if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop && (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) && (isOpenMPWorksharingDirective(ParentRegion) || - ParentRegion == OMPD_loop)) { + EnclosingConstruct == OMPD_loop)) { int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4; SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) << true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber << getOpenMPDirectiveName(CurrentRegion); return true; } + if (CurrentRegion == OMPD_cancellation_point || CurrentRegion == OMPD_cancel) { // OpenMP [2.16, Nesting of Regions] @@ -4881,27 +4892,17 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, // construct-type-clause is not taskgroup must be closely nested inside an // OpenMP construct that matches the type specified in // construct-type-clause. -NestingProhibited = -!((CancelRegion == OMPD_parallel && - (ParentRegion == OMPD_parallel || -ParentRegion == OMPD_target_parallel)) || - (CancelRegion == OMPD_for && - (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || -ParentRegion == OMPD_target_parallel_for || -ParentRegion == OMPD_distribute_parallel_for || -ParentRegion == OMPD_teams_distribute_parallel_for || -ParentRegion == OMPD_target_teams_distribute_parallel_for)) || - (CancelRegion == OMPD_taskgroup && - (ParentRegion == OMPD_task || -
[llvm-branch-commits] [clang] [clang][OpenMP] Update validity check for reduction with `inscan` (PR #98500)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/98500 Follow-up to 81cdf9472c (check for `scan` nesting). Also, it eliminates the mentions of combined directives in `ActOnOpenMPReductionClause`. >From b58e4fae4b0c22c11e8a0d0e29b6f21c28d4da86 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 11 Jul 2024 10:47:41 -0500 Subject: [PATCH] [clang][OpenMP] Update validity check for reduction with `inscan` Follow-up to 81cdf9472c (check for `scan` nesting). Also, it eliminates the mentions of combined directives in `ActOnOpenMPReductionClause`. --- clang/lib/Sema/SemaOpenMP.cpp | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7ca89b0d4eb70..dc77a51b6569e 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -18603,14 +18603,22 @@ OMPClause *SemaOpenMP::ActOnOpenMPReductionClause( // worksharing-loop construct, a worksharing-loop SIMD construct, a simd // construct, a parallel worksharing-loop construct or a parallel // worksharing-loop SIMD construct. - if (Modifier == OMPC_REDUCTION_inscan && - (DSAStack->getCurrentDirective() != OMPD_for && - DSAStack->getCurrentDirective() != OMPD_for_simd && - DSAStack->getCurrentDirective() != OMPD_simd && - DSAStack->getCurrentDirective() != OMPD_parallel_for && - DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { -Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); -return nullptr; + // [5.2:136:1-4] A reduction clause with the inscan reduction-modifier may + // only appear on a worksharing-loop construct, a simd construct or a + // combined or composite construct for which any of the aforementioned + // constructs is a constituent construct and distribute is not a constituent + // construct. + if (Modifier == OMPC_REDUCTION_inscan) { +SmallVector LeafOrComposite; +ArrayRef CurrentLOC = getLeafOrCompositeConstructs( +DSAStack->getCurrentDirective(), LeafOrComposite); +bool Valid = llvm::any_of(CurrentLOC, [](OpenMPDirectiveKind DK) { + return llvm::is_contained({OMPD_for, OMPD_simd, OMPD_for_simd}, DK); +}); +if (!Valid) { + Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); + return nullptr; +} } ReductionData RD(VarList.size(), Modifier); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang][OpenMP] Update validity check for reduction with `inscan` (PR #98500)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/98500 >From b58e4fae4b0c22c11e8a0d0e29b6f21c28d4da86 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 11 Jul 2024 10:47:41 -0500 Subject: [PATCH] [clang][OpenMP] Update validity check for reduction with `inscan` Follow-up to 81cdf9472c (check for `scan` nesting). Also, it eliminates the mentions of combined directives in `ActOnOpenMPReductionClause`. --- clang/lib/Sema/SemaOpenMP.cpp | 24 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7ca89b0d4eb70..dc77a51b6569e 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -18603,14 +18603,22 @@ OMPClause *SemaOpenMP::ActOnOpenMPReductionClause( // worksharing-loop construct, a worksharing-loop SIMD construct, a simd // construct, a parallel worksharing-loop construct or a parallel // worksharing-loop SIMD construct. - if (Modifier == OMPC_REDUCTION_inscan && - (DSAStack->getCurrentDirective() != OMPD_for && - DSAStack->getCurrentDirective() != OMPD_for_simd && - DSAStack->getCurrentDirective() != OMPD_simd && - DSAStack->getCurrentDirective() != OMPD_parallel_for && - DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { -Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); -return nullptr; + // [5.2:136:1-4] A reduction clause with the inscan reduction-modifier may + // only appear on a worksharing-loop construct, a simd construct or a + // combined or composite construct for which any of the aforementioned + // constructs is a constituent construct and distribute is not a constituent + // construct. + if (Modifier == OMPC_REDUCTION_inscan) { +SmallVector LeafOrComposite; +ArrayRef CurrentLOC = getLeafOrCompositeConstructs( +DSAStack->getCurrentDirective(), LeafOrComposite); +bool Valid = llvm::any_of(CurrentLOC, [](OpenMPDirectiveKind DK) { + return llvm::is_contained({OMPD_for, OMPD_simd, OMPD_for_simd}, DK); +}); +if (!Valid) { + Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); + return nullptr; +} } ReductionData RD(VarList.size(), Modifier); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang][OpenMP] Simplify check for taskloop in `ActOnOpenMPLoopInitia… (PR #98633)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/98633 …lization` Replace the explicit list of compound directives ending with taskloop with checking for the last leaf construct. >From 08ddba05e36c6c5b6fa5b4b158fbef21b77ab415 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 11 Jul 2024 14:02:41 -0500 Subject: [PATCH] [clang][OpenMP] Simplify check for taskloop in `ActOnOpenMPLoopInitialization` Replace the explicit list of compound directives ending with taskloop with checking for the last leaf construct. --- clang/lib/Sema/SemaOpenMP.cpp | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 2340873c8fdd9..118cda253a437 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -9090,14 +9090,15 @@ void SemaOpenMP::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, isOpenMPSimdDirective(DKind) ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) : OMPC_private; + auto isOpenMPTaskloopDirective = [](OpenMPDirectiveKind DK) { +return getLeafConstructsOrSelf(DK).back() == OMPD_taskloop; + }; if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && DVar.CKind != PredeterminedCKind && DVar.RefExpr && (getLangOpts().OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && DVar.CKind != OMPC_private))) || - ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || - DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop || - DKind == OMPD_parallel_master_taskloop || - DKind == OMPD_parallel_masked_taskloop || + ((isOpenMPWorksharingDirective(DKind) || + isOpenMPTaskloopDirective(DKind) || isOpenMPDistributeDirective(DKind)) && !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang][OpenMP] Simplify check for taskloop in `ActOnOpenMPLoopInitia… (PR #98633)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/98633 >From 08ddba05e36c6c5b6fa5b4b158fbef21b77ab415 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 11 Jul 2024 14:02:41 -0500 Subject: [PATCH 1/2] [clang][OpenMP] Simplify check for taskloop in `ActOnOpenMPLoopInitialization` Replace the explicit list of compound directives ending with taskloop with checking for the last leaf construct. --- clang/lib/Sema/SemaOpenMP.cpp | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 2340873c8fdd9..118cda253a437 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -9090,14 +9090,15 @@ void SemaOpenMP::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, isOpenMPSimdDirective(DKind) ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) : OMPC_private; + auto isOpenMPTaskloopDirective = [](OpenMPDirectiveKind DK) { +return getLeafConstructsOrSelf(DK).back() == OMPD_taskloop; + }; if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && DVar.CKind != PredeterminedCKind && DVar.RefExpr && (getLangOpts().OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && DVar.CKind != OMPC_private))) || - ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || - DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop || - DKind == OMPD_parallel_master_taskloop || - DKind == OMPD_parallel_masked_taskloop || + ((isOpenMPWorksharingDirective(DKind) || + isOpenMPTaskloopDirective(DKind) || isOpenMPDistributeDirective(DKind)) && !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && >From f38af28828a08daf3ba3a7f70104c38ccc6e4732 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 12 Jul 2024 08:58:28 -0500 Subject: [PATCH 2/2] Capitalize IsOpenMPTaskloopDirective --- clang/lib/Sema/SemaOpenMP.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 118cda253a437..c1a58fc7f2076 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -9090,7 +9090,7 @@ void SemaOpenMP::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, isOpenMPSimdDirective(DKind) ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) : OMPC_private; - auto isOpenMPTaskloopDirective = [](OpenMPDirectiveKind DK) { + auto IsOpenMPTaskloopDirective = [](OpenMPDirectiveKind DK) { return getLeafConstructsOrSelf(DK).back() == OMPD_taskloop; }; if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && @@ -9098,7 +9098,7 @@ void SemaOpenMP::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, (getLangOpts().OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && DVar.CKind != OMPC_private))) || ((isOpenMPWorksharingDirective(DKind) || - isOpenMPTaskloopDirective(DKind) || + IsOpenMPTaskloopDirective(DKind) || isOpenMPDistributeDirective(DKind)) && !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang][OpenMP] Simplify check for taskloop in `ActOnOpenMPLoopInitia… (PR #98633)
@@ -9090,14 +9090,15 @@ void SemaOpenMP::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, isOpenMPSimdDirective(DKind) ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) : OMPC_private; + auto isOpenMPTaskloopDirective = [](OpenMPDirectiveKind DK) { kparzysz wrote: Done https://github.com/llvm/llvm-project/pull/98633 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [MLIR][OpenMP] Automate operand structure definition (PR #99508)
@@ -12,11 +12,52 @@ #include "mlir/TableGen/GenInfo.h" +#include "mlir/TableGen/CodeGenHelpers.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/TypeSwitch.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" using namespace llvm; +/// The code block defining the base mixin class for combining clause operand +/// structures. +static const char *const baseMixinClass = R"( +namespace detail { +template +struct Clauses : public Mixins... {}; +} // namespace detail +)"; + +/// The code block defining operation argument structures. +static const char *const operationArgStruct = R"( +using {0}Operands = detail::Clauses<{1}>; +)"; + +/// Remove multiple optional prefixes and suffixes from \c str. +/// +/// Prefixes and suffixes are attempted to be removed once in the order they +/// appear in the \c prefixes and \c suffixes arguments. All prefixes are +/// processed before suffixes are. This means it will behave as shown in the +/// following example: +/// - str: "PrePreNameSuf1Suf2" +/// - prefixes: ["Pre"] +/// - suffixes: ["Suf1", "Suf2"] +/// - return: "PreNameSuf1" +static StringRef stripPrefixAndSuffix(StringRef str, + llvm::ArrayRef prefixes, + llvm::ArrayRef suffixes) { + for (StringRef prefix : prefixes) +if (str.starts_with(prefix)) + str = str.substr(prefix.size()); + + for (StringRef suffix : suffixes) +if (str.ends_with(suffix)) + str = str.substr(0, str.size() - suffix.size()); kparzysz wrote: `str = str.drop_back(suffix.size())` https://github.com/llvm/llvm-project/pull/99508 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [MLIR][OpenMP] Automate operand structure definition (PR #99508)
@@ -12,11 +12,52 @@ #include "mlir/TableGen/GenInfo.h" +#include "mlir/TableGen/CodeGenHelpers.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/TypeSwitch.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" using namespace llvm; +/// The code block defining the base mixin class for combining clause operand +/// structures. +static const char *const baseMixinClass = R"( +namespace detail { +template +struct Clauses : public Mixins... {}; +} // namespace detail +)"; + +/// The code block defining operation argument structures. +static const char *const operationArgStruct = R"( +using {0}Operands = detail::Clauses<{1}>; +)"; + +/// Remove multiple optional prefixes and suffixes from \c str. +/// +/// Prefixes and suffixes are attempted to be removed once in the order they +/// appear in the \c prefixes and \c suffixes arguments. All prefixes are +/// processed before suffixes are. This means it will behave as shown in the +/// following example: +/// - str: "PrePreNameSuf1Suf2" +/// - prefixes: ["Pre"] +/// - suffixes: ["Suf1", "Suf2"] +/// - return: "PreNameSuf1" +static StringRef stripPrefixAndSuffix(StringRef str, + llvm::ArrayRef prefixes, + llvm::ArrayRef suffixes) { + for (StringRef prefix : prefixes) +if (str.starts_with(prefix)) + str = str.substr(prefix.size()); kparzysz wrote: `str = str.drop_front(prefix.size())` https://github.com/llvm/llvm-project/pull/99508 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] [MLIR][OpenMP] Automate operand structure definition (PR #99508)
@@ -408,17 +408,26 @@ class ElementsAttrBase : let storageType = [{ ::mlir::ElementsAttr }]; let returnType = [{ ::mlir::ElementsAttr }]; let convertFromStorage = "$_self"; + + // The underlying C++ value type of each element. + string elementReturnType = ?; kparzysz wrote: This may need wider support, specifically we may need to generate an accessor function in .h.inc/.cpp.inc. Something like https://github.com/llvm/llvm-project/blob/main/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp#L1204, for example. I'm wary about making this kind of change in a widely shared file. Maybe we could just handle this in OmpOpGen.cpp? Specifically, infer this information in there based on the type of the attribute? https://github.com/llvm/llvm-project/pull/99508 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [Flang][OpenMP] Prevent re-composition of composite constructs (PR #102613)
@@ -2263,24 +2321,13 @@ static void genOMPDispatch(lower::AbstractConverter &converter, // Composite constructs case llvm::omp::Directive::OMPD_distribute_parallel_do: -genCompositeDistributeParallelDo(converter, symTable, semaCtx, eval, loc, - queue, item, *loopDsp); -break; case llvm::omp::Directive::OMPD_distribute_parallel_do_simd: -genCompositeDistributeParallelDoSimd(converter, symTable, semaCtx, eval, - loc, queue, item, *loopDsp); -break; case llvm::omp::Directive::OMPD_distribute_simd: -genCompositeDistributeSimd(converter, symTable, semaCtx, eval, loc, queue, - item, *loopDsp); -break; case llvm::omp::Directive::OMPD_do_simd: -genCompositeDoSimd(converter, symTable, semaCtx, eval, loc, queue, item, - *loopDsp); -break; case llvm::omp::Directive::OMPD_taskloop_simd: -genCompositeTaskloopSimd(converter, symTable, semaCtx, eval, loc, queue, - item, *loopDsp); +// Composite constructs should have been split into a sequence of leaf +// constructs and lowered by genOMPCompositeDispatch(). +llvm_unreachable("Unexpected composite construct."); break; default: kparzysz wrote: Maybe you could delete the specific cases with composite constructs, and add `assert(!isCompositeConstruct(dir))` to the default label. https://github.com/llvm/llvm-project/pull/102613 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [Flang][OpenMP] Prevent re-composition of composite constructs (PR #102613)
@@ -2141,13 +2154,50 @@ static void genCompositeTaskloopSimd( semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, mlir::Location loc, const ConstructQueue &queue, ConstructQueue::const_iterator item, DataSharingProcessor &dsp) { + assert(std::distance(item, queue.end()) == 2 && "Invalid leaf constructs"); TODO(loc, "Composite TASKLOOP SIMD"); } //===--===// // Dispatch //===--===// +static bool genOMPCompositeDispatch( +lower::AbstractConverter &converter, lower::SymMap &symTable, +semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, +mlir::Location loc, const ConstructQueue &queue, +ConstructQueue::const_iterator item, DataSharingProcessor &dsp) { + using llvm::omp::Directive; + using llvm::omp::getLeafConstructs, lower::omp::matchLeafSequence; + + if (matchLeafSequence( + item, queue, + getLeafConstructs(Directive::OMPD_distribute_parallel_do))) kparzysz wrote: Maybe `matchLeafSequence` could take the directive, and call `getLeafConstructs` itself. It would make these calls a bit tidier... https://github.com/llvm/llvm-project/pull/102613 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [Flang][OpenMP] Prevent re-composition of composite constructs (PR #102613)
@@ -90,38 +83,33 @@ ConstructQueue buildConstructQueue( Fortran::lower::pft::Evaluation &eval, const parser::CharBlock &source, llvm::omp::Directive compound, const List &clauses) { - List constructs; - ConstructDecomposition decompose(modOp, semaCtx, eval, compound, clauses); assert(!decompose.output.empty() && "Construct decomposition failed"); - llvm::SmallVector loweringUnits; - std::ignore = - llvm::omp::getLeafOrCompositeConstructs(compound, loweringUnits); - uint32_t version = getOpenMPVersionAttribute(modOp); - - int leafIndex = 0; - for (llvm::omp::Directive dir_id : loweringUnits) { -llvm::ArrayRef leafsOrSelf = -llvm::omp::getLeafConstructsOrSelf(dir_id); -size_t numLeafs = leafsOrSelf.size(); - -llvm::ArrayRef toMerge{&decompose.output[leafIndex], - numLeafs}; -auto &uc = constructs.emplace_back(mergeConstructs(version, toMerge)); - -if (!transferLocations(clauses, uc.clauses)) { - // If some clauses are left without source information, use the - // directive's source. - for (auto &clause : uc.clauses) { -if (clause.source.empty()) - clause.source = source; - } -} -leafIndex += numLeafs; + for (UnitConstruct &uc : decompose.output) { +assert(getLeafConstructs(uc.id).empty() && "unexpected compound directive"); +// If some clauses are left without source information, use the directive's +// source. +for (auto &clause : uc.clauses) + if (clause.source.empty()) +clause.source = source; } - return constructs; + return decompose.output; +} + +bool matchLeafSequence(ConstructQueue::const_iterator item, + const ConstructQueue &queue, + llvm::ArrayRef directives) { + for (auto [dir, leaf] : + llvm::zip_longest(directives, llvm::make_range(item, queue.end( { +if (!dir || !leaf) kparzysz wrote: `0` is a legitimate directive id (`OMPD_allocate`). https://github.com/llvm/llvm-project/pull/102613 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert unique clauses in ClauseProcessor (PR #81622)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/81622 Temporarily rename old clause list to `clauses2`, old clause iterator to `ClauseIterator2`. Change `findUniqueClause` to iterate over `omp::Clause` objects, modify all handlers to operate on 'omp::clause::xyz` equivalents. [Clause representation 2/6] >From bdf305038dcb144bfdfbf6d32bedf3e8a481e463 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 6 Feb 2024 17:06:29 -0600 Subject: [PATCH] [flang][OpenMP] Convert unique clauses in ClauseProcessor Temporarily rename old clause list to `clauses2`, old clause iterator to `ClauseIterator2`. Change `findUniqueClause` to iterate over `omp::Clause` objects, modify all handlers to operate on 'omp::clause::xyz` equivalents. --- flang/lib/Lower/OpenMP.cpp | 242 + 1 file changed, 114 insertions(+), 128 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 24bef1d999548b..d7a93db15a4bb8 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1669,7 +1669,8 @@ class ClauseProcessor { ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses(clauses) {} + : converter(converter), semaCtx(semaCtx), clauses2(clauses), +clauses(omp::makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. bool @@ -1769,7 +1770,8 @@ class ClauseProcessor { llvm::omp::Directive directive) const; private: - using ClauseIterator = std::list::const_iterator; + using ClauseIterator = omp::List::const_iterator; + using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -1782,14 +1784,26 @@ class ClauseProcessor { return end; } + /// Utility to find a clause within a range in the clause list. + template + static ClauseIterator2 findClause2(ClauseIterator2 begin, + ClauseIterator2 end) { +for (ClauseIterator2 it = begin; it != end; ++it) { + if (std::get_if(&it->u)) +return it; +} + +return end; + } + /// Return the first instance of the given clause found in the clause list or /// `nullptr` if not present. If more than one instance is expected, use /// `findRepeatableClause` instead. template const T * findUniqueClause(const Fortran::parser::CharBlock **source = nullptr) const { -ClauseIterator it = findClause(clauses.v.begin(), clauses.v.end()); -if (it != clauses.v.end()) { +ClauseIterator it = findClause(clauses.begin(), clauses.end()); +if (it != clauses.end()) { if (source) *source = &it->source; return &std::get(it->u); @@ -1804,9 +1818,9 @@ class ClauseProcessor { std::function callbackFn) const { bool found = false; -ClauseIterator nextIt, endIt = clauses.v.end(); -for (ClauseIterator it = clauses.v.begin(); it != endIt; it = nextIt) { - nextIt = findClause(it, endIt); +ClauseIterator2 nextIt, endIt = clauses2.v.end(); +for (ClauseIterator2 it = clauses2.v.begin(); it != endIt; it = nextIt) { + nextIt = findClause2(it, endIt); if (nextIt != endIt) { callbackFn(&std::get(nextIt->u), nextIt->source); @@ -1829,7 +1843,8 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses; + const Fortran::parser::OmpClauseList &clauses2; + omp::List clauses; }; //===--===// @@ -2294,64 +2309,55 @@ class ReductionProcessor { }; static mlir::omp::ScheduleModifier -translateScheduleModifier(const Fortran::parser::OmpScheduleModifierType &m) { - switch (m.v) { - case Fortran::parser::OmpScheduleModifierType::ModType::Monotonic: +translateScheduleModifier(const omp::clause::Schedule::ModType &m) { + switch (m) { + case omp::clause::Schedule::ModType::Monotonic: return mlir::omp::ScheduleModifier::monotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Nonmonotonic: + case omp::clause::Schedule::ModType::Nonmonotonic: return mlir::omp::ScheduleModifier::nonmonotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Simd: + case omp::clause::Schedule::ModType::Simd: return mlir::omp::ScheduleModifier::simd; } return mlir::omp::ScheduleModifier::none; } static mlir::omp::ScheduleModifier -getScheduleModifier(const Fortran::parser::OmpScheduleClause &x) { - const auto &modifier = - std::get>(x.t); +getScheduleModifier(const omp::clause::Schedule &clause) { + using ScheduleModifier = omp::clause::Schedule::Sch
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/81623 …essor Rename `findRepeatableClause` to `findRepeatableClause2`, and make the new `findRepeatableClause` operate on new `omp::Clause` objects. Leave `Map` unchanged, because it will require more changes for it to work. >From be33fa2419d24490a221f78fbba4f2b7097b6011 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 6 Feb 2024 17:06:29 -0600 Subject: [PATCH] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProcessor Rename `findRepeatableClause` to `findRepeatableClause2`, and make the new `findRepeatableClause` operate on new `omp::Clause` objects. Leave `Map` unchanged, because it will require more changes for it to work. --- flang/include/flang/Evaluate/tools.h | 23 + flang/lib/Lower/OpenMP.cpp | 632 +-- 2 files changed, 328 insertions(+), 327 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index d257da1a709642..e974944e88 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -430,6 +430,29 @@ template std::optional ExtractCoarrayRef(const A &x) { } } +struct ExtractSubstringHelper { + template static std::optional visit(T &&) { +return std::nullopt; + } + + static std::optional visit(const Substring &e) { return e; } + + template + static std::optional visit(const Designator &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } + + template + static std::optional visit(const Expr &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } +}; + +template +std::optional ExtractSubstring(const A &x) { + return ExtractSubstringHelper::visit(x); +} + // If an expression is simply a whole symbol data designator, // extract and return that symbol, else null. template const Symbol *UnwrapWholeSymbolDataRef(const A &x) { diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index d7a93db15a4bb8..4b21ab934c9393 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -72,9 +72,9 @@ getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) { return sym; } -static void genObjectList(const Fortran::parser::OmpObjectList &objectList, - Fortran::lower::AbstractConverter &converter, - llvm::SmallVectorImpl &operands) { +static void genObjectList2(const Fortran::parser::OmpObjectList &objectList, + Fortran::lower::AbstractConverter &converter, + llvm::SmallVectorImpl &operands) { auto addOperands = [&](Fortran::lower::SymbolRef sym) { const mlir::Value variable = converter.getSymbolAddress(sym); if (variable) { @@ -93,27 +93,6 @@ static void genObjectList(const Fortran::parser::OmpObjectList &objectList, } } -static void gatherFuncAndVarSyms( -const Fortran::parser::OmpObjectList &objList, -mlir::omp::DeclareTargetCaptureClause clause, -llvm::SmallVectorImpl &symbolAndClause) { - for (const Fortran::parser::OmpObject &ompObject : objList.v) { -Fortran::common::visit( -Fortran::common::visitors{ -[&](const Fortran::parser::Designator &designator) { - if (const Fortran::parser::Name *name = - Fortran::semantics::getDesignatorNameIfDataRef( - designator)) { -symbolAndClause.emplace_back(clause, *name->symbol); - } -}, -[&](const Fortran::parser::Name &name) { - symbolAndClause.emplace_back(clause, *name.symbol); -}}, -ompObject.u); - } -} - static Fortran::lower::pft::Evaluation * getCollapsedLoopEval(Fortran::lower::pft::Evaluation &eval, int collapseValue) { // Return the Evaluation of the innermost collapsed loop, or the current one @@ -1257,6 +1236,32 @@ List makeList(const parser::OmpClauseList &clauses, } } // namespace omp +static void genObjectList(const omp::ObjectList &objects, + Fortran::lower::AbstractConverter &converter, + llvm::SmallVectorImpl &operands) { + for (const omp::Object &object : objects) { +const Fortran::semantics::Symbol *sym = object.sym; +assert(sym && "Expected Symbol"); +if (mlir::Value variable = converter.getSymbolAddress(*sym)) { + operands.push_back(variable); +} else { + if (const auto *details = + sym->detailsIf()) { +operands.push_back(converter.getSymbolAddress(details->symbol())); +converter.copySymbolBinding(details->symbol(), *sym); + } +} + } +} + +static void gatherFuncAndVarSyms( +const omp::ObjectList &objects, +mlir::omp::DeclareTargetCaptureClause clause, +llvm::SmallVectorImpl &symbolAndClause) { + for (const omp::Object &object : objects) +symbolAndClause.emplace_b
[llvm-branch-commits] [flang] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr (PR #81626)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/81626 The related functions are `gatherDataOperandAddrAndBounds` and `genBoundsOps`. The former is used in OpenACC as well, and it was updated to pass evaluate::Expr instead of parser objects. The difference in the test case comes from unfolded conversions of index expressions, which are explicitly of type integer(kind=8). Delete now unused `findRepeatableClause2` and `findClause2`. Add `AsGenericExpr` that takes std::optional. It already returns optional Expr. Making it accept an optional Expr as input would reduce the number of necessary checks when handling frequent optional values in evaluator. >From f4ed9e51d5f3d0d8c56a569b15299011653dd22f Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 8 Feb 2024 08:33:40 -0600 Subject: [PATCH] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr The related functions are `gatherDataOperandAddrAndBounds` and `genBoundsOps`. The former is used in OpenACC as well, and it was updated to pass evaluate::Expr instead of parser objects. The difference in the test case comes from unfolded conversions of index expressions, which are explicitly of type integer(kind=8). Delete now unused `findRepeatableClause2` and `findClause2`. Add `AsGenericExpr` that takes std::optional. It already returns optional Expr. Making it accept an optional Expr as input would reduce the number of necessary checks when handling frequent optional values in evaluator. --- flang/include/flang/Evaluate/tools.h | 8 + flang/lib/Lower/DirectivesCommon.h | 389 --- flang/lib/Lower/OpenACC.cpp | 54 ++-- flang/lib/Lower/OpenMP.cpp | 105 +++- 4 files changed, 311 insertions(+), 245 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index e974944e88..d5713cfe420a2e 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -148,6 +148,14 @@ inline Expr AsGenericExpr(Expr &&x) { return std::move(x); } std::optional> AsGenericExpr(DataRef &&); std::optional> AsGenericExpr(const Symbol &); +// Propagate std::optional from input to output. +template +std::optional> AsGenericExpr(std::optional &&x) { + if (!x) +return std::nullopt; + return AsGenericExpr(std::move(*x)); +} + template common::IfNoLvalue::category>>, A> AsCategoryExpr( A &&x) { diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h index 8d560db34e05bf..2fa90572bc63eb 100644 --- a/flang/lib/Lower/DirectivesCommon.h +++ b/flang/lib/Lower/DirectivesCommon.h @@ -808,6 +808,75 @@ genBaseBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, return bounds; } +namespace detail { +template // +static T &&AsRvalueRef(T &&t) { + return std::move(t); +} +template // +static T AsRvalueRef(T &t) { + return t; +} +template // +static T AsRvalueRef(const T &t) { + return t; +} + +// Helper class for stripping enclosing parentheses and a conversion that +// preserves type category. This is used for triplet elements, which are +// always of type integer(kind=8). The lower/upper bounds are converted to +// an "index" type, which is 64-bit, so the explicit conversion to kind=8 +// (if present) is not needed. When it's present, though, it causes generated +// names to contain "int(..., kind=8)". +struct PeelConvert { + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Expr> + &expr) { +return std::visit( +[](auto &&s) { return visit_with_category(s); }, +expr.u); + } + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Convert, + Category> &expr) { +return AsGenericExpr(AsRvalueRef(expr.left())); + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + + template + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr> +&expr) { +return std::visit([](auto &&s) { return visit_with_category(s); }, + expr.u); + } + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr &expr) { +return std::visit([](auto &&s) { return visit(s); }, expr.u); + } + template // + static Fortran::semantics::MaybeExpr visit(const T &) { +return std::nullopt; + } +}; + +static Fortran::semantics::SomeExpr +peelOuterConvert(Fortran::semantics::SomeExpr &expr) { + if (auto peeled = PeelConvert::visit(expr)) +return *peeled; + return expr; +} +} // namespace detail + /// Generate bounds operations for an array section when subscripts are /// provided. template @@ -815,7 +884,7 @@ llvm::Small
[llvm-branch-commits] [flang] [flang][OpenMP] Convert processTODO and remove unused objects (PR #81627)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/81627 Remove `ClauseIterator2` and `clauses2` from ClauseProcessor. [Clause representation 5/6] >From 2e0088679635755536125a60de7508b6abcbf790 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 9 Feb 2024 15:03:54 -0600 Subject: [PATCH] [flang][OpenMP] Convert processTODO and remove unused objects Remove `ClauseIterator2` and `clauses2` from ClauseProcessor. --- flang/lib/Lower/OpenMP.cpp | 75 ++ 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 7cf8fcc0a3d274..8dcd0708e6245c 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1668,13 +1668,11 @@ void DataSharingProcessor::defaultPrivatize() { /// methods that relate to clauses that can impact the lowering of that /// construct. class ClauseProcessor { - using ClauseTy = Fortran::parser::OmpClause; - public: ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses2(clauses), + : converter(converter), semaCtx(semaCtx), clauses(omp::makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. @@ -1775,7 +1773,6 @@ class ClauseProcessor { private: using ClauseIterator = omp::List::const_iterator; - using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -1835,7 +1832,6 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses2; omp::List clauses; }; @@ -3131,19 +3127,17 @@ bool ClauseProcessor::processMotionClauses( template void ClauseProcessor::processTODO(mlir::Location currentLocation, llvm::omp::Directive directive) const { - auto checkUnhandledClause = [&](const auto *x) { + auto checkUnhandledClause = [&](llvm::omp::Clause id, const auto *x) { if (!x) return; TODO(currentLocation, - "Unhandled clause " + - llvm::StringRef(Fortran::parser::ParseTreeDumper::GetNodeName(*x)) - .upper() + + "Unhandled clause " + llvm::omp::getOpenMPClauseName(id).upper() + " in " + llvm::omp::getOpenMPDirectiveName(directive).upper() + " construct"); }; - for (ClauseIterator2 it = clauses2.v.begin(); it != clauses2.v.end(); ++it) -(checkUnhandledClause(std::get_if(&it->u)), ...); + for (ClauseIterator it = clauses.begin(); it != clauses.end(); ++it) +(checkUnhandledClause(it->id, std::get_if(&it->u)), ...); } //===--===// @@ -3722,8 +3716,8 @@ genSingleOp(Fortran::lower::AbstractConverter &converter, ClauseProcessor cp(converter, semaCtx, beginClauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_single); + cp.processTODO(currentLocation, + llvm::omp::Directive::OMPD_single); ClauseProcessor(converter, semaCtx, endClauseList).processNowait(nowaitAttr); @@ -3756,10 +3750,9 @@ genTaskOp(Fortran::lower::AbstractConverter &converter, cp.processMergeable(mergeableAttr); cp.processPriority(stmtCtx, priorityClauseOperand); cp.processDepend(dependTypeOperands, dependOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_task); + cp.processTODO(currentLocation, +llvm::omp::Directive::OMPD_task); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) @@ -3784,7 +3777,7 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter, llvm::SmallVector allocateOperands, allocatorOperands; ClauseProcessor cp(converter, semaCtx, clauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( + cp.processTODO( currentLocation, llvm::omp::Directive::OMPD_taskgroup); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) @@ -3868,8 +3861,7 @@ genEnterExitUpdateDataOp(Fortran::lower::AbstractConverter &converter, cp.processMap(currentLocation, directive, stmtCtx, mapOperands); } - cp.processTODO(currentLocation, - directive); + cp.processTODO(currentLocation, directive); return firOpBuilder.create(currentLocation, ifClauseOperand, deviceOperand, nullptr, mlir::ValueRange(), @@ -4052,16 +4044,11 @@ genTargetOp(Fortran::lower::AbstractConverter &c
[llvm-branch-commits] [flang] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause (PR #81629)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/81629 [Clause representation 6/6] >From c5adb1dee4fdc31fe56390109db79d2551069a3e Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Sat, 10 Feb 2024 08:50:48 -0600 Subject: [PATCH] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause --- flang/lib/Lower/OpenMP.cpp | 303 ++--- 1 file changed, 149 insertions(+), 154 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 8dcd0708e6245c..88402828053e63 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1277,14 +1277,15 @@ class DataSharingProcessor { llvm::SetVector symbolsInNestedRegions; llvm::SetVector symbolsInParentRegions; Fortran::lower::AbstractConverter &converter; + Fortran::semantics::SemanticsContext &semaCtx; fir::FirOpBuilder &firOpBuilder; - const Fortran::parser::OmpClauseList &opClauseList; + omp::List clauses; Fortran::lower::pft::Evaluation &eval; bool needBarrier(); void collectSymbols(Fortran::semantics::Symbol::Flag flag); void collectOmpObjectListSymbol( - const Fortran::parser::OmpObjectList &ompObjectList, + const omp::ObjectList &objects, llvm::SetVector &symbolSet); void collectSymbolsForPrivatization(); void insertBarrier(); @@ -1301,11 +1302,12 @@ class DataSharingProcessor { public: DataSharingProcessor(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &opClauseList, Fortran::lower::pft::Evaluation &eval) - : hasLastPrivateOp(false), converter(converter), -firOpBuilder(converter.getFirOpBuilder()), opClauseList(opClauseList), -eval(eval) {} + : hasLastPrivateOp(false), converter(converter), semaCtx(semaCtx), +firOpBuilder(converter.getFirOpBuilder()), +clauses(omp::makeList(opClauseList, semaCtx)), eval(eval) {} // Privatisation is split into two steps. // Step1 performs cloning of all privatisation clauses and copying for // firstprivates. Step1 is performed at the place where process/processStep1 @@ -1383,30 +1385,28 @@ void DataSharingProcessor::copyLastPrivateSymbol( } void DataSharingProcessor::collectOmpObjectListSymbol( -const Fortran::parser::OmpObjectList &ompObjectList, +const omp::ObjectList &objects, llvm::SetVector &symbolSet) { - for (const Fortran::parser::OmpObject &ompObject : ompObjectList.v) { -Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject); + for (const omp::Object &object : objects) { +Fortran::semantics::Symbol *sym = object.sym; symbolSet.insert(sym); } } void DataSharingProcessor::collectSymbolsForPrivatization() { bool hasCollapse = false; - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { + for (const omp::Clause &clause : clauses) { if (const auto &privateClause = -std::get_if(&clause.u)) { +std::get_if(&clause.u)) { collectOmpObjectListSymbol(privateClause->v, privatizedSymbols); } else if (const auto &firstPrivateClause = - std::get_if( - &clause.u)) { + std::get_if(&clause.u)) { collectOmpObjectListSymbol(firstPrivateClause->v, privatizedSymbols); } else if (const auto &lastPrivateClause = - std::get_if( - &clause.u)) { + std::get_if(&clause.u)) { collectOmpObjectListSymbol(lastPrivateClause->v, privatizedSymbols); hasLastPrivateOp = true; -} else if (std::get_if(&clause.u)) { +} else if (std::get_if(&clause.u)) { hasCollapse = true; } } @@ -1439,138 +1439,135 @@ void DataSharingProcessor::insertBarrier() { void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { bool cmpCreated = false; mlir::OpBuilder::InsertPoint localInsPt = firOpBuilder.saveInsertionPoint(); - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { -if (std::get_if(&clause.u)) { - // TODO: Add lastprivate support for simd construct - if (mlir::isa(op)) { -if (&eval == &eval.parentConstruct->getLastNestedEvaluation()) { - // For `omp.sections`, lastprivatized variables occur in - // lexically final `omp.section` operation. The following FIR - // shall be generated for the same: - // - // omp.sections lastprivate(...) { - // omp.section {...} - // omp.section {...} - // omp.section { - // fir.allocate for `private`/`firstprivate` - // - // fir.if %true { - // ^%lpv_update_blk - // } - // } - // } - // - // To keep code consistency while handling privatization -
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
https://github.com/kparzysz edited https://github.com/llvm/llvm-project/pull/81623 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr (PR #81626)
https://github.com/kparzysz edited https://github.com/llvm/llvm-project/pull/81626 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert processTODO and remove unused objects (PR #81627)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81627 >From 1299d5190a3c273d2af4ab8c7f800af7df4e4ef6 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 9 Feb 2024 15:03:54 -0600 Subject: [PATCH] [flang][OpenMP] Convert processTODO and remove unused objects Remove `ClauseIterator2` and `clauses2` from ClauseProcessor. --- flang/lib/Lower/OpenMP.cpp | 75 ++ 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 4309d69434839f..51ed0fe03dbe38 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1669,13 +1669,11 @@ void DataSharingProcessor::defaultPrivatize() { /// methods that relate to clauses that can impact the lowering of that /// construct. class ClauseProcessor { - using ClauseTy = Fortran::parser::OmpClause; - public: ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses2(clauses), + : converter(converter), semaCtx(semaCtx), clauses(omp::makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. @@ -1776,7 +1774,6 @@ class ClauseProcessor { private: using ClauseIterator = omp::List::const_iterator; - using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -1836,7 +1833,6 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses2; omp::List clauses; }; @@ -3132,19 +3128,17 @@ bool ClauseProcessor::processMotionClauses( template void ClauseProcessor::processTODO(mlir::Location currentLocation, llvm::omp::Directive directive) const { - auto checkUnhandledClause = [&](const auto *x) { + auto checkUnhandledClause = [&](llvm::omp::Clause id, const auto *x) { if (!x) return; TODO(currentLocation, - "Unhandled clause " + - llvm::StringRef(Fortran::parser::ParseTreeDumper::GetNodeName(*x)) - .upper() + + "Unhandled clause " + llvm::omp::getOpenMPClauseName(id).upper() + " in " + llvm::omp::getOpenMPDirectiveName(directive).upper() + " construct"); }; - for (ClauseIterator2 it = clauses2.v.begin(); it != clauses2.v.end(); ++it) -(checkUnhandledClause(std::get_if(&it->u)), ...); + for (ClauseIterator it = clauses.begin(); it != clauses.end(); ++it) +(checkUnhandledClause(it->id, std::get_if(&it->u)), ...); } //===--===// @@ -3723,8 +3717,8 @@ genSingleOp(Fortran::lower::AbstractConverter &converter, ClauseProcessor cp(converter, semaCtx, beginClauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_single); + cp.processTODO(currentLocation, + llvm::omp::Directive::OMPD_single); ClauseProcessor(converter, semaCtx, endClauseList).processNowait(nowaitAttr); @@ -3757,10 +3751,9 @@ genTaskOp(Fortran::lower::AbstractConverter &converter, cp.processMergeable(mergeableAttr); cp.processPriority(stmtCtx, priorityClauseOperand); cp.processDepend(dependTypeOperands, dependOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_task); + cp.processTODO(currentLocation, +llvm::omp::Directive::OMPD_task); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) @@ -3785,7 +3778,7 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter, llvm::SmallVector allocateOperands, allocatorOperands; ClauseProcessor cp(converter, semaCtx, clauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( + cp.processTODO( currentLocation, llvm::omp::Directive::OMPD_taskgroup); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) @@ -3869,8 +3862,7 @@ genEnterExitUpdateDataOp(Fortran::lower::AbstractConverter &converter, cp.processMap(currentLocation, directive, stmtCtx, mapOperands); } - cp.processTODO(currentLocation, - directive); + cp.processTODO(currentLocation, directive); return firOpBuilder.create(currentLocation, ifClauseOperand, deviceOperand, nullptr, mlir::ValueRange(), @@ -4053,16 +4045,11 @@ genTargetOp(Fortran::lower::AbstractConverter &converter, cp.processNowait(nowaitAttr); cp.processMap(currentLocation, directive, stmt
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81623 >From 841f10e44e5ec5cfc6b166421f878089a17c623c Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 6 Feb 2024 17:06:29 -0600 Subject: [PATCH] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProcessor Rename `findRepeatableClause` to `findRepeatableClause2`, and make the new `findRepeatableClause` operate on new `omp::Clause` objects. Leave `Map` unchanged, because it will require more changes for it to work. --- flang/include/flang/Evaluate/tools.h | 23 + flang/lib/Lower/OpenMP.cpp | 632 +-- 2 files changed, 328 insertions(+), 327 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index d257da1a709642..e974944e88 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -430,6 +430,29 @@ template std::optional ExtractCoarrayRef(const A &x) { } } +struct ExtractSubstringHelper { + template static std::optional visit(T &&) { +return std::nullopt; + } + + static std::optional visit(const Substring &e) { return e; } + + template + static std::optional visit(const Designator &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } + + template + static std::optional visit(const Expr &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } +}; + +template +std::optional ExtractSubstring(const A &x) { + return ExtractSubstringHelper::visit(x); +} + // If an expression is simply a whole symbol data designator, // extract and return that symbol, else null. template const Symbol *UnwrapWholeSymbolDataRef(const A &x) { diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 4156887c8ff531..caae5c0cef9251 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -72,9 +72,9 @@ getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) { return sym; } -static void genObjectList(const Fortran::parser::OmpObjectList &objectList, - Fortran::lower::AbstractConverter &converter, - llvm::SmallVectorImpl &operands) { +static void genObjectList2(const Fortran::parser::OmpObjectList &objectList, + Fortran::lower::AbstractConverter &converter, + llvm::SmallVectorImpl &operands) { auto addOperands = [&](Fortran::lower::SymbolRef sym) { const mlir::Value variable = converter.getSymbolAddress(sym); if (variable) { @@ -93,27 +93,6 @@ static void genObjectList(const Fortran::parser::OmpObjectList &objectList, } } -static void gatherFuncAndVarSyms( -const Fortran::parser::OmpObjectList &objList, -mlir::omp::DeclareTargetCaptureClause clause, -llvm::SmallVectorImpl &symbolAndClause) { - for (const Fortran::parser::OmpObject &ompObject : objList.v) { -Fortran::common::visit( -Fortran::common::visitors{ -[&](const Fortran::parser::Designator &designator) { - if (const Fortran::parser::Name *name = - Fortran::semantics::getDesignatorNameIfDataRef( - designator)) { -symbolAndClause.emplace_back(clause, *name->symbol); - } -}, -[&](const Fortran::parser::Name &name) { - symbolAndClause.emplace_back(clause, *name.symbol); -}}, -ompObject.u); - } -} - static Fortran::lower::pft::Evaluation * getCollapsedLoopEval(Fortran::lower::pft::Evaluation &eval, int collapseValue) { // Return the Evaluation of the innermost collapsed loop, or the current one @@ -1258,6 +1237,32 @@ List makeList(const parser::OmpClauseList &clauses, } } // namespace omp +static void genObjectList(const omp::ObjectList &objects, + Fortran::lower::AbstractConverter &converter, + llvm::SmallVectorImpl &operands) { + for (const omp::Object &object : objects) { +const Fortran::semantics::Symbol *sym = object.sym; +assert(sym && "Expected Symbol"); +if (mlir::Value variable = converter.getSymbolAddress(*sym)) { + operands.push_back(variable); +} else { + if (const auto *details = + sym->detailsIf()) { +operands.push_back(converter.getSymbolAddress(details->symbol())); +converter.copySymbolBinding(details->symbol(), *sym); + } +} + } +} + +static void gatherFuncAndVarSyms( +const omp::ObjectList &objects, +mlir::omp::DeclareTargetCaptureClause clause, +llvm::SmallVectorImpl &symbolAndClause) { + for (const omp::Object &object : objects) +symbolAndClause.emplace_back(clause, *object.sym); +} + //===--===// // DataSharingProcessor //===--===// @
[llvm-branch-commits] [flang] [flang][OpenMP] Convert processTODO and remove unused objects (PR #81627)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81627 >From 1299d5190a3c273d2af4ab8c7f800af7df4e4ef6 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 9 Feb 2024 15:03:54 -0600 Subject: [PATCH] [flang][OpenMP] Convert processTODO and remove unused objects Remove `ClauseIterator2` and `clauses2` from ClauseProcessor. --- flang/lib/Lower/OpenMP.cpp | 75 ++ 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 4309d69434839..51ed0fe03dbe3 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1669,13 +1669,11 @@ void DataSharingProcessor::defaultPrivatize() { /// methods that relate to clauses that can impact the lowering of that /// construct. class ClauseProcessor { - using ClauseTy = Fortran::parser::OmpClause; - public: ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses2(clauses), + : converter(converter), semaCtx(semaCtx), clauses(omp::makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. @@ -1776,7 +1774,6 @@ class ClauseProcessor { private: using ClauseIterator = omp::List::const_iterator; - using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -1836,7 +1833,6 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses2; omp::List clauses; }; @@ -3132,19 +3128,17 @@ bool ClauseProcessor::processMotionClauses( template void ClauseProcessor::processTODO(mlir::Location currentLocation, llvm::omp::Directive directive) const { - auto checkUnhandledClause = [&](const auto *x) { + auto checkUnhandledClause = [&](llvm::omp::Clause id, const auto *x) { if (!x) return; TODO(currentLocation, - "Unhandled clause " + - llvm::StringRef(Fortran::parser::ParseTreeDumper::GetNodeName(*x)) - .upper() + + "Unhandled clause " + llvm::omp::getOpenMPClauseName(id).upper() + " in " + llvm::omp::getOpenMPDirectiveName(directive).upper() + " construct"); }; - for (ClauseIterator2 it = clauses2.v.begin(); it != clauses2.v.end(); ++it) -(checkUnhandledClause(std::get_if(&it->u)), ...); + for (ClauseIterator it = clauses.begin(); it != clauses.end(); ++it) +(checkUnhandledClause(it->id, std::get_if(&it->u)), ...); } //===--===// @@ -3723,8 +3717,8 @@ genSingleOp(Fortran::lower::AbstractConverter &converter, ClauseProcessor cp(converter, semaCtx, beginClauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_single); + cp.processTODO(currentLocation, + llvm::omp::Directive::OMPD_single); ClauseProcessor(converter, semaCtx, endClauseList).processNowait(nowaitAttr); @@ -3757,10 +3751,9 @@ genTaskOp(Fortran::lower::AbstractConverter &converter, cp.processMergeable(mergeableAttr); cp.processPriority(stmtCtx, priorityClauseOperand); cp.processDepend(dependTypeOperands, dependOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_task); + cp.processTODO(currentLocation, +llvm::omp::Directive::OMPD_task); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) @@ -3785,7 +3778,7 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter, llvm::SmallVector allocateOperands, allocatorOperands; ClauseProcessor cp(converter, semaCtx, clauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( + cp.processTODO( currentLocation, llvm::omp::Directive::OMPD_taskgroup); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) @@ -3869,8 +3862,7 @@ genEnterExitUpdateDataOp(Fortran::lower::AbstractConverter &converter, cp.processMap(currentLocation, directive, stmtCtx, mapOperands); } - cp.processTODO(currentLocation, - directive); + cp.processTODO(currentLocation, directive); return firOpBuilder.create(currentLocation, ifClauseOperand, deviceOperand, nullptr, mlir::ValueRange(), @@ -4053,16 +4045,11 @@ genTargetOp(Fortran::lower::AbstractConverter &converter, cp.processNowait(nowaitAttr); cp.processMap(currentLocation, directive, stmtCt
[llvm-branch-commits] [flang] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr (PR #81626)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81626 >From 87437159da37749ad395d84a3fc1b729bd9e2480 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 8 Feb 2024 08:33:40 -0600 Subject: [PATCH] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr The related functions are `gatherDataOperandAddrAndBounds` and `genBoundsOps`. The former is used in OpenACC as well, and it was updated to pass evaluate::Expr instead of parser objects. The difference in the test case comes from unfolded conversions of index expressions, which are explicitly of type integer(kind=8). Delete now unused `findRepeatableClause2` and `findClause2`. Add `AsGenericExpr` that takes std::optional. It already returns optional Expr. Making it accept an optional Expr as input would reduce the number of necessary checks when handling frequent optional values in evaluator. --- flang/include/flang/Evaluate/tools.h | 8 + flang/lib/Lower/DirectivesCommon.h | 389 --- flang/lib/Lower/OpenACC.cpp | 54 ++-- flang/lib/Lower/OpenMP.cpp | 105 +++- 4 files changed, 311 insertions(+), 245 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index e974944e88..d5713cfe420a2e 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -148,6 +148,14 @@ inline Expr AsGenericExpr(Expr &&x) { return std::move(x); } std::optional> AsGenericExpr(DataRef &&); std::optional> AsGenericExpr(const Symbol &); +// Propagate std::optional from input to output. +template +std::optional> AsGenericExpr(std::optional &&x) { + if (!x) +return std::nullopt; + return AsGenericExpr(std::move(*x)); +} + template common::IfNoLvalue::category>>, A> AsCategoryExpr( A &&x) { diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h index 8d560db34e05bf..2fa90572bc63eb 100644 --- a/flang/lib/Lower/DirectivesCommon.h +++ b/flang/lib/Lower/DirectivesCommon.h @@ -808,6 +808,75 @@ genBaseBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, return bounds; } +namespace detail { +template // +static T &&AsRvalueRef(T &&t) { + return std::move(t); +} +template // +static T AsRvalueRef(T &t) { + return t; +} +template // +static T AsRvalueRef(const T &t) { + return t; +} + +// Helper class for stripping enclosing parentheses and a conversion that +// preserves type category. This is used for triplet elements, which are +// always of type integer(kind=8). The lower/upper bounds are converted to +// an "index" type, which is 64-bit, so the explicit conversion to kind=8 +// (if present) is not needed. When it's present, though, it causes generated +// names to contain "int(..., kind=8)". +struct PeelConvert { + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Expr> + &expr) { +return std::visit( +[](auto &&s) { return visit_with_category(s); }, +expr.u); + } + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Convert, + Category> &expr) { +return AsGenericExpr(AsRvalueRef(expr.left())); + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + + template + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr> +&expr) { +return std::visit([](auto &&s) { return visit_with_category(s); }, + expr.u); + } + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr &expr) { +return std::visit([](auto &&s) { return visit(s); }, expr.u); + } + template // + static Fortran::semantics::MaybeExpr visit(const T &) { +return std::nullopt; + } +}; + +static Fortran::semantics::SomeExpr +peelOuterConvert(Fortran::semantics::SomeExpr &expr) { + if (auto peeled = PeelConvert::visit(expr)) +return *peeled; + return expr; +} +} // namespace detail + /// Generate bounds operations for an array section when subscripts are /// provided. template @@ -815,7 +884,7 @@ llvm::SmallVector genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext &stmtCtx, - const std::list &subscripts, + const std::vector &subscripts, std::stringstream &asFortran, fir::ExtendedValue &dataExv, bool dataExvIsAssumedSize, AddrAndBoundsInfo &info, bool treatIndexAsSection = false) { @@ -828,8 +897,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1)
[llvm-branch-commits] [flang] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause (PR #81629)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81629 >From 61d3ad32f0b5ab4903319add4ca5b68cd3e5ad3d Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Sat, 10 Feb 2024 08:50:48 -0600 Subject: [PATCH] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause --- flang/lib/Lower/OpenMP.cpp | 303 ++--- 1 file changed, 149 insertions(+), 154 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 51ed0fe03dbe38..e45ab842b15556 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1278,14 +1278,15 @@ class DataSharingProcessor { llvm::SetVector symbolsInNestedRegions; llvm::SetVector symbolsInParentRegions; Fortran::lower::AbstractConverter &converter; + Fortran::semantics::SemanticsContext &semaCtx; fir::FirOpBuilder &firOpBuilder; - const Fortran::parser::OmpClauseList &opClauseList; + omp::List clauses; Fortran::lower::pft::Evaluation &eval; bool needBarrier(); void collectSymbols(Fortran::semantics::Symbol::Flag flag); void collectOmpObjectListSymbol( - const Fortran::parser::OmpObjectList &ompObjectList, + const omp::ObjectList &objects, llvm::SetVector &symbolSet); void collectSymbolsForPrivatization(); void insertBarrier(); @@ -1302,11 +1303,12 @@ class DataSharingProcessor { public: DataSharingProcessor(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &opClauseList, Fortran::lower::pft::Evaluation &eval) - : hasLastPrivateOp(false), converter(converter), -firOpBuilder(converter.getFirOpBuilder()), opClauseList(opClauseList), -eval(eval) {} + : hasLastPrivateOp(false), converter(converter), semaCtx(semaCtx), +firOpBuilder(converter.getFirOpBuilder()), +clauses(omp::makeList(opClauseList, semaCtx)), eval(eval) {} // Privatisation is split into two steps. // Step1 performs cloning of all privatisation clauses and copying for // firstprivates. Step1 is performed at the place where process/processStep1 @@ -1384,30 +1386,28 @@ void DataSharingProcessor::copyLastPrivateSymbol( } void DataSharingProcessor::collectOmpObjectListSymbol( -const Fortran::parser::OmpObjectList &ompObjectList, +const omp::ObjectList &objects, llvm::SetVector &symbolSet) { - for (const Fortran::parser::OmpObject &ompObject : ompObjectList.v) { -Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject); + for (const omp::Object &object : objects) { +Fortran::semantics::Symbol *sym = object.sym; symbolSet.insert(sym); } } void DataSharingProcessor::collectSymbolsForPrivatization() { bool hasCollapse = false; - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { + for (const omp::Clause &clause : clauses) { if (const auto &privateClause = -std::get_if(&clause.u)) { +std::get_if(&clause.u)) { collectOmpObjectListSymbol(privateClause->v, privatizedSymbols); } else if (const auto &firstPrivateClause = - std::get_if( - &clause.u)) { + std::get_if(&clause.u)) { collectOmpObjectListSymbol(firstPrivateClause->v, privatizedSymbols); } else if (const auto &lastPrivateClause = - std::get_if( - &clause.u)) { + std::get_if(&clause.u)) { collectOmpObjectListSymbol(lastPrivateClause->v, privatizedSymbols); hasLastPrivateOp = true; -} else if (std::get_if(&clause.u)) { +} else if (std::get_if(&clause.u)) { hasCollapse = true; } } @@ -1440,138 +1440,135 @@ void DataSharingProcessor::insertBarrier() { void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { bool cmpCreated = false; mlir::OpBuilder::InsertPoint localInsPt = firOpBuilder.saveInsertionPoint(); - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { -if (std::get_if(&clause.u)) { - // TODO: Add lastprivate support for simd construct - if (mlir::isa(op)) { -if (&eval == &eval.parentConstruct->getLastNestedEvaluation()) { - // For `omp.sections`, lastprivatized variables occur in - // lexically final `omp.section` operation. The following FIR - // shall be generated for the same: - // - // omp.sections lastprivate(...) { - // omp.section {...} - // omp.section {...} - // omp.section { - // fir.allocate for `private`/`firstprivate` - // - // fir.if %true { - // ^%lpv_update_blk - // } - // } - // } - // - // To keep code consistency while handling privatization - // through this control flow
[llvm-branch-commits] [flang] [flang][OpenMP] Convert unique clauses in ClauseProcessor (PR #81622)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81622 >From 57c70c53a3898d7fc45fd0a71368ae20fe8a1a85 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 6 Feb 2024 17:06:29 -0600 Subject: [PATCH] [flang][OpenMP] Convert unique clauses in ClauseProcessor Temporarily rename old clause list to `clauses2`, old clause iterator to `ClauseIterator2`. Change `findUniqueClause` to iterate over `omp::Clause` objects, modify all handlers to operate on 'omp::clause::xyz` equivalents. --- flang/lib/Lower/OpenMP.cpp | 242 + 1 file changed, 114 insertions(+), 128 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index ae3619609b80ff..4156887c8ff531 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1670,7 +1670,8 @@ class ClauseProcessor { ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses(clauses) {} + : converter(converter), semaCtx(semaCtx), clauses2(clauses), +clauses(omp::makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. bool @@ -1770,7 +1771,8 @@ class ClauseProcessor { llvm::omp::Directive directive) const; private: - using ClauseIterator = std::list::const_iterator; + using ClauseIterator = omp::List::const_iterator; + using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -1783,14 +1785,26 @@ class ClauseProcessor { return end; } + /// Utility to find a clause within a range in the clause list. + template + static ClauseIterator2 findClause2(ClauseIterator2 begin, + ClauseIterator2 end) { +for (ClauseIterator2 it = begin; it != end; ++it) { + if (std::get_if(&it->u)) +return it; +} + +return end; + } + /// Return the first instance of the given clause found in the clause list or /// `nullptr` if not present. If more than one instance is expected, use /// `findRepeatableClause` instead. template const T * findUniqueClause(const Fortran::parser::CharBlock **source = nullptr) const { -ClauseIterator it = findClause(clauses.v.begin(), clauses.v.end()); -if (it != clauses.v.end()) { +ClauseIterator it = findClause(clauses.begin(), clauses.end()); +if (it != clauses.end()) { if (source) *source = &it->source; return &std::get(it->u); @@ -1805,9 +1819,9 @@ class ClauseProcessor { std::function callbackFn) const { bool found = false; -ClauseIterator nextIt, endIt = clauses.v.end(); -for (ClauseIterator it = clauses.v.begin(); it != endIt; it = nextIt) { - nextIt = findClause(it, endIt); +ClauseIterator2 nextIt, endIt = clauses2.v.end(); +for (ClauseIterator2 it = clauses2.v.begin(); it != endIt; it = nextIt) { + nextIt = findClause2(it, endIt); if (nextIt != endIt) { callbackFn(&std::get(nextIt->u), nextIt->source); @@ -1830,7 +1844,8 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses; + const Fortran::parser::OmpClauseList &clauses2; + omp::List clauses; }; //===--===// @@ -2295,64 +2310,55 @@ class ReductionProcessor { }; static mlir::omp::ScheduleModifier -translateScheduleModifier(const Fortran::parser::OmpScheduleModifierType &m) { - switch (m.v) { - case Fortran::parser::OmpScheduleModifierType::ModType::Monotonic: +translateScheduleModifier(const omp::clause::Schedule::ModType &m) { + switch (m) { + case omp::clause::Schedule::ModType::Monotonic: return mlir::omp::ScheduleModifier::monotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Nonmonotonic: + case omp::clause::Schedule::ModType::Nonmonotonic: return mlir::omp::ScheduleModifier::nonmonotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Simd: + case omp::clause::Schedule::ModType::Simd: return mlir::omp::ScheduleModifier::simd; } return mlir::omp::ScheduleModifier::none; } static mlir::omp::ScheduleModifier -getScheduleModifier(const Fortran::parser::OmpScheduleClause &x) { - const auto &modifier = - std::get>(x.t); +getScheduleModifier(const omp::clause::Schedule &clause) { + using ScheduleModifier = omp::clause::Schedule::ScheduleModifier; + const auto &modifier = std::get>(clause.t); // The input may have the modifier any order, so we look for one that isn't // SIMD. If modifier is not set at all, fall down to the bottom and return // "none". if (modifier) { -
[llvm-branch-commits] [flang] [flang][OpenMP] Convert unique clauses in ClauseProcessor (PR #81622)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81622 >From 57c70c53a3898d7fc45fd0a71368ae20fe8a1a85 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 6 Feb 2024 17:06:29 -0600 Subject: [PATCH] [flang][OpenMP] Convert unique clauses in ClauseProcessor Temporarily rename old clause list to `clauses2`, old clause iterator to `ClauseIterator2`. Change `findUniqueClause` to iterate over `omp::Clause` objects, modify all handlers to operate on 'omp::clause::xyz` equivalents. --- flang/lib/Lower/OpenMP.cpp | 242 + 1 file changed, 114 insertions(+), 128 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index ae3619609b80ff..4156887c8ff531 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1670,7 +1670,8 @@ class ClauseProcessor { ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses(clauses) {} + : converter(converter), semaCtx(semaCtx), clauses2(clauses), +clauses(omp::makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. bool @@ -1770,7 +1771,8 @@ class ClauseProcessor { llvm::omp::Directive directive) const; private: - using ClauseIterator = std::list::const_iterator; + using ClauseIterator = omp::List::const_iterator; + using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -1783,14 +1785,26 @@ class ClauseProcessor { return end; } + /// Utility to find a clause within a range in the clause list. + template + static ClauseIterator2 findClause2(ClauseIterator2 begin, + ClauseIterator2 end) { +for (ClauseIterator2 it = begin; it != end; ++it) { + if (std::get_if(&it->u)) +return it; +} + +return end; + } + /// Return the first instance of the given clause found in the clause list or /// `nullptr` if not present. If more than one instance is expected, use /// `findRepeatableClause` instead. template const T * findUniqueClause(const Fortran::parser::CharBlock **source = nullptr) const { -ClauseIterator it = findClause(clauses.v.begin(), clauses.v.end()); -if (it != clauses.v.end()) { +ClauseIterator it = findClause(clauses.begin(), clauses.end()); +if (it != clauses.end()) { if (source) *source = &it->source; return &std::get(it->u); @@ -1805,9 +1819,9 @@ class ClauseProcessor { std::function callbackFn) const { bool found = false; -ClauseIterator nextIt, endIt = clauses.v.end(); -for (ClauseIterator it = clauses.v.begin(); it != endIt; it = nextIt) { - nextIt = findClause(it, endIt); +ClauseIterator2 nextIt, endIt = clauses2.v.end(); +for (ClauseIterator2 it = clauses2.v.begin(); it != endIt; it = nextIt) { + nextIt = findClause2(it, endIt); if (nextIt != endIt) { callbackFn(&std::get(nextIt->u), nextIt->source); @@ -1830,7 +1844,8 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses; + const Fortran::parser::OmpClauseList &clauses2; + omp::List clauses; }; //===--===// @@ -2295,64 +2310,55 @@ class ReductionProcessor { }; static mlir::omp::ScheduleModifier -translateScheduleModifier(const Fortran::parser::OmpScheduleModifierType &m) { - switch (m.v) { - case Fortran::parser::OmpScheduleModifierType::ModType::Monotonic: +translateScheduleModifier(const omp::clause::Schedule::ModType &m) { + switch (m) { + case omp::clause::Schedule::ModType::Monotonic: return mlir::omp::ScheduleModifier::monotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Nonmonotonic: + case omp::clause::Schedule::ModType::Nonmonotonic: return mlir::omp::ScheduleModifier::nonmonotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Simd: + case omp::clause::Schedule::ModType::Simd: return mlir::omp::ScheduleModifier::simd; } return mlir::omp::ScheduleModifier::none; } static mlir::omp::ScheduleModifier -getScheduleModifier(const Fortran::parser::OmpScheduleClause &x) { - const auto &modifier = - std::get>(x.t); +getScheduleModifier(const omp::clause::Schedule &clause) { + using ScheduleModifier = omp::clause::Schedule::ScheduleModifier; + const auto &modifier = std::get>(clause.t); // The input may have the modifier any order, so we look for one that isn't // SIMD. If modifier is not set at all, fall down to the bottom and return // "none". if (modifier) { -
[llvm-branch-commits] [flang] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause (PR #81629)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81629 >From 61d3ad32f0b5ab4903319add4ca5b68cd3e5ad3d Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Sat, 10 Feb 2024 08:50:48 -0600 Subject: [PATCH] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause --- flang/lib/Lower/OpenMP.cpp | 303 ++--- 1 file changed, 149 insertions(+), 154 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 51ed0fe03dbe38..e45ab842b15556 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1278,14 +1278,15 @@ class DataSharingProcessor { llvm::SetVector symbolsInNestedRegions; llvm::SetVector symbolsInParentRegions; Fortran::lower::AbstractConverter &converter; + Fortran::semantics::SemanticsContext &semaCtx; fir::FirOpBuilder &firOpBuilder; - const Fortran::parser::OmpClauseList &opClauseList; + omp::List clauses; Fortran::lower::pft::Evaluation &eval; bool needBarrier(); void collectSymbols(Fortran::semantics::Symbol::Flag flag); void collectOmpObjectListSymbol( - const Fortran::parser::OmpObjectList &ompObjectList, + const omp::ObjectList &objects, llvm::SetVector &symbolSet); void collectSymbolsForPrivatization(); void insertBarrier(); @@ -1302,11 +1303,12 @@ class DataSharingProcessor { public: DataSharingProcessor(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &opClauseList, Fortran::lower::pft::Evaluation &eval) - : hasLastPrivateOp(false), converter(converter), -firOpBuilder(converter.getFirOpBuilder()), opClauseList(opClauseList), -eval(eval) {} + : hasLastPrivateOp(false), converter(converter), semaCtx(semaCtx), +firOpBuilder(converter.getFirOpBuilder()), +clauses(omp::makeList(opClauseList, semaCtx)), eval(eval) {} // Privatisation is split into two steps. // Step1 performs cloning of all privatisation clauses and copying for // firstprivates. Step1 is performed at the place where process/processStep1 @@ -1384,30 +1386,28 @@ void DataSharingProcessor::copyLastPrivateSymbol( } void DataSharingProcessor::collectOmpObjectListSymbol( -const Fortran::parser::OmpObjectList &ompObjectList, +const omp::ObjectList &objects, llvm::SetVector &symbolSet) { - for (const Fortran::parser::OmpObject &ompObject : ompObjectList.v) { -Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject); + for (const omp::Object &object : objects) { +Fortran::semantics::Symbol *sym = object.sym; symbolSet.insert(sym); } } void DataSharingProcessor::collectSymbolsForPrivatization() { bool hasCollapse = false; - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { + for (const omp::Clause &clause : clauses) { if (const auto &privateClause = -std::get_if(&clause.u)) { +std::get_if(&clause.u)) { collectOmpObjectListSymbol(privateClause->v, privatizedSymbols); } else if (const auto &firstPrivateClause = - std::get_if( - &clause.u)) { + std::get_if(&clause.u)) { collectOmpObjectListSymbol(firstPrivateClause->v, privatizedSymbols); } else if (const auto &lastPrivateClause = - std::get_if( - &clause.u)) { + std::get_if(&clause.u)) { collectOmpObjectListSymbol(lastPrivateClause->v, privatizedSymbols); hasLastPrivateOp = true; -} else if (std::get_if(&clause.u)) { +} else if (std::get_if(&clause.u)) { hasCollapse = true; } } @@ -1440,138 +1440,135 @@ void DataSharingProcessor::insertBarrier() { void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { bool cmpCreated = false; mlir::OpBuilder::InsertPoint localInsPt = firOpBuilder.saveInsertionPoint(); - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { -if (std::get_if(&clause.u)) { - // TODO: Add lastprivate support for simd construct - if (mlir::isa(op)) { -if (&eval == &eval.parentConstruct->getLastNestedEvaluation()) { - // For `omp.sections`, lastprivatized variables occur in - // lexically final `omp.section` operation. The following FIR - // shall be generated for the same: - // - // omp.sections lastprivate(...) { - // omp.section {...} - // omp.section {...} - // omp.section { - // fir.allocate for `private`/`firstprivate` - // - // fir.if %true { - // ^%lpv_update_blk - // } - // } - // } - // - // To keep code consistency while handling privatization - // through this control flow
[llvm-branch-commits] [flang] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr (PR #81626)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81626 >From 87437159da37749ad395d84a3fc1b729bd9e2480 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 8 Feb 2024 08:33:40 -0600 Subject: [PATCH] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr The related functions are `gatherDataOperandAddrAndBounds` and `genBoundsOps`. The former is used in OpenACC as well, and it was updated to pass evaluate::Expr instead of parser objects. The difference in the test case comes from unfolded conversions of index expressions, which are explicitly of type integer(kind=8). Delete now unused `findRepeatableClause2` and `findClause2`. Add `AsGenericExpr` that takes std::optional. It already returns optional Expr. Making it accept an optional Expr as input would reduce the number of necessary checks when handling frequent optional values in evaluator. --- flang/include/flang/Evaluate/tools.h | 8 + flang/lib/Lower/DirectivesCommon.h | 389 --- flang/lib/Lower/OpenACC.cpp | 54 ++-- flang/lib/Lower/OpenMP.cpp | 105 +++- 4 files changed, 311 insertions(+), 245 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index e974944e88..d5713cfe420a2e 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -148,6 +148,14 @@ inline Expr AsGenericExpr(Expr &&x) { return std::move(x); } std::optional> AsGenericExpr(DataRef &&); std::optional> AsGenericExpr(const Symbol &); +// Propagate std::optional from input to output. +template +std::optional> AsGenericExpr(std::optional &&x) { + if (!x) +return std::nullopt; + return AsGenericExpr(std::move(*x)); +} + template common::IfNoLvalue::category>>, A> AsCategoryExpr( A &&x) { diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h index 8d560db34e05bf..2fa90572bc63eb 100644 --- a/flang/lib/Lower/DirectivesCommon.h +++ b/flang/lib/Lower/DirectivesCommon.h @@ -808,6 +808,75 @@ genBaseBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, return bounds; } +namespace detail { +template // +static T &&AsRvalueRef(T &&t) { + return std::move(t); +} +template // +static T AsRvalueRef(T &t) { + return t; +} +template // +static T AsRvalueRef(const T &t) { + return t; +} + +// Helper class for stripping enclosing parentheses and a conversion that +// preserves type category. This is used for triplet elements, which are +// always of type integer(kind=8). The lower/upper bounds are converted to +// an "index" type, which is 64-bit, so the explicit conversion to kind=8 +// (if present) is not needed. When it's present, though, it causes generated +// names to contain "int(..., kind=8)". +struct PeelConvert { + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Expr> + &expr) { +return std::visit( +[](auto &&s) { return visit_with_category(s); }, +expr.u); + } + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Convert, + Category> &expr) { +return AsGenericExpr(AsRvalueRef(expr.left())); + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + + template + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr> +&expr) { +return std::visit([](auto &&s) { return visit_with_category(s); }, + expr.u); + } + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr &expr) { +return std::visit([](auto &&s) { return visit(s); }, expr.u); + } + template // + static Fortran::semantics::MaybeExpr visit(const T &) { +return std::nullopt; + } +}; + +static Fortran::semantics::SomeExpr +peelOuterConvert(Fortran::semantics::SomeExpr &expr) { + if (auto peeled = PeelConvert::visit(expr)) +return *peeled; + return expr; +} +} // namespace detail + /// Generate bounds operations for an array section when subscripts are /// provided. template @@ -815,7 +884,7 @@ llvm::SmallVector genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext &stmtCtx, - const std::list &subscripts, + const std::vector &subscripts, std::stringstream &asFortran, fir::ExtendedValue &dataExv, bool dataExvIsAssumedSize, AddrAndBoundsInfo &info, bool treatIndexAsSection = false) { @@ -828,8 +897,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1)
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81623 >From 841f10e44e5ec5cfc6b166421f878089a17c623c Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 6 Feb 2024 17:06:29 -0600 Subject: [PATCH] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProcessor Rename `findRepeatableClause` to `findRepeatableClause2`, and make the new `findRepeatableClause` operate on new `omp::Clause` objects. Leave `Map` unchanged, because it will require more changes for it to work. --- flang/include/flang/Evaluate/tools.h | 23 + flang/lib/Lower/OpenMP.cpp | 632 +-- 2 files changed, 328 insertions(+), 327 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index d257da1a709642..e974944e88 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -430,6 +430,29 @@ template std::optional ExtractCoarrayRef(const A &x) { } } +struct ExtractSubstringHelper { + template static std::optional visit(T &&) { +return std::nullopt; + } + + static std::optional visit(const Substring &e) { return e; } + + template + static std::optional visit(const Designator &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } + + template + static std::optional visit(const Expr &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } +}; + +template +std::optional ExtractSubstring(const A &x) { + return ExtractSubstringHelper::visit(x); +} + // If an expression is simply a whole symbol data designator, // extract and return that symbol, else null. template const Symbol *UnwrapWholeSymbolDataRef(const A &x) { diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 4156887c8ff531..caae5c0cef9251 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -72,9 +72,9 @@ getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) { return sym; } -static void genObjectList(const Fortran::parser::OmpObjectList &objectList, - Fortran::lower::AbstractConverter &converter, - llvm::SmallVectorImpl &operands) { +static void genObjectList2(const Fortran::parser::OmpObjectList &objectList, + Fortran::lower::AbstractConverter &converter, + llvm::SmallVectorImpl &operands) { auto addOperands = [&](Fortran::lower::SymbolRef sym) { const mlir::Value variable = converter.getSymbolAddress(sym); if (variable) { @@ -93,27 +93,6 @@ static void genObjectList(const Fortran::parser::OmpObjectList &objectList, } } -static void gatherFuncAndVarSyms( -const Fortran::parser::OmpObjectList &objList, -mlir::omp::DeclareTargetCaptureClause clause, -llvm::SmallVectorImpl &symbolAndClause) { - for (const Fortran::parser::OmpObject &ompObject : objList.v) { -Fortran::common::visit( -Fortran::common::visitors{ -[&](const Fortran::parser::Designator &designator) { - if (const Fortran::parser::Name *name = - Fortran::semantics::getDesignatorNameIfDataRef( - designator)) { -symbolAndClause.emplace_back(clause, *name->symbol); - } -}, -[&](const Fortran::parser::Name &name) { - symbolAndClause.emplace_back(clause, *name.symbol); -}}, -ompObject.u); - } -} - static Fortran::lower::pft::Evaluation * getCollapsedLoopEval(Fortran::lower::pft::Evaluation &eval, int collapseValue) { // Return the Evaluation of the innermost collapsed loop, or the current one @@ -1258,6 +1237,32 @@ List makeList(const parser::OmpClauseList &clauses, } } // namespace omp +static void genObjectList(const omp::ObjectList &objects, + Fortran::lower::AbstractConverter &converter, + llvm::SmallVectorImpl &operands) { + for (const omp::Object &object : objects) { +const Fortran::semantics::Symbol *sym = object.sym; +assert(sym && "Expected Symbol"); +if (mlir::Value variable = converter.getSymbolAddress(*sym)) { + operands.push_back(variable); +} else { + if (const auto *details = + sym->detailsIf()) { +operands.push_back(converter.getSymbolAddress(details->symbol())); +converter.copySymbolBinding(details->symbol(), *sym); + } +} + } +} + +static void gatherFuncAndVarSyms( +const omp::ObjectList &objects, +mlir::omp::DeclareTargetCaptureClause clause, +llvm::SmallVectorImpl &symbolAndClause) { + for (const omp::Object &object : objects) +symbolAndClause.emplace_back(clause, *object.sym); +} + //===--===// // DataSharingProcessor //===--===// @
[llvm-branch-commits] [flang] [llvm] [flang][OpenMP] Main splitting functionality dev-complete (PR #82003)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/82003 [flang][OpenMP] TableGen support for getting leaf constructs Implement getLeafConstructs(D), which for a composite directive D will return the list of the constituent leaf directives. [flang][OpenMP] Set OpenMP attributes in MLIR module in bbc before lowering Right now attributes like OpenMP version or target attributes for offload are set after lowering in bbc. The flang frontend sets them before lowering, making them available in the lowering process. This change sets them before lowering in bbc as well. getOpenMPVersion >From ac2d8fd31c0a2b8f818a73a619496d5263c3ccb8 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 16 Jan 2024 16:40:47 -0600 Subject: [PATCH] [flang][OpenMP] Main splitting functionality dev-complete [flang][OpenMP] TableGen support for getting leaf constructs Implement getLeafConstructs(D), which for a composite directive D will return the list of the constituent leaf directives. [flang][OpenMP] Set OpenMP attributes in MLIR module in bbc before lowering Right now attributes like OpenMP version or target attributes for offload are set after lowering in bbc. The flang frontend sets them before lowering, making them available in the lowering process. This change sets them before lowering in bbc as well. getOpenMPVersion --- flang/lib/Lower/OpenMP.cpp| 1044 - flang/tools/bbc/bbc.cpp |2 +- .../llvm/Frontend/Directive/DirectiveBase.td |4 + llvm/include/llvm/Frontend/OpenMP/OMP.td | 60 +- llvm/include/llvm/TableGen/DirectiveEmitter.h |4 + llvm/utils/TableGen/DirectiveEmitter.cpp | 77 ++ 6 files changed, 1174 insertions(+), 17 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index e45ab842b15556..ed6a0063848b18 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -31,6 +31,7 @@ #include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "mlir/Dialect/SCF/IR/SCF.h" #include "mlir/Transforms/RegionUtils.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" #include "llvm/Support/CommandLine.h" @@ -48,6 +49,29 @@ using DeclareTargetCapturePair = // Common helper functions //===--===// +static llvm::ArrayRef getWorksharing() { + static llvm::omp::Directive worksharing[] = { + llvm::omp::Directive::OMPD_do, llvm::omp::Directive::OMPD_for, + llvm::omp::Directive::OMPD_scope, llvm::omp::Directive::OMPD_sections, + llvm::omp::Directive::OMPD_single, llvm::omp::Directive::OMPD_workshare, + }; + return worksharing; +} + +static llvm::ArrayRef getWorksharingLoop() { + static llvm::omp::Directive worksharingLoop[] = { + llvm::omp::Directive::OMPD_do, + llvm::omp::Directive::OMPD_for, + }; + return worksharingLoop; +} + +static uint32_t getOpenMPVersion(const mlir::ModuleOp &mod) { + if (mlir::Attribute verAttr = mod->getAttr("omp.version")) +return llvm::cast(verAttr).getVersion(); + llvm_unreachable("Exoecting OpenMP version attribute in module"); +} + static Fortran::semantics::Symbol * getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) { Fortran::semantics::Symbol *sym = nullptr; @@ -166,6 +190,15 @@ struct SymDsgExtractor { return t; } + static semantics::Symbol *symbol_addr(const evaluate::SymbolRef &ref) { +// Symbols cannot be created after semantic checks, so all symbol +// pointers that are non-null must point to one of those pre-existing +// objects. Throughout the code, symbols are often pointed to by +// non-const pointers, so there is no harm in casting the constness +// away. +return const_cast(&ref.get()); + } + template // static SymDsg visit(T &&) { // Use this to see missing overloads: @@ -175,19 +208,12 @@ struct SymDsgExtractor { template // static SymDsg visit(const evaluate::Designator &e) { -// Symbols cannot be created after semantic checks, so all symbol -// pointers that are non-null must point to one of those pre-existing -// objects. Throughout the code, symbols are often pointed to by -// non-const pointers, so there is no harm in casting the constness -// away. -return std::make_tuple(const_cast(e.GetLastSymbol()), +return std::make_tuple(symbol_addr(*e.GetLastSymbol()), evaluate::AsGenericExpr(AsRvalueRef(e))); } static SymDsg visit(const evaluate::ProcedureDesignator &e) { -// See comment above regarding const_cast. -return std::make_tuple(const_cast(e.GetSymbol()), - std::nullopt); +return std::make_tuple(symbol_addr(*e.GetSymbol()), std::nullopt); } template // @@ -313,6 +339,42 @@ std::optional maybeApply(F &&func, const std::optional &inp) { return std
[llvm-branch-commits] [flang] [llvm] [flang][OpenMP] Main splitting functionality dev-complete (PR #82003)
https://github.com/kparzysz converted_to_draft https://github.com/llvm/llvm-project/pull/82003 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [flang][OpenMP] Main splitting functionality dev-complete (PR #82003)
kparzysz wrote: This is a follow-up to the [previous draft](https://github.com/llvm/llvm-project/pull/80059), based on the clause-representation stack. https://github.com/llvm/llvm-project/pull/82003 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [flang][OpenMP] Main splitting functionality dev-complete (PR #82003)
https://github.com/kparzysz edited https://github.com/llvm/llvm-project/pull/82003 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert unique clauses in ClauseProcessor (PR #81622)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81622 >From 57c70c53a3898d7fc45fd0a71368ae20fe8a1a85 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 6 Feb 2024 17:06:29 -0600 Subject: [PATCH] [flang][OpenMP] Convert unique clauses in ClauseProcessor Temporarily rename old clause list to `clauses2`, old clause iterator to `ClauseIterator2`. Change `findUniqueClause` to iterate over `omp::Clause` objects, modify all handlers to operate on 'omp::clause::xyz` equivalents. --- flang/lib/Lower/OpenMP.cpp | 242 + 1 file changed, 114 insertions(+), 128 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index ae3619609b80ff..4156887c8ff531 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1670,7 +1670,8 @@ class ClauseProcessor { ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses(clauses) {} + : converter(converter), semaCtx(semaCtx), clauses2(clauses), +clauses(omp::makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. bool @@ -1770,7 +1771,8 @@ class ClauseProcessor { llvm::omp::Directive directive) const; private: - using ClauseIterator = std::list::const_iterator; + using ClauseIterator = omp::List::const_iterator; + using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -1783,14 +1785,26 @@ class ClauseProcessor { return end; } + /// Utility to find a clause within a range in the clause list. + template + static ClauseIterator2 findClause2(ClauseIterator2 begin, + ClauseIterator2 end) { +for (ClauseIterator2 it = begin; it != end; ++it) { + if (std::get_if(&it->u)) +return it; +} + +return end; + } + /// Return the first instance of the given clause found in the clause list or /// `nullptr` if not present. If more than one instance is expected, use /// `findRepeatableClause` instead. template const T * findUniqueClause(const Fortran::parser::CharBlock **source = nullptr) const { -ClauseIterator it = findClause(clauses.v.begin(), clauses.v.end()); -if (it != clauses.v.end()) { +ClauseIterator it = findClause(clauses.begin(), clauses.end()); +if (it != clauses.end()) { if (source) *source = &it->source; return &std::get(it->u); @@ -1805,9 +1819,9 @@ class ClauseProcessor { std::function callbackFn) const { bool found = false; -ClauseIterator nextIt, endIt = clauses.v.end(); -for (ClauseIterator it = clauses.v.begin(); it != endIt; it = nextIt) { - nextIt = findClause(it, endIt); +ClauseIterator2 nextIt, endIt = clauses2.v.end(); +for (ClauseIterator2 it = clauses2.v.begin(); it != endIt; it = nextIt) { + nextIt = findClause2(it, endIt); if (nextIt != endIt) { callbackFn(&std::get(nextIt->u), nextIt->source); @@ -1830,7 +1844,8 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses; + const Fortran::parser::OmpClauseList &clauses2; + omp::List clauses; }; //===--===// @@ -2295,64 +2310,55 @@ class ReductionProcessor { }; static mlir::omp::ScheduleModifier -translateScheduleModifier(const Fortran::parser::OmpScheduleModifierType &m) { - switch (m.v) { - case Fortran::parser::OmpScheduleModifierType::ModType::Monotonic: +translateScheduleModifier(const omp::clause::Schedule::ModType &m) { + switch (m) { + case omp::clause::Schedule::ModType::Monotonic: return mlir::omp::ScheduleModifier::monotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Nonmonotonic: + case omp::clause::Schedule::ModType::Nonmonotonic: return mlir::omp::ScheduleModifier::nonmonotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Simd: + case omp::clause::Schedule::ModType::Simd: return mlir::omp::ScheduleModifier::simd; } return mlir::omp::ScheduleModifier::none; } static mlir::omp::ScheduleModifier -getScheduleModifier(const Fortran::parser::OmpScheduleClause &x) { - const auto &modifier = - std::get>(x.t); +getScheduleModifier(const omp::clause::Schedule &clause) { + using ScheduleModifier = omp::clause::Schedule::ScheduleModifier; + const auto &modifier = std::get>(clause.t); // The input may have the modifier any order, so we look for one that isn't // SIMD. If modifier is not set at all, fall down to the bottom and return // "none". if (modifier) { -
[llvm-branch-commits] [flang] [flang][OpenMP] Convert processTODO and remove unused objects (PR #81627)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81627 >From 1299d5190a3c273d2af4ab8c7f800af7df4e4ef6 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 9 Feb 2024 15:03:54 -0600 Subject: [PATCH] [flang][OpenMP] Convert processTODO and remove unused objects Remove `ClauseIterator2` and `clauses2` from ClauseProcessor. --- flang/lib/Lower/OpenMP.cpp | 75 ++ 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 4309d69434839f..51ed0fe03dbe38 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1669,13 +1669,11 @@ void DataSharingProcessor::defaultPrivatize() { /// methods that relate to clauses that can impact the lowering of that /// construct. class ClauseProcessor { - using ClauseTy = Fortran::parser::OmpClause; - public: ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses2(clauses), + : converter(converter), semaCtx(semaCtx), clauses(omp::makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. @@ -1776,7 +1774,6 @@ class ClauseProcessor { private: using ClauseIterator = omp::List::const_iterator; - using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -1836,7 +1833,6 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses2; omp::List clauses; }; @@ -3132,19 +3128,17 @@ bool ClauseProcessor::processMotionClauses( template void ClauseProcessor::processTODO(mlir::Location currentLocation, llvm::omp::Directive directive) const { - auto checkUnhandledClause = [&](const auto *x) { + auto checkUnhandledClause = [&](llvm::omp::Clause id, const auto *x) { if (!x) return; TODO(currentLocation, - "Unhandled clause " + - llvm::StringRef(Fortran::parser::ParseTreeDumper::GetNodeName(*x)) - .upper() + + "Unhandled clause " + llvm::omp::getOpenMPClauseName(id).upper() + " in " + llvm::omp::getOpenMPDirectiveName(directive).upper() + " construct"); }; - for (ClauseIterator2 it = clauses2.v.begin(); it != clauses2.v.end(); ++it) -(checkUnhandledClause(std::get_if(&it->u)), ...); + for (ClauseIterator it = clauses.begin(); it != clauses.end(); ++it) +(checkUnhandledClause(it->id, std::get_if(&it->u)), ...); } //===--===// @@ -3723,8 +3717,8 @@ genSingleOp(Fortran::lower::AbstractConverter &converter, ClauseProcessor cp(converter, semaCtx, beginClauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_single); + cp.processTODO(currentLocation, + llvm::omp::Directive::OMPD_single); ClauseProcessor(converter, semaCtx, endClauseList).processNowait(nowaitAttr); @@ -3757,10 +3751,9 @@ genTaskOp(Fortran::lower::AbstractConverter &converter, cp.processMergeable(mergeableAttr); cp.processPriority(stmtCtx, priorityClauseOperand); cp.processDepend(dependTypeOperands, dependOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_task); + cp.processTODO(currentLocation, +llvm::omp::Directive::OMPD_task); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) @@ -3785,7 +3778,7 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter, llvm::SmallVector allocateOperands, allocatorOperands; ClauseProcessor cp(converter, semaCtx, clauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( + cp.processTODO( currentLocation, llvm::omp::Directive::OMPD_taskgroup); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) @@ -3869,8 +3862,7 @@ genEnterExitUpdateDataOp(Fortran::lower::AbstractConverter &converter, cp.processMap(currentLocation, directive, stmtCtx, mapOperands); } - cp.processTODO(currentLocation, - directive); + cp.processTODO(currentLocation, directive); return firOpBuilder.create(currentLocation, ifClauseOperand, deviceOperand, nullptr, mlir::ValueRange(), @@ -4053,16 +4045,11 @@ genTargetOp(Fortran::lower::AbstractConverter &converter, cp.processNowait(nowaitAttr); cp.processMap(currentLocation, directive, stmt
[llvm-branch-commits] [flang] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr (PR #81626)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81626 >From 87437159da37749ad395d84a3fc1b729bd9e2480 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 8 Feb 2024 08:33:40 -0600 Subject: [PATCH] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr The related functions are `gatherDataOperandAddrAndBounds` and `genBoundsOps`. The former is used in OpenACC as well, and it was updated to pass evaluate::Expr instead of parser objects. The difference in the test case comes from unfolded conversions of index expressions, which are explicitly of type integer(kind=8). Delete now unused `findRepeatableClause2` and `findClause2`. Add `AsGenericExpr` that takes std::optional. It already returns optional Expr. Making it accept an optional Expr as input would reduce the number of necessary checks when handling frequent optional values in evaluator. --- flang/include/flang/Evaluate/tools.h | 8 + flang/lib/Lower/DirectivesCommon.h | 389 --- flang/lib/Lower/OpenACC.cpp | 54 ++-- flang/lib/Lower/OpenMP.cpp | 105 +++- 4 files changed, 311 insertions(+), 245 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index e974944e88..d5713cfe420a2e 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -148,6 +148,14 @@ inline Expr AsGenericExpr(Expr &&x) { return std::move(x); } std::optional> AsGenericExpr(DataRef &&); std::optional> AsGenericExpr(const Symbol &); +// Propagate std::optional from input to output. +template +std::optional> AsGenericExpr(std::optional &&x) { + if (!x) +return std::nullopt; + return AsGenericExpr(std::move(*x)); +} + template common::IfNoLvalue::category>>, A> AsCategoryExpr( A &&x) { diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h index 8d560db34e05bf..2fa90572bc63eb 100644 --- a/flang/lib/Lower/DirectivesCommon.h +++ b/flang/lib/Lower/DirectivesCommon.h @@ -808,6 +808,75 @@ genBaseBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, return bounds; } +namespace detail { +template // +static T &&AsRvalueRef(T &&t) { + return std::move(t); +} +template // +static T AsRvalueRef(T &t) { + return t; +} +template // +static T AsRvalueRef(const T &t) { + return t; +} + +// Helper class for stripping enclosing parentheses and a conversion that +// preserves type category. This is used for triplet elements, which are +// always of type integer(kind=8). The lower/upper bounds are converted to +// an "index" type, which is 64-bit, so the explicit conversion to kind=8 +// (if present) is not needed. When it's present, though, it causes generated +// names to contain "int(..., kind=8)". +struct PeelConvert { + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Expr> + &expr) { +return std::visit( +[](auto &&s) { return visit_with_category(s); }, +expr.u); + } + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Convert, + Category> &expr) { +return AsGenericExpr(AsRvalueRef(expr.left())); + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + + template + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr> +&expr) { +return std::visit([](auto &&s) { return visit_with_category(s); }, + expr.u); + } + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr &expr) { +return std::visit([](auto &&s) { return visit(s); }, expr.u); + } + template // + static Fortran::semantics::MaybeExpr visit(const T &) { +return std::nullopt; + } +}; + +static Fortran::semantics::SomeExpr +peelOuterConvert(Fortran::semantics::SomeExpr &expr) { + if (auto peeled = PeelConvert::visit(expr)) +return *peeled; + return expr; +} +} // namespace detail + /// Generate bounds operations for an array section when subscripts are /// provided. template @@ -815,7 +884,7 @@ llvm::SmallVector genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext &stmtCtx, - const std::list &subscripts, + const std::vector &subscripts, std::stringstream &asFortran, fir::ExtendedValue &dataExv, bool dataExvIsAssumedSize, AddrAndBoundsInfo &info, bool treatIndexAsSection = false) { @@ -828,8 +897,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1)
[llvm-branch-commits] [flang] [flang][OpenMP] Convert unique clauses in ClauseProcessor (PR #81622)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81622 >From 57c70c53a3898d7fc45fd0a71368ae20fe8a1a85 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 6 Feb 2024 17:06:29 -0600 Subject: [PATCH] [flang][OpenMP] Convert unique clauses in ClauseProcessor Temporarily rename old clause list to `clauses2`, old clause iterator to `ClauseIterator2`. Change `findUniqueClause` to iterate over `omp::Clause` objects, modify all handlers to operate on 'omp::clause::xyz` equivalents. --- flang/lib/Lower/OpenMP.cpp | 242 + 1 file changed, 114 insertions(+), 128 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index ae3619609b80ff..4156887c8ff531 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1670,7 +1670,8 @@ class ClauseProcessor { ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses(clauses) {} + : converter(converter), semaCtx(semaCtx), clauses2(clauses), +clauses(omp::makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. bool @@ -1770,7 +1771,8 @@ class ClauseProcessor { llvm::omp::Directive directive) const; private: - using ClauseIterator = std::list::const_iterator; + using ClauseIterator = omp::List::const_iterator; + using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -1783,14 +1785,26 @@ class ClauseProcessor { return end; } + /// Utility to find a clause within a range in the clause list. + template + static ClauseIterator2 findClause2(ClauseIterator2 begin, + ClauseIterator2 end) { +for (ClauseIterator2 it = begin; it != end; ++it) { + if (std::get_if(&it->u)) +return it; +} + +return end; + } + /// Return the first instance of the given clause found in the clause list or /// `nullptr` if not present. If more than one instance is expected, use /// `findRepeatableClause` instead. template const T * findUniqueClause(const Fortran::parser::CharBlock **source = nullptr) const { -ClauseIterator it = findClause(clauses.v.begin(), clauses.v.end()); -if (it != clauses.v.end()) { +ClauseIterator it = findClause(clauses.begin(), clauses.end()); +if (it != clauses.end()) { if (source) *source = &it->source; return &std::get(it->u); @@ -1805,9 +1819,9 @@ class ClauseProcessor { std::function callbackFn) const { bool found = false; -ClauseIterator nextIt, endIt = clauses.v.end(); -for (ClauseIterator it = clauses.v.begin(); it != endIt; it = nextIt) { - nextIt = findClause(it, endIt); +ClauseIterator2 nextIt, endIt = clauses2.v.end(); +for (ClauseIterator2 it = clauses2.v.begin(); it != endIt; it = nextIt) { + nextIt = findClause2(it, endIt); if (nextIt != endIt) { callbackFn(&std::get(nextIt->u), nextIt->source); @@ -1830,7 +1844,8 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses; + const Fortran::parser::OmpClauseList &clauses2; + omp::List clauses; }; //===--===// @@ -2295,64 +2310,55 @@ class ReductionProcessor { }; static mlir::omp::ScheduleModifier -translateScheduleModifier(const Fortran::parser::OmpScheduleModifierType &m) { - switch (m.v) { - case Fortran::parser::OmpScheduleModifierType::ModType::Monotonic: +translateScheduleModifier(const omp::clause::Schedule::ModType &m) { + switch (m) { + case omp::clause::Schedule::ModType::Monotonic: return mlir::omp::ScheduleModifier::monotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Nonmonotonic: + case omp::clause::Schedule::ModType::Nonmonotonic: return mlir::omp::ScheduleModifier::nonmonotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Simd: + case omp::clause::Schedule::ModType::Simd: return mlir::omp::ScheduleModifier::simd; } return mlir::omp::ScheduleModifier::none; } static mlir::omp::ScheduleModifier -getScheduleModifier(const Fortran::parser::OmpScheduleClause &x) { - const auto &modifier = - std::get>(x.t); +getScheduleModifier(const omp::clause::Schedule &clause) { + using ScheduleModifier = omp::clause::Schedule::ScheduleModifier; + const auto &modifier = std::get>(clause.t); // The input may have the modifier any order, so we look for one that isn't // SIMD. If modifier is not set at all, fall down to the bottom and return // "none". if (modifier) { -
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81623 >From 841f10e44e5ec5cfc6b166421f878089a17c623c Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 6 Feb 2024 17:06:29 -0600 Subject: [PATCH] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProcessor Rename `findRepeatableClause` to `findRepeatableClause2`, and make the new `findRepeatableClause` operate on new `omp::Clause` objects. Leave `Map` unchanged, because it will require more changes for it to work. --- flang/include/flang/Evaluate/tools.h | 23 + flang/lib/Lower/OpenMP.cpp | 632 +-- 2 files changed, 328 insertions(+), 327 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index d257da1a709642..e974944e88 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -430,6 +430,29 @@ template std::optional ExtractCoarrayRef(const A &x) { } } +struct ExtractSubstringHelper { + template static std::optional visit(T &&) { +return std::nullopt; + } + + static std::optional visit(const Substring &e) { return e; } + + template + static std::optional visit(const Designator &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } + + template + static std::optional visit(const Expr &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } +}; + +template +std::optional ExtractSubstring(const A &x) { + return ExtractSubstringHelper::visit(x); +} + // If an expression is simply a whole symbol data designator, // extract and return that symbol, else null. template const Symbol *UnwrapWholeSymbolDataRef(const A &x) { diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 4156887c8ff531..caae5c0cef9251 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -72,9 +72,9 @@ getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) { return sym; } -static void genObjectList(const Fortran::parser::OmpObjectList &objectList, - Fortran::lower::AbstractConverter &converter, - llvm::SmallVectorImpl &operands) { +static void genObjectList2(const Fortran::parser::OmpObjectList &objectList, + Fortran::lower::AbstractConverter &converter, + llvm::SmallVectorImpl &operands) { auto addOperands = [&](Fortran::lower::SymbolRef sym) { const mlir::Value variable = converter.getSymbolAddress(sym); if (variable) { @@ -93,27 +93,6 @@ static void genObjectList(const Fortran::parser::OmpObjectList &objectList, } } -static void gatherFuncAndVarSyms( -const Fortran::parser::OmpObjectList &objList, -mlir::omp::DeclareTargetCaptureClause clause, -llvm::SmallVectorImpl &symbolAndClause) { - for (const Fortran::parser::OmpObject &ompObject : objList.v) { -Fortran::common::visit( -Fortran::common::visitors{ -[&](const Fortran::parser::Designator &designator) { - if (const Fortran::parser::Name *name = - Fortran::semantics::getDesignatorNameIfDataRef( - designator)) { -symbolAndClause.emplace_back(clause, *name->symbol); - } -}, -[&](const Fortran::parser::Name &name) { - symbolAndClause.emplace_back(clause, *name.symbol); -}}, -ompObject.u); - } -} - static Fortran::lower::pft::Evaluation * getCollapsedLoopEval(Fortran::lower::pft::Evaluation &eval, int collapseValue) { // Return the Evaluation of the innermost collapsed loop, or the current one @@ -1258,6 +1237,32 @@ List makeList(const parser::OmpClauseList &clauses, } } // namespace omp +static void genObjectList(const omp::ObjectList &objects, + Fortran::lower::AbstractConverter &converter, + llvm::SmallVectorImpl &operands) { + for (const omp::Object &object : objects) { +const Fortran::semantics::Symbol *sym = object.sym; +assert(sym && "Expected Symbol"); +if (mlir::Value variable = converter.getSymbolAddress(*sym)) { + operands.push_back(variable); +} else { + if (const auto *details = + sym->detailsIf()) { +operands.push_back(converter.getSymbolAddress(details->symbol())); +converter.copySymbolBinding(details->symbol(), *sym); + } +} + } +} + +static void gatherFuncAndVarSyms( +const omp::ObjectList &objects, +mlir::omp::DeclareTargetCaptureClause clause, +llvm::SmallVectorImpl &symbolAndClause) { + for (const omp::Object &object : objects) +symbolAndClause.emplace_back(clause, *object.sym); +} + //===--===// // DataSharingProcessor //===--===// @
[llvm-branch-commits] [flang] [flang][OpenMP] Convert processTODO and remove unused objects (PR #81627)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81627 >From 1299d5190a3c273d2af4ab8c7f800af7df4e4ef6 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 9 Feb 2024 15:03:54 -0600 Subject: [PATCH] [flang][OpenMP] Convert processTODO and remove unused objects Remove `ClauseIterator2` and `clauses2` from ClauseProcessor. --- flang/lib/Lower/OpenMP.cpp | 75 ++ 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 4309d69434839f..51ed0fe03dbe38 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -1669,13 +1669,11 @@ void DataSharingProcessor::defaultPrivatize() { /// methods that relate to clauses that can impact the lowering of that /// construct. class ClauseProcessor { - using ClauseTy = Fortran::parser::OmpClause; - public: ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses2(clauses), + : converter(converter), semaCtx(semaCtx), clauses(omp::makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. @@ -1776,7 +1774,6 @@ class ClauseProcessor { private: using ClauseIterator = omp::List::const_iterator; - using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -1836,7 +1833,6 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses2; omp::List clauses; }; @@ -3132,19 +3128,17 @@ bool ClauseProcessor::processMotionClauses( template void ClauseProcessor::processTODO(mlir::Location currentLocation, llvm::omp::Directive directive) const { - auto checkUnhandledClause = [&](const auto *x) { + auto checkUnhandledClause = [&](llvm::omp::Clause id, const auto *x) { if (!x) return; TODO(currentLocation, - "Unhandled clause " + - llvm::StringRef(Fortran::parser::ParseTreeDumper::GetNodeName(*x)) - .upper() + + "Unhandled clause " + llvm::omp::getOpenMPClauseName(id).upper() + " in " + llvm::omp::getOpenMPDirectiveName(directive).upper() + " construct"); }; - for (ClauseIterator2 it = clauses2.v.begin(); it != clauses2.v.end(); ++it) -(checkUnhandledClause(std::get_if(&it->u)), ...); + for (ClauseIterator it = clauses.begin(); it != clauses.end(); ++it) +(checkUnhandledClause(it->id, std::get_if(&it->u)), ...); } //===--===// @@ -3723,8 +3717,8 @@ genSingleOp(Fortran::lower::AbstractConverter &converter, ClauseProcessor cp(converter, semaCtx, beginClauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_single); + cp.processTODO(currentLocation, + llvm::omp::Directive::OMPD_single); ClauseProcessor(converter, semaCtx, endClauseList).processNowait(nowaitAttr); @@ -3757,10 +3751,9 @@ genTaskOp(Fortran::lower::AbstractConverter &converter, cp.processMergeable(mergeableAttr); cp.processPriority(stmtCtx, priorityClauseOperand); cp.processDepend(dependTypeOperands, dependOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_task); + cp.processTODO(currentLocation, +llvm::omp::Directive::OMPD_task); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) @@ -3785,7 +3778,7 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter, llvm::SmallVector allocateOperands, allocatorOperands; ClauseProcessor cp(converter, semaCtx, clauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( + cp.processTODO( currentLocation, llvm::omp::Directive::OMPD_taskgroup); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) @@ -3869,8 +3862,7 @@ genEnterExitUpdateDataOp(Fortran::lower::AbstractConverter &converter, cp.processMap(currentLocation, directive, stmtCtx, mapOperands); } - cp.processTODO(currentLocation, - directive); + cp.processTODO(currentLocation, directive); return firOpBuilder.create(currentLocation, ifClauseOperand, deviceOperand, nullptr, mlir::ValueRange(), @@ -4053,16 +4045,11 @@ genTargetOp(Fortran::lower::AbstractConverter &converter, cp.processNowait(nowaitAttr); cp.processMap(currentLocation, directive, stmt
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81623 >From 841f10e44e5ec5cfc6b166421f878089a17c623c Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 6 Feb 2024 17:06:29 -0600 Subject: [PATCH] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProcessor Rename `findRepeatableClause` to `findRepeatableClause2`, and make the new `findRepeatableClause` operate on new `omp::Clause` objects. Leave `Map` unchanged, because it will require more changes for it to work. --- flang/include/flang/Evaluate/tools.h | 23 + flang/lib/Lower/OpenMP.cpp | 632 +-- 2 files changed, 328 insertions(+), 327 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index d257da1a709642..e974944e88 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -430,6 +430,29 @@ template std::optional ExtractCoarrayRef(const A &x) { } } +struct ExtractSubstringHelper { + template static std::optional visit(T &&) { +return std::nullopt; + } + + static std::optional visit(const Substring &e) { return e; } + + template + static std::optional visit(const Designator &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } + + template + static std::optional visit(const Expr &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } +}; + +template +std::optional ExtractSubstring(const A &x) { + return ExtractSubstringHelper::visit(x); +} + // If an expression is simply a whole symbol data designator, // extract and return that symbol, else null. template const Symbol *UnwrapWholeSymbolDataRef(const A &x) { diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index 4156887c8ff531..caae5c0cef9251 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -72,9 +72,9 @@ getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) { return sym; } -static void genObjectList(const Fortran::parser::OmpObjectList &objectList, - Fortran::lower::AbstractConverter &converter, - llvm::SmallVectorImpl &operands) { +static void genObjectList2(const Fortran::parser::OmpObjectList &objectList, + Fortran::lower::AbstractConverter &converter, + llvm::SmallVectorImpl &operands) { auto addOperands = [&](Fortran::lower::SymbolRef sym) { const mlir::Value variable = converter.getSymbolAddress(sym); if (variable) { @@ -93,27 +93,6 @@ static void genObjectList(const Fortran::parser::OmpObjectList &objectList, } } -static void gatherFuncAndVarSyms( -const Fortran::parser::OmpObjectList &objList, -mlir::omp::DeclareTargetCaptureClause clause, -llvm::SmallVectorImpl &symbolAndClause) { - for (const Fortran::parser::OmpObject &ompObject : objList.v) { -Fortran::common::visit( -Fortran::common::visitors{ -[&](const Fortran::parser::Designator &designator) { - if (const Fortran::parser::Name *name = - Fortran::semantics::getDesignatorNameIfDataRef( - designator)) { -symbolAndClause.emplace_back(clause, *name->symbol); - } -}, -[&](const Fortran::parser::Name &name) { - symbolAndClause.emplace_back(clause, *name.symbol); -}}, -ompObject.u); - } -} - static Fortran::lower::pft::Evaluation * getCollapsedLoopEval(Fortran::lower::pft::Evaluation &eval, int collapseValue) { // Return the Evaluation of the innermost collapsed loop, or the current one @@ -1258,6 +1237,32 @@ List makeList(const parser::OmpClauseList &clauses, } } // namespace omp +static void genObjectList(const omp::ObjectList &objects, + Fortran::lower::AbstractConverter &converter, + llvm::SmallVectorImpl &operands) { + for (const omp::Object &object : objects) { +const Fortran::semantics::Symbol *sym = object.sym; +assert(sym && "Expected Symbol"); +if (mlir::Value variable = converter.getSymbolAddress(*sym)) { + operands.push_back(variable); +} else { + if (const auto *details = + sym->detailsIf()) { +operands.push_back(converter.getSymbolAddress(details->symbol())); +converter.copySymbolBinding(details->symbol(), *sym); + } +} + } +} + +static void gatherFuncAndVarSyms( +const omp::ObjectList &objects, +mlir::omp::DeclareTargetCaptureClause clause, +llvm::SmallVectorImpl &symbolAndClause) { + for (const omp::Object &object : objects) +symbolAndClause.emplace_back(clause, *object.sym); +} + //===--===// // DataSharingProcessor //===--===// @
[llvm-branch-commits] [flang] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr (PR #81626)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81626 >From 87437159da37749ad395d84a3fc1b729bd9e2480 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 8 Feb 2024 08:33:40 -0600 Subject: [PATCH] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr The related functions are `gatherDataOperandAddrAndBounds` and `genBoundsOps`. The former is used in OpenACC as well, and it was updated to pass evaluate::Expr instead of parser objects. The difference in the test case comes from unfolded conversions of index expressions, which are explicitly of type integer(kind=8). Delete now unused `findRepeatableClause2` and `findClause2`. Add `AsGenericExpr` that takes std::optional. It already returns optional Expr. Making it accept an optional Expr as input would reduce the number of necessary checks when handling frequent optional values in evaluator. --- flang/include/flang/Evaluate/tools.h | 8 + flang/lib/Lower/DirectivesCommon.h | 389 --- flang/lib/Lower/OpenACC.cpp | 54 ++-- flang/lib/Lower/OpenMP.cpp | 105 +++- 4 files changed, 311 insertions(+), 245 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index e974944e88..d5713cfe420a2e 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -148,6 +148,14 @@ inline Expr AsGenericExpr(Expr &&x) { return std::move(x); } std::optional> AsGenericExpr(DataRef &&); std::optional> AsGenericExpr(const Symbol &); +// Propagate std::optional from input to output. +template +std::optional> AsGenericExpr(std::optional &&x) { + if (!x) +return std::nullopt; + return AsGenericExpr(std::move(*x)); +} + template common::IfNoLvalue::category>>, A> AsCategoryExpr( A &&x) { diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h index 8d560db34e05bf..2fa90572bc63eb 100644 --- a/flang/lib/Lower/DirectivesCommon.h +++ b/flang/lib/Lower/DirectivesCommon.h @@ -808,6 +808,75 @@ genBaseBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, return bounds; } +namespace detail { +template // +static T &&AsRvalueRef(T &&t) { + return std::move(t); +} +template // +static T AsRvalueRef(T &t) { + return t; +} +template // +static T AsRvalueRef(const T &t) { + return t; +} + +// Helper class for stripping enclosing parentheses and a conversion that +// preserves type category. This is used for triplet elements, which are +// always of type integer(kind=8). The lower/upper bounds are converted to +// an "index" type, which is 64-bit, so the explicit conversion to kind=8 +// (if present) is not needed. When it's present, though, it causes generated +// names to contain "int(..., kind=8)". +struct PeelConvert { + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Expr> + &expr) { +return std::visit( +[](auto &&s) { return visit_with_category(s); }, +expr.u); + } + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Convert, + Category> &expr) { +return AsGenericExpr(AsRvalueRef(expr.left())); + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + + template + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr> +&expr) { +return std::visit([](auto &&s) { return visit_with_category(s); }, + expr.u); + } + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr &expr) { +return std::visit([](auto &&s) { return visit(s); }, expr.u); + } + template // + static Fortran::semantics::MaybeExpr visit(const T &) { +return std::nullopt; + } +}; + +static Fortran::semantics::SomeExpr +peelOuterConvert(Fortran::semantics::SomeExpr &expr) { + if (auto peeled = PeelConvert::visit(expr)) +return *peeled; + return expr; +} +} // namespace detail + /// Generate bounds operations for an array section when subscripts are /// provided. template @@ -815,7 +884,7 @@ llvm::SmallVector genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext &stmtCtx, - const std::list &subscripts, + const std::vector &subscripts, std::stringstream &asFortran, fir::ExtendedValue &dataExv, bool dataExvIsAssumedSize, AddrAndBoundsInfo &info, bool treatIndexAsSection = false) { @@ -828,8 +897,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1)
[llvm-branch-commits] [flang] [llvm] [flang][OpenMP] Main splitting functionality dev-complete (PR #82003)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/82003 >From ac2d8fd31c0a2b8f818a73a619496d5263c3ccb8 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 16 Jan 2024 16:40:47 -0600 Subject: [PATCH 1/2] [flang][OpenMP] Main splitting functionality dev-complete [flang][OpenMP] TableGen support for getting leaf constructs Implement getLeafConstructs(D), which for a composite directive D will return the list of the constituent leaf directives. [flang][OpenMP] Set OpenMP attributes in MLIR module in bbc before lowering Right now attributes like OpenMP version or target attributes for offload are set after lowering in bbc. The flang frontend sets them before lowering, making them available in the lowering process. This change sets them before lowering in bbc as well. getOpenMPVersion --- flang/lib/Lower/OpenMP.cpp| 1044 - flang/tools/bbc/bbc.cpp |2 +- .../llvm/Frontend/Directive/DirectiveBase.td |4 + llvm/include/llvm/Frontend/OpenMP/OMP.td | 60 +- llvm/include/llvm/TableGen/DirectiveEmitter.h |4 + llvm/utils/TableGen/DirectiveEmitter.cpp | 77 ++ 6 files changed, 1174 insertions(+), 17 deletions(-) diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp index e45ab842b15556..ed6a0063848b18 100644 --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -31,6 +31,7 @@ #include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "mlir/Dialect/SCF/IR/SCF.h" #include "mlir/Transforms/RegionUtils.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" #include "llvm/Support/CommandLine.h" @@ -48,6 +49,29 @@ using DeclareTargetCapturePair = // Common helper functions //===--===// +static llvm::ArrayRef getWorksharing() { + static llvm::omp::Directive worksharing[] = { + llvm::omp::Directive::OMPD_do, llvm::omp::Directive::OMPD_for, + llvm::omp::Directive::OMPD_scope, llvm::omp::Directive::OMPD_sections, + llvm::omp::Directive::OMPD_single, llvm::omp::Directive::OMPD_workshare, + }; + return worksharing; +} + +static llvm::ArrayRef getWorksharingLoop() { + static llvm::omp::Directive worksharingLoop[] = { + llvm::omp::Directive::OMPD_do, + llvm::omp::Directive::OMPD_for, + }; + return worksharingLoop; +} + +static uint32_t getOpenMPVersion(const mlir::ModuleOp &mod) { + if (mlir::Attribute verAttr = mod->getAttr("omp.version")) +return llvm::cast(verAttr).getVersion(); + llvm_unreachable("Exoecting OpenMP version attribute in module"); +} + static Fortran::semantics::Symbol * getOmpObjectSymbol(const Fortran::parser::OmpObject &ompObject) { Fortran::semantics::Symbol *sym = nullptr; @@ -166,6 +190,15 @@ struct SymDsgExtractor { return t; } + static semantics::Symbol *symbol_addr(const evaluate::SymbolRef &ref) { +// Symbols cannot be created after semantic checks, so all symbol +// pointers that are non-null must point to one of those pre-existing +// objects. Throughout the code, symbols are often pointed to by +// non-const pointers, so there is no harm in casting the constness +// away. +return const_cast(&ref.get()); + } + template // static SymDsg visit(T &&) { // Use this to see missing overloads: @@ -175,19 +208,12 @@ struct SymDsgExtractor { template // static SymDsg visit(const evaluate::Designator &e) { -// Symbols cannot be created after semantic checks, so all symbol -// pointers that are non-null must point to one of those pre-existing -// objects. Throughout the code, symbols are often pointed to by -// non-const pointers, so there is no harm in casting the constness -// away. -return std::make_tuple(const_cast(e.GetLastSymbol()), +return std::make_tuple(symbol_addr(*e.GetLastSymbol()), evaluate::AsGenericExpr(AsRvalueRef(e))); } static SymDsg visit(const evaluate::ProcedureDesignator &e) { -// See comment above regarding const_cast. -return std::make_tuple(const_cast(e.GetSymbol()), - std::nullopt); +return std::make_tuple(symbol_addr(*e.GetSymbol()), std::nullopt); } template // @@ -313,6 +339,42 @@ std::optional maybeApply(F &&func, const std::optional &inp) { return std::move(func(*inp)); } +std::optional +getBaseObject(const Object &object, + Fortran::semantics::SemanticsContext &semaCtx) { + // If it's just the symbol, then there is no base. + if (!object.dsg) +return std::nullopt; + + auto maybeRef = evaluate::ExtractDataRef(*object.dsg); + if (!maybeRef) +return std::nullopt; + + evaluate::DataRef ref = *maybeRef; + + if (std::get_if(&ref.u)) { +return std::nullopt; + } else if (auto *comp = std::get_if(&ref.u)) { +const evaluate::DataRef &base = comp
[llvm-branch-commits] [flang] [flang][OpenMP] Convert unique clauses in ClauseProcessor (PR #81622)
@@ -2639,54 +2641,50 @@ bool ClauseProcessor::processFinal(Fortran::lower::StatementContext &stmtCtx, } bool ClauseProcessor::processHint(mlir::IntegerAttr &result) const { - if (auto *hintClause = findUniqueClause()) { + if (auto *clause = findUniqueClause()) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); -const auto *expr = Fortran::semantics::GetExpr(hintClause->v); -int64_t hintValue = *Fortran::evaluate::ToInt64(*expr); +int64_t hintValue = *Fortran::evaluate::ToInt64(clause->v); result = firOpBuilder.getI64IntegerAttr(hintValue); return true; } return false; } bool ClauseProcessor::processMergeable(mlir::UnitAttr &result) const { - return markClauseOccurrence(result); + return markClauseOccurrence(result); } bool ClauseProcessor::processNowait(mlir::UnitAttr &result) const { - return markClauseOccurrence(result); + return markClauseOccurrence(result); } bool ClauseProcessor::processNumTeams(Fortran::lower::StatementContext &stmtCtx, mlir::Value &result) const { // TODO Get lower and upper bounds for num_teams when parser is updated to // accept both. - if (auto *numTeamsClause = findUniqueClause()) { -result = fir::getBase(converter.genExprValue( -*Fortran::semantics::GetExpr(numTeamsClause->v), stmtCtx)); + if (auto *clause = findUniqueClause()) { +result = fir::getBase(converter.genExprValue(clause->v, stmtCtx)); return true; } return false; } bool ClauseProcessor::processNumThreads( Fortran::lower::StatementContext &stmtCtx, mlir::Value &result) const { - if (auto *numThreadsClause = findUniqueClause()) { + if (auto *clause = findUniqueClause()) { // OMPIRBuilder expects `NUM_THREADS` clause as a `Value`. -result = fir::getBase(converter.genExprValue( -*Fortran::semantics::GetExpr(numThreadsClause->v), stmtCtx)); +result = fir::getBase(converter.genExprValue(clause->v, stmtCtx)); return true; } return false; } bool ClauseProcessor::processOrdered(mlir::IntegerAttr &result) const { - if (auto *orderedClause = findUniqueClause()) { + if (auto *clause = findUniqueClause()) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); int64_t orderedClauseValue = 0l; -if (orderedClause->v.has_value()) { - const auto *expr = Fortran::semantics::GetExpr(orderedClause->v); - orderedClauseValue = *Fortran::evaluate::ToInt64(*expr); +if (clause->v.has_value()) { kparzysz wrote: Done https://github.com/llvm/llvm-project/pull/81622 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert unique clauses in ClauseProcessor (PR #81622)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81622 >From fafbd98f05958d6983d87803b94536b9041b63dc Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 21 Feb 2024 14:26:11 -0600 Subject: [PATCH] [flang][OpenMP] Convert unique clauses in ClauseProcessor Temporarily rename old clause list to `clauses2`, old clause iterator to `ClauseIterator2`. Change `findUniqueClause` to iterate over `omp::Clause` objects, modify all handlers to operate on 'omp::clause::xyz` equivalents. --- flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 211 + flang/lib/Lower/OpenMP/ClauseProcessor.h | 36 +++- flang/lib/Lower/OpenMP/Clauses.cpp | 6 +- flang/lib/Lower/OpenMP/Clauses.h | 15 +- 4 files changed, 129 insertions(+), 139 deletions(-) diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index a41f8312a28c9e..9987cd73fc7670 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -11,6 +11,7 @@ //===--===// #include "ClauseProcessor.h" +#include "Clauses.h" #include "flang/Lower/PFTBuilder.h" #include "flang/Parser/tools.h" @@ -30,64 +31,55 @@ static void checkMapType(mlir::Location location, mlir::Type type) { } static mlir::omp::ScheduleModifier -translateScheduleModifier(const Fortran::parser::OmpScheduleModifierType &m) { - switch (m.v) { - case Fortran::parser::OmpScheduleModifierType::ModType::Monotonic: +translateScheduleModifier(const omp::clause::Schedule::ModType &m) { + switch (m) { + case omp::clause::Schedule::ModType::Monotonic: return mlir::omp::ScheduleModifier::monotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Nonmonotonic: + case omp::clause::Schedule::ModType::Nonmonotonic: return mlir::omp::ScheduleModifier::nonmonotonic; - case Fortran::parser::OmpScheduleModifierType::ModType::Simd: + case omp::clause::Schedule::ModType::Simd: return mlir::omp::ScheduleModifier::simd; } return mlir::omp::ScheduleModifier::none; } static mlir::omp::ScheduleModifier -getScheduleModifier(const Fortran::parser::OmpScheduleClause &x) { - const auto &modifier = - std::get>(x.t); +getScheduleModifier(const omp::clause::Schedule &clause) { + using ScheduleModifier = omp::clause::Schedule::ScheduleModifier; + const auto &modifier = std::get>(clause.t); // The input may have the modifier any order, so we look for one that isn't // SIMD. If modifier is not set at all, fall down to the bottom and return // "none". if (modifier) { -const auto &modType1 = -std::get(modifier->t); -if (modType1.v.v == -Fortran::parser::OmpScheduleModifierType::ModType::Simd) { - const auto &modType2 = std::get< - std::optional>( - modifier->t); - if (modType2 && - modType2->v.v != - Fortran::parser::OmpScheduleModifierType::ModType::Simd) -return translateScheduleModifier(modType2->v); - +using ModType = omp::clause::Schedule::ModType; +const auto &modType1 = std::get(modifier->t); +if (modType1 == ModType::Simd) { + const auto &modType2 = std::get>(modifier->t); + if (modType2 && *modType2 != ModType::Simd) +return translateScheduleModifier(*modType2); return mlir::omp::ScheduleModifier::none; } -return translateScheduleModifier(modType1.v); +return translateScheduleModifier(modType1); } return mlir::omp::ScheduleModifier::none; } static mlir::omp::ScheduleModifier -getSimdModifier(const Fortran::parser::OmpScheduleClause &x) { - const auto &modifier = - std::get>(x.t); +getSimdModifier(const omp::clause::Schedule &clause) { + using ScheduleModifier = omp::clause::Schedule::ScheduleModifier; + const auto &modifier = std::get>(clause.t); // Either of the two possible modifiers in the input can be the SIMD modifier, // so look in either one, and return simd if we find one. Not found = return // "none". if (modifier) { -const auto &modType1 = -std::get(modifier->t); -if (modType1.v.v == Fortran::parser::OmpScheduleModifierType::ModType::Simd) +using ModType = omp::clause::Schedule::ModType; +const auto &modType1 = std::get(modifier->t); +if (modType1 == ModType::Simd) return mlir::omp::ScheduleModifier::simd; -const auto &modType2 = std::get< -std::optional>( -modifier->t); -if (modType2 && modType2->v.v == - Fortran::parser::OmpScheduleModifierType::ModType::Simd) +const auto &modType2 = std::get>(modifier->t); +if (modType2 && *modType2 == ModType::Simd) return mlir::omp::ScheduleModifier::simd; } return mlir::omp::ScheduleModifier::none; @@ -141,21 +133,21 @@ genAllocateClause(Fortran::lower::AbstractConverter &converter, genObjectList(ompObject
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
@@ -2865,53 +2865,45 @@ bool ClauseProcessor::processDepend( llvm::SmallVectorImpl &dependOperands) const { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - return findRepeatableClause( - [&](const ClauseTy::Depend *dependClause, + return findRepeatableClause( + [&](const omp::clause::Depend &clause, const Fortran::parser::CharBlock &) { -const std::list &depVal = -std::get>( -std::get( -dependClause->v.u) -.t); +assert(std::holds_alternative(clause.u) && + "Only InOut is handled at the moment"); +const auto &inOut = std::get(clause.u); +const auto &objects = std::get(inOut.t); + mlir::omp::ClauseTaskDependAttr dependTypeOperand = -genDependKindAttr(firOpBuilder, dependClause); -dependTypeOperands.insert(dependTypeOperands.end(), depVal.size(), - dependTypeOperand); -for (const Fortran::parser::Designator &ompObject : depVal) { - Fortran::semantics::Symbol *sym = nullptr; - std::visit( - Fortran::common::visitors{ - [&](const Fortran::parser::DataRef &designator) { -if (const Fortran::parser::Name *name = -std::get_if(&designator.u)) { - sym = name->symbol; -} else if (std::get_if>( - &designator.u)) { - TODO(converter.getCurrentLocation(), - "array sections not supported for task depend"); -} - }, - [&](const Fortran::parser::Substring &designator) { -TODO(converter.getCurrentLocation(), - "substring not supported for task depend"); - }}, - (ompObject).u); +genDependKindAttr(firOpBuilder, clause); +dependTypeOperands.append(objects.size(), dependTypeOperand); + +for (const omp::Object &object : objects) { + assert(object.dsg && "Expecting designator"); + + if (Fortran::evaluate::ExtractSubstring(*object.dsg)) { +TODO(converter.getCurrentLocation(), + "substring not supported for task depend"); + } else if (Fortran::evaluate::IsArrayElement(*object.dsg)) { +TODO(converter.getCurrentLocation(), + "array sections not supported for task depend"); + } + + Fortran::semantics::Symbol *sym = object.sym; const mlir::Value variable = converter.getSymbolAddress(*sym); dependOperands.push_back(variable); } kparzysz wrote: The old code is below for reference. First, the code created (unconditionally) a list of designators from the list of objects. In my implementation, if an object was a designator, the designator would be present in `omp::Object`. If the object is not a designator, the code would fail at runtime in both cases. Then, a `DataRef` object is obtained from the designator, if present, but that's only to get the symbol out of it. The other two cases (Substring and ArrayElement) are both TODO, which is what my code does as well. ``` const std::list &depVal = std::get>( std::get( dependClause->v.u) .t); mlir::omp::ClauseTaskDependAttr dependTypeOperand = genDependKindAttr(firOpBuilder, dependClause); dependTypeOperands.insert(dependTypeOperands.end(), depVal.size(), dependTypeOperand); for (const Fortran::parser::Designator &ompObject : depVal) { Fortran::semantics::Symbol *sym = nullptr; std::visit( Fortran::common::visitors{ [&](const Fortran::parser::DataRef &designator) { if (const Fortran::parser::Name *name = std::get_if(&designator.u)) { sym = name->symbol; } else if (std::get_if>( &designator.u)) { TODO(converter.getCurrentLocation(), "array sections not supported for task depend"); } }, [&](const Fortran::parser::Substring &designator) { TODO(converter.getCurrentLocation(), "substring not supported for task depend"); }}, (ompObject).u); const mlir::Value variable = converter.getSymbolAddress(*sym); ``` https://github.com/llvm/llvm-project/pull/81623 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81623 >From 655dce519efb87f8d3babf3b7a5d6132bb82e2a6 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 21 Feb 2024 15:51:38 -0600 Subject: [PATCH] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProcessor Rename `findRepeatableClause` to `findRepeatableClause2`, and make the new `findRepeatableClause` operate on new `omp::Clause` objects. Leave `Map` unchanged, because it will require more changes for it to work. --- flang/include/flang/Evaluate/tools.h | 23 ++ flang/lib/Lower/OpenMP/ClauseProcessor.cpp| 218 -- flang/lib/Lower/OpenMP/ClauseProcessor.h | 29 ++- flang/lib/Lower/OpenMP/Clauses.cpp| 6 - flang/lib/Lower/OpenMP/Clauses.h | 6 + flang/lib/Lower/OpenMP/OpenMP.cpp | 182 +++ flang/lib/Lower/OpenMP/ReductionProcessor.cpp | 155 ++--- flang/lib/Lower/OpenMP/ReductionProcessor.h | 23 +- flang/lib/Lower/OpenMP/Utils.cpp | 41 ++-- flang/lib/Lower/OpenMP/Utils.h| 10 +- 10 files changed, 348 insertions(+), 345 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index d257da1a709642..e974944e88 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -430,6 +430,29 @@ template std::optional ExtractCoarrayRef(const A &x) { } } +struct ExtractSubstringHelper { + template static std::optional visit(T &&) { +return std::nullopt; + } + + static std::optional visit(const Substring &e) { return e; } + + template + static std::optional visit(const Designator &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } + + template + static std::optional visit(const Expr &e) { +return std::visit([](auto &&s) { return visit(s); }, e.u); + } +}; + +template +std::optional ExtractSubstring(const A &x) { + return ExtractSubstringHelper::visit(x); +} + // If an expression is simply a whole symbol data designator, // extract and return that symbol, else null. template const Symbol *UnwrapWholeSymbolDataRef(const A &x) { diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 9987cd73fc7670..6e45a939333d62 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -87,7 +87,7 @@ getSimdModifier(const omp::clause::Schedule &clause) { static void genAllocateClause(Fortran::lower::AbstractConverter &converter, - const Fortran::parser::OmpAllocateClause &ompAllocateClause, + const omp::clause::Allocate &clause, llvm::SmallVectorImpl &allocatorOperands, llvm::SmallVectorImpl &allocateOperands) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); @@ -95,21 +95,18 @@ genAllocateClause(Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext stmtCtx; mlir::Value allocatorOperand; - const Fortran::parser::OmpObjectList &ompObjectList = - std::get(ompAllocateClause.t); - const auto &allocateModifier = std::get< - std::optional>( - ompAllocateClause.t); + const omp::ObjectList &objectList = std::get(clause.t); + const auto &modifier = + std::get>(clause.t); // If the allocate modifier is present, check if we only use the allocator // submodifier. ALIGN in this context is unimplemented const bool onlyAllocator = - allocateModifier && - std::holds_alternative< - Fortran::parser::OmpAllocateClause::AllocateModifier::Allocator>( - allocateModifier->u); + modifier && + std::holds_alternative( + modifier->u); - if (allocateModifier && !onlyAllocator) { + if (modifier && !onlyAllocator) { TODO(currentLocation, "OmpAllocateClause ALIGN modifier"); } @@ -117,20 +114,17 @@ genAllocateClause(Fortran::lower::AbstractConverter &converter, // to list of allocators, otherwise, add default allocator to // list of allocators. if (onlyAllocator) { -const auto &allocatorValue = std::get< -Fortran::parser::OmpAllocateClause::AllocateModifier::Allocator>( -allocateModifier->u); -allocatorOperand = fir::getBase(converter.genExprValue( -*Fortran::semantics::GetExpr(allocatorValue.v), stmtCtx)); -allocatorOperands.insert(allocatorOperands.end(), ompObjectList.v.size(), - allocatorOperand); +const auto &value = +std::get(modifier->u); +mlir::Value operand = +fir::getBase(converter.genExprValue(value.v, stmtCtx)); +allocatorOperands.append(objectList.size(), operand); } else { -allocatorOperand = firOpBuilder.createIntegerConstant( +mlir::Value operand = firOpBuilder.createIntegerConstant( currentLocation, firOpBuilder.getI32Type(), 1);
[llvm-branch-commits] [flang] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr (PR #81626)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81626 >From bf64cd32fdba5af2b40c36c801228adf6ef53405 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 21 Feb 2024 16:39:35 -0600 Subject: [PATCH] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr The related functions are `gatherDataOperandAddrAndBounds` and `genBoundsOps`. The former is used in OpenACC as well, and it was updated to pass evaluate::Expr instead of parser objects. The difference in the test case comes from unfolded conversions of index expressions, which are explicitly of type integer(kind=8). Delete now unused `findRepeatableClause2` and `findClause2`. Add `AsGenericExpr` that takes std::optional. It already returns optional Expr. Making it accept an optional Expr as input would reduce the number of necessary checks when handling frequent optional values in evaluator. --- flang/include/flang/Evaluate/tools.h | 8 + flang/lib/Lower/DirectivesCommon.h | 389 + flang/lib/Lower/OpenACC.cpp| 54 ++- flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 44 ++- flang/lib/Lower/OpenMP/ClauseProcessor.h | 59 +--- flang/lib/Lower/OpenMP/OpenMP.cpp | 19 +- 6 files changed, 317 insertions(+), 256 deletions(-) diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index e974944e88..d5713cfe420a2e 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -148,6 +148,14 @@ inline Expr AsGenericExpr(Expr &&x) { return std::move(x); } std::optional> AsGenericExpr(DataRef &&); std::optional> AsGenericExpr(const Symbol &); +// Propagate std::optional from input to output. +template +std::optional> AsGenericExpr(std::optional &&x) { + if (!x) +return std::nullopt; + return AsGenericExpr(std::move(*x)); +} + template common::IfNoLvalue::category>>, A> AsCategoryExpr( A &&x) { diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h index 8d560db34e05bf..2fa90572bc63eb 100644 --- a/flang/lib/Lower/DirectivesCommon.h +++ b/flang/lib/Lower/DirectivesCommon.h @@ -808,6 +808,75 @@ genBaseBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, return bounds; } +namespace detail { +template // +static T &&AsRvalueRef(T &&t) { + return std::move(t); +} +template // +static T AsRvalueRef(T &t) { + return t; +} +template // +static T AsRvalueRef(const T &t) { + return t; +} + +// Helper class for stripping enclosing parentheses and a conversion that +// preserves type category. This is used for triplet elements, which are +// always of type integer(kind=8). The lower/upper bounds are converted to +// an "index" type, which is 64-bit, so the explicit conversion to kind=8 +// (if present) is not needed. When it's present, though, it causes generated +// names to contain "int(..., kind=8)". +struct PeelConvert { + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Expr> + &expr) { +return std::visit( +[](auto &&s) { return visit_with_category(s); }, +expr.u); + } + template + static Fortran::semantics::MaybeExpr visit_with_category( + const Fortran::evaluate::Convert, + Category> &expr) { +return AsGenericExpr(AsRvalueRef(expr.left())); + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + template + static Fortran::semantics::MaybeExpr visit_with_category(const T &) { +return std::nullopt; // + } + + template + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr> +&expr) { +return std::visit([](auto &&s) { return visit_with_category(s); }, + expr.u); + } + static Fortran::semantics::MaybeExpr + visit(const Fortran::evaluate::Expr &expr) { +return std::visit([](auto &&s) { return visit(s); }, expr.u); + } + template // + static Fortran::semantics::MaybeExpr visit(const T &) { +return std::nullopt; + } +}; + +static Fortran::semantics::SomeExpr +peelOuterConvert(Fortran::semantics::SomeExpr &expr) { + if (auto peeled = PeelConvert::visit(expr)) +return *peeled; + return expr; +} +} // namespace detail + /// Generate bounds operations for an array section when subscripts are /// provided. template @@ -815,7 +884,7 @@ llvm::SmallVector genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext &stmtCtx, - const std::list &subscripts, + const std::vector &subscripts, std::stringstream &asFortran, fir::ExtendedValue &dataExv, bool dataExvIsAssumedSize, AddrAndBoundsInfo &info, bool treatIndexAsSection = false) { @@ -828,8 +897,7 @@ genBo
[llvm-branch-commits] [flang] [flang][OpenMP] Convert processTODO and remove unused objects (PR #81627)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81627 >From 7e785c4caa8d66457dabab31eca2bab505a05c0d Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 21 Feb 2024 16:56:47 -0600 Subject: [PATCH] [flang][OpenMP] Convert processTODO and remove unused objects Remove `ClauseIterator2` and `clauses2` from ClauseProcessor. --- flang/lib/Lower/OpenMP/ClauseProcessor.h | 16 +++ flang/lib/Lower/OpenMP/OpenMP.cpp| 54 +--- 2 files changed, 25 insertions(+), 45 deletions(-) diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index 47d80024295121..f2d8bcebf0b07a 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -46,13 +46,11 @@ namespace omp { /// methods that relate to clauses that can impact the lowering of that /// construct. class ClauseProcessor { - using ClauseTy = Fortran::parser::OmpClause; - public: ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), clauses2(clauses), + : converter(converter), semaCtx(semaCtx), clauses(makeList(clauses, semaCtx)) {} // 'Unique' clauses: They can appear at most once in the clause list. @@ -157,7 +155,6 @@ class ClauseProcessor { private: using ClauseIterator = List::const_iterator; - using ClauseIterator2 = std::list::const_iterator; /// Utility to find a clause within a range in the clause list. template @@ -183,7 +180,6 @@ class ClauseProcessor { Fortran::lower::AbstractConverter &converter; Fortran::semantics::SemanticsContext &semaCtx; - const Fortran::parser::OmpClauseList &clauses2; List clauses; }; @@ -239,19 +235,17 @@ bool ClauseProcessor::processMotionClauses( template void ClauseProcessor::processTODO(mlir::Location currentLocation, llvm::omp::Directive directive) const { - auto checkUnhandledClause = [&](const auto *x) { + auto checkUnhandledClause = [&](llvm::omp::Clause id, const auto *x) { if (!x) return; TODO(currentLocation, - "Unhandled clause " + - llvm::StringRef(Fortran::parser::ParseTreeDumper::GetNodeName(*x)) - .upper() + + "Unhandled clause " + llvm::omp::getOpenMPClauseName(id).upper() + " in " + llvm::omp::getOpenMPDirectiveName(directive).upper() + " construct"); }; - for (ClauseIterator2 it = clauses2.v.begin(); it != clauses2.v.end(); ++it) -(checkUnhandledClause(std::get_if(&it->u)), ...); + for (ClauseIterator it = clauses.begin(); it != clauses.end(); ++it) +(checkUnhandledClause(it->id, std::get_if(&it->u)), ...); } template diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index c828fc7919b3bc..a07aba28bd76f6 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -683,9 +683,7 @@ genTaskOp(Fortran::lower::AbstractConverter &converter, cp.processMergeable(mergeableAttr); cp.processPriority(stmtCtx, priorityClauseOperand); cp.processDepend(dependTypeOperands, dependOperands); - cp.processTODO( + cp.processTODO( currentLocation, llvm::omp::Directive::OMPD_task); return genOpWithBody( @@ -711,8 +709,8 @@ genTaskGroupOp(Fortran::lower::AbstractConverter &converter, llvm::SmallVector allocateOperands, allocatorOperands; ClauseProcessor cp(converter, semaCtx, clauseList); cp.processAllocate(allocatorOperands, allocateOperands); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_taskgroup); + cp.processTODO(currentLocation, +llvm::omp::Directive::OMPD_taskgroup); return genOpWithBody( OpWithBodyGenInfo(converter, semaCtx, currentLocation, eval) .setGenNested(genNested) @@ -983,16 +981,12 @@ genTargetOp(Fortran::lower::AbstractConverter &converter, cp.processMap(currentLocation, directive, stmtCtx, mapOperands, &mapSymTypes, &mapSymLocs, &mapSymbols); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_target); + cp.processTODO(currentLocation, + llvm::omp::Directive::OMPD_target); + // 5.8.1 Implicit Data-Mapping Attribute Rules // The following code follows the implicit data-mapping rules to map all the // symbols used inside the region that have not been explicitly mapped using @@ -1097,8 +1091,8 @@ genTeamsOp(Fortran::lower::AbstractConverter &converter, cp.processDefault(); cp.processNumTeams(stmtCtx, numTeamsClauseOperand); cp.processThreadLimit(stmtCtx, threadLimitClauseOperand); - cp.processTODO( - currentLocation, llvm::omp::Directive::OMPD_teams); + cp.processTODO(currentLocation, +
[llvm-branch-commits] [flang] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause (PR #81629)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/81629 >From 158901f346ae6ff3f010b2c96c01129b578291ee Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 21 Feb 2024 17:10:30 -0600 Subject: [PATCH] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause --- .../lib/Lower/OpenMP/DataSharingProcessor.cpp | 277 +- flang/lib/Lower/OpenMP/DataSharingProcessor.h | 13 +- flang/lib/Lower/OpenMP/OpenMP.cpp | 6 +- 3 files changed, 146 insertions(+), 150 deletions(-) diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp index 136bda0b582ee3..3b687d03adf371 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp @@ -79,30 +79,28 @@ void DataSharingProcessor::copyLastPrivateSymbol( } void DataSharingProcessor::collectOmpObjectListSymbol( -const Fortran::parser::OmpObjectList &ompObjectList, +const omp::ObjectList &objects, llvm::SetVector &symbolSet) { - for (const Fortran::parser::OmpObject &ompObject : ompObjectList.v) { -Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject); + for (const omp::Object &object : objects) { +Fortran::semantics::Symbol *sym = object.id(); symbolSet.insert(sym); } } void DataSharingProcessor::collectSymbolsForPrivatization() { bool hasCollapse = false; - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { + for (const omp::Clause &clause : clauses) { if (const auto &privateClause = -std::get_if(&clause.u)) { +std::get_if(&clause.u)) { collectOmpObjectListSymbol(privateClause->v, privatizedSymbols); } else if (const auto &firstPrivateClause = - std::get_if( - &clause.u)) { + std::get_if(&clause.u)) { collectOmpObjectListSymbol(firstPrivateClause->v, privatizedSymbols); } else if (const auto &lastPrivateClause = - std::get_if( - &clause.u)) { + std::get_if(&clause.u)) { collectOmpObjectListSymbol(lastPrivateClause->v, privatizedSymbols); hasLastPrivateOp = true; -} else if (std::get_if(&clause.u)) { +} else if (std::get_if(&clause.u)) { hasCollapse = true; } } @@ -135,138 +133,135 @@ void DataSharingProcessor::insertBarrier() { void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { bool cmpCreated = false; mlir::OpBuilder::InsertPoint localInsPt = firOpBuilder.saveInsertionPoint(); - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { -if (std::get_if(&clause.u)) { - // TODO: Add lastprivate support for simd construct - if (mlir::isa(op)) { -if (&eval == &eval.parentConstruct->getLastNestedEvaluation()) { - // For `omp.sections`, lastprivatized variables occur in - // lexically final `omp.section` operation. The following FIR - // shall be generated for the same: - // - // omp.sections lastprivate(...) { - // omp.section {...} - // omp.section {...} - // omp.section { - // fir.allocate for `private`/`firstprivate` - // - // fir.if %true { - // ^%lpv_update_blk - // } - // } - // } - // - // To keep code consistency while handling privatization - // through this control flow, add a `fir.if` operation - // that always evaluates to true, in order to create - // a dedicated sub-region in `omp.section` where - // lastprivate FIR can reside. Later canonicalizations - // will optimize away this operation. - if (!eval.lowerAsUnstructured()) { -auto ifOp = firOpBuilder.create( -op->getLoc(), -firOpBuilder.createIntegerConstant( -op->getLoc(), firOpBuilder.getIntegerType(1), 0x1), -/*else*/ false); -firOpBuilder.setInsertionPointToStart( -&ifOp.getThenRegion().front()); - -const Fortran::parser::OpenMPConstruct *parentOmpConstruct = - eval.parentConstruct->getIf(); -assert(parentOmpConstruct && - "Expected a valid enclosing OpenMP construct"); -const Fortran::parser::OpenMPSectionsConstruct *sectionsConstruct = -std::get_if( -&parentOmpConstruct->u); -assert(sectionsConstruct && - "Expected an enclosing omp.sections construct"); -const Fortran::parser::OmpClauseList §ionsEndClauseList = -std::get( -std::get( -sectionsConstruct->t) -.t); -for (const Fortran::parser::OmpClause &otherClause :
[llvm-branch-commits] [flang] [flang][Lower] Convert OMP Map and related functions to evaluate::Expr (PR #81626)
kparzysz wrote: It's a dangling reference problem: https://github.com/llvm/llvm-project/pull/82800. https://github.com/llvm/llvm-project/pull/81626 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause (PR #81629)
@@ -135,138 +133,135 @@ void DataSharingProcessor::insertBarrier() { void DataSharingProcessor::insertLastPrivateCompare(mlir::Operation *op) { bool cmpCreated = false; mlir::OpBuilder::InsertPoint localInsPt = firOpBuilder.saveInsertionPoint(); - for (const Fortran::parser::OmpClause &clause : opClauseList.v) { kparzysz wrote: The code functionality is unchanged. One reason for the seemingly large differences in the diff is that I replaced the `if (get_if)` with `if (!get_if) continue;` to reduce indentation. https://github.com/llvm/llvm-project/pull/81629 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [OpenMP][MLIR] Add new arguments to map_info to help support record type maps (PR #82851)
kparzysz wrote: Is the `ptr_and_obj` modifier connected to the new arguments? https://github.com/llvm/llvm-project/pull/82851 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [OpenMP][MLIR] Add new arguments to map_info to help support record type maps (PR #82851)
kparzysz wrote: Yeah, I didn't realize this was a part of a series. :) https://github.com/llvm/llvm-project/pull/82851 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [Flang][OpenMP][MLIR] Initial derived type member map support (PR #82853)
@@ -919,8 +924,27 @@ bool ClauseProcessor::processMap( for (const Fortran::parser::OmpObject &ompObject : std::get(mapClause->v.t).v) { + llvm::omp::OpenMPOffloadMappingFlags objectsMapTypeBits = mapTypeBits; + checkAndApplyDeclTargetMapFlags(converter, objectsMapTypeBits, + *getOmpObjectSymbol(ompObject)); + llvm::SmallVector bounds; std::stringstream asFortran; + const Fortran::semantics::Symbol *parentSym = nullptr; + + if (getOmpObjectSymbol(ompObject)->owner().IsDerivedType()) { +const auto *designator = +Fortran::parser::Unwrap( +ompObject.u); +assert(designator && "Expected a designator from derived type " + "component during map clause processing"); +parentSym = GetFirstName(*designator).symbol; kparzysz wrote: We will need to traverse all parents. For example given `x%y%z`, `GetFirstName` will return `x`. The type of `x` does not have a member `z`, so findComponentMemberPlacement will fail. https://github.com/llvm/llvm-project/pull/82853 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [OpenMP][MLIR] Add new arguments to map_info to help support record type maps (PR #82851)
kparzysz wrote: I'm not sure if member placement alone is sufficient. As I commented in the other PR, for `x%y%z` we need to map the `z` component of the flattened structure of `x`, which we don't have a representation of. https://github.com/llvm/llvm-project/pull/82851 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] release/18.x: Convert many LivePhysRegs uses to LiveRegUnits (PR #84118)
@@ -313,7 +313,7 @@ MachineBasicBlock::reverse_iterator SIOptimizeExecMasking::findExecCopy( return E; } -// XXX - Seems LivePhysRegs doesn't work correctly since it will incorrectly +// XXX - Seems LiveRegUnits doesn't work correctly since it will incorrectly kparzysz wrote: I think LiveRegUnits fixes this issue, doesn't it? https://github.com/llvm/llvm-project/pull/84118 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][CodeGen] Fix use-after-free in BoxedProcedurePass (PR #84376)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/84376 Replacing an element of an operation range while traversing the range can make the range invalid. Store the operations in a separate list, and traverse the list instead. Additionally, avoid inspecting an operation that has been replaced. This was detected by address sanitizer. >From 58cda6db7030e178fbd861312dcee372e1558611 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 7 Mar 2024 14:21:45 -0600 Subject: [PATCH] [flang][CodeGen] Fix use-after-free in BoxedProcedurePass Replacing an element of an operation range while traversing the range can make the range invalid. Store the operations in a separate list, and traverse the list instead. Additionally, avoid inspecting an operation that has been replaced. This was detected by address sanitizer. --- .../lib/Optimizer/CodeGen/BoxedProcedure.cpp | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp b/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp index 4cf39716a73755..2e34b0a1b492b1 100644 --- a/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp +++ b/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp @@ -208,7 +208,12 @@ class BoxedProcedurePass mlir::IRRewriter rewriter(context); BoxprocTypeRewriter typeConverter(mlir::UnknownLoc::get(context)); mlir::Dialect *firDialect = context->getLoadedDialect("fir"); - getModule().walk([&](mlir::Operation *op) { + llvm::SmallVector operations; + + getModule().walk([&](mlir::Operation *op) { operations.push_back(op); }); + + for (mlir::Operation *op : operations) { +bool opIsValid = true; typeConverter.setLocation(op->getLoc()); if (auto addr = mlir::dyn_cast(op)) { mlir::Type ty = addr.getVal().getType(); @@ -220,6 +225,7 @@ class BoxedProcedurePass rewriter.setInsertionPoint(addr); rewriter.replaceOpWithNewOp( addr, typeConverter.convertType(addr.getType()), addr.getVal()); +opIsValid = false; } else if (typeConverter.needsConversion(resTy)) { rewriter.startOpModification(op); op->getResult(0).setType(typeConverter.convertType(resTy)); @@ -271,10 +277,12 @@ class BoxedProcedurePass llvm::ArrayRef{tramp}); rewriter.replaceOpWithNewOp(embox, toTy, adjustCall.getResult(0)); +opIsValid = false; } else { // Just forward the function as a pointer. rewriter.replaceOpWithNewOp(embox, toTy, embox.getFunc()); +opIsValid = false; } } else if (auto global = mlir::dyn_cast(op)) { auto ty = global.getType(); @@ -297,6 +305,7 @@ class BoxedProcedurePass rewriter.replaceOpWithNewOp( mem, toTy, uniqName, bindcName, isPinned, mem.getTypeparams(), mem.getShape()); +opIsValid = false; } } else if (auto mem = mlir::dyn_cast(op)) { auto ty = mem.getType(); @@ -310,6 +319,7 @@ class BoxedProcedurePass rewriter.replaceOpWithNewOp( mem, toTy, uniqName, bindcName, mem.getTypeparams(), mem.getShape()); +opIsValid = false; } } else if (auto coor = mlir::dyn_cast(op)) { auto ty = coor.getType(); @@ -321,6 +331,7 @@ class BoxedProcedurePass auto toBaseTy = typeConverter.convertType(baseTy); rewriter.replaceOpWithNewOp(coor, toTy, coor.getRef(), coor.getCoor(), toBaseTy); +opIsValid = false; } } else if (auto index = mlir::dyn_cast(op)) { auto ty = index.getType(); @@ -332,6 +343,7 @@ class BoxedProcedurePass auto toOnTy = typeConverter.convertType(onTy); rewriter.replaceOpWithNewOp( index, toTy, index.getFieldId(), toOnTy, index.getTypeparams()); +opIsValid = false; } } else if (auto index = mlir::dyn_cast(op)) { auto ty = index.getType(); @@ -343,6 +355,7 @@ class BoxedProcedurePass auto toOnTy = typeConverter.convertType(onTy); rewriter.replaceOpWithNewOp( index, toTy, index.getFieldId(), toOnTy, index.getTypeparams()); +opIsValid = false; } } else if (op->getDialect() == firDialect) { rewriter.startOpModification(op); @@ -354,7 +367,7 @@ class BoxedProcedurePass rewriter.finalizeOpModification(op); } // Ensure block arguments are updated if needed. -if (op->getNumRegions() != 0) { +if (opIsValid && op->getNumRegions() != 0) { rewriter.startOpModifica
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
@@ -181,45 +172,41 @@ genDependKindAttr(fir::FirOpBuilder &firOpBuilder, pbKind); } -static mlir::Value getIfClauseOperand( -Fortran::lower::AbstractConverter &converter, -const Fortran::parser::OmpClause::If *ifClause, -Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName, -mlir::Location clauseLocation) { +static mlir::Value +getIfClauseOperand(Fortran::lower::AbstractConverter &converter, + const omp::clause::If &clause, + omp::clause::If::DirectiveNameModifier directiveName, + mlir::Location clauseLocation) { // Only consider the clause if it's intended for the given directive. - auto &directive = std::get< - std::optional>( - ifClause->v.t); + auto &directive = + std::get>(clause.t); if (directive && directive.value() != directiveName) return nullptr; Fortran::lower::StatementContext stmtCtx; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - auto &expr = std::get(ifClause->v.t); mlir::Value ifVal = fir::getBase( - converter.genExprValue(*Fortran::semantics::GetExpr(expr), stmtCtx)); + converter.genExprValue(std::get(clause.t), stmtCtx)); return firOpBuilder.createConvert(clauseLocation, firOpBuilder.getI1Type(), ifVal); } static void addUseDeviceClause(Fortran::lower::AbstractConverter &converter, - const Fortran::parser::OmpObjectList &useDeviceClause, + const omp::ObjectList &objects, llvm::SmallVectorImpl &operands, llvm::SmallVectorImpl &useDeviceTypes, llvm::SmallVectorImpl &useDeviceLocs, llvm::SmallVectorImpl &useDeviceSymbols) { - genObjectList(useDeviceClause, converter, operands); + genObjectList(objects, converter, operands); for (mlir::Value &operand : operands) { checkMapType(operand.getLoc(), operand.getType()); useDeviceTypes.push_back(operand.getType()); useDeviceLocs.push_back(operand.getLoc()); } - for (const Fortran::parser::OmpObject &ompObject : useDeviceClause.v) { -Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject); -useDeviceSymbols.push_back(sym); - } + for (const omp::Object &object : objects) +useDeviceSymbols.push_back(object.id()); kparzysz wrote: Because `object.id()` returns `Symbol*`. Also, same reason as above. https://github.com/llvm/llvm-project/pull/81623 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
@@ -87,50 +87,44 @@ getSimdModifier(const omp::clause::Schedule &clause) { static void genAllocateClause(Fortran::lower::AbstractConverter &converter, - const Fortran::parser::OmpAllocateClause &ompAllocateClause, + const omp::clause::Allocate &clause, llvm::SmallVectorImpl &allocatorOperands, llvm::SmallVectorImpl &allocateOperands) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); mlir::Location currentLocation = converter.getCurrentLocation(); Fortran::lower::StatementContext stmtCtx; mlir::Value allocatorOperand; - const Fortran::parser::OmpObjectList &ompObjectList = - std::get(ompAllocateClause.t); - const auto &allocateModifier = std::get< - std::optional>( - ompAllocateClause.t); + const omp::ObjectList &objectList = std::get(clause.t); + const auto &modifier = + std::get>(clause.t); // If the allocate modifier is present, check if we only use the allocator // submodifier. ALIGN in this context is unimplemented const bool onlyAllocator = - allocateModifier && - std::holds_alternative< - Fortran::parser::OmpAllocateClause::AllocateModifier::Allocator>( - allocateModifier->u); + modifier && + std::holds_alternative( + modifier->u); - if (allocateModifier && !onlyAllocator) { + if (modifier && !onlyAllocator) { TODO(currentLocation, "OmpAllocateClause ALIGN modifier"); } // Check if allocate clause has allocator specified. If so, add it // to list of allocators, otherwise, add default allocator to // list of allocators. if (onlyAllocator) { -const auto &allocatorValue = std::get< -Fortran::parser::OmpAllocateClause::AllocateModifier::Allocator>( -allocateModifier->u); -allocatorOperand = fir::getBase(converter.genExprValue( -*Fortran::semantics::GetExpr(allocatorValue.v), stmtCtx)); -allocatorOperands.insert(allocatorOperands.end(), ompObjectList.v.size(), - allocatorOperand); +const auto &value = +std::get(modifier->u); +mlir::Value operand = +fir::getBase(converter.genExprValue(value.v, stmtCtx)); kparzysz wrote: Because it works on `parser` objects, which we no longer have here. https://github.com/llvm/llvm-project/pull/81623 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
https://github.com/kparzysz edited https://github.com/llvm/llvm-project/pull/81623 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
@@ -181,45 +172,41 @@ genDependKindAttr(fir::FirOpBuilder &firOpBuilder, pbKind); } -static mlir::Value getIfClauseOperand( -Fortran::lower::AbstractConverter &converter, -const Fortran::parser::OmpClause::If *ifClause, -Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName, -mlir::Location clauseLocation) { +static mlir::Value +getIfClauseOperand(Fortran::lower::AbstractConverter &converter, + const omp::clause::If &clause, + omp::clause::If::DirectiveNameModifier directiveName, + mlir::Location clauseLocation) { // Only consider the clause if it's intended for the given directive. - auto &directive = std::get< - std::optional>( - ifClause->v.t); + auto &directive = + std::get>(clause.t); if (directive && directive.value() != directiveName) return nullptr; Fortran::lower::StatementContext stmtCtx; fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - auto &expr = std::get(ifClause->v.t); mlir::Value ifVal = fir::getBase( - converter.genExprValue(*Fortran::semantics::GetExpr(expr), stmtCtx)); + converter.genExprValue(std::get(clause.t), stmtCtx)); return firOpBuilder.createConvert(clauseLocation, firOpBuilder.getI1Type(), ifVal); } static void addUseDeviceClause(Fortran::lower::AbstractConverter &converter, - const Fortran::parser::OmpObjectList &useDeviceClause, + const omp::ObjectList &objects, llvm::SmallVectorImpl &operands, llvm::SmallVectorImpl &useDeviceTypes, llvm::SmallVectorImpl &useDeviceLocs, llvm::SmallVectorImpl &useDeviceSymbols) { - genObjectList(useDeviceClause, converter, operands); + genObjectList(objects, converter, operands); for (mlir::Value &operand : operands) { checkMapType(operand.getLoc(), operand.getType()); useDeviceTypes.push_back(operand.getType()); useDeviceLocs.push_back(operand.getLoc()); } - for (const Fortran::parser::OmpObject &ompObject : useDeviceClause.v) { -Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject); -useDeviceSymbols.push_back(sym); - } + for (const omp::Object &object : objects) +useDeviceSymbols.push_back(object.id()); kparzysz wrote: All things that were previously in `parser::Something` were have been translated into the new clauses: `OmpObject` is now `Symbol*` plus designator (`MaybeExpr`), other things are mostly `SomeExpr`. The old code that computed these is no longer needed in places where it used to be. https://github.com/llvm/llvm-project/pull/81623 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert repeatable clauses (except Map) in ClauseProc… (PR #81623)
https://github.com/kparzysz edited https://github.com/llvm/llvm-project/pull/81623 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause (PR #81629)
@@ -1384,30 +1386,28 @@ void DataSharingProcessor::copyLastPrivateSymbol( } void DataSharingProcessor::collectOmpObjectListSymbol( -const Fortran::parser::OmpObjectList &ompObjectList, +const omp::ObjectList &objects, llvm::SetVector &symbolSet) { - for (const Fortran::parser::OmpObject &ompObject : ompObjectList.v) { -Fortran::semantics::Symbol *sym = getOmpObjectSymbol(ompObject); + for (const omp::Object &object : objects) { +Fortran::semantics::Symbol *sym = object.sym; kparzysz wrote: Done. https://github.com/llvm/llvm-project/pull/81629 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Convert DataSharingProcessor to omp::Clause (PR #81629)
@@ -1278,14 +1278,15 @@ class DataSharingProcessor { llvm::SetVector symbolsInNestedRegions; llvm::SetVector symbolsInParentRegions; Fortran::lower::AbstractConverter &converter; + Fortran::semantics::SemanticsContext &semaCtx; kparzysz wrote: Removed. https://github.com/llvm/llvm-project/pull/81629 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [flang][OpenMP] Main splitting functionality dev-complete (PR #82003)
https://github.com/kparzysz closed https://github.com/llvm/llvm-project/pull/82003 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [flang][OpenMP] Main splitting functionality dev-complete (PR #83264)
https://github.com/kparzysz closed https://github.com/llvm/llvm-project/pull/83264 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [llvm] [flang][OpenMP] Main splitting functionality dev-complete (PR #82495)
https://github.com/kparzysz closed https://github.com/llvm/llvm-project/pull/82495 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [Flang][OpenMP][Lower] Use clause operand structures (PR #86802)
https://github.com/kparzysz approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/86802 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] lower reductions of assumed shape arrays (PR #86982)
https://github.com/kparzysz approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/86982 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Move clause/object conversion to happen early, in genOMP (PR #87074)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/87074 This removes the last use of genOmpObectList2, which has now been removed. >From 77d870f34c21f1265462adecbeac09f55707bb42 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 29 Mar 2024 09:20:41 -0500 Subject: [PATCH] [flang][OpenMP] Move clause/object conversion to happen early, in genOMP This removes the last use of genOmpObectList2, which has now been removed. --- flang/lib/Lower/OpenMP/ClauseProcessor.h | 5 +- flang/lib/Lower/OpenMP/DataSharingProcessor.h | 5 +- flang/lib/Lower/OpenMP/OpenMP.cpp | 409 +- flang/lib/Lower/OpenMP/Utils.cpp | 30 +- flang/lib/Lower/OpenMP/Utils.h| 6 +- 5 files changed, 211 insertions(+), 244 deletions(-) diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index db7a1b8335f818..f4d659b70cfee7 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -49,9 +49,8 @@ class ClauseProcessor { public: ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, - const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), -clauses(makeClauses(clauses, semaCtx)) {} + const List &clauses) + : converter(converter), semaCtx(semaCtx), clauses(clauses) {} // 'Unique' clauses: They can appear at most once in the clause list. bool processCollapse( diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.h b/flang/lib/Lower/OpenMP/DataSharingProcessor.h index c11ee299c5d085..ef7b14327278e3 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.h +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.h @@ -78,13 +78,12 @@ class DataSharingProcessor { public: DataSharingProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, - const Fortran::parser::OmpClauseList &opClauseList, + const List &clauses, Fortran::lower::pft::Evaluation &eval, bool useDelayedPrivatization = false, Fortran::lower::SymMap *symTable = nullptr) : hasLastPrivateOp(false), converter(converter), -firOpBuilder(converter.getFirOpBuilder()), -clauses(omp::makeClauses(opClauseList, semaCtx)), eval(eval), +firOpBuilder(converter.getFirOpBuilder()), clauses(clauses), eval(eval), useDelayedPrivatization(useDelayedPrivatization), symTable(symTable) {} // Privatisation is split into two steps. diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 692d81f9188be3..77d6c8503f0c34 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -17,6 +17,7 @@ #include "DataSharingProcessor.h" #include "DirectivesCommon.h" #include "ReductionProcessor.h" +#include "Utils.h" #include "flang/Common/idioms.h" #include "flang/Lower/Bridge.h" #include "flang/Lower/ConvertExpr.h" @@ -310,14 +311,15 @@ static void getDeclareTargetInfo( } else if (const auto *clauseList{ Fortran::parser::Unwrap( spec.u)}) { -if (clauseList->v.empty()) { +List clauses = makeClauses(*clauseList, semaCtx); +if (clauses.empty()) { // Case: declare target, implicit capture of function symbolAndClause.emplace_back( mlir::omp::DeclareTargetCaptureClause::to, eval.getOwningProcedure()->getSubprogramSymbol()); } -ClauseProcessor cp(converter, semaCtx, *clauseList); +ClauseProcessor cp(converter, semaCtx, clauses); cp.processDeviceType(clauseOps); cp.processEnter(symbolAndClause); cp.processLink(symbolAndClause); @@ -597,14 +599,11 @@ static void removeStoreOp(mlir::Operation *reductionOp, mlir::Value symVal) { // TODO: Generate the reduction operation during lowering instead of creating // and removing operations since this is not a robust approach. Also, removing // ops in the builder (instead of a rewriter) is probably not the best approach. -static void -genOpenMPReduction(Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semaCtx, - const Fortran::parser::OmpClauseList &clauseList) { +static void genOpenMPReduction(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, + const List &clauses) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - List clauses{makeClauses(clauseList, semaCtx)}; - for (const Clause &clause : clauses) { if (const auto &reductionClause = std::get_if(&clause.u)) { @@ -737,7 +736,7 @@ str
[llvm-branch-commits] [flang] [Flang][OpenMP][Lower] Refactor lowering of compound constructs (PR #87070)
@@ -710,6 +710,81 @@ genOpenMPReduction(Fortran::lower::AbstractConverter &converter, } } +/// Split a combined directive into an outer leaf directive and the (possibly +/// combined) rest of the combined directive. Composite directives and +/// non-compound directives are not split, in which case it will return the +/// input directive as its first output and an empty value as its second output. +static std::pair> kparzysz wrote: We have llvm::omp::getLeafConstructs that breaks up any combined/composite directive into leafs. I have functions `is[Leaf|Combined|Composite]Construct` in a local commit, I can make a PR for it. https://github.com/llvm/llvm-project/pull/87070 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [Flang][OpenMP][Lower] Refactor lowering of compound constructs (PR #87070)
@@ -710,6 +710,81 @@ genOpenMPReduction(Fortran::lower::AbstractConverter &converter, } } +/// Split a combined directive into an outer leaf directive and the (possibly +/// combined) rest of the combined directive. Composite directives and +/// non-compound directives are not split, in which case it will return the +/// input directive as its first output and an empty value as its second output. +static std::pair> kparzysz wrote: Posted: https://github.com/llvm/llvm-project/pull/87076 https://github.com/llvm/llvm-project/pull/87070 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Move clause/object conversion to happen early, in genOMP (PR #87086)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/87086 This removes the last use of genOmpObectList2, which has now been removed. >From f725face892cef4faf9f17d4b549541bdbcd7e08 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 29 Mar 2024 09:20:41 -0500 Subject: [PATCH] [flang][OpenMP] Move clause/object conversion to happen early, in genOMP This removes the last use of genOmpObectList2, which has now been removed. --- flang/lib/Lower/OpenMP/ClauseProcessor.h | 5 +- flang/lib/Lower/OpenMP/DataSharingProcessor.h | 5 +- flang/lib/Lower/OpenMP/OpenMP.cpp | 424 +- flang/lib/Lower/OpenMP/Utils.cpp | 30 +- flang/lib/Lower/OpenMP/Utils.h| 6 +- 5 files changed, 218 insertions(+), 252 deletions(-) diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index db7a1b8335f818..f4d659b70cfee7 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -49,9 +49,8 @@ class ClauseProcessor { public: ClauseProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, - const Fortran::parser::OmpClauseList &clauses) - : converter(converter), semaCtx(semaCtx), -clauses(makeClauses(clauses, semaCtx)) {} + const List &clauses) + : converter(converter), semaCtx(semaCtx), clauses(clauses) {} // 'Unique' clauses: They can appear at most once in the clause list. bool processCollapse( diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.h b/flang/lib/Lower/OpenMP/DataSharingProcessor.h index c11ee299c5d085..ef7b14327278e3 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.h +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.h @@ -78,13 +78,12 @@ class DataSharingProcessor { public: DataSharingProcessor(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semaCtx, - const Fortran::parser::OmpClauseList &opClauseList, + const List &clauses, Fortran::lower::pft::Evaluation &eval, bool useDelayedPrivatization = false, Fortran::lower::SymMap *symTable = nullptr) : hasLastPrivateOp(false), converter(converter), -firOpBuilder(converter.getFirOpBuilder()), -clauses(omp::makeClauses(opClauseList, semaCtx)), eval(eval), +firOpBuilder(converter.getFirOpBuilder()), clauses(clauses), eval(eval), useDelayedPrivatization(useDelayedPrivatization), symTable(symTable) {} // Privatisation is split into two steps. diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index edae453972d3d9..23dc25ac1ae9a1 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -17,6 +17,7 @@ #include "DataSharingProcessor.h" #include "DirectivesCommon.h" #include "ReductionProcessor.h" +#include "Utils.h" #include "flang/Common/idioms.h" #include "flang/Lower/Bridge.h" #include "flang/Lower/ConvertExpr.h" @@ -310,14 +311,15 @@ static void getDeclareTargetInfo( } else if (const auto *clauseList{ Fortran::parser::Unwrap( spec.u)}) { -if (clauseList->v.empty()) { +List clauses = makeClauses(*clauseList, semaCtx); +if (clauses.empty()) { // Case: declare target, implicit capture of function symbolAndClause.emplace_back( mlir::omp::DeclareTargetCaptureClause::to, eval.getOwningProcedure()->getSubprogramSymbol()); } -ClauseProcessor cp(converter, semaCtx, *clauseList); +ClauseProcessor cp(converter, semaCtx, clauses); cp.processDeviceType(clauseOps); cp.processEnter(symbolAndClause); cp.processLink(symbolAndClause); @@ -597,14 +599,11 @@ static void removeStoreOp(mlir::Operation *reductionOp, mlir::Value symVal) { // TODO: Generate the reduction operation during lowering instead of creating // and removing operations since this is not a robust approach. Also, removing // ops in the builder (instead of a rewriter) is probably not the best approach. -static void -genOpenMPReduction(Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semaCtx, - const Fortran::parser::OmpClauseList &clauseList) { +static void genOpenMPReduction(Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semaCtx, + const List &clauses) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - List clauses{makeClauses(clauseList, semaCtx)}; - for (const Clause &clause : clauses) { if (const auto &reductionClause = std::get_if(&clause.u)) { @@ -812,7 +811,7 @@ str
[llvm-branch-commits] [flang] [flang][OpenMP] Move clause/object conversion to happen early, in genOMP (PR #87074)
https://github.com/kparzysz closed https://github.com/llvm/llvm-project/pull/87074 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [flang] [flang][OpenMP] Move clause/object conversion to happen early, in genOMP (PR #87074)
kparzysz wrote: Replaced by https://github.com/llvm/llvm-project/pull/87086 https://github.com/llvm/llvm-project/pull/87074 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Frontend][OpenMP] Refactor getLeafConstructs, add getCompoundConstruct (PR #87247)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/87247 Emit a special leaf constuct table in DirectiveEmitter.cpp, which will allow both decomposition of a construct into leafs, and composition of constituent constructs into a single compound construct (is possible). >From 2fec99813013adf1ab6b262132ddebe4356ce643 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 1 Apr 2024 10:07:45 -0500 Subject: [PATCH] [Frontend][OpenMP] Refactor getLeafConstructs, add getCompoundConstruct Emit a special leaf constuct table in DirectiveEmitter.cpp, which will allow both decomposition of a construct into leafs, and composition of constituent constructs into a single compound construct (is possible). --- llvm/include/llvm/Frontend/OpenMP/OMP.h | 7 + llvm/lib/Frontend/OpenMP/OMP.cpp | 64 +- llvm/unittests/Frontend/CMakeLists.txt| 1 + llvm/unittests/Frontend/OpenMPComposeTest.cpp | 40 llvm/utils/TableGen/DirectiveEmitter.cpp | 194 +++--- 5 files changed, 235 insertions(+), 71 deletions(-) create mode 100644 llvm/unittests/Frontend/OpenMPComposeTest.cpp diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.h b/llvm/include/llvm/Frontend/OpenMP/OMP.h index a85cd9d344c6d7..4ed47f15dfe59e 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.h @@ -15,4 +15,11 @@ #include "llvm/Frontend/OpenMP/OMP.h.inc" +#include "llvm/ADT/ArrayRef.h" + +namespace llvm::omp { +ArrayRef getLeafConstructs(Directive D); +Directive getCompoundConstruct(ArrayRef Parts); +} // namespace llvm::omp + #endif // LLVM_FRONTEND_OPENMP_OMP_H diff --git a/llvm/lib/Frontend/OpenMP/OMP.cpp b/llvm/lib/Frontend/OpenMP/OMP.cpp index 4f2f95392648b3..dd99d3d074fd1e 100644 --- a/llvm/lib/Frontend/OpenMP/OMP.cpp +++ b/llvm/lib/Frontend/OpenMP/OMP.cpp @@ -8,12 +8,74 @@ #include "llvm/Frontend/OpenMP/OMP.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include +#include +#include + using namespace llvm; -using namespace omp; +using namespace llvm::omp; #define GEN_DIRECTIVES_IMPL #include "llvm/Frontend/OpenMP/OMP.inc" + +namespace llvm::omp { +ArrayRef getLeafConstructs(Directive D) { + auto Idx = static_cast(D); + if (Idx < 0 || Idx >= static_cast(Directive_enumSize)) +return {}; + const auto *Row = LeafConstructTable[LeafConstructTableOrdering[Idx]]; + return ArrayRef(&Row[2], &Row[2] + static_cast(Row[1])); +} + +Directive getCompoundConstruct(ArrayRef Parts) { + if (Parts.empty()) +return OMPD_unknown; + + // Parts don't have to be leafs, so expand them into leafs first. + // Store the expanded leafs in the same format as rows in the leaf + // table (generated by tablegen). + SmallVector RawLeafs(2); + for (Directive P : Parts) { +ArrayRef Ls = getLeafConstructs(P); +if (!Ls.empty()) + RawLeafs.append(Ls.begin(), Ls.end()); +else + RawLeafs.push_back(P); + } + + auto GivenLeafs{ArrayRef(RawLeafs).drop_front(2)}; + if (GivenLeafs.size() == 1) +return GivenLeafs.front(); + RawLeafs[1] = static_cast(GivenLeafs.size()); + + auto Iter = llvm::lower_bound( + LeafConstructTable, + static_cast>(RawLeafs.data()), + [](const auto *RowA, const auto *RowB) { +const auto *BeginA = &RowA[2]; +const auto *EndA = BeginA + static_cast(RowA[1]); +const auto *BeginB = &RowB[2]; +const auto *EndB = BeginB + static_cast(RowB[1]); +if (BeginA == EndA && BeginB == EndB) + return static_cast(RowA[0]) < static_cast(RowB[0]); +return std::lexicographical_compare(BeginA, EndA, BeginB, EndB); + }); + + if (Iter == std::end(LeafConstructTable)) +return OMPD_unknown; + + // Verify that we got a match. + Directive Found = (*Iter)[0]; + ArrayRef FoundLeafs = getLeafConstructs(Found); + if (FoundLeafs == GivenLeafs) +return Found; + return OMPD_unknown; +} +} // namespace llvm::omp diff --git a/llvm/unittests/Frontend/CMakeLists.txt b/llvm/unittests/Frontend/CMakeLists.txt index c6f60142d6276a..ddb6a16cbb984e 100644 --- a/llvm/unittests/Frontend/CMakeLists.txt +++ b/llvm/unittests/Frontend/CMakeLists.txt @@ -14,6 +14,7 @@ add_llvm_unittest(LLVMFrontendTests OpenMPContextTest.cpp OpenMPIRBuilderTest.cpp OpenMPParsingTest.cpp + OpenMPComposeTest.cpp DEPENDS acc_gen diff --git a/llvm/unittests/Frontend/OpenMPComposeTest.cpp b/llvm/unittests/Frontend/OpenMPComposeTest.cpp new file mode 100644 index 00..2dc35aca8842e9 --- /dev/null +++ b/llvm/unittests/Frontend/OpenMPComposeTest.cpp @@ -0,0 +1,40 @@ +//===- llvm/unittests/Frontend/OpenMPComposeTest.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LIC
[llvm-branch-commits] [llvm] [Frontend][OpenMP] Refactor getLeafConstructs, add getCompoundConstruct (PR #87247)
https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/87247 >From 291dc48d5e0b7e0ee39681a1276bd1d63f456b01 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 1 Apr 2024 10:07:45 -0500 Subject: [PATCH] [Frontend][OpenMP] Refactor getLeafConstructs, add getCompoundConstruct Emit a special leaf constuct table in DirectiveEmitter.cpp, which will allow both decomposition of a construct into leafs, and composition of constituent constructs into a single compound construct (is possible). --- llvm/include/llvm/Frontend/OpenMP/OMP.h | 7 + llvm/lib/Frontend/OpenMP/OMP.cpp | 64 +- llvm/test/TableGen/directive1.td | 19 +- llvm/test/TableGen/directive2.td | 19 +- llvm/unittests/Frontend/CMakeLists.txt| 1 + llvm/unittests/Frontend/OpenMPComposeTest.cpp | 41 llvm/utils/TableGen/DirectiveEmitter.cpp | 194 +++--- 7 files changed, 258 insertions(+), 87 deletions(-) create mode 100644 llvm/unittests/Frontend/OpenMPComposeTest.cpp diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.h b/llvm/include/llvm/Frontend/OpenMP/OMP.h index a85cd9d344c6d7..4ed47f15dfe59e 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.h @@ -15,4 +15,11 @@ #include "llvm/Frontend/OpenMP/OMP.h.inc" +#include "llvm/ADT/ArrayRef.h" + +namespace llvm::omp { +ArrayRef getLeafConstructs(Directive D); +Directive getCompoundConstruct(ArrayRef Parts); +} // namespace llvm::omp + #endif // LLVM_FRONTEND_OPENMP_OMP_H diff --git a/llvm/lib/Frontend/OpenMP/OMP.cpp b/llvm/lib/Frontend/OpenMP/OMP.cpp index 4f2f95392648b3..dd99d3d074fd1e 100644 --- a/llvm/lib/Frontend/OpenMP/OMP.cpp +++ b/llvm/lib/Frontend/OpenMP/OMP.cpp @@ -8,12 +8,74 @@ #include "llvm/Frontend/OpenMP/OMP.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include +#include +#include + using namespace llvm; -using namespace omp; +using namespace llvm::omp; #define GEN_DIRECTIVES_IMPL #include "llvm/Frontend/OpenMP/OMP.inc" + +namespace llvm::omp { +ArrayRef getLeafConstructs(Directive D) { + auto Idx = static_cast(D); + if (Idx < 0 || Idx >= static_cast(Directive_enumSize)) +return {}; + const auto *Row = LeafConstructTable[LeafConstructTableOrdering[Idx]]; + return ArrayRef(&Row[2], &Row[2] + static_cast(Row[1])); +} + +Directive getCompoundConstruct(ArrayRef Parts) { + if (Parts.empty()) +return OMPD_unknown; + + // Parts don't have to be leafs, so expand them into leafs first. + // Store the expanded leafs in the same format as rows in the leaf + // table (generated by tablegen). + SmallVector RawLeafs(2); + for (Directive P : Parts) { +ArrayRef Ls = getLeafConstructs(P); +if (!Ls.empty()) + RawLeafs.append(Ls.begin(), Ls.end()); +else + RawLeafs.push_back(P); + } + + auto GivenLeafs{ArrayRef(RawLeafs).drop_front(2)}; + if (GivenLeafs.size() == 1) +return GivenLeafs.front(); + RawLeafs[1] = static_cast(GivenLeafs.size()); + + auto Iter = llvm::lower_bound( + LeafConstructTable, + static_cast>(RawLeafs.data()), + [](const auto *RowA, const auto *RowB) { +const auto *BeginA = &RowA[2]; +const auto *EndA = BeginA + static_cast(RowA[1]); +const auto *BeginB = &RowB[2]; +const auto *EndB = BeginB + static_cast(RowB[1]); +if (BeginA == EndA && BeginB == EndB) + return static_cast(RowA[0]) < static_cast(RowB[0]); +return std::lexicographical_compare(BeginA, EndA, BeginB, EndB); + }); + + if (Iter == std::end(LeafConstructTable)) +return OMPD_unknown; + + // Verify that we got a match. + Directive Found = (*Iter)[0]; + ArrayRef FoundLeafs = getLeafConstructs(Found); + if (FoundLeafs == GivenLeafs) +return Found; + return OMPD_unknown; +} +} // namespace llvm::omp diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td index 3184f625ead928..e6150210e7e9a4 100644 --- a/llvm/test/TableGen/directive1.td +++ b/llvm/test/TableGen/directive1.td @@ -52,6 +52,7 @@ def TDL_DirA : Directive<"dira"> { // CHECK-EMPTY: // CHECK-NEXT: #include "llvm/ADT/ArrayRef.h" // CHECK-NEXT: #include "llvm/ADT/BitmaskEnum.h" +// CHECK-NEXT: #include // CHECK-EMPTY: // CHECK-NEXT: namespace llvm { // CHECK-NEXT: class StringRef; @@ -112,7 +113,7 @@ def TDL_DirA : Directive<"dira"> { // CHECK-NEXT: /// Return true if \p C is a valid clause for \p D in version \p Version. // CHECK-NEXT: bool isAllowedClauseForDirective(Directive D, Clause C, unsigned Version); // CHECK-EMPTY: -// CHECK-NEXT: llvm::ArrayRef getLeafConstructs(Directive D); +// CHECK-NEXT: constexpr std::size_t getMaxLeafCount() { return 0; } // CHECK-NEXT: Association getDirectiveAssociation(Directive D); // CHECK-NEXT:
[llvm-branch-commits] [llvm] [Frontend][OpenMP] Add functions for checking construct type (PR #87258)
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/87258 Implement helper functions to identify leaf, composite, and combined constructs. >From a889f3074fc8c4ae5c6d9480308be0501217b9ff Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 11 Mar 2024 12:55:38 -0500 Subject: [PATCH] [Frontend][OpenMP] Add functions for checking construct type Implement helper functions to identify leaf, composite, and combined constructs. --- llvm/include/llvm/Frontend/OpenMP/OMP.h | 4 +++ llvm/lib/Frontend/OpenMP/OMP.cpp | 25 ++ llvm/unittests/Frontend/OpenMPComposeTest.cpp | 26 +++ 3 files changed, 55 insertions(+) diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.h b/llvm/include/llvm/Frontend/OpenMP/OMP.h index 4ed47f15dfe59e..ec8ae68f1c2ca0 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.h @@ -20,6 +20,10 @@ namespace llvm::omp { ArrayRef getLeafConstructs(Directive D); Directive getCompoundConstruct(ArrayRef Parts); + +bool isLeafConstruct(Directive D); +bool isCompositeConstruct(Directive D); +bool isCombinedConstruct(Directive D); } // namespace llvm::omp #endif // LLVM_FRONTEND_OPENMP_OMP_H diff --git a/llvm/lib/Frontend/OpenMP/OMP.cpp b/llvm/lib/Frontend/OpenMP/OMP.cpp index dd99d3d074fd1e..98d7c63bb8537e 100644 --- a/llvm/lib/Frontend/OpenMP/OMP.cpp +++ b/llvm/lib/Frontend/OpenMP/OMP.cpp @@ -78,4 +78,29 @@ Directive getCompoundConstruct(ArrayRef Parts) { return Found; return OMPD_unknown; } + +bool isLeafConstruct(Directive D) { return getLeafConstructs(D).empty(); } + +bool isCompositeConstruct(Directive D) { + // OpenMP Spec 5.2: [17.3, 8-9] + // If directive-name-A and directive-name-B both correspond to loop- + // associated constructs then directive-name is a composite construct + llvm::ArrayRef Leafs{getLeafConstructs(D)}; + if (Leafs.empty()) +return false; + if (getDirectiveAssociation(Leafs.front()) != Association::Loop) +return false; + + size_t numLoopConstructs = + llvm::count_if(Leafs.drop_front(), [](Directive L) { +return getDirectiveAssociation(L) == Association::Loop; + }); + return numLoopConstructs != 0; +} + +bool isCombinedConstruct(Directive D) { + // OpenMP Spec 5.2: [17.3, 9-10] + // Otherwise directive-name is a combined construct. + return !getLeafConstructs(D).empty() && !isCompositeConstruct(D); +} } // namespace llvm::omp diff --git a/llvm/unittests/Frontend/OpenMPComposeTest.cpp b/llvm/unittests/Frontend/OpenMPComposeTest.cpp index 29b1be4eb3432c..cc02af8bf67c26 100644 --- a/llvm/unittests/Frontend/OpenMPComposeTest.cpp +++ b/llvm/unittests/Frontend/OpenMPComposeTest.cpp @@ -39,3 +39,29 @@ TEST(Composition, GetCompoundConstruct) { Directive C7 = getCompoundConstruct({OMPD_parallel_for, OMPD_simd}); ASSERT_EQ(C7, OMPD_parallel_for_simd); } + +TEST(Composition, IsLeafConstruct) { + ASSERT_TRUE(isLeafConstruct(OMPD_loop)); + ASSERT_TRUE(isLeafConstruct(OMPD_teams)); + ASSERT_FALSE(isLeafConstruct(OMPD_for_simd)); + ASSERT_FALSE(isLeafConstruct(OMPD_distribute_simd)); +} + +TEST(Composition, IsCompositeConstruct) { + ASSERT_TRUE(isCompositeConstruct(OMPD_distribute_simd)); + ASSERT_FALSE(isCompositeConstruct(OMPD_for)); + ASSERT_TRUE(isCompositeConstruct(OMPD_for_simd)); + // directive-name-A = "parallel", directive-name-B = "for simd", + // only directive-name-A is loop-associated, so this is not a + // composite construct, even though "for simd" is. + ASSERT_FALSE(isCompositeConstruct(OMPD_parallel_for_simd)); +} + +TEST(Composition, IsCombinedConstruct) { + // "parallel for simd" is a combined construct, see comment in + // IsCompositeConstruct. + ASSERT_TRUE(isCombinedConstruct(OMPD_parallel_for_simd)); + ASSERT_FALSE(isCombinedConstruct(OMPD_for_simd)); + ASSERT_TRUE(isCombinedConstruct(OMPD_parallel_for)); + ASSERT_FALSE(isCombinedConstruct(OMPD_parallel)); +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Frontend][OpenMP] Refactor getLeafConstructs, add getCompoundConstruct (PR #87247)
https://github.com/kparzysz edited https://github.com/llvm/llvm-project/pull/87247 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Frontend][OpenMP] Refactor getLeafConstructs, add getCompoundConstruct (PR #87247)
https://github.com/kparzysz commented: I have considered putting more information in the .td file, but I decided against it. The main reason was that TableGen would need to have a lot more knowledge about OMP directives than it does now: - It would need to be aware of OpenMP's definitions of "composite" vs. "combined" directives. This information would need to be encoded in the directive emitter (as a part of TableGen), plus it would also be in the OMP.cpp file (as a part of the compiler). In my view, the .td file should be easy to update (or in other words hard to make a mistake in). - The directive emitter is shared between OpenMP and OpenACC, and this change would mean that we need to distinguish these two targets in the emitters. Even if there was 1000 directives to search through, the search is binary, requiring in the worst case ~10 steps. https://github.com/llvm/llvm-project/pull/87247 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Frontend][OpenMP] Refactor getLeafConstructs, add getCompoundConstruct (PR #87247)
@@ -8,12 +8,74 @@ #include "llvm/Frontend/OpenMP/OMP.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include +#include +#include + using namespace llvm; -using namespace omp; +using namespace llvm::omp; #define GEN_DIRECTIVES_IMPL #include "llvm/Frontend/OpenMP/OMP.inc" + +namespace llvm::omp { +ArrayRef getLeafConstructs(Directive D) { + auto Idx = static_cast(D); + if (Idx < 0 || Idx >= static_cast(Directive_enumSize)) kparzysz wrote: The underlying type of `Directive` is int, that's why I used int, but your suggestion is ok as well. https://github.com/llvm/llvm-project/pull/87247 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Frontend][OpenMP] Refactor getLeafConstructs, add getCompoundConstruct (PR #87247)
@@ -8,12 +8,74 @@ #include "llvm/Frontend/OpenMP/OMP.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include +#include +#include + using namespace llvm; -using namespace omp; +using namespace llvm::omp; #define GEN_DIRECTIVES_IMPL #include "llvm/Frontend/OpenMP/OMP.inc" + +namespace llvm::omp { +ArrayRef getLeafConstructs(Directive D) { + auto Idx = static_cast(D); + if (Idx < 0 || Idx >= static_cast(Directive_enumSize)) +return {}; + const auto *Row = LeafConstructTable[LeafConstructTableOrdering[Idx]]; + return ArrayRef(&Row[2], &Row[2] + static_cast(Row[1])); +} + +Directive getCompoundConstruct(ArrayRef Parts) { + if (Parts.empty()) +return OMPD_unknown; + + // Parts don't have to be leafs, so expand them into leafs first. + // Store the expanded leafs in the same format as rows in the leaf + // table (generated by tablegen). + SmallVector RawLeafs(2); + for (Directive P : Parts) { +ArrayRef Ls = getLeafConstructs(P); +if (!Ls.empty()) + RawLeafs.append(Ls.begin(), Ls.end()); +else + RawLeafs.push_back(P); + } + + auto GivenLeafs{ArrayRef(RawLeafs).drop_front(2)}; kparzysz wrote: Done https://github.com/llvm/llvm-project/pull/87247 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Frontend][OpenMP] Refactor getLeafConstructs, add getCompoundConstruct (PR #87247)
@@ -0,0 +1,41 @@ +//===- llvm/unittests/Frontend/OpenMPComposeTest.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Frontend/OpenMP/OMP.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::omp; + +TEST(Composition, GetLeafConstructs) { + ArrayRef L1 = getLeafConstructs(OMPD_loop); + ASSERT_EQ(L1, (ArrayRef{})); + ArrayRef L2 = getLeafConstructs(OMPD_parallel_for); + ASSERT_EQ(L2, (ArrayRef{OMPD_parallel, OMPD_for})); + ArrayRef L3 = getLeafConstructs(OMPD_parallel_for_simd); + ASSERT_EQ(L3, (ArrayRef{OMPD_parallel, OMPD_for, OMPD_simd})); +} + +TEST(Composition, GetCompoundConstruct) { + Directive C1 = + getCompoundConstruct({OMPD_target, OMPD_teams, OMPD_distribute}); + ASSERT_EQ(C1, OMPD_target_teams_distribute); + Directive C2 = getCompoundConstruct({OMPD_target}); + ASSERT_EQ(C2, OMPD_target); + Directive C3 = getCompoundConstruct({OMPD_target, OMPD_masked}); + ASSERT_EQ(C3, OMPD_unknown); + Directive C4 = getCompoundConstruct({OMPD_target, OMPD_teams_distribute}); + ASSERT_EQ(C4, OMPD_target_teams_distribute); + Directive C5 = getCompoundConstruct({OMPD_target, OMPD_teams_distribute}); + ASSERT_EQ(C5, OMPD_target_teams_distribute); kparzysz wrote: Indeed. Removed. https://github.com/llvm/llvm-project/pull/87247 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits