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;
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() {
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;
}
/// 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
/// 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.
/// 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 {
}
/// 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
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;
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))
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());
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());
// 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;
}
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;
+ }
}
}
ArrayRef<DeclRefExpr *> getLinkGlobals() const {
assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
"Expected target executable directive.");
- return Stack.back().first.back().DeclareTargetLinkVarDecls;
+ return getTopOfStack().DeclareTargetLinkVarDecls;
}
};
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
// 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
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");
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));
}
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;
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;
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) ||
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;
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.");
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.");
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;
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;
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;
}
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(),
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)) {
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 =
// 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();
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);
}
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;
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();
}
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;
}
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(
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;
}