diff --git a/mlir/include/mlir/IR/Dominance.h b/mlir/include/mlir/IR/Dominance.h index 2536ce585b3fd..95c99bd59f7b2 100644 --- a/mlir/include/mlir/IR/Dominance.h +++ b/mlir/include/mlir/IR/Dominance.h @@ -141,8 +141,8 @@ class DominanceInfo : public detail::DominanceInfoBase { /// are in the same block and A properly dominates B within the block, or if /// the block that contains A properly dominates the block that contains B. In /// an SSACFG region, Operation A dominates Operation B in the same block if A - /// preceeds B. In a Graph region, all operations in a block dominate all - /// other operations in the same block. + /// preceeds B. In a Graph region, all operations in a block properly dominate + /// all operations in the same block. /// /// The `enclosingOpOk` flag says whether we should return true if the B op /// is enclosed by a region on A. @@ -176,9 +176,14 @@ class DominanceInfo : public detail::DominanceInfoBase { /// Return true if the specified block A properly dominates block B, i.e.: if /// block A contains block B, or if the region which contains block A also /// contains block B or some parent of block B and block A dominates that - /// block in that kind of region. In an SSACFG region, block A dominates - /// block B if all control flow paths from the entry block to block B flow - /// through block A. In a Graph region, all blocks dominate all other blocks. + /// block in that kind of region. + /// + /// In an SSACFG region, block A dominates block B if all control flow paths + /// from the entry block to block B flow through block A. + /// + /// Graph regions have only a single block. To be consistent with "proper + /// dominance" of ops, the single block is considered to properly dominate + /// itself in a graph region. bool properlyDominates(Block *a, Block *b) const { return super::properlyDominates(a, b); } diff --git a/mlir/lib/IR/Dominance.cpp b/mlir/lib/IR/Dominance.cpp index 2b138ae223546..31f7e7dbc925c 100644 --- a/mlir/lib/IR/Dominance.cpp +++ b/mlir/lib/IR/Dominance.cpp @@ -34,7 +34,8 @@ DominanceInfoBase::~DominanceInfoBase() { delete entry.second.getPointer(); } -template void DominanceInfoBase::invalidate() { +template +void DominanceInfoBase::invalidate() { for (auto entry : dominanceInfos) delete entry.second.getPointer(); dominanceInfos.clear(); @@ -217,9 +218,10 @@ template bool DominanceInfoBase::properlyDominates(Block *a, Block *b) const { assert(a && b && "null blocks not allowed"); - // A block dominates itself but does not properly dominate itself. + // A block dominates, but does not properly dominate, itself unless this + // is a graph region. if (a == b) - return false; + return !hasSSADominance(a); // If both blocks are not in the same region, `a` properly dominates `b` if // `b` is defined in an operation region that (recursively) ends up being @@ -269,7 +271,7 @@ bool DominanceInfo::properlyDominatesImpl(Operation *a, Operation *b, Block *aBlock = a->getBlock(), *bBlock = b->getBlock(); assert(aBlock && bBlock && "operations must be in a block"); - // An instruction dominates, but does not properlyDominate, itself unless this + // An operation dominates, but does not properly dominate, itself unless this // is a graph region. if (a == b) return !hasSSADominance(aBlock); diff --git a/mlir/test/Analysis/test-dominance.mlir b/mlir/test/Analysis/test-dominance.mlir index 3c53193db7f72..a926a8271200a 100644 --- a/mlir/test/Analysis/test-dominance.mlir +++ b/mlir/test/Analysis/test-dominance.mlir @@ -1,4 +1,4 @@ -// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(test-print-dominance))" -split-input-file 2>&1 | FileCheck %s +// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(test-print-dominance))" -split-input-file | FileCheck %s // CHECK-LABEL: Testing : func_condBranch func.func @func_condBranch(%cond : i1) { @@ -10,40 +10,117 @@ func.func @func_condBranch(%cond : i1) { ^exit: return } -// CHECK-LABEL: --- DominanceInfo --- -// CHECK-NEXT: Nearest(0, 0) = 0 -// CHECK-NEXT: Nearest(0, 1) = 0 -// CHECK-NEXT: Nearest(0, 2) = 0 -// CHECK-NEXT: Nearest(0, 3) = 0 + +// CHECK: --- DominanceInfo --- +// CHECK: Nearest(0, 0) = 0 +// CHECK: Nearest(0, 1) = 0 +// CHECK: Nearest(0, 2) = 0 +// CHECK: Nearest(0, 3) = 0 +// CHECK: Nearest(0, 4) = 4 // CHECK: Nearest(1, 0) = 0 -// CHECK-NEXT: Nearest(1, 1) = 1 -// CHECK-NEXT: Nearest(1, 2) = 0 -// CHECK-NEXT: Nearest(1, 3) = 0 +// CHECK: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 2) = 0 +// CHECK: Nearest(1, 3) = 0 +// CHECK: Nearest(1, 4) = 4 // CHECK: Nearest(2, 0) = 0 -// CHECK-NEXT: Nearest(2, 1) = 0 -// CHECK-NEXT: Nearest(2, 2) = 2 -// CHECK-NEXT: Nearest(2, 3) = 0 +// CHECK: Nearest(2, 1) = 0 +// CHECK: Nearest(2, 2) = 2 +// CHECK: Nearest(2, 3) = 0 +// CHECK: Nearest(2, 4) = 4 // CHECK: Nearest(3, 0) = 0 -// CHECK-NEXT: Nearest(3, 1) = 0 -// CHECK-NEXT: Nearest(3, 2) = 0 -// CHECK-NEXT: Nearest(3, 3) = 3 -// CHECK-LABEL: --- PostDominanceInfo --- -// CHECK-NEXT: Nearest(0, 0) = 0 -// CHECK-NEXT: Nearest(0, 1) = 3 -// CHECK-NEXT: Nearest(0, 2) = 3 -// CHECK-NEXT: Nearest(0, 3) = 3 +// CHECK: Nearest(3, 1) = 0 +// CHECK: Nearest(3, 2) = 0 +// CHECK: Nearest(3, 3) = 3 +// CHECK: Nearest(3, 4) = 4 +// CHECK: Nearest(4, 0) = 4 +// CHECK: Nearest(4, 1) = 4 +// CHECK: Nearest(4, 2) = 4 +// CHECK: Nearest(4, 3) = 4 +// CHECK: Nearest(4, 4) = 4 + +// CHECK: --- PostDominanceInfo --- +// CHECK: Nearest(0, 0) = 0 +// CHECK: Nearest(0, 1) = 3 +// CHECK: Nearest(0, 2) = 3 +// CHECK: Nearest(0, 3) = 3 +// CHECK: Nearest(0, 4) = 4 // CHECK: Nearest(1, 0) = 3 -// CHECK-NEXT: Nearest(1, 1) = 1 -// CHECK-NEXT: Nearest(1, 2) = 3 -// CHECK-NEXT: Nearest(1, 3) = 3 +// CHECK: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 2) = 3 +// CHECK: Nearest(1, 3) = 3 +// CHECK: Nearest(1, 4) = 4 // CHECK: Nearest(2, 0) = 3 -// CHECK-NEXT: Nearest(2, 1) = 3 -// CHECK-NEXT: Nearest(2, 2) = 2 -// CHECK-NEXT: Nearest(2, 3) = 3 +// CHECK: Nearest(2, 1) = 3 +// CHECK: Nearest(2, 2) = 2 +// CHECK: Nearest(2, 3) = 3 +// CHECK: Nearest(2, 4) = 4 // CHECK: Nearest(3, 0) = 3 -// CHECK-NEXT: Nearest(3, 1) = 3 -// CHECK-NEXT: Nearest(3, 2) = 3 -// CHECK-NEXT: Nearest(3, 3) = 3 +// CHECK: Nearest(3, 1) = 3 +// CHECK: Nearest(3, 2) = 3 +// CHECK: Nearest(3, 3) = 3 +// CHECK: Nearest(3, 4) = 4 +// CHECK: Nearest(4, 0) = 4 +// CHECK: Nearest(4, 1) = 4 +// CHECK: Nearest(4, 2) = 4 +// CHECK: Nearest(4, 3) = 4 +// CHECK: Nearest(4, 4) = 4 + +// CHECK: --- Block Dominance relationship --- +// CHECK: dominates(0, 0) = 1 (properly = 0) +// CHECK: dominates(0, 1) = 1 (properly = 1) +// CHECK: dominates(0, 2) = 1 (properly = 1) +// CHECK: dominates(0, 3) = 1 (properly = 1) +// CHECK: dominates(0, 4) = 0 (properly = 0) +// CHECK: dominates(1, 0) = 0 (properly = 0) +// CHECK: dominates(1, 1) = 1 (properly = 0) +// CHECK: dominates(1, 2) = 0 (properly = 0) +// CHECK: dominates(1, 3) = 0 (properly = 0) +// CHECK: dominates(1, 4) = 0 (properly = 0) +// CHECK: dominates(2, 0) = 0 (properly = 0) +// CHECK: dominates(2, 1) = 0 (properly = 0) +// CHECK: dominates(2, 2) = 1 (properly = 0) +// CHECK: dominates(2, 3) = 0 (properly = 0) +// CHECK: dominates(2, 4) = 0 (properly = 0) +// CHECK: dominates(3, 0) = 0 (properly = 0) +// CHECK: dominates(3, 1) = 0 (properly = 0) +// CHECK: dominates(3, 2) = 0 (properly = 0) +// CHECK: dominates(3, 3) = 1 (properly = 0) +// CHECK: dominates(3, 4) = 0 (properly = 0) +// CHECK: dominates(4, 0) = 1 (properly = 1) +// CHECK: dominates(4, 1) = 1 (properly = 1) +// CHECK: dominates(4, 2) = 1 (properly = 1) +// CHECK: dominates(4, 3) = 1 (properly = 1) +// CHECK: dominates(4, 4) = 1 (properly = 1) + +// CHECK: --- Block PostDominance relationship --- +// CHECK: postdominates(0, 0) = 1 (properly = 0) +// CHECK: postdominates(0, 1) = 0 (properly = 0) +// CHECK: postdominates(0, 2) = 0 (properly = 0) +// CHECK: postdominates(0, 3) = 0 (properly = 0) +// CHECK: postdominates(0, 4) = 0 (properly = 0) +// CHECK: postdominates(1, 0) = 0 (properly = 0) +// CHECK: postdominates(1, 1) = 1 (properly = 0) +// CHECK: postdominates(1, 2) = 0 (properly = 0) +// CHECK: postdominates(1, 3) = 0 (properly = 0) +// CHECK: postdominates(1, 4) = 0 (properly = 0) +// CHECK: postdominates(2, 0) = 0 (properly = 0) +// CHECK: postdominates(2, 1) = 0 (properly = 0) +// CHECK: postdominates(2, 2) = 1 (properly = 0) +// CHECK: postdominates(2, 3) = 0 (properly = 0) +// CHECK: postdominates(2, 4) = 0 (properly = 0) +// CHECK: postdominates(3, 0) = 1 (properly = 1) +// CHECK: postdominates(3, 1) = 1 (properly = 1) +// CHECK: postdominates(3, 2) = 1 (properly = 1) +// CHECK: postdominates(3, 3) = 1 (properly = 0) +// CHECK: postdominates(3, 4) = 0 (properly = 0) +// CHECK: postdominates(4, 0) = 1 (properly = 1) +// CHECK: postdominates(4, 1) = 1 (properly = 1) +// CHECK: postdominates(4, 2) = 1 (properly = 1) +// CHECK: postdominates(4, 3) = 1 (properly = 1) +// CHECK: postdominates(4, 4) = 1 (properly = 1) + +// CHECK: module attributes {test.block_ids = array} +// CHECK: func.func @func_condBranch({{.*}}) attributes {test.block_ids = array} // ----- @@ -60,32 +137,117 @@ func.func @func_loop(%arg0 : i32, %arg1 : i32) { ^exit: return } -// CHECK-LABEL: --- DominanceInfo --- + +// CHECK: --- DominanceInfo --- +// CHECK: Nearest(0, 0) = 0 +// CHECK: Nearest(0, 1) = 0 +// CHECK: Nearest(0, 2) = 0 +// CHECK: Nearest(0, 3) = 0 +// CHECK: Nearest(0, 4) = 4 // CHECK: Nearest(1, 0) = 0 -// CHECK-NEXT: Nearest(1, 1) = 1 -// CHECK-NEXT: Nearest(1, 2) = 1 -// CHECK-NEXT: Nearest(1, 3) = 1 +// CHECK: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 2) = 1 +// CHECK: Nearest(1, 3) = 1 +// CHECK: Nearest(1, 4) = 4 // CHECK: Nearest(2, 0) = 0 -// CHECK-NEXT: Nearest(2, 1) = 1 -// CHECK-NEXT: Nearest(2, 2) = 2 -// CHECK-NEXT: Nearest(2, 3) = 1 +// CHECK: Nearest(2, 1) = 1 +// CHECK: Nearest(2, 2) = 2 +// CHECK: Nearest(2, 3) = 1 +// CHECK: Nearest(2, 4) = 4 // CHECK: Nearest(3, 0) = 0 -// CHECK-NEXT: Nearest(3, 1) = 1 -// CHECK-NEXT: Nearest(3, 2) = 1 -// CHECK-NEXT: Nearest(3, 3) = 3 -// CHECK-LABEL: --- PostDominanceInfo --- +// CHECK: Nearest(3, 1) = 1 +// CHECK: Nearest(3, 2) = 1 +// CHECK: Nearest(3, 3) = 3 +// CHECK: Nearest(3, 4) = 4 +// CHECK: Nearest(4, 0) = 4 +// CHECK: Nearest(4, 1) = 4 +// CHECK: Nearest(4, 2) = 4 +// CHECK: Nearest(4, 3) = 4 +// CHECK: Nearest(4, 4) = 4 + +// CHECK: --- PostDominanceInfo --- +// CHECK: Nearest(0, 0) = 0 +// CHECK: Nearest(0, 1) = 1 +// CHECK: Nearest(0, 2) = 1 +// CHECK: Nearest(0, 3) = 3 +// CHECK: Nearest(0, 4) = 4 // CHECK: Nearest(1, 0) = 1 -// CHECK-NEXT: Nearest(1, 1) = 1 -// CHECK-NEXT: Nearest(1, 2) = 1 -// CHECK-NEXT: Nearest(1, 3) = 3 +// CHECK: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 2) = 1 +// CHECK: Nearest(1, 3) = 3 +// CHECK: Nearest(1, 4) = 4 // CHECK: Nearest(2, 0) = 1 -// CHECK-NEXT: Nearest(2, 1) = 1 -// CHECK-NEXT: Nearest(2, 2) = 2 -// CHECK-NEXT: Nearest(2, 3) = 3 +// CHECK: Nearest(2, 1) = 1 +// CHECK: Nearest(2, 2) = 2 +// CHECK: Nearest(2, 3) = 3 +// CHECK: Nearest(2, 4) = 4 // CHECK: Nearest(3, 0) = 3 -// CHECK-NEXT: Nearest(3, 1) = 3 -// CHECK-NEXT: Nearest(3, 2) = 3 -// CHECK-NEXT: Nearest(3, 3) = 3 +// CHECK: Nearest(3, 1) = 3 +// CHECK: Nearest(3, 2) = 3 +// CHECK: Nearest(3, 3) = 3 +// CHECK: Nearest(3, 4) = 4 +// CHECK: Nearest(4, 0) = 4 +// CHECK: Nearest(4, 1) = 4 +// CHECK: Nearest(4, 2) = 4 +// CHECK: Nearest(4, 3) = 4 +// CHECK: Nearest(4, 4) = 4 + +// CHECK: --- Block Dominance relationship --- +// CHECK: dominates(0, 0) = 1 (properly = 0) +// CHECK: dominates(0, 1) = 1 (properly = 1) +// CHECK: dominates(0, 2) = 1 (properly = 1) +// CHECK: dominates(0, 3) = 1 (properly = 1) +// CHECK: dominates(0, 4) = 0 (properly = 0) +// CHECK: dominates(1, 0) = 0 (properly = 0) +// CHECK: dominates(1, 1) = 1 (properly = 0) +// CHECK: dominates(1, 2) = 1 (properly = 1) +// CHECK: dominates(1, 3) = 1 (properly = 1) +// CHECK: dominates(1, 4) = 0 (properly = 0) +// CHECK: dominates(2, 0) = 0 (properly = 0) +// CHECK: dominates(2, 1) = 0 (properly = 0) +// CHECK: dominates(2, 2) = 1 (properly = 0) +// CHECK: dominates(2, 3) = 0 (properly = 0) +// CHECK: dominates(2, 4) = 0 (properly = 0) +// CHECK: dominates(3, 0) = 0 (properly = 0) +// CHECK: dominates(3, 1) = 0 (properly = 0) +// CHECK: dominates(3, 2) = 0 (properly = 0) +// CHECK: dominates(3, 3) = 1 (properly = 0) +// CHECK: dominates(3, 4) = 0 (properly = 0) +// CHECK: dominates(4, 0) = 1 (properly = 1) +// CHECK: dominates(4, 1) = 1 (properly = 1) +// CHECK: dominates(4, 2) = 1 (properly = 1) +// CHECK: dominates(4, 3) = 1 (properly = 1) +// CHECK: dominates(4, 4) = 1 (properly = 1) + +// CHECK: --- Block PostDominance relationship --- +// CHECK: postdominates(0, 0) = 1 (properly = 0) +// CHECK: postdominates(0, 1) = 0 (properly = 0) +// CHECK: postdominates(0, 2) = 0 (properly = 0) +// CHECK: postdominates(0, 3) = 0 (properly = 0) +// CHECK: postdominates(0, 4) = 0 (properly = 0) +// CHECK: postdominates(1, 0) = 1 (properly = 1) +// CHECK: postdominates(1, 1) = 1 (properly = 0) +// CHECK: postdominates(1, 2) = 1 (properly = 1) +// CHECK: postdominates(1, 3) = 0 (properly = 0) +// CHECK: postdominates(1, 4) = 0 (properly = 0) +// CHECK: postdominates(2, 0) = 0 (properly = 0) +// CHECK: postdominates(2, 1) = 0 (properly = 0) +// CHECK: postdominates(2, 2) = 1 (properly = 0) +// CHECK: postdominates(2, 3) = 0 (properly = 0) +// CHECK: postdominates(2, 4) = 0 (properly = 0) +// CHECK: postdominates(3, 0) = 1 (properly = 1) +// CHECK: postdominates(3, 1) = 1 (properly = 1) +// CHECK: postdominates(3, 2) = 1 (properly = 1) +// CHECK: postdominates(3, 3) = 1 (properly = 0) +// CHECK: postdominates(3, 4) = 0 (properly = 0) +// CHECK: postdominates(4, 0) = 1 (properly = 1) +// CHECK: postdominates(4, 1) = 1 (properly = 1) +// CHECK: postdominates(4, 2) = 1 (properly = 1) +// CHECK: postdominates(4, 3) = 1 (properly = 1) +// CHECK: postdominates(4, 4) = 1 (properly = 1) + +// CHECK: module attributes {test.block_ids = array} +// CHECK: func.func @func_loop({{.*}}) attributes {test.block_ids = array} // ----- @@ -95,16 +257,57 @@ func.func @nested_region(%arg0 : index, %arg1 : index, %arg2 : index) { return } -// CHECK-LABEL: --- DominanceInfo --- -// CHECK-NEXT: Nearest(0, 0) = 0 -// CHECK-NEXT: Nearest(0, 1) = 1 +// CHECK: --- DominanceInfo --- +// CHECK: Nearest(0, 0) = 0 +// CHECK: Nearest(0, 1) = 1 +// CHECK: Nearest(0, 2) = 2 // CHECK: Nearest(1, 0) = 1 -// CHECK-NEXT: Nearest(1, 1) = 1 -// CHECK-LABEL: --- PostDominanceInfo --- -// CHECK-NEXT: Nearest(0, 0) = 0 -// CHECK-NEXT: Nearest(0, 1) = 1 +// CHECK: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 2) = 2 +// CHECK: Nearest(2, 0) = 2 +// CHECK: Nearest(2, 1) = 2 +// CHECK: Nearest(2, 2) = 2 + +// CHECK: --- PostDominanceInfo --- +// CHECK: Nearest(0, 0) = 0 +// CHECK: Nearest(0, 1) = 1 +// CHECK: Nearest(0, 2) = 2 // CHECK: Nearest(1, 0) = 1 -// CHECK-NEXT: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 2) = 2 +// CHECK: Nearest(2, 0) = 2 +// CHECK: Nearest(2, 1) = 2 +// CHECK: Nearest(2, 2) = 2 + +// CHECK: --- Block Dominance relationship --- +// CHECK: dominates(0, 0) = 1 (properly = 0) +// CHECK: dominates(0, 1) = 0 (properly = 0) +// CHECK: dominates(0, 2) = 0 (properly = 0) +// CHECK: dominates(1, 0) = 1 (properly = 1) +// CHECK: dominates(1, 1) = 1 (properly = 0) +// CHECK: dominates(1, 2) = 0 (properly = 0) +// CHECK: dominates(2, 0) = 1 (properly = 1) +// CHECK: dominates(2, 1) = 1 (properly = 1) +// CHECK: dominates(2, 2) = 1 (properly = 1) + +// CHECK: --- Block PostDominance relationship --- +// CHECK: postdominates(0, 0) = 1 (properly = 0) +// CHECK: postdominates(0, 1) = 0 (properly = 0) +// CHECK: postdominates(0, 2) = 0 (properly = 0) +// CHECK: postdominates(1, 0) = 1 (properly = 1) +// CHECK: postdominates(1, 1) = 1 (properly = 0) +// CHECK: postdominates(1, 2) = 0 (properly = 0) +// CHECK: postdominates(2, 0) = 1 (properly = 1) +// CHECK: postdominates(2, 1) = 1 (properly = 1) +// CHECK: postdominates(2, 2) = 1 (properly = 1) + +// CHECK: module attributes {test.block_ids = array} { +// CHECK: func.func @nested_region({{.*}}) attributes {test.block_ids = array} { +// CHECK: scf.for {{.*}} { +// CHECK: } {test.block_ids = array} +// CHECK: return +// CHECK: } +// CHECK: } // ----- @@ -117,32 +320,126 @@ func.func @nested_region2(%arg0 : index, %arg1 : index, %arg2 : index) { } return } -// CHECK-LABEL: --- DominanceInfo --- + +// CHECK: --- DominanceInfo --- +// CHECK: Nearest(0, 0) = 0 +// CHECK: Nearest(0, 1) = 1 +// CHECK: Nearest(0, 2) = 2 +// CHECK: Nearest(0, 3) = 3 +// CHECK: Nearest(0, 4) = 4 // CHECK: Nearest(1, 0) = 1 -// CHECK-NEXT: Nearest(1, 1) = 1 -// CHECK-NEXT: Nearest(1, 2) = 2 -// CHECK-NEXT: Nearest(1, 3) = 3 +// CHECK: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 2) = 2 +// CHECK: Nearest(1, 3) = 3 +// CHECK: Nearest(1, 4) = 4 // CHECK: Nearest(2, 0) = 2 -// CHECK-NEXT: Nearest(2, 1) = 2 -// CHECK-NEXT: Nearest(2, 2) = 2 -// CHECK-NEXT: Nearest(2, 3) = 3 +// CHECK: Nearest(2, 1) = 2 +// CHECK: Nearest(2, 2) = 2 +// CHECK: Nearest(2, 3) = 3 +// CHECK: Nearest(2, 4) = 4 // CHECK: Nearest(3, 0) = 3 -// CHECK-NEXT: Nearest(3, 1) = 3 -// CHECK-NEXT: Nearest(3, 2) = 3 -// CHECK-NEXT: Nearest(3, 3) = 3 -// CHECK-LABEL: --- PostDominanceInfo --- -// CHECK-NEXT: Nearest(0, 0) = 0 -// CHECK-NEXT: Nearest(0, 1) = 1 -// CHECK-NEXT: Nearest(0, 2) = 2 -// CHECK-NEXT: Nearest(0, 3) = 3 +// CHECK: Nearest(3, 1) = 3 +// CHECK: Nearest(3, 2) = 3 +// CHECK: Nearest(3, 3) = 3 +// CHECK: Nearest(3, 4) = 4 +// CHECK: Nearest(4, 0) = 4 +// CHECK: Nearest(4, 1) = 4 +// CHECK: Nearest(4, 2) = 4 +// CHECK: Nearest(4, 3) = 4 +// CHECK: Nearest(4, 4) = 4 + +// CHECK: --- PostDominanceInfo --- +// CHECK: Nearest(0, 0) = 0 +// CHECK: Nearest(0, 1) = 1 +// CHECK: Nearest(0, 2) = 2 +// CHECK: Nearest(0, 3) = 3 +// CHECK: Nearest(0, 4) = 4 // CHECK: Nearest(1, 0) = 1 -// CHECK-NEXT: Nearest(1, 1) = 1 -// CHECK-NEXT: Nearest(1, 2) = 2 -// CHECK-NEXT: Nearest(1, 3) = 3 +// CHECK: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 2) = 2 +// CHECK: Nearest(1, 3) = 3 +// CHECK: Nearest(1, 4) = 4 // CHECK: Nearest(2, 0) = 2 -// CHECK-NEXT: Nearest(2, 1) = 2 -// CHECK-NEXT: Nearest(2, 2) = 2 -// CHECK-NEXT: Nearest(2, 3) = 3 +// CHECK: Nearest(2, 1) = 2 +// CHECK: Nearest(2, 2) = 2 +// CHECK: Nearest(2, 3) = 3 +// CHECK: Nearest(2, 4) = 4 +// CHECK: Nearest(3, 0) = 3 +// CHECK: Nearest(3, 1) = 3 +// CHECK: Nearest(3, 2) = 3 +// CHECK: Nearest(3, 3) = 3 +// CHECK: Nearest(3, 4) = 4 +// CHECK: Nearest(4, 0) = 4 +// CHECK: Nearest(4, 1) = 4 +// CHECK: Nearest(4, 2) = 4 +// CHECK: Nearest(4, 3) = 4 +// CHECK: Nearest(4, 4) = 4 + +// CHECK: --- Block Dominance relationship --- +// CHECK: dominates(0, 0) = 1 (properly = 0) +// CHECK: dominates(0, 1) = 0 (properly = 0) +// CHECK: dominates(0, 2) = 0 (properly = 0) +// CHECK: dominates(0, 3) = 0 (properly = 0) +// CHECK: dominates(0, 4) = 0 (properly = 0) +// CHECK: dominates(1, 0) = 1 (properly = 1) +// CHECK: dominates(1, 1) = 1 (properly = 0) +// CHECK: dominates(1, 2) = 0 (properly = 0) +// CHECK: dominates(1, 3) = 0 (properly = 0) +// CHECK: dominates(1, 4) = 0 (properly = 0) +// CHECK: dominates(2, 0) = 1 (properly = 1) +// CHECK: dominates(2, 1) = 1 (properly = 1) +// CHECK: dominates(2, 2) = 1 (properly = 0) +// CHECK: dominates(2, 3) = 0 (properly = 0) +// CHECK: dominates(2, 4) = 0 (properly = 0) +// CHECK: dominates(3, 0) = 1 (properly = 1) +// CHECK: dominates(3, 1) = 1 (properly = 1) +// CHECK: dominates(3, 2) = 1 (properly = 1) +// CHECK: dominates(3, 3) = 1 (properly = 0) +// CHECK: dominates(3, 4) = 0 (properly = 0) +// CHECK: dominates(4, 0) = 1 (properly = 1) +// CHECK: dominates(4, 1) = 1 (properly = 1) +// CHECK: dominates(4, 2) = 1 (properly = 1) +// CHECK: dominates(4, 3) = 1 (properly = 1) +// CHECK: dominates(4, 4) = 1 (properly = 1) + +// CHECK: --- Block PostDominance relationship --- +// CHECK: postdominates(0, 0) = 1 (properly = 0) +// CHECK: postdominates(0, 1) = 0 (properly = 0) +// CHECK: postdominates(0, 2) = 0 (properly = 0) +// CHECK: postdominates(0, 3) = 0 (properly = 0) +// CHECK: postdominates(0, 4) = 0 (properly = 0) +// CHECK: postdominates(1, 0) = 1 (properly = 1) +// CHECK: postdominates(1, 1) = 1 (properly = 0) +// CHECK: postdominates(1, 2) = 0 (properly = 0) +// CHECK: postdominates(1, 3) = 0 (properly = 0) +// CHECK: postdominates(1, 4) = 0 (properly = 0) +// CHECK: postdominates(2, 0) = 1 (properly = 1) +// CHECK: postdominates(2, 1) = 1 (properly = 1) +// CHECK: postdominates(2, 2) = 1 (properly = 0) +// CHECK: postdominates(2, 3) = 0 (properly = 0) +// CHECK: postdominates(2, 4) = 0 (properly = 0) +// CHECK: postdominates(3, 0) = 1 (properly = 1) +// CHECK: postdominates(3, 1) = 1 (properly = 1) +// CHECK: postdominates(3, 2) = 1 (properly = 1) +// CHECK: postdominates(3, 3) = 1 (properly = 0) +// CHECK: postdominates(3, 4) = 0 (properly = 0) +// CHECK: postdominates(4, 0) = 1 (properly = 1) +// CHECK: postdominates(4, 1) = 1 (properly = 1) +// CHECK: postdominates(4, 2) = 1 (properly = 1) +// CHECK: postdominates(4, 3) = 1 (properly = 1) +// CHECK: postdominates(4, 4) = 1 (properly = 1) + +// CHECK: module attributes {test.block_ids = array} { +// CHECK: func.func @nested_region2({{.*}}) attributes {test.block_ids = array} { +// CHECK: scf.for {{.*}} { +// CHECK: scf.for {{.*}} { +// CHECK: scf.for {{.*}} { +// CHECK: } {test.block_ids = array} +// CHECK: } {test.block_ids = array} +// CHECK: } {test.block_ids = array} +// CHECK: return +// CHECK: } +// CHECK: } // ----- @@ -167,141 +464,219 @@ func.func @func_loop_nested_region( ^exit: return } -// CHECK-LABEL: --- DominanceInfo --- + +// CHECK: --- DominanceInfo --- +// CHECK: Nearest(0, 0) = 0 +// CHECK: Nearest(0, 1) = 0 +// CHECK: Nearest(0, 2) = 0 +// CHECK: Nearest(0, 3) = 0 +// CHECK: Nearest(0, 4) = 0 +// CHECK: Nearest(0, 5) = 0 +// CHECK: Nearest(0, 6) = 6 +// CHECK: Nearest(1, 0) = 0 +// CHECK: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 2) = 1 +// CHECK: Nearest(1, 3) = 1 +// CHECK: Nearest(1, 4) = 1 +// CHECK: Nearest(1, 5) = 1 +// CHECK: Nearest(1, 6) = 6 // CHECK: Nearest(2, 0) = 0 -// CHECK-NEXT: Nearest(2, 1) = 1 -// CHECK-NEXT: Nearest(2, 2) = 2 -// CHECK-NEXT: Nearest(2, 3) = 2 -// CHECK-NEXT: Nearest(2, 4) = 2 -// CHECK-NEXT: Nearest(2, 5) = 1 +// CHECK: Nearest(2, 1) = 1 +// CHECK: Nearest(2, 2) = 2 +// CHECK: Nearest(2, 3) = 2 +// CHECK: Nearest(2, 4) = 2 +// CHECK: Nearest(2, 5) = 1 +// CHECK: Nearest(2, 6) = 6 // CHECK: Nearest(3, 0) = 0 -// CHECK-NEXT: Nearest(3, 1) = 1 -// CHECK-NEXT: Nearest(3, 2) = 2 -// CHECK-NEXT: Nearest(3, 3) = 3 -// CHECK-NEXT: Nearest(3, 4) = 4 -// CHECK-NEXT: Nearest(3, 5) = 1 +// CHECK: Nearest(3, 1) = 1 +// CHECK: Nearest(3, 2) = 2 +// CHECK: Nearest(3, 3) = 3 +// CHECK: Nearest(3, 4) = 4 +// CHECK: Nearest(3, 5) = 1 +// CHECK: Nearest(3, 6) = 6 // CHECK: Nearest(4, 0) = 0 -// CHECK-NEXT: Nearest(4, 1) = 1 -// CHECK-NEXT: Nearest(4, 2) = 2 -// CHECK-NEXT: Nearest(4, 3) = 4 -// CHECK-NEXT: Nearest(4, 4) = 4 -// CHECK-NEXT: Nearest(4, 5) = 1 -// CHECK-LABEL: --- PostDominanceInfo --- +// CHECK: Nearest(4, 1) = 1 +// CHECK: Nearest(4, 2) = 2 +// CHECK: Nearest(4, 3) = 4 +// CHECK: Nearest(4, 4) = 4 +// CHECK: Nearest(4, 5) = 1 +// CHECK: Nearest(4, 6) = 6 +// CHECK: Nearest(5, 0) = 0 +// CHECK: Nearest(5, 1) = 1 +// CHECK: Nearest(5, 2) = 1 +// CHECK: Nearest(5, 3) = 1 +// CHECK: Nearest(5, 4) = 1 +// CHECK: Nearest(5, 5) = 5 +// CHECK: Nearest(5, 6) = 6 +// CHECK: Nearest(6, 0) = 6 +// CHECK: Nearest(6, 1) = 6 +// CHECK: Nearest(6, 2) = 6 +// CHECK: Nearest(6, 3) = 6 +// CHECK: Nearest(6, 4) = 6 +// CHECK: Nearest(6, 5) = 6 +// CHECK: Nearest(6, 6) = 6 + +// CHECK: --- PostDominanceInfo --- +// CHECK: Nearest(0, 0) = 0 +// CHECK: Nearest(0, 1) = 1 +// CHECK: Nearest(0, 2) = 1 +// CHECK: Nearest(0, 3) = 1 +// CHECK: Nearest(0, 4) = 1 +// CHECK: Nearest(0, 5) = 5 +// CHECK: Nearest(0, 6) = 6 +// CHECK: Nearest(1, 0) = 1 +// CHECK: Nearest(1, 1) = 1 +// CHECK: Nearest(1, 2) = 1 +// CHECK: Nearest(1, 3) = 1 +// CHECK: Nearest(1, 4) = 1 +// CHECK: Nearest(1, 5) = 5 +// CHECK: Nearest(1, 6) = 6 // CHECK: Nearest(2, 0) = 1 -// CHECK-NEXT: Nearest(2, 1) = 1 -// CHECK-NEXT: Nearest(2, 2) = 2 -// CHECK-NEXT: Nearest(2, 3) = 2 -// CHECK-NEXT: Nearest(2, 4) = 2 -// CHECK-NEXT: Nearest(2, 5) = 5 +// CHECK: Nearest(2, 1) = 1 +// CHECK: Nearest(2, 2) = 2 +// CHECK: Nearest(2, 3) = 2 +// CHECK: Nearest(2, 4) = 2 +// CHECK: Nearest(2, 5) = 5 +// CHECK: Nearest(2, 6) = 6 // CHECK: Nearest(3, 0) = 1 -// CHECK-NEXT: Nearest(3, 1) = 1 -// CHECK-NEXT: Nearest(3, 2) = 2 -// CHECK-NEXT: Nearest(3, 3) = 3 -// CHECK-NEXT: Nearest(3, 4) = 4 -// CHECK-NEXT: Nearest(3, 5) = 5 +// CHECK: Nearest(3, 1) = 1 +// CHECK: Nearest(3, 2) = 2 +// CHECK: Nearest(3, 3) = 3 +// CHECK: Nearest(3, 4) = 4 +// CHECK: Nearest(3, 5) = 5 +// CHECK: Nearest(3, 6) = 6 // CHECK: Nearest(4, 0) = 1 -// CHECK-NEXT: Nearest(4, 1) = 1 -// CHECK-NEXT: Nearest(4, 2) = 2 -// CHECK-NEXT: Nearest(4, 3) = 4 -// CHECK-NEXT: Nearest(4, 4) = 4 -// CHECK-NEXT: Nearest(4, 5) = 5 -// CHECK-LABEL: --- Block Dominance relationship --- -// CHECK-NEXT: dominates(0, 0) = true -// CHECK-NEXT: dominates(0, 1) = true -// CHECK-NEXT: dominates(0, 2) = true -// CHECK-NEXT: dominates(0, 3) = true -// CHECK-NEXT: dominates(0, 4) = true -// CHECK-NEXT: dominates(0, 5) = true -// CHECK-NEXT: dominates(0, 6) = false -// CHECK-NEXT: dominates(1, 0) = false -// CHECK-NEXT: dominates(1, 1) = true -// CHECK-NEXT: dominates(1, 2) = true -// CHECK-NEXT: dominates(1, 3) = true -// CHECK-NEXT: dominates(1, 4) = true -// CHECK-NEXT: dominates(1, 5) = true -// CHECK-NEXT: dominates(1, 6) = false -// CHECK-NEXT: dominates(2, 0) = false -// CHECK-NEXT: dominates(2, 1) = false -// CHECK-NEXT: dominates(2, 2) = true -// CHECK-NEXT: dominates(2, 3) = true -// CHECK-NEXT: dominates(2, 4) = true -// CHECK-NEXT: dominates(2, 5) = false -// CHECK-NEXT: dominates(2, 6) = false -// CHECK-NEXT: dominates(3, 0) = false -// CHECK-NEXT: dominates(3, 1) = false -// CHECK-NEXT: dominates(3, 2) = false -// CHECK-NEXT: dominates(3, 3) = true -// CHECK-NEXT: dominates(3, 4) = false -// CHECK-NEXT: dominates(3, 5) = false -// CHECK-NEXT: dominates(3, 6) = false -// CHECK-NEXT: dominates(4, 0) = false -// CHECK-NEXT: dominates(4, 1) = false -// CHECK-NEXT: dominates(4, 2) = false -// CHECK-NEXT: dominates(4, 3) = true -// CHECK-NEXT: dominates(4, 4) = true -// CHECK-NEXT: dominates(4, 5) = false -// CHECK-NEXT: dominates(4, 6) = false -// CHECK-NEXT: dominates(5, 0) = false -// CHECK-NEXT: dominates(5, 1) = false -// CHECK-NEXT: dominates(5, 2) = false -// CHECK-NEXT: dominates(5, 3) = false -// CHECK-NEXT: dominates(5, 4) = false -// CHECK-NEXT: dominates(5, 5) = true -// CHECK-NEXT: dominates(5, 6) = false -// CHECK-NEXT: dominates(6, 0) = true -// CHECK-NEXT: dominates(6, 1) = true -// CHECK-NEXT: dominates(6, 2) = true -// CHECK-NEXT: dominates(6, 3) = true -// CHECK-NEXT: dominates(6, 4) = true -// CHECK-NEXT: dominates(6, 5) = true -// CHECK-NEXT: dominates(6, 6) = true -// CHECK-LABEL: --- Block PostDominance relationship --- -// CHECK-NEXT: postdominates(0, 0) = true -// CHECK-NEXT: postdominates(0, 1) = false -// CHECK-NEXT: postdominates(0, 2) = false -// CHECK-NEXT: postdominates(0, 3) = false -// CHECK-NEXT: postdominates(0, 4) = false -// CHECK-NEXT: postdominates(0, 5) = false -// CHECK-NEXT: postdominates(0, 6) = false -// CHECK-NEXT: postdominates(1, 0) = true -// CHECK-NEXT: postdominates(1, 1) = true -// CHECK-NEXT: postdominates(1, 2) = true -// CHECK-NEXT: postdominates(1, 3) = true -// CHECK-NEXT: postdominates(1, 4) = true -// CHECK-NEXT: postdominates(1, 5) = false -// CHECK-NEXT: postdominates(1, 6) = false -// CHECK-NEXT: postdominates(2, 0) = false -// CHECK-NEXT: postdominates(2, 1) = false -// CHECK-NEXT: postdominates(2, 2) = true -// CHECK-NEXT: postdominates(2, 3) = true -// CHECK-NEXT: postdominates(2, 4) = true -// CHECK-NEXT: postdominates(2, 5) = false -// CHECK-NEXT: postdominates(2, 6) = false -// CHECK-NEXT: postdominates(3, 0) = false -// CHECK-NEXT: postdominates(3, 1) = false -// CHECK-NEXT: postdominates(3, 2) = false -// CHECK-NEXT: postdominates(3, 3) = true -// CHECK-NEXT: postdominates(3, 4) = false -// CHECK-NEXT: postdominates(3, 5) = false -// CHECK-NEXT: postdominates(3, 6) = false -// CHECK-NEXT: postdominates(4, 0) = false -// CHECK-NEXT: postdominates(4, 1) = false -// CHECK-NEXT: postdominates(4, 2) = false -// CHECK-NEXT: postdominates(4, 3) = true -// CHECK-NEXT: postdominates(4, 4) = true -// CHECK-NEXT: postdominates(4, 5) = false -// CHECK-NEXT: postdominates(4, 6) = false -// CHECK-NEXT: postdominates(5, 0) = true -// CHECK-NEXT: postdominates(5, 1) = true -// CHECK-NEXT: postdominates(5, 2) = true -// CHECK-NEXT: postdominates(5, 3) = true -// CHECK-NEXT: postdominates(5, 4) = true -// CHECK-NEXT: postdominates(5, 5) = true -// CHECK-NEXT: postdominates(5, 6) = false -// CHECK-NEXT: postdominates(6, 0) = true -// CHECK-NEXT: postdominates(6, 1) = true -// CHECK-NEXT: postdominates(6, 2) = true -// CHECK-NEXT: postdominates(6, 3) = true -// CHECK-NEXT: postdominates(6, 4) = true -// CHECK-NEXT: postdominates(6, 5) = true -// CHECK-NEXT: postdominates(6, 6) = true +// CHECK: Nearest(4, 1) = 1 +// CHECK: Nearest(4, 2) = 2 +// CHECK: Nearest(4, 3) = 4 +// CHECK: Nearest(4, 4) = 4 +// CHECK: Nearest(4, 5) = 5 +// CHECK: Nearest(4, 6) = 6 +// CHECK: Nearest(5, 0) = 5 +// CHECK: Nearest(5, 1) = 5 +// CHECK: Nearest(5, 2) = 5 +// CHECK: Nearest(5, 3) = 5 +// CHECK: Nearest(5, 4) = 5 +// CHECK: Nearest(5, 5) = 5 +// CHECK: Nearest(5, 6) = 6 +// CHECK: Nearest(6, 0) = 6 +// CHECK: Nearest(6, 1) = 6 +// CHECK: Nearest(6, 2) = 6 +// CHECK: Nearest(6, 3) = 6 +// CHECK: Nearest(6, 4) = 6 +// CHECK: Nearest(6, 5) = 6 +// CHECK: Nearest(6, 6) = 6 + +// CHECK: --- Block Dominance relationship --- +// CHECK: dominates(0, 0) = 1 (properly = 0) +// CHECK: dominates(0, 1) = 1 (properly = 1) +// CHECK: dominates(0, 2) = 1 (properly = 1) +// CHECK: dominates(0, 3) = 1 (properly = 1) +// CHECK: dominates(0, 4) = 1 (properly = 1) +// CHECK: dominates(0, 5) = 1 (properly = 1) +// CHECK: dominates(0, 6) = 0 (properly = 0) +// CHECK: dominates(1, 0) = 0 (properly = 0) +// CHECK: dominates(1, 1) = 1 (properly = 0) +// CHECK: dominates(1, 2) = 1 (properly = 1) +// CHECK: dominates(1, 3) = 1 (properly = 1) +// CHECK: dominates(1, 4) = 1 (properly = 1) +// CHECK: dominates(1, 5) = 1 (properly = 1) +// CHECK: dominates(1, 6) = 0 (properly = 0) +// CHECK: dominates(2, 0) = 0 (properly = 0) +// CHECK: dominates(2, 1) = 0 (properly = 0) +// CHECK: dominates(2, 2) = 1 (properly = 0) +// CHECK: dominates(2, 3) = 1 (properly = 1) +// CHECK: dominates(2, 4) = 1 (properly = 1) +// CHECK: dominates(2, 5) = 0 (properly = 0) +// CHECK: dominates(2, 6) = 0 (properly = 0) +// CHECK: dominates(3, 0) = 0 (properly = 0) +// CHECK: dominates(3, 1) = 0 (properly = 0) +// CHECK: dominates(3, 2) = 0 (properly = 0) +// CHECK: dominates(3, 3) = 1 (properly = 0) +// CHECK: dominates(3, 4) = 0 (properly = 0) +// CHECK: dominates(3, 5) = 0 (properly = 0) +// CHECK: dominates(3, 6) = 0 (properly = 0) +// CHECK: dominates(4, 0) = 0 (properly = 0) +// CHECK: dominates(4, 1) = 0 (properly = 0) +// CHECK: dominates(4, 2) = 0 (properly = 0) +// CHECK: dominates(4, 3) = 1 (properly = 1) +// CHECK: dominates(4, 4) = 1 (properly = 0) +// CHECK: dominates(4, 5) = 0 (properly = 0) +// CHECK: dominates(4, 6) = 0 (properly = 0) +// CHECK: dominates(5, 0) = 0 (properly = 0) +// CHECK: dominates(5, 1) = 0 (properly = 0) +// CHECK: dominates(5, 2) = 0 (properly = 0) +// CHECK: dominates(5, 3) = 0 (properly = 0) +// CHECK: dominates(5, 4) = 0 (properly = 0) +// CHECK: dominates(5, 5) = 1 (properly = 0) +// CHECK: dominates(5, 6) = 0 (properly = 0) +// CHECK: dominates(6, 0) = 1 (properly = 1) +// CHECK: dominates(6, 1) = 1 (properly = 1) +// CHECK: dominates(6, 2) = 1 (properly = 1) +// CHECK: dominates(6, 3) = 1 (properly = 1) +// CHECK: dominates(6, 4) = 1 (properly = 1) +// CHECK: dominates(6, 5) = 1 (properly = 1) +// CHECK: dominates(6, 6) = 1 (properly = 1) + +// CHECK: --- Block PostDominance relationship --- +// CHECK: postdominates(0, 0) = 1 (properly = 0) +// CHECK: postdominates(0, 1) = 0 (properly = 0) +// CHECK: postdominates(0, 2) = 0 (properly = 0) +// CHECK: postdominates(0, 3) = 0 (properly = 0) +// CHECK: postdominates(0, 4) = 0 (properly = 0) +// CHECK: postdominates(0, 5) = 0 (properly = 0) +// CHECK: postdominates(0, 6) = 0 (properly = 0) +// CHECK: postdominates(1, 0) = 1 (properly = 1) +// CHECK: postdominates(1, 1) = 1 (properly = 0) +// CHECK: postdominates(1, 2) = 1 (properly = 1) +// CHECK: postdominates(1, 3) = 1 (properly = 1) +// CHECK: postdominates(1, 4) = 1 (properly = 1) +// CHECK: postdominates(1, 5) = 0 (properly = 0) +// CHECK: postdominates(1, 6) = 0 (properly = 0) +// CHECK: postdominates(2, 0) = 0 (properly = 0) +// CHECK: postdominates(2, 1) = 0 (properly = 0) +// CHECK: postdominates(2, 2) = 1 (properly = 0) +// CHECK: postdominates(2, 3) = 1 (properly = 1) +// CHECK: postdominates(2, 4) = 1 (properly = 1) +// CHECK: postdominates(2, 5) = 0 (properly = 0) +// CHECK: postdominates(2, 6) = 0 (properly = 0) +// CHECK: postdominates(3, 0) = 0 (properly = 0) +// CHECK: postdominates(3, 1) = 0 (properly = 0) +// CHECK: postdominates(3, 2) = 0 (properly = 0) +// CHECK: postdominates(3, 3) = 1 (properly = 0) +// CHECK: postdominates(3, 4) = 0 (properly = 0) +// CHECK: postdominates(3, 5) = 0 (properly = 0) +// CHECK: postdominates(3, 6) = 0 (properly = 0) +// CHECK: postdominates(4, 0) = 0 (properly = 0) +// CHECK: postdominates(4, 1) = 0 (properly = 0) +// CHECK: postdominates(4, 2) = 0 (properly = 0) +// CHECK: postdominates(4, 3) = 1 (properly = 1) +// CHECK: postdominates(4, 4) = 1 (properly = 0) +// CHECK: postdominates(4, 5) = 0 (properly = 0) +// CHECK: postdominates(4, 6) = 0 (properly = 0) +// CHECK: postdominates(5, 0) = 1 (properly = 1) +// CHECK: postdominates(5, 1) = 1 (properly = 1) +// CHECK: postdominates(5, 2) = 1 (properly = 1) +// CHECK: postdominates(5, 3) = 1 (properly = 1) +// CHECK: postdominates(5, 4) = 1 (properly = 1) +// CHECK: postdominates(5, 5) = 1 (properly = 0) +// CHECK: postdominates(5, 6) = 0 (properly = 0) +// CHECK: postdominates(6, 0) = 1 (properly = 1) +// CHECK: postdominates(6, 1) = 1 (properly = 1) +// CHECK: postdominates(6, 2) = 1 (properly = 1) +// CHECK: postdominates(6, 3) = 1 (properly = 1) +// CHECK: postdominates(6, 4) = 1 (properly = 1) +// CHECK: postdominates(6, 5) = 1 (properly = 1) +// CHECK: postdominates(6, 6) = 1 (properly = 1) + +// CHECK: module attributes {test.block_ids = array} { +// CHECK: func.func @func_loop_nested_region({{.*}}) attributes {test.block_ids = array} { +// CHECK: ^{{.*}} +// CHECK: ^{{.*}} +// CHECK: scf.for {{.*}} { +// CHECK: scf.for {{.*}} { +// CHECK: } {test.block_ids = array} +// CHECK: } {test.block_ids = array} +// CHECK: ^{{.*}} +// CHECK: } +// CHECK: } diff --git a/mlir/test/lib/IR/TestDominance.cpp b/mlir/test/lib/IR/TestDominance.cpp index fab80bdacb032..b34149b3e2cbd 100644 --- a/mlir/test/lib/IR/TestDominance.cpp +++ b/mlir/test/lib/IR/TestDominance.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "mlir/IR/Builders.h" #include "mlir/IR/Dominance.h" #include "mlir/IR/SymbolTable.h" #include "mlir/Pass/Pass.h" @@ -24,24 +25,46 @@ static bool dominatesOrPostDominates(DominanceInfo &dominanceInfo, Block *a, Block *b) { return dominanceInfo.dominates(a, b); } - static bool dominatesOrPostDominates(PostDominanceInfo &dominanceInfo, Block *a, Block *b) { return dominanceInfo.postDominates(a, b); } +static bool properlyDominatesOrPostDominates(DominanceInfo &dominanceInfo, + Block *a, Block *b) { + return dominanceInfo.properlyDominates(a, b); +} +static bool properlyDominatesOrPostDominates(PostDominanceInfo &dominanceInfo, + Block *a, Block *b) { + return dominanceInfo.properlyPostDominates(a, b); +} namespace { /// Helper class to print dominance information. class DominanceTest { public: + static constexpr StringRef kBlockIdsAttrName = "test.block_ids"; + /// Constructs a new test instance using the given operation. DominanceTest(Operation *operation) : operation(operation) { - // Create unique ids for each block. + Builder b(operation->getContext()); + + // Helper function that annotates the IR with block IDs. + auto annotateBlockId = [&](Operation *op, int64_t blockId) { + auto idAttr = op->getAttrOfType(kBlockIdsAttrName); + SmallVector ids; + if (idAttr) + ids = llvm::to_vector(idAttr.asArrayRef()); + ids.push_back(blockId); + op->setAttr(kBlockIdsAttrName, b.getDenseI64ArrayAttr(ids)); + }; + + // Create unique IDs for each block. operation->walk([&](Operation *nested) { if (blockIds.count(nested->getBlock()) > 0) return; blockIds.insert({nested->getBlock(), blockIds.size()}); + annotateBlockId(nested->getBlock()->getParentOp(), blockIds.size() - 1); }); } @@ -61,26 +84,28 @@ class DominanceTest { if (!visited.insert(nestedBlock).second) return; if (printCommonDominatorInfo) { - llvm::errs() << "Nearest(" << blockIds[block] << ", " + llvm::outs() << "Nearest(" << blockIds[block] << ", " << blockIds[nestedBlock] << ") = "; Block *dom = dominanceInfo.findNearestCommonDominator(block, nestedBlock); if (dom) - llvm::errs() << blockIds[dom]; + llvm::outs() << blockIds[dom]; else - llvm::errs() << ""; - llvm::errs() << "\n"; + llvm::outs() << ""; + llvm::outs() << "\n"; } else { if (std::is_same::value) - llvm::errs() << "dominates("; - else - llvm::errs() << "postdominates("; - llvm::errs() << blockIds[block] << ", " << blockIds[nestedBlock] - << ") = "; - if (dominatesOrPostDominates(dominanceInfo, block, nestedBlock)) - llvm::errs() << "true\n"; + llvm::outs() << "dominates("; else - llvm::errs() << "false\n"; + llvm::outs() << "postdominates("; + llvm::outs() << blockIds[block] << ", " << blockIds[nestedBlock] + << ") = " + << std::to_string(dominatesOrPostDominates( + dominanceInfo, block, nestedBlock)) + << " (properly = " + << std::to_string(properlyDominatesOrPostDominates( + dominanceInfo, block, nestedBlock)) + << ")\n"; } }); }); @@ -101,24 +126,24 @@ struct TestDominancePass } void runOnOperation() override { - llvm::errs() << "Testing : " << getOperation().getName() << "\n"; + llvm::outs() << "Testing : " << getOperation().getName() << "\n"; DominanceTest dominanceTest(getOperation()); // Print dominance information. - llvm::errs() << "--- DominanceInfo ---\n"; + llvm::outs() << "--- DominanceInfo ---\n"; dominanceTest.printDominance(getAnalysis(), /*printCommonDominatorInfo=*/true); - llvm::errs() << "--- PostDominanceInfo ---\n"; + llvm::outs() << "--- PostDominanceInfo ---\n"; dominanceTest.printDominance(getAnalysis(), /*printCommonDominatorInfo=*/true); // Print dominance relationship between blocks. - llvm::errs() << "--- Block Dominance relationship ---\n"; + llvm::outs() << "--- Block Dominance relationship ---\n"; dominanceTest.printDominance(getAnalysis(), /*printCommonDominatorInfo=*/false); - llvm::errs() << "--- Block PostDominance relationship ---\n"; + llvm::outs() << "--- Block PostDominance relationship ---\n"; dominanceTest.printDominance(getAnalysis(), /*printCommonDominatorInfo=*/false); }