[Mlir-commits] [mlir] [mlir][dataflow] Add visitBranchPropertyArgument API to SparseDataFlowAnalysis and apply it in LivenessAnalysis/RemoveDeadValues (PR #169816)
lonely eagle
llvmlistbot at llvm.org
Sat Dec 27 09:03:08 PST 2025
https://github.com/linuxlonelyeagle updated https://github.com/llvm/llvm-project/pull/169816
>From 0d92e8db2519fcdf97517d0df395f509e26ee266 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Thu, 27 Nov 2025 13:56:51 +0000
Subject: [PATCH 01/11] add visitBranchRegionArgument interface to sparse
backward dataflow analysis and apply it to LivenessAnalysis.
---
.../mlir/Analysis/DataFlow/LivenessAnalysis.h | 2 ++
.../mlir/Analysis/DataFlow/SparseAnalysis.h | 2 ++
.../Analysis/DataFlow/LivenessAnalysis.cpp | 20 +++++++++++++++++++
mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 14 ++++++++++++-
.../XeGPU/Transforms/XeGPUPropagateLayout.cpp | 2 ++
.../TestSparseBackwardDataFlowAnalysis.cpp | 2 ++
6 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
index cf1fd6e2d48ca..80d63ad5715ac 100644
--- a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
@@ -87,6 +87,8 @@ class LivenessAnalysis : public SparseBackwardDataFlowAnalysis<Liveness> {
void visitCallOperand(OpOperand &operand) override;
void setToExitState(Liveness *lattice) override;
+
+ void visitBranchRegionArgument(BlockArgument &argument) override;
};
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
index 360d3c7e62000..097da72fb6bb3 100644
--- a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
@@ -431,6 +431,8 @@ class AbstractSparseBackwardDataFlowAnalysis : public DataFlowAnalysis {
// Visit operands on branch instructions that are not forwarded.
virtual void visitBranchOperand(OpOperand &operand) = 0;
+ virtual void visitBranchRegionArgument(BlockArgument &argument) = 0;
+
// Visit operands on call instructions that are not forwarded.
virtual void visitCallOperand(OpOperand &operand) = 0;
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index 20be50c8e8a5b..69c945e83c141 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -303,6 +303,26 @@ void LivenessAnalysis::visitCallOperand(OpOperand &operand) {
propagateIfChanged(operandLiveness, operandLiveness->markLive());
}
+void LivenessAnalysis::visitBranchRegionArgument(BlockArgument &blockArgument) {
+ Operation *parentOp = blockArgument.getOwner()->getParentOp();
+ LDBG() << "Visiting branch region argument: " << blockArgument
+ << "in op: " << OpWithFlags(parentOp, OpPrintingFlags().skipRegions());
+ Liveness *argumentLiveness = getLatticeElement(blockArgument);
+ SmallVector<Liveness *> parentResultsLiveness;
+ for (Value result : parentOp->getResults())
+ parentResultsLiveness.push_back(getLatticeElement(result));
+
+ for (Liveness *resultLattice : parentResultsLiveness) {
+ if (resultLattice->isLive) {
+ LDBG() << "Marking branch argument live: " << blockArgument;
+ propagateIfChanged(argumentLiveness, argumentLiveness->markLive());
+ return;
+ }
+ }
+ (void)visitOperation(parentOp, ArrayRef<Liveness *>{argumentLiveness},
+ parentResultsLiveness);
+}
+
void LivenessAnalysis::setToExitState(Liveness *lattice) {
LDBG() << "setToExitState for lattice: " << lattice;
if (lattice->isLive) {
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index 8e63ae86753b4..d442135363392 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -599,7 +599,7 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
// All operands not forwarded to any successor. This set can be non-contiguous
// in the presence of multiple successors.
BitVector unaccounted(op->getNumOperands(), true);
-
+ SmallVector<BlockArgument> regionArguments;
for (RegionSuccessor &successor : successors) {
OperandRange operands = branch.getEntrySuccessorOperands(successor);
MutableArrayRef<OpOperand> opoperands = operandsToOpOperands(operands);
@@ -609,12 +609,24 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
*getLatticeElementFor(getProgramPointAfter(op), input));
unaccounted.reset(operand.getOperandNumber());
}
+
+ if (successor.isParent())
+ continue;
+ auto arguments = successor.getSuccessor()->getArguments();
+ for (BlockArgument argument : arguments) {
+ if (llvm::find(inputs, argument) == inputs.end()) {
+ regionArguments.push_back(argument);
+ }
+ }
}
// All operands not forwarded to regions are typically parameters of the
// branch operation itself (for example the boolean for if/else).
for (int index : unaccounted.set_bits()) {
visitBranchOperand(op->getOpOperand(index));
}
+ for (BlockArgument argument : regionArguments) {
+ visitBranchRegionArgument(argument);
+ }
}
void AbstractSparseBackwardDataFlowAnalysis::
diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
index 7fc75e7294ea3..a27abb569a38b 100644
--- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
+++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
@@ -449,6 +449,8 @@ class LayoutInfoPropagation
void visitCallOperand(OpOperand &operand) override {};
+ void visitBranchRegionArgument(BlockArgument &argument) override {};
+
void visitExternalCall(CallOpInterface call,
ArrayRef<LayoutInfoLattice *> operands,
ArrayRef<const LayoutInfoLattice *> results) override {
diff --git a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
index 0bdb7c25c3b5f..c7c2e68e9d95d 100644
--- a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
+++ b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
@@ -82,6 +82,8 @@ class WrittenToAnalysis : public SparseBackwardDataFlowAnalysis<WrittenTo> {
void visitCallOperand(OpOperand &operand) override;
+ void visitBranchRegionArgument(BlockArgument &argument) override {}
+
void visitExternalCall(CallOpInterface call, ArrayRef<WrittenTo *> operands,
ArrayRef<const WrittenTo *> results) override;
>From d48c19bfc4170bc65b9624d3d52ce87e9162451b Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Thu, 27 Nov 2025 14:28:51 +0000
Subject: [PATCH 02/11] rebase main and add test.
---
.../Analysis/DataFlow/LivenessAnalysis.cpp | 32 -------------------
mlir/test/Transforms/remove-dead-values.mlir | 17 ++++++++++
2 files changed, 17 insertions(+), 32 deletions(-)
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index 69c945e83c141..70ee411b03c99 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -137,7 +137,6 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
// Populating such blocks in `blocks`.
bool mayLive = false;
SmallVector<Block *, 4> blocks;
- SmallVector<BlockArgument> argumentNotOperand;
if (auto regionBranchOp = dyn_cast<RegionBranchOpInterface>(op)) {
if (op->getNumResults() != 0) {
// This mark value of type 1.c liveness as may live, because the region
@@ -166,25 +165,6 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
blocks.push_back(&block);
}
}
-
- // In the block of the successor block argument of RegionBranchOpInterface,
- // there may be arguments of RegionBranchOpInterface, such as the IV of
- // scf.forOp. Explicitly set this argument to live.
- for (Region ®ion : op->getRegions()) {
- SmallVector<RegionSuccessor> successors;
- regionBranchOp.getSuccessorRegions(region, successors);
- for (RegionSuccessor successor : successors) {
- if (successor.isParent())
- continue;
- auto arguments = successor.getSuccessor()->getArguments();
- ValueRange regionInputs = successor.getSuccessorInputs();
- for (auto argument : arguments) {
- if (llvm::find(regionInputs, argument) == regionInputs.end()) {
- argumentNotOperand.push_back(argument);
- }
- }
- }
- }
} else if (isa<BranchOpInterface>(op)) {
// We cannot track all successor blocks of the branch operation(More
// specifically, it's the successor's successor). Additionally, different
@@ -244,24 +224,12 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
Liveness *operandLiveness = getLatticeElement(operand.get());
LDBG() << "Marking branch operand live: " << operand.get();
propagateIfChanged(operandLiveness, operandLiveness->markLive());
- for (BlockArgument argument : argumentNotOperand) {
- Liveness *argumentLiveness = getLatticeElement(argument);
- LDBG() << "Marking RegionBranchOp's argument live: " << argument;
- // TODO: this is overly conservative: we should be able to eliminate
- // unused values in a RegionBranchOpInterface operation but that may
- // requires removing operation results which is beyond current
- // capabilities of this pass right now.
- propagateIfChanged(argumentLiveness, argumentLiveness->markLive());
- }
}
// Now that we have checked for memory-effecting ops in the blocks of concern,
// we will simply visit the op with this non-forwarded operand to potentially
// mark it "live" due to type (1.a/3) liveness.
SmallVector<Liveness *, 4> operandLiveness;
- operandLiveness.push_back(getLatticeElement(operand.get()));
- for (BlockArgument argument : argumentNotOperand)
- operandLiveness.push_back(getLatticeElement(argument));
SmallVector<const Liveness *, 4> resultsLiveness;
for (const Value result : op->getResults())
resultsLiveness.push_back(getLatticeElement(result));
diff --git a/mlir/test/Transforms/remove-dead-values.mlir b/mlir/test/Transforms/remove-dead-values.mlir
index 71306676d48e9..bd730915c6dcd 100644
--- a/mlir/test/Transforms/remove-dead-values.mlir
+++ b/mlir/test/Transforms/remove-dead-values.mlir
@@ -714,3 +714,20 @@ func.func private @remove_dead_branch_op(%c: i1, %arg0: i64, %arg1: i64) -> (i64
^bb2:
return %arg1 : i64
}
+
+// -----
+
+// CHECK-LABEL: func @affine_loop_no_use_iv_has_side_effect_op
+func.func @affine_loop_no_use_iv_has_side_effect_op() {
+ %c1 = arith.constant 1 : index
+ %alloc = memref.alloc() : memref<10xindex>
+ affine.for %arg0 = 0 to 79 {
+ memref.store %c1, %alloc[%c1] : memref<10xindex>
+ }
+// CHECK: %[[C1:.*]] = arith.constant 1 : index
+// CHECK: %[[ALLOC:.*]] = memref.alloc() : memref<10xindex>
+// CHECK: affine.for %[[VAL_0:.*]] = 0 to 79 {
+// CHECK: memref.store %[[C1]], %[[ALLOC]]{{\[}}%[[C1]]] : memref<10xindex>
+// CHECK: }
+ return
+}
>From b828788bca2ccb0bdf11b9475f63c64405eea655 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Fri, 28 Nov 2025 08:51:21 +0000
Subject: [PATCH 03/11] add test-liveness-analysis test.
---
.../DataFlow/test-liveness-analysis.mlir | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir b/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir
index 768f1cfcb3d02..f92c3ff7c46a8 100644
--- a/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir
+++ b/mlir/test/Analysis/DataFlow/test-liveness-analysis.mlir
@@ -315,3 +315,28 @@ func.func @dead_block() {
^bb4:
return
}
+
+// -----
+
+// CHECK-LABEL: test_tag: for:
+// CHECK-NEXT: region: #0:
+// CHECK-NEXT: argument: #0: live
+func.func @affine_loop_no_use_iv_has_side_effect_op() {
+ %c1 = arith.constant 1 : index
+ %alloc = memref.alloc() : memref<10xindex>
+ affine.for %arg0 = 0 to 79 {
+ memref.store %c1, %alloc[%c1] : memref<10xindex>
+ } {tag = "for"}
+ return
+}
+
+// -----
+
+// CHECK-LABEL: test_tag: for:
+// CHECK-NEXT: region: #0:
+// CHECK-NEXT: argument: #0: not live
+func.func @affine_loop_no_use_iv() {
+ affine.for %arg0 = 0 to 79 {
+ } {tag = "for"}
+ return
+}
>From d83d7287737036426eb18e20c292c6358cb76414 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Mon, 1 Dec 2025 01:58:37 +0000
Subject: [PATCH 04/11] update code.
---
mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp | 2 +-
mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index 70ee411b03c99..f7c32be572bd0 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -276,7 +276,7 @@ void LivenessAnalysis::visitBranchRegionArgument(BlockArgument &blockArgument) {
LDBG() << "Visiting branch region argument: " << blockArgument
<< "in op: " << OpWithFlags(parentOp, OpPrintingFlags().skipRegions());
Liveness *argumentLiveness = getLatticeElement(blockArgument);
- SmallVector<Liveness *> parentResultsLiveness;
+ SmallVector<Liveness *, 4> parentResultsLiveness;
for (Value result : parentOp->getResults())
parentResultsLiveness.push_back(getLatticeElement(result));
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index d442135363392..7fd8a97f88a17 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -612,9 +612,10 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
if (successor.isParent())
continue;
- auto arguments = successor.getSuccessor()->getArguments();
+ MutableArrayRef<BlockArgument> arguments =
+ successor.getSuccessor()->getArguments();
for (BlockArgument argument : arguments) {
- if (llvm::find(inputs, argument) == inputs.end()) {
+ if (!llvm::is_contained(inputs, argument)) {
regionArguments.push_back(argument);
}
}
>From 6ff0ed62e7394f5b01145b8c0274b270eab42524 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Mon, 1 Dec 2025 08:02:58 +0000
Subject: [PATCH 05/11] add comment.
---
mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index 7fd8a97f88a17..a2b5c75ea90f3 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -615,6 +615,8 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
MutableArrayRef<BlockArgument> arguments =
successor.getSuccessor()->getArguments();
for (BlockArgument argument : arguments) {
+ // Visit property blockArgument of RegionBranchOp which isn't "control
+ // flow block arguments". For example, the IV of a loop.
if (!llvm::is_contained(inputs, argument)) {
regionArguments.push_back(argument);
}
>From bb94dfb598fb58ba4f861c1bcab65bec2ad38fa0 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Mon, 1 Dec 2025 17:51:13 +0000
Subject: [PATCH 06/11] reserve parentResultsLiveness.
---
mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index f7c32be572bd0..5c90a5f14540b 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -276,7 +276,8 @@ void LivenessAnalysis::visitBranchRegionArgument(BlockArgument &blockArgument) {
LDBG() << "Visiting branch region argument: " << blockArgument
<< "in op: " << OpWithFlags(parentOp, OpPrintingFlags().skipRegions());
Liveness *argumentLiveness = getLatticeElement(blockArgument);
- SmallVector<Liveness *, 4> parentResultsLiveness;
+ SmallVector<Liveness *> parentResultsLiveness;
+ parentResultsLiveness.reserve(parentOp->getNumResults());
for (Value result : parentOp->getResults())
parentResultsLiveness.push_back(getLatticeElement(result));
>From 3a2ede3c72c22295b5a7c2868911a43eb4d9712e Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Thu, 18 Dec 2025 10:16:27 +0000
Subject: [PATCH 07/11] add
operandLiveness.push_back(getLatticeElement(operand.get()));
---
mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index 5c90a5f14540b..a43ac15ce65a6 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -230,6 +230,7 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
// we will simply visit the op with this non-forwarded operand to potentially
// mark it "live" due to type (1.a/3) liveness.
SmallVector<Liveness *, 4> operandLiveness;
+ operandLiveness.push_back(getLatticeElement(operand.get()));
SmallVector<const Liveness *, 4> resultsLiveness;
for (const Value result : op->getResults())
resultsLiveness.push_back(getLatticeElement(result));
>From 82d4d4f0c095840c9ff6e56ef1b7175a1efce0c7 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Sat, 27 Dec 2025 12:17:21 +0000
Subject: [PATCH 08/11] basic change bug test fail.
---
.../Analysis/DataFlow/IntegerRangeAnalysis.h | 3 ++
.../mlir/Analysis/DataFlow/LivenessAnalysis.h | 2 +-
.../mlir/Analysis/DataFlow/SparseAnalysis.h | 19 +++++++++++-
.../DataFlow/IntegerRangeAnalysis.cpp | 31 ++++++++++---------
.../Analysis/DataFlow/LivenessAnalysis.cpp | 3 +-
mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 25 ++++++++++++---
.../XeGPU/Transforms/XeGPUPropagateLayout.cpp | 2 +-
.../TestSparseBackwardDataFlowAnalysis.cpp | 2 +-
8 files changed, 62 insertions(+), 25 deletions(-)
diff --git a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
index 4975cedb282e4..c3db94e0f9a26 100644
--- a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
@@ -70,6 +70,9 @@ class IntegerRangeAnalysis
visitNonControlFlowArguments(Operation *op, const RegionSuccessor &successor,
ArrayRef<IntegerValueRangeLattice *> argLattices,
unsigned firstIndex) override;
+
+
+ void visitBranchPropertyArgument(SmallVector<BlockArgument> arguments, ArrayRef<IntegerValueRangeLattice *> argLattices) override;
};
/// Succeeds if an op can be converted to its unsigned equivalent without
diff --git a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
index 80d63ad5715ac..3edee8c60f188 100644
--- a/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/LivenessAnalysis.h
@@ -88,7 +88,7 @@ class LivenessAnalysis : public SparseBackwardDataFlowAnalysis<Liveness> {
void setToExitState(Liveness *lattice) override;
- void visitBranchRegionArgument(BlockArgument &argument) override;
+ void visitBranchPropertyArgument(BlockArgument &argument) override;
};
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
index 097da72fb6bb3..9f542773e0a20 100644
--- a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
@@ -217,6 +217,10 @@ class AbstractSparseForwardDataFlowAnalysis : public DataFlowAnalysis {
Operation *op, const RegionSuccessor &successor,
ArrayRef<AbstractSparseLattice *> argLattices, unsigned firstIndex) = 0;
+ virtual void visitBranchPropertyArgumentImpl(
+ SmallVector<BlockArgument> arguments,
+ ArrayRef<AbstractSparseLattice *> argLattices) = 0;
+
/// Get the lattice element of a value.
virtual AbstractSparseLattice *getLatticeElement(Value value) = 0;
@@ -335,6 +339,11 @@ class SparseForwardDataFlowAnalysis
firstIndex + successor.getSuccessorInputs().size()));
}
+ virtual void visitBranchPropertyArgument(SmallVector<BlockArgument> arguments,
+ ArrayRef<StateT *> argLattices) {
+ setAllToEntryStates(argLattices);
+ }
+
protected:
/// Get the lattice element for a value.
StateT *getLatticeElement(Value value) override {
@@ -391,6 +400,14 @@ class SparseForwardDataFlowAnalysis
argLattices.size()},
firstIndex);
}
+ void visitBranchPropertyArgumentImpl(
+ SmallVector<BlockArgument> arguments,
+ ArrayRef<AbstractSparseLattice *> argLattices) override {
+ visitBranchPropertyArgument(
+ arguments, {reinterpret_cast<StateT *const *>(argLattices.begin()),
+ argLattices.size()});
+ }
+
void setToEntryState(AbstractSparseLattice *lattice) override {
return setToEntryState(reinterpret_cast<StateT *>(lattice));
}
@@ -431,7 +448,7 @@ class AbstractSparseBackwardDataFlowAnalysis : public DataFlowAnalysis {
// Visit operands on branch instructions that are not forwarded.
virtual void visitBranchOperand(OpOperand &operand) = 0;
- virtual void visitBranchRegionArgument(BlockArgument &argument) = 0;
+ virtual void visitBranchPropertyArgument(BlockArgument &argument) = 0;
// Visit operands on call instructions that are not forwarded.
virtual void visitCallOperand(OpOperand &operand) = 0;
diff --git a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
index a93e605445465..912c6ff4327e7 100644
--- a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
@@ -180,6 +180,14 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
return;
}
+ return SparseForwardDataFlowAnalysis::visitNonControlFlowArguments(
+ op, successor, argLattices, firstIndex);
+}
+
+void IntegerRangeAnalysis::visitBranchPropertyArgument(
+ SmallVector<BlockArgument> arguments,
+ ArrayRef<IntegerValueRangeLattice *> argLattices) {
+
/// Given a lower bound, upper bound, or step from a LoopLikeInterface return
/// the lower/upper bound for that result if possible.
auto getLoopBoundFromFold = [&](OpFoldResult loopBound, Type boundType,
@@ -202,21 +210,16 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
: APInt::getSignedMinValue(width);
};
+ Operation *op = arguments.front().getOwner()->getParentOp();
// Infer bounds for loop arguments that have static bounds
if (auto loop = dyn_cast<LoopLikeOpInterface>(op)) {
- std::optional<llvm::SmallVector<Value>> maybeIvs =
- loop.getLoopInductionVars();
- if (!maybeIvs) {
- return SparseForwardDataFlowAnalysis ::visitNonControlFlowArguments(
- op, successor, argLattices, firstIndex);
- }
// This shouldn't be returning nullopt if there are indunction variables.
SmallVector<OpFoldResult> lowerBounds = *loop.getLoopLowerBounds();
SmallVector<OpFoldResult> upperBounds = *loop.getLoopUpperBounds();
SmallVector<OpFoldResult> steps = *loop.getLoopSteps();
- for (auto [iv, lowerBound, upperBound, step] :
- llvm::zip_equal(*maybeIvs, lowerBounds, upperBounds, steps)) {
- Block *block = iv.getParentBlock();
+ for (auto [iv, lowerBound, upperBound, step, argLattice] : llvm::zip_equal(
+ arguments, lowerBounds, upperBounds, steps, argLattices)) {
+ Block *block = iv.getOwner();
APInt min = getLoopBoundFromFold(lowerBound, iv.getType(), block,
/*getUpper=*/false);
APInt max = getLoopBoundFromFold(upperBound, iv.getType(), block,
@@ -237,14 +240,12 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
// resulting range is meaningless and should not be used in further
// inferences.
if (max.sge(min)) {
- IntegerValueRangeLattice *ivEntry = getLatticeElement(iv);
auto ivRange = ConstantIntRanges::fromSigned(min, max);
- propagateIfChanged(ivEntry, ivEntry->join(IntegerValueRange{ivRange}));
+ propagateIfChanged(argLattice,
+ argLattice->join(IntegerValueRange{ivRange}));
}
}
return;
}
-
- return SparseForwardDataFlowAnalysis::visitNonControlFlowArguments(
- op, successor, argLattices, firstIndex);
-}
+ // setAllToEntryStates(argLattices);
+}
\ No newline at end of file
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index a43ac15ce65a6..5cd2a250bf334 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -272,7 +272,8 @@ void LivenessAnalysis::visitCallOperand(OpOperand &operand) {
propagateIfChanged(operandLiveness, operandLiveness->markLive());
}
-void LivenessAnalysis::visitBranchRegionArgument(BlockArgument &blockArgument) {
+void LivenessAnalysis::visitBranchPropertyArgument(
+ BlockArgument &blockArgument) {
Operation *parentOp = blockArgument.getOwner()->getParentOp();
LDBG() << "Visiting branch region argument: " << blockArgument
<< "in op: " << OpWithFlags(parentOp, OpPrintingFlags().skipRegions());
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index a2b5c75ea90f3..06299a91e6597 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -320,11 +320,26 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
if (!inputs.empty())
firstIndex = cast<BlockArgument>(inputs.front()).getArgNumber();
Region *region = point->getBlock()->getParent();
+ auto nonControlFlowArguments =
+ region->getArguments().slice(firstIndex, inputs.size());
visitNonControlFlowArgumentsImpl(
- branch,
- RegionSuccessor(region, region->getArguments().slice(
- firstIndex, inputs.size())),
- lattices, firstIndex);
+ branch, RegionSuccessor(region, nonControlFlowArguments), lattices,
+ firstIndex);
+ MutableArrayRef<BlockArgument> propertyArguments =
+ nonControlFlowArguments.empty()
+ ? region->getArguments()
+ : region->getArguments().slice(0, firstIndex);
+ SmallVector<AbstractSparseLattice *> propertyArgumentLattices;
+ propertyArgumentLattices.reserve(propertyArguments.size());
+ for (BlockArgument argument : propertyArguments) {
+ AbstractSparseLattice *propertyArgumentLattice =
+ getLatticeElement(argument);
+ propertyArgumentLattices.push_back(propertyArgumentLattice);
+ }
+ if (!propertyArguments.empty())
+ visitBranchPropertyArgumentImpl(
+ {propertyArguments.begin(), propertyArguments.end()},
+ propertyArgumentLattices);
}
}
@@ -628,7 +643,7 @@ void AbstractSparseBackwardDataFlowAnalysis::visitRegionSuccessors(
visitBranchOperand(op->getOpOperand(index));
}
for (BlockArgument argument : regionArguments) {
- visitBranchRegionArgument(argument);
+ visitBranchPropertyArgument(argument);
}
}
diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
index a27abb569a38b..ae2fbf0ba0a92 100644
--- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
+++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp
@@ -449,7 +449,7 @@ class LayoutInfoPropagation
void visitCallOperand(OpOperand &operand) override {};
- void visitBranchRegionArgument(BlockArgument &argument) override {};
+ void visitBranchPropertyArgument(BlockArgument &argument) override {};
void visitExternalCall(CallOpInterface call,
ArrayRef<LayoutInfoLattice *> operands,
diff --git a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
index c7c2e68e9d95d..076231d0e22db 100644
--- a/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
+++ b/mlir/test/lib/Analysis/DataFlow/TestSparseBackwardDataFlowAnalysis.cpp
@@ -82,7 +82,7 @@ class WrittenToAnalysis : public SparseBackwardDataFlowAnalysis<WrittenTo> {
void visitCallOperand(OpOperand &operand) override;
- void visitBranchRegionArgument(BlockArgument &argument) override {}
+ void visitBranchPropertyArgument(BlockArgument &argument) override {}
void visitExternalCall(CallOpInterface call, ArrayRef<WrittenTo *> operands,
ArrayRef<const WrittenTo *> results) override;
>From 236adceab74198a2a7677f0afe52d88f7e0aa980 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Sat, 27 Dec 2025 15:19:00 +0000
Subject: [PATCH 09/11] rebase main and clang-format.
---
mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
index c3db94e0f9a26..5f280be4445d7 100644
--- a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
@@ -71,8 +71,9 @@ class IntegerRangeAnalysis
ArrayRef<IntegerValueRangeLattice *> argLattices,
unsigned firstIndex) override;
-
- void visitBranchPropertyArgument(SmallVector<BlockArgument> arguments, ArrayRef<IntegerValueRangeLattice *> argLattices) override;
+ void visitBranchPropertyArgument(
+ SmallVector<BlockArgument> arguments,
+ ArrayRef<IntegerValueRangeLattice *> argLattices) override;
};
/// Succeeds if an op can be converted to its unsigned equivalent without
>From 3502e5ab86a6c958ac9aa41146b4f03942f03693 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Sat, 27 Dec 2025 16:50:17 +0000
Subject: [PATCH 10/11] test success.
---
.../DataFlow/IntegerRangeAnalysis.cpp | 6 -----
mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp | 22 ++++++++++++++++---
2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
index 912c6ff4327e7..6ad3d3c81b403 100644
--- a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
@@ -177,11 +177,7 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
};
inferrable.inferResultRangesFromOptional(argRanges, joinCallback);
- return;
}
-
- return SparseForwardDataFlowAnalysis::visitNonControlFlowArguments(
- op, successor, argLattices, firstIndex);
}
void IntegerRangeAnalysis::visitBranchPropertyArgument(
@@ -245,7 +241,5 @@ void IntegerRangeAnalysis::visitBranchPropertyArgument(
argLattice->join(IntegerValueRange{ivRange}));
}
}
- return;
}
- // setAllToEntryStates(argLattices);
}
\ No newline at end of file
diff --git a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
index 06299a91e6597..05998285251ac 100644
--- a/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/SparseAnalysis.cpp
@@ -311,6 +311,21 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
if (!point->isBlockStart()) {
if (!inputs.empty())
firstIndex = cast<OpResult>(inputs.front()).getResultNumber();
+
+ Region *region = point->getBlock()->getParent();
+ MutableArrayRef<BlockArgument> propertyArguments =
+ region->getArguments().drop_back(inputs.size());
+ SmallVector<AbstractSparseLattice *> propertyArgumentLattices;
+ propertyArgumentLattices.reserve(propertyArguments.size());
+ for (BlockArgument argument : propertyArguments) {
+ AbstractSparseLattice *propertyArgumentLattice =
+ getLatticeElement(argument);
+ propertyArgumentLattices.push_back(propertyArgumentLattice);
+ }
+ if (!propertyArguments.empty())
+ visitBranchPropertyArgumentImpl(
+ {propertyArguments.begin(), propertyArguments.end()},
+ propertyArgumentLattices);
visitNonControlFlowArgumentsImpl(
branch,
RegionSuccessor(
@@ -322,9 +337,7 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
Region *region = point->getBlock()->getParent();
auto nonControlFlowArguments =
region->getArguments().slice(firstIndex, inputs.size());
- visitNonControlFlowArgumentsImpl(
- branch, RegionSuccessor(region, nonControlFlowArguments), lattices,
- firstIndex);
+
MutableArrayRef<BlockArgument> propertyArguments =
nonControlFlowArguments.empty()
? region->getArguments()
@@ -340,6 +353,9 @@ void AbstractSparseForwardDataFlowAnalysis::visitRegionSuccessors(
visitBranchPropertyArgumentImpl(
{propertyArguments.begin(), propertyArguments.end()},
propertyArgumentLattices);
+ visitNonControlFlowArgumentsImpl(
+ branch, RegionSuccessor(region, nonControlFlowArguments), lattices,
+ firstIndex);
}
}
>From c12bd52956a788ce6c6933ceafcc853fdea4bc14 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Sat, 27 Dec 2025 17:02:48 +0000
Subject: [PATCH 11/11] add simple doc and fix nit.
---
.../mlir/Analysis/DataFlow/IntegerRangeAnalysis.h | 2 +-
mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h | 10 +++++++---
mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp | 4 ++--
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
index 5f280be4445d7..f0c517bf75eba 100644
--- a/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h
@@ -72,7 +72,7 @@ class IntegerRangeAnalysis
unsigned firstIndex) override;
void visitBranchPropertyArgument(
- SmallVector<BlockArgument> arguments,
+ ArrayRef<BlockArgument> arguments,
ArrayRef<IntegerValueRangeLattice *> argLattices) override;
};
diff --git a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
index 9f542773e0a20..5b0c3249fc7fc 100644
--- a/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
+++ b/mlir/include/mlir/Analysis/DataFlow/SparseAnalysis.h
@@ -218,7 +218,7 @@ class AbstractSparseForwardDataFlowAnalysis : public DataFlowAnalysis {
ArrayRef<AbstractSparseLattice *> argLattices, unsigned firstIndex) = 0;
virtual void visitBranchPropertyArgumentImpl(
- SmallVector<BlockArgument> arguments,
+ ArrayRef<BlockArgument> arguments,
ArrayRef<AbstractSparseLattice *> argLattices) = 0;
/// Get the lattice element of a value.
@@ -339,7 +339,9 @@ class SparseForwardDataFlowAnalysis
firstIndex + successor.getSuccessorInputs().size()));
}
- virtual void visitBranchPropertyArgument(SmallVector<BlockArgument> arguments,
+ // visitBranchPropertyArgument is used to visit the property argument of a
+ // branch op, such as the loop's IV.
+ virtual void visitBranchPropertyArgument(ArrayRef<BlockArgument> arguments,
ArrayRef<StateT *> argLattices) {
setAllToEntryStates(argLattices);
}
@@ -401,7 +403,7 @@ class SparseForwardDataFlowAnalysis
firstIndex);
}
void visitBranchPropertyArgumentImpl(
- SmallVector<BlockArgument> arguments,
+ ArrayRef<BlockArgument> arguments,
ArrayRef<AbstractSparseLattice *> argLattices) override {
visitBranchPropertyArgument(
arguments, {reinterpret_cast<StateT *const *>(argLattices.begin()),
@@ -448,6 +450,8 @@ class AbstractSparseBackwardDataFlowAnalysis : public DataFlowAnalysis {
// Visit operands on branch instructions that are not forwarded.
virtual void visitBranchOperand(OpOperand &operand) = 0;
+ // visitBranchPropertyArgument is used to visit the property argument of a
+ // branch op, such as the loop's IV
virtual void visitBranchPropertyArgument(BlockArgument &argument) = 0;
// Visit operands on call instructions that are not forwarded.
diff --git a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
index 6ad3d3c81b403..76dd7669af674 100644
--- a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
@@ -181,7 +181,7 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
}
void IntegerRangeAnalysis::visitBranchPropertyArgument(
- SmallVector<BlockArgument> arguments,
+ ArrayRef<BlockArgument> arguments,
ArrayRef<IntegerValueRangeLattice *> argLattices) {
/// Given a lower bound, upper bound, or step from a LoopLikeInterface return
@@ -242,4 +242,4 @@ void IntegerRangeAnalysis::visitBranchPropertyArgument(
}
}
}
-}
\ No newline at end of file
+}
More information about the Mlir-commits
mailing list