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