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