1 //===- 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 
10 #include "llvm/AsmParser/Parser.h"
11 #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 
18 using namespace llvm;
19 
20 namespace {
21 
22 class TestFunctionAnalysis {
23 public:
24   struct Result {
Result__anone814850a0111::TestFunctionAnalysis::Result25     Result(int Count) : InstructionCount(Count) {}
26     int InstructionCount;
27   };
28 
29   /// \brief Returns an opaque, unique ID for this pass type.
ID()30   static void *ID() { return (void *)&PassID; }
31 
32   /// \brief Returns the name of the analysis.
name()33   static StringRef name() { return "TestFunctionAnalysis"; }
34 
TestFunctionAnalysis(int & Runs)35   TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
36 
37   /// \brief Run the analysis pass over the function and return a result.
run(Function & F,FunctionAnalysisManager * AM)38   Result run(Function &F, FunctionAnalysisManager *AM) {
39     ++Runs;
40     int Count = 0;
41     for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI)
42       for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
43            ++II)
44         ++Count;
45     return Result(Count);
46   }
47 
48 private:
49   /// \brief Private static data to provide unique ID.
50   static char PassID;
51 
52   int &Runs;
53 };
54 
55 char TestFunctionAnalysis::PassID;
56 
57 class TestModuleAnalysis {
58 public:
59   struct Result {
Result__anone814850a0111::TestModuleAnalysis::Result60     Result(int Count) : FunctionCount(Count) {}
61     int FunctionCount;
62   };
63 
ID()64   static void *ID() { return (void *)&PassID; }
65 
name()66   static StringRef name() { return "TestModuleAnalysis"; }
67 
TestModuleAnalysis(int & Runs)68   TestModuleAnalysis(int &Runs) : Runs(Runs) {}
69 
run(Module & M,ModuleAnalysisManager * AM)70   Result run(Module &M, ModuleAnalysisManager *AM) {
71     ++Runs;
72     int Count = 0;
73     for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
74       ++Count;
75     return Result(Count);
76   }
77 
78 private:
79   static char PassID;
80 
81   int &Runs;
82 };
83 
84 char TestModuleAnalysis::PassID;
85 
86 struct TestModulePass {
TestModulePass__anone814850a0111::TestModulePass87   TestModulePass(int &RunCount) : RunCount(RunCount) {}
88 
run__anone814850a0111::TestModulePass89   PreservedAnalyses run(Module &M) {
90     ++RunCount;
91     return PreservedAnalyses::none();
92   }
93 
name__anone814850a0111::TestModulePass94   static StringRef name() { return "TestModulePass"; }
95 
96   int &RunCount;
97 };
98 
99 struct TestPreservingModulePass {
run__anone814850a0111::TestPreservingModulePass100   PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
101 
name__anone814850a0111::TestPreservingModulePass102   static StringRef name() { return "TestPreservingModulePass"; }
103 };
104 
105 struct TestMinPreservingModulePass {
run__anone814850a0111::TestMinPreservingModulePass106   PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM) {
107     PreservedAnalyses PA;
108 
109     // Force running an analysis.
110     (void)AM->getResult<TestModuleAnalysis>(M);
111 
112     PA.preserve<FunctionAnalysisManagerModuleProxy>();
113     return PA;
114   }
115 
name__anone814850a0111::TestMinPreservingModulePass116   static StringRef name() { return "TestMinPreservingModulePass"; }
117 };
118 
119 struct TestFunctionPass {
TestFunctionPass__anone814850a0111::TestFunctionPass120   TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
121                    int &AnalyzedFunctionCount,
122                    bool OnlyUseCachedResults = false)
123       : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
124         AnalyzedFunctionCount(AnalyzedFunctionCount),
125         OnlyUseCachedResults(OnlyUseCachedResults) {}
126 
run__anone814850a0111::TestFunctionPass127   PreservedAnalyses run(Function &F, FunctionAnalysisManager *AM) {
128     ++RunCount;
129 
130     const ModuleAnalysisManager &MAM =
131         AM->getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
132     if (TestModuleAnalysis::Result *TMA =
133             MAM.getCachedResult<TestModuleAnalysis>(*F.getParent()))
134       AnalyzedFunctionCount += TMA->FunctionCount;
135 
136     if (OnlyUseCachedResults) {
137       // Hack to force the use of the cached interface.
138       if (TestFunctionAnalysis::Result *AR =
139               AM->getCachedResult<TestFunctionAnalysis>(F))
140         AnalyzedInstrCount += AR->InstructionCount;
141     } else {
142       // Typical path just runs the analysis as needed.
143       TestFunctionAnalysis::Result &AR = AM->getResult<TestFunctionAnalysis>(F);
144       AnalyzedInstrCount += AR.InstructionCount;
145     }
146 
147     return PreservedAnalyses::all();
148   }
149 
name__anone814850a0111::TestFunctionPass150   static StringRef name() { return "TestFunctionPass"; }
151 
152   int &RunCount;
153   int &AnalyzedInstrCount;
154   int &AnalyzedFunctionCount;
155   bool OnlyUseCachedResults;
156 };
157 
158 // A test function pass that invalidates all function analyses for a function
159 // with a specific name.
160 struct TestInvalidationFunctionPass {
TestInvalidationFunctionPass__anone814850a0111::TestInvalidationFunctionPass161   TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
162 
run__anone814850a0111::TestInvalidationFunctionPass163   PreservedAnalyses run(Function &F) {
164     return F.getName() == Name ? PreservedAnalyses::none()
165                                : PreservedAnalyses::all();
166   }
167 
name__anone814850a0111::TestInvalidationFunctionPass168   static StringRef name() { return "TestInvalidationFunctionPass"; }
169 
170   StringRef Name;
171 };
172 
parseIR(const char * IR)173 std::unique_ptr<Module> parseIR(const char *IR) {
174   LLVMContext &C = getGlobalContext();
175   SMDiagnostic Err;
176   return parseAssemblyString(IR, Err, C);
177 }
178 
179 class PassManagerTest : public ::testing::Test {
180 protected:
181   std::unique_ptr<Module> M;
182 
183 public:
PassManagerTest()184   PassManagerTest()
185       : M(parseIR("define void @f() {\n"
186                   "entry:\n"
187                   "  call void @g()\n"
188                   "  call void @h()\n"
189                   "  ret void\n"
190                   "}\n"
191                   "define void @g() {\n"
192                   "  ret void\n"
193                   "}\n"
194                   "define void @h() {\n"
195                   "  ret void\n"
196                   "}\n")) {}
197 };
198 
TEST_F(PassManagerTest,BasicPreservedAnalyses)199 TEST_F(PassManagerTest, BasicPreservedAnalyses) {
200   PreservedAnalyses PA1 = PreservedAnalyses();
201   EXPECT_FALSE(PA1.preserved<TestFunctionAnalysis>());
202   EXPECT_FALSE(PA1.preserved<TestModuleAnalysis>());
203   PreservedAnalyses PA2 = PreservedAnalyses::none();
204   EXPECT_FALSE(PA2.preserved<TestFunctionAnalysis>());
205   EXPECT_FALSE(PA2.preserved<TestModuleAnalysis>());
206   PreservedAnalyses PA3 = PreservedAnalyses::all();
207   EXPECT_TRUE(PA3.preserved<TestFunctionAnalysis>());
208   EXPECT_TRUE(PA3.preserved<TestModuleAnalysis>());
209   PreservedAnalyses PA4 = PA1;
210   EXPECT_FALSE(PA4.preserved<TestFunctionAnalysis>());
211   EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
212   PA4 = PA3;
213   EXPECT_TRUE(PA4.preserved<TestFunctionAnalysis>());
214   EXPECT_TRUE(PA4.preserved<TestModuleAnalysis>());
215   PA4 = std::move(PA2);
216   EXPECT_FALSE(PA4.preserved<TestFunctionAnalysis>());
217   EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
218   PA4.preserve<TestFunctionAnalysis>();
219   EXPECT_TRUE(PA4.preserved<TestFunctionAnalysis>());
220   EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
221   PA1.preserve<TestModuleAnalysis>();
222   EXPECT_FALSE(PA1.preserved<TestFunctionAnalysis>());
223   EXPECT_TRUE(PA1.preserved<TestModuleAnalysis>());
224   PA1.preserve<TestFunctionAnalysis>();
225   EXPECT_TRUE(PA1.preserved<TestFunctionAnalysis>());
226   EXPECT_TRUE(PA1.preserved<TestModuleAnalysis>());
227   PA1.intersect(PA4);
228   EXPECT_TRUE(PA1.preserved<TestFunctionAnalysis>());
229   EXPECT_FALSE(PA1.preserved<TestModuleAnalysis>());
230 }
231 
TEST_F(PassManagerTest,Basic)232 TEST_F(PassManagerTest, Basic) {
233   FunctionAnalysisManager FAM;
234   int FunctionAnalysisRuns = 0;
235   FAM.registerPass(TestFunctionAnalysis(FunctionAnalysisRuns));
236 
237   ModuleAnalysisManager MAM;
238   int ModuleAnalysisRuns = 0;
239   MAM.registerPass(TestModuleAnalysis(ModuleAnalysisRuns));
240   MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
241   FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM));
242 
243   ModulePassManager MPM;
244 
245   // Count the runs over a Function.
246   int FunctionPassRunCount1 = 0;
247   int AnalyzedInstrCount1 = 0;
248   int AnalyzedFunctionCount1 = 0;
249   {
250     // Pointless scoped copy to test move assignment.
251     ModulePassManager NestedMPM;
252     FunctionPassManager FPM;
253     {
254       // Pointless scope to test move assignment.
255       FunctionPassManager NestedFPM;
256       NestedFPM.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1,
257                                    AnalyzedFunctionCount1));
258       FPM = std::move(NestedFPM);
259     }
260     NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
261     MPM = std::move(NestedMPM);
262   }
263 
264   // Count the runs over a module.
265   int ModulePassRunCount = 0;
266   MPM.addPass(TestModulePass(ModulePassRunCount));
267 
268   // Count the runs over a Function in a separate manager.
269   int FunctionPassRunCount2 = 0;
270   int AnalyzedInstrCount2 = 0;
271   int AnalyzedFunctionCount2 = 0;
272   {
273     FunctionPassManager FPM;
274     FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
275                                  AnalyzedFunctionCount2));
276     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
277   }
278 
279   // A third function pass manager but with only preserving intervening passes
280   // and with a function pass that invalidates exactly one analysis.
281   MPM.addPass(TestPreservingModulePass());
282   int FunctionPassRunCount3 = 0;
283   int AnalyzedInstrCount3 = 0;
284   int AnalyzedFunctionCount3 = 0;
285   {
286     FunctionPassManager FPM;
287     FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
288                                  AnalyzedFunctionCount3));
289     FPM.addPass(TestInvalidationFunctionPass("f"));
290     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
291   }
292 
293   // A fourth function pass manager but with a minimal intervening passes.
294   MPM.addPass(TestMinPreservingModulePass());
295   int FunctionPassRunCount4 = 0;
296   int AnalyzedInstrCount4 = 0;
297   int AnalyzedFunctionCount4 = 0;
298   {
299     FunctionPassManager FPM;
300     FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
301                                  AnalyzedFunctionCount4));
302     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
303   }
304 
305   // A fifth function pass manager but which uses only cached results.
306   int FunctionPassRunCount5 = 0;
307   int AnalyzedInstrCount5 = 0;
308   int AnalyzedFunctionCount5 = 0;
309   {
310     FunctionPassManager FPM;
311     FPM.addPass(TestInvalidationFunctionPass("f"));
312     FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
313                                  AnalyzedFunctionCount5,
314                                  /*OnlyUseCachedResults=*/true));
315     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
316   }
317 
318   MPM.run(*M, &MAM);
319 
320   // Validate module pass counters.
321   EXPECT_EQ(1, ModulePassRunCount);
322 
323   // Validate all function pass counter sets are the same.
324   EXPECT_EQ(3, FunctionPassRunCount1);
325   EXPECT_EQ(5, AnalyzedInstrCount1);
326   EXPECT_EQ(0, AnalyzedFunctionCount1);
327   EXPECT_EQ(3, FunctionPassRunCount2);
328   EXPECT_EQ(5, AnalyzedInstrCount2);
329   EXPECT_EQ(0, AnalyzedFunctionCount2);
330   EXPECT_EQ(3, FunctionPassRunCount3);
331   EXPECT_EQ(5, AnalyzedInstrCount3);
332   EXPECT_EQ(0, AnalyzedFunctionCount3);
333   EXPECT_EQ(3, FunctionPassRunCount4);
334   EXPECT_EQ(5, AnalyzedInstrCount4);
335   EXPECT_EQ(0, AnalyzedFunctionCount4);
336   EXPECT_EQ(3, FunctionPassRunCount5);
337   EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
338   EXPECT_EQ(0, AnalyzedFunctionCount5);
339 
340   // Validate the analysis counters:
341   //   first run over 3 functions, then module pass invalidates
342   //   second run over 3 functions, nothing invalidates
343   //   third run over 0 functions, but 1 function invalidated
344   //   fourth run over 1 function
345   EXPECT_EQ(7, FunctionAnalysisRuns);
346 
347   EXPECT_EQ(1, ModuleAnalysisRuns);
348 }
349 }
350