xref: /minix3/external/bsd/llvm/dist/llvm/unittests/IR/PassManagerTest.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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