[mlir][IR] Make verifyDominanceOfContainedRegions iterative (#74428)

This commit refactors `verifyDominanceOfContainedRegions` to iterative
algorithms similar to https://reviews.llvm.org/D154925 to fix stack
overflow for deeply nested regions (e.g.
https://github.com/llvm/circt/issues/5316). There should be no
functional change except that this could result in slightly different
order of verification.
This commit is contained in:
Hideto Ueno 2023-12-05 18:06:28 +09:00 committed by GitHub
parent eaba81fd24
commit 892abd34d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -378,39 +378,39 @@ static void diagnoseInvalidOperandDominance(Operation &op, unsigned operandNo) {
LogicalResult
OperationVerifier::verifyDominanceOfContainedRegions(Operation &op,
DominanceInfo &domInfo) {
for (Region &region : op.getRegions()) {
// Verify the dominance of each of the held operations.
for (Block &block : region) {
// Dominance is only meaningful inside reachable blocks.
bool isReachable = domInfo.isReachableFromEntry(&block);
llvm::SmallVector<Operation *, 8> worklist{&op};
while (!worklist.empty()) {
auto *op = worklist.pop_back_val();
for (auto &region : op->getRegions())
for (auto &block : region.getBlocks()) {
// Dominance is only meaningful inside reachable blocks.
bool isReachable = domInfo.isReachableFromEntry(&block);
for (auto &op : block) {
if (isReachable) {
// Check that operands properly dominate this use.
for (const auto &operand : llvm::enumerate(op.getOperands())) {
if (domInfo.properlyDominates(operand.value(), &op))
continue;
for (Operation &op : block) {
if (isReachable) {
// Check that operands properly dominate this use.
for (const auto &operand : llvm::enumerate(op.getOperands())) {
if (domInfo.properlyDominates(operand.value(), &op))
diagnoseInvalidOperandDominance(op, operand.index());
return failure();
}
}
// Recursively verify dominance within each operation in the block,
// even if the block itself is not reachable, or we are in a region
// which doesn't respect dominance.
if (verifyRecursively && op.getNumRegions() != 0) {
// If this operation is IsolatedFromAbove, then we'll handle it in
// the outer verification loop.
if (op.hasTrait<OpTrait::IsIsolatedFromAbove>())
continue;
diagnoseInvalidOperandDominance(op, operand.index());
return failure();
worklist.push_back(&op);
}
}
// Recursively verify dominance within each operation in the block, even
// if the block itself is not reachable, or we are in a region which
// doesn't respect dominance.
if (verifyRecursively && op.getNumRegions() != 0) {
// If this operation is IsolatedFromAbove, then we'll handle it in the
// outer verification loop.
if (op.hasTrait<OpTrait::IsIsolatedFromAbove>())
continue;
if (failed(verifyDominanceOfContainedRegions(op, domInfo)))
return failure();
}
}
}
}
return success();
}