Index: include/clang/AST/StmtOpenMP.h =================================================================== --- include/clang/AST/StmtOpenMP.h +++ include/clang/AST/StmtOpenMP.h @@ -324,6 +324,11 @@ /// allocated: loop counters, their updates and final values. /// PrevLowerBound and PrevUpperBound are used to communicate blocking /// information in composite constructs which require loop blocking + /// DistInc is used to generate the increment expression for the distribute + /// loop when combined with a further nested loop + /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the + /// for loop when combined with a previous distribute loop in the same pragma + /// (e.g. 'distribute parallel for') /// enum { AssociatedStmtOffset = 0, @@ -339,7 +344,7 @@ // specify the offset to the end (and start of the following counters/ // updates/finals arrays). DefaultEnd = 9, - // The following 7 exprs are used by worksharing loops only. + // The following 12 exprs are used by worksharing and distribute loops only. IsLastIterVariableOffset = 9, LowerBoundVariableOffset = 10, UpperBoundVariableOffset = 11, @@ -350,9 +355,11 @@ NumIterationsOffset = 16, PrevLowerBoundVariableOffset = 17, PrevUpperBoundVariableOffset = 18, + DistIncOffset = 19, + PrevEnsureUpperBoundOffset = 20, // Offset to the end (and start of the following counters/updates/finals // arrays) for worksharing loop directives. - WorksharingEnd = 19, + WorksharingEnd = 21, }; /// \brief Get the counters storage. @@ -521,6 +528,20 @@ "expected worksharing loop directive"); *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB; } + void setDistInc(Expr *DistInc) { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + *std::next(child_begin(), DistIncOffset) = DistInc; + } + void setPrevEnsureUpperBound(Expr *PrevEUB) { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + *std::next(child_begin(), PrevEnsureUpperBoundOffset) = PrevEUB; + } void setCounters(ArrayRef A); void setPrivateCounters(ArrayRef A); void setInits(ArrayRef A); @@ -555,7 +576,7 @@ Expr *UB; /// \brief Stride - local variable passed to runtime. Expr *ST; - /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations). + /// \brief EnsureUpperBound -- expression UB = min(UB, NumIterations). Expr *EUB; /// \brief Update of LowerBound for statically sheduled 'omp for' loops. Expr *NLB; @@ -567,6 +588,16 @@ /// \brief PreviousUpperBound - local variable passed to runtime in the /// enclosing schedule or null if that does not apply. Expr *PrevUB; + /// \brief DistInc - increment expression for distribute loop when found + /// combined with a further loop level (e.g. in 'distribute parallel for') + /// expression IV = IV + ST + Expr *DistInc; + /// \brief PrevEUB - expression similar to EUB but to be used when loop + /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for' + /// when ensuring that the UB is either the calculated UB by the runtime or + /// the end of the assigned distribute chunk) + /// expression UB = min (UB, PrevUB) + Expr *PrevEUB; /// \brief Counters Loop counters. SmallVector Counters; /// \brief PrivateCounters Loop counters. @@ -608,6 +639,8 @@ NumIterations = nullptr; PrevLB = nullptr; PrevUB = nullptr; + DistInc = nullptr; + PrevEUB = nullptr; Counters.resize(Size); PrivateCounters.resize(Size); Inits.resize(Size); @@ -739,6 +772,22 @@ return const_cast(reinterpret_cast( *std::next(child_begin(), PrevUpperBoundVariableOffset))); } + Expr *getDistInc() const { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + return const_cast(reinterpret_cast( + *std::next(child_begin(), DistIncOffset))); + } + Expr *getPrevEnsureUpperBound() const { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + return const_cast(reinterpret_cast( + *std::next(child_begin(), PrevEnsureUpperBoundOffset))); + } const Stmt *getBody() const { // This relies on the loop form is already checked by Sema. Stmt *Body = getAssociatedStmt()->IgnoreContainers(true); Index: lib/AST/StmtOpenMP.cpp =================================================================== --- lib/AST/StmtOpenMP.cpp +++ lib/AST/StmtOpenMP.cpp @@ -149,6 +149,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -201,6 +203,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -366,6 +370,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -417,6 +423,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -753,6 +761,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -896,6 +906,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -947,6 +959,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -997,6 +1011,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1071,6 +1087,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1127,6 +1145,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1182,6 +1202,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1236,6 +1258,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1330,6 +1354,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1383,6 +1409,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1438,6 +1466,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1496,6 +1526,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1576,6 +1608,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1634,6 +1668,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1695,6 +1731,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); @@ -1753,6 +1791,8 @@ Dir->setNumIterations(Exprs.NumIterations); Dir->setPrevLowerBoundVariable(Exprs.PrevLB); Dir->setPrevUpperBoundVariable(Exprs.PrevUB); + Dir->setDistInc(Exprs.DistInc); + Dir->setPrevEnsureUpperBound(Exprs.PrevEUB); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); Index: lib/Basic/OpenMPKinds.cpp =================================================================== --- lib/Basic/OpenMPKinds.cpp +++ lib/Basic/OpenMPKinds.cpp @@ -873,6 +873,7 @@ case OMPD_parallel_for: case OMPD_parallel_for_simd: case OMPD_parallel_sections: + case OMPD_distribute_parallel_for: CaptureRegions.push_back(OMPD_parallel); break; case OMPD_target_teams: @@ -902,7 +903,6 @@ case OMPD_taskloop_simd: case OMPD_distribute_parallel_for_simd: case OMPD_distribute_simd: - case OMPD_distribute_parallel_for: case OMPD_teams_distribute: case OMPD_teams_distribute_simd: case OMPD_teams_distribute_parallel_for_simd: Index: lib/Sema/SemaOpenMP.cpp =================================================================== --- lib/Sema/SemaOpenMP.cpp +++ lib/Sema/SemaOpenMP.cpp @@ -4181,6 +4181,36 @@ return 0; } + // Create: increment expression for distribute loop when combined in a same + // directive with for as IV = IV + ST; ensure upper bound expression based + // on PrevUB instead of NumIterations - used to implement 'for' when found + // in combination with 'distribute', like in 'distribute parallel for' + SourceLocation DistIncLoc; + ExprResult DistCond, DistInc, PrevEUB; + if (isOpenMPLoopBoundSharingDirective(DKind)) { + DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()); + assert(DistCond.isUsable() && "distribute cond expr was not built"); + + DistInc = + SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); + assert(DistInc.isUsable() && "distribute inc expr was not built"); + DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), + DistInc.get()); + DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get()); + assert(DistInc.isUsable() && "distribute inc expr was not built"); + + // Build expression: UB = min(UB, prevUB) for #for in composite or combined + // construct + SourceLocation DistEUBLoc; + ExprResult IsUBGreater = + SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); + ExprResult CondOp = SemaRef.ActOnConditionalOp( + DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); + PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), + CondOp.get()); + PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); + } + // Build updates and final values of the loop counters. bool HasErrors = false; Built.Counters.resize(NestedLoopCount); @@ -4295,6 +4325,8 @@ Built.NUB = NextUB.get(); Built.PrevLB = PrevLB.get(); Built.PrevUB = PrevUB.get(); + Built.DistInc = DistInc.get(); + Built.PrevEUB = PrevEUB.get(); Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get(); // Fill data for doacross depend clauses. Index: lib/Serialization/ASTReaderStmt.cpp =================================================================== --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -2571,6 +2571,8 @@ if (isOpenMPLoopBoundSharingDirective(D->getDirectiveKind())) { D->setPrevLowerBoundVariable(Record.readSubExpr()); D->setPrevUpperBoundVariable(Record.readSubExpr()); + D->setDistInc(Record.readSubExpr()); + D->setPrevEnsureUpperBound(Record.readSubExpr()); } SmallVector Sub; unsigned CollapsedNum = D->getCollapsedNumber(); Index: lib/Serialization/ASTWriterStmt.cpp =================================================================== --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -2241,6 +2241,8 @@ if (isOpenMPLoopBoundSharingDirective(D->getDirectiveKind())) { Record.AddStmt(D->getPrevLowerBoundVariable()); Record.AddStmt(D->getPrevUpperBoundVariable()); + Record.AddStmt(D->getDistInc()); + Record.AddStmt(D->getPrevEnsureUpperBound()); } for (auto I : D->counters()) { Record.AddStmt(I);