blob: 38ef1a432905b36900692ae509129f6c671ec4e1 [file] [log] [blame]
Chandler Carruth90a835d2013-11-09 13:09:08 +00001//===- 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
18using namespace llvm;
19
20namespace {
21
Chandler Carruth74015a72013-11-13 01:12:08 +000022class TestAnalysisPass {
23public:
24 typedef Function IRUnitT;
25
26 struct Result {
27 Result(int Count) : InstructionCount(Count) {}
Chandler Carruth74015a72013-11-13 01:12:08 +000028 int InstructionCount;
29 };
30
31 /// \brief Returns an opaque, unique ID for this pass type.
32 static void *ID() { return (void *)&PassID; }
33
Chandler Carruth851a2aa2013-11-21 02:11:31 +000034 TestAnalysisPass(int &Runs) : Runs(Runs) {}
35
Chandler Carruth74015a72013-11-13 01:12:08 +000036 /// \brief Run the analysis pass over the function and return a result.
37 Result run(Function *F) {
Chandler Carruth851a2aa2013-11-21 02:11:31 +000038 ++Runs;
Chandler Carruth74015a72013-11-13 01:12:08 +000039 int Count = 0;
40 for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE; ++BBI)
41 for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
42 ++II)
43 ++Count;
44 return Result(Count);
45 }
46
47private:
48 /// \brief Private static data to provide unique ID.
49 static char PassID;
Chandler Carruth851a2aa2013-11-21 02:11:31 +000050
51 int &Runs;
Chandler Carruth74015a72013-11-13 01:12:08 +000052};
53
54char TestAnalysisPass::PassID;
55
Chandler Carruth90a835d2013-11-09 13:09:08 +000056struct TestModulePass {
57 TestModulePass(int &RunCount) : RunCount(RunCount) {}
58
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000059 PreservedAnalyses run(Module *M) {
Chandler Carruth90a835d2013-11-09 13:09:08 +000060 ++RunCount;
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000061 return PreservedAnalyses::none();
Chandler Carruth90a835d2013-11-09 13:09:08 +000062 }
63
64 int &RunCount;
65};
66
67struct TestFunctionPass {
Chandler Carruthed1ffe02013-11-20 04:01:38 +000068 TestFunctionPass(FunctionAnalysisManager &AM, int &RunCount,
69 int &AnalyzedInstrCount)
70 : AM(AM), RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {}
Chandler Carruth90a835d2013-11-09 13:09:08 +000071
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000072 PreservedAnalyses run(Function *F) {
Chandler Carruth90a835d2013-11-09 13:09:08 +000073 ++RunCount;
Chandler Carruth74015a72013-11-13 01:12:08 +000074
75 const TestAnalysisPass::Result &AR = AM.getResult<TestAnalysisPass>(F);
76 AnalyzedInstrCount += AR.InstructionCount;
77
Chandler Carruth851a2aa2013-11-21 02:11:31 +000078 return PreservedAnalyses::all();
Chandler Carruth90a835d2013-11-09 13:09:08 +000079 }
80
Chandler Carruthed1ffe02013-11-20 04:01:38 +000081 FunctionAnalysisManager &AM;
Chandler Carruth90a835d2013-11-09 13:09:08 +000082 int &RunCount;
Chandler Carruth74015a72013-11-13 01:12:08 +000083 int &AnalyzedInstrCount;
Chandler Carruth90a835d2013-11-09 13:09:08 +000084};
85
86Module *parseIR(const char *IR) {
87 LLVMContext &C = getGlobalContext();
88 SMDiagnostic Err;
89 return ParseAssemblyString(IR, 0, Err, C);
90}
91
92class PassManagerTest : public ::testing::Test {
93protected:
94 OwningPtr<Module> M;
95
96public:
97 PassManagerTest()
98 : M(parseIR("define void @f() {\n"
99 "entry:\n"
100 " call void @g()\n"
101 " call void @h()\n"
102 " ret void\n"
103 "}\n"
104 "define void @g() {\n"
105 " ret void\n"
106 "}\n"
107 "define void @h() {\n"
108 " ret void\n"
109 "}\n")) {}
110};
111
112TEST_F(PassManagerTest, Basic) {
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000113 FunctionAnalysisManager FAM;
114 int AnalysisRuns = 0;
115 FAM.registerPass(TestAnalysisPass(AnalysisRuns));
Chandler Carruth74015a72013-11-13 01:12:08 +0000116
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000117 ModuleAnalysisManager MAM;
118 MAM.registerPass(FunctionAnalysisModuleProxy(FAM));
119
120 ModulePassManager MPM(&MAM);
121
122 // Count the runs over a Function.
123 FunctionPassManager FPM1(&FAM);
124 int FunctionPassRunCount1 = 0;
125 int AnalyzedInstrCount1 = 0;
126 FPM1.addPass(TestFunctionPass(FAM, FunctionPassRunCount1, AnalyzedInstrCount1));
127 MPM.addPass(createModuleToFunctionPassAdaptor(FPM1, &MAM));
Chandler Carruth90a835d2013-11-09 13:09:08 +0000128
129 // Count the runs over a module.
130 int ModulePassRunCount = 0;
131 MPM.addPass(TestModulePass(ModulePassRunCount));
132
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000133 // Count the runs over a Function in a separate manager.
134 FunctionPassManager FPM2(&FAM);
135 int FunctionPassRunCount2 = 0;
136 int AnalyzedInstrCount2 = 0;
137 FPM2.addPass(TestFunctionPass(FAM, FunctionPassRunCount2, AnalyzedInstrCount2));
138 MPM.addPass(createModuleToFunctionPassAdaptor(FPM2, &MAM));
Chandler Carruth90a835d2013-11-09 13:09:08 +0000139
Chandler Carruthed1ffe02013-11-20 04:01:38 +0000140 MPM.run(M.get());
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000141
142 // Validate module pass counters.
Chandler Carruth90a835d2013-11-09 13:09:08 +0000143 EXPECT_EQ(1, ModulePassRunCount);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000144
145 // Validate both function pass counter sets.
146 EXPECT_EQ(3, FunctionPassRunCount1);
147 EXPECT_EQ(5, AnalyzedInstrCount1);
148 EXPECT_EQ(3, FunctionPassRunCount2);
149 EXPECT_EQ(5, AnalyzedInstrCount2);
150
151 // Validate the analysis counters.
152 EXPECT_EQ(6, AnalysisRuns);
Chandler Carruth90a835d2013-11-09 13:09:08 +0000153}
Chandler Carruth90a835d2013-11-09 13:09:08 +0000154}