================
@@ -15783,6 +15828,100 @@ static Expr *makeFloorIVRef(Sema &SemaRef,
ArrayRef<VarDecl *> FloorIndVars,
OrigCntVar->getExprLoc());
}
+/// Whether \p Counter is compiler generated (e.g. a fuse index).
+static bool isGeneratedLoopCounter(const Expr *Counter) {
+ const auto *DRE = dyn_cast<DeclRefExpr>(Counter);
+ const auto *VD = DRE ? dyn_cast<VarDecl>(DRE->getDecl()) : nullptr;
+ return VD && VD->isImplicit() && !isa<OMPCapturedExprDecl>(VD);
+}
+
+/// Wrap \p S so it runs only if every loop in \p Loops has iterations.
+static Stmt *
+guardByLoopPreConds(ASTContext &Context,
+ ArrayRef<OMPLoopBasedDirective::HelperExprs> Loops,
+ Stmt *S) {
+ for (const auto &Loop : llvm::reverse(Loops))
+ S = IfStmt::Create(Context, SourceLocation(), IfStatementKind::Ordinary,
+ nullptr, nullptr, Loop.PreCond, SourceLocation(),
+ SourceLocation(), S, SourceLocation(), nullptr);
+ return S;
+}
+
+/// Run loop \p I's inits only if all enclosing loops have iterations.
+/// Declarations are left as is.
+static void
+guardNestedLoopInit(ASTContext &Context,
+ ArrayRef<OMPLoopBasedDirective::HelperExprs> LoopHelpers,
+ unsigned I, SmallVectorImpl<Stmt *> &OriginalInit) {
+ if (I == 0)
+ return;
+ for (Stmt *&Init : OriginalInit)
+ if (Init && !isa<DeclStmt>(Init))
+ Init = guardByLoopPreConds(Context, LoopHelpers.take_front(I), Init);
+}
+
+/// Build loop variable finalization statement from HelperExprs.Finals.
+/// Each Final runs only if its loop, and with \p IsLoopNest all enclosing
+/// loops, have iterations; \p NestedFinals[I] is emitted with loop I's.
+/// Returns nullptr if there is nothing to finalize.
+/// Compiler-generated counters and class-type iterators are skipped.
+static Stmt *
+buildLoopFinalization(ASTContext &Context,
+ ArrayRef<OMPLoopBasedDirective::HelperExprs> LoopHelpers,
+ bool IsLoopNest = false,
+ ArrayRef<Stmt *> NestedFinals = {}) {
+ auto GetFinals = [](const OMPLoopBasedDirective::HelperExprs &Helper) {
+ SmallVector<Stmt *, 2> Finals;
+ for (auto [Counter, Final] :
+ llvm::zip_equal(Helper.Counters, Helper.Finals)) {
+ if (isGeneratedLoopCounter(Counter))
+ continue;
+ // FIXME: finalize class-type iterators too (random-access arithmetic
+ // is available per the canonical loop form).
+ QualType CounterTy = Counter->getType();
+ if (Final &&
+ (CounterTy->isArithmeticType() || CounterTy->isPointerType()))
+ Finals.push_back(Final);
+ }
+ return Finals;
+ };
+ auto MakeCompound = [&Context](ArrayRef<Stmt *> Stmts) -> Stmt * {
+ return CompoundStmt::Create(Context, Stmts, FPOptionsOverride(),
+ SourceLocation(), SourceLocation());
+ };
+
+ auto GetNestedFinals = [&](size_t I) -> Stmt * {
+ return I < NestedFinals.size() ? NestedFinals[I] : nullptr;
+ };
+
+ if (IsLoopNest) {
+ // if (P0) { F0; if (P1) { F1; ... } }, built from the innermost loop out.
+ Stmt *Nested = nullptr;
+ for (size_t I = LoopHelpers.size(); I-- > 0;) {
+ SmallVector<Stmt *, 2> Body = GetFinals(LoopHelpers[I]);
+ if (Stmt *F = GetNestedFinals(I))
+ Body.push_back(F);
+ if (Nested)
+ Body.push_back(Nested);
+ if (Body.empty())
+ continue;
+ Nested = guardByLoopPreConds(Context, LoopHelpers[I],
+ Body.size() == 1 ? Body.front()
+ : MakeCompound(Body));
+ }
+ return Nested;
+ }
+
+ SmallVector<Stmt *, 8> FinalizationStmts;
+ for (auto [I, Helper] : llvm::enumerate(LoopHelpers)) {
+ for (Stmt *Final : GetFinals(Helper))
+ FinalizationStmts.push_back(guardByLoopPreConds(Context, Helper, Final));
+ if (Stmt *F = GetNestedFinals(I))
+ FinalizationStmts.push_back(F);
+ }
+ return FinalizationStmts.empty() ? nullptr : MakeCompound(FinalizationStmts);
----------------
alexey-bataev wrote:
```suggestion
// if (P0) { F0; if (P1) { F1; ... } }, built from the innermost loop out.
Stmt *Nested = nullptr;
for (size_t I = LoopHelpers.size(); I-- > 0;) {
SmallVector<Stmt *, 2> Body = GetFinals(LoopHelpers[I]);
if (Stmt *F = GetNestedFinals(I))
Body.push_back(F);
if (Nested)
Body.push_back(Nested);
if (Body.empty())
continue;
Nested = guardByLoopPreConds(Context, LoopHelpers[I],
Body.size() == 1 ? Body.front()
: MakeCompound(Body));
}
return Nested;
```
https://github.com/llvm/llvm-project/pull/214717
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits