LLVM 24.0.0git
VPlan.cpp
Go to the documentation of this file.
1//===- VPlan.cpp - Vectorizer Plan ----------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This is the LLVM vectorization plan. It represents a candidate for
11/// vectorization, allowing to plan and optimize how to vectorize a given loop
12/// before generating LLVM-IR.
13/// The vectorizer uses vectorization plans to estimate the costs of potential
14/// candidates and if profitable to execute the desired plan, generating vector
15/// LLVM-IR code.
16///
17//===----------------------------------------------------------------------===//
18
19#include "VPlan.h"
21#include "VPlanCFG.h"
22#include "VPlanDominatorTree.h"
23#include "VPlanHelpers.h"
24#include "VPlanPatternMatch.h"
25#include "VPlanTransforms.h"
26#include "VPlanUtils.h"
27#include "VectorizeOptions.h"
29#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/Twine.h"
36#include "llvm/IR/BasicBlock.h"
37#include "llvm/IR/CFG.h"
38#include "llvm/IR/IRBuilder.h"
39#include "llvm/IR/Instruction.h"
41#include "llvm/IR/Type.h"
42#include "llvm/IR/Value.h"
45#include "llvm/Support/Debug.h"
51#include <cassert>
52#include <string>
53
54using namespace llvm;
55using namespace llvm::VPlanPatternMatch;
56
57namespace llvm {
59} // namespace llvm
60
61/// @{
62/// Metadata attribute names
63const char LLVMLoopVectorizeFollowupAll[] = "llvm.loop.vectorize.followup_all";
65 "llvm.loop.vectorize.followup_vectorized";
67 "llvm.loop.vectorize.followup_epilogue";
68/// @}
69
70#define DEBUG_TYPE "loop-vectorize"
71
72#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
74 const VPBasicBlock *Parent = R.getParent();
75 VPSlotTracker SlotTracker(Parent ? Parent->getPlan() : nullptr);
76 R.print(OS, "", SlotTracker);
77 return OS;
78}
79#endif
80
82 const ElementCount &VF) const {
83 switch (LaneKind) {
85 // Lane = RuntimeVF - VF.getKnownMinValue() + Lane
86 return Builder.CreateSub(getRuntimeVF(Builder, Builder.getInt32Ty(), VF),
87 Builder.getInt32(VF.getKnownMinValue() - Lane));
89 return Builder.getInt64(Lane);
90 }
91 llvm_unreachable("Unknown lane kind");
92}
93
94#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
96 if (const VPRecipeBase *R = getDefiningRecipe())
97 R->print(OS, "", SlotTracker);
98 else
100}
101
102void VPValue::dump() const {
103 const VPRecipeBase *Instr = getDefiningRecipe();
105 (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
107 dbgs() << "\n";
108}
109
110void VPRecipeBase::dump() const {
111 VPSlotTracker SlotTracker(getParent() ? getParent()->getPlan() : nullptr);
112 print(dbgs(), "", SlotTracker);
113 dbgs() << "\n";
114}
115#endif
116
117#if !defined(NDEBUG)
118bool VPRecipeValue::isDefinedBy(const VPDef *D) const {
119 return getDefiningRecipe() == D;
120}
121#endif
122
124 auto *RecipeValue = dyn_cast<VPRecipeValue>(this);
125 if (!RecipeValue)
126 return nullptr;
127 if (auto *MultiDef = dyn_cast<VPMultiDefValue>(RecipeValue))
128 return MultiDef->getDef();
129 return static_cast<VPSingleDefRecipe *>(RecipeValue);
130}
131
133 return const_cast<VPValue *>(this)->getDefiningRecipe();
134}
135
137 return cast<VPIRValue>(this)->getValue();
138}
139
141
143 switch (getVPValueID()) {
144 case VPVIRValueSC:
145 return cast<VPIRValue>(this)->getType();
146 case VPRegionValueSC:
147 return cast<VPRegionValue>(this)->getType();
148 case VPVSymbolicSC:
149 return cast<VPSymbolicValue>(this)->getType();
152 return cast<VPRecipeValue>(this)->getScalarType();
153 }
154 llvm_unreachable("Unhandled VPValue subclass");
155}
156
158 assert(Users.empty() &&
159 "trying to delete a VPRecipeValue with remaining users");
160}
161
164 assert(Def && "VPSingleDefValue requires a defining recipe");
165 Def->addDefinedValue(this);
166}
167
169 getDefiningRecipe()->removeDefinedValue(this);
170}
171
173 : VPRecipeValue(VPVMultiDefValueSC, UV, Ty), Def(Def) {
174 assert(Def && "VPMultiDefValue requires a defining recipe");
175 Def->addDefinedValue(this);
176}
177
179 getDefiningRecipe()->removeDefinedValue(this);
180}
181
182/// \return the VPBasicBlock that is the entry of Block, possibly indirectly.
189
196
197/// \return the VPBasicBlock that is the exit of Block, possibly indirectly.
199 const VPBlockBase *Block = this;
201 Block = Region->getExiting();
203}
204
211
213 if (!Successors.empty() || !Parent)
214 return this;
215 assert(Parent->getExiting() == this &&
216 "Block w/o successors not the exiting block of its parent.");
217 return Parent->getEnclosingBlockWithSuccessors();
218}
219
221 if (!Predecessors.empty() || !Parent)
222 return this;
223 assert(Parent->getEntry() == this &&
224 "Block w/o predecessors not the entry of its parent.");
225 return Parent->getEnclosingBlockWithPredecessors();
226}
227
229 iterator It = begin();
230 while (It != end() && It->isPhi())
231 It++;
232 return It;
233}
234
242
243Value *VPTransformState::get(const VPValue *Def, const VPLane &Lane) {
245 "VPRegionValue must be materialized before VPTransformState::get");
247 return Def->getUnderlyingValue();
248
249 if (hasScalarValue(Def, Lane))
250 return Data.VPV2Scalars[Def][Lane.mapToCacheIndex(VF)];
251
252 if (!Lane.isFirstLane() && vputils::isSingleScalar(Def) &&
254 return Data.VPV2Scalars[Def][0];
255 }
256
258 auto *VecPart = Data.VPV2Vector[Def];
259 if (!VecPart->getType()->isVectorTy()) {
260 assert(Lane.isFirstLane() && "cannot get lane > 0 for scalar");
261 return VecPart;
262 }
263 // TODO: Cache created scalar values.
264 Value *LaneV = Lane.getAsRuntimeExpr(Builder, VF);
265 auto *Extract = Builder.CreateExtractElement(VecPart, LaneV);
266 // set(Def, Extract, Instance);
267 return Extract;
268}
269
270Value *VPTransformState::get(const VPValue *Def, bool NeedsSingleScalar) {
272 "VPRegionValue must be materialized before VPTransformState::get");
273 if (NeedsSingleScalar) {
274 assert((VF.isScalar() || isa<VPIRValue, VPSymbolicValue>(Def) ||
276 (hasScalarValue(Def, VPLane(0)) &&
277 Data.VPV2Scalars[Def].size() == 1)) &&
278 "Trying to access a single scalar per part but has multiple scalars "
279 "per part.");
280 return get(Def, VPLane(0));
281 }
282
283 // If Values have been set for this Def return the one relevant for \p Part.
284 if (hasVectorValue(Def))
285 return Data.VPV2Vector[Def];
286
287 auto GetBroadcastInstrs = [this](Value *V) {
288 if (VF.isScalar())
289 return V;
290 // Broadcast the scalar into all locations in the vector.
291 Value *Shuf = Builder.CreateVectorSplat(VF, V, "broadcast");
292 return Shuf;
293 };
294
295 Value *ScalarValue = get(Def, VPLane(0));
298 if (auto *LastInst = dyn_cast<Instruction>(get(Def, LastLane)))
299 // Set the insert point after the last scalarized instruction. This
300 // ensures the insertelement sequence will directly follow the scalar
301 // definitions.
302 if (auto InsertPt = LastInst->getInsertionPointAfterDef())
303 Builder.SetInsertPoint(*InsertPt);
304 Value *VectorValue = GetBroadcastInstrs(ScalarValue);
305 set(Def, VectorValue);
306 return VectorValue;
307}
308
310 const DILocation *DIL = DL;
311 // When a FSDiscriminator is enabled, we don't need to add the multiply
312 // factors to the discriminators.
313 if (DIL &&
314 Builder.GetInsertBlock()
315 ->getParent()
316 ->shouldEmitDebugInfoForProfiling() &&
318 // FIXME: For scalable vectors, assume vscale=1.
319 unsigned UF = Plan->getConcreteUF();
320 auto NewDIL =
321 DIL->cloneByMultiplyingDuplicationFactor(UF * VF.getKnownMinValue());
322 if (NewDIL)
323 Builder.SetCurrentDebugLocation(*NewDIL);
324 else
325 LLVM_DEBUG(dbgs() << "Failed to create new discriminator: "
326 << DIL->getFilename() << " Line: " << DIL->getLine());
327 } else
328 Builder.SetCurrentDebugLocation(DL);
329}
330
332 for (VPBlockBase *VPB : vp_depth_first_shallow(Plan->getEntry())) {
333 if (!VPBlockUtils::isHeader(VPB, VPDT))
334 continue;
335 auto *Header = cast<VPBasicBlock>(VPB);
336 auto *LatchVPBB = cast<VPBasicBlock>(Header->getPredecessors()[1]);
337 BasicBlock *VectorLatchBB = CFG.VPBB2IRBB[LatchVPBB];
338
339 for (VPRecipeBase &R : Header->phis()) {
340 auto *PhiR = cast<VPSingleDefRecipe>(&R);
341 bool NeedsSingleScalar =
342 isa<VPPhi>(PhiR) || (isa<VPReductionPHIRecipe>(PhiR) &&
343 cast<VPReductionPHIRecipe>(PhiR)->isInLoop());
344
345 Value *Phi = get(PhiR, NeedsSingleScalar);
346 Value *Val = get(PhiR->getOperand(1), NeedsSingleScalar);
347 cast<PHINode>(Phi)->addIncoming(Val, VectorLatchBB);
348 }
349 }
350}
351
352BasicBlock *VPBasicBlock::createEmptyBasicBlock(VPTransformState &State) {
353 auto &CFG = State.CFG;
354 // BB stands for IR BasicBlocks. VPBB stands for VPlan VPBasicBlocks.
355 // Pred stands for Predessor. Prev stands for Previous - last visited/created.
356 BasicBlock *PrevBB = CFG.PrevBB;
357 BasicBlock *NewBB = BasicBlock::Create(PrevBB->getContext(), getName(),
358 PrevBB->getParent(), CFG.ExitBB);
359 LLVM_DEBUG(dbgs() << "LV: created " << NewBB->getName() << '\n');
360
361 return NewBB;
362}
363
365 auto &CFG = State.CFG;
366 BasicBlock *NewBB = CFG.VPBB2IRBB[this];
367
368 // Register NewBB in its loop. In innermost loops its the same for all
369 // BB's.
370 Loop *ParentLoop = State.CurrentParentLoop;
371 // If this block has a sole successor that is an exit block or is an exit
372 // block itself then it needs adding to the same parent loop as the exit
373 // block.
374 VPBlockBase *SuccOrExitVPB = getSingleSuccessor();
375 SuccOrExitVPB = SuccOrExitVPB ? SuccOrExitVPB : this;
376 if (State.Plan->isExitBlock(SuccOrExitVPB)) {
377 ParentLoop = State.LI->getLoopFor(
378 cast<VPIRBasicBlock>(SuccOrExitVPB)->getIRBasicBlock());
379 }
380
381 if (ParentLoop && !State.LI->getLoopFor(NewBB))
382 ParentLoop->addBasicBlockToLoop(NewBB, *State.LI);
383
385 if (VPBlockUtils::isHeader(this, State.VPDT)) {
386 // There's no block for the latch yet, connect to the preheader only.
387 Preds = {getPredecessors()[0]};
388 } else {
389 Preds = to_vector(getPredecessors());
390 }
391
392 // Hook up the new basic block to its predecessors.
393 for (VPBlockBase *PredVPBlock : Preds) {
394 VPBasicBlock *PredVPBB = PredVPBlock->getExitingBasicBlock();
395 auto &PredVPSuccessors = PredVPBB->getHierarchicalSuccessors();
396 assert(CFG.VPBB2IRBB.contains(PredVPBB) &&
397 "Predecessor basic-block not found building successor.");
398 BasicBlock *PredBB = CFG.VPBB2IRBB[PredVPBB];
399 auto *PredBBTerminator = PredBB->getTerminator();
400 LLVM_DEBUG(dbgs() << "LV: draw edge from " << PredBB->getName() << '\n');
401
402 if (isa<UnreachableInst>(PredBBTerminator)) {
403 assert(PredVPSuccessors.size() == 1 &&
404 "Predecessor ending w/o branch must have single successor.");
405 DebugLoc DL = PredBBTerminator->getDebugLoc();
406 PredBBTerminator->eraseFromParent();
407 auto *Br = UncondBrInst::Create(NewBB, PredBB);
408 Br->setDebugLoc(DL);
409 } else if (auto *UBI = dyn_cast<UncondBrInst>(PredBBTerminator)) {
410 UBI->setSuccessor(NewBB);
411 } else {
412 // Set each forward successor here when it is created, excluding
413 // backedges. A backward successor is set when the branch is created.
414 // Generated successors are redirected, as for the entry block and for
415 // blocks bypassing a vector loop during epilogue vectorization. Edges
416 // already present in the generated IR need no update; this happens during
417 // epilogue vectorization, where the plan models blocks generated for the
418 // main vector loop.
419 // TODO: Remove the exception by modeling those terminators using
420 // BranchOnCond.
421 auto *TermBr = cast<CondBrInst>(PredBBTerminator);
422 if (TermBr->getSuccessor(0) != NewBB &&
423 TermBr->getSuccessor(1) != NewBB) {
424 unsigned Idx = PredVPSuccessors.front() == this ? 0 : 1;
425 BasicBlock *ReplacedSucc = TermBr->getSuccessor(Idx);
426 assert(
427 (!ReplacedSucc || isa<VPIRBasicBlock>(PredVPBB)) &&
428 "only VPIRBasicBlock predecessors may have an existing successor "
429 "redirected");
430 if (ReplacedSucc)
431 ReplacedSucc->removePredecessor(PredBB, /*KeepOneInputPHIs=*/true);
432 TermBr->setSuccessor(Idx, NewBB);
433 if (ReplacedSucc)
434 CFG.DTU.applyUpdates({{DominatorTree::Delete, PredBB, ReplacedSucc}});
435 }
436 }
437 CFG.DTU.applyUpdates({{DominatorTree::Insert, PredBB, NewBB}});
438 }
439}
440
443 "VPIRBasicBlock can have at most two successors at the moment!");
444 // Move completely disconnected blocks to their final position.
445 if (IRBB->hasNPredecessors(0) && succ_begin(IRBB) == succ_end(IRBB))
446 IRBB->moveAfter(State->CFG.PrevBB);
447 State->Builder.SetInsertPoint(IRBB->getTerminator());
448 State->CFG.PrevBB = IRBB;
449 State->CFG.VPBB2IRBB[this] = IRBB;
450 executeRecipes(State, IRBB);
451 // Create a branch instruction to terminate IRBB if one was not created yet
452 // and is needed.
453 if (getSingleSuccessor() && isa<UnreachableInst>(IRBB->getTerminator())) {
454 auto *Br = State->Builder.CreateBr(IRBB);
455 Br->setOperand(0, nullptr);
456 IRBB->getTerminator()->eraseFromParent();
457 } else {
458 assert((getNumSuccessors() == 0 ||
459 isa<UncondBrInst, CondBrInst>(IRBB->getTerminator())) &&
460 "other blocks must be terminated by a branch");
461 }
462
463 connectToPredecessors(*State);
464}
465
466VPIRBasicBlock *VPIRBasicBlock::clone() {
467 auto *NewBlock = getPlan()->createEmptyVPIRBasicBlock(IRBB);
468 for (VPRecipeBase &R : Recipes)
469 NewBlock->appendRecipe(R.clone());
470 return NewBlock;
471}
472
474 if (VPBlockUtils::isHeader(this, State->VPDT)) {
475 // Create and register the new vector loop.
476 Loop *PrevParentLoop = State->CurrentParentLoop;
477 State->CurrentParentLoop = State->LI->AllocateLoop();
478
479 // Insert the new loop into the loop nest and register the new basic blocks
480 // before calling any utilities such as SCEV that require valid LoopInfo.
481 if (PrevParentLoop)
482 PrevParentLoop->addChildLoop(State->CurrentParentLoop);
483 else
484 State->LI->addTopLevelLoop(State->CurrentParentLoop);
485 }
486
487 // 1. Create an IR basic block.
488 BasicBlock *NewBB = createEmptyBasicBlock(*State);
489
490 State->Builder.SetInsertPoint(NewBB);
491 // Temporarily terminate with unreachable until CFG is rewired.
492 UnreachableInst *Terminator = State->Builder.CreateUnreachable();
493 State->Builder.SetInsertPoint(Terminator);
494
495 State->CFG.PrevBB = NewBB;
496 State->CFG.VPBB2IRBB[this] = NewBB;
497 connectToPredecessors(*State);
498
499 // 2. Fill the IR basic block with IR instructions.
500 executeRecipes(State, NewBB);
501
502 // If this block is a latch, update CurrentParentLoop.
503 if (VPBlockUtils::isLatch(this, State->VPDT))
504 State->CurrentParentLoop = State->CurrentParentLoop->getParentLoop();
505}
506
507VPBasicBlock *VPBasicBlock::clone() {
508 auto *NewBlock = getPlan()->createVPBasicBlock(getName());
509 for (VPRecipeBase &R : *this)
510 NewBlock->appendRecipe(R.clone());
511 return NewBlock;
512}
513
515 LLVM_DEBUG(dbgs() << "LV: vectorizing VPBB: " << getName()
516 << " in BB: " << BB->getName() << '\n');
517
518 State->CFG.PrevVPBB = this;
519
520 for (VPRecipeBase &Recipe : Recipes) {
521 State->setDebugLocFrom(Recipe.getDebugLoc());
522 Recipe.execute(*State);
523 }
524
525 LLVM_DEBUG(dbgs() << "LV: filled BB: " << *BB);
526}
527
528VPBasicBlock *VPBasicBlock::splitAt(iterator SplitAt) {
529 assert((SplitAt == end() || SplitAt->getParent() == this) &&
530 "can only split at a position in the same block");
531
532 // Create new empty block after the block to split.
533 auto *SplitBlock = getPlan()->createVPBasicBlock(getName() + ".split");
535
536 // If this is the exiting block, make the split the new exiting block.
537 auto *ParentRegion = getParent();
538 if (ParentRegion && ParentRegion->getExiting() == this)
539 ParentRegion->setExiting(SplitBlock);
540
541 // Finally, move the recipes starting at SplitAt to new block.
542 for (VPRecipeBase &ToMove :
543 make_early_inc_range(make_range(SplitAt, this->end())))
544 ToMove.moveBefore(SplitBlock->end());
545
546 return SplitBlock;
547}
548
549/// Return the enclosing loop region for region \p P. The templated version is
550/// used to support both const and non-const block arguments.
551template <typename T> static T *getEnclosingLoopRegionForRegion(T *P) {
552 if (P && P->isReplicator()) {
553 P = P->getParent();
554 // Multiple loop regions can be nested, but replicate regions can only be
555 // nested inside a loop region or must be outside any other region.
556 assert((!P || !P->isReplicator()) && "unexpected nested replicate regions");
557 }
558 return P;
559}
560
564
568
569static bool hasConditionalTerminator(const VPBasicBlock *VPBB) {
570 if (VPBB->empty()) {
571 assert(
572 VPBB->getNumSuccessors() < 2 &&
573 "block with multiple successors doesn't have a recipe as terminator");
574 return false;
575 }
576
577 const VPRecipeBase *R = &VPBB->back();
578 [[maybe_unused]] bool IsSwitch =
580 cast<VPInstruction>(R)->getOpcode() == Instruction::Switch;
581 [[maybe_unused]] bool IsBranchOnTwoConds = match(R, m_BranchOnTwoConds());
582 [[maybe_unused]] bool IsCondBranch =
585 if (VPBB->getNumSuccessors() == 2 ||
586 (VPBB->isExiting() && !VPBB->getParent()->isReplicator())) {
587 assert((IsCondBranch || IsSwitch || IsBranchOnTwoConds) &&
588 "block with multiple successors not terminated by "
589 "conditional branch nor switch recipe");
590
591 return true;
592 }
593
594 if (VPBB->getNumSuccessors() > 2) {
595 assert((IsSwitch || IsBranchOnTwoConds) &&
596 "block with more than 2 successors not terminated by a switch or "
597 "branch-on-two-conds recipe");
598 return true;
599 }
600
601 assert(
602 !IsCondBranch && !IsBranchOnTwoConds &&
603 "block with 0 or 1 successors terminated by conditional branch recipe");
604 return false;
605}
606
608 if (hasConditionalTerminator(this))
609 return &back();
610 return nullptr;
611}
612
614 if (hasConditionalTerminator(this))
615 return &back();
616 return nullptr;
617}
618
620 return getParent() && getParent()->getExitingBasicBlock() == this;
621}
622
623#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
628
629void VPBlockBase::printSuccessors(raw_ostream &O, const Twine &Indent) const {
630 if (!hasSuccessors()) {
631 O << Indent << "No successors\n";
632 } else {
633 O << Indent << "Successor(s): ";
634 ListSeparator LS;
635 for (auto *Succ : getSuccessors())
636 O << LS << Succ->getName();
637 O << '\n';
638 }
639}
640
641void VPBasicBlock::print(raw_ostream &O, const Twine &Indent,
642 VPSlotTracker &SlotTracker) const {
643 O << Indent << getName() << ":\n";
644
645 auto RecipeIndent = Indent + " ";
646 for (const VPRecipeBase &Recipe : *this) {
647 Recipe.print(O, RecipeIndent, SlotTracker);
648 O << '\n';
649 }
650
651 printSuccessors(O, Indent);
652}
653#endif
654
655std::pair<VPBlockBase *, VPBlockBase *>
658 VPBlockBase *Exiting = nullptr;
659 bool InRegion = Entry->getParent();
660 // First, clone blocks reachable from Entry.
661 for (VPBlockBase *BB : vp_depth_first_shallow(Entry)) {
662 VPBlockBase *NewBB = BB->clone();
663 Old2NewVPBlocks[BB] = NewBB;
664 if (InRegion && BB->getNumSuccessors() == 0) {
665 assert(!Exiting && "Multiple exiting blocks?");
666 Exiting = BB;
667 }
668 }
669 assert((!InRegion || Exiting) && "regions must have a single exiting block");
670
671 // Second, update the predecessors & successors of the cloned blocks.
672 for (VPBlockBase *BB : vp_depth_first_shallow(Entry)) {
673 VPBlockBase *NewBB = Old2NewVPBlocks[BB];
675 for (VPBlockBase *Pred : BB->getPredecessors()) {
676 NewPreds.push_back(Old2NewVPBlocks[Pred]);
677 }
678 NewBB->setPredecessors(NewPreds);
680 for (VPBlockBase *Succ : BB->successors()) {
681 NewSuccs.push_back(Old2NewVPBlocks[Succ]);
682 }
683 NewBB->setSuccessors(NewSuccs);
684 }
685
686#if !defined(NDEBUG)
687 // Verify that the order of predecessors and successors matches in the cloned
688 // version.
689 for (const auto &[OldBB, NewBB] :
691 vp_depth_first_shallow(Old2NewVPBlocks[Entry]))) {
692 for (const auto &[OldPred, NewPred] :
693 zip(OldBB->getPredecessors(), NewBB->getPredecessors()))
694 assert(NewPred == Old2NewVPBlocks[OldPred] && "Different predecessors");
695
696 for (const auto &[OldSucc, NewSucc] :
697 zip(OldBB->successors(), NewBB->successors()))
698 assert(NewSucc == Old2NewVPBlocks[OldSucc] && "Different successors");
699 }
700#endif
701
702 return std::make_pair(Old2NewVPBlocks[Entry],
703 Exiting ? Old2NewVPBlocks[Exiting] : nullptr);
704}
705
707 const auto *EntryBB = cast<VPBasicBlock>(getEntry());
708 assert(isReplicator() && EntryBB && EntryBB->size() == 1 &&
709 "not a valid replicating region");
710 return cast<VPBranchOnMaskRecipe>(&EntryBB->front());
711}
712
713VPRegionBlock *VPRegionBlock::clone() {
714 const auto &[NewEntry, NewExiting] = VPBlockUtils::cloneFrom(getEntry());
715 VPlan &Plan = *getPlan();
716 VPRegionValue *CanIV = getCanonicalIV();
717 VPRegionBlock *NewRegion =
718 CanIV ? Plan.createLoopRegion(CanIV->getType(), CanIV->getDebugLoc(),
719 getName(), NewEntry, NewExiting)
720 : Plan.createReplicateRegion(NewEntry, NewExiting, getName());
721
722 if (getHeaderMask())
723 NewRegion->createHeaderMask();
724
725 if (CanIV && !hasCanonicalIVNUW())
726 NewRegion->CanIVInfo->clearNUW();
727
728 for (VPBlockBase *Block : vp_depth_first_shallow(NewEntry))
729 Block->setParent(NewRegion);
730 return NewRegion;
731}
732
734 llvm_unreachable("regions must get dissolved before ::execute");
735}
736
739 for (VPRecipeBase &R : Recipes)
740 Cost += R.cost(VF, Ctx);
741
742 // Charge cost for unconditional branches outside replicate regions that
743 // cannot be folded.
744 const VPBlockBase *Succ = getSingleSuccessor();
745 const VPRegionBlock *Region = getParent();
746 if (Succ && !Succ->getSinglePredecessor() &&
747 (!Region || !Region->isReplicator())) {
748 Cost += Ctx.Opts.force_target_instruction_cost
749 ? InstructionCost(*Ctx.Opts.force_target_instruction_cost)
750 : Ctx.TTI.getCFInstrCost(Instruction::UncondBr, Ctx.CostKind);
751 }
752 return Cost;
753}
754
755const VPBasicBlock *VPBasicBlock::getCFGPredecessor(unsigned Idx) const {
756 const VPBlockBase *Pred = nullptr;
757 if (hasPredecessors()) {
758 Pred = getPredecessors()[Idx];
759 } else {
760 auto *Region = getParent();
761 assert(Region && !Region->isReplicator() && Region->getEntry() == this &&
762 "must be in the entry block of a non-replicate region");
763 assert(Idx < 2 && Region->getNumPredecessors() == 1 &&
764 "loop region has a single predecessor (preheader), its entry block "
765 "has 2 incoming blocks");
766
767 // Idx == 0 selects the predecessor of the region, Idx == 1 selects the
768 // region itself whose exiting block feeds the phi across the backedge.
769 Pred = Idx == 0 ? Region->getSinglePredecessor() : Region;
770 }
771 return Pred->getExitingBasicBlock();
772}
773
775 if (!isReplicator()) {
778 Cost += Block->cost(VF, Ctx);
779 // Add the costs of the loop's backedge and canonical IV increment
780 auto AddCost = [&](InstructionCost C, const char *Name) {
781 if (Ctx.Opts.force_target_instruction_cost)
782 C = InstructionCost(*Ctx.Opts.force_target_instruction_cost);
783 LLVM_DEBUG(dbgs() << "Cost of " << C << " for VF " << VF << ": " << Name
784 << "\n");
785 Cost += C;
786 };
787 AddCost(Ctx.TTI.getCFInstrCost(Instruction::UncondBr, Ctx.CostKind),
788 "vector loop backedge");
790 AddCost(Ctx.TTI.getArithmeticInstrCost(
791 Instruction::Add, getCanonicalIVType(), Ctx.CostKind),
792 "canonical IV increment");
793 return Cost;
794 }
795
796 // Compute the cost of a replicate region. Replicating isn't supported for
797 // scalable vectors, return an invalid cost for them.
798 // TODO: Discard scalable VPlans with replicate recipes earlier after
799 // construction.
800 if (VF.isScalable())
802
803 // Compute and return the cost of the branch on the mask in the entry, the
804 // conditionally executed recipes and the unconditional branch from the
805 // conditionally executed block to the exiting block for each lane.
806 assert(VF.isVector() && "Can only compute vector cost at the moment.");
808
809 // If the vector loop executes at most once and the region is predicated on
810 // the header mask, the branches fold away.
812 match(getEntryBranchOnMask()->getOperand(0),
814 return Then->cost(VF, Ctx);
815
816 InstructionCost Cost = getEntry()->cost(VF, Ctx);
817 Cost += Then->cost(VF, Ctx);
818 InstructionCost ThenBranchCost;
819 if (Ctx.Opts.force_target_instruction_cost) {
820 ThenBranchCost = InstructionCost(*Ctx.Opts.force_target_instruction_cost);
821 } else {
822 ThenBranchCost =
823 VF.getFixedValue() *
824 Ctx.TTI.getCFInstrCost(Instruction::UncondBr, Ctx.CostKind);
825 ThenBranchCost /=
826 Ctx.getCostDivisor(getEntryBranchOnMask()->getExecutionFrequency());
827 }
828 LLVM_DEBUG(dbgs() << "Cost of " << ThenBranchCost << " for VF " << VF
829 << ": unconditional branches from " << Then->getName()
830 << "\n");
831 return Cost + ThenBranchCost;
832}
833
834#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
836 VPSlotTracker &SlotTracker) const {
837 O << Indent << (isReplicator() ? "<xVFxUF> " : "<x1> ") << getName() << ": {";
838 auto NewIndent = Indent + " ";
839 if (auto *CanIV = getCanonicalIV()) {
840 O << '\n';
841 CanIV->print(O, SlotTracker);
842 O << " = CANONICAL-IV\n";
843 }
844 if (auto *HdrMask = getUsedHeaderMask()) {
845 HdrMask->print(O, SlotTracker);
846 O << " = HEADER-MASK\n";
847 }
848 for (auto *BlockBase : vp_depth_first_shallow(Entry)) {
849 O << '\n';
850 BlockBase->print(O, NewIndent, SlotTracker);
851 }
852 O << Indent << "}\n";
853
854 printSuccessors(O, Indent);
855}
856#endif
857
859 auto *Header = cast<VPBasicBlock>(getEntry());
860 auto *ExitingLatch = cast<VPBasicBlock>(getExiting());
861 auto *CanIV = getCanonicalIV();
862 if (!CanIV->user_empty()) {
863 VPlan &Plan = *getPlan();
864 auto *Zero = Plan.getZero(CanIV->getType());
865 DebugLoc DL = CanIV->getDebugLoc();
867 VPBuilder HeaderBuilder(Header->begin());
868 auto *ScalarR =
869 HeaderBuilder.createScalarPhi({Zero, CanIVInc}, DL, "index");
870 CanIV->replaceAllUsesWith(ScalarR);
871 }
872
873 VPBlockBase *Preheader = getSinglePredecessor();
874 VPBlockUtils::disconnectBlocks(Preheader, this);
875
876 for (VPBlockBase *VPB : vp_depth_first_shallow(Entry))
877 VPB->setParent(getParent());
878
879 VPBlockUtils::connectBlocks(Preheader, Header);
880 VPBlockUtils::transferSuccessors(this, ExitingLatch);
881 VPBlockUtils::connectBlocks(ExitingLatch, Header);
882}
883
885 // TODO: Represent the increment as VPRegionValue as well.
886 VPRegionValue *CanIV = getCanonicalIV();
887 assert(CanIV && "Expected a canonical IV");
888
889 if (auto *Inc = vputils::findCanonicalIVIncrement(*getPlan()))
890 return Inc;
891
892 assert(!getPlan()->getVFxUF().isMaterialized() &&
893 "VFxUF can be used only before it is materialized.");
894 auto *ExitingLatch = cast<VPBasicBlock>(getExiting());
895 return VPBuilder(ExitingLatch->getTerminator())
896 .createOverflowingOp(Instruction::Add, {CanIV, &getPlan()->getVFxUF()},
897 {hasCanonicalIVNUW(), /* HasNSW */ false},
898 CanIV->getDebugLoc(), "index.next");
899}
900
901VPlan::VPlan(Loop *L, Type *IdxTy)
902 : VectorTripCount(IdxTy), VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
903 setEntry(createVPIRBasicBlock(L->getLoopPreheader()));
904 ScalarHeader = createVPIRBasicBlock(L->getHeader());
905
906 SmallVector<BasicBlock *> IRExitBlocks;
907 L->getUniqueExitBlocks(IRExitBlocks);
908 for (BasicBlock *EB : IRExitBlocks)
909 ExitBlocks.push_back(createVPIRBasicBlock(EB));
910}
911
913 VPSymbolicValue DummyValue(nullptr);
914
915 // Redirect all recipe operands to DummyValue before deleting blocks.
916 for (VPBasicBlock *VPBB :
918 for (VPRecipeBase &R : *VPBB)
919 for (unsigned I = 0, E = R.getNumOperands(); I != E; I++)
920 R.setOperand(I, &DummyValue);
921
922 for (auto [Idx, VPB] : enumerate(CreatedBlocks)) {
923 assert(VPB->getNumber() == Idx && "block with mismatched number");
924 delete VPB;
925 }
926 for (VPValue *VPV : getLiveIns())
927 delete VPV;
928}
929
931 return is_contained(ExitBlocks, VPBB);
932}
933
934/// To make RUN_VPLAN_PASS print final VPlan.
935static void printFinalVPlan(VPlan &) {}
936
937/// Generate the code inside the preheader and body of the vectorized loop.
938/// Assumes a single pre-header basic-block was created for this. Introduce
939/// additional basic-blocks as needed, and fill them all.
942 "all region blocks must be dissolved before ::execute");
943
944 // Initialize CFG state.
945 State->CFG.PrevVPBB = nullptr;
946 State->CFG.ExitBB = State->CFG.PrevBB->getSingleSuccessor();
947
948 // Update VPDominatorTree since VPBasicBlock may be removed after State was
949 // constructed.
950 State->VPDT.recalculate(*this);
951
952 // Disconnect VectorPreHeader from ExitBB in both the CFG and DT.
953 BasicBlock *VectorPreHeader = State->CFG.PrevBB;
954 cast<UncondBrInst>(VectorPreHeader->getTerminator())->setSuccessor(nullptr);
955 State->CFG.DTU.applyUpdates(
956 {{DominatorTree::Delete, VectorPreHeader, State->CFG.ExitBB}});
957
958 LLVM_DEBUG(dbgs() << "Executing best plan with VF=" << State->VF
959 << ", UF=" << getConcreteUF() << '\n');
960 setName("Final VPlan");
961 // TODO: RUN_VPLAN_PASS/VPlanTransforms::runPass should automatically dump
962 // VPlans after some specific stages when "-debug" is specified, but that
963 // hasn't been implemented yet. For now, just do both:
964 LLVM_DEBUG(dump());
966
967 BasicBlock *ScalarPh = State->CFG.ExitBB;
968 VPBasicBlock *ScalarPhVPBB = getScalarPreheader();
969 if (ScalarPhVPBB) {
970 // Disconnect scalar preheader and scalar header, as the dominator tree edge
971 // will be updated as part of VPlan execution. This allows keeping the DTU
972 // logic generic during VPlan execution.
973 State->CFG.DTU.applyUpdates(
974 {{DominatorTree::Delete, ScalarPh, ScalarPh->getSingleSuccessor()}});
975 }
977 Entry);
978 // Generate code for the VPlan, in parts of the vector skeleton, loop body and
979 // successor blocks including the middle, exit and scalar preheader blocks.
980 for (VPBlockBase *Block : RPOT)
981 Block->execute(State);
982
983 if (hasEarlyExit()) {
984 // Fix up LoopInfo for extra dispatch blocks when vectorizing loops with
985 // early exits. For dispatch blocks, we need to find the smallest common
986 // loop of all successors that are in a loop. Note: we only need to update
987 // loop info for blocks after the middle block, but there is no easy way to
988 // get those at this point.
989 for (VPBlockBase *VPB : reverse(RPOT)) {
990 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
991 if (!VPBB || isa<VPIRBasicBlock>(VPBB))
992 continue;
993 BasicBlock *BB = State->CFG.VPBB2IRBB[VPBB];
994 Loop *L = State->LI->getLoopFor(BB);
995 if (!L || any_of(successors(BB),
996 [L](BasicBlock *Succ) { return L->contains(Succ); }))
997 continue;
998 // Find the innermost loop containing all successors that are in a loop.
999 // Successors not in any loop don't constrain the target loop.
1000 Loop *Target = nullptr;
1001 for (BasicBlock *Succ : successors(BB)) {
1002 Loop *SuccLoop = State->LI->getLoopFor(Succ);
1003 if (!SuccLoop)
1004 continue;
1005 if (!Target)
1006 Target = SuccLoop;
1007 else
1008 Target = State->LI->getSmallestCommonLoop(Target, SuccLoop);
1009 }
1010 State->LI->removeBlock(BB);
1011 if (Target)
1012 Target->addBasicBlockToLoop(BB, *State->LI);
1013 }
1014 }
1015
1016 // If the original loop is unreachable, delete it and all its blocks.
1017 if (!ScalarPhVPBB) {
1018 // DeleteDeadBlocks will remove single-entry phis. Remove them from the exit
1019 // VPIRBBs in VPlan as well, otherwise we would retain references to deleted
1020 // IR instructions.
1021 for (VPIRBasicBlock *EB : getExitBlocks()) {
1022 for (VPRecipeBase &R : make_early_inc_range(EB->phis())) {
1023 if (R.getNumOperands() == 1)
1024 R.eraseFromParent();
1025 }
1026 }
1027
1028 Loop *OrigLoop =
1029 State->LI->getLoopFor(getScalarHeader()->getIRBasicBlock());
1030 SmallVector<BasicBlock *> Blocks(OrigLoop->block_begin(),
1031 OrigLoop->block_end());
1032 Blocks.push_back(ScalarPh);
1033 while (!OrigLoop->isInnermost())
1034 State->LI->erase(*OrigLoop->begin());
1035 State->LI->erase(OrigLoop);
1036 for (auto *BB : Blocks)
1037 State->LI->removeBlock(BB);
1038 DeleteDeadBlocks(Blocks, &State->CFG.DTU);
1039 }
1040
1041 State->CFG.DTU.flush();
1042
1043 // Fix the latch (backedge) value of all header phis in all loop headers.
1044 State->fixupHeaderPhis();
1045}
1046
1048 // For now only return the cost of the vector loop region, ignoring any other
1049 // blocks, like the preheader or middle blocks, expect for checking them for
1050 // recipes with invalid costs.
1052
1053 // If the cost of the loop region is invalid or any recipe in the skeleton
1054 // outside loop regions are invalid return an invalid cost.
1057 [&VF, &Ctx](VPBasicBlock *VPBB) {
1058 return !VPBB->cost(VF, Ctx).isValid();
1059 }))
1061
1062 return Cost;
1063}
1064
1066 // Find the vector loop region by following the last successor of each block,
1067 // starting from the plan's entry; the vector code path is always the last
1068 // successor. When vectorizing the epilogue, the path leads through the blocks
1069 // generated for the main vector loop. Each block on the path is entered from
1070 // its first predecessor. Stop at a block entered from another predecessor,
1071 // e.g. a loop header entered via its back-edge in a plain CFG, before regions
1072 // are created or after they have been dissolved.
1073 for (VPBlockBase *B = Entry; B;) {
1074 if (auto *R = dyn_cast<VPRegionBlock>(B))
1075 return R->isReplicator() || R->getNumPredecessors() != 1 ? nullptr : R;
1076 if (!B->hasSuccessors())
1077 return nullptr;
1078 VPBlockBase *Succ = B->getSuccessors().back();
1079 if (Succ->getPredecessors().front() != B)
1080 return nullptr;
1081 B = Succ;
1082 }
1083 return nullptr;
1084}
1085
1087 return const_cast<VPlan *>(this)->getVectorLoopRegion();
1088}
1089
1091 const VPRegionBlock *LoopRegion = getVectorLoopRegion();
1092 assert(LoopRegion && "expected a vector loop region");
1094 vp_depth_first_shallow(LoopRegion->getEntry())),
1095 [](const VPRegionBlock *R) { return !R->isReplicator(); });
1096}
1097
1098#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1101
1102 if (!VF.user_empty()) {
1103 O << "\nLive-in ";
1104 VF.printAsOperand(O, SlotTracker);
1105 O << " = VF";
1106 }
1107
1108 if (!UF.user_empty()) {
1109 O << "\nLive-in ";
1110 UF.printAsOperand(O, SlotTracker);
1111 O << " = UF";
1112 }
1113
1114 if (!VFxUF.user_empty()) {
1115 O << "\nLive-in ";
1116 VFxUF.printAsOperand(O, SlotTracker);
1117 O << " = VF * UF";
1118 }
1119
1120 if (!VectorTripCount.user_empty()) {
1121 O << "\nLive-in ";
1122 VectorTripCount.printAsOperand(O, SlotTracker);
1123 O << " = vector-trip-count";
1124 }
1125
1126 O << "\n";
1127 if (TripCount && !TripCount->user_empty()) {
1128 if (isa<VPIRValue>(TripCount))
1129 O << "Live-in ";
1130 TripCount->printAsOperand(O, SlotTracker);
1131 O << " = original trip-count";
1132 O << "\n";
1133 }
1134}
1135
1139
1140 O << "VPlan '" << getName() << "' {";
1141
1142 printLiveIns(O);
1143
1145 RPOT(getEntry());
1146 for (const VPBlockBase *Block : RPOT) {
1147 O << '\n';
1148 Block->print(O, "", SlotTracker);
1149 }
1150
1151 O << "}\n";
1152}
1153
1154std::string VPlan::getName() const {
1155 std::string Out;
1156 raw_string_ostream RSO(Out);
1157 RSO << Name << " for ";
1158 if (!VFs.empty()) {
1159 RSO << "VF={" << VFs[0];
1160 for (ElementCount VF : drop_begin(VFs))
1161 RSO << "," << VF;
1162 RSO << "},";
1163 }
1164
1165 if (UFs.empty()) {
1166 RSO << "UF>=1";
1167 } else {
1168 RSO << "UF={" << UFs[0];
1169 for (unsigned UF : drop_begin(UFs))
1170 RSO << "," << UF;
1171 RSO << "}";
1172 }
1173
1174 return Out;
1175}
1176
1179 VPlanPrinter Printer(O, *this);
1180 Printer.dump();
1181}
1182
1184void VPlan::dump() const { print(dbgs()); }
1185#endif
1186
1187static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry,
1188 DenseMap<VPValue *, VPValue *> &Old2NewVPValues) {
1189 // Update the operands of all cloned recipes starting at NewEntry. This
1190 // traverses all reachable blocks. This is done in two steps, to handle cycles
1191 // in PHI recipes.
1193 OldDeepRPOT(Entry);
1195 NewDeepRPOT(NewEntry);
1196 // First, collect all mappings from old to new VPValues defined by cloned
1197 // recipes.
1198 for (const auto &[OldBB, NewBB] :
1201 assert(OldBB->getRecipeList().size() == NewBB->getRecipeList().size() &&
1202 "blocks must have the same number of recipes");
1203 for (const auto &[OldR, NewR] : zip(*OldBB, *NewBB)) {
1204 assert(OldR.getNumOperands() == NewR.getNumOperands() &&
1205 "recipes must have the same number of operands");
1206 assert(OldR.getNumDefinedValues() == NewR.getNumDefinedValues() &&
1207 "recipes must define the same number of operands");
1208 for (const auto &[OldV, NewV] :
1209 zip(OldR.definedValues(), NewR.definedValues()))
1210 Old2NewVPValues[OldV] = NewV;
1211 }
1212 }
1213
1214 // Update all operands to use cloned VPValues.
1215 for (VPBasicBlock *NewBB :
1217 for (VPRecipeBase &NewR : *NewBB)
1218 for (unsigned I = 0, E = NewR.getNumOperands(); I != E; ++I) {
1219 VPValue *NewOp = Old2NewVPValues.lookup(NewR.getOperand(I));
1220 NewR.setOperand(I, NewOp);
1221 }
1222 }
1223}
1224
1226 unsigned NumBlocksBeforeCloning = CreatedBlocks.size();
1227 // Clone blocks.
1228 const auto &[NewEntry, __] = VPBlockUtils::cloneFrom(Entry);
1229
1230 BasicBlock *ScalarHeaderIRBB = getScalarHeader()->getIRBasicBlock();
1231 VPIRBasicBlock *NewScalarHeader = nullptr;
1232 if (getScalarHeader()->hasPredecessors()) {
1233 NewScalarHeader = cast<VPIRBasicBlock>(*find_if(
1234 vp_depth_first_shallow(NewEntry), [ScalarHeaderIRBB](VPBlockBase *VPB) {
1235 auto *VPIRBB = dyn_cast<VPIRBasicBlock>(VPB);
1236 return VPIRBB && VPIRBB->getIRBasicBlock() == ScalarHeaderIRBB;
1237 }));
1238 } else {
1239 NewScalarHeader = createVPIRBasicBlock(ScalarHeaderIRBB);
1240 }
1241 // Create VPlan, clone live-ins and remap operands in the cloned blocks.
1242 auto *NewPlan =
1243 new VPlan(cast<VPBasicBlock>(NewEntry), NewScalarHeader, getIndexType());
1244 DenseMap<VPValue *, VPValue *> Old2NewVPValues;
1245 for (VPIRValue *OldLiveIn : getLiveIns())
1246 Old2NewVPValues[OldLiveIn] = NewPlan->getOrAddLiveIn(OldLiveIn);
1247
1248 if (auto *TripCountIRV = dyn_cast_or_null<VPIRValue>(TripCount))
1249 Old2NewVPValues[TripCountIRV] = NewPlan->getOrAddLiveIn(TripCountIRV);
1250 // else NewTripCount will be created and inserted into Old2NewVPValues when
1251 // TripCount is cloned. In any case NewPlan->TripCount is updated below.
1252
1253 assert(none_of(Old2NewVPValues.keys(), IsaPred<VPSymbolicValue>) &&
1254 "All VPSymbolicValues must be handled below");
1255
1256 if (auto *LoopRegion = getVectorLoopRegion()) {
1257 auto *NewLoopRegion = NewPlan->getVectorLoopRegion();
1258 for (auto [Old, New] : zip_equal(LoopRegion->getRegionValues(),
1259 NewLoopRegion->getRegionValues())) {
1260 Old2NewVPValues[Old] = New;
1261 if (Old->isMaterialized())
1262 New->markMaterialized();
1263 }
1264 }
1265
1266 // Map and propagate materialized state for symbolic values.
1267 for (auto [OldSV, NewSV] :
1268 {std::pair{&VectorTripCount, &NewPlan->VectorTripCount},
1269 {&VF, &NewPlan->VF},
1270 {&UF, &NewPlan->UF},
1271 {&VFxUF, &NewPlan->VFxUF}}) {
1272 Old2NewVPValues[OldSV] = NewSV;
1273 if (OldSV->isMaterialized())
1274 NewSV->markMaterialized();
1275 }
1276
1277 remapOperands(Entry, NewEntry, Old2NewVPValues);
1278
1279 // Initialize remaining fields of cloned VPlan.
1280 NewPlan->VFs = VFs;
1281 NewPlan->UFs = UFs;
1282 // TODO: Adjust names.
1283 NewPlan->Name = Name;
1284 if (TripCount) {
1285 assert(Old2NewVPValues.contains(TripCount) &&
1286 "TripCount must have been added to Old2NewVPValues");
1287 NewPlan->TripCount = Old2NewVPValues[TripCount];
1288 }
1289
1290 // Transfer all cloned blocks (the second half of all current blocks) from
1291 // current to new VPlan.
1292 unsigned NumBlocksAfterCloning = CreatedBlocks.size();
1293 for (unsigned I :
1294 seq<unsigned>(NumBlocksBeforeCloning, NumBlocksAfterCloning)) {
1295 this->CreatedBlocks[I]->setPlan(NewPlan);
1296 this->CreatedBlocks[I]->setNumber(NewPlan->CreatedBlocks.size());
1297 NewPlan->CreatedBlocks.push_back(this->CreatedBlocks[I]);
1298 }
1299 CreatedBlocks.truncate(NumBlocksBeforeCloning);
1300
1301 // Update ExitBlocks of the new plan.
1302 for (VPBlockBase *VPB : NewPlan->CreatedBlocks) {
1303 if (VPB->getNumSuccessors() == 0 && isa<VPIRBasicBlock>(VPB) &&
1304 VPB != NewScalarHeader)
1305 NewPlan->ExitBlocks.push_back(cast<VPIRBasicBlock>(VPB));
1306 }
1307
1308 return NewPlan;
1309}
1310
1312 auto *VPIRBB = new VPIRBasicBlock(IRBB);
1313 VPIRBB->setPlan(this);
1314 VPIRBB->setNumber(CreatedBlocks.size());
1315 CreatedBlocks.push_back(VPIRBB);
1316 return VPIRBB;
1317}
1318
1320 auto *VPIRBB = createEmptyVPIRBasicBlock(IRBB);
1321 for (Instruction &I :
1322 make_range(IRBB->begin(), IRBB->getTerminator()->getIterator()))
1323 VPIRBB->appendRecipe(VPIRInstruction::create(I));
1324 return VPIRBB;
1325}
1326
1327#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1328
1329Twine VPlanPrinter::getUID(const VPBlockBase *Block) {
1330 return (isa<VPRegionBlock>(Block) ? "cluster_N" : "N") +
1331 Twine(getOrCreateBID(Block));
1332}
1333
1335 Depth = 1;
1336 bumpIndent(0);
1337 OS << "digraph VPlan {\n";
1338 OS << "graph [labelloc=t, fontsize=30; label=\"Vectorization Plan";
1339 if (!Plan.getName().empty())
1340 OS << "\\n" << DOT::EscapeString(Plan.getName());
1341
1342 {
1343 // Print live-ins.
1344 std::string Str;
1345 raw_string_ostream SS(Str);
1346 Plan.printLiveIns(SS);
1348 StringRef(Str).rtrim('\n').split(Lines, "\n");
1349 for (auto Line : Lines)
1350 OS << DOT::EscapeString(Line.str()) << "\\n";
1351 }
1352
1353 OS << "\"]\n";
1354 OS << "node [shape=rect, fontname=Courier, fontsize=30]\n";
1355 OS << "edge [fontname=Courier, fontsize=30]\n";
1356 OS << "compound=true\n";
1357
1358 for (const VPBlockBase *Block : vp_depth_first_shallow(Plan.getEntry()))
1359 dumpBlock(Block);
1360
1361 OS << "}\n";
1362}
1363
1364void VPlanPrinter::dumpBlock(const VPBlockBase *Block) {
1366 dumpBasicBlock(BasicBlock);
1368 dumpRegion(Region);
1369 else
1370 llvm_unreachable("Unsupported kind of VPBlock.");
1371}
1372
1373void VPlanPrinter::drawEdge(const VPBlockBase *From, const VPBlockBase *To,
1374 bool Hidden, const Twine &Label) {
1375 // Due to "dot" we print an edge between two regions as an edge between the
1376 // exiting basic block and the entry basic of the respective regions.
1377 const VPBlockBase *Tail = From->getExitingBasicBlock();
1378 const VPBlockBase *Head = To->getEntryBasicBlock();
1379 OS << Indent << getUID(Tail) << " -> " << getUID(Head);
1380 OS << " [ label=\"" << Label << '\"';
1381 if (Tail != From)
1382 OS << " ltail=" << getUID(From);
1383 if (Head != To)
1384 OS << " lhead=" << getUID(To);
1385 if (Hidden)
1386 OS << "; splines=none";
1387 OS << "]\n";
1388}
1389
1390void VPlanPrinter::dumpEdges(const VPBlockBase *Block) {
1391 auto &Successors = Block->getSuccessors();
1392 if (Successors.size() == 1)
1393 drawEdge(Block, Successors.front(), false, "");
1394 else if (Successors.size() == 2) {
1395 drawEdge(Block, Successors.front(), false, "T");
1396 drawEdge(Block, Successors.back(), false, "F");
1397 } else {
1398 unsigned SuccessorNumber = 0;
1399 for (auto *Successor : Successors)
1400 drawEdge(Block, Successor, false, Twine(SuccessorNumber++));
1401 }
1402}
1403
1404void VPlanPrinter::dumpBasicBlock(const VPBasicBlock *BasicBlock) {
1405 // Implement dot-formatted dump by performing plain-text dump into the
1406 // temporary storage followed by some post-processing.
1407 OS << Indent << getUID(BasicBlock) << " [label =\n";
1408 bumpIndent(1);
1409 std::string Str;
1410 raw_string_ostream SS(Str);
1411 // Use no indentation as we need to wrap the lines into quotes ourselves.
1412 BasicBlock->print(SS, "", SlotTracker);
1413
1414 // We need to process each line of the output separately, so split
1415 // single-string plain-text dump.
1417 StringRef(Str).rtrim('\n').split(Lines, "\n");
1418
1419 auto EmitLine = [&](StringRef Line, StringRef Suffix) {
1420 OS << Indent << '"' << DOT::EscapeString(Line.str()) << "\\l\"" << Suffix;
1421 };
1422
1423 // Don't need the "+" after the last line.
1424 for (auto Line : make_range(Lines.begin(), Lines.end() - 1))
1425 EmitLine(Line, " +\n");
1426 EmitLine(Lines.back(), "\n");
1427
1428 bumpIndent(-1);
1429 OS << Indent << "]\n";
1430
1431 dumpEdges(BasicBlock);
1432}
1433
1434void VPlanPrinter::dumpRegion(const VPRegionBlock *Region) {
1435 OS << Indent << "subgraph " << getUID(Region) << " {\n";
1436 bumpIndent(1);
1437 OS << Indent << "fontname=Courier\n"
1438 << Indent << "label=\""
1439 << DOT::EscapeString(Region->isReplicator() ? "<xVFxUF> " : "<x1> ")
1440 << DOT::EscapeString(Region->getName()) << "\"\n";
1441
1442 if (auto *CanIV = Region->getCanonicalIV()) {
1443 OS << Indent << "\"";
1444 std::string Op;
1445 raw_string_ostream S(Op);
1446 CanIV->printAsOperand(S, SlotTracker);
1447 OS << DOT::EscapeString(Op);
1448 OS << " = CANONICAL-IV\"\n";
1449 }
1450
1451 // Dump the blocks of the region.
1452 assert(Region->getEntry() && "Region contains no inner blocks.");
1453 for (const VPBlockBase *Block : vp_depth_first_shallow(Region->getEntry()))
1454 dumpBlock(Block);
1455 bumpIndent(-1);
1456 OS << Indent << "}\n";
1457 dumpEdges(Region);
1458}
1459
1460#endif
1461
1462/// Returns true if there is a vector loop region and \p VPV is defined in a
1463/// loop region.
1464static bool isDefinedInsideLoopRegions(const VPValue *VPV) {
1465 if (isa<VPRegionValue>(VPV))
1466 return true;
1467 const VPRecipeBase *DefR = VPV->getDefiningRecipe();
1468 return DefR && (DefR->getParent()->getEnclosingLoopRegion() ||
1469 !DefR->getParent()->getPlan()->getVectorLoopRegion());
1470}
1471
1476 replaceUsesWithIf(New, [](VPUser *) { return true; });
1477 if (auto *SV = dyn_cast<VPSymbolicValue>(this))
1478 SV->markMaterialized();
1479}
1480
1482 VPValue *New, llvm::function_ref<bool(VPUser *U)> ShouldReplace) {
1484 // Note that this early exit is required for correctness; the implementation
1485 // below relies on the number of users for this VPValue to decrease, which
1486 // isn't the case if this == New.
1487 if (this == New)
1488 return;
1489
1490 for (unsigned J = 0; J < getNumUsers();) {
1491 VPUser *User = Users[J];
1492 bool RemovedUser = false;
1493 for (unsigned I = 0, E = User->getNumOperands(); I < E; ++I) {
1494 if (User->getOperand(I) != this || !ShouldReplace(User))
1495 continue;
1496
1497 RemovedUser = true;
1498 User->setOperand(I, New);
1499 }
1500 // If a user got removed after updating the current user, the next user to
1501 // update will be moved to the current position, so we only need to
1502 // increment the index if the number of users did not change.
1503 if (!RemovedUser)
1504 J++;
1505 }
1506}
1507
1509 for (unsigned Idx = 0; Idx != getNumOperands(); ++Idx) {
1510 if (getOperand(Idx) == From)
1511 setOperand(Idx, To);
1512 }
1513}
1514
1515#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1517 OS << Tracker.getOrCreateName(this);
1518}
1519
1522 Op->printAsOperand(O, SlotTracker);
1523 });
1524}
1525#endif
1526
1527void VPSlotTracker::assignName(const VPValue *V) {
1528 assert(!VPValue2Name.contains(V) && "VPValue already has a name!");
1529 auto *UV = V->getUnderlyingValue();
1530 auto *VPI = dyn_cast_or_null<VPInstruction>(V);
1531 if (!UV && !(VPI && !VPI->getName().empty())) {
1532 VPValue2Name[V] = (Twine("vp<%") + Twine(NextSlot) + ">").str();
1533 NextSlot++;
1534 return;
1535 }
1536
1537 // Use the name of the underlying Value, wrapped in "ir<>", and versioned by
1538 // appending ".Number" to the name if there are multiple uses.
1539 std::string Name;
1540 if (UV)
1541 Name = getName(UV);
1542 else
1543 Name = VPI->getName();
1544
1545 assert(!Name.empty() && "Name cannot be empty.");
1546 StringRef Prefix = UV ? "ir<" : "vp<%";
1547 std::string BaseName = (Twine(Prefix) + Name + Twine(">")).str();
1548
1549 // First assign the base name for V.
1550 const auto &[A, _] = VPValue2Name.try_emplace(V, BaseName);
1551 // Integer or FP constants with different types will result in the same string
1552 // due to stripping types.
1554 return;
1555
1556 // If it is already used by C > 0 other VPValues, increase the version counter
1557 // C and use it for V.
1558 const auto &[C, UseInserted] = BaseName2Version.try_emplace(BaseName, 0);
1559 if (!UseInserted) {
1560 C->second++;
1561 A->second = (BaseName + Twine(".") + Twine(C->second)).str();
1562 }
1563}
1564
1565void VPSlotTracker::assignNames(const VPlan &Plan) {
1566 if (!Plan.VF.user_empty())
1567 assignName(&Plan.VF);
1568 if (!Plan.UF.user_empty())
1569 assignName(&Plan.UF);
1570 if (!Plan.VFxUF.user_empty())
1571 assignName(&Plan.VFxUF);
1572 assignName(&Plan.VectorTripCount);
1573 for (VPValue *LI : Plan.getLiveIns())
1574 assignName(LI);
1575
1576 ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<const VPBlockBase *>>
1577 RPOT(VPBlockDeepTraversalWrapper<const VPBlockBase *>(Plan.getEntry()));
1578 for (const VPBlockBase *VPB : RPOT) {
1579 if (auto *VPBB = dyn_cast<VPBasicBlock>(VPB))
1580 assignNames(VPBB);
1581 else
1582 for (auto *RV : cast<VPRegionBlock>(VPB)->getRegionValues())
1583 assignName(RV);
1584 }
1585}
1586
1587void VPSlotTracker::assignNames(const VPBasicBlock *VPBB) {
1588 for (const VPRecipeBase &Recipe : *VPBB)
1589 for (VPValue *Def : Recipe.definedValues())
1590 assignName(Def);
1591}
1592
1593ModuleSlotTracker &VPSlotTracker::getOrCreateMST() {
1594 // F is null for unit tests with incomplete IR.
1595 if (!MST) {
1596 MST = std::make_unique<ModuleSlotTracker>(getModule());
1597 if (F)
1598 MST->incorporateFunction(*F);
1599 }
1600 return *MST;
1601}
1602
1603std::string VPSlotTracker::getName(const Value *V) {
1604 std::string Name;
1605 raw_string_ostream S(Name);
1606 // If V isn't an instruction in a basic block or named, it can be printed
1607 // directly without ModuleSlotTracker.
1608 auto *I = dyn_cast<Instruction>(V);
1609 if (!I || I->hasName() || !I->getParent()) {
1610 V->printAsOperand(S, false);
1611 return Name;
1612 }
1613
1614 V->printAsOperand(S, false, getOrCreateMST());
1615 return Name;
1616}
1617
1619 N->printAsOperand(O, getOrCreateMST(), getModule());
1620}
1621
1622std::string VPSlotTracker::getOrCreateName(const VPValue *V) const {
1623 std::string Name = VPValue2Name.lookup(V);
1624 if (!Name.empty())
1625 return Name;
1626
1627 // If no name was assigned, no VPlan was provided when creating the slot
1628 // tracker or it is not reachable from the provided VPlan. This can happen,
1629 // e.g. when trying to print a recipe that has not been inserted into a VPlan
1630 // in a debugger.
1631 // TODO: Update VPSlotTracker constructor to assign names to recipes &
1632 // VPValues not associated with a VPlan, instead of constructing names ad-hoc
1633 // here.
1634
1635 // Use the underlying value's name, if there is one.
1636 if (auto *UV = V->getUnderlyingValue()) {
1637 std::string Name;
1638 raw_string_ostream S(Name);
1639 UV->printAsOperand(S, false);
1640 return (Twine("ir<") + Name + ">").str();
1641 }
1642
1643 return "<badref>";
1644}
1645
1647 const std::function<bool(ElementCount)> &Predicate, VFRange &Range) {
1648 assert(!Range.isEmpty() && "Trying to test an empty VF range.");
1649 bool PredicateAtRangeStart = Predicate(Range.Start);
1650
1651 for (ElementCount TmpVF : VFRange(Range.Start * 2, Range.End))
1652 if (Predicate(TmpVF) != PredicateAtRangeStart) {
1653 Range.End = TmpVF;
1654 break;
1655 }
1656
1657 return PredicateAtRangeStart;
1658}
1659
1661 assert(count_if(VPlans,
1662 [VF](const VPlanPtr &Plan) { return Plan->hasVF(VF); }) ==
1663 1 &&
1664 "Multiple VPlans for VF.");
1665
1666 for (const VPlanPtr &Plan : VPlans) {
1667 if (Plan->hasVF(VF))
1668 return *Plan.get();
1669 }
1670 llvm_unreachable("No plan found!");
1671}
1672
1675 // Reserve first location for self reference to the LoopID metadata node.
1676 MDs.push_back(nullptr);
1677 bool IsUnrollMetadata = false;
1678 MDNode *LoopID = L->getLoopID();
1679 if (LoopID) {
1680 // First find existing loop unrolling disable metadata.
1681 for (unsigned I = 1, IE = LoopID->getNumOperands(); I < IE; ++I) {
1682 auto *MD = dyn_cast<MDNode>(LoopID->getOperand(I));
1683 if (MD) {
1684 const auto *S = dyn_cast<MDString>(MD->getOperand(0));
1685 if (!S)
1686 continue;
1687 if (S->getString().starts_with("llvm.loop.unroll.runtime.disable"))
1688 continue;
1689 IsUnrollMetadata =
1690 S->getString().starts_with("llvm.loop.unroll.disable");
1691 }
1692 MDs.push_back(LoopID->getOperand(I));
1693 }
1694 }
1695
1696 if (!IsUnrollMetadata) {
1697 // Add runtime unroll disable metadata.
1698 LLVMContext &Context = L->getHeader()->getContext();
1699 SmallVector<Metadata *, 1> DisableOperands;
1700 DisableOperands.push_back(
1701 MDString::get(Context, "llvm.loop.unroll.runtime.disable"));
1702 MDNode *DisableNode = MDNode::get(Context, DisableOperands);
1703 MDs.push_back(DisableNode);
1704 MDNode *NewLoopID = MDNode::get(Context, MDs);
1705 // Set operand 0 to refer to the loop id itself.
1706 NewLoopID->replaceOperandWith(0, NewLoopID);
1707 L->setLoopID(NewLoopID);
1708 }
1709}
1710
1712 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
1713 bool VectorizingEpilogue, MDNode *OrigLoopID,
1714 std::optional<unsigned> OrigAverageTripCount,
1715 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1716 bool DisableRuntimeUnroll, bool UnrollVectorizedLoop) {
1717 // Update the metadata of the scalar loop. Skip the update when vectorizing
1718 // the epilogue loop to ensure it is updated only once. Also skip the update
1719 // when the scalar loop became unreachable.
1720 auto *ScalarPH = Plan.getScalarPreheader();
1721 if (ScalarPH && !VectorizingEpilogue) {
1722 std::optional<MDNode *> RemainderLoopID =
1725 if (RemainderLoopID) {
1726 OrigLoop->setLoopID(*RemainderLoopID);
1727 } else {
1728 if (DisableRuntimeUnroll)
1730
1731 LoopVectorizeHints Hints(Opts, OrigLoop,
1732 /*InterleaveOnlyWhenForced*/ false, *ORE);
1733 Hints.setAlreadyVectorized();
1734 }
1735 }
1736 // Tag the scalar remainder so downstream passes (e.g. the unroller and
1737 // WarnMissedTransforms) can produce more informative remarks. Only emit
1738 // when remarks are enabled.
1739 if (ORE->enabled() && ScalarPH && ScalarPH->hasPredecessors())
1740 OrigLoop->addIntLoopAttribute("llvm.loop.vectorize.epilogue", 1);
1741
1742 if (!VectorLoop)
1743 return;
1744
1745 if (std::optional<MDNode *> VectorizedLoopID = makeFollowupLoopID(
1746 OrigLoopID, {LLVMLoopVectorizeFollowupAll,
1748 VectorLoop->setLoopID(*VectorizedLoopID);
1749 } else {
1750 // Keep all loop hints from the original loop on the vector loop (we'll
1751 // replace the vectorizer-specific hints below).
1752 if (OrigLoopID)
1753 VectorLoop->setLoopID(OrigLoopID);
1754
1755 if (!VectorizingEpilogue) {
1756 LoopVectorizeHints Hints(Opts, VectorLoop,
1757 /*InterleaveOnlyWhenForced*/ false, *ORE);
1758 Hints.setAlreadyVectorized();
1759 }
1760 }
1761 // Tag the vector loop body so downstream passes can identify it. Only
1762 // emit when remarks are enabled.
1763 if (ORE->enabled())
1764 VectorLoop->addIntLoopAttribute("llvm.loop.vectorize.body", 1);
1765 if (!UnrollVectorizedLoop || VectorizingEpilogue)
1767
1768 // Set/update profile weights for the vector and remainder loops as original
1769 // loop iterations are now distributed among them. Note that original loop
1770 // becomes the scalar remainder loop after vectorization.
1771 //
1772 // For cases like foldTailByMasking() and requiresScalarEpiloque() we may
1773 // end up getting slightly roughened result but that should be OK since
1774 // profile is not inherently precise anyway. Note also possible bypass of
1775 // vector code caused by legality checks is ignored, assigning all the weight
1776 // to the vector loop, optimistically.
1777 //
1778 // For scalable vectorization we can't know at compile time how many
1779 // iterations of the loop are handled in one vector iteration, so instead
1780 // use the value of vscale used for tuning.
1781 unsigned AverageVectorTripCount = 0;
1782 unsigned RemainderAverageTripCount = 0;
1783 auto EC = VectorLoop->getLoopPreheader()->getParent()->getEntryCount();
1784 auto IsProfiled = EC && *EC != 0;
1785 if (!OrigAverageTripCount) {
1786 if (!IsProfiled)
1787 return;
1788 auto &SE = *PSE.getSE();
1789 AverageVectorTripCount = SE.getSmallConstantTripCount(VectorLoop);
1790 if (ProfcheckDisableMetadataFixes || !AverageVectorTripCount)
1791 return;
1792 if (ScalarPH)
1793 RemainderAverageTripCount =
1794 SE.getSmallConstantTripCount(OrigLoop) % EstimatedVFxUF;
1795 // Setting to 1 should be sufficient to generate the correct branch weights.
1796 OrigLoopInvocationWeight = 1;
1797 } else {
1798 // Calculate number of iterations in unrolled loop.
1799 AverageVectorTripCount = *OrigAverageTripCount / EstimatedVFxUF;
1800 // Calculate number of iterations for remainder loop.
1801 RemainderAverageTripCount = *OrigAverageTripCount % EstimatedVFxUF;
1802 }
1803 if (HeaderVPBB) {
1804 setLoopEstimatedTripCount(VectorLoop, AverageVectorTripCount,
1805 OrigLoopInvocationWeight);
1806 }
1807
1808 if (ScalarPH) {
1809 setLoopEstimatedTripCount(OrigLoop, RemainderAverageTripCount,
1810 OrigLoopInvocationWeight);
1811 }
1812}
1813
1814#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1816 if (VPlans.empty()) {
1817 O << "LV: No VPlans built.\n";
1818 return;
1819 }
1820 for (const auto &Plan : VPlans)
1821 if (Opts.vplan_print_in_dot_format)
1822 Plan->printDOT(O);
1823 else
1824 Plan->print(O);
1825}
1826#endif
1827
1828bool llvm::canConstantBeExtended(const APInt *C, Type *NarrowType,
1830 APInt TruncatedVal = C->trunc(NarrowType->getScalarSizeInBits());
1831 unsigned WideSize = C->getBitWidth();
1832 APInt ExtendedVal = ExtKind == TTI::PR_SignExtend
1833 ? TruncatedVal.sext(WideSize)
1834 : TruncatedVal.zext(WideSize);
1835 return ExtendedVal == *C;
1836}
1837
1840 if (auto *IRV = dyn_cast<VPIRValue>(V))
1841 return TTI::getOperandInfo(IRV->getValue());
1842
1843 return {};
1844}
1845
1846#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1848 if (!PlanForSlotTracker)
1849 return nullptr;
1850 if (!SlotTracker)
1851 SlotTracker = std::make_unique<VPSlotTracker>(PlanForSlotTracker);
1852 return SlotTracker.get();
1853}
1854#endif
1855
1858 TTI::VectorInstrContext VIC, bool AlwaysIncludeReplicatingR) {
1859 if (VF.isScalar())
1860 return 0;
1861
1862 assert(!VF.isScalable() &&
1863 "Scalarization overhead not supported for scalable vectors");
1864
1865 InstructionCost ScalarizationCost = 0;
1866 // Compute the cost of scalarizing the result if needed.
1867 if (!ResultTy->isVoidTy()) {
1868 for (Type *VectorTy :
1869 to_vector(getContainedTypes(toVectorizedTy(ResultTy, VF)))) {
1870 ScalarizationCost += TTI.getScalarizationOverhead(
1872 /*Insert=*/true, /*Extract=*/false, CostKind,
1873 /*ForPoisonSrc=*/true, {}, VIC);
1874 }
1875 }
1876 // Compute the cost of scalarizing the operands, skipping ones that do not
1877 // require extraction/scalarization and do not incur any overhead.
1878 SmallPtrSet<const VPValue *, 4> UniqueOperands;
1880 for (auto *Op : Operands) {
1881 if (isa<VPIRValue>(Op) ||
1882 (!AlwaysIncludeReplicatingR &&
1885 cast<VPReplicateRecipe>(Op)->getOpcode() == Instruction::Load) ||
1886 !UniqueOperands.insert(Op).second)
1887 continue;
1888 Tys.push_back(toVectorizedTy(Op->getScalarType(), VF));
1889 }
1890 return ScalarizationCost +
1891 TTI.getOperandsScalarizationOverhead(Tys, CostKind, VIC);
1892}
1893
1895 ElementCount VF) {
1896 const Instruction *UI = R->getUnderlyingInstr();
1897 if (isa<LoadInst>(UI))
1898 return true;
1899 assert(isa<StoreInst>(UI) && "R must either be a load or store");
1900
1901 if (!NumPredStores) {
1902 // Count the number of predicated stores in the VPlan, caching the result.
1903 // Only stores where scatter is not legal are counted, matching the legacy
1904 // cost model behavior.
1905 const VPlan &Plan = *R->getParent()->getPlan();
1906 NumPredStores = 0;
1907 for (const VPRegionBlock *VPRB :
1910 assert(VPRB->isReplicator() && "must only contain replicate regions");
1911 for (const VPBasicBlock *VPBB :
1913 vp_depth_first_shallow(VPRB->getEntry()))) {
1914 for (const VPReplicateRecipe &RepR :
1916 if (!isa<StoreInst>(RepR.getUnderlyingInstr()))
1917 continue;
1918 // Check if scatter is legal for this store. If so, don't count it.
1919 Type *Ty = RepR.getOperand(0)->getScalarType();
1920 auto *VTy = VectorType::get(Ty, VF);
1921 const Align Alignment =
1922 getLoadStoreAlignment(RepR.getUnderlyingInstr());
1923 if (!TTI.isLegalMaskedScatter(VTy, Alignment))
1924 ++(*NumPredStores);
1925 }
1926 }
1927 }
1928 }
1929 return *NumPredStores > Opts.vectorize_num_stores_pred;
1930}
1931
1933 return is_contained({Intrinsic::assume, Intrinsic::lifetime_end,
1934 Intrinsic::lifetime_start, Intrinsic::sideeffect,
1935 Intrinsic::pseudoprobe,
1936 Intrinsic::experimental_noalias_scope_decl},
1937 ID);
1938}
1939
1940uint64_t
1941VPCostContext::getCostDivisor(std::optional<VPExecutionFrequency> Freq) const {
1942 if (CostKind == TTI::TCK_CodeSize || !Freq)
1943 return 1;
1944 // A recorded frequency is neither zero nor always-executing, so the
1945 // probability is non-zero and the division below is safe.
1946 return divideNearest(
1948 vputils::getExecutionProbability(Freq->Freq).getNumerator());
1949}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu next use AMDGPU Next Use Analysis Printer
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:690
Flatten the CFG
#define _
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This file defines the LoopVectorizationLegality class.
This file provides a LoopVectorizationPlanner class.
#define I(x, y, z)
Definition MD5.cpp:57
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define P(N)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static StringRef getName(Value *V)
SI Fold Operands
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
This file contains the declarations of different VPlan-related auxiliary helpers.
This file provides utility VPlan to VPlan transformations.
#define RUN_VPLAN_PASS(PASS,...)
static void addRuntimeUnrollDisableMetaData(Loop *L)
Definition VPlan.cpp:1673
static void printFinalVPlan(VPlan &)
To make RUN_VPLAN_PASS print final VPlan.
Definition VPlan.cpp:935
static T * getEnclosingLoopRegionForRegion(T *P)
Return the enclosing loop region for region P.
Definition VPlan.cpp:551
const char LLVMLoopVectorizeFollowupAll[]
Definition VPlan.cpp:63
static bool isDefinedInsideLoopRegions(const VPValue *VPV)
Returns true if there is a vector loop region and VPV is defined in a loop region.
Definition VPlan.cpp:1464
static bool hasConditionalTerminator(const VPBasicBlock *VPBB)
Definition VPlan.cpp:569
const char LLVMLoopVectorizeFollowupVectorized[]
Definition VPlan.cpp:64
static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry, DenseMap< VPValue *, VPValue * > &Old2NewVPValues)
Definition VPlan.cpp:1187
const char LLVMLoopVectorizeFollowupEpilogue[]
Definition VPlan.cpp:66
This file contains the declarations of the Vectorization Plan base classes:
static bool IsCondBranch(unsigned BrOpc)
Class for arbitrary precision integers.
Definition APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition APInt.h:230
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1057
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
Definition APInt.cpp:1030
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:440
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
size_t size() const
Definition BasicBlock.h:461
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
LLVM_ABI void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Update PHI nodes in this BasicBlock before removal of predecessor Pred.
static uint32_t getDenominator()
std::optional< const DILocation * > cloneByMultiplyingDuplicationFactor(unsigned DF) const
Returns a new DILocation with duplication factor DF * current duplication factor encoded in the discr...
A debug info location.
Definition DebugLoc.h:126
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:757
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:793
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
constexpr bool isVector() const
One or more elements.
Definition TypeSize.h:321
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:317
std::optional< uint64_t > getEntryCount() const
Get the entry count for this function.
Common base class shared among various IRBuilders.
Definition IRBuilder.h:111
static InstructionCost getInvalid(CostType Val=0)
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
A helper class to return the specified delimiter string after the first invocation of operator String...
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
block_iterator block_end() const
void addChildLoop(LoopT *NewChild)
Add the specified loop to be a child of this loop.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
iterator begin() const
block_iterator block_begin() const
VPlan & getPlanFor(ElementCount VF) const
Return the VPlan for VF.
Definition VPlan.cpp:1660
void updateLoopMetadataAndProfileInfo(Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan, bool VectorizingEpilogue, MDNode *OrigLoopID, std::optional< unsigned > OrigAverageTripCount, unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF, bool DisableRuntimeUnroll, bool UnrollVectorizedLoop)
Update loop metadata and profile info for both the scalar remainder loop and VectorLoop,...
Definition VPlan.cpp:1711
static bool getDecisionAndClampRange(const std::function< bool(ElementCount)> &Predicate, VFRange &Range)
Test a Predicate on a Range of VF's.
Definition VPlan.cpp:1646
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1815
Utility class for getting and setting loop vectorizer hints in the form of loop metadata.
LLVM_ABI void setAlreadyVectorized()
Mark the loop L as already vectorized by setting the width to 1.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
void addIntLoopAttribute(StringRef Name, unsigned Value, ArrayRef< StringRef > RemovePrefixes={}) const
Add an integer metadata attribute to this loop's loop-ID node.
Definition LoopInfo.cpp:614
void setLoopID(MDNode *LoopID) const
Set the llvm.loop loop id metadata for this loop.
Definition LoopInfo.cpp:582
Metadata node.
Definition Metadata.h:1081
LLVM_ABI void replaceOperandWith(unsigned I, Metadata *New)
Replace a specific operand.
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1437
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1443
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition Metadata.cpp:597
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
Manage lifetime of a slot tracker for printing IR.
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
Definition RegionInfo.h:323
This class provides computation of slot numbers for LLVM Assembly writing.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
Definition StringMap.h:370
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition StringRef.h:838
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
static LLVM_ABI OperandValueInfo getOperandInfo(const Value *V)
Collect properties of V used in cost analysis, e.g. OP_PowerOf2.
@ TCK_CodeSize
Instruction code size.
llvm::VectorInstrContext VectorInstrContext
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
This function has undefined behavior.
void setOperand(unsigned i, Value *Val)
Definition User.h:212
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4494
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition VPlan.h:4575
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4525
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
Definition VPlan.cpp:473
iterator end()
Definition VPlan.h:4535
iterator begin()
Recipe iterator methods.
Definition VPlan.h:4533
VPBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Definition VPlan.cpp:507
InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override
Return the cost of this VPBasicBlock.
Definition VPlan.cpp:737
const VPBasicBlock * getCFGPredecessor(unsigned Idx) const
Returns the predecessor block at index Idx with the predecessors as per the corresponding plain CFG.
Definition VPlan.cpp:755
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:228
void connectToPredecessors(VPTransformState &State)
Connect the VPBBs predecessors' in the VPlan CFG to the IR basic block generated for this VPBB.
Definition VPlan.cpp:364
VPRegionBlock * getEnclosingLoopRegion()
Definition VPlan.cpp:561
VPBasicBlock * splitAt(iterator SplitAt)
Split current block at SplitAt by inserting a new block between the current block and its successors ...
Definition VPlan.cpp:528
RecipeListTy Recipes
The VPRecipes held in the order of output instructions to generate.
Definition VPlan.h:4509
void executeRecipes(VPTransformState *State, BasicBlock *BB)
Execute the recipes in the IR basic block BB.
Definition VPlan.cpp:514
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print this VPBsicBlock to O, prefixing all lines with Indent.
Definition VPlan.cpp:641
bool isExiting() const
Returns true if the block is exiting it's parent region.
Definition VPlan.cpp:619
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:607
const VPRecipeBase & back() const
Definition VPlan.h:4547
bool empty() const
Definition VPlan.h:4544
size_t size() const
Definition VPlan.h:4543
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:99
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
Definition VPlan.h:309
VPRegionBlock * getParent()
Definition VPlan.h:197
const VPBasicBlock * getExitingBasicBlock() const
Definition VPlan.cpp:198
size_t getNumSuccessors() const
Definition VPlan.h:247
iterator_range< VPBlockBase ** > successors()
Definition VPlan.h:229
virtual void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const =0
Print plain-text dump of this VPBlockBase to O, prefixing all lines with Indent.
bool hasPredecessors() const
Returns true if this block has any predecessors.
Definition VPlan.h:227
void printSuccessors(raw_ostream &O, const Twine &Indent) const
Print the successors of this block to O, prefixing all lines with Indent.
Definition VPlan.cpp:629
size_t getNumPredecessors() const
Definition VPlan.h:248
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
Definition VPlan.h:300
VPBlockBase * getEnclosingBlockWithPredecessors()
Definition VPlan.cpp:220
bool hasSuccessors() const
Returns true if this block has any successors.
Definition VPlan.h:225
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:232
virtual InstructionCost cost(ElementCount VF, VPCostContext &Ctx)=0
Return the cost of the block.
VPlan * getPlan()
Definition VPlan.h:201
const std::string & getName() const
Definition VPlan.h:188
VPBlockBase * getSinglePredecessor() const
Definition VPlan.h:243
const VPBlocksTy & getHierarchicalSuccessors()
Definition VPlan.h:267
VPBlockBase * getEnclosingBlockWithSuccessors()
An Enclosing Block of a block B is any block containing B, including B itself.
Definition VPlan.cpp:212
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:183
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:237
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:221
VPBlockBase(VPBlockTy SC, const std::string &N)
Definition VPlan.h:394
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBase NewBlock after BlockPtr.
Definition VPlanUtils.h:330
static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop latch, using isHeader().
static bool isHeader(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop header, based on regions or VPDT in their absence.
static void connectBlocks(VPBlockBase *From, VPBlockBase *To, unsigned PredIdx=-1u, unsigned SuccIdx=-1u)
Connect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:375
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:393
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:441
static void transferSuccessors(VPBlockBase *Old, VPBlockBase *New)
Transfer successors from Old to New. New must have no successors.
Definition VPlanUtils.h:425
static std::pair< VPBlockBase *, VPBlockBase * > cloneFrom(VPBlockBase *Entry)
Clone the CFG for all nodes reachable from Entry, including cloning the blocks and their recipes.
Definition VPlan.cpp:656
A recipe for generating conditional branches on the bits of a mask.
Definition VPlan.h:3564
VPInstruction * createOverflowingOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt, Type *ResultTy=nullptr)
Create a phi with IncomingValues, using the default flags for the result type, unless Flags is set.
This class augments a recipe with a set of VPValues defined by the recipe.
Definition VPlanValue.h:508
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4653
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
Definition VPlan.cpp:441
BasicBlock * getIRBasicBlock() const
Definition VPlan.h:4677
VPIRBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Definition VPlan.cpp:466
static LLVM_ABI_FOR_TEST VPIRInstruction * create(Instruction &I)
Create a new VPIRPhi for \I , if it is a PHINode, otherwise create a VPIRInstruction.
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1324
In what follows, the term "input IR" refers to code that is fed into the vectorizer whereas the term ...
static VPLane getLastLaneForVF(const ElementCount &VF)
Value * getAsRuntimeExpr(IRBuilderBase &Builder, const ElementCount &VF) const
Returns an expression describing the lane index that can be used at runtime.
Definition VPlan.cpp:81
bool isFirstLane() const
Returns true if this is the first lane of the whole vector.
static VPLane getFirstLane()
@ ScalableLast
For ScalableLast, Lane is the offset from the start of the last N-element subvector in a scalable vec...
@ First
For First, Lane is the index into the first N elements of a fixed-vector <N x <ElTy>> or a scalable v...
unsigned mapToCacheIndex(const ElementCount &VF) const
Maps the lane to a cache index based on VF.
LLVM_ABI_FOR_TEST VPMultiDefValue(VPRecipeBase *Def, Value *UV, Type *Ty)
Definition VPlan.cpp:172
~VPMultiDefValue() override
Definition VPlan.cpp:178
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:406
void dump() const
Dump the recipe to stderr (for debugging).
Definition VPlan.cpp:110
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const
Print the recipe, delegating to printRecipe().
virtual LLVM_ABI_FOR_TEST ~VPRecipeValue()=0
Definition VPlan.cpp:157
VPRecipeValue(unsigned char SC, Value *UV, Type *Ty=nullptr)
Definition VPlanValue.h:342
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4725
VPRegionBlock * clone() override
Clone all blocks in the single-entry single-exit region of the block and their recipes without updati...
Definition VPlan.cpp:713
const VPBlockBase * getEntry() const
Definition VPlan.h:4769
void dissolveToCFGLoop()
Remove the current region from its VPlan, connecting its predecessor to its entry,...
Definition VPlan.cpp:858
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4801
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
Definition VPlan.h:4872
VPRegionValue * getUsedHeaderMask() const
Return the header mask if it exists and is used, or null otherwise.
Definition VPlan.h:4865
VPInstruction * getOrCreateCanonicalIVIncrement()
Get the canonical IV increment instruction if it exists.
Definition VPlan.cpp:884
InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override
Return the cost of the block.
Definition VPlan.cpp:774
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print this VPRegionBlock to O (recursively), prefixing all lines with Indent.
Definition VPlan.cpp:835
Type * getCanonicalIVType() const
Return the type of the canonical IV for loop regions.
Definition VPlan.h:4853
const VPBranchOnMaskRecipe * getEntryBranchOnMask() const
Return the VPBranchOnMaskRecipe from the entry block of this replicating region.
Definition VPlan.cpp:706
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4889
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPRegionBlock,...
Definition VPlan.cpp:733
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4845
const VPBlockBase * getExiting() const
Definition VPlan.h:4781
VPRegionValue * getHeaderMask() const
Return the header mask of the region, or null if not set.
Definition VPlan.h:4858
friend class VPlan
Definition VPlan.h:4726
VPValues are defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:247
DebugLoc getDebugLoc() const
Returns the debug location of the VPRegionValue.
Definition VPlanValue.h:262
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3457
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:608
VPSingleDefValue(VPSingleDefRecipe *Def, Value *UV=nullptr, Type *Ty=nullptr)
Construct a VPSingleDefValue. Must only be used by VPSingleDefRecipe.
Definition VPlan.cpp:162
~VPSingleDefValue() override
Definition VPlan.cpp:168
friend class VPSingleDefRecipe
Definition VPlanValue.h:360
This class can be used to assign names to VPValues.
std::string getOrCreateName(const VPValue *V) const
Returns the name assigned to V, if there is one, otherwise try to construct one from the underlying v...
Definition VPlan.cpp:1622
const Module * getModule() const
Returns the module the plan operates on, if any.
void printMetadataAsOperand(raw_ostream &O, const MDNode *N)
Print a reference to metadata node N to O.
Definition VPlan.cpp:1618
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:212
Type * getType() const
Returns the scalar type of this symbolic value.
Definition VPlanValue.h:227
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:396
void replaceUsesOfWith(VPValue *From, VPValue *To)
Replaces all uses of From in the VPUser with To.
Definition VPlan.cpp:1508
void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const
Print the operands to O.
Definition VPlan.cpp:1520
operand_range operands()
Definition VPlanValue.h:472
void setOperand(unsigned I, VPValue *New)
Definition VPlanValue.h:445
unsigned getNumOperands() const
Definition VPlanValue.h:436
VPValue * getOperand(unsigned N) const
Definition VPlanValue.h:437
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Definition VPlan.cpp:142
Value * getLiveInIRValue() const
Return the underlying IR value for a VPIRValue.
Definition VPlan.cpp:136
bool isDefinedOutsideLoopRegions() const
Returns true if the VPValue is defined outside any loop.
Definition VPlan.cpp:1472
unsigned getVPValueID() const
Definition VPlanValue.h:101
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:123
void printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const
Definition VPlan.cpp:1516
void assertNotMaterialized() const
Assert that this VPValue has not been materialized, if it is a VPSymbolicValue.
Definition VPlanValue.h:580
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
Definition VPlanValue.h:75
void replaceUsesWithIf(VPValue *New, llvm::function_ref< bool(VPUser *U)> ShouldReplace)
Go through the uses list for this VPValue and make each use point to New if the callback ShouldReplac...
Definition VPlan.cpp:1481
bool user_empty() const
Definition VPlanValue.h:161
@ VPVSingleDefValueSC
A symbolic live-in VPValue without IR backing.
Definition VPlanValue.h:85
@ VPVSymbolicSC
A live-in VPValue wrapping an IR Value.
Definition VPlanValue.h:84
@ VPRegionValueSC
A VPValue defined by a multi-def recipe.
Definition VPlanValue.h:87
@ VPVMultiDefValueSC
A VPValue defined by a VPSingleDefRecipe.
Definition VPlanValue.h:86
void dump() const
Dump the value to stderr (for debugging).
Definition VPlan.cpp:102
void print(raw_ostream &OS, VPSlotTracker &Tracker) const
Definition VPlan.cpp:95
void replaceAllUsesWith(VPValue *New)
Definition VPlan.cpp:1475
unsigned getNumUsers() const
Definition VPlanValue.h:115
LLVM_DUMP_METHOD void dump()
Definition VPlan.cpp:1334
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4912
LLVM_ABI_FOR_TEST void printDOT(raw_ostream &O) const
Print this VPlan in DOT format to O.
Definition VPlan.cpp:1178
friend class VPSlotTracker
Definition VPlan.h:4914
std::string getName() const
Return a string with the name of the plan and the applicable VFs and UFs.
Definition VPlan.cpp:1154
VPBasicBlock * getEntry()
Definition VPlan.h:5004
Type * getIndexType() const
The type of the canonical induction variable of the vector loop.
Definition VPlan.h:5348
void setName(const Twine &newName)
Definition VPlan.h:5181
LLVM_ABI_FOR_TEST ~VPlan()
Definition VPlan.cpp:912
bool isExitBlock(VPBlockBase *VPBB)
Returns true if VPBB is an exit block.
Definition VPlan.cpp:930
friend class VPlanPrinter
Definition VPlan.h:4913
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5107
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
Definition VPlan.cpp:1311
auto getLiveIns() const
Return the list of live-in VPValues available in the VPlan.
Definition VPlan.h:5245
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:5070
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1065
bool hasEarlyExit() const
Returns true if the VPlan is based on a loop with an early exit.
Definition VPlan.h:5318
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this plan.
Definition VPlan.cpp:1047
LLVM_ABI_FOR_TEST bool isOuterLoop() const
Returns true if this VPlan is for an outer loop, i.e., its vector loop region contains a nested loop ...
Definition VPlan.cpp:1090
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5163
void setEntry(VPBasicBlock *VPBB)
Definition VPlan.h:4993
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
Definition VPlan.h:5268
LLVM_ABI_FOR_TEST VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
Definition VPlan.cpp:1319
LLVM_DUMP_METHOD void dump() const
Dump the plan to stderr (for debugging).
Definition VPlan.cpp:1184
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:5060
void execute(VPTransformState *State)
Generate the IR code for this VPlan.
Definition VPlan.cpp:940
LLVM_ABI_FOR_TEST void print(raw_ostream &O) const
Print this VPlan to O.
Definition VPlan.cpp:1137
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
Definition VPlan.h:5066
void printLiveIns(raw_ostream &O) const
Print the live-ins of this VPlan to O.
Definition VPlan.cpp:1099
LLVM_ABI_FOR_TEST VPlan * duplicate()
Clone the current VPlan, update all VPValues of the new VPlan and cloned recipes to refer to the clon...
Definition VPlan.cpp:1225
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:169
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI std::string EscapeString(const std::string &Label)
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
bool match(Val *V, const Pattern &P)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
VPInstruction_match< VPInstruction::BranchOnTwoConds > m_BranchOnTwoConds()
VPInstruction_match< VPInstruction::BranchOnCount > m_BranchOnCount()
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
BranchProbability getExecutionProbability(BlockFrequency Freq)
Returns Freq as a BranchProbability, relative to the full mass.
bool isSingleScalar(const VPValue *VPV)
Returns true if VPV is a single scalar, either because it produces the same value for all lanes or on...
VPInstruction * findCanonicalIVIncrement(VPlan &Plan)
Find the canonical IV increment of Plan's vector loop region.
bool onlyFirstLaneUsed(const VPValue *Def)
Returns true if only the first lane of Def is used by all users.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
Definition STLExtras.h:846
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
Definition LoopInfo.cpp:61
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition STLExtras.h:856
InstructionCost Cost
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto successors(const MachineBasicBlock *BB)
LLVM_ABI cl::opt< bool > EnableFSDiscriminator
VPBuilderBase<> VPBuilder
Definition VPlan.h:69
Value * getRuntimeVF(IRBuilderBase &B, Type *Ty, ElementCount VF)
Return the runtime value for VF.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI std::optional< MDNode * > makeFollowupLoopID(MDNode *OrigLoopID, ArrayRef< StringRef > FollowupAttrs, const char *InheritOptionsAttrsPrefix="", bool AlwaysNew=false)
Create a new loop identifier for a loop created from a loop transformation.
void interleaveComma(const Container &c, StreamT &os, UnaryFunctor each_fn)
Definition STLExtras.h:2329
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
Align getLoadStoreAlignment(const Value *I)
A helper function that returns the alignment of load or store instruction.
iterator_range< df_iterator< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_depth_first_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order.
Definition VPlanCFG.h:250
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
constexpr T divideNearest(U Numerator, V Denominator)
Returns (Numerator / Denominator) rounded by round-half-up.
Definition MathExtras.h:453
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
Type * toVectorizedTy(Type *Ty, ElementCount EC)
A helper for converting to vectorized types.
bool canConstantBeExtended(const APInt *C, Type *NarrowType, TTI::PartialReductionExtendKind ExtKind)
Check if a constant CI can be safely treated as having been extended from a narrower type with the gi...
Definition VPlan.cpp:1828
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI bool setLoopEstimatedTripCount(Loop *L, unsigned EstimatedTripCount, std::optional< unsigned > EstimatedLoopInvocationWeight=std::nullopt)
Set llvm.loop.estimated_trip_count with the value EstimatedTripCount in the loop metadata of L.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2035
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
ArrayRef< Type * > getContainedTypes(Type *const &Ty)
Returns the types contained in Ty.
LLVM_ABI void DeleteDeadBlocks(ArrayRef< BasicBlock * > BBs, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified blocks from BB.
std::unique_ptr< VPlan > VPlanPtr
Definition VPlan.h:80
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
A range of powers-of-2 vectorization factors with fixed start and adjustable end.
Struct to hold various analysis needed for cost computations.
uint64_t getCostDivisor(std::optional< VPExecutionFrequency > Freq) const
Definition VPlan.cpp:1941
TargetTransformInfo::OperandValueInfo getOperandInfo(VPValue *V) const
Returns the OperandInfo for V, if it is a live-in.
Definition VPlan.cpp:1839
static bool isFreeScalarIntrinsic(Intrinsic::ID ID)
Returns true if ID is a pseudo intrinsic that is dropped via scalarization rather than widened.
Definition VPlan.cpp:1932
static bool executesAtMostOnce(const VPlan &Plan, ElementCount VF)
Returns true if the vector loop body of Plan is known to execute at most once at VF,...
std::optional< unsigned > NumPredStores
Number of predicated stores in the VPlan, computed on demand.
InstructionCost getScalarizationOverhead(Type *ResultTy, ArrayRef< const VPValue * > Operands, ElementCount VF, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None, bool AlwaysIncludeReplicatingR=false)
Estimate the overhead of scalarizing a recipe with result type ResultTy and Operands with VF.
Definition VPlan.cpp:1856
TargetTransformInfo::TargetCostKind CostKind
VPSlotTracker * getSlotTracker()
Return a VPSlotTracker to re-use for printing, lazily constructing it on first use.
Definition VPlan.cpp:1847
const TargetTransformInfo & TTI
bool useEmulatedMaskMemRefHack(const VPReplicateRecipe *R, ElementCount VF)
Returns true if an artificially high cost for emulated masked memrefs should be used.
Definition VPlan.cpp:1894
const VectorizeOptions & Opts
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:274
Type * getType() const
Returns the type of the underlying IR value.
Definition VPlan.cpp:140
VPTransformState holds information passed down when "executing" a VPlan, needed for generating the ou...
LoopInfo * LI
Hold a pointer to LoopInfo to register new basic blocks in the loop.
void fixupHeaderPhis()
Add the backedge (latch) incoming value to the canonical, reduction and first-order recurrence phis i...
Definition VPlan.cpp:331
struct llvm::VPTransformState::DataState Data
struct llvm::VPTransformState::CFGState CFG
IRBuilderBase & Builder
Hold a reference to the IRBuilder used to generate output IR code.
bool hasScalarValue(const VPValue *Def, VPLane Lane)
Value * get(const VPValue *Def, bool NeedsSingleScalar=false)
Get the generated vector Value for a given VPValue Def if NeedsSingleScalar is false,...
Definition VPlan.cpp:270
const TargetTransformInfo * TTI
Target Transform Info.
VPTransformState(const TargetTransformInfo *TTI, ElementCount VF, LoopInfo *LI, DominatorTree *DT, AssumptionCache *AC, IRBuilderBase &Builder, VPlan *Plan, Loop *CurrentParentLoop)
Definition VPlan.cpp:235
VPlan * Plan
Pointer to the VPlan code is generated for.
void set(const VPValue *Def, Value *V, bool IsScalar=false)
Set the generated vector Value for a given VPValue, if IsScalar is false.
bool hasVectorValue(const VPValue *Def)
VPDominatorTree VPDT
VPlan-based dominator tree.
ElementCount VF
The chosen Vectorization Factor of the loop being vectorized.
AssumptionCache * AC
Hold a pointer to AssumptionCache to register new assumptions after replicating assume calls.
void setDebugLocFrom(DebugLoc DL)
Set the debug location in the builder using the debug location DL.
Definition VPlan.cpp:309
Loop * CurrentParentLoop
The parent loop object for the current scope, or nullptr.