1*f4a2713aSLionel Sambuc //===- llvm/unittest/IR/PassManager.cpp - PassManager tests ---------------===// 2*f4a2713aSLionel Sambuc // 3*f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure 4*f4a2713aSLionel Sambuc // 5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source 6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details. 7*f4a2713aSLionel Sambuc // 8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===// 9*f4a2713aSLionel Sambuc 10*f4a2713aSLionel Sambuc #include "llvm/Assembly/Parser.h" 11*f4a2713aSLionel Sambuc #include "llvm/IR/Function.h" 12*f4a2713aSLionel Sambuc #include "llvm/IR/LLVMContext.h" 13*f4a2713aSLionel Sambuc #include "llvm/IR/Module.h" 14*f4a2713aSLionel Sambuc #include "llvm/IR/PassManager.h" 15*f4a2713aSLionel Sambuc #include "llvm/Support/SourceMgr.h" 16*f4a2713aSLionel Sambuc #include "gtest/gtest.h" 17*f4a2713aSLionel Sambuc 18*f4a2713aSLionel Sambuc using namespace llvm; 19*f4a2713aSLionel Sambuc 20*f4a2713aSLionel Sambuc namespace { 21*f4a2713aSLionel Sambuc 22*f4a2713aSLionel Sambuc class TestAnalysisPass { 23*f4a2713aSLionel Sambuc public: 24*f4a2713aSLionel Sambuc typedef Function IRUnitT; 25*f4a2713aSLionel Sambuc 26*f4a2713aSLionel Sambuc struct Result { 27*f4a2713aSLionel Sambuc Result(int Count) : InstructionCount(Count) {} 28*f4a2713aSLionel Sambuc bool invalidate(Function *) { return true; } 29*f4a2713aSLionel Sambuc int InstructionCount; 30*f4a2713aSLionel Sambuc }; 31*f4a2713aSLionel Sambuc 32*f4a2713aSLionel Sambuc /// \brief Returns an opaque, unique ID for this pass type. 33*f4a2713aSLionel Sambuc static void *ID() { return (void *)&PassID; } 34*f4a2713aSLionel Sambuc 35*f4a2713aSLionel Sambuc /// \brief Run the analysis pass over the function and return a result. 36*f4a2713aSLionel Sambuc Result run(Function *F) { 37*f4a2713aSLionel Sambuc int Count = 0; 38*f4a2713aSLionel Sambuc for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE; ++BBI) 39*f4a2713aSLionel Sambuc for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE; 40*f4a2713aSLionel Sambuc ++II) 41*f4a2713aSLionel Sambuc ++Count; 42*f4a2713aSLionel Sambuc return Result(Count); 43*f4a2713aSLionel Sambuc } 44*f4a2713aSLionel Sambuc 45*f4a2713aSLionel Sambuc private: 46*f4a2713aSLionel Sambuc /// \brief Private static data to provide unique ID. 47*f4a2713aSLionel Sambuc static char PassID; 48*f4a2713aSLionel Sambuc }; 49*f4a2713aSLionel Sambuc 50*f4a2713aSLionel Sambuc char TestAnalysisPass::PassID; 51*f4a2713aSLionel Sambuc 52*f4a2713aSLionel Sambuc struct TestModulePass { 53*f4a2713aSLionel Sambuc TestModulePass(int &RunCount) : RunCount(RunCount) {} 54*f4a2713aSLionel Sambuc 55*f4a2713aSLionel Sambuc bool run(Module *M) { 56*f4a2713aSLionel Sambuc ++RunCount; 57*f4a2713aSLionel Sambuc return true; 58*f4a2713aSLionel Sambuc } 59*f4a2713aSLionel Sambuc 60*f4a2713aSLionel Sambuc int &RunCount; 61*f4a2713aSLionel Sambuc }; 62*f4a2713aSLionel Sambuc 63*f4a2713aSLionel Sambuc struct TestFunctionPass { 64*f4a2713aSLionel Sambuc TestFunctionPass(AnalysisManager &AM, int &RunCount, int &AnalyzedInstrCount) 65*f4a2713aSLionel Sambuc : AM(AM), RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) { 66*f4a2713aSLionel Sambuc } 67*f4a2713aSLionel Sambuc 68*f4a2713aSLionel Sambuc bool run(Function *F) { 69*f4a2713aSLionel Sambuc ++RunCount; 70*f4a2713aSLionel Sambuc 71*f4a2713aSLionel Sambuc const TestAnalysisPass::Result &AR = AM.getResult<TestAnalysisPass>(F); 72*f4a2713aSLionel Sambuc AnalyzedInstrCount += AR.InstructionCount; 73*f4a2713aSLionel Sambuc 74*f4a2713aSLionel Sambuc return true; 75*f4a2713aSLionel Sambuc } 76*f4a2713aSLionel Sambuc 77*f4a2713aSLionel Sambuc AnalysisManager &AM; 78*f4a2713aSLionel Sambuc int &RunCount; 79*f4a2713aSLionel Sambuc int &AnalyzedInstrCount; 80*f4a2713aSLionel Sambuc }; 81*f4a2713aSLionel Sambuc 82*f4a2713aSLionel Sambuc Module *parseIR(const char *IR) { 83*f4a2713aSLionel Sambuc LLVMContext &C = getGlobalContext(); 84*f4a2713aSLionel Sambuc SMDiagnostic Err; 85*f4a2713aSLionel Sambuc return ParseAssemblyString(IR, 0, Err, C); 86*f4a2713aSLionel Sambuc } 87*f4a2713aSLionel Sambuc 88*f4a2713aSLionel Sambuc class PassManagerTest : public ::testing::Test { 89*f4a2713aSLionel Sambuc protected: 90*f4a2713aSLionel Sambuc OwningPtr<Module> M; 91*f4a2713aSLionel Sambuc 92*f4a2713aSLionel Sambuc public: 93*f4a2713aSLionel Sambuc PassManagerTest() 94*f4a2713aSLionel Sambuc : M(parseIR("define void @f() {\n" 95*f4a2713aSLionel Sambuc "entry:\n" 96*f4a2713aSLionel Sambuc " call void @g()\n" 97*f4a2713aSLionel Sambuc " call void @h()\n" 98*f4a2713aSLionel Sambuc " ret void\n" 99*f4a2713aSLionel Sambuc "}\n" 100*f4a2713aSLionel Sambuc "define void @g() {\n" 101*f4a2713aSLionel Sambuc " ret void\n" 102*f4a2713aSLionel Sambuc "}\n" 103*f4a2713aSLionel Sambuc "define void @h() {\n" 104*f4a2713aSLionel Sambuc " ret void\n" 105*f4a2713aSLionel Sambuc "}\n")) {} 106*f4a2713aSLionel Sambuc }; 107*f4a2713aSLionel Sambuc 108*f4a2713aSLionel Sambuc TEST_F(PassManagerTest, Basic) { 109*f4a2713aSLionel Sambuc AnalysisManager AM(M.get()); 110*f4a2713aSLionel Sambuc AM.registerAnalysisPass(TestAnalysisPass()); 111*f4a2713aSLionel Sambuc 112*f4a2713aSLionel Sambuc ModulePassManager MPM(M.get(), &AM); 113*f4a2713aSLionel Sambuc FunctionPassManager FPM(&AM); 114*f4a2713aSLionel Sambuc 115*f4a2713aSLionel Sambuc // Count the runs over a module. 116*f4a2713aSLionel Sambuc int ModulePassRunCount = 0; 117*f4a2713aSLionel Sambuc MPM.addPass(TestModulePass(ModulePassRunCount)); 118*f4a2713aSLionel Sambuc 119*f4a2713aSLionel Sambuc // Count the runs over a Function. 120*f4a2713aSLionel Sambuc int FunctionPassRunCount = 0; 121*f4a2713aSLionel Sambuc int AnalyzedInstrCount = 0; 122*f4a2713aSLionel Sambuc FPM.addPass(TestFunctionPass(AM, FunctionPassRunCount, AnalyzedInstrCount)); 123*f4a2713aSLionel Sambuc MPM.addPass(FPM); 124*f4a2713aSLionel Sambuc 125*f4a2713aSLionel Sambuc MPM.run(); 126*f4a2713aSLionel Sambuc EXPECT_EQ(1, ModulePassRunCount); 127*f4a2713aSLionel Sambuc EXPECT_EQ(3, FunctionPassRunCount); 128*f4a2713aSLionel Sambuc EXPECT_EQ(5, AnalyzedInstrCount); 129*f4a2713aSLionel Sambuc } 130*f4a2713aSLionel Sambuc 131*f4a2713aSLionel Sambuc } 132