1 //===- llvm/unittest/IR/PassManager.cpp - PassManager tests ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
22 class TestAnalysisPass {
24 typedef Function IRUnitT;
27 Result(int Count) : InstructionCount(Count) {}
31 /// \brief Returns an opaque, unique ID for this pass type.
32 static void *ID() { return (void *)&PassID; }
34 TestAnalysisPass(int &Runs) : Runs(Runs) {}
36 /// \brief Run the analysis pass over the function and return a result.
37 Result run(Function *F) {
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;
48 /// \brief Private static data to provide unique ID.
54 char TestAnalysisPass::PassID;
56 struct TestModulePass {
57 TestModulePass(int &RunCount) : RunCount(RunCount) {}
59 PreservedAnalyses run(Module *M) {
61 return PreservedAnalyses::none();
67 struct TestPreservingModulePass {
68 PreservedAnalyses run(Module *M) {
69 return PreservedAnalyses::all();
73 struct TestMinPreservingModulePass {
74 PreservedAnalyses run(Module *M) {
76 PA.preserve<FunctionAnalysisManagerModuleProxy>();
81 struct TestFunctionPass {
82 TestFunctionPass(int &RunCount, int &AnalyzedInstrCount)
83 : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {}
85 PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) {
88 const TestAnalysisPass::Result &AR = AM->getResult<TestAnalysisPass>(F);
89 AnalyzedInstrCount += AR.InstructionCount;
91 return PreservedAnalyses::all();
95 int &AnalyzedInstrCount;
98 Module *parseIR(const char *IR) {
99 LLVMContext &C = getGlobalContext();
101 return ParseAssemblyString(IR, 0, Err, C);
104 class PassManagerTest : public ::testing::Test {
110 : M(parseIR("define void @f() {\n"
116 "define void @g() {\n"
119 "define void @h() {\n"
124 TEST_F(PassManagerTest, Basic) {
125 FunctionAnalysisManager FAM;
126 int AnalysisRuns = 0;
127 FAM.registerPass(TestAnalysisPass(AnalysisRuns));
129 ModuleAnalysisManager MAM;
130 MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
132 ModulePassManager MPM;
134 // Count the runs over a Function.
135 FunctionPassManager FPM1;
136 int FunctionPassRunCount1 = 0;
137 int AnalyzedInstrCount1 = 0;
138 FPM1.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1));
139 MPM.addPass(createModuleToFunctionPassAdaptor(FPM1));
141 // Count the runs over a module.
142 int ModulePassRunCount = 0;
143 MPM.addPass(TestModulePass(ModulePassRunCount));
145 // Count the runs over a Function in a separate manager.
146 FunctionPassManager FPM2;
147 int FunctionPassRunCount2 = 0;
148 int AnalyzedInstrCount2 = 0;
149 FPM2.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2));
150 MPM.addPass(createModuleToFunctionPassAdaptor(FPM2));
152 // A third function pass manager but with only preserving intervening passes.
153 MPM.addPass(TestPreservingModulePass());
154 FunctionPassManager FPM3;
155 int FunctionPassRunCount3 = 0;
156 int AnalyzedInstrCount3 = 0;
157 FPM3.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3));
158 MPM.addPass(createModuleToFunctionPassAdaptor(FPM3));
160 // A fourth function pass manager but with a minimal intervening passes.
161 MPM.addPass(TestMinPreservingModulePass());
162 FunctionPassManager FPM4;
163 int FunctionPassRunCount4 = 0;
164 int AnalyzedInstrCount4 = 0;
165 FPM4.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4));
166 MPM.addPass(createModuleToFunctionPassAdaptor(FPM4));
168 MPM.run(M.get(), &MAM);
170 // Validate module pass counters.
171 EXPECT_EQ(1, ModulePassRunCount);
173 // Validate both function pass counter sets.
174 EXPECT_EQ(3, FunctionPassRunCount1);
175 EXPECT_EQ(5, AnalyzedInstrCount1);
176 EXPECT_EQ(3, FunctionPassRunCount2);
177 EXPECT_EQ(5, AnalyzedInstrCount2);
178 EXPECT_EQ(3, FunctionPassRunCount3);
179 EXPECT_EQ(5, AnalyzedInstrCount3);
180 EXPECT_EQ(3, FunctionPassRunCount4);
181 EXPECT_EQ(5, AnalyzedInstrCount4);
183 // Validate the analysis counters.
184 EXPECT_EQ(9, AnalysisRuns);