diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2018-08-13 14:05:43 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2018-08-13 14:05:43 +0000 |
commit | 0ce6360e0efdf12fbecc5a931a43449091e6f5f0 (patch) | |
tree | 087ec9e72ccfa67300ffe8f9f80f3b208220ba7c /clang/lib/Sema | |
parent | 8d4a6615e17fec9555e44f5ece87fc75900e25d2 (diff) | |
download | bcm5719-llvm-0ce6360e0efdf12fbecc5a931a43449091e6f5f0.tar.gz bcm5719-llvm-0ce6360e0efdf12fbecc5a931a43449091e6f5f0.zip |
[OPENMP] Fix emission of the loop doacross constructs.
The number of loops associated with the OpenMP loop constructs should
not be considered as the number loops to collapse.
llvm-svn: 339568
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 263 |
1 files changed, 179 insertions, 84 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index b455d4fb439..342496f9d8b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -73,6 +73,8 @@ public: }; using OperatorOffsetTy = llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; + using DoacrossDependMapTy = + llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; private: struct DSAInfo { @@ -97,8 +99,6 @@ private: llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; using CriticalsWithHintsTy = llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; - using DoacrossDependMapTy = - llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; struct ReductionData { using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; SourceRange ReductionRange; @@ -137,7 +137,7 @@ private: /// first argument (Expr *) contains optional argument of the /// 'ordered' clause, the second one is true if the regions has 'ordered' /// clause, false otherwise. - llvm::PointerIntPair<const Expr *, 1, bool> OrderedRegion; + llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; bool NowaitRegion = false; bool CancelRegion = false; unsigned AssociatedLoops = 1; @@ -398,23 +398,42 @@ public: } /// Marks current region as ordered (it has an 'ordered' clause). - void setOrderedRegion(bool IsOrdered, const Expr *Param) { + void setOrderedRegion(bool IsOrdered, const Expr *Param, + OMPOrderedClause *Clause) { assert(!isStackEmpty()); - Stack.back().first.back().OrderedRegion.setInt(IsOrdered); - Stack.back().first.back().OrderedRegion.setPointer(Param); + if (IsOrdered) + Stack.back().first.back().OrderedRegion.emplace(Param, Clause); + else + Stack.back().first.back().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(); + } + /// 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(); } /// 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.getInt(); + return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue(); } /// Returns optional parameter for the ordered region. - const Expr *getParentOrderedRegionParam() const { - if (isStackEmpty() || Stack.back().first.size() == 1) - return nullptr; - return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer(); + 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(); } /// Marks current region as nowait (it has a 'nowait' clause). void setNowaitRegion(bool IsNowait = true) { @@ -3745,6 +3764,13 @@ public: Expr *buildCounterInit() const; /// Build step of the counter be used for codegen. Expr *buildCounterStep() const; + /// Build loop data with counter value for depend clauses in ordered + /// directives. + Expr * + buildOrderedLoopData(Scope *S, + llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, + SourceLocation Loc, Expr *Inc = nullptr, + OverloadedOperatorKind OOK = OO_Amp); /// Return true if any expression is dependent. bool dependent() const; @@ -3909,7 +3935,12 @@ bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { SemaRef.Diag(S->getBeginLoc(), diag::ext_omp_loop_not_canonical_init) << S->getSourceRange(); - return setLCDeclAndLB(Var, nullptr, Var->getInit()); + return setLCDeclAndLB( + Var, + buildDeclRefExpr(SemaRef, Var, + Var->getType().getNonReferenceType(), + DS->getBeginLoc()), + Var->getInit()); } } } @@ -4271,7 +4302,8 @@ Expr *OpenMPIterationSpaceChecker::buildPreCond( /// Build reference expression to the counter be used for codegen. DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( - llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const { + llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, + DSAStackTy &DSA) const { auto *VD = dyn_cast<VarDecl>(LCDecl); if (!VD) { VD = SemaRef.isOpenMPCapturedDecl(LCDecl); @@ -4311,6 +4343,62 @@ Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } /// Build step of the counter be used for codegen. Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } +Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( + Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, + SourceLocation Loc, Expr *Inc, OverloadedOperatorKind OOK) { + Expr *Cnt = SemaRef.DefaultLvalueConversion(LCRef).get(); + if (!Cnt) + return nullptr; + if (Inc) { + assert((OOK == OO_Plus || OOK == OO_Minus) && + "Expected only + or - operations for depend clauses."); + BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; + Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); + if (!Cnt) + return nullptr; + } + ExprResult Diff; + QualType VarType = LCDecl->getType().getNonReferenceType(); + if (VarType->isIntegerType() || VarType->isPointerType() || + SemaRef.getLangOpts().CPlusPlus) { + // Upper - Lower + Expr *Upper = + TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get(); + Expr *Lower = + TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt; + if (!Upper || !Lower) + return nullptr; + + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); + + if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { + // BuildBinOp already emitted error, this one is to point user to upper + // and lower bound, and to tell what is passed to 'operator-'. + SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) + << Upper->getSourceRange() << Lower->getSourceRange(); + return nullptr; + } + } + + if (!Diff.isUsable()) + return nullptr; + + // Parentheses (for dumping/debugging purposes only). + Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); + if (!Diff.isUsable()) + return nullptr; + + ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); + if (!NewStep.isUsable()) + return nullptr; + // (Upper - Lower) / Step + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); + if (!Diff.isUsable()) + return nullptr; + + return Diff.get(); +} + /// Iteration space of a single for loop. struct LoopIterationSpace final { /// Condition of the loop. @@ -4370,7 +4458,8 @@ void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { static bool checkOpenMPIterationSpace( OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, - Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, + unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, + Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { @@ -4380,9 +4469,9 @@ static bool checkOpenMPIterationSpace( if (!For) { SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) - << getOpenMPDirectiveName(DKind) << NestedLoopCount + << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; - if (NestedLoopCount > 1) { + if (TotalNestedLoopCount > 1) { if (CollapseLoopCountExpr && OrderedLoopCountExpr) SemaRef.Diag(DSA.getConstructLoc(), diag::note_omp_collapse_ordered_expr) @@ -4515,6 +4604,36 @@ static bool checkOpenMPIterationSpace( ResultIterSpace.PrivateCounterVar == nullptr || ResultIterSpace.CounterInit == nullptr || ResultIterSpace.CounterStep == nullptr); + if (!HasErrors && DSA.isOrderedRegion()) { + if (DSA.getOrderedRegionParam().second->getNumForLoops()) { + DSA.getOrderedRegionParam().second->setLoopNumIterations( + CurrentNestedLoopCount, ResultIterSpace.NumIterations); + DSA.getOrderedRegionParam().second->setLoopCounter( + CurrentNestedLoopCount, ResultIterSpace.CounterVar); + } + for (auto &Pair : DSA.getDoacrossDependClauses()) { + if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { + // Erroneous case - clause has some problems. + continue; + } + if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && + Pair.second.size() <= CurrentNestedLoopCount) { + // Erroneous case - clause has some problems. + Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); + continue; + } + Expr *CntValue; + if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) + CntValue = ISC.buildOrderedLoopData(DSA.getCurScope(), Captures, + Pair.first->getDependencyLoc()); + else + CntValue = ISC.buildOrderedLoopData( + DSA.getCurScope(), Captures, Pair.first->getDependencyLoc(), + Pair.second[CurrentNestedLoopCount].first, + Pair.second[CurrentNestedLoopCount].second); + Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); + } + } return HasErrors; } @@ -4700,6 +4819,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) NestedLoopCount = Result.getLimitedValue(); } + unsigned OrderedLoopCount = 1; if (OrderedLoopCountExpr) { // Found 'ordered' clause - calculate collapse number. llvm::APSInt Result; @@ -4712,20 +4832,21 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, diag::note_collapse_loop_count) << CollapseLoopCountExpr->getSourceRange(); } - NestedLoopCount = Result.getLimitedValue(); + OrderedLoopCount = Result.getLimitedValue(); } } // This is helper routine for loop directives (e.g., 'for', 'simd', // 'for simd', etc.). llvm::MapVector<const Expr *, DeclRefExpr *> Captures; SmallVector<LoopIterationSpace, 4> IterSpaces; - IterSpaces.resize(NestedLoopCount); + IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount)); Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { - if (checkOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, - NestedLoopCount, CollapseLoopCountExpr, - OrderedLoopCountExpr, VarsWithImplicitDSA, - IterSpaces[Cnt], Captures)) + if (checkOpenMPIterationSpace( + DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, + std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, + OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], + Captures)) return 0; // Move on to the next nested for loop, or to the loop body. // OpenMP [2.8.1, simd construct, Restrictions] @@ -4734,6 +4855,27 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // any two loops. CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); } + for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { + if (checkOpenMPIterationSpace( + DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, + std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, + OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], + Captures)) + return 0; + if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { + // Handle initialization of captured loop iterator variables. + auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); + if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { + Captures[DRE] = DRE; + } + } + // Move on to the next nested for loop, or to the loop body. + // OpenMP [2.8.1, simd construct, Restrictions] + // All loops associated with the construct must be perfectly nested; that + // is, there must be no intervening code nor any OpenMP directive between + // any two loops. + CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); + } Built.clear(/* size */ NestedLoopCount); @@ -5113,7 +5255,6 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Built.Inits.resize(NestedLoopCount); Built.Updates.resize(NestedLoopCount); Built.Finals.resize(NestedLoopCount); - SmallVector<Expr *, 4> LoopMultipliers; { ExprResult Div; // Go from inner nested loop to outer. @@ -5183,7 +5324,6 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, HasErrors = true; break; } - LoopMultipliers.push_back(Div.get()); } if (!Update.isUsable() || !Final.isUsable()) { HasErrors = true; @@ -5231,55 +5371,6 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Built.DistCombinedFields.NLB = CombNextLB.get(); Built.DistCombinedFields.NUB = CombNextUB.get(); - Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get(); - // Fill data for doacross depend clauses. - for (const auto &Pair : DSA.getDoacrossDependClauses()) { - if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) { - Pair.first->setCounterValue(CounterVal); - } else { - if (NestedLoopCount != Pair.second.size() || - NestedLoopCount != LoopMultipliers.size() + 1) { - // Erroneous case - clause has some problems. - Pair.first->setCounterValue(CounterVal); - continue; - } - assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink); - auto I = Pair.second.rbegin(); - auto IS = IterSpaces.rbegin(); - auto ILM = LoopMultipliers.rbegin(); - Expr *UpCounterVal = CounterVal; - Expr *Multiplier = nullptr; - for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { - if (I->first) { - assert(IS->CounterStep); - Expr *NormalizedOffset = - SemaRef - .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div, - I->first, IS->CounterStep) - .get(); - if (Multiplier) { - NormalizedOffset = - SemaRef - .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul, - NormalizedOffset, Multiplier) - .get(); - } - assert(I->second == OO_Plus || I->second == OO_Minus); - BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub; - UpCounterVal = SemaRef - .BuildBinOp(CurScope, I->first->getExprLoc(), BOK, - UpCounterVal, NormalizedOffset) - .get(); - } - Multiplier = *ILM; - ++I; - ++IS; - ++ILM; - } - Pair.first->setCounterValue(UpCounterVal); - } - } - return NestedLoopCount; } @@ -5847,12 +5938,12 @@ StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); ErrorFound = true; - } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { + } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { Diag(DependFound->getBeginLoc(), diag::err_omp_ordered_directive_without_param); ErrorFound = true; } else if (TC || Clauses.empty()) { - if (const Expr *Param = DSAStack->getParentOrderedRegionParam()) { + if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) << (TC != nullptr); @@ -8628,9 +8719,11 @@ OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, } else { NumForLoops = nullptr; } - DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); - return new (Context) - OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); + auto *Clause = OMPOrderedClause::Create( + Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, + StartLoc, LParenLoc, EndLoc); + DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); + return Clause; } OMPClause *Sema::ActOnOpenMPSimpleClause( @@ -11486,8 +11579,9 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, DSAStackTy::OperatorOffsetTy OpsOffs; llvm::APSInt DepCounter(/*BitWidth=*/32); llvm::APSInt TotalDepCount(/*BitWidth=*/32); - if (DepKind == OMPC_DEPEND_sink) { - if (const Expr *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { + if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { + if (const Expr *OrderedCountExpr = + DSAStack->getParentOrderedRegionParam().first) { TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); TotalDepCount.setIsUnsigned(/*Val=*/true); } @@ -11503,7 +11597,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation ELoc = RefExpr->getExprLoc(); Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); if (DepKind == OMPC_DEPEND_sink) { - if (DSAStack->getParentOrderedRegionParam() && + if (DSAStack->getParentOrderedRegionParam().first && DepCounter >= TotalDepCount) { Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); continue; @@ -11569,7 +11663,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, continue; } if (!CurContext->isDependentContext() && - DSAStack->getParentOrderedRegionParam() && + DSAStack->getParentOrderedRegionParam().first && DepCounter != DSAStack->isParentLoopControlVariable(D).first) { const ValueDecl *VD = DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); @@ -11607,7 +11701,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && TotalDepCount > VarList.size() && - DSAStack->getParentOrderedRegionParam() && + DSAStack->getParentOrderedRegionParam().first && DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); @@ -11617,7 +11711,8 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, return nullptr; auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, - DepKind, DepLoc, ColonLoc, Vars); + DepKind, DepLoc, ColonLoc, Vars, + TotalDepCount.getZExtValue()); if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && DSAStack->isParentOrderedRegion()) DSAStack->addDoacrossDependClause(C, OpsOffs); |