diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-26 19:24:09 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-26 19:24:09 +0000 |
commit | f0c55418e2b09eaab37c820d3756cc1b4584d084 (patch) | |
tree | 9263bf60f263bb5a7aaa4d2c1be43e5fc4d942e0 /lib/Sema/SemaOpenMP.cpp | |
parent | 583e75cce441388bc562fa225d23499261a0091e (diff) |
Notes
Diffstat (limited to 'lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 327 |
1 files changed, 206 insertions, 121 deletions
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index d7a6d2e5885ee..fb13669407fc1 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -118,7 +118,9 @@ private: typedef SmallVector<SharingMapTy, 4> StackTy; /// \brief Stack of used declaration and their data-sharing attributes. - StackTy Stack; + DeclSAMapTy Threadprivates; + const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; + SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; /// \brief true, if check for DSA must be from parent directive, false, if /// from current directive. OpenMPClauseKind ClauseKindMode = OMPC_unknown; @@ -133,8 +135,14 @@ private: /// \brief Checks if the variable is a local for OpenMP region. bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); + bool isStackEmpty() const { + return Stack.empty() || + Stack.back().second != CurrentNonCapturingFunctionScope || + Stack.back().first.empty(); + } + public: - explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {} + explicit DSAStackTy(Sema &S) : SemaRef(S) {} bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } @@ -144,13 +152,38 @@ public: void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc) { - Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc)); - Stack.back().DefaultAttrLoc = Loc; + if (Stack.empty() || + Stack.back().second != CurrentNonCapturingFunctionScope) + Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); + Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); + Stack.back().first.back().DefaultAttrLoc = Loc; } void pop() { - assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!"); - Stack.pop_back(); + assert(!Stack.back().first.empty() && + "Data-sharing attributes stack is empty!"); + Stack.back().first.pop_back(); + } + + /// Start new OpenMP region stack in new non-capturing function. + void pushFunction() { + const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); + assert(!isa<CapturingScopeInfo>(CurFnScope)); + CurrentNonCapturingFunctionScope = CurFnScope; + } + /// Pop region stack for non-capturing function. + void popFunction(const FunctionScopeInfo *OldFSI) { + if (!Stack.empty() && Stack.back().second == OldFSI) { + assert(Stack.back().first.empty()); + Stack.pop_back(); + } + CurrentNonCapturingFunctionScope = nullptr; + for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { + if (!isa<CapturingScopeInfo>(FSI)) { + CurrentNonCapturingFunctionScope = FSI; + break; + } + } } void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) { @@ -229,31 +262,35 @@ public: /// \brief Returns currently analyzed directive. OpenMPDirectiveKind getCurrentDirective() const { - return Stack.back().Directive; + return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; } /// \brief Returns parent directive. OpenMPDirectiveKind getParentDirective() const { - if (Stack.size() > 2) - return Stack[Stack.size() - 2].Directive; - return OMPD_unknown; + if (isStackEmpty() || Stack.back().first.size() == 1) + return OMPD_unknown; + return std::next(Stack.back().first.rbegin())->Directive; } /// \brief Set default data sharing attribute to none. void setDefaultDSANone(SourceLocation Loc) { - Stack.back().DefaultAttr = DSA_none; - Stack.back().DefaultAttrLoc = Loc; + assert(!isStackEmpty()); + Stack.back().first.back().DefaultAttr = DSA_none; + Stack.back().first.back().DefaultAttrLoc = Loc; } /// \brief Set default data sharing attribute to shared. void setDefaultDSAShared(SourceLocation Loc) { - Stack.back().DefaultAttr = DSA_shared; - Stack.back().DefaultAttrLoc = Loc; + assert(!isStackEmpty()); + Stack.back().first.back().DefaultAttr = DSA_shared; + Stack.back().first.back().DefaultAttrLoc = Loc; } DefaultDataSharingAttributes getDefaultDSA() const { - return Stack.back().DefaultAttr; + return isStackEmpty() ? DSA_unspecified + : Stack.back().first.back().DefaultAttr; } SourceLocation getDefaultDSALocation() const { - return Stack.back().DefaultAttrLoc; + return isStackEmpty() ? SourceLocation() + : Stack.back().first.back().DefaultAttrLoc; } /// \brief Checks if the specified variable is a threadprivate. @@ -264,52 +301,64 @@ public: /// \brief Marks current region as ordered (it has an 'ordered' clause). void setOrderedRegion(bool IsOrdered, Expr *Param) { - Stack.back().OrderedRegion.setInt(IsOrdered); - Stack.back().OrderedRegion.setPointer(Param); + assert(!isStackEmpty()); + Stack.back().first.back().OrderedRegion.setInt(IsOrdered); + Stack.back().first.back().OrderedRegion.setPointer(Param); } /// \brief Returns true, if parent region is ordered (has associated /// 'ordered' clause), false - otherwise. bool isParentOrderedRegion() const { - if (Stack.size() > 2) - return Stack[Stack.size() - 2].OrderedRegion.getInt(); - return false; + if (isStackEmpty() || Stack.back().first.size() == 1) + return false; + return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt(); } /// \brief Returns optional parameter for the ordered region. Expr *getParentOrderedRegionParam() const { - if (Stack.size() > 2) - return Stack[Stack.size() - 2].OrderedRegion.getPointer(); - return nullptr; + if (isStackEmpty() || Stack.back().first.size() == 1) + return nullptr; + return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer(); } /// \brief Marks current region as nowait (it has a 'nowait' clause). void setNowaitRegion(bool IsNowait = true) { - Stack.back().NowaitRegion = IsNowait; + assert(!isStackEmpty()); + Stack.back().first.back().NowaitRegion = IsNowait; } /// \brief Returns true, if parent region is nowait (has associated /// 'nowait' clause), false - otherwise. bool isParentNowaitRegion() const { - if (Stack.size() > 2) - return Stack[Stack.size() - 2].NowaitRegion; - return false; + if (isStackEmpty() || Stack.back().first.size() == 1) + return false; + return std::next(Stack.back().first.rbegin())->NowaitRegion; } /// \brief Marks parent region as cancel region. void setParentCancelRegion(bool Cancel = true) { - if (Stack.size() > 2) - Stack[Stack.size() - 2].CancelRegion = - Stack[Stack.size() - 2].CancelRegion || Cancel; + if (!isStackEmpty() && Stack.back().first.size() > 1) { + auto &StackElemRef = *std::next(Stack.back().first.rbegin()); + StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; + } } /// \brief Return true if current region has inner cancel construct. - bool isCancelRegion() const { return Stack.back().CancelRegion; } + bool isCancelRegion() const { + return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; + } /// \brief Set collapse value for the region. - void setAssociatedLoops(unsigned Val) { Stack.back().AssociatedLoops = Val; } + void setAssociatedLoops(unsigned Val) { + assert(!isStackEmpty()); + Stack.back().first.back().AssociatedLoops = Val; + } /// \brief Return collapse value for region. - unsigned getAssociatedLoops() const { return Stack.back().AssociatedLoops; } + unsigned getAssociatedLoops() const { + return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; + } /// \brief Marks current target region as one with closely nested teams /// region. void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { - if (Stack.size() > 2) - Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc; + if (!isStackEmpty() && Stack.back().first.size() > 1) { + std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = + TeamsRegionLoc; + } } /// \brief Returns true, if current region has closely nested teams region. bool hasInnerTeamsRegion() const { @@ -317,14 +366,20 @@ public: } /// \brief Returns location of the nested teams region (if any). SourceLocation getInnerTeamsRegionLoc() const { - if (Stack.size() > 1) - return Stack.back().InnerTeamsRegionLoc; - return SourceLocation(); + return isStackEmpty() ? SourceLocation() + : Stack.back().first.back().InnerTeamsRegionLoc; } - Scope *getCurScope() const { return Stack.back().CurScope; } - Scope *getCurScope() { return Stack.back().CurScope; } - SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } + Scope *getCurScope() const { + return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; + } + Scope *getCurScope() { + return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; + } + SourceLocation getConstructLoc() { + return isStackEmpty() ? SourceLocation() + : Stack.back().first.back().ConstructLoc; + } /// Do the check specified in \a Check to all component lists and return true /// if any issue is found. @@ -333,8 +388,10 @@ public: const llvm::function_ref< bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, OpenMPClauseKind)> &Check) { - auto SI = Stack.rbegin(); - auto SE = Stack.rend(); + if (isStackEmpty()) + return false; + auto SI = Stack.back().first.rbegin(); + auto SE = Stack.back().first.rend(); if (SI == SE) return false; @@ -361,9 +418,9 @@ public: ValueDecl *VD, OMPClauseMappableExprCommon::MappableExprComponentListRef Components, OpenMPClauseKind WhereFoundClauseKind) { - assert(Stack.size() > 1 && + assert(!isStackEmpty() && "Not expecting to retrieve components from a empty stack!"); - auto &MEC = Stack.back().MappedExprComponents[VD]; + auto &MEC = Stack.back().first.back().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()); @@ -371,23 +428,25 @@ public: } unsigned getNestingLevel() const { - assert(Stack.size() > 1); - return Stack.size() - 2; + assert(!isStackEmpty()); + return Stack.back().first.size() - 1; } void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) { - assert(Stack.size() > 2); - assert(isOpenMPWorksharingDirective(Stack[Stack.size() - 2].Directive)); - Stack[Stack.size() - 2].DoacrossDepends.insert({C, OpsOffs}); + assert(!isStackEmpty() && Stack.back().first.size() > 1); + auto &StackElem = *std::next(Stack.back().first.rbegin()); + assert(isOpenMPWorksharingDirective(StackElem.Directive)); + StackElem.DoacrossDepends.insert({C, OpsOffs}); } llvm::iterator_range<DoacrossDependMapTy::const_iterator> getDoacrossDependClauses() const { - assert(Stack.size() > 1); - if (isOpenMPWorksharingDirective(Stack[Stack.size() - 1].Directive)) { - auto &Ref = Stack[Stack.size() - 1].DoacrossDepends; + assert(!isStackEmpty()); + auto &StackElem = Stack.back().first.back(); + if (isOpenMPWorksharingDirective(StackElem.Directive)) { + auto &Ref = StackElem.DoacrossDepends; return llvm::make_range(Ref.begin(), Ref.end()); } - return llvm::make_range(Stack[0].DoacrossDepends.end(), - Stack[0].DoacrossDepends.end()); + return llvm::make_range(StackElem.DoacrossDepends.end(), + StackElem.DoacrossDepends.end()); } }; bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { @@ -416,7 +475,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter, auto *VD = dyn_cast<VarDecl>(D); auto *FD = dyn_cast<FieldDecl>(D); DSAVarData DVar; - if (Iter == std::prev(Stack.rend())) { + if (isStackEmpty() || Iter == Stack.back().first.rend()) { // 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 @@ -490,8 +549,9 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter, // bound to the current team is shared. if (isOpenMPTaskingDirective(DVar.DKind)) { DSAVarData DVarTemp; - for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend(); - I != EE; ++I) { + auto I = Iter, E = Stack.back().first.rend(); + do { + ++I; // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables // Referenced in a Construct, implicitly determined, p.6] // In a task construct, if no default clause is present, a variable @@ -503,9 +563,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter, DVar.CKind = OMPC_firstprivate; return DVar; } - if (isParallelOrTaskRegion(I->Directive)) - break; - } + } while (I != E && !isParallelOrTaskRegion(I->Directive)); DVar.CKind = (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; return DVar; @@ -520,12 +578,13 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter, } Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { - assert(Stack.size() > 1 && "Data sharing attributes stack is empty"); + assert(!isStackEmpty() && "Data sharing attributes stack is empty"); D = getCanonicalDecl(D); - auto It = Stack.back().AlignedMap.find(D); - if (It == Stack.back().AlignedMap.end()) { + auto &StackElem = Stack.back().first.back(); + auto It = StackElem.AlignedMap.find(D); + if (It == StackElem.AlignedMap.end()) { assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); - Stack.back().AlignedMap[D] = NewDE; + StackElem.AlignedMap[D] = NewDE; return nullptr; } else { assert(It->second && "Unexpected nullptr expr in the aligned map"); @@ -535,35 +594,43 @@ Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { } void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) { - assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); + assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); D = getCanonicalDecl(D); - Stack.back().LCVMap.insert( - std::make_pair(D, LCDeclInfo(Stack.back().LCVMap.size() + 1, Capture))); + auto &StackElem = Stack.back().first.back(); + StackElem.LCVMap.insert( + {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)}); } DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) { - assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); + assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); D = getCanonicalDecl(D); - return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D] - : LCDeclInfo(0, nullptr); + auto &StackElem = Stack.back().first.back(); + auto It = StackElem.LCVMap.find(D); + if (It != StackElem.LCVMap.end()) + return It->second; + return {0, nullptr}; } DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { - assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); + assert(!isStackEmpty() && Stack.back().first.size() > 1 && + "Data-sharing attributes stack is empty"); D = getCanonicalDecl(D); - return Stack[Stack.size() - 2].LCVMap.count(D) > 0 - ? Stack[Stack.size() - 2].LCVMap[D] - : LCDeclInfo(0, nullptr); + auto &StackElem = *std::next(Stack.back().first.rbegin()); + auto It = StackElem.LCVMap.find(D); + if (It != StackElem.LCVMap.end()) + return It->second; + return {0, nullptr}; } ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { - assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); - if (Stack[Stack.size() - 2].LCVMap.size() < I) + assert(!isStackEmpty() && Stack.back().first.size() > 1 && + "Data-sharing attributes stack is empty"); + auto &StackElem = *std::next(Stack.back().first.rbegin()); + if (StackElem.LCVMap.size() < I) return nullptr; - for (auto &Pair : Stack[Stack.size() - 2].LCVMap) { + for (auto &Pair : StackElem.LCVMap) if (Pair.second.first == I) return Pair.first; - } return nullptr; } @@ -571,13 +638,13 @@ void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, DeclRefExpr *PrivateCopy) { D = getCanonicalDecl(D); if (A == OMPC_threadprivate) { - auto &Data = Stack[0].SharingMap[D]; + auto &Data = Threadprivates[D]; Data.Attributes = A; Data.RefExpr.setPointer(E); Data.PrivateCopy = nullptr; } else { - assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); - auto &Data = Stack.back().SharingMap[D]; + assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); + auto &Data = Stack.back().first.back().SharingMap[D]; assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || @@ -592,7 +659,7 @@ void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, Data.RefExpr.setPointerAndInt(E, IsLastprivate); Data.PrivateCopy = PrivateCopy; if (PrivateCopy) { - auto &Data = Stack.back().SharingMap[PrivateCopy->getDecl()]; + auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; Data.Attributes = A; Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); Data.PrivateCopy = nullptr; @@ -602,19 +669,17 @@ void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { D = D->getCanonicalDecl(); - if (Stack.size() > 2) { - reverse_iterator I = Iter, E = std::prev(Stack.rend()); + if (!isStackEmpty() && Stack.back().first.size() > 1) { + reverse_iterator I = Iter, E = Stack.back().first.rend(); Scope *TopScope = nullptr; - while (I != E && !isParallelOrTaskRegion(I->Directive)) { + while (I != E && !isParallelOrTaskRegion(I->Directive)) ++I; - } if (I == E) return false; TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; Scope *CurScope = getCurScope(); - while (CurScope != TopScope && !CurScope->isDeclScope(D)) { + while (CurScope != TopScope && !CurScope->isDeclScope(D)) CurScope = CurScope->getParent(); - } return CurScope != TopScope; } return false; @@ -665,16 +730,16 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { D->getLocation()), OMPC_threadprivate); } - if (Stack[0].SharingMap.count(D)) { - DVar.RefExpr = Stack[0].SharingMap[D].RefExpr.getPointer(); + auto TI = Threadprivates.find(D); + if (TI != Threadprivates.end()) { + DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); DVar.CKind = OMPC_threadprivate; return DVar; } - if (Stack.size() == 1) { + if (isStackEmpty()) // Not in OpenMP execution region and top scope was already checked. return DVar; - } // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced // in a Construct, C/C++, predetermined, p.4] @@ -722,11 +787,10 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { // Explicitly specified attributes and local variables with predetermined // attributes. - auto StartI = std::next(Stack.rbegin()); - auto EndI = std::prev(Stack.rend()); - if (FromParent && StartI != EndI) { + auto StartI = std::next(Stack.back().first.rbegin()); + auto EndI = Stack.back().first.rend(); + if (FromParent && StartI != EndI) StartI = std::next(StartI); - } auto I = std::prev(StartI); if (I->SharingMap.count(D)) { DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer(); @@ -740,12 +804,15 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, bool FromParent) { + if (isStackEmpty()) { + StackTy::reverse_iterator I; + return getDSA(I, D); + } D = getCanonicalDecl(D); - auto StartI = Stack.rbegin(); - auto EndI = std::prev(Stack.rend()); - if (FromParent && StartI != EndI) { + auto StartI = Stack.back().first.rbegin(); + auto EndI = Stack.back().first.rend(); + if (FromParent && StartI != EndI) StartI = std::next(StartI); - } return getDSA(StartI, D); } @@ -754,33 +821,40 @@ DSAStackTy::hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, bool FromParent) { + if (isStackEmpty()) + return {}; D = getCanonicalDecl(D); - auto StartI = std::next(Stack.rbegin()); - auto EndI = Stack.rend(); - if (FromParent && StartI != EndI) { + 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) { + if (StartI == EndI) + return {}; + auto I = std::prev(StartI); + do { + ++I; if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) continue; DSAVarData DVar = getDSA(I, D); if (CPred(DVar.CKind)) return DVar; - } - return DSAVarData(); + } while (I != EndI); + return {}; } DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, bool FromParent) { + if (isStackEmpty()) + return {}; D = getCanonicalDecl(D); - auto StartI = std::next(Stack.rbegin()); - auto EndI = Stack.rend(); + auto StartI = std::next(Stack.back().first.rbegin()); + auto EndI = Stack.back().first.rend(); if (FromParent && StartI != EndI) StartI = std::next(StartI); if (StartI == EndI || !DPred(StartI->Directive)) - return DSAVarData(); + return {}; DSAVarData DVar = getDSA(StartI, D); return CPred(DVar.CKind) ? DVar : DSAVarData(); } @@ -790,9 +864,11 @@ bool DSAStackTy::hasExplicitDSA( unsigned Level, bool NotLastprivate) { if (CPred(ClauseKindMode)) return true; + if (isStackEmpty()) + return false; D = getCanonicalDecl(D); - auto StartI = std::next(Stack.begin()); - auto EndI = Stack.end(); + 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); @@ -805,8 +881,10 @@ bool DSAStackTy::hasExplicitDSA( bool DSAStackTy::hasExplicitDirective( const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, unsigned Level) { - auto StartI = std::next(Stack.begin()); - auto EndI = Stack.end(); + if (isStackEmpty()) + 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); @@ -819,13 +897,12 @@ bool DSAStackTy::hasDirective( &DPred, bool FromParent) { // We look only in the enclosing region. - if (Stack.size() < 2) + if (isStackEmpty()) return false; - auto StartI = std::next(Stack.rbegin()); - auto EndI = std::prev(Stack.rend()); - if (FromParent && StartI != EndI) { + 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) { if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) return true; @@ -839,6 +916,14 @@ void Sema::InitDataSharingAttributesStack() { #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) +void Sema::pushOpenMPFunctionRegion() { + DSAStack->pushFunction(); +} + +void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { + DSAStack->popFunction(OldFSI); +} + bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) { assert(LangOpts.OpenMP && "OpenMP is not allowed"); |