r256330 - [OPENMP 4.5] Parsing/sema for 'depend(sink:vec)' clause in 'ordered' directive.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 23 02:27:46 PST 2015
Author: abataev
Date: Wed Dec 23 04:27:45 2015
New Revision: 256330
URL: http://llvm.org/viewvc/llvm-project?rev=256330&view=rev
Log:
[OPENMP 4.5] Parsing/sema for 'depend(sink:vec)' clause in 'ordered' directive.
OpenMP 4.5 adds 'depend(sink:vec)' in 'ordered' directive for doacross loop synchronization. Patch adds parsing and semantic analysis for this clause.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Basic/OpenMPKinds.def
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
cfe/trunk/lib/Sema/SemaOpenMP.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/test/OpenMP/ordered_ast_print.cpp
cfe/trunk/test/OpenMP/ordered_messages.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=256330&r1=256329&r2=256330&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Dec 23 04:27:45 2015
@@ -7951,6 +7951,16 @@ def err_omp_firstprivate_distribute_in_t
"reduction variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">;
def err_omp_depend_clause_thread_simd : Error<
"'depend' clauses cannot be mixed with '%0' clause">;
+def err_omp_depend_sink_wrong_expr : Error<
+ "expected expression form x[+-d], where x is the loop iteration variable and d is a constant non-negative integer">;
+def err_omp_depend_sink_expected_loop_iteration : Error<
+ "expected %0 loop iteration variable">;
+def err_omp_depend_sink_unexpected_expr : Error<
+ "unexpected expression: number of expressions is larger than the number of associated loops">;
+def err_omp_depend_sink_expected_plus_minus : Error<
+ "expected '+' or '-' operation">;
+def err_omp_depend_sink_source_not_allowed : Error<
+ "'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=256330&r1=256329&r2=256330&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Wed Dec 23 04:27:45 2015
@@ -255,6 +255,7 @@ OPENMP_DEPEND_KIND(in)
OPENMP_DEPEND_KIND(out)
OPENMP_DEPEND_KIND(inout)
OPENMP_DEPEND_KIND(source)
+OPENMP_DEPEND_KIND(sink)
// Modifiers for 'linear' clause.
OPENMP_LINEAR_KIND(val)
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=256330&r1=256329&r2=256330&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Dec 23 04:27:45 2015
@@ -7760,8 +7760,10 @@ private:
/// \brief Initialization of data-sharing attributes stack.
void InitDataSharingAttributesStack();
void DestroyDataSharingAttributesStack();
- ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op,
- OpenMPClauseKind CKind);
+ ExprResult
+ VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind,
+ bool StrictlyPositive = true);
+
public:
/// \brief Return true if the provided declaration \a VD should be captured by
/// reference in the provided scope \a RSI. This will take into account the
Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=256330&r1=256329&r2=256330&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Wed Dec 23 04:27:45 2015
@@ -2556,6 +2556,7 @@ void CGOpenMPRuntime::emitTaskCall(
DepKind = DepInOut;
break;
case OMPC_DEPEND_source:
+ case OMPC_DEPEND_sink:
case OMPC_DEPEND_unknown:
llvm_unreachable("Unknown task dependence type");
}
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=256330&r1=256329&r2=256330&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Wed Dec 23 04:27:45 2015
@@ -89,7 +89,7 @@ private:
};
typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
- typedef llvm::DenseSet<VarDecl *> LoopControlVariablesSetTy;
+ typedef llvm::DenseMap<VarDecl *, unsigned> LoopControlVariablesMapTy;
typedef llvm::SmallDenseMap<VarDecl *, MapInfo, 64> MappedDeclsTy;
typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
CriticalsWithHintsTy;
@@ -98,7 +98,7 @@ private:
DeclSAMapTy SharingMap;
AlignedMapTy AlignedMap;
MappedDeclsTy MappedDecls;
- LoopControlVariablesSetTy LCVSet;
+ LoopControlVariablesMapTy LCVMap;
DefaultDataSharingAttributes DefaultAttr;
SourceLocation DefaultAttrLoc;
OpenMPDirectiveKind Directive;
@@ -111,19 +111,19 @@ private:
llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
bool NowaitRegion;
bool CancelRegion;
- unsigned CollapseNumber;
+ unsigned AssociatedLoops;
SourceLocation InnerTeamsRegionLoc;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope, SourceLocation Loc)
- : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
+ : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified),
Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
ConstructLoc(Loc), OrderedRegion(), NowaitRegion(false),
- CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {}
+ CancelRegion(false), AssociatedLoops(1), InnerTeamsRegionLoc() {}
SharingMapTy()
- : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified),
+ : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified),
Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
ConstructLoc(), OrderedRegion(), NowaitRegion(false),
- CancelRegion(false), CollapseNumber(1), InnerTeamsRegionLoc() {}
+ CancelRegion(false), AssociatedLoops(1), InnerTeamsRegionLoc() {}
};
typedef SmallVector<SharingMapTy, 64> StackTy;
@@ -185,7 +185,17 @@ public:
void addLoopControlVariable(VarDecl *D);
/// \brief Check if the specified variable is a loop control variable for
/// current region.
- bool isLoopControlVariable(VarDecl *D);
+ /// \return The index of the loop control variable in the list of associated
+ /// for-loops (from outer to inner).
+ unsigned isLoopControlVariable(VarDecl *D);
+ /// \brief Check if the specified variable is a loop control variable for
+ /// parent region.
+ /// \return The index of the loop control variable in the list of associated
+ /// for-loops (from outer to inner).
+ unsigned isParentLoopControlVariable(VarDecl *D);
+ /// \brief Get the loop control variable for the I-th loop (or nullptr) in
+ /// parent directive.
+ VarDecl *getParentLoopControlVariable(unsigned I);
/// \brief Adds explicit data sharing attribute to the specified declaration.
void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
@@ -303,11 +313,9 @@ public:
}
/// \brief Set collapse value for the region.
- void setCollapseNumber(unsigned Val) { Stack.back().CollapseNumber = Val; }
+ void setAssociatedLoops(unsigned Val) { Stack.back().AssociatedLoops = Val; }
/// \brief Return collapse value for region.
- unsigned getCollapseNumber() const {
- return Stack.back().CollapseNumber;
- }
+ unsigned getAssociatedLoops() const { return Stack.back().AssociatedLoops; }
/// \brief Marks current target region as one with closely nested teams
/// region.
@@ -486,13 +494,32 @@ DeclRefExpr *DSAStackTy::addUniqueAligne
void DSAStackTy::addLoopControlVariable(VarDecl *D) {
assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
D = D->getCanonicalDecl();
- Stack.back().LCVSet.insert(D);
+ Stack.back().LCVMap.insert(std::make_pair(D, Stack.back().LCVMap.size() + 1));
}
-bool DSAStackTy::isLoopControlVariable(VarDecl *D) {
+unsigned DSAStackTy::isLoopControlVariable(VarDecl *D) {
assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
D = D->getCanonicalDecl();
- return Stack.back().LCVSet.count(D) > 0;
+ return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D] : 0;
+}
+
+unsigned DSAStackTy::isParentLoopControlVariable(VarDecl *D) {
+ assert(Stack.size() > 2 && "Data-sharing attributes stack is empty");
+ D = D->getCanonicalDecl();
+ return Stack[Stack.size() - 2].LCVMap.count(D) > 0
+ ? Stack[Stack.size() - 2].LCVMap[D]
+ : 0;
+}
+
+VarDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) {
+ assert(Stack.size() > 2 && "Data-sharing attributes stack is empty");
+ if (Stack[Stack.size() - 2].LCVMap.size() < I)
+ return nullptr;
+ for (auto &Pair : Stack[Stack.size() - 2].LCVMap) {
+ if (Pair.second == I)
+ return Pair.first;
+ }
+ return nullptr;
}
void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
@@ -3368,14 +3395,13 @@ struct LoopIterationSpace {
void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
assert(getLangOpts().OpenMP && "OpenMP is not active.");
assert(Init && "Expected loop in canonical form.");
- unsigned CollapseIteration = DSAStack->getCollapseNumber();
- if (CollapseIteration > 0 &&
+ unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
+ if (AssociatedLoops > 0 &&
isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
OpenMPIterationSpaceChecker ISC(*this, ForLoc);
- if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) {
+ if (!ISC.CheckInit(Init, /*EmitDiags=*/false))
DSAStack->addLoopControlVariable(ISC.GetLoopVar());
- }
- DSAStack->setCollapseNumber(CollapseIteration - 1);
+ DSAStack->setAssociatedLoops(AssociatedLoops - 1);
}
}
@@ -4576,6 +4602,7 @@ StmtResult Sema::ActOnOpenMPOrderedDirec
SourceLocation EndLoc) {
OMPClause *DependFound = nullptr;
OMPClause *DependSourceClause = nullptr;
+ OMPClause *DependSinkClause = nullptr;
bool ErrorFound = false;
OMPThreadsClause *TC = nullptr;
OMPSIMDClause *SC = nullptr;
@@ -4590,6 +4617,18 @@ StmtResult Sema::ActOnOpenMPOrderedDirec
ErrorFound = true;
} else
DependSourceClause = C;
+ if (DependSinkClause) {
+ Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
+ << 0;
+ ErrorFound = true;
+ }
+ } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
+ if (DependSourceClause) {
+ Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
+ << 1;
+ ErrorFound = true;
+ }
+ DependSinkClause = C;
}
} else if (C->getClauseKind() == OMPC_threads)
TC = cast<OMPThreadsClause>(C);
@@ -5753,7 +5792,8 @@ OMPClause *Sema::ActOnOpenMPNumThreadsCl
}
ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
- OpenMPClauseKind CKind) {
+ OpenMPClauseKind CKind,
+ bool StrictlyPositive) {
if (!E)
return ExprError();
if (E->isValueDependent() || E->isTypeDependent() ||
@@ -5763,9 +5803,11 @@ ExprResult Sema::VerifyPositiveIntegerCo
ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
if (ICE.isInvalid())
return ExprError();
- if (!Result.isStrictlyPositive()) {
+ if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
+ (!StrictlyPositive && !Result.isNonNegative())) {
Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
- << getOpenMPClauseName(CKind) << 1 << E->getSourceRange();
+ << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
+ << E->getSourceRange();
return ExprError();
}
if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
@@ -5773,10 +5815,10 @@ ExprResult Sema::VerifyPositiveIntegerCo
<< E->getSourceRange();
return ExprError();
}
- if (CKind == OMPC_collapse)
- DSAStack->setCollapseNumber(Result.getExtValue());
+ if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
+ DSAStack->setAssociatedLoops(Result.getExtValue());
else if (CKind == OMPC_ordered)
- DSAStack->setCollapseNumber(Result.getExtValue());
+ DSAStack->setAssociatedLoops(Result.getExtValue());
return ICE;
}
@@ -7990,29 +8032,32 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc) {
if (DSAStack->getCurrentDirective() == OMPD_ordered &&
- DepKind != OMPC_DEPEND_source) {
+ DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
std::string Values = "'";
Values += getOpenMPSimpleClauseTypeName(OMPC_depend, OMPC_DEPEND_source);
+ Values += "' or '";
+ Values += getOpenMPSimpleClauseTypeName(OMPC_depend, OMPC_DEPEND_sink);
Values += "'";
Diag(DepLoc, diag::err_omp_unexpected_clause_value)
<< Values << getOpenMPClauseName(OMPC_depend);
return nullptr;
}
if (DSAStack->getCurrentDirective() != OMPD_ordered &&
- (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source)) {
+ (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
+ DepKind == OMPC_DEPEND_sink)) {
std::string Values;
std::string Sep(", ");
for (unsigned i = 0; i < OMPC_DEPEND_unknown; ++i) {
- if (i == OMPC_DEPEND_source)
+ if (i == OMPC_DEPEND_source || i == OMPC_DEPEND_sink)
continue;
Values += "'";
Values += getOpenMPSimpleClauseTypeName(OMPC_depend, i);
Values += "'";
switch (i) {
- case OMPC_DEPEND_unknown - 3:
+ case OMPC_DEPEND_unknown - 4:
Values += " or ";
break;
- case OMPC_DEPEND_unknown - 2:
+ case OMPC_DEPEND_unknown - 3:
break;
default:
Values += Sep;
@@ -8024,38 +8069,128 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe
return nullptr;
}
SmallVector<Expr *, 8> Vars;
- for (auto &RefExpr : VarList) {
- assert(RefExpr && "NULL expr in OpenMP shared clause.");
- if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
- // It will be analyzed later.
- Vars.push_back(RefExpr);
- continue;
- }
+ llvm::APSInt DepCounter(/*BitWidth=*/32);
+ llvm::APSInt TotalDepCount(/*BitWidth=*/32);
+ if (DepKind == OMPC_DEPEND_sink) {
+ if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) {
+ TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
+ TotalDepCount.setIsUnsigned(/*Val=*/true);
+ }
+ }
+ if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
+ DSAStack->getParentOrderedRegionParam()) {
+ for (auto &RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP shared clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr) ||
+ (DepKind == OMPC_DEPEND_sink && CurContext->isDependentContext())) {
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ continue;
+ }
- SourceLocation ELoc = RefExpr->getExprLoc();
- // OpenMP [2.11.1.1, Restrictions, p.3]
- // A variable that is part of another variable (such as a field of a
- // structure) but is not an array element or an array section cannot appear
- // in a depend clause.
- auto *SimpleExpr = RefExpr->IgnoreParenCasts();
- auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
- auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
- auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
- if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
- (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) ||
- (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
- !ASE->getBase()->getType()->isArrayType())) {
- Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
- << RefExpr->getSourceRange();
- continue;
+ SourceLocation ELoc = RefExpr->getExprLoc();
+ auto *SimpleExpr = RefExpr->IgnoreParenCasts();
+ if (DepKind == OMPC_DEPEND_sink) {
+ if (DepCounter >= TotalDepCount) {
+ Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
+ continue;
+ }
+ ++DepCounter;
+ // OpenMP [2.13.9, Summary]
+ // depend(dependence-type : vec), where dependence-type is:
+ // 'sink' and where vec is the iteration vector, which has the form:
+ // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
+ // where n is the value specified by the ordered clause in the loop
+ // directive, xi denotes the loop iteration variable of the i-th nested
+ // loop associated with the loop directive, and di is a constant
+ // non-negative integer.
+ SimpleExpr = SimpleExpr->IgnoreImplicit();
+ auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
+ if (!DE) {
+ OverloadedOperatorKind OOK = OO_None;
+ SourceLocation OOLoc;
+ Expr *LHS, *RHS;
+ if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
+ OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
+ OOLoc = BO->getOperatorLoc();
+ LHS = BO->getLHS()->IgnoreParenImpCasts();
+ RHS = BO->getRHS()->IgnoreParenImpCasts();
+ } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
+ OOK = OCE->getOperator();
+ OOLoc = OCE->getOperatorLoc();
+ LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
+ RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
+ } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
+ OOK = MCE->getMethodDecl()
+ ->getNameInfo()
+ .getName()
+ .getCXXOverloadedOperator();
+ OOLoc = MCE->getCallee()->getExprLoc();
+ LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
+ RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
+ } else {
+ Diag(ELoc, diag::err_omp_depend_sink_wrong_expr);
+ continue;
+ }
+ DE = dyn_cast<DeclRefExpr>(LHS);
+ if (!DE) {
+ Diag(LHS->getExprLoc(),
+ diag::err_omp_depend_sink_expected_loop_iteration)
+ << DSAStack->getParentLoopControlVariable(
+ DepCounter.getZExtValue());
+ continue;
+ }
+ if (OOK != OO_Plus && OOK != OO_Minus) {
+ Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
+ continue;
+ }
+ ExprResult Res = VerifyPositiveIntegerConstantInClause(
+ RHS, OMPC_depend, /*StrictlyPositive=*/false);
+ if (Res.isInvalid())
+ continue;
+ }
+ auto *VD = dyn_cast<VarDecl>(DE->getDecl());
+ if (!CurContext->isDependentContext() &&
+ DSAStack->getParentOrderedRegionParam() &&
+ (!VD || DepCounter != DSAStack->isParentLoopControlVariable(VD))) {
+ Diag(DE->getExprLoc(),
+ diag::err_omp_depend_sink_expected_loop_iteration)
+ << DSAStack->getParentLoopControlVariable(
+ DepCounter.getZExtValue());
+ continue;
+ }
+ } else {
+ // OpenMP [2.11.1.1, Restrictions, p.3]
+ // A variable that is part of another variable (such as a field of a
+ // structure) but is not an array element or an array section cannot
+ // appear in a depend clause.
+ auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr);
+ auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
+ auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
+ if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
+ (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) ||
+ (ASE && !ASE->getBase()->getType()->isAnyPointerType() &&
+ !ASE->getBase()->getType()->isArrayType())) {
+ Diag(ELoc, diag::err_omp_expected_var_name_or_array_item)
+ << RefExpr->getSourceRange();
+ continue;
+ }
+ }
+
+ Vars.push_back(RefExpr->IgnoreParenImpCasts());
}
- Vars.push_back(RefExpr->IgnoreParenImpCasts());
+ if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
+ TotalDepCount > VarList.size() &&
+ DSAStack->getParentOrderedRegionParam()) {
+ Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
+ << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
+ }
+ if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
+ Vars.empty())
+ return nullptr;
}
- if (DepKind != OMPC_DEPEND_source && Vars.empty())
- return nullptr;
-
return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind,
DepLoc, ColonLoc, Vars);
}
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=256330&r1=256329&r2=256330&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Wed Dec 23 04:27:45 2015
@@ -6275,6 +6275,11 @@ TreeTransform<Derived>::TransformForStmt
if (Init.isInvalid())
return StmtError();
+ // In OpenMP loop region loop control variable must be captured and be
+ // private. Perform analysis of first part (if any).
+ if (getSema().getLangOpts().OpenMP && Init.isUsable())
+ getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get());
+
// Transform the condition
ExprResult Cond;
VarDecl *ConditionVar = nullptr;
Modified: cfe/trunk/test/OpenMP/ordered_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_ast_print.cpp?rev=256330&r1=256329&r2=256330&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/ordered_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/ordered_ast_print.cpp Wed Dec 23 04:27:45 2015
@@ -8,7 +8,7 @@
void foo() {}
-template <class T>
+template <class T, int N>
T tmain (T argc) {
T b = argc, c, d, e, f, g;
static T a;
@@ -45,6 +45,7 @@ T tmain (T argc) {
#pragma omp parallel for ordered(1)
for (int i =0 ; i < argc; ++i) {
#pragma omp ordered depend(source)
+ #pragma omp ordered depend(sink:i+N)
a = 2;
}
return (0);
@@ -84,6 +85,7 @@ T tmain (T argc) {
// CHECK-NEXT: #pragma omp parallel for ordered(1)
// CHECK-NEXT: for (int i = 0; i < argc; ++i) {
// CHECK-NEXT: #pragma omp ordered depend(source)
+// CHECK-NEXT: #pragma omp ordered depend(sink : i + 3)
// CHECK-NEXT: a = 2;
// CHECK-NEXT: }
// CHECK: static T a;
@@ -120,6 +122,7 @@ T tmain (T argc) {
// CHECK-NEXT: #pragma omp parallel for ordered(1)
// CHECK-NEXT: for (int i = 0; i < argc; ++i) {
// CHECK-NEXT: #pragma omp ordered depend(source)
+// CHECK-NEXT: #pragma omp ordered depend(sink : i + N)
// CHECK-NEXT: a = 2;
// CHECK-NEXT: }
@@ -161,6 +164,7 @@ int main (int argc, char **argv) {
#pragma omp parallel for ordered(1)
for (int i =0 ; i < argc; ++i) {
#pragma omp ordered depend(source)
+ #pragma omp ordered depend(sink: i - 5)
a = 2;
}
// CHECK-NEXT: #pragma omp for ordered
@@ -196,9 +200,10 @@ int main (int argc, char **argv) {
// CHECK-NEXT: #pragma omp parallel for ordered(1)
// CHECK-NEXT: for (int i = 0; i < argc; ++i) {
// CHECK-NEXT: #pragma omp ordered depend(source)
+// CHECK-NEXT: #pragma omp ordered depend(sink : i - 5)
// CHECK-NEXT: a = 2;
// CHECK-NEXT: }
- return tmain(argc);
+ return tmain<int, 3>(argc);
}
#endif
Modified: cfe/trunk/test/OpenMP/ordered_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_messages.cpp?rev=256330&r1=256329&r2=256330&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/ordered_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/ordered_messages.cpp Wed Dec 23 04:27:45 2015
@@ -4,6 +4,7 @@ int foo();
template <class T>
T foo() {
+ T k;
#pragma omp for ordered
for (int i = 0; i < 10; ++i) {
L1:
@@ -95,28 +96,44 @@ T foo() {
#pragma omp parallel for ordered
for (int i = 0; i < 10; ++i) {
#pragma omp ordered depend(source) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}}
+ #pragma omp ordered depend(sink : i) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}}
}
-#pragma omp parallel for ordered(1) // expected-note 3 {{'ordered' clause with specified parameter}}
+#pragma omp parallel for ordered(2) // expected-note 5 {{'ordered' clause with specified parameter}}
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
#pragma omp ordered depend // expected-error {{expected '(' after 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}}
-#pragma omp ordered depend( // expected-error {{expected ')'}} expected-error {{expected 'source' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-note {{to match this '('}}
+#pragma omp ordered depend( // expected-error {{expected ')'}} expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-note {{to match this '('}}
#pragma omp ordered depend(source // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp ordered depend(sink // expected-error {{expected expression}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-error {{expected ')'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-note {{to match this '('}}
+#pragma omp ordered depend(sink : // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}}
+#pragma omp ordered depend(sink : i // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'j' loop iteration variable}}
+#pragma omp ordered depend(sink : i) // expected-error {{expected 'j' loop iteration variable}}
#pragma omp ordered depend(source)
if (i == j)
#pragma omp ordered depend(source) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}}
;
+ if (i == j)
+#pragma omp ordered depend(sink : i, j) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}}
+ ;
#pragma omp ordered depend(source) threads // expected-error {{'depend' clauses cannot be mixed with 'threads' clause}}
#pragma omp ordered simd depend(source) // expected-error {{'depend' clauses cannot be mixed with 'simd' clause}}
#pragma omp ordered depend(source) depend(source) // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'depend' clause with 'source' dependence}}
-#pragma omp ordered depend(in : i) // expected-error {{expected 'source' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}}
+#pragma omp ordered depend(in : i) // expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}}
+#pragma omp ordered depend(sink : i, j)
+#pragma omp ordered depend(sink : j, i) // expected-error {{expected 'i' loop iteration variable}} expected-error {{expected 'j' loop iteration variable}}
+#pragma omp ordered depend(sink : i, j, k) // expected-error {{unexpected expression: number of expressions is larger than the number of associated loops}}
+#pragma omp ordered depend(sink : i+foo(), j/4) // expected-error {{expression is not an integral constant expression}} expected-error {{expected '+' or '-' operation}}
+#pragma omp ordered depend(sink : i*0, j-4)// expected-error {{expected '+' or '-' operation}}
+#pragma omp ordered depend(sink : i-0, j+sizeof(T)) depend(sink : i-0, j+sizeof(T))
+#pragma omp ordered depend(sink : i-0, j+sizeof(T)) depend(source) // expected-error {{'depend(source)' clause cannot be mixed with 'depend(sink:vec)' clauses}}
+#pragma omp ordered depend(source) depend(sink : i-0, j+sizeof(T)) // expected-error {{'depend(sink:vec)' clauses cannot be mixed with 'depend(source)' clause}}
}
}
-
return T();
}
int foo() {
+int k;
#pragma omp for ordered
for (int i = 0; i < 10; ++i) {
L1:
@@ -208,23 +225,39 @@ int foo() {
#pragma omp parallel for ordered
for (int i = 0; i < 10; ++i) {
#pragma omp ordered depend(source) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}}
+ #pragma omp ordered depend(sink : i) // expected-error {{'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter}}
}
-#pragma omp parallel for ordered(1) // expected-note 3 {{'ordered' clause with specified parameter}}
+#pragma omp parallel for ordered(2) // expected-note 5 {{'ordered' clause with specified parameter}}
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
#pragma omp ordered depend // expected-error {{expected '(' after 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}}
-#pragma omp ordered depend( // expected-error {{expected ')'}} expected-error {{expected 'source' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-note {{to match this '('}}
+#pragma omp ordered depend( // expected-error {{expected ')'}} expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-note {{to match this '('}}
#pragma omp ordered depend(source // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp ordered depend(sink // expected-error {{expected expression}} expected-warning {{missing ':' or ')' after dependency type - ignoring}} expected-error {{expected ')'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}} expected-note {{to match this '('}}
+#pragma omp ordered depend(sink : // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected expression}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}}
+#pragma omp ordered depend(sink : i // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'j' loop iteration variable}}
+#pragma omp ordered depend(sink : i) // expected-error {{expected 'j' loop iteration variable}}
#pragma omp ordered depend(source)
if (i == j)
#pragma omp ordered depend(source) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}}
;
+ if (i == j)
+#pragma omp ordered depend(sink : i, j) // expected-error {{'#pragma omp ordered' with 'depend' clause cannot be an immediate substatement}}
+ ;
#pragma omp ordered depend(source) threads // expected-error {{'depend' clauses cannot be mixed with 'threads' clause}}
#pragma omp ordered simd depend(source) // expected-error {{'depend' clauses cannot be mixed with 'simd' clause}}
#pragma omp ordered depend(source) depend(source) // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'depend' clause with 'source' dependence}}
-#pragma omp ordered depend(in : i) // expected-error {{expected 'source' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}}
+#pragma omp ordered depend(in : i) // expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}}
+#pragma omp ordered depend(sink : i, j)
+#pragma omp ordered depend(sink : j, i) // expected-error {{expected 'i' loop iteration variable}} expected-error {{expected 'j' loop iteration variable}}
+#pragma omp ordered depend(sink : i, j, k) // expected-error {{unexpected expression: number of expressions is larger than the number of associated loops}}
+#pragma omp ordered depend(sink : i+foo(), j/4) // expected-error {{expression is not an integral constant expression}} expected-error {{expected '+' or '-' operation}}
+#pragma omp ordered depend(sink : i*0, j-4)// expected-error {{expected '+' or '-' operation}}
+#pragma omp ordered depend(sink : i-0, j+sizeof(int)) depend(sink : i-0, j+sizeof(int))
+#pragma omp ordered depend(sink : i-0, j+sizeof(int)) depend(source) // expected-error {{'depend(source)' clause cannot be mixed with 'depend(sink:vec)' clauses}}
+#pragma omp ordered depend(source) depend(sink : i-0, j+sizeof(int)) // expected-error {{'depend(sink:vec)' clauses cannot be mixed with 'depend(source)' clause}}
}
}
- return foo<int>();
+ return foo<int>(); // expected-note {{in instantiation of function template specialization 'foo<int>' requested here}}
}
More information about the cfe-commits
mailing list