[clang] [OpenMP][Docs] Update OpenMP release notes with 'omp scope' (PR #109752)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/109752 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [OpenMP][Docs] Update OpenMP supported features table (PR #109726)
https://github.com/alexey-bataev approved this pull request. LG Also, add to Release notes https://github.com/llvm/llvm-project/pull/109726 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang][OpenMP] Add codegen for scope directive (PR #109197)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/109197 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [clang][OpenMP] Add codegen for scope directive (PR #109197)
@@ -0,0 +1,2267 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix=CHECK1 + +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify -Wno-vla %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK1 + +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify -Wno-vla %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK4 + +// RUN: %clang_cc1 -verify -Wno-vla -triple x86_64-apple-darwin10 -std=c++11 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5 +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK6 + +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}" +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}" +// RUN: %clang_cc1 -verify -Wno-vla -triple x86_64-apple-darwin10 -std=c++11 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}" +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}" +// expected-no-diagnostics + +typedef void **omp_allocator_handle_t; +extern const omp_allocator_handle_t omp_null_allocator; +extern const omp_allocator_handle_t omp_default_mem_alloc; +extern const omp_allocator_handle_t omp_large_cap_mem_alloc; +extern const omp_allocator_handle_t omp_const_mem_alloc; +extern const omp_allocator_handle_t omp_high_bw_mem_alloc; +extern const omp_allocator_handle_t omp_low_lat_mem_alloc; +extern const omp_allocator_handle_t omp_cgroup_mem_alloc; +extern const omp_allocator_handle_t omp_pteam_mem_alloc; +extern const omp_allocator_handle_t omp_thread_mem_alloc; alexey-bataev wrote: Why do you need these decls? https://github.com/llvm/llvm-project/pull/109197 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Slightly refactor EndOpenMPDSABlock for readability, NFC (PR #109003)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/109003 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Slightly refactor EndOpenMPDSABlock for readability, NFC (PR #109003)
@@ -2861,113 +2861,120 @@ void SemaOpenMP::EndOpenMPDSABlock(Stmt *CurDirective) { // clause requires an accessible, unambiguous default constructor for the // class type, unless the list item is also specified in a firstprivate // clause. - if (const auto *D = dyn_cast_or_null(CurDirective)) { -for (OMPClause *C : D->clauses()) { - if (auto *Clause = dyn_cast(C)) { -SmallVector PrivateCopies; -for (Expr *DE : Clause->varlist()) { - if (DE->isValueDependent() || DE->isTypeDependent()) { -PrivateCopies.push_back(nullptr); -continue; - } - auto *DRE = cast(DE->IgnoreParens()); - auto *VD = cast(DRE->getDecl()); - QualType Type = VD->getType().getNonReferenceType(); - const DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(VD, /*FromParent=*/false); - if (DVar.CKind == OMPC_lastprivate) { -// Generate helper private variable and initialize it with the -// default value. The address of the original variable is replaced -// by the address of the new private variable in CodeGen. This new -// variable is not added to IdResolver, so the code in the OpenMP -// region uses original variable for proper diagnostics. -VarDecl *VDPrivate = buildVarDecl( -SemaRef, DE->getExprLoc(), Type.getUnqualifiedType(), -VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); -SemaRef.ActOnUninitializedDecl(VDPrivate); -if (VDPrivate->isInvalidDecl()) { - PrivateCopies.push_back(nullptr); - continue; -} -PrivateCopies.push_back(buildDeclRefExpr( -SemaRef, VDPrivate, DE->getType(), DE->getExprLoc())); - } else { -// The variable is also a firstprivate, so initialization sequence -// for private copy is generated already. -PrivateCopies.push_back(nullptr); - } -} -Clause->setPrivateCopies(PrivateCopies); -continue; - } - // Finalize nontemporal clause by handling private copies, if any. - if (auto *Clause = dyn_cast(C)) { -SmallVector PrivateRefs; -for (Expr *RefExpr : Clause->varlist()) { - assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); - SourceLocation ELoc; - SourceRange ERange; - Expr *SimpleRefExpr = RefExpr; - auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); - if (Res.second) -// It will be analyzed later. -PrivateRefs.push_back(RefExpr); - ValueDecl *D = Res.first; - if (!D) -continue; - const DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(D, /*FromParent=*/false); - PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy - : SimpleRefExpr); -} -Clause->setPrivateRefs(PrivateRefs); + auto finalizeLastprivate = [&](OMPLastprivateClause *Clause) { alexey-bataev wrote: FinalizeLastprivate https://github.com/llvm/llvm-project/pull/109003 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Slightly refactor EndOpenMPDSABlock for readability, NFC (PR #109003)
@@ -2861,113 +2861,120 @@ void SemaOpenMP::EndOpenMPDSABlock(Stmt *CurDirective) { // clause requires an accessible, unambiguous default constructor for the // class type, unless the list item is also specified in a firstprivate // clause. - if (const auto *D = dyn_cast_or_null(CurDirective)) { -for (OMPClause *C : D->clauses()) { - if (auto *Clause = dyn_cast(C)) { -SmallVector PrivateCopies; -for (Expr *DE : Clause->varlist()) { - if (DE->isValueDependent() || DE->isTypeDependent()) { -PrivateCopies.push_back(nullptr); -continue; - } - auto *DRE = cast(DE->IgnoreParens()); - auto *VD = cast(DRE->getDecl()); - QualType Type = VD->getType().getNonReferenceType(); - const DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(VD, /*FromParent=*/false); - if (DVar.CKind == OMPC_lastprivate) { -// Generate helper private variable and initialize it with the -// default value. The address of the original variable is replaced -// by the address of the new private variable in CodeGen. This new -// variable is not added to IdResolver, so the code in the OpenMP -// region uses original variable for proper diagnostics. -VarDecl *VDPrivate = buildVarDecl( -SemaRef, DE->getExprLoc(), Type.getUnqualifiedType(), -VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); -SemaRef.ActOnUninitializedDecl(VDPrivate); -if (VDPrivate->isInvalidDecl()) { - PrivateCopies.push_back(nullptr); - continue; -} -PrivateCopies.push_back(buildDeclRefExpr( -SemaRef, VDPrivate, DE->getType(), DE->getExprLoc())); - } else { -// The variable is also a firstprivate, so initialization sequence -// for private copy is generated already. -PrivateCopies.push_back(nullptr); - } -} -Clause->setPrivateCopies(PrivateCopies); -continue; - } - // Finalize nontemporal clause by handling private copies, if any. - if (auto *Clause = dyn_cast(C)) { -SmallVector PrivateRefs; -for (Expr *RefExpr : Clause->varlist()) { - assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); - SourceLocation ELoc; - SourceRange ERange; - Expr *SimpleRefExpr = RefExpr; - auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); - if (Res.second) -// It will be analyzed later. -PrivateRefs.push_back(RefExpr); - ValueDecl *D = Res.first; - if (!D) -continue; - const DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(D, /*FromParent=*/false); - PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy - : SimpleRefExpr); -} -Clause->setPrivateRefs(PrivateRefs); + auto finalizeLastprivate = [&](OMPLastprivateClause *Clause) { +SmallVector PrivateCopies; +for (Expr *DE : Clause->varlist()) { + if (DE->isValueDependent() || DE->isTypeDependent()) { +PrivateCopies.push_back(nullptr); continue; } - if (auto *Clause = dyn_cast(C)) { -for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { - OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); - auto *DRE = dyn_cast(D.Allocator->IgnoreParenImpCasts()); - if (!DRE) -continue; - ValueDecl *VD = DRE->getDecl(); - if (!VD || !isa(VD)) -continue; - DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(VD, /*FromParent=*/false); - // OpenMP [2.12.5, target Construct] - // Memory allocators that appear in a uses_allocators clause cannot - // appear in other data-sharing attribute clauses or data-mapping - // attribute clauses in the same construct. - Expr *MapExpr = nullptr; - if (DVar.RefExpr || - DSAStack->checkMappableExprComponentListsForDecl( - VD, /*CurrentRegionOnly=*/true, - [VD, &MapExpr]( - OMPClauseMappableExprCommon::MappableExprComponentListRef - MapExprComponents, - OpenMPClauseKind C) { -auto MI = MapExprComponents.rbegin(); -auto ME = MapExprComponents.rend(); -if (MI != ME && -MI->getAssociatedDeclaration()->getCanonicalDecl() == -VD->getCanonicalDecl()) { - MapExpr = MI->getAssociatedExpression(); - return true; -} -return false; -
[clang] [clang][OpenMP] Slightly refactor EndOpenMPDSABlock for readability, NFC (PR #109003)
@@ -2861,113 +2861,120 @@ void SemaOpenMP::EndOpenMPDSABlock(Stmt *CurDirective) { // clause requires an accessible, unambiguous default constructor for the // class type, unless the list item is also specified in a firstprivate // clause. - if (const auto *D = dyn_cast_or_null(CurDirective)) { -for (OMPClause *C : D->clauses()) { - if (auto *Clause = dyn_cast(C)) { -SmallVector PrivateCopies; -for (Expr *DE : Clause->varlist()) { - if (DE->isValueDependent() || DE->isTypeDependent()) { -PrivateCopies.push_back(nullptr); -continue; - } - auto *DRE = cast(DE->IgnoreParens()); - auto *VD = cast(DRE->getDecl()); - QualType Type = VD->getType().getNonReferenceType(); - const DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(VD, /*FromParent=*/false); - if (DVar.CKind == OMPC_lastprivate) { -// Generate helper private variable and initialize it with the -// default value. The address of the original variable is replaced -// by the address of the new private variable in CodeGen. This new -// variable is not added to IdResolver, so the code in the OpenMP -// region uses original variable for proper diagnostics. -VarDecl *VDPrivate = buildVarDecl( -SemaRef, DE->getExprLoc(), Type.getUnqualifiedType(), -VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); -SemaRef.ActOnUninitializedDecl(VDPrivate); -if (VDPrivate->isInvalidDecl()) { - PrivateCopies.push_back(nullptr); - continue; -} -PrivateCopies.push_back(buildDeclRefExpr( -SemaRef, VDPrivate, DE->getType(), DE->getExprLoc())); - } else { -// The variable is also a firstprivate, so initialization sequence -// for private copy is generated already. -PrivateCopies.push_back(nullptr); - } -} -Clause->setPrivateCopies(PrivateCopies); -continue; - } - // Finalize nontemporal clause by handling private copies, if any. - if (auto *Clause = dyn_cast(C)) { -SmallVector PrivateRefs; -for (Expr *RefExpr : Clause->varlist()) { - assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); - SourceLocation ELoc; - SourceRange ERange; - Expr *SimpleRefExpr = RefExpr; - auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); - if (Res.second) -// It will be analyzed later. -PrivateRefs.push_back(RefExpr); - ValueDecl *D = Res.first; - if (!D) -continue; - const DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(D, /*FromParent=*/false); - PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy - : SimpleRefExpr); -} -Clause->setPrivateRefs(PrivateRefs); + auto finalizeLastprivate = [&](OMPLastprivateClause *Clause) { +SmallVector PrivateCopies; +for (Expr *DE : Clause->varlist()) { + if (DE->isValueDependent() || DE->isTypeDependent()) { +PrivateCopies.push_back(nullptr); continue; } - if (auto *Clause = dyn_cast(C)) { -for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { - OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); - auto *DRE = dyn_cast(D.Allocator->IgnoreParenImpCasts()); - if (!DRE) -continue; - ValueDecl *VD = DRE->getDecl(); - if (!VD || !isa(VD)) -continue; - DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(VD, /*FromParent=*/false); - // OpenMP [2.12.5, target Construct] - // Memory allocators that appear in a uses_allocators clause cannot - // appear in other data-sharing attribute clauses or data-mapping - // attribute clauses in the same construct. - Expr *MapExpr = nullptr; - if (DVar.RefExpr || - DSAStack->checkMappableExprComponentListsForDecl( - VD, /*CurrentRegionOnly=*/true, - [VD, &MapExpr]( - OMPClauseMappableExprCommon::MappableExprComponentListRef - MapExprComponents, - OpenMPClauseKind C) { -auto MI = MapExprComponents.rbegin(); -auto ME = MapExprComponents.rend(); -if (MI != ME && -MI->getAssociatedDeclaration()->getCanonicalDecl() == -VD->getCanonicalDecl()) { - MapExpr = MI->getAssociatedExpression(); - return true; -} -return false; -
[clang] [clang][OpenMP] Slightly refactor EndOpenMPDSABlock for readability, NFC (PR #109003)
@@ -2861,113 +2861,120 @@ void SemaOpenMP::EndOpenMPDSABlock(Stmt *CurDirective) { // clause requires an accessible, unambiguous default constructor for the // class type, unless the list item is also specified in a firstprivate // clause. - if (const auto *D = dyn_cast_or_null(CurDirective)) { -for (OMPClause *C : D->clauses()) { - if (auto *Clause = dyn_cast(C)) { -SmallVector PrivateCopies; -for (Expr *DE : Clause->varlist()) { - if (DE->isValueDependent() || DE->isTypeDependent()) { -PrivateCopies.push_back(nullptr); -continue; - } - auto *DRE = cast(DE->IgnoreParens()); - auto *VD = cast(DRE->getDecl()); - QualType Type = VD->getType().getNonReferenceType(); - const DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(VD, /*FromParent=*/false); - if (DVar.CKind == OMPC_lastprivate) { -// Generate helper private variable and initialize it with the -// default value. The address of the original variable is replaced -// by the address of the new private variable in CodeGen. This new -// variable is not added to IdResolver, so the code in the OpenMP -// region uses original variable for proper diagnostics. -VarDecl *VDPrivate = buildVarDecl( -SemaRef, DE->getExprLoc(), Type.getUnqualifiedType(), -VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); -SemaRef.ActOnUninitializedDecl(VDPrivate); -if (VDPrivate->isInvalidDecl()) { - PrivateCopies.push_back(nullptr); - continue; -} -PrivateCopies.push_back(buildDeclRefExpr( -SemaRef, VDPrivate, DE->getType(), DE->getExprLoc())); - } else { -// The variable is also a firstprivate, so initialization sequence -// for private copy is generated already. -PrivateCopies.push_back(nullptr); - } -} -Clause->setPrivateCopies(PrivateCopies); -continue; - } - // Finalize nontemporal clause by handling private copies, if any. - if (auto *Clause = dyn_cast(C)) { -SmallVector PrivateRefs; -for (Expr *RefExpr : Clause->varlist()) { - assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); - SourceLocation ELoc; - SourceRange ERange; - Expr *SimpleRefExpr = RefExpr; - auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); - if (Res.second) -// It will be analyzed later. -PrivateRefs.push_back(RefExpr); - ValueDecl *D = Res.first; - if (!D) -continue; - const DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(D, /*FromParent=*/false); - PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy - : SimpleRefExpr); -} -Clause->setPrivateRefs(PrivateRefs); + auto finalizeLastprivate = [&](OMPLastprivateClause *Clause) { +SmallVector PrivateCopies; +for (Expr *DE : Clause->varlist()) { + if (DE->isValueDependent() || DE->isTypeDependent()) { +PrivateCopies.push_back(nullptr); continue; } - if (auto *Clause = dyn_cast(C)) { -for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { - OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); - auto *DRE = dyn_cast(D.Allocator->IgnoreParenImpCasts()); - if (!DRE) -continue; - ValueDecl *VD = DRE->getDecl(); - if (!VD || !isa(VD)) -continue; - DSAStackTy::DSAVarData DVar = - DSAStack->getTopDSA(VD, /*FromParent=*/false); - // OpenMP [2.12.5, target Construct] - // Memory allocators that appear in a uses_allocators clause cannot - // appear in other data-sharing attribute clauses or data-mapping - // attribute clauses in the same construct. - Expr *MapExpr = nullptr; - if (DVar.RefExpr || - DSAStack->checkMappableExprComponentListsForDecl( - VD, /*CurrentRegionOnly=*/true, - [VD, &MapExpr]( - OMPClauseMappableExprCommon::MappableExprComponentListRef - MapExprComponents, - OpenMPClauseKind C) { -auto MI = MapExprComponents.rbegin(); -auto ME = MapExprComponents.rend(); -if (MI != ME && -MI->getAssociatedDeclaration()->getCanonicalDecl() == -VD->getCanonicalDecl()) { - MapExpr = MI->getAssociatedExpression(); - return true; -} -return false; -
[clang] [clang][OpenMP] Simplify handling of implicit DSA/mapping information (PR #106786)
https://github.com/alexey-bataev approved this pull request. https://github.com/llvm/llvm-project/pull/106786 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CGOpenMPRuntime] Avoid repeated hash lookups (NFC) (PR #107358)
https://github.com/alexey-bataev approved this pull request. https://github.com/llvm/llvm-project/pull/107358 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CGOpenMPRuntime] Use DenseMap::operator[] (NFC) (PR #107158)
https://github.com/alexey-bataev approved this pull request. https://github.com/llvm/llvm-project/pull/107158 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Simplify handling of implicit DSA/mapping information (PR #106786)
@@ -6060,69 +6057,55 @@ StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective( return StmtError(); // Generate list of implicitly defined firstprivate variables. VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); +VariableImplicitInfo ImpInfo = DSAChecker.getImplicitInfo(); -SmallVector ImplicitFirstprivates( -DSAChecker.getImplicitFirstprivate()); -SmallVector ImplicitPrivates(DSAChecker.getImplicitPrivate()); -const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1; -SmallVector ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete]; -SmallVector -ImplicitMapModifiers[DefaultmapKindNum]; SmallVector -ImplicitMapModifiersLoc[DefaultmapKindNum]; +ImplicitMapModifiersLoc[VariableImplicitInfo::DefaultmapKindNum]; // Get the original location of present modifier from Defaultmap clause. -SourceLocation PresentModifierLocs[DefaultmapKindNum]; +SourceLocation PresentModifierLocs[VariableImplicitInfo::DefaultmapKindNum]; for (OMPClause *C : Clauses) { if (auto *DMC = dyn_cast(C)) if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present) PresentModifierLocs[DMC->getDefaultmapKind()] = DMC->getDefaultmapModifierLoc(); } -for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) { + +for (unsigned VC = 0; VC < VariableImplicitInfo::DefaultmapKindNum; ++VC) { auto K = static_cast(VC); alexey-bataev wrote: ```suggestion for (OpenMPDefaultmapClauseKind K : enum_seq_inclusive(OMPC_DEFAULTMAP_scalar, OMPC_DEFAULTMAP_unknown)) { ``` https://github.com/llvm/llvm-project/pull/106786 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] Diagnostic check for imperfect loop collapse (PR #96087)
alexey-bataev wrote: > Can you explain why the critical section version of the code is safe, and why > it is an improvement over simply not collapsing the loop? 1. I'm not saying it is safe, I'm just saying that something like this might be safe 2. Without properly collapsing the loops, the compiler won't be able to properly schedule the execution per programmer's request https://github.com/llvm/llvm-project/pull/96087 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] Diagnostic check for imperfect loop collapse (PR #96087)
alexey-bataev wrote: I suggest defining the canonical (pessimistic in performance, but optimistic in correctness) form of the loop and emit it in the frontend. Later OpenMPOpt pass can optimize this "canonical" (slow but correct) form to better (but still correct) form, if possible (dropping critical section, for example, if it is proved it is safe). https://github.com/llvm/llvm-project/pull/96087 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] Diagnostic check for imperfect loop collapse (PR #96087)
alexey-bataev wrote: > > something like > > > > > > ``` > > > bool Init[N] = {false}; > > > for (int ij = 0; ij < N*N; ij++) { > > > int i = ij / N, j = ij % N; > > > #pragma omp critical > > > if (!Init[i]) { > > > arr2[i] = i; > > > Init[i] = true; > > > } > > > arr1[i][j] += arr2[i]; > > > } > > > ``` > > > > I don't think synthesizing a critical region inside the collapsed loop will > be a win overall, and also I don't quite see how it helps in this case. A > correct version would be doing something like serialising the loop, I think, > which I suppose sort of bypasses the problem, but doesn't really solve it. > (When would we do such a transformation? How much analysis do we need to > avoid killing performance in non-contrived cases?) It should be done in the frontend. And here we should care about correctness, not performance. Sure, this can be optimized for better performance later in OpenMPOpt pass, but from the frontend we should get it working correctly. https://github.com/llvm/llvm-project/pull/96087 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] Diagnostic check for imperfect loop collapse (PR #96087)
alexey-bataev wrote: > > > FWIW, I don't think there's a reasonable, safe way to collapse loops like > > > this and maintain parallel semantics, but ICBW. > > > > > > I think, there is a proper way. Just annotate these instructions with > > something like: > > ``` > > if (first inner loop iteration) { > > arr[i][i] = ...; > > } > > ``` > > > > > > > > > > > > > > > > > > > > > > > > and it should be correct > > I think you're right for this particular test case, but I don't think that > solution works in general. Consider something like: > > ``` > int arr1[N][N], arr2[N]; > > #pragma omp parallel for collapse(2) > { > for (int i = 0; i < N; i++) { > arr2[i] = i; > for (int j = 0; j < N; j++) { > arr1[i][j] += arr2[i]; > } > } > } > ``` > > Now, if collapsed loop iterations take place in parallel or in an arbitrary > order, there could be a read from arr2[i] before the write (in the "first" > inner loop iteration). That is, I think we'd have something like: > > ``` > for (int ij = 0; ij < N*N; ij++) { > int i = ij / N, j = ij % N; > if (j == 0) { > arr2[i] = i; > } > arr1[i][j] += arr2[i]; > } > ``` > > and that's still not safe. something like ``` bool Init[N] = {false}; for (int ij = 0; ij < N*N; ij++) { int i = ij / N, j = ij % N; #pragma omp critical if (!Init[i]) { arr2[i] = i; Init[i] = true; } arr1[i][j] += arr2[i]; } ``` remarks or anything else still is not correct in this case. https://github.com/llvm/llvm-project/pull/96087 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
https://github.com/alexey-bataev closed https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] Diagnostic check for imperfect loop collapse (PR #96087)
alexey-bataev wrote: > FWIW, I don't think there's a reasonable, safe way to collapse loops like > this and maintain parallel semantics, but ICBW. I think, there is a proper way. Just annotate these instructions with something like: ``` if (first inner loop iteration) { arr[i][i] = ...; } ``` and it should be correct https://github.com/llvm/llvm-project/pull/96087 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][OMPX] Add the code generation for multi-dim `thread_limit` clause (PR #102717)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/102717 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Fix the wrong transform of `num_teams` claused introduced in #99732 (PR #102716)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/102716 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Serialization] Use traditional for loops (NFC) (PR #102761)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/102761 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Fix the wrong transform of `num_teams` claused introduced in #99732 (PR #102716)
alexey-bataev wrote: > > A test is required > > > > I literally don't know how to test this TBH. I think our current OpenMP tests > generally don't cover this at all. They do. To test this, you need to use clause in the template and check that template params successfully replaced upon instantiation. https://github.com/llvm/llvm-project/pull/102716 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Fix the wrong transform of `num_teams` claused introduced in #99732 (PR #102716)
https://github.com/alexey-bataev commented: A test is required https://github.com/llvm/llvm-project/pull/102716 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema][OpenMP] Allow `thread_limit` to accept multiple expressions (PR #102715)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/102715 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][OMPX] Add the code generation for multi-dim `num_teams` (PR #101407)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/101407 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -13034,13 +13034,36 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetUpdateDirective( Clauses, AStmt); } +/// This checks whether a \p ClauseType clause \p C has at most \p Max +/// expression. If not, a diag of number \p Diag will be emitted. +template +static bool checkNumExprsInClause(SemaBase &SemaRef, + ArrayRef Clauses, + unsigned MaxNum, unsigned Diag) { + auto ClauseItr = llvm::find_if(Clauses, llvm::IsaPred); + if (ClauseItr != Clauses.end()) { alexey-bataev wrote: if (ClauseItr == Clauses.end()) return true; https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
https://github.com/alexey-bataev closed https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fix issue: [Clang][OpenMP] Implicit conversion with `pragma omp taskloop` #100536 (PR #101812)
alexey-bataev wrote: Again, I doubt this is the right fix. I assume the proper fix should properly cast expressions to the required type before using them in the expressions. This patch not fixes the issues, but hides it. https://github.com/llvm/llvm-project/pull/101812 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -13004,13 +13004,34 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetUpdateDirective( Clauses, AStmt); } +// This checks whether num_teams clause only has one expression. alexey-bataev wrote: Use `///` style of comment here https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [OpenMP][Map][NFC] improve map chain. (PR #101903)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/101903 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,204 @@ struct MappableVarListInfo { }; } // namespace +static DeclRefExpr *buildImplicitMap(Sema &S, QualType BaseType, + DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + VarDecl *VD = buildVarDecl(S, Range.getEnd(), BaseType, "_s"); + DeclRefExpr *MapperVarRef = + buildDeclRefExpr(S, VD, BaseType, SourceLocation()); + + // Create implicit map clause for mapper. + SmallVector SExprs; + for (auto *FD : RD->fields()) { +Expr *BE = S.BuildMemberExpr( +MapperVarRef, /*IsArrow=*/false, Range.getBegin(), +NestedNameSpecifierLoc(), Range.getBegin(), FD, +DeclAccessPair::make(FD, FD->getAccess()), +/*HadMultipleCandidates=*/false, +DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()), +FD->getType(), VK_LValue, OK_Ordinary); +SExprs.push_back(BE); + } + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperId; + OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); + + OMPClause *MapClause = S.OpenMP().ActOnOpenMPMapClause( + nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, + MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs, + OMPVarListLocTy()); + Maps.push_back(MapClause); + return MapperVarRef; +} + +static ExprResult buildImplicitMapper(Sema &S, QualType BaseType, + DSAStackTy *Stack) { + + // Build impilicit map for mapper + SmallVector Maps; + DeclRefExpr *MapperVarRef = buildImplicitMap(S, BaseType, Stack, Maps); + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + + // Create implicit default mapper for "RD". + DeclarationName MapperId; + auto &DeclNames = Ctx.DeclarationNames; + MapperId = DeclNames.getIdentifier(&Ctx.Idents.get("default")); + auto *DMD = OMPDeclareMapperDecl::Create(Ctx, DCT, SourceLocation(), MapperId, + BaseType, MapperId, Maps, nullptr); + Scope *Scope = S.getScopeForContext(DCT); + if (Scope) +S.PushOnScopeChains(DMD, Scope, /*AddToContext*/ false); + DCT->addDecl(DMD); + DMD->setAccess(clang::AS_none); + auto *VD = cast(MapperVarRef)->getDecl(); + VD->setDeclContext(DMD); + VD->setLexicalDeclContext(DMD); + DMD->addDecl(VD); + DMD->setMapperVarRef(MapperVarRef); + FieldDecl *FD = *RD->field_begin(); + // create mapper refence. + return DeclRefExpr::Create(Ctx, NestedNameSpecifierLoc{}, FD->getLocation(), + DMD, false, SourceLocation(), BaseType, VK_LValue); +} + +// Look up the user-defined mapper given the mapper name and mapper type, +// return true if found one. +static bool hasUserDefinedMapper(Sema &SemaRef, Scope *S, + CXXScopeSpec &MapperIdScopeSpec, + const DeclarationNameInfo &MapperId, + QualType Type) { + // Find all user-defined mappers with the given MapperId. + SmallVector, 4> Lookups; + LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); + Lookup.suppressDiagnostics(); + while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec, + /*ObjectType=*/QualType())) { +NamedDecl *D = Lookup.getRepresentativeDecl(); +while (S && !S->isDeclScope(D)) + S = S->getParent(); +if (S) + S = S->getParent(); +Lookups.emplace_back(); +Lookups.back().append(Lookup.begin(), Lookup.end()); +Lookup.clear(); + } + if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || + Type->isInstantiationDependentType() || + Type->containsUnexpandedParameterPack() || + filterLookupForUDReductionAndMapper(Lookups, [](ValueDecl *D) { +return !D->isInvalidDecl() && + (D->getType()->isDependentType() || +D->getType()->isInstantiationDependentType() || +D->getType()->containsUnexpandedParameterPack()); + })) +return false; + // Perform argument dependent lookup. + SourceLocation Loc = MapperId.getLoc(); + if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) +argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); + if (filterLookupForUDReductionAndMapper( + Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { +if (!D->isInvalidDecl() && +SemaRef.Context.hasSameType(D->getType(), Type)) + ret
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
https://github.com/alexey-bataev approved this pull request. LG with a nit https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
https://github.com/alexey-bataev edited https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -9193,6 +9207,63 @@ StmtResult TreeTransform::TransformOMPExecutableDirective( AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc()); } +/// This is mostly the same as above, but allows 'informational' class +/// directives when rebuilding the stmt. It still takes an +/// OMPExecutableDirective-type argument because we're reusing that as the +/// superclass for the 'assume' directive at present, instead of defining a +/// mostly-identical OMPInformationalDirective parent class. +template +StmtResult TreeTransform::TransformOMPInformationalDirective( +OMPExecutableDirective *D) { + + // Transform the clauses + llvm::SmallVector TClauses; + ArrayRef Clauses = D->clauses(); + TClauses.reserve(Clauses.size()); + for (ArrayRef::iterator I = Clauses.begin(), E = Clauses.end(); + I != E; ++I) { +if (*I) { + getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind()); + OMPClause *Clause = getDerived().TransformOMPClause(*I); + getDerived().getSema().OpenMP().EndOpenMPClause(); + if (Clause) +TClauses.push_back(Clause); +} else { + TClauses.push_back(nullptr); +} + } + StmtResult AssociatedStmt; + if (D->hasAssociatedStmt() && D->getAssociatedStmt()) { +getDerived().getSema().OpenMP().ActOnOpenMPRegionStart( +D->getDirectiveKind(), +/*CurScope=*/nullptr); +StmtResult Body; +{ + Sema::CompoundScopeRAII CompoundScope(getSema()); + Stmt *CS = nullptr; + if (D->getDirectiveKind() == OMPD_assume) +CS = D->getAssociatedStmt(); + else +llvm_unreachable("Unexpected informational directive"); alexey-bataev wrote: ```suggestion assert(D->getDirectiveKind() == OMPD_assume && "Unexpected informational directive"); CS = D->getAssociatedStmt(); ``` https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -3532,6 +3532,10 @@ class Parser : public CodeCompletionHandler { OpenMPDirectiveKind DKind, SourceLocation Loc, bool ReadDirectiveWithinMetadirective); + StmtResult ParseOpenMPInformationalDirective( alexey-bataev wrote: Add a comment for the function https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -9193,6 +9207,63 @@ StmtResult TreeTransform::TransformOMPExecutableDirective( AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc()); } +/// This is mostly the same as above, but allows 'informational' class +/// directives when rebuilding the stmt. It still takes an +/// OMPExecutableDirective-type argument because we're reusing that as the +/// superclass for the 'assume' directive at present, instead of defining a +/// mostly-identical OMPInformationalDirective parent class. +template +StmtResult TreeTransform::TransformOMPInformationalDirective( +OMPExecutableDirective *D) { + + // Transform the clauses + llvm::SmallVector TClauses; + ArrayRef Clauses = D->clauses(); + TClauses.reserve(Clauses.size()); + for (ArrayRef::iterator I = Clauses.begin(), E = Clauses.end(); + I != E; ++I) { +if (*I) { + getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind()); + OMPClause *Clause = getDerived().TransformOMPClause(*I); + getDerived().getSema().OpenMP().EndOpenMPClause(); + if (Clause) +TClauses.push_back(Clause); +} else { + TClauses.push_back(nullptr); +} + } + StmtResult AssociatedStmt; + if (D->hasAssociatedStmt() && D->getAssociatedStmt()) { +getDerived().getSema().OpenMP().ActOnOpenMPRegionStart( +D->getDirectiveKind(), +/*CurScope=*/nullptr); +StmtResult Body; +{ + Sema::CompoundScopeRAII CompoundScope(getSema()); + Stmt *CS = nullptr; + if (D->getDirectiveKind() == OMPD_assume) +CS = D->getAssociatedStmt(); + else +llvm_unreachable("Unexpected informational directive"); + Body = getDerived().TransformStmt(CS); +} +AssociatedStmt = +getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses); +if (AssociatedStmt.isInvalid()) { + return StmtError(); +} alexey-bataev wrote: Drop extra braces https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
https://github.com/alexey-bataev commented: Add the notest to OpenMPSupport.rst and release notes https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -399,6 +399,14 @@ class SemaOpenMP : public SemaBase { OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); + StmtResult ActOnOpenMPInformationalDirective( + OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, + ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc); + StmtResult ActOnOpenMPAssumeDirective(ArrayRef Clauses, alexey-bataev wrote: Add a comment for the function https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -9193,6 +9207,63 @@ StmtResult TreeTransform::TransformOMPExecutableDirective( AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc()); } +/// This is mostly the same as above, but allows 'informational' class +/// directives when rebuilding the stmt. It still takes an +/// OMPExecutableDirective-type argument because we're reusing that as the +/// superclass for the 'assume' directive at present, instead of defining a +/// mostly-identical OMPInformationalDirective parent class. +template +StmtResult TreeTransform::TransformOMPInformationalDirective( +OMPExecutableDirective *D) { + + // Transform the clauses + llvm::SmallVector TClauses; + ArrayRef Clauses = D->clauses(); + TClauses.reserve(Clauses.size()); + for (ArrayRef::iterator I = Clauses.begin(), E = Clauses.end(); + I != E; ++I) { alexey-bataev wrote: ```suggestion for (OMPClause *C : Clauses) { ``` https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -9193,6 +9207,63 @@ StmtResult TreeTransform::TransformOMPExecutableDirective( AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc()); } +/// This is mostly the same as above, but allows 'informational' class +/// directives when rebuilding the stmt. It still takes an +/// OMPExecutableDirective-type argument because we're reusing that as the +/// superclass for the 'assume' directive at present, instead of defining a +/// mostly-identical OMPInformationalDirective parent class. +template +StmtResult TreeTransform::TransformOMPInformationalDirective( +OMPExecutableDirective *D) { + + // Transform the clauses + llvm::SmallVector TClauses; + ArrayRef Clauses = D->clauses(); + TClauses.reserve(Clauses.size()); + for (ArrayRef::iterator I = Clauses.begin(), E = Clauses.end(); + I != E; ++I) { +if (*I) { + getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind()); + OMPClause *Clause = getDerived().TransformOMPClause(*I); + getDerived().getSema().OpenMP().EndOpenMPClause(); + if (Clause) +TClauses.push_back(Clause); +} else { + TClauses.push_back(nullptr); +} + } + StmtResult AssociatedStmt; + if (D->hasAssociatedStmt() && D->getAssociatedStmt()) { +getDerived().getSema().OpenMP().ActOnOpenMPRegionStart( +D->getDirectiveKind(), +/*CurScope=*/nullptr); +StmtResult Body; +{ + Sema::CompoundScopeRAII CompoundScope(getSema()); + Stmt *CS = nullptr; + if (D->getDirectiveKind() == OMPD_assume) +CS = D->getAssociatedStmt(); + else +llvm_unreachable("Unexpected informational directive"); + Body = getDerived().TransformStmt(CS); +} +AssociatedStmt = +getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses); +if (AssociatedStmt.isInvalid()) { + return StmtError(); +} + } + if (TClauses.size() != Clauses.size()) { +return StmtError(); + } alexey-bataev wrote: Drop extra braces https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -399,6 +399,14 @@ class SemaOpenMP : public SemaBase { OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); + StmtResult ActOnOpenMPInformationalDirective( alexey-bataev wrote: Add a comment for the function https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
https://github.com/alexey-bataev edited https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
https://github.com/alexey-bataev commented: Add info to OpenMPSupport.rst and release notes https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,204 @@ struct MappableVarListInfo { }; } // namespace +static DeclRefExpr *buildImplicitMap(Sema &S, QualType BaseType, + DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + VarDecl *VD = buildVarDecl(S, Range.getEnd(), BaseType, "_s"); + DeclRefExpr *MapperVarRef = + buildDeclRefExpr(S, VD, BaseType, SourceLocation()); + + // Create implicit map clause for mapper. + SmallVector SExprs; + for (auto *FD : RD->fields()) { +Expr *BE = S.BuildMemberExpr( +MapperVarRef, /*IsArrow=*/false, Range.getBegin(), +NestedNameSpecifierLoc(), Range.getBegin(), FD, +DeclAccessPair::make(FD, FD->getAccess()), +/*HadMultipleCandidates=*/false, +DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()), +FD->getType(), VK_LValue, OK_Ordinary); +SExprs.push_back(BE); + } + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperId; + OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); + + OMPClause *MapClause = S.OpenMP().ActOnOpenMPMapClause( + nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, + MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs, + OMPVarListLocTy()); + Maps.push_back(MapClause); + return MapperVarRef; +} + +static ExprResult buildImplicitMapper(Sema &S, QualType BaseType, + DSAStackTy *Stack) { + + // Build impilicit map for mapper + SmallVector Maps; + DeclRefExpr *MapperVarRef = buildImplicitMap(S, BaseType, Stack, Maps); + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + + // Create implicit default mapper for "RD". + DeclarationName MapperId; + auto &DeclNames = Ctx.DeclarationNames; + MapperId = DeclNames.getIdentifier(&Ctx.Idents.get("default")); + auto *DMD = OMPDeclareMapperDecl::Create(Ctx, DCT, SourceLocation(), MapperId, + BaseType, MapperId, Maps, nullptr); + Scope *Scope = S.getScopeForContext(DCT); + if (Scope) +S.PushOnScopeChains(DMD, Scope, /*AddToContext*/ false); + DCT->addDecl(DMD); + DMD->setAccess(clang::AS_none); + auto *VD = cast(MapperVarRef)->getDecl(); + VD->setDeclContext(DMD); + VD->setLexicalDeclContext(DMD); + DMD->addDecl(VD); + DMD->setMapperVarRef(MapperVarRef); + FieldDecl *FD = *RD->field_begin(); + // create mapper refence. + return DeclRefExpr::Create(Ctx, NestedNameSpecifierLoc{}, FD->getLocation(), + DMD, false, SourceLocation(), BaseType, VK_LValue); +} + +// Look up the user-defined mapper given the mapper name and mapper type, +// return true if found one. +static bool hasUserDefinedMapper(Sema &SemaRef, Scope *S, + CXXScopeSpec &MapperIdScopeSpec, + const DeclarationNameInfo &MapperId, + QualType Type) { + // Find all user-defined mappers with the given MapperId. + SmallVector, 4> Lookups; + LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); + Lookup.suppressDiagnostics(); + if (S) +while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec, alexey-bataev wrote: ```suggestion while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec, ``` https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,204 @@ struct MappableVarListInfo { }; } // namespace +static DeclRefExpr *buildImplicitMap(Sema &S, QualType BaseType, + DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + VarDecl *VD = buildVarDecl(S, Range.getEnd(), BaseType, "_s"); + DeclRefExpr *MapperVarRef = + buildDeclRefExpr(S, VD, BaseType, SourceLocation()); + + // Create implicit map clause for mapper. + SmallVector SExprs; + for (auto *FD : RD->fields()) { +Expr *BE = S.BuildMemberExpr( +MapperVarRef, /*IsArrow=*/false, Range.getBegin(), +NestedNameSpecifierLoc(), Range.getBegin(), FD, +DeclAccessPair::make(FD, FD->getAccess()), +/*HadMultipleCandidates=*/false, +DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()), +FD->getType(), VK_LValue, OK_Ordinary); +SExprs.push_back(BE); + } + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperId; + OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); + + OMPClause *MapClause = S.OpenMP().ActOnOpenMPMapClause( + nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, + MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs, + OMPVarListLocTy()); + Maps.push_back(MapClause); + return MapperVarRef; +} + +static ExprResult buildImplicitMapper(Sema &S, QualType BaseType, + DSAStackTy *Stack) { + + // Build impilicit map for mapper + SmallVector Maps; + DeclRefExpr *MapperVarRef = buildImplicitMap(S, BaseType, Stack, Maps); + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + + // Create implicit default mapper for "RD". + DeclarationName MapperId; + auto &DeclNames = Ctx.DeclarationNames; + MapperId = DeclNames.getIdentifier(&Ctx.Idents.get("default")); + auto *DMD = OMPDeclareMapperDecl::Create(Ctx, DCT, SourceLocation(), MapperId, + BaseType, MapperId, Maps, nullptr); + Scope *Scope = S.getScopeForContext(DCT); + if (Scope) +S.PushOnScopeChains(DMD, Scope, /*AddToContext*/ false); + DCT->addDecl(DMD); + DMD->setAccess(clang::AS_none); + auto *VD = cast(MapperVarRef)->getDecl(); + VD->setDeclContext(DMD); + VD->setLexicalDeclContext(DMD); + DMD->addDecl(VD); + DMD->setMapperVarRef(MapperVarRef); + FieldDecl *FD = *RD->field_begin(); + // create mapper refence. + return DeclRefExpr::Create(Ctx, NestedNameSpecifierLoc{}, FD->getLocation(), + DMD, false, SourceLocation(), BaseType, VK_LValue); +} + +// Look up the user-defined mapper given the mapper name and mapper type, +// return true if found one. +static bool hasUserDefinedMapper(Sema &SemaRef, Scope *S, + CXXScopeSpec &MapperIdScopeSpec, + const DeclarationNameInfo &MapperId, + QualType Type) { + // Find all user-defined mappers with the given MapperId. + SmallVector, 4> Lookups; + LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); + Lookup.suppressDiagnostics(); + if (S) +while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec, + /*ObjectType=*/QualType())) { + NamedDecl *D = Lookup.getRepresentativeDecl(); + while (S && !S->isDeclScope(D)) +S = S->getParent(); + if (S) +S = S->getParent(); + Lookups.emplace_back(); + Lookups.back().append(Lookup.begin(), Lookup.end()); + Lookup.clear(); +} + if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || + Type->isInstantiationDependentType() || + Type->containsUnexpandedParameterPack() || + filterLookupForUDReductionAndMapper(Lookups, [](ValueDecl *D) { +return !D->isInvalidDecl() && + (D->getType()->isDependentType() || +D->getType()->isInstantiationDependentType() || +D->getType()->containsUnexpandedParameterPack()); + })) +return false; + // Perform argument dependent lookup. + SourceLocation Loc = MapperId.getLoc(); + if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) +argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); + if (filterLookupForUDReductionAndMapper( + Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { +if (!D->isInvalidDecl() && +SemaRef.Context.hasSameType(D->getT
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
https://github.com/alexey-bataev edited https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [OpenMP][Doc] Add `ompx_bare` entry in `OpenMPSupport.rst` (PR #101711)
alexey-bataev wrote: Add also to the release notes https://github.com/llvm/llvm-project/pull/101711 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,150 @@ struct MappableVarListInfo { }; } // namespace +static std::pair +buildImplicitMap(Sema &S, QualType BaseType, DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + ImplicitName.setName( + Ctx.DeclarationNames.getIdentifier(&Ctx.Idents.get("_s"))); + DeclarationName VN = ImplicitName.getName(); + TypeSourceInfo *TInfo = + Ctx.getTrivialTypeSourceInfo(BaseType, Range.getEnd()); + VarDecl *VD = + VarDecl::Create(Ctx, DCT, Range.getEnd(), Range.getEnd(), + VN.getAsIdentifierInfo(), BaseType, TInfo, SC_None); + DeclRefExpr *MapperVarRef = + buildDeclRefExpr(S, VD, BaseType, SourceLocation()); + + // Create implicit map clause for mapper. + SmallVector SExprs; + for (auto *FD : RD->fields()) { +Expr *BE = S.BuildMemberExpr( +MapperVarRef, /*IsArrow=*/false, Range.getBegin(), +NestedNameSpecifierLoc(), Range.getBegin(), FD, +DeclAccessPair::make(FD, FD->getAccess()), +/*HadMultipleCandidates=*/false, +DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()), +FD->getType(), VK_LValue, OK_Ordinary); +SExprs.push_back(BE); + } + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperId; + OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); + + OMPClause *MapClasue = S.OpenMP().ActOnOpenMPMapClause( + nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, + MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs, + OMPVarListLocTy()); + Maps.push_back(MapClasue); + return {MapperVarRef, VD}; +} + +static ExprResult buildImplicitMapper(Sema &S, QualType BaseType, + DSAStackTy *Stack) { + + // Build impilicit map for mapper + SmallVector Maps; + VarDecl *VD; + DeclRefExpr *MapperVarRef; + std::tie(MapperVarRef, VD) = buildImplicitMap(S, BaseType, Stack, Maps); + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + + // Create implicit default mapper for "RD". + DeclarationName MapperId; + auto &DeclNames = Ctx.DeclarationNames; + MapperId = DeclNames.getIdentifier(&Ctx.Idents.get("default")); + auto *DMD = OMPDeclareMapperDecl::Create(Ctx, DCT, SourceLocation(), MapperId, + BaseType, MapperId, Maps, nullptr); + Scope *Scope = S.getScopeForContext(DCT); + if (Scope) +S.PushOnScopeChains(DMD, Scope, /*AddToContext*/ false); + DCT->addDecl(DMD); + DMD->setAccess(clang::AS_none); + VD->setDeclContext(DMD); + VD->setLexicalDeclContext(DMD); + DMD->addDecl(VD); + DMD->setMapperVarRef(MapperVarRef); + FieldDecl *FD = *RD->field_begin(); + // create mapper refence. + return DeclRefExpr::Create(Ctx, NestedNameSpecifierLoc{}, FD->getLocation(), + DMD, false, SourceLocation(), BaseType, VK_LValue); +} + +static bool IsImplicitMapperNeeded(Sema &S, DSAStackTy *Stack, + QualType CanonType, const Expr *E) { + + // DFS over data members in structures/classes. + SmallVector, 4> Types(1, + {CanonType, nullptr}); + llvm::DenseMap Visited; + SmallVector, 4> ParentChain(1, {nullptr, 1}); + while (!Types.empty()) { +QualType BaseType; +FieldDecl *CurFD; +std::tie(BaseType, CurFD) = Types.pop_back_val(); +while (ParentChain.back().second == 0) + ParentChain.pop_back(); +--ParentChain.back().second; +if (BaseType.isNull()) + continue; +// Only structs/classes are allowed to have mappers. +const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl(); +if (!RD) + continue; +auto It = Visited.find(BaseType.getTypePtr()); +if (It == Visited.end()) { + // Try to find the associated user-defined mapper. + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo DefaultMapperId; + DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier( + &S.Context.Idents.get("default"))); + DefaultMapperId.setLoc(E->getExprLoc()); + ExprResult ER = buildUserDefinedMapperRef( + S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId, BaseType, + /*UnresolvedMapper=*/nullptr); + if (ER.isInvalid()) +continue; + It = Vi
[clang] [Clang][Sema][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
alexey-bataev wrote: > > Update OpenMPSupport.rst and include info about changes to release notes > > This is not part of OpenMP standard so I don't think we need to update > `OpenMPSupport.rst`. We do not inform OpenMP committee here, just users :) For users it would be good to have this info https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
https://github.com/alexey-bataev commented: Need a test with the nesting of the directives https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -377,6 +377,8 @@ bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter); /// otherwise - false. bool isOpenMPExecutableDirective(OpenMPDirectiveKind DKind); +bool isOpenMPInformationalDirective(OpenMPDirectiveKind DKind); alexey-bataev wrote: Add a comment for the function https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
https://github.com/alexey-bataev edited https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -6468,6 +6468,36 @@ class OMPErrorDirective final : public OMPExecutableDirective { return T->getStmtClass() == OMPErrorDirectiveClass; } }; + +// It's not really an executable directive, but it seems convenient to use +// that as the parent class. +class OMPAssumeDirective : public OMPExecutableDirective { alexey-bataev wrote: `class OMPAssumeDirective final : public OMPExecutableDirective` https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
@@ -9487,13 +9606,17 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, unsigned NestedLoopCount = 1; bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) && !isOpenMPLoopTransformationDirective(DKind); + llvm::SmallPtrSet CollapsedLoopVarDecls{}; alexey-bataev wrote: `llvm::SmallPtrSet CollapsedLoopVarDecls;` https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
@@ -10,8 +10,9 @@ // //===--===// -#include "clang/AST/ASTContext.h" #include "clang/AST/StmtOpenMP.h" +#include "clang/AST/ASTContext.h" alexey-bataev wrote: Do this reordering in a separate NFC patch https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,150 @@ struct MappableVarListInfo { }; } // namespace +static std::pair +buildImplicitMap(Sema &S, QualType BaseType, DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + ImplicitName.setName( + Ctx.DeclarationNames.getIdentifier(&Ctx.Idents.get("_s"))); + DeclarationName VN = ImplicitName.getName(); + TypeSourceInfo *TInfo = + Ctx.getTrivialTypeSourceInfo(BaseType, Range.getEnd()); + VarDecl *VD = + VarDecl::Create(Ctx, DCT, Range.getEnd(), Range.getEnd(), + VN.getAsIdentifierInfo(), BaseType, TInfo, SC_None); + DeclRefExpr *MapperVarRef = + buildDeclRefExpr(S, VD, BaseType, SourceLocation()); + + // Create implicit map clause for mapper. + SmallVector SExprs; + for (auto *FD : RD->fields()) { +Expr *BE = S.BuildMemberExpr( +MapperVarRef, /*IsArrow=*/false, Range.getBegin(), +NestedNameSpecifierLoc(), Range.getBegin(), FD, +DeclAccessPair::make(FD, FD->getAccess()), +/*HadMultipleCandidates=*/false, +DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()), +FD->getType(), VK_LValue, OK_Ordinary); +SExprs.push_back(BE); + } + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperId; + OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); + + OMPClause *MapClasue = S.OpenMP().ActOnOpenMPMapClause( + nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, + MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs, + OMPVarListLocTy()); + Maps.push_back(MapClasue); + return {MapperVarRef, VD}; +} + +static ExprResult buildImplicitMapper(Sema &S, QualType BaseType, + DSAStackTy *Stack) { + + // Build impilicit map for mapper + SmallVector Maps; + VarDecl *VD; + DeclRefExpr *MapperVarRef; + std::tie(MapperVarRef, VD) = buildImplicitMap(S, BaseType, Stack, Maps); + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + + // Create implicit default mapper for "RD". + DeclarationName MapperId; + auto &DeclNames = Ctx.DeclarationNames; + MapperId = DeclNames.getIdentifier(&Ctx.Idents.get("default")); + auto *DMD = OMPDeclareMapperDecl::Create(Ctx, DCT, SourceLocation(), MapperId, + BaseType, MapperId, Maps, nullptr); + Scope *Scope = S.getScopeForContext(DCT); + if (Scope) +S.PushOnScopeChains(DMD, Scope, /*AddToContext*/ false); + DCT->addDecl(DMD); + DMD->setAccess(clang::AS_none); + VD->setDeclContext(DMD); + VD->setLexicalDeclContext(DMD); + DMD->addDecl(VD); + DMD->setMapperVarRef(MapperVarRef); + FieldDecl *FD = *RD->field_begin(); + // create mapper refence. + return DeclRefExpr::Create(Ctx, NestedNameSpecifierLoc{}, FD->getLocation(), + DMD, false, SourceLocation(), BaseType, VK_LValue); +} + +static bool IsImplicitMapperNeeded(Sema &S, DSAStackTy *Stack, + QualType CanonType, const Expr *E) { + + // DFS over data members in structures/classes. + SmallVector, 4> Types(1, + {CanonType, nullptr}); + llvm::DenseMap Visited; + SmallVector, 4> ParentChain(1, {nullptr, 1}); + while (!Types.empty()) { +QualType BaseType; +FieldDecl *CurFD; +std::tie(BaseType, CurFD) = Types.pop_back_val(); alexey-bataev wrote: ```suggestion auto [BaseType, CurFD] = Types.pop_back_val(); ``` https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,150 @@ struct MappableVarListInfo { }; } // namespace +static std::pair +buildImplicitMap(Sema &S, QualType BaseType, DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + ImplicitName.setName( + Ctx.DeclarationNames.getIdentifier(&Ctx.Idents.get("_s"))); + DeclarationName VN = ImplicitName.getName(); + TypeSourceInfo *TInfo = + Ctx.getTrivialTypeSourceInfo(BaseType, Range.getEnd()); + VarDecl *VD = + VarDecl::Create(Ctx, DCT, Range.getEnd(), Range.getEnd(), + VN.getAsIdentifierInfo(), BaseType, TInfo, SC_None); + DeclRefExpr *MapperVarRef = + buildDeclRefExpr(S, VD, BaseType, SourceLocation()); + + // Create implicit map clause for mapper. + SmallVector SExprs; + for (auto *FD : RD->fields()) { +Expr *BE = S.BuildMemberExpr( +MapperVarRef, /*IsArrow=*/false, Range.getBegin(), +NestedNameSpecifierLoc(), Range.getBegin(), FD, +DeclAccessPair::make(FD, FD->getAccess()), +/*HadMultipleCandidates=*/false, +DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()), +FD->getType(), VK_LValue, OK_Ordinary); +SExprs.push_back(BE); + } + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperId; + OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); + + OMPClause *MapClasue = S.OpenMP().ActOnOpenMPMapClause( + nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, + MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs, + OMPVarListLocTy()); + Maps.push_back(MapClasue); + return {MapperVarRef, VD}; +} + +static ExprResult buildImplicitMapper(Sema &S, QualType BaseType, + DSAStackTy *Stack) { + + // Build impilicit map for mapper + SmallVector Maps; + VarDecl *VD; + DeclRefExpr *MapperVarRef; + std::tie(MapperVarRef, VD) = buildImplicitMap(S, BaseType, Stack, Maps); + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + + // Create implicit default mapper for "RD". + DeclarationName MapperId; + auto &DeclNames = Ctx.DeclarationNames; + MapperId = DeclNames.getIdentifier(&Ctx.Idents.get("default")); + auto *DMD = OMPDeclareMapperDecl::Create(Ctx, DCT, SourceLocation(), MapperId, + BaseType, MapperId, Maps, nullptr); + Scope *Scope = S.getScopeForContext(DCT); + if (Scope) +S.PushOnScopeChains(DMD, Scope, /*AddToContext*/ false); + DCT->addDecl(DMD); + DMD->setAccess(clang::AS_none); + VD->setDeclContext(DMD); + VD->setLexicalDeclContext(DMD); + DMD->addDecl(VD); + DMD->setMapperVarRef(MapperVarRef); + FieldDecl *FD = *RD->field_begin(); + // create mapper refence. + return DeclRefExpr::Create(Ctx, NestedNameSpecifierLoc{}, FD->getLocation(), + DMD, false, SourceLocation(), BaseType, VK_LValue); +} + +static bool IsImplicitMapperNeeded(Sema &S, DSAStackTy *Stack, + QualType CanonType, const Expr *E) { + + // DFS over data members in structures/classes. + SmallVector, 4> Types(1, + {CanonType, nullptr}); + llvm::DenseMap Visited; + SmallVector, 4> ParentChain(1, {nullptr, 1}); + while (!Types.empty()) { +QualType BaseType; +FieldDecl *CurFD; +std::tie(BaseType, CurFD) = Types.pop_back_val(); +while (ParentChain.back().second == 0) + ParentChain.pop_back(); +--ParentChain.back().second; +if (BaseType.isNull()) + continue; +// Only structs/classes are allowed to have mappers. +const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl(); +if (!RD) + continue; +auto It = Visited.find(BaseType.getTypePtr()); +if (It == Visited.end()) { + // Try to find the associated user-defined mapper. + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo DefaultMapperId; + DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier( + &S.Context.Idents.get("default"))); + DefaultMapperId.setLoc(E->getExprLoc()); + ExprResult ER = buildUserDefinedMapperRef( + S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId, BaseType, + /*UnresolvedMapper=*/nullptr); + if (ER.isInvalid()) +continue; + It = Vi
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,150 @@ struct MappableVarListInfo { }; } // namespace +static std::pair +buildImplicitMap(Sema &S, QualType BaseType, DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + ImplicitName.setName( + Ctx.DeclarationNames.getIdentifier(&Ctx.Idents.get("_s"))); + DeclarationName VN = ImplicitName.getName(); + TypeSourceInfo *TInfo = + Ctx.getTrivialTypeSourceInfo(BaseType, Range.getEnd()); + VarDecl *VD = + VarDecl::Create(Ctx, DCT, Range.getEnd(), Range.getEnd(), + VN.getAsIdentifierInfo(), BaseType, TInfo, SC_None); + DeclRefExpr *MapperVarRef = + buildDeclRefExpr(S, VD, BaseType, SourceLocation()); + + // Create implicit map clause for mapper. + SmallVector SExprs; + for (auto *FD : RD->fields()) { +Expr *BE = S.BuildMemberExpr( +MapperVarRef, /*IsArrow=*/false, Range.getBegin(), +NestedNameSpecifierLoc(), Range.getBegin(), FD, +DeclAccessPair::make(FD, FD->getAccess()), +/*HadMultipleCandidates=*/false, +DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()), +FD->getType(), VK_LValue, OK_Ordinary); +SExprs.push_back(BE); + } + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperId; + OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); + + OMPClause *MapClasue = S.OpenMP().ActOnOpenMPMapClause( + nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, + MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs, + OMPVarListLocTy()); + Maps.push_back(MapClasue); + return {MapperVarRef, VD}; +} + +static ExprResult buildImplicitMapper(Sema &S, QualType BaseType, + DSAStackTy *Stack) { + + // Build impilicit map for mapper + SmallVector Maps; + VarDecl *VD; + DeclRefExpr *MapperVarRef; + std::tie(MapperVarRef, VD) = buildImplicitMap(S, BaseType, Stack, Maps); + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + + // Create implicit default mapper for "RD". + DeclarationName MapperId; + auto &DeclNames = Ctx.DeclarationNames; + MapperId = DeclNames.getIdentifier(&Ctx.Idents.get("default")); + auto *DMD = OMPDeclareMapperDecl::Create(Ctx, DCT, SourceLocation(), MapperId, + BaseType, MapperId, Maps, nullptr); + Scope *Scope = S.getScopeForContext(DCT); + if (Scope) +S.PushOnScopeChains(DMD, Scope, /*AddToContext*/ false); + DCT->addDecl(DMD); + DMD->setAccess(clang::AS_none); + VD->setDeclContext(DMD); + VD->setLexicalDeclContext(DMD); + DMD->addDecl(VD); + DMD->setMapperVarRef(MapperVarRef); + FieldDecl *FD = *RD->field_begin(); + // create mapper refence. + return DeclRefExpr::Create(Ctx, NestedNameSpecifierLoc{}, FD->getLocation(), + DMD, false, SourceLocation(), BaseType, VK_LValue); +} + +static bool IsImplicitMapperNeeded(Sema &S, DSAStackTy *Stack, alexey-bataev wrote: ```suggestion static bool isImplicitMapperNeeded(Sema &S, DSAStackTy *Stack, ``` https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,150 @@ struct MappableVarListInfo { }; } // namespace +static std::pair +buildImplicitMap(Sema &S, QualType BaseType, DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + ImplicitName.setName( + Ctx.DeclarationNames.getIdentifier(&Ctx.Idents.get("_s"))); + DeclarationName VN = ImplicitName.getName(); + TypeSourceInfo *TInfo = + Ctx.getTrivialTypeSourceInfo(BaseType, Range.getEnd()); + VarDecl *VD = + VarDecl::Create(Ctx, DCT, Range.getEnd(), Range.getEnd(), + VN.getAsIdentifierInfo(), BaseType, TInfo, SC_None); + DeclRefExpr *MapperVarRef = + buildDeclRefExpr(S, VD, BaseType, SourceLocation()); + + // Create implicit map clause for mapper. + SmallVector SExprs; + for (auto *FD : RD->fields()) { +Expr *BE = S.BuildMemberExpr( +MapperVarRef, /*IsArrow=*/false, Range.getBegin(), +NestedNameSpecifierLoc(), Range.getBegin(), FD, +DeclAccessPair::make(FD, FD->getAccess()), +/*HadMultipleCandidates=*/false, +DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()), +FD->getType(), VK_LValue, OK_Ordinary); +SExprs.push_back(BE); + } + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperId; + OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); + + OMPClause *MapClasue = S.OpenMP().ActOnOpenMPMapClause( alexey-bataev wrote: ```suggestion OMPClause *MapClause = S.OpenMP().ActOnOpenMPMapClause( ``` https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,150 @@ struct MappableVarListInfo { }; } // namespace +static std::pair +buildImplicitMap(Sema &S, QualType BaseType, DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + ImplicitName.setName( + Ctx.DeclarationNames.getIdentifier(&Ctx.Idents.get("_s"))); + DeclarationName VN = ImplicitName.getName(); + TypeSourceInfo *TInfo = + Ctx.getTrivialTypeSourceInfo(BaseType, Range.getEnd()); + VarDecl *VD = + VarDecl::Create(Ctx, DCT, Range.getEnd(), Range.getEnd(), + VN.getAsIdentifierInfo(), BaseType, TInfo, SC_None); alexey-bataev wrote: ```suggestion VarDecl *VD = buildVarDecl(S, Range.getEnd(), BaseType, "_s"); ``` https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,150 @@ struct MappableVarListInfo { }; } // namespace +static std::pair +buildImplicitMap(Sema &S, QualType BaseType, DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + ImplicitName.setName( + Ctx.DeclarationNames.getIdentifier(&Ctx.Idents.get("_s"))); + DeclarationName VN = ImplicitName.getName(); + TypeSourceInfo *TInfo = + Ctx.getTrivialTypeSourceInfo(BaseType, Range.getEnd()); + VarDecl *VD = + VarDecl::Create(Ctx, DCT, Range.getEnd(), Range.getEnd(), + VN.getAsIdentifierInfo(), BaseType, TInfo, SC_None); + DeclRefExpr *MapperVarRef = + buildDeclRefExpr(S, VD, BaseType, SourceLocation()); + + // Create implicit map clause for mapper. + SmallVector SExprs; + for (auto *FD : RD->fields()) { +Expr *BE = S.BuildMemberExpr( +MapperVarRef, /*IsArrow=*/false, Range.getBegin(), +NestedNameSpecifierLoc(), Range.getBegin(), FD, +DeclAccessPair::make(FD, FD->getAccess()), +/*HadMultipleCandidates=*/false, +DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()), +FD->getType(), VK_LValue, OK_Ordinary); +SExprs.push_back(BE); + } + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperId; + OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); + + OMPClause *MapClasue = S.OpenMP().ActOnOpenMPMapClause( + nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, + MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs, + OMPVarListLocTy()); + Maps.push_back(MapClasue); + return {MapperVarRef, VD}; +} + +static ExprResult buildImplicitMapper(Sema &S, QualType BaseType, + DSAStackTy *Stack) { + + // Build impilicit map for mapper + SmallVector Maps; + VarDecl *VD; + DeclRefExpr *MapperVarRef; + std::tie(MapperVarRef, VD) = buildImplicitMap(S, BaseType, Stack, Maps); alexey-bataev wrote: ```suggestion auto [MapperVarRef, VD] = buildImplicitMap(S, BaseType, Stack, Maps); ``` https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP]Generate implicit default mapper for mapping array section. (PR #101101)
@@ -20796,6 +20796,150 @@ struct MappableVarListInfo { }; } // namespace +static std::pair +buildImplicitMap(Sema &S, QualType BaseType, DSAStackTy *Stack, + SmallVectorImpl &Maps) { + + const RecordDecl *RD = BaseType->getAsRecordDecl(); + // AST context is RD's ParentASTContext(). + ASTContext &Ctx = RD->getParentASTContext(); + // DeclContext is RD's DeclContext. + DeclContext *DCT = const_cast(RD->getDeclContext()); + SourceRange Range = RD->getSourceRange(); + DeclarationNameInfo ImplicitName; + // Dummy variable _s for Mapper. + ImplicitName.setName( + Ctx.DeclarationNames.getIdentifier(&Ctx.Idents.get("_s"))); + DeclarationName VN = ImplicitName.getName(); + TypeSourceInfo *TInfo = + Ctx.getTrivialTypeSourceInfo(BaseType, Range.getEnd()); + VarDecl *VD = + VarDecl::Create(Ctx, DCT, Range.getEnd(), Range.getEnd(), + VN.getAsIdentifierInfo(), BaseType, TInfo, SC_None); + DeclRefExpr *MapperVarRef = + buildDeclRefExpr(S, VD, BaseType, SourceLocation()); + + // Create implicit map clause for mapper. + SmallVector SExprs; + for (auto *FD : RD->fields()) { +Expr *BE = S.BuildMemberExpr( +MapperVarRef, /*IsArrow=*/false, Range.getBegin(), +NestedNameSpecifierLoc(), Range.getBegin(), FD, +DeclAccessPair::make(FD, FD->getAccess()), +/*HadMultipleCandidates=*/false, +DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()), +FD->getType(), VK_LValue, OK_Ordinary); +SExprs.push_back(BE); + } + CXXScopeSpec MapperIdScopeSpec; + DeclarationNameInfo MapperId; + OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); + + OMPClause *MapClasue = S.OpenMP().ActOnOpenMPMapClause( + nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, + MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom, + /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs, + OMPVarListLocTy()); + Maps.push_back(MapClasue); + return {MapperVarRef, VD}; alexey-bataev wrote: Why need to return pair here, if MapperVarRef points to the same VD? https://github.com/llvm/llvm-project/pull/101101 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -2013,6 +2064,184 @@ class OMPMergeableClause : public OMPClause { } }; +/// This represents the 'absent' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume absent() +/// \endcode +/// In this example directive '#pragma omp assume' has an 'absent' clause. +class OMPAbsentClause final +: public OMPDirectiveListClause, + private llvm::TrailingObjects { + friend OMPDirectiveListClause; + friend TrailingObjects; + +public: + /// Build 'absent' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param NumKinds Number of directive kinds listed in the clause. + OMPAbsentClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_absent, StartLoc, LParenLoc, EndLoc, NumKinds) {} + + /// Build an empty clause. + OMPAbsentClause(unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_absent, SourceLocation(), SourceLocation(), +SourceLocation(), NumKinds) {} + + static OMPAbsentClause *Create(const ASTContext &C, + ArrayRef DKVec, + SourceLocation Loc, SourceLocation LLoc, + SourceLocation RLoc); + + static OMPAbsentClause *CreateEmpty(const ASTContext &C, unsigned NumKinds); + + static bool classof(const OMPClause *C) { +return C->getClauseKind() == llvm::omp::OMPC_absent; + } +}; + +/// This represents the 'contains' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume contains() +/// \endcode +/// In this example directive '#pragma omp assume' has a 'contains' clause. +class OMPContainsClause final +: public OMPDirectiveListClause, + private llvm::TrailingObjects { + friend OMPDirectiveListClause; + friend TrailingObjects; + +public: + /// Build 'contains' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param NumKinds Number of directive kinds listed in the clause. + OMPContainsClause(SourceLocation StartLoc, SourceLocation LParenLoc, +SourceLocation EndLoc, unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_contains, StartLoc, LParenLoc, EndLoc, NumKinds) {} + + /// Build an empty clause. + OMPContainsClause(unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_contains, SourceLocation(), SourceLocation(), +SourceLocation(), NumKinds) {} + + static OMPContainsClause *Create(const ASTContext &C, + ArrayRef DKVec, + SourceLocation Loc, SourceLocation LLoc, + SourceLocation RLoc); + + static OMPContainsClause *CreateEmpty(const ASTContext &C, unsigned NumKinds); + + static bool classof(const OMPClause *C) { +return C->getClauseKind() == llvm::omp::OMPC_contains; + } +}; + +/// This represents the 'holds' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume holds() +/// \endcode +/// In this example directive '#pragma omp assume' has a 'holds' clause. +class OMPHoldsClause final +: public OMPOneStmtClause { + friend class OMPClauseReader; + +public: + /// Build 'holds' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPHoldsClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPOneStmtClause(E, StartLoc, LParenLoc, EndLoc) {} + + /// Build an empty clause. + OMPHoldsClause() : OMPOneStmtClause() {} + + Expr *getExpr() const { return getStmtAs(); } + void setExpr(Expr *E) { setStmt(E); } +}; + +/// This represents the 'no_openmp' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume no_openmp +/// \endcode +/// In this example directive '#pragma omp assume' has a 'no_openmp' clause. +class OMPNoOpenMPClause final +: public OMPNoChildClause { +public: + /// Build 'no_openmp' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPNoOpenMPClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPNoChildClause(StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPNoOpenMPClause() : OMPNoChildClause() {} +}; + +/// This represents the 'no_openmp_routines' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume no_openmp_routines +/// \endcode +/// In this example directive '#pragma omp assume' has a 'no_openmp_routines' +/// clause. +class OMPNoOpe
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
alexey-bataev wrote: > OpenMPIterationSpaceChecker is still passed a pointer to CollapsedLoopDecls, > because one caller passes a nullptr, and we don't want to do the analysis in > that case. Still pass by reference, just pass empty where it is not required https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
https://github.com/alexey-bataev commented: Update OpenMPSupport.rst and include info about changes to release notes https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -2013,6 +2064,184 @@ class OMPMergeableClause : public OMPClause { } }; +/// This represents the 'absent' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume absent() +/// \endcode +/// In this example directive '#pragma omp assume' has an 'absent' clause. +class OMPAbsentClause final +: public OMPDirectiveListClause, + private llvm::TrailingObjects { + friend OMPDirectiveListClause; + friend TrailingObjects; + +public: + /// Build 'absent' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param NumKinds Number of directive kinds listed in the clause. + OMPAbsentClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_absent, StartLoc, LParenLoc, EndLoc, NumKinds) {} + + /// Build an empty clause. + OMPAbsentClause(unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_absent, SourceLocation(), SourceLocation(), +SourceLocation(), NumKinds) {} + alexey-bataev wrote: These constructions must be private/protected https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -2013,6 +2064,184 @@ class OMPMergeableClause : public OMPClause { } }; +/// This represents the 'absent' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume absent() +/// \endcode +/// In this example directive '#pragma omp assume' has an 'absent' clause. +class OMPAbsentClause final +: public OMPDirectiveListClause, + private llvm::TrailingObjects { + friend OMPDirectiveListClause; + friend TrailingObjects; + +public: + /// Build 'absent' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param NumKinds Number of directive kinds listed in the clause. + OMPAbsentClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_absent, StartLoc, LParenLoc, EndLoc, NumKinds) {} + + /// Build an empty clause. + OMPAbsentClause(unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_absent, SourceLocation(), SourceLocation(), +SourceLocation(), NumKinds) {} + + static OMPAbsentClause *Create(const ASTContext &C, + ArrayRef DKVec, + SourceLocation Loc, SourceLocation LLoc, + SourceLocation RLoc); + + static OMPAbsentClause *CreateEmpty(const ASTContext &C, unsigned NumKinds); + + static bool classof(const OMPClause *C) { +return C->getClauseKind() == llvm::omp::OMPC_absent; + } +}; + +/// This represents the 'contains' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume contains() +/// \endcode +/// In this example directive '#pragma omp assume' has a 'contains' clause. +class OMPContainsClause final +: public OMPDirectiveListClause, + private llvm::TrailingObjects { + friend OMPDirectiveListClause; + friend TrailingObjects; + +public: + /// Build 'contains' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param NumKinds Number of directive kinds listed in the clause. + OMPContainsClause(SourceLocation StartLoc, SourceLocation LParenLoc, +SourceLocation EndLoc, unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_contains, StartLoc, LParenLoc, EndLoc, NumKinds) {} + + /// Build an empty clause. + OMPContainsClause(unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_contains, SourceLocation(), SourceLocation(), +SourceLocation(), NumKinds) {} + alexey-bataev wrote: Private or protected constructors https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -2013,6 +2064,184 @@ class OMPMergeableClause : public OMPClause { } }; +/// This represents the 'absent' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume absent() +/// \endcode +/// In this example directive '#pragma omp assume' has an 'absent' clause. +class OMPAbsentClause final +: public OMPDirectiveListClause, + private llvm::TrailingObjects { + friend OMPDirectiveListClause; + friend TrailingObjects; + +public: + /// Build 'absent' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param NumKinds Number of directive kinds listed in the clause. + OMPAbsentClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_absent, StartLoc, LParenLoc, EndLoc, NumKinds) {} + + /// Build an empty clause. + OMPAbsentClause(unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_absent, SourceLocation(), SourceLocation(), +SourceLocation(), NumKinds) {} + + static OMPAbsentClause *Create(const ASTContext &C, + ArrayRef DKVec, + SourceLocation Loc, SourceLocation LLoc, + SourceLocation RLoc); + + static OMPAbsentClause *CreateEmpty(const ASTContext &C, unsigned NumKinds); + + static bool classof(const OMPClause *C) { +return C->getClauseKind() == llvm::omp::OMPC_absent; + } +}; + +/// This represents the 'contains' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume contains() +/// \endcode +/// In this example directive '#pragma omp assume' has a 'contains' clause. +class OMPContainsClause final +: public OMPDirectiveListClause, + private llvm::TrailingObjects { + friend OMPDirectiveListClause; + friend TrailingObjects; + +public: + /// Build 'contains' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param NumKinds Number of directive kinds listed in the clause. + OMPContainsClause(SourceLocation StartLoc, SourceLocation LParenLoc, +SourceLocation EndLoc, unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_contains, StartLoc, LParenLoc, EndLoc, NumKinds) {} + + /// Build an empty clause. + OMPContainsClause(unsigned NumKinds) + : OMPDirectiveListClause( +llvm::omp::OMPC_contains, SourceLocation(), SourceLocation(), +SourceLocation(), NumKinds) {} + + static OMPContainsClause *Create(const ASTContext &C, + ArrayRef DKVec, + SourceLocation Loc, SourceLocation LLoc, + SourceLocation RLoc); + + static OMPContainsClause *CreateEmpty(const ASTContext &C, unsigned NumKinds); + + static bool classof(const OMPClause *C) { +return C->getClauseKind() == llvm::omp::OMPC_contains; + } +}; + +/// This represents the 'holds' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume holds() +/// \endcode +/// In this example directive '#pragma omp assume' has a 'holds' clause. +class OMPHoldsClause final +: public OMPOneStmtClause { + friend class OMPClauseReader; + +public: + /// Build 'holds' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPHoldsClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPOneStmtClause(E, StartLoc, LParenLoc, EndLoc) {} + + /// Build an empty clause. + OMPHoldsClause() : OMPOneStmtClause() {} + + Expr *getExpr() const { return getStmtAs(); } + void setExpr(Expr *E) { setStmt(E); } +}; + +/// This represents the 'no_openmp' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume no_openmp +/// \endcode +/// In this example directive '#pragma omp assume' has a 'no_openmp' clause. +class OMPNoOpenMPClause final +: public OMPNoChildClause { +public: + /// Build 'no_openmp' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPNoOpenMPClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPNoChildClause(StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPNoOpenMPClause() : OMPNoChildClause() {} +}; + +/// This represents the 'no_openmp_routines' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume no_openmp_routines +/// \endcode +/// In this example directive '#pragma omp assume' has a 'no_openmp_routines' +/// clause. +class OMPNoOpe
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -342,6 +342,57 @@ template class OMPVarListClause : public OMPClause { } }; +template class OMPDirectiveListClause : public OMPClause { alexey-bataev wrote: Why do you need this? https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
@@ -9475,6 +9555,36 @@ static Expr *buildPostUpdate(Sema &S, ArrayRef PostUpdates) { return PostUpdate; } +class ForVarDeclFinder : public RecursiveASTVisitor { alexey-bataev wrote: final class and description https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
@@ -9475,6 +9555,36 @@ static Expr *buildPostUpdate(Sema &S, ArrayRef PostUpdates) { return PostUpdate; } +class ForVarDeclFinder : public RecursiveASTVisitor { + int NestingDepth; alexey-bataev wrote: `int NestingDepth = 0;` https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
@@ -9069,7 +9147,8 @@ static bool checkOpenMPIterationSpace( Expr *OrderedLoopCountExpr, SemaOpenMP::VarsWithInheritedDSAType &VarsWithImplicitDSA, llvm::MutableArrayRef ResultIterSpaces, -llvm::MapVector &Captures) { +llvm::MapVector &Captures, +const llvm::SmallSet *CollapsedLoopVarDecls) { alexey-bataev wrote: Reference and SmallSetImpl https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
@@ -7668,6 +7669,47 @@ struct LoopIterationSpace final { Expr *FinalCondition = nullptr; }; +class ForSubExprChecker : public RecursiveASTVisitor { + const llvm::SmallSet *CollapsedLoopVarDecls; + VarDecl *ForbiddenVar; alexey-bataev wrote: `VarDecl *ForbiddenVar = nullptr;` https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
@@ -7668,6 +7669,47 @@ struct LoopIterationSpace final { Expr *FinalCondition = nullptr; }; +class ForSubExprChecker : public RecursiveASTVisitor { + const llvm::SmallSet *CollapsedLoopVarDecls; + VarDecl *ForbiddenVar; + SourceRange ErrLoc; + +public: + explicit ForSubExprChecker( + const llvm::SmallSet *CollapsedLoopVarDecls) + : CollapsedLoopVarDecls(CollapsedLoopVarDecls), ForbiddenVar(nullptr) {} + + bool shouldVisitImplicitCode() const { return true; } + + bool VisitDeclRefExpr(DeclRefExpr *E) { +ValueDecl *VD = E->getDecl(); +if (!isa(VD)) + return true; +VarDecl *V = VD->getPotentiallyDecomposedVarDecl(); +if (V->getType()->isReferenceType()) { + VarDecl *VD = V->getDefinition(); + if (VD->hasInit()) { +Expr *I = VD->getInit(); +DeclRefExpr *DRE = dyn_cast(I); +if (!DRE) + return true; +V = DRE->getDecl()->getPotentiallyDecomposedVarDecl(); + } +} +Decl *Canon = V->getCanonicalDecl(); +if (CollapsedLoopVarDecls->contains(Canon)) { + ForbiddenVar = V; + ErrLoc = E->getSourceRange(); + return false; +} + +return true; + } + + VarDecl *getForbiddenVar() { return ForbiddenVar; } + SourceRange &getErrRange() { return ErrLoc; } alexey-bataev wrote: const functions https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Diagnose badly-formed collapsed imperfect loop nests (#60678) (PR #101305)
@@ -7668,6 +7669,47 @@ struct LoopIterationSpace final { Expr *FinalCondition = nullptr; }; +class ForSubExprChecker : public RecursiveASTVisitor { + const llvm::SmallSet *CollapsedLoopVarDecls; + VarDecl *ForbiddenVar; + SourceRange ErrLoc; + +public: + explicit ForSubExprChecker( + const llvm::SmallSet *CollapsedLoopVarDecls) + : CollapsedLoopVarDecls(CollapsedLoopVarDecls), ForbiddenVar(nullptr) {} + + bool shouldVisitImplicitCode() const { return true; } alexey-bataev wrote: unused? Drop then https://github.com/llvm/llvm-project/pull/101305 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Rename `varlists` to `varlist`, NFC (PR #101058)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/101058 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -2013,6 +2014,179 @@ class OMPMergeableClause : public OMPClause { } }; +/// This represents the 'absent' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume absent() +/// \endcode +/// In this example directive '#pragma omp assume' has an 'absent' clause. +class OMPAbsentClause final : public OMPNoChildClause { + llvm::SmallSet DirectiveKinds; + + /// Location of '('. + SourceLocation LParenLoc; + +public: + /// Build 'absent' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPAbsentClause(llvm::SmallSet &DKSet, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPNoChildClause(StartLoc, EndLoc), DirectiveKinds(DKSet), +LParenLoc(LParenLoc) {} + + /// Build an empty clause. + OMPAbsentClause() : OMPNoChildClause() {} + + SourceLocation getLParenLoc() { return LParenLoc; } + + void setLParenLoc(SourceLocation S) { LParenLoc = S; } + + llvm::SmallSet &getDirectiveKinds() { +return DirectiveKinds; + } + + void setDirectiveKinds(llvm::SmallSet &DKS) { +DirectiveKinds = DKS; + } +}; + +/// This represents the 'contains' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume contains() +/// \endcode +/// In this example directive '#pragma omp assume' has a 'contains' clause. +class OMPContainsClause final +: public OMPNoChildClause { + llvm::SmallSet DirectiveKinds; alexey-bataev wrote: I mean that dynamic data types (do vectors, sets, etc.) are not allowed in AST https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -2013,6 +2014,179 @@ class OMPMergeableClause : public OMPClause { } }; +/// This represents the 'absent' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume absent() +/// \endcode +/// In this example directive '#pragma omp assume' has an 'absent' clause. +class OMPAbsentClause final : public OMPNoChildClause { + llvm::SmallSet DirectiveKinds; alexey-bataev wrote: Must be tail allocated https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP] OpenMP 5.1 "assume" directive parsing support (PR #92731)
@@ -2013,6 +2014,179 @@ class OMPMergeableClause : public OMPClause { } }; +/// This represents the 'absent' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume absent() +/// \endcode +/// In this example directive '#pragma omp assume' has an 'absent' clause. +class OMPAbsentClause final : public OMPNoChildClause { + llvm::SmallSet DirectiveKinds; + + /// Location of '('. + SourceLocation LParenLoc; + +public: + /// Build 'absent' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPAbsentClause(llvm::SmallSet &DKSet, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPNoChildClause(StartLoc, EndLoc), DirectiveKinds(DKSet), +LParenLoc(LParenLoc) {} + + /// Build an empty clause. + OMPAbsentClause() : OMPNoChildClause() {} + + SourceLocation getLParenLoc() { return LParenLoc; } + + void setLParenLoc(SourceLocation S) { LParenLoc = S; } + + llvm::SmallSet &getDirectiveKinds() { +return DirectiveKinds; + } + + void setDirectiveKinds(llvm::SmallSet &DKS) { +DirectiveKinds = DKS; + } +}; + +/// This represents the 'contains' clause in the '#pragma omp assume' +/// directive. +/// +/// \code +/// #pragma omp assume contains() +/// \endcode +/// In this example directive '#pragma omp assume' has a 'contains' clause. +class OMPContainsClause final +: public OMPNoChildClause { + llvm::SmallSet DirectiveKinds; alexey-bataev wrote: Bad approach, use tail allocation to keep this https://github.com/llvm/llvm-project/pull/92731 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -21587,32 +21597,39 @@ const ValueDecl *SemaOpenMP::getOpenMPDeclareMapperVarName() const { return cast(DSAStack->getDeclareMapperVarRef())->getDecl(); } -OMPClause *SemaOpenMP::ActOnOpenMPNumTeamsClause(Expr *NumTeams, +OMPClause *SemaOpenMP::ActOnOpenMPNumTeamsClause(ArrayRef VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { - Expr *ValExpr = NumTeams; - Stmt *HelperValStmt = nullptr; - - // OpenMP [teams Constrcut, Restrictions] - // The num_teams expression must evaluate to a positive integer value. - if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_num_teams, - /*StrictlyPositive=*/true)) + if (VarList.empty()) return nullptr; + for (Expr *ValExpr : VarList) { +// OpenMP [teams Constrcut, Restrictions] +// The num_teams expression must evaluate to a positive integer value. +if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_num_teams, + /*StrictlyPositive=*/true)) + return nullptr; + } + OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( DKind, OMPC_num_teams, getLangOpts().OpenMP); - if (CaptureRegion != OMPD_unknown && - !SemaRef.CurContext->isDependentContext()) { + if (CaptureRegion == OMPD_unknown || SemaRef.CurContext->isDependentContext()) +return OMPNumTeamsClause::Create(getASTContext(), StartLoc, LParenLoc, + EndLoc, VarList, /*PreInit=*/nullptr); + + llvm::MapVector Captures; + SmallVector Vars; + for (Expr *ValExpr : VarList) { ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); -llvm::MapVector Captures; ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); -HelperValStmt = buildPreInits(getASTContext(), Captures); +Vars.push_back(ValExpr); } - return new (getASTContext()) OMPNumTeamsClause( - ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); alexey-bataev wrote: Here CaptureRegion is set, but you dropped it and because of this the expression started being passed by reference instead of by value https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -3793,8 +3793,8 @@ bool RecursiveASTVisitor::VisitOMPMapClause(OMPMapClause *C) { template bool RecursiveASTVisitor::VisitOMPNumTeamsClause( OMPNumTeamsClause *C) { + TRY_TO(VisitOMPClauseList(C)); TRY_TO(VisitOMPClauseWithPreInit(C)); alexey-bataev wrote: IIRC, it is part of VisitOMPClauseList https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Remove some dead code in getNumTeamsExprForTargetDirective (PR #95695)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/95695 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Remove some dead code in getNumTeamsExprForTargetDirective (PR #95695)
@@ -6037,8 +6037,6 @@ const Expr *CGOpenMPRuntime::getNumTeamsExprForTargetDirective( MinTeamsVal = MaxTeamsVal = 1; return nullptr; } - MinTeamsVal = MaxTeamsVal = 1; - return nullptr; alexey-bataev wrote: Wrong fix, previous `if` statement should be removed/fixed https://github.com/llvm/llvm-project/pull/95695 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Mark all SIMD regions as non-throwing (PR #100162)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/100162 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -13901,6 +13901,20 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDirective( return StmtError(); } + const OMPClause *NumTeamsClause = nullptr; + bool HasNumTeamsClause = llvm::any_of(Clauses, [&](const OMPClause *C) { +NumTeamsClause = C; +return C->getClauseKind() == OMPC_num_teams; + }); alexey-bataev wrote: ```suggestion auto *It = find_if(Clauses, IsaPred); bool HasNumTeamsClause = HasNumTeamsClause != Clauses.end(); ``` https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -843,9 +843,8 @@ void OMPClauseProfiler::VisitOMPAllocateClause(const OMPAllocateClause *C) { VisitOMPClauseList(C); } void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) { + VisitOMPClauseList(C); VistOMPClauseWithPreInit(C); alexey-bataev wrote: Can be dropped https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -3793,8 +3793,8 @@ bool RecursiveASTVisitor::VisitOMPMapClause(OMPMapClause *C) { template bool RecursiveASTVisitor::VisitOMPNumTeamsClause( OMPNumTeamsClause *C) { + TRY_TO(VisitOMPClauseList(C)); TRY_TO(VisitOMPClauseWithPreInit(C)); alexey-bataev wrote: I think this can be dropped https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -6131,60 +6131,77 @@ class OMPMapClause final : public OMPMappableExprListClause, /// \endcode /// In this example directive '#pragma omp teams' has clause 'num_teams' /// with single expression 'n'. -class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { - friend class OMPClauseReader; +/// +/// When 'ompx_bare' clause exists on a 'target' directive, 'num_teams' clause +/// can accept up to three expressions. +/// +/// \code +/// #pragma omp target teams ompx_bare num_teams(x, y, z) +/// \endcode +class OMPNumTeamsClause final +: public OMPVarListClause, + public OMPClauseWithPreInit, + private llvm::TrailingObjects { + friend OMPVarListClause; + friend TrailingObjects; /// Location of '('. SourceLocation LParenLoc; - /// NumTeams number. - Stmt *NumTeams = nullptr; + OMPNumTeamsClause(const ASTContext &C, SourceLocation StartLoc, +SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) + : OMPVarListClause(llvm::omp::OMPC_num_teams, StartLoc, LParenLoc, EndLoc, + N), +OMPClauseWithPreInit(this) {} - /// Set the NumTeams number. - /// - /// \param E NumTeams number. - void setNumTeams(Expr *E) { NumTeams = E; } + /// Build an empty clause. + OMPNumTeamsClause(unsigned N) + : OMPVarListClause(llvm::omp::OMPC_num_teams, SourceLocation(), + SourceLocation(), SourceLocation(), N), +OMPClauseWithPreInit(this) {} public: - /// Build 'num_teams' clause. + /// Creates clause with a list of variables \a VL. /// - /// \param E Expression associated with this clause. - /// \param HelperE Helper Expression associated with this clause. - /// \param CaptureRegion Innermost OpenMP region where expressions in this - /// clause must be captured. + /// \param C AST context. /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, -SourceLocation StartLoc, SourceLocation LParenLoc, -SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_num_teams, StartLoc, EndLoc), -OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTeams(E) { -setPreInitStmt(HelperE, CaptureRegion); - } + /// \param VL List of references to the variables. + /// \param PreInit + static OMPNumTeamsClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef VL, + Stmt *PreInit); - /// Build an empty clause. - OMPNumTeamsClause() - : OMPClause(llvm::omp::OMPC_num_teams, SourceLocation(), - SourceLocation()), -OMPClauseWithPreInit(this) {} + /// Creates an empty clause with \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + static OMPNumTeamsClause *CreateEmpty(const ASTContext &C, unsigned N); /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } /// Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } - /// Return NumTeams number. - Expr *getNumTeams() { return cast(NumTeams); } + /// Return NumTeams number. By default, we return the first expression. + Expr *getNumTeams() { return getVarRefs().front(); } - /// Return NumTeams number. - Expr *getNumTeams() const { return cast(NumTeams); } + /// Return NumTeams number. By default, we return the first expression. + Expr *getNumTeams() const { +return const_cast(this)->getNumTeams(); + } alexey-bataev wrote: I think these should return ArrayRef https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -11350,8 +11350,13 @@ void OMPClauseReader::VisitOMPAllocateClause(OMPAllocateClause *C) { void OMPClauseReader::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) { VisitOMPClauseWithPreInit(C); - C->setNumTeams(Record.readSubExpr()); C->setLParenLoc(Record.readSourceLocation()); + unsigned NumVars = C->varlist_size(); + SmallVector Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) alexey-bataev wrote: ```suggestion for (unsigned I : seq(NumVars)) ``` https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -812,6 +812,7 @@ int bar(int n){ // CHECK1-NEXT:[[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 // CHECK1-NEXT:[[DOTCAPTURE_EXPR__ADDR2:%.*]] = alloca i64, align 8 // CHECK1-NEXT:[[AA_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT:[[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 alexey-bataev wrote: I think it is because you used the default capture region, which makes passing the value by reference instead of by value https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Move "loop" directive mapping from sema to codegen (PR #99905)
https://github.com/alexey-bataev approved this pull request. LG https://github.com/llvm/llvm-project/pull/99905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Move "loop" directive mapping from sema to codegen (PR #99905)
@@ -3852,44 +3895,44 @@ static bool emitWorksharingDirective(CodeGenFunction &CGF, OMPLoopScope LoopScope(CGF, S); return CGF.EmitScalarExpr(S.getNumIterations()); }; -const auto &&FirstGen = [&S, HasCancel](CodeGenFunction &CGF) { - CodeGenFunction::OMPCancelStackRAII CancelRegion( - CGF, S.getDirectiveKind(), HasCancel); +const auto &&FirstGen = [&S, HasCancel, EKind](CodeGenFunction &CGF) { + CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel); (void)CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, emitDispatchForLoopBounds); // Emit an implicit barrier at the end. CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getBeginLoc(), OMPD_for); }; -const auto &&SecondGen = [&S, HasCancel, +const auto &&SecondGen = [&S, HasCancel, EKind, &HasLastprivates](CodeGenFunction &CGF) { - CodeGenFunction::OMPCancelStackRAII CancelRegion( - CGF, S.getDirectiveKind(), HasCancel); + CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel); HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, emitDispatchForLoopBounds); }; -if (!isOpenMPParallelDirective(S.getDirectiveKind())) +if (!isOpenMPParallelDirective(EKind)) emitScanBasedDirectiveDecls(CGF, S, NumIteratorsGen); emitScanBasedDirective(CGF, S, NumIteratorsGen, FirstGen, SecondGen); -if (!isOpenMPParallelDirective(S.getDirectiveKind())) +if (!isOpenMPParallelDirective(EKind)) emitScanBasedDirectiveFinals(CGF, S, NumIteratorsGen); } else { -CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(), - HasCancel); +CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, EKind, HasCancel); HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, emitDispatchForLoopBounds); } return HasLastprivates; } -static bool isSupportedByOpenMPIRBuilder(const OMPForDirective &S) { - if (S.hasCancel()) +// Pass OMPLoopDirective (instead of OMPForDirective) to make this check +// available for "loop bind(parallel)", which maps to "for". +static bool isForSupportedByOpenMPIRBuilder(const OMPLoopDirective &S, +bool HasCancel) { + if (HasCancel) return false; for (OMPClause *C : S.clauses()) { -if (isa(C)) +if (isa(C) || isa(C)) alexey-bataev wrote: ```suggestion if (isa(C)) ``` https://github.com/llvm/llvm-project/pull/99905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][OpenMP] Move "loop" directive mapping from sema to codegen (PR #99905)
@@ -2534,21 +2563,24 @@ static void emitCommonSimdLoop(CodeGenFunction &CGF, const OMPLoopDirective &S, static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S, PrePostActionTy &Action) { Action.Enter(CGF); - assert(isOpenMPSimdDirective(S.getDirectiveKind()) && - "Expected simd directive"); OMPLoopScope PreInitScope(CGF, S); // if (PreCond) { // for (IV in 0..LastIteration) BODY; // ; // } - // - if (isOpenMPDistributeDirective(S.getDirectiveKind()) || - isOpenMPWorksharingDirective(S.getDirectiveKind()) || - isOpenMPTaskLoopDirective(S.getDirectiveKind())) { -(void)EmitOMPHelperVar(CGF, cast(S.getLowerBoundVariable())); -(void)EmitOMPHelperVar(CGF, cast(S.getUpperBoundVariable())); + + // The presence of lower/upper bound variable depends on the actual directive + // kind in the AST node. The variables must be emitted because some of the + // expressions associated with the loop will use them. + OpenMPDirectiveKind DKind = S.getDirectiveKind(); + if (isOpenMPDistributeDirective(DKind) || + isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || + isOpenMPGenericLoopDirective(DKind)) { +EmitOMPHelperVar(CGF, cast(S.getLowerBoundVariable())); +EmitOMPHelperVar(CGF, cast(S.getUpperBoundVariable())); alexey-bataev wrote: ```suggestion (void)EmitOMPHelperVar(CGF, cast(S.getLowerBoundVariable())); (void)EmitOMPHelperVar(CGF, cast(S.getUpperBoundVariable())); ``` https://github.com/llvm/llvm-project/pull/99905 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -21703,32 +21703,37 @@ const ValueDecl *SemaOpenMP::getOpenMPDeclareMapperVarName() const { return cast(DSAStack->getDeclareMapperVarRef())->getDecl(); } -OMPClause *SemaOpenMP::ActOnOpenMPNumTeamsClause(Expr *NumTeams, +OMPClause *SemaOpenMP::ActOnOpenMPNumTeamsClause(ArrayRef VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { - Expr *ValExpr = NumTeams; - Stmt *HelperValStmt = nullptr; - - // OpenMP [teams Constrcut, Restrictions] - // The num_teams expression must evaluate to a positive integer value. - if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_num_teams, - /*StrictlyPositive=*/true)) + if (VarList.empty()) alexey-bataev wrote: Yes https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][OpenMP] Allow `num_teams` to accept multiple expressions (PR #99732)
@@ -21703,32 +21703,37 @@ const ValueDecl *SemaOpenMP::getOpenMPDeclareMapperVarName() const { return cast(DSAStack->getDeclareMapperVarRef())->getDecl(); } -OMPClause *SemaOpenMP::ActOnOpenMPNumTeamsClause(Expr *NumTeams, +OMPClause *SemaOpenMP::ActOnOpenMPNumTeamsClause(ArrayRef VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { - Expr *ValExpr = NumTeams; - Stmt *HelperValStmt = nullptr; - - // OpenMP [teams Constrcut, Restrictions] - // The num_teams expression must evaluate to a positive integer value. - if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_num_teams, - /*StrictlyPositive=*/true)) + if (VarList.empty()) alexey-bataev wrote: Here no, you need to add a check in the whole directive processing function (check checkSimdlenSafelenSpecified and some other similar) https://github.com/llvm/llvm-project/pull/99732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [openmp] [Clang][OpenMP] Add interchange directive (PR #93022)
@@ -14853,6 +14861,158 @@ StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt, buildPreInits(Context, PreInits)); } +StmtResult SemaOpenMP::ActOnOpenMPInterchangeDirective( +ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, +SourceLocation EndLoc) { + ASTContext &Context = getASTContext(); + DeclContext *CurContext = SemaRef.CurContext; + Scope *CurScope = SemaRef.getCurScope(); + + // Empty statement should only be possible if there already was an error. + if (!AStmt) +return StmtError(); + + // interchange without permutation clause swaps two loops. + constexpr size_t NumLoops = 2; + + // Verify and diagnose loop nest. + SmallVector LoopHelpers(NumLoops); + Stmt *Body = nullptr; + SmallVector, 2> OriginalInits; + if (!checkTransformableLoopNest(OMPD_interchange, AStmt, NumLoops, + LoopHelpers, Body, OriginalInits)) +return StmtError(); + + // Delay interchange to when template is completely instantiated. + if (CurContext->isDependentContext()) +return OMPInterchangeDirective::Create(Context, StartLoc, EndLoc, Clauses, + NumLoops, AStmt, nullptr, nullptr); + + assert(LoopHelpers.size() == NumLoops && + "Expecting loop iteration space dimensionaly to match number of " + "affected loops"); + assert(OriginalInits.size() == NumLoops && + "Expecting loop iteration space dimensionaly to match number of " + "affected loops"); + + // Decode the permutation clause. + constexpr uint64_t Permutation[] = {1, 0}; + + // Find the affected loops. + SmallVector LoopStmts(NumLoops, nullptr); + collectLoopStmts(AStmt, LoopStmts); + + // Collect pre-init statements on the order before the permuation. + SmallVector PreInits; + for (auto I : llvm::seq(NumLoops)) { +OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; + +assert(LoopHelper.Counters.size() == 1 && + "Single-dimensional loop iteration space expected"); +auto *OrigCntVar = cast(LoopHelper.Counters.front()); + +std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); alexey-bataev wrote: Just saying, that better to use SmallString where possible. If you think, std::string is good enough here, I'm fine with it. It was just a suggestion. https://github.com/llvm/llvm-project/pull/93022 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits