blob: b0d4cbe031844376d1fe1f4d435fcbfdcbfa50b4 [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:
Chandler Carruth74015a72013-11-13 01:12:08 +000024 struct Result {
25 Result(int Count) : InstructionCount(Count) {}
Chandler Carruth74015a72013-11-13 01:12:08 +000026 int InstructionCount;
27 };
28
29 /// \brief Returns an opaque, unique ID for this pass type.
30 static void *ID() { return (void *)&PassID; }
31
Chandler Carruth851a2aa2013-11-21 02:11:31 +000032 TestAnalysisPass(int &Runs) : Runs(Runs) {}
33
Chandler Carruth74015a72013-11-13 01:12:08 +000034 /// \brief Run the analysis pass over the function and return a result.
35 Result run(Function *F) {
Chandler Carruth851a2aa2013-11-21 02:11:31 +000036 ++Runs;
Chandler Carruth74015a72013-11-13 01:12:08 +000037 int Count = 0;
38 for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE; ++BBI)
39 for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
40 ++II)
41 ++Count;
42 return Result(Count);
43 }
44
45private:
46 /// \brief Private static data to provide unique ID.
47 static char PassID;
Chandler Carruth851a2aa2013-11-21 02:11:31 +000048
49 int &Runs;
Chandler Carruth74015a72013-11-13 01:12:08 +000050};
51
52char TestAnalysisPass::PassID;
53
Chandler Carruth90a835d2013-11-09 13:09:08 +000054struct TestModulePass {
55 TestModulePass(int &RunCount) : RunCount(RunCount) {}
56
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000057 PreservedAnalyses run(Module *M) {
Chandler Carruth90a835d2013-11-09 13:09:08 +000058 ++RunCount;
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000059 return PreservedAnalyses::none();
Chandler Carruth90a835d2013-11-09 13:09:08 +000060 }
61
62 int &RunCount;
63};
64
Chandler Carruth2846e9e2013-11-21 10:53:05 +000065struct TestPreservingModulePass {
66 PreservedAnalyses run(Module *M) {
67 return PreservedAnalyses::all();
68 }
69};
70
71struct TestMinPreservingModulePass {
72 PreservedAnalyses run(Module *M) {
73 PreservedAnalyses PA;
Chandler Carruthb3e72192013-11-22 00:43:29 +000074 PA.preserve<FunctionAnalysisManagerModuleProxy>();
Chandler Carruth2846e9e2013-11-21 10:53:05 +000075 return PA;
76 }
77};
78
Chandler Carruth90a835d2013-11-09 13:09:08 +000079struct TestFunctionPass {
Chandler Carruthb3e72192013-11-22 00:43:29 +000080 TestFunctionPass(int &RunCount, int &AnalyzedInstrCount)
81 : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {}
Chandler Carruth90a835d2013-11-09 13:09:08 +000082
Chandler Carruthb3e72192013-11-22 00:43:29 +000083 PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) {
Chandler Carruth90a835d2013-11-09 13:09:08 +000084 ++RunCount;
Chandler Carruth74015a72013-11-13 01:12:08 +000085
Chandler Carruthb3e72192013-11-22 00:43:29 +000086 const TestAnalysisPass::Result &AR = AM->getResult<TestAnalysisPass>(F);
Chandler Carruth74015a72013-11-13 01:12:08 +000087 AnalyzedInstrCount += AR.InstructionCount;
88
Chandler Carruth851a2aa2013-11-21 02:11:31 +000089 return PreservedAnalyses::all();
Chandler Carruth90a835d2013-11-09 13:09:08 +000090 }
91
92 int &RunCount;
Chandler Carruth74015a72013-11-13 01:12:08 +000093 int &AnalyzedInstrCount;
Chandler Carruth90a835d2013-11-09 13:09:08 +000094};
95
96Module *parseIR(const char *IR) {
97 LLVMContext &C = getGlobalContext();
98 SMDiagnostic Err;
99 return ParseAssemblyString(IR, 0, Err, C);
100}
101
102class PassManagerTest : public ::testing::Test {
103protected:
104 OwningPtr<Module> M;
105
106public:
107 PassManagerTest()
108 : M(parseIR("define void @f() {\n"
109 "entry:\n"
110 " call void @g()\n"
111 " call void @h()\n"
112 " ret void\n"
113 "}\n"
114 "define void @g() {\n"
115 " ret void\n"
116 "}\n"
117 "define void @h() {\n"
118 " ret void\n"
119 "}\n")) {}
120};
121
122TEST_F(PassManagerTest, Basic) {
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000123 FunctionAnalysisManager FAM;
124 int AnalysisRuns = 0;
125 FAM.registerPass(TestAnalysisPass(AnalysisRuns));
Chandler Carruth74015a72013-11-13 01:12:08 +0000126
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000127 ModuleAnalysisManager MAM;
Chandler Carruthb3e72192013-11-22 00:43:29 +0000128 MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000129
Chandler Carruthb3e72192013-11-22 00:43:29 +0000130 ModulePassManager MPM;
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000131
132 // Count the runs over a Function.
Chandler Carruthb3e72192013-11-22 00:43:29 +0000133 FunctionPassManager FPM1;
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000134 int FunctionPassRunCount1 = 0;
135 int AnalyzedInstrCount1 = 0;
Chandler Carruthb3e72192013-11-22 00:43:29 +0000136 FPM1.addPass(TestFunctionPass(FunctionPassRunCount1, AnalyzedInstrCount1));
137 MPM.addPass(createModuleToFunctionPassAdaptor(FPM1));
Chandler Carruth90a835d2013-11-09 13:09:08 +0000138
139 // Count the runs over a module.
140 int ModulePassRunCount = 0;
141 MPM.addPass(TestModulePass(ModulePassRunCount));
142
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000143 // Count the runs over a Function in a separate manager.
Chandler Carruthb3e72192013-11-22 00:43:29 +0000144 FunctionPassManager FPM2;
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000145 int FunctionPassRunCount2 = 0;
146 int AnalyzedInstrCount2 = 0;
Chandler Carruthb3e72192013-11-22 00:43:29 +0000147 FPM2.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2));
148 MPM.addPass(createModuleToFunctionPassAdaptor(FPM2));
Chandler Carruth90a835d2013-11-09 13:09:08 +0000149
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000150 // A third function pass manager but with only preserving intervening passes.
151 MPM.addPass(TestPreservingModulePass());
Chandler Carruthb3e72192013-11-22 00:43:29 +0000152 FunctionPassManager FPM3;
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000153 int FunctionPassRunCount3 = 0;
154 int AnalyzedInstrCount3 = 0;
Chandler Carruthb3e72192013-11-22 00:43:29 +0000155 FPM3.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3));
156 MPM.addPass(createModuleToFunctionPassAdaptor(FPM3));
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000157
158 // A fourth function pass manager but with a minimal intervening passes.
159 MPM.addPass(TestMinPreservingModulePass());
Chandler Carruthb3e72192013-11-22 00:43:29 +0000160 FunctionPassManager FPM4;
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000161 int FunctionPassRunCount4 = 0;
162 int AnalyzedInstrCount4 = 0;
Chandler Carruthb3e72192013-11-22 00:43:29 +0000163 FPM4.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4));
164 MPM.addPass(createModuleToFunctionPassAdaptor(FPM4));
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000165
Chandler Carruthb3e72192013-11-22 00:43:29 +0000166 MPM.run(M.get(), &MAM);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000167
168 // Validate module pass counters.
Chandler Carruth90a835d2013-11-09 13:09:08 +0000169 EXPECT_EQ(1, ModulePassRunCount);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000170
171 // Validate both function pass counter sets.
172 EXPECT_EQ(3, FunctionPassRunCount1);
173 EXPECT_EQ(5, AnalyzedInstrCount1);
174 EXPECT_EQ(3, FunctionPassRunCount2);
175 EXPECT_EQ(5, AnalyzedInstrCount2);
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000176 EXPECT_EQ(3, FunctionPassRunCount3);
177 EXPECT_EQ(5, AnalyzedInstrCount3);
178 EXPECT_EQ(3, FunctionPassRunCount4);
179 EXPECT_EQ(5, AnalyzedInstrCount4);
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000180
181 // Validate the analysis counters.
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000182 EXPECT_EQ(9, AnalysisRuns);
Chandler Carruth90a835d2013-11-09 13:09:08 +0000183}
Chandler Carruth90a835d2013-11-09 13:09:08 +0000184}