xref: /llvm-project/mlir/test/lib/Analysis/TestCFGLoopInfo.cpp (revision 34a35a8b244243f5a4ad5d531007bccfeaa0b02e)
1 //===- TestCFGLoopInfo.cpp - Test CFG loop info analysis ------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements logic for testing the CFGLoopInfo analysis.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "mlir/Analysis/CFGLoopInfo.h"
14 #include "mlir/Interfaces/FunctionInterfaces.h"
15 #include "mlir/Pass/Pass.h"
16 
17 using namespace mlir;
18 
19 namespace {
20 /// A testing pass that applies the CFGLoopInfo analysis on a region and prints
21 /// the information it collected to llvm::errs().
22 struct TestCFGLoopInfo
23     : public PassWrapper<TestCFGLoopInfo, InterfacePass<FunctionOpInterface>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID__anone491a2740111::TestCFGLoopInfo24   MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestCFGLoopInfo)
25 
26   StringRef getArgument() const final { return "test-cfg-loop-info"; }
getDescription__anone491a2740111::TestCFGLoopInfo27   StringRef getDescription() const final {
28     return "Test the loop info analysis.";
29   }
30 
31   void runOnOperation() override;
32 };
33 } // namespace
34 
runOnOperation()35 void TestCFGLoopInfo::runOnOperation() {
36   auto func = getOperation();
37   DominanceInfo &domInfo = getAnalysis<DominanceInfo>();
38   Region &region = func.getFunctionBody();
39 
40   // Prints the label of the test.
41   llvm::errs() << "Testing : " << func.getNameAttr() << "\n";
42   if (region.empty()) {
43     llvm::errs() << "empty region\n";
44     return;
45   }
46 
47   // Print all the block identifiers first such that the tests can match them.
48   llvm::errs() << "Blocks : ";
49   region.front().printAsOperand(llvm::errs());
50   for (auto &block : region.getBlocks()) {
51     llvm::errs() << ", ";
52     block.printAsOperand(llvm::errs());
53   }
54   llvm::errs() << "\n";
55 
56   if (region.getBlocks().size() == 1) {
57     llvm::errs() << "no loops\n";
58     return;
59   }
60 
61   llvm::DominatorTreeBase<mlir::Block, false> &domTree =
62       domInfo.getDomTree(&region);
63   mlir::CFGLoopInfo loopInfo(domTree);
64 
65   if (loopInfo.getTopLevelLoops().empty())
66     llvm::errs() << "no loops\n";
67   else
68     loopInfo.print(llvm::errs());
69 }
70 
71 namespace mlir {
72 namespace test {
registerTestCFGLoopInfoPass()73 void registerTestCFGLoopInfoPass() { PassRegistration<TestCFGLoopInfo>(); }
74 } // namespace test
75 } // namespace mlir
76