blob: 7709453cb74421b83809ee2d7a0a2ab4aabc4a43 [file] [log] [blame]
Chandler Carruth90a835d2013-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 Carruth9a67b072017-06-06 11:06:56 +000010#include "llvm/IR/PassManager.h"
Chandler Carruth9aca9182014-01-07 12:34:26 +000011#include "llvm/AsmParser/Parser.h"
Chandler Carruth90a835d2013-11-09 13:09:08 +000012#include "llvm/IR/Function.h"
13#include "llvm/IR/LLVMContext.h"
14#include "llvm/IR/Module.h"
Chandler Carruth90a835d2013-11-09 13:09:08 +000015#include "llvm/Support/SourceMgr.h"
16#include "gtest/gtest.h"
17
18using namespace llvm;
19
20namespace {
21
Chandler Carruth30a07302016-03-11 10:33:22 +000022class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {
Chandler Carruth74015a72013-11-13 01:12:08 +000023public:
Chandler Carruth74015a72013-11-13 01:12:08 +000024 struct Result {
25 Result(int Count) : InstructionCount(Count) {}
Chandler Carruth74015a72013-11-13 01:12:08 +000026 int InstructionCount;
27 };
28
Chandler Carruth2ad18582013-11-23 01:25:02 +000029 TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
Chandler Carruth851a2aa2013-11-21 02:11:31 +000030
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000031 /// Run the analysis pass over the function and return a result.
Chandler Carruthb47f8012016-03-11 11:05:24 +000032 Result run(Function &F, FunctionAnalysisManager &AM) {
Chandler Carruth851a2aa2013-11-21 02:11:31 +000033 ++Runs;
Chandler Carruth74015a72013-11-13 01:12:08 +000034 int Count = 0;
Chandler Carruthd174ce42015-01-05 02:47:05 +000035 for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI)
Chandler Carruth74015a72013-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 Carruth30a07302016-03-11 10:33:22 +000043 friend AnalysisInfoMixin<TestFunctionAnalysis>;
Chandler Carruthdab4eae2016-11-23 17:53:26 +000044 static AnalysisKey Key;
Chandler Carruthb4faf132016-03-11 10:22:49 +000045
Chandler Carruth851a2aa2013-11-21 02:11:31 +000046 int &Runs;
Chandler Carruth74015a72013-11-13 01:12:08 +000047};
48
Chandler Carruthdab4eae2016-11-23 17:53:26 +000049AnalysisKey TestFunctionAnalysis::Key;
Chandler Carruthb4faf132016-03-11 10:22:49 +000050
Chandler Carruth30a07302016-03-11 10:33:22 +000051class TestModuleAnalysis : public AnalysisInfoMixin<TestModuleAnalysis> {
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000052public:
53 struct Result {
54 Result(int Count) : FunctionCount(Count) {}
55 int FunctionCount;
56 };
57
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000058 TestModuleAnalysis(int &Runs) : Runs(Runs) {}
59
Chandler Carruthb47f8012016-03-11 11:05:24 +000060 Result run(Module &M, ModuleAnalysisManager &AM) {
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000061 ++Runs;
62 int Count = 0;
Chandler Carruthd174ce42015-01-05 02:47:05 +000063 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000064 ++Count;
65 return Result(Count);
66 }
67
68private:
Chandler Carruth30a07302016-03-11 10:33:22 +000069 friend AnalysisInfoMixin<TestModuleAnalysis>;
Chandler Carruthdab4eae2016-11-23 17:53:26 +000070 static AnalysisKey Key;
Chandler Carruthb4faf132016-03-11 10:22:49 +000071
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000072 int &Runs;
73};
74
Chandler Carruthdab4eae2016-11-23 17:53:26 +000075AnalysisKey TestModuleAnalysis::Key;
Chandler Carruthb4faf132016-03-11 10:22:49 +000076
Chandler Carruth30a07302016-03-11 10:33:22 +000077struct TestModulePass : PassInfoMixin<TestModulePass> {
Chandler Carruth90a835d2013-11-09 13:09:08 +000078 TestModulePass(int &RunCount) : RunCount(RunCount) {}
79
Chandler Carruth164a2aa62016-06-17 00:11:01 +000080 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
Chandler Carruth90a835d2013-11-09 13:09:08 +000081 ++RunCount;
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000082 return PreservedAnalyses::none();
Chandler Carruth90a835d2013-11-09 13:09:08 +000083 }
84
85 int &RunCount;
86};
87
Chandler Carruth30a07302016-03-11 10:33:22 +000088struct TestPreservingModulePass : PassInfoMixin<TestPreservingModulePass> {
Chandler Carruth164a2aa62016-06-17 00:11:01 +000089 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
90 return PreservedAnalyses::all();
91 }
Chandler Carruth2846e9e2013-11-21 10:53:05 +000092};
93
Chandler Carruth30a07302016-03-11 10:33:22 +000094struct TestFunctionPass : PassInfoMixin<TestFunctionPass> {
Chandler Carruthde9afd82013-11-23 00:38:42 +000095 TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000096 int &AnalyzedFunctionCount,
Chandler Carruthde9afd82013-11-23 00:38:42 +000097 bool OnlyUseCachedResults = false)
98 : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000099 AnalyzedFunctionCount(AnalyzedFunctionCount),
Chandler Carruthde9afd82013-11-23 00:38:42 +0000100 OnlyUseCachedResults(OnlyUseCachedResults) {}
Chandler Carruth90a835d2013-11-09 13:09:08 +0000101
Chandler Carruthb47f8012016-03-11 11:05:24 +0000102 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
Chandler Carruth90a835d2013-11-09 13:09:08 +0000103 ++RunCount;
Chandler Carruth74015a72013-11-13 01:12:08 +0000104
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000105 const ModuleAnalysisManager &MAM =
Chandler Carruthb47f8012016-03-11 11:05:24 +0000106 AM.getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
Chandler Carrutheedf9fc2014-02-05 21:41:42 +0000107 if (TestModuleAnalysis::Result *TMA =
Chandler Carruthd174ce42015-01-05 02:47:05 +0000108 MAM.getCachedResult<TestModuleAnalysis>(*F.getParent()))
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000109 AnalyzedFunctionCount += TMA->FunctionCount;
110
Chandler Carruthde9afd82013-11-23 00:38:42 +0000111 if (OnlyUseCachedResults) {
112 // Hack to force the use of the cached interface.
Chandler Carrutheedf9fc2014-02-05 21:41:42 +0000113 if (TestFunctionAnalysis::Result *AR =
Chandler Carruthb47f8012016-03-11 11:05:24 +0000114 AM.getCachedResult<TestFunctionAnalysis>(F))
Chandler Carruthde9afd82013-11-23 00:38:42 +0000115 AnalyzedInstrCount += AR->InstructionCount;
116 } else {
117 // Typical path just runs the analysis as needed.
Chandler Carruthb47f8012016-03-11 11:05:24 +0000118 TestFunctionAnalysis::Result &AR = AM.getResult<TestFunctionAnalysis>(F);
Chandler Carruthde9afd82013-11-23 00:38:42 +0000119 AnalyzedInstrCount += AR.InstructionCount;
120 }
Chandler Carruth74015a72013-11-13 01:12:08 +0000121
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000122 return PreservedAnalyses::all();
Chandler Carruth90a835d2013-11-09 13:09:08 +0000123 }
124
125 int &RunCount;
Chandler Carruth74015a72013-11-13 01:12:08 +0000126 int &AnalyzedInstrCount;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000127 int &AnalyzedFunctionCount;
Chandler Carruthde9afd82013-11-23 00:38:42 +0000128 bool OnlyUseCachedResults;
Chandler Carruth90a835d2013-11-09 13:09:08 +0000129};
130
Chandler Carruthbceeb222013-11-22 23:38:07 +0000131// A test function pass that invalidates all function analyses for a function
132// with a specific name.
Chandler Carruth30a07302016-03-11 10:33:22 +0000133struct TestInvalidationFunctionPass
134 : PassInfoMixin<TestInvalidationFunctionPass> {
Chandler Carruthbceeb222013-11-22 23:38:07 +0000135 TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
136
Chandler Carruth164a2aa62016-06-17 00:11:01 +0000137 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
Chandler Carruthd174ce42015-01-05 02:47:05 +0000138 return F.getName() == Name ? PreservedAnalyses::none()
139 : PreservedAnalyses::all();
Chandler Carruthbceeb222013-11-22 23:38:07 +0000140 }
141
142 StringRef Name;
143};
144
Mehdi Amini03b42e42016-04-14 21:59:01 +0000145std::unique_ptr<Module> parseIR(LLVMContext &Context, const char *IR) {
Chandler Carruth90a835d2013-11-09 13:09:08 +0000146 SMDiagnostic Err;
Mehdi Amini03b42e42016-04-14 21:59:01 +0000147 return parseAssemblyString(IR, Err, Context);
Chandler Carruth90a835d2013-11-09 13:09:08 +0000148}
149
150class PassManagerTest : public ::testing::Test {
151protected:
Mehdi Amini03b42e42016-04-14 21:59:01 +0000152 LLVMContext Context;
Ahmed Charles56440fd2014-03-06 05:51:42 +0000153 std::unique_ptr<Module> M;
Chandler Carruth90a835d2013-11-09 13:09:08 +0000154
155public:
156 PassManagerTest()
Mehdi Amini03b42e42016-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 Carruth90a835d2013-11-09 13:09:08 +0000169};
170
Chandler Carruthba90ae92016-12-27 08:40:39 +0000171TEST(PreservedAnalysesTest, Basic) {
Chandler Carruth999b92d2014-03-13 10:42:18 +0000172 PreservedAnalyses PA1 = PreservedAnalyses();
Chandler Carruthba90ae92016-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 Carruth999b92d2014-03-13 10:42:18 +0000195 PreservedAnalyses PA4 = PA1;
Chandler Carruthba90ae92016-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 Carruth999b92d2014-03-13 10:42:18 +0000201 PA4 = PA3;
Chandler Carruthba90ae92016-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 Carruth999b92d2014-03-13 10:42:18 +0000207 PA4 = std::move(PA2);
Chandler Carruthba90ae92016-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 Carruth9c350652017-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 Carruthba90ae92016-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 Carruth999b92d2014-03-13 10:42:18 +0000268 PA1.preserve<TestFunctionAnalysis>();
Chandler Carruthba90ae92016-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 Carruth999b92d2014-03-13 10:42:18 +0000396}
397
Chandler Carruth90a835d2013-11-09 13:09:08 +0000398TEST_F(PassManagerTest, Basic) {
Chandler Carruth6b981642016-12-10 06:34:44 +0000399 FunctionAnalysisManager FAM(/*DebugLogging*/ true);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000400 int FunctionAnalysisRuns = 0;
Chandler Carruthedf59962016-02-18 09:45:17 +0000401 FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
Chandler Carruth74015a72013-11-13 01:12:08 +0000402
Chandler Carruth6b981642016-12-10 06:34:44 +0000403 ModuleAnalysisManager MAM(/*DebugLogging*/ true);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000404 int ModuleAnalysisRuns = 0;
Chandler Carruthedf59962016-02-18 09:45:17 +0000405 MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
406 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
407 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000408
Chandler Carruthb3e72192013-11-22 00:43:29 +0000409 ModulePassManager MPM;
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000410
411 // Count the runs over a Function.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000412 int FunctionPassRunCount1 = 0;
413 int AnalyzedInstrCount1 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000414 int AnalyzedFunctionCount1 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000415 {
Chandler Carruth999b92d2014-03-13 10:42:18 +0000416 // Pointless scoped copy to test move assignment.
Chandler Carruth6b981642016-12-10 06:34:44 +0000417 ModulePassManager NestedMPM(/*DebugLogging*/ true);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000418 FunctionPassManager FPM;
Chandler Carruth999b92d2014-03-13 10:42:18 +0000419 {
420 // Pointless scope to test move assignment.
Chandler Carruth6b981642016-12-10 06:34:44 +0000421 FunctionPassManager NestedFPM(/*DebugLogging*/ true);
Chandler Carruth74a8a222016-06-17 07:15:29 +0000422 NestedFPM.addPass(TestFunctionPass(
423 FunctionPassRunCount1, AnalyzedInstrCount1, AnalyzedFunctionCount1));
Chandler Carruth999b92d2014-03-13 10:42:18 +0000424 FPM = std::move(NestedFPM);
425 }
426 NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
427 MPM = std::move(NestedMPM);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000428 }
Chandler Carruth90a835d2013-11-09 13:09:08 +0000429
430 // Count the runs over a module.
431 int ModulePassRunCount = 0;
432 MPM.addPass(TestModulePass(ModulePassRunCount));
433
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000434 // Count the runs over a Function in a separate manager.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000435 int FunctionPassRunCount2 = 0;
436 int AnalyzedInstrCount2 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000437 int AnalyzedFunctionCount2 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000438 {
Chandler Carruth6b981642016-12-10 06:34:44 +0000439 FunctionPassManager FPM(/*DebugLogging*/ true);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000440 FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
441 AnalyzedFunctionCount2));
442 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
443 }
Chandler Carruth90a835d2013-11-09 13:09:08 +0000444
Chandler Carruthbceeb222013-11-22 23:38:07 +0000445 // A third function pass manager but with only preserving intervening passes
446 // and with a function pass that invalidates exactly one analysis.
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000447 MPM.addPass(TestPreservingModulePass());
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000448 int FunctionPassRunCount3 = 0;
449 int AnalyzedInstrCount3 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000450 int AnalyzedFunctionCount3 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000451 {
Chandler Carruth6b981642016-12-10 06:34:44 +0000452 FunctionPassManager FPM(/*DebugLogging*/ true);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000453 FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
454 AnalyzedFunctionCount3));
455 FPM.addPass(TestInvalidationFunctionPass("f"));
456 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
457 }
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000458
Chandler Carruth6b981642016-12-10 06:34:44 +0000459 // A fourth function pass manager but with only preserving intervening
460 // passes but triggering the module analysis.
461 MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000462 int FunctionPassRunCount4 = 0;
463 int AnalyzedInstrCount4 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000464 int AnalyzedFunctionCount4 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000465 {
466 FunctionPassManager FPM;
467 FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
468 AnalyzedFunctionCount4));
469 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
470 }
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000471
Chandler Carruth6b981642016-12-10 06:34:44 +0000472 // A fifth function pass manager which invalidates one function first but
473 // uses only cached results.
Chandler Carruthde9afd82013-11-23 00:38:42 +0000474 int FunctionPassRunCount5 = 0;
475 int AnalyzedInstrCount5 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000476 int AnalyzedFunctionCount5 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000477 {
Chandler Carruth6b981642016-12-10 06:34:44 +0000478 FunctionPassManager FPM(/*DebugLogging*/ true);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000479 FPM.addPass(TestInvalidationFunctionPass("f"));
480 FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
481 AnalyzedFunctionCount5,
482 /*OnlyUseCachedResults=*/true));
483 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
484 }
Chandler Carruthde9afd82013-11-23 00:38:42 +0000485
Chandler Carruthb47f8012016-03-11 11:05:24 +0000486 MPM.run(*M, MAM);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000487
488 // Validate module pass counters.
Chandler Carruth90a835d2013-11-09 13:09:08 +0000489 EXPECT_EQ(1, ModulePassRunCount);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000490
Chandler Carruthbceeb222013-11-22 23:38:07 +0000491 // Validate all function pass counter sets are the same.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000492 EXPECT_EQ(3, FunctionPassRunCount1);
493 EXPECT_EQ(5, AnalyzedInstrCount1);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000494 EXPECT_EQ(0, AnalyzedFunctionCount1);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000495 EXPECT_EQ(3, FunctionPassRunCount2);
496 EXPECT_EQ(5, AnalyzedInstrCount2);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000497 EXPECT_EQ(0, AnalyzedFunctionCount2);
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000498 EXPECT_EQ(3, FunctionPassRunCount3);
499 EXPECT_EQ(5, AnalyzedInstrCount3);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000500 EXPECT_EQ(0, AnalyzedFunctionCount3);
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000501 EXPECT_EQ(3, FunctionPassRunCount4);
502 EXPECT_EQ(5, AnalyzedInstrCount4);
Chandler Carruth6b981642016-12-10 06:34:44 +0000503 EXPECT_EQ(9, AnalyzedFunctionCount4);
Chandler Carruthde9afd82013-11-23 00:38:42 +0000504 EXPECT_EQ(3, FunctionPassRunCount5);
505 EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
Chandler Carruth6b981642016-12-10 06:34:44 +0000506 EXPECT_EQ(9, AnalyzedFunctionCount5);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000507
Chandler Carruthbceeb222013-11-22 23:38:07 +0000508 // Validate the analysis counters:
509 // first run over 3 functions, then module pass invalidates
510 // second run over 3 functions, nothing invalidates
511 // third run over 0 functions, but 1 function invalidated
512 // fourth run over 1 function
Chandler Carruth6b981642016-12-10 06:34:44 +0000513 // fifth run invalidates 1 function first, but runs over 0 functions
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000514 EXPECT_EQ(7, FunctionAnalysisRuns);
515
516 EXPECT_EQ(1, ModuleAnalysisRuns);
Chandler Carruth90a835d2013-11-09 13:09:08 +0000517}
Chandler Carruth9b35e6d2016-08-19 18:36:06 +0000518
519// A customized pass manager that passes extra arguments through the
520// infrastructure.
521typedef AnalysisManager<Function, int> CustomizedAnalysisManager;
522typedef PassManager<Function, CustomizedAnalysisManager, int, int &>
523 CustomizedPassManager;
524
525class CustomizedAnalysis : public AnalysisInfoMixin<CustomizedAnalysis> {
526public:
527 struct Result {
528 Result(int I) : I(I) {}
529 int I;
530 };
531
532 Result run(Function &F, CustomizedAnalysisManager &AM, int I) {
533 return Result(I);
534 }
535
536private:
537 friend AnalysisInfoMixin<CustomizedAnalysis>;
Chandler Carruthdab4eae2016-11-23 17:53:26 +0000538 static AnalysisKey Key;
Chandler Carruth9b35e6d2016-08-19 18:36:06 +0000539};
540
Chandler Carruthdab4eae2016-11-23 17:53:26 +0000541AnalysisKey CustomizedAnalysis::Key;
Chandler Carruth9b35e6d2016-08-19 18:36:06 +0000542
543struct CustomizedPass : PassInfoMixin<CustomizedPass> {
544 std::function<void(CustomizedAnalysis::Result &, int &)> Callback;
545
546 template <typename CallbackT>
547 CustomizedPass(CallbackT Callback) : Callback(Callback) {}
548
549 PreservedAnalyses run(Function &F, CustomizedAnalysisManager &AM, int I,
550 int &O) {
551 Callback(AM.getResult<CustomizedAnalysis>(F, I), O);
552 return PreservedAnalyses::none();
553 }
554};
555
556TEST_F(PassManagerTest, CustomizedPassManagerArgs) {
557 CustomizedAnalysisManager AM;
558 AM.registerPass([&] { return CustomizedAnalysis(); });
559
560 CustomizedPassManager PM;
561
562 // Add an instance of the customized pass that just accumulates the input
563 // after it is round-tripped through the analysis.
564 int Result = 0;
565 PM.addPass(
566 CustomizedPass([](CustomizedAnalysis::Result &R, int &O) { O += R.I; }));
567
568 // Run this over every function with the input of 42.
569 for (Function &F : *M)
570 PM.run(F, AM, 42, Result);
571
572 // And ensure that we accumulated the correct result.
573 EXPECT_EQ(42 * (int)M->size(), Result);
574}
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000575
576/// A test analysis pass which caches in its result another analysis pass and
577/// uses it to serve queries. This requires the result to invalidate itself
578/// when its dependency is invalidated.
579struct TestIndirectFunctionAnalysis
580 : public AnalysisInfoMixin<TestIndirectFunctionAnalysis> {
581 struct Result {
Chandler Carruthba90ae92016-12-27 08:40:39 +0000582 Result(TestFunctionAnalysis::Result &FDep, TestModuleAnalysis::Result &MDep)
583 : FDep(FDep), MDep(MDep) {}
584 TestFunctionAnalysis::Result &FDep;
585 TestModuleAnalysis::Result &MDep;
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000586
587 bool invalidate(Function &F, const PreservedAnalyses &PA,
588 FunctionAnalysisManager::Invalidator &Inv) {
Chandler Carruthba90ae92016-12-27 08:40:39 +0000589 auto PAC = PA.getChecker<TestIndirectFunctionAnalysis>();
590 return !(PAC.preserved() ||
591 PAC.preservedSet<AllAnalysesOn<Function>>()) ||
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000592 Inv.invalidate<TestFunctionAnalysis>(F, PA);
593 }
594 };
595
596 TestIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
597
598 /// Run the analysis pass over the function and return a result.
599 Result run(Function &F, FunctionAnalysisManager &AM) {
600 ++Runs;
Chandler Carruthba90ae92016-12-27 08:40:39 +0000601 auto &FDep = AM.getResult<TestFunctionAnalysis>(F);
602 auto &Proxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
603 const ModuleAnalysisManager &MAM = Proxy.getManager();
604 // For the test, we insist that the module analysis starts off in the
605 // cache.
606 auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
607 // And register the dependency as module analysis dependencies have to be
608 // pre-registered on the proxy.
609 Proxy.registerOuterAnalysisInvalidation<TestModuleAnalysis,
610 TestIndirectFunctionAnalysis>();
611 return Result(FDep, MDep);
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000612 }
613
614private:
615 friend AnalysisInfoMixin<TestIndirectFunctionAnalysis>;
616 static AnalysisKey Key;
617
618 int &Runs;
619};
620
621AnalysisKey TestIndirectFunctionAnalysis::Key;
622
Chandler Carruthba90ae92016-12-27 08:40:39 +0000623/// A test analysis pass which chaches in its result the result from the above
624/// indirect analysis pass.
625///
626/// This allows us to ensure that whenever an analysis pass is invalidated due
627/// to dependencies (especially dependencies across IR units that trigger
628/// asynchronous invalidation) we correctly detect that this may in turn cause
629/// other analysis to be invalidated.
630struct TestDoublyIndirectFunctionAnalysis
631 : public AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis> {
632 struct Result {
633 Result(TestIndirectFunctionAnalysis::Result &IDep) : IDep(IDep) {}
634 TestIndirectFunctionAnalysis::Result &IDep;
635
636 bool invalidate(Function &F, const PreservedAnalyses &PA,
637 FunctionAnalysisManager::Invalidator &Inv) {
638 auto PAC = PA.getChecker<TestDoublyIndirectFunctionAnalysis>();
639 return !(PAC.preserved() ||
640 PAC.preservedSet<AllAnalysesOn<Function>>()) ||
641 Inv.invalidate<TestIndirectFunctionAnalysis>(F, PA);
642 }
643 };
644
645 TestDoublyIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
646
647 /// Run the analysis pass over the function and return a result.
648 Result run(Function &F, FunctionAnalysisManager &AM) {
649 ++Runs;
650 auto &IDep = AM.getResult<TestIndirectFunctionAnalysis>(F);
651 return Result(IDep);
652 }
653
654private:
655 friend AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis>;
656 static AnalysisKey Key;
657
658 int &Runs;
659};
660
661AnalysisKey TestDoublyIndirectFunctionAnalysis::Key;
662
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000663struct LambdaPass : public PassInfoMixin<LambdaPass> {
664 using FuncT = std::function<PreservedAnalyses(Function &, FunctionAnalysisManager &)>;
665
666 LambdaPass(FuncT Func) : Func(std::move(Func)) {}
667
668 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
669 return Func(F, AM);
670 }
671
672 FuncT Func;
673};
674
675TEST_F(PassManagerTest, IndirectAnalysisInvalidation) {
676 FunctionAnalysisManager FAM(/*DebugLogging*/ true);
Chandler Carruthba90ae92016-12-27 08:40:39 +0000677 int FunctionAnalysisRuns = 0, ModuleAnalysisRuns = 0,
678 IndirectAnalysisRuns = 0, DoublyIndirectAnalysisRuns = 0;
679 FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000680 FAM.registerPass(
681 [&] { return TestIndirectFunctionAnalysis(IndirectAnalysisRuns); });
Chandler Carruthba90ae92016-12-27 08:40:39 +0000682 FAM.registerPass([&] {
683 return TestDoublyIndirectFunctionAnalysis(DoublyIndirectAnalysisRuns);
684 });
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000685
686 ModuleAnalysisManager MAM(/*DebugLogging*/ true);
Chandler Carruthba90ae92016-12-27 08:40:39 +0000687 MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000688 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
689 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
690
Chandler Carruthba90ae92016-12-27 08:40:39 +0000691 int InstrCount = 0, FunctionCount = 0;
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000692 ModulePassManager MPM(/*DebugLogging*/ true);
693 FunctionPassManager FPM(/*DebugLogging*/ true);
694 // First just use the analysis to get the instruction count, and preserve
695 // everything.
696 FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
Chandler Carruthba90ae92016-12-27 08:40:39 +0000697 auto &DoublyIndirectResult =
698 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
699 auto &IndirectResult = DoublyIndirectResult.IDep;
700 InstrCount += IndirectResult.FDep.InstructionCount;
701 FunctionCount += IndirectResult.MDep.FunctionCount;
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000702 return PreservedAnalyses::all();
703 }));
704 // Next, invalidate
705 // - both analyses for "f",
706 // - just the underlying (indirect) analysis for "g", and
707 // - just the direct analysis for "h".
708 FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
Chandler Carruthba90ae92016-12-27 08:40:39 +0000709 auto &DoublyIndirectResult =
710 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
711 auto &IndirectResult = DoublyIndirectResult.IDep;
712 InstrCount += IndirectResult.FDep.InstructionCount;
713 FunctionCount += IndirectResult.MDep.FunctionCount;
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000714 auto PA = PreservedAnalyses::none();
715 if (F.getName() == "g")
716 PA.preserve<TestFunctionAnalysis>();
717 else if (F.getName() == "h")
718 PA.preserve<TestIndirectFunctionAnalysis>();
719 return PA;
720 }));
721 // Finally, use the analysis again on each function, forcing re-computation
722 // for all of them.
723 FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
Chandler Carruthba90ae92016-12-27 08:40:39 +0000724 auto &DoublyIndirectResult =
725 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
726 auto &IndirectResult = DoublyIndirectResult.IDep;
727 InstrCount += IndirectResult.FDep.InstructionCount;
728 FunctionCount += IndirectResult.MDep.FunctionCount;
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000729 return PreservedAnalyses::all();
730 }));
Chandler Carruthba90ae92016-12-27 08:40:39 +0000731
732 // Create a second function pass manager. This will cause the module-level
733 // invalidation to occur, which will force yet another invalidation of the
734 // indirect function-level analysis as the module analysis it depends on gets
735 // invalidated.
736 FunctionPassManager FPM2(/*DebugLogging*/ true);
737 FPM2.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
738 auto &DoublyIndirectResult =
739 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
740 auto &IndirectResult = DoublyIndirectResult.IDep;
741 InstrCount += IndirectResult.FDep.InstructionCount;
742 FunctionCount += IndirectResult.MDep.FunctionCount;
743 return PreservedAnalyses::all();
744 }));
745
746 // Add a requires pass to populate the module analysis and then our function
747 // pass pipeline.
748 MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000749 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthba90ae92016-12-27 08:40:39 +0000750 // Now require the module analysis again (it will have been invalidated once)
751 // and then use it again from a function pass manager.
752 MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
753 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM2)));
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000754 MPM.run(*M, MAM);
755
756 // There are generally two possible runs for each of the three functions. But
757 // for one function, we only invalidate the indirect analysis so the base one
758 // only gets run five times.
Chandler Carruthba90ae92016-12-27 08:40:39 +0000759 EXPECT_EQ(5, FunctionAnalysisRuns);
760 // The module analysis pass should be run twice here.
761 EXPECT_EQ(2, ModuleAnalysisRuns);
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000762 // The indirect analysis is invalidated for each function (either directly or
763 // indirectly) and run twice for each.
Chandler Carruthba90ae92016-12-27 08:40:39 +0000764 EXPECT_EQ(9, IndirectAnalysisRuns);
765 EXPECT_EQ(9, DoublyIndirectAnalysisRuns);
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000766
Chandler Carruthba90ae92016-12-27 08:40:39 +0000767 // There are five instructions in the module and we add the count four
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000768 // times.
Chandler Carruthba90ae92016-12-27 08:40:39 +0000769 EXPECT_EQ(5 * 4, InstrCount);
770
771 // There are three functions and we count them four times for each of the
772 // three functions.
773 EXPECT_EQ(3 * 4 * 3, FunctionCount);
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000774}
Chandler Carruth90a835d2013-11-09 13:09:08 +0000775}