11#include " mlir/Analysis/AliasAnalysis.h"
2+ #include " mlir/Analysis/Liveness.h"
23#include " mlir/IR/AsmState.h"
34#include " mlir/Dialect/Func/IR/FuncOps.h"
45#include " mlir/Dialect/Linalg/IR/Linalg.h"
@@ -90,6 +91,7 @@ class LabBufferStatsAnalysis {
9091 // Step 2: 找 buffer owner,并计算 def/lastUse/size
9192 func.walk ([&](Operation *op) {
9293 Value result;
94+ mlir::Liveness liveness (func);
9395
9496 if (auto allocOp = dyn_cast<memref::AllocOp>(op)) {
9597 result = allocOp.getResult ();
@@ -108,14 +110,22 @@ class LabBufferStatsAnalysis {
108110 return ; // 教学版:先跳过动态 shape
109111
110112 int def = opIndex[op];
111- int lastUse = def;
112113
113- for (OpOperand &use : result.getUses ()) {
114- Operation *user = use.getOwner ();
115- auto it = opIndex.find (user);
116- if (it != opIndex.end ())
117- lastUse = std::max (lastUse, it->second );
118- }
114+ // First version: 直接找最后一个使用点
115+ // int lastUse = def;
116+
117+ // for (OpOperand &use : result.getUses()) {
118+ // Operation *user = use.getOwner();
119+ // auto it = opIndex.find(user);
120+ // if (it != opIndex.end())
121+ // lastUse = std::max(lastUse, it->second);
122+ // }
123+
124+ auto indexOp = findLastSemanticUser (func, liveness, result);
125+ if (!indexOp)
126+ return ; // 没有语义使用点?先跳过
127+ int lastUse = opIndex[indexOp];
128+
119129
120130 buffers.push_back (BufferRecord{
121131 result,
@@ -168,6 +178,31 @@ class LabBufferStatsAnalysis {
168178 return numElems * elemBytes;
169179 }
170180
181+ static Operation *findLastSemanticUser (func::FuncOp funcOp,
182+ mlir::Liveness &liveness,
183+ Value value) {
184+ Operation *lastUser = nullptr ;
185+
186+ funcOp.walk ([&](Operation *op) {
187+ bool usesValue = false ;
188+ for (Value operand : op->getOperands ()) {
189+ if (operand == value) {
190+ usesValue = true ;
191+ break ;
192+ }
193+ }
194+ if (!usesValue)
195+ return ;
196+
197+ // 如果这个 op 使用了 value,并且 op 之后 value 已死,
198+ // 就把它视为“最后语义使用点”的候选。
199+ if (liveness.isDeadAfter (value, op))
200+ lastUser = op;
201+ });
202+
203+ return lastUser;
204+ }
205+
171206 static bool isBufferOwner (Value v) {
172207 Operation *defOp = v.getDefiningOp ();
173208 return isa_and_nonnull<memref::AllocOp, memref::AllocaOp>(defOp);
0 commit comments