blob: 13b87f1022e5c853b8c6e8e28b527d89744988f7 [file] [log] [blame]
Chandler Carruthea998842013-11-09 13:09:08 +00001//===- llvm/unittest/IR/PassManager.cpp - PassManager tests ---------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Chandler Carruth3c0d6072017-06-06 11:06:56 +000010#include "llvm/IR/PassManager.h"
Chandler Carruthbc65a8d2014-01-07 12:34:26 +000011#include "llvm/AsmParser/Parser.h"
Chandler Carruthea998842013-11-09 13:09:08 +000012#include "llvm/IR/Function.h"
13#include "llvm/IR/LLVMContext.h"
14#include "llvm/IR/Module.h"
Chandler Carruthea998842013-11-09 13:09:08 +000015#include "llvm/Support/SourceMgr.h"
16#include "gtest/gtest.h"
17
18using namespace llvm;
19
20namespace {
21
Chandler Carruth18e9a2b2016-03-11 10:33:22 +000022class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {
Chandler Carruthf348c972013-11-13 01:12:08 +000023public:
Chandler Carruthf348c972013-11-13 01:12:08 +000024 struct Result {
25 Result(int Count) : InstructionCount(Count) {}
Chandler Carruthf348c972013-11-13 01:12:08 +000026 int InstructionCount;
27 };
28
Chandler Carruth2ea11512013-11-23 01:25:02 +000029 TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
Chandler Carruth7fac06c2013-11-21 02:11:31 +000030
Adrian Prantl26b584c2018-05-01 15:54:18 +000031 /// Run the analysis pass over the function and return a result.
Chandler Carruth8e27cb22016-03-11 11:05:24 +000032 Result run(Function &F, FunctionAnalysisManager &AM) {
Chandler Carruth7fac06c2013-11-21 02:11:31 +000033 ++Runs;
Chandler Carruthf348c972013-11-13 01:12:08 +000034 int Count = 0;
Chandler Carruthb246ace2015-01-05 02:47:05 +000035 for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI)
Chandler Carruthf348c972013-11-13 01:12:08 +000036 for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
37 ++II)
38 ++Count;
39 return Result(Count);
40 }
41
42private:
Chandler Carruth18e9a2b2016-03-11 10:33:22 +000043 friend AnalysisInfoMixin<TestFunctionAnalysis>;
Chandler Carruth33d56812016-11-23 17:53:26 +000044 static AnalysisKey Key;
Chandler Carruthe95015f2016-03-11 10:22:49 +000045
Chandler Carruth7fac06c2013-11-21 02:11:31 +000046 int &Runs;
Chandler Carruthf348c972013-11-13 01:12:08 +000047};
48
Chandler Carruth33d56812016-11-23 17:53:26 +000049AnalysisKey TestFunctionAnalysis::Key;
Chandler Carruthe95015f2016-03-11 10:22:49 +000050
Chandler Carruth18e9a2b2016-03-11 10:33:22 +000051class TestModuleAnalysis : public AnalysisInfoMixin<TestModuleAnalysis> {
Chandler Carruthe5106652013-11-23 01:25:07 +000052public:
53 struct Result {
54 Result(int Count) : FunctionCount(Count) {}
55 int FunctionCount;
56 };
57
Chandler Carruthe5106652013-11-23 01:25:07 +000058 TestModuleAnalysis(int &Runs) : Runs(Runs) {}
59
Chandler Carruth8e27cb22016-03-11 11:05:24 +000060 Result run(Module &M, ModuleAnalysisManager &AM) {
Chandler Carruthe5106652013-11-23 01:25:07 +000061 ++Runs;
62 int Count = 0;
Chandler Carruthb246ace2015-01-05 02:47:05 +000063 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
Chandler Carruthe5106652013-11-23 01:25:07 +000064 ++Count;
65 return Result(Count);
66 }
67
68private:
Chandler Carruth18e9a2b2016-03-11 10:33:22 +000069 friend AnalysisInfoMixin<TestModuleAnalysis>;
Chandler Carruth33d56812016-11-23 17:53:26 +000070 static AnalysisKey Key;
Chandler Carruthe95015f2016-03-11 10:22:49 +000071
Chandler Carruthe5106652013-11-23 01:25:07 +000072 int &Runs;
73};
74
Chandler Carruth33d56812016-11-23 17:53:26 +000075AnalysisKey TestModuleAnalysis::Key;
Chandler Carruthe95015f2016-03-11 10:22:49 +000076
Chandler Carruth18e9a2b2016-03-11 10:33:22 +000077struct TestModulePass : PassInfoMixin<TestModulePass> {
Chandler Carruthea998842013-11-09 13:09:08 +000078 TestModulePass(int &RunCount) : RunCount(RunCount) {}
79
Chandler Carruth04d0fe92016-06-17 00:11:01 +000080 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
Chandler Carruthea998842013-11-09 13:09:08 +000081 ++RunCount;
Chandler Carruthc49e7e62013-11-20 11:31:50 +000082 return PreservedAnalyses::none();
Chandler Carruthea998842013-11-09 13:09:08 +000083 }
84
85 int &RunCount;
86};
87
Chandler Carruth18e9a2b2016-03-11 10:33:22 +000088struct TestPreservingModulePass : PassInfoMixin<TestPreservingModulePass> {
Chandler Carruth04d0fe92016-06-17 00:11:01 +000089 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
90 return PreservedAnalyses::all();
91 }
Chandler Carruthedd2b492013-11-21 10:53:05 +000092};
93
Chandler Carruth18e9a2b2016-03-11 10:33:22 +000094struct TestFunctionPass : PassInfoMixin<TestFunctionPass> {
Chandler Carruthb88831b2013-11-23 00:38:42 +000095 TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
Chandler Carruthe5106652013-11-23 01:25:07 +000096 int &AnalyzedFunctionCount,
Chandler Carruthb88831b2013-11-23 00:38:42 +000097 bool OnlyUseCachedResults = false)
98 : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
Chandler Carruthe5106652013-11-23 01:25:07 +000099 AnalyzedFunctionCount(AnalyzedFunctionCount),
Chandler Carruthb88831b2013-11-23 00:38:42 +0000100 OnlyUseCachedResults(OnlyUseCachedResults) {}
Chandler Carruthea998842013-11-09 13:09:08 +0000101
Chandler Carruth8e27cb22016-03-11 11:05:24 +0000102 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
Chandler Carruthea998842013-11-09 13:09:08 +0000103 ++RunCount;
Chandler Carruthf348c972013-11-13 01:12:08 +0000104
Chandler Carruthe5106652013-11-23 01:25:07 +0000105 const ModuleAnalysisManager &MAM =
Chandler Carruth8e27cb22016-03-11 11:05:24 +0000106 AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
Chandler Carruth77b655c2014-02-05 21:41:42 +0000107 if (TestModuleAnalysis::Result *TMA =
Chandler Carruthb246ace2015-01-05 02:47:05 +0000108 MAM.getCachedResult<TestModuleAnalysis>(*F.getParent()))
Chandler Carruthe5106652013-11-23 01:25:07 +0000109 AnalyzedFunctionCount += TMA->FunctionCount;
110
Chandler Carruthb88831b2013-11-23 00:38:42 +0000111 if (OnlyUseCachedResults) {
112 // Hack to force the use of the cached interface.
Chandler Carruth77b655c2014-02-05 21:41:42 +0000113 if (TestFunctionAnalysis::Result *AR =
Chandler Carruth8e27cb22016-03-11 11:05:24 +0000114 AM.getCachedResult<TestFunctionAnalysis>(F))
Chandler Carruthb88831b2013-11-23 00:38:42 +0000115 AnalyzedInstrCount += AR->InstructionCount;
116 } else {
117 // Typical path just runs the analysis as needed.
Chandler Carruth8e27cb22016-03-11 11:05:24 +0000118 TestFunctionAnalysis::Result &AR = AM.getResult<TestFunctionAnalysis>(F);
Chandler Carruthb88831b2013-11-23 00:38:42 +0000119 AnalyzedInstrCount += AR.InstructionCount;
120 }
Chandler Carruthf348c972013-11-13 01:12:08 +0000121
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000122 return PreservedAnalyses::all();
Chandler Carruthea998842013-11-09 13:09:08 +0000123 }
124
125 int &RunCount;
Chandler Carruthf348c972013-11-13 01:12:08 +0000126 int &AnalyzedInstrCount;
Chandler Carruthe5106652013-11-23 01:25:07 +0000127 int &AnalyzedFunctionCount;
Chandler Carruthb88831b2013-11-23 00:38:42 +0000128 bool OnlyUseCachedResults;
Chandler Carruthea998842013-11-09 13:09:08 +0000129};
130
Chandler Carruth4d32e852013-11-22 23:38:07 +0000131// A test function pass that invalidates all function analyses for a function
132// with a specific name.
Chandler Carruth18e9a2b2016-03-11 10:33:22 +0000133struct TestInvalidationFunctionPass
134 : PassInfoMixin<TestInvalidationFunctionPass> {
Chandler Carruth4d32e852013-11-22 23:38:07 +0000135 TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
136
Chandler Carruth04d0fe92016-06-17 00:11:01 +0000137 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
Chandler Carruthb246ace2015-01-05 02:47:05 +0000138 return F.getName() == Name ? PreservedAnalyses::none()
139 : PreservedAnalyses::all();
Chandler Carruth4d32e852013-11-22 23:38:07 +0000140 }
141
142 StringRef Name;
143};
144
Mehdi Amini8be77072016-04-14 21:59:01 +0000145std::unique_ptr<Module> parseIR(LLVMContext &Context, const char *IR) {
Chandler Carruthea998842013-11-09 13:09:08 +0000146 SMDiagnostic Err;
Mehdi Amini8be77072016-04-14 21:59:01 +0000147 return parseAssemblyString(IR, Err, Context);
Chandler Carruthea998842013-11-09 13:09:08 +0000148}
149
150class PassManagerTest : public ::testing::Test {
151protected:
Mehdi Amini8be77072016-04-14 21:59:01 +0000152 LLVMContext Context;
Ahmed Charlesf4ccd112014-03-06 05:51:42 +0000153 std::unique_ptr<Module> M;
Chandler Carruthea998842013-11-09 13:09:08 +0000154
155public:
156 PassManagerTest()
Mehdi Amini8be77072016-04-14 21:59:01 +0000157 : M(parseIR(Context, "define void @f() {\n"
158 "entry:\n"
159 " call void @g()\n"
160 " call void @h()\n"
161 " ret void\n"
162 "}\n"
163 "define void @g() {\n"
164 " ret void\n"
165 "}\n"
166 "define void @h() {\n"
167 " ret void\n"
168 "}\n")) {}
Chandler Carruthea998842013-11-09 13:09:08 +0000169};
170
Chandler Carruth0fc44672016-12-27 08:40:39 +0000171TEST(PreservedAnalysesTest, Basic) {
Chandler Carruth2d740922014-03-13 10:42:18 +0000172 PreservedAnalyses PA1 = PreservedAnalyses();
Chandler Carruth0fc44672016-12-27 08:40:39 +0000173 {
174 auto PAC = PA1.getChecker<TestFunctionAnalysis>();
175 EXPECT_FALSE(PAC.preserved());
176 EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
177 }
178 {
179 auto PAC = PA1.getChecker<TestModuleAnalysis>();
180 EXPECT_FALSE(PAC.preserved());
181 EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Module>>());
182 }
183 auto PA2 = PreservedAnalyses::none();
184 {
185 auto PAC = PA2.getChecker<TestFunctionAnalysis>();
186 EXPECT_FALSE(PAC.preserved());
187 EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
188 }
189 auto PA3 = PreservedAnalyses::all();
190 {
191 auto PAC = PA3.getChecker<TestFunctionAnalysis>();
192 EXPECT_TRUE(PAC.preserved());
193 EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
194 }
Chandler Carruth2d740922014-03-13 10:42:18 +0000195 PreservedAnalyses PA4 = PA1;
Chandler Carruth0fc44672016-12-27 08:40:39 +0000196 {
197 auto PAC = PA4.getChecker<TestFunctionAnalysis>();
198 EXPECT_FALSE(PAC.preserved());
199 EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
200 }
Chandler Carruth2d740922014-03-13 10:42:18 +0000201 PA4 = PA3;
Chandler Carruth0fc44672016-12-27 08:40:39 +0000202 {
203 auto PAC = PA4.getChecker<TestFunctionAnalysis>();
204 EXPECT_TRUE(PAC.preserved());
205 EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
206 }
Chandler Carruth2d740922014-03-13 10:42:18 +0000207 PA4 = std::move(PA2);
Chandler Carruth0fc44672016-12-27 08:40:39 +0000208 {
209 auto PAC = PA4.getChecker<TestFunctionAnalysis>();
210 EXPECT_FALSE(PAC.preserved());
211 EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
212 }
Chandler Carruth79b7faa2017-07-09 07:23:27 +0000213 auto PA5 = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>();
214 {
215 auto PAC = PA5.getChecker<TestFunctionAnalysis>();
216 EXPECT_FALSE(PAC.preserved());
217 EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
218 EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Module>>());
219 }
Chandler Carruth0fc44672016-12-27 08:40:39 +0000220}
221
222TEST(PreservedAnalysesTest, Preserve) {
223 auto PA = PreservedAnalyses::none();
224 PA.preserve<TestFunctionAnalysis>();
225 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
226 EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>().preserved());
227 PA.preserve<TestModuleAnalysis>();
228 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
229 EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>().preserved());
230
231 // Redundant calls are fine.
232 PA.preserve<TestFunctionAnalysis>();
233 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
234 EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>().preserved());
235}
236
237TEST(PreservedAnalysesTest, PreserveSets) {
238 auto PA = PreservedAnalyses::none();
239 PA.preserveSet<AllAnalysesOn<Function>>();
240 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
241 .preservedSet<AllAnalysesOn<Function>>());
242 EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>()
243 .preservedSet<AllAnalysesOn<Module>>());
244 PA.preserveSet<AllAnalysesOn<Module>>();
245 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
246 .preservedSet<AllAnalysesOn<Function>>());
247 EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
248 .preservedSet<AllAnalysesOn<Module>>());
249
250 // Mixing is fine.
251 PA.preserve<TestFunctionAnalysis>();
252 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
253 .preservedSet<AllAnalysesOn<Function>>());
254 EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
255 .preservedSet<AllAnalysesOn<Module>>());
256
257 // Redundant calls are fine.
258 PA.preserveSet<AllAnalysesOn<Module>>();
259 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
260 .preservedSet<AllAnalysesOn<Function>>());
261 EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
262 .preservedSet<AllAnalysesOn<Module>>());
263}
264
265TEST(PreservedAnalysisTest, Intersect) {
266 // Setup the initial sets.
267 auto PA1 = PreservedAnalyses::none();
Chandler Carruth2d740922014-03-13 10:42:18 +0000268 PA1.preserve<TestFunctionAnalysis>();
Chandler Carruth0fc44672016-12-27 08:40:39 +0000269 PA1.preserveSet<AllAnalysesOn<Module>>();
270 auto PA2 = PreservedAnalyses::none();
271 PA2.preserve<TestFunctionAnalysis>();
272 PA2.preserveSet<AllAnalysesOn<Function>>();
273 PA2.preserve<TestModuleAnalysis>();
274 PA2.preserveSet<AllAnalysesOn<Module>>();
275 auto PA3 = PreservedAnalyses::none();
276 PA3.preserve<TestModuleAnalysis>();
277 PA3.preserveSet<AllAnalysesOn<Function>>();
278
279 // Self intersection is a no-op.
280 auto Intersected = PA1;
281 Intersected.intersect(PA1);
282 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
283 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
284 .preservedSet<AllAnalysesOn<Function>>());
285 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
286 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
287 .preservedSet<AllAnalysesOn<Module>>());
288
289 // Intersecting with all is a no-op.
290 Intersected.intersect(PreservedAnalyses::all());
291 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
292 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
293 .preservedSet<AllAnalysesOn<Function>>());
294 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
295 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
296 .preservedSet<AllAnalysesOn<Module>>());
297
298 // Intersecting a narrow set with a more broad set is the narrow set.
299 Intersected.intersect(PA2);
300 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
301 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
302 .preservedSet<AllAnalysesOn<Function>>());
303 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
304 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
305 .preservedSet<AllAnalysesOn<Module>>());
306
307 // Intersecting a broad set with a more narrow set is the narrow set.
308 Intersected = PA2;
309 Intersected.intersect(PA1);
310 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
311 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
312 .preservedSet<AllAnalysesOn<Function>>());
313 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
314 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
315 .preservedSet<AllAnalysesOn<Module>>());
316
317 // Intersecting with empty clears.
318 Intersected.intersect(PreservedAnalyses::none());
319 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
320 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
321 .preservedSet<AllAnalysesOn<Function>>());
322 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
323 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>()
324 .preservedSet<AllAnalysesOn<Module>>());
325
326 // Intersecting non-overlapping clears.
327 Intersected = PA1;
328 Intersected.intersect(PA3);
329 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
330 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
331 .preservedSet<AllAnalysesOn<Function>>());
332 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
333 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>()
334 .preservedSet<AllAnalysesOn<Module>>());
335
336 // Intersecting with moves works in when there is storage on both sides.
337 Intersected = PA1;
338 auto Tmp = PA2;
339 Intersected.intersect(std::move(Tmp));
340 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
341 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
342 .preservedSet<AllAnalysesOn<Function>>());
343 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
344 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
345 .preservedSet<AllAnalysesOn<Module>>());
346
347 // Intersecting with move works for incoming all and existing all.
348 auto Tmp2 = PreservedAnalyses::all();
349 Intersected.intersect(std::move(Tmp2));
350 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
351 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
352 .preservedSet<AllAnalysesOn<Function>>());
353 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
354 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
355 .preservedSet<AllAnalysesOn<Module>>());
356 Intersected = PreservedAnalyses::all();
357 auto Tmp3 = PA1;
358 Intersected.intersect(std::move(Tmp3));
359 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
360 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
361 .preservedSet<AllAnalysesOn<Function>>());
362 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
363 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
364 .preservedSet<AllAnalysesOn<Module>>());
365}
366
367TEST(PreservedAnalysisTest, Abandon) {
368 auto PA = PreservedAnalyses::none();
369
370 // We can abandon things after they are preserved.
371 PA.preserve<TestFunctionAnalysis>();
372 PA.abandon<TestFunctionAnalysis>();
373 EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>().preserved());
374
375 // Repeated is fine, and abandoning if they were never preserved is fine.
376 PA.abandon<TestFunctionAnalysis>();
377 EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>().preserved());
378 PA.abandon<TestModuleAnalysis>();
379 EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>().preserved());
380
381 // Even if the sets are preserved, the abandoned analyses' checker won't
382 // return true for those sets.
383 PA.preserveSet<AllAnalysesOn<Function>>();
384 PA.preserveSet<AllAnalysesOn<Module>>();
385 EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>()
386 .preservedSet<AllAnalysesOn<Function>>());
387 EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>()
388 .preservedSet<AllAnalysesOn<Module>>());
389
390 // But an arbitrary (opaque) analysis will still observe the sets as
391 // preserved. This also checks that we can use an explicit ID rather than
392 // a type.
393 AnalysisKey FakeKey, *FakeID = &FakeKey;
394 EXPECT_TRUE(PA.getChecker(FakeID).preservedSet<AllAnalysesOn<Function>>());
395 EXPECT_TRUE(PA.getChecker(FakeID).preservedSet<AllAnalysesOn<Module>>());
Chandler Carruth2d740922014-03-13 10:42:18 +0000396}
397
Chandler Carruthea998842013-11-09 13:09:08 +0000398TEST_F(PassManagerTest, Basic) {
Chandler Carruth8bf27802016-12-10 06:34:44 +0000399 FunctionAnalysisManager FAM(/*DebugLogging*/ true);
Chandler Carruthe5106652013-11-23 01:25:07 +0000400 int FunctionAnalysisRuns = 0;
Chandler Carruth67a41f02016-02-18 09:45:17 +0000401 FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
Chandler Carruthf348c972013-11-13 01:12:08 +0000402
Chandler Carruth8bf27802016-12-10 06:34:44 +0000403 ModuleAnalysisManager MAM(/*DebugLogging*/ true);
Chandler Carruthe5106652013-11-23 01:25:07 +0000404 int ModuleAnalysisRuns = 0;
Chandler Carruth67a41f02016-02-18 09:45:17 +0000405 MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
406 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
407 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000408
Fedor Sergeeve6959a62018-09-20 17:08:45 +0000409 MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
410 FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
411
Chandler Carruthd793a052013-11-22 00:43:29 +0000412 ModulePassManager MPM;
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000413
414 // Count the runs over a Function.
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000415 int FunctionPassRunCount1 = 0;
416 int AnalyzedInstrCount1 = 0;
Chandler Carruthe5106652013-11-23 01:25:07 +0000417 int AnalyzedFunctionCount1 = 0;
Chandler Carruth15903b72014-03-09 11:49:53 +0000418 {
Chandler Carruth2d740922014-03-13 10:42:18 +0000419 // Pointless scoped copy to test move assignment.
Chandler Carruth8bf27802016-12-10 06:34:44 +0000420 ModulePassManager NestedMPM(/*DebugLogging*/ true);
Chandler Carruth15903b72014-03-09 11:49:53 +0000421 FunctionPassManager FPM;
Chandler Carruth2d740922014-03-13 10:42:18 +0000422 {
423 // Pointless scope to test move assignment.
Chandler Carruth8bf27802016-12-10 06:34:44 +0000424 FunctionPassManager NestedFPM(/*DebugLogging*/ true);
Chandler Carruthbd6882c2016-06-17 07:15:29 +0000425 NestedFPM.addPass(TestFunctionPass(
426 FunctionPassRunCount1, AnalyzedInstrCount1, AnalyzedFunctionCount1));
Chandler Carruth2d740922014-03-13 10:42:18 +0000427 FPM = std::move(NestedFPM);
428 }
429 NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
430 MPM = std::move(NestedMPM);
Chandler Carruth15903b72014-03-09 11:49:53 +0000431 }
Chandler Carruthea998842013-11-09 13:09:08 +0000432
433 // Count the runs over a module.
434 int ModulePassRunCount = 0;
435 MPM.addPass(TestModulePass(ModulePassRunCount));
436
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000437 // Count the runs over a Function in a separate manager.
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000438 int FunctionPassRunCount2 = 0;
439 int AnalyzedInstrCount2 = 0;
Chandler Carruthe5106652013-11-23 01:25:07 +0000440 int AnalyzedFunctionCount2 = 0;
Chandler Carruth15903b72014-03-09 11:49:53 +0000441 {
Chandler Carruth8bf27802016-12-10 06:34:44 +0000442 FunctionPassManager FPM(/*DebugLogging*/ true);
Chandler Carruth15903b72014-03-09 11:49:53 +0000443 FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
444 AnalyzedFunctionCount2));
445 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
446 }
Chandler Carruthea998842013-11-09 13:09:08 +0000447
Chandler Carruth4d32e852013-11-22 23:38:07 +0000448 // A third function pass manager but with only preserving intervening passes
449 // and with a function pass that invalidates exactly one analysis.
Chandler Carruthedd2b492013-11-21 10:53:05 +0000450 MPM.addPass(TestPreservingModulePass());
Chandler Carruthedd2b492013-11-21 10:53:05 +0000451 int FunctionPassRunCount3 = 0;
452 int AnalyzedInstrCount3 = 0;
Chandler Carruthe5106652013-11-23 01:25:07 +0000453 int AnalyzedFunctionCount3 = 0;
Chandler Carruth15903b72014-03-09 11:49:53 +0000454 {
Chandler Carruth8bf27802016-12-10 06:34:44 +0000455 FunctionPassManager FPM(/*DebugLogging*/ true);
Chandler Carruth15903b72014-03-09 11:49:53 +0000456 FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
457 AnalyzedFunctionCount3));
458 FPM.addPass(TestInvalidationFunctionPass("f"));
459 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
460 }
Chandler Carruthedd2b492013-11-21 10:53:05 +0000461
Chandler Carruth8bf27802016-12-10 06:34:44 +0000462 // A fourth function pass manager but with only preserving intervening
463 // passes but triggering the module analysis.
464 MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
Chandler Carruthedd2b492013-11-21 10:53:05 +0000465 int FunctionPassRunCount4 = 0;
466 int AnalyzedInstrCount4 = 0;
Chandler Carruthe5106652013-11-23 01:25:07 +0000467 int AnalyzedFunctionCount4 = 0;
Chandler Carruth15903b72014-03-09 11:49:53 +0000468 {
469 FunctionPassManager FPM;
470 FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
471 AnalyzedFunctionCount4));
472 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
473 }
Chandler Carruthedd2b492013-11-21 10:53:05 +0000474
Chandler Carruth8bf27802016-12-10 06:34:44 +0000475 // A fifth function pass manager which invalidates one function first but
476 // uses only cached results.
Chandler Carruthb88831b2013-11-23 00:38:42 +0000477 int FunctionPassRunCount5 = 0;
478 int AnalyzedInstrCount5 = 0;
Chandler Carruthe5106652013-11-23 01:25:07 +0000479 int AnalyzedFunctionCount5 = 0;
Chandler Carruth15903b72014-03-09 11:49:53 +0000480 {
Chandler Carruth8bf27802016-12-10 06:34:44 +0000481 FunctionPassManager FPM(/*DebugLogging*/ true);
Chandler Carruth15903b72014-03-09 11:49:53 +0000482 FPM.addPass(TestInvalidationFunctionPass("f"));
483 FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
484 AnalyzedFunctionCount5,
485 /*OnlyUseCachedResults=*/true));
486 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
487 }
Chandler Carruthb88831b2013-11-23 00:38:42 +0000488
Chandler Carruth8e27cb22016-03-11 11:05:24 +0000489 MPM.run(*M, MAM);
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000490
491 // Validate module pass counters.
Chandler Carruthea998842013-11-09 13:09:08 +0000492 EXPECT_EQ(1, ModulePassRunCount);
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000493
Chandler Carruth4d32e852013-11-22 23:38:07 +0000494 // Validate all function pass counter sets are the same.
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000495 EXPECT_EQ(3, FunctionPassRunCount1);
496 EXPECT_EQ(5, AnalyzedInstrCount1);
Chandler Carruthe5106652013-11-23 01:25:07 +0000497 EXPECT_EQ(0, AnalyzedFunctionCount1);
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000498 EXPECT_EQ(3, FunctionPassRunCount2);
499 EXPECT_EQ(5, AnalyzedInstrCount2);
Chandler Carruthe5106652013-11-23 01:25:07 +0000500 EXPECT_EQ(0, AnalyzedFunctionCount2);
Chandler Carruthedd2b492013-11-21 10:53:05 +0000501 EXPECT_EQ(3, FunctionPassRunCount3);
502 EXPECT_EQ(5, AnalyzedInstrCount3);
Chandler Carruthe5106652013-11-23 01:25:07 +0000503 EXPECT_EQ(0, AnalyzedFunctionCount3);
Chandler Carruthedd2b492013-11-21 10:53:05 +0000504 EXPECT_EQ(3, FunctionPassRunCount4);
505 EXPECT_EQ(5, AnalyzedInstrCount4);
Chandler Carruth8bf27802016-12-10 06:34:44 +0000506 EXPECT_EQ(9, AnalyzedFunctionCount4);
Chandler Carruthb88831b2013-11-23 00:38:42 +0000507 EXPECT_EQ(3, FunctionPassRunCount5);
508 EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
Chandler Carruth8bf27802016-12-10 06:34:44 +0000509 EXPECT_EQ(9, AnalyzedFunctionCount5);
Chandler Carruth7fac06c2013-11-21 02:11:31 +0000510
Chandler Carruth4d32e852013-11-22 23:38:07 +0000511 // Validate the analysis counters:
512 // first run over 3 functions, then module pass invalidates
513 // second run over 3 functions, nothing invalidates
514 // third run over 0 functions, but 1 function invalidated
515 // fourth run over 1 function
Chandler Carruth8bf27802016-12-10 06:34:44 +0000516 // fifth run invalidates 1 function first, but runs over 0 functions
Chandler Carruthe5106652013-11-23 01:25:07 +0000517 EXPECT_EQ(7, FunctionAnalysisRuns);
518
519 EXPECT_EQ(1, ModuleAnalysisRuns);
Chandler Carruthea998842013-11-09 13:09:08 +0000520}
Chandler Carruth8c28aa12016-08-19 18:36:06 +0000521
522// A customized pass manager that passes extra arguments through the
523// infrastructure.
524typedef AnalysisManager<Function, int> CustomizedAnalysisManager;
525typedef PassManager<Function, CustomizedAnalysisManager, int, int &>
526 CustomizedPassManager;
527
528class CustomizedAnalysis : public AnalysisInfoMixin<CustomizedAnalysis> {
529public:
530 struct Result {
531 Result(int I) : I(I) {}
532 int I;
533 };
534
535 Result run(Function &F, CustomizedAnalysisManager &AM, int I) {
536 return Result(I);
537 }
538
539private:
540 friend AnalysisInfoMixin<CustomizedAnalysis>;
Chandler Carruth33d56812016-11-23 17:53:26 +0000541 static AnalysisKey Key;
Chandler Carruth8c28aa12016-08-19 18:36:06 +0000542};
543
Chandler Carruth33d56812016-11-23 17:53:26 +0000544AnalysisKey CustomizedAnalysis::Key;
Chandler Carruth8c28aa12016-08-19 18:36:06 +0000545
546struct CustomizedPass : PassInfoMixin<CustomizedPass> {
547 std::function<void(CustomizedAnalysis::Result &, int &)> Callback;
548
549 template <typename CallbackT>
550 CustomizedPass(CallbackT Callback) : Callback(Callback) {}
551
552 PreservedAnalyses run(Function &F, CustomizedAnalysisManager &AM, int I,
553 int &O) {
554 Callback(AM.getResult<CustomizedAnalysis>(F, I), O);
555 return PreservedAnalyses::none();
556 }
557};
558
559TEST_F(PassManagerTest, CustomizedPassManagerArgs) {
560 CustomizedAnalysisManager AM;
561 AM.registerPass([&] { return CustomizedAnalysis(); });
Fedor Sergeeve6959a62018-09-20 17:08:45 +0000562 PassInstrumentationCallbacks PIC;
563 AM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
Chandler Carruth8c28aa12016-08-19 18:36:06 +0000564
565 CustomizedPassManager PM;
566
567 // Add an instance of the customized pass that just accumulates the input
568 // after it is round-tripped through the analysis.
569 int Result = 0;
570 PM.addPass(
571 CustomizedPass([](CustomizedAnalysis::Result &R, int &O) { O += R.I; }));
572
573 // Run this over every function with the input of 42.
574 for (Function &F : *M)
575 PM.run(F, AM, 42, Result);
576
577 // And ensure that we accumulated the correct result.
578 EXPECT_EQ(42 * (int)M->size(), Result);
579}
Chandler Carruth78a68062016-11-28 22:04:31 +0000580
581/// A test analysis pass which caches in its result another analysis pass and
582/// uses it to serve queries. This requires the result to invalidate itself
583/// when its dependency is invalidated.
584struct TestIndirectFunctionAnalysis
585 : public AnalysisInfoMixin<TestIndirectFunctionAnalysis> {
586 struct Result {
Chandler Carruth0fc44672016-12-27 08:40:39 +0000587 Result(TestFunctionAnalysis::Result &FDep, TestModuleAnalysis::Result &MDep)
588 : FDep(FDep), MDep(MDep) {}
589 TestFunctionAnalysis::Result &FDep;
590 TestModuleAnalysis::Result &MDep;
Chandler Carruth78a68062016-11-28 22:04:31 +0000591
592 bool invalidate(Function &F, const PreservedAnalyses &PA,
593 FunctionAnalysisManager::Invalidator &Inv) {
Chandler Carruth0fc44672016-12-27 08:40:39 +0000594 auto PAC = PA.getChecker<TestIndirectFunctionAnalysis>();
595 return !(PAC.preserved() ||
596 PAC.preservedSet<AllAnalysesOn<Function>>()) ||
Chandler Carruth78a68062016-11-28 22:04:31 +0000597 Inv.invalidate<TestFunctionAnalysis>(F, PA);
598 }
599 };
600
601 TestIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
602
603 /// Run the analysis pass over the function and return a result.
604 Result run(Function &F, FunctionAnalysisManager &AM) {
605 ++Runs;
Chandler Carruth0fc44672016-12-27 08:40:39 +0000606 auto &FDep = AM.getResult<TestFunctionAnalysis>(F);
607 auto &Proxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
608 const ModuleAnalysisManager &MAM = Proxy.getManager();
609 // For the test, we insist that the module analysis starts off in the
610 // cache.
611 auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
612 // And register the dependency as module analysis dependencies have to be
613 // pre-registered on the proxy.
614 Proxy.registerOuterAnalysisInvalidation<TestModuleAnalysis,
615 TestIndirectFunctionAnalysis>();
616 return Result(FDep, MDep);
Chandler Carruth78a68062016-11-28 22:04:31 +0000617 }
618
619private:
620 friend AnalysisInfoMixin<TestIndirectFunctionAnalysis>;
621 static AnalysisKey Key;
622
623 int &Runs;
624};
625
626AnalysisKey TestIndirectFunctionAnalysis::Key;
627
Chandler Carruth0fc44672016-12-27 08:40:39 +0000628/// A test analysis pass which chaches in its result the result from the above
629/// indirect analysis pass.
630///
631/// This allows us to ensure that whenever an analysis pass is invalidated due
632/// to dependencies (especially dependencies across IR units that trigger
633/// asynchronous invalidation) we correctly detect that this may in turn cause
634/// other analysis to be invalidated.
635struct TestDoublyIndirectFunctionAnalysis
636 : public AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis> {
637 struct Result {
638 Result(TestIndirectFunctionAnalysis::Result &IDep) : IDep(IDep) {}
639 TestIndirectFunctionAnalysis::Result &IDep;
640
641 bool invalidate(Function &F, const PreservedAnalyses &PA,
642 FunctionAnalysisManager::Invalidator &Inv) {
643 auto PAC = PA.getChecker<TestDoublyIndirectFunctionAnalysis>();
644 return !(PAC.preserved() ||
645 PAC.preservedSet<AllAnalysesOn<Function>>()) ||
646 Inv.invalidate<TestIndirectFunctionAnalysis>(F, PA);
647 }
648 };
649
650 TestDoublyIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
651
652 /// Run the analysis pass over the function and return a result.
653 Result run(Function &F, FunctionAnalysisManager &AM) {
654 ++Runs;
655 auto &IDep = AM.getResult<TestIndirectFunctionAnalysis>(F);
656 return Result(IDep);
657 }
658
659private:
660 friend AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis>;
661 static AnalysisKey Key;
662
663 int &Runs;
664};
665
666AnalysisKey TestDoublyIndirectFunctionAnalysis::Key;
667
Chandler Carruth78a68062016-11-28 22:04:31 +0000668struct LambdaPass : public PassInfoMixin<LambdaPass> {
669 using FuncT = std::function<PreservedAnalyses(Function &, FunctionAnalysisManager &)>;
670
671 LambdaPass(FuncT Func) : Func(std::move(Func)) {}
672
673 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
674 return Func(F, AM);
675 }
676
677 FuncT Func;
678};
679
680TEST_F(PassManagerTest, IndirectAnalysisInvalidation) {
681 FunctionAnalysisManager FAM(/*DebugLogging*/ true);
Chandler Carruth0fc44672016-12-27 08:40:39 +0000682 int FunctionAnalysisRuns = 0, ModuleAnalysisRuns = 0,
683 IndirectAnalysisRuns = 0, DoublyIndirectAnalysisRuns = 0;
684 FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
Chandler Carruth78a68062016-11-28 22:04:31 +0000685 FAM.registerPass(
686 [&] { return TestIndirectFunctionAnalysis(IndirectAnalysisRuns); });
Chandler Carruth0fc44672016-12-27 08:40:39 +0000687 FAM.registerPass([&] {
688 return TestDoublyIndirectFunctionAnalysis(DoublyIndirectAnalysisRuns);
689 });
Chandler Carruth78a68062016-11-28 22:04:31 +0000690
691 ModuleAnalysisManager MAM(/*DebugLogging*/ true);
Chandler Carruth0fc44672016-12-27 08:40:39 +0000692 MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
Chandler Carruth78a68062016-11-28 22:04:31 +0000693 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
694 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
695
Fedor Sergeeve6959a62018-09-20 17:08:45 +0000696 PassInstrumentationCallbacks PIC;
697 MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
698 FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
699
Chandler Carruth0fc44672016-12-27 08:40:39 +0000700 int InstrCount = 0, FunctionCount = 0;
Chandler Carruth78a68062016-11-28 22:04:31 +0000701 ModulePassManager MPM(/*DebugLogging*/ true);
702 FunctionPassManager FPM(/*DebugLogging*/ true);
703 // First just use the analysis to get the instruction count, and preserve
704 // everything.
705 FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
Chandler Carruth0fc44672016-12-27 08:40:39 +0000706 auto &DoublyIndirectResult =
707 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
708 auto &IndirectResult = DoublyIndirectResult.IDep;
709 InstrCount += IndirectResult.FDep.InstructionCount;
710 FunctionCount += IndirectResult.MDep.FunctionCount;
Chandler Carruth78a68062016-11-28 22:04:31 +0000711 return PreservedAnalyses::all();
712 }));
713 // Next, invalidate
714 // - both analyses for "f",
715 // - just the underlying (indirect) analysis for "g", and
716 // - just the direct analysis for "h".
717 FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
Chandler Carruth0fc44672016-12-27 08:40:39 +0000718 auto &DoublyIndirectResult =
719 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
720 auto &IndirectResult = DoublyIndirectResult.IDep;
721 InstrCount += IndirectResult.FDep.InstructionCount;
722 FunctionCount += IndirectResult.MDep.FunctionCount;
Chandler Carruth78a68062016-11-28 22:04:31 +0000723 auto PA = PreservedAnalyses::none();
724 if (F.getName() == "g")
725 PA.preserve<TestFunctionAnalysis>();
726 else if (F.getName() == "h")
727 PA.preserve<TestIndirectFunctionAnalysis>();
728 return PA;
729 }));
730 // Finally, use the analysis again on each function, forcing re-computation
731 // for all of them.
732 FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
Chandler Carruth0fc44672016-12-27 08:40:39 +0000733 auto &DoublyIndirectResult =
734 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
735 auto &IndirectResult = DoublyIndirectResult.IDep;
736 InstrCount += IndirectResult.FDep.InstructionCount;
737 FunctionCount += IndirectResult.MDep.FunctionCount;
Chandler Carruth78a68062016-11-28 22:04:31 +0000738 return PreservedAnalyses::all();
739 }));
Chandler Carruth0fc44672016-12-27 08:40:39 +0000740
741 // Create a second function pass manager. This will cause the module-level
742 // invalidation to occur, which will force yet another invalidation of the
743 // indirect function-level analysis as the module analysis it depends on gets
744 // invalidated.
745 FunctionPassManager FPM2(/*DebugLogging*/ true);
746 FPM2.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
747 auto &DoublyIndirectResult =
748 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
749 auto &IndirectResult = DoublyIndirectResult.IDep;
750 InstrCount += IndirectResult.FDep.InstructionCount;
751 FunctionCount += IndirectResult.MDep.FunctionCount;
752 return PreservedAnalyses::all();
753 }));
754
755 // Add a requires pass to populate the module analysis and then our function
756 // pass pipeline.
757 MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
Chandler Carruth78a68062016-11-28 22:04:31 +0000758 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruth0fc44672016-12-27 08:40:39 +0000759 // Now require the module analysis again (it will have been invalidated once)
760 // and then use it again from a function pass manager.
761 MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
762 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM2)));
Chandler Carruth78a68062016-11-28 22:04:31 +0000763 MPM.run(*M, MAM);
764
765 // There are generally two possible runs for each of the three functions. But
766 // for one function, we only invalidate the indirect analysis so the base one
767 // only gets run five times.
Chandler Carruth0fc44672016-12-27 08:40:39 +0000768 EXPECT_EQ(5, FunctionAnalysisRuns);
769 // The module analysis pass should be run twice here.
770 EXPECT_EQ(2, ModuleAnalysisRuns);
Chandler Carruth78a68062016-11-28 22:04:31 +0000771 // The indirect analysis is invalidated for each function (either directly or
772 // indirectly) and run twice for each.
Chandler Carruth0fc44672016-12-27 08:40:39 +0000773 EXPECT_EQ(9, IndirectAnalysisRuns);
774 EXPECT_EQ(9, DoublyIndirectAnalysisRuns);
Chandler Carruth78a68062016-11-28 22:04:31 +0000775
Chandler Carruth0fc44672016-12-27 08:40:39 +0000776 // There are five instructions in the module and we add the count four
Chandler Carruth78a68062016-11-28 22:04:31 +0000777 // times.
Chandler Carruth0fc44672016-12-27 08:40:39 +0000778 EXPECT_EQ(5 * 4, InstrCount);
779
780 // There are three functions and we count them four times for each of the
781 // three functions.
782 EXPECT_EQ(3 * 4 * 3, FunctionCount);
Chandler Carruth78a68062016-11-28 22:04:31 +0000783}
Chandler Carruthea998842013-11-09 13:09:08 +0000784}