[Mlir-commits] [mlir] [mlir] Fix liveness analysis (PR #88848)

Ivan Kulagin llvmlistbot at llvm.org
Thu May 2 07:08:19 PDT 2024


https://github.com/ikulagin updated https://github.com/llvm/llvm-project/pull/88848

>From 78c6a8d12489406504b3bf3d798dea7e9e57074f Mon Sep 17 00:00:00 2001
From: ikulagin <i.kulagin at ispras.ru>
Date: Tue, 16 Apr 2024 09:42:16 +0300
Subject: [PATCH 1/4] [mlir] Fix liveness analysis.

Signed-off-by: ikulagin <i.kulagin at ispras.ru>
---
 mlir/lib/Analysis/Liveness.cpp        | 17 +++++---
 mlir/test/Analysis/test-liveness.mlir | 56 +++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/mlir/lib/Analysis/Liveness.cpp b/mlir/lib/Analysis/Liveness.cpp
index a8e0daeabf4061..50ac7129dab87f 100644
--- a/mlir/lib/Analysis/Liveness.cpp
+++ b/mlir/lib/Analysis/Liveness.cpp
@@ -67,11 +67,18 @@ struct BlockInfoBuilder {
     // Mark all nested operation results as defined, and nested operation
     // operands as used. All defined value will be removed from the used set
     // at the end.
-    block->walk([&](Operation *op) {
-      for (Value result : op->getResults())
-        defValues.insert(result);
-      for (Value operand : op->getOperands())
-        useValues.insert(operand);
+    block->walk([&](Block *nestedBlock) {
+      if (block != nestedBlock) {
+        for (BlockArgument arg : nestedBlock->getArguments()) {
+          defValues.insert(arg);
+        }
+      }
+      for (Operation &op : *nestedBlock) {
+        for (Value result : op.getResults())
+          defValues.insert(result);
+        for (Value operand : op.getOperands())
+          useValues.insert(operand);
+      }
     });
     llvm::set_subtract(useValues, defValues);
   }
diff --git a/mlir/test/Analysis/test-liveness.mlir b/mlir/test/Analysis/test-liveness.mlir
index 8ae3d09a6cd122..17b5e7d5ae8990 100644
--- a/mlir/test/Analysis/test-liveness.mlir
+++ b/mlir/test/Analysis/test-liveness.mlir
@@ -493,3 +493,59 @@ func.func @nested_region3(
   }
   return %1 : i32
 }
+
+// -----
+
+// CHECK-LABEL: Testing : nested_region4
+
+func.func @nested_region4(%arg0: index, %arg1: index, %arg2: index) {
+  // CHECK: Block: 0
+  // CHECK-NEXT: LiveIn:
+  // CHECK-NEXT: LiveOut:
+  // CHECK-NEXT: BeginLivenessIntervals
+  // CHECK-NEXT: val_3
+  // CHECK-NEXT: %c0_i32 = arith.constant 0
+  // CHECK-NEXT: %c1_i32 = arith.constant 1
+  // CHECK-NEXT: %0 = scf.for
+  // COM: Skipping the body of the scf.for...
+  // CHECK:      val_4
+  // CHECK-NEXT: %c1_i32 = arith.constant 1
+  // CHECK-NEXT: %0 = scf.for
+  // COM: Skipping the body of the scf.for...
+  // CHECK:      // %1 = arith.addi
+  // CHECK-NEXT: val_5
+  // CHECK-NEXT: %0 = scf.for
+  // COM: Skipping the body of the scf.for...
+  // CHECK:      EndLivenessIntervals
+  // CHECK-NEXT: BeginCurrentlyLive
+  // CHECK-NEXT: %c0_i32 = arith.constant 0
+  // CHECK-SAME: arg0 at 0 arg1 at 0 arg2 at 0 val_3
+  // CHECK-NEXT: %c1_i32 = arith.constant 1
+  // CHECK-SAME: arg0 at 0 arg1 at 0 arg2 at 0 val_3 val_4
+  // CHECK-NEXT: %0 = scf.for
+  // COM: Skipping the body of the scf.for...
+  // CHECK:      arg0 at 0 arg1 at 0 arg2 at 0 val_3 val_4 val_5
+  // CHECK-NEXT: EndCurrentlyLive
+  %c0_i32 = arith.constant 0 : i32
+  %c1_i32 = arith.constant 1 : i32
+
+  %0 = scf.for %arg3 = %arg0 to %arg1 step %arg2 iter_args(%arg4 = %c0_i32) -> (i32) {
+    // CHECK-NEXT: Block: 1
+    // CHECK-NEXT: LiveIn: val_4
+    // CHECK-NEXT: LiveOut:
+    // CHECK-NEXT: BeginLivenessIntervals
+    // CHECK-NEXT: val_8
+    // CHECK-NEXT: %1 = arith.addi
+    // CHECK-NEXT: scf.yield %1
+    // CHECK-NEXT: EndLivenessIntervals
+    // CHECK-NEXT: BeginCurrentlyLive
+    // CHECK-NEXT: %1 = arith.addi
+    // CHECK-SAME: val_4 arg0 at 1 arg1 at 1 val_8
+    // CHECK-NEXT: scf.yield %1
+    // CHECK-SAME: val_8
+    // CHECK-NEXT: EndCurrentlyLive
+    %1 = arith.addi %arg4, %c1_i32 : i32
+    scf.yield %1 : i32
+  }
+  return
+}

>From 1056f592ac45970aec15c49347a037f837a61f76 Mon Sep 17 00:00:00 2001
From: ikulagin <i.kulagin at ispras.ru>
Date: Sun, 21 Apr 2024 22:13:07 +0300
Subject: [PATCH 2/4] [mlir] Changed walk to visit child blocks for each
 operation

Signed-off-by: ikulagin <i.kulagin at ispras.ru>
---
 mlir/lib/Analysis/Liveness.cpp        | 22 ++++++++++------------
 mlir/test/Analysis/test-liveness.mlir |  6 +++---
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/mlir/lib/Analysis/Liveness.cpp b/mlir/lib/Analysis/Liveness.cpp
index 50ac7129dab87f..81b9b9e61e0c65 100644
--- a/mlir/lib/Analysis/Liveness.cpp
+++ b/mlir/lib/Analysis/Liveness.cpp
@@ -67,18 +67,16 @@ struct BlockInfoBuilder {
     // Mark all nested operation results as defined, and nested operation
     // operands as used. All defined value will be removed from the used set
     // at the end.
-    block->walk([&](Block *nestedBlock) {
-      if (block != nestedBlock) {
-        for (BlockArgument arg : nestedBlock->getArguments()) {
-          defValues.insert(arg);
-        }
-      }
-      for (Operation &op : *nestedBlock) {
-        for (Value result : op.getResults())
-          defValues.insert(result);
-        for (Value operand : op.getOperands())
-          useValues.insert(operand);
-      }
+    block->walk([&](Operation *op) {
+      for (Value result : op->getResults())
+        defValues.insert(result);
+      for (Value operand : op->getOperands())
+        useValues.insert(operand);
+      for (Region &region : op->getRegions())
+        for (Block &child : region.getBlocks())
+          for (BlockArgument arg : child.getArguments()) {
+            defValues.insert(arg);
+          }
     });
     llvm::set_subtract(useValues, defValues);
   }
diff --git a/mlir/test/Analysis/test-liveness.mlir b/mlir/test/Analysis/test-liveness.mlir
index 17b5e7d5ae8990..d21aa817e85f2e 100644
--- a/mlir/test/Analysis/test-liveness.mlir
+++ b/mlir/test/Analysis/test-liveness.mlir
@@ -500,8 +500,8 @@ func.func @nested_region3(
 
 func.func @nested_region4(%arg0: index, %arg1: index, %arg2: index) {
   // CHECK: Block: 0
-  // CHECK-NEXT: LiveIn:
-  // CHECK-NEXT: LiveOut:
+  // CHECK-NEXT: LiveIn:{{ *$}}
+  // CHECK-NEXT: LiveOut:{{ *$}}
   // CHECK-NEXT: BeginLivenessIntervals
   // CHECK-NEXT: val_3
   // CHECK-NEXT: %c0_i32 = arith.constant 0
@@ -532,7 +532,7 @@ func.func @nested_region4(%arg0: index, %arg1: index, %arg2: index) {
   %0 = scf.for %arg3 = %arg0 to %arg1 step %arg2 iter_args(%arg4 = %c0_i32) -> (i32) {
     // CHECK-NEXT: Block: 1
     // CHECK-NEXT: LiveIn: val_4
-    // CHECK-NEXT: LiveOut:
+    // CHECK-NEXT: LiveOut:{{ *$}}
     // CHECK-NEXT: BeginLivenessIntervals
     // CHECK-NEXT: val_8
     // CHECK-NEXT: %1 = arith.addi

>From 00ae6f3f8bdb9ac6f33cb1fa098fc1a44ddca430 Mon Sep 17 00:00:00 2001
From: ikulagin <i.kulagin at ispras.ru>
Date: Wed, 24 Apr 2024 01:20:14 +0300
Subject: [PATCH 3/4] [mlir] Refactoring: Remove unnecessary curly braces from
 for-loop

---
 mlir/lib/Analysis/Liveness.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/mlir/lib/Analysis/Liveness.cpp b/mlir/lib/Analysis/Liveness.cpp
index 81b9b9e61e0c65..e3245d68b36998 100644
--- a/mlir/lib/Analysis/Liveness.cpp
+++ b/mlir/lib/Analysis/Liveness.cpp
@@ -74,9 +74,8 @@ struct BlockInfoBuilder {
         useValues.insert(operand);
       for (Region &region : op->getRegions())
         for (Block &child : region.getBlocks())
-          for (BlockArgument arg : child.getArguments()) {
+          for (BlockArgument arg : child.getArguments())
             defValues.insert(arg);
-          }
     });
     llvm::set_subtract(useValues, defValues);
   }

>From f23ddb6e13f2f4b1d15afbd2e5296565d5e80de1 Mon Sep 17 00:00:00 2001
From: ikulagin <i.kulagin at ispras.ru>
Date: Thu, 2 May 2024 17:07:13 +0300
Subject: [PATCH 4/4] [mlir] Minimize testcase

---
 mlir/test/Analysis/test-liveness.mlir | 67 +++++++++++++++------------
 1 file changed, 38 insertions(+), 29 deletions(-)

diff --git a/mlir/test/Analysis/test-liveness.mlir b/mlir/test/Analysis/test-liveness.mlir
index d21aa817e85f2e..07f2a2f3f7cf6c 100644
--- a/mlir/test/Analysis/test-liveness.mlir
+++ b/mlir/test/Analysis/test-liveness.mlir
@@ -502,47 +502,56 @@ func.func @nested_region4(%arg0: index, %arg1: index, %arg2: index) {
   // CHECK: Block: 0
   // CHECK-NEXT: LiveIn:{{ *$}}
   // CHECK-NEXT: LiveOut:{{ *$}}
+
   // CHECK-NEXT: BeginLivenessIntervals
-  // CHECK-NEXT: val_3
-  // CHECK-NEXT: %c0_i32 = arith.constant 0
-  // CHECK-NEXT: %c1_i32 = arith.constant 1
-  // CHECK-NEXT: %0 = scf.for
-  // COM: Skipping the body of the scf.for...
-  // CHECK:      val_4
-  // CHECK-NEXT: %c1_i32 = arith.constant 1
-  // CHECK-NEXT: %0 = scf.for
-  // COM: Skipping the body of the scf.for...
-  // CHECK:      // %1 = arith.addi
-  // CHECK-NEXT: val_5
-  // CHECK-NEXT: %0 = scf.for
-  // COM: Skipping the body of the scf.for...
-  // CHECK:      EndLivenessIntervals
+  // CHECK-NEXT: [[VAL3:[a-z0-9_]+]]{{ *:}}
+  // CHECK-NEXT: %{{.*}} = arith.constant 0
+  // CHECK-NEXT: %{{.*}} = arith.constant 1
+  // CHECK-NEXT: %{{.*}} = scf.for
+  // COM:         Skipping the body of the scf.for...
+  // CHECK:      }
+
+  // CHECK-NEXT: [[VAL4:[a-z0-9_]+]]{{ *:}}
+  // CHECK-NEXT: %{{.*}} = arith.constant 1
+  // CHECK-NEXT: %{{.*}} = scf.for
+  // COM:         Skipping the body of the scf.for...
+  // CHECK:      }
+  // CHECK-NEXT: %{{.*}} = arith.addi %{{.*}}, %{{.*}} : {{[a-z0-9]}}
+
+  // CHECK-NEXT: [[VAL5:[a-z0-9_]+]]{{ *:}}
+  // CHECK-NEXT: %{{.*}} = scf.for
+  // COM:         Skipping the body of the scf.for...
+  // CHECK:      }
+  // CHECK-NEXT: EndLivenessIntervals
+
   // CHECK-NEXT: BeginCurrentlyLive
-  // CHECK-NEXT: %c0_i32 = arith.constant 0
-  // CHECK-SAME: arg0 at 0 arg1 at 0 arg2 at 0 val_3
-  // CHECK-NEXT: %c1_i32 = arith.constant 1
-  // CHECK-SAME: arg0 at 0 arg1 at 0 arg2 at 0 val_3 val_4
-  // CHECK-NEXT: %0 = scf.for
-  // COM: Skipping the body of the scf.for...
-  // CHECK:      arg0 at 0 arg1 at 0 arg2 at 0 val_3 val_4 val_5
+  // CHECK-NEXT: %{{.*}} = arith.constant 0
+  // CHECK-SAME: arg0 at 0 arg1 at 0 arg2 at 0 [[VAL3]]
+  // CHECK-NEXT: %{{.*}} = arith.constant 1
+  // CHECK-SAME: arg0 at 0 arg1 at 0 arg2 at 0 [[VAL3]] [[VAL4]]
+  // CHECK-NEXT: %{{.*}} = scf.for
+  // COM:          Skipping the body of the scf.for...
+  // CHECK:      }
+  // CHECK-SAME: arg0 at 0 arg1 at 0 arg2 at 0 [[VAL3]] [[VAL4]] [[VAL5]]
   // CHECK-NEXT: EndCurrentlyLive
   %c0_i32 = arith.constant 0 : i32
   %c1_i32 = arith.constant 1 : i32
 
   %0 = scf.for %arg3 = %arg0 to %arg1 step %arg2 iter_args(%arg4 = %c0_i32) -> (i32) {
     // CHECK-NEXT: Block: 1
-    // CHECK-NEXT: LiveIn: val_4
+    // CHECK-NEXT: LiveIn: [[VAL4]]{{ *$}}
     // CHECK-NEXT: LiveOut:{{ *$}}
     // CHECK-NEXT: BeginLivenessIntervals
-    // CHECK-NEXT: val_8
-    // CHECK-NEXT: %1 = arith.addi
-    // CHECK-NEXT: scf.yield %1
+    // CHECK-NEXT: [[VAL8:[a-z0-9_]+]]{{ *:}}
+    // CHECK-NEXT: %{{.*}} = arith.addi
+    // CHECK-NEXT: scf.yield
     // CHECK-NEXT: EndLivenessIntervals
+
     // CHECK-NEXT: BeginCurrentlyLive
-    // CHECK-NEXT: %1 = arith.addi
-    // CHECK-SAME: val_4 arg0 at 1 arg1 at 1 val_8
-    // CHECK-NEXT: scf.yield %1
-    // CHECK-SAME: val_8
+    // CHECK-NEXT: %{{.*}} = arith.addi
+    // CHECK-SAME: [[VAL4]] arg0 at 1 arg1 at 1 [[VAL8]]
+    // CHECK-NEXT: scf.yield %{{[a-z0-9]+}}
+    // CHECK-SAME: [[VAL8]]
     // CHECK-NEXT: EndCurrentlyLive
     %1 = arith.addi %arg4, %c1_i32 : i32
     scf.yield %1 : i32



More information about the Mlir-commits mailing list