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/IR/SymbolTable.h"
17#include "mlir/Pass/Pass.h"
18
19using namespace mlir;
20
21/// Overloaded helper to call the right function based on whether we are testing
22/// dominance or post-dominance.
23static bool dominatesOrPostDominates(DominanceInfo &dominanceInfo, Block *a,
24 Block *b) {
25 return dominanceInfo.dominates(a, b);
26}
27
28static bool dominatesOrPostDominates(PostDominanceInfo &dominanceInfo, Block *a,
29 Block *b) {
30 return dominanceInfo.postDominates(a, b);
31}
32
33namespace {
34
35/// Helper class to print dominance information.
36class DominanceTest {
37public:
38 /// Constructs a new test instance using the given operation.
39 DominanceTest(Operation *operation) : operation(operation) {
40 // Create unique ids for each block.
41 operation->walk(callback: [&](Operation *nested) {
42 if (blockIds.count(Val: nested->getBlock()) > 0)
43 return;
44 blockIds.insert(KV: {nested->getBlock(), blockIds.size()});
45 });
46 }
47
48 /// Prints dominance information of all blocks.
49 template <typename DominanceT>
50 void printDominance(DominanceT &dominanceInfo,
51 bool printCommonDominatorInfo) {
52 DenseSet<Block *> parentVisited;
53 operation->walk([&](Operation *op) {
54 Block *block = op->getBlock();
55 if (!parentVisited.insert(V: block).second)
56 return;
57
58 DenseSet<Block *> visited;
59 operation->walk([&](Operation *nested) {
60 Block *nestedBlock = nested->getBlock();
61 if (!visited.insert(V: nestedBlock).second)
62 return;
63 if (printCommonDominatorInfo) {
64 llvm::errs() << "Nearest(" << blockIds[block] << ", "
65 << blockIds[nestedBlock] << ") = ";
66 Block *dom =
67 dominanceInfo.findNearestCommonDominator(block, nestedBlock);
68 if (dom)
69 llvm::errs() << blockIds[dom];
70 else
71 llvm::errs() << "<no dom>";
72 llvm::errs() << "\n";
73 } else {
74 if (std::is_same<DominanceInfo, DominanceT>::value)
75 llvm::errs() << "dominates(";
76 else
77 llvm::errs() << "postdominates(";
78 llvm::errs() << blockIds[block] << ", " << blockIds[nestedBlock]
79 << ") = ";
80 if (dominatesOrPostDominates(dominanceInfo, block, nestedBlock))
81 llvm::errs() << "true\n";
82 else
83 llvm::errs() << "false\n";
84 }
85 });
86 });
87 }
88
89private:
90 Operation *operation;
91 DenseMap<Block *, size_t> blockIds;
92};
93
94struct TestDominancePass
95 : public PassWrapper<TestDominancePass, InterfacePass<SymbolOpInterface>> {
96 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestDominancePass)
97
98 StringRef getArgument() const final { return "test-print-dominance"; }
99 StringRef getDescription() const final {
100 return "Print the dominance information for multiple regions.";
101 }
102
103 void runOnOperation() override {
104 llvm::errs() << "Testing : " << getOperation().getName() << "\n";
105 DominanceTest dominanceTest(getOperation());
106
107 // Print dominance information.
108 llvm::errs() << "--- DominanceInfo ---\n";
109 dominanceTest.printDominance(getAnalysis<DominanceInfo>(),
110 /*printCommonDominatorInfo=*/true);
111
112 llvm::errs() << "--- PostDominanceInfo ---\n";
113 dominanceTest.printDominance(getAnalysis<PostDominanceInfo>(),
114 /*printCommonDominatorInfo=*/true);
115
116 // Print dominance relationship between blocks.
117 llvm::errs() << "--- Block Dominance relationship ---\n";
118 dominanceTest.printDominance(getAnalysis<DominanceInfo>(),
119 /*printCommonDominatorInfo=*/false);
120
121 llvm::errs() << "--- Block PostDominance relationship ---\n";
122 dominanceTest.printDominance(getAnalysis<PostDominanceInfo>(),
123 /*printCommonDominatorInfo=*/false);
124 }
125};
126
127} // namespace
128
129namespace mlir {
130namespace test {
131void registerTestDominancePass() { PassRegistration<TestDominancePass>(); }
132} // namespace test
133} // namespace mlir
134

source code of mlir/test/lib/IR/TestDominance.cpp