================
@@ -14983,35 +14985,118 @@ StmtResult
SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
FloorIndVars[I] = FloorCntDecl;
}
- // Iteration variable for the tile (i.e. inner) loop.
+ // Logical iteration variable for the tile loop. Retains the meaning of
+ // the original logical iteration number (floor_iv + tile_cnt) so that
+ // LoopHelper.Updates can derive the original loop variable unchanged.
{
- std::string TileCntName =
+ std::string TileIVName =
(Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
- // Reuse the iteration variable created by checkOpenMPLoop. It is also
- // used by the expressions to derive the original iteration variable's
- // value from the logical iteration number.
- auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
- TileCntDecl->setDeclName(
- &SemaRef.PP.getIdentifierTable().get(TileCntName));
- TileIndVars[I] = TileCntDecl;
+ auto *TileIVDecl = cast<VarDecl>(IterVarRef->getDecl());
+
TileIVDecl->setDeclName(&SemaRef.PP.getIdentifierTable().get(TileIVName));
+ TileIndVars[I] = TileIVDecl;
+ }
+
+ // Loop counter for the rectangular tile loop [0, TileSize).
+ {
+ std::string TileCntName =
+ (Twine(".tile.cnt.") + llvm::utostr(I) + ".iv." + OrigVarName).str();
+ VarDecl *TileCntDecl =
+ buildVarDecl(SemaRef, {}, CntTy, TileCntName, nullptr, OrigCntVar);
+ TileCntVars[I] = TileCntDecl;
}
addLoopPreInits(Context, LoopHelper, LoopStmts[I], OriginalInits[I],
PreInits);
+
+ // Declare the logical tile IV in PreInits so it is in scope for the
+ // entire loop nest (it will be assigned in each tile loop body).
+ {
+ Decl *TileIVDeclPtr = TileIndVars[I];
+ PreInits.push_back(new (Context) DeclStmt(
+ DeclGroupRef::Create(Context, &TileIVDeclPtr, 1), {}, {}));
+ }
}
// Once the original iteration values are set, append the innermost body.
Stmt *Inner = Body;
+ // Build a combined validity predicate that guards the innermost body.
+ // For each tiled dimension, check that the logical iteration number
+ // (.tile.iv) is within the original trip count. This is required because the
+ // tile loop now has rectangular (constant) bounds and may overshoot on the
+ // remainder tile. The predicate is: .tile.iv.0 < N0 && .tile.iv.1 < N1 ...
+ //
+ // Optimization: if every dimension's trip count is a compile-time constant
+ // that is evenly divisible by the corresponding tile size (also a constant),
+ // then the remainder tile is empty and the predicate is trivially true.
+ //
+ bool PredicateNeeded = false;
+ for (unsigned I = 0; I < NumLoops; ++I) {
+ Expr *TSExpr = SizesClause->getSizesRefs()[I];
+ Expr *NExpr = LoopHelpers[I].NumIterations;
+ Expr::EvalResult TSResult;
+ Expr::EvalResult NResult;
+ if (TSExpr->EvaluateAsInt(TSResult, Context) &&
+ NExpr->EvaluateAsInt(NResult, Context)) {
+ llvm::APSInt TileVal = TSResult.Val.getInt();
+ llvm::APSInt TripVal = NResult.Val.getInt();
+ if (TileVal.isStrictlyPositive() && TripVal.srem(TileVal).isZero())
+ continue;
+ }
+ PredicateNeeded = true;
+ break;
+ }
+
+ if (PredicateNeeded) {
+ Expr *CombinedPred = nullptr;
+ for (unsigned I = 0; I < NumLoops; ++I) {
+ auto *OrigCntVar = cast<DeclRefExpr>(LoopHelpers[I].Counters[0]);
+ QualType IVTy = LoopHelpers[I].NumIterations->getType();
+ Expr *FloorRef = buildDeclRefExpr(SemaRef, FloorIndVars[I], IVTy,
+ OrigCntVar->getExprLoc());
+ Expr *TileCntRef = buildDeclRefExpr(SemaRef, TileCntVars[I], IVTy,
+ OrigCntVar->getExprLoc());
+ ExprResult Sum = SemaRef.BuildBinOp(CurScope, OrigCntVar->getExprLoc(),
+ BO_Add, FloorRef, TileCntRef);
+ if (!Sum.isUsable())
+ return StmtError();
+ ExprResult DimPred =
+ SemaRef.BuildBinOp(CurScope, OrigCntVar->getExprLoc(), BO_LT,
+ Sum.get(), LoopHelpers[I].NumIterations);
+ if (!DimPred.isUsable())
+ return StmtError();
+ if (CombinedPred) {
+ ExprResult Combined =
+ SemaRef.BuildBinOp(CurScope, OrigCntVar->getExprLoc(), BO_LAnd,
+ CombinedPred, DimPred.get());
+ if (!Combined.isUsable())
+ return StmtError();
+ CombinedPred = Combined.get();
+ } else {
+ CombinedPred = DimPred.get();
+ }
+ }
+ // Use the source body's location for the synthetic if-statement and
+ // AttributedStmt so any later diagnostic points at the original body
+ // location.
+ SourceLocation SyntheticLoc =
+ Body ? Body->getBeginLoc() : Inner->getBeginLoc();
+ Stmt *PredIf = IfStmt::Create(
+ Context, SyntheticLoc, IfStatementKind::Ordinary, nullptr, nullptr,
----------------
Meinersbur wrote:
```suggestion
Context, SyntheticLoc, IfStatementKind::Ordinary, /*Init=*/ nullptr,
/*varDecl=*/ nullptr,
```
https://github.com/llvm/llvm-project/pull/191114
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits