1 //===- TestDominance.cpp - Test dominance construction and information
2 //-------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains test passes for constructing and resolving dominance
11 // information.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "mlir/IR/Dominance.h"
16 #include "mlir/Pass/Pass.h"
17
18 using namespace mlir;
19
20 /// Overloaded helper to call the right function based on whether we are testing
21 /// dominance or post-dominance.
dominatesOrPostDominates(DominanceInfo & dominanceInfo,Block * a,Block * b)22 static bool dominatesOrPostDominates(DominanceInfo &dominanceInfo, Block *a,
23 Block *b) {
24 return dominanceInfo.dominates(a, b);
25 }
26
dominatesOrPostDominates(PostDominanceInfo & dominanceInfo,Block * a,Block * b)27 static bool dominatesOrPostDominates(PostDominanceInfo &dominanceInfo, Block *a,
28 Block *b) {
29 return dominanceInfo.postDominates(a, b);
30 }
31
32 namespace {
33
34 /// Helper class to print dominance information.
35 class DominanceTest {
36 public:
37 /// Constructs a new test instance using the given operation.
DominanceTest(Operation * operation)38 DominanceTest(Operation *operation) : operation(operation) {
39 // Create unique ids for each block.
40 operation->walk([&](Operation *nested) {
41 if (blockIds.count(nested->getBlock()) > 0)
42 return;
43 blockIds.insert({nested->getBlock(), blockIds.size()});
44 });
45 }
46
47 /// Prints dominance information of all blocks.
48 template <typename DominanceT>
printDominance(DominanceT & dominanceInfo,bool printCommonDominatorInfo)49 void printDominance(DominanceT &dominanceInfo,
50 bool printCommonDominatorInfo) {
51 DenseSet<Block *> parentVisited;
52 operation->walk([&](Operation *op) {
53 Block *block = op->getBlock();
54 if (!parentVisited.insert(block).second)
55 return;
56
57 DenseSet<Block *> visited;
58 operation->walk([&](Operation *nested) {
59 Block *nestedBlock = nested->getBlock();
60 if (!visited.insert(nestedBlock).second)
61 return;
62 if (printCommonDominatorInfo) {
63 llvm::errs() << "Nearest(" << blockIds[block] << ", "
64 << blockIds[nestedBlock] << ") = ";
65 Block *dom =
66 dominanceInfo.findNearestCommonDominator(block, nestedBlock);
67 if (dom)
68 llvm::errs() << blockIds[dom];
69 else
70 llvm::errs() << "<no dom>";
71 llvm::errs() << "\n";
72 } else {
73 if (std::is_same<DominanceInfo, DominanceT>::value)
74 llvm::errs() << "dominates(";
75 else
76 llvm::errs() << "postdominates(";
77 llvm::errs() << blockIds[block] << ", " << blockIds[nestedBlock]
78 << ") = ";
79 if (dominatesOrPostDominates(dominanceInfo, block, nestedBlock))
80 llvm::errs() << "true\n";
81 else
82 llvm::errs() << "false\n";
83 }
84 });
85 });
86 }
87
88 private:
89 Operation *operation;
90 DenseMap<Block *, size_t> blockIds;
91 };
92
93 struct TestDominancePass : public PassWrapper<TestDominancePass, FunctionPass> {
94
runOnFunction__anon8f071b940111::TestDominancePass95 void runOnFunction() override {
96 llvm::errs() << "Testing : " << getFunction().getName() << "\n";
97 DominanceTest dominanceTest(getFunction());
98
99 // Print dominance information.
100 llvm::errs() << "--- DominanceInfo ---\n";
101 dominanceTest.printDominance(getAnalysis<DominanceInfo>(),
102 /*printCommonDominatorInfo=*/true);
103
104 llvm::errs() << "--- PostDominanceInfo ---\n";
105 dominanceTest.printDominance(getAnalysis<PostDominanceInfo>(),
106 /*printCommonDominatorInfo=*/true);
107
108 // Print dominance relationship between blocks.
109 llvm::errs() << "--- Block Dominance relationship ---\n";
110 dominanceTest.printDominance(getAnalysis<DominanceInfo>(),
111 /*printCommonDominatorInfo=*/false);
112
113 llvm::errs() << "--- Block PostDominance relationship ---\n";
114 dominanceTest.printDominance(getAnalysis<PostDominanceInfo>(),
115 /*printCommonDominatorInfo=*/false);
116 }
117 };
118
119 } // end anonymous namespace
120
121 namespace mlir {
122 namespace test {
registerTestDominancePass()123 void registerTestDominancePass() {
124 PassRegistration<TestDominancePass>(
125 "test-print-dominance",
126 "Print the dominance information for multiple regions.");
127 }
128 } // namespace test
129 } // namespace mlir
130