blob: d23d85b88287efda84a9cb87eae907a1f8c375b6 [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
Chandler Carruth2846e9e2013-11-21 10:53:05 +000067struct TestPreservingModulePass {
68 PreservedAnalyses run(Module *M) {
69 return PreservedAnalyses::all();
70 }
71};
72
73struct TestMinPreservingModulePass {
74 PreservedAnalyses run(Module *M) {
75 PreservedAnalyses PA;
76 PA.preserve<FunctionAnalysisModuleProxy>();
77 return PA;
78 }
79};
80
Chandler Carruth90a835d2013-11-09 13:09:08 +000081struct TestFunctionPass {
Chandler Carruthed1ffe02013-11-20 04:01:38 +000082 TestFunctionPass(FunctionAnalysisManager &AM, int &RunCount,
83 int &AnalyzedInstrCount)
84 : AM(AM), RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {}
Chandler Carruth90a835d2013-11-09 13:09:08 +000085
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000086 PreservedAnalyses run(Function *F) {
Chandler Carruth90a835d2013-11-09 13:09:08 +000087 ++RunCount;
Chandler Carruth74015a72013-11-13 01:12:08 +000088
89 const TestAnalysisPass::Result &AR = AM.getResult<TestAnalysisPass>(F);
90 AnalyzedInstrCount += AR.InstructionCount;
91
Chandler Carruth851a2aa2013-11-21 02:11:31 +000092 return PreservedAnalyses::all();
Chandler Carruth90a835d2013-11-09 13:09:08 +000093 }
94
Chandler Carruthed1ffe02013-11-20 04:01:38 +000095 FunctionAnalysisManager &AM;
Chandler Carruth90a835d2013-11-09 13:09:08 +000096 int &RunCount;
Chandler Carruth74015a72013-11-13 01:12:08 +000097 int &AnalyzedInstrCount;
Chandler Carruth90a835d2013-11-09 13:09:08 +000098};
99
100Module *parseIR(const char *IR) {
101 LLVMContext &C = getGlobalContext();
102 SMDiagnostic Err;
103 return ParseAssemblyString(IR, 0, Err, C);
104}
105
106class PassManagerTest : public ::testing::Test {
107protected:
108 OwningPtr<Module> M;
109
110public:
111 PassManagerTest()
112 : M(parseIR("define void @f() {\n"
113 "entry:\n"
114 " call void @g()\n"
115 " call void @h()\n"
116 " ret void\n"
117 "}\n"
118 "define void @g() {\n"
119 " ret void\n"
120 "}\n"
121 "define void @h() {\n"
122 " ret void\n"
123 "}\n")) {}
124};
125
126TEST_F(PassManagerTest, Basic) {
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000127 FunctionAnalysisManager FAM;
128 int AnalysisRuns = 0;
129 FAM.registerPass(TestAnalysisPass(AnalysisRuns));
Chandler Carruth74015a72013-11-13 01:12:08 +0000130
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000131 ModuleAnalysisManager MAM;
132 MAM.registerPass(FunctionAnalysisModuleProxy(FAM));
133
134 ModulePassManager MPM(&MAM);
135
136 // Count the runs over a Function.
137 FunctionPassManager FPM1(&FAM);
138 int FunctionPassRunCount1 = 0;
139 int AnalyzedInstrCount1 = 0;
140 FPM1.addPass(TestFunctionPass(FAM, FunctionPassRunCount1, AnalyzedInstrCount1));
141 MPM.addPass(createModuleToFunctionPassAdaptor(FPM1, &MAM));
Chandler Carruth90a835d2013-11-09 13:09:08 +0000142
143 // Count the runs over a module.
144 int ModulePassRunCount = 0;
145 MPM.addPass(TestModulePass(ModulePassRunCount));
146
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000147 // Count the runs over a Function in a separate manager.
148 FunctionPassManager FPM2(&FAM);
149 int FunctionPassRunCount2 = 0;
150 int AnalyzedInstrCount2 = 0;
151 FPM2.addPass(TestFunctionPass(FAM, FunctionPassRunCount2, AnalyzedInstrCount2));
152 MPM.addPass(createModuleToFunctionPassAdaptor(FPM2, &MAM));
Chandler Carruth90a835d2013-11-09 13:09:08 +0000153
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000154 // A third function pass manager but with only preserving intervening passes.
155 MPM.addPass(TestPreservingModulePass());
156 FunctionPassManager FPM3(&FAM);
157 int FunctionPassRunCount3 = 0;
158 int AnalyzedInstrCount3 = 0;
159 FPM3.addPass(TestFunctionPass(FAM, FunctionPassRunCount3, AnalyzedInstrCount3));
160 MPM.addPass(createModuleToFunctionPassAdaptor(FPM3, &MAM));
161
162 // A fourth function pass manager but with a minimal intervening passes.
163 MPM.addPass(TestMinPreservingModulePass());
164 FunctionPassManager FPM4(&FAM);
165 int FunctionPassRunCount4 = 0;
166 int AnalyzedInstrCount4 = 0;
167 FPM4.addPass(TestFunctionPass(FAM, FunctionPassRunCount4, AnalyzedInstrCount4));
168 MPM.addPass(createModuleToFunctionPassAdaptor(FPM4, &MAM));
169
Chandler Carruthed1ffe02013-11-20 04:01:38 +0000170 MPM.run(M.get());
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000171
172 // Validate module pass counters.
Chandler Carruth90a835d2013-11-09 13:09:08 +0000173 EXPECT_EQ(1, ModulePassRunCount);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000174
175 // Validate both function pass counter sets.
176 EXPECT_EQ(3, FunctionPassRunCount1);
177 EXPECT_EQ(5, AnalyzedInstrCount1);
178 EXPECT_EQ(3, FunctionPassRunCount2);
179 EXPECT_EQ(5, AnalyzedInstrCount2);
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000180 EXPECT_EQ(3, FunctionPassRunCount3);
181 EXPECT_EQ(5, AnalyzedInstrCount3);
182 EXPECT_EQ(3, FunctionPassRunCount4);
183 EXPECT_EQ(5, AnalyzedInstrCount4);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000184
185 // Validate the analysis counters.
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000186 EXPECT_EQ(9, AnalysisRuns);
Chandler Carruth90a835d2013-11-09 13:09:08 +0000187}
Chandler Carruth90a835d2013-11-09 13:09:08 +0000188}