1717#include " mlir/Dialect/Func/IR/FuncOps.h"
1818#include " mlir/Dialect/MemRef/IR/MemRef.h"
1919#include " mlir/IR/Operation.h"
20+ #include " mlir/IR/Value.h"
21+ #include " mlir/Interfaces/SideEffectInterfaces.h"
2022#include " llvm/Support/Debug.h"
23+ #include " llvm/Support/ErrorHandling.h"
2124
2225#define DEBUG_TYPE " optimize-allocation-liveness"
2326#define DBGS () (llvm::dbgs() << ' [' << DEBUG_TYPE << " ] " )
@@ -88,6 +91,19 @@ static bool hasMemoryAllocEffect(MemoryEffectOpInterface memEffectOp) {
8891 return false ;
8992}
9093
94+ // / Extracts OpResult's with Allocate effects from given op
95+ static SmallVector<OpResult>
96+ collectAllocations (MemoryEffectOpInterface allocOp) {
97+ SmallVector<MemoryEffects::EffectInstance> effects;
98+ allocOp.getEffects (effects);
99+ SmallVector<OpResult> allocResults;
100+ for (const MemoryEffects::EffectInstance &it : effects)
101+ if (isa<MemoryEffects::Allocate>(it.getEffect ()))
102+ if (auto val = it.getValue (); val && val.getDefiningOp () == allocOp)
103+ allocResults.push_back (cast<OpResult>(val));
104+ return allocResults;
105+ }
106+
91107struct OptimizeAllocationLiveness
92108 : public bufferization::impl::OptimizeAllocationLivenessPassBase<
93109 OptimizeAllocationLiveness> {
@@ -109,7 +125,15 @@ struct OptimizeAllocationLiveness
109125 auto allocOp = memEffectOp;
110126 LDBG (" Checking alloc op: " << allocOp);
111127
112- auto deallocOp = findUserWithFreeSideEffect (allocOp->getResult (0 ));
128+ SmallVector<OpResult> allocationResults = collectAllocations (allocOp);
129+ // Multiple allocations from a single op are not considered here yet.
130+ if (allocationResults.size () != 1 )
131+ return WalkResult::advance ();
132+
133+ OpResult allocResult = allocationResults[0 ];
134+ LDBG (" On allocation result: " << allocResult);
135+
136+ auto *deallocOp = findUserWithFreeSideEffect (allocResult);
113137 if (!deallocOp || (deallocOp->getBlock () != allocOp->getBlock ())) {
114138 // The pass handles allocations that have a single dealloc op in the
115139 // same block. We also should not hoist the dealloc op out of
@@ -119,9 +143,9 @@ struct OptimizeAllocationLiveness
119143
120144 Operation *lastUser = nullptr ;
121145 const BufferViewFlowAnalysis::ValueSetT &deps =
122- analysis.resolve (allocOp-> getResult ( 0 ) );
146+ analysis.resolve (allocResult );
123147 for (auto dep : llvm::make_early_inc_range (deps)) {
124- for (auto user : dep.getUsers ()) {
148+ for (auto * user : dep.getUsers ()) {
125149 // We are looking for a non dealloc op user.
126150 // check if user is the dealloc op itself.
127151 if (user == deallocOp)
0 commit comments