diff options
author | Samuel Antao <sfantao@us.ibm.com> | 2016-04-27 22:40:57 +0000 |
---|---|---|
committer | Samuel Antao <sfantao@us.ibm.com> | 2016-04-27 22:40:57 +0000 |
commit | 86ace55d53589fadc96a2f6f01a0b3bca782da18 (patch) | |
tree | 7fd404273a35f8cf73afbd13d41fec1746a41cf6 /clang/lib/Sema/SemaOpenMP.cpp | |
parent | c493085c8dca9f317051be9ccf5c89e36812d9eb (diff) | |
download | bcm5719-llvm-86ace55d53589fadc96a2f6f01a0b3bca782da18.tar.gz bcm5719-llvm-86ace55d53589fadc96a2f6f01a0b3bca782da18.zip |
[OpenMP] Map clause codegeneration.
Summary:
Implement codegen for the map clause. All the new list items in 4.5 specification are supported.
Fix bug in the generation of array sections that was exposed by some of the map clause tests: for pointer types the offsets have to be calculated from the pointee not the pointer.
Reviewers: hfinkel, kkwli0, carlo.bertolli, arpith-jacob, ABataev
Subscribers: ABataev, cfe-commits, caomhin, fraggamuffin
Differential Revision: http://reviews.llvm.org/D16749
llvm-svn: 267808
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 07417020758..a57bbfc1d53 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -887,16 +887,56 @@ bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, // array section, the runtime library may pass the NULL value to the // device instead of the value passed to it by the compiler. - // FIXME: Right now, only implicit maps are implemented. Properly mapping - // values requires having the map, private, and firstprivate clauses SEMA - // and parsing in place, which we don't yet. if (Ty->isReferenceType()) Ty = Ty->castAs<ReferenceType>()->getPointeeType(); - IsByRef = !Ty->isScalarType(); + + // Locate map clauses and see if the variable being captured is referred to + // in any of those clauses. Here we only care about variables, not fields, + // because fields are part of aggregates. + bool IsVariableUsedInMapClause = false; + bool IsVariableAssociatedWithSection = false; + + DSAStack->checkMappableExprComponentListsForDecl( + D, /*CurrentRegionOnly=*/true, + [&](OMPClauseMappableExprCommon::MappableExprComponentListRef + MapExprComponents) { + + auto EI = MapExprComponents.rbegin(); + auto EE = MapExprComponents.rend(); + + assert(EI != EE && "Invalid map expression!"); + + if (isa<DeclRefExpr>(EI->getAssociatedExpression())) + IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; + + ++EI; + if (EI == EE) + return false; + + if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || + isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || + isa<MemberExpr>(EI->getAssociatedExpression())) { + IsVariableAssociatedWithSection = true; + // There is nothing more we need to know about this variable. + return true; + } + + // Keep looking for more map info. + return false; + }); + + if (IsVariableUsedInMapClause) { + // If variable is identified in a map clause it is always captured by + // reference except if it is a pointer that is dereferenced somehow. + IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); + } else { + // By default, all the data that has a scalar type is mapped by copy. + IsByRef = !Ty->isScalarType(); + } } - // When passing data by value, we need to make sure it fits the uintptr size + // When passing data by copy, we need to make sure it fits the uintptr size // and alignment, because the runtime library only deals with uintptr types. // If it does not fit the uintptr size, we need to pass the data by reference // instead. |