Make succ_iterator a real random access iterator and clean up a couple of users.
[oota-llvm.git] / unittests / Analysis / CFGTest.cpp
1 //===- CFGTest.cpp - CFG 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/Analysis/CFG.h"
11 #include "llvm/ADT/OwningPtr.h"
12 #include "llvm/Analysis/LoopInfo.h"
13 #include "llvm/AsmParser/Parser.h"
14 #include "llvm/IR/Dominators.h"
15 #include "llvm/IR/Function.h"
16 #include "llvm/IR/LLVMContext.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Pass.h"
19 #include "llvm/PassManager.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/InstIterator.h"
22 #include "llvm/Support/SourceMgr.h"
23 #include "gtest/gtest.h"
24
25 using namespace llvm;
26
27 namespace {
28
29 // This fixture assists in running the isPotentiallyReachable utility four ways
30 // and ensuring it produces the correct answer each time.
31 class IsPotentiallyReachableTest : public testing::Test {
32 protected:
33   void ParseAssembly(const char *Assembly) {
34     M.reset(new Module("Module", getGlobalContext()));
35
36     SMDiagnostic Error;
37     bool Parsed = ParseAssemblyString(Assembly, M.get(),
38                                       Error, M->getContext()) == M.get();
39
40     std::string errMsg;
41     raw_string_ostream os(errMsg);
42     Error.print("", os);
43
44     if (!Parsed) {
45       // A failure here means that the test itself is buggy.
46       report_fatal_error(os.str().c_str());
47     }
48
49     Function *F = M->getFunction("test");
50     if (F == NULL)
51       report_fatal_error("Test must have a function named @test");
52
53     A = B = NULL;
54     for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
55       if (I->hasName()) {
56         if (I->getName() == "A")
57           A = &*I;
58         else if (I->getName() == "B")
59           B = &*I;
60       }
61     }
62     if (A == NULL)
63       report_fatal_error("@test must have an instruction %A");
64     if (B == NULL)
65       report_fatal_error("@test must have an instruction %B");
66   }
67
68   void ExpectPath(bool ExpectedResult) {
69     static char ID;
70     class IsPotentiallyReachableTestPass : public FunctionPass {
71      public:
72       IsPotentiallyReachableTestPass(bool ExpectedResult,
73                                      Instruction *A, Instruction *B)
74           : FunctionPass(ID), ExpectedResult(ExpectedResult), A(A), B(B) {}
75
76       static int initialize() {
77         PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass",
78                                     "", &ID, 0, true, true);
79         PassRegistry::getPassRegistry()->registerPass(*PI, false);
80         initializeLoopInfoPass(*PassRegistry::getPassRegistry());
81         initializeDominatorTreeWrapperPassPass(
82             *PassRegistry::getPassRegistry());
83         return 0;
84       }
85
86       void getAnalysisUsage(AnalysisUsage &AU) const {
87         AU.setPreservesAll();
88         AU.addRequired<LoopInfo>();
89         AU.addRequired<DominatorTreeWrapperPass>();
90       }
91
92       bool runOnFunction(Function &F) {
93         if (!F.hasName() || F.getName() != "test")
94           return false;
95
96         LoopInfo *LI = &getAnalysis<LoopInfo>();
97         DominatorTree *DT =
98             &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
99         EXPECT_EQ(isPotentiallyReachable(A, B, 0, 0), ExpectedResult);
100         EXPECT_EQ(isPotentiallyReachable(A, B, DT, 0), ExpectedResult);
101         EXPECT_EQ(isPotentiallyReachable(A, B, 0, LI), ExpectedResult);
102         EXPECT_EQ(isPotentiallyReachable(A, B, DT, LI), ExpectedResult);
103         return false;
104       }
105       bool ExpectedResult;
106       Instruction *A, *B;
107     };
108
109     static int initialize = IsPotentiallyReachableTestPass::initialize();
110     (void)initialize;
111
112     IsPotentiallyReachableTestPass *P =
113         new IsPotentiallyReachableTestPass(ExpectedResult, A, B);
114     PassManager PM;
115     PM.add(P);
116     PM.run(*M);
117   }
118
119   OwningPtr<Module> M;
120   Instruction *A, *B;
121 };
122
123 }
124
125 TEST_F(IsPotentiallyReachableTest, SameBlockNoPath) {
126   ParseAssembly(
127       "define void @test() {\n"
128       "entry:\n"
129       "  bitcast i8 undef to i8\n"
130       "  %B = bitcast i8 undef to i8\n"
131       "  bitcast i8 undef to i8\n"
132       "  bitcast i8 undef to i8\n"
133       "  %A = bitcast i8 undef to i8\n"
134       "  ret void\n"
135       "}\n");
136   ExpectPath(false);
137 }
138
139 TEST_F(IsPotentiallyReachableTest, SameBlockPath) {
140   ParseAssembly(
141       "define void @test() {\n"
142       "entry:\n"
143       "  %A = bitcast i8 undef to i8\n"
144       "  bitcast i8 undef to i8\n"
145       "  bitcast i8 undef to i8\n"
146       "  %B = bitcast i8 undef to i8\n"
147       "  ret void\n"
148       "}\n");
149   ExpectPath(true);
150 }
151
152 TEST_F(IsPotentiallyReachableTest, SameBlockNoLoop) {
153   ParseAssembly(
154       "define void @test() {\n"
155       "entry:\n"
156       "  br label %middle\n"
157       "middle:\n"
158       "  %B = bitcast i8 undef to i8\n"
159       "  bitcast i8 undef to i8\n"
160       "  bitcast i8 undef to i8\n"
161       "  %A = bitcast i8 undef to i8\n"
162       "  br label %nextblock\n"
163       "nextblock:\n"
164       "  ret void\n"
165       "}\n");
166   ExpectPath(false);
167 }
168
169 TEST_F(IsPotentiallyReachableTest, StraightNoPath) {
170   ParseAssembly(
171       "define void @test() {\n"
172       "entry:\n"
173       "  %B = bitcast i8 undef to i8\n"
174       "  br label %exit\n"
175       "exit:\n"
176       "  %A = bitcast i8 undef to i8\n"
177       "  ret void\n"
178       "}");
179   ExpectPath(false);
180 }
181
182 TEST_F(IsPotentiallyReachableTest, StraightPath) {
183   ParseAssembly(
184       "define void @test() {\n"
185       "entry:\n"
186       "  %A = bitcast i8 undef to i8\n"
187       "  br label %exit\n"
188       "exit:\n"
189       "  %B = bitcast i8 undef to i8\n"
190       "  ret void\n"
191       "}");
192   ExpectPath(true);
193 }
194
195 TEST_F(IsPotentiallyReachableTest, DestUnreachable) {
196   ParseAssembly(
197       "define void @test() {\n"
198       "entry:\n"
199       "  br label %midblock\n"
200       "midblock:\n"
201       "  %A = bitcast i8 undef to i8\n"
202       "  ret void\n"
203       "unreachable:\n"
204       "  %B = bitcast i8 undef to i8\n"
205       "  br label %midblock\n"
206       "}");
207   ExpectPath(false);
208 }
209
210 TEST_F(IsPotentiallyReachableTest, BranchToReturn) {
211   ParseAssembly(
212       "define void @test(i1 %x) {\n"
213       "entry:\n"
214       "  %A = bitcast i8 undef to i8\n"
215       "  br i1 %x, label %block1, label %block2\n"
216       "block1:\n"
217       "  ret void\n"
218       "block2:\n"
219       "  %B = bitcast i8 undef to i8\n"
220       "  ret void\n"
221       "}");
222   ExpectPath(true);
223 }
224
225 TEST_F(IsPotentiallyReachableTest, SimpleLoop1) {
226   ParseAssembly(
227       "declare i1 @switch()\n"
228       "\n"
229       "define void @test() {\n"
230       "entry:\n"
231       "  br label %loop\n"
232       "loop:\n"
233       "  %B = bitcast i8 undef to i8\n"
234       "  %A = bitcast i8 undef to i8\n"
235       "  %x = call i1 @switch()\n"
236       "  br i1 %x, label %loop, label %exit\n"
237       "exit:\n"
238       "  ret void\n"
239       "}");
240   ExpectPath(true);
241 }
242
243 TEST_F(IsPotentiallyReachableTest, SimpleLoop2) {
244   ParseAssembly(
245       "declare i1 @switch()\n"
246       "\n"
247       "define void @test() {\n"
248       "entry:\n"
249       "  %B = bitcast i8 undef to i8\n"
250       "  br label %loop\n"
251       "loop:\n"
252       "  %A = bitcast i8 undef to i8\n"
253       "  %x = call i1 @switch()\n"
254       "  br i1 %x, label %loop, label %exit\n"
255       "exit:\n"
256       "  ret void\n"
257       "}");
258   ExpectPath(false);
259 }
260
261 TEST_F(IsPotentiallyReachableTest, SimpleLoop3) {
262   ParseAssembly(
263       "declare i1 @switch()\n"
264       "\n"
265       "define void @test() {\n"
266       "entry:\n"
267       "  br label %loop\n"
268       "loop:\n"
269       "  %B = bitcast i8 undef to i8\n"
270       "  %x = call i1 @switch()\n"
271       "  br i1 %x, label %loop, label %exit\n"
272       "exit:\n"
273       "  %A = bitcast i8 undef to i8\n"
274       "  ret void\n"
275       "}");
276   ExpectPath(false);
277 }
278
279
280 TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOther1) {
281   ParseAssembly(
282       "declare i1 @switch()\n"
283       "\n"
284       "define void @test() {\n"
285       "entry:\n"
286       "  br label %loop1\n"
287       "loop1:\n"
288       "  %A = bitcast i8 undef to i8\n"
289       "  %x = call i1 @switch()\n"
290       "  br i1 %x, label %loop1, label %loop1exit\n"
291       "loop1exit:\n"
292       "  br label %loop2\n"
293       "loop2:\n"
294       "  %B = bitcast i8 undef to i8\n"
295       "  %y = call i1 @switch()\n"
296       "  br i1 %x, label %loop2, label %loop2exit\n"
297       "loop2exit:"
298       "  ret void\n"
299       "}");
300   ExpectPath(true);
301 }
302
303 TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOther2) {
304   ParseAssembly(
305       "declare i1 @switch()\n"
306       "\n"
307       "define void @test() {\n"
308       "entry:\n"
309       "  br label %loop1\n"
310       "loop1:\n"
311       "  %B = bitcast i8 undef to i8\n"
312       "  %x = call i1 @switch()\n"
313       "  br i1 %x, label %loop1, label %loop1exit\n"
314       "loop1exit:\n"
315       "  br label %loop2\n"
316       "loop2:\n"
317       "  %A = bitcast i8 undef to i8\n"
318       "  %y = call i1 @switch()\n"
319       "  br i1 %x, label %loop2, label %loop2exit\n"
320       "loop2exit:"
321       "  ret void\n"
322       "}");
323   ExpectPath(false);
324 }
325
326 TEST_F(IsPotentiallyReachableTest, OneLoopAfterTheOtherInsideAThirdLoop) {
327   ParseAssembly(
328       "declare i1 @switch()\n"
329       "\n"
330       "define void @test() {\n"
331       "entry:\n"
332       "  br label %outerloop3\n"
333       "outerloop3:\n"
334       "  br label %innerloop1\n"
335       "innerloop1:\n"
336       "  %B = bitcast i8 undef to i8\n"
337       "  %x = call i1 @switch()\n"
338       "  br i1 %x, label %innerloop1, label %innerloop1exit\n"
339       "innerloop1exit:\n"
340       "  br label %innerloop2\n"
341       "innerloop2:\n"
342       "  %A = bitcast i8 undef to i8\n"
343       "  %y = call i1 @switch()\n"
344       "  br i1 %x, label %innerloop2, label %innerloop2exit\n"
345       "innerloop2exit:"
346       "  ;; In outer loop3 now.\n"
347       "  %z = call i1 @switch()\n"
348       "  br i1 %z, label %outerloop3, label %exit\n"
349       "exit:\n"
350       "  ret void\n"
351       "}");
352   ExpectPath(true);
353 }
354
355 static const char *BranchInsideLoopIR =
356     "declare i1 @switch()\n"
357     "\n"
358     "define void @test() {\n"
359     "entry:\n"
360     "  br label %loop\n"
361     "loop:\n"
362     "  %x = call i1 @switch()\n"
363     "  br i1 %x, label %nextloopblock, label %exit\n"
364     "nextloopblock:\n"
365     "  %y = call i1 @switch()\n"
366     "  br i1 %y, label %left, label %right\n"
367     "left:\n"
368     "  %A = bitcast i8 undef to i8\n"
369     "  br label %loop\n"
370     "right:\n"
371     "  %B = bitcast i8 undef to i8\n"
372     "  br label %loop\n"
373     "exit:\n"
374     "  ret void\n"
375     "}";
376
377 TEST_F(IsPotentiallyReachableTest, BranchInsideLoop) {
378   ParseAssembly(BranchInsideLoopIR);
379   ExpectPath(true);
380 }
381
382 TEST_F(IsPotentiallyReachableTest, ModifyTest) {
383   ParseAssembly(BranchInsideLoopIR);
384
385   succ_iterator S = succ_begin(++M->getFunction("test")->begin());
386   BasicBlock *OldBB = S[0];
387   S[0] = S[1];
388   ExpectPath(false);
389   S[0] = OldBB;
390   ExpectPath(true);
391 }