blob: b3a039a364fcf053afb2566f650115d8f472b0a8 [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 Carruth9aca9182014-01-07 12:34:26 +000010#include "llvm/AsmParser/Parser.h"
Chandler Carruth90a835d2013-11-09 13:09:08 +000011#include "llvm/IR/Function.h"
12#include "llvm/IR/LLVMContext.h"
13#include "llvm/IR/Module.h"
14#include "llvm/IR/PassManager.h"
15#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
Chandler Carruth74015a72013-11-13 01:12:08 +000031 /// \brief 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 }
213}
214
215TEST(PreservedAnalysesTest, Preserve) {
216 auto PA = PreservedAnalyses::none();
217 PA.preserve<TestFunctionAnalysis>();
218 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
219 EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>().preserved());
220 PA.preserve<TestModuleAnalysis>();
221 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
222 EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>().preserved());
223
224 // Redundant calls are fine.
225 PA.preserve<TestFunctionAnalysis>();
226 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
227 EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>().preserved());
228}
229
230TEST(PreservedAnalysesTest, PreserveSets) {
231 auto PA = PreservedAnalyses::none();
232 PA.preserveSet<AllAnalysesOn<Function>>();
233 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
234 .preservedSet<AllAnalysesOn<Function>>());
235 EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>()
236 .preservedSet<AllAnalysesOn<Module>>());
237 PA.preserveSet<AllAnalysesOn<Module>>();
238 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
239 .preservedSet<AllAnalysesOn<Function>>());
240 EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
241 .preservedSet<AllAnalysesOn<Module>>());
242
243 // Mixing is fine.
244 PA.preserve<TestFunctionAnalysis>();
245 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
246 .preservedSet<AllAnalysesOn<Function>>());
247 EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
248 .preservedSet<AllAnalysesOn<Module>>());
249
250 // Redundant calls are fine.
251 PA.preserveSet<AllAnalysesOn<Module>>();
252 EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
253 .preservedSet<AllAnalysesOn<Function>>());
254 EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
255 .preservedSet<AllAnalysesOn<Module>>());
256}
257
258TEST(PreservedAnalysisTest, Intersect) {
259 // Setup the initial sets.
260 auto PA1 = PreservedAnalyses::none();
Chandler Carruth999b92d2014-03-13 10:42:18 +0000261 PA1.preserve<TestFunctionAnalysis>();
Chandler Carruthba90ae92016-12-27 08:40:39 +0000262 PA1.preserveSet<AllAnalysesOn<Module>>();
263 auto PA2 = PreservedAnalyses::none();
264 PA2.preserve<TestFunctionAnalysis>();
265 PA2.preserveSet<AllAnalysesOn<Function>>();
266 PA2.preserve<TestModuleAnalysis>();
267 PA2.preserveSet<AllAnalysesOn<Module>>();
268 auto PA3 = PreservedAnalyses::none();
269 PA3.preserve<TestModuleAnalysis>();
270 PA3.preserveSet<AllAnalysesOn<Function>>();
271
272 // Self intersection is a no-op.
273 auto Intersected = PA1;
274 Intersected.intersect(PA1);
275 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
276 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
277 .preservedSet<AllAnalysesOn<Function>>());
278 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
279 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
280 .preservedSet<AllAnalysesOn<Module>>());
281
282 // Intersecting with all is a no-op.
283 Intersected.intersect(PreservedAnalyses::all());
284 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
285 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
286 .preservedSet<AllAnalysesOn<Function>>());
287 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
288 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
289 .preservedSet<AllAnalysesOn<Module>>());
290
291 // Intersecting a narrow set with a more broad set is the narrow set.
292 Intersected.intersect(PA2);
293 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
294 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
295 .preservedSet<AllAnalysesOn<Function>>());
296 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
297 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
298 .preservedSet<AllAnalysesOn<Module>>());
299
300 // Intersecting a broad set with a more narrow set is the narrow set.
301 Intersected = PA2;
302 Intersected.intersect(PA1);
303 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
304 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
305 .preservedSet<AllAnalysesOn<Function>>());
306 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
307 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
308 .preservedSet<AllAnalysesOn<Module>>());
309
310 // Intersecting with empty clears.
311 Intersected.intersect(PreservedAnalyses::none());
312 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
313 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
314 .preservedSet<AllAnalysesOn<Function>>());
315 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
316 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>()
317 .preservedSet<AllAnalysesOn<Module>>());
318
319 // Intersecting non-overlapping clears.
320 Intersected = PA1;
321 Intersected.intersect(PA3);
322 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
323 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
324 .preservedSet<AllAnalysesOn<Function>>());
325 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
326 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>()
327 .preservedSet<AllAnalysesOn<Module>>());
328
329 // Intersecting with moves works in when there is storage on both sides.
330 Intersected = PA1;
331 auto Tmp = PA2;
332 Intersected.intersect(std::move(Tmp));
333 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
334 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
335 .preservedSet<AllAnalysesOn<Function>>());
336 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
337 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
338 .preservedSet<AllAnalysesOn<Module>>());
339
340 // Intersecting with move works for incoming all and existing all.
341 auto Tmp2 = PreservedAnalyses::all();
342 Intersected.intersect(std::move(Tmp2));
343 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
344 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
345 .preservedSet<AllAnalysesOn<Function>>());
346 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
347 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
348 .preservedSet<AllAnalysesOn<Module>>());
349 Intersected = PreservedAnalyses::all();
350 auto Tmp3 = PA1;
351 Intersected.intersect(std::move(Tmp3));
352 EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
353 EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
354 .preservedSet<AllAnalysesOn<Function>>());
355 EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
356 EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
357 .preservedSet<AllAnalysesOn<Module>>());
358}
359
360TEST(PreservedAnalysisTest, Abandon) {
361 auto PA = PreservedAnalyses::none();
362
363 // We can abandon things after they are preserved.
364 PA.preserve<TestFunctionAnalysis>();
365 PA.abandon<TestFunctionAnalysis>();
366 EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>().preserved());
367
368 // Repeated is fine, and abandoning if they were never preserved is fine.
369 PA.abandon<TestFunctionAnalysis>();
370 EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>().preserved());
371 PA.abandon<TestModuleAnalysis>();
372 EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>().preserved());
373
374 // Even if the sets are preserved, the abandoned analyses' checker won't
375 // return true for those sets.
376 PA.preserveSet<AllAnalysesOn<Function>>();
377 PA.preserveSet<AllAnalysesOn<Module>>();
378 EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>()
379 .preservedSet<AllAnalysesOn<Function>>());
380 EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>()
381 .preservedSet<AllAnalysesOn<Module>>());
382
383 // But an arbitrary (opaque) analysis will still observe the sets as
384 // preserved. This also checks that we can use an explicit ID rather than
385 // a type.
386 AnalysisKey FakeKey, *FakeID = &FakeKey;
387 EXPECT_TRUE(PA.getChecker(FakeID).preservedSet<AllAnalysesOn<Function>>());
388 EXPECT_TRUE(PA.getChecker(FakeID).preservedSet<AllAnalysesOn<Module>>());
Chandler Carruth999b92d2014-03-13 10:42:18 +0000389}
390
Chandler Carruth90a835d2013-11-09 13:09:08 +0000391TEST_F(PassManagerTest, Basic) {
Chandler Carruth6b981642016-12-10 06:34:44 +0000392 FunctionAnalysisManager FAM(/*DebugLogging*/ true);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000393 int FunctionAnalysisRuns = 0;
Chandler Carruthedf59962016-02-18 09:45:17 +0000394 FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
Chandler Carruth74015a72013-11-13 01:12:08 +0000395
Chandler Carruth6b981642016-12-10 06:34:44 +0000396 ModuleAnalysisManager MAM(/*DebugLogging*/ true);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000397 int ModuleAnalysisRuns = 0;
Chandler Carruthedf59962016-02-18 09:45:17 +0000398 MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
399 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
400 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000401
Chandler Carruthb3e72192013-11-22 00:43:29 +0000402 ModulePassManager MPM;
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000403
404 // Count the runs over a Function.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000405 int FunctionPassRunCount1 = 0;
406 int AnalyzedInstrCount1 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000407 int AnalyzedFunctionCount1 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000408 {
Chandler Carruth999b92d2014-03-13 10:42:18 +0000409 // Pointless scoped copy to test move assignment.
Chandler Carruth6b981642016-12-10 06:34:44 +0000410 ModulePassManager NestedMPM(/*DebugLogging*/ true);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000411 FunctionPassManager FPM;
Chandler Carruth999b92d2014-03-13 10:42:18 +0000412 {
413 // Pointless scope to test move assignment.
Chandler Carruth6b981642016-12-10 06:34:44 +0000414 FunctionPassManager NestedFPM(/*DebugLogging*/ true);
Chandler Carruth74a8a222016-06-17 07:15:29 +0000415 NestedFPM.addPass(TestFunctionPass(
416 FunctionPassRunCount1, AnalyzedInstrCount1, AnalyzedFunctionCount1));
Chandler Carruth999b92d2014-03-13 10:42:18 +0000417 FPM = std::move(NestedFPM);
418 }
419 NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
420 MPM = std::move(NestedMPM);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000421 }
Chandler Carruth90a835d2013-11-09 13:09:08 +0000422
423 // Count the runs over a module.
424 int ModulePassRunCount = 0;
425 MPM.addPass(TestModulePass(ModulePassRunCount));
426
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000427 // Count the runs over a Function in a separate manager.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000428 int FunctionPassRunCount2 = 0;
429 int AnalyzedInstrCount2 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000430 int AnalyzedFunctionCount2 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000431 {
Chandler Carruth6b981642016-12-10 06:34:44 +0000432 FunctionPassManager FPM(/*DebugLogging*/ true);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000433 FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
434 AnalyzedFunctionCount2));
435 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
436 }
Chandler Carruth90a835d2013-11-09 13:09:08 +0000437
Chandler Carruthbceeb222013-11-22 23:38:07 +0000438 // A third function pass manager but with only preserving intervening passes
439 // and with a function pass that invalidates exactly one analysis.
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000440 MPM.addPass(TestPreservingModulePass());
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000441 int FunctionPassRunCount3 = 0;
442 int AnalyzedInstrCount3 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000443 int AnalyzedFunctionCount3 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000444 {
Chandler Carruth6b981642016-12-10 06:34:44 +0000445 FunctionPassManager FPM(/*DebugLogging*/ true);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000446 FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
447 AnalyzedFunctionCount3));
448 FPM.addPass(TestInvalidationFunctionPass("f"));
449 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
450 }
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000451
Chandler Carruth6b981642016-12-10 06:34:44 +0000452 // A fourth function pass manager but with only preserving intervening
453 // passes but triggering the module analysis.
454 MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000455 int FunctionPassRunCount4 = 0;
456 int AnalyzedInstrCount4 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000457 int AnalyzedFunctionCount4 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000458 {
459 FunctionPassManager FPM;
460 FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
461 AnalyzedFunctionCount4));
462 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
463 }
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000464
Chandler Carruth6b981642016-12-10 06:34:44 +0000465 // A fifth function pass manager which invalidates one function first but
466 // uses only cached results.
Chandler Carruthde9afd82013-11-23 00:38:42 +0000467 int FunctionPassRunCount5 = 0;
468 int AnalyzedInstrCount5 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000469 int AnalyzedFunctionCount5 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000470 {
Chandler Carruth6b981642016-12-10 06:34:44 +0000471 FunctionPassManager FPM(/*DebugLogging*/ true);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000472 FPM.addPass(TestInvalidationFunctionPass("f"));
473 FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
474 AnalyzedFunctionCount5,
475 /*OnlyUseCachedResults=*/true));
476 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
477 }
Chandler Carruthde9afd82013-11-23 00:38:42 +0000478
Chandler Carruthb47f8012016-03-11 11:05:24 +0000479 MPM.run(*M, MAM);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000480
481 // Validate module pass counters.
Chandler Carruth90a835d2013-11-09 13:09:08 +0000482 EXPECT_EQ(1, ModulePassRunCount);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000483
Chandler Carruthbceeb222013-11-22 23:38:07 +0000484 // Validate all function pass counter sets are the same.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000485 EXPECT_EQ(3, FunctionPassRunCount1);
486 EXPECT_EQ(5, AnalyzedInstrCount1);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000487 EXPECT_EQ(0, AnalyzedFunctionCount1);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000488 EXPECT_EQ(3, FunctionPassRunCount2);
489 EXPECT_EQ(5, AnalyzedInstrCount2);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000490 EXPECT_EQ(0, AnalyzedFunctionCount2);
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000491 EXPECT_EQ(3, FunctionPassRunCount3);
492 EXPECT_EQ(5, AnalyzedInstrCount3);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000493 EXPECT_EQ(0, AnalyzedFunctionCount3);
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000494 EXPECT_EQ(3, FunctionPassRunCount4);
495 EXPECT_EQ(5, AnalyzedInstrCount4);
Chandler Carruth6b981642016-12-10 06:34:44 +0000496 EXPECT_EQ(9, AnalyzedFunctionCount4);
Chandler Carruthde9afd82013-11-23 00:38:42 +0000497 EXPECT_EQ(3, FunctionPassRunCount5);
498 EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
Chandler Carruth6b981642016-12-10 06:34:44 +0000499 EXPECT_EQ(9, AnalyzedFunctionCount5);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000500
Chandler Carruthbceeb222013-11-22 23:38:07 +0000501 // Validate the analysis counters:
502 // first run over 3 functions, then module pass invalidates
503 // second run over 3 functions, nothing invalidates
504 // third run over 0 functions, but 1 function invalidated
505 // fourth run over 1 function
Chandler Carruth6b981642016-12-10 06:34:44 +0000506 // fifth run invalidates 1 function first, but runs over 0 functions
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000507 EXPECT_EQ(7, FunctionAnalysisRuns);
508
509 EXPECT_EQ(1, ModuleAnalysisRuns);
Chandler Carruth90a835d2013-11-09 13:09:08 +0000510}
Chandler Carruth9b35e6d2016-08-19 18:36:06 +0000511
512// A customized pass manager that passes extra arguments through the
513// infrastructure.
514typedef AnalysisManager<Function, int> CustomizedAnalysisManager;
515typedef PassManager<Function, CustomizedAnalysisManager, int, int &>
516 CustomizedPassManager;
517
518class CustomizedAnalysis : public AnalysisInfoMixin<CustomizedAnalysis> {
519public:
520 struct Result {
521 Result(int I) : I(I) {}
522 int I;
523 };
524
525 Result run(Function &F, CustomizedAnalysisManager &AM, int I) {
526 return Result(I);
527 }
528
529private:
530 friend AnalysisInfoMixin<CustomizedAnalysis>;
Chandler Carruthdab4eae2016-11-23 17:53:26 +0000531 static AnalysisKey Key;
Chandler Carruth9b35e6d2016-08-19 18:36:06 +0000532};
533
Chandler Carruthdab4eae2016-11-23 17:53:26 +0000534AnalysisKey CustomizedAnalysis::Key;
Chandler Carruth9b35e6d2016-08-19 18:36:06 +0000535
536struct CustomizedPass : PassInfoMixin<CustomizedPass> {
537 std::function<void(CustomizedAnalysis::Result &, int &)> Callback;
538
539 template <typename CallbackT>
540 CustomizedPass(CallbackT Callback) : Callback(Callback) {}
541
542 PreservedAnalyses run(Function &F, CustomizedAnalysisManager &AM, int I,
543 int &O) {
544 Callback(AM.getResult<CustomizedAnalysis>(F, I), O);
545 return PreservedAnalyses::none();
546 }
547};
548
549TEST_F(PassManagerTest, CustomizedPassManagerArgs) {
550 CustomizedAnalysisManager AM;
551 AM.registerPass([&] { return CustomizedAnalysis(); });
552
553 CustomizedPassManager PM;
554
555 // Add an instance of the customized pass that just accumulates the input
556 // after it is round-tripped through the analysis.
557 int Result = 0;
558 PM.addPass(
559 CustomizedPass([](CustomizedAnalysis::Result &R, int &O) { O += R.I; }));
560
561 // Run this over every function with the input of 42.
562 for (Function &F : *M)
563 PM.run(F, AM, 42, Result);
564
565 // And ensure that we accumulated the correct result.
566 EXPECT_EQ(42 * (int)M->size(), Result);
567}
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000568
569/// A test analysis pass which caches in its result another analysis pass and
570/// uses it to serve queries. This requires the result to invalidate itself
571/// when its dependency is invalidated.
572struct TestIndirectFunctionAnalysis
573 : public AnalysisInfoMixin<TestIndirectFunctionAnalysis> {
574 struct Result {
Chandler Carruthba90ae92016-12-27 08:40:39 +0000575 Result(TestFunctionAnalysis::Result &FDep, TestModuleAnalysis::Result &MDep)
576 : FDep(FDep), MDep(MDep) {}
577 TestFunctionAnalysis::Result &FDep;
578 TestModuleAnalysis::Result &MDep;
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000579
580 bool invalidate(Function &F, const PreservedAnalyses &PA,
581 FunctionAnalysisManager::Invalidator &Inv) {
Chandler Carruthba90ae92016-12-27 08:40:39 +0000582 auto PAC = PA.getChecker<TestIndirectFunctionAnalysis>();
583 return !(PAC.preserved() ||
584 PAC.preservedSet<AllAnalysesOn<Function>>()) ||
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000585 Inv.invalidate<TestFunctionAnalysis>(F, PA);
586 }
587 };
588
589 TestIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
590
591 /// Run the analysis pass over the function and return a result.
592 Result run(Function &F, FunctionAnalysisManager &AM) {
593 ++Runs;
Chandler Carruthba90ae92016-12-27 08:40:39 +0000594 auto &FDep = AM.getResult<TestFunctionAnalysis>(F);
595 auto &Proxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
596 const ModuleAnalysisManager &MAM = Proxy.getManager();
597 // For the test, we insist that the module analysis starts off in the
598 // cache.
599 auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
600 // And register the dependency as module analysis dependencies have to be
601 // pre-registered on the proxy.
602 Proxy.registerOuterAnalysisInvalidation<TestModuleAnalysis,
603 TestIndirectFunctionAnalysis>();
604 return Result(FDep, MDep);
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000605 }
606
607private:
608 friend AnalysisInfoMixin<TestIndirectFunctionAnalysis>;
609 static AnalysisKey Key;
610
611 int &Runs;
612};
613
614AnalysisKey TestIndirectFunctionAnalysis::Key;
615
Chandler Carruthba90ae92016-12-27 08:40:39 +0000616/// A test analysis pass which chaches in its result the result from the above
617/// indirect analysis pass.
618///
619/// This allows us to ensure that whenever an analysis pass is invalidated due
620/// to dependencies (especially dependencies across IR units that trigger
621/// asynchronous invalidation) we correctly detect that this may in turn cause
622/// other analysis to be invalidated.
623struct TestDoublyIndirectFunctionAnalysis
624 : public AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis> {
625 struct Result {
626 Result(TestIndirectFunctionAnalysis::Result &IDep) : IDep(IDep) {}
627 TestIndirectFunctionAnalysis::Result &IDep;
628
629 bool invalidate(Function &F, const PreservedAnalyses &PA,
630 FunctionAnalysisManager::Invalidator &Inv) {
631 auto PAC = PA.getChecker<TestDoublyIndirectFunctionAnalysis>();
632 return !(PAC.preserved() ||
633 PAC.preservedSet<AllAnalysesOn<Function>>()) ||
634 Inv.invalidate<TestIndirectFunctionAnalysis>(F, PA);
635 }
636 };
637
638 TestDoublyIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}
639
640 /// Run the analysis pass over the function and return a result.
641 Result run(Function &F, FunctionAnalysisManager &AM) {
642 ++Runs;
643 auto &IDep = AM.getResult<TestIndirectFunctionAnalysis>(F);
644 return Result(IDep);
645 }
646
647private:
648 friend AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis>;
649 static AnalysisKey Key;
650
651 int &Runs;
652};
653
654AnalysisKey TestDoublyIndirectFunctionAnalysis::Key;
655
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000656struct LambdaPass : public PassInfoMixin<LambdaPass> {
657 using FuncT = std::function<PreservedAnalyses(Function &, FunctionAnalysisManager &)>;
658
659 LambdaPass(FuncT Func) : Func(std::move(Func)) {}
660
661 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
662 return Func(F, AM);
663 }
664
665 FuncT Func;
666};
667
668TEST_F(PassManagerTest, IndirectAnalysisInvalidation) {
669 FunctionAnalysisManager FAM(/*DebugLogging*/ true);
Chandler Carruthba90ae92016-12-27 08:40:39 +0000670 int FunctionAnalysisRuns = 0, ModuleAnalysisRuns = 0,
671 IndirectAnalysisRuns = 0, DoublyIndirectAnalysisRuns = 0;
672 FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000673 FAM.registerPass(
674 [&] { return TestIndirectFunctionAnalysis(IndirectAnalysisRuns); });
Chandler Carruthba90ae92016-12-27 08:40:39 +0000675 FAM.registerPass([&] {
676 return TestDoublyIndirectFunctionAnalysis(DoublyIndirectAnalysisRuns);
677 });
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000678
679 ModuleAnalysisManager MAM(/*DebugLogging*/ true);
Chandler Carruthba90ae92016-12-27 08:40:39 +0000680 MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000681 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
682 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
683
Chandler Carruthba90ae92016-12-27 08:40:39 +0000684 int InstrCount = 0, FunctionCount = 0;
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000685 ModulePassManager MPM(/*DebugLogging*/ true);
686 FunctionPassManager FPM(/*DebugLogging*/ true);
687 // First just use the analysis to get the instruction count, and preserve
688 // everything.
689 FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
Chandler Carruthba90ae92016-12-27 08:40:39 +0000690 auto &DoublyIndirectResult =
691 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
692 auto &IndirectResult = DoublyIndirectResult.IDep;
693 InstrCount += IndirectResult.FDep.InstructionCount;
694 FunctionCount += IndirectResult.MDep.FunctionCount;
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000695 return PreservedAnalyses::all();
696 }));
697 // Next, invalidate
698 // - both analyses for "f",
699 // - just the underlying (indirect) analysis for "g", and
700 // - just the direct analysis for "h".
701 FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
Chandler Carruthba90ae92016-12-27 08:40:39 +0000702 auto &DoublyIndirectResult =
703 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
704 auto &IndirectResult = DoublyIndirectResult.IDep;
705 InstrCount += IndirectResult.FDep.InstructionCount;
706 FunctionCount += IndirectResult.MDep.FunctionCount;
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000707 auto PA = PreservedAnalyses::none();
708 if (F.getName() == "g")
709 PA.preserve<TestFunctionAnalysis>();
710 else if (F.getName() == "h")
711 PA.preserve<TestIndirectFunctionAnalysis>();
712 return PA;
713 }));
714 // Finally, use the analysis again on each function, forcing re-computation
715 // for all of them.
716 FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
Chandler Carruthba90ae92016-12-27 08:40:39 +0000717 auto &DoublyIndirectResult =
718 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
719 auto &IndirectResult = DoublyIndirectResult.IDep;
720 InstrCount += IndirectResult.FDep.InstructionCount;
721 FunctionCount += IndirectResult.MDep.FunctionCount;
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000722 return PreservedAnalyses::all();
723 }));
Chandler Carruthba90ae92016-12-27 08:40:39 +0000724
725 // Create a second function pass manager. This will cause the module-level
726 // invalidation to occur, which will force yet another invalidation of the
727 // indirect function-level analysis as the module analysis it depends on gets
728 // invalidated.
729 FunctionPassManager FPM2(/*DebugLogging*/ true);
730 FPM2.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
731 auto &DoublyIndirectResult =
732 AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
733 auto &IndirectResult = DoublyIndirectResult.IDep;
734 InstrCount += IndirectResult.FDep.InstructionCount;
735 FunctionCount += IndirectResult.MDep.FunctionCount;
736 return PreservedAnalyses::all();
737 }));
738
739 // Add a requires pass to populate the module analysis and then our function
740 // pass pipeline.
741 MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000742 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
Chandler Carruthba90ae92016-12-27 08:40:39 +0000743 // Now require the module analysis again (it will have been invalidated once)
744 // and then use it again from a function pass manager.
745 MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
746 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM2)));
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000747 MPM.run(*M, MAM);
748
749 // There are generally two possible runs for each of the three functions. But
750 // for one function, we only invalidate the indirect analysis so the base one
751 // only gets run five times.
Chandler Carruthba90ae92016-12-27 08:40:39 +0000752 EXPECT_EQ(5, FunctionAnalysisRuns);
753 // The module analysis pass should be run twice here.
754 EXPECT_EQ(2, ModuleAnalysisRuns);
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000755 // The indirect analysis is invalidated for each function (either directly or
756 // indirectly) and run twice for each.
Chandler Carruthba90ae92016-12-27 08:40:39 +0000757 EXPECT_EQ(9, IndirectAnalysisRuns);
758 EXPECT_EQ(9, DoublyIndirectAnalysisRuns);
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000759
Chandler Carruthba90ae92016-12-27 08:40:39 +0000760 // There are five instructions in the module and we add the count four
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000761 // times.
Chandler Carruthba90ae92016-12-27 08:40:39 +0000762 EXPECT_EQ(5 * 4, InstrCount);
763
764 // There are three functions and we count them four times for each of the
765 // three functions.
766 EXPECT_EQ(3 * 4 * 3, FunctionCount);
Chandler Carruth3ab2a5a2016-11-28 22:04:31 +0000767}
Chandler Carruth90a835d2013-11-09 13:09:08 +0000768}