11f58dda4SAyal Zaks //===- VPlan.cpp - Vectorizer Plan ----------------------------------------===//
21f58dda4SAyal Zaks //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61f58dda4SAyal Zaks //
71f58dda4SAyal Zaks //===----------------------------------------------------------------------===//
81f58dda4SAyal Zaks ///
91f58dda4SAyal Zaks /// \file
101f58dda4SAyal Zaks /// This is the LLVM vectorization plan. It represents a candidate for
111f58dda4SAyal Zaks /// vectorization, allowing to plan and optimize how to vectorize a given loop
121f58dda4SAyal Zaks /// before generating LLVM-IR.
131f58dda4SAyal Zaks /// The vectorizer uses vectorization plans to estimate the costs of potential
141f58dda4SAyal Zaks /// candidates and if profitable to execute the desired plan, generating vector
151f58dda4SAyal Zaks /// LLVM-IR code.
161f58dda4SAyal Zaks ///
171f58dda4SAyal Zaks //===----------------------------------------------------------------------===//
181f58dda4SAyal Zaks 
191f58dda4SAyal Zaks #include "VPlan.h"
202a34ac86SDiego Caballero #include "VPlanDominatorTree.h"
216cadde7fSEugene Zelenko #include "llvm/ADT/DepthFirstIterator.h"
221f58dda4SAyal Zaks #include "llvm/ADT/PostOrderIterator.h"
23533f8576SFlorian Hahn #include "llvm/ADT/STLExtras.h"
246cadde7fSEugene Zelenko #include "llvm/ADT/SmallVector.h"
256cadde7fSEugene Zelenko #include "llvm/ADT/Twine.h"
261f58dda4SAyal Zaks #include "llvm/Analysis/LoopInfo.h"
271f58dda4SAyal Zaks #include "llvm/IR/BasicBlock.h"
286cadde7fSEugene Zelenko #include "llvm/IR/CFG.h"
295a723576SFlorian Hahn #include "llvm/IR/IRBuilder.h"
306cadde7fSEugene Zelenko #include "llvm/IR/Instruction.h"
316cadde7fSEugene Zelenko #include "llvm/IR/Instructions.h"
326cadde7fSEugene Zelenko #include "llvm/IR/Type.h"
336cadde7fSEugene Zelenko #include "llvm/IR/Value.h"
346cadde7fSEugene Zelenko #include "llvm/Support/Casting.h"
354c1a1d3cSReid Kleckner #include "llvm/Support/CommandLine.h"
366cadde7fSEugene Zelenko #include "llvm/Support/Debug.h"
372a34ac86SDiego Caballero #include "llvm/Support/GenericDomTreeConstruction.h"
381f58dda4SAyal Zaks #include "llvm/Support/GraphWriter.h"
396cadde7fSEugene Zelenko #include "llvm/Support/raw_ostream.h"
401f58dda4SAyal Zaks #include "llvm/Transforms/Utils/BasicBlockUtils.h"
41583abd0eSFlorian Hahn #include "llvm/Transforms/Utils/LoopVersioning.h"
429bc866ccSFlorian Hahn #include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
436cadde7fSEugene Zelenko #include <cassert>
446cadde7fSEugene Zelenko #include <string>
456cadde7fSEugene Zelenko #include <vector>
461f58dda4SAyal Zaks 
471f58dda4SAyal Zaks using namespace llvm;
48ea7f3035SHideki Saito extern cl::opt<bool> EnableVPlanNativePath;
491f58dda4SAyal Zaks 
501f58dda4SAyal Zaks #define DEBUG_TYPE "vplan"
511f58dda4SAyal Zaks 
5292205cb2SAndrei Elovikov #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
operator <<(raw_ostream & OS,const VPValue & V)538b9d1f3cSGil Rapaport raw_ostream &llvm::operator<<(raw_ostream &OS, const VPValue &V) {
5440e7bfc4SFlorian Hahn   const VPInstruction *Instr = dyn_cast<VPInstruction>(&V);
5540e7bfc4SFlorian Hahn   VPSlotTracker SlotTracker(
5640e7bfc4SFlorian Hahn       (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
5740e7bfc4SFlorian Hahn   V.print(OS, SlotTracker);
588b9d1f3cSGil Rapaport   return OS;
598b9d1f3cSGil Rapaport }
6092205cb2SAndrei Elovikov #endif
618b9d1f3cSGil Rapaport 
getAsRuntimeExpr(IRBuilderBase & Builder,const ElementCount & VF) const625a723576SFlorian Hahn Value *VPLane::getAsRuntimeExpr(IRBuilderBase &Builder,
63fec0a0adSDavid Sherwood                                 const ElementCount &VF) const {
64fec0a0adSDavid Sherwood   switch (LaneKind) {
65fec0a0adSDavid Sherwood   case VPLane::Kind::ScalableLast:
66fec0a0adSDavid Sherwood     // Lane = RuntimeVF - VF.getKnownMinValue() + Lane
67fec0a0adSDavid Sherwood     return Builder.CreateSub(getRuntimeVF(Builder, Builder.getInt32Ty(), VF),
68fec0a0adSDavid Sherwood                              Builder.getInt32(VF.getKnownMinValue() - Lane));
69fec0a0adSDavid Sherwood   case VPLane::Kind::First:
70fec0a0adSDavid Sherwood     return Builder.getInt32(Lane);
71fec0a0adSDavid Sherwood   }
72fec0a0adSDavid Sherwood   llvm_unreachable("Unknown lane kind");
73fec0a0adSDavid Sherwood }
74fec0a0adSDavid Sherwood 
VPValue(const unsigned char SC,Value * UV,VPDef * Def)7552f3714dSFlorian Hahn VPValue::VPValue(const unsigned char SC, Value *UV, VPDef *Def)
7652f3714dSFlorian Hahn     : SubclassID(SC), UnderlyingVal(UV), Def(Def) {
7752f3714dSFlorian Hahn   if (Def)
7852f3714dSFlorian Hahn     Def->addDefinedValue(this);
7952f3714dSFlorian Hahn }
8052f3714dSFlorian Hahn 
~VPValue()8152f3714dSFlorian Hahn VPValue::~VPValue() {
8252f3714dSFlorian Hahn   assert(Users.empty() && "trying to delete a VPValue with remaining users");
8352f3714dSFlorian Hahn   if (Def)
8452f3714dSFlorian Hahn     Def->removeDefinedValue(this);
8552f3714dSFlorian Hahn }
8652f3714dSFlorian Hahn 
8792205cb2SAndrei Elovikov #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
print(raw_ostream & OS,VPSlotTracker & SlotTracker) const8840e7bfc4SFlorian Hahn void VPValue::print(raw_ostream &OS, VPSlotTracker &SlotTracker) const {
89eb0371e4SFlorian Hahn   if (const VPRecipeBase *R = dyn_cast_or_null<VPRecipeBase>(Def))
90eb0371e4SFlorian Hahn     R->print(OS, "", SlotTracker);
9140e7bfc4SFlorian Hahn   else
9240e7bfc4SFlorian Hahn     printAsOperand(OS, SlotTracker);
9340e7bfc4SFlorian Hahn }
9440e7bfc4SFlorian Hahn 
dump() const95c671e34bSFlorian Hahn void VPValue::dump() const {
96eb0371e4SFlorian Hahn   const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this->Def);
97c671e34bSFlorian Hahn   VPSlotTracker SlotTracker(
98c671e34bSFlorian Hahn       (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
99c671e34bSFlorian Hahn   print(dbgs(), SlotTracker);
100c671e34bSFlorian Hahn   dbgs() << "\n";
101c671e34bSFlorian Hahn }
102c671e34bSFlorian Hahn 
dump() const103eb0371e4SFlorian Hahn void VPDef::dump() const {
104eb0371e4SFlorian Hahn   const VPRecipeBase *Instr = dyn_cast_or_null<VPRecipeBase>(this);
105eb0371e4SFlorian Hahn   VPSlotTracker SlotTracker(
106eb0371e4SFlorian Hahn       (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
107c671e34bSFlorian Hahn   print(dbgs(), "", SlotTracker);
108c671e34bSFlorian Hahn   dbgs() << "\n";
109c671e34bSFlorian Hahn }
11092205cb2SAndrei Elovikov #endif
111c671e34bSFlorian Hahn 
11205afa555SFlorian Hahn // Get the top-most entry block of \p Start. This is the entry block of the
11305afa555SFlorian Hahn // containing VPlan. This function is templated to support both const and non-const blocks
getPlanEntry(T * Start)11405afa555SFlorian Hahn template <typename T> static T *getPlanEntry(T *Start) {
11505afa555SFlorian Hahn   T *Next = Start;
11605afa555SFlorian Hahn   T *Current = Start;
11705afa555SFlorian Hahn   while ((Next = Next->getParent()))
11805afa555SFlorian Hahn     Current = Next;
11905afa555SFlorian Hahn 
12005afa555SFlorian Hahn   SmallSetVector<T *, 8> WorkList;
12105afa555SFlorian Hahn   WorkList.insert(Current);
12205afa555SFlorian Hahn 
12305afa555SFlorian Hahn   for (unsigned i = 0; i < WorkList.size(); i++) {
12405afa555SFlorian Hahn     T *Current = WorkList[i];
12505afa555SFlorian Hahn     if (Current->getNumPredecessors() == 0)
12605afa555SFlorian Hahn       return Current;
12705afa555SFlorian Hahn     auto &Predecessors = Current->getPredecessors();
12805afa555SFlorian Hahn     WorkList.insert(Predecessors.begin(), Predecessors.end());
12905afa555SFlorian Hahn   }
13005afa555SFlorian Hahn 
13105afa555SFlorian Hahn   llvm_unreachable("VPlan without any entry node without predecessors");
13205afa555SFlorian Hahn }
13305afa555SFlorian Hahn 
getPlan()13405afa555SFlorian Hahn VPlan *VPBlockBase::getPlan() { return getPlanEntry(this)->Plan; }
13505afa555SFlorian Hahn 
getPlan() const13605afa555SFlorian Hahn const VPlan *VPBlockBase::getPlan() const { return getPlanEntry(this)->Plan; }
13705afa555SFlorian Hahn 
1381f58dda4SAyal Zaks /// \return the VPBasicBlock that is the entry of Block, possibly indirectly.
getEntryBasicBlock() const1391f58dda4SAyal Zaks const VPBasicBlock *VPBlockBase::getEntryBasicBlock() const {
1401f58dda4SAyal Zaks   const VPBlockBase *Block = this;
1411f58dda4SAyal Zaks   while (const VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
1421f58dda4SAyal Zaks     Block = Region->getEntry();
1431f58dda4SAyal Zaks   return cast<VPBasicBlock>(Block);
1441f58dda4SAyal Zaks }
1451f58dda4SAyal Zaks 
getEntryBasicBlock()1461f58dda4SAyal Zaks VPBasicBlock *VPBlockBase::getEntryBasicBlock() {
1471f58dda4SAyal Zaks   VPBlockBase *Block = this;
1481f58dda4SAyal Zaks   while (VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
1491f58dda4SAyal Zaks     Block = Region->getEntry();
1501f58dda4SAyal Zaks   return cast<VPBasicBlock>(Block);
1511f58dda4SAyal Zaks }
1521f58dda4SAyal Zaks 
setPlan(VPlan * ParentPlan)15305afa555SFlorian Hahn void VPBlockBase::setPlan(VPlan *ParentPlan) {
15405afa555SFlorian Hahn   assert(ParentPlan->getEntry() == this &&
15505afa555SFlorian Hahn          "Can only set plan on its entry block.");
15605afa555SFlorian Hahn   Plan = ParentPlan;
15705afa555SFlorian Hahn }
15805afa555SFlorian Hahn 
1591f58dda4SAyal Zaks /// \return the VPBasicBlock that is the exit of Block, possibly indirectly.
getExitingBasicBlock() const1606abce17fSFlorian Hahn const VPBasicBlock *VPBlockBase::getExitingBasicBlock() const {
1611f58dda4SAyal Zaks   const VPBlockBase *Block = this;
1621f58dda4SAyal Zaks   while (const VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
1636abce17fSFlorian Hahn     Block = Region->getExiting();
1641f58dda4SAyal Zaks   return cast<VPBasicBlock>(Block);
1651f58dda4SAyal Zaks }
1661f58dda4SAyal Zaks 
getExitingBasicBlock()1676abce17fSFlorian Hahn VPBasicBlock *VPBlockBase::getExitingBasicBlock() {
1681f58dda4SAyal Zaks   VPBlockBase *Block = this;
1691f58dda4SAyal Zaks   while (VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
1706abce17fSFlorian Hahn     Block = Region->getExiting();
1711f58dda4SAyal Zaks   return cast<VPBasicBlock>(Block);
1721f58dda4SAyal Zaks }
1731f58dda4SAyal Zaks 
getEnclosingBlockWithSuccessors()1741f58dda4SAyal Zaks VPBlockBase *VPBlockBase::getEnclosingBlockWithSuccessors() {
1751f58dda4SAyal Zaks   if (!Successors.empty() || !Parent)
1761f58dda4SAyal Zaks     return this;
1776abce17fSFlorian Hahn   assert(Parent->getExiting() == this &&
1786abce17fSFlorian Hahn          "Block w/o successors not the exiting block of its parent.");
1791f58dda4SAyal Zaks   return Parent->getEnclosingBlockWithSuccessors();
1801f58dda4SAyal Zaks }
1811f58dda4SAyal Zaks 
getEnclosingBlockWithPredecessors()1821f58dda4SAyal Zaks VPBlockBase *VPBlockBase::getEnclosingBlockWithPredecessors() {
1831f58dda4SAyal Zaks   if (!Predecessors.empty() || !Parent)
1841f58dda4SAyal Zaks     return this;
1851f58dda4SAyal Zaks   assert(Parent->getEntry() == this &&
1861f58dda4SAyal Zaks          "Block w/o predecessors not the entry of its parent.");
1871f58dda4SAyal Zaks   return Parent->getEnclosingBlockWithPredecessors();
1881f58dda4SAyal Zaks }
1891f58dda4SAyal Zaks 
deleteCFG(VPBlockBase * Entry)1901f58dda4SAyal Zaks void VPBlockBase::deleteCFG(VPBlockBase *Entry) {
19119aacdb7SKazu Hirata   SmallVector<VPBlockBase *, 8> Blocks(depth_first(Entry));
1921f58dda4SAyal Zaks 
1931f58dda4SAyal Zaks   for (VPBlockBase *Block : Blocks)
1941f58dda4SAyal Zaks     delete Block;
1951f58dda4SAyal Zaks }
1961f58dda4SAyal Zaks 
getFirstNonPhi()197be6e8e50SDavid Green VPBasicBlock::iterator VPBasicBlock::getFirstNonPhi() {
198be6e8e50SDavid Green   iterator It = begin();
199942e068dSFlorian Hahn   while (It != end() && It->isPhi())
200be6e8e50SDavid Green     It++;
201be6e8e50SDavid Green   return It;
202be6e8e50SDavid Green }
203be6e8e50SDavid Green 
get(VPValue * Def,const VPIteration & Instance)2043201274dSFlorian Hahn Value *VPTransformState::get(VPValue *Def, const VPIteration &Instance) {
205daaa0e35SFlorian Hahn   if (!Def->getDef())
2063201274dSFlorian Hahn     return Def->getLiveInIRValue();
2073201274dSFlorian Hahn 
208fec0a0adSDavid Sherwood   if (hasScalarValue(Def, Instance)) {
209fec0a0adSDavid Sherwood     return Data
210fec0a0adSDavid Sherwood         .PerPartScalars[Def][Instance.Part][Instance.Lane.mapToCacheIndex(VF)];
211fec0a0adSDavid Sherwood   }
2123201274dSFlorian Hahn 
21354a14c26SFlorian Hahn   assert(hasVectorValue(Def, Instance.Part));
2143201274dSFlorian Hahn   auto *VecPart = Data.PerPartOutput[Def][Instance.Part];
2153201274dSFlorian Hahn   if (!VecPart->getType()->isVectorTy()) {
216fec0a0adSDavid Sherwood     assert(Instance.Lane.isFirstLane() && "cannot get lane > 0 for scalar");
2173201274dSFlorian Hahn     return VecPart;
2183201274dSFlorian Hahn   }
2193201274dSFlorian Hahn   // TODO: Cache created scalar values.
220fec0a0adSDavid Sherwood   Value *Lane = Instance.Lane.getAsRuntimeExpr(Builder, VF);
221fec0a0adSDavid Sherwood   auto *Extract = Builder.CreateExtractElement(VecPart, Lane);
22254a14c26SFlorian Hahn   // set(Def, Extract, Instance);
22354a14c26SFlorian Hahn   return Extract;
2243201274dSFlorian Hahn }
getPreheaderBBFor(VPRecipeBase * R)225256c6b0bSFlorian Hahn BasicBlock *VPTransformState::CFGState::getPreheaderBBFor(VPRecipeBase *R) {
226256c6b0bSFlorian Hahn   VPRegionBlock *LoopRegion = R->getParent()->getEnclosingLoopRegion();
227256c6b0bSFlorian Hahn   return VPBB2IRBB[LoopRegion->getPreheaderVPBB()];
228256c6b0bSFlorian Hahn }
2293201274dSFlorian Hahn 
addNewMetadata(Instruction * To,const Instruction * Orig)230583abd0eSFlorian Hahn void VPTransformState::addNewMetadata(Instruction *To,
231583abd0eSFlorian Hahn                                       const Instruction *Orig) {
232583abd0eSFlorian Hahn   // If the loop was versioned with memchecks, add the corresponding no-alias
233583abd0eSFlorian Hahn   // metadata.
234583abd0eSFlorian Hahn   if (LVer && (isa<LoadInst>(Orig) || isa<StoreInst>(Orig)))
235583abd0eSFlorian Hahn     LVer->annotateInstWithNoAlias(To, Orig);
236583abd0eSFlorian Hahn }
237583abd0eSFlorian Hahn 
addMetadata(Instruction * To,Instruction * From)238583abd0eSFlorian Hahn void VPTransformState::addMetadata(Instruction *To, Instruction *From) {
239583abd0eSFlorian Hahn   propagateMetadata(To, From);
240583abd0eSFlorian Hahn   addNewMetadata(To, From);
241583abd0eSFlorian Hahn }
242583abd0eSFlorian Hahn 
addMetadata(ArrayRef<Value * > To,Instruction * From)243583abd0eSFlorian Hahn void VPTransformState::addMetadata(ArrayRef<Value *> To, Instruction *From) {
244583abd0eSFlorian Hahn   for (Value *V : To) {
245583abd0eSFlorian Hahn     if (Instruction *I = dyn_cast<Instruction>(V))
246583abd0eSFlorian Hahn       addMetadata(I, From);
247583abd0eSFlorian Hahn   }
248583abd0eSFlorian Hahn }
249583abd0eSFlorian Hahn 
setDebugLocFromInst(const Value * V)250b0da3c6fSFlorian Hahn void VPTransformState::setDebugLocFromInst(const Value *V) {
251b4694229SFlorian Hahn   const Instruction *Inst = dyn_cast<Instruction>(V);
252b4694229SFlorian Hahn   if (!Inst) {
253b4694229SFlorian Hahn     Builder.SetCurrentDebugLocation(DebugLoc());
254b4694229SFlorian Hahn     return;
255b4694229SFlorian Hahn   }
256b0da3c6fSFlorian Hahn 
257b4694229SFlorian Hahn   const DILocation *DIL = Inst->getDebugLoc();
258b0da3c6fSFlorian Hahn   // When a FSDiscriminator is enabled, we don't need to add the multiply
259b0da3c6fSFlorian Hahn   // factors to the discriminators.
260b0da3c6fSFlorian Hahn   if (DIL && Inst->getFunction()->isDebugInfoForProfiling() &&
261b0da3c6fSFlorian Hahn       !isa<DbgInfoIntrinsic>(Inst) && !EnableFSDiscriminator) {
262b0da3c6fSFlorian Hahn     // FIXME: For scalable vectors, assume vscale=1.
263b0da3c6fSFlorian Hahn     auto NewDIL =
264b0da3c6fSFlorian Hahn         DIL->cloneByMultiplyingDuplicationFactor(UF * VF.getKnownMinValue());
265b0da3c6fSFlorian Hahn     if (NewDIL)
266b0da3c6fSFlorian Hahn       Builder.SetCurrentDebugLocation(*NewDIL);
267b0da3c6fSFlorian Hahn     else
268b0da3c6fSFlorian Hahn       LLVM_DEBUG(dbgs() << "Failed to create new discriminator: "
269b0da3c6fSFlorian Hahn                         << DIL->getFilename() << " Line: " << DIL->getLine());
270b0da3c6fSFlorian Hahn   } else
271b0da3c6fSFlorian Hahn     Builder.SetCurrentDebugLocation(DIL);
272b0da3c6fSFlorian Hahn }
273b0da3c6fSFlorian Hahn 
2741f58dda4SAyal Zaks BasicBlock *
createEmptyBasicBlock(VPTransformState::CFGState & CFG)2751f58dda4SAyal Zaks VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
2761f58dda4SAyal Zaks   // BB stands for IR BasicBlocks. VPBB stands for VPlan VPBasicBlocks.
2771f58dda4SAyal Zaks   // Pred stands for Predessor. Prev stands for Previous - last visited/created.
2781f58dda4SAyal Zaks   BasicBlock *PrevBB = CFG.PrevBB;
2791f58dda4SAyal Zaks   BasicBlock *NewBB = BasicBlock::Create(PrevBB->getContext(), getName(),
280e8673f2fSFlorian Hahn                                          PrevBB->getParent(), CFG.ExitBB);
281d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "LV: created " << NewBB->getName() << '\n');
2821f58dda4SAyal Zaks 
2831f58dda4SAyal Zaks   // Hook up the new basic block to its predecessors.
2841f58dda4SAyal Zaks   for (VPBlockBase *PredVPBlock : getHierarchicalPredecessors()) {
2856abce17fSFlorian Hahn     VPBasicBlock *PredVPBB = PredVPBlock->getExitingBasicBlock();
286416a5080SFlorian Hahn     auto &PredVPSuccessors = PredVPBB->getHierarchicalSuccessors();
2871f58dda4SAyal Zaks     BasicBlock *PredBB = CFG.VPBB2IRBB[PredVPBB];
288ea7f3035SHideki Saito 
2891f58dda4SAyal Zaks     assert(PredBB && "Predecessor basic-block not found building successor.");
2901f58dda4SAyal Zaks     auto *PredBBTerminator = PredBB->getTerminator();
291d34e60caSNicola Zaghen     LLVM_DEBUG(dbgs() << "LV: draw edge from" << PredBB->getName() << '\n');
292256c6b0bSFlorian Hahn 
293256c6b0bSFlorian Hahn     auto *TermBr = dyn_cast<BranchInst>(PredBBTerminator);
294e66127e6SFlorian Hahn     if (isa<UnreachableInst>(PredBBTerminator)) {
2951f58dda4SAyal Zaks       assert(PredVPSuccessors.size() == 1 &&
2961f58dda4SAyal Zaks              "Predecessor ending w/o branch must have single successor.");
29729fe998eSFlorian Hahn       DebugLoc DL = PredBBTerminator->getDebugLoc();
2981f58dda4SAyal Zaks       PredBBTerminator->eraseFromParent();
29929fe998eSFlorian Hahn       auto *Br = BranchInst::Create(NewBB, PredBB);
30029fe998eSFlorian Hahn       Br->setDebugLoc(DL);
301e66127e6SFlorian Hahn     } else if (TermBr && !TermBr->isConditional()) {
302e66127e6SFlorian Hahn       TermBr->setSuccessor(0, NewBB);
303256c6b0bSFlorian Hahn     } else {
304416a5080SFlorian Hahn       // Set each forward successor here when it is created, excluding
305416a5080SFlorian Hahn       // backedges. A backward successor is set when the branch is created.
306416a5080SFlorian Hahn       unsigned idx = PredVPSuccessors.front() == this ? 0 : 1;
307416a5080SFlorian Hahn       assert(!TermBr->getSuccessor(idx) &&
308416a5080SFlorian Hahn              "Trying to reset an existing successor block.");
309416a5080SFlorian Hahn       TermBr->setSuccessor(idx, NewBB);
3101f58dda4SAyal Zaks     }
3111f58dda4SAyal Zaks   }
3121f58dda4SAyal Zaks   return NewBB;
3131f58dda4SAyal Zaks }
3141f58dda4SAyal Zaks 
execute(VPTransformState * State)3151f58dda4SAyal Zaks void VPBasicBlock::execute(VPTransformState *State) {
316d4626eb0SDavid Sherwood   bool Replica = State->Instance && !State->Instance->isFirstIteration();
3171f58dda4SAyal Zaks   VPBasicBlock *PrevVPBB = State->CFG.PrevVPBB;
3181f58dda4SAyal Zaks   VPBlockBase *SingleHPred = nullptr;
3191f58dda4SAyal Zaks   BasicBlock *NewBB = State->CFG.PrevBB; // Reuse it if possible.
3201f58dda4SAyal Zaks 
321e66127e6SFlorian Hahn   auto IsLoopRegion = [](VPBlockBase *BB) {
322256c6b0bSFlorian Hahn     auto *R = dyn_cast<VPRegionBlock>(BB);
323256c6b0bSFlorian Hahn     return R && !R->isReplicator();
324256c6b0bSFlorian Hahn   };
325256c6b0bSFlorian Hahn 
326bea69b23SFlorian Hahn   // 1. Create an IR basic block, or reuse the last one or ExitBB if possible.
327bea69b23SFlorian Hahn   if (getPlan()->getVectorLoopRegion()->getSingleSuccessor() == this) {
328bea69b23SFlorian Hahn     // ExitBB can be re-used for the exit block of the Plan.
329bea69b23SFlorian Hahn     NewBB = State->CFG.ExitBB;
330bea69b23SFlorian Hahn     State->CFG.PrevBB = NewBB;
331416a5080SFlorian Hahn 
332416a5080SFlorian Hahn     // Update the branch instruction in the predecessor to branch to ExitBB.
333416a5080SFlorian Hahn     VPBlockBase *PredVPB = getSingleHierarchicalPredecessor();
334416a5080SFlorian Hahn     VPBasicBlock *ExitingVPBB = PredVPB->getExitingBasicBlock();
335416a5080SFlorian Hahn     assert(PredVPB->getSingleSuccessor() == this &&
336416a5080SFlorian Hahn            "predecessor must have the current block as only successor");
337416a5080SFlorian Hahn     BasicBlock *ExitingBB = State->CFG.VPBB2IRBB[ExitingVPBB];
338416a5080SFlorian Hahn     // The Exit block of a loop is always set to be successor 0 of the Exiting
339416a5080SFlorian Hahn     // block.
340416a5080SFlorian Hahn     cast<BranchInst>(ExitingBB->getTerminator())->setSuccessor(0, NewBB);
341bea69b23SFlorian Hahn   } else if (PrevVPBB && /* A */
3421f58dda4SAyal Zaks              !((SingleHPred = getSingleHierarchicalPredecessor()) &&
3436abce17fSFlorian Hahn                SingleHPred->getExitingBasicBlock() == PrevVPBB &&
344256c6b0bSFlorian Hahn                PrevVPBB->getSingleHierarchicalSuccessor() &&
345256c6b0bSFlorian Hahn                (SingleHPred->getParent() == getEnclosingLoopRegion() &&
346e66127e6SFlorian Hahn                 !IsLoopRegion(SingleHPred))) &&         /* B */
3471f58dda4SAyal Zaks              !(Replica && getPredecessors().empty())) { /* C */
348bea69b23SFlorian Hahn     // The last IR basic block is reused, as an optimization, in three cases:
349bea69b23SFlorian Hahn     // A. the first VPBB reuses the loop pre-header BB - when PrevVPBB is null;
350bea69b23SFlorian Hahn     // B. when the current VPBB has a single (hierarchical) predecessor which
351bea69b23SFlorian Hahn     //    is PrevVPBB and the latter has a single (hierarchical) successor which
352bea69b23SFlorian Hahn     //    both are in the same non-replicator region; and
353bea69b23SFlorian Hahn     // C. when the current VPBB is an entry of a region replica - where PrevVPBB
3546abce17fSFlorian Hahn     //    is the exiting VPBB of this region from a previous instance, or the
355bea69b23SFlorian Hahn     //    predecessor of this region.
356bea69b23SFlorian Hahn 
3571f58dda4SAyal Zaks     NewBB = createEmptyBasicBlock(State->CFG);
3581f58dda4SAyal Zaks     State->Builder.SetInsertPoint(NewBB);
3591f58dda4SAyal Zaks     // Temporarily terminate with unreachable until CFG is rewired.
3601f58dda4SAyal Zaks     UnreachableInst *Terminator = State->Builder.CreateUnreachable();
361bea69b23SFlorian Hahn     // Register NewBB in its loop. In innermost loops its the same for all
362bea69b23SFlorian Hahn     // BB's.
363256c6b0bSFlorian Hahn     if (State->CurrentVectorLoop)
3641ff022e2SFlorian Hahn       State->CurrentVectorLoop->addBasicBlockToLoop(NewBB, *State->LI);
3651f58dda4SAyal Zaks     State->Builder.SetInsertPoint(Terminator);
36614e3650fSFlorian Hahn     State->CFG.PrevBB = NewBB;
3671ff022e2SFlorian Hahn   }
368f8101e4dSFlorian Hahn 
3691f58dda4SAyal Zaks   // 2. Fill the IR basic block with IR instructions.
370d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "LV: vectorizing VPBB:" << getName()
3711f58dda4SAyal Zaks                     << " in BB:" << NewBB->getName() << '\n');
3721f58dda4SAyal Zaks 
3731f58dda4SAyal Zaks   State->CFG.VPBB2IRBB[this] = NewBB;
3741f58dda4SAyal Zaks   State->CFG.PrevVPBB = this;
3751f58dda4SAyal Zaks 
3761f58dda4SAyal Zaks   for (VPRecipeBase &Recipe : Recipes)
3771f58dda4SAyal Zaks     Recipe.execute(*State);
3781f58dda4SAyal Zaks 
379d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "LV: filled BB:" << *NewBB);
3801f58dda4SAyal Zaks }
3811f58dda4SAyal Zaks 
dropAllReferences(VPValue * NewValue)382348d85a6SFlorian Hahn void VPBasicBlock::dropAllReferences(VPValue *NewValue) {
383348d85a6SFlorian Hahn   for (VPRecipeBase &R : Recipes) {
384c0c0ae16SFlorian Hahn     for (auto *Def : R.definedValues())
385cd608dc8SFlorian Hahn       Def->replaceAllUsesWith(NewValue);
386348d85a6SFlorian Hahn 
38785fe5c93SFlorian Hahn     for (unsigned I = 0, E = R.getNumOperands(); I != E; I++)
38885fe5c93SFlorian Hahn       R.setOperand(I, NewValue);
389348d85a6SFlorian Hahn   }
390348d85a6SFlorian Hahn }
391348d85a6SFlorian Hahn 
splitAt(iterator SplitAt)392ccebf7a1SFlorian Hahn VPBasicBlock *VPBasicBlock::splitAt(iterator SplitAt) {
393bdada754SFlorian Hahn   assert((SplitAt == end() || SplitAt->getParent() == this) &&
394ccebf7a1SFlorian Hahn          "can only split at a position in the same block");
395ccebf7a1SFlorian Hahn 
3963b35113fSFlorian Hahn   SmallVector<VPBlockBase *, 2> Succs(successors());
397ccebf7a1SFlorian Hahn   // First, disconnect the current block from its successors.
398ccebf7a1SFlorian Hahn   for (VPBlockBase *Succ : Succs)
399ccebf7a1SFlorian Hahn     VPBlockUtils::disconnectBlocks(this, Succ);
400ccebf7a1SFlorian Hahn 
401ccebf7a1SFlorian Hahn   // Create new empty block after the block to split.
402ccebf7a1SFlorian Hahn   auto *SplitBlock = new VPBasicBlock(getName() + ".split");
403ccebf7a1SFlorian Hahn   VPBlockUtils::insertBlockAfter(SplitBlock, this);
404ccebf7a1SFlorian Hahn 
405ccebf7a1SFlorian Hahn   // Add successors for block to split to new block.
406ccebf7a1SFlorian Hahn   for (VPBlockBase *Succ : Succs)
407ccebf7a1SFlorian Hahn     VPBlockUtils::connectBlocks(SplitBlock, Succ);
408ccebf7a1SFlorian Hahn 
409ccebf7a1SFlorian Hahn   // Finally, move the recipes starting at SplitAt to new block.
410ccebf7a1SFlorian Hahn   for (VPRecipeBase &ToMove :
411ccebf7a1SFlorian Hahn        make_early_inc_range(make_range(SplitAt, this->end())))
412ccebf7a1SFlorian Hahn     ToMove.moveBefore(*SplitBlock, SplitBlock->end());
413ccebf7a1SFlorian Hahn 
414ccebf7a1SFlorian Hahn   return SplitBlock;
415ccebf7a1SFlorian Hahn }
416ccebf7a1SFlorian Hahn 
getEnclosingLoopRegion()417256c6b0bSFlorian Hahn VPRegionBlock *VPBasicBlock::getEnclosingLoopRegion() {
418256c6b0bSFlorian Hahn   VPRegionBlock *P = getParent();
419256c6b0bSFlorian Hahn   if (P && P->isReplicator()) {
420256c6b0bSFlorian Hahn     P = P->getParent();
421256c6b0bSFlorian Hahn     assert(!cast<VPRegionBlock>(P)->isReplicator() &&
422256c6b0bSFlorian Hahn            "unexpected nested replicate regions");
423256c6b0bSFlorian Hahn   }
424256c6b0bSFlorian Hahn   return P;
425256c6b0bSFlorian Hahn }
426256c6b0bSFlorian Hahn 
hasConditionalTerminator(const VPBasicBlock * VPBB)427a5bb4a3bSFlorian Hahn static bool hasConditionalTerminator(const VPBasicBlock *VPBB) {
428a5bb4a3bSFlorian Hahn   if (VPBB->empty()) {
429a5bb4a3bSFlorian Hahn     assert(
430a5bb4a3bSFlorian Hahn         VPBB->getNumSuccessors() < 2 &&
431a5bb4a3bSFlorian Hahn         "block with multiple successors doesn't have a recipe as terminator");
432a5bb4a3bSFlorian Hahn     return false;
433a5bb4a3bSFlorian Hahn   }
434a5bb4a3bSFlorian Hahn 
435a5bb4a3bSFlorian Hahn   const VPRecipeBase *R = &VPBB->back();
436a5bb4a3bSFlorian Hahn   auto *VPI = dyn_cast<VPInstruction>(R);
437a5bb4a3bSFlorian Hahn   bool IsCondBranch =
438a5bb4a3bSFlorian Hahn       isa<VPBranchOnMaskRecipe>(R) ||
439a5bb4a3bSFlorian Hahn       (VPI && (VPI->getOpcode() == VPInstruction::BranchOnCond ||
440a5bb4a3bSFlorian Hahn                VPI->getOpcode() == VPInstruction::BranchOnCount));
441a8d2a381SBenjamin Kramer   (void)IsCondBranch;
442a5bb4a3bSFlorian Hahn 
443a5bb4a3bSFlorian Hahn   if (VPBB->getNumSuccessors() >= 2 || VPBB->isExiting()) {
444a5bb4a3bSFlorian Hahn     assert(IsCondBranch && "block with multiple successors not terminated by "
445a5bb4a3bSFlorian Hahn                            "conditional branch recipe");
446a5bb4a3bSFlorian Hahn 
447a5bb4a3bSFlorian Hahn     return true;
448a5bb4a3bSFlorian Hahn   }
449a5bb4a3bSFlorian Hahn 
450a5bb4a3bSFlorian Hahn   assert(
451a5bb4a3bSFlorian Hahn       !IsCondBranch &&
452a5bb4a3bSFlorian Hahn       "block with 0 or 1 successors terminated by conditional branch recipe");
453a5bb4a3bSFlorian Hahn   return false;
454a5bb4a3bSFlorian Hahn }
455a5bb4a3bSFlorian Hahn 
getTerminator()456a5bb4a3bSFlorian Hahn VPRecipeBase *VPBasicBlock::getTerminator() {
457a5bb4a3bSFlorian Hahn   if (hasConditionalTerminator(this))
458a5bb4a3bSFlorian Hahn     return &back();
459a5bb4a3bSFlorian Hahn   return nullptr;
460a5bb4a3bSFlorian Hahn }
461a5bb4a3bSFlorian Hahn 
getTerminator() const462a5bb4a3bSFlorian Hahn const VPRecipeBase *VPBasicBlock::getTerminator() const {
463a5bb4a3bSFlorian Hahn   if (hasConditionalTerminator(this))
464a5bb4a3bSFlorian Hahn     return &back();
465a5bb4a3bSFlorian Hahn   return nullptr;
466a5bb4a3bSFlorian Hahn }
467a5bb4a3bSFlorian Hahn 
isExiting() const468a5bb4a3bSFlorian Hahn bool VPBasicBlock::isExiting() const {
469a5bb4a3bSFlorian Hahn   return getParent()->getExitingBasicBlock() == this;
470a5bb4a3bSFlorian Hahn }
471a5bb4a3bSFlorian Hahn 
47292205cb2SAndrei Elovikov #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
printSuccessors(raw_ostream & O,const Twine & Indent) const4731465e777SFlorian Hahn void VPBlockBase::printSuccessors(raw_ostream &O, const Twine &Indent) const {
4741465e777SFlorian Hahn   if (getSuccessors().empty()) {
4751465e777SFlorian Hahn     O << Indent << "No successors\n";
4761465e777SFlorian Hahn   } else {
4771465e777SFlorian Hahn     O << Indent << "Successor(s): ";
4781465e777SFlorian Hahn     ListSeparator LS;
4791465e777SFlorian Hahn     for (auto *Succ : getSuccessors())
4801465e777SFlorian Hahn       O << LS << Succ->getName();
4811465e777SFlorian Hahn     O << '\n';
4821465e777SFlorian Hahn   }
4831465e777SFlorian Hahn }
4841465e777SFlorian Hahn 
print(raw_ostream & O,const Twine & Indent,VPSlotTracker & SlotTracker) const48593a9d2deSAndrei Elovikov void VPBasicBlock::print(raw_ostream &O, const Twine &Indent,
48693a9d2deSAndrei Elovikov                          VPSlotTracker &SlotTracker) const {
48793a9d2deSAndrei Elovikov   O << Indent << getName() << ":\n";
48893a9d2deSAndrei Elovikov 
48993a9d2deSAndrei Elovikov   auto RecipeIndent = Indent + "  ";
49093a9d2deSAndrei Elovikov   for (const VPRecipeBase &Recipe : *this) {
49193a9d2deSAndrei Elovikov     Recipe.print(O, RecipeIndent, SlotTracker);
49293a9d2deSAndrei Elovikov     O << '\n';
49393a9d2deSAndrei Elovikov   }
49493a9d2deSAndrei Elovikov 
4951465e777SFlorian Hahn   printSuccessors(O, Indent);
49693a9d2deSAndrei Elovikov }
49792205cb2SAndrei Elovikov #endif
49893a9d2deSAndrei Elovikov 
dropAllReferences(VPValue * NewValue)499bd0b1311SFlorian Hahn void VPRegionBlock::dropAllReferences(VPValue *NewValue) {
500bd0b1311SFlorian Hahn   for (VPBlockBase *Block : depth_first(Entry))
501bd0b1311SFlorian Hahn     // Drop all references in VPBasicBlocks and replace all uses with
502bd0b1311SFlorian Hahn     // DummyValue.
503bd0b1311SFlorian Hahn     Block->dropAllReferences(NewValue);
504bd0b1311SFlorian Hahn }
505bd0b1311SFlorian Hahn 
execute(VPTransformState * State)5061f58dda4SAyal Zaks void VPRegionBlock::execute(VPTransformState *State) {
5071f58dda4SAyal Zaks   ReversePostOrderTraversal<VPBlockBase *> RPOT(Entry);
5081f58dda4SAyal Zaks 
5091f58dda4SAyal Zaks   if (!isReplicator()) {
510f8101e4dSFlorian Hahn     // Create and register the new vector loop.
5118cd18927SFlorian Hahn     Loop *PrevLoop = State->CurrentVectorLoop;
512f8101e4dSFlorian Hahn     State->CurrentVectorLoop = State->LI->AllocateLoop();
513256c6b0bSFlorian Hahn     BasicBlock *VectorPH = State->CFG.VPBB2IRBB[getPreheaderVPBB()];
514256c6b0bSFlorian Hahn     Loop *ParentLoop = State->LI->getLoopFor(VectorPH);
515f8101e4dSFlorian Hahn 
516f8101e4dSFlorian Hahn     // Insert the new loop into the loop nest and register the new basic blocks
517f8101e4dSFlorian Hahn     // before calling any utilities such as SCEV that require valid LoopInfo.
518f8101e4dSFlorian Hahn     if (ParentLoop)
519f8101e4dSFlorian Hahn       ParentLoop->addChildLoop(State->CurrentVectorLoop);
520f8101e4dSFlorian Hahn     else
521f8101e4dSFlorian Hahn       State->LI->addTopLevelLoop(State->CurrentVectorLoop);
522f8101e4dSFlorian Hahn 
5231f58dda4SAyal Zaks     // Visit the VPBlocks connected to "this", starting from it.
5241f58dda4SAyal Zaks     for (VPBlockBase *Block : RPOT) {
525d34e60caSNicola Zaghen       LLVM_DEBUG(dbgs() << "LV: VPBlock in RPO " << Block->getName() << '\n');
5261f58dda4SAyal Zaks       Block->execute(State);
5271f58dda4SAyal Zaks     }
5288cd18927SFlorian Hahn 
5298cd18927SFlorian Hahn     State->CurrentVectorLoop = PrevLoop;
5301f58dda4SAyal Zaks     return;
5311f58dda4SAyal Zaks   }
5321f58dda4SAyal Zaks 
5331f58dda4SAyal Zaks   assert(!State->Instance && "Replicating a Region with non-null instance.");
5341f58dda4SAyal Zaks 
5351f58dda4SAyal Zaks   // Enter replicating mode.
536d4626eb0SDavid Sherwood   State->Instance = VPIteration(0, 0);
5371f58dda4SAyal Zaks 
5381f58dda4SAyal Zaks   for (unsigned Part = 0, UF = State->UF; Part < UF; ++Part) {
5391f58dda4SAyal Zaks     State->Instance->Part = Part;
540f4257c58SDavid Sherwood     assert(!State->VF.isScalable() && "VF is assumed to be non scalable.");
541f4257c58SDavid Sherwood     for (unsigned Lane = 0, VF = State->VF.getKnownMinValue(); Lane < VF;
542f4257c58SDavid Sherwood          ++Lane) {
543fec0a0adSDavid Sherwood       State->Instance->Lane = VPLane(Lane, VPLane::Kind::First);
5441f58dda4SAyal Zaks       // Visit the VPBlocks connected to \p this, starting from it.
5451f58dda4SAyal Zaks       for (VPBlockBase *Block : RPOT) {
546d34e60caSNicola Zaghen         LLVM_DEBUG(dbgs() << "LV: VPBlock in RPO " << Block->getName() << '\n');
5471f58dda4SAyal Zaks         Block->execute(State);
5481f58dda4SAyal Zaks       }
5491f58dda4SAyal Zaks     }
5501f58dda4SAyal Zaks   }
5511f58dda4SAyal Zaks 
5521f58dda4SAyal Zaks   // Exit replicating mode.
5531f58dda4SAyal Zaks   State->Instance.reset();
5541f58dda4SAyal Zaks }
5551f58dda4SAyal Zaks 
55692205cb2SAndrei Elovikov #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
print(raw_ostream & O,const Twine & Indent,VPSlotTracker & SlotTracker) const55793a9d2deSAndrei Elovikov void VPRegionBlock::print(raw_ostream &O, const Twine &Indent,
55893a9d2deSAndrei Elovikov                           VPSlotTracker &SlotTracker) const {
55993a9d2deSAndrei Elovikov   O << Indent << (isReplicator() ? "<xVFxUF> " : "<x1> ") << getName() << ": {";
56093a9d2deSAndrei Elovikov   auto NewIndent = Indent + "  ";
56193a9d2deSAndrei Elovikov   for (auto *BlockBase : depth_first(Entry)) {
56293a9d2deSAndrei Elovikov     O << '\n';
56393a9d2deSAndrei Elovikov     BlockBase->print(O, NewIndent, SlotTracker);
56493a9d2deSAndrei Elovikov   }
56593a9d2deSAndrei Elovikov   O << Indent << "}\n";
5661465e777SFlorian Hahn 
5671465e777SFlorian Hahn   printSuccessors(O, Indent);
56893a9d2deSAndrei Elovikov }
56992205cb2SAndrei Elovikov #endif
57093a9d2deSAndrei Elovikov 
getActiveLaneMaskPhi()57103fee671SDavid Sherwood VPActiveLaneMaskPHIRecipe *VPlan::getActiveLaneMaskPhi() {
57203fee671SDavid Sherwood   VPBasicBlock *Header = getVectorLoopRegion()->getEntryBasicBlock();
57303fee671SDavid Sherwood   for (VPRecipeBase &R : Header->phis()) {
57403fee671SDavid Sherwood     if (isa<VPActiveLaneMaskPHIRecipe>(&R))
57503fee671SDavid Sherwood       return cast<VPActiveLaneMaskPHIRecipe>(&R);
57603fee671SDavid Sherwood   }
57703fee671SDavid Sherwood   return nullptr;
57803fee671SDavid Sherwood }
57903fee671SDavid Sherwood 
canSimplifyBranchOnCond(VPInstruction * Term)58003fee671SDavid Sherwood static bool canSimplifyBranchOnCond(VPInstruction *Term) {
58103fee671SDavid Sherwood   VPInstruction *Not = dyn_cast<VPInstruction>(Term->getOperand(0));
58203fee671SDavid Sherwood   if (!Not || Not->getOpcode() != VPInstruction::Not)
58303fee671SDavid Sherwood     return false;
58403fee671SDavid Sherwood 
58503fee671SDavid Sherwood   VPInstruction *ALM = dyn_cast<VPInstruction>(Not->getOperand(0));
58603fee671SDavid Sherwood   return ALM && ALM->getOpcode() == VPInstruction::ActiveLaneMask;
58703fee671SDavid Sherwood }
58803fee671SDavid Sherwood 
prepareToExecute(Value * TripCountV,Value * VectorTripCountV,Value * CanonicalIVStartValue,VPTransformState & State,bool IsEpilogueVectorization)58965c4d619SFlorian Hahn void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
59065c4d619SFlorian Hahn                              Value *CanonicalIVStartValue,
5910dddf04cSFlorian Hahn                              VPTransformState &State,
5920dddf04cSFlorian Hahn                              bool IsEpilogueVectorization) {
593eaf48dd9SFlorian Hahn 
594eaf48dd9SFlorian Hahn   VPBasicBlock *ExitingVPBB = getVectorLoopRegion()->getExitingBasicBlock();
595eaf48dd9SFlorian Hahn   auto *Term = dyn_cast<VPInstruction>(&ExitingVPBB->back());
59603fee671SDavid Sherwood   // Try to simplify the branch condition if TC <= VF * UF when preparing to
59703fee671SDavid Sherwood   // execute the plan for the main vector loop. We only do this if the
59803fee671SDavid Sherwood   // terminator is:
59903fee671SDavid Sherwood   //  1. BranchOnCount, or
60003fee671SDavid Sherwood   //  2. BranchOnCond where the input is Not(ActiveLaneMask).
60103fee671SDavid Sherwood   if (!IsEpilogueVectorization && Term && isa<ConstantInt>(TripCountV) &&
60203fee671SDavid Sherwood       (Term->getOpcode() == VPInstruction::BranchOnCount ||
60303fee671SDavid Sherwood        (Term->getOpcode() == VPInstruction::BranchOnCond &&
60403fee671SDavid Sherwood         canSimplifyBranchOnCond(Term)))) {
605eaf48dd9SFlorian Hahn     ConstantInt *C = cast<ConstantInt>(TripCountV);
606eaf48dd9SFlorian Hahn     uint64_t TCVal = C->getZExtValue();
607eaf48dd9SFlorian Hahn     if (TCVal && TCVal <= State.VF.getKnownMinValue() * State.UF) {
608eaf48dd9SFlorian Hahn       auto *BOC =
609eaf48dd9SFlorian Hahn           new VPInstruction(VPInstruction::BranchOnCond,
610eaf48dd9SFlorian Hahn                             {getOrAddExternalDef(State.Builder.getTrue())});
611eaf48dd9SFlorian Hahn       Term->eraseFromParent();
612eaf48dd9SFlorian Hahn       ExitingVPBB->appendRecipe(BOC);
613eaf48dd9SFlorian Hahn       // TODO: Further simplifications are possible
614eaf48dd9SFlorian Hahn       //      1. Replace inductions with constants.
615eaf48dd9SFlorian Hahn       //      2. Replace vector loop region with VPBasicBlock.
616eaf48dd9SFlorian Hahn     }
617eaf48dd9SFlorian Hahn   }
618eaf48dd9SFlorian Hahn 
6199d297c78SFlorian Hahn   // Check if the trip count is needed, and if so build it.
6209d297c78SFlorian Hahn   if (TripCount && TripCount->getNumUsers()) {
6219d297c78SFlorian Hahn     for (unsigned Part = 0, UF = State.UF; Part < UF; ++Part)
6229d297c78SFlorian Hahn       State.set(TripCount, TripCountV, Part);
6239d297c78SFlorian Hahn   }
6249d297c78SFlorian Hahn 
6259d297c78SFlorian Hahn   // Check if the backedge taken count is needed, and if so build it.
6269d297c78SFlorian Hahn   if (BackedgeTakenCount && BackedgeTakenCount->getNumUsers()) {
627256c6b0bSFlorian Hahn     IRBuilder<> Builder(State.CFG.PrevBB->getTerminator());
6289d297c78SFlorian Hahn     auto *TCMO = Builder.CreateSub(TripCountV,
6299d297c78SFlorian Hahn                                    ConstantInt::get(TripCountV->getType(), 1),
6309d297c78SFlorian Hahn                                    "trip.count.minus.1");
6319d297c78SFlorian Hahn     auto VF = State.VF;
6329d297c78SFlorian Hahn     Value *VTCMO =
6339d297c78SFlorian Hahn         VF.isScalar() ? TCMO : Builder.CreateVectorSplat(VF, TCMO, "broadcast");
6349d297c78SFlorian Hahn     for (unsigned Part = 0, UF = State.UF; Part < UF; ++Part)
6359d297c78SFlorian Hahn       State.set(BackedgeTakenCount, VTCMO, Part);
6369d297c78SFlorian Hahn   }
63765c4d619SFlorian Hahn 
63865c4d619SFlorian Hahn   for (unsigned Part = 0, UF = State.UF; Part < UF; ++Part)
63965c4d619SFlorian Hahn     State.set(&VectorTripCount, VectorTripCountV, Part);
64065c4d619SFlorian Hahn 
64165c4d619SFlorian Hahn   // When vectorizing the epilogue loop, the canonical induction start value
64265c4d619SFlorian Hahn   // needs to be changed from zero to the value after the main vector loop.
64365c4d619SFlorian Hahn   if (CanonicalIVStartValue) {
6442c14cdf8SFlorian Hahn     VPValue *VPV = getOrAddExternalDef(CanonicalIVStartValue);
64565c4d619SFlorian Hahn     auto *IV = getCanonicalIV();
646165e36bfSFlorian Hahn     assert(all_of(IV->users(),
647165e36bfSFlorian Hahn                   [](const VPUser *U) {
648b3e8ace1SFlorian Hahn                     if (isa<VPScalarIVStepsRecipe>(U))
649b3e8ace1SFlorian Hahn                       return true;
650165e36bfSFlorian Hahn                     auto *VPI = cast<VPInstruction>(U);
651165e36bfSFlorian Hahn                     return VPI->getOpcode() ==
652165e36bfSFlorian Hahn                                VPInstruction::CanonicalIVIncrement ||
653165e36bfSFlorian Hahn                            VPI->getOpcode() ==
654165e36bfSFlorian Hahn                                VPInstruction::CanonicalIVIncrementNUW;
655165e36bfSFlorian Hahn                   }) &&
656b3e8ace1SFlorian Hahn            "the canonical IV should only be used by its increments or "
657b3e8ace1SFlorian Hahn            "ScalarIVSteps when "
658165e36bfSFlorian Hahn            "resetting the start value");
65965c4d619SFlorian Hahn     IV->setOperand(0, VPV);
66065c4d619SFlorian Hahn   }
6619d297c78SFlorian Hahn }
6629d297c78SFlorian Hahn 
663256c6b0bSFlorian Hahn /// Generate the code inside the preheader and body of the vectorized loop.
664256c6b0bSFlorian Hahn /// Assumes a single pre-header basic-block was created for this. Introduce
665256c6b0bSFlorian Hahn /// additional basic-blocks as needed, and fill them all.
execute(VPTransformState * State)6661f58dda4SAyal Zaks void VPlan::execute(VPTransformState *State) {
667f8101e4dSFlorian Hahn   // Set the reverse mapping from VPValues to Values for code generation.
6688b9d1f3cSGil Rapaport   for (auto &Entry : Value2VPValue)
6698b9d1f3cSGil Rapaport     State->VPValue2Value[Entry.second] = Entry.first;
6708b9d1f3cSGil Rapaport 
671f8101e4dSFlorian Hahn   // Initialize CFG state.
672f8101e4dSFlorian Hahn   State->CFG.PrevVPBB = nullptr;
673256c6b0bSFlorian Hahn   State->CFG.ExitBB = State->CFG.PrevBB->getSingleSuccessor();
674256c6b0bSFlorian Hahn   BasicBlock *VectorPreHeader = State->CFG.PrevBB;
675256c6b0bSFlorian Hahn   State->Builder.SetInsertPoint(VectorPreHeader->getTerminator());
676e8673f2fSFlorian Hahn 
677256c6b0bSFlorian Hahn   // Generate code in the loop pre-header and body.
6781f58dda4SAyal Zaks   for (VPBlockBase *Block : depth_first(Entry))
6791f58dda4SAyal Zaks     Block->execute(State);
6801f58dda4SAyal Zaks 
6816abce17fSFlorian Hahn   VPBasicBlock *LatchVPBB = getVectorLoopRegion()->getExitingBasicBlock();
682bea69b23SFlorian Hahn   BasicBlock *VectorLatchBB = State->CFG.VPBB2IRBB[LatchVPBB];
6831f58dda4SAyal Zaks 
68465c4d619SFlorian Hahn   // Fix the latch value of canonical, reduction and first-order recurrences
68565c4d619SFlorian Hahn   // phis in the vector loop.
686e47d2202SFlorian Hahn   VPBasicBlock *Header = getVectorLoopRegion()->getEntryBasicBlock();
68765c4d619SFlorian Hahn   for (VPRecipeBase &R : Header->phis()) {
68865c4d619SFlorian Hahn     // Skip phi-like recipes that generate their backedege values themselves.
689d1d35632SFlorian Hahn     if (isa<VPWidenPHIRecipe>(&R))
69065c4d619SFlorian Hahn       continue;
69165c4d619SFlorian Hahn 
692d1d35632SFlorian Hahn     if (isa<VPWidenPointerInductionRecipe>(&R) ||
693d1d35632SFlorian Hahn         isa<VPWidenIntOrFpInductionRecipe>(&R)) {
694d1d35632SFlorian Hahn       PHINode *Phi = nullptr;
695d1d35632SFlorian Hahn       if (isa<VPWidenIntOrFpInductionRecipe>(&R)) {
696d1d35632SFlorian Hahn         Phi = cast<PHINode>(State->get(R.getVPSingleValue(), 0));
697d1d35632SFlorian Hahn       } else {
698d1d35632SFlorian Hahn         auto *WidenPhi = cast<VPWidenPointerInductionRecipe>(&R);
699d1d35632SFlorian Hahn         // TODO: Split off the case that all users of a pointer phi are scalar
700d1d35632SFlorian Hahn         // from the VPWidenPointerInductionRecipe.
701*5f620d00SFlorian Hahn         if (WidenPhi->onlyScalarsGenerated(State->VF))
702d1d35632SFlorian Hahn           continue;
703d1d35632SFlorian Hahn 
704d1d35632SFlorian Hahn         auto *GEP = cast<GetElementPtrInst>(State->get(WidenPhi, 0));
705d1d35632SFlorian Hahn         Phi = cast<PHINode>(GEP->getPointerOperand());
706d1d35632SFlorian Hahn       }
707d1d35632SFlorian Hahn 
708e7bf2ea9SFlorian Hahn       Phi->setIncomingBlock(1, VectorLatchBB);
709e7bf2ea9SFlorian Hahn 
710e7bf2ea9SFlorian Hahn       // Move the last step to the end of the latch block. This ensures
711e7bf2ea9SFlorian Hahn       // consistent placement of all induction updates.
712e7bf2ea9SFlorian Hahn       Instruction *Inc = cast<Instruction>(Phi->getIncomingValue(1));
713e7bf2ea9SFlorian Hahn       Inc->moveBefore(VectorLatchBB->getTerminator()->getPrevNode());
714e7bf2ea9SFlorian Hahn       continue;
715e7bf2ea9SFlorian Hahn     }
716e7bf2ea9SFlorian Hahn 
71765c4d619SFlorian Hahn     auto *PhiR = cast<VPHeaderPHIRecipe>(&R);
71865c4d619SFlorian Hahn     // For  canonical IV, first-order recurrences and in-order reduction phis,
71965c4d619SFlorian Hahn     // only a single part is generated, which provides the last part from the
72065c4d619SFlorian Hahn     // previous iteration. For non-ordered reductions all UF parts are
72165c4d619SFlorian Hahn     // generated.
72265c4d619SFlorian Hahn     bool SinglePartNeeded = isa<VPCanonicalIVPHIRecipe>(PhiR) ||
72365c4d619SFlorian Hahn                             isa<VPFirstOrderRecurrencePHIRecipe>(PhiR) ||
72403fee671SDavid Sherwood                             (isa<VPReductionPHIRecipe>(PhiR) &&
72503fee671SDavid Sherwood                              cast<VPReductionPHIRecipe>(PhiR)->isOrdered());
72665c4d619SFlorian Hahn     unsigned LastPartForNewPhi = SinglePartNeeded ? 1 : State->UF;
72765c4d619SFlorian Hahn 
72865c4d619SFlorian Hahn     for (unsigned Part = 0; Part < LastPartForNewPhi; ++Part) {
72965c4d619SFlorian Hahn       Value *Phi = State->get(PhiR, Part);
73065c4d619SFlorian Hahn       Value *Val = State->get(PhiR->getBackedgeValue(),
73165c4d619SFlorian Hahn                               SinglePartNeeded ? State->UF - 1 : Part);
73265c4d619SFlorian Hahn       cast<PHINode>(Phi)->addIncoming(Val, VectorLatchBB);
73365c4d619SFlorian Hahn     }
73465c4d619SFlorian Hahn   }
73565c4d619SFlorian Hahn 
736ea7f3035SHideki Saito   // We do not attempt to preserve DT for outer loop vectorization currently.
737256c6b0bSFlorian Hahn   if (!EnableVPlanNativePath) {
738256c6b0bSFlorian Hahn     BasicBlock *VectorHeaderBB = State->CFG.VPBB2IRBB[Header];
739256c6b0bSFlorian Hahn     State->DT->addNewBlock(VectorHeaderBB, VectorPreHeader);
7408a4077faSFlorian Hahn     updateDominatorTree(State->DT, VectorHeaderBB, VectorLatchBB,
7412c494f09SFlorian Hahn                         State->CFG.ExitBB);
7421f58dda4SAyal Zaks   }
743256c6b0bSFlorian Hahn }
7441f58dda4SAyal Zaks 
74592205cb2SAndrei Elovikov #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
74693a9d2deSAndrei Elovikov LLVM_DUMP_METHOD
print(raw_ostream & O) const74793a9d2deSAndrei Elovikov void VPlan::print(raw_ostream &O) const {
74893a9d2deSAndrei Elovikov   VPSlotTracker SlotTracker(this);
74993a9d2deSAndrei Elovikov 
750f759d512SFlorian Hahn   O << "VPlan '" << Name << "' {";
751ab33427cSFlorian Hahn 
752d4a8fc3aSFlorian Hahn   if (VectorTripCount.getNumUsers() > 0) {
753d4a8fc3aSFlorian Hahn     O << "\nLive-in ";
754d4a8fc3aSFlorian Hahn     VectorTripCount.printAsOperand(O, SlotTracker);
755d4a8fc3aSFlorian Hahn     O << " = vector-trip-count\n";
756d4a8fc3aSFlorian Hahn   }
757d4a8fc3aSFlorian Hahn 
758ab33427cSFlorian Hahn   if (BackedgeTakenCount && BackedgeTakenCount->getNumUsers()) {
759ab33427cSFlorian Hahn     O << "\nLive-in ";
760ab33427cSFlorian Hahn     BackedgeTakenCount->printAsOperand(O, SlotTracker);
761ab33427cSFlorian Hahn     O << " = backedge-taken count\n";
762ab33427cSFlorian Hahn   }
763ab33427cSFlorian Hahn 
76493a9d2deSAndrei Elovikov   for (const VPBlockBase *Block : depth_first(getEntry())) {
76593a9d2deSAndrei Elovikov     O << '\n';
76693a9d2deSAndrei Elovikov     Block->print(O, "", SlotTracker);
76793a9d2deSAndrei Elovikov   }
7683bebec65SFlorian Hahn 
7693bebec65SFlorian Hahn   if (!LiveOuts.empty())
7703bebec65SFlorian Hahn     O << "\n";
7713bebec65SFlorian Hahn   for (auto &KV : LiveOuts) {
7723bebec65SFlorian Hahn     O << "Live-out ";
7733bebec65SFlorian Hahn     KV.second->getPhi()->printAsOperand(O);
7743bebec65SFlorian Hahn     O << " = ";
7753bebec65SFlorian Hahn     KV.second->getOperand(0)->printAsOperand(O, SlotTracker);
7763bebec65SFlorian Hahn     O << "\n";
7773bebec65SFlorian Hahn   }
7783bebec65SFlorian Hahn 
77993a9d2deSAndrei Elovikov   O << "}\n";
78093a9d2deSAndrei Elovikov }
78193a9d2deSAndrei Elovikov 
78293a9d2deSAndrei Elovikov LLVM_DUMP_METHOD
printDOT(raw_ostream & O) const78393a9d2deSAndrei Elovikov void VPlan::printDOT(raw_ostream &O) const {
78493a9d2deSAndrei Elovikov   VPlanPrinter Printer(O, *this);
78593a9d2deSAndrei Elovikov   Printer.dump();
78693a9d2deSAndrei Elovikov }
78793a9d2deSAndrei Elovikov 
788e9c68422SFlorian Hahn LLVM_DUMP_METHOD
dump() const78993a9d2deSAndrei Elovikov void VPlan::dump() const { print(dbgs()); }
790e9c68422SFlorian Hahn #endif
791e9c68422SFlorian Hahn 
addLiveOut(PHINode * PN,VPValue * V)7923bebec65SFlorian Hahn void VPlan::addLiveOut(PHINode *PN, VPValue *V) {
7933bebec65SFlorian Hahn   assert(LiveOuts.count(PN) == 0 && "an exit value for PN already exists");
7943bebec65SFlorian Hahn   LiveOuts.insert({PN, new VPLiveOut(PN, V)});
7953bebec65SFlorian Hahn }
7963bebec65SFlorian Hahn 
updateDominatorTree(DominatorTree * DT,BasicBlock * LoopHeaderBB,BasicBlock * LoopLatchBB,BasicBlock * LoopExitBB)7978a4077faSFlorian Hahn void VPlan::updateDominatorTree(DominatorTree *DT, BasicBlock *LoopHeaderBB,
798948e7452SEvgeniy Brevnov                                 BasicBlock *LoopLatchBB,
799948e7452SEvgeniy Brevnov                                 BasicBlock *LoopExitBB) {
8001f58dda4SAyal Zaks   // The vector body may be more than a single basic-block by this point.
8011f58dda4SAyal Zaks   // Update the dominator tree information inside the vector body by propagating
8021f58dda4SAyal Zaks   // it from header to latch, expecting only triangular control-flow, if any.
8031f58dda4SAyal Zaks   BasicBlock *PostDomSucc = nullptr;
8041f58dda4SAyal Zaks   for (auto *BB = LoopHeaderBB; BB != LoopLatchBB; BB = PostDomSucc) {
8051f58dda4SAyal Zaks     // Get the list of successors of this block.
8061f58dda4SAyal Zaks     std::vector<BasicBlock *> Succs(succ_begin(BB), succ_end(BB));
8071f58dda4SAyal Zaks     assert(Succs.size() <= 2 &&
8081f58dda4SAyal Zaks            "Basic block in vector loop has more than 2 successors.");
8091f58dda4SAyal Zaks     PostDomSucc = Succs[0];
8101f58dda4SAyal Zaks     if (Succs.size() == 1) {
8111f58dda4SAyal Zaks       assert(PostDomSucc->getSinglePredecessor() &&
8121f58dda4SAyal Zaks              "PostDom successor has more than one predecessor.");
8131f58dda4SAyal Zaks       DT->addNewBlock(PostDomSucc, BB);
8141f58dda4SAyal Zaks       continue;
8151f58dda4SAyal Zaks     }
8161f58dda4SAyal Zaks     BasicBlock *InterimSucc = Succs[1];
8171f58dda4SAyal Zaks     if (PostDomSucc->getSingleSuccessor() == InterimSucc) {
8181f58dda4SAyal Zaks       PostDomSucc = Succs[1];
8191f58dda4SAyal Zaks       InterimSucc = Succs[0];
8201f58dda4SAyal Zaks     }
8211f58dda4SAyal Zaks     assert(InterimSucc->getSingleSuccessor() == PostDomSucc &&
8221f58dda4SAyal Zaks            "One successor of a basic block does not lead to the other.");
8231f58dda4SAyal Zaks     assert(InterimSucc->getSinglePredecessor() &&
8241f58dda4SAyal Zaks            "Interim successor has more than one predecessor.");
8254de31bbaSVedant Kumar     assert(PostDomSucc->hasNPredecessors(2) &&
8261f58dda4SAyal Zaks            "PostDom successor has more than two predecessors.");
8271f58dda4SAyal Zaks     DT->addNewBlock(InterimSucc, BB);
8281f58dda4SAyal Zaks     DT->addNewBlock(PostDomSucc, BB);
8291f58dda4SAyal Zaks   }
830948e7452SEvgeniy Brevnov   // Latch block is a new dominator for the loop exit.
831948e7452SEvgeniy Brevnov   DT->changeImmediateDominator(LoopExitBB, LoopLatchBB);
832948e7452SEvgeniy Brevnov   assert(DT->verify(DominatorTree::VerificationLevel::Fast));
8331f58dda4SAyal Zaks }
8341f58dda4SAyal Zaks 
83592205cb2SAndrei Elovikov #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
83603975b7fSFlorian Hahn 
getUID(const VPBlockBase * Block)83772661f33SKazu Hirata Twine VPlanPrinter::getUID(const VPBlockBase *Block) {
8381f58dda4SAyal Zaks   return (isa<VPRegionBlock>(Block) ? "cluster_N" : "N") +
8391f58dda4SAyal Zaks          Twine(getOrCreateBID(Block));
8401f58dda4SAyal Zaks }
8411f58dda4SAyal Zaks 
getOrCreateName(const VPBlockBase * Block)84272661f33SKazu Hirata Twine VPlanPrinter::getOrCreateName(const VPBlockBase *Block) {
8431f58dda4SAyal Zaks   const std::string &Name = Block->getName();
8441f58dda4SAyal Zaks   if (!Name.empty())
8451f58dda4SAyal Zaks     return Name;
8461f58dda4SAyal Zaks   return "VPB" + Twine(getOrCreateBID(Block));
8471f58dda4SAyal Zaks }
8481f58dda4SAyal Zaks 
dump()8491f58dda4SAyal Zaks void VPlanPrinter::dump() {
8501f58dda4SAyal Zaks   Depth = 1;
8511f58dda4SAyal Zaks   bumpIndent(0);
8521f58dda4SAyal Zaks   OS << "digraph VPlan {\n";
8531f58dda4SAyal Zaks   OS << "graph [labelloc=t, fontsize=30; label=\"Vectorization Plan";
8541f58dda4SAyal Zaks   if (!Plan.getName().empty())
8551f58dda4SAyal Zaks     OS << "\\n" << DOT::EscapeString(Plan.getName());
85640e7bfc4SFlorian Hahn   if (Plan.BackedgeTakenCount) {
857fd2c15e6SFlorian Hahn     OS << ", where:\\n";
85840e7bfc4SFlorian Hahn     Plan.BackedgeTakenCount->print(OS, SlotTracker);
85940e7bfc4SFlorian Hahn     OS << " := BackedgeTakenCount";
86040e7bfc4SFlorian Hahn   }
8611f58dda4SAyal Zaks   OS << "\"]\n";
8621f58dda4SAyal Zaks   OS << "node [shape=rect, fontname=Courier, fontsize=30]\n";
8631f58dda4SAyal Zaks   OS << "edge [fontname=Courier, fontsize=30]\n";
8641f58dda4SAyal Zaks   OS << "compound=true\n";
8651f58dda4SAyal Zaks 
866e9c68422SFlorian Hahn   for (const VPBlockBase *Block : depth_first(Plan.getEntry()))
8671f58dda4SAyal Zaks     dumpBlock(Block);
8681f58dda4SAyal Zaks 
8691f58dda4SAyal Zaks   OS << "}\n";
8701f58dda4SAyal Zaks }
8711f58dda4SAyal Zaks 
dumpBlock(const VPBlockBase * Block)8721f58dda4SAyal Zaks void VPlanPrinter::dumpBlock(const VPBlockBase *Block) {
8731f58dda4SAyal Zaks   if (const VPBasicBlock *BasicBlock = dyn_cast<VPBasicBlock>(Block))
8741f58dda4SAyal Zaks     dumpBasicBlock(BasicBlock);
8751f58dda4SAyal Zaks   else if (const VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
8761f58dda4SAyal Zaks     dumpRegion(Region);
8771f58dda4SAyal Zaks   else
8781f58dda4SAyal Zaks     llvm_unreachable("Unsupported kind of VPBlock.");
8791f58dda4SAyal Zaks }
8801f58dda4SAyal Zaks 
drawEdge(const VPBlockBase * From,const VPBlockBase * To,bool Hidden,const Twine & Label)8811f58dda4SAyal Zaks void VPlanPrinter::drawEdge(const VPBlockBase *From, const VPBlockBase *To,
8821f58dda4SAyal Zaks                             bool Hidden, const Twine &Label) {
8831f58dda4SAyal Zaks   // Due to "dot" we print an edge between two regions as an edge between the
8846abce17fSFlorian Hahn   // exiting basic block and the entry basic of the respective regions.
8856abce17fSFlorian Hahn   const VPBlockBase *Tail = From->getExitingBasicBlock();
8861f58dda4SAyal Zaks   const VPBlockBase *Head = To->getEntryBasicBlock();
8871f58dda4SAyal Zaks   OS << Indent << getUID(Tail) << " -> " << getUID(Head);
8881f58dda4SAyal Zaks   OS << " [ label=\"" << Label << '\"';
8891f58dda4SAyal Zaks   if (Tail != From)
8901f58dda4SAyal Zaks     OS << " ltail=" << getUID(From);
8911f58dda4SAyal Zaks   if (Head != To)
8921f58dda4SAyal Zaks     OS << " lhead=" << getUID(To);
8931f58dda4SAyal Zaks   if (Hidden)
8941f58dda4SAyal Zaks     OS << "; splines=none";
8951f58dda4SAyal Zaks   OS << "]\n";
8961f58dda4SAyal Zaks }
8971f58dda4SAyal Zaks 
dumpEdges(const VPBlockBase * Block)8981f58dda4SAyal Zaks void VPlanPrinter::dumpEdges(const VPBlockBase *Block) {
8991f58dda4SAyal Zaks   auto &Successors = Block->getSuccessors();
9001f58dda4SAyal Zaks   if (Successors.size() == 1)
9011f58dda4SAyal Zaks     drawEdge(Block, Successors.front(), false, "");
9021f58dda4SAyal Zaks   else if (Successors.size() == 2) {
9031f58dda4SAyal Zaks     drawEdge(Block, Successors.front(), false, "T");
9041f58dda4SAyal Zaks     drawEdge(Block, Successors.back(), false, "F");
9051f58dda4SAyal Zaks   } else {
9061f58dda4SAyal Zaks     unsigned SuccessorNumber = 0;
9071f58dda4SAyal Zaks     for (auto *Successor : Successors)
9081f58dda4SAyal Zaks       drawEdge(Block, Successor, false, Twine(SuccessorNumber++));
9091f58dda4SAyal Zaks   }
9101f58dda4SAyal Zaks }
9111f58dda4SAyal Zaks 
dumpBasicBlock(const VPBasicBlock * BasicBlock)9121f58dda4SAyal Zaks void VPlanPrinter::dumpBasicBlock(const VPBasicBlock *BasicBlock) {
91393a9d2deSAndrei Elovikov   // Implement dot-formatted dump by performing plain-text dump into the
91493a9d2deSAndrei Elovikov   // temporary storage followed by some post-processing.
9151f58dda4SAyal Zaks   OS << Indent << getUID(BasicBlock) << " [label =\n";
9161f58dda4SAyal Zaks   bumpIndent(1);
91793a9d2deSAndrei Elovikov   std::string Str;
91893a9d2deSAndrei Elovikov   raw_string_ostream SS(Str);
91993a9d2deSAndrei Elovikov   // Use no indentation as we need to wrap the lines into quotes ourselves.
92093a9d2deSAndrei Elovikov   BasicBlock->print(SS, "", SlotTracker);
9214e4ecae0SHideki Saito 
92293a9d2deSAndrei Elovikov   // We need to process each line of the output separately, so split
92393a9d2deSAndrei Elovikov   // single-string plain-text dump.
92493a9d2deSAndrei Elovikov   SmallVector<StringRef, 0> Lines;
92593a9d2deSAndrei Elovikov   StringRef(Str).rtrim('\n').split(Lines, "\n");
9264e4ecae0SHideki Saito 
92793a9d2deSAndrei Elovikov   auto EmitLine = [&](StringRef Line, StringRef Suffix) {
92893a9d2deSAndrei Elovikov     OS << Indent << '"' << DOT::EscapeString(Line.str()) << "\\l\"" << Suffix;
92993a9d2deSAndrei Elovikov   };
930d0953014SDiego Caballero 
93193a9d2deSAndrei Elovikov   // Don't need the "+" after the last line.
93293a9d2deSAndrei Elovikov   for (auto Line : make_range(Lines.begin(), Lines.end() - 1))
93393a9d2deSAndrei Elovikov     EmitLine(Line, " +\n");
93493a9d2deSAndrei Elovikov   EmitLine(Lines.back(), "\n");
935d0953014SDiego Caballero 
93693a9d2deSAndrei Elovikov   bumpIndent(-1);
93793a9d2deSAndrei Elovikov   OS << Indent << "]\n";
93893a9d2deSAndrei Elovikov 
9391f58dda4SAyal Zaks   dumpEdges(BasicBlock);
9401f58dda4SAyal Zaks }
9411f58dda4SAyal Zaks 
dumpRegion(const VPRegionBlock * Region)9421f58dda4SAyal Zaks void VPlanPrinter::dumpRegion(const VPRegionBlock *Region) {
9431f58dda4SAyal Zaks   OS << Indent << "subgraph " << getUID(Region) << " {\n";
9441f58dda4SAyal Zaks   bumpIndent(1);
9451f58dda4SAyal Zaks   OS << Indent << "fontname=Courier\n"
9461f58dda4SAyal Zaks      << Indent << "label=\""
9471f58dda4SAyal Zaks      << DOT::EscapeString(Region->isReplicator() ? "<xVFxUF> " : "<x1> ")
9481f58dda4SAyal Zaks      << DOT::EscapeString(Region->getName()) << "\"\n";
9491f58dda4SAyal Zaks   // Dump the blocks of the region.
9501f58dda4SAyal Zaks   assert(Region->getEntry() && "Region contains no inner blocks.");
9511f58dda4SAyal Zaks   for (const VPBlockBase *Block : depth_first(Region->getEntry()))
9521f58dda4SAyal Zaks     dumpBlock(Block);
9531f58dda4SAyal Zaks   bumpIndent(-1);
9541f58dda4SAyal Zaks   OS << Indent << "}\n";
9551f58dda4SAyal Zaks   dumpEdges(Region);
9561f58dda4SAyal Zaks }
9571f58dda4SAyal Zaks 
print(raw_ostream & O) const95893a9d2deSAndrei Elovikov void VPlanIngredient::print(raw_ostream &O) const {
9591f58dda4SAyal Zaks   if (auto *Inst = dyn_cast<Instruction>(V)) {
9601f58dda4SAyal Zaks     if (!Inst->getType()->isVoidTy()) {
96193a9d2deSAndrei Elovikov       Inst->printAsOperand(O, false);
96293a9d2deSAndrei Elovikov       O << " = ";
9631f58dda4SAyal Zaks     }
96493a9d2deSAndrei Elovikov     O << Inst->getOpcodeName() << " ";
9651f58dda4SAyal Zaks     unsigned E = Inst->getNumOperands();
9661f58dda4SAyal Zaks     if (E > 0) {
96793a9d2deSAndrei Elovikov       Inst->getOperand(0)->printAsOperand(O, false);
9681f58dda4SAyal Zaks       for (unsigned I = 1; I < E; ++I)
96993a9d2deSAndrei Elovikov         Inst->getOperand(I)->printAsOperand(O << ", ", false);
9701f58dda4SAyal Zaks     }
9711f58dda4SAyal Zaks   } else // !Inst
97293a9d2deSAndrei Elovikov     V->printAsOperand(O, false);
9731f58dda4SAyal Zaks }
9747333aa9fSHal Finkel 
97555689904SFlorian Hahn #endif
9767333aa9fSHal Finkel 
9772a34ac86SDiego Caballero template void DomTreeBuilder::Calculate<VPDominatorTree>(VPDominatorTree &DT);
978a4dc7feeSFlorian Hahn 
replaceAllUsesWith(VPValue * New)97909e516c5SFlorian Hahn void VPValue::replaceAllUsesWith(VPValue *New) {
980f5fe7abeSFlorian Hahn   for (unsigned J = 0; J < getNumUsers();) {
981f5fe7abeSFlorian Hahn     VPUser *User = Users[J];
982f5fe7abeSFlorian Hahn     unsigned NumUsers = getNumUsers();
98309e516c5SFlorian Hahn     for (unsigned I = 0, E = User->getNumOperands(); I < E; ++I)
98409e516c5SFlorian Hahn       if (User->getOperand(I) == this)
98509e516c5SFlorian Hahn         User->setOperand(I, New);
986f5fe7abeSFlorian Hahn     // If a user got removed after updating the current user, the next user to
987f5fe7abeSFlorian Hahn     // update will be moved to the current position, so we only need to
988f5fe7abeSFlorian Hahn     // increment the index if the number of users did not change.
989f5fe7abeSFlorian Hahn     if (NumUsers == getNumUsers())
990f5fe7abeSFlorian Hahn       J++;
991f5fe7abeSFlorian Hahn   }
99209e516c5SFlorian Hahn }
99309e516c5SFlorian Hahn 
99492205cb2SAndrei Elovikov #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
printAsOperand(raw_ostream & OS,VPSlotTracker & Tracker) const99540e7bfc4SFlorian Hahn void VPValue::printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const {
996e6a74803SFlorian Hahn   if (const Value *UV = getUnderlyingValue()) {
997e6a74803SFlorian Hahn     OS << "ir<";
998e6a74803SFlorian Hahn     UV->printAsOperand(OS, false);
999e6a74803SFlorian Hahn     OS << ">";
1000e6a74803SFlorian Hahn     return;
1001e6a74803SFlorian Hahn   }
1002e6a74803SFlorian Hahn 
100340e7bfc4SFlorian Hahn   unsigned Slot = Tracker.getSlot(this);
100440e7bfc4SFlorian Hahn   if (Slot == unsigned(-1))
100540e7bfc4SFlorian Hahn     OS << "<badref>";
100640e7bfc4SFlorian Hahn   else
1007e6a74803SFlorian Hahn     OS << "vp<%" << Tracker.getSlot(this) << ">";
100840e7bfc4SFlorian Hahn }
100940e7bfc4SFlorian Hahn 
printOperands(raw_ostream & O,VPSlotTracker & SlotTracker) const1010091c5c9aSFlorian Hahn void VPUser::printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const {
1011533f8576SFlorian Hahn   interleaveComma(operands(), O, [&O, &SlotTracker](VPValue *Op) {
1012091c5c9aSFlorian Hahn     Op->printAsOperand(O, SlotTracker);
1013533f8576SFlorian Hahn   });
1014091c5c9aSFlorian Hahn }
101592205cb2SAndrei Elovikov #endif
1016091c5c9aSFlorian Hahn 
visitRegion(VPRegionBlock * Region,Old2NewTy & Old2New,InterleavedAccessInfo & IAI)1017a4dc7feeSFlorian Hahn void VPInterleavedAccessInfo::visitRegion(VPRegionBlock *Region,
1018a4dc7feeSFlorian Hahn                                           Old2NewTy &Old2New,
1019a4dc7feeSFlorian Hahn                                           InterleavedAccessInfo &IAI) {
1020a4dc7feeSFlorian Hahn   ReversePostOrderTraversal<VPBlockBase *> RPOT(Region->getEntry());
1021a4dc7feeSFlorian Hahn   for (VPBlockBase *Base : RPOT) {
1022a4dc7feeSFlorian Hahn     visitBlock(Base, Old2New, IAI);
1023a4dc7feeSFlorian Hahn   }
1024a4dc7feeSFlorian Hahn }
1025a4dc7feeSFlorian Hahn 
visitBlock(VPBlockBase * Block,Old2NewTy & Old2New,InterleavedAccessInfo & IAI)1026a4dc7feeSFlorian Hahn void VPInterleavedAccessInfo::visitBlock(VPBlockBase *Block, Old2NewTy &Old2New,
1027a4dc7feeSFlorian Hahn                                          InterleavedAccessInfo &IAI) {
1028a4dc7feeSFlorian Hahn   if (VPBasicBlock *VPBB = dyn_cast<VPBasicBlock>(Block)) {
1029a4dc7feeSFlorian Hahn     for (VPRecipeBase &VPI : *VPBB) {
1030c2275278SFlorian Hahn       if (isa<VPHeaderPHIRecipe>(&VPI))
1031c11fd0dfSFlorian Hahn         continue;
1032a4dc7feeSFlorian Hahn       assert(isa<VPInstruction>(&VPI) && "Can only handle VPInstructions");
1033a4dc7feeSFlorian Hahn       auto *VPInst = cast<VPInstruction>(&VPI);
1034b0c9a71bSFlorian Hahn 
1035b0c9a71bSFlorian Hahn       auto *Inst = dyn_cast_or_null<Instruction>(VPInst->getUnderlyingValue());
1036b0c9a71bSFlorian Hahn       if (!Inst)
1037b0c9a71bSFlorian Hahn         continue;
1038a4dc7feeSFlorian Hahn       auto *IG = IAI.getInterleaveGroup(Inst);
1039a4dc7feeSFlorian Hahn       if (!IG)
1040a4dc7feeSFlorian Hahn         continue;
1041a4dc7feeSFlorian Hahn 
1042a4dc7feeSFlorian Hahn       auto NewIGIter = Old2New.find(IG);
1043a4dc7feeSFlorian Hahn       if (NewIGIter == Old2New.end())
1044a4dc7feeSFlorian Hahn         Old2New[IG] = new InterleaveGroup<VPInstruction>(
104532851f8dSGuillaume Chatelet             IG->getFactor(), IG->isReverse(), IG->getAlign());
1046a4dc7feeSFlorian Hahn 
1047a4dc7feeSFlorian Hahn       if (Inst == IG->getInsertPos())
1048a4dc7feeSFlorian Hahn         Old2New[IG]->setInsertPos(VPInst);
1049a4dc7feeSFlorian Hahn 
1050a4dc7feeSFlorian Hahn       InterleaveGroupMap[VPInst] = Old2New[IG];
1051a4dc7feeSFlorian Hahn       InterleaveGroupMap[VPInst]->insertMember(
1052a4dc7feeSFlorian Hahn           VPInst, IG->getIndex(Inst),
1053837a1b84SGuillaume Chatelet           Align(IG->isReverse() ? (-1) * int(IG->getFactor())
1054837a1b84SGuillaume Chatelet                                 : IG->getFactor()));
1055a4dc7feeSFlorian Hahn     }
1056a4dc7feeSFlorian Hahn   } else if (VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
1057a4dc7feeSFlorian Hahn     visitRegion(Region, Old2New, IAI);
1058a4dc7feeSFlorian Hahn   else
1059a4dc7feeSFlorian Hahn     llvm_unreachable("Unsupported kind of VPBlock.");
1060a4dc7feeSFlorian Hahn }
1061a4dc7feeSFlorian Hahn 
VPInterleavedAccessInfo(VPlan & Plan,InterleavedAccessInfo & IAI)1062a4dc7feeSFlorian Hahn VPInterleavedAccessInfo::VPInterleavedAccessInfo(VPlan &Plan,
1063a4dc7feeSFlorian Hahn                                                  InterleavedAccessInfo &IAI) {
1064a4dc7feeSFlorian Hahn   Old2NewTy Old2New;
10651817c526SFlorian Hahn   visitRegion(Plan.getVectorLoopRegion(), Old2New, IAI);
1066a4dc7feeSFlorian Hahn }
106740e7bfc4SFlorian Hahn 
assignSlot(const VPValue * V)106840e7bfc4SFlorian Hahn void VPSlotTracker::assignSlot(const VPValue *V) {
106940e7bfc4SFlorian Hahn   assert(Slots.find(V) == Slots.end() && "VPValue already has a slot!");
107040e7bfc4SFlorian Hahn   Slots[V] = NextSlot++;
107140e7bfc4SFlorian Hahn }
107240e7bfc4SFlorian Hahn 
assignSlots(const VPlan & Plan)107340e7bfc4SFlorian Hahn void VPSlotTracker::assignSlots(const VPlan &Plan) {
107440e7bfc4SFlorian Hahn 
10752c14cdf8SFlorian Hahn   for (const auto &P : Plan.VPExternalDefs)
10762c14cdf8SFlorian Hahn     assignSlot(P.second);
107740e7bfc4SFlorian Hahn 
107865c4d619SFlorian Hahn   assignSlot(&Plan.VectorTripCount);
107940e7bfc4SFlorian Hahn   if (Plan.BackedgeTakenCount)
108040e7bfc4SFlorian Hahn     assignSlot(Plan.BackedgeTakenCount);
108140e7bfc4SFlorian Hahn 
1082160e729cSFlorian Hahn   ReversePostOrderTraversal<
1083160e729cSFlorian Hahn       VPBlockRecursiveTraversalWrapper<const VPBlockBase *>>
1084160e729cSFlorian Hahn       RPOT(VPBlockRecursiveTraversalWrapper<const VPBlockBase *>(
1085160e729cSFlorian Hahn           Plan.getEntry()));
1086160e729cSFlorian Hahn   for (const VPBasicBlock *VPBB :
1087160e729cSFlorian Hahn        VPBlockUtils::blocksOnly<const VPBasicBlock>(RPOT))
1088160e729cSFlorian Hahn     for (const VPRecipeBase &Recipe : *VPBB)
1089160e729cSFlorian Hahn       for (VPValue *Def : Recipe.definedValues())
1090160e729cSFlorian Hahn         assignSlot(Def);
109140e7bfc4SFlorian Hahn }
10928f12175fSFlorian Hahn 
onlyFirstLaneUsed(VPValue * Def)10938f12175fSFlorian Hahn bool vputils::onlyFirstLaneUsed(VPValue *Def) {
1094c1a9d149SFlorian Hahn   return all_of(Def->users(),
1095c1a9d149SFlorian Hahn                 [Def](VPUser *U) { return U->onlyFirstLaneUsed(Def); });
10968f12175fSFlorian Hahn }
1097a65f2730SFlorian Hahn 
getOrCreateVPValueForSCEVExpr(VPlan & Plan,const SCEV * Expr,ScalarEvolution & SE)1098a65f2730SFlorian Hahn VPValue *vputils::getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
1099a65f2730SFlorian Hahn                                                 ScalarEvolution &SE) {
1100a65f2730SFlorian Hahn   if (auto *E = dyn_cast<SCEVConstant>(Expr))
1101a65f2730SFlorian Hahn     return Plan.getOrAddExternalDef(E->getValue());
1102a65f2730SFlorian Hahn   if (auto *E = dyn_cast<SCEVUnknown>(Expr))
1103a65f2730SFlorian Hahn     return Plan.getOrAddExternalDef(E->getValue());
1104a65f2730SFlorian Hahn 
1105a65f2730SFlorian Hahn   VPBasicBlock *Preheader = Plan.getEntry()->getEntryBasicBlock();
1106a65f2730SFlorian Hahn   VPValue *Step = new VPExpandSCEVRecipe(Expr, SE);
1107a65f2730SFlorian Hahn   Preheader->appendRecipe(cast<VPRecipeBase>(Step->getDef()));
1108a65f2730SFlorian Hahn   return Step;
1109a65f2730SFlorian Hahn }
1110