Revert "[clang-repl] Enable native CPU detection by default (#77491)" (#79178)
[llvm-project.git] / mlir / unittests / Pass / AnalysisManagerTest.cpp
blobd494db86a9de90b47a478d1cde307f02ff7decfa
1 //===- AnalysisManagerTest.cpp - AnalysisManager unit tests ---------------===//
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 //===----------------------------------------------------------------------===//
9 #include "mlir/Pass/AnalysisManager.h"
10 #include "mlir/Dialect/Func/IR/FuncOps.h"
11 #include "mlir/IR/Builders.h"
12 #include "mlir/IR/BuiltinOps.h"
13 #include "mlir/Pass/Pass.h"
14 #include "mlir/Pass/PassManager.h"
15 #include "gtest/gtest.h"
17 using namespace mlir;
18 using namespace mlir::detail;
20 namespace {
21 /// Minimal class definitions for two analyses.
22 struct MyAnalysis {
23 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(MyAnalysis)
25 MyAnalysis(Operation *) {}
27 struct OtherAnalysis {
28 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(OtherAnalysis)
30 OtherAnalysis(Operation *) {}
32 struct OpSpecificAnalysis {
33 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(OpSpecificAnalysis)
35 OpSpecificAnalysis(ModuleOp) {}
38 TEST(AnalysisManagerTest, FineGrainModuleAnalysisPreservation) {
39 MLIRContext context;
41 // Test fine grain invalidation of the module analysis manager.
42 OwningOpRef<ModuleOp> module(ModuleOp::create(UnknownLoc::get(&context)));
43 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr);
44 AnalysisManager am = mam;
46 // Query two different analyses, but only preserve one before invalidating.
47 am.getAnalysis<MyAnalysis>();
48 am.getAnalysis<OtherAnalysis>();
50 detail::PreservedAnalyses pa;
51 pa.preserve<MyAnalysis>();
52 am.invalidate(pa);
54 // Check that only MyAnalysis is preserved.
55 EXPECT_TRUE(am.getCachedAnalysis<MyAnalysis>().has_value());
56 EXPECT_FALSE(am.getCachedAnalysis<OtherAnalysis>().has_value());
59 TEST(AnalysisManagerTest, FineGrainFunctionAnalysisPreservation) {
60 MLIRContext context;
61 context.loadDialect<func::FuncDialect>();
62 Builder builder(&context);
64 // Create a function and a module.
65 OwningOpRef<ModuleOp> module(ModuleOp::create(UnknownLoc::get(&context)));
66 func::FuncOp func1 =
67 func::FuncOp::create(builder.getUnknownLoc(), "foo",
68 builder.getFunctionType(std::nullopt, std::nullopt));
69 func1.setPrivate();
70 module->push_back(func1);
72 // Test fine grain invalidation of the function analysis manager.
73 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr);
74 AnalysisManager am = mam;
75 AnalysisManager fam = am.nest(func1);
77 // Query two different analyses, but only preserve one before invalidating.
78 fam.getAnalysis<MyAnalysis>();
79 fam.getAnalysis<OtherAnalysis>();
81 detail::PreservedAnalyses pa;
82 pa.preserve<MyAnalysis>();
83 fam.invalidate(pa);
85 // Check that only MyAnalysis is preserved.
86 EXPECT_TRUE(fam.getCachedAnalysis<MyAnalysis>().has_value());
87 EXPECT_FALSE(fam.getCachedAnalysis<OtherAnalysis>().has_value());
90 TEST(AnalysisManagerTest, FineGrainChildFunctionAnalysisPreservation) {
91 MLIRContext context;
92 context.loadDialect<func::FuncDialect>();
93 Builder builder(&context);
95 // Create a function and a module.
96 OwningOpRef<ModuleOp> module(ModuleOp::create(UnknownLoc::get(&context)));
97 func::FuncOp func1 =
98 func::FuncOp::create(builder.getUnknownLoc(), "foo",
99 builder.getFunctionType(std::nullopt, std::nullopt));
100 func1.setPrivate();
101 module->push_back(func1);
103 // Test fine grain invalidation of a function analysis from within a module
104 // analysis manager.
105 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr);
106 AnalysisManager am = mam;
108 // Check that the analysis cache is initially empty.
109 EXPECT_FALSE(am.getCachedChildAnalysis<MyAnalysis>(func1).has_value());
111 // Query two different analyses, but only preserve one before invalidating.
112 am.getChildAnalysis<MyAnalysis>(func1);
113 am.getChildAnalysis<OtherAnalysis>(func1);
115 detail::PreservedAnalyses pa;
116 pa.preserve<MyAnalysis>();
117 am.invalidate(pa);
119 // Check that only MyAnalysis is preserved.
120 EXPECT_TRUE(am.getCachedChildAnalysis<MyAnalysis>(func1).has_value());
121 EXPECT_FALSE(am.getCachedChildAnalysis<OtherAnalysis>(func1).has_value());
124 /// Test analyses with custom invalidation logic.
125 struct TestAnalysisSet {
126 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestAnalysisSet)
129 struct CustomInvalidatingAnalysis {
130 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(CustomInvalidatingAnalysis)
132 CustomInvalidatingAnalysis(Operation *) {}
134 bool isInvalidated(const AnalysisManager::PreservedAnalyses &pa) {
135 return !pa.isPreserved<TestAnalysisSet>();
139 TEST(AnalysisManagerTest, CustomInvalidation) {
140 MLIRContext context;
141 Builder builder(&context);
143 // Create a function and a module.
144 OwningOpRef<ModuleOp> module(ModuleOp::create(UnknownLoc::get(&context)));
145 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr);
146 AnalysisManager am = mam;
148 detail::PreservedAnalyses pa;
150 // Check that the analysis is invalidated properly.
151 am.getAnalysis<CustomInvalidatingAnalysis>();
152 am.invalidate(pa);
153 EXPECT_FALSE(am.getCachedAnalysis<CustomInvalidatingAnalysis>().has_value());
155 // Check that the analysis is preserved properly.
156 am.getAnalysis<CustomInvalidatingAnalysis>();
157 pa.preserve<TestAnalysisSet>();
158 am.invalidate(pa);
159 EXPECT_TRUE(am.getCachedAnalysis<CustomInvalidatingAnalysis>().has_value());
162 TEST(AnalysisManagerTest, OpSpecificAnalysis) {
163 MLIRContext context;
165 // Create a module.
166 OwningOpRef<ModuleOp> module(ModuleOp::create(UnknownLoc::get(&context)));
167 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr);
168 AnalysisManager am = mam;
170 // Query the op specific analysis for the module and verify that its cached.
171 am.getAnalysis<OpSpecificAnalysis, ModuleOp>();
172 EXPECT_TRUE(am.getCachedAnalysis<OpSpecificAnalysis>().has_value());
175 struct AnalysisWithDependency {
176 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(AnalysisWithDependency)
178 AnalysisWithDependency(Operation *, AnalysisManager &am) {
179 am.getAnalysis<MyAnalysis>();
182 bool isInvalidated(const AnalysisManager::PreservedAnalyses &pa) {
183 return !pa.isPreserved<AnalysisWithDependency>() ||
184 !pa.isPreserved<MyAnalysis>();
188 TEST(AnalysisManagerTest, DependentAnalysis) {
189 MLIRContext context;
191 // Create a module.
192 OwningOpRef<ModuleOp> module(ModuleOp::create(UnknownLoc::get(&context)));
193 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr);
194 AnalysisManager am = mam;
196 am.getAnalysis<AnalysisWithDependency>();
197 EXPECT_TRUE(am.getCachedAnalysis<AnalysisWithDependency>().has_value());
198 EXPECT_TRUE(am.getCachedAnalysis<MyAnalysis>().has_value());
200 detail::PreservedAnalyses pa;
201 pa.preserve<AnalysisWithDependency>();
202 am.invalidate(pa);
204 EXPECT_FALSE(am.getCachedAnalysis<AnalysisWithDependency>().has_value());
205 EXPECT_FALSE(am.getCachedAnalysis<MyAnalysis>().has_value());
208 struct AnalysisWithNestedDependency {
209 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(AnalysisWithNestedDependency)
211 AnalysisWithNestedDependency(Operation *, AnalysisManager &am) {
212 am.getAnalysis<AnalysisWithDependency>();
215 bool isInvalidated(const AnalysisManager::PreservedAnalyses &pa) {
216 return !pa.isPreserved<AnalysisWithNestedDependency>() ||
217 !pa.isPreserved<AnalysisWithDependency>();
221 TEST(AnalysisManagerTest, NestedDependentAnalysis) {
222 MLIRContext context;
224 // Create a module.
225 OwningOpRef<ModuleOp> module(ModuleOp::create(UnknownLoc::get(&context)));
226 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr);
227 AnalysisManager am = mam;
229 am.getAnalysis<AnalysisWithNestedDependency>();
230 EXPECT_TRUE(am.getCachedAnalysis<AnalysisWithNestedDependency>().has_value());
231 EXPECT_TRUE(am.getCachedAnalysis<AnalysisWithDependency>().has_value());
232 EXPECT_TRUE(am.getCachedAnalysis<MyAnalysis>().has_value());
234 detail::PreservedAnalyses pa;
235 pa.preserve<AnalysisWithDependency>();
236 pa.preserve<AnalysisWithNestedDependency>();
237 am.invalidate(pa);
239 EXPECT_FALSE(
240 am.getCachedAnalysis<AnalysisWithNestedDependency>().has_value());
241 EXPECT_FALSE(am.getCachedAnalysis<AnalysisWithDependency>().has_value());
242 EXPECT_FALSE(am.getCachedAnalysis<MyAnalysis>().has_value());
245 struct AnalysisWith2Ctors {
246 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(AnalysisWith2Ctors)
248 AnalysisWith2Ctors(Operation *) { ctor1called = true; }
250 AnalysisWith2Ctors(Operation *, AnalysisManager &) { ctor2called = true; }
252 bool ctor1called = false;
253 bool ctor2called = false;
256 TEST(AnalysisManagerTest, DependentAnalysis2Ctors) {
257 MLIRContext context;
259 // Create a module.
260 OwningOpRef<ModuleOp> module(ModuleOp::create(UnknownLoc::get(&context)));
261 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr);
262 AnalysisManager am = mam;
264 auto &an = am.getAnalysis<AnalysisWith2Ctors>();
265 EXPECT_FALSE(an.ctor1called);
266 EXPECT_TRUE(an.ctor2called);
269 } // namespace