10b57cec5SDimitry Andric //===- FlatternCFG.cpp - Code to perform CFG flattening -------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Reduce conditional branches in CFG. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 140b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 150b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Local.h" 160b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h" 170b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 180b57cec5SDimitry Andric #include "llvm/IR/IRBuilder.h" 190b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h" 200b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 210b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 220b57cec5SDimitry Andric #include "llvm/IR/Value.h" 230b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 240b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 250b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 260b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h" 270b57cec5SDimitry Andric #include <cassert> 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric using namespace llvm; 300b57cec5SDimitry Andric 31*0fca6ea1SDimitry Andric #define DEBUG_TYPE "flatten-cfg" 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric namespace { 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric class FlattenCFGOpt { 360b57cec5SDimitry Andric AliasAnalysis *AA; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric /// Use parallel-and or parallel-or to generate conditions for 390b57cec5SDimitry Andric /// conditional branches. 400b57cec5SDimitry Andric bool FlattenParallelAndOr(BasicBlock *BB, IRBuilder<> &Builder); 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric /// If \param BB is the merge block of an if-region, attempt to merge 430b57cec5SDimitry Andric /// the if-region with an adjacent if-region upstream if two if-regions 440b57cec5SDimitry Andric /// contain identical instructions. 450b57cec5SDimitry Andric bool MergeIfRegion(BasicBlock *BB, IRBuilder<> &Builder); 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric /// Compare a pair of blocks: \p Block1 and \p Block2, which 485ffd83dbSDimitry Andric /// are from two if-regions, where \p Head2 is the entry block of the 2nd 495ffd83dbSDimitry Andric /// if-region. \returns true if \p Block1 and \p Block2 contain identical 500b57cec5SDimitry Andric /// instructions, and have no memory reference alias with \p Head2. 510b57cec5SDimitry Andric /// This is used as a legality check for merging if-regions. 525ffd83dbSDimitry Andric bool CompareIfRegionBlock(BasicBlock *Block1, BasicBlock *Block2, 535ffd83dbSDimitry Andric BasicBlock *Head2); 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric public: 560b57cec5SDimitry Andric FlattenCFGOpt(AliasAnalysis *AA) : AA(AA) {} 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric bool run(BasicBlock *BB); 590b57cec5SDimitry Andric }; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric } // end anonymous namespace 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric /// If \param [in] BB has more than one predecessor that is a conditional 640b57cec5SDimitry Andric /// branch, attempt to use parallel and/or for the branch condition. \returns 650b57cec5SDimitry Andric /// true on success. 660b57cec5SDimitry Andric /// 670b57cec5SDimitry Andric /// Before: 680b57cec5SDimitry Andric /// ...... 690b57cec5SDimitry Andric /// %cmp10 = fcmp une float %tmp1, %tmp2 708bcb0991SDimitry Andric /// br i1 %cmp10, label %if.then, label %lor.rhs 710b57cec5SDimitry Andric /// 720b57cec5SDimitry Andric /// lor.rhs: 730b57cec5SDimitry Andric /// ...... 740b57cec5SDimitry Andric /// %cmp11 = fcmp une float %tmp3, %tmp4 750b57cec5SDimitry Andric /// br i1 %cmp11, label %if.then, label %ifend 760b57cec5SDimitry Andric /// 770b57cec5SDimitry Andric /// if.end: // the merge block 780b57cec5SDimitry Andric /// ...... 790b57cec5SDimitry Andric /// 800b57cec5SDimitry Andric /// if.then: // has two predecessors, both of them contains conditional branch. 810b57cec5SDimitry Andric /// ...... 820b57cec5SDimitry Andric /// br label %if.end; 830b57cec5SDimitry Andric /// 840b57cec5SDimitry Andric /// After: 850b57cec5SDimitry Andric /// ...... 860b57cec5SDimitry Andric /// %cmp10 = fcmp une float %tmp1, %tmp2 870b57cec5SDimitry Andric /// ...... 880b57cec5SDimitry Andric /// %cmp11 = fcmp une float %tmp3, %tmp4 890b57cec5SDimitry Andric /// %cmp12 = or i1 %cmp10, %cmp11 // parallel-or mode. 900b57cec5SDimitry Andric /// br i1 %cmp12, label %if.then, label %ifend 910b57cec5SDimitry Andric /// 920b57cec5SDimitry Andric /// if.end: 930b57cec5SDimitry Andric /// ...... 940b57cec5SDimitry Andric /// 950b57cec5SDimitry Andric /// if.then: 960b57cec5SDimitry Andric /// ...... 970b57cec5SDimitry Andric /// br label %if.end; 980b57cec5SDimitry Andric /// 990b57cec5SDimitry Andric /// Current implementation handles two cases. 1005ffd83dbSDimitry Andric /// Case 1: BB is on the else-path. 1010b57cec5SDimitry Andric /// 1020b57cec5SDimitry Andric /// BB1 1030b57cec5SDimitry Andric /// / | 1040b57cec5SDimitry Andric /// BB2 | 1050b57cec5SDimitry Andric /// / \ | 1060b57cec5SDimitry Andric /// BB3 \ | where, BB1, BB2 contain conditional branches. 1070b57cec5SDimitry Andric /// \ | / BB3 contains unconditional branch. 1085ffd83dbSDimitry Andric /// \ | / BB4 corresponds to BB which is also the merge. 1090b57cec5SDimitry Andric /// BB => BB4 1100b57cec5SDimitry Andric /// 1110b57cec5SDimitry Andric /// 1120b57cec5SDimitry Andric /// Corresponding source code: 1130b57cec5SDimitry Andric /// 1140b57cec5SDimitry Andric /// if (a == b && c == d) 1150b57cec5SDimitry Andric /// statement; // BB3 1160b57cec5SDimitry Andric /// 1175ffd83dbSDimitry Andric /// Case 2: BB is on the then-path. 1180b57cec5SDimitry Andric /// 1190b57cec5SDimitry Andric /// BB1 1200b57cec5SDimitry Andric /// / | 1210b57cec5SDimitry Andric /// | BB2 1220b57cec5SDimitry Andric /// \ / | where BB1, BB2 contain conditional branches. 1230b57cec5SDimitry Andric /// BB => BB3 | BB3 contains unconditiona branch and corresponds 1245ffd83dbSDimitry Andric /// \ / to BB. BB4 is the merge. 1250b57cec5SDimitry Andric /// BB4 1260b57cec5SDimitry Andric /// 1270b57cec5SDimitry Andric /// Corresponding source code: 1280b57cec5SDimitry Andric /// 1290b57cec5SDimitry Andric /// if (a == b || c == d) 1300b57cec5SDimitry Andric /// statement; // BB3 1310b57cec5SDimitry Andric /// 1325ffd83dbSDimitry Andric /// In both cases, BB is the common successor of conditional branches. 1335ffd83dbSDimitry Andric /// In Case 1, BB (BB4) has an unconditional branch (BB3) as 1345ffd83dbSDimitry Andric /// its predecessor. In Case 2, BB (BB3) only has conditional branches 1350b57cec5SDimitry Andric /// as its predecessors. 1360b57cec5SDimitry Andric bool FlattenCFGOpt::FlattenParallelAndOr(BasicBlock *BB, IRBuilder<> &Builder) { 1370b57cec5SDimitry Andric PHINode *PHI = dyn_cast<PHINode>(BB->begin()); 1380b57cec5SDimitry Andric if (PHI) 1390b57cec5SDimitry Andric return false; // For simplicity, avoid cases containing PHI nodes. 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric BasicBlock *LastCondBlock = nullptr; 1420b57cec5SDimitry Andric BasicBlock *FirstCondBlock = nullptr; 1430b57cec5SDimitry Andric BasicBlock *UnCondBlock = nullptr; 1440b57cec5SDimitry Andric int Idx = -1; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric // Check predecessors of \param BB. 1470b57cec5SDimitry Andric SmallPtrSet<BasicBlock *, 16> Preds(pred_begin(BB), pred_end(BB)); 148bdd1243dSDimitry Andric for (BasicBlock *Pred : Preds) { 1490b57cec5SDimitry Andric BranchInst *PBI = dyn_cast<BranchInst>(Pred->getTerminator()); 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric // All predecessors should terminate with a branch. 1520b57cec5SDimitry Andric if (!PBI) 1530b57cec5SDimitry Andric return false; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric BasicBlock *PP = Pred->getSinglePredecessor(); 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric if (PBI->isUnconditional()) { 1580b57cec5SDimitry Andric // Case 1: Pred (BB3) is an unconditional block, it should 1590b57cec5SDimitry Andric // have a single predecessor (BB2) that is also a predecessor 1600b57cec5SDimitry Andric // of \param BB (BB4) and should not have address-taken. 1610b57cec5SDimitry Andric // There should exist only one such unconditional 1620b57cec5SDimitry Andric // branch among the predecessors. 163349cc55cSDimitry Andric if (UnCondBlock || !PP || !Preds.contains(PP) || 1640b57cec5SDimitry Andric Pred->hasAddressTaken()) 1650b57cec5SDimitry Andric return false; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric UnCondBlock = Pred; 1680b57cec5SDimitry Andric continue; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric // Only conditional branches are allowed beyond this point. 1720b57cec5SDimitry Andric assert(PBI->isConditional()); 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric // Condition's unique use should be the branch instruction. 1750b57cec5SDimitry Andric Value *PC = PBI->getCondition(); 1760b57cec5SDimitry Andric if (!PC || !PC->hasOneUse()) 1770b57cec5SDimitry Andric return false; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric if (PP && Preds.count(PP)) { 1800b57cec5SDimitry Andric // These are internal condition blocks to be merged from, e.g., 1810b57cec5SDimitry Andric // BB2 in both cases. 1820b57cec5SDimitry Andric // Should not be address-taken. 1830b57cec5SDimitry Andric if (Pred->hasAddressTaken()) 1840b57cec5SDimitry Andric return false; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric // Instructions in the internal condition blocks should be safe 1870b57cec5SDimitry Andric // to hoist up. 1880b57cec5SDimitry Andric for (BasicBlock::iterator BI = Pred->begin(), BE = PBI->getIterator(); 1890b57cec5SDimitry Andric BI != BE;) { 1900b57cec5SDimitry Andric Instruction *CI = &*BI++; 1910b57cec5SDimitry Andric if (isa<PHINode>(CI) || !isSafeToSpeculativelyExecute(CI)) 1920b57cec5SDimitry Andric return false; 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric } else { 1950b57cec5SDimitry Andric // This is the condition block to be merged into, e.g. BB1 in 1960b57cec5SDimitry Andric // both cases. 1970b57cec5SDimitry Andric if (FirstCondBlock) 1980b57cec5SDimitry Andric return false; 1990b57cec5SDimitry Andric FirstCondBlock = Pred; 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric // Find whether BB is uniformly on the true (or false) path 2030b57cec5SDimitry Andric // for all of its predecessors. 2040b57cec5SDimitry Andric BasicBlock *PS1 = PBI->getSuccessor(0); 2050b57cec5SDimitry Andric BasicBlock *PS2 = PBI->getSuccessor(1); 2060b57cec5SDimitry Andric BasicBlock *PS = (PS1 == BB) ? PS2 : PS1; 2070b57cec5SDimitry Andric int CIdx = (PS1 == BB) ? 0 : 1; 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric if (Idx == -1) 2100b57cec5SDimitry Andric Idx = CIdx; 2110b57cec5SDimitry Andric else if (CIdx != Idx) 2120b57cec5SDimitry Andric return false; 2130b57cec5SDimitry Andric 2140b57cec5SDimitry Andric // PS is the successor which is not BB. Check successors to identify 2150b57cec5SDimitry Andric // the last conditional branch. 216349cc55cSDimitry Andric if (!Preds.contains(PS)) { 2170b57cec5SDimitry Andric // Case 2. 2180b57cec5SDimitry Andric LastCondBlock = Pred; 2190b57cec5SDimitry Andric } else { 2200b57cec5SDimitry Andric // Case 1 2210b57cec5SDimitry Andric BranchInst *BPS = dyn_cast<BranchInst>(PS->getTerminator()); 2220b57cec5SDimitry Andric if (BPS && BPS->isUnconditional()) { 2230b57cec5SDimitry Andric // Case 1: PS(BB3) should be an unconditional branch. 2240b57cec5SDimitry Andric LastCondBlock = Pred; 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric if (!FirstCondBlock || !LastCondBlock || (FirstCondBlock == LastCondBlock)) 2300b57cec5SDimitry Andric return false; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric Instruction *TBB = LastCondBlock->getTerminator(); 2330b57cec5SDimitry Andric BasicBlock *PS1 = TBB->getSuccessor(0); 2340b57cec5SDimitry Andric BasicBlock *PS2 = TBB->getSuccessor(1); 2350b57cec5SDimitry Andric BranchInst *PBI1 = dyn_cast<BranchInst>(PS1->getTerminator()); 2360b57cec5SDimitry Andric BranchInst *PBI2 = dyn_cast<BranchInst>(PS2->getTerminator()); 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric // If PS1 does not jump into PS2, but PS2 jumps into PS1, 2390b57cec5SDimitry Andric // attempt branch inversion. 2400b57cec5SDimitry Andric if (!PBI1 || !PBI1->isUnconditional() || 2410b57cec5SDimitry Andric (PS1->getTerminator()->getSuccessor(0) != PS2)) { 2420b57cec5SDimitry Andric // Check whether PS2 jumps into PS1. 2430b57cec5SDimitry Andric if (!PBI2 || !PBI2->isUnconditional() || 2440b57cec5SDimitry Andric (PS2->getTerminator()->getSuccessor(0) != PS1)) 2450b57cec5SDimitry Andric return false; 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric // Do branch inversion. 2480b57cec5SDimitry Andric BasicBlock *CurrBlock = LastCondBlock; 2490b57cec5SDimitry Andric bool EverChanged = false; 2500b57cec5SDimitry Andric for (; CurrBlock != FirstCondBlock; 2510b57cec5SDimitry Andric CurrBlock = CurrBlock->getSinglePredecessor()) { 2528bcb0991SDimitry Andric auto *BI = cast<BranchInst>(CurrBlock->getTerminator()); 2538bcb0991SDimitry Andric auto *CI = dyn_cast<CmpInst>(BI->getCondition()); 2540b57cec5SDimitry Andric if (!CI) 2550b57cec5SDimitry Andric continue; 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric CmpInst::Predicate Predicate = CI->getPredicate(); 2580b57cec5SDimitry Andric // Canonicalize icmp_ne -> icmp_eq, fcmp_one -> fcmp_oeq 2590b57cec5SDimitry Andric if ((Predicate == CmpInst::ICMP_NE) || (Predicate == CmpInst::FCMP_ONE)) { 2600b57cec5SDimitry Andric CI->setPredicate(ICmpInst::getInversePredicate(Predicate)); 2610b57cec5SDimitry Andric BI->swapSuccessors(); 2620b57cec5SDimitry Andric EverChanged = true; 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric return EverChanged; 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric // PS1 must have a conditional branch. 2690b57cec5SDimitry Andric if (!PBI1 || !PBI1->isUnconditional()) 2700b57cec5SDimitry Andric return false; 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric // PS2 should not contain PHI node. 2730b57cec5SDimitry Andric PHI = dyn_cast<PHINode>(PS2->begin()); 2740b57cec5SDimitry Andric if (PHI) 2750b57cec5SDimitry Andric return false; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric // Do the transformation. 2780b57cec5SDimitry Andric BasicBlock *CB; 2798bcb0991SDimitry Andric BranchInst *PBI = cast<BranchInst>(FirstCondBlock->getTerminator()); 2800b57cec5SDimitry Andric bool Iteration = true; 2810b57cec5SDimitry Andric IRBuilder<>::InsertPointGuard Guard(Builder); 2820b57cec5SDimitry Andric Value *PC = PBI->getCondition(); 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric do { 2850b57cec5SDimitry Andric CB = PBI->getSuccessor(1 - Idx); 2860b57cec5SDimitry Andric // Delete the conditional branch. 287bdd1243dSDimitry Andric FirstCondBlock->back().eraseFromParent(); 288bdd1243dSDimitry Andric FirstCondBlock->splice(FirstCondBlock->end(), CB); 2890b57cec5SDimitry Andric PBI = cast<BranchInst>(FirstCondBlock->getTerminator()); 2900b57cec5SDimitry Andric Value *CC = PBI->getCondition(); 2910b57cec5SDimitry Andric // Merge conditions. 2920b57cec5SDimitry Andric Builder.SetInsertPoint(PBI); 2930b57cec5SDimitry Andric Value *NC; 2940b57cec5SDimitry Andric if (Idx == 0) 2950b57cec5SDimitry Andric // Case 2, use parallel or. 2960b57cec5SDimitry Andric NC = Builder.CreateOr(PC, CC); 2970b57cec5SDimitry Andric else 2980b57cec5SDimitry Andric // Case 1, use parallel and. 2990b57cec5SDimitry Andric NC = Builder.CreateAnd(PC, CC); 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric PBI->replaceUsesOfWith(CC, NC); 3020b57cec5SDimitry Andric PC = NC; 3030b57cec5SDimitry Andric if (CB == LastCondBlock) 3040b57cec5SDimitry Andric Iteration = false; 3050b57cec5SDimitry Andric // Remove internal conditional branches. 3060b57cec5SDimitry Andric CB->dropAllReferences(); 3070b57cec5SDimitry Andric // make CB unreachable and let downstream to delete the block. 3080b57cec5SDimitry Andric new UnreachableInst(CB->getContext(), CB); 3090b57cec5SDimitry Andric } while (Iteration); 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Use parallel and/or in:\n" << *FirstCondBlock); 3120b57cec5SDimitry Andric return true; 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric 3155ffd83dbSDimitry Andric /// Compare blocks from two if-regions, where \param Head2 is the entry of the 3165ffd83dbSDimitry Andric /// 2nd if-region. \param Block1 is a block in the 1st if-region to compare. 3175ffd83dbSDimitry Andric /// \param Block2 is a block in the 2nd if-region to compare. \returns true if 3185ffd83dbSDimitry Andric /// Block1 and Block2 have identical instructions and do not have 3195ffd83dbSDimitry Andric /// memory reference alias with Head2. 3205ffd83dbSDimitry Andric bool FlattenCFGOpt::CompareIfRegionBlock(BasicBlock *Block1, BasicBlock *Block2, 3215ffd83dbSDimitry Andric BasicBlock *Head2) { 3220b57cec5SDimitry Andric Instruction *PTI2 = Head2->getTerminator(); 3230b57cec5SDimitry Andric Instruction *PBI2 = &Head2->front(); 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric // Check whether instructions in Block1 and Block2 are identical 3260b57cec5SDimitry Andric // and do not alias with instructions in Head2. 3270b57cec5SDimitry Andric BasicBlock::iterator iter1 = Block1->begin(); 3280b57cec5SDimitry Andric BasicBlock::iterator end1 = Block1->getTerminator()->getIterator(); 3290b57cec5SDimitry Andric BasicBlock::iterator iter2 = Block2->begin(); 3300b57cec5SDimitry Andric BasicBlock::iterator end2 = Block2->getTerminator()->getIterator(); 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric while (true) { 3330b57cec5SDimitry Andric if (iter1 == end1) { 3340b57cec5SDimitry Andric if (iter2 != end2) 3350b57cec5SDimitry Andric return false; 3360b57cec5SDimitry Andric break; 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric if (!iter1->isIdenticalTo(&*iter2)) 3400b57cec5SDimitry Andric return false; 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric // Illegal to remove instructions with side effects except 3430b57cec5SDimitry Andric // non-volatile stores. 3440b57cec5SDimitry Andric if (iter1->mayHaveSideEffects()) { 3450b57cec5SDimitry Andric Instruction *CurI = &*iter1; 3460b57cec5SDimitry Andric StoreInst *SI = dyn_cast<StoreInst>(CurI); 3470b57cec5SDimitry Andric if (!SI || SI->isVolatile()) 3480b57cec5SDimitry Andric return false; 3490b57cec5SDimitry Andric } 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric // For simplicity and speed, data dependency check can be 3520b57cec5SDimitry Andric // avoided if read from memory doesn't exist. 3530b57cec5SDimitry Andric if (iter1->mayReadFromMemory()) 3540b57cec5SDimitry Andric return false; 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric if (iter1->mayWriteToMemory()) { 3570b57cec5SDimitry Andric for (BasicBlock::iterator BI(PBI2), BE(PTI2); BI != BE; ++BI) { 3580b57cec5SDimitry Andric if (BI->mayReadFromMemory() || BI->mayWriteToMemory()) { 3590b57cec5SDimitry Andric // Check alias with Head2. 360fe6060f1SDimitry Andric if (!AA || !AA->isNoAlias(&*iter1, &*BI)) 3610b57cec5SDimitry Andric return false; 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric } 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric ++iter1; 3660b57cec5SDimitry Andric ++iter2; 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric return true; 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric /// Check whether \param BB is the merge block of a if-region. If yes, check 3730b57cec5SDimitry Andric /// whether there exists an adjacent if-region upstream, the two if-regions 3740b57cec5SDimitry Andric /// contain identical instructions and can be legally merged. \returns true if 3750b57cec5SDimitry Andric /// the two if-regions are merged. 3760b57cec5SDimitry Andric /// 3770b57cec5SDimitry Andric /// From: 3780b57cec5SDimitry Andric /// if (a) 3790b57cec5SDimitry Andric /// statement; 3800b57cec5SDimitry Andric /// if (b) 3810b57cec5SDimitry Andric /// statement; 3820b57cec5SDimitry Andric /// 3830b57cec5SDimitry Andric /// To: 3840b57cec5SDimitry Andric /// if (a || b) 3850b57cec5SDimitry Andric /// statement; 3865ffd83dbSDimitry Andric /// 3875ffd83dbSDimitry Andric /// 3885ffd83dbSDimitry Andric /// And from: 3895ffd83dbSDimitry Andric /// if (a) 3905ffd83dbSDimitry Andric /// ; 3915ffd83dbSDimitry Andric /// else 3925ffd83dbSDimitry Andric /// statement; 3935ffd83dbSDimitry Andric /// if (b) 3945ffd83dbSDimitry Andric /// ; 3955ffd83dbSDimitry Andric /// else 3965ffd83dbSDimitry Andric /// statement; 3975ffd83dbSDimitry Andric /// 3985ffd83dbSDimitry Andric /// To: 3995ffd83dbSDimitry Andric /// if (a && b) 4005ffd83dbSDimitry Andric /// ; 4015ffd83dbSDimitry Andric /// else 4025ffd83dbSDimitry Andric /// statement; 4035ffd83dbSDimitry Andric /// 4045ffd83dbSDimitry Andric /// We always take the form of the first if-region. This means that if the 4055ffd83dbSDimitry Andric /// statement in the first if-region, is in the "then-path", while in the second 4065ffd83dbSDimitry Andric /// if-region it is in the "else-path", then we convert the second to the first 4075ffd83dbSDimitry Andric /// form, by inverting the condition and the branch successors. The same 4085ffd83dbSDimitry Andric /// approach goes for the opposite case. 4090b57cec5SDimitry Andric bool FlattenCFGOpt::MergeIfRegion(BasicBlock *BB, IRBuilder<> &Builder) { 4104c2d3b02SDimitry Andric // We cannot merge the if-region if the merge point has phi nodes. 4114c2d3b02SDimitry Andric if (isa<PHINode>(BB->front())) 4124c2d3b02SDimitry Andric return false; 4134c2d3b02SDimitry Andric 4140b57cec5SDimitry Andric BasicBlock *IfTrue2, *IfFalse2; 415fe6060f1SDimitry Andric BranchInst *DomBI2 = GetIfCondition(BB, IfTrue2, IfFalse2); 416fe6060f1SDimitry Andric if (!DomBI2) 417fe6060f1SDimitry Andric return false; 418fe6060f1SDimitry Andric Instruction *CInst2 = dyn_cast<Instruction>(DomBI2->getCondition()); 4190b57cec5SDimitry Andric if (!CInst2) 4200b57cec5SDimitry Andric return false; 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric BasicBlock *SecondEntryBlock = CInst2->getParent(); 4230b57cec5SDimitry Andric if (SecondEntryBlock->hasAddressTaken()) 4240b57cec5SDimitry Andric return false; 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric BasicBlock *IfTrue1, *IfFalse1; 427fe6060f1SDimitry Andric BranchInst *DomBI1 = GetIfCondition(SecondEntryBlock, IfTrue1, IfFalse1); 428fe6060f1SDimitry Andric if (!DomBI1) 429fe6060f1SDimitry Andric return false; 430fe6060f1SDimitry Andric Instruction *CInst1 = dyn_cast<Instruction>(DomBI1->getCondition()); 4310b57cec5SDimitry Andric if (!CInst1) 4320b57cec5SDimitry Andric return false; 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric BasicBlock *FirstEntryBlock = CInst1->getParent(); 435bdd1243dSDimitry Andric // Don't die trying to process degenerate/unreachable code. 436bdd1243dSDimitry Andric if (FirstEntryBlock == SecondEntryBlock) 437bdd1243dSDimitry Andric return false; 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric // Either then-path or else-path should be empty. 4405ffd83dbSDimitry Andric bool InvertCond2 = false; 4415ffd83dbSDimitry Andric BinaryOperator::BinaryOps CombineOp; 4425ffd83dbSDimitry Andric if (IfFalse1 == FirstEntryBlock) { 4435ffd83dbSDimitry Andric // The else-path is empty, so we must use "or" operation to combine the 4445ffd83dbSDimitry Andric // conditions. 4455ffd83dbSDimitry Andric CombineOp = BinaryOperator::Or; 4465ffd83dbSDimitry Andric if (IfFalse2 != SecondEntryBlock) { 4475ffd83dbSDimitry Andric if (IfTrue2 != SecondEntryBlock) 4480b57cec5SDimitry Andric return false; 4495ffd83dbSDimitry Andric 4505ffd83dbSDimitry Andric InvertCond2 = true; 4515ffd83dbSDimitry Andric std::swap(IfTrue2, IfFalse2); 4525ffd83dbSDimitry Andric } 4535ffd83dbSDimitry Andric 4545ffd83dbSDimitry Andric if (!CompareIfRegionBlock(IfTrue1, IfTrue2, SecondEntryBlock)) 4555ffd83dbSDimitry Andric return false; 4565ffd83dbSDimitry Andric } else if (IfTrue1 == FirstEntryBlock) { 4575ffd83dbSDimitry Andric // The then-path is empty, so we must use "and" operation to combine the 4585ffd83dbSDimitry Andric // conditions. 4595ffd83dbSDimitry Andric CombineOp = BinaryOperator::And; 4605ffd83dbSDimitry Andric if (IfTrue2 != SecondEntryBlock) { 4615ffd83dbSDimitry Andric if (IfFalse2 != SecondEntryBlock) 4625ffd83dbSDimitry Andric return false; 4635ffd83dbSDimitry Andric 4645ffd83dbSDimitry Andric InvertCond2 = true; 4655ffd83dbSDimitry Andric std::swap(IfTrue2, IfFalse2); 4665ffd83dbSDimitry Andric } 4675ffd83dbSDimitry Andric 4685ffd83dbSDimitry Andric if (!CompareIfRegionBlock(IfFalse1, IfFalse2, SecondEntryBlock)) 4695ffd83dbSDimitry Andric return false; 4705ffd83dbSDimitry Andric } else 4710b57cec5SDimitry Andric return false; 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric Instruction *PTI2 = SecondEntryBlock->getTerminator(); 4740b57cec5SDimitry Andric Instruction *PBI2 = &SecondEntryBlock->front(); 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric // Check whether \param SecondEntryBlock has side-effect and is safe to 4770b57cec5SDimitry Andric // speculate. 4780b57cec5SDimitry Andric for (BasicBlock::iterator BI(PBI2), BE(PTI2); BI != BE; ++BI) { 4790b57cec5SDimitry Andric Instruction *CI = &*BI; 4800b57cec5SDimitry Andric if (isa<PHINode>(CI) || CI->mayHaveSideEffects() || 4810b57cec5SDimitry Andric !isSafeToSpeculativelyExecute(CI)) 4820b57cec5SDimitry Andric return false; 4830b57cec5SDimitry Andric } 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric // Merge \param SecondEntryBlock into \param FirstEntryBlock. 486bdd1243dSDimitry Andric FirstEntryBlock->back().eraseFromParent(); 487bdd1243dSDimitry Andric FirstEntryBlock->splice(FirstEntryBlock->end(), SecondEntryBlock); 4888bcb0991SDimitry Andric BranchInst *PBI = cast<BranchInst>(FirstEntryBlock->getTerminator()); 489fe6060f1SDimitry Andric assert(PBI->getCondition() == CInst2); 4900b57cec5SDimitry Andric BasicBlock *SaveInsertBB = Builder.GetInsertBlock(); 4910b57cec5SDimitry Andric BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint(); 4920b57cec5SDimitry Andric Builder.SetInsertPoint(PBI); 4935ffd83dbSDimitry Andric if (InvertCond2) { 49406c3fb27SDimitry Andric InvertBranch(PBI, Builder); 4955ffd83dbSDimitry Andric } 49606c3fb27SDimitry Andric Value *NC = Builder.CreateBinOp(CombineOp, CInst1, PBI->getCondition()); 49706c3fb27SDimitry Andric PBI->replaceUsesOfWith(PBI->getCondition(), NC); 4980b57cec5SDimitry Andric Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt); 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric // Remove IfTrue1 5010b57cec5SDimitry Andric if (IfTrue1 != FirstEntryBlock) { 5020b57cec5SDimitry Andric IfTrue1->dropAllReferences(); 5030b57cec5SDimitry Andric IfTrue1->eraseFromParent(); 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric // Remove IfFalse1 5070b57cec5SDimitry Andric if (IfFalse1 != FirstEntryBlock) { 5080b57cec5SDimitry Andric IfFalse1->dropAllReferences(); 5090b57cec5SDimitry Andric IfFalse1->eraseFromParent(); 5100b57cec5SDimitry Andric } 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric // Remove \param SecondEntryBlock 5130b57cec5SDimitry Andric SecondEntryBlock->dropAllReferences(); 5140b57cec5SDimitry Andric SecondEntryBlock->eraseFromParent(); 5150b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "If conditions merged into:\n" << *FirstEntryBlock); 5160b57cec5SDimitry Andric return true; 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric bool FlattenCFGOpt::run(BasicBlock *BB) { 5200b57cec5SDimitry Andric assert(BB && BB->getParent() && "Block not embedded in function!"); 5210b57cec5SDimitry Andric assert(BB->getTerminator() && "Degenerate basic block encountered!"); 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric IRBuilder<> Builder(BB); 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric if (FlattenParallelAndOr(BB, Builder) || MergeIfRegion(BB, Builder)) 5260b57cec5SDimitry Andric return true; 5270b57cec5SDimitry Andric return false; 5280b57cec5SDimitry Andric } 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric /// FlattenCFG - This function is used to flatten a CFG. For 5310b57cec5SDimitry Andric /// example, it uses parallel-and and parallel-or mode to collapse 5320b57cec5SDimitry Andric /// if-conditions and merge if-regions with identical statements. 5335ffd83dbSDimitry Andric bool llvm::FlattenCFG(BasicBlock *BB, AAResults *AA) { 5340b57cec5SDimitry Andric return FlattenCFGOpt(AA).run(BB); 5350b57cec5SDimitry Andric } 536