summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-03-11 19:51:42 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2019-03-11 19:51:42 +0000
commita495c6403b5348bc0243393ab5ee467983b3c8eb (patch)
tree697749812ce92630cd003a6521b3098508825c58 /clang/lib
parent51f84f6bae537a1fdcd0ed869a087605807f54bf (diff)
downloadbcm5719-llvm-a495c6403b5348bc0243393ab5ee467983b3c8eb.tar.gz
bcm5719-llvm-a495c6403b5348bc0243393ab5ee467983b3c8eb.zip
[OPENMP]Fix codegen for declare target link in target regions.
If the declare target link global is used in the target region indirectly (used in the inner parallel, teams, etc. regions), we may miss this variable and it leads to incorrect codegen. llvm-svn: 355858
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp48
1 files changed, 46 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 6c4c4a845ce..32e493ed57c 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -147,6 +147,9 @@ private:
/// Reference to the taskgroup task_reduction reference expression.
Expr *TaskgroupReductionRef = nullptr;
llvm::DenseSet<QualType> MappedClassesQualTypes;
+ /// List of globals marked as declare target link in this target region
+ /// (isOpenMPTargetExecutionDirective(Directive) == true).
+ llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope, SourceLocation Loc)
: Directive(DKind), DirectiveName(Name), CurScope(CurScope),
@@ -674,6 +677,31 @@ public:
return StackElem.MappedClassesQualTypes.count(QT) != 0;
}
+ /// Adds global declare target to the parent target region.
+ void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
+ assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
+ E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
+ "Expected declare target link global.");
+ if (isStackEmpty())
+ return;
+ auto It = Stack.back().first.rbegin();
+ while (It != Stack.back().first.rend() &&
+ !isOpenMPTargetExecutionDirective(It->Directive))
+ ++It;
+ if (It != Stack.back().first.rend()) {
+ assert(isOpenMPTargetExecutionDirective(It->Directive) &&
+ "Expected target executable directive.");
+ It->DeclareTargetLinkVarDecls.push_back(E);
+ }
+ }
+
+ /// Returns the list of globals with declare target link if current directive
+ /// is target.
+ ArrayRef<DeclRefExpr *> getLinkGlobals() const {
+ assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
+ "Expected target executable directive.");
+ return Stack.back().first.back().DeclareTargetLinkVarDecls;
+ }
};
bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
@@ -2414,8 +2442,18 @@ public:
// Define implicit data-sharing attributes for task.
DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
- !Stack->isLoopControlVariable(VD).first)
+ !Stack->isLoopControlVariable(VD).first) {
ImplicitFirstprivate.push_back(E);
+ return;
+ }
+
+ // Store implicitly used globals with declare target link for parent
+ // target.
+ if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
+ *Res == OMPDeclareTargetDeclAttr::MT_Link) {
+ Stack->addToParentTargetRegionLinkGlobals(E);
+ return;
+ }
}
}
void VisitMemberExpr(MemberExpr *E) {
@@ -2573,7 +2611,13 @@ public:
}
DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
- : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
+ : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
+ // Process declare target link variables for the target directives.
+ if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
+ for (DeclRefExpr *E : Stack->getLinkGlobals())
+ Visit(E);
+ }
+ }
};
} // namespace
OpenPOWER on IntegriCloud