forked from OSchip/llvm-project
Refactor OpenMP stack management.
Instead of duplicating access to the directive stack throughout SemaOpenMP.cpp, consolidate it to a few methods and call those everywhere else. In passing, simplify adjacent code where possible. No functionality change intended. llvm-svn: 362172
This commit is contained in:
parent
073f3f1609
commit
375dec5e45
|
@ -173,18 +173,78 @@ private:
|
|||
bool ForceCaptureByReferenceInTargetExecutable = false;
|
||||
CriticalsWithHintsTy Criticals;
|
||||
|
||||
using iterator = StackTy::const_reverse_iterator;
|
||||
/// Iterators over the stack iterate in order from innermost to outermost
|
||||
/// directive.
|
||||
using const_iterator = StackTy::const_reverse_iterator;
|
||||
const_iterator begin() const {
|
||||
return Stack.empty() ? const_iterator() : Stack.back().first.rbegin();
|
||||
}
|
||||
const_iterator end() const {
|
||||
return Stack.empty() ? const_iterator() : Stack.back().first.rend();
|
||||
}
|
||||
using iterator = StackTy::reverse_iterator;
|
||||
iterator begin() {
|
||||
return Stack.empty() ? iterator() : Stack.back().first.rbegin();
|
||||
}
|
||||
iterator end() {
|
||||
return Stack.empty() ? iterator() : Stack.back().first.rend();
|
||||
}
|
||||
|
||||
DSAVarData getDSA(iterator &Iter, ValueDecl *D) const;
|
||||
|
||||
/// Checks if the variable is a local for OpenMP region.
|
||||
bool isOpenMPLocal(VarDecl *D, iterator Iter) const;
|
||||
// Convenience operations to get at the elements of the stack.
|
||||
|
||||
bool isStackEmpty() const {
|
||||
return Stack.empty() ||
|
||||
Stack.back().second != CurrentNonCapturingFunctionScope ||
|
||||
Stack.back().first.empty();
|
||||
}
|
||||
size_t getStackSize() const {
|
||||
return isStackEmpty() ? 0 : Stack.back().first.size();
|
||||
}
|
||||
|
||||
SharingMapTy *getTopOfStackOrNull() {
|
||||
if (isStackEmpty())
|
||||
return nullptr;
|
||||
return &Stack.back().first.back();
|
||||
}
|
||||
const SharingMapTy *getTopOfStackOrNull() const {
|
||||
return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
|
||||
}
|
||||
SharingMapTy &getTopOfStack() {
|
||||
assert(!isStackEmpty() && "no current directive");
|
||||
return *getTopOfStackOrNull();
|
||||
}
|
||||
const SharingMapTy &getTopOfStack() const {
|
||||
return const_cast<DSAStackTy&>(*this).getTopOfStack();
|
||||
}
|
||||
|
||||
SharingMapTy *getSecondOnStackOrNull() {
|
||||
size_t Size = getStackSize();
|
||||
if (Size <= 1)
|
||||
return nullptr;
|
||||
return &Stack.back().first[Size - 2];
|
||||
}
|
||||
const SharingMapTy *getSecondOnStackOrNull() const {
|
||||
return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
|
||||
}
|
||||
|
||||
/// Get the stack element at a certain level (previously returned by
|
||||
/// \c getNestingLevel).
|
||||
///
|
||||
/// Note that nesting levels count from outermost to innermost, and this is
|
||||
/// the reverse of our iteration order where new inner levels are pushed at
|
||||
/// the front of the stack.
|
||||
SharingMapTy &getStackElemAtLevel(unsigned Level) {
|
||||
assert(Level < getStackSize() && "no such stack element");
|
||||
return Stack.back().first[Level];
|
||||
}
|
||||
const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
|
||||
return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
|
||||
}
|
||||
|
||||
DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
|
||||
|
||||
/// Checks if the variable is a local for OpenMP region.
|
||||
bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
|
||||
|
||||
/// Vector of previously declared requires directives
|
||||
SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
|
||||
|
@ -249,28 +309,28 @@ public:
|
|||
void loopInit() {
|
||||
assert(isOpenMPLoopDirective(getCurrentDirective()) &&
|
||||
"Expected loop-based directive.");
|
||||
Stack.back().first.back().LoopStart = true;
|
||||
getTopOfStack().LoopStart = true;
|
||||
}
|
||||
/// Start capturing of the variables in the loop context.
|
||||
void loopStart() {
|
||||
assert(isOpenMPLoopDirective(getCurrentDirective()) &&
|
||||
"Expected loop-based directive.");
|
||||
Stack.back().first.back().LoopStart = false;
|
||||
getTopOfStack().LoopStart = false;
|
||||
}
|
||||
/// true, if variables are captured, false otherwise.
|
||||
bool isLoopStarted() const {
|
||||
assert(isOpenMPLoopDirective(getCurrentDirective()) &&
|
||||
"Expected loop-based directive.");
|
||||
return !Stack.back().first.back().LoopStart;
|
||||
return !getTopOfStack().LoopStart;
|
||||
}
|
||||
/// Marks (or clears) declaration as possibly loop counter.
|
||||
void resetPossibleLoopCounter(const Decl *D = nullptr) {
|
||||
Stack.back().first.back().PossiblyLoopCounter =
|
||||
getTopOfStack().PossiblyLoopCounter =
|
||||
D ? D->getCanonicalDecl() : D;
|
||||
}
|
||||
/// Gets the possible loop counter decl.
|
||||
const Decl *getPossiblyLoopCunter() const {
|
||||
return Stack.back().first.back().PossiblyLoopCounter;
|
||||
return getTopOfStack().PossiblyLoopCounter;
|
||||
}
|
||||
/// Start new OpenMP region stack in new non-capturing function.
|
||||
void pushFunction() {
|
||||
|
@ -350,16 +410,16 @@ public:
|
|||
Expr *&TaskgroupDescriptor) const;
|
||||
/// Return reduction reference expression for the current taskgroup.
|
||||
Expr *getTaskgroupReductionRef() const {
|
||||
assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
|
||||
assert(getTopOfStack().Directive == OMPD_taskgroup &&
|
||||
"taskgroup reference expression requested for non taskgroup "
|
||||
"directive.");
|
||||
return Stack.back().first.back().TaskgroupReductionRef;
|
||||
return getTopOfStack().TaskgroupReductionRef;
|
||||
}
|
||||
/// Checks if the given \p VD declaration is actually a taskgroup reduction
|
||||
/// descriptor variable at the \p Level of OpenMP regions.
|
||||
bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
|
||||
return Stack.back().first[Level].TaskgroupReductionRef &&
|
||||
cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
|
||||
return getStackElemAtLevel(Level).TaskgroupReductionRef &&
|
||||
cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
|
||||
->getDecl() == VD;
|
||||
}
|
||||
|
||||
|
@ -405,18 +465,18 @@ public:
|
|||
|
||||
/// Returns currently analyzed directive.
|
||||
OpenMPDirectiveKind getCurrentDirective() const {
|
||||
return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
|
||||
const SharingMapTy *Top = getTopOfStackOrNull();
|
||||
return Top ? Top->Directive : OMPD_unknown;
|
||||
}
|
||||
/// Returns directive kind at specified level.
|
||||
OpenMPDirectiveKind getDirective(unsigned Level) const {
|
||||
assert(!isStackEmpty() && "No directive at specified level.");
|
||||
return Stack.back().first[Level].Directive;
|
||||
return getStackElemAtLevel(Level).Directive;
|
||||
}
|
||||
/// Returns parent directive.
|
||||
OpenMPDirectiveKind getParentDirective() const {
|
||||
if (isStackEmpty() || Stack.back().first.size() == 1)
|
||||
return OMPD_unknown;
|
||||
return std::next(Stack.back().first.rbegin())->Directive;
|
||||
const SharingMapTy *Parent = getSecondOnStackOrNull();
|
||||
return Parent ? Parent->Directive : OMPD_unknown;
|
||||
}
|
||||
|
||||
/// Add requires decl to internal vector
|
||||
|
@ -468,41 +528,38 @@ public:
|
|||
|
||||
/// Set default data sharing attribute to none.
|
||||
void setDefaultDSANone(SourceLocation Loc) {
|
||||
assert(!isStackEmpty());
|
||||
Stack.back().first.back().DefaultAttr = DSA_none;
|
||||
Stack.back().first.back().DefaultAttrLoc = Loc;
|
||||
getTopOfStack().DefaultAttr = DSA_none;
|
||||
getTopOfStack().DefaultAttrLoc = Loc;
|
||||
}
|
||||
/// Set default data sharing attribute to shared.
|
||||
void setDefaultDSAShared(SourceLocation Loc) {
|
||||
assert(!isStackEmpty());
|
||||
Stack.back().first.back().DefaultAttr = DSA_shared;
|
||||
Stack.back().first.back().DefaultAttrLoc = Loc;
|
||||
getTopOfStack().DefaultAttr = DSA_shared;
|
||||
getTopOfStack().DefaultAttrLoc = Loc;
|
||||
}
|
||||
/// Set default data mapping attribute to 'tofrom:scalar'.
|
||||
void setDefaultDMAToFromScalar(SourceLocation Loc) {
|
||||
assert(!isStackEmpty());
|
||||
Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
|
||||
Stack.back().first.back().DefaultMapAttrLoc = Loc;
|
||||
getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar;
|
||||
getTopOfStack().DefaultMapAttrLoc = Loc;
|
||||
}
|
||||
|
||||
DefaultDataSharingAttributes getDefaultDSA() const {
|
||||
return isStackEmpty() ? DSA_unspecified
|
||||
: Stack.back().first.back().DefaultAttr;
|
||||
: getTopOfStack().DefaultAttr;
|
||||
}
|
||||
SourceLocation getDefaultDSALocation() const {
|
||||
return isStackEmpty() ? SourceLocation()
|
||||
: Stack.back().first.back().DefaultAttrLoc;
|
||||
: getTopOfStack().DefaultAttrLoc;
|
||||
}
|
||||
DefaultMapAttributes getDefaultDMA() const {
|
||||
return isStackEmpty() ? DMA_unspecified
|
||||
: Stack.back().first.back().DefaultMapAttr;
|
||||
: getTopOfStack().DefaultMapAttr;
|
||||
}
|
||||
DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
|
||||
return Stack.back().first[Level].DefaultMapAttr;
|
||||
return getStackElemAtLevel(Level).DefaultMapAttr;
|
||||
}
|
||||
SourceLocation getDefaultDMALocation() const {
|
||||
return isStackEmpty() ? SourceLocation()
|
||||
: Stack.back().first.back().DefaultMapAttrLoc;
|
||||
: getTopOfStack().DefaultMapAttrLoc;
|
||||
}
|
||||
|
||||
/// Checks if the specified variable is a threadprivate.
|
||||
|
@ -514,82 +571,77 @@ public:
|
|||
/// Marks current region as ordered (it has an 'ordered' clause).
|
||||
void setOrderedRegion(bool IsOrdered, const Expr *Param,
|
||||
OMPOrderedClause *Clause) {
|
||||
assert(!isStackEmpty());
|
||||
if (IsOrdered)
|
||||
Stack.back().first.back().OrderedRegion.emplace(Param, Clause);
|
||||
getTopOfStack().OrderedRegion.emplace(Param, Clause);
|
||||
else
|
||||
Stack.back().first.back().OrderedRegion.reset();
|
||||
getTopOfStack().OrderedRegion.reset();
|
||||
}
|
||||
/// Returns true, if region is ordered (has associated 'ordered' clause),
|
||||
/// false - otherwise.
|
||||
bool isOrderedRegion() const {
|
||||
if (isStackEmpty())
|
||||
return false;
|
||||
return Stack.back().first.rbegin()->OrderedRegion.hasValue();
|
||||
if (const SharingMapTy *Top = getTopOfStackOrNull())
|
||||
return Top->OrderedRegion.hasValue();
|
||||
return false;
|
||||
}
|
||||
/// Returns optional parameter for the ordered region.
|
||||
std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
|
||||
if (isStackEmpty() ||
|
||||
!Stack.back().first.rbegin()->OrderedRegion.hasValue())
|
||||
return std::make_pair(nullptr, nullptr);
|
||||
return Stack.back().first.rbegin()->OrderedRegion.getValue();
|
||||
if (const SharingMapTy *Top = getTopOfStackOrNull())
|
||||
if (Top->OrderedRegion.hasValue())
|
||||
return Top->OrderedRegion.getValue();
|
||||
return std::make_pair(nullptr, nullptr);
|
||||
}
|
||||
/// Returns true, if parent region is ordered (has associated
|
||||
/// 'ordered' clause), false - otherwise.
|
||||
bool isParentOrderedRegion() const {
|
||||
if (isStackEmpty() || Stack.back().first.size() == 1)
|
||||
return false;
|
||||
return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
|
||||
if (const SharingMapTy *Parent = getSecondOnStackOrNull())
|
||||
return Parent->OrderedRegion.hasValue();
|
||||
return false;
|
||||
}
|
||||
/// Returns optional parameter for the ordered region.
|
||||
std::pair<const Expr *, OMPOrderedClause *>
|
||||
getParentOrderedRegionParam() const {
|
||||
if (isStackEmpty() || Stack.back().first.size() == 1 ||
|
||||
!std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
|
||||
return std::make_pair(nullptr, nullptr);
|
||||
return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
|
||||
if (const SharingMapTy *Parent = getSecondOnStackOrNull())
|
||||
if (Parent->OrderedRegion.hasValue())
|
||||
return Parent->OrderedRegion.getValue();
|
||||
return std::make_pair(nullptr, nullptr);
|
||||
}
|
||||
/// Marks current region as nowait (it has a 'nowait' clause).
|
||||
void setNowaitRegion(bool IsNowait = true) {
|
||||
assert(!isStackEmpty());
|
||||
Stack.back().first.back().NowaitRegion = IsNowait;
|
||||
getTopOfStack().NowaitRegion = IsNowait;
|
||||
}
|
||||
/// Returns true, if parent region is nowait (has associated
|
||||
/// 'nowait' clause), false - otherwise.
|
||||
bool isParentNowaitRegion() const {
|
||||
if (isStackEmpty() || Stack.back().first.size() == 1)
|
||||
return false;
|
||||
return std::next(Stack.back().first.rbegin())->NowaitRegion;
|
||||
if (const SharingMapTy *Parent = getSecondOnStackOrNull())
|
||||
return Parent->NowaitRegion;
|
||||
return false;
|
||||
}
|
||||
/// Marks parent region as cancel region.
|
||||
void setParentCancelRegion(bool Cancel = true) {
|
||||
if (!isStackEmpty() && Stack.back().first.size() > 1) {
|
||||
auto &StackElemRef = *std::next(Stack.back().first.rbegin());
|
||||
StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
|
||||
}
|
||||
if (SharingMapTy *Parent = getSecondOnStackOrNull())
|
||||
Parent->CancelRegion |= Cancel;
|
||||
}
|
||||
/// Return true if current region has inner cancel construct.
|
||||
bool isCancelRegion() const {
|
||||
return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
|
||||
const SharingMapTy *Top = getTopOfStackOrNull();
|
||||
return Top ? Top->CancelRegion : false;
|
||||
}
|
||||
|
||||
/// Set collapse value for the region.
|
||||
void setAssociatedLoops(unsigned Val) {
|
||||
assert(!isStackEmpty());
|
||||
Stack.back().first.back().AssociatedLoops = Val;
|
||||
getTopOfStack().AssociatedLoops = Val;
|
||||
}
|
||||
/// Return collapse value for region.
|
||||
unsigned getAssociatedLoops() const {
|
||||
return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
|
||||
const SharingMapTy *Top = getTopOfStackOrNull();
|
||||
return Top ? Top->AssociatedLoops : 0;
|
||||
}
|
||||
|
||||
/// Marks current target region as one with closely nested teams
|
||||
/// region.
|
||||
void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
|
||||
if (!isStackEmpty() && Stack.back().first.size() > 1) {
|
||||
std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
|
||||
TeamsRegionLoc;
|
||||
}
|
||||
if (SharingMapTy *Parent = getSecondOnStackOrNull())
|
||||
Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
|
||||
}
|
||||
/// Returns true, if current region has closely nested teams region.
|
||||
bool hasInnerTeamsRegion() const {
|
||||
|
@ -597,16 +649,17 @@ public:
|
|||
}
|
||||
/// Returns location of the nested teams region (if any).
|
||||
SourceLocation getInnerTeamsRegionLoc() const {
|
||||
return isStackEmpty() ? SourceLocation()
|
||||
: Stack.back().first.back().InnerTeamsRegionLoc;
|
||||
const SharingMapTy *Top = getTopOfStackOrNull();
|
||||
return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
|
||||
}
|
||||
|
||||
Scope *getCurScope() const {
|
||||
return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
|
||||
const SharingMapTy *Top = getTopOfStackOrNull();
|
||||
return Top ? Top->CurScope : nullptr;
|
||||
}
|
||||
SourceLocation getConstructLoc() const {
|
||||
return isStackEmpty() ? SourceLocation()
|
||||
: Stack.back().first.back().ConstructLoc;
|
||||
const SharingMapTy *Top = getTopOfStackOrNull();
|
||||
return Top ? Top->ConstructLoc : SourceLocation();
|
||||
}
|
||||
|
||||
/// Do the check specified in \a Check to all component lists and return true
|
||||
|
@ -619,8 +672,8 @@ public:
|
|||
Check) const {
|
||||
if (isStackEmpty())
|
||||
return false;
|
||||
auto SI = Stack.back().first.rbegin();
|
||||
auto SE = Stack.back().first.rend();
|
||||
auto SI = begin();
|
||||
auto SE = end();
|
||||
|
||||
if (SI == SE)
|
||||
return false;
|
||||
|
@ -649,17 +702,12 @@ public:
|
|||
bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
|
||||
OpenMPClauseKind)>
|
||||
Check) const {
|
||||
if (isStackEmpty())
|
||||
if (getStackSize() <= Level)
|
||||
return false;
|
||||
|
||||
auto StartI = Stack.back().first.begin();
|
||||
auto EndI = Stack.back().first.end();
|
||||
if (std::distance(StartI, EndI) <= (int)Level)
|
||||
return false;
|
||||
std::advance(StartI, Level);
|
||||
|
||||
auto MI = StartI->MappedExprComponents.find(VD);
|
||||
if (MI != StartI->MappedExprComponents.end())
|
||||
const SharingMapTy &StackElem = getStackElemAtLevel(Level);
|
||||
auto MI = StackElem.MappedExprComponents.find(VD);
|
||||
if (MI != StackElem.MappedExprComponents.end())
|
||||
for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
|
||||
MI->second.Components)
|
||||
if (Check(L, MI->second.Kind))
|
||||
|
@ -673,10 +721,7 @@ public:
|
|||
const ValueDecl *VD,
|
||||
OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
|
||||
OpenMPClauseKind WhereFoundClauseKind) {
|
||||
assert(!isStackEmpty() &&
|
||||
"Not expecting to retrieve components from a empty stack!");
|
||||
MappedExprComponentTy &MEC =
|
||||
Stack.back().first.back().MappedExprComponents[VD];
|
||||
MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
|
||||
// Create new entry and append the new components there.
|
||||
MEC.Components.resize(MEC.Components.size() + 1);
|
||||
MEC.Components.back().append(Components.begin(), Components.end());
|
||||
|
@ -685,19 +730,17 @@ public:
|
|||
|
||||
unsigned getNestingLevel() const {
|
||||
assert(!isStackEmpty());
|
||||
return Stack.back().first.size() - 1;
|
||||
return getStackSize() - 1;
|
||||
}
|
||||
void addDoacrossDependClause(OMPDependClause *C,
|
||||
const OperatorOffsetTy &OpsOffs) {
|
||||
assert(!isStackEmpty() && Stack.back().first.size() > 1);
|
||||
SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
|
||||
assert(isOpenMPWorksharingDirective(StackElem.Directive));
|
||||
StackElem.DoacrossDepends.try_emplace(C, OpsOffs);
|
||||
SharingMapTy *Parent = getSecondOnStackOrNull();
|
||||
assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
|
||||
Parent->DoacrossDepends.try_emplace(C, OpsOffs);
|
||||
}
|
||||
llvm::iterator_range<DoacrossDependMapTy::const_iterator>
|
||||
getDoacrossDependClauses() const {
|
||||
assert(!isStackEmpty());
|
||||
const SharingMapTy &StackElem = Stack.back().first.back();
|
||||
const SharingMapTy &StackElem = getTopOfStack();
|
||||
if (isOpenMPWorksharingDirective(StackElem.Directive)) {
|
||||
const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
|
||||
return llvm::make_range(Ref.begin(), Ref.end());
|
||||
|
@ -708,13 +751,13 @@ public:
|
|||
|
||||
// Store types of classes which have been explicitly mapped
|
||||
void addMappedClassesQualTypes(QualType QT) {
|
||||
SharingMapTy &StackElem = Stack.back().first.back();
|
||||
SharingMapTy &StackElem = getTopOfStack();
|
||||
StackElem.MappedClassesQualTypes.insert(QT);
|
||||
}
|
||||
|
||||
// Return set of mapped classes types
|
||||
bool isClassPreviouslyMapped(QualType QT) const {
|
||||
const SharingMapTy &StackElem = Stack.back().first.back();
|
||||
const SharingMapTy &StackElem = getTopOfStack();
|
||||
return StackElem.MappedClassesQualTypes.count(QT) != 0;
|
||||
}
|
||||
|
||||
|
@ -723,16 +766,11 @@ public:
|
|||
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);
|
||||
for (auto &Elem : *this) {
|
||||
if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
|
||||
Elem.DeclareTargetLinkVarDecls.push_back(E);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -741,7 +779,7 @@ public:
|
|||
ArrayRef<DeclRefExpr *> getLinkGlobals() const {
|
||||
assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
|
||||
"Expected target executable directive.");
|
||||
return Stack.back().first.back().DeclareTargetLinkVarDecls;
|
||||
return getTopOfStack().DeclareTargetLinkVarDecls;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -797,13 +835,13 @@ static ValueDecl *getCanonicalDecl(ValueDecl *D) {
|
|||
getCanonicalDecl(const_cast<const ValueDecl *>(D)));
|
||||
}
|
||||
|
||||
DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
|
||||
DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
|
||||
ValueDecl *D) const {
|
||||
D = getCanonicalDecl(D);
|
||||
auto *VD = dyn_cast<VarDecl>(D);
|
||||
const auto *FD = dyn_cast<FieldDecl>(D);
|
||||
DSAVarData DVar;
|
||||
if (isStackEmpty() || Iter == Stack.back().first.rend()) {
|
||||
if (Iter == end()) {
|
||||
// OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
|
||||
// in a region but not in construct]
|
||||
// File-scope or namespace-scope variables referenced in called routines
|
||||
|
@ -878,7 +916,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
|
|||
// bound to the current team is shared.
|
||||
if (isOpenMPTaskingDirective(DVar.DKind)) {
|
||||
DSAVarData DVarTemp;
|
||||
iterator I = Iter, E = Stack.back().first.rend();
|
||||
const_iterator I = Iter, E = end();
|
||||
do {
|
||||
++I;
|
||||
// OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
|
||||
|
@ -910,7 +948,7 @@ const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
|
|||
const Expr *NewDE) {
|
||||
assert(!isStackEmpty() && "Data sharing attributes stack is empty");
|
||||
D = getCanonicalDecl(D);
|
||||
SharingMapTy &StackElem = Stack.back().first.back();
|
||||
SharingMapTy &StackElem = getTopOfStack();
|
||||
auto It = StackElem.AlignedMap.find(D);
|
||||
if (It == StackElem.AlignedMap.end()) {
|
||||
assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
|
||||
|
@ -924,7 +962,7 @@ const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
|
|||
void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
|
||||
assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
|
||||
D = getCanonicalDecl(D);
|
||||
SharingMapTy &StackElem = Stack.back().first.back();
|
||||
SharingMapTy &StackElem = getTopOfStack();
|
||||
StackElem.LCVMap.try_emplace(
|
||||
D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
|
||||
}
|
||||
|
@ -933,7 +971,7 @@ const DSAStackTy::LCDeclInfo
|
|||
DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
|
||||
assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
|
||||
D = getCanonicalDecl(D);
|
||||
const SharingMapTy &StackElem = Stack.back().first.back();
|
||||
const SharingMapTy &StackElem = getTopOfStack();
|
||||
auto It = StackElem.LCVMap.find(D);
|
||||
if (It != StackElem.LCVMap.end())
|
||||
return It->second;
|
||||
|
@ -942,23 +980,21 @@ DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
|
|||
|
||||
const DSAStackTy::LCDeclInfo
|
||||
DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
|
||||
assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
|
||||
"Data-sharing attributes stack is empty");
|
||||
const SharingMapTy *Parent = getSecondOnStackOrNull();
|
||||
assert(Parent && "Data-sharing attributes stack is empty");
|
||||
D = getCanonicalDecl(D);
|
||||
const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
|
||||
auto It = StackElem.LCVMap.find(D);
|
||||
if (It != StackElem.LCVMap.end())
|
||||
auto It = Parent->LCVMap.find(D);
|
||||
if (It != Parent->LCVMap.end())
|
||||
return It->second;
|
||||
return {0, nullptr};
|
||||
}
|
||||
|
||||
const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
|
||||
assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
|
||||
"Data-sharing attributes stack is empty");
|
||||
const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
|
||||
if (StackElem.LCVMap.size() < I)
|
||||
const SharingMapTy *Parent = getSecondOnStackOrNull();
|
||||
assert(Parent && "Data-sharing attributes stack is empty");
|
||||
if (Parent->LCVMap.size() < I)
|
||||
return nullptr;
|
||||
for (const auto &Pair : StackElem.LCVMap)
|
||||
for (const auto &Pair : Parent->LCVMap)
|
||||
if (Pair.second.first == I)
|
||||
return Pair.first;
|
||||
return nullptr;
|
||||
|
@ -973,8 +1009,7 @@ void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
|
|||
Data.RefExpr.setPointer(E);
|
||||
Data.PrivateCopy = nullptr;
|
||||
} else {
|
||||
assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
|
||||
DSAInfo &Data = Stack.back().first.back().SharingMap[D];
|
||||
DSAInfo &Data = getTopOfStack().SharingMap[D];
|
||||
assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
|
||||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
|
||||
(A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
|
||||
|
@ -989,8 +1024,7 @@ void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
|
|||
Data.RefExpr.setPointerAndInt(E, IsLastprivate);
|
||||
Data.PrivateCopy = PrivateCopy;
|
||||
if (PrivateCopy) {
|
||||
DSAInfo &Data =
|
||||
Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
|
||||
DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
|
||||
Data.Attributes = A;
|
||||
Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
|
||||
Data.PrivateCopy = nullptr;
|
||||
|
@ -1035,16 +1069,16 @@ void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
|
|||
D = getCanonicalDecl(D);
|
||||
assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
|
||||
assert(
|
||||
Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
|
||||
getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
|
||||
"Additional reduction info may be specified only for reduction items.");
|
||||
ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
|
||||
ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
|
||||
assert(ReductionData.ReductionRange.isInvalid() &&
|
||||
Stack.back().first.back().Directive == OMPD_taskgroup &&
|
||||
getTopOfStack().Directive == OMPD_taskgroup &&
|
||||
"Additional reduction info may be specified only once for reduction "
|
||||
"items.");
|
||||
ReductionData.set(BOK, SR);
|
||||
Expr *&TaskgroupReductionRef =
|
||||
Stack.back().first.back().TaskgroupReductionRef;
|
||||
getTopOfStack().TaskgroupReductionRef;
|
||||
if (!TaskgroupReductionRef) {
|
||||
VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
|
||||
SemaRef.Context.VoidPtrTy, ".task_red.");
|
||||
|
@ -1058,16 +1092,16 @@ void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
|
|||
D = getCanonicalDecl(D);
|
||||
assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
|
||||
assert(
|
||||
Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
|
||||
getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
|
||||
"Additional reduction info may be specified only for reduction items.");
|
||||
ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
|
||||
ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
|
||||
assert(ReductionData.ReductionRange.isInvalid() &&
|
||||
Stack.back().first.back().Directive == OMPD_taskgroup &&
|
||||
getTopOfStack().Directive == OMPD_taskgroup &&
|
||||
"Additional reduction info may be specified only once for reduction "
|
||||
"items.");
|
||||
ReductionData.set(ReductionRef, SR);
|
||||
Expr *&TaskgroupReductionRef =
|
||||
Stack.back().first.back().TaskgroupReductionRef;
|
||||
getTopOfStack().TaskgroupReductionRef;
|
||||
if (!TaskgroupReductionRef) {
|
||||
VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
|
||||
SemaRef.Context.VoidPtrTy, ".task_red.");
|
||||
|
@ -1081,11 +1115,7 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
|
|||
Expr *&TaskgroupDescriptor) const {
|
||||
D = getCanonicalDecl(D);
|
||||
assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
|
||||
if (Stack.back().first.empty())
|
||||
return DSAVarData();
|
||||
for (iterator I = std::next(Stack.back().first.rbegin(), 1),
|
||||
E = Stack.back().first.rend();
|
||||
I != E; std::advance(I, 1)) {
|
||||
for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
|
||||
const DSAInfo &Data = I->SharingMap.lookup(D);
|
||||
if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
|
||||
continue;
|
||||
|
@ -1110,11 +1140,7 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
|
|||
Expr *&TaskgroupDescriptor) const {
|
||||
D = getCanonicalDecl(D);
|
||||
assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
|
||||
if (Stack.back().first.empty())
|
||||
return DSAVarData();
|
||||
for (iterator I = std::next(Stack.back().first.rbegin(), 1),
|
||||
E = Stack.back().first.rend();
|
||||
I != E; std::advance(I, 1)) {
|
||||
for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
|
||||
const DSAInfo &Data = I->SharingMap.lookup(D);
|
||||
if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
|
||||
continue;
|
||||
|
@ -1134,21 +1160,17 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
|
|||
return DSAVarData();
|
||||
}
|
||||
|
||||
bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
|
||||
bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
|
||||
D = D->getCanonicalDecl();
|
||||
if (!isStackEmpty()) {
|
||||
iterator I = Iter, E = Stack.back().first.rend();
|
||||
Scope *TopScope = nullptr;
|
||||
while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) &&
|
||||
!isOpenMPTargetExecutionDirective(I->Directive))
|
||||
++I;
|
||||
if (I == E)
|
||||
return false;
|
||||
TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
|
||||
Scope *CurScope = getCurScope();
|
||||
while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
|
||||
CurScope = CurScope->getParent();
|
||||
return CurScope != TopScope;
|
||||
for (const_iterator E = end(); I != E; ++I) {
|
||||
if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
|
||||
isOpenMPTargetExecutionDirective(I->Directive)) {
|
||||
Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
|
||||
Scope *CurScope = getCurScope();
|
||||
while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
|
||||
CurScope = CurScope->getParent();
|
||||
return CurScope != TopScope;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1236,15 +1258,14 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
|
|||
if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
|
||||
VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
|
||||
!isLoopControlVariable(D).first) {
|
||||
iterator IterTarget =
|
||||
std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(),
|
||||
[](const SharingMapTy &Data) {
|
||||
return isOpenMPTargetExecutionDirective(Data.Directive);
|
||||
});
|
||||
if (IterTarget != Stack.back().first.rend()) {
|
||||
iterator ParentIterTarget = std::next(IterTarget, 1);
|
||||
for (iterator Iter = Stack.back().first.rbegin();
|
||||
Iter != ParentIterTarget; std::advance(Iter, 1)) {
|
||||
const_iterator IterTarget =
|
||||
std::find_if(begin(), end(), [](const SharingMapTy &Data) {
|
||||
return isOpenMPTargetExecutionDirective(Data.Directive);
|
||||
});
|
||||
if (IterTarget != end()) {
|
||||
const_iterator ParentIterTarget = IterTarget + 1;
|
||||
for (const_iterator Iter = begin();
|
||||
Iter != ParentIterTarget; ++Iter) {
|
||||
if (isOpenMPLocal(VD, Iter)) {
|
||||
DVar.RefExpr =
|
||||
buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
|
||||
|
@ -1253,7 +1274,7 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
|
|||
return DVar;
|
||||
}
|
||||
}
|
||||
if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) {
|
||||
if (!isClauseParsingMode() || IterTarget != begin()) {
|
||||
auto DSAIter = IterTarget->SharingMap.find(D);
|
||||
if (DSAIter != IterTarget->SharingMap.end() &&
|
||||
isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
|
||||
|
@ -1261,7 +1282,7 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
|
|||
DVar.CKind = OMPC_threadprivate;
|
||||
return DVar;
|
||||
}
|
||||
iterator End = Stack.back().first.rend();
|
||||
const_iterator End = end();
|
||||
if (!SemaRef.isOpenMPCapturedByRef(
|
||||
D, std::distance(ParentIterTarget, End))) {
|
||||
DVar.RefExpr =
|
||||
|
@ -1321,10 +1342,10 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
|
|||
|
||||
// Explicitly specified attributes and local variables with predetermined
|
||||
// attributes.
|
||||
iterator I = Stack.back().first.rbegin();
|
||||
iterator EndI = Stack.back().first.rend();
|
||||
const_iterator I = begin();
|
||||
const_iterator EndI = end();
|
||||
if (FromParent && I != EndI)
|
||||
std::advance(I, 1);
|
||||
++I;
|
||||
auto It = I->SharingMap.find(D);
|
||||
if (It != I->SharingMap.end()) {
|
||||
const DSAInfo &Data = It->getSecond();
|
||||
|
@ -1341,14 +1362,14 @@ const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
|
|||
const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
|
||||
bool FromParent) const {
|
||||
if (isStackEmpty()) {
|
||||
iterator I;
|
||||
const_iterator I;
|
||||
return getDSA(I, D);
|
||||
}
|
||||
D = getCanonicalDecl(D);
|
||||
iterator StartI = Stack.back().first.rbegin();
|
||||
iterator EndI = Stack.back().first.rend();
|
||||
const_iterator StartI = begin();
|
||||
const_iterator EndI = end();
|
||||
if (FromParent && StartI != EndI)
|
||||
std::advance(StartI, 1);
|
||||
++StartI;
|
||||
return getDSA(StartI, D);
|
||||
}
|
||||
|
||||
|
@ -1360,14 +1381,15 @@ DSAStackTy::hasDSA(ValueDecl *D,
|
|||
if (isStackEmpty())
|
||||
return {};
|
||||
D = getCanonicalDecl(D);
|
||||
iterator I = Stack.back().first.rbegin();
|
||||
iterator EndI = Stack.back().first.rend();
|
||||
const_iterator I = begin();
|
||||
const_iterator EndI = end();
|
||||
if (FromParent && I != EndI)
|
||||
std::advance(I, 1);
|
||||
for (; I != EndI; std::advance(I, 1)) {
|
||||
if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive))
|
||||
++I;
|
||||
for (; I != EndI; ++I) {
|
||||
if (!DPred(I->Directive) &&
|
||||
!isImplicitOrExplicitTaskingRegion(I->Directive))
|
||||
continue;
|
||||
iterator NewI = I;
|
||||
const_iterator NewI = I;
|
||||
DSAVarData DVar = getDSA(NewI, D);
|
||||
if (I == NewI && CPred(DVar.CKind))
|
||||
return DVar;
|
||||
|
@ -1382,13 +1404,13 @@ const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
|
|||
if (isStackEmpty())
|
||||
return {};
|
||||
D = getCanonicalDecl(D);
|
||||
iterator StartI = Stack.back().first.rbegin();
|
||||
iterator EndI = Stack.back().first.rend();
|
||||
const_iterator StartI = begin();
|
||||
const_iterator EndI = end();
|
||||
if (FromParent && StartI != EndI)
|
||||
std::advance(StartI, 1);
|
||||
++StartI;
|
||||
if (StartI == EndI || !DPred(StartI->Directive))
|
||||
return {};
|
||||
iterator NewI = StartI;
|
||||
const_iterator NewI = StartI;
|
||||
DSAVarData DVar = getDSA(NewI, D);
|
||||
return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
|
||||
}
|
||||
|
@ -1396,23 +1418,19 @@ const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
|
|||
bool DSAStackTy::hasExplicitDSA(
|
||||
const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
|
||||
unsigned Level, bool NotLastprivate) const {
|
||||
if (isStackEmpty())
|
||||
if (getStackSize() <= Level)
|
||||
return false;
|
||||
D = getCanonicalDecl(D);
|
||||
auto StartI = Stack.back().first.begin();
|
||||
auto EndI = Stack.back().first.end();
|
||||
if (std::distance(StartI, EndI) <= (int)Level)
|
||||
return false;
|
||||
std::advance(StartI, Level);
|
||||
auto I = StartI->SharingMap.find(D);
|
||||
if ((I != StartI->SharingMap.end()) &&
|
||||
I->getSecond().RefExpr.getPointer() &&
|
||||
CPred(I->getSecond().Attributes) &&
|
||||
(!NotLastprivate || !I->getSecond().RefExpr.getInt()))
|
||||
const SharingMapTy &StackElem = getStackElemAtLevel(Level);
|
||||
auto I = StackElem.SharingMap.find(D);
|
||||
if (I != StackElem.SharingMap.end() &&
|
||||
I->getSecond().RefExpr.getPointer() &&
|
||||
CPred(I->getSecond().Attributes) &&
|
||||
(!NotLastprivate || !I->getSecond().RefExpr.getInt()))
|
||||
return true;
|
||||
// Check predetermined rules for the loop control variables.
|
||||
auto LI = StartI->LCVMap.find(D);
|
||||
if (LI != StartI->LCVMap.end())
|
||||
auto LI = StackElem.LCVMap.find(D);
|
||||
if (LI != StackElem.LCVMap.end())
|
||||
return CPred(OMPC_private);
|
||||
return false;
|
||||
}
|
||||
|
@ -1420,14 +1438,10 @@ bool DSAStackTy::hasExplicitDSA(
|
|||
bool DSAStackTy::hasExplicitDirective(
|
||||
const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
|
||||
unsigned Level) const {
|
||||
if (isStackEmpty())
|
||||
if (getStackSize() <= Level)
|
||||
return false;
|
||||
auto StartI = Stack.back().first.begin();
|
||||
auto EndI = Stack.back().first.end();
|
||||
if (std::distance(StartI, EndI) <= (int)Level)
|
||||
return false;
|
||||
std::advance(StartI, Level);
|
||||
return DPred(StartI->Directive);
|
||||
const SharingMapTy &StackElem = getStackElemAtLevel(Level);
|
||||
return DPred(StackElem.Directive);
|
||||
}
|
||||
|
||||
bool DSAStackTy::hasDirective(
|
||||
|
@ -1436,13 +1450,9 @@ bool DSAStackTy::hasDirective(
|
|||
DPred,
|
||||
bool FromParent) const {
|
||||
// We look only in the enclosing region.
|
||||
if (isStackEmpty())
|
||||
return false;
|
||||
auto StartI = std::next(Stack.back().first.rbegin());
|
||||
auto EndI = Stack.back().first.rend();
|
||||
if (FromParent && StartI != EndI)
|
||||
StartI = std::next(StartI);
|
||||
for (auto I = StartI, EE = EndI; I != EE; ++I) {
|
||||
size_t Skip = FromParent ? 2 : 1;
|
||||
for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
|
||||
I != E; ++I) {
|
||||
if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue