LegacyPassManagerTest.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. //===- llvm/unittest/IR/LegacyPassManager.cpp - Legacy 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. // This unit test exercises the legacy pass manager infrastructure. We use the
  11. // old names as well to ensure that the source-level compatibility wrapper
  12. // works for out-of-tree code that expects to include llvm/PassManager.h and
  13. // subclass the core pass classes.
  14. //
  15. //===----------------------------------------------------------------------===//
  16. #include "llvm/PassManager.h"
  17. #include "llvm/ADT/SmallVector.h"
  18. #include "llvm/Analysis/CallGraphSCCPass.h"
  19. #include "llvm/Analysis/LoopInfo.h"
  20. #include "llvm/Analysis/LoopPass.h"
  21. #include "llvm/IR/BasicBlock.h"
  22. #include "llvm/IR/CallingConv.h"
  23. #include "llvm/IR/Constants.h"
  24. #include "llvm/IR/DataLayout.h"
  25. #include "llvm/IR/DerivedTypes.h"
  26. #include "llvm/IR/Function.h"
  27. #include "llvm/IR/GlobalVariable.h"
  28. #include "llvm/IR/IRPrintingPasses.h"
  29. #include "llvm/IR/InlineAsm.h"
  30. #include "llvm/IR/Instructions.h"
  31. #include "llvm/IR/LLVMContext.h"
  32. #include "llvm/IR/Module.h"
  33. #include "llvm/IR/Verifier.h"
  34. #include "llvm/Pass.h"
  35. #include "llvm/Support/MathExtras.h"
  36. #include "llvm/Support/raw_ostream.h"
  37. #include "gtest/gtest.h"
  38. using namespace llvm;
  39. namespace llvm {
  40. void initializeModuleNDMPass(PassRegistry&);
  41. void initializeFPassPass(PassRegistry&);
  42. void initializeCGPassPass(PassRegistry&);
  43. void initializeLPassPass(PassRegistry&);
  44. void initializeBPassPass(PassRegistry&);
  45. namespace {
  46. // ND = no deps
  47. // NM = no modifications
  48. struct ModuleNDNM: public ModulePass {
  49. public:
  50. static char run;
  51. static char ID;
  52. ModuleNDNM() : ModulePass(ID) { }
  53. bool runOnModule(Module &M) override {
  54. run++;
  55. return false;
  56. }
  57. void getAnalysisUsage(AnalysisUsage &AU) const override {
  58. AU.setPreservesAll();
  59. }
  60. };
  61. char ModuleNDNM::ID=0;
  62. char ModuleNDNM::run=0;
  63. struct ModuleNDM : public ModulePass {
  64. public:
  65. static char run;
  66. static char ID;
  67. ModuleNDM() : ModulePass(ID) {}
  68. bool runOnModule(Module &M) override {
  69. run++;
  70. return true;
  71. }
  72. };
  73. char ModuleNDM::ID=0;
  74. char ModuleNDM::run=0;
  75. struct ModuleNDM2 : public ModulePass {
  76. public:
  77. static char run;
  78. static char ID;
  79. ModuleNDM2() : ModulePass(ID) {}
  80. bool runOnModule(Module &M) override {
  81. run++;
  82. return true;
  83. }
  84. };
  85. char ModuleNDM2::ID=0;
  86. char ModuleNDM2::run=0;
  87. struct ModuleDNM : public ModulePass {
  88. public:
  89. static char run;
  90. static char ID;
  91. ModuleDNM() : ModulePass(ID) {
  92. initializeModuleNDMPass(*PassRegistry::getPassRegistry());
  93. }
  94. bool runOnModule(Module &M) override {
  95. EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
  96. run++;
  97. return false;
  98. }
  99. void getAnalysisUsage(AnalysisUsage &AU) const override {
  100. AU.addRequired<ModuleNDM>();
  101. AU.setPreservesAll();
  102. }
  103. };
  104. char ModuleDNM::ID=0;
  105. char ModuleDNM::run=0;
  106. template<typename P>
  107. struct PassTestBase : public P {
  108. protected:
  109. static int runc;
  110. static bool initialized;
  111. static bool finalized;
  112. int allocated;
  113. void run() {
  114. EXPECT_TRUE(initialized);
  115. EXPECT_FALSE(finalized);
  116. EXPECT_EQ(0, allocated);
  117. allocated++;
  118. runc++;
  119. }
  120. public:
  121. static char ID;
  122. static void finishedOK(int run) {
  123. EXPECT_GT(runc, 0);
  124. EXPECT_TRUE(initialized);
  125. EXPECT_TRUE(finalized);
  126. EXPECT_EQ(run, runc);
  127. }
  128. PassTestBase() : P(ID), allocated(0) {
  129. initialized = false;
  130. finalized = false;
  131. runc = 0;
  132. }
  133. void releaseMemory() override {
  134. EXPECT_GT(runc, 0);
  135. EXPECT_GT(allocated, 0);
  136. allocated--;
  137. }
  138. };
  139. template<typename P> char PassTestBase<P>::ID;
  140. template<typename P> int PassTestBase<P>::runc;
  141. template<typename P> bool PassTestBase<P>::initialized;
  142. template<typename P> bool PassTestBase<P>::finalized;
  143. template<typename T, typename P>
  144. struct PassTest : public PassTestBase<P> {
  145. public:
  146. #ifndef _MSC_VER // MSVC complains that Pass is not base class.
  147. using llvm::Pass::doInitialization;
  148. using llvm::Pass::doFinalization;
  149. #endif
  150. bool doInitialization(T &t) override {
  151. EXPECT_FALSE(PassTestBase<P>::initialized);
  152. PassTestBase<P>::initialized = true;
  153. return false;
  154. }
  155. bool doFinalization(T &t) override {
  156. EXPECT_FALSE(PassTestBase<P>::finalized);
  157. PassTestBase<P>::finalized = true;
  158. EXPECT_EQ(0, PassTestBase<P>::allocated);
  159. return false;
  160. }
  161. };
  162. struct CGPass : public PassTest<CallGraph, CallGraphSCCPass> {
  163. public:
  164. CGPass() {
  165. initializeCGPassPass(*PassRegistry::getPassRegistry());
  166. }
  167. bool runOnSCC(CallGraphSCC &SCMM) override {
  168. EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
  169. run();
  170. return false;
  171. }
  172. };
  173. struct FPass : public PassTest<Module, FunctionPass> {
  174. public:
  175. bool runOnFunction(Function &F) override {
  176. // FIXME: PR4112
  177. // EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
  178. run();
  179. return false;
  180. }
  181. };
  182. struct LPass : public PassTestBase<LoopPass> {
  183. private:
  184. static int initcount;
  185. static int fincount;
  186. public:
  187. LPass() {
  188. initializeLPassPass(*PassRegistry::getPassRegistry());
  189. initcount = 0; fincount=0;
  190. EXPECT_FALSE(initialized);
  191. }
  192. static void finishedOK(int run, int finalized) {
  193. PassTestBase<LoopPass>::finishedOK(run);
  194. EXPECT_EQ(run, initcount);
  195. EXPECT_EQ(finalized, fincount);
  196. }
  197. using llvm::Pass::doInitialization;
  198. using llvm::Pass::doFinalization;
  199. bool doInitialization(Loop* L, LPPassManager &LPM) override {
  200. initialized = true;
  201. initcount++;
  202. return false;
  203. }
  204. bool runOnLoop(Loop *L, LPPassManager &LPM) override {
  205. EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
  206. run();
  207. return false;
  208. }
  209. bool doFinalization() override {
  210. fincount++;
  211. finalized = true;
  212. return false;
  213. }
  214. };
  215. int LPass::initcount=0;
  216. int LPass::fincount=0;
  217. struct BPass : public PassTestBase<BasicBlockPass> {
  218. private:
  219. static int inited;
  220. static int fin;
  221. public:
  222. static void finishedOK(int run, int N) {
  223. PassTestBase<BasicBlockPass>::finishedOK(run);
  224. EXPECT_EQ(inited, N);
  225. EXPECT_EQ(fin, N);
  226. }
  227. BPass() {
  228. inited = 0;
  229. fin = 0;
  230. }
  231. bool doInitialization(Module &M) override {
  232. EXPECT_FALSE(initialized);
  233. initialized = true;
  234. return false;
  235. }
  236. bool doInitialization(Function &F) override {
  237. inited++;
  238. return false;
  239. }
  240. bool runOnBasicBlock(BasicBlock &BB) override {
  241. EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
  242. run();
  243. return false;
  244. }
  245. bool doFinalization(Function &F) override {
  246. fin++;
  247. return false;
  248. }
  249. bool doFinalization(Module &M) override {
  250. EXPECT_FALSE(finalized);
  251. finalized = true;
  252. EXPECT_EQ(0, allocated);
  253. return false;
  254. }
  255. };
  256. int BPass::inited=0;
  257. int BPass::fin=0;
  258. struct OnTheFlyTest: public ModulePass {
  259. public:
  260. static char ID;
  261. OnTheFlyTest() : ModulePass(ID) {
  262. initializeFPassPass(*PassRegistry::getPassRegistry());
  263. }
  264. bool runOnModule(Module &M) override {
  265. EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
  266. for (Module::iterator I=M.begin(),E=M.end(); I != E; ++I) {
  267. Function &F = *I;
  268. {
  269. SCOPED_TRACE("Running on the fly function pass");
  270. getAnalysis<FPass>(F);
  271. }
  272. }
  273. return false;
  274. }
  275. void getAnalysisUsage(AnalysisUsage &AU) const override {
  276. AU.addRequired<FPass>();
  277. }
  278. };
  279. char OnTheFlyTest::ID=0;
  280. TEST(PassManager, RunOnce) {
  281. Module M("test-once", getGlobalContext());
  282. struct ModuleNDNM *mNDNM = new ModuleNDNM();
  283. struct ModuleDNM *mDNM = new ModuleDNM();
  284. struct ModuleNDM *mNDM = new ModuleNDM();
  285. struct ModuleNDM2 *mNDM2 = new ModuleNDM2();
  286. mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
  287. PassManager Passes;
  288. Passes.add(new DataLayoutPass());
  289. Passes.add(mNDM2);
  290. Passes.add(mNDM);
  291. Passes.add(mNDNM);
  292. Passes.add(mDNM);
  293. Passes.run(M);
  294. // each pass must be run exactly once, since nothing invalidates them
  295. EXPECT_EQ(1, mNDM->run);
  296. EXPECT_EQ(1, mNDNM->run);
  297. EXPECT_EQ(1, mDNM->run);
  298. EXPECT_EQ(1, mNDM2->run);
  299. }
  300. TEST(PassManager, ReRun) {
  301. Module M("test-rerun", getGlobalContext());
  302. struct ModuleNDNM *mNDNM = new ModuleNDNM();
  303. struct ModuleDNM *mDNM = new ModuleDNM();
  304. struct ModuleNDM *mNDM = new ModuleNDM();
  305. struct ModuleNDM2 *mNDM2 = new ModuleNDM2();
  306. mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
  307. PassManager Passes;
  308. Passes.add(new DataLayoutPass());
  309. Passes.add(mNDM);
  310. Passes.add(mNDNM);
  311. Passes.add(mNDM2);// invalidates mNDM needed by mDNM
  312. Passes.add(mDNM);
  313. Passes.run(M);
  314. // Some passes must be rerun because a pass that modified the
  315. // module/function was run in between
  316. EXPECT_EQ(2, mNDM->run);
  317. EXPECT_EQ(1, mNDNM->run);
  318. EXPECT_EQ(1, mNDM2->run);
  319. EXPECT_EQ(1, mDNM->run);
  320. }
  321. Module* makeLLVMModule();
  322. template<typename T>
  323. void MemoryTestHelper(int run) {
  324. std::unique_ptr<Module> M(makeLLVMModule());
  325. T *P = new T();
  326. PassManager Passes;
  327. Passes.add(new DataLayoutPass());
  328. Passes.add(P);
  329. Passes.run(*M);
  330. T::finishedOK(run);
  331. }
  332. template<typename T>
  333. void MemoryTestHelper(int run, int N) {
  334. Module *M = makeLLVMModule();
  335. T *P = new T();
  336. PassManager Passes;
  337. Passes.add(new DataLayoutPass());
  338. Passes.add(P);
  339. Passes.run(*M);
  340. T::finishedOK(run, N);
  341. delete M;
  342. }
  343. TEST(PassManager, Memory) {
  344. // SCC#1: test1->test2->test3->test1
  345. // SCC#2: test4
  346. // SCC#3: indirect call node
  347. {
  348. SCOPED_TRACE("Callgraph pass");
  349. MemoryTestHelper<CGPass>(3);
  350. }
  351. {
  352. SCOPED_TRACE("Function pass");
  353. MemoryTestHelper<FPass>(4);// 4 functions
  354. }
  355. {
  356. SCOPED_TRACE("Loop pass");
  357. MemoryTestHelper<LPass>(2, 1); //2 loops, 1 function
  358. }
  359. {
  360. SCOPED_TRACE("Basic block pass");
  361. MemoryTestHelper<BPass>(7, 4); //9 basic blocks
  362. }
  363. }
  364. TEST(PassManager, MemoryOnTheFly) {
  365. Module *M = makeLLVMModule();
  366. {
  367. SCOPED_TRACE("Running OnTheFlyTest");
  368. struct OnTheFlyTest *O = new OnTheFlyTest();
  369. PassManager Passes;
  370. Passes.add(new DataLayoutPass());
  371. Passes.add(O);
  372. Passes.run(*M);
  373. FPass::finishedOK(4);
  374. }
  375. delete M;
  376. }
  377. Module* makeLLVMModule() {
  378. // Module Construction
  379. Module* mod = new Module("test-mem", getGlobalContext());
  380. mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
  381. "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
  382. "a:0:64-s:64:64-f80:128:128");
  383. mod->setTargetTriple("x86_64-unknown-linux-gnu");
  384. // Type Definitions
  385. std::vector<Type*>FuncTy_0_args;
  386. FunctionType* FuncTy_0 = FunctionType::get(
  387. /*Result=*/IntegerType::get(getGlobalContext(), 32),
  388. /*Params=*/FuncTy_0_args,
  389. /*isVarArg=*/false);
  390. std::vector<Type*>FuncTy_2_args;
  391. FuncTy_2_args.push_back(IntegerType::get(getGlobalContext(), 1));
  392. FunctionType* FuncTy_2 = FunctionType::get(
  393. /*Result=*/Type::getVoidTy(getGlobalContext()),
  394. /*Params=*/FuncTy_2_args,
  395. /*isVarArg=*/false);
  396. // Function Declarations
  397. Function* func_test1 = Function::Create(
  398. /*Type=*/FuncTy_0,
  399. /*Linkage=*/GlobalValue::ExternalLinkage,
  400. /*Name=*/"test1", mod);
  401. func_test1->setCallingConv(CallingConv::C);
  402. AttributeSet func_test1_PAL;
  403. func_test1->setAttributes(func_test1_PAL);
  404. Function* func_test2 = Function::Create(
  405. /*Type=*/FuncTy_0,
  406. /*Linkage=*/GlobalValue::ExternalLinkage,
  407. /*Name=*/"test2", mod);
  408. func_test2->setCallingConv(CallingConv::C);
  409. AttributeSet func_test2_PAL;
  410. func_test2->setAttributes(func_test2_PAL);
  411. Function* func_test3 = Function::Create(
  412. /*Type=*/FuncTy_0,
  413. /*Linkage=*/GlobalValue::ExternalLinkage,
  414. /*Name=*/"test3", mod);
  415. func_test3->setCallingConv(CallingConv::C);
  416. AttributeSet func_test3_PAL;
  417. func_test3->setAttributes(func_test3_PAL);
  418. Function* func_test4 = Function::Create(
  419. /*Type=*/FuncTy_2,
  420. /*Linkage=*/GlobalValue::ExternalLinkage,
  421. /*Name=*/"test4", mod);
  422. func_test4->setCallingConv(CallingConv::C);
  423. AttributeSet func_test4_PAL;
  424. func_test4->setAttributes(func_test4_PAL);
  425. // Global Variable Declarations
  426. // Constant Definitions
  427. // Global Variable Definitions
  428. // Function Definitions
  429. // Function: test1 (func_test1)
  430. {
  431. BasicBlock* label_entry = BasicBlock::Create(getGlobalContext(), "entry",func_test1,nullptr);
  432. // Block entry (label_entry)
  433. CallInst* int32_3 = CallInst::Create(func_test2, "", label_entry);
  434. int32_3->setCallingConv(CallingConv::C);
  435. int32_3->setTailCall(false);AttributeSet int32_3_PAL;
  436. int32_3->setAttributes(int32_3_PAL);
  437. ReturnInst::Create(getGlobalContext(), int32_3, label_entry);
  438. }
  439. // Function: test2 (func_test2)
  440. {
  441. BasicBlock* label_entry_5 = BasicBlock::Create(getGlobalContext(), "entry",func_test2,nullptr);
  442. // Block entry (label_entry_5)
  443. CallInst* int32_6 = CallInst::Create(func_test3, "", label_entry_5);
  444. int32_6->setCallingConv(CallingConv::C);
  445. int32_6->setTailCall(false);AttributeSet int32_6_PAL;
  446. int32_6->setAttributes(int32_6_PAL);
  447. ReturnInst::Create(getGlobalContext(), int32_6, label_entry_5);
  448. }
  449. // Function: test3 (func_test3)
  450. {
  451. BasicBlock* label_entry_8 = BasicBlock::Create(getGlobalContext(), "entry",func_test3,nullptr);
  452. // Block entry (label_entry_8)
  453. CallInst* int32_9 = CallInst::Create(func_test1, "", label_entry_8);
  454. int32_9->setCallingConv(CallingConv::C);
  455. int32_9->setTailCall(false);AttributeSet int32_9_PAL;
  456. int32_9->setAttributes(int32_9_PAL);
  457. ReturnInst::Create(getGlobalContext(), int32_9, label_entry_8);
  458. }
  459. // Function: test4 (func_test4)
  460. {
  461. Function::arg_iterator args = func_test4->arg_begin();
  462. Value* int1_f = args++;
  463. int1_f->setName("f");
  464. BasicBlock* label_entry_11 = BasicBlock::Create(getGlobalContext(), "entry",func_test4,nullptr);
  465. BasicBlock* label_bb = BasicBlock::Create(getGlobalContext(), "bb",func_test4,nullptr);
  466. BasicBlock* label_bb1 = BasicBlock::Create(getGlobalContext(), "bb1",func_test4,nullptr);
  467. BasicBlock* label_return = BasicBlock::Create(getGlobalContext(), "return",func_test4,nullptr);
  468. // Block entry (label_entry_11)
  469. BranchInst::Create(label_bb, label_entry_11);
  470. // Block bb (label_bb)
  471. BranchInst::Create(label_bb, label_bb1, int1_f, label_bb);
  472. // Block bb1 (label_bb1)
  473. BranchInst::Create(label_bb1, label_return, int1_f, label_bb1);
  474. // Block return (label_return)
  475. ReturnInst::Create(getGlobalContext(), label_return);
  476. }
  477. return mod;
  478. }
  479. }
  480. }
  481. INITIALIZE_PASS(ModuleNDM, "mndm", "mndm", false, false)
  482. INITIALIZE_PASS_BEGIN(CGPass, "cgp","cgp", false, false)
  483. INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
  484. INITIALIZE_PASS_END(CGPass, "cgp","cgp", false, false)
  485. INITIALIZE_PASS(FPass, "fp","fp", false, false)
  486. INITIALIZE_PASS_BEGIN(LPass, "lp","lp", false, false)
  487. INITIALIZE_PASS_DEPENDENCY(LoopInfo)
  488. INITIALIZE_PASS_END(LPass, "lp","lp", false, false)
  489. INITIALIZE_PASS(BPass, "bp","bp", false, false)