From: Richard Smith Date: Thu, 30 May 2019 23:21:14 +0000 (+0000) Subject: Refactor OpenMP stack management. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a7fb0fca0bbe2fea51490be70f219d1d818fac8f;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@362172 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 19a7d784c5..5a6b49961f 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -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(*this).getTopOfStackOrNull(); + } + SharingMapTy &getTopOfStack() { + assert(!isStackEmpty() && "no current directive"); + return *getTopOfStackOrNull(); + } + const SharingMapTy &getTopOfStack() const { + return const_cast(*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(*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(*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 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(Stack.back().first[Level].TaskgroupReductionRef) + return getStackElemAtLevel(Level).TaskgroupReductionRef && + cast(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 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 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()) - return false; - - auto StartI = Stack.back().first.begin(); - auto EndI = Stack.back().first.end(); - if (std::distance(StartI, EndI) <= (int)Level) + if (getStackSize() <= 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 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 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(D))); } -DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter, +DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, ValueDecl *D) const { D = getCanonicalDecl(D); auto *VD = dyn_cast(D); const auto *FD = dyn_cast(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 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 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; }