30 #include "llvm/ADT/MapVector.h" 31 #include "llvm/Support/CommandLine.h" 32 #include "llvm/Support/Debug.h" 35 #define DEBUG_TYPE "affine-data-copy-generate" 52 struct AffineDataCopyGeneration
53 :
public AffineDataCopyGenerationBase<AffineDataCopyGeneration> {
54 AffineDataCopyGeneration() =
default;
55 explicit AffineDataCopyGeneration(
unsigned slowMemorySpace,
56 unsigned fastMemorySpace,
57 unsigned tagMemorySpace,
58 int minDmaTransferSize,
59 uint64_t fastMemCapacityBytes) {
60 this->slowMemorySpace = slowMemorySpace;
61 this->fastMemorySpace = fastMemorySpace;
62 this->tagMemorySpace = tagMemorySpace;
63 this->minDmaTransferSize = minDmaTransferSize;
64 this->fastMemoryCapacity = fastMemCapacityBytes / 1024;
67 void runOnOperation()
override;
71 Value zeroIndex =
nullptr;
80 std::unique_ptr<OperationPass<func::FuncOp>>
82 unsigned fastMemorySpace,
83 unsigned tagMemorySpace,
84 int minDmaTransferSize,
85 uint64_t fastMemCapacityBytes) {
86 return std::make_unique<AffineDataCopyGeneration>(
87 slowMemorySpace, fastMemorySpace, tagMemorySpace, minDmaTransferSize,
88 fastMemCapacityBytes);
90 std::unique_ptr<OperationPass<func::FuncOp>>
92 return std::make_unique<AffineDataCopyGeneration>();
99 void AffineDataCopyGeneration::runOnBlock(
Block *block,
104 uint64_t fastMemCapacityBytes =
106 ? fastMemoryCapacity * 1024
107 : fastMemoryCapacity;
109 fastMemorySpace, tagMemorySpace,
110 fastMemCapacityBytes};
126 return isa<AffineLoadOp, AffineStoreOp, AffineForOp>(op) &&
127 copyNests.count(&op) == 0;
132 while (it != block->
end()) {
135 if ((forOp = dyn_cast<AffineForOp>(&*it)) && copyNests.count(forOp) == 0) {
138 llvm::None, copyNests);
141 auto exceedsCapacity = [&](AffineForOp forOp) {
145 return (footprint.hasValue() &&
146 static_cast<uint64_t
>(footprint.getValue()) >
147 fastMemCapacityBytes);
156 bool recurseInner = skipNonUnitStrideLoops ? forOp.getStep() != 1
157 : exceedsCapacity(forOp);
161 runOnBlock(forOp.getBody(), copyNests);
173 llvm::None, copyNests);
176 curBegin = std::find_if(std::next(it), block->
end(), [&](
Operation &op) {
177 return isa<AffineLoadOp, AffineStoreOp, AffineForOp>(op) &&
178 copyNests.count(&op) == 0;
182 assert(copyNests.count(&*it) == 0 &&
183 "all copy nests generated should have been skipped above");
190 if (curBegin != block->
end()) {
193 "can't be a terminator");
196 std::prev(block->
end()), copyOptions,
197 llvm::None, copyNests);
201 void AffineDataCopyGeneration::runOnOperation() {
202 func::FuncOp f = getOperation();
213 for (
auto &block : f)
214 runOnBlock(&block, copyNests);
223 if (
auto forOp = dyn_cast<AffineForOp>(op))
225 else if (isa<AffineLoadOp, AffineStoreOp>(op))
226 copyOps.push_back(op);
233 AffineLoadOp::getCanonicalizationPatterns(patterns, &getContext());
234 AffineStoreOp::getCanonicalizationPatterns(patterns, &getContext());
Include the generated interface declarations.
Operation is a basic unit of execution within MLIR.
This class represents a frozen set of patterns that can be processed by a pattern applicator...
Block represents an ordered list of Operations.
LogicalResult applyOpPatternsAndFold(Operation *op, const FrozenRewritePatternSet &patterns, bool *erased=nullptr)
Applies the specified patterns on op alone while also trying to fold it, by selecting the highest ben...
Optional< int64_t > getMemoryFootprintBytes(AffineForOp forOp, int memorySpace=-1)
Gets the memory footprint of all data touched in the specified memory space in bytes; if the memory s...
LogicalResult promoteIfSingleIteration(AffineForOp forOp)
Promotes the loop body of a AffineForOp to its containing block if the loop was known to have a singl...
This class provides the API for ops that are known to be terminators.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Explicit copy / DMA generation options for mlir::affineDataCopyGenerate.
LogicalResult affineDataCopyGenerate(Block::iterator begin, Block::iterator end, const AffineCopyOptions ©Options, Optional< Value > filterMemRef, DenseSet< Operation *> ©Nests)
Performs explicit copying for the contiguous sequence of operations in the block iterator range [`beg...
Specialization of arith.constant op that returns an integer of index type.
std::unique_ptr< OperationPass< func::FuncOp > > createAffineDataCopyGenerationPass(unsigned slowMemorySpace, unsigned fastMemorySpace, unsigned tagMemorySpace=0, int minDmaTransferSize=1024, uint64_t fastMemCapacityBytes=std::numeric_limits< uint64_t >::max())
Performs packing (or explicit copying) of accessed memref regions into buffers in the specified faste...
This class helps build Operations.
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)