1*9880d681SAndroid Build Coastguard Worker //===- Local.cpp - Unit tests for Local -----------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/Local.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/BasicBlock.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
15*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker using namespace llvm;
18*9880d681SAndroid Build Coastguard Worker
TEST(Local,RecursivelyDeleteDeadPHINodes)19*9880d681SAndroid Build Coastguard Worker TEST(Local, RecursivelyDeleteDeadPHINodes) {
20*9880d681SAndroid Build Coastguard Worker LLVMContext C;
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker IRBuilder<> builder(C);
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker // Make blocks
25*9880d681SAndroid Build Coastguard Worker BasicBlock *bb0 = BasicBlock::Create(C);
26*9880d681SAndroid Build Coastguard Worker BasicBlock *bb1 = BasicBlock::Create(C);
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker builder.SetInsertPoint(bb0);
29*9880d681SAndroid Build Coastguard Worker PHINode *phi = builder.CreatePHI(Type::getInt32Ty(C), 2);
30*9880d681SAndroid Build Coastguard Worker BranchInst *br0 = builder.CreateCondBr(builder.getTrue(), bb0, bb1);
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker builder.SetInsertPoint(bb1);
33*9880d681SAndroid Build Coastguard Worker BranchInst *br1 = builder.CreateBr(bb0);
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker phi->addIncoming(phi, bb0);
36*9880d681SAndroid Build Coastguard Worker phi->addIncoming(phi, bb1);
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker // The PHI will be removed
39*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker // Make sure the blocks only contain the branches
42*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(&bb0->front(), br0);
43*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(&bb1->front(), br1);
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker builder.SetInsertPoint(bb0);
46*9880d681SAndroid Build Coastguard Worker phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker builder.SetInsertPoint(bb0);
51*9880d681SAndroid Build Coastguard Worker phi = builder.CreatePHI(Type::getInt32Ty(C), 0);
52*9880d681SAndroid Build Coastguard Worker builder.CreateAdd(phi, phi);
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(RecursivelyDeleteDeadPHINode(phi));
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker bb0->dropAllReferences();
57*9880d681SAndroid Build Coastguard Worker bb1->dropAllReferences();
58*9880d681SAndroid Build Coastguard Worker delete bb0;
59*9880d681SAndroid Build Coastguard Worker delete bb1;
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
TEST(Local,RemoveDuplicatePHINodes)62*9880d681SAndroid Build Coastguard Worker TEST(Local, RemoveDuplicatePHINodes) {
63*9880d681SAndroid Build Coastguard Worker LLVMContext C;
64*9880d681SAndroid Build Coastguard Worker IRBuilder<> B(C);
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Function> F(
67*9880d681SAndroid Build Coastguard Worker Function::Create(FunctionType::get(B.getVoidTy(), false),
68*9880d681SAndroid Build Coastguard Worker GlobalValue::ExternalLinkage, "F"));
69*9880d681SAndroid Build Coastguard Worker BasicBlock *Entry(BasicBlock::Create(C, "", F.get()));
70*9880d681SAndroid Build Coastguard Worker BasicBlock *BB(BasicBlock::Create(C, "", F.get()));
71*9880d681SAndroid Build Coastguard Worker BranchInst::Create(BB, Entry);
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker B.SetInsertPoint(BB);
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker AssertingVH<PHINode> P1 = B.CreatePHI(Type::getInt32Ty(C), 2);
76*9880d681SAndroid Build Coastguard Worker P1->addIncoming(B.getInt32(42), Entry);
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker PHINode *P2 = B.CreatePHI(Type::getInt32Ty(C), 2);
79*9880d681SAndroid Build Coastguard Worker P2->addIncoming(B.getInt32(42), Entry);
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker AssertingVH<PHINode> P3 = B.CreatePHI(Type::getInt32Ty(C), 2);
82*9880d681SAndroid Build Coastguard Worker P3->addIncoming(B.getInt32(42), Entry);
83*9880d681SAndroid Build Coastguard Worker P3->addIncoming(B.getInt32(23), BB);
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker PHINode *P4 = B.CreatePHI(Type::getInt32Ty(C), 2);
86*9880d681SAndroid Build Coastguard Worker P4->addIncoming(B.getInt32(42), Entry);
87*9880d681SAndroid Build Coastguard Worker P4->addIncoming(B.getInt32(23), BB);
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker P1->addIncoming(P3, BB);
90*9880d681SAndroid Build Coastguard Worker P2->addIncoming(P4, BB);
91*9880d681SAndroid Build Coastguard Worker BranchInst::Create(BB, BB);
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker // Verify that we can eliminate PHIs that become duplicates after chaning PHIs
94*9880d681SAndroid Build Coastguard Worker // downstream.
95*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(EliminateDuplicatePHINodes(BB));
96*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(3U, BB->size());
97*9880d681SAndroid Build Coastguard Worker }
98