aboutsummaryrefslogtreecommitdiff
path: root/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp')
-rw-r--r--mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp33
1 files changed, 32 insertions, 1 deletions
diff --git a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
index d705d8d4..20be50c 100644
--- a/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/LivenessAnalysis.cpp
@@ -137,7 +137,8 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
// Populating such blocks in `blocks`.
bool mayLive = false;
SmallVector<Block *, 4> blocks;
- if (isa<RegionBranchOpInterface>(op)) {
+ 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
// branch operation has a return value, and the non-forwarded operand can
@@ -165,6 +166,25 @@ 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 &region : 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
@@ -224,6 +244,15 @@ 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,
@@ -231,6 +260,8 @@ void LivenessAnalysis::visitBranchOperand(OpOperand &operand) {
// 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));