71#include "llvm/ADT/StringExtras.h"
72#include "llvm/Support/Debug.h"
76#define GEN_PASS_DEF_ACCLOOPTILING
77#include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
81#define DEBUG_TYPE "acc-loop-tile"
87 ACCLoopTilingImpl(
MLIRContext *context, int32_t defaultTileSize,
90 defaultTileSize(defaultTileSize), accSupport(accSupport) {}
95 LogicalResult checkTileSizeTypes(acc::LoopOp loop,
97 auto ivTypes = loop.getBody().getArgumentTypes();
98 for (
size_t i = 0; i < tileSizes.size() && i < ivTypes.size(); ++i) {
99 Type tileType = tileSizes[i].getType();
100 Type ivType = ivTypes[i];
104 if (constVal && *constVal < 0)
108 auto tileIntType = dyn_cast<IntegerType>(tileType);
109 auto ivIntType = dyn_cast<IntegerType>(ivType);
110 if (tileIntType && ivIntType) {
111 if (tileIntType.getWidth() > ivIntType.getWidth()) {
112 accSupport.
emitNYI(loop.getLoc(),
113 "tile size type (i" +
114 std::to_string(tileIntType.getWidth()) +
115 ") is wider than loop IV type (i" +
116 std::to_string(ivIntType.getWidth()) +
")");
124 void emitTilingRemarks(acc::LoopOp loop,
ArrayRef<Value> tileSizes)
const {
129 auto getTileSizeStr = [&](
Value v) -> std::string {
132 if (name.empty() || name ==
"-1")
137 for (
Value v : tileSizes)
138 tileStrs.push_back(getTileSizeStr(v));
139 return "Tiling " + std::to_string(tileSizes.size()) +
140 "-level loop nest with tile(" + llvm::join(tileStrs,
",") +
147 for (
Value tileSize : tileSizes) {
149 if (val && *val < 0) {
153 return "Picking default tile size " +
154 std::to_string(defaultTileSize) +
155 " for unknown tile size '*'";
162 LogicalResult matchAndRewrite(acc::LoopOp origLoop,
165 if (origLoop.getTileValues().empty())
169 origLoop.getTileValues().end());
174 if (origLoop.getCollapseAttr()) {
175 accSupport.
emitNYI(origLoop.getLoc(),
176 "a tile clause combined with a collapse clause on the "
182 if (failed(checkTileSizeTypes(origLoop, tileSizes)))
187 emitTilingRemarks(origLoop, tileSizes);
189 LLVM_DEBUG(llvm::dbgs() <<
"\nBefore tiling:\n" << *origLoop <<
"\n");
193 origLoop.getTileOperandsMutable().clear();
194 origLoop.removeTileOperandsSegmentsAttr();
195 origLoop.removeTileOperandsDeviceTypeAttr();
203 LLVM_DEBUG(llvm::dbgs() <<
"\nAfter tiling:\n " << *origLoop <<
"\n");
208 int32_t defaultTileSize;
214 using ACCLoopTilingBase<ACCLoopTiling>::ACCLoopTilingBase;
217 ACCLoopTilingBase<ACCLoopTiling>::getDependentDialects(registry);
221 void runOnOperation()
override {
222 func::FuncOp funcOp = getOperation();
227 patterns.
insert<ACCLoopTilingImpl>(context, defaultTileSize, accSupport);
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
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...
RewritePatternSet & insert(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
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, std::function< std::string()> messageFn, llvm::StringRef category="openacc")
Emit an OpenACC remark with lazy message generation.
std::string getVariableName(Value v, VariableNameConfig config={})
Get the variable name for a given value.
InFlightDiagnostic emitNYI(Location loc, const Twine &message)
Report a case that is not yet supported by the implementation.
mlir::acc::LoopOp tileACCLoops(mlir::acc::LoopOp tileLoop, const llvm::SmallVector< mlir::Value > &tileSizes, int32_t defaultTileSize, mlir::RewriterBase &rewriter)
Tile a single fused acc.loop that carries all associated induction variables (one IV per tile dimensi...
void registerAllExtensions(DialectRegistry ®istry)
Register the standard OpenACC models for GPU, LLVM and MemRef IR.
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...
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...