|
@@ -318,8 +318,9 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
|
|
/// \brief Offsets to the stored exprs.
|
|
|
/// This enumeration contains offsets to all the pointers to children
|
|
|
/// expressions stored in OMPLoopDirective.
|
|
|
- /// The first 9 children are nesessary for all the loop directives, and
|
|
|
- /// the next 10 are specific to the worksharing ones.
|
|
|
+ /// The first 9 children are necessary for all the loop directives,
|
|
|
+ /// the next 8 are specific to the worksharing ones, and the next 11 are
|
|
|
+ /// used for combined constructs containing two pragmas associated to loops.
|
|
|
/// After the fixed children, three arrays of length CollapsedNum are
|
|
|
/// allocated: loop counters, their updates and final values.
|
|
|
/// PrevLowerBound and PrevUpperBound are used to communicate blocking
|
|
@@ -344,7 +345,7 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
|
|
// specify the offset to the end (and start of the following counters/
|
|
|
// updates/finals arrays).
|
|
|
DefaultEnd = 9,
|
|
|
- // The following 12 exprs are used by worksharing and distribute loops only.
|
|
|
+ // The following 8 exprs are used by worksharing and distribute loops only.
|
|
|
IsLastIterVariableOffset = 9,
|
|
|
LowerBoundVariableOffset = 10,
|
|
|
UpperBoundVariableOffset = 11,
|
|
@@ -353,13 +354,22 @@ class OMPLoopDirective : public OMPExecutableDirective {
|
|
|
NextLowerBoundOffset = 14,
|
|
|
NextUpperBoundOffset = 15,
|
|
|
NumIterationsOffset = 16,
|
|
|
+ // Offset to the end for worksharing loop directives.
|
|
|
+ WorksharingEnd = 17,
|
|
|
PrevLowerBoundVariableOffset = 17,
|
|
|
PrevUpperBoundVariableOffset = 18,
|
|
|
DistIncOffset = 19,
|
|
|
PrevEnsureUpperBoundOffset = 20,
|
|
|
+ CombinedLowerBoundVariableOffset = 21,
|
|
|
+ CombinedUpperBoundVariableOffset = 22,
|
|
|
+ CombinedEnsureUpperBoundOffset = 23,
|
|
|
+ CombinedInitOffset = 24,
|
|
|
+ CombinedConditionOffset = 25,
|
|
|
+ CombinedNextLowerBoundOffset = 26,
|
|
|
+ CombinedNextUpperBoundOffset = 27,
|
|
|
// Offset to the end (and start of the following counters/updates/finals
|
|
|
- // arrays) for worksharing loop directives.
|
|
|
- WorksharingEnd = 21,
|
|
|
+ // arrays) for combined distribute loop directives.
|
|
|
+ CombinedDistributeEnd = 28,
|
|
|
};
|
|
|
|
|
|
/// \brief Get the counters storage.
|
|
@@ -423,11 +433,12 @@ protected:
|
|
|
|
|
|
/// \brief Offset to the start of children expression arrays.
|
|
|
static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
|
|
|
- return (isOpenMPWorksharingDirective(Kind) ||
|
|
|
- isOpenMPTaskLoopDirective(Kind) ||
|
|
|
- isOpenMPDistributeDirective(Kind))
|
|
|
- ? WorksharingEnd
|
|
|
- : DefaultEnd;
|
|
|
+ if (isOpenMPLoopBoundSharingDirective(Kind))
|
|
|
+ return CombinedDistributeEnd;
|
|
|
+ if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
|
|
|
+ isOpenMPDistributeDirective(Kind))
|
|
|
+ return WorksharingEnd;
|
|
|
+ return DefaultEnd;
|
|
|
}
|
|
|
|
|
|
/// \brief Children number.
|
|
@@ -515,33 +526,60 @@ protected:
|
|
|
*std::next(child_begin(), NumIterationsOffset) = NI;
|
|
|
}
|
|
|
void setPrevLowerBoundVariable(Expr *PrevLB) {
|
|
|
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPDistributeDirective(getDirectiveKind())) &&
|
|
|
- "expected worksharing loop directive");
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
*std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB;
|
|
|
}
|
|
|
void setPrevUpperBoundVariable(Expr *PrevUB) {
|
|
|
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPDistributeDirective(getDirectiveKind())) &&
|
|
|
- "expected worksharing loop directive");
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
*std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
|
|
|
}
|
|
|
void setDistInc(Expr *DistInc) {
|
|
|
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPDistributeDirective(getDirectiveKind())) &&
|
|
|
- "expected worksharing loop directive");
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
*std::next(child_begin(), DistIncOffset) = DistInc;
|
|
|
}
|
|
|
void setPrevEnsureUpperBound(Expr *PrevEUB) {
|
|
|
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPDistributeDirective(getDirectiveKind())) &&
|
|
|
- "expected worksharing loop directive");
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
*std::next(child_begin(), PrevEnsureUpperBoundOffset) = PrevEUB;
|
|
|
}
|
|
|
+ void setCombinedLowerBoundVariable(Expr *CombLB) {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ *std::next(child_begin(), CombinedLowerBoundVariableOffset) = CombLB;
|
|
|
+ }
|
|
|
+ void setCombinedUpperBoundVariable(Expr *CombUB) {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ *std::next(child_begin(), CombinedUpperBoundVariableOffset) = CombUB;
|
|
|
+ }
|
|
|
+ void setCombinedEnsureUpperBound(Expr *CombEUB) {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ *std::next(child_begin(), CombinedEnsureUpperBoundOffset) = CombEUB;
|
|
|
+ }
|
|
|
+ void setCombinedInit(Expr *CombInit) {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ *std::next(child_begin(), CombinedInitOffset) = CombInit;
|
|
|
+ }
|
|
|
+ void setCombinedCond(Expr *CombCond) {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ *std::next(child_begin(), CombinedConditionOffset) = CombCond;
|
|
|
+ }
|
|
|
+ void setCombinedNextLowerBound(Expr *CombNLB) {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ *std::next(child_begin(), CombinedNextLowerBoundOffset) = CombNLB;
|
|
|
+ }
|
|
|
+ void setCombinedNextUpperBound(Expr *CombNUB) {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ *std::next(child_begin(), CombinedNextUpperBoundOffset) = CombNUB;
|
|
|
+ }
|
|
|
void setCounters(ArrayRef<Expr *> A);
|
|
|
void setPrivateCounters(ArrayRef<Expr *> A);
|
|
|
void setInits(ArrayRef<Expr *> A);
|
|
@@ -549,6 +587,33 @@ protected:
|
|
|
void setFinals(ArrayRef<Expr *> A);
|
|
|
|
|
|
public:
|
|
|
+ /// The expressions built to support OpenMP loops in combined/composite
|
|
|
+ /// pragmas (e.g. pragma omp distribute parallel for)
|
|
|
+ struct DistCombinedHelperExprs {
|
|
|
+ /// DistributeLowerBound - used when composing 'omp distribute' with
|
|
|
+ /// 'omp for' in a same construct.
|
|
|
+ Expr *LB;
|
|
|
+ /// DistributeUpperBound - used when composing 'omp distribute' with
|
|
|
+ /// 'omp for' in a same construct.
|
|
|
+ Expr *UB;
|
|
|
+ /// DistributeEnsureUpperBound - used when composing 'omp distribute'
|
|
|
+ /// with 'omp for' in a same construct, EUB depends on DistUB
|
|
|
+ Expr *EUB;
|
|
|
+ /// Distribute loop iteration variable init used when composing 'omp
|
|
|
+ /// distribute'
|
|
|
+ /// with 'omp for' in a same construct
|
|
|
+ Expr *Init;
|
|
|
+ /// Distribute Loop condition used when composing 'omp distribute'
|
|
|
+ /// with 'omp for' in a same construct
|
|
|
+ Expr *Cond;
|
|
|
+ /// Update of LowerBound for statically sheduled omp loops for
|
|
|
+ /// outer loop in combined constructs (e.g. 'distribute parallel for')
|
|
|
+ Expr *NLB;
|
|
|
+ /// Update of UpperBound for statically sheduled omp loops for
|
|
|
+ /// outer loop in combined constructs (e.g. 'distribute parallel for')
|
|
|
+ Expr *NUB;
|
|
|
+ };
|
|
|
+
|
|
|
/// \brief The expressions built for the OpenMP loop CodeGen for the
|
|
|
/// whole collapsed loop nest.
|
|
|
struct HelperExprs {
|
|
@@ -611,6 +676,9 @@ public:
|
|
|
/// Init statement for all captured expressions.
|
|
|
Stmt *PreInits;
|
|
|
|
|
|
+ /// Expressions used when combining OpenMP loop pragmas
|
|
|
+ DistCombinedHelperExprs DistCombinedFields;
|
|
|
+
|
|
|
/// \brief Check if all the expressions are built (does not check the
|
|
|
/// worksharing ones).
|
|
|
bool builtAll() {
|
|
@@ -654,6 +722,13 @@ public:
|
|
|
Finals[i] = nullptr;
|
|
|
}
|
|
|
PreInits = nullptr;
|
|
|
+ DistCombinedFields.LB = nullptr;
|
|
|
+ DistCombinedFields.UB = nullptr;
|
|
|
+ DistCombinedFields.EUB = nullptr;
|
|
|
+ DistCombinedFields.Init = nullptr;
|
|
|
+ DistCombinedFields.Cond = nullptr;
|
|
|
+ DistCombinedFields.NLB = nullptr;
|
|
|
+ DistCombinedFields.NUB = nullptr;
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -757,37 +832,71 @@ public:
|
|
|
*std::next(child_begin(), NumIterationsOffset)));
|
|
|
}
|
|
|
Expr *getPrevLowerBoundVariable() const {
|
|
|
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPDistributeDirective(getDirectiveKind())) &&
|
|
|
- "expected worksharing loop directive");
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
*std::next(child_begin(), PrevLowerBoundVariableOffset)));
|
|
|
}
|
|
|
Expr *getPrevUpperBoundVariable() const {
|
|
|
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPDistributeDirective(getDirectiveKind())) &&
|
|
|
- "expected worksharing loop directive");
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
*std::next(child_begin(), PrevUpperBoundVariableOffset)));
|
|
|
}
|
|
|
Expr *getDistInc() const {
|
|
|
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPDistributeDirective(getDirectiveKind())) &&
|
|
|
- "expected worksharing loop directive");
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
*std::next(child_begin(), DistIncOffset)));
|
|
|
}
|
|
|
Expr *getPrevEnsureUpperBound() const {
|
|
|
- assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPTaskLoopDirective(getDirectiveKind()) ||
|
|
|
- isOpenMPDistributeDirective(getDirectiveKind())) &&
|
|
|
- "expected worksharing loop directive");
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
*std::next(child_begin(), PrevEnsureUpperBoundOffset)));
|
|
|
}
|
|
|
+ Expr *getCombinedLowerBoundVariable() const {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
+ *std::next(child_begin(), CombinedLowerBoundVariableOffset)));
|
|
|
+ }
|
|
|
+ Expr *getCombinedUpperBoundVariable() const {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
+ *std::next(child_begin(), CombinedUpperBoundVariableOffset)));
|
|
|
+ }
|
|
|
+ Expr *getCombinedEnsureUpperBound() const {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
+ *std::next(child_begin(), CombinedEnsureUpperBoundOffset)));
|
|
|
+ }
|
|
|
+ Expr *getCombinedInit() const {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
+ *std::next(child_begin(), CombinedInitOffset)));
|
|
|
+ }
|
|
|
+ Expr *getCombinedCond() const {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
+ *std::next(child_begin(), CombinedConditionOffset)));
|
|
|
+ }
|
|
|
+ Expr *getCombinedNextLowerBound() const {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
+ *std::next(child_begin(), CombinedNextLowerBoundOffset)));
|
|
|
+ }
|
|
|
+ Expr *getCombinedNextUpperBound() const {
|
|
|
+ assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
|
|
|
+ "expected loop bound sharing directive");
|
|
|
+ return const_cast<Expr *>(reinterpret_cast<const Expr *>(
|
|
|
+ *std::next(child_begin(), CombinedNextUpperBoundOffset)));
|
|
|
+ }
|
|
|
const Stmt *getBody() const {
|
|
|
// This relies on the loop form is already checked by Sema.
|
|
|
Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
|