summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorSamuel Antao <sfantao@us.ibm.com>2015-10-02 17:14:03 +0000
committerSamuel Antao <sfantao@us.ibm.com>2015-10-02 17:14:03 +0000
commit4be30e92dc1a3f2df67d2a03c9b3b1cda55cc5cf (patch)
treeb670ea594cebf892ef2872b7927623e4e19d1db3 /clang/lib
parent1f385618c018b57fd0c32e125954c4dc32dfb936 (diff)
downloadbcm5719-llvm-4be30e92dc1a3f2df67d2a03c9b3b1cda55cc5cf.tar.gz
bcm5719-llvm-4be30e92dc1a3f2df67d2a03c9b3b1cda55cc5cf.zip
[OpenMP] Capture global variables in target regions.
All global variables that are not enclosed in a declare target region must be captured in the target region as local variables do. Currently, there is no support for declare target, so this patch adds support for capturing all the global variables used in a the target region. llvm-svn: 249154
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp4
-rw-r--r--clang/lib/Sema/SemaExpr.cpp14
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp52
3 files changed, 67 insertions, 3 deletions
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 28194680b23..7a7557e732d 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -424,6 +424,10 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
DKind == OMPD_parallel_sections; // TODO add next directives.
}
+bool clang::isOpenMPTargetDirective(OpenMPDirectiveKind DKind) {
+ return DKind == OMPD_target; // TODO add next directives.
+}
+
bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_teams; // TODO add next directives.
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index be0da09f265..0aa9a6c53cd 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13183,10 +13183,18 @@ bool Sema::tryCaptureVariable(
if (getLangOpts().OpenMP) {
if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
// OpenMP private variables should not be captured in outer scope, so
- // just break here.
+ // just break here. Similarly, global variables that are captured in a
+ // target region should not be captured outside the scope of the region.
if (RSI->CapRegionKind == CR_OpenMP) {
- if (isOpenMPPrivateVar(Var, OpenMPLevel)) {
- Nested = true;
+ auto isTargetCap = isOpenMPTargetCapturedVar(Var, OpenMPLevel);
+ // When we detect target captures we are looking from inside the
+ // target region, therefore we need to propagate the capture from the
+ // enclosing region. Therefore, the capture is not initially nested.
+ if (isTargetCap)
+ FunctionScopesIndex--;
+
+ if (isTargetCap || isOpenMPPrivateVar(Var, OpenMPLevel)) {
+ Nested = !isTargetCap;
DeclRefType = DeclRefType.getUnqualifiedType();
CaptureType = Context.getLValueReferenceType(DeclRefType);
break;
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 7c32fab5b58..ae146a38105 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -194,6 +194,13 @@ public:
bool hasExplicitDSA(VarDecl *D,
const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
unsigned Level);
+
+ /// \brief Returns true if the directive at level \Level matches in the
+ /// specified \a DPred predicate.
+ bool hasExplicitDirective(
+ const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
+ unsigned Level);
+
/// \brief Finds a directive which matches specified \a DPred predicate.
template <class NamedDirectivesPredicate>
bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent);
@@ -661,6 +668,19 @@ bool DSAStackTy::hasExplicitDSA(
CPred(StartI->SharingMap[D].Attributes);
}
+bool DSAStackTy::hasExplicitDirective(
+ const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
+ unsigned Level) {
+ if (isClauseParsingMode())
+ ++Level;
+ auto StartI = Stack.rbegin();
+ auto EndI = std::prev(Stack.rend());
+ if (std::distance(StartI, EndI) <= (int)Level)
+ return false;
+ std::advance(StartI, Level);
+ return DPred(StartI->Directive);
+}
+
template <class NamedDirectivesPredicate>
bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) {
auto StartI = std::next(Stack.rbegin());
@@ -684,6 +704,30 @@ void Sema::InitDataSharingAttributesStack() {
bool Sema::IsOpenMPCapturedVar(VarDecl *VD) {
assert(LangOpts.OpenMP && "OpenMP is not allowed");
VD = VD->getCanonicalDecl();
+
+ // If we are attempting to capture a global variable in a directive with
+ // 'target' we return true so that this global is also mapped to the device.
+ //
+ // FIXME: If the declaration is enclosed in a 'declare target' directive,
+ // then it should not be captured. Therefore, an extra check has to be
+ // inserted here once support for 'declare target' is added.
+ //
+ if (!VD->hasLocalStorage()) {
+ if (DSAStack->getCurrentDirective() == OMPD_target &&
+ !DSAStack->isClauseParsingMode()) {
+ return true;
+ }
+ if (DSAStack->getCurScope() &&
+ DSAStack->hasDirective(
+ [](OpenMPDirectiveKind K, const DeclarationNameInfo &DNI,
+ SourceLocation Loc) -> bool {
+ return isOpenMPTargetDirective(K);
+ },
+ false)) {
+ return true;
+ }
+ }
+
if (DSAStack->getCurrentDirective() != OMPD_unknown &&
(!DSAStack->isClauseParsingMode() ||
DSAStack->getParentDirective() != OMPD_unknown)) {
@@ -708,6 +752,14 @@ bool Sema::isOpenMPPrivateVar(VarDecl *VD, unsigned Level) {
VD, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level);
}
+bool Sema::isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level) {
+ assert(LangOpts.OpenMP && "OpenMP is not allowed");
+ // Return true if the current level is no longer enclosed in a target region.
+
+ return !VD->hasLocalStorage() &&
+ DSAStack->hasExplicitDirective(isOpenMPTargetDirective, Level);
+}
+
void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
OpenPOWER on IntegriCloud