[Mlir-commits] [mlir] 6054bfa - [mlir] Support buffer hoisting on allocas

Tres Popp llvmlistbot at llvm.org
Tue May 25 05:50:13 PDT 2021


Author: Tres Popp
Date: 2021-05-25T14:50:01+02:00
New Revision: 6054bfa8132ac06a140e1896d8cdd8dc79a01bd8

URL: https://github.com/llvm/llvm-project/commit/6054bfa8132ac06a140e1896d8cdd8dc79a01bd8
DIFF: https://github.com/llvm/llvm-project/commit/6054bfa8132ac06a140e1896d8cdd8dc79a01bd8.diff

LOG: [mlir] Support buffer hoisting on allocas

This adds support for hoisting allocas in both BufferHoisting and
BufferLoopHoisting.

Differential Revision: https://reviews.llvm.org/D102681

Added: 
    

Modified: 
    mlir/lib/Transforms/BufferOptimizations.cpp
    mlir/test/Transforms/buffer-loop-hoisting.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Transforms/BufferOptimizations.cpp b/mlir/lib/Transforms/BufferOptimizations.cpp
index 7d5b84db668b..b5dad2b5d393 100644
--- a/mlir/lib/Transforms/BufferOptimizations.cpp
+++ b/mlir/lib/Transforms/BufferOptimizations.cpp
@@ -125,12 +125,19 @@ class BufferAllocationHoisting : public BufferPlacementTransformationBase {
 public:
   BufferAllocationHoisting(Operation *op)
       : BufferPlacementTransformationBase(op), dominators(op),
-        postDominators(op) {}
+        postDominators(op), scopeOp(op) {}
 
   /// Moves allocations upwards.
   void hoist() {
-    for (BufferPlacementAllocs::AllocEntry &entry : allocs) {
-      Value allocValue = std::get<0>(entry);
+    SmallVector<Value> allocsAndAllocas;
+    for (BufferPlacementAllocs::AllocEntry &entry : allocs)
+      allocsAndAllocas.push_back(std::get<0>(entry));
+    scopeOp->walk(
+        [&](memref::AllocaOp op) { allocsAndAllocas.push_back(op.memref()); });
+
+    for (auto allocValue : allocsAndAllocas) {
+      if (!StateT::shouldHoistOpType(allocValue.getDefiningOp()))
+        continue;
       Operation *definingOp = allocValue.getDefiningOp();
       assert(definingOp && "No defining op");
       auto operands = definingOp->getOperands();
@@ -222,6 +229,10 @@ class BufferAllocationHoisting : public BufferPlacementTransformationBase {
 
   /// The map storing the final placement blocks of a given alloc value.
   llvm::DenseMap<Value, Block *> placementBlocks;
+
+  /// The operation that this transformation is working on. It is used to also
+  /// gather allocas.
+  Operation *scopeOp;
 };
 
 /// A state implementation compatible with the `BufferAllocationHoisting` class
@@ -249,6 +260,11 @@ struct BufferAllocationHoistingState : BufferAllocationHoistingStateBase {
     return !BufferPlacementTransformationBase::isLoop(op);
   }
 
+  /// Returns true if the given operation should be considered for hoisting.
+  static bool shouldHoistOpType(Operation *op) {
+    return llvm::isa<memref::AllocOp>(op);
+  }
+
   /// Sets the current placement block to the given block.
   void recordMoveToDominator(Block *block) { placementBlock = block; }
 
@@ -281,6 +297,11 @@ struct BufferAllocationLoopHoistingState : BufferAllocationHoistingStateBase {
            !dominators->dominates(aliasDominatorBlock, op->getBlock());
   }
 
+  /// Returns true if the given operation should be considered for hoisting.
+  static bool shouldHoistOpType(Operation *op) {
+    return llvm::isa<memref::AllocOp, memref::AllocaOp>(op);
+  }
+
   /// Does not change the internal placement block, as we want to move
   /// operations out of loops only.
   void recordMoveToDominator(Block *block) {}

diff  --git a/mlir/test/Transforms/buffer-loop-hoisting.mlir b/mlir/test/Transforms/buffer-loop-hoisting.mlir
index c5e727b89449..1b810b217d9f 100644
--- a/mlir/test/Transforms/buffer-loop-hoisting.mlir
+++ b/mlir/test/Transforms/buffer-loop-hoisting.mlir
@@ -458,3 +458,32 @@ func @partial_hoist_multiple_loop_dependency(
 // CHECK-NEXT: {{.*}} = scf.for
 // CHECK-NEXT: %[[ALLOC1:.*]] = memref.alloc({{.*}})
 // CHECK-NEXT: {{.*}} = scf.for
+
+// -----
+
+// Test with allocas to ensure that op is also considered.
+
+// CHECK-LABEL: func @hoist_alloca
+func @hoist_alloca(
+  %lb: index,
+  %ub: index,
+  %step: index,
+  %buf: memref<2xf32>,
+  %res: memref<2xf32>) {
+  %0 = memref.alloca() : memref<2xf32>
+  %1 = scf.for %i = %lb to %ub step %step
+    iter_args(%iterBuf = %buf) -> memref<2xf32> {
+    %2 = scf.for %i2 = %lb to %ub step %step
+      iter_args(%iterBuf2 = %iterBuf) -> memref<2xf32> {
+        %3 = memref.alloca() : memref<2xf32>
+        scf.yield %0 : memref<2xf32>
+    }
+    scf.yield %0 : memref<2xf32>
+  }
+  test.copy(%1, %res) : (memref<2xf32>, memref<2xf32>)
+  return
+}
+
+//      CHECK: %[[ALLOCA0:.*]] = memref.alloca({{.*}})
+// CHECK-NEXT: %[[ALLOCA1:.*]] = memref.alloca({{.*}})
+// CHECK-NEXT: {{.*}} = scf.for


        


More information about the Mlir-commits mailing list