66#include "llvm/Support/Debug.h"
70#define GEN_PASS_DEF_ACCLOOPTILING
71#include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
75#define DEBUG_TYPE "acc-loop-tile"
81 ACCLoopTilingImpl(
MLIRContext *context, int32_t defaultTileSize,
84 defaultTileSize(defaultTileSize), accSupport(accSupport) {}
89 LogicalResult checkTileSizeTypes(acc::LoopOp loop,
91 auto ivTypes = loop.getBody().getArgumentTypes();
92 for (
size_t i = 0; i < tileSizes.size() && i < ivTypes.size(); ++i) {
93 Type tileType = tileSizes[i].getType();
94 Type ivType = ivTypes[i];
98 if (constVal && *constVal < 0)
102 auto tileIntType = dyn_cast<IntegerType>(tileType);
103 auto ivIntType = dyn_cast<IntegerType>(ivType);
104 if (tileIntType && ivIntType) {
105 if (tileIntType.getWidth() > ivIntType.getWidth()) {
106 accSupport.
emitNYI(loop.getLoc(),
107 "tile size type (i" +
108 std::to_string(tileIntType.getWidth()) +
109 ") is wider than loop IV type (i" +
110 std::to_string(ivIntType.getWidth()) +
")");
118 void emitTilingRemarks(acc::LoopOp loop,
ArrayRef<Value> tileSizes)
const {
120 size_t tileLevel = tileSizes.size();
122 "Tiling " + std::to_string(tileLevel) +
"-level loop nest with tile(";
123 for (
size_t i = 0; i < tileSizes.size(); ++i) {
128 msg += std::to_string(*val);
129 if (i < tileSizes.size() - 1)
137 for (
Value tileSize : tileSizes) {
139 if (val && *val < 0) {
140 std::string unknownMsg =
"Picking default tile size " +
141 std::to_string(defaultTileSize) +
142 " for unknown tile size '*'";
148 LogicalResult matchAndRewrite(acc::LoopOp origLoop,
151 if (origLoop.getTileValues().empty())
155 origLoop.getTileValues().end());
156 unsigned tileCount = tileSizes.size();
157 unsigned collapseCount = origLoop.getCollapseValue().value_or(1);
160 if (failed(checkTileSizeTypes(origLoop, tileSizes)))
165 emitTilingRemarks(origLoop, tileSizes);
167 LLVM_DEBUG(llvm::dbgs() <<
"\nBefore tiling:\n" << *origLoop <<
"\n");
171 origLoop.getTileOperandsMutable().clear();
172 origLoop.removeTileOperandsSegmentsAttr();
173 origLoop.removeTileOperandsDeviceTypeAttr();
177 if (collapseCount < tileCount) {
181 rewriter.
replaceOp(origLoop, loopsToTile[0]);
182 LLVM_DEBUG(llvm::dbgs() <<
"\nAfter uncollapsing:\n"
183 << *loopsToTile[0] <<
"\n");
185 loopsToTile.push_back(origLoop);
193 LLVM_DEBUG(llvm::dbgs() <<
"\nAfter tiling:\n " << *loopsToTile[0] <<
"\n");
198 int32_t defaultTileSize;
204 using ACCLoopTilingBase<ACCLoopTiling>::ACCLoopTilingBase;
206 void runOnOperation()
override {
207 func::FuncOp funcOp = getOperation();
212 patterns.insert<ACCLoopTilingImpl>(context, defaultTileSize, accSupport);
This class allows control over how the GreedyPatternRewriteDriver works.
GreedyRewriteConfig & setMaxIterations(int64_t iterations)
GreedyRewriteConfig & setUseTopDownTraversal(bool use=true)
MLIRContext is the top-level object for a collection of MLIR operations.
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
virtual void finalizeOpModification(Operation *op)
This method is used to signal the end of an in-place modification of the given operation.
virtual void startOpModification(Operation *op)
This method is used to notify the rewriter that an in-place operation modification is about to happen...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
remark::detail::InFlightRemark emitRemark(Operation *op, const Twine &message, llvm::StringRef category="openacc")
Emit an OpenACC remark.
InFlightDiagnostic emitNYI(Location loc, const Twine &message)
Report a case that is not yet supported by the implementation.
mlir::acc::LoopOp tileACCLoops(llvm::SmallVector< mlir::acc::LoopOp > &tileLoops, const llvm::SmallVector< mlir::Value > &tileSizes, int32_t defaultTileSize, mlir::RewriterBase &rewriter)
Tile ACC loops according to the given tile sizes.
llvm::SmallVector< mlir::acc::LoopOp > uncollapseLoops(mlir::acc::LoopOp origLoop, unsigned tileCount, unsigned collapseCount, mlir::RewriterBase &rewriter)
Uncollapse tile loops with multiple IVs and collapseCount < tileCount.
Include the generated interface declarations.
std::optional< int64_t > getConstantIntValue(OpFoldResult ofr)
If ofr is a constant integer or an IntegerAttr, return the integer.
LogicalResult applyPatternsGreedily(Region ®ion, const FrozenRewritePatternSet &patterns, GreedyRewriteConfig config=GreedyRewriteConfig(), bool *changed=nullptr)
Rewrite ops in the given region, which must be isolated from above, by repeatedly applying the highes...
const FrozenRewritePatternSet & patterns
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...