@@ -48,6 +48,32 @@ static Value buildBoolValue(OpBuilder &builder, Location loc, bool value) {
48
48
49
49
static bool isMemref (Value v) { return v.getType ().isa <BaseMemRefType>(); }
50
50
51
+ // / Return "true" if the given op is guaranteed to have no "Allocate" or "Free"
52
+ // / side effect.
53
+ static bool hasNoAllocateOrFreeSideEffect (Operation *op) {
54
+ if (isa<MemoryEffectOpInterface>(op))
55
+ return hasEffect<MemoryEffects::Allocate>(op) ||
56
+ hasEffect<MemoryEffects::Free>(op);
57
+ // If the op does not implement the MemoryEffectOpInterface but has has
58
+ // recursive memory effects, then this op in isolation (without its body) does
59
+ // not have any side effects. The ops inside the regions of this op will be
60
+ // processed separately.
61
+ return op->hasTrait <OpTrait::HasRecursiveMemoryEffects>();
62
+ }
63
+
64
+ // / Return "true" if the given op has buffer semantics. I.e., it has buffer
65
+ // / operands, buffer results and/or buffer region entry block arguments.
66
+ static bool hasBufferSemantics (Operation *op) {
67
+ if (llvm::any_of (op->getOperands (), isMemref) ||
68
+ llvm::any_of (op->getResults (), isMemref))
69
+ return true ;
70
+ for (Region ®ion : op->getRegions ())
71
+ if (!region.empty ())
72
+ if (llvm::any_of (region.front ().getArguments (), isMemref))
73
+ return true ;
74
+ return false ;
75
+ }
76
+
51
77
// ===----------------------------------------------------------------------===//
52
78
// Backedges analysis
53
79
// ===----------------------------------------------------------------------===//
@@ -462,31 +488,6 @@ BufferDeallocation::materializeUniqueOwnership(OpBuilder &builder, Value memref,
462
488
return state.getMemrefWithUniqueOwnership (builder, memref, block);
463
489
}
464
490
465
- static bool regionOperatesOnMemrefValues (Region ®ion) {
466
- auto checkBlock = [](Block *block) {
467
- if (llvm::any_of (block->getArguments (), isMemref))
468
- return WalkResult::interrupt ();
469
- for (Operation &op : *block) {
470
- if (llvm::any_of (op.getOperands (), isMemref))
471
- return WalkResult::interrupt ();
472
- if (llvm::any_of (op.getResults (), isMemref))
473
- return WalkResult::interrupt ();
474
- }
475
- return WalkResult::advance ();
476
- };
477
- WalkResult result = region.walk (checkBlock);
478
- if (result.wasInterrupted ())
479
- return true ;
480
-
481
- // Note: Block::walk/Region::walk visits only blocks that are nested under
482
- // nested operations, but not direct children.
483
- for (Block &block : region)
484
- if (checkBlock (&block).wasInterrupted ())
485
- return true ;
486
-
487
- return false ;
488
- }
489
-
490
491
LogicalResult
491
492
BufferDeallocation::verifyFunctionPreconditions (FunctionOpInterface op) {
492
493
// (1) Ensure that there are supported loops only (no explicit control flow
@@ -512,9 +513,8 @@ LogicalResult BufferDeallocation::verifyOperationPreconditions(Operation *op) {
512
513
size_t size = regions.size ();
513
514
if (((size == 1 && !op->getResults ().empty ()) || size > 1 ) &&
514
515
!dyn_cast<RegionBranchOpInterface>(op)) {
515
- if (llvm::any_of (regions, regionOperatesOnMemrefValues))
516
- return op->emitError (" All operations with attached regions need to "
517
- " implement the RegionBranchOpInterface." );
516
+ return op->emitError (" All operations with attached regions need to "
517
+ " implement the RegionBranchOpInterface." );
518
518
}
519
519
520
520
// (2) The pass does not work properly when deallocations are already present.
@@ -648,6 +648,12 @@ LogicalResult BufferDeallocation::deallocate(Block *block) {
648
648
// For each operation in the block, handle the interfaces that affect aliasing
649
649
// and ownership of memrefs.
650
650
for (Operation &op : llvm::make_early_inc_range (*block)) {
651
+ // Skip ops that do not operate on buffers, have no Allocate/Free side
652
+ // effect and are not terminators. (bufferization.dealloc ops are inserted
653
+ // in front of terminators, so terminators cannot be skipped.)
654
+ if (!op.hasTrait <OpTrait::IsTerminator>() && !hasBufferSemantics (&op) &&
655
+ hasNoAllocateOrFreeSideEffect (&op))
656
+ continue ;
651
657
FailureOr<Operation *> result = handleAllInterfaces (&op);
652
658
if (failed (result))
653
659
return failure ();
0 commit comments