summaryrefslogtreecommitdiffstats
path: root/mlir/lib/Transforms/PipelineDataTransfer.cpp
diff options
context:
space:
mode:
authorUday Bondhugula <bondhugula@google.com>2019-02-11 16:33:53 -0800
committerjpienaar <jpienaar@google.com>2019-03-29 16:24:08 -0700
commit8b3f841daf3ad728eab81c73b8fafdc050627fa6 (patch)
tree87ea816e56dd331f72ec4d9c2a7bc86cf5a36a11 /mlir/lib/Transforms/PipelineDataTransfer.cpp
parentf5eed89df06fbaf8c1dc7241bbbcfba8b5dea6ea (diff)
downloadbcm5719-llvm-8b3f841daf3ad728eab81c73b8fafdc050627fa6.tar.gz
bcm5719-llvm-8b3f841daf3ad728eab81c73b8fafdc050627fa6.zip
Generate dealloc's for the alloc's of dma-generate.
- for the DMA buffers being allocated (and their tags), generate corresponding deallocs - minor related update to replaceAllMemRefUsesWith and PipelineDataTransfer pass Code generation for DMA transfers was being done with the initial simplifying assumption that the alloc's would map to scoped allocations, and so no deallocations would be necessary. Drop this assumption to generalize. Note that even with scoped allocations, unrolling loops that have scoped allocations could create a series of allocations and exhaustion of fast memory. Having a end of lifetime marker like a dealloc in fact allows creating new scopes if necessary when lowering to a backend and still utilize scoped allocation. DMA buffers created by -dma-generate are guaranteed to have either non-overlapping lifetimes or nested lifetimes. PiperOrigin-RevId: 233502632
Diffstat (limited to 'mlir/lib/Transforms/PipelineDataTransfer.cpp')
-rw-r--r--mlir/lib/Transforms/PipelineDataTransfer.cpp21
1 files changed, 16 insertions, 5 deletions
diff --git a/mlir/lib/Transforms/PipelineDataTransfer.cpp b/mlir/lib/Transforms/PipelineDataTransfer.cpp
index cfa045f2279..5c2e38205e7 100644
--- a/mlir/lib/Transforms/PipelineDataTransfer.cpp
+++ b/mlir/lib/Transforms/PipelineDataTransfer.cpp
@@ -124,8 +124,9 @@ static bool doubleBuffer(Value *oldMemRef, OpPointer<AffineForOp> forOp) {
// replaceAllMemRefUsesWith will always succeed unless the forOp body has
// non-deferencing uses of the memref.
- if (!replaceAllMemRefUsesWith(oldMemRef, newMemRef, {ivModTwoOp}, AffineMap(),
- {}, &*forOp->getBody()->begin())) {
+ if (!replaceAllMemRefUsesWith(
+ oldMemRef, newMemRef, {ivModTwoOp}, AffineMap(), {},
+ /*domInstFilter=*/&*forOp->getBody()->begin())) {
LLVM_DEBUG(llvm::dbgs()
<< "memref replacement for double buffering failed\n";);
ivModTwoOp->getInstruction()->erase();
@@ -284,10 +285,20 @@ PipelineDataTransfer::runOnAffineForOp(OpPointer<AffineForOp> forOp) {
// If the old memref has no more uses, remove its 'dead' alloc if it was
// alloc'ed. (note: DMA buffers are rarely function live-in; but a 'dim'
// operation could have been used on it if it was dynamically shaped in
- // order to create the double buffer above)
- if (oldMemRef->use_empty())
- if (auto *allocInst = oldMemRef->getDefiningInst())
+ // order to create the double buffer above.)
+ // '-canonicalize' does this in a more general way, but we'll anyway do the
+ // simple/common case so that the output / test cases looks clear.
+ if (auto *allocInst = oldMemRef->getDefiningInst()) {
+ if (oldMemRef->use_empty()) {
allocInst->erase();
+ } else if (oldMemRef->hasOneUse()) {
+ auto *singleUse = oldMemRef->use_begin()->getOwner();
+ if (singleUse->isa<DeallocOp>()) {
+ singleUse->erase();
+ oldMemRef->getDefiningInst()->erase();
+ }
+ }
+ }
}
// Double the buffers for tag memrefs.
OpenPOWER on IntegriCloud