@@ -29,11 +29,16 @@ static bool isKnownControlFlowInterface(Operation *op) {
29
29
// / Check if the size of the allocation is less than the given size. The
30
30
// / transformation is only applied to small buffers since large buffers could
31
31
// / exceed the stack space.
32
- static bool isSmallAlloc (Value alloc, unsigned maximumSizeInBytes) {
32
+ static bool isSmallAlloc (Value alloc, unsigned maximumSizeInBytes,
33
+ unsigned bitwidthOfIndexType) {
33
34
auto type = alloc.getType ().dyn_cast <ShapedType>();
34
35
if (!type || !type.hasStaticShape ())
35
36
return false ;
36
- return type.getSizeInBits () < maximumSizeInBytes * 8 ;
37
+ // For index types, use the provided size, as the type does not know.
38
+ unsigned int bitwidth = type.getElementType ().isIndex ()
39
+ ? bitwidthOfIndexType
40
+ : type.getElementTypeBitWidth ();
41
+ return type.getNumElements () * bitwidth <= maximumSizeInBytes * 8 ;
37
42
}
38
43
39
44
// / Checks whether the given aliases leave the allocation scope.
@@ -281,14 +286,15 @@ class BufferPlacementPromotion : BufferPlacementTransformationBase {
281
286
: BufferPlacementTransformationBase(op) {}
282
287
283
288
// / Promote buffers to stack-based allocations.
284
- void promote (unsigned maximumSize) {
289
+ void promote (unsigned maximumSize, unsigned bitwidthOfIndexType ) {
285
290
for (BufferPlacementAllocs::AllocEntry &entry : allocs) {
286
291
Value alloc = std::get<0 >(entry);
292
+ Operation *dealloc = std::get<1 >(entry);
287
293
// Checking several requirements to transform an AllocOp into an AllocaOp.
288
294
// The transformation is done if the allocation is limited to a given
289
295
// size. Furthermore, a deallocation must not be defined for this
290
296
// allocation entry and a parent allocation scope must exist.
291
- if (!isSmallAlloc (alloc, maximumSize) || std::get< 1 >(entry) ||
297
+ if (!isSmallAlloc (alloc, maximumSize, bitwidthOfIndexType ) || dealloc ||
292
298
!hasAllocationScope (alloc, aliases))
293
299
continue ;
294
300
@@ -340,17 +346,17 @@ struct BufferLoopHoistingPass : BufferLoopHoistingBase<BufferLoopHoistingPass> {
340
346
struct PromoteBuffersToStackPass
341
347
: PromoteBuffersToStackBase<PromoteBuffersToStackPass> {
342
348
343
- PromoteBuffersToStackPass (unsigned maxAllocSizeInBytes)
344
- : maximumSize(maxAllocSizeInBytes) {}
349
+ PromoteBuffersToStackPass (unsigned maxAllocSizeInBytes,
350
+ unsigned bitwidthOfIndexType) {
351
+ this ->maxAllocSizeInBytes = maxAllocSizeInBytes;
352
+ this ->bitwidthOfIndexType = bitwidthOfIndexType;
353
+ }
345
354
346
355
void runOnFunction () override {
347
356
// Move all allocation nodes and convert candidates into allocas.
348
357
BufferPlacementPromotion optimizer (getFunction ());
349
- optimizer.promote (maximumSize );
358
+ optimizer.promote (this -> maxAllocSizeInBytes , this -> bitwidthOfIndexType );
350
359
}
351
-
352
- private:
353
- const unsigned maximumSize;
354
360
};
355
361
356
362
} // end anonymous namespace
@@ -364,6 +370,8 @@ std::unique_ptr<Pass> mlir::createBufferLoopHoistingPass() {
364
370
}
365
371
366
372
std::unique_ptr<Pass>
367
- mlir::createPromoteBuffersToStackPass (unsigned maxAllocSizeInBytes) {
368
- return std::make_unique<PromoteBuffersToStackPass>(maxAllocSizeInBytes);
373
+ mlir::createPromoteBuffersToStackPass (unsigned maxAllocSizeInBytes,
374
+ unsigned bitwidthOfIndexType) {
375
+ return std::make_unique<PromoteBuffersToStackPass>(maxAllocSizeInBytes,
376
+ bitwidthOfIndexType);
369
377
}
0 commit comments