12cab237bSDimitry Andric //===- VPlan.cpp - Vectorizer Plan ----------------------------------------===//
22cab237bSDimitry Andric //
32cab237bSDimitry Andric //                     The LLVM Compiler Infrastructure
42cab237bSDimitry Andric //
52cab237bSDimitry Andric // This file is distributed under the University of Illinois Open Source
62cab237bSDimitry Andric // License. See LICENSE.TXT for details.
72cab237bSDimitry Andric //
82cab237bSDimitry Andric //===----------------------------------------------------------------------===//
92cab237bSDimitry Andric ///
102cab237bSDimitry Andric /// \file
112cab237bSDimitry Andric /// This is the LLVM vectorization plan. It represents a candidate for
122cab237bSDimitry Andric /// vectorization, allowing to plan and optimize how to vectorize a given loop
132cab237bSDimitry Andric /// before generating LLVM-IR.
142cab237bSDimitry Andric /// The vectorizer uses vectorization plans to estimate the costs of potential
152cab237bSDimitry Andric /// candidates and if profitable to execute the desired plan, generating vector
162cab237bSDimitry Andric /// LLVM-IR code.
172cab237bSDimitry Andric ///
182cab237bSDimitry Andric //===----------------------------------------------------------------------===//
192cab237bSDimitry Andric 
202cab237bSDimitry Andric #include "VPlan.h"
214ba319b5SDimitry Andric #include "VPlanDominatorTree.h"
222cab237bSDimitry Andric #include "llvm/ADT/DepthFirstIterator.h"
232cab237bSDimitry Andric #include "llvm/ADT/PostOrderIterator.h"
242cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
252cab237bSDimitry Andric #include "llvm/ADT/Twine.h"
262cab237bSDimitry Andric #include "llvm/Analysis/LoopInfo.h"
272cab237bSDimitry Andric #include "llvm/IR/BasicBlock.h"
282cab237bSDimitry Andric #include "llvm/IR/CFG.h"
292cab237bSDimitry Andric #include "llvm/IR/InstrTypes.h"
302cab237bSDimitry Andric #include "llvm/IR/Instruction.h"
312cab237bSDimitry Andric #include "llvm/IR/Instructions.h"
322cab237bSDimitry Andric #include "llvm/IR/Type.h"
332cab237bSDimitry Andric #include "llvm/IR/Value.h"
342cab237bSDimitry Andric #include "llvm/Support/Casting.h"
352cab237bSDimitry Andric #include "llvm/Support/Debug.h"
362cab237bSDimitry Andric #include "llvm/Support/ErrorHandling.h"
374ba319b5SDimitry Andric #include "llvm/Support/GenericDomTreeConstruction.h"
382cab237bSDimitry Andric #include "llvm/Support/GraphWriter.h"
392cab237bSDimitry Andric #include "llvm/Support/raw_ostream.h"
402cab237bSDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
412cab237bSDimitry Andric #include <cassert>
422cab237bSDimitry Andric #include <iterator>
432cab237bSDimitry Andric #include <string>
442cab237bSDimitry Andric #include <vector>
452cab237bSDimitry Andric 
462cab237bSDimitry Andric using namespace llvm;
47*b5893f02SDimitry Andric extern cl::opt<bool> EnableVPlanNativePath;
482cab237bSDimitry Andric 
492cab237bSDimitry Andric #define DEBUG_TYPE "vplan"
502cab237bSDimitry Andric 
operator <<(raw_ostream & OS,const VPValue & V)512cab237bSDimitry Andric raw_ostream &llvm::operator<<(raw_ostream &OS, const VPValue &V) {
522cab237bSDimitry Andric   if (const VPInstruction *Instr = dyn_cast<VPInstruction>(&V))
532cab237bSDimitry Andric     Instr->print(OS);
542cab237bSDimitry Andric   else
552cab237bSDimitry Andric     V.printAsOperand(OS);
562cab237bSDimitry Andric   return OS;
572cab237bSDimitry Andric }
582cab237bSDimitry Andric 
592cab237bSDimitry Andric /// \return the VPBasicBlock that is the entry of Block, possibly indirectly.
getEntryBasicBlock() const602cab237bSDimitry Andric const VPBasicBlock *VPBlockBase::getEntryBasicBlock() const {
612cab237bSDimitry Andric   const VPBlockBase *Block = this;
622cab237bSDimitry Andric   while (const VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
632cab237bSDimitry Andric     Block = Region->getEntry();
642cab237bSDimitry Andric   return cast<VPBasicBlock>(Block);
652cab237bSDimitry Andric }
662cab237bSDimitry Andric 
getEntryBasicBlock()672cab237bSDimitry Andric VPBasicBlock *VPBlockBase::getEntryBasicBlock() {
682cab237bSDimitry Andric   VPBlockBase *Block = this;
692cab237bSDimitry Andric   while (VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
702cab237bSDimitry Andric     Block = Region->getEntry();
712cab237bSDimitry Andric   return cast<VPBasicBlock>(Block);
722cab237bSDimitry Andric }
732cab237bSDimitry Andric 
742cab237bSDimitry Andric /// \return the VPBasicBlock that is the exit of Block, possibly indirectly.
getExitBasicBlock() const752cab237bSDimitry Andric const VPBasicBlock *VPBlockBase::getExitBasicBlock() const {
762cab237bSDimitry Andric   const VPBlockBase *Block = this;
772cab237bSDimitry Andric   while (const VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
782cab237bSDimitry Andric     Block = Region->getExit();
792cab237bSDimitry Andric   return cast<VPBasicBlock>(Block);
802cab237bSDimitry Andric }
812cab237bSDimitry Andric 
getExitBasicBlock()822cab237bSDimitry Andric VPBasicBlock *VPBlockBase::getExitBasicBlock() {
832cab237bSDimitry Andric   VPBlockBase *Block = this;
842cab237bSDimitry Andric   while (VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
852cab237bSDimitry Andric     Block = Region->getExit();
862cab237bSDimitry Andric   return cast<VPBasicBlock>(Block);
872cab237bSDimitry Andric }
882cab237bSDimitry Andric 
getEnclosingBlockWithSuccessors()892cab237bSDimitry Andric VPBlockBase *VPBlockBase::getEnclosingBlockWithSuccessors() {
902cab237bSDimitry Andric   if (!Successors.empty() || !Parent)
912cab237bSDimitry Andric     return this;
922cab237bSDimitry Andric   assert(Parent->getExit() == this &&
932cab237bSDimitry Andric          "Block w/o successors not the exit of its parent.");
942cab237bSDimitry Andric   return Parent->getEnclosingBlockWithSuccessors();
952cab237bSDimitry Andric }
962cab237bSDimitry Andric 
getEnclosingBlockWithPredecessors()972cab237bSDimitry Andric VPBlockBase *VPBlockBase::getEnclosingBlockWithPredecessors() {
982cab237bSDimitry Andric   if (!Predecessors.empty() || !Parent)
992cab237bSDimitry Andric     return this;
1002cab237bSDimitry Andric   assert(Parent->getEntry() == this &&
1012cab237bSDimitry Andric          "Block w/o predecessors not the entry of its parent.");
1022cab237bSDimitry Andric   return Parent->getEnclosingBlockWithPredecessors();
1032cab237bSDimitry Andric }
1042cab237bSDimitry Andric 
deleteCFG(VPBlockBase * Entry)1052cab237bSDimitry Andric void VPBlockBase::deleteCFG(VPBlockBase *Entry) {
1062cab237bSDimitry Andric   SmallVector<VPBlockBase *, 8> Blocks;
1072cab237bSDimitry Andric   for (VPBlockBase *Block : depth_first(Entry))
1082cab237bSDimitry Andric     Blocks.push_back(Block);
1092cab237bSDimitry Andric 
1102cab237bSDimitry Andric   for (VPBlockBase *Block : Blocks)
1112cab237bSDimitry Andric     delete Block;
1122cab237bSDimitry Andric }
1132cab237bSDimitry Andric 
1142cab237bSDimitry Andric BasicBlock *
createEmptyBasicBlock(VPTransformState::CFGState & CFG)1152cab237bSDimitry Andric VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
1162cab237bSDimitry Andric   // BB stands for IR BasicBlocks. VPBB stands for VPlan VPBasicBlocks.
1172cab237bSDimitry Andric   // Pred stands for Predessor. Prev stands for Previous - last visited/created.
1182cab237bSDimitry Andric   BasicBlock *PrevBB = CFG.PrevBB;
1192cab237bSDimitry Andric   BasicBlock *NewBB = BasicBlock::Create(PrevBB->getContext(), getName(),
1202cab237bSDimitry Andric                                          PrevBB->getParent(), CFG.LastBB);
1214ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "LV: created " << NewBB->getName() << '\n');
1222cab237bSDimitry Andric 
1232cab237bSDimitry Andric   // Hook up the new basic block to its predecessors.
1242cab237bSDimitry Andric   for (VPBlockBase *PredVPBlock : getHierarchicalPredecessors()) {
1252cab237bSDimitry Andric     VPBasicBlock *PredVPBB = PredVPBlock->getExitBasicBlock();
1262cab237bSDimitry Andric     auto &PredVPSuccessors = PredVPBB->getSuccessors();
1272cab237bSDimitry Andric     BasicBlock *PredBB = CFG.VPBB2IRBB[PredVPBB];
128*b5893f02SDimitry Andric 
129*b5893f02SDimitry Andric     // In outer loop vectorization scenario, the predecessor BBlock may not yet
130*b5893f02SDimitry Andric     // be visited(backedge). Mark the VPBasicBlock for fixup at the end of
131*b5893f02SDimitry Andric     // vectorization. We do not encounter this case in inner loop vectorization
132*b5893f02SDimitry Andric     // as we start out by building a loop skeleton with the vector loop header
133*b5893f02SDimitry Andric     // and latch blocks. As a result, we never enter this function for the
134*b5893f02SDimitry Andric     // header block in the non VPlan-native path.
135*b5893f02SDimitry Andric     if (!PredBB) {
136*b5893f02SDimitry Andric       assert(EnableVPlanNativePath &&
137*b5893f02SDimitry Andric              "Unexpected null predecessor in non VPlan-native path");
138*b5893f02SDimitry Andric       CFG.VPBBsToFix.push_back(PredVPBB);
139*b5893f02SDimitry Andric       continue;
140*b5893f02SDimitry Andric     }
141*b5893f02SDimitry Andric 
1422cab237bSDimitry Andric     assert(PredBB && "Predecessor basic-block not found building successor.");
1432cab237bSDimitry Andric     auto *PredBBTerminator = PredBB->getTerminator();
1444ba319b5SDimitry Andric     LLVM_DEBUG(dbgs() << "LV: draw edge from" << PredBB->getName() << '\n');
1452cab237bSDimitry Andric     if (isa<UnreachableInst>(PredBBTerminator)) {
1462cab237bSDimitry Andric       assert(PredVPSuccessors.size() == 1 &&
1472cab237bSDimitry Andric              "Predecessor ending w/o branch must have single successor.");
1482cab237bSDimitry Andric       PredBBTerminator->eraseFromParent();
1492cab237bSDimitry Andric       BranchInst::Create(NewBB, PredBB);
1502cab237bSDimitry Andric     } else {
1512cab237bSDimitry Andric       assert(PredVPSuccessors.size() == 2 &&
1522cab237bSDimitry Andric              "Predecessor ending with branch must have two successors.");
1532cab237bSDimitry Andric       unsigned idx = PredVPSuccessors.front() == this ? 0 : 1;
1542cab237bSDimitry Andric       assert(!PredBBTerminator->getSuccessor(idx) &&
1552cab237bSDimitry Andric              "Trying to reset an existing successor block.");
1562cab237bSDimitry Andric       PredBBTerminator->setSuccessor(idx, NewBB);
1572cab237bSDimitry Andric     }
1582cab237bSDimitry Andric   }
1592cab237bSDimitry Andric   return NewBB;
1602cab237bSDimitry Andric }
1612cab237bSDimitry Andric 
execute(VPTransformState * State)1622cab237bSDimitry Andric void VPBasicBlock::execute(VPTransformState *State) {
1632cab237bSDimitry Andric   bool Replica = State->Instance &&
1642cab237bSDimitry Andric                  !(State->Instance->Part == 0 && State->Instance->Lane == 0);
1652cab237bSDimitry Andric   VPBasicBlock *PrevVPBB = State->CFG.PrevVPBB;
1662cab237bSDimitry Andric   VPBlockBase *SingleHPred = nullptr;
1672cab237bSDimitry Andric   BasicBlock *NewBB = State->CFG.PrevBB; // Reuse it if possible.
1682cab237bSDimitry Andric 
1692cab237bSDimitry Andric   // 1. Create an IR basic block, or reuse the last one if possible.
1702cab237bSDimitry Andric   // The last IR basic block is reused, as an optimization, in three cases:
1712cab237bSDimitry Andric   // A. the first VPBB reuses the loop header BB - when PrevVPBB is null;
1722cab237bSDimitry Andric   // B. when the current VPBB has a single (hierarchical) predecessor which
1732cab237bSDimitry Andric   //    is PrevVPBB and the latter has a single (hierarchical) successor; and
1742cab237bSDimitry Andric   // C. when the current VPBB is an entry of a region replica - where PrevVPBB
1752cab237bSDimitry Andric   //    is the exit of this region from a previous instance, or the predecessor
1762cab237bSDimitry Andric   //    of this region.
1772cab237bSDimitry Andric   if (PrevVPBB && /* A */
1782cab237bSDimitry Andric       !((SingleHPred = getSingleHierarchicalPredecessor()) &&
1792cab237bSDimitry Andric         SingleHPred->getExitBasicBlock() == PrevVPBB &&
1802cab237bSDimitry Andric         PrevVPBB->getSingleHierarchicalSuccessor()) && /* B */
1812cab237bSDimitry Andric       !(Replica && getPredecessors().empty())) {       /* C */
1822cab237bSDimitry Andric     NewBB = createEmptyBasicBlock(State->CFG);
1832cab237bSDimitry Andric     State->Builder.SetInsertPoint(NewBB);
1842cab237bSDimitry Andric     // Temporarily terminate with unreachable until CFG is rewired.
1852cab237bSDimitry Andric     UnreachableInst *Terminator = State->Builder.CreateUnreachable();
1862cab237bSDimitry Andric     State->Builder.SetInsertPoint(Terminator);
1872cab237bSDimitry Andric     // Register NewBB in its loop. In innermost loops its the same for all BB's.
1882cab237bSDimitry Andric     Loop *L = State->LI->getLoopFor(State->CFG.LastBB);
1892cab237bSDimitry Andric     L->addBasicBlockToLoop(NewBB, *State->LI);
1902cab237bSDimitry Andric     State->CFG.PrevBB = NewBB;
1912cab237bSDimitry Andric   }
1922cab237bSDimitry Andric 
1932cab237bSDimitry Andric   // 2. Fill the IR basic block with IR instructions.
1944ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "LV: vectorizing VPBB:" << getName()
1952cab237bSDimitry Andric                     << " in BB:" << NewBB->getName() << '\n');
1962cab237bSDimitry Andric 
1972cab237bSDimitry Andric   State->CFG.VPBB2IRBB[this] = NewBB;
1982cab237bSDimitry Andric   State->CFG.PrevVPBB = this;
1992cab237bSDimitry Andric 
2002cab237bSDimitry Andric   for (VPRecipeBase &Recipe : Recipes)
2012cab237bSDimitry Andric     Recipe.execute(*State);
2022cab237bSDimitry Andric 
203*b5893f02SDimitry Andric   VPValue *CBV;
204*b5893f02SDimitry Andric   if (EnableVPlanNativePath && (CBV = getCondBit())) {
205*b5893f02SDimitry Andric     Value *IRCBV = CBV->getUnderlyingValue();
206*b5893f02SDimitry Andric     assert(IRCBV && "Unexpected null underlying value for condition bit");
207*b5893f02SDimitry Andric 
208*b5893f02SDimitry Andric     // Condition bit value in a VPBasicBlock is used as the branch selector. In
209*b5893f02SDimitry Andric     // the VPlan-native path case, since all branches are uniform we generate a
210*b5893f02SDimitry Andric     // branch instruction using the condition value from vector lane 0 and dummy
211*b5893f02SDimitry Andric     // successors. The successors are fixed later when the successor blocks are
212*b5893f02SDimitry Andric     // visited.
213*b5893f02SDimitry Andric     Value *NewCond = State->Callback.getOrCreateVectorValues(IRCBV, 0);
214*b5893f02SDimitry Andric     NewCond = State->Builder.CreateExtractElement(NewCond,
215*b5893f02SDimitry Andric                                                   State->Builder.getInt32(0));
216*b5893f02SDimitry Andric 
217*b5893f02SDimitry Andric     // Replace the temporary unreachable terminator with the new conditional
218*b5893f02SDimitry Andric     // branch.
219*b5893f02SDimitry Andric     auto *CurrentTerminator = NewBB->getTerminator();
220*b5893f02SDimitry Andric     assert(isa<UnreachableInst>(CurrentTerminator) &&
221*b5893f02SDimitry Andric            "Expected to replace unreachable terminator with conditional "
222*b5893f02SDimitry Andric            "branch.");
223*b5893f02SDimitry Andric     auto *CondBr = BranchInst::Create(NewBB, nullptr, NewCond);
224*b5893f02SDimitry Andric     CondBr->setSuccessor(0, nullptr);
225*b5893f02SDimitry Andric     ReplaceInstWithInst(CurrentTerminator, CondBr);
226*b5893f02SDimitry Andric   }
227*b5893f02SDimitry Andric 
2284ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "LV: filled BB:" << *NewBB);
2292cab237bSDimitry Andric }
2302cab237bSDimitry Andric 
execute(VPTransformState * State)2312cab237bSDimitry Andric void VPRegionBlock::execute(VPTransformState *State) {
2322cab237bSDimitry Andric   ReversePostOrderTraversal<VPBlockBase *> RPOT(Entry);
2332cab237bSDimitry Andric 
2342cab237bSDimitry Andric   if (!isReplicator()) {
2352cab237bSDimitry Andric     // Visit the VPBlocks connected to "this", starting from it.
2362cab237bSDimitry Andric     for (VPBlockBase *Block : RPOT) {
237*b5893f02SDimitry Andric       if (EnableVPlanNativePath) {
238*b5893f02SDimitry Andric         // The inner loop vectorization path does not represent loop preheader
239*b5893f02SDimitry Andric         // and exit blocks as part of the VPlan. In the VPlan-native path, skip
240*b5893f02SDimitry Andric         // vectorizing loop preheader block. In future, we may replace this
241*b5893f02SDimitry Andric         // check with the check for loop preheader.
242*b5893f02SDimitry Andric         if (Block->getNumPredecessors() == 0)
243*b5893f02SDimitry Andric           continue;
244*b5893f02SDimitry Andric 
245*b5893f02SDimitry Andric         // Skip vectorizing loop exit block. In future, we may replace this
246*b5893f02SDimitry Andric         // check with the check for loop exit.
247*b5893f02SDimitry Andric         if (Block->getNumSuccessors() == 0)
248*b5893f02SDimitry Andric           continue;
249*b5893f02SDimitry Andric       }
250*b5893f02SDimitry Andric 
2514ba319b5SDimitry Andric       LLVM_DEBUG(dbgs() << "LV: VPBlock in RPO " << Block->getName() << '\n');
2522cab237bSDimitry Andric       Block->execute(State);
2532cab237bSDimitry Andric     }
2542cab237bSDimitry Andric     return;
2552cab237bSDimitry Andric   }
2562cab237bSDimitry Andric 
2572cab237bSDimitry Andric   assert(!State->Instance && "Replicating a Region with non-null instance.");
2582cab237bSDimitry Andric 
2592cab237bSDimitry Andric   // Enter replicating mode.
2602cab237bSDimitry Andric   State->Instance = {0, 0};
2612cab237bSDimitry Andric 
2622cab237bSDimitry Andric   for (unsigned Part = 0, UF = State->UF; Part < UF; ++Part) {
2632cab237bSDimitry Andric     State->Instance->Part = Part;
2642cab237bSDimitry Andric     for (unsigned Lane = 0, VF = State->VF; Lane < VF; ++Lane) {
2652cab237bSDimitry Andric       State->Instance->Lane = Lane;
2662cab237bSDimitry Andric       // Visit the VPBlocks connected to \p this, starting from it.
2672cab237bSDimitry Andric       for (VPBlockBase *Block : RPOT) {
2684ba319b5SDimitry Andric         LLVM_DEBUG(dbgs() << "LV: VPBlock in RPO " << Block->getName() << '\n');
2692cab237bSDimitry Andric         Block->execute(State);
2702cab237bSDimitry Andric       }
2712cab237bSDimitry Andric     }
2722cab237bSDimitry Andric   }
2732cab237bSDimitry Andric 
2742cab237bSDimitry Andric   // Exit replicating mode.
2752cab237bSDimitry Andric   State->Instance.reset();
2762cab237bSDimitry Andric }
2772cab237bSDimitry Andric 
insertBefore(VPRecipeBase * InsertPos)2784ba319b5SDimitry Andric void VPRecipeBase::insertBefore(VPRecipeBase *InsertPos) {
2794ba319b5SDimitry Andric   Parent = InsertPos->getParent();
2804ba319b5SDimitry Andric   Parent->getRecipeList().insert(InsertPos->getIterator(), this);
2814ba319b5SDimitry Andric }
2824ba319b5SDimitry Andric 
eraseFromParent()2834ba319b5SDimitry Andric iplist<VPRecipeBase>::iterator VPRecipeBase::eraseFromParent() {
2844ba319b5SDimitry Andric   return getParent()->getRecipeList().erase(getIterator());
2854ba319b5SDimitry Andric }
2864ba319b5SDimitry Andric 
generateInstruction(VPTransformState & State,unsigned Part)2872cab237bSDimitry Andric void VPInstruction::generateInstruction(VPTransformState &State,
2882cab237bSDimitry Andric                                         unsigned Part) {
2892cab237bSDimitry Andric   IRBuilder<> &Builder = State.Builder;
2902cab237bSDimitry Andric 
2912cab237bSDimitry Andric   if (Instruction::isBinaryOp(getOpcode())) {
2922cab237bSDimitry Andric     Value *A = State.get(getOperand(0), Part);
2932cab237bSDimitry Andric     Value *B = State.get(getOperand(1), Part);
2942cab237bSDimitry Andric     Value *V = Builder.CreateBinOp((Instruction::BinaryOps)getOpcode(), A, B);
2952cab237bSDimitry Andric     State.set(this, V, Part);
2962cab237bSDimitry Andric     return;
2972cab237bSDimitry Andric   }
2982cab237bSDimitry Andric 
2992cab237bSDimitry Andric   switch (getOpcode()) {
3002cab237bSDimitry Andric   case VPInstruction::Not: {
3012cab237bSDimitry Andric     Value *A = State.get(getOperand(0), Part);
3022cab237bSDimitry Andric     Value *V = Builder.CreateNot(A);
3032cab237bSDimitry Andric     State.set(this, V, Part);
3042cab237bSDimitry Andric     break;
3052cab237bSDimitry Andric   }
306*b5893f02SDimitry Andric   case VPInstruction::ICmpULE: {
307*b5893f02SDimitry Andric     Value *IV = State.get(getOperand(0), Part);
308*b5893f02SDimitry Andric     Value *TC = State.get(getOperand(1), Part);
309*b5893f02SDimitry Andric     Value *V = Builder.CreateICmpULE(IV, TC);
310*b5893f02SDimitry Andric     State.set(this, V, Part);
311*b5893f02SDimitry Andric     break;
312*b5893f02SDimitry Andric   }
3132cab237bSDimitry Andric   default:
3142cab237bSDimitry Andric     llvm_unreachable("Unsupported opcode for instruction");
3152cab237bSDimitry Andric   }
3162cab237bSDimitry Andric }
3172cab237bSDimitry Andric 
execute(VPTransformState & State)3182cab237bSDimitry Andric void VPInstruction::execute(VPTransformState &State) {
3192cab237bSDimitry Andric   assert(!State.Instance && "VPInstruction executing an Instance");
3202cab237bSDimitry Andric   for (unsigned Part = 0; Part < State.UF; ++Part)
3212cab237bSDimitry Andric     generateInstruction(State, Part);
3222cab237bSDimitry Andric }
3232cab237bSDimitry Andric 
print(raw_ostream & O,const Twine & Indent) const3242cab237bSDimitry Andric void VPInstruction::print(raw_ostream &O, const Twine &Indent) const {
3252cab237bSDimitry Andric   O << " +\n" << Indent << "\"EMIT ";
3262cab237bSDimitry Andric   print(O);
3272cab237bSDimitry Andric   O << "\\l\"";
3282cab237bSDimitry Andric }
3292cab237bSDimitry Andric 
print(raw_ostream & O) const3302cab237bSDimitry Andric void VPInstruction::print(raw_ostream &O) const {
3312cab237bSDimitry Andric   printAsOperand(O);
3322cab237bSDimitry Andric   O << " = ";
3332cab237bSDimitry Andric 
3342cab237bSDimitry Andric   switch (getOpcode()) {
3352cab237bSDimitry Andric   case VPInstruction::Not:
3362cab237bSDimitry Andric     O << "not";
3372cab237bSDimitry Andric     break;
338*b5893f02SDimitry Andric   case VPInstruction::ICmpULE:
339*b5893f02SDimitry Andric     O << "icmp ule";
340*b5893f02SDimitry Andric     break;
341*b5893f02SDimitry Andric   case VPInstruction::SLPLoad:
342*b5893f02SDimitry Andric     O << "combined load";
343*b5893f02SDimitry Andric     break;
344*b5893f02SDimitry Andric   case VPInstruction::SLPStore:
345*b5893f02SDimitry Andric     O << "combined store";
346*b5893f02SDimitry Andric     break;
3472cab237bSDimitry Andric   default:
3482cab237bSDimitry Andric     O << Instruction::getOpcodeName(getOpcode());
3492cab237bSDimitry Andric   }
3502cab237bSDimitry Andric 
3512cab237bSDimitry Andric   for (const VPValue *Operand : operands()) {
3522cab237bSDimitry Andric     O << " ";
3532cab237bSDimitry Andric     Operand->printAsOperand(O);
3542cab237bSDimitry Andric   }
3552cab237bSDimitry Andric }
3562cab237bSDimitry Andric 
3572cab237bSDimitry Andric /// Generate the code inside the body of the vectorized loop. Assumes a single
3582cab237bSDimitry Andric /// LoopVectorBody basic-block was created for this. Introduce additional
3592cab237bSDimitry Andric /// basic-blocks as needed, and fill them all.
execute(VPTransformState * State)3602cab237bSDimitry Andric void VPlan::execute(VPTransformState *State) {
361*b5893f02SDimitry Andric   // -1. Check if the backedge taken count is needed, and if so build it.
362*b5893f02SDimitry Andric   if (BackedgeTakenCount && BackedgeTakenCount->getNumUsers()) {
363*b5893f02SDimitry Andric     Value *TC = State->TripCount;
364*b5893f02SDimitry Andric     IRBuilder<> Builder(State->CFG.PrevBB->getTerminator());
365*b5893f02SDimitry Andric     auto *TCMO = Builder.CreateSub(TC, ConstantInt::get(TC->getType(), 1),
366*b5893f02SDimitry Andric                                    "trip.count.minus.1");
367*b5893f02SDimitry Andric     Value2VPValue[TCMO] = BackedgeTakenCount;
368*b5893f02SDimitry Andric   }
369*b5893f02SDimitry Andric 
3702cab237bSDimitry Andric   // 0. Set the reverse mapping from VPValues to Values for code generation.
3712cab237bSDimitry Andric   for (auto &Entry : Value2VPValue)
3722cab237bSDimitry Andric     State->VPValue2Value[Entry.second] = Entry.first;
3732cab237bSDimitry Andric 
3742cab237bSDimitry Andric   BasicBlock *VectorPreHeaderBB = State->CFG.PrevBB;
3752cab237bSDimitry Andric   BasicBlock *VectorHeaderBB = VectorPreHeaderBB->getSingleSuccessor();
3762cab237bSDimitry Andric   assert(VectorHeaderBB && "Loop preheader does not have a single successor.");
3772cab237bSDimitry Andric   BasicBlock *VectorLatchBB = VectorHeaderBB;
3782cab237bSDimitry Andric 
3792cab237bSDimitry Andric   // 1. Make room to generate basic-blocks inside loop body if needed.
3802cab237bSDimitry Andric   VectorLatchBB = VectorHeaderBB->splitBasicBlock(
3812cab237bSDimitry Andric       VectorHeaderBB->getFirstInsertionPt(), "vector.body.latch");
3822cab237bSDimitry Andric   Loop *L = State->LI->getLoopFor(VectorHeaderBB);
3832cab237bSDimitry Andric   L->addBasicBlockToLoop(VectorLatchBB, *State->LI);
3842cab237bSDimitry Andric   // Remove the edge between Header and Latch to allow other connections.
3852cab237bSDimitry Andric   // Temporarily terminate with unreachable until CFG is rewired.
3862cab237bSDimitry Andric   // Note: this asserts the generated code's assumption that
3872cab237bSDimitry Andric   // getFirstInsertionPt() can be dereferenced into an Instruction.
3882cab237bSDimitry Andric   VectorHeaderBB->getTerminator()->eraseFromParent();
3892cab237bSDimitry Andric   State->Builder.SetInsertPoint(VectorHeaderBB);
3902cab237bSDimitry Andric   UnreachableInst *Terminator = State->Builder.CreateUnreachable();
3912cab237bSDimitry Andric   State->Builder.SetInsertPoint(Terminator);
3922cab237bSDimitry Andric 
3932cab237bSDimitry Andric   // 2. Generate code in loop body.
3942cab237bSDimitry Andric   State->CFG.PrevVPBB = nullptr;
3952cab237bSDimitry Andric   State->CFG.PrevBB = VectorHeaderBB;
3962cab237bSDimitry Andric   State->CFG.LastBB = VectorLatchBB;
3972cab237bSDimitry Andric 
3982cab237bSDimitry Andric   for (VPBlockBase *Block : depth_first(Entry))
3992cab237bSDimitry Andric     Block->execute(State);
4002cab237bSDimitry Andric 
401*b5893f02SDimitry Andric   // Setup branch terminator successors for VPBBs in VPBBsToFix based on
402*b5893f02SDimitry Andric   // VPBB's successors.
403*b5893f02SDimitry Andric   for (auto VPBB : State->CFG.VPBBsToFix) {
404*b5893f02SDimitry Andric     assert(EnableVPlanNativePath &&
405*b5893f02SDimitry Andric            "Unexpected VPBBsToFix in non VPlan-native path");
406*b5893f02SDimitry Andric     BasicBlock *BB = State->CFG.VPBB2IRBB[VPBB];
407*b5893f02SDimitry Andric     assert(BB && "Unexpected null basic block for VPBB");
408*b5893f02SDimitry Andric 
409*b5893f02SDimitry Andric     unsigned Idx = 0;
410*b5893f02SDimitry Andric     auto *BBTerminator = BB->getTerminator();
411*b5893f02SDimitry Andric 
412*b5893f02SDimitry Andric     for (VPBlockBase *SuccVPBlock : VPBB->getHierarchicalSuccessors()) {
413*b5893f02SDimitry Andric       VPBasicBlock *SuccVPBB = SuccVPBlock->getEntryBasicBlock();
414*b5893f02SDimitry Andric       BBTerminator->setSuccessor(Idx, State->CFG.VPBB2IRBB[SuccVPBB]);
415*b5893f02SDimitry Andric       ++Idx;
416*b5893f02SDimitry Andric     }
417*b5893f02SDimitry Andric   }
418*b5893f02SDimitry Andric 
4192cab237bSDimitry Andric   // 3. Merge the temporary latch created with the last basic-block filled.
4202cab237bSDimitry Andric   BasicBlock *LastBB = State->CFG.PrevBB;
4212cab237bSDimitry Andric   // Connect LastBB to VectorLatchBB to facilitate their merge.
422*b5893f02SDimitry Andric   assert((EnableVPlanNativePath ||
423*b5893f02SDimitry Andric           isa<UnreachableInst>(LastBB->getTerminator())) &&
424*b5893f02SDimitry Andric          "Expected InnerLoop VPlan CFG to terminate with unreachable");
425*b5893f02SDimitry Andric   assert((!EnableVPlanNativePath || isa<BranchInst>(LastBB->getTerminator())) &&
426*b5893f02SDimitry Andric          "Expected VPlan CFG to terminate with branch in NativePath");
4272cab237bSDimitry Andric   LastBB->getTerminator()->eraseFromParent();
4282cab237bSDimitry Andric   BranchInst::Create(VectorLatchBB, LastBB);
4292cab237bSDimitry Andric 
4302cab237bSDimitry Andric   // Merge LastBB with Latch.
4312cab237bSDimitry Andric   bool Merged = MergeBlockIntoPredecessor(VectorLatchBB, nullptr, State->LI);
4322cab237bSDimitry Andric   (void)Merged;
4332cab237bSDimitry Andric   assert(Merged && "Could not merge last basic block with latch.");
4342cab237bSDimitry Andric   VectorLatchBB = LastBB;
4352cab237bSDimitry Andric 
436*b5893f02SDimitry Andric   // We do not attempt to preserve DT for outer loop vectorization currently.
437*b5893f02SDimitry Andric   if (!EnableVPlanNativePath)
4382cab237bSDimitry Andric     updateDominatorTree(State->DT, VectorPreHeaderBB, VectorLatchBB);
4392cab237bSDimitry Andric }
4402cab237bSDimitry Andric 
updateDominatorTree(DominatorTree * DT,BasicBlock * LoopPreHeaderBB,BasicBlock * LoopLatchBB)4412cab237bSDimitry Andric void VPlan::updateDominatorTree(DominatorTree *DT, BasicBlock *LoopPreHeaderBB,
4422cab237bSDimitry Andric                                 BasicBlock *LoopLatchBB) {
4432cab237bSDimitry Andric   BasicBlock *LoopHeaderBB = LoopPreHeaderBB->getSingleSuccessor();
4442cab237bSDimitry Andric   assert(LoopHeaderBB && "Loop preheader does not have a single successor.");
4452cab237bSDimitry Andric   DT->addNewBlock(LoopHeaderBB, LoopPreHeaderBB);
4462cab237bSDimitry Andric   // The vector body may be more than a single basic-block by this point.
4472cab237bSDimitry Andric   // Update the dominator tree information inside the vector body by propagating
4482cab237bSDimitry Andric   // it from header to latch, expecting only triangular control-flow, if any.
4492cab237bSDimitry Andric   BasicBlock *PostDomSucc = nullptr;
4502cab237bSDimitry Andric   for (auto *BB = LoopHeaderBB; BB != LoopLatchBB; BB = PostDomSucc) {
4512cab237bSDimitry Andric     // Get the list of successors of this block.
4522cab237bSDimitry Andric     std::vector<BasicBlock *> Succs(succ_begin(BB), succ_end(BB));
4532cab237bSDimitry Andric     assert(Succs.size() <= 2 &&
4542cab237bSDimitry Andric            "Basic block in vector loop has more than 2 successors.");
4552cab237bSDimitry Andric     PostDomSucc = Succs[0];
4562cab237bSDimitry Andric     if (Succs.size() == 1) {
4572cab237bSDimitry Andric       assert(PostDomSucc->getSinglePredecessor() &&
4582cab237bSDimitry Andric              "PostDom successor has more than one predecessor.");
4592cab237bSDimitry Andric       DT->addNewBlock(PostDomSucc, BB);
4602cab237bSDimitry Andric       continue;
4612cab237bSDimitry Andric     }
4622cab237bSDimitry Andric     BasicBlock *InterimSucc = Succs[1];
4632cab237bSDimitry Andric     if (PostDomSucc->getSingleSuccessor() == InterimSucc) {
4642cab237bSDimitry Andric       PostDomSucc = Succs[1];
4652cab237bSDimitry Andric       InterimSucc = Succs[0];
4662cab237bSDimitry Andric     }
4672cab237bSDimitry Andric     assert(InterimSucc->getSingleSuccessor() == PostDomSucc &&
4682cab237bSDimitry Andric            "One successor of a basic block does not lead to the other.");
4692cab237bSDimitry Andric     assert(InterimSucc->getSinglePredecessor() &&
4702cab237bSDimitry Andric            "Interim successor has more than one predecessor.");
471*b5893f02SDimitry Andric     assert(PostDomSucc->hasNPredecessors(2) &&
4722cab237bSDimitry Andric            "PostDom successor has more than two predecessors.");
4732cab237bSDimitry Andric     DT->addNewBlock(InterimSucc, BB);
4742cab237bSDimitry Andric     DT->addNewBlock(PostDomSucc, BB);
4752cab237bSDimitry Andric   }
4762cab237bSDimitry Andric }
4772cab237bSDimitry Andric 
getUID(const VPBlockBase * Block)4782cab237bSDimitry Andric const Twine VPlanPrinter::getUID(const VPBlockBase *Block) {
4792cab237bSDimitry Andric   return (isa<VPRegionBlock>(Block) ? "cluster_N" : "N") +
4802cab237bSDimitry Andric          Twine(getOrCreateBID(Block));
4812cab237bSDimitry Andric }
4822cab237bSDimitry Andric 
getOrCreateName(const VPBlockBase * Block)4832cab237bSDimitry Andric const Twine VPlanPrinter::getOrCreateName(const VPBlockBase *Block) {
4842cab237bSDimitry Andric   const std::string &Name = Block->getName();
4852cab237bSDimitry Andric   if (!Name.empty())
4862cab237bSDimitry Andric     return Name;
4872cab237bSDimitry Andric   return "VPB" + Twine(getOrCreateBID(Block));
4882cab237bSDimitry Andric }
4892cab237bSDimitry Andric 
dump()4902cab237bSDimitry Andric void VPlanPrinter::dump() {
4912cab237bSDimitry Andric   Depth = 1;
4922cab237bSDimitry Andric   bumpIndent(0);
4932cab237bSDimitry Andric   OS << "digraph VPlan {\n";
4942cab237bSDimitry Andric   OS << "graph [labelloc=t, fontsize=30; label=\"Vectorization Plan";
4952cab237bSDimitry Andric   if (!Plan.getName().empty())
4962cab237bSDimitry Andric     OS << "\\n" << DOT::EscapeString(Plan.getName());
497*b5893f02SDimitry Andric   if (!Plan.Value2VPValue.empty() || Plan.BackedgeTakenCount) {
4982cab237bSDimitry Andric     OS << ", where:";
499*b5893f02SDimitry Andric     if (Plan.BackedgeTakenCount)
500*b5893f02SDimitry Andric       OS << "\\n"
501*b5893f02SDimitry Andric          << *Plan.getOrCreateBackedgeTakenCount() << " := BackedgeTakenCount";
5022cab237bSDimitry Andric     for (auto Entry : Plan.Value2VPValue) {
5032cab237bSDimitry Andric       OS << "\\n" << *Entry.second;
5042cab237bSDimitry Andric       OS << DOT::EscapeString(" := ");
5052cab237bSDimitry Andric       Entry.first->printAsOperand(OS, false);
5062cab237bSDimitry Andric     }
5072cab237bSDimitry Andric   }
5082cab237bSDimitry Andric   OS << "\"]\n";
5092cab237bSDimitry Andric   OS << "node [shape=rect, fontname=Courier, fontsize=30]\n";
5102cab237bSDimitry Andric   OS << "edge [fontname=Courier, fontsize=30]\n";
5112cab237bSDimitry Andric   OS << "compound=true\n";
5122cab237bSDimitry Andric 
5132cab237bSDimitry Andric   for (VPBlockBase *Block : depth_first(Plan.getEntry()))
5142cab237bSDimitry Andric     dumpBlock(Block);
5152cab237bSDimitry Andric 
5162cab237bSDimitry Andric   OS << "}\n";
5172cab237bSDimitry Andric }
5182cab237bSDimitry Andric 
dumpBlock(const VPBlockBase * Block)5192cab237bSDimitry Andric void VPlanPrinter::dumpBlock(const VPBlockBase *Block) {
5202cab237bSDimitry Andric   if (const VPBasicBlock *BasicBlock = dyn_cast<VPBasicBlock>(Block))
5212cab237bSDimitry Andric     dumpBasicBlock(BasicBlock);
5222cab237bSDimitry Andric   else if (const VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
5232cab237bSDimitry Andric     dumpRegion(Region);
5242cab237bSDimitry Andric   else
5252cab237bSDimitry Andric     llvm_unreachable("Unsupported kind of VPBlock.");
5262cab237bSDimitry Andric }
5272cab237bSDimitry Andric 
drawEdge(const VPBlockBase * From,const VPBlockBase * To,bool Hidden,const Twine & Label)5282cab237bSDimitry Andric void VPlanPrinter::drawEdge(const VPBlockBase *From, const VPBlockBase *To,
5292cab237bSDimitry Andric                             bool Hidden, const Twine &Label) {
5302cab237bSDimitry Andric   // Due to "dot" we print an edge between two regions as an edge between the
5312cab237bSDimitry Andric   // exit basic block and the entry basic of the respective regions.
5322cab237bSDimitry Andric   const VPBlockBase *Tail = From->getExitBasicBlock();
5332cab237bSDimitry Andric   const VPBlockBase *Head = To->getEntryBasicBlock();
5342cab237bSDimitry Andric   OS << Indent << getUID(Tail) << " -> " << getUID(Head);
5352cab237bSDimitry Andric   OS << " [ label=\"" << Label << '\"';
5362cab237bSDimitry Andric   if (Tail != From)
5372cab237bSDimitry Andric     OS << " ltail=" << getUID(From);
5382cab237bSDimitry Andric   if (Head != To)
5392cab237bSDimitry Andric     OS << " lhead=" << getUID(To);
5402cab237bSDimitry Andric   if (Hidden)
5412cab237bSDimitry Andric     OS << "; splines=none";
5422cab237bSDimitry Andric   OS << "]\n";
5432cab237bSDimitry Andric }
5442cab237bSDimitry Andric 
dumpEdges(const VPBlockBase * Block)5452cab237bSDimitry Andric void VPlanPrinter::dumpEdges(const VPBlockBase *Block) {
5462cab237bSDimitry Andric   auto &Successors = Block->getSuccessors();
5472cab237bSDimitry Andric   if (Successors.size() == 1)
5482cab237bSDimitry Andric     drawEdge(Block, Successors.front(), false, "");
5492cab237bSDimitry Andric   else if (Successors.size() == 2) {
5502cab237bSDimitry Andric     drawEdge(Block, Successors.front(), false, "T");
5512cab237bSDimitry Andric     drawEdge(Block, Successors.back(), false, "F");
5522cab237bSDimitry Andric   } else {
5532cab237bSDimitry Andric     unsigned SuccessorNumber = 0;
5542cab237bSDimitry Andric     for (auto *Successor : Successors)
5552cab237bSDimitry Andric       drawEdge(Block, Successor, false, Twine(SuccessorNumber++));
5562cab237bSDimitry Andric   }
5572cab237bSDimitry Andric }
5582cab237bSDimitry Andric 
dumpBasicBlock(const VPBasicBlock * BasicBlock)5592cab237bSDimitry Andric void VPlanPrinter::dumpBasicBlock(const VPBasicBlock *BasicBlock) {
5602cab237bSDimitry Andric   OS << Indent << getUID(BasicBlock) << " [label =\n";
5612cab237bSDimitry Andric   bumpIndent(1);
5622cab237bSDimitry Andric   OS << Indent << "\"" << DOT::EscapeString(BasicBlock->getName()) << ":\\n\"";
5632cab237bSDimitry Andric   bumpIndent(1);
5642cab237bSDimitry Andric   for (const VPRecipeBase &Recipe : *BasicBlock)
5652cab237bSDimitry Andric     Recipe.print(OS, Indent);
5664ba319b5SDimitry Andric 
5674ba319b5SDimitry Andric   // Dump the condition bit.
5684ba319b5SDimitry Andric   const VPValue *CBV = BasicBlock->getCondBit();
5694ba319b5SDimitry Andric   if (CBV) {
5704ba319b5SDimitry Andric     OS << " +\n" << Indent << " \"CondBit: ";
5714ba319b5SDimitry Andric     if (const VPInstruction *CBI = dyn_cast<VPInstruction>(CBV)) {
5724ba319b5SDimitry Andric       CBI->printAsOperand(OS);
5734ba319b5SDimitry Andric       OS << " (" << DOT::EscapeString(CBI->getParent()->getName()) << ")\\l\"";
574*b5893f02SDimitry Andric     } else {
5754ba319b5SDimitry Andric       CBV->printAsOperand(OS);
576*b5893f02SDimitry Andric       OS << "\"";
577*b5893f02SDimitry Andric     }
5784ba319b5SDimitry Andric   }
5794ba319b5SDimitry Andric 
5802cab237bSDimitry Andric   bumpIndent(-2);
5812cab237bSDimitry Andric   OS << "\n" << Indent << "]\n";
5822cab237bSDimitry Andric   dumpEdges(BasicBlock);
5832cab237bSDimitry Andric }
5842cab237bSDimitry Andric 
dumpRegion(const VPRegionBlock * Region)5852cab237bSDimitry Andric void VPlanPrinter::dumpRegion(const VPRegionBlock *Region) {
5862cab237bSDimitry Andric   OS << Indent << "subgraph " << getUID(Region) << " {\n";
5872cab237bSDimitry Andric   bumpIndent(1);
5882cab237bSDimitry Andric   OS << Indent << "fontname=Courier\n"
5892cab237bSDimitry Andric      << Indent << "label=\""
5902cab237bSDimitry Andric      << DOT::EscapeString(Region->isReplicator() ? "<xVFxUF> " : "<x1> ")
5912cab237bSDimitry Andric      << DOT::EscapeString(Region->getName()) << "\"\n";
5922cab237bSDimitry Andric   // Dump the blocks of the region.
5932cab237bSDimitry Andric   assert(Region->getEntry() && "Region contains no inner blocks.");
5942cab237bSDimitry Andric   for (const VPBlockBase *Block : depth_first(Region->getEntry()))
5952cab237bSDimitry Andric     dumpBlock(Block);
5962cab237bSDimitry Andric   bumpIndent(-1);
5972cab237bSDimitry Andric   OS << Indent << "}\n";
5982cab237bSDimitry Andric   dumpEdges(Region);
5992cab237bSDimitry Andric }
6002cab237bSDimitry Andric 
printAsIngredient(raw_ostream & O,Value * V)6012cab237bSDimitry Andric void VPlanPrinter::printAsIngredient(raw_ostream &O, Value *V) {
6022cab237bSDimitry Andric   std::string IngredientString;
6032cab237bSDimitry Andric   raw_string_ostream RSO(IngredientString);
6042cab237bSDimitry Andric   if (auto *Inst = dyn_cast<Instruction>(V)) {
6052cab237bSDimitry Andric     if (!Inst->getType()->isVoidTy()) {
6062cab237bSDimitry Andric       Inst->printAsOperand(RSO, false);
6072cab237bSDimitry Andric       RSO << " = ";
6082cab237bSDimitry Andric     }
6092cab237bSDimitry Andric     RSO << Inst->getOpcodeName() << " ";
6102cab237bSDimitry Andric     unsigned E = Inst->getNumOperands();
6112cab237bSDimitry Andric     if (E > 0) {
6122cab237bSDimitry Andric       Inst->getOperand(0)->printAsOperand(RSO, false);
6132cab237bSDimitry Andric       for (unsigned I = 1; I < E; ++I)
6142cab237bSDimitry Andric         Inst->getOperand(I)->printAsOperand(RSO << ", ", false);
6152cab237bSDimitry Andric     }
6162cab237bSDimitry Andric   } else // !Inst
6172cab237bSDimitry Andric     V->printAsOperand(RSO, false);
6182cab237bSDimitry Andric   RSO.flush();
6192cab237bSDimitry Andric   O << DOT::EscapeString(IngredientString);
6202cab237bSDimitry Andric }
6212cab237bSDimitry Andric 
print(raw_ostream & O,const Twine & Indent) const6222cab237bSDimitry Andric void VPWidenRecipe::print(raw_ostream &O, const Twine &Indent) const {
6232cab237bSDimitry Andric   O << " +\n" << Indent << "\"WIDEN\\l\"";
6242cab237bSDimitry Andric   for (auto &Instr : make_range(Begin, End))
6252cab237bSDimitry Andric     O << " +\n" << Indent << "\"  " << VPlanIngredient(&Instr) << "\\l\"";
6262cab237bSDimitry Andric }
6272cab237bSDimitry Andric 
print(raw_ostream & O,const Twine & Indent) const6282cab237bSDimitry Andric void VPWidenIntOrFpInductionRecipe::print(raw_ostream &O,
6292cab237bSDimitry Andric                                           const Twine &Indent) const {
6302cab237bSDimitry Andric   O << " +\n" << Indent << "\"WIDEN-INDUCTION";
6312cab237bSDimitry Andric   if (Trunc) {
6322cab237bSDimitry Andric     O << "\\l\"";
6332cab237bSDimitry Andric     O << " +\n" << Indent << "\"  " << VPlanIngredient(IV) << "\\l\"";
6342cab237bSDimitry Andric     O << " +\n" << Indent << "\"  " << VPlanIngredient(Trunc) << "\\l\"";
6352cab237bSDimitry Andric   } else
6362cab237bSDimitry Andric     O << " " << VPlanIngredient(IV) << "\\l\"";
6372cab237bSDimitry Andric }
6382cab237bSDimitry Andric 
print(raw_ostream & O,const Twine & Indent) const6392cab237bSDimitry Andric void VPWidenPHIRecipe::print(raw_ostream &O, const Twine &Indent) const {
6402cab237bSDimitry Andric   O << " +\n" << Indent << "\"WIDEN-PHI " << VPlanIngredient(Phi) << "\\l\"";
6412cab237bSDimitry Andric }
6422cab237bSDimitry Andric 
print(raw_ostream & O,const Twine & Indent) const6432cab237bSDimitry Andric void VPBlendRecipe::print(raw_ostream &O, const Twine &Indent) const {
6442cab237bSDimitry Andric   O << " +\n" << Indent << "\"BLEND ";
6452cab237bSDimitry Andric   Phi->printAsOperand(O, false);
6462cab237bSDimitry Andric   O << " =";
6472cab237bSDimitry Andric   if (!User) {
6482cab237bSDimitry Andric     // Not a User of any mask: not really blending, this is a
6492cab237bSDimitry Andric     // single-predecessor phi.
6502cab237bSDimitry Andric     O << " ";
6512cab237bSDimitry Andric     Phi->getIncomingValue(0)->printAsOperand(O, false);
6522cab237bSDimitry Andric   } else {
6532cab237bSDimitry Andric     for (unsigned I = 0, E = User->getNumOperands(); I < E; ++I) {
6542cab237bSDimitry Andric       O << " ";
6552cab237bSDimitry Andric       Phi->getIncomingValue(I)->printAsOperand(O, false);
6562cab237bSDimitry Andric       O << "/";
6572cab237bSDimitry Andric       User->getOperand(I)->printAsOperand(O);
6582cab237bSDimitry Andric     }
6592cab237bSDimitry Andric   }
6602cab237bSDimitry Andric   O << "\\l\"";
6612cab237bSDimitry Andric }
6622cab237bSDimitry Andric 
print(raw_ostream & O,const Twine & Indent) const6632cab237bSDimitry Andric void VPReplicateRecipe::print(raw_ostream &O, const Twine &Indent) const {
6642cab237bSDimitry Andric   O << " +\n"
6652cab237bSDimitry Andric     << Indent << "\"" << (IsUniform ? "CLONE " : "REPLICATE ")
6662cab237bSDimitry Andric     << VPlanIngredient(Ingredient);
6672cab237bSDimitry Andric   if (AlsoPack)
6682cab237bSDimitry Andric     O << " (S->V)";
6692cab237bSDimitry Andric   O << "\\l\"";
6702cab237bSDimitry Andric }
6712cab237bSDimitry Andric 
print(raw_ostream & O,const Twine & Indent) const6722cab237bSDimitry Andric void VPPredInstPHIRecipe::print(raw_ostream &O, const Twine &Indent) const {
6732cab237bSDimitry Andric   O << " +\n"
6742cab237bSDimitry Andric     << Indent << "\"PHI-PREDICATED-INSTRUCTION " << VPlanIngredient(PredInst)
6752cab237bSDimitry Andric     << "\\l\"";
6762cab237bSDimitry Andric }
6772cab237bSDimitry Andric 
print(raw_ostream & O,const Twine & Indent) const6782cab237bSDimitry Andric void VPWidenMemoryInstructionRecipe::print(raw_ostream &O,
6792cab237bSDimitry Andric                                            const Twine &Indent) const {
6802cab237bSDimitry Andric   O << " +\n" << Indent << "\"WIDEN " << VPlanIngredient(&Instr);
6812cab237bSDimitry Andric   if (User) {
6822cab237bSDimitry Andric     O << ", ";
6832cab237bSDimitry Andric     User->getOperand(0)->printAsOperand(O);
6842cab237bSDimitry Andric   }
6852cab237bSDimitry Andric   O << "\\l\"";
6862cab237bSDimitry Andric }
6874ba319b5SDimitry Andric 
6884ba319b5SDimitry Andric template void DomTreeBuilder::Calculate<VPDominatorTree>(VPDominatorTree &DT);
689*b5893f02SDimitry Andric 
replaceAllUsesWith(VPValue * New)690*b5893f02SDimitry Andric void VPValue::replaceAllUsesWith(VPValue *New) {
691*b5893f02SDimitry Andric   for (VPUser *User : users())
692*b5893f02SDimitry Andric     for (unsigned I = 0, E = User->getNumOperands(); I < E; ++I)
693*b5893f02SDimitry Andric       if (User->getOperand(I) == this)
694*b5893f02SDimitry Andric         User->setOperand(I, New);
695*b5893f02SDimitry Andric }
696*b5893f02SDimitry Andric 
visitRegion(VPRegionBlock * Region,Old2NewTy & Old2New,InterleavedAccessInfo & IAI)697*b5893f02SDimitry Andric void VPInterleavedAccessInfo::visitRegion(VPRegionBlock *Region,
698*b5893f02SDimitry Andric                                           Old2NewTy &Old2New,
699*b5893f02SDimitry Andric                                           InterleavedAccessInfo &IAI) {
700*b5893f02SDimitry Andric   ReversePostOrderTraversal<VPBlockBase *> RPOT(Region->getEntry());
701*b5893f02SDimitry Andric   for (VPBlockBase *Base : RPOT) {
702*b5893f02SDimitry Andric     visitBlock(Base, Old2New, IAI);
703*b5893f02SDimitry Andric   }
704*b5893f02SDimitry Andric }
705*b5893f02SDimitry Andric 
visitBlock(VPBlockBase * Block,Old2NewTy & Old2New,InterleavedAccessInfo & IAI)706*b5893f02SDimitry Andric void VPInterleavedAccessInfo::visitBlock(VPBlockBase *Block, Old2NewTy &Old2New,
707*b5893f02SDimitry Andric                                          InterleavedAccessInfo &IAI) {
708*b5893f02SDimitry Andric   if (VPBasicBlock *VPBB = dyn_cast<VPBasicBlock>(Block)) {
709*b5893f02SDimitry Andric     for (VPRecipeBase &VPI : *VPBB) {
710*b5893f02SDimitry Andric       assert(isa<VPInstruction>(&VPI) && "Can only handle VPInstructions");
711*b5893f02SDimitry Andric       auto *VPInst = cast<VPInstruction>(&VPI);
712*b5893f02SDimitry Andric       auto *Inst = cast<Instruction>(VPInst->getUnderlyingValue());
713*b5893f02SDimitry Andric       auto *IG = IAI.getInterleaveGroup(Inst);
714*b5893f02SDimitry Andric       if (!IG)
715*b5893f02SDimitry Andric         continue;
716*b5893f02SDimitry Andric 
717*b5893f02SDimitry Andric       auto NewIGIter = Old2New.find(IG);
718*b5893f02SDimitry Andric       if (NewIGIter == Old2New.end())
719*b5893f02SDimitry Andric         Old2New[IG] = new InterleaveGroup<VPInstruction>(
720*b5893f02SDimitry Andric             IG->getFactor(), IG->isReverse(), IG->getAlignment());
721*b5893f02SDimitry Andric 
722*b5893f02SDimitry Andric       if (Inst == IG->getInsertPos())
723*b5893f02SDimitry Andric         Old2New[IG]->setInsertPos(VPInst);
724*b5893f02SDimitry Andric 
725*b5893f02SDimitry Andric       InterleaveGroupMap[VPInst] = Old2New[IG];
726*b5893f02SDimitry Andric       InterleaveGroupMap[VPInst]->insertMember(
727*b5893f02SDimitry Andric           VPInst, IG->getIndex(Inst),
728*b5893f02SDimitry Andric           IG->isReverse() ? (-1) * int(IG->getFactor()) : IG->getFactor());
729*b5893f02SDimitry Andric     }
730*b5893f02SDimitry Andric   } else if (VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
731*b5893f02SDimitry Andric     visitRegion(Region, Old2New, IAI);
732*b5893f02SDimitry Andric   else
733*b5893f02SDimitry Andric     llvm_unreachable("Unsupported kind of VPBlock.");
734*b5893f02SDimitry Andric }
735*b5893f02SDimitry Andric 
VPInterleavedAccessInfo(VPlan & Plan,InterleavedAccessInfo & IAI)736*b5893f02SDimitry Andric VPInterleavedAccessInfo::VPInterleavedAccessInfo(VPlan &Plan,
737*b5893f02SDimitry Andric                                                  InterleavedAccessInfo &IAI) {
738*b5893f02SDimitry Andric   Old2NewTy Old2New;
739*b5893f02SDimitry Andric   visitRegion(cast<VPRegionBlock>(Plan.getEntry()), Old2New, IAI);
740*b5893f02SDimitry Andric }
741