20#include "llvm/ADT/STLExtras.h"
25 int32_t defaultTileSize,
30 if (constVal && *constVal < 0) {
32 return mlir::arith::ConstantOp::create(
33 rewriter, loc, targetType,
42 if (loop.hasVector() || loop.getVectorValue()) {
43 loop.removeVectorAttr();
44 loop.removeVectorOperandsDeviceTypeAttr();
45 }
else if (loop.hasWorker() || loop.getWorkerValue()) {
46 loop.removeWorkerAttr();
47 loop.removeWorkerNumOperandsDeviceTypeAttr();
56 mlir::acc::CombinedConstructsTypeAttr combinedAttr,
mlir::Location loc) {
57 mlir::ArrayAttr collapseAttr = mlir::ArrayAttr{};
58 mlir::ArrayAttr collapseDeviceTypeAttr = mlir::ArrayAttr{};
59 auto newLoop = mlir::acc::LoopOp::create(
60 rewriter, loc, origLoop->getResultTypes(), lb, ub, step, inclusiveUBAttr,
61 collapseAttr, collapseDeviceTypeAttr, origLoop.getGangOperands(),
62 origLoop.getGangOperandsArgTypeAttr(),
63 origLoop.getGangOperandsSegmentsAttr(),
64 origLoop.getGangOperandsDeviceTypeAttr(), origLoop.getWorkerNumOperands(),
65 origLoop.getWorkerNumOperandsDeviceTypeAttr(),
66 origLoop.getVectorOperands(), origLoop.getVectorOperandsDeviceTypeAttr(),
67 origLoop.getSeqAttr(), origLoop.getIndependentAttr(),
68 origLoop.getAuto_Attr(), origLoop.getGangAttr(), origLoop.getWorkerAttr(),
70 mlir::ArrayAttr{}, origLoop.getCacheOperands(),
71 origLoop.getPrivateOperands(), origLoop.getFirstprivateOperands(),
72 origLoop.getReductionOperands(), combinedAttr);
78 mlir::acc::LoopOp targetLoop,
94 movedOps.push_back(op);
95 rewriter.startOpModification(op);
98 targetLoop.getBody().getOperations().splice(
99 targetLoop.getBody().getOperations().begin(),
100 sourceLoop.getBody().getOperations(), begin, end);
103 for (
auto [i, newIV] : llvm::enumerate(newIVs))
113static mlir::acc::LoopOp
120 tileLoop, rewriter, lbs, ubs, steps, inclusiveUBAttr,
121 mlir::acc::CombinedConstructsTypeAttr{}, loc);
126 if (tileLoop.hasGang() ||
127 tileLoop.getGangValue(mlir::acc::GangArgType::Num) ||
128 tileLoop.getGangValue(mlir::acc::GangArgType::Dim) ||
129 tileLoop.getGangValue(mlir::acc::GangArgType::Static)) {
130 elementLoop.removeGangAttr();
131 elementLoop.removeGangOperandsArgTypeAttr();
132 elementLoop.removeGangOperandsSegmentsAttr();
133 elementLoop.removeGangOperandsDeviceTypeAttr();
134 elementLoop.getGangOperandsMutable().clear();
136 if (tileLoop.hasVector() || tileLoop.getVectorValue()) {
137 elementLoop.removeWorkerAttr();
138 elementLoop.removeWorkerNumOperandsDeviceTypeAttr();
139 elementLoop.getWorkerNumOperandsMutable().clear();
145 elementLoop.getRegion().begin());
147 mlir::acc::YieldOp::create(rewriter, loc);
149 elementLoop.getBody().addArgument(ivType, loc);
163 const unsigned tileCount = tileSizes.size();
168 const unsigned numIVs = origIVs.size();
169 const size_t nOps = tileLoop.getBody().getOperations().size();
173 for (
unsigned i = 0; i < numIVs; ++i) {
174 if (tileLoop.getInclusiveUpperboundAttr())
175 inclusiveUBs.push_back(
176 tileLoop.getInclusiveUpperboundAttr().asArrayRef()[i]);
178 inclusiveUBs.push_back(
false);
186 for (
unsigned i = 0; i < numIVs; ++i) {
189 tileSizes[i], defaultTileSize, origSteps[i].
getType(), rewriter, loc);
191 mlir::arith::MulIOp::create(rewriter, loc, origSteps[i], tileSize);
192 scaledSteps.push_back(scaled);
193 tileLoopSteps.push_back(scaled);
195 tileLoopSteps.push_back(origSteps[i]);
204 for (
unsigned i = 0; i < tileCount; ++i) {
206 mlir::arith::AddIOp::create(rewriter, loc, origIVs[i], scaledSteps[i]);
208 if (inclusiveUBs[i]) {
211 rewriter, loc, scaledSteps[i].
getType(),
213 newUB = mlir::arith::SubIOp::create(rewriter, loc, stepped, c1);
216 mlir::arith::MinSIOp::create(rewriter, loc, origUBs[i], newUB));
217 elemLBs.push_back(origIVs[i]);
218 elemSteps.push_back(origSteps[i]);
219 elemIVTypes.push_back(origIVs[i].
getType());
220 elemInclusiveUBs.push_back(inclusiveUBs[i]);
226 if (llvm::is_contained(elemInclusiveUBs,
true))
230 mlir::acc::LoopOp elementLoop =
232 elemInclAttr, elemIVTypes, loc);
237 elementLoop.getBody().getArguments());
239 origIVs.begin() + tileCount);
245 tileLoop.getStepMutable().clear();
246 tileLoop.getStepMutable().append(tileLoopSteps);
static void removeWorkerVectorFromLoop(mlir::acc::LoopOp loop)
static void moveOpsAndReplaceIVs(mlir::acc::LoopOp sourceLoop, mlir::acc::LoopOp targetLoop, llvm::ArrayRef< mlir::Value > newIVs, llvm::ArrayRef< mlir::Value > origIVs, size_t nOps, mlir::RewriterBase &rewriter)
static mlir::Value resolveAndCastTileSize(mlir::Value tileSize, int32_t defaultTileSize, mlir::Type targetType, mlir::RewriterBase &rewriter, mlir::Location loc)
static mlir::acc::LoopOp createACCLoopFromOriginal(mlir::acc::LoopOp origLoop, mlir::RewriterBase &rewriter, mlir::ValueRange lb, mlir::ValueRange ub, mlir::ValueRange step, mlir::DenseBoolArrayAttr inclusiveUBAttr, mlir::acc::CombinedConstructsTypeAttr combinedAttr, mlir::Location loc)
static mlir::acc::LoopOp createElementGroupLoop(mlir::acc::LoopOp tileLoop, mlir::RewriterBase &rewriter, mlir::ValueRange lbs, mlir::ValueRange ubs, mlir::ValueRange steps, mlir::DenseBoolArrayAttr inclusiveUBAttr, llvm::ArrayRef< mlir::Type > ivTypes, mlir::Location loc)
Block represents an ordered list of Operations.
OpListType::iterator iterator
IntegerAttr getIntegerAttr(Type type, int64_t value)
DenseBoolArrayAttr getDenseBoolArrayAttr(ArrayRef< bool > values)
Tensor-typed DenseArrayAttr getters.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes={}, ArrayRef< Location > locs={})
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
Operation is the basic unit of execution within MLIR.
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
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 provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
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 replaceAllUsesInRegionWith(Value orig, Value replacement, Region ®ion)
Replace all uses of orig within the given region with replacement.
std::optional< int64_t > getConstantIntValue(OpFoldResult ofr)
If ofr is a constant integer or an IntegerAttr, return the integer.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
Value getValueOrCreateCastToIndexLike(OpBuilder &b, Location loc, Type targetType, Value value)
Create a cast from an index-like value (index or integer) to another index-like value.
detail::DenseArrayAttrImpl< int32_t > DenseI32ArrayAttr
detail::DenseArrayAttrImpl< bool > DenseBoolArrayAttr