blob: 41af0b0bd25c4165b98b34b4e4a3679619a8a765 [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 Carruth2ad18582013-11-23 01:25:02 +000022class 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
29 /// \brief Returns an opaque, unique ID for this pass type.
30 static void *ID() { return (void *)&PassID; }
31
Chandler Carruthe5e8fb32015-01-05 12:21:44 +000032 /// \brief Returns the name of the analysis.
33 static StringRef name() { return "TestFunctionAnalysis"; }
34
Chandler Carruth2ad18582013-11-23 01:25:02 +000035 TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
Chandler Carruth851a2aa2013-11-21 02:11:31 +000036
Chandler Carruth74015a72013-11-13 01:12:08 +000037 /// \brief Run the analysis pass over the function and return a result.
Chandler Carruthd174ce42015-01-05 02:47:05 +000038 Result run(Function &F, FunctionAnalysisManager *AM) {
Chandler Carruth851a2aa2013-11-21 02:11:31 +000039 ++Runs;
Chandler Carruth74015a72013-11-13 01:12:08 +000040 int Count = 0;
Chandler Carruthd174ce42015-01-05 02:47:05 +000041 for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI)
Chandler Carruth74015a72013-11-13 01:12:08 +000042 for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
43 ++II)
44 ++Count;
45 return Result(Count);
46 }
47
48private:
49 /// \brief Private static data to provide unique ID.
50 static char PassID;
Chandler Carruth851a2aa2013-11-21 02:11:31 +000051
52 int &Runs;
Chandler Carruth74015a72013-11-13 01:12:08 +000053};
54
Chandler Carruth2ad18582013-11-23 01:25:02 +000055char TestFunctionAnalysis::PassID;
Chandler Carruth74015a72013-11-13 01:12:08 +000056
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000057class TestModuleAnalysis {
58public:
59 struct Result {
60 Result(int Count) : FunctionCount(Count) {}
61 int FunctionCount;
62 };
63
Chandler Carruth5ae74a62014-03-10 02:12:14 +000064 static void *ID() { return (void *)&PassID; }
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000065
Chandler Carruthe5e8fb32015-01-05 12:21:44 +000066 static StringRef name() { return "TestModuleAnalysis"; }
67
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000068 TestModuleAnalysis(int &Runs) : Runs(Runs) {}
69
Chandler Carruthd174ce42015-01-05 02:47:05 +000070 Result run(Module &M, ModuleAnalysisManager *AM) {
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000071 ++Runs;
72 int Count = 0;
Chandler Carruthd174ce42015-01-05 02:47:05 +000073 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000074 ++Count;
75 return Result(Count);
76 }
77
78private:
79 static char PassID;
80
81 int &Runs;
82};
83
84char TestModuleAnalysis::PassID;
85
Chandler Carruth90a835d2013-11-09 13:09:08 +000086struct TestModulePass {
87 TestModulePass(int &RunCount) : RunCount(RunCount) {}
88
Chandler Carruthd174ce42015-01-05 02:47:05 +000089 PreservedAnalyses run(Module &M) {
Chandler Carruth90a835d2013-11-09 13:09:08 +000090 ++RunCount;
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000091 return PreservedAnalyses::none();
Chandler Carruth90a835d2013-11-09 13:09:08 +000092 }
93
Chandler Carrutha13f27c2014-01-11 11:52:05 +000094 static StringRef name() { return "TestModulePass"; }
95
Chandler Carruth90a835d2013-11-09 13:09:08 +000096 int &RunCount;
97};
98
Chandler Carruth2846e9e2013-11-21 10:53:05 +000099struct TestPreservingModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +0000100 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carrutha13f27c2014-01-11 11:52:05 +0000101
102 static StringRef name() { return "TestPreservingModulePass"; }
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000103};
104
105struct TestMinPreservingModulePass {
Chandler Carruthd174ce42015-01-05 02:47:05 +0000106 PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM) {
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000107 PreservedAnalyses PA;
Chandler Carruthde9afd82013-11-23 00:38:42 +0000108
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000109 // Force running an analysis.
110 (void)AM->getResult<TestModuleAnalysis>(M);
Chandler Carruthde9afd82013-11-23 00:38:42 +0000111
Chandler Carruthb3e72192013-11-22 00:43:29 +0000112 PA.preserve<FunctionAnalysisManagerModuleProxy>();
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000113 return PA;
114 }
Chandler Carrutha13f27c2014-01-11 11:52:05 +0000115
116 static StringRef name() { return "TestMinPreservingModulePass"; }
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000117};
118
Chandler Carruth90a835d2013-11-09 13:09:08 +0000119struct TestFunctionPass {
Chandler Carruthde9afd82013-11-23 00:38:42 +0000120 TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000121 int &AnalyzedFunctionCount,
Chandler Carruthde9afd82013-11-23 00:38:42 +0000122 bool OnlyUseCachedResults = false)
123 : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000124 AnalyzedFunctionCount(AnalyzedFunctionCount),
Chandler Carruthde9afd82013-11-23 00:38:42 +0000125 OnlyUseCachedResults(OnlyUseCachedResults) {}
Chandler Carruth90a835d2013-11-09 13:09:08 +0000126
Chandler Carruthd174ce42015-01-05 02:47:05 +0000127 PreservedAnalyses run(Function &F, FunctionAnalysisManager *AM) {
Chandler Carruth90a835d2013-11-09 13:09:08 +0000128 ++RunCount;
Chandler Carruth74015a72013-11-13 01:12:08 +0000129
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000130 const ModuleAnalysisManager &MAM =
131 AM->getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
Chandler Carrutheedf9fc2014-02-05 21:41:42 +0000132 if (TestModuleAnalysis::Result *TMA =
Chandler Carruthd174ce42015-01-05 02:47:05 +0000133 MAM.getCachedResult<TestModuleAnalysis>(*F.getParent()))
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000134 AnalyzedFunctionCount += TMA->FunctionCount;
135
Chandler Carruthde9afd82013-11-23 00:38:42 +0000136 if (OnlyUseCachedResults) {
137 // Hack to force the use of the cached interface.
Chandler Carrutheedf9fc2014-02-05 21:41:42 +0000138 if (TestFunctionAnalysis::Result *AR =
Chandler Carruth2ad18582013-11-23 01:25:02 +0000139 AM->getCachedResult<TestFunctionAnalysis>(F))
Chandler Carruthde9afd82013-11-23 00:38:42 +0000140 AnalyzedInstrCount += AR->InstructionCount;
141 } else {
142 // Typical path just runs the analysis as needed.
Chandler Carrutheedf9fc2014-02-05 21:41:42 +0000143 TestFunctionAnalysis::Result &AR = AM->getResult<TestFunctionAnalysis>(F);
Chandler Carruthde9afd82013-11-23 00:38:42 +0000144 AnalyzedInstrCount += AR.InstructionCount;
145 }
Chandler Carruth74015a72013-11-13 01:12:08 +0000146
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000147 return PreservedAnalyses::all();
Chandler Carruth90a835d2013-11-09 13:09:08 +0000148 }
149
Chandler Carrutha13f27c2014-01-11 11:52:05 +0000150 static StringRef name() { return "TestFunctionPass"; }
151
Chandler Carruth90a835d2013-11-09 13:09:08 +0000152 int &RunCount;
Chandler Carruth74015a72013-11-13 01:12:08 +0000153 int &AnalyzedInstrCount;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000154 int &AnalyzedFunctionCount;
Chandler Carruthde9afd82013-11-23 00:38:42 +0000155 bool OnlyUseCachedResults;
Chandler Carruth90a835d2013-11-09 13:09:08 +0000156};
157
Chandler Carruthbceeb222013-11-22 23:38:07 +0000158// A test function pass that invalidates all function analyses for a function
159// with a specific name.
160struct TestInvalidationFunctionPass {
161 TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
162
Chandler Carruthd174ce42015-01-05 02:47:05 +0000163 PreservedAnalyses run(Function &F) {
164 return F.getName() == Name ? PreservedAnalyses::none()
165 : PreservedAnalyses::all();
Chandler Carruthbceeb222013-11-22 23:38:07 +0000166 }
167
Chandler Carrutha13f27c2014-01-11 11:52:05 +0000168 static StringRef name() { return "TestInvalidationFunctionPass"; }
169
Chandler Carruthbceeb222013-11-22 23:38:07 +0000170 StringRef Name;
171};
172
Chandler Carruthd174ce42015-01-05 02:47:05 +0000173std::unique_ptr<Module> parseIR(const char *IR) {
Chandler Carruth90a835d2013-11-09 13:09:08 +0000174 LLVMContext &C = getGlobalContext();
175 SMDiagnostic Err;
Chandler Carruthd174ce42015-01-05 02:47:05 +0000176 return parseAssemblyString(IR, Err, C);
Chandler Carruth90a835d2013-11-09 13:09:08 +0000177}
178
179class PassManagerTest : public ::testing::Test {
180protected:
Ahmed Charles56440fd2014-03-06 05:51:42 +0000181 std::unique_ptr<Module> M;
Chandler Carruth90a835d2013-11-09 13:09:08 +0000182
183public:
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
Chandler Carruth999b92d2014-03-13 10:42:18 +0000199TEST_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
Chandler Carruth90a835d2013-11-09 13:09:08 +0000232TEST_F(PassManagerTest, Basic) {
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000233 FunctionAnalysisManager FAM;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000234 int FunctionAnalysisRuns = 0;
235 FAM.registerPass(TestFunctionAnalysis(FunctionAnalysisRuns));
Chandler Carruth74015a72013-11-13 01:12:08 +0000236
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000237 ModuleAnalysisManager MAM;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000238 int ModuleAnalysisRuns = 0;
239 MAM.registerPass(TestModuleAnalysis(ModuleAnalysisRuns));
Chandler Carruthb3e72192013-11-22 00:43:29 +0000240 MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000241 FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM));
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000242
Chandler Carruthb3e72192013-11-22 00:43:29 +0000243 ModulePassManager MPM;
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000244
245 // Count the runs over a Function.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000246 int FunctionPassRunCount1 = 0;
247 int AnalyzedInstrCount1 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000248 int AnalyzedFunctionCount1 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000249 {
Chandler Carruth999b92d2014-03-13 10:42:18 +0000250 // Pointless scoped copy to test move assignment.
251 ModulePassManager NestedMPM;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000252 FunctionPassManager FPM;
Chandler Carruth999b92d2014-03-13 10:42:18 +0000253 {
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);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000262 }
Chandler Carruth90a835d2013-11-09 13:09:08 +0000263
264 // Count the runs over a module.
265 int ModulePassRunCount = 0;
266 MPM.addPass(TestModulePass(ModulePassRunCount));
267
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000268 // Count the runs over a Function in a separate manager.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000269 int FunctionPassRunCount2 = 0;
270 int AnalyzedInstrCount2 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000271 int AnalyzedFunctionCount2 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000272 {
273 FunctionPassManager FPM;
274 FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
275 AnalyzedFunctionCount2));
276 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
277 }
Chandler Carruth90a835d2013-11-09 13:09:08 +0000278
Chandler Carruthbceeb222013-11-22 23:38:07 +0000279 // A third function pass manager but with only preserving intervening passes
280 // and with a function pass that invalidates exactly one analysis.
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000281 MPM.addPass(TestPreservingModulePass());
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000282 int FunctionPassRunCount3 = 0;
283 int AnalyzedInstrCount3 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000284 int AnalyzedFunctionCount3 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000285 {
286 FunctionPassManager FPM;
287 FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
288 AnalyzedFunctionCount3));
289 FPM.addPass(TestInvalidationFunctionPass("f"));
290 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
291 }
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000292
293 // A fourth function pass manager but with a minimal intervening passes.
294 MPM.addPass(TestMinPreservingModulePass());
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000295 int FunctionPassRunCount4 = 0;
296 int AnalyzedInstrCount4 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000297 int AnalyzedFunctionCount4 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000298 {
299 FunctionPassManager FPM;
300 FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
301 AnalyzedFunctionCount4));
302 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
303 }
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000304
Chandler Carruthde9afd82013-11-23 00:38:42 +0000305 // A fifth function pass manager but which uses only cached results.
Chandler Carruthde9afd82013-11-23 00:38:42 +0000306 int FunctionPassRunCount5 = 0;
307 int AnalyzedInstrCount5 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000308 int AnalyzedFunctionCount5 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000309 {
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 }
Chandler Carruthde9afd82013-11-23 00:38:42 +0000317
Chandler Carruthd174ce42015-01-05 02:47:05 +0000318 MPM.run(*M, &MAM);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000319
320 // Validate module pass counters.
Chandler Carruth90a835d2013-11-09 13:09:08 +0000321 EXPECT_EQ(1, ModulePassRunCount);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000322
Chandler Carruthbceeb222013-11-22 23:38:07 +0000323 // Validate all function pass counter sets are the same.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000324 EXPECT_EQ(3, FunctionPassRunCount1);
325 EXPECT_EQ(5, AnalyzedInstrCount1);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000326 EXPECT_EQ(0, AnalyzedFunctionCount1);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000327 EXPECT_EQ(3, FunctionPassRunCount2);
328 EXPECT_EQ(5, AnalyzedInstrCount2);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000329 EXPECT_EQ(0, AnalyzedFunctionCount2);
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000330 EXPECT_EQ(3, FunctionPassRunCount3);
331 EXPECT_EQ(5, AnalyzedInstrCount3);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000332 EXPECT_EQ(0, AnalyzedFunctionCount3);
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000333 EXPECT_EQ(3, FunctionPassRunCount4);
334 EXPECT_EQ(5, AnalyzedInstrCount4);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000335 EXPECT_EQ(0, AnalyzedFunctionCount4);
Chandler Carruthde9afd82013-11-23 00:38:42 +0000336 EXPECT_EQ(3, FunctionPassRunCount5);
337 EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000338 EXPECT_EQ(0, AnalyzedFunctionCount5);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000339
Chandler Carruthbceeb222013-11-22 23:38:07 +0000340 // 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
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000345 EXPECT_EQ(7, FunctionAnalysisRuns);
346
347 EXPECT_EQ(1, ModuleAnalysisRuns);
Chandler Carruth90a835d2013-11-09 13:09:08 +0000348}
Chandler Carruth90a835d2013-11-09 13:09:08 +0000349}