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 : public AnalysisBase<TestFunctionAnalysis> { 23 public: 24 struct Result { 25 Result(int Count) : InstructionCount(Count) {} 26 int InstructionCount; 27 }; 28 29 TestFunctionAnalysis(int &Runs) : Runs(Runs) {} 30 31 /// \brief Run the analysis pass over the function and return a result. 32 Result run(Function &F, FunctionAnalysisManager *AM) { 33 ++Runs; 34 int Count = 0; 35 for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) 36 for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE; 37 ++II) 38 ++Count; 39 return Result(Count); 40 } 41 42 private: 43 int &Runs; 44 }; 45 46 class TestModuleAnalysis : public AnalysisBase<TestModuleAnalysis> { 47 public: 48 struct Result { 49 Result(int Count) : FunctionCount(Count) {} 50 int FunctionCount; 51 }; 52 53 TestModuleAnalysis(int &Runs) : Runs(Runs) {} 54 55 Result run(Module &M, ModuleAnalysisManager *AM) { 56 ++Runs; 57 int Count = 0; 58 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 59 ++Count; 60 return Result(Count); 61 } 62 63 private: 64 int &Runs; 65 }; 66 67 struct TestModulePass : PassBase<TestModulePass> { 68 TestModulePass(int &RunCount) : RunCount(RunCount) {} 69 70 PreservedAnalyses run(Module &M) { 71 ++RunCount; 72 return PreservedAnalyses::none(); 73 } 74 75 int &RunCount; 76 }; 77 78 struct TestPreservingModulePass : PassBase<TestPreservingModulePass> { 79 PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); } 80 }; 81 82 struct TestMinPreservingModulePass : PassBase<TestMinPreservingModulePass> { 83 PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM) { 84 PreservedAnalyses PA; 85 86 // Force running an analysis. 87 (void)AM->getResult<TestModuleAnalysis>(M); 88 89 PA.preserve<FunctionAnalysisManagerModuleProxy>(); 90 return PA; 91 } 92 }; 93 94 struct TestFunctionPass : PassBase<TestFunctionPass> { 95 TestFunctionPass(int &RunCount, int &AnalyzedInstrCount, 96 int &AnalyzedFunctionCount, 97 bool OnlyUseCachedResults = false) 98 : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount), 99 AnalyzedFunctionCount(AnalyzedFunctionCount), 100 OnlyUseCachedResults(OnlyUseCachedResults) {} 101 102 PreservedAnalyses run(Function &F, FunctionAnalysisManager *AM) { 103 ++RunCount; 104 105 const ModuleAnalysisManager &MAM = 106 AM->getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager(); 107 if (TestModuleAnalysis::Result *TMA = 108 MAM.getCachedResult<TestModuleAnalysis>(*F.getParent())) 109 AnalyzedFunctionCount += TMA->FunctionCount; 110 111 if (OnlyUseCachedResults) { 112 // Hack to force the use of the cached interface. 113 if (TestFunctionAnalysis::Result *AR = 114 AM->getCachedResult<TestFunctionAnalysis>(F)) 115 AnalyzedInstrCount += AR->InstructionCount; 116 } else { 117 // Typical path just runs the analysis as needed. 118 TestFunctionAnalysis::Result &AR = AM->getResult<TestFunctionAnalysis>(F); 119 AnalyzedInstrCount += AR.InstructionCount; 120 } 121 122 return PreservedAnalyses::all(); 123 } 124 125 int &RunCount; 126 int &AnalyzedInstrCount; 127 int &AnalyzedFunctionCount; 128 bool OnlyUseCachedResults; 129 }; 130 131 // A test function pass that invalidates all function analyses for a function 132 // with a specific name. 133 struct TestInvalidationFunctionPass : PassBase<TestInvalidationFunctionPass> { 134 TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {} 135 136 PreservedAnalyses run(Function &F) { 137 return F.getName() == Name ? PreservedAnalyses::none() 138 : PreservedAnalyses::all(); 139 } 140 141 StringRef Name; 142 }; 143 144 std::unique_ptr<Module> parseIR(const char *IR) { 145 LLVMContext &C = getGlobalContext(); 146 SMDiagnostic Err; 147 return parseAssemblyString(IR, Err, C); 148 } 149 150 class PassManagerTest : public ::testing::Test { 151 protected: 152 std::unique_ptr<Module> M; 153 154 public: 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 170 TEST_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 203 TEST_F(PassManagerTest, Basic) { 204 FunctionAnalysisManager FAM; 205 int FunctionAnalysisRuns = 0; 206 FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); }); 207 208 ModuleAnalysisManager MAM; 209 int ModuleAnalysisRuns = 0; 210 MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); }); 211 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); 212 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); }); 213 214 ModulePassManager MPM; 215 216 // Count the runs over a Function. 217 int FunctionPassRunCount1 = 0; 218 int AnalyzedInstrCount1 = 0; 219 int AnalyzedFunctionCount1 = 0; 220 { 221 // Pointless scoped copy to test move assignment. 222 ModulePassManager NestedMPM; 223 FunctionPassManager FPM; 224 { 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); 233 } 234 235 // Count the runs over a module. 236 int ModulePassRunCount = 0; 237 MPM.addPass(TestModulePass(ModulePassRunCount)); 238 239 // Count the runs over a Function in a separate manager. 240 int FunctionPassRunCount2 = 0; 241 int AnalyzedInstrCount2 = 0; 242 int AnalyzedFunctionCount2 = 0; 243 { 244 FunctionPassManager FPM; 245 FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2, 246 AnalyzedFunctionCount2)); 247 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); 248 } 249 250 // A third function pass manager but with only preserving intervening passes 251 // and with a function pass that invalidates exactly one analysis. 252 MPM.addPass(TestPreservingModulePass()); 253 int FunctionPassRunCount3 = 0; 254 int AnalyzedInstrCount3 = 0; 255 int AnalyzedFunctionCount3 = 0; 256 { 257 FunctionPassManager FPM; 258 FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3, 259 AnalyzedFunctionCount3)); 260 FPM.addPass(TestInvalidationFunctionPass("f")); 261 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); 262 } 263 264 // A fourth function pass manager but with a minimal intervening passes. 265 MPM.addPass(TestMinPreservingModulePass()); 266 int FunctionPassRunCount4 = 0; 267 int AnalyzedInstrCount4 = 0; 268 int AnalyzedFunctionCount4 = 0; 269 { 270 FunctionPassManager FPM; 271 FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4, 272 AnalyzedFunctionCount4)); 273 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); 274 } 275 276 // A fifth function pass manager but which uses only cached results. 277 int FunctionPassRunCount5 = 0; 278 int AnalyzedInstrCount5 = 0; 279 int AnalyzedFunctionCount5 = 0; 280 { 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 } 288 289 MPM.run(*M, &MAM); 290 291 // Validate module pass counters. 292 EXPECT_EQ(1, ModulePassRunCount); 293 294 // Validate all function pass counter sets are the same. 295 EXPECT_EQ(3, FunctionPassRunCount1); 296 EXPECT_EQ(5, AnalyzedInstrCount1); 297 EXPECT_EQ(0, AnalyzedFunctionCount1); 298 EXPECT_EQ(3, FunctionPassRunCount2); 299 EXPECT_EQ(5, AnalyzedInstrCount2); 300 EXPECT_EQ(0, AnalyzedFunctionCount2); 301 EXPECT_EQ(3, FunctionPassRunCount3); 302 EXPECT_EQ(5, AnalyzedInstrCount3); 303 EXPECT_EQ(0, AnalyzedFunctionCount3); 304 EXPECT_EQ(3, FunctionPassRunCount4); 305 EXPECT_EQ(5, AnalyzedInstrCount4); 306 EXPECT_EQ(0, AnalyzedFunctionCount4); 307 EXPECT_EQ(3, FunctionPassRunCount5); 308 EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached. 309 EXPECT_EQ(0, AnalyzedFunctionCount5); 310 311 // 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 316 EXPECT_EQ(7, FunctionAnalysisRuns); 317 318 EXPECT_EQ(1, ModuleAnalysisRuns); 319 } 320 } 321