7cb4f8d8b03a228c3f7beee46abfba4e1539b268
[oota-llvm.git] / unittests / IR / PassManagerTest.cpp
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/Assembly/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 TestAnalysisPass {
23 public:
24   typedef Function IRUnitT;
25
26   struct Result {
27     Result(int Count) : InstructionCount(Count) {}
28     bool invalidate(Function *) { return true; }
29     int InstructionCount;
30   };
31
32   /// \brief Returns an opaque, unique ID for this pass type.
33   static void *ID() { return (void *)&PassID; }
34
35   TestAnalysisPass(int &Runs) : Runs(Runs) {}
36
37   /// \brief Run the analysis pass over the function and return a result.
38   Result run(Function *F) {
39     ++Runs;
40     int Count = 0;
41     for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE; ++BBI)
42       for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
43            ++II)
44         ++Count;
45     return Result(Count);
46   }
47
48 private:
49   /// \brief Private static data to provide unique ID.
50   static char PassID;
51
52   int &Runs;
53 };
54
55 char TestAnalysisPass::PassID;
56
57 struct TestModulePass {
58   TestModulePass(int &RunCount) : RunCount(RunCount) {}
59
60   PreservedAnalyses run(Module *M) {
61     ++RunCount;
62     return PreservedAnalyses::none();
63   }
64
65   int &RunCount;
66 };
67
68 struct TestFunctionPass {
69   TestFunctionPass(FunctionAnalysisManager &AM, int &RunCount,
70                    int &AnalyzedInstrCount)
71       : AM(AM), RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {}
72
73   PreservedAnalyses run(Function *F) {
74     ++RunCount;
75
76     const TestAnalysisPass::Result &AR = AM.getResult<TestAnalysisPass>(F);
77     AnalyzedInstrCount += AR.InstructionCount;
78
79     return PreservedAnalyses::all();
80   }
81
82   FunctionAnalysisManager &AM;
83   int &RunCount;
84   int &AnalyzedInstrCount;
85 };
86
87 Module *parseIR(const char *IR) {
88   LLVMContext &C = getGlobalContext();
89   SMDiagnostic Err;
90   return ParseAssemblyString(IR, 0, Err, C);
91 }
92
93 class PassManagerTest : public ::testing::Test {
94 protected:
95   OwningPtr<Module> M;
96
97 public:
98   PassManagerTest()
99       : M(parseIR("define void @f() {\n"
100                   "entry:\n"
101                   "  call void @g()\n"
102                   "  call void @h()\n"
103                   "  ret void\n"
104                   "}\n"
105                   "define void @g() {\n"
106                   "  ret void\n"
107                   "}\n"
108                   "define void @h() {\n"
109                   "  ret void\n"
110                   "}\n")) {}
111 };
112
113 TEST_F(PassManagerTest, Basic) {
114   FunctionAnalysisManager FAM;
115   int AnalysisRuns = 0;
116   FAM.registerPass(TestAnalysisPass(AnalysisRuns));
117
118   ModuleAnalysisManager MAM;
119   MAM.registerPass(FunctionAnalysisModuleProxy(FAM));
120
121   ModulePassManager MPM(&MAM);
122
123   // Count the runs over a Function.
124   FunctionPassManager FPM1(&FAM);
125   int FunctionPassRunCount1 = 0;
126   int AnalyzedInstrCount1 = 0;
127   FPM1.addPass(TestFunctionPass(FAM, FunctionPassRunCount1, AnalyzedInstrCount1));
128   MPM.addPass(createModuleToFunctionPassAdaptor(FPM1, &MAM));
129
130   // Count the runs over a module.
131   int ModulePassRunCount = 0;
132   MPM.addPass(TestModulePass(ModulePassRunCount));
133
134   // Count the runs over a Function in a separate manager.
135   FunctionPassManager FPM2(&FAM);
136   int FunctionPassRunCount2 = 0;
137   int AnalyzedInstrCount2 = 0;
138   FPM2.addPass(TestFunctionPass(FAM, FunctionPassRunCount2, AnalyzedInstrCount2));
139   MPM.addPass(createModuleToFunctionPassAdaptor(FPM2, &MAM));
140
141   MPM.run(M.get());
142
143   // Validate module pass counters.
144   EXPECT_EQ(1, ModulePassRunCount);
145
146   // Validate both function pass counter sets.
147   EXPECT_EQ(3, FunctionPassRunCount1);
148   EXPECT_EQ(5, AnalyzedInstrCount1);
149   EXPECT_EQ(3, FunctionPassRunCount2);
150   EXPECT_EQ(5, AnalyzedInstrCount2);
151
152   // Validate the analysis counters.
153   EXPECT_EQ(6, AnalysisRuns);
154 }
155 }