1 //===- VPlan.cpp - Vectorizer Plan ----------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This is the LLVM vectorization plan. It represents a candidate for
12 /// vectorization, allowing to plan and optimize how to vectorize a given loop
13 /// before generating LLVM-IR.
14 /// The vectorizer uses vectorization plans to estimate the costs of potential
15 /// candidates and if profitable to execute the desired plan, generating vector
16 /// LLVM-IR code.
17 ///
18 //===----------------------------------------------------------------------===//
19 
20 #include "VPlan.h"
21 #include "VPlanDominatorTree.h"
22 #include "llvm/ADT/DepthFirstIterator.h"
23 #include "llvm/ADT/PostOrderIterator.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/ADT/Twine.h"
26 #include "llvm/Analysis/LoopInfo.h"
27 #include "llvm/IR/BasicBlock.h"
28 #include "llvm/IR/CFG.h"
29 #include "llvm/IR/InstrTypes.h"
30 #include "llvm/IR/Instruction.h"
31 #include "llvm/IR/Instructions.h"
32 #include "llvm/IR/Type.h"
33 #include "llvm/IR/Value.h"
34 #include "llvm/Support/Casting.h"
35 #include "llvm/Support/Debug.h"
36 #include "llvm/Support/ErrorHandling.h"
37 #include "llvm/Support/GenericDomTreeConstruction.h"
38 #include "llvm/Support/GraphWriter.h"
39 #include "llvm/Support/raw_ostream.h"
40 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
41 #include <cassert>
42 #include <iterator>
43 #include <string>
44 #include <vector>
45 
46 using namespace llvm;
47 
48 #define DEBUG_TYPE "vplan"
49 
operator <<(raw_ostream & OS,const VPValue & V)50 raw_ostream &llvm::operator<<(raw_ostream &OS, const VPValue &V) {
51   if (const VPInstruction *Instr = dyn_cast<VPInstruction>(&V))
52     Instr->print(OS);
53   else
54     V.printAsOperand(OS);
55   return OS;
56 }
57 
58 /// \return the VPBasicBlock that is the entry of Block, possibly indirectly.
getEntryBasicBlock() const59 const VPBasicBlock *VPBlockBase::getEntryBasicBlock() const {
60   const VPBlockBase *Block = this;
61   while (const VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
62     Block = Region->getEntry();
63   return cast<VPBasicBlock>(Block);
64 }
65 
getEntryBasicBlock()66 VPBasicBlock *VPBlockBase::getEntryBasicBlock() {
67   VPBlockBase *Block = this;
68   while (VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
69     Block = Region->getEntry();
70   return cast<VPBasicBlock>(Block);
71 }
72 
73 /// \return the VPBasicBlock that is the exit of Block, possibly indirectly.
getExitBasicBlock() const74 const VPBasicBlock *VPBlockBase::getExitBasicBlock() const {
75   const VPBlockBase *Block = this;
76   while (const VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
77     Block = Region->getExit();
78   return cast<VPBasicBlock>(Block);
79 }
80 
getExitBasicBlock()81 VPBasicBlock *VPBlockBase::getExitBasicBlock() {
82   VPBlockBase *Block = this;
83   while (VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
84     Block = Region->getExit();
85   return cast<VPBasicBlock>(Block);
86 }
87 
getEnclosingBlockWithSuccessors()88 VPBlockBase *VPBlockBase::getEnclosingBlockWithSuccessors() {
89   if (!Successors.empty() || !Parent)
90     return this;
91   assert(Parent->getExit() == this &&
92          "Block w/o successors not the exit of its parent.");
93   return Parent->getEnclosingBlockWithSuccessors();
94 }
95 
getEnclosingBlockWithPredecessors()96 VPBlockBase *VPBlockBase::getEnclosingBlockWithPredecessors() {
97   if (!Predecessors.empty() || !Parent)
98     return this;
99   assert(Parent->getEntry() == this &&
100          "Block w/o predecessors not the entry of its parent.");
101   return Parent->getEnclosingBlockWithPredecessors();
102 }
103 
deleteCFG(VPBlockBase * Entry)104 void VPBlockBase::deleteCFG(VPBlockBase *Entry) {
105   SmallVector<VPBlockBase *, 8> Blocks;
106   for (VPBlockBase *Block : depth_first(Entry))
107     Blocks.push_back(Block);
108 
109   for (VPBlockBase *Block : Blocks)
110     delete Block;
111 }
112 
113 BasicBlock *
createEmptyBasicBlock(VPTransformState::CFGState & CFG)114 VPBasicBlock::createEmptyBasicBlock(VPTransformState::CFGState &CFG) {
115   // BB stands for IR BasicBlocks. VPBB stands for VPlan VPBasicBlocks.
116   // Pred stands for Predessor. Prev stands for Previous - last visited/created.
117   BasicBlock *PrevBB = CFG.PrevBB;
118   BasicBlock *NewBB = BasicBlock::Create(PrevBB->getContext(), getName(),
119                                          PrevBB->getParent(), CFG.LastBB);
120   LLVM_DEBUG(dbgs() << "LV: created " << NewBB->getName() << '\n');
121 
122   // Hook up the new basic block to its predecessors.
123   for (VPBlockBase *PredVPBlock : getHierarchicalPredecessors()) {
124     VPBasicBlock *PredVPBB = PredVPBlock->getExitBasicBlock();
125     auto &PredVPSuccessors = PredVPBB->getSuccessors();
126     BasicBlock *PredBB = CFG.VPBB2IRBB[PredVPBB];
127     assert(PredBB && "Predecessor basic-block not found building successor.");
128     auto *PredBBTerminator = PredBB->getTerminator();
129     LLVM_DEBUG(dbgs() << "LV: draw edge from" << PredBB->getName() << '\n');
130     if (isa<UnreachableInst>(PredBBTerminator)) {
131       assert(PredVPSuccessors.size() == 1 &&
132              "Predecessor ending w/o branch must have single successor.");
133       PredBBTerminator->eraseFromParent();
134       BranchInst::Create(NewBB, PredBB);
135     } else {
136       assert(PredVPSuccessors.size() == 2 &&
137              "Predecessor ending with branch must have two successors.");
138       unsigned idx = PredVPSuccessors.front() == this ? 0 : 1;
139       assert(!PredBBTerminator->getSuccessor(idx) &&
140              "Trying to reset an existing successor block.");
141       PredBBTerminator->setSuccessor(idx, NewBB);
142     }
143   }
144   return NewBB;
145 }
146 
execute(VPTransformState * State)147 void VPBasicBlock::execute(VPTransformState *State) {
148   bool Replica = State->Instance &&
149                  !(State->Instance->Part == 0 && State->Instance->Lane == 0);
150   VPBasicBlock *PrevVPBB = State->CFG.PrevVPBB;
151   VPBlockBase *SingleHPred = nullptr;
152   BasicBlock *NewBB = State->CFG.PrevBB; // Reuse it if possible.
153 
154   // 1. Create an IR basic block, or reuse the last one if possible.
155   // The last IR basic block is reused, as an optimization, in three cases:
156   // A. the first VPBB reuses the loop header BB - when PrevVPBB is null;
157   // B. when the current VPBB has a single (hierarchical) predecessor which
158   //    is PrevVPBB and the latter has a single (hierarchical) successor; and
159   // C. when the current VPBB is an entry of a region replica - where PrevVPBB
160   //    is the exit of this region from a previous instance, or the predecessor
161   //    of this region.
162   if (PrevVPBB && /* A */
163       !((SingleHPred = getSingleHierarchicalPredecessor()) &&
164         SingleHPred->getExitBasicBlock() == PrevVPBB &&
165         PrevVPBB->getSingleHierarchicalSuccessor()) && /* B */
166       !(Replica && getPredecessors().empty())) {       /* C */
167     NewBB = createEmptyBasicBlock(State->CFG);
168     State->Builder.SetInsertPoint(NewBB);
169     // Temporarily terminate with unreachable until CFG is rewired.
170     UnreachableInst *Terminator = State->Builder.CreateUnreachable();
171     State->Builder.SetInsertPoint(Terminator);
172     // Register NewBB in its loop. In innermost loops its the same for all BB's.
173     Loop *L = State->LI->getLoopFor(State->CFG.LastBB);
174     L->addBasicBlockToLoop(NewBB, *State->LI);
175     State->CFG.PrevBB = NewBB;
176   }
177 
178   // 2. Fill the IR basic block with IR instructions.
179   LLVM_DEBUG(dbgs() << "LV: vectorizing VPBB:" << getName()
180                     << " in BB:" << NewBB->getName() << '\n');
181 
182   State->CFG.VPBB2IRBB[this] = NewBB;
183   State->CFG.PrevVPBB = this;
184 
185   for (VPRecipeBase &Recipe : Recipes)
186     Recipe.execute(*State);
187 
188   LLVM_DEBUG(dbgs() << "LV: filled BB:" << *NewBB);
189 }
190 
execute(VPTransformState * State)191 void VPRegionBlock::execute(VPTransformState *State) {
192   ReversePostOrderTraversal<VPBlockBase *> RPOT(Entry);
193 
194   if (!isReplicator()) {
195     // Visit the VPBlocks connected to "this", starting from it.
196     for (VPBlockBase *Block : RPOT) {
197       LLVM_DEBUG(dbgs() << "LV: VPBlock in RPO " << Block->getName() << '\n');
198       Block->execute(State);
199     }
200     return;
201   }
202 
203   assert(!State->Instance && "Replicating a Region with non-null instance.");
204 
205   // Enter replicating mode.
206   State->Instance = {0, 0};
207 
208   for (unsigned Part = 0, UF = State->UF; Part < UF; ++Part) {
209     State->Instance->Part = Part;
210     for (unsigned Lane = 0, VF = State->VF; Lane < VF; ++Lane) {
211       State->Instance->Lane = Lane;
212       // Visit the VPBlocks connected to \p this, starting from it.
213       for (VPBlockBase *Block : RPOT) {
214         LLVM_DEBUG(dbgs() << "LV: VPBlock in RPO " << Block->getName() << '\n');
215         Block->execute(State);
216       }
217     }
218   }
219 
220   // Exit replicating mode.
221   State->Instance.reset();
222 }
223 
insertBefore(VPRecipeBase * InsertPos)224 void VPRecipeBase::insertBefore(VPRecipeBase *InsertPos) {
225   Parent = InsertPos->getParent();
226   Parent->getRecipeList().insert(InsertPos->getIterator(), this);
227 }
228 
eraseFromParent()229 iplist<VPRecipeBase>::iterator VPRecipeBase::eraseFromParent() {
230   return getParent()->getRecipeList().erase(getIterator());
231 }
232 
generateInstruction(VPTransformState & State,unsigned Part)233 void VPInstruction::generateInstruction(VPTransformState &State,
234                                         unsigned Part) {
235   IRBuilder<> &Builder = State.Builder;
236 
237   if (Instruction::isBinaryOp(getOpcode())) {
238     Value *A = State.get(getOperand(0), Part);
239     Value *B = State.get(getOperand(1), Part);
240     Value *V = Builder.CreateBinOp((Instruction::BinaryOps)getOpcode(), A, B);
241     State.set(this, V, Part);
242     return;
243   }
244 
245   switch (getOpcode()) {
246   case VPInstruction::Not: {
247     Value *A = State.get(getOperand(0), Part);
248     Value *V = Builder.CreateNot(A);
249     State.set(this, V, Part);
250     break;
251   }
252   default:
253     llvm_unreachable("Unsupported opcode for instruction");
254   }
255 }
256 
execute(VPTransformState & State)257 void VPInstruction::execute(VPTransformState &State) {
258   assert(!State.Instance && "VPInstruction executing an Instance");
259   for (unsigned Part = 0; Part < State.UF; ++Part)
260     generateInstruction(State, Part);
261 }
262 
print(raw_ostream & O,const Twine & Indent) const263 void VPInstruction::print(raw_ostream &O, const Twine &Indent) const {
264   O << " +\n" << Indent << "\"EMIT ";
265   print(O);
266   O << "\\l\"";
267 }
268 
print(raw_ostream & O) const269 void VPInstruction::print(raw_ostream &O) const {
270   printAsOperand(O);
271   O << " = ";
272 
273   switch (getOpcode()) {
274   case VPInstruction::Not:
275     O << "not";
276     break;
277   default:
278     O << Instruction::getOpcodeName(getOpcode());
279   }
280 
281   for (const VPValue *Operand : operands()) {
282     O << " ";
283     Operand->printAsOperand(O);
284   }
285 }
286 
287 /// Generate the code inside the body of the vectorized loop. Assumes a single
288 /// LoopVectorBody basic-block was created for this. Introduce additional
289 /// basic-blocks as needed, and fill them all.
execute(VPTransformState * State)290 void VPlan::execute(VPTransformState *State) {
291   // 0. Set the reverse mapping from VPValues to Values for code generation.
292   for (auto &Entry : Value2VPValue)
293     State->VPValue2Value[Entry.second] = Entry.first;
294 
295   BasicBlock *VectorPreHeaderBB = State->CFG.PrevBB;
296   BasicBlock *VectorHeaderBB = VectorPreHeaderBB->getSingleSuccessor();
297   assert(VectorHeaderBB && "Loop preheader does not have a single successor.");
298   BasicBlock *VectorLatchBB = VectorHeaderBB;
299 
300   // 1. Make room to generate basic-blocks inside loop body if needed.
301   VectorLatchBB = VectorHeaderBB->splitBasicBlock(
302       VectorHeaderBB->getFirstInsertionPt(), "vector.body.latch");
303   Loop *L = State->LI->getLoopFor(VectorHeaderBB);
304   L->addBasicBlockToLoop(VectorLatchBB, *State->LI);
305   // Remove the edge between Header and Latch to allow other connections.
306   // Temporarily terminate with unreachable until CFG is rewired.
307   // Note: this asserts the generated code's assumption that
308   // getFirstInsertionPt() can be dereferenced into an Instruction.
309   VectorHeaderBB->getTerminator()->eraseFromParent();
310   State->Builder.SetInsertPoint(VectorHeaderBB);
311   UnreachableInst *Terminator = State->Builder.CreateUnreachable();
312   State->Builder.SetInsertPoint(Terminator);
313 
314   // 2. Generate code in loop body.
315   State->CFG.PrevVPBB = nullptr;
316   State->CFG.PrevBB = VectorHeaderBB;
317   State->CFG.LastBB = VectorLatchBB;
318 
319   for (VPBlockBase *Block : depth_first(Entry))
320     Block->execute(State);
321 
322   // 3. Merge the temporary latch created with the last basic-block filled.
323   BasicBlock *LastBB = State->CFG.PrevBB;
324   // Connect LastBB to VectorLatchBB to facilitate their merge.
325   assert(isa<UnreachableInst>(LastBB->getTerminator()) &&
326          "Expected VPlan CFG to terminate with unreachable");
327   LastBB->getTerminator()->eraseFromParent();
328   BranchInst::Create(VectorLatchBB, LastBB);
329 
330   // Merge LastBB with Latch.
331   bool Merged = MergeBlockIntoPredecessor(VectorLatchBB, nullptr, State->LI);
332   (void)Merged;
333   assert(Merged && "Could not merge last basic block with latch.");
334   VectorLatchBB = LastBB;
335 
336   updateDominatorTree(State->DT, VectorPreHeaderBB, VectorLatchBB);
337 }
338 
updateDominatorTree(DominatorTree * DT,BasicBlock * LoopPreHeaderBB,BasicBlock * LoopLatchBB)339 void VPlan::updateDominatorTree(DominatorTree *DT, BasicBlock *LoopPreHeaderBB,
340                                 BasicBlock *LoopLatchBB) {
341   BasicBlock *LoopHeaderBB = LoopPreHeaderBB->getSingleSuccessor();
342   assert(LoopHeaderBB && "Loop preheader does not have a single successor.");
343   DT->addNewBlock(LoopHeaderBB, LoopPreHeaderBB);
344   // The vector body may be more than a single basic-block by this point.
345   // Update the dominator tree information inside the vector body by propagating
346   // it from header to latch, expecting only triangular control-flow, if any.
347   BasicBlock *PostDomSucc = nullptr;
348   for (auto *BB = LoopHeaderBB; BB != LoopLatchBB; BB = PostDomSucc) {
349     // Get the list of successors of this block.
350     std::vector<BasicBlock *> Succs(succ_begin(BB), succ_end(BB));
351     assert(Succs.size() <= 2 &&
352            "Basic block in vector loop has more than 2 successors.");
353     PostDomSucc = Succs[0];
354     if (Succs.size() == 1) {
355       assert(PostDomSucc->getSinglePredecessor() &&
356              "PostDom successor has more than one predecessor.");
357       DT->addNewBlock(PostDomSucc, BB);
358       continue;
359     }
360     BasicBlock *InterimSucc = Succs[1];
361     if (PostDomSucc->getSingleSuccessor() == InterimSucc) {
362       PostDomSucc = Succs[1];
363       InterimSucc = Succs[0];
364     }
365     assert(InterimSucc->getSingleSuccessor() == PostDomSucc &&
366            "One successor of a basic block does not lead to the other.");
367     assert(InterimSucc->getSinglePredecessor() &&
368            "Interim successor has more than one predecessor.");
369     assert(pred_size(PostDomSucc) == 2 &&
370            "PostDom successor has more than two predecessors.");
371     DT->addNewBlock(InterimSucc, BB);
372     DT->addNewBlock(PostDomSucc, BB);
373   }
374 }
375 
getUID(const VPBlockBase * Block)376 const Twine VPlanPrinter::getUID(const VPBlockBase *Block) {
377   return (isa<VPRegionBlock>(Block) ? "cluster_N" : "N") +
378          Twine(getOrCreateBID(Block));
379 }
380 
getOrCreateName(const VPBlockBase * Block)381 const Twine VPlanPrinter::getOrCreateName(const VPBlockBase *Block) {
382   const std::string &Name = Block->getName();
383   if (!Name.empty())
384     return Name;
385   return "VPB" + Twine(getOrCreateBID(Block));
386 }
387 
dump()388 void VPlanPrinter::dump() {
389   Depth = 1;
390   bumpIndent(0);
391   OS << "digraph VPlan {\n";
392   OS << "graph [labelloc=t, fontsize=30; label=\"Vectorization Plan";
393   if (!Plan.getName().empty())
394     OS << "\\n" << DOT::EscapeString(Plan.getName());
395   if (!Plan.Value2VPValue.empty()) {
396     OS << ", where:";
397     for (auto Entry : Plan.Value2VPValue) {
398       OS << "\\n" << *Entry.second;
399       OS << DOT::EscapeString(" := ");
400       Entry.first->printAsOperand(OS, false);
401     }
402   }
403   OS << "\"]\n";
404   OS << "node [shape=rect, fontname=Courier, fontsize=30]\n";
405   OS << "edge [fontname=Courier, fontsize=30]\n";
406   OS << "compound=true\n";
407 
408   for (VPBlockBase *Block : depth_first(Plan.getEntry()))
409     dumpBlock(Block);
410 
411   OS << "}\n";
412 }
413 
dumpBlock(const VPBlockBase * Block)414 void VPlanPrinter::dumpBlock(const VPBlockBase *Block) {
415   if (const VPBasicBlock *BasicBlock = dyn_cast<VPBasicBlock>(Block))
416     dumpBasicBlock(BasicBlock);
417   else if (const VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
418     dumpRegion(Region);
419   else
420     llvm_unreachable("Unsupported kind of VPBlock.");
421 }
422 
drawEdge(const VPBlockBase * From,const VPBlockBase * To,bool Hidden,const Twine & Label)423 void VPlanPrinter::drawEdge(const VPBlockBase *From, const VPBlockBase *To,
424                             bool Hidden, const Twine &Label) {
425   // Due to "dot" we print an edge between two regions as an edge between the
426   // exit basic block and the entry basic of the respective regions.
427   const VPBlockBase *Tail = From->getExitBasicBlock();
428   const VPBlockBase *Head = To->getEntryBasicBlock();
429   OS << Indent << getUID(Tail) << " -> " << getUID(Head);
430   OS << " [ label=\"" << Label << '\"';
431   if (Tail != From)
432     OS << " ltail=" << getUID(From);
433   if (Head != To)
434     OS << " lhead=" << getUID(To);
435   if (Hidden)
436     OS << "; splines=none";
437   OS << "]\n";
438 }
439 
dumpEdges(const VPBlockBase * Block)440 void VPlanPrinter::dumpEdges(const VPBlockBase *Block) {
441   auto &Successors = Block->getSuccessors();
442   if (Successors.size() == 1)
443     drawEdge(Block, Successors.front(), false, "");
444   else if (Successors.size() == 2) {
445     drawEdge(Block, Successors.front(), false, "T");
446     drawEdge(Block, Successors.back(), false, "F");
447   } else {
448     unsigned SuccessorNumber = 0;
449     for (auto *Successor : Successors)
450       drawEdge(Block, Successor, false, Twine(SuccessorNumber++));
451   }
452 }
453 
dumpBasicBlock(const VPBasicBlock * BasicBlock)454 void VPlanPrinter::dumpBasicBlock(const VPBasicBlock *BasicBlock) {
455   OS << Indent << getUID(BasicBlock) << " [label =\n";
456   bumpIndent(1);
457   OS << Indent << "\"" << DOT::EscapeString(BasicBlock->getName()) << ":\\n\"";
458   bumpIndent(1);
459   for (const VPRecipeBase &Recipe : *BasicBlock)
460     Recipe.print(OS, Indent);
461 
462   // Dump the condition bit.
463   const VPValue *CBV = BasicBlock->getCondBit();
464   if (CBV) {
465     OS << " +\n" << Indent << " \"CondBit: ";
466     if (const VPInstruction *CBI = dyn_cast<VPInstruction>(CBV)) {
467       CBI->printAsOperand(OS);
468       OS << " (" << DOT::EscapeString(CBI->getParent()->getName()) << ")\\l\"";
469     } else
470       CBV->printAsOperand(OS);
471   }
472 
473   bumpIndent(-2);
474   OS << "\n" << Indent << "]\n";
475   dumpEdges(BasicBlock);
476 }
477 
dumpRegion(const VPRegionBlock * Region)478 void VPlanPrinter::dumpRegion(const VPRegionBlock *Region) {
479   OS << Indent << "subgraph " << getUID(Region) << " {\n";
480   bumpIndent(1);
481   OS << Indent << "fontname=Courier\n"
482      << Indent << "label=\""
483      << DOT::EscapeString(Region->isReplicator() ? "<xVFxUF> " : "<x1> ")
484      << DOT::EscapeString(Region->getName()) << "\"\n";
485   // Dump the blocks of the region.
486   assert(Region->getEntry() && "Region contains no inner blocks.");
487   for (const VPBlockBase *Block : depth_first(Region->getEntry()))
488     dumpBlock(Block);
489   bumpIndent(-1);
490   OS << Indent << "}\n";
491   dumpEdges(Region);
492 }
493 
printAsIngredient(raw_ostream & O,Value * V)494 void VPlanPrinter::printAsIngredient(raw_ostream &O, Value *V) {
495   std::string IngredientString;
496   raw_string_ostream RSO(IngredientString);
497   if (auto *Inst = dyn_cast<Instruction>(V)) {
498     if (!Inst->getType()->isVoidTy()) {
499       Inst->printAsOperand(RSO, false);
500       RSO << " = ";
501     }
502     RSO << Inst->getOpcodeName() << " ";
503     unsigned E = Inst->getNumOperands();
504     if (E > 0) {
505       Inst->getOperand(0)->printAsOperand(RSO, false);
506       for (unsigned I = 1; I < E; ++I)
507         Inst->getOperand(I)->printAsOperand(RSO << ", ", false);
508     }
509   } else // !Inst
510     V->printAsOperand(RSO, false);
511   RSO.flush();
512   O << DOT::EscapeString(IngredientString);
513 }
514 
print(raw_ostream & O,const Twine & Indent) const515 void VPWidenRecipe::print(raw_ostream &O, const Twine &Indent) const {
516   O << " +\n" << Indent << "\"WIDEN\\l\"";
517   for (auto &Instr : make_range(Begin, End))
518     O << " +\n" << Indent << "\"  " << VPlanIngredient(&Instr) << "\\l\"";
519 }
520 
print(raw_ostream & O,const Twine & Indent) const521 void VPWidenIntOrFpInductionRecipe::print(raw_ostream &O,
522                                           const Twine &Indent) const {
523   O << " +\n" << Indent << "\"WIDEN-INDUCTION";
524   if (Trunc) {
525     O << "\\l\"";
526     O << " +\n" << Indent << "\"  " << VPlanIngredient(IV) << "\\l\"";
527     O << " +\n" << Indent << "\"  " << VPlanIngredient(Trunc) << "\\l\"";
528   } else
529     O << " " << VPlanIngredient(IV) << "\\l\"";
530 }
531 
print(raw_ostream & O,const Twine & Indent) const532 void VPWidenPHIRecipe::print(raw_ostream &O, const Twine &Indent) const {
533   O << " +\n" << Indent << "\"WIDEN-PHI " << VPlanIngredient(Phi) << "\\l\"";
534 }
535 
print(raw_ostream & O,const Twine & Indent) const536 void VPBlendRecipe::print(raw_ostream &O, const Twine &Indent) const {
537   O << " +\n" << Indent << "\"BLEND ";
538   Phi->printAsOperand(O, false);
539   O << " =";
540   if (!User) {
541     // Not a User of any mask: not really blending, this is a
542     // single-predecessor phi.
543     O << " ";
544     Phi->getIncomingValue(0)->printAsOperand(O, false);
545   } else {
546     for (unsigned I = 0, E = User->getNumOperands(); I < E; ++I) {
547       O << " ";
548       Phi->getIncomingValue(I)->printAsOperand(O, false);
549       O << "/";
550       User->getOperand(I)->printAsOperand(O);
551     }
552   }
553   O << "\\l\"";
554 }
555 
print(raw_ostream & O,const Twine & Indent) const556 void VPReplicateRecipe::print(raw_ostream &O, const Twine &Indent) const {
557   O << " +\n"
558     << Indent << "\"" << (IsUniform ? "CLONE " : "REPLICATE ")
559     << VPlanIngredient(Ingredient);
560   if (AlsoPack)
561     O << " (S->V)";
562   O << "\\l\"";
563 }
564 
print(raw_ostream & O,const Twine & Indent) const565 void VPPredInstPHIRecipe::print(raw_ostream &O, const Twine &Indent) const {
566   O << " +\n"
567     << Indent << "\"PHI-PREDICATED-INSTRUCTION " << VPlanIngredient(PredInst)
568     << "\\l\"";
569 }
570 
print(raw_ostream & O,const Twine & Indent) const571 void VPWidenMemoryInstructionRecipe::print(raw_ostream &O,
572                                            const Twine &Indent) const {
573   O << " +\n" << Indent << "\"WIDEN " << VPlanIngredient(&Instr);
574   if (User) {
575     O << ", ";
576     User->getOperand(0)->printAsOperand(O);
577   }
578   O << "\\l\"";
579 }
580 
581 template void DomTreeBuilder::Calculate<VPDominatorTree>(VPDominatorTree &DT);
582