1*9880d681SAndroid Build Coastguard Worker //===- FlatternCFG.cpp - Code to perform CFG flattening ---------------===//
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 // Reduce conditional branches in CFG.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/Local.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallPtrSet.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/AliasAnalysis.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ValueTracking.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
22*9880d681SAndroid Build Coastguard Worker using namespace llvm;
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "flattencfg"
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker namespace {
27*9880d681SAndroid Build Coastguard Worker class FlattenCFGOpt {
28*9880d681SAndroid Build Coastguard Worker AliasAnalysis *AA;
29*9880d681SAndroid Build Coastguard Worker /// \brief Use parallel-and or parallel-or to generate conditions for
30*9880d681SAndroid Build Coastguard Worker /// conditional branches.
31*9880d681SAndroid Build Coastguard Worker bool FlattenParallelAndOr(BasicBlock *BB, IRBuilder<> &Builder);
32*9880d681SAndroid Build Coastguard Worker /// \brief If \param BB is the merge block of an if-region, attempt to merge
33*9880d681SAndroid Build Coastguard Worker /// the if-region with an adjacent if-region upstream if two if-regions
34*9880d681SAndroid Build Coastguard Worker /// contain identical instructions.
35*9880d681SAndroid Build Coastguard Worker bool MergeIfRegion(BasicBlock *BB, IRBuilder<> &Builder);
36*9880d681SAndroid Build Coastguard Worker /// \brief Compare a pair of blocks: \p Block1 and \p Block2, which
37*9880d681SAndroid Build Coastguard Worker /// are from two if-regions whose entry blocks are \p Head1 and \p
38*9880d681SAndroid Build Coastguard Worker /// Head2. \returns true if \p Block1 and \p Block2 contain identical
39*9880d681SAndroid Build Coastguard Worker /// instructions, and have no memory reference alias with \p Head2.
40*9880d681SAndroid Build Coastguard Worker /// This is used as a legality check for merging if-regions.
41*9880d681SAndroid Build Coastguard Worker bool CompareIfRegionBlock(BasicBlock *Head1, BasicBlock *Head2,
42*9880d681SAndroid Build Coastguard Worker BasicBlock *Block1, BasicBlock *Block2);
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker public:
FlattenCFGOpt(AliasAnalysis * AA)45*9880d681SAndroid Build Coastguard Worker FlattenCFGOpt(AliasAnalysis *AA) : AA(AA) {}
46*9880d681SAndroid Build Coastguard Worker bool run(BasicBlock *BB);
47*9880d681SAndroid Build Coastguard Worker };
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker /// If \param [in] BB has more than one predecessor that is a conditional
51*9880d681SAndroid Build Coastguard Worker /// branch, attempt to use parallel and/or for the branch condition. \returns
52*9880d681SAndroid Build Coastguard Worker /// true on success.
53*9880d681SAndroid Build Coastguard Worker ///
54*9880d681SAndroid Build Coastguard Worker /// Before:
55*9880d681SAndroid Build Coastguard Worker /// ......
56*9880d681SAndroid Build Coastguard Worker /// %cmp10 = fcmp une float %tmp1, %tmp2
57*9880d681SAndroid Build Coastguard Worker /// br i1 %cmp1, label %if.then, label %lor.rhs
58*9880d681SAndroid Build Coastguard Worker ///
59*9880d681SAndroid Build Coastguard Worker /// lor.rhs:
60*9880d681SAndroid Build Coastguard Worker /// ......
61*9880d681SAndroid Build Coastguard Worker /// %cmp11 = fcmp une float %tmp3, %tmp4
62*9880d681SAndroid Build Coastguard Worker /// br i1 %cmp11, label %if.then, label %ifend
63*9880d681SAndroid Build Coastguard Worker ///
64*9880d681SAndroid Build Coastguard Worker /// if.end: // the merge block
65*9880d681SAndroid Build Coastguard Worker /// ......
66*9880d681SAndroid Build Coastguard Worker ///
67*9880d681SAndroid Build Coastguard Worker /// if.then: // has two predecessors, both of them contains conditional branch.
68*9880d681SAndroid Build Coastguard Worker /// ......
69*9880d681SAndroid Build Coastguard Worker /// br label %if.end;
70*9880d681SAndroid Build Coastguard Worker ///
71*9880d681SAndroid Build Coastguard Worker /// After:
72*9880d681SAndroid Build Coastguard Worker /// ......
73*9880d681SAndroid Build Coastguard Worker /// %cmp10 = fcmp une float %tmp1, %tmp2
74*9880d681SAndroid Build Coastguard Worker /// ......
75*9880d681SAndroid Build Coastguard Worker /// %cmp11 = fcmp une float %tmp3, %tmp4
76*9880d681SAndroid Build Coastguard Worker /// %cmp12 = or i1 %cmp10, %cmp11 // parallel-or mode.
77*9880d681SAndroid Build Coastguard Worker /// br i1 %cmp12, label %if.then, label %ifend
78*9880d681SAndroid Build Coastguard Worker ///
79*9880d681SAndroid Build Coastguard Worker /// if.end:
80*9880d681SAndroid Build Coastguard Worker /// ......
81*9880d681SAndroid Build Coastguard Worker ///
82*9880d681SAndroid Build Coastguard Worker /// if.then:
83*9880d681SAndroid Build Coastguard Worker /// ......
84*9880d681SAndroid Build Coastguard Worker /// br label %if.end;
85*9880d681SAndroid Build Coastguard Worker ///
86*9880d681SAndroid Build Coastguard Worker /// Current implementation handles two cases.
87*9880d681SAndroid Build Coastguard Worker /// Case 1: \param BB is on the else-path.
88*9880d681SAndroid Build Coastguard Worker ///
89*9880d681SAndroid Build Coastguard Worker /// BB1
90*9880d681SAndroid Build Coastguard Worker /// / |
91*9880d681SAndroid Build Coastguard Worker /// BB2 |
92*9880d681SAndroid Build Coastguard Worker /// / \ |
93*9880d681SAndroid Build Coastguard Worker /// BB3 \ | where, BB1, BB2 contain conditional branches.
94*9880d681SAndroid Build Coastguard Worker /// \ | / BB3 contains unconditional branch.
95*9880d681SAndroid Build Coastguard Worker /// \ | / BB4 corresponds to \param BB which is also the merge.
96*9880d681SAndroid Build Coastguard Worker /// BB => BB4
97*9880d681SAndroid Build Coastguard Worker ///
98*9880d681SAndroid Build Coastguard Worker ///
99*9880d681SAndroid Build Coastguard Worker /// Corresponding source code:
100*9880d681SAndroid Build Coastguard Worker ///
101*9880d681SAndroid Build Coastguard Worker /// if (a == b && c == d)
102*9880d681SAndroid Build Coastguard Worker /// statement; // BB3
103*9880d681SAndroid Build Coastguard Worker ///
104*9880d681SAndroid Build Coastguard Worker /// Case 2: \param BB BB is on the then-path.
105*9880d681SAndroid Build Coastguard Worker ///
106*9880d681SAndroid Build Coastguard Worker /// BB1
107*9880d681SAndroid Build Coastguard Worker /// / |
108*9880d681SAndroid Build Coastguard Worker /// | BB2
109*9880d681SAndroid Build Coastguard Worker /// \ / | where BB1, BB2 contain conditional branches.
110*9880d681SAndroid Build Coastguard Worker /// BB => BB3 | BB3 contains unconditiona branch and corresponds
111*9880d681SAndroid Build Coastguard Worker /// \ / to \param BB. BB4 is the merge.
112*9880d681SAndroid Build Coastguard Worker /// BB4
113*9880d681SAndroid Build Coastguard Worker ///
114*9880d681SAndroid Build Coastguard Worker /// Corresponding source code:
115*9880d681SAndroid Build Coastguard Worker ///
116*9880d681SAndroid Build Coastguard Worker /// if (a == b || c == d)
117*9880d681SAndroid Build Coastguard Worker /// statement; // BB3
118*9880d681SAndroid Build Coastguard Worker ///
119*9880d681SAndroid Build Coastguard Worker /// In both cases, \param BB is the common successor of conditional branches.
120*9880d681SAndroid Build Coastguard Worker /// In Case 1, \param BB (BB4) has an unconditional branch (BB3) as
121*9880d681SAndroid Build Coastguard Worker /// its predecessor. In Case 2, \param BB (BB3) only has conditional branches
122*9880d681SAndroid Build Coastguard Worker /// as its predecessors.
123*9880d681SAndroid Build Coastguard Worker ///
FlattenParallelAndOr(BasicBlock * BB,IRBuilder<> & Builder)124*9880d681SAndroid Build Coastguard Worker bool FlattenCFGOpt::FlattenParallelAndOr(BasicBlock *BB, IRBuilder<> &Builder) {
125*9880d681SAndroid Build Coastguard Worker PHINode *PHI = dyn_cast<PHINode>(BB->begin());
126*9880d681SAndroid Build Coastguard Worker if (PHI)
127*9880d681SAndroid Build Coastguard Worker return false; // For simplicity, avoid cases containing PHI nodes.
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker BasicBlock *LastCondBlock = nullptr;
130*9880d681SAndroid Build Coastguard Worker BasicBlock *FirstCondBlock = nullptr;
131*9880d681SAndroid Build Coastguard Worker BasicBlock *UnCondBlock = nullptr;
132*9880d681SAndroid Build Coastguard Worker int Idx = -1;
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker // Check predecessors of \param BB.
135*9880d681SAndroid Build Coastguard Worker SmallPtrSet<BasicBlock *, 16> Preds(pred_begin(BB), pred_end(BB));
136*9880d681SAndroid Build Coastguard Worker for (SmallPtrSetIterator<BasicBlock *> PI = Preds.begin(), PE = Preds.end();
137*9880d681SAndroid Build Coastguard Worker PI != PE; ++PI) {
138*9880d681SAndroid Build Coastguard Worker BasicBlock *Pred = *PI;
139*9880d681SAndroid Build Coastguard Worker BranchInst *PBI = dyn_cast<BranchInst>(Pred->getTerminator());
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker // All predecessors should terminate with a branch.
142*9880d681SAndroid Build Coastguard Worker if (!PBI)
143*9880d681SAndroid Build Coastguard Worker return false;
144*9880d681SAndroid Build Coastguard Worker
145*9880d681SAndroid Build Coastguard Worker BasicBlock *PP = Pred->getSinglePredecessor();
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker if (PBI->isUnconditional()) {
148*9880d681SAndroid Build Coastguard Worker // Case 1: Pred (BB3) is an unconditional block, it should
149*9880d681SAndroid Build Coastguard Worker // have a single predecessor (BB2) that is also a predecessor
150*9880d681SAndroid Build Coastguard Worker // of \param BB (BB4) and should not have address-taken.
151*9880d681SAndroid Build Coastguard Worker // There should exist only one such unconditional
152*9880d681SAndroid Build Coastguard Worker // branch among the predecessors.
153*9880d681SAndroid Build Coastguard Worker if (UnCondBlock || !PP || (Preds.count(PP) == 0) ||
154*9880d681SAndroid Build Coastguard Worker Pred->hasAddressTaken())
155*9880d681SAndroid Build Coastguard Worker return false;
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker UnCondBlock = Pred;
158*9880d681SAndroid Build Coastguard Worker continue;
159*9880d681SAndroid Build Coastguard Worker }
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Worker // Only conditional branches are allowed beyond this point.
162*9880d681SAndroid Build Coastguard Worker assert(PBI->isConditional());
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker // Condition's unique use should be the branch instruction.
165*9880d681SAndroid Build Coastguard Worker Value *PC = PBI->getCondition();
166*9880d681SAndroid Build Coastguard Worker if (!PC || !PC->hasOneUse())
167*9880d681SAndroid Build Coastguard Worker return false;
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker if (PP && Preds.count(PP)) {
170*9880d681SAndroid Build Coastguard Worker // These are internal condition blocks to be merged from, e.g.,
171*9880d681SAndroid Build Coastguard Worker // BB2 in both cases.
172*9880d681SAndroid Build Coastguard Worker // Should not be address-taken.
173*9880d681SAndroid Build Coastguard Worker if (Pred->hasAddressTaken())
174*9880d681SAndroid Build Coastguard Worker return false;
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker // Instructions in the internal condition blocks should be safe
177*9880d681SAndroid Build Coastguard Worker // to hoist up.
178*9880d681SAndroid Build Coastguard Worker for (BasicBlock::iterator BI = Pred->begin(), BE = PBI->getIterator();
179*9880d681SAndroid Build Coastguard Worker BI != BE;) {
180*9880d681SAndroid Build Coastguard Worker Instruction *CI = &*BI++;
181*9880d681SAndroid Build Coastguard Worker if (isa<PHINode>(CI) || !isSafeToSpeculativelyExecute(CI))
182*9880d681SAndroid Build Coastguard Worker return false;
183*9880d681SAndroid Build Coastguard Worker }
184*9880d681SAndroid Build Coastguard Worker } else {
185*9880d681SAndroid Build Coastguard Worker // This is the condition block to be merged into, e.g. BB1 in
186*9880d681SAndroid Build Coastguard Worker // both cases.
187*9880d681SAndroid Build Coastguard Worker if (FirstCondBlock)
188*9880d681SAndroid Build Coastguard Worker return false;
189*9880d681SAndroid Build Coastguard Worker FirstCondBlock = Pred;
190*9880d681SAndroid Build Coastguard Worker }
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker // Find whether BB is uniformly on the true (or false) path
193*9880d681SAndroid Build Coastguard Worker // for all of its predecessors.
194*9880d681SAndroid Build Coastguard Worker BasicBlock *PS1 = PBI->getSuccessor(0);
195*9880d681SAndroid Build Coastguard Worker BasicBlock *PS2 = PBI->getSuccessor(1);
196*9880d681SAndroid Build Coastguard Worker BasicBlock *PS = (PS1 == BB) ? PS2 : PS1;
197*9880d681SAndroid Build Coastguard Worker int CIdx = (PS1 == BB) ? 0 : 1;
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker if (Idx == -1)
200*9880d681SAndroid Build Coastguard Worker Idx = CIdx;
201*9880d681SAndroid Build Coastguard Worker else if (CIdx != Idx)
202*9880d681SAndroid Build Coastguard Worker return false;
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker // PS is the successor which is not BB. Check successors to identify
205*9880d681SAndroid Build Coastguard Worker // the last conditional branch.
206*9880d681SAndroid Build Coastguard Worker if (Preds.count(PS) == 0) {
207*9880d681SAndroid Build Coastguard Worker // Case 2.
208*9880d681SAndroid Build Coastguard Worker LastCondBlock = Pred;
209*9880d681SAndroid Build Coastguard Worker } else {
210*9880d681SAndroid Build Coastguard Worker // Case 1
211*9880d681SAndroid Build Coastguard Worker BranchInst *BPS = dyn_cast<BranchInst>(PS->getTerminator());
212*9880d681SAndroid Build Coastguard Worker if (BPS && BPS->isUnconditional()) {
213*9880d681SAndroid Build Coastguard Worker // Case 1: PS(BB3) should be an unconditional branch.
214*9880d681SAndroid Build Coastguard Worker LastCondBlock = Pred;
215*9880d681SAndroid Build Coastguard Worker }
216*9880d681SAndroid Build Coastguard Worker }
217*9880d681SAndroid Build Coastguard Worker }
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker if (!FirstCondBlock || !LastCondBlock || (FirstCondBlock == LastCondBlock))
220*9880d681SAndroid Build Coastguard Worker return false;
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker TerminatorInst *TBB = LastCondBlock->getTerminator();
223*9880d681SAndroid Build Coastguard Worker BasicBlock *PS1 = TBB->getSuccessor(0);
224*9880d681SAndroid Build Coastguard Worker BasicBlock *PS2 = TBB->getSuccessor(1);
225*9880d681SAndroid Build Coastguard Worker BranchInst *PBI1 = dyn_cast<BranchInst>(PS1->getTerminator());
226*9880d681SAndroid Build Coastguard Worker BranchInst *PBI2 = dyn_cast<BranchInst>(PS2->getTerminator());
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker // If PS1 does not jump into PS2, but PS2 jumps into PS1,
229*9880d681SAndroid Build Coastguard Worker // attempt branch inversion.
230*9880d681SAndroid Build Coastguard Worker if (!PBI1 || !PBI1->isUnconditional() ||
231*9880d681SAndroid Build Coastguard Worker (PS1->getTerminator()->getSuccessor(0) != PS2)) {
232*9880d681SAndroid Build Coastguard Worker // Check whether PS2 jumps into PS1.
233*9880d681SAndroid Build Coastguard Worker if (!PBI2 || !PBI2->isUnconditional() ||
234*9880d681SAndroid Build Coastguard Worker (PS2->getTerminator()->getSuccessor(0) != PS1))
235*9880d681SAndroid Build Coastguard Worker return false;
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Worker // Do branch inversion.
238*9880d681SAndroid Build Coastguard Worker BasicBlock *CurrBlock = LastCondBlock;
239*9880d681SAndroid Build Coastguard Worker bool EverChanged = false;
240*9880d681SAndroid Build Coastguard Worker for (;CurrBlock != FirstCondBlock;
241*9880d681SAndroid Build Coastguard Worker CurrBlock = CurrBlock->getSinglePredecessor()) {
242*9880d681SAndroid Build Coastguard Worker BranchInst *BI = dyn_cast<BranchInst>(CurrBlock->getTerminator());
243*9880d681SAndroid Build Coastguard Worker CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition());
244*9880d681SAndroid Build Coastguard Worker if (!CI)
245*9880d681SAndroid Build Coastguard Worker continue;
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker CmpInst::Predicate Predicate = CI->getPredicate();
248*9880d681SAndroid Build Coastguard Worker // Canonicalize icmp_ne -> icmp_eq, fcmp_one -> fcmp_oeq
249*9880d681SAndroid Build Coastguard Worker if ((Predicate == CmpInst::ICMP_NE) || (Predicate == CmpInst::FCMP_ONE)) {
250*9880d681SAndroid Build Coastguard Worker CI->setPredicate(ICmpInst::getInversePredicate(Predicate));
251*9880d681SAndroid Build Coastguard Worker BI->swapSuccessors();
252*9880d681SAndroid Build Coastguard Worker EverChanged = true;
253*9880d681SAndroid Build Coastguard Worker }
254*9880d681SAndroid Build Coastguard Worker }
255*9880d681SAndroid Build Coastguard Worker return EverChanged;
256*9880d681SAndroid Build Coastguard Worker }
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Worker // PS1 must have a conditional branch.
259*9880d681SAndroid Build Coastguard Worker if (!PBI1 || !PBI1->isUnconditional())
260*9880d681SAndroid Build Coastguard Worker return false;
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker // PS2 should not contain PHI node.
263*9880d681SAndroid Build Coastguard Worker PHI = dyn_cast<PHINode>(PS2->begin());
264*9880d681SAndroid Build Coastguard Worker if (PHI)
265*9880d681SAndroid Build Coastguard Worker return false;
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker // Do the transformation.
268*9880d681SAndroid Build Coastguard Worker BasicBlock *CB;
269*9880d681SAndroid Build Coastguard Worker BranchInst *PBI = dyn_cast<BranchInst>(FirstCondBlock->getTerminator());
270*9880d681SAndroid Build Coastguard Worker bool Iteration = true;
271*9880d681SAndroid Build Coastguard Worker IRBuilder<>::InsertPointGuard Guard(Builder);
272*9880d681SAndroid Build Coastguard Worker Value *PC = PBI->getCondition();
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Worker do {
275*9880d681SAndroid Build Coastguard Worker CB = PBI->getSuccessor(1 - Idx);
276*9880d681SAndroid Build Coastguard Worker // Delete the conditional branch.
277*9880d681SAndroid Build Coastguard Worker FirstCondBlock->getInstList().pop_back();
278*9880d681SAndroid Build Coastguard Worker FirstCondBlock->getInstList()
279*9880d681SAndroid Build Coastguard Worker .splice(FirstCondBlock->end(), CB->getInstList());
280*9880d681SAndroid Build Coastguard Worker PBI = cast<BranchInst>(FirstCondBlock->getTerminator());
281*9880d681SAndroid Build Coastguard Worker Value *CC = PBI->getCondition();
282*9880d681SAndroid Build Coastguard Worker // Merge conditions.
283*9880d681SAndroid Build Coastguard Worker Builder.SetInsertPoint(PBI);
284*9880d681SAndroid Build Coastguard Worker Value *NC;
285*9880d681SAndroid Build Coastguard Worker if (Idx == 0)
286*9880d681SAndroid Build Coastguard Worker // Case 2, use parallel or.
287*9880d681SAndroid Build Coastguard Worker NC = Builder.CreateOr(PC, CC);
288*9880d681SAndroid Build Coastguard Worker else
289*9880d681SAndroid Build Coastguard Worker // Case 1, use parallel and.
290*9880d681SAndroid Build Coastguard Worker NC = Builder.CreateAnd(PC, CC);
291*9880d681SAndroid Build Coastguard Worker
292*9880d681SAndroid Build Coastguard Worker PBI->replaceUsesOfWith(CC, NC);
293*9880d681SAndroid Build Coastguard Worker PC = NC;
294*9880d681SAndroid Build Coastguard Worker if (CB == LastCondBlock)
295*9880d681SAndroid Build Coastguard Worker Iteration = false;
296*9880d681SAndroid Build Coastguard Worker // Remove internal conditional branches.
297*9880d681SAndroid Build Coastguard Worker CB->dropAllReferences();
298*9880d681SAndroid Build Coastguard Worker // make CB unreachable and let downstream to delete the block.
299*9880d681SAndroid Build Coastguard Worker new UnreachableInst(CB->getContext(), CB);
300*9880d681SAndroid Build Coastguard Worker } while (Iteration);
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Use parallel and/or in:\n" << *FirstCondBlock);
303*9880d681SAndroid Build Coastguard Worker return true;
304*9880d681SAndroid Build Coastguard Worker }
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Worker /// Compare blocks from two if-regions, where \param Head1 is the entry of the
307*9880d681SAndroid Build Coastguard Worker /// 1st if-region. \param Head2 is the entry of the 2nd if-region. \param
308*9880d681SAndroid Build Coastguard Worker /// Block1 is a block in the 1st if-region to compare. \param Block2 is a block
309*9880d681SAndroid Build Coastguard Worker // in the 2nd if-region to compare. \returns true if \param Block1 and \param
310*9880d681SAndroid Build Coastguard Worker /// Block2 have identical instructions and do not have memory reference alias
311*9880d681SAndroid Build Coastguard Worker /// with \param Head2.
312*9880d681SAndroid Build Coastguard Worker ///
CompareIfRegionBlock(BasicBlock * Head1,BasicBlock * Head2,BasicBlock * Block1,BasicBlock * Block2)313*9880d681SAndroid Build Coastguard Worker bool FlattenCFGOpt::CompareIfRegionBlock(BasicBlock *Head1, BasicBlock *Head2,
314*9880d681SAndroid Build Coastguard Worker BasicBlock *Block1,
315*9880d681SAndroid Build Coastguard Worker BasicBlock *Block2) {
316*9880d681SAndroid Build Coastguard Worker TerminatorInst *PTI2 = Head2->getTerminator();
317*9880d681SAndroid Build Coastguard Worker Instruction *PBI2 = &Head2->front();
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker bool eq1 = (Block1 == Head1);
320*9880d681SAndroid Build Coastguard Worker bool eq2 = (Block2 == Head2);
321*9880d681SAndroid Build Coastguard Worker if (eq1 || eq2) {
322*9880d681SAndroid Build Coastguard Worker // An empty then-path or else-path.
323*9880d681SAndroid Build Coastguard Worker return (eq1 == eq2);
324*9880d681SAndroid Build Coastguard Worker }
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Worker // Check whether instructions in Block1 and Block2 are identical
327*9880d681SAndroid Build Coastguard Worker // and do not alias with instructions in Head2.
328*9880d681SAndroid Build Coastguard Worker BasicBlock::iterator iter1 = Block1->begin();
329*9880d681SAndroid Build Coastguard Worker BasicBlock::iterator end1 = Block1->getTerminator()->getIterator();
330*9880d681SAndroid Build Coastguard Worker BasicBlock::iterator iter2 = Block2->begin();
331*9880d681SAndroid Build Coastguard Worker BasicBlock::iterator end2 = Block2->getTerminator()->getIterator();
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker while (1) {
334*9880d681SAndroid Build Coastguard Worker if (iter1 == end1) {
335*9880d681SAndroid Build Coastguard Worker if (iter2 != end2)
336*9880d681SAndroid Build Coastguard Worker return false;
337*9880d681SAndroid Build Coastguard Worker break;
338*9880d681SAndroid Build Coastguard Worker }
339*9880d681SAndroid Build Coastguard Worker
340*9880d681SAndroid Build Coastguard Worker if (!iter1->isIdenticalTo(&*iter2))
341*9880d681SAndroid Build Coastguard Worker return false;
342*9880d681SAndroid Build Coastguard Worker
343*9880d681SAndroid Build Coastguard Worker // Illegal to remove instructions with side effects except
344*9880d681SAndroid Build Coastguard Worker // non-volatile stores.
345*9880d681SAndroid Build Coastguard Worker if (iter1->mayHaveSideEffects()) {
346*9880d681SAndroid Build Coastguard Worker Instruction *CurI = &*iter1;
347*9880d681SAndroid Build Coastguard Worker StoreInst *SI = dyn_cast<StoreInst>(CurI);
348*9880d681SAndroid Build Coastguard Worker if (!SI || SI->isVolatile())
349*9880d681SAndroid Build Coastguard Worker return false;
350*9880d681SAndroid Build Coastguard Worker }
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Worker // For simplicity and speed, data dependency check can be
353*9880d681SAndroid Build Coastguard Worker // avoided if read from memory doesn't exist.
354*9880d681SAndroid Build Coastguard Worker if (iter1->mayReadFromMemory())
355*9880d681SAndroid Build Coastguard Worker return false;
356*9880d681SAndroid Build Coastguard Worker
357*9880d681SAndroid Build Coastguard Worker if (iter1->mayWriteToMemory()) {
358*9880d681SAndroid Build Coastguard Worker for (BasicBlock::iterator BI(PBI2), BE(PTI2); BI != BE; ++BI) {
359*9880d681SAndroid Build Coastguard Worker if (BI->mayReadFromMemory() || BI->mayWriteToMemory()) {
360*9880d681SAndroid Build Coastguard Worker // Check alias with Head2.
361*9880d681SAndroid Build Coastguard Worker if (!AA || AA->alias(&*iter1, &*BI))
362*9880d681SAndroid Build Coastguard Worker return false;
363*9880d681SAndroid Build Coastguard Worker }
364*9880d681SAndroid Build Coastguard Worker }
365*9880d681SAndroid Build Coastguard Worker }
366*9880d681SAndroid Build Coastguard Worker ++iter1;
367*9880d681SAndroid Build Coastguard Worker ++iter2;
368*9880d681SAndroid Build Coastguard Worker }
369*9880d681SAndroid Build Coastguard Worker
370*9880d681SAndroid Build Coastguard Worker return true;
371*9880d681SAndroid Build Coastguard Worker }
372*9880d681SAndroid Build Coastguard Worker
373*9880d681SAndroid Build Coastguard Worker /// Check whether \param BB is the merge block of a if-region. If yes, check
374*9880d681SAndroid Build Coastguard Worker /// whether there exists an adjacent if-region upstream, the two if-regions
375*9880d681SAndroid Build Coastguard Worker /// contain identical instructions and can be legally merged. \returns true if
376*9880d681SAndroid Build Coastguard Worker /// the two if-regions are merged.
377*9880d681SAndroid Build Coastguard Worker ///
378*9880d681SAndroid Build Coastguard Worker /// From:
379*9880d681SAndroid Build Coastguard Worker /// if (a)
380*9880d681SAndroid Build Coastguard Worker /// statement;
381*9880d681SAndroid Build Coastguard Worker /// if (b)
382*9880d681SAndroid Build Coastguard Worker /// statement;
383*9880d681SAndroid Build Coastguard Worker ///
384*9880d681SAndroid Build Coastguard Worker /// To:
385*9880d681SAndroid Build Coastguard Worker /// if (a || b)
386*9880d681SAndroid Build Coastguard Worker /// statement;
387*9880d681SAndroid Build Coastguard Worker ///
MergeIfRegion(BasicBlock * BB,IRBuilder<> & Builder)388*9880d681SAndroid Build Coastguard Worker bool FlattenCFGOpt::MergeIfRegion(BasicBlock *BB, IRBuilder<> &Builder) {
389*9880d681SAndroid Build Coastguard Worker BasicBlock *IfTrue2, *IfFalse2;
390*9880d681SAndroid Build Coastguard Worker Value *IfCond2 = GetIfCondition(BB, IfTrue2, IfFalse2);
391*9880d681SAndroid Build Coastguard Worker Instruction *CInst2 = dyn_cast_or_null<Instruction>(IfCond2);
392*9880d681SAndroid Build Coastguard Worker if (!CInst2)
393*9880d681SAndroid Build Coastguard Worker return false;
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Worker BasicBlock *SecondEntryBlock = CInst2->getParent();
396*9880d681SAndroid Build Coastguard Worker if (SecondEntryBlock->hasAddressTaken())
397*9880d681SAndroid Build Coastguard Worker return false;
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Worker BasicBlock *IfTrue1, *IfFalse1;
400*9880d681SAndroid Build Coastguard Worker Value *IfCond1 = GetIfCondition(SecondEntryBlock, IfTrue1, IfFalse1);
401*9880d681SAndroid Build Coastguard Worker Instruction *CInst1 = dyn_cast_or_null<Instruction>(IfCond1);
402*9880d681SAndroid Build Coastguard Worker if (!CInst1)
403*9880d681SAndroid Build Coastguard Worker return false;
404*9880d681SAndroid Build Coastguard Worker
405*9880d681SAndroid Build Coastguard Worker BasicBlock *FirstEntryBlock = CInst1->getParent();
406*9880d681SAndroid Build Coastguard Worker
407*9880d681SAndroid Build Coastguard Worker // Either then-path or else-path should be empty.
408*9880d681SAndroid Build Coastguard Worker if ((IfTrue1 != FirstEntryBlock) && (IfFalse1 != FirstEntryBlock))
409*9880d681SAndroid Build Coastguard Worker return false;
410*9880d681SAndroid Build Coastguard Worker if ((IfTrue2 != SecondEntryBlock) && (IfFalse2 != SecondEntryBlock))
411*9880d681SAndroid Build Coastguard Worker return false;
412*9880d681SAndroid Build Coastguard Worker
413*9880d681SAndroid Build Coastguard Worker TerminatorInst *PTI2 = SecondEntryBlock->getTerminator();
414*9880d681SAndroid Build Coastguard Worker Instruction *PBI2 = &SecondEntryBlock->front();
415*9880d681SAndroid Build Coastguard Worker
416*9880d681SAndroid Build Coastguard Worker if (!CompareIfRegionBlock(FirstEntryBlock, SecondEntryBlock, IfTrue1,
417*9880d681SAndroid Build Coastguard Worker IfTrue2))
418*9880d681SAndroid Build Coastguard Worker return false;
419*9880d681SAndroid Build Coastguard Worker
420*9880d681SAndroid Build Coastguard Worker if (!CompareIfRegionBlock(FirstEntryBlock, SecondEntryBlock, IfFalse1,
421*9880d681SAndroid Build Coastguard Worker IfFalse2))
422*9880d681SAndroid Build Coastguard Worker return false;
423*9880d681SAndroid Build Coastguard Worker
424*9880d681SAndroid Build Coastguard Worker // Check whether \param SecondEntryBlock has side-effect and is safe to
425*9880d681SAndroid Build Coastguard Worker // speculate.
426*9880d681SAndroid Build Coastguard Worker for (BasicBlock::iterator BI(PBI2), BE(PTI2); BI != BE; ++BI) {
427*9880d681SAndroid Build Coastguard Worker Instruction *CI = &*BI;
428*9880d681SAndroid Build Coastguard Worker if (isa<PHINode>(CI) || CI->mayHaveSideEffects() ||
429*9880d681SAndroid Build Coastguard Worker !isSafeToSpeculativelyExecute(CI))
430*9880d681SAndroid Build Coastguard Worker return false;
431*9880d681SAndroid Build Coastguard Worker }
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Worker // Merge \param SecondEntryBlock into \param FirstEntryBlock.
434*9880d681SAndroid Build Coastguard Worker FirstEntryBlock->getInstList().pop_back();
435*9880d681SAndroid Build Coastguard Worker FirstEntryBlock->getInstList()
436*9880d681SAndroid Build Coastguard Worker .splice(FirstEntryBlock->end(), SecondEntryBlock->getInstList());
437*9880d681SAndroid Build Coastguard Worker BranchInst *PBI = dyn_cast<BranchInst>(FirstEntryBlock->getTerminator());
438*9880d681SAndroid Build Coastguard Worker Value *CC = PBI->getCondition();
439*9880d681SAndroid Build Coastguard Worker BasicBlock *SaveInsertBB = Builder.GetInsertBlock();
440*9880d681SAndroid Build Coastguard Worker BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint();
441*9880d681SAndroid Build Coastguard Worker Builder.SetInsertPoint(PBI);
442*9880d681SAndroid Build Coastguard Worker Value *NC = Builder.CreateOr(CInst1, CC);
443*9880d681SAndroid Build Coastguard Worker PBI->replaceUsesOfWith(CC, NC);
444*9880d681SAndroid Build Coastguard Worker Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker // Remove IfTrue1
447*9880d681SAndroid Build Coastguard Worker if (IfTrue1 != FirstEntryBlock) {
448*9880d681SAndroid Build Coastguard Worker IfTrue1->dropAllReferences();
449*9880d681SAndroid Build Coastguard Worker IfTrue1->eraseFromParent();
450*9880d681SAndroid Build Coastguard Worker }
451*9880d681SAndroid Build Coastguard Worker
452*9880d681SAndroid Build Coastguard Worker // Remove IfFalse1
453*9880d681SAndroid Build Coastguard Worker if (IfFalse1 != FirstEntryBlock) {
454*9880d681SAndroid Build Coastguard Worker IfFalse1->dropAllReferences();
455*9880d681SAndroid Build Coastguard Worker IfFalse1->eraseFromParent();
456*9880d681SAndroid Build Coastguard Worker }
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker // Remove \param SecondEntryBlock
459*9880d681SAndroid Build Coastguard Worker SecondEntryBlock->dropAllReferences();
460*9880d681SAndroid Build Coastguard Worker SecondEntryBlock->eraseFromParent();
461*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "If conditions merged into:\n" << *FirstEntryBlock);
462*9880d681SAndroid Build Coastguard Worker return true;
463*9880d681SAndroid Build Coastguard Worker }
464*9880d681SAndroid Build Coastguard Worker
run(BasicBlock * BB)465*9880d681SAndroid Build Coastguard Worker bool FlattenCFGOpt::run(BasicBlock *BB) {
466*9880d681SAndroid Build Coastguard Worker bool Changed = false;
467*9880d681SAndroid Build Coastguard Worker assert(BB && BB->getParent() && "Block not embedded in function!");
468*9880d681SAndroid Build Coastguard Worker assert(BB->getTerminator() && "Degenerate basic block encountered!");
469*9880d681SAndroid Build Coastguard Worker
470*9880d681SAndroid Build Coastguard Worker IRBuilder<> Builder(BB);
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Worker if (FlattenParallelAndOr(BB, Builder))
473*9880d681SAndroid Build Coastguard Worker return true;
474*9880d681SAndroid Build Coastguard Worker
475*9880d681SAndroid Build Coastguard Worker if (MergeIfRegion(BB, Builder))
476*9880d681SAndroid Build Coastguard Worker return true;
477*9880d681SAndroid Build Coastguard Worker
478*9880d681SAndroid Build Coastguard Worker return Changed;
479*9880d681SAndroid Build Coastguard Worker }
480*9880d681SAndroid Build Coastguard Worker
481*9880d681SAndroid Build Coastguard Worker /// FlattenCFG - This function is used to flatten a CFG. For
482*9880d681SAndroid Build Coastguard Worker /// example, it uses parallel-and and parallel-or mode to collapse
483*9880d681SAndroid Build Coastguard Worker // if-conditions and merge if-regions with identical statements.
484*9880d681SAndroid Build Coastguard Worker ///
FlattenCFG(BasicBlock * BB,AliasAnalysis * AA)485*9880d681SAndroid Build Coastguard Worker bool llvm::FlattenCFG(BasicBlock *BB, AliasAnalysis *AA) {
486*9880d681SAndroid Build Coastguard Worker return FlattenCFGOpt(AA).run(BB);
487*9880d681SAndroid Build Coastguard Worker }
488