================
@@ -14983,35 +14994,113 @@ 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).
+ if (IntraTileMustBeCanonical) {
+ 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).
+ if (IntraTileMustBeCanonical) {
+ 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.
+ //
+ // The min-bounded path clamps the tile loop's upper bound directly so no
+ // predicate is needed.
+ if (IntraTileMustBeCanonical) {
+ bool PredicateNeeded = false;
+ for (unsigned I = 0; I < NumLoops; ++I) {
+ Expr *TSExpr = SizesClause->getSizesRefs()[I];
+ Expr *NExpr = LoopHelpers[I].NumIterations;
+ bool TSConst =
+ !TSExpr->containsErrors() && TSExpr->isIntegerConstantExpr(Context);
+ bool NConst = NExpr->isIntegerConstantExpr(Context);
----------------
Meinersbur wrote:
Instead of checking in advance, why not check whether the result of
`TSExpr->EvaluateAsInt()`/`NExpr->EvaluateAsInt()` was successful?
https://github.com/llvm/llvm-project/pull/191114
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits