PassManagerTest.cpp 11 KB

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