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"
28#include "llvm/ADT/STLExtras.h"
31#include "llvm/ADT/Twine.h"
35#include "llvm/IR/BasicBlock.h"
36#include "llvm/IR/CFG.h"
37#include "llvm/IR/IRBuilder.h"
38#include "llvm/IR/Instruction.h"
40#include "llvm/IR/Type.h"
41#include "llvm/IR/Value.h"
44#include "llvm/Support/Debug.h"
50#include <cassert>
51#include <string>
52
53using namespace llvm;
54using namespace llvm::VPlanPatternMatch;
55
56namespace llvm {
60} // namespace llvm
61
62/// @{
63/// Metadata attribute names
64const char LLVMLoopVectorizeFollowupAll[] = "llvm.loop.vectorize.followup_all";
66 "llvm.loop.vectorize.followup_vectorized";
68 "llvm.loop.vectorize.followup_epilogue";
69/// @}
70
72 "vplan-print-in-dot-format", cl::Hidden,
73 cl::desc("Use dot format instead of plain text when dumping VPlans"));
74
75#define DEBUG_TYPE "loop-vectorize"
76
77#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
79 const VPBasicBlock *Parent = R.getParent();
80 VPSlotTracker SlotTracker(Parent ? Parent->getPlan() : nullptr);
81 R.print(OS, "", SlotTracker);
82 return OS;
83}
84#endif
85
87 const ElementCount &VF) const {
88 switch (LaneKind) {
90 // Lane = RuntimeVF - VF.getKnownMinValue() + Lane
91 return Builder.CreateSub(getRuntimeVF(Builder, Builder.getInt32Ty(), VF),
92 Builder.getInt32(VF.getKnownMinValue() - Lane));
94 return Builder.getInt64(Lane);
95 }
96 llvm_unreachable("Unknown lane kind");
97}
98
99#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
101 if (const VPRecipeBase *R = getDefiningRecipe())
102 R->print(OS, "", SlotTracker);
103 else
105}
106
107void VPValue::dump() const {
108 const VPRecipeBase *Instr = getDefiningRecipe();
110 (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() : nullptr);
112 dbgs() << "\n";
113}
114
115void VPRecipeBase::dump() const {
116 VPSlotTracker SlotTracker(getParent() ? getParent()->getPlan() : nullptr);
117 print(dbgs(), "", SlotTracker);
118 dbgs() << "\n";
119}
120#endif
121
122#if !defined(NDEBUG)
123bool VPRecipeValue::isDefinedBy(const VPDef *D) const {
124 return getDefiningRecipe() == D;
125}
126#endif
127
129 auto *RecipeValue = dyn_cast<VPRecipeValue>(this);
130 if (!RecipeValue)
131 return nullptr;
132 if (auto *MultiDef = dyn_cast<VPMultiDefValue>(RecipeValue))
133 return MultiDef->getDef();
134 return static_cast<VPSingleDefRecipe *>(RecipeValue);
135}
136
138 return const_cast<VPValue *>(this)->getDefiningRecipe();
139}
140
142 return cast<VPIRValue>(this)->getValue();
143}
144
146
148 switch (getVPValueID()) {
149 case VPVIRValueSC:
150 return cast<VPIRValue>(this)->getType();
151 case VPRegionValueSC:
152 return cast<VPRegionValue>(this)->getType();
153 case VPVSymbolicSC:
154 return cast<VPSymbolicValue>(this)->getType();
157 return cast<VPRecipeValue>(this)->getScalarType();
158 }
159 llvm_unreachable("Unhandled VPValue subclass");
160}
161
163 assert(Users.empty() &&
164 "trying to delete a VPRecipeValue with remaining users");
165}
166
169 assert(Def && "VPSingleDefValue requires a defining recipe");
170 Def->addDefinedValue(this);
171}
172
174 getDefiningRecipe()->removeDefinedValue(this);
175}
176
178 : VPRecipeValue(VPVMultiDefValueSC, UV, Ty), Def(Def) {
179 assert(Def && "VPMultiDefValue requires a defining recipe");
180 Def->addDefinedValue(this);
181}
182
184 getDefiningRecipe()->removeDefinedValue(this);
185}
186
187/// \return the VPBasicBlock that is the entry of Block, possibly indirectly.
194
201
202/// \return the VPBasicBlock that is the exit of Block, possibly indirectly.
204 const VPBlockBase *Block = this;
206 Block = Region->getExiting();
208}
209
216
218 if (!Successors.empty() || !Parent)
219 return this;
220 assert(Parent->getExiting() == this &&
221 "Block w/o successors not the exiting block of its parent.");
222 return Parent->getEnclosingBlockWithSuccessors();
223}
224
226 if (!Predecessors.empty() || !Parent)
227 return this;
228 assert(Parent->getEntry() == this &&
229 "Block w/o predecessors not the entry of its parent.");
230 return Parent->getEnclosingBlockWithPredecessors();
231}
232
234 iterator It = begin();
235 while (It != end() && It->isPhi())
236 It++;
237 return It;
238}
239
247
248Value *VPTransformState::get(const VPValue *Def, const VPLane &Lane) {
250 "VPRegionValue must be materialized before VPTransformState::get");
252 return Def->getUnderlyingValue();
253
254 if (hasScalarValue(Def, Lane))
255 return Data.VPV2Scalars[Def][Lane.mapToCacheIndex(VF)];
256
257 if (!Lane.isFirstLane() && vputils::isSingleScalar(Def) &&
259 return Data.VPV2Scalars[Def][0];
260 }
261
262 // Look through BuildVector to avoid redundant extracts.
263 // TODO: Remove once replicate regions are unrolled explicitly.
264 if (Lane.getKind() == VPLane::Kind::First && match(Def, m_BuildVector())) {
265 auto *BuildVector = cast<VPInstruction>(Def);
266 return get(BuildVector->getOperand(Lane.getKnownLane()), true);
267 }
268
270 auto *VecPart = Data.VPV2Vector[Def];
271 if (!VecPart->getType()->isVectorTy()) {
272 assert(Lane.isFirstLane() && "cannot get lane > 0 for scalar");
273 return VecPart;
274 }
275 // TODO: Cache created scalar values.
276 Value *LaneV = Lane.getAsRuntimeExpr(Builder, VF);
277 auto *Extract = Builder.CreateExtractElement(VecPart, LaneV);
278 // set(Def, Extract, Instance);
279 return Extract;
280}
281
282Value *VPTransformState::get(const VPValue *Def, bool NeedsScalar) {
284 "VPRegionValue must be materialized before VPTransformState::get");
285 if (NeedsScalar) {
286 assert((VF.isScalar() || isa<VPIRValue, VPSymbolicValue>(Def) ||
288 (hasScalarValue(Def, VPLane(0)) &&
289 Data.VPV2Scalars[Def].size() == 1)) &&
290 "Trying to access a single scalar per part but has multiple scalars "
291 "per part.");
292 return get(Def, VPLane(0));
293 }
294
295 // If Values have been set for this Def return the one relevant for \p Part.
296 if (hasVectorValue(Def))
297 return Data.VPV2Vector[Def];
298
299 auto GetBroadcastInstrs = [this](Value *V) {
300 if (VF.isScalar())
301 return V;
302 // Broadcast the scalar into all locations in the vector.
303 Value *Shuf = Builder.CreateVectorSplat(VF, V, "broadcast");
304 return Shuf;
305 };
306
307 Value *ScalarValue = get(Def, VPLane(0));
310 if (auto *LastInst = dyn_cast<Instruction>(get(Def, LastLane)))
311 // Set the insert point after the last scalarized instruction. This
312 // ensures the insertelement sequence will directly follow the scalar
313 // definitions.
314 if (auto InsertPt = LastInst->getInsertionPointAfterDef())
315 Builder.SetInsertPoint(*InsertPt);
316 Value *VectorValue = GetBroadcastInstrs(ScalarValue);
317 set(Def, VectorValue);
318 return VectorValue;
319}
320
322 const DILocation *DIL = DL;
323 // When a FSDiscriminator is enabled, we don't need to add the multiply
324 // factors to the discriminators.
325 if (DIL &&
326 Builder.GetInsertBlock()
327 ->getParent()
328 ->shouldEmitDebugInfoForProfiling() &&
330 // FIXME: For scalable vectors, assume vscale=1.
331 unsigned UF = Plan->getConcreteUF();
332 auto NewDIL =
333 DIL->cloneByMultiplyingDuplicationFactor(UF * VF.getKnownMinValue());
334 if (NewDIL)
335 Builder.SetCurrentDebugLocation(*NewDIL);
336 else
337 LLVM_DEBUG(dbgs() << "Failed to create new discriminator: "
338 << DIL->getFilename() << " Line: " << DIL->getLine());
339 } else
340 Builder.SetCurrentDebugLocation(DL);
341}
342
344 for (VPBlockBase *VPB : vp_depth_first_shallow(Plan->getEntry())) {
345 if (!VPBlockUtils::isHeader(VPB, VPDT))
346 continue;
347 auto *Header = cast<VPBasicBlock>(VPB);
348 auto *LatchVPBB = cast<VPBasicBlock>(Header->getPredecessors()[1]);
349 BasicBlock *VectorLatchBB = CFG.VPBB2IRBB[LatchVPBB];
350
351 for (VPRecipeBase &R : Header->phis()) {
352 auto *PhiR = cast<VPSingleDefRecipe>(&R);
353 bool NeedsScalar =
354 isa<VPPhi>(PhiR) || (isa<VPReductionPHIRecipe>(PhiR) &&
355 cast<VPReductionPHIRecipe>(PhiR)->isInLoop());
356
357 Value *Phi = get(PhiR, NeedsScalar);
358 Value *Val = get(PhiR->getOperand(1), NeedsScalar);
359 cast<PHINode>(Phi)->addIncoming(Val, VectorLatchBB);
360 }
361 }
362}
363
364BasicBlock *VPBasicBlock::createEmptyBasicBlock(VPTransformState &State) {
365 auto &CFG = State.CFG;
366 // BB stands for IR BasicBlocks. VPBB stands for VPlan VPBasicBlocks.
367 // Pred stands for Predessor. Prev stands for Previous - last visited/created.
368 BasicBlock *PrevBB = CFG.PrevBB;
369 BasicBlock *NewBB = BasicBlock::Create(PrevBB->getContext(), getName(),
370 PrevBB->getParent(), CFG.ExitBB);
371 LLVM_DEBUG(dbgs() << "LV: created " << NewBB->getName() << '\n');
372
373 return NewBB;
374}
375
377 auto &CFG = State.CFG;
378 BasicBlock *NewBB = CFG.VPBB2IRBB[this];
379
380 // Register NewBB in its loop. In innermost loops its the same for all
381 // BB's.
382 Loop *ParentLoop = State.CurrentParentLoop;
383 // If this block has a sole successor that is an exit block or is an exit
384 // block itself then it needs adding to the same parent loop as the exit
385 // block.
386 VPBlockBase *SuccOrExitVPB = getSingleSuccessor();
387 SuccOrExitVPB = SuccOrExitVPB ? SuccOrExitVPB : this;
388 if (State.Plan->isExitBlock(SuccOrExitVPB)) {
389 ParentLoop = State.LI->getLoopFor(
390 cast<VPIRBasicBlock>(SuccOrExitVPB)->getIRBasicBlock());
391 }
392
393 if (ParentLoop && !State.LI->getLoopFor(NewBB))
394 ParentLoop->addBasicBlockToLoop(NewBB, *State.LI);
395
397 if (VPBlockUtils::isHeader(this, State.VPDT)) {
398 // There's no block for the latch yet, connect to the preheader only.
399 Preds = {getPredecessors()[0]};
400 } else {
401 Preds = to_vector(getPredecessors());
402 }
403
404 // Hook up the new basic block to its predecessors.
405 for (VPBlockBase *PredVPBlock : Preds) {
406 VPBasicBlock *PredVPBB = PredVPBlock->getExitingBasicBlock();
407 auto &PredVPSuccessors = PredVPBB->getHierarchicalSuccessors();
408 assert(CFG.VPBB2IRBB.contains(PredVPBB) &&
409 "Predecessor basic-block not found building successor.");
410 BasicBlock *PredBB = CFG.VPBB2IRBB[PredVPBB];
411 auto *PredBBTerminator = PredBB->getTerminator();
412 LLVM_DEBUG(dbgs() << "LV: draw edge from " << PredBB->getName() << '\n');
413
414 if (isa<UnreachableInst>(PredBBTerminator)) {
415 assert(PredVPSuccessors.size() == 1 &&
416 "Predecessor ending w/o branch must have single successor.");
417 DebugLoc DL = PredBBTerminator->getDebugLoc();
418 PredBBTerminator->eraseFromParent();
419 auto *Br = UncondBrInst::Create(NewBB, PredBB);
420 Br->setDebugLoc(DL);
421 } else if (auto *UBI = dyn_cast<UncondBrInst>(PredBBTerminator)) {
422 UBI->setSuccessor(NewBB);
423 } else {
424 // Set each forward successor here when it is created, excluding
425 // backedges. A backward successor is set when the branch is created.
426 // Generated successors are redirected, as for the entry block and for
427 // blocks bypassing both vector loops during epilogue vectorization. Edges
428 // already present in the generated IR need no update; this happens during
429 // epilogue vectorization, where the plan models blocks generated for the
430 // main vector loop.
431 // TODO: Remove the exception by modeling those terminators using
432 // BranchOnCond.
433 auto *TermBr = cast<CondBrInst>(PredBBTerminator);
434 if (TermBr->getSuccessor(0) != NewBB &&
435 TermBr->getSuccessor(1) != NewBB) {
436 unsigned Idx = PredVPSuccessors.front() == this ? 0 : 1;
437 BasicBlock *ReplacedSucc = TermBr->getSuccessor(Idx);
438 assert(
439 (!ReplacedSucc || isa<VPIRBasicBlock>(PredVPBB)) &&
440 "only VPIRBasicBlock predecessors may have an existing successor "
441 "redirected");
442 if (ReplacedSucc)
443 ReplacedSucc->removePredecessor(PredBB, /*KeepOneInputPHIs=*/true);
444 TermBr->setSuccessor(Idx, NewBB);
445 if (ReplacedSucc)
446 CFG.DTU.applyUpdates({{DominatorTree::Delete, PredBB, ReplacedSucc}});
447 }
448 }
449 CFG.DTU.applyUpdates({{DominatorTree::Insert, PredBB, NewBB}});
450 }
451}
452
455 "VPIRBasicBlock can have at most two successors at the moment!");
456 // Move completely disconnected blocks to their final position.
457 if (IRBB->hasNPredecessors(0) && succ_begin(IRBB) == succ_end(IRBB))
458 IRBB->moveAfter(State->CFG.PrevBB);
459 State->Builder.SetInsertPoint(IRBB->getTerminator());
460 State->CFG.PrevBB = IRBB;
461 State->CFG.VPBB2IRBB[this] = IRBB;
462 executeRecipes(State, IRBB);
463 // Create a branch instruction to terminate IRBB if one was not created yet
464 // and is needed.
465 if (getSingleSuccessor() && isa<UnreachableInst>(IRBB->getTerminator())) {
466 auto *Br = State->Builder.CreateBr(IRBB);
467 Br->setOperand(0, nullptr);
468 IRBB->getTerminator()->eraseFromParent();
469 } else {
470 assert((getNumSuccessors() == 0 ||
471 isa<UncondBrInst, CondBrInst>(IRBB->getTerminator())) &&
472 "other blocks must be terminated by a branch");
473 }
474
475 connectToPredecessors(*State);
476}
477
478VPIRBasicBlock *VPIRBasicBlock::clone() {
479 auto *NewBlock = getPlan()->createEmptyVPIRBasicBlock(IRBB);
480 for (VPRecipeBase &R : Recipes)
481 NewBlock->appendRecipe(R.clone());
482 return NewBlock;
483}
484
486 if (VPBlockUtils::isHeader(this, State->VPDT)) {
487 // Create and register the new vector loop.
488 Loop *PrevParentLoop = State->CurrentParentLoop;
489 State->CurrentParentLoop = State->LI->AllocateLoop();
490
491 // Insert the new loop into the loop nest and register the new basic blocks
492 // before calling any utilities such as SCEV that require valid LoopInfo.
493 if (PrevParentLoop)
494 PrevParentLoop->addChildLoop(State->CurrentParentLoop);
495 else
496 State->LI->addTopLevelLoop(State->CurrentParentLoop);
497 }
498
499 // 1. Create an IR basic block.
500 BasicBlock *NewBB = createEmptyBasicBlock(*State);
501
502 State->Builder.SetInsertPoint(NewBB);
503 // Temporarily terminate with unreachable until CFG is rewired.
504 UnreachableInst *Terminator = State->Builder.CreateUnreachable();
505 State->Builder.SetInsertPoint(Terminator);
506
507 State->CFG.PrevBB = NewBB;
508 State->CFG.VPBB2IRBB[this] = NewBB;
509 connectToPredecessors(*State);
510
511 // 2. Fill the IR basic block with IR instructions.
512 executeRecipes(State, NewBB);
513
514 // If this block is a latch, update CurrentParentLoop.
515 if (VPBlockUtils::isLatch(this, State->VPDT))
516 State->CurrentParentLoop = State->CurrentParentLoop->getParentLoop();
517}
518
519VPBasicBlock *VPBasicBlock::clone() {
520 auto *NewBlock = getPlan()->createVPBasicBlock(getName());
521 for (VPRecipeBase &R : *this)
522 NewBlock->appendRecipe(R.clone());
523 return NewBlock;
524}
525
527 LLVM_DEBUG(dbgs() << "LV: vectorizing VPBB: " << getName()
528 << " in BB: " << BB->getName() << '\n');
529
530 State->CFG.PrevVPBB = this;
531
532 for (VPRecipeBase &Recipe : Recipes) {
533 State->setDebugLocFrom(Recipe.getDebugLoc());
534 Recipe.execute(*State);
535 }
536
537 LLVM_DEBUG(dbgs() << "LV: filled BB: " << *BB);
538}
539
540VPBasicBlock *VPBasicBlock::splitAt(iterator SplitAt) {
541 assert((SplitAt == end() || SplitAt->getParent() == this) &&
542 "can only split at a position in the same block");
543
544 // Create new empty block after the block to split.
545 auto *SplitBlock = getPlan()->createVPBasicBlock(getName() + ".split");
547
548 // If this is the exiting block, make the split the new exiting block.
549 auto *ParentRegion = getParent();
550 if (ParentRegion && ParentRegion->getExiting() == this)
551 ParentRegion->setExiting(SplitBlock);
552
553 // Finally, move the recipes starting at SplitAt to new block.
554 for (VPRecipeBase &ToMove :
555 make_early_inc_range(make_range(SplitAt, this->end())))
556 ToMove.moveBefore(*SplitBlock, SplitBlock->end());
557
558 return SplitBlock;
559}
560
561/// Return the enclosing loop region for region \p P. The templated version is
562/// used to support both const and non-const block arguments.
563template <typename T> static T *getEnclosingLoopRegionForRegion(T *P) {
564 if (P && P->isReplicator()) {
565 P = P->getParent();
566 // Multiple loop regions can be nested, but replicate regions can only be
567 // nested inside a loop region or must be outside any other region.
568 assert((!P || !P->isReplicator()) && "unexpected nested replicate regions");
569 }
570 return P;
571}
572
576
580
581static bool hasConditionalTerminator(const VPBasicBlock *VPBB) {
582 if (VPBB->empty()) {
583 assert(
584 VPBB->getNumSuccessors() < 2 &&
585 "block with multiple successors doesn't have a recipe as terminator");
586 return false;
587 }
588
589 const VPRecipeBase *R = &VPBB->back();
590 [[maybe_unused]] bool IsSwitch =
592 cast<VPInstruction>(R)->getOpcode() == Instruction::Switch;
593 [[maybe_unused]] bool IsBranchOnTwoConds = match(R, m_BranchOnTwoConds());
594 [[maybe_unused]] bool IsCondBranch =
597 if (VPBB->getNumSuccessors() == 2 ||
598 (VPBB->isExiting() && !VPBB->getParent()->isReplicator())) {
599 assert((IsCondBranch || IsSwitch || IsBranchOnTwoConds) &&
600 "block with multiple successors not terminated by "
601 "conditional branch nor switch recipe");
602
603 return true;
604 }
605
606 if (VPBB->getNumSuccessors() > 2) {
607 assert((IsSwitch || IsBranchOnTwoConds) &&
608 "block with more than 2 successors not terminated by a switch or "
609 "branch-on-two-conds recipe");
610 return true;
611 }
612
613 assert(
614 !IsCondBranch && !IsBranchOnTwoConds &&
615 "block with 0 or 1 successors terminated by conditional branch recipe");
616 return false;
617}
618
620 if (hasConditionalTerminator(this))
621 return &back();
622 return nullptr;
623}
624
626 if (hasConditionalTerminator(this))
627 return &back();
628 return nullptr;
629}
630
632 return getParent() && getParent()->getExitingBasicBlock() == this;
633}
634
635#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
640
641void VPBlockBase::printSuccessors(raw_ostream &O, const Twine &Indent) const {
642 if (!hasSuccessors()) {
643 O << Indent << "No successors\n";
644 } else {
645 O << Indent << "Successor(s): ";
646 ListSeparator LS;
647 for (auto *Succ : getSuccessors())
648 O << LS << Succ->getName();
649 O << '\n';
650 }
651}
652
653void VPBasicBlock::print(raw_ostream &O, const Twine &Indent,
654 VPSlotTracker &SlotTracker) const {
655 O << Indent << getName() << ":\n";
656
657 auto RecipeIndent = Indent + " ";
658 for (const VPRecipeBase &Recipe : *this) {
659 Recipe.print(O, RecipeIndent, SlotTracker);
660 O << '\n';
661 }
662
663 printSuccessors(O, Indent);
664}
665#endif
666
667std::pair<VPBlockBase *, VPBlockBase *>
670 VPBlockBase *Exiting = nullptr;
671 bool InRegion = Entry->getParent();
672 // First, clone blocks reachable from Entry.
673 for (VPBlockBase *BB : vp_depth_first_shallow(Entry)) {
674 VPBlockBase *NewBB = BB->clone();
675 Old2NewVPBlocks[BB] = NewBB;
676 if (InRegion && BB->getNumSuccessors() == 0) {
677 assert(!Exiting && "Multiple exiting blocks?");
678 Exiting = BB;
679 }
680 }
681 assert((!InRegion || Exiting) && "regions must have a single exiting block");
682
683 // Second, update the predecessors & successors of the cloned blocks.
684 for (VPBlockBase *BB : vp_depth_first_shallow(Entry)) {
685 VPBlockBase *NewBB = Old2NewVPBlocks[BB];
687 for (VPBlockBase *Pred : BB->getPredecessors()) {
688 NewPreds.push_back(Old2NewVPBlocks[Pred]);
689 }
690 NewBB->setPredecessors(NewPreds);
692 for (VPBlockBase *Succ : BB->successors()) {
693 NewSuccs.push_back(Old2NewVPBlocks[Succ]);
694 }
695 NewBB->setSuccessors(NewSuccs);
696 }
697
698#if !defined(NDEBUG)
699 // Verify that the order of predecessors and successors matches in the cloned
700 // version.
701 for (const auto &[OldBB, NewBB] :
703 vp_depth_first_shallow(Old2NewVPBlocks[Entry]))) {
704 for (const auto &[OldPred, NewPred] :
705 zip(OldBB->getPredecessors(), NewBB->getPredecessors()))
706 assert(NewPred == Old2NewVPBlocks[OldPred] && "Different predecessors");
707
708 for (const auto &[OldSucc, NewSucc] :
709 zip(OldBB->successors(), NewBB->successors()))
710 assert(NewSucc == Old2NewVPBlocks[OldSucc] && "Different successors");
711 }
712#endif
713
714 return std::make_pair(Old2NewVPBlocks[Entry],
715 Exiting ? Old2NewVPBlocks[Exiting] : nullptr);
716}
717
719 const auto *EntryBB = cast<VPBasicBlock>(getEntry());
720 assert(isReplicator() && EntryBB && EntryBB->size() == 1 &&
721 "not a valid replicating region");
722 return cast<VPBranchOnMaskRecipe>(&EntryBB->front());
723}
724
725VPRegionBlock *VPRegionBlock::clone() {
726 const auto &[NewEntry, NewExiting] = VPBlockUtils::cloneFrom(getEntry());
727 VPlan &Plan = *getPlan();
728 VPRegionValue *CanIV = getCanonicalIV();
729 VPRegionBlock *NewRegion =
730 CanIV ? Plan.createLoopRegion(CanIV->getType(), CanIV->getDebugLoc(),
731 getName(), NewEntry, NewExiting)
732 : Plan.createReplicateRegion(NewEntry, NewExiting, getName());
733
734 if (getHeaderMask())
735 NewRegion->createHeaderMask();
736
737 if (CanIV && !hasCanonicalIVNUW())
738 NewRegion->CanIVInfo->clearNUW();
739
740 for (VPBlockBase *Block : vp_depth_first_shallow(NewEntry))
741 Block->setParent(NewRegion);
742 return NewRegion;
743}
744
746 llvm_unreachable("regions must get dissolved before ::execute");
747}
748
751 for (VPRecipeBase &R : Recipes)
752 Cost += R.cost(VF, Ctx);
753 return Cost;
754}
755
756const VPBasicBlock *VPBasicBlock::getCFGPredecessor(unsigned Idx) const {
757 const VPBlockBase *Pred = nullptr;
758 if (hasPredecessors()) {
759 Pred = getPredecessors()[Idx];
760 } else {
761 auto *Region = getParent();
762 assert(Region && !Region->isReplicator() && Region->getEntry() == this &&
763 "must be in the entry block of a non-replicate region");
764 assert(Idx < 2 && Region->getNumPredecessors() == 1 &&
765 "loop region has a single predecessor (preheader), its entry block "
766 "has 2 incoming blocks");
767
768 // Idx == 0 selects the predecessor of the region, Idx == 1 selects the
769 // region itself whose exiting block feeds the phi across the backedge.
770 Pred = Idx == 0 ? Region->getSinglePredecessor() : Region;
771 }
772 return Pred->getExitingBasicBlock();
773}
774
776 if (!isReplicator()) {
779 Cost += Block->cost(VF, Ctx);
780 // Add the costs of the loop's backedge and canonical IV increment
781 auto AddCost = [&](InstructionCost C, const char *Name) {
782 if (ForceTargetInstructionCost.getNumOccurrences())
784 LLVM_DEBUG(dbgs() << "Cost of " << C << " for VF " << VF << ": " << Name
785 << "\n");
786 Cost += C;
787 };
788 AddCost(Ctx.TTI.getCFInstrCost(Instruction::UncondBr, Ctx.CostKind),
789 "vector loop backedge");
791 AddCost(Ctx.TTI.getArithmeticInstrCost(
792 Instruction::Add, getCanonicalIVType(), Ctx.CostKind),
793 "canonical IV increment");
794 return Cost;
795 }
796
797 // Compute the cost of a replicate region. Replicating isn't supported for
798 // scalable vectors, return an invalid cost for them.
799 // TODO: Discard scalable VPlans with replicate recipes earlier after
800 // construction.
801 if (VF.isScalable())
803
804 // Compute and return the cost of the conditionally executed recipes.
805 assert(VF.isVector() && "Can only compute vector cost at the moment.");
807 return Then->cost(VF, Ctx);
808}
809
810#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
812 VPSlotTracker &SlotTracker) const {
813 O << Indent << (isReplicator() ? "<xVFxUF> " : "<x1> ") << getName() << ": {";
814 auto NewIndent = Indent + " ";
815 if (auto *CanIV = getCanonicalIV()) {
816 O << '\n';
817 CanIV->print(O, SlotTracker);
818 O << " = CANONICAL-IV\n";
819 }
820 if (auto *HdrMask = getUsedHeaderMask()) {
821 HdrMask->print(O, SlotTracker);
822 O << " = HEADER-MASK\n";
823 }
824 for (auto *BlockBase : vp_depth_first_shallow(Entry)) {
825 O << '\n';
826 BlockBase->print(O, NewIndent, SlotTracker);
827 }
828 O << Indent << "}\n";
829
830 printSuccessors(O, Indent);
831}
832#endif
833
835 auto *Header = cast<VPBasicBlock>(getEntry());
836 auto *ExitingLatch = cast<VPBasicBlock>(getExiting());
837 auto *CanIV = getCanonicalIV();
838 if (!CanIV->user_empty()) {
839 VPlan &Plan = *getPlan();
840 auto *Zero = Plan.getZero(CanIV->getType());
841 DebugLoc DL = CanIV->getDebugLoc();
843 VPBuilder HeaderBuilder(Header, Header->begin());
844 auto *ScalarR =
845 HeaderBuilder.createScalarPhi({Zero, CanIVInc}, DL, "index");
846 CanIV->replaceAllUsesWith(ScalarR);
847 }
848
849 VPBlockBase *Preheader = getSinglePredecessor();
850 VPBlockUtils::disconnectBlocks(Preheader, this);
851
852 for (VPBlockBase *VPB : vp_depth_first_shallow(Entry))
853 VPB->setParent(getParent());
854
855 VPBlockUtils::connectBlocks(Preheader, Header);
856 VPBlockUtils::transferSuccessors(this, ExitingLatch);
857 VPBlockUtils::connectBlocks(ExitingLatch, Header);
858}
859
861 // TODO: Represent the increment as VPRegionValue as well.
862 VPRegionValue *CanIV = getCanonicalIV();
863 assert(CanIV && "Expected a canonical IV");
864
865 if (auto *Inc = vputils::findCanonicalIVIncrement(*getPlan()))
866 return Inc;
867
868 assert(!getPlan()->getVFxUF().isMaterialized() &&
869 "VFxUF can be used only before it is materialized.");
870 auto *ExitingLatch = cast<VPBasicBlock>(getExiting());
871 return VPBuilder(ExitingLatch->getTerminator())
872 .createOverflowingOp(Instruction::Add, {CanIV, &getPlan()->getVFxUF()},
873 {hasCanonicalIVNUW(), /* HasNSW */ false},
874 CanIV->getDebugLoc(), "index.next");
875}
876
877VPlan::VPlan(Loop *L, Type *IdxTy)
878 : VectorTripCount(IdxTy), VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
879 setEntry(createVPIRBasicBlock(L->getLoopPreheader()));
880 ScalarHeader = createVPIRBasicBlock(L->getHeader());
881
882 SmallVector<BasicBlock *> IRExitBlocks;
883 L->getUniqueExitBlocks(IRExitBlocks);
884 for (BasicBlock *EB : IRExitBlocks)
885 ExitBlocks.push_back(createVPIRBasicBlock(EB));
886}
887
889 VPSymbolicValue DummyValue(nullptr);
890
891 // Redirect all recipe operands to DummyValue before deleting blocks.
892 for (VPBasicBlock *VPBB :
894 for (VPRecipeBase &R : *VPBB)
895 for (unsigned I = 0, E = R.getNumOperands(); I != E; I++)
896 R.setOperand(I, &DummyValue);
897
898 for (auto [Idx, VPB] : enumerate(CreatedBlocks)) {
899 assert(VPB->getNumber() == Idx && "block with mismatched number");
900 delete VPB;
901 }
902 for (VPValue *VPV : getLiveIns())
903 delete VPV;
904 delete BackedgeTakenCount;
905}
906
908 return is_contained(ExitBlocks, VPBB);
909}
910
911/// To make RUN_VPLAN_PASS print final VPlan.
912static void printFinalVPlan(VPlan &) {}
913
914/// Generate the code inside the preheader and body of the vectorized loop.
915/// Assumes a single pre-header basic-block was created for this. Introduce
916/// additional basic-blocks as needed, and fill them all.
919 "all region blocks must be dissolved before ::execute");
920
921 // Initialize CFG state.
922 State->CFG.PrevVPBB = nullptr;
923 State->CFG.ExitBB = State->CFG.PrevBB->getSingleSuccessor();
924
925 // Update VPDominatorTree since VPBasicBlock may be removed after State was
926 // constructed.
927 State->VPDT.recalculate(*this);
928
929 // Disconnect VectorPreHeader from ExitBB in both the CFG and DT.
930 BasicBlock *VectorPreHeader = State->CFG.PrevBB;
931 cast<UncondBrInst>(VectorPreHeader->getTerminator())->setSuccessor(nullptr);
932 State->CFG.DTU.applyUpdates(
933 {{DominatorTree::Delete, VectorPreHeader, State->CFG.ExitBB}});
934
935 LLVM_DEBUG(dbgs() << "Executing best plan with VF=" << State->VF
936 << ", UF=" << getConcreteUF() << '\n');
937 setName("Final VPlan");
938 // TODO: RUN_VPLAN_PASS/VPlanTransforms::runPass should automatically dump
939 // VPlans after some specific stages when "-debug" is specified, but that
940 // hasn't been implemented yet. For now, just do both:
941 LLVM_DEBUG(dump());
943
944 BasicBlock *ScalarPh = State->CFG.ExitBB;
945 VPBasicBlock *ScalarPhVPBB = getScalarPreheader();
946 if (ScalarPhVPBB) {
947 // Disconnect scalar preheader and scalar header, as the dominator tree edge
948 // will be updated as part of VPlan execution. This allows keeping the DTU
949 // logic generic during VPlan execution.
950 State->CFG.DTU.applyUpdates(
951 {{DominatorTree::Delete, ScalarPh, ScalarPh->getSingleSuccessor()}});
952 }
954 Entry);
955 // Generate code for the VPlan, in parts of the vector skeleton, loop body and
956 // successor blocks including the middle, exit and scalar preheader blocks.
957 for (VPBlockBase *Block : RPOT)
958 Block->execute(State);
959
960 if (hasEarlyExit()) {
961 // Fix up LoopInfo for extra dispatch blocks when vectorizing loops with
962 // early exits. For dispatch blocks, we need to find the smallest common
963 // loop of all successors that are in a loop. Note: we only need to update
964 // loop info for blocks after the middle block, but there is no easy way to
965 // get those at this point.
966 for (VPBlockBase *VPB : reverse(RPOT)) {
967 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
968 if (!VPBB || isa<VPIRBasicBlock>(VPBB))
969 continue;
970 BasicBlock *BB = State->CFG.VPBB2IRBB[VPBB];
971 Loop *L = State->LI->getLoopFor(BB);
972 if (!L || any_of(successors(BB),
973 [L](BasicBlock *Succ) { return L->contains(Succ); }))
974 continue;
975 // Find the innermost loop containing all successors that are in a loop.
976 // Successors not in any loop don't constrain the target loop.
977 Loop *Target = nullptr;
978 for (BasicBlock *Succ : successors(BB)) {
979 Loop *SuccLoop = State->LI->getLoopFor(Succ);
980 if (!SuccLoop)
981 continue;
982 if (!Target)
983 Target = SuccLoop;
984 else
985 Target = State->LI->getSmallestCommonLoop(Target, SuccLoop);
986 }
987 State->LI->removeBlock(BB);
988 if (Target)
989 Target->addBasicBlockToLoop(BB, *State->LI);
990 }
991 }
992
993 // If the original loop is unreachable, delete it and all its blocks.
994 if (!ScalarPhVPBB) {
995 // DeleteDeadBlocks will remove single-entry phis. Remove them from the exit
996 // VPIRBBs in VPlan as well, otherwise we would retain references to deleted
997 // IR instructions.
998 for (VPIRBasicBlock *EB : getExitBlocks()) {
999 for (VPRecipeBase &R : make_early_inc_range(EB->phis())) {
1000 if (R.getNumOperands() == 1)
1001 R.eraseFromParent();
1002 }
1003 }
1004
1005 Loop *OrigLoop =
1006 State->LI->getLoopFor(getScalarHeader()->getIRBasicBlock());
1007 SmallVector<BasicBlock *> Blocks(OrigLoop->block_begin(),
1008 OrigLoop->block_end());
1009 Blocks.push_back(ScalarPh);
1010 while (!OrigLoop->isInnermost())
1011 State->LI->erase(*OrigLoop->begin());
1012 State->LI->erase(OrigLoop);
1013 for (auto *BB : Blocks)
1014 State->LI->removeBlock(BB);
1015 DeleteDeadBlocks(Blocks, &State->CFG.DTU);
1016 }
1017
1018 State->CFG.DTU.flush();
1019
1020 // Fix the latch (backedge) value of all header phis in all loop headers.
1021 State->fixupHeaderPhis();
1022}
1023
1025 // For now only return the cost of the vector loop region, ignoring any other
1026 // blocks, like the preheader or middle blocks, expect for checking them for
1027 // recipes with invalid costs.
1029
1030 // If the cost of the loop region is invalid or any recipe in the skeleton
1031 // outside loop regions are invalid return an invalid cost.
1034 [&VF, &Ctx](VPBasicBlock *VPBB) {
1035 return !VPBB->cost(VF, Ctx).isValid();
1036 }))
1038
1039 return Cost;
1040}
1041
1043 // Find the vector loop region by following the last successor of each block,
1044 // starting from the plan's entry; the vector code path is always the last
1045 // successor. Every block on the path has a single predecessor, except the
1046 // vector preheader, which is also entered from the block bypassing the main
1047 // vector loop when vectorizing the epilogue. Stop at any other block with
1048 // multiple predecessors: in a plain CFG that is the loop header (no region
1049 // exists yet), in a region based CFG the scalar preheader.
1050 for (VPBlockBase *B = Entry; B;) {
1051 if (auto *R = dyn_cast<VPRegionBlock>(B))
1052 return R->isReplicator() || R->getNumPredecessors() != 1 ? nullptr : R;
1053 VPBlockBase *Succ =
1054 B->hasSuccessors() ? B->getSuccessors().back() : nullptr;
1055 if (B->getNumPredecessors() > 1 && !isa_and_present<VPRegionBlock>(Succ))
1056 return nullptr;
1057 B = Succ;
1058 }
1059 return nullptr;
1060}
1061
1063 return const_cast<VPlan *>(this)->getVectorLoopRegion();
1064}
1065
1067 const VPRegionBlock *LoopRegion = getVectorLoopRegion();
1068 assert(LoopRegion && "expected a vector loop region");
1070 vp_depth_first_shallow(LoopRegion->getEntry())),
1071 [](const VPRegionBlock *R) { return !R->isReplicator(); });
1072}
1073
1074#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1077
1078 if (!VF.user_empty()) {
1079 O << "\nLive-in ";
1080 VF.printAsOperand(O, SlotTracker);
1081 O << " = VF";
1082 }
1083
1084 if (!UF.user_empty()) {
1085 O << "\nLive-in ";
1086 UF.printAsOperand(O, SlotTracker);
1087 O << " = UF";
1088 }
1089
1090 if (!VFxUF.user_empty()) {
1091 O << "\nLive-in ";
1092 VFxUF.printAsOperand(O, SlotTracker);
1093 O << " = VF * UF";
1094 }
1095
1096 if (!VectorTripCount.user_empty()) {
1097 O << "\nLive-in ";
1098 VectorTripCount.printAsOperand(O, SlotTracker);
1099 O << " = vector-trip-count";
1100 }
1101
1102 if (BackedgeTakenCount && !BackedgeTakenCount->user_empty()) {
1103 O << "\nLive-in ";
1104 BackedgeTakenCount->printAsOperand(O, SlotTracker);
1105 O << " = backedge-taken count";
1106 }
1107
1108 O << "\n";
1109 if (TripCount && !TripCount->user_empty()) {
1110 if (isa<VPIRValue>(TripCount))
1111 O << "Live-in ";
1112 TripCount->printAsOperand(O, SlotTracker);
1113 O << " = original trip-count";
1114 O << "\n";
1115 }
1116}
1117
1121
1122 O << "VPlan '" << getName() << "' {";
1123
1124 printLiveIns(O);
1125
1127 RPOT(getEntry());
1128 for (const VPBlockBase *Block : RPOT) {
1129 O << '\n';
1130 Block->print(O, "", SlotTracker);
1131 }
1132
1133 O << "}\n";
1134}
1135
1136std::string VPlan::getName() const {
1137 std::string Out;
1138 raw_string_ostream RSO(Out);
1139 RSO << Name << " for ";
1140 if (!VFs.empty()) {
1141 RSO << "VF={" << VFs[0];
1142 for (ElementCount VF : drop_begin(VFs))
1143 RSO << "," << VF;
1144 RSO << "},";
1145 }
1146
1147 if (UFs.empty()) {
1148 RSO << "UF>=1";
1149 } else {
1150 RSO << "UF={" << UFs[0];
1151 for (unsigned UF : drop_begin(UFs))
1152 RSO << "," << UF;
1153 RSO << "}";
1154 }
1155
1156 return Out;
1157}
1158
1161 VPlanPrinter Printer(O, *this);
1162 Printer.dump();
1163}
1164
1166void VPlan::dump() const { print(dbgs()); }
1167#endif
1168
1169static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry,
1170 DenseMap<VPValue *, VPValue *> &Old2NewVPValues) {
1171 // Update the operands of all cloned recipes starting at NewEntry. This
1172 // traverses all reachable blocks. This is done in two steps, to handle cycles
1173 // in PHI recipes.
1175 OldDeepRPOT(Entry);
1177 NewDeepRPOT(NewEntry);
1178 // First, collect all mappings from old to new VPValues defined by cloned
1179 // recipes.
1180 for (const auto &[OldBB, NewBB] :
1183 assert(OldBB->getRecipeList().size() == NewBB->getRecipeList().size() &&
1184 "blocks must have the same number of recipes");
1185 for (const auto &[OldR, NewR] : zip(*OldBB, *NewBB)) {
1186 assert(OldR.getNumOperands() == NewR.getNumOperands() &&
1187 "recipes must have the same number of operands");
1188 assert(OldR.getNumDefinedValues() == NewR.getNumDefinedValues() &&
1189 "recipes must define the same number of operands");
1190 for (const auto &[OldV, NewV] :
1191 zip(OldR.definedValues(), NewR.definedValues()))
1192 Old2NewVPValues[OldV] = NewV;
1193 }
1194 }
1195
1196 // Update all operands to use cloned VPValues.
1197 for (VPBasicBlock *NewBB :
1199 for (VPRecipeBase &NewR : *NewBB)
1200 for (unsigned I = 0, E = NewR.getNumOperands(); I != E; ++I) {
1201 VPValue *NewOp = Old2NewVPValues.lookup(NewR.getOperand(I));
1202 NewR.setOperand(I, NewOp);
1203 }
1204 }
1205}
1206
1208 unsigned NumBlocksBeforeCloning = CreatedBlocks.size();
1209 // Clone blocks.
1210 const auto &[NewEntry, __] = VPBlockUtils::cloneFrom(Entry);
1211
1212 BasicBlock *ScalarHeaderIRBB = getScalarHeader()->getIRBasicBlock();
1213 VPIRBasicBlock *NewScalarHeader = nullptr;
1214 if (getScalarHeader()->hasPredecessors()) {
1215 NewScalarHeader = cast<VPIRBasicBlock>(*find_if(
1216 vp_depth_first_shallow(NewEntry), [ScalarHeaderIRBB](VPBlockBase *VPB) {
1217 auto *VPIRBB = dyn_cast<VPIRBasicBlock>(VPB);
1218 return VPIRBB && VPIRBB->getIRBasicBlock() == ScalarHeaderIRBB;
1219 }));
1220 } else {
1221 NewScalarHeader = createVPIRBasicBlock(ScalarHeaderIRBB);
1222 }
1223 // Create VPlan, clone live-ins and remap operands in the cloned blocks.
1224 auto *NewPlan =
1225 new VPlan(cast<VPBasicBlock>(NewEntry), NewScalarHeader, getIndexType());
1226 DenseMap<VPValue *, VPValue *> Old2NewVPValues;
1227 for (VPIRValue *OldLiveIn : getLiveIns())
1228 Old2NewVPValues[OldLiveIn] = NewPlan->getOrAddLiveIn(OldLiveIn);
1229
1230 if (auto *TripCountIRV = dyn_cast_or_null<VPIRValue>(TripCount))
1231 Old2NewVPValues[TripCountIRV] = NewPlan->getOrAddLiveIn(TripCountIRV);
1232 // else NewTripCount will be created and inserted into Old2NewVPValues when
1233 // TripCount is cloned. In any case NewPlan->TripCount is updated below.
1234
1235 assert(none_of(Old2NewVPValues.keys(), IsaPred<VPSymbolicValue>) &&
1236 "All VPSymbolicValues must be handled below");
1237
1238 if (auto *LoopRegion = getVectorLoopRegion()) {
1239 auto *NewLoopRegion = NewPlan->getVectorLoopRegion();
1240 for (auto [Old, New] : zip_equal(LoopRegion->getRegionValues(),
1241 NewLoopRegion->getRegionValues())) {
1242 Old2NewVPValues[Old] = New;
1243 if (Old->isMaterialized())
1244 New->markMaterialized();
1245 }
1246 }
1247
1248 if (BackedgeTakenCount)
1249 NewPlan->BackedgeTakenCount =
1250 new VPSymbolicValue(BackedgeTakenCount->getType());
1251
1252 // Map and propagate materialized state for symbolic values.
1253 for (auto [OldSV, NewSV] :
1254 {std::pair{&VectorTripCount, &NewPlan->VectorTripCount},
1255 {&VF, &NewPlan->VF},
1256 {&UF, &NewPlan->UF},
1257 {&VFxUF, &NewPlan->VFxUF},
1258 {BackedgeTakenCount, NewPlan->BackedgeTakenCount}}) {
1259 if (!OldSV)
1260 continue;
1261 Old2NewVPValues[OldSV] = NewSV;
1262 if (OldSV->isMaterialized())
1263 NewSV->markMaterialized();
1264 }
1265
1266 remapOperands(Entry, NewEntry, Old2NewVPValues);
1267
1268 // Initialize remaining fields of cloned VPlan.
1269 NewPlan->VFs = VFs;
1270 NewPlan->UFs = UFs;
1271 // TODO: Adjust names.
1272 NewPlan->Name = Name;
1273 if (TripCount) {
1274 assert(Old2NewVPValues.contains(TripCount) &&
1275 "TripCount must have been added to Old2NewVPValues");
1276 NewPlan->TripCount = Old2NewVPValues[TripCount];
1277 }
1278
1279 // Transfer all cloned blocks (the second half of all current blocks) from
1280 // current to new VPlan.
1281 unsigned NumBlocksAfterCloning = CreatedBlocks.size();
1282 for (unsigned I :
1283 seq<unsigned>(NumBlocksBeforeCloning, NumBlocksAfterCloning)) {
1284 this->CreatedBlocks[I]->setPlan(NewPlan);
1285 this->CreatedBlocks[I]->setNumber(NewPlan->CreatedBlocks.size());
1286 NewPlan->CreatedBlocks.push_back(this->CreatedBlocks[I]);
1287 }
1288 CreatedBlocks.truncate(NumBlocksBeforeCloning);
1289
1290 // Update ExitBlocks of the new plan.
1291 for (VPBlockBase *VPB : NewPlan->CreatedBlocks) {
1292 if (VPB->getNumSuccessors() == 0 && isa<VPIRBasicBlock>(VPB) &&
1293 VPB != NewScalarHeader)
1294 NewPlan->ExitBlocks.push_back(cast<VPIRBasicBlock>(VPB));
1295 }
1296
1297 return NewPlan;
1298}
1299
1301 auto *VPIRBB = new VPIRBasicBlock(IRBB);
1302 VPIRBB->setPlan(this);
1303 VPIRBB->setNumber(CreatedBlocks.size());
1304 CreatedBlocks.push_back(VPIRBB);
1305 return VPIRBB;
1306}
1307
1309 auto *VPIRBB = createEmptyVPIRBasicBlock(IRBB);
1310 for (Instruction &I :
1311 make_range(IRBB->begin(), IRBB->getTerminator()->getIterator()))
1312 VPIRBB->appendRecipe(VPIRInstruction::create(I));
1313 return VPIRBB;
1314}
1315
1316#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1317
1318Twine VPlanPrinter::getUID(const VPBlockBase *Block) {
1319 return (isa<VPRegionBlock>(Block) ? "cluster_N" : "N") +
1320 Twine(getOrCreateBID(Block));
1321}
1322
1324 Depth = 1;
1325 bumpIndent(0);
1326 OS << "digraph VPlan {\n";
1327 OS << "graph [labelloc=t, fontsize=30; label=\"Vectorization Plan";
1328 if (!Plan.getName().empty())
1329 OS << "\\n" << DOT::EscapeString(Plan.getName());
1330
1331 {
1332 // Print live-ins.
1333 std::string Str;
1334 raw_string_ostream SS(Str);
1335 Plan.printLiveIns(SS);
1337 StringRef(Str).rtrim('\n').split(Lines, "\n");
1338 for (auto Line : Lines)
1339 OS << DOT::EscapeString(Line.str()) << "\\n";
1340 }
1341
1342 OS << "\"]\n";
1343 OS << "node [shape=rect, fontname=Courier, fontsize=30]\n";
1344 OS << "edge [fontname=Courier, fontsize=30]\n";
1345 OS << "compound=true\n";
1346
1347 for (const VPBlockBase *Block : vp_depth_first_shallow(Plan.getEntry()))
1348 dumpBlock(Block);
1349
1350 OS << "}\n";
1351}
1352
1353void VPlanPrinter::dumpBlock(const VPBlockBase *Block) {
1355 dumpBasicBlock(BasicBlock);
1357 dumpRegion(Region);
1358 else
1359 llvm_unreachable("Unsupported kind of VPBlock.");
1360}
1361
1362void VPlanPrinter::drawEdge(const VPBlockBase *From, const VPBlockBase *To,
1363 bool Hidden, const Twine &Label) {
1364 // Due to "dot" we print an edge between two regions as an edge between the
1365 // exiting basic block and the entry basic of the respective regions.
1366 const VPBlockBase *Tail = From->getExitingBasicBlock();
1367 const VPBlockBase *Head = To->getEntryBasicBlock();
1368 OS << Indent << getUID(Tail) << " -> " << getUID(Head);
1369 OS << " [ label=\"" << Label << '\"';
1370 if (Tail != From)
1371 OS << " ltail=" << getUID(From);
1372 if (Head != To)
1373 OS << " lhead=" << getUID(To);
1374 if (Hidden)
1375 OS << "; splines=none";
1376 OS << "]\n";
1377}
1378
1379void VPlanPrinter::dumpEdges(const VPBlockBase *Block) {
1380 auto &Successors = Block->getSuccessors();
1381 if (Successors.size() == 1)
1382 drawEdge(Block, Successors.front(), false, "");
1383 else if (Successors.size() == 2) {
1384 drawEdge(Block, Successors.front(), false, "T");
1385 drawEdge(Block, Successors.back(), false, "F");
1386 } else {
1387 unsigned SuccessorNumber = 0;
1388 for (auto *Successor : Successors)
1389 drawEdge(Block, Successor, false, Twine(SuccessorNumber++));
1390 }
1391}
1392
1393void VPlanPrinter::dumpBasicBlock(const VPBasicBlock *BasicBlock) {
1394 // Implement dot-formatted dump by performing plain-text dump into the
1395 // temporary storage followed by some post-processing.
1396 OS << Indent << getUID(BasicBlock) << " [label =\n";
1397 bumpIndent(1);
1398 std::string Str;
1399 raw_string_ostream SS(Str);
1400 // Use no indentation as we need to wrap the lines into quotes ourselves.
1401 BasicBlock->print(SS, "", SlotTracker);
1402
1403 // We need to process each line of the output separately, so split
1404 // single-string plain-text dump.
1406 StringRef(Str).rtrim('\n').split(Lines, "\n");
1407
1408 auto EmitLine = [&](StringRef Line, StringRef Suffix) {
1409 OS << Indent << '"' << DOT::EscapeString(Line.str()) << "\\l\"" << Suffix;
1410 };
1411
1412 // Don't need the "+" after the last line.
1413 for (auto Line : make_range(Lines.begin(), Lines.end() - 1))
1414 EmitLine(Line, " +\n");
1415 EmitLine(Lines.back(), "\n");
1416
1417 bumpIndent(-1);
1418 OS << Indent << "]\n";
1419
1420 dumpEdges(BasicBlock);
1421}
1422
1423void VPlanPrinter::dumpRegion(const VPRegionBlock *Region) {
1424 OS << Indent << "subgraph " << getUID(Region) << " {\n";
1425 bumpIndent(1);
1426 OS << Indent << "fontname=Courier\n"
1427 << Indent << "label=\""
1428 << DOT::EscapeString(Region->isReplicator() ? "<xVFxUF> " : "<x1> ")
1429 << DOT::EscapeString(Region->getName()) << "\"\n";
1430
1431 if (auto *CanIV = Region->getCanonicalIV()) {
1432 OS << Indent << "\"";
1433 std::string Op;
1434 raw_string_ostream S(Op);
1435 CanIV->printAsOperand(S, SlotTracker);
1436 OS << DOT::EscapeString(Op);
1437 OS << " = CANONICAL-IV\"\n";
1438 }
1439
1440 // Dump the blocks of the region.
1441 assert(Region->getEntry() && "Region contains no inner blocks.");
1442 for (const VPBlockBase *Block : vp_depth_first_shallow(Region->getEntry()))
1443 dumpBlock(Block);
1444 bumpIndent(-1);
1445 OS << Indent << "}\n";
1446 dumpEdges(Region);
1447}
1448
1449#endif
1450
1451/// Returns true if there is a vector loop region and \p VPV is defined in a
1452/// loop region.
1453static bool isDefinedInsideLoopRegions(const VPValue *VPV) {
1454 if (isa<VPRegionValue>(VPV))
1455 return true;
1456 const VPRecipeBase *DefR = VPV->getDefiningRecipe();
1457 return DefR && (DefR->getParent()->getEnclosingLoopRegion() ||
1458 !DefR->getParent()->getPlan()->getVectorLoopRegion());
1459}
1460
1465 replaceUsesWithIf(New, [](VPUser &, unsigned) { return true; });
1466 if (auto *SV = dyn_cast<VPSymbolicValue>(this))
1467 SV->markMaterialized();
1468}
1469
1471 VPValue *New,
1472 llvm::function_ref<bool(VPUser &U, unsigned Idx)> ShouldReplace) {
1474 // Note that this early exit is required for correctness; the implementation
1475 // below relies on the number of users for this VPValue to decrease, which
1476 // isn't the case if this == New.
1477 if (this == New)
1478 return;
1479
1480 for (unsigned J = 0; J < getNumUsers();) {
1481 VPUser *User = Users[J];
1482 bool RemovedUser = false;
1483 for (unsigned I = 0, E = User->getNumOperands(); I < E; ++I) {
1484 if (User->getOperand(I) != this || !ShouldReplace(*User, I))
1485 continue;
1486
1487 RemovedUser = true;
1488 User->setOperand(I, New);
1489 }
1490 // If a user got removed after updating the current user, the next user to
1491 // update will be moved to the current position, so we only need to
1492 // increment the index if the number of users did not change.
1493 if (!RemovedUser)
1494 J++;
1495 }
1496}
1497
1499 for (unsigned Idx = 0; Idx != getNumOperands(); ++Idx) {
1500 if (getOperand(Idx) == From)
1501 setOperand(Idx, To);
1502 }
1503}
1504
1505#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1507 OS << Tracker.getOrCreateName(this);
1508}
1509
1512 Op->printAsOperand(O, SlotTracker);
1513 });
1514}
1515#endif
1516
1517void VPSlotTracker::assignName(const VPValue *V) {
1518 assert(!VPValue2Name.contains(V) && "VPValue already has a name!");
1519 auto *UV = V->getUnderlyingValue();
1520 auto *VPI = dyn_cast_or_null<VPInstruction>(V);
1521 if (!UV && !(VPI && !VPI->getName().empty())) {
1522 VPValue2Name[V] = (Twine("vp<%") + Twine(NextSlot) + ">").str();
1523 NextSlot++;
1524 return;
1525 }
1526
1527 // Use the name of the underlying Value, wrapped in "ir<>", and versioned by
1528 // appending ".Number" to the name if there are multiple uses.
1529 std::string Name;
1530 if (UV)
1531 Name = getName(UV);
1532 else
1533 Name = VPI->getName();
1534
1535 assert(!Name.empty() && "Name cannot be empty.");
1536 StringRef Prefix = UV ? "ir<" : "vp<%";
1537 std::string BaseName = (Twine(Prefix) + Name + Twine(">")).str();
1538
1539 // First assign the base name for V.
1540 const auto &[A, _] = VPValue2Name.try_emplace(V, BaseName);
1541 // Integer or FP constants with different types will result in the same string
1542 // due to stripping types.
1544 return;
1545
1546 // If it is already used by C > 0 other VPValues, increase the version counter
1547 // C and use it for V.
1548 const auto &[C, UseInserted] = BaseName2Version.try_emplace(BaseName, 0);
1549 if (!UseInserted) {
1550 C->second++;
1551 A->second = (BaseName + Twine(".") + Twine(C->second)).str();
1552 }
1553}
1554
1555void VPSlotTracker::assignNames(const VPlan &Plan) {
1556 if (!Plan.VF.user_empty())
1557 assignName(&Plan.VF);
1558 if (!Plan.UF.user_empty())
1559 assignName(&Plan.UF);
1560 if (!Plan.VFxUF.user_empty())
1561 assignName(&Plan.VFxUF);
1562 assignName(&Plan.VectorTripCount);
1563 if (Plan.BackedgeTakenCount)
1564 assignName(Plan.BackedgeTakenCount);
1565 for (VPValue *LI : Plan.getLiveIns())
1566 assignName(LI);
1567
1568 ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<const VPBlockBase *>>
1569 RPOT(VPBlockDeepTraversalWrapper<const VPBlockBase *>(Plan.getEntry()));
1570 for (const VPBlockBase *VPB : RPOT) {
1571 if (auto *VPBB = dyn_cast<VPBasicBlock>(VPB))
1572 assignNames(VPBB);
1573 else
1574 for (auto *RV : cast<VPRegionBlock>(VPB)->getRegionValues())
1575 assignName(RV);
1576 }
1577}
1578
1579void VPSlotTracker::assignNames(const VPBasicBlock *VPBB) {
1580 for (const VPRecipeBase &Recipe : *VPBB)
1581 for (VPValue *Def : Recipe.definedValues())
1582 assignName(Def);
1583}
1584
1585ModuleSlotTracker &VPSlotTracker::getOrCreateMST() {
1586 // F is null for unit tests with incomplete IR.
1587 if (!MST) {
1588 MST = std::make_unique<ModuleSlotTracker>(getModule());
1589 if (F)
1590 MST->incorporateFunction(*F);
1591 }
1592 return *MST;
1593}
1594
1595std::string VPSlotTracker::getName(const Value *V) {
1596 std::string Name;
1597 raw_string_ostream S(Name);
1598 // If V isn't an instruction in a basic block or named, it can be printed
1599 // directly without ModuleSlotTracker.
1600 auto *I = dyn_cast<Instruction>(V);
1601 if (!I || I->hasName() || !I->getParent()) {
1602 V->printAsOperand(S, false);
1603 return Name;
1604 }
1605
1606 V->printAsOperand(S, false, getOrCreateMST());
1607 return Name;
1608}
1609
1610std::string VPSlotTracker::getOrCreateName(const VPValue *V) const {
1611 std::string Name = VPValue2Name.lookup(V);
1612 if (!Name.empty())
1613 return Name;
1614
1615 // If no name was assigned, no VPlan was provided when creating the slot
1616 // tracker or it is not reachable from the provided VPlan. This can happen,
1617 // e.g. when trying to print a recipe that has not been inserted into a VPlan
1618 // in a debugger.
1619 // TODO: Update VPSlotTracker constructor to assign names to recipes &
1620 // VPValues not associated with a VPlan, instead of constructing names ad-hoc
1621 // here.
1622
1623 // Use the underlying value's name, if there is one.
1624 if (auto *UV = V->getUnderlyingValue()) {
1625 std::string Name;
1626 raw_string_ostream S(Name);
1627 UV->printAsOperand(S, false);
1628 return (Twine("ir<") + Name + ">").str();
1629 }
1630
1631 return "<badref>";
1632}
1633
1635 VPValue *TrueVal,
1636 VPValue *FalseVal, DebugLoc DL) {
1637 assert(ChainOp->getScalarType()->isIntegerTy(1) &&
1638 "ChainOp must be i1 for AnyOf reduction");
1639 VPIRFlags Flags(RecurKind::Or, /*IsOrdered=*/false, /*IsInLoop=*/false,
1640 FastMathFlags());
1641 auto *OrReduce =
1643 auto *Freeze = createNaryOp(Instruction::Freeze, {OrReduce}, DL);
1644 return createSelect(Freeze, TrueVal, FalseVal, DL, "rdx.select");
1645}
1646
1648 const std::function<bool(ElementCount)> &Predicate, VFRange &Range) {
1649 assert(!Range.isEmpty() && "Trying to test an empty VF range.");
1650 bool PredicateAtRangeStart = Predicate(Range.Start);
1651
1652 for (ElementCount TmpVF : VFRange(Range.Start * 2, Range.End))
1653 if (Predicate(TmpVF) != PredicateAtRangeStart) {
1654 Range.End = TmpVF;
1655 break;
1656 }
1657
1658 return PredicateAtRangeStart;
1659}
1660
1663 bool Reverse, DebugLoc DL) {
1664 VPlan &Plan = getPlan();
1666 if (Reverse) {
1667 // When folding the tail, we may compute an address that we don't in the
1668 // original scalar loop: drop the GEP no-wrap flags in this case. Otherwise
1669 // preserve existing flags without no-unsigned-wrap, as we will emit
1670 // negative indices.
1671 GEPNoWrapFlags ReverseFlags = Plan.hasTailFolded()
1673 : Flags.withoutNoUnsignedWrap();
1674 return tryInsertInstruction(new VPVectorEndPointerRecipe(
1675 Ptr, &Plan.getVF(), SourceElementTy, /*Stride=*/-1, ReverseFlags, DL));
1676 }
1677 Type *StrideTy = Plan.getDataLayout().getIndexType(Ptr->getScalarType());
1678 VPValue *StrideOne = Plan.getConstantInt(StrideTy, 1);
1679 return createVectorPointer(Ptr, SourceElementTy, StrideOne, Flags, DL);
1680}
1681
1683 assert(count_if(VPlans,
1684 [VF](const VPlanPtr &Plan) { return Plan->hasVF(VF); }) ==
1685 1 &&
1686 "Multiple VPlans for VF.");
1687
1688 for (const VPlanPtr &Plan : VPlans) {
1689 if (Plan->hasVF(VF))
1690 return *Plan.get();
1691 }
1692 llvm_unreachable("No plan found!");
1693}
1694
1697 // Reserve first location for self reference to the LoopID metadata node.
1698 MDs.push_back(nullptr);
1699 bool IsUnrollMetadata = false;
1700 MDNode *LoopID = L->getLoopID();
1701 if (LoopID) {
1702 // First find existing loop unrolling disable metadata.
1703 for (unsigned I = 1, IE = LoopID->getNumOperands(); I < IE; ++I) {
1704 auto *MD = dyn_cast<MDNode>(LoopID->getOperand(I));
1705 if (MD) {
1706 const auto *S = dyn_cast<MDString>(MD->getOperand(0));
1707 if (!S)
1708 continue;
1709 if (S->getString().starts_with("llvm.loop.unroll.runtime.disable"))
1710 continue;
1711 IsUnrollMetadata =
1712 S->getString().starts_with("llvm.loop.unroll.disable");
1713 }
1714 MDs.push_back(LoopID->getOperand(I));
1715 }
1716 }
1717
1718 if (!IsUnrollMetadata) {
1719 // Add runtime unroll disable metadata.
1720 LLVMContext &Context = L->getHeader()->getContext();
1721 SmallVector<Metadata *, 1> DisableOperands;
1722 DisableOperands.push_back(
1723 MDString::get(Context, "llvm.loop.unroll.runtime.disable"));
1724 MDNode *DisableNode = MDNode::get(Context, DisableOperands);
1725 MDs.push_back(DisableNode);
1726 MDNode *NewLoopID = MDNode::get(Context, MDs);
1727 // Set operand 0 to refer to the loop id itself.
1728 NewLoopID->replaceOperandWith(0, NewLoopID);
1729 L->setLoopID(NewLoopID);
1730 }
1731}
1732
1734 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
1735 bool VectorizingEpilogue, MDNode *OrigLoopID,
1736 std::optional<unsigned> OrigAverageTripCount,
1737 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1738 bool DisableRuntimeUnroll, bool UnrollVectorizedLoop) {
1739 // Update the metadata of the scalar loop. Skip the update when vectorizing
1740 // the epilogue loop to ensure it is updated only once. Also skip the update
1741 // when the scalar loop became unreachable.
1742 auto *ScalarPH = Plan.getScalarPreheader();
1743 if (ScalarPH && !VectorizingEpilogue) {
1744 std::optional<MDNode *> RemainderLoopID =
1747 if (RemainderLoopID) {
1748 OrigLoop->setLoopID(*RemainderLoopID);
1749 } else {
1750 if (DisableRuntimeUnroll)
1752
1753 LoopVectorizeHints Hints(OrigLoop, /*InterleaveOnlyWhenForced*/ false,
1754 *ORE);
1755 Hints.setAlreadyVectorized();
1756 }
1757 }
1758 // Tag the scalar remainder so downstream passes (e.g. the unroller and
1759 // WarnMissedTransforms) can produce more informative remarks. Only emit
1760 // when remarks are enabled.
1761 if (ORE->enabled() && ScalarPH && ScalarPH->hasPredecessors())
1762 OrigLoop->addIntLoopAttribute("llvm.loop.vectorize.epilogue", 1);
1763
1764 if (!VectorLoop)
1765 return;
1766
1767 if (std::optional<MDNode *> VectorizedLoopID = makeFollowupLoopID(
1768 OrigLoopID, {LLVMLoopVectorizeFollowupAll,
1770 VectorLoop->setLoopID(*VectorizedLoopID);
1771 } else {
1772 // Keep all loop hints from the original loop on the vector loop (we'll
1773 // replace the vectorizer-specific hints below).
1774 if (OrigLoopID)
1775 VectorLoop->setLoopID(OrigLoopID);
1776
1777 if (!VectorizingEpilogue) {
1778 LoopVectorizeHints Hints(VectorLoop, /*InterleaveOnlyWhenForced*/ false,
1779 *ORE);
1780 Hints.setAlreadyVectorized();
1781 }
1782 }
1783 // Tag the vector loop body so downstream passes can identify it. Only
1784 // emit when remarks are enabled.
1785 if (ORE->enabled())
1786 VectorLoop->addIntLoopAttribute("llvm.loop.vectorize.body", 1);
1787 if (!UnrollVectorizedLoop || VectorizingEpilogue)
1789
1790 // Set/update profile weights for the vector and remainder loops as original
1791 // loop iterations are now distributed among them. Note that original loop
1792 // becomes the scalar remainder loop after vectorization.
1793 //
1794 // For cases like foldTailByMasking() and requiresScalarEpiloque() we may
1795 // end up getting slightly roughened result but that should be OK since
1796 // profile is not inherently precise anyway. Note also possible bypass of
1797 // vector code caused by legality checks is ignored, assigning all the weight
1798 // to the vector loop, optimistically.
1799 //
1800 // For scalable vectorization we can't know at compile time how many
1801 // iterations of the loop are handled in one vector iteration, so instead
1802 // use the value of vscale used for tuning.
1803 unsigned AverageVectorTripCount = 0;
1804 unsigned RemainderAverageTripCount = 0;
1805 auto EC = VectorLoop->getLoopPreheader()->getParent()->getEntryCount();
1806 auto IsProfiled = EC && *EC != 0;
1807 if (!OrigAverageTripCount) {
1808 if (!IsProfiled)
1809 return;
1810 auto &SE = *PSE.getSE();
1811 AverageVectorTripCount = SE.getSmallConstantTripCount(VectorLoop);
1812 if (ProfcheckDisableMetadataFixes || !AverageVectorTripCount)
1813 return;
1814 if (ScalarPH)
1815 RemainderAverageTripCount =
1816 SE.getSmallConstantTripCount(OrigLoop) % EstimatedVFxUF;
1817 // Setting to 1 should be sufficient to generate the correct branch weights.
1818 OrigLoopInvocationWeight = 1;
1819 } else {
1820 // Calculate number of iterations in unrolled loop.
1821 AverageVectorTripCount = *OrigAverageTripCount / EstimatedVFxUF;
1822 // Calculate number of iterations for remainder loop.
1823 RemainderAverageTripCount = *OrigAverageTripCount % EstimatedVFxUF;
1824 }
1825 if (HeaderVPBB) {
1826 setLoopEstimatedTripCount(VectorLoop, AverageVectorTripCount,
1827 OrigLoopInvocationWeight);
1828 }
1829
1830 if (ScalarPH) {
1831 setLoopEstimatedTripCount(OrigLoop, RemainderAverageTripCount,
1832 OrigLoopInvocationWeight);
1833 }
1834}
1835
1836#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1838 if (VPlans.empty()) {
1839 O << "LV: No VPlans built.\n";
1840 return;
1841 }
1842 for (const auto &Plan : VPlans)
1844 Plan->printDOT(O);
1845 else
1846 Plan->print(O);
1847}
1848#endif
1849
1850bool llvm::canConstantBeExtended(const APInt *C, Type *NarrowType,
1852 APInt TruncatedVal = C->trunc(NarrowType->getScalarSizeInBits());
1853 unsigned WideSize = C->getBitWidth();
1854 APInt ExtendedVal = ExtKind == TTI::PR_SignExtend
1855 ? TruncatedVal.sext(WideSize)
1856 : TruncatedVal.zext(WideSize);
1857 return ExtendedVal == *C;
1858}
1859
1862 if (auto *IRV = dyn_cast<VPIRValue>(V))
1863 return TTI::getOperandInfo(IRV->getValue());
1864
1865 return {};
1866}
1867
1868#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1870 if (!PlanForSlotTracker)
1871 return nullptr;
1872 if (!SlotTracker)
1873 SlotTracker = std::make_unique<VPSlotTracker>(PlanForSlotTracker);
1874 return SlotTracker.get();
1875}
1876#endif
1877
1880 TTI::VectorInstrContext VIC, bool AlwaysIncludeReplicatingR) {
1881 if (VF.isScalar())
1882 return 0;
1883
1884 assert(!VF.isScalable() &&
1885 "Scalarization overhead not supported for scalable vectors");
1886
1887 InstructionCost ScalarizationCost = 0;
1888 // Compute the cost of scalarizing the result if needed.
1889 if (!ResultTy->isVoidTy()) {
1890 for (Type *VectorTy :
1891 to_vector(getContainedTypes(toVectorizedTy(ResultTy, VF)))) {
1892 ScalarizationCost += TTI.getScalarizationOverhead(
1894 /*Insert=*/true, /*Extract=*/false, CostKind,
1895 /*ForPoisonSrc=*/true, {}, VIC);
1896 }
1897 }
1898 // Compute the cost of scalarizing the operands, skipping ones that do not
1899 // require extraction/scalarization and do not incur any overhead.
1900 SmallPtrSet<const VPValue *, 4> UniqueOperands;
1902 for (auto *Op : Operands) {
1903 if (isa<VPIRValue>(Op) ||
1904 (!AlwaysIncludeReplicatingR &&
1907 cast<VPReplicateRecipe>(Op)->getOpcode() == Instruction::Load) ||
1908 !UniqueOperands.insert(Op).second)
1909 continue;
1910 Tys.push_back(toVectorizedTy(Op->getScalarType(), VF));
1911 }
1912 return ScalarizationCost +
1913 TTI.getOperandsScalarizationOverhead(Tys, CostKind, VIC);
1914}
1915
1917 ElementCount VF) {
1918 const Instruction *UI = R->getUnderlyingInstr();
1919 if (isa<LoadInst>(UI))
1920 return true;
1921 assert(isa<StoreInst>(UI) && "R must either be a load or store");
1922
1923 if (!NumPredStores) {
1924 // Count the number of predicated stores in the VPlan, caching the result.
1925 // Only stores where scatter is not legal are counted, matching the legacy
1926 // cost model behavior.
1927 const VPlan &Plan = *R->getParent()->getPlan();
1928 NumPredStores = 0;
1929 for (const VPRegionBlock *VPRB :
1932 assert(VPRB->isReplicator() && "must only contain replicate regions");
1933 for (const VPBasicBlock *VPBB :
1935 vp_depth_first_shallow(VPRB->getEntry()))) {
1936 for (const VPReplicateRecipe &RepR :
1938 if (!isa<StoreInst>(RepR.getUnderlyingInstr()))
1939 continue;
1940 // Check if scatter is legal for this store. If so, don't count it.
1941 Type *Ty = RepR.getOperand(0)->getScalarType();
1942 auto *VTy = VectorType::get(Ty, VF);
1943 const Align Alignment =
1944 getLoadStoreAlignment(RepR.getUnderlyingInstr());
1945 if (!TTI.isLegalMaskedScatter(VTy, Alignment))
1946 ++(*NumPredStores);
1947 }
1948 }
1949 }
1950 }
1952}
1953
1955 return is_contained({Intrinsic::assume, Intrinsic::lifetime_end,
1956 Intrinsic::lifetime_start, Intrinsic::sideeffect,
1957 Intrinsic::pseudoprobe,
1958 Intrinsic::experimental_noalias_scope_decl},
1959 ID);
1960}
1961
1962uint64_t
1963VPCostContext::getCostDivisor(std::optional<VPExecutionFrequency> Freq) const {
1964 if (CostKind == TTI::TCK_CodeSize || !Freq)
1965 return 1;
1966 // A recorded frequency is neither zero nor always-executing, so the
1967 // probability is non-zero and the division below is safe.
1968 return divideNearest(
1970 vputils::getExecutionProbability(Freq->Freq).getNumerator());
1971}
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:678
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:1695
static void printFinalVPlan(VPlan &)
To make RUN_VPLAN_PASS print final VPlan.
Definition VPlan.cpp:912
static T * getEnclosingLoopRegionForRegion(T *P)
Return the enclosing loop region for region P.
Definition VPlan.cpp:563
const char LLVMLoopVectorizeFollowupAll[]
Definition VPlan.cpp:64
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:1453
static bool hasConditionalTerminator(const VPBasicBlock *VPBB)
Definition VPlan.cpp:581
const char LLVMLoopVectorizeFollowupVectorized[]
Definition VPlan.cpp:65
static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry, DenseMap< VPValue *, VPValue * > &Old2NewVPValues)
Definition VPlan.cpp:1169
const char LLVMLoopVectorizeFollowupEpilogue[]
Definition VPlan.cpp:67
static cl::opt< bool > PrintVPlansInDotFormat("vplan-print-in-dot-format", cl::Hidden, cl::desc("Use dot format instead of plain text when dumping VPlans"))
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:446
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:467
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...
LLVM_ABI IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
A debug info location.
Definition DebugLoc.h:126
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:285
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:249
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:320
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:316
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
std::optional< uint64_t > getEntryCount() const
Get the entry count for this function.
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags none()
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
static InstructionCost getInvalid(CostType Val=0)
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
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:1682
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:1733
static bool getDecisionAndClampRange(const std::function< bool(ElementCount)> &Predicate, VFRange &Range)
Test a Predicate on a Range of VF's.
Definition VPlan.cpp:1647
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1837
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:615
void setLoopID(MDNode *LoopID) const
Set the llvm.loop loop id metadata for this loop.
Definition LoopInfo.cpp:583
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:320
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 isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
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:4427
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition VPlan.h:4502
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4454
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
Definition VPlan.cpp:485
iterator end()
Definition VPlan.h:4464
iterator begin()
Recipe iterator methods.
Definition VPlan.h:4462
VPBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Definition VPlan.cpp:519
InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override
Return the cost of this VPBasicBlock.
Definition VPlan.cpp:749
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:756
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:233
void connectToPredecessors(VPTransformState &State)
Connect the VPBBs predecessors' in the VPlan CFG to the IR basic block generated for this VPBB.
Definition VPlan.cpp:376
VPRegionBlock * getEnclosingLoopRegion()
Definition VPlan.cpp:573
VPBasicBlock * splitAt(iterator SplitAt)
Split current block at SplitAt by inserting a new block between the current block and its successors ...
Definition VPlan.cpp:540
RecipeListTy Recipes
The VPRecipes held in the order of output instructions to generate.
Definition VPlan.h:4442
void executeRecipes(VPTransformState *State, BasicBlock *BB)
Execute the recipes in the IR basic block BB.
Definition VPlan.cpp:526
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:653
bool isExiting() const
Returns true if the block is exiting it's parent region.
Definition VPlan.cpp:631
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:619
const VPRecipeBase & back() const
Definition VPlan.h:4476
bool empty() const
Definition VPlan.h:4473
size_t size() const
Definition VPlan.h:4472
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:95
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
Definition VPlan.h:315
VPRegionBlock * getParent()
Definition VPlan.h:193
const VPBasicBlock * getExitingBasicBlock() const
Definition VPlan.cpp:203
size_t getNumSuccessors() const
Definition VPlan.h:243
iterator_range< VPBlockBase ** > successors()
Definition VPlan.h:225
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:223
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:641
size_t getNumPredecessors() const
Definition VPlan.h:244
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
Definition VPlan.h:306
VPBlockBase * getEnclosingBlockWithPredecessors()
Definition VPlan.cpp:225
bool hasSuccessors() const
Returns true if this block has any successors.
Definition VPlan.h:221
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:228
VPlan * getPlan()
Definition VPlan.h:197
const std::string & getName() const
Definition VPlan.h:184
VPBlockBase * getSinglePredecessor() const
Definition VPlan.h:239
const VPBlocksTy & getHierarchicalSuccessors()
Definition VPlan.h:263
VPBlockBase * getEnclosingBlockWithSuccessors()
An Enclosing Block of a block B is any block containing B, including B itself.
Definition VPlan.cpp:217
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:188
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:233
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:217
VPBlockBase(VPBlockTy SC, const std::string &N)
Definition VPlan.h:400
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBase NewBlock after BlockPtr.
Definition VPlanUtils.h:320
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:365
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:383
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:431
static void transferSuccessors(VPBlockBase *Old, VPBlockBase *New)
Transfer successors from Old to New. New must have no successors.
Definition VPlanUtils.h:415
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:668
A recipe for generating conditional branches on the bits of a mask.
Definition VPlan.h:3519
VPlan-based builder utility analogous to IRBuilder.
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.
VPSingleDefRecipe * createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, bool Reverse, DebugLoc DL)
Create a vector pointer recipe for a consecutive memory access to Ptr with element type SourceElement...
Definition VPlan.cpp:1662
VPVectorPointerRecipe * createVectorPointer(VPValue *Ptr, Type *SourceElementTy, VPValue *Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
VPInstruction * createAnyOfReduction(VPValue *ChainOp, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown())
Create an AnyOf reduction pattern: or-reduce ChainOp, freeze the result, then select between TrueVal ...
Definition VPlan.cpp:1634
VPInstruction * createOverflowingOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt)
Create a select of TrueVal and FalseVal based on Cond, using the default flags for the result type,...
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Instruction *Inst=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", Type *ResultTy=nullptr)
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
This class augments a recipe with a set of VPValues defined by the recipe.
Definition VPlanValue.h:510
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4580
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
Definition VPlan.cpp:453
BasicBlock * getIRBasicBlock() const
Definition VPlan.h:4604
VPIRBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Definition VPlan.cpp:478
Class to record and manage LLVM IR flags.
Definition VPlan.h:704
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:1306
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
Definition VPlan.h:1360
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:86
Kind getKind() const
Returns the Kind of lane offset.
bool isFirstLane() const
Returns true if this is the first lane of the whole vector.
unsigned getKnownLane() const
Returns a compile-time known value for the lane index and asserts if the lane can only be calculated ...
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:177
~VPMultiDefValue() override
Definition VPlan.cpp:183
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:411
void dump() const
Dump the recipe to stderr (for debugging).
Definition VPlan.cpp:115
VPBasicBlock * getParent()
Definition VPlan.h:483
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:162
VPRecipeValue(unsigned char SC, Value *UV, Type *Ty=nullptr)
Definition VPlanValue.h:347
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4652
VPRegionBlock * clone() override
Clone all blocks in the single-entry single-exit region of the block and their recipes without updati...
Definition VPlan.cpp:725
const VPBlockBase * getEntry() const
Definition VPlan.h:4696
void dissolveToCFGLoop()
Remove the current region from its VPlan, connecting its predecessor to its entry,...
Definition VPlan.cpp:834
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4728
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
Definition VPlan.h:4799
VPRegionValue * getUsedHeaderMask() const
Return the header mask if it exists and is used, or null otherwise.
Definition VPlan.h:4792
VPInstruction * getOrCreateCanonicalIVIncrement()
Get the canonical IV increment instruction if it exists.
Definition VPlan.cpp:860
InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override
Return the cost of the block.
Definition VPlan.cpp:775
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:811
Type * getCanonicalIVType() const
Return the type of the canonical IV for loop regions.
Definition VPlan.h:4780
const VPBranchOnMaskRecipe * getEntryBranchOnMask() const
Return the VPBranchOnMaskRecipe from the entry block of this replicating region.
Definition VPlan.cpp:718
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4816
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPRegionBlock,...
Definition VPlan.cpp:745
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4772
const VPBlockBase * getExiting() const
Definition VPlan.h:4708
VPRegionValue * getHeaderMask() const
Return the header mask of the region, or null if not set.
Definition VPlan.h:4785
friend class VPlan
Definition VPlan.h:4653
VPValues are defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:252
DebugLoc getDebugLoc() const
Returns the debug location of the VPRegionValue.
Definition VPlanValue.h:267
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3410
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:619
LLVM_ABI_FOR_TEST VPSingleDefValue(VPSingleDefRecipe *Def, Value *UV=nullptr, Type *Ty=nullptr)
Construct a VPSingleDefValue. Must only be used by VPSingleDefRecipe.
Definition VPlan.cpp:167
~VPSingleDefValue() override
Definition VPlan.cpp:173
friend class VPSingleDefRecipe
Definition VPlanValue.h:365
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:1610
const Module * getModule() const
Returns the module the plan operates on, if any.
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:217
Type * getType() const
Returns the scalar type of this symbolic value.
Definition VPlanValue.h:232
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:401
void replaceUsesOfWith(VPValue *From, VPValue *To)
Replaces all uses of From in the VPUser with To.
Definition VPlan.cpp:1498
void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const
Print the operands to O.
Definition VPlan.cpp:1510
operand_range operands()
Definition VPlanValue.h:474
void setOperand(unsigned I, VPValue *New)
Definition VPlanValue.h:447
unsigned getNumOperands() const
Definition VPlanValue.h:441
VPValue * getOperand(unsigned N) const
Definition VPlanValue.h:442
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:147
Value * getLiveInIRValue() const
Return the underlying IR value for a VPIRValue.
Definition VPlan.cpp:141
bool isDefinedOutsideLoopRegions() const
Returns true if the VPValue is defined outside any loop.
Definition VPlan.cpp:1461
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:128
void printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const
Definition VPlan.cpp:1506
void assertNotMaterialized() const
Assert that this VPValue has not been materialized, if it is a VPSymbolicValue.
Definition VPlanValue.h:582
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
Definition VPlanValue.h:75
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:107
void print(raw_ostream &OS, VPSlotTracker &Tracker) const
Definition VPlan.cpp:100
void replaceAllUsesWith(VPValue *New)
Definition VPlan.cpp:1464
unsigned getNumUsers() const
Definition VPlanValue.h:115
void replaceUsesWithIf(VPValue *New, llvm::function_ref< bool(VPUser &U, unsigned Idx)> ShouldReplace)
Go through the uses list for this VPValue and make each use point to New if the callback ShouldReplac...
Definition VPlan.cpp:1470
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:2285
LLVM_DUMP_METHOD void dump()
Definition VPlan.cpp:1323
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4839
LLVM_ABI_FOR_TEST void printDOT(raw_ostream &O) const
Print this VPlan in DOT format to O.
Definition VPlan.cpp:1160
friend class VPSlotTracker
Definition VPlan.h:4841
std::string getName() const
Return a string with the name of the plan and the applicable VFs and UFs.
Definition VPlan.cpp:1136
const DataLayout & getDataLayout() const
Definition VPlan.h:5053
VPBasicBlock * getEntry()
Definition VPlan.h:4935
Type * getIndexType() const
The type of the canonical induction variable of the vector loop.
Definition VPlan.h:5284
void setName(const Twine &newName)
Definition VPlan.h:5117
LLVM_ABI_FOR_TEST ~VPlan()
Definition VPlan.cpp:888
bool isExitBlock(VPBlockBase *VPBB)
Returns true if VPBB is an exit block.
Definition VPlan.cpp:907
friend class VPlanPrinter
Definition VPlan.h:4840
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5047
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
Definition VPlan.cpp:1300
auto getLiveIns() const
Return the list of live-in VPValues available in the VPlan.
Definition VPlan.h:5181
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:5001
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1042
bool hasEarlyExit() const
Returns true if the VPlan is based on a loop with an early exit.
Definition VPlan.h:5254
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this plan.
Definition VPlan.cpp:1024
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:1066
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5099
void setEntry(VPBasicBlock *VPBB)
Definition VPlan.h:4924
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
Definition VPlan.h:5204
LLVM_ABI_FOR_TEST VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
Definition VPlan.cpp:1308
LLVM_DUMP_METHOD void dump() const
Dump the plan to stderr (for debugging).
Definition VPlan.cpp:1166
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4991
void execute(VPTransformState *State)
Generate the IR code for this VPlan.
Definition VPlan.cpp:917
LLVM_ABI_FOR_TEST void print(raw_ostream &O) const
Print this VPlan to O.
Definition VPlan.cpp:1119
bool hasTailFolded() const
Returns true if the vector loop region is tail-folded.
Definition VPlan.h:4956
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
Definition VPlan.h:4997
void printLiveIns(raw_ostream &O) const
Print the live-ins of this VPlan to O.
Definition VPlan.cpp:1075
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5040
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:1207
VPIRValue * getConstantInt(Type *Ty, uint64_t Val, bool IsSigned=false)
Return a VPIRValue wrapping a ConstantInt with the given type and value.
Definition VPlan.h:5155
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:319
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:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
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:81
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
bool match(Val *V, const Pattern &P)
VPInstruction_match< VPInstruction::BranchOnTwoConds > m_BranchOnTwoConds()
VPInstruction_match< VPInstruction::BranchOnCount > m_BranchOnCount()
VPInstruction_match< VPInstruction::BuildVector > m_BuildVector()
BuildVector is matches only its opcode, w/o matching its operands as the number of operands is not fi...
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
BranchProbability getExecutionProbability(BlockFrequency Freq)
Returns Freq as a BranchProbability, relative to AlwaysExecutesFreq.
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.
GEPNoWrapFlags getGEPFlagsForPtr(VPValue *Ptr)
Returns the GEP nowrap flags for Ptr, looking through pointer casts mirroring Value::stripPointerCast...
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:60
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
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
cl::opt< unsigned > ForceTargetInstructionCost("force-target-instruction-cost", cl::init(0), cl::Hidden, cl::desc("A flag that overrides the target's expected cost for " "an instruction to a single constant value. Mostly " "useful for getting consistent testing."))
Definition VPlan.cpp:58
bool isa_and_present(const Y &Val)
isa_and_present<X> - Functionally identical to isa, except that a null value is accepted.
Definition Casting.h:669
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:1850
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)
@ Or
Bitwise or logical OR of integers.
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.
cl::opt< unsigned > NumberOfStoresToPredicate("vectorize-num-stores-pred", cl::init(1), cl::Hidden, cl::desc("Max number of stores to be predicated behind an if."))
The number of stores in a loop that are allowed to need predication.
Definition VPlan.cpp:59
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:76
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
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:1963
TargetTransformInfo::OperandValueInfo getOperandInfo(VPValue *V) const
Returns the OperandInfo for V, if it is a live-in.
Definition VPlan.cpp:1861
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:1954
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:1878
TargetTransformInfo::TargetCostKind CostKind
VPSlotTracker * getSlotTracker()
Return a VPSlotTracker to re-use for printing, lazily constructing it on first use.
Definition VPlan.cpp:1869
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:1916
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:279
Type * getType() const
Returns the type of the underlying IR value.
Definition VPlan.cpp:145
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:343
struct llvm::VPTransformState::DataState Data
struct llvm::VPTransformState::CFGState CFG
Value * get(const VPValue *Def, bool IsScalar=false)
Get the generated vector Value for a given VPValue Def if IsScalar is false, otherwise return the gen...
Definition VPlan.cpp:282
IRBuilderBase & Builder
Hold a reference to the IRBuilder used to generate output IR code.
bool hasScalarValue(const VPValue *Def, VPLane Lane)
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:240
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:321
Loop * CurrentParentLoop
The parent loop object for the current scope, or nullptr.