blob: 857b5283c41b54d0148243bfd271ad886d0cbe5e [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 Carruth3a634352016-02-26 11:44:45 +000022class TestFunctionAnalysis : public AnalysisBase<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 Carruthd174ce42015-01-05 02:47:05 +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 Carruth851a2aa2013-11-21 02:11:31 +000043 int &Runs;
Chandler Carruth74015a72013-11-13 01:12:08 +000044};
45
Chandler Carruth3a634352016-02-26 11:44:45 +000046class TestModuleAnalysis : public AnalysisBase<TestModuleAnalysis> {
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000047public:
48 struct Result {
49 Result(int Count) : FunctionCount(Count) {}
50 int FunctionCount;
51 };
52
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000053 TestModuleAnalysis(int &Runs) : Runs(Runs) {}
54
Chandler Carruthd174ce42015-01-05 02:47:05 +000055 Result run(Module &M, ModuleAnalysisManager *AM) {
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000056 ++Runs;
57 int Count = 0;
Chandler Carruthd174ce42015-01-05 02:47:05 +000058 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000059 ++Count;
60 return Result(Count);
61 }
62
63private:
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000064 int &Runs;
65};
66
Chandler Carruth3a634352016-02-26 11:44:45 +000067struct TestModulePass : PassBase<TestModulePass> {
Chandler Carruth90a835d2013-11-09 13:09:08 +000068 TestModulePass(int &RunCount) : RunCount(RunCount) {}
69
Chandler Carruthd174ce42015-01-05 02:47:05 +000070 PreservedAnalyses run(Module &M) {
Chandler Carruth90a835d2013-11-09 13:09:08 +000071 ++RunCount;
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000072 return PreservedAnalyses::none();
Chandler Carruth90a835d2013-11-09 13:09:08 +000073 }
74
75 int &RunCount;
76};
77
Chandler Carruth3a634352016-02-26 11:44:45 +000078struct TestPreservingModulePass : PassBase<TestPreservingModulePass> {
Chandler Carruthd174ce42015-01-05 02:47:05 +000079 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
Chandler Carruth2846e9e2013-11-21 10:53:05 +000080};
81
Chandler Carruth3a634352016-02-26 11:44:45 +000082struct TestMinPreservingModulePass : PassBase<TestMinPreservingModulePass> {
Chandler Carruthd174ce42015-01-05 02:47:05 +000083 PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM) {
Chandler Carruth2846e9e2013-11-21 10:53:05 +000084 PreservedAnalyses PA;
Chandler Carruthde9afd82013-11-23 00:38:42 +000085
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +000086 // Force running an analysis.
87 (void)AM->getResult<TestModuleAnalysis>(M);
Chandler Carruthde9afd82013-11-23 00:38:42 +000088
Chandler Carruthb3e72192013-11-22 00:43:29 +000089 PA.preserve<FunctionAnalysisManagerModuleProxy>();
Chandler Carruth2846e9e2013-11-21 10:53:05 +000090 return PA;
91 }
92};
93
Chandler Carruth3a634352016-02-26 11:44:45 +000094struct TestFunctionPass : PassBase<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 Carruthd174ce42015-01-05 02:47:05 +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 =
106 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 Carruth2ad18582013-11-23 01:25:02 +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 Carrutheedf9fc2014-02-05 21:41:42 +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 Carruth3a634352016-02-26 11:44:45 +0000133struct TestInvalidationFunctionPass : PassBase<TestInvalidationFunctionPass> {
Chandler Carruthbceeb222013-11-22 23:38:07 +0000134 TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
135
Chandler Carruthd174ce42015-01-05 02:47:05 +0000136 PreservedAnalyses run(Function &F) {
137 return F.getName() == Name ? PreservedAnalyses::none()
138 : PreservedAnalyses::all();
Chandler Carruthbceeb222013-11-22 23:38:07 +0000139 }
140
141 StringRef Name;
142};
143
Chandler Carruthd174ce42015-01-05 02:47:05 +0000144std::unique_ptr<Module> parseIR(const char *IR) {
Chandler Carruth90a835d2013-11-09 13:09:08 +0000145 LLVMContext &C = getGlobalContext();
146 SMDiagnostic Err;
Chandler Carruthd174ce42015-01-05 02:47:05 +0000147 return parseAssemblyString(IR, Err, C);
Chandler Carruth90a835d2013-11-09 13:09:08 +0000148}
149
150class PassManagerTest : public ::testing::Test {
151protected:
Ahmed Charles56440fd2014-03-06 05:51:42 +0000152 std::unique_ptr<Module> M;
Chandler Carruth90a835d2013-11-09 13:09:08 +0000153
154public:
155 PassManagerTest()
156 : M(parseIR("define void @f() {\n"
157 "entry:\n"
158 " call void @g()\n"
159 " call void @h()\n"
160 " ret void\n"
161 "}\n"
162 "define void @g() {\n"
163 " ret void\n"
164 "}\n"
165 "define void @h() {\n"
166 " ret void\n"
167 "}\n")) {}
168};
169
Chandler Carruth999b92d2014-03-13 10:42:18 +0000170TEST_F(PassManagerTest, BasicPreservedAnalyses) {
171 PreservedAnalyses PA1 = PreservedAnalyses();
172 EXPECT_FALSE(PA1.preserved<TestFunctionAnalysis>());
173 EXPECT_FALSE(PA1.preserved<TestModuleAnalysis>());
174 PreservedAnalyses PA2 = PreservedAnalyses::none();
175 EXPECT_FALSE(PA2.preserved<TestFunctionAnalysis>());
176 EXPECT_FALSE(PA2.preserved<TestModuleAnalysis>());
177 PreservedAnalyses PA3 = PreservedAnalyses::all();
178 EXPECT_TRUE(PA3.preserved<TestFunctionAnalysis>());
179 EXPECT_TRUE(PA3.preserved<TestModuleAnalysis>());
180 PreservedAnalyses PA4 = PA1;
181 EXPECT_FALSE(PA4.preserved<TestFunctionAnalysis>());
182 EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
183 PA4 = PA3;
184 EXPECT_TRUE(PA4.preserved<TestFunctionAnalysis>());
185 EXPECT_TRUE(PA4.preserved<TestModuleAnalysis>());
186 PA4 = std::move(PA2);
187 EXPECT_FALSE(PA4.preserved<TestFunctionAnalysis>());
188 EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
189 PA4.preserve<TestFunctionAnalysis>();
190 EXPECT_TRUE(PA4.preserved<TestFunctionAnalysis>());
191 EXPECT_FALSE(PA4.preserved<TestModuleAnalysis>());
192 PA1.preserve<TestModuleAnalysis>();
193 EXPECT_FALSE(PA1.preserved<TestFunctionAnalysis>());
194 EXPECT_TRUE(PA1.preserved<TestModuleAnalysis>());
195 PA1.preserve<TestFunctionAnalysis>();
196 EXPECT_TRUE(PA1.preserved<TestFunctionAnalysis>());
197 EXPECT_TRUE(PA1.preserved<TestModuleAnalysis>());
198 PA1.intersect(PA4);
199 EXPECT_TRUE(PA1.preserved<TestFunctionAnalysis>());
200 EXPECT_FALSE(PA1.preserved<TestModuleAnalysis>());
201}
202
Chandler Carruth90a835d2013-11-09 13:09:08 +0000203TEST_F(PassManagerTest, Basic) {
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000204 FunctionAnalysisManager FAM;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000205 int FunctionAnalysisRuns = 0;
Chandler Carruthedf59962016-02-18 09:45:17 +0000206 FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
Chandler Carruth74015a72013-11-13 01:12:08 +0000207
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000208 ModuleAnalysisManager MAM;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000209 int ModuleAnalysisRuns = 0;
Chandler Carruthedf59962016-02-18 09:45:17 +0000210 MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
211 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
212 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000213
Chandler Carruthb3e72192013-11-22 00:43:29 +0000214 ModulePassManager MPM;
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000215
216 // Count the runs over a Function.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000217 int FunctionPassRunCount1 = 0;
218 int AnalyzedInstrCount1 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000219 int AnalyzedFunctionCount1 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000220 {
Chandler Carruth999b92d2014-03-13 10:42:18 +0000221 // Pointless scoped copy to test move assignment.
222 ModulePassManager NestedMPM;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000223 FunctionPassManager FPM;
Chandler Carruth999b92d2014-03-13 10:42:18 +0000224 {
225 // Pointless scope to test move assignment.
226 FunctionPassManager NestedFPM;
227 NestedFPM.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1,
228 AnalyzedFunctionCount1));
229 FPM = std::move(NestedFPM);
230 }
231 NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
232 MPM = std::move(NestedMPM);
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000233 }
Chandler Carruth90a835d2013-11-09 13:09:08 +0000234
235 // Count the runs over a module.
236 int ModulePassRunCount = 0;
237 MPM.addPass(TestModulePass(ModulePassRunCount));
238
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000239 // Count the runs over a Function in a separate manager.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000240 int FunctionPassRunCount2 = 0;
241 int AnalyzedInstrCount2 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000242 int AnalyzedFunctionCount2 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000243 {
244 FunctionPassManager FPM;
245 FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
246 AnalyzedFunctionCount2));
247 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
248 }
Chandler Carruth90a835d2013-11-09 13:09:08 +0000249
Chandler Carruthbceeb222013-11-22 23:38:07 +0000250 // A third function pass manager but with only preserving intervening passes
251 // and with a function pass that invalidates exactly one analysis.
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000252 MPM.addPass(TestPreservingModulePass());
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000253 int FunctionPassRunCount3 = 0;
254 int AnalyzedInstrCount3 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000255 int AnalyzedFunctionCount3 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000256 {
257 FunctionPassManager FPM;
258 FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
259 AnalyzedFunctionCount3));
260 FPM.addPass(TestInvalidationFunctionPass("f"));
261 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
262 }
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000263
264 // A fourth function pass manager but with a minimal intervening passes.
265 MPM.addPass(TestMinPreservingModulePass());
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000266 int FunctionPassRunCount4 = 0;
267 int AnalyzedInstrCount4 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000268 int AnalyzedFunctionCount4 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000269 {
270 FunctionPassManager FPM;
271 FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
272 AnalyzedFunctionCount4));
273 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
274 }
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000275
Chandler Carruthde9afd82013-11-23 00:38:42 +0000276 // A fifth function pass manager but which uses only cached results.
Chandler Carruthde9afd82013-11-23 00:38:42 +0000277 int FunctionPassRunCount5 = 0;
278 int AnalyzedInstrCount5 = 0;
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000279 int AnalyzedFunctionCount5 = 0;
Chandler Carruthc3f3da32014-03-09 11:49:53 +0000280 {
281 FunctionPassManager FPM;
282 FPM.addPass(TestInvalidationFunctionPass("f"));
283 FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
284 AnalyzedFunctionCount5,
285 /*OnlyUseCachedResults=*/true));
286 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
287 }
Chandler Carruthde9afd82013-11-23 00:38:42 +0000288
Chandler Carruthd174ce42015-01-05 02:47:05 +0000289 MPM.run(*M, &MAM);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000290
291 // Validate module pass counters.
Chandler Carruth90a835d2013-11-09 13:09:08 +0000292 EXPECT_EQ(1, ModulePassRunCount);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000293
Chandler Carruthbceeb222013-11-22 23:38:07 +0000294 // Validate all function pass counter sets are the same.
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000295 EXPECT_EQ(3, FunctionPassRunCount1);
296 EXPECT_EQ(5, AnalyzedInstrCount1);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000297 EXPECT_EQ(0, AnalyzedFunctionCount1);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000298 EXPECT_EQ(3, FunctionPassRunCount2);
299 EXPECT_EQ(5, AnalyzedInstrCount2);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000300 EXPECT_EQ(0, AnalyzedFunctionCount2);
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000301 EXPECT_EQ(3, FunctionPassRunCount3);
302 EXPECT_EQ(5, AnalyzedInstrCount3);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000303 EXPECT_EQ(0, AnalyzedFunctionCount3);
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000304 EXPECT_EQ(3, FunctionPassRunCount4);
305 EXPECT_EQ(5, AnalyzedInstrCount4);
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000306 EXPECT_EQ(0, AnalyzedFunctionCount4);
Chandler Carruthde9afd82013-11-23 00:38:42 +0000307 EXPECT_EQ(3, FunctionPassRunCount5);
308 EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000309 EXPECT_EQ(0, AnalyzedFunctionCount5);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000310
Chandler Carruthbceeb222013-11-22 23:38:07 +0000311 // Validate the analysis counters:
312 // first run over 3 functions, then module pass invalidates
313 // second run over 3 functions, nothing invalidates
314 // third run over 0 functions, but 1 function invalidated
315 // fourth run over 1 function
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000316 EXPECT_EQ(7, FunctionAnalysisRuns);
317
318 EXPECT_EQ(1, ModuleAnalysisRuns);
Chandler Carruth90a835d2013-11-09 13:09:08 +0000319}
Chandler Carruth90a835d2013-11-09 13:09:08 +0000320}