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
396BasicBlock *VPBasicBlock::createEmptyBasicBlock(VPTransformState &State) {
397 auto &CFG = State.CFG;
398 // BB stands for IR BasicBlocks. VPBB stands for VPlan VPBasicBlocks.
399 // Pred stands for Predessor. Prev stands for Previous - last visited/created.
400 BasicBlock *PrevBB = CFG.PrevBB;
401 BasicBlock *NewBB = BasicBlock::Create(PrevBB->getContext(), getName(),
402 PrevBB->getParent(), CFG.ExitBB);
403 LLVM_DEBUG(dbgs() << "LV: created " << NewBB->getName() << '\n');
404
405 return NewBB;
406}
407
409 auto &CFG = State.CFG;
410 BasicBlock *NewBB = CFG.VPBB2IRBB[this];
411
412 // Register NewBB in its loop. In innermost loops its the same for all
413 // BB's.
414 Loop *ParentLoop = State.CurrentParentLoop;
415 // If this block has a sole successor that is an exit block or is an exit
416 // block itself then it needs adding to the same parent loop as the exit
417 // block.
418 VPBlockBase *SuccOrExitVPB = getSingleSuccessor();
419 SuccOrExitVPB = SuccOrExitVPB ? SuccOrExitVPB : this;
420 if (State.Plan->isExitBlock(SuccOrExitVPB)) {
421 ParentLoop = State.LI->getLoopFor(
422 cast<VPIRBasicBlock>(SuccOrExitVPB)->getIRBasicBlock());
423 }
424
425 if (ParentLoop && !State.LI->getLoopFor(NewBB))
426 ParentLoop->addBasicBlockToLoop(NewBB, *State.LI);
427
429 if (VPBlockUtils::isHeader(this, State.VPDT)) {
430 // There's no block for the latch yet, connect to the preheader only.
431 Preds = {getPredecessors()[0]};
432 } else {
433 Preds = to_vector(getPredecessors());
434 }
435
436 // Hook up the new basic block to its predecessors.
437 for (VPBlockBase *PredVPBlock : Preds) {
438 VPBasicBlock *PredVPBB = PredVPBlock->getExitingBasicBlock();
439 auto &PredVPSuccessors = PredVPBB->getHierarchicalSuccessors();
440 assert(CFG.VPBB2IRBB.contains(PredVPBB) &&
441 "Predecessor basic-block not found building successor.");
442 BasicBlock *PredBB = CFG.VPBB2IRBB[PredVPBB];
443 auto *PredBBTerminator = PredBB->getTerminator();
444 LLVM_DEBUG(dbgs() << "LV: draw edge from " << PredBB->getName() << '\n');
445
446 if (isa<UnreachableInst>(PredBBTerminator)) {
447 assert(PredVPSuccessors.size() == 1 &&
448 "Predecessor ending w/o branch must have single successor.");
449 DebugLoc DL = PredBBTerminator->getDebugLoc();
450 PredBBTerminator->eraseFromParent();
451 auto *Br = UncondBrInst::Create(NewBB, PredBB);
452 Br->setDebugLoc(DL);
453 } else if (auto *UBI = dyn_cast<UncondBrInst>(PredBBTerminator)) {
454 UBI->setSuccessor(NewBB);
455 } else {
456 // Set each forward successor here when it is created, excluding
457 // backedges. A backward successor is set when the branch is created.
458 // Branches to VPIRBasicBlocks must have the same successors in VPlan as
459 // in the original IR, except when the predecessor is the entry block.
460 // This enables including SCEV and memory runtime check blocks in VPlan.
461 // TODO: Remove exception by modeling the terminator of entry block using
462 // BranchOnCond.
463 unsigned idx = PredVPSuccessors.front() == this ? 0 : 1;
464 auto *TermBr = cast<CondBrInst>(PredBBTerminator);
465 assert((!TermBr->getSuccessor(idx) ||
466 (isa<VPIRBasicBlock>(this) &&
467 (TermBr->getSuccessor(idx) == NewBB ||
468 PredVPBlock == getPlan()->getEntry()))) &&
469 "Trying to reset an existing successor block.");
470 TermBr->setSuccessor(idx, NewBB);
471 }
472 CFG.DTU.applyUpdates({{DominatorTree::Insert, PredBB, NewBB}});
473 }
474}
475
478 "VPIRBasicBlock can have at most two successors at the moment!");
479 // Move completely disconnected blocks to their final position.
480 if (IRBB->hasNPredecessors(0) && succ_begin(IRBB) == succ_end(IRBB))
481 IRBB->moveAfter(State->CFG.PrevBB);
482 State->Builder.SetInsertPoint(IRBB->getTerminator());
483 State->CFG.PrevBB = IRBB;
484 State->CFG.VPBB2IRBB[this] = IRBB;
485 executeRecipes(State, IRBB);
486 // Create a branch instruction to terminate IRBB if one was not created yet
487 // and is needed.
488 if (getSingleSuccessor() && isa<UnreachableInst>(IRBB->getTerminator())) {
489 auto *Br = State->Builder.CreateBr(IRBB);
490 Br->setOperand(0, nullptr);
491 IRBB->getTerminator()->eraseFromParent();
492 } else {
493 assert((getNumSuccessors() == 0 ||
494 isa<UncondBrInst, CondBrInst>(IRBB->getTerminator())) &&
495 "other blocks must be terminated by a branch");
496 }
497
498 connectToPredecessors(*State);
499}
500
501VPIRBasicBlock *VPIRBasicBlock::clone() {
502 auto *NewBlock = getPlan()->createEmptyVPIRBasicBlock(IRBB);
503 for (VPRecipeBase &R : Recipes)
504 NewBlock->appendRecipe(R.clone());
505 return NewBlock;
506}
507
509 if (VPBlockUtils::isHeader(this, State->VPDT)) {
510 // Create and register the new vector loop.
511 Loop *PrevParentLoop = State->CurrentParentLoop;
512 State->CurrentParentLoop = State->LI->AllocateLoop();
513
514 // Insert the new loop into the loop nest and register the new basic blocks
515 // before calling any utilities such as SCEV that require valid LoopInfo.
516 if (PrevParentLoop)
517 PrevParentLoop->addChildLoop(State->CurrentParentLoop);
518 else
519 State->LI->addTopLevelLoop(State->CurrentParentLoop);
520 }
521
522 // 1. Create an IR basic block.
523 BasicBlock *NewBB = createEmptyBasicBlock(*State);
524
525 State->Builder.SetInsertPoint(NewBB);
526 // Temporarily terminate with unreachable until CFG is rewired.
527 UnreachableInst *Terminator = State->Builder.CreateUnreachable();
528 State->Builder.SetInsertPoint(Terminator);
529
530 State->CFG.PrevBB = NewBB;
531 State->CFG.VPBB2IRBB[this] = NewBB;
532 connectToPredecessors(*State);
533
534 // 2. Fill the IR basic block with IR instructions.
535 executeRecipes(State, NewBB);
536
537 // If this block is a latch, update CurrentParentLoop.
538 if (VPBlockUtils::isLatch(this, State->VPDT))
539 State->CurrentParentLoop = State->CurrentParentLoop->getParentLoop();
540}
541
542VPBasicBlock *VPBasicBlock::clone() {
543 auto *NewBlock = getPlan()->createVPBasicBlock(getName());
544 for (VPRecipeBase &R : *this)
545 NewBlock->appendRecipe(R.clone());
546 return NewBlock;
547}
548
550 LLVM_DEBUG(dbgs() << "LV: vectorizing VPBB: " << getName()
551 << " in BB: " << BB->getName() << '\n');
552
553 State->CFG.PrevVPBB = this;
554
555 for (VPRecipeBase &Recipe : Recipes) {
556 State->setDebugLocFrom(Recipe.getDebugLoc());
557 Recipe.execute(*State);
558 }
559
560 LLVM_DEBUG(dbgs() << "LV: filled BB: " << *BB);
561}
562
563VPBasicBlock *VPBasicBlock::splitAt(iterator SplitAt) {
564 assert((SplitAt == end() || SplitAt->getParent() == this) &&
565 "can only split at a position in the same block");
566
567 // Create new empty block after the block to split.
568 auto *SplitBlock = getPlan()->createVPBasicBlock(getName() + ".split");
570
571 // If this is the exiting block, make the split the new exiting block.
572 auto *ParentRegion = getParent();
573 if (ParentRegion && ParentRegion->getExiting() == this)
574 ParentRegion->setExiting(SplitBlock);
575
576 // Finally, move the recipes starting at SplitAt to new block.
577 for (VPRecipeBase &ToMove :
578 make_early_inc_range(make_range(SplitAt, this->end())))
579 ToMove.moveBefore(*SplitBlock, SplitBlock->end());
580
581 return SplitBlock;
582}
583
584/// Return the enclosing loop region for region \p P. The templated version is
585/// used to support both const and non-const block arguments.
586template <typename T> static T *getEnclosingLoopRegionForRegion(T *P) {
587 if (P && P->isReplicator()) {
588 P = P->getParent();
589 // Multiple loop regions can be nested, but replicate regions can only be
590 // nested inside a loop region or must be outside any other region.
591 assert((!P || !P->isReplicator()) && "unexpected nested replicate regions");
592 }
593 return P;
594}
595
599
603
604static bool hasConditionalTerminator(const VPBasicBlock *VPBB) {
605 if (VPBB->empty()) {
606 assert(
607 VPBB->getNumSuccessors() < 2 &&
608 "block with multiple successors doesn't have a recipe as terminator");
609 return false;
610 }
611
612 const VPRecipeBase *R = &VPBB->back();
613 [[maybe_unused]] bool IsSwitch =
615 cast<VPInstruction>(R)->getOpcode() == Instruction::Switch;
616 [[maybe_unused]] bool IsBranchOnTwoConds = match(R, m_BranchOnTwoConds());
617 [[maybe_unused]] bool IsCondBranch =
620 if (VPBB->getNumSuccessors() == 2 ||
621 (VPBB->isExiting() && !VPBB->getParent()->isReplicator())) {
622 assert((IsCondBranch || IsSwitch || IsBranchOnTwoConds) &&
623 "block with multiple successors not terminated by "
624 "conditional branch nor switch recipe");
625
626 return true;
627 }
628
629 if (VPBB->getNumSuccessors() > 2) {
630 assert((IsSwitch || IsBranchOnTwoConds) &&
631 "block with more than 2 successors not terminated by a switch or "
632 "branch-on-two-conds recipe");
633 return true;
634 }
635
636 assert(
637 !IsCondBranch && !IsBranchOnTwoConds &&
638 "block with 0 or 1 successors terminated by conditional branch recipe");
639 return false;
640}
641
643 if (hasConditionalTerminator(this))
644 return &back();
645 return nullptr;
646}
647
649 if (hasConditionalTerminator(this))
650 return &back();
651 return nullptr;
652}
653
655 return getParent() && getParent()->getExitingBasicBlock() == this;
656}
657
658#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
663
664void VPBlockBase::printSuccessors(raw_ostream &O, const Twine &Indent) const {
665 if (!hasSuccessors()) {
666 O << Indent << "No successors\n";
667 } else {
668 O << Indent << "Successor(s): ";
669 ListSeparator LS;
670 for (auto *Succ : getSuccessors())
671 O << LS << Succ->getName();
672 O << '\n';
673 }
674}
675
676void VPBasicBlock::print(raw_ostream &O, const Twine &Indent,
677 VPSlotTracker &SlotTracker) const {
678 O << Indent << getName() << ":\n";
679
680 auto RecipeIndent = Indent + " ";
681 for (const VPRecipeBase &Recipe : *this) {
682 Recipe.print(O, RecipeIndent, SlotTracker);
683 O << '\n';
684 }
685
686 printSuccessors(O, Indent);
687}
688#endif
689
690std::pair<VPBlockBase *, VPBlockBase *>
693 VPBlockBase *Exiting = nullptr;
694 bool InRegion = Entry->getParent();
695 // First, clone blocks reachable from Entry.
696 for (VPBlockBase *BB : vp_depth_first_shallow(Entry)) {
697 VPBlockBase *NewBB = BB->clone();
698 Old2NewVPBlocks[BB] = NewBB;
699 if (InRegion && BB->getNumSuccessors() == 0) {
700 assert(!Exiting && "Multiple exiting blocks?");
701 Exiting = BB;
702 }
703 }
704 assert((!InRegion || Exiting) && "regions must have a single exiting block");
705
706 // Second, update the predecessors & successors of the cloned blocks.
707 for (VPBlockBase *BB : vp_depth_first_shallow(Entry)) {
708 VPBlockBase *NewBB = Old2NewVPBlocks[BB];
710 for (VPBlockBase *Pred : BB->getPredecessors()) {
711 NewPreds.push_back(Old2NewVPBlocks[Pred]);
712 }
713 NewBB->setPredecessors(NewPreds);
715 for (VPBlockBase *Succ : BB->successors()) {
716 NewSuccs.push_back(Old2NewVPBlocks[Succ]);
717 }
718 NewBB->setSuccessors(NewSuccs);
719 }
720
721#if !defined(NDEBUG)
722 // Verify that the order of predecessors and successors matches in the cloned
723 // version.
724 for (const auto &[OldBB, NewBB] :
726 vp_depth_first_shallow(Old2NewVPBlocks[Entry]))) {
727 for (const auto &[OldPred, NewPred] :
728 zip(OldBB->getPredecessors(), NewBB->getPredecessors()))
729 assert(NewPred == Old2NewVPBlocks[OldPred] && "Different predecessors");
730
731 for (const auto &[OldSucc, NewSucc] :
732 zip(OldBB->successors(), NewBB->successors()))
733 assert(NewSucc == Old2NewVPBlocks[OldSucc] && "Different successors");
734 }
735#endif
736
737 return std::make_pair(Old2NewVPBlocks[Entry],
738 Exiting ? Old2NewVPBlocks[Exiting] : nullptr);
739}
740
741VPRegionBlock *VPRegionBlock::clone() {
742 const auto &[NewEntry, NewExiting] = VPBlockUtils::cloneFrom(getEntry());
743 VPlan &Plan = *getPlan();
744 VPRegionValue *CanIV = getCanonicalIV();
745 VPRegionBlock *NewRegion =
746 CanIV ? Plan.createLoopRegion(CanIV->getType(), CanIV->getDebugLoc(),
747 getName(), NewEntry, NewExiting)
748 : Plan.createReplicateRegion(NewEntry, NewExiting, getName());
749
750 if (getHeaderMask())
751 NewRegion->createHeaderMask();
752
753 for (VPBlockBase *Block : vp_depth_first_shallow(NewEntry))
754 Block->setParent(NewRegion);
755 return NewRegion;
756}
757
759 llvm_unreachable("regions must get dissolved before ::execute");
760}
761
764 for (VPRecipeBase &R : Recipes)
765 Cost += R.cost(VF, Ctx);
766 return Cost;
767}
768
769const VPBasicBlock *VPBasicBlock::getCFGPredecessor(unsigned Idx) const {
770 const VPBlockBase *Pred = nullptr;
771 if (hasPredecessors()) {
772 Pred = getPredecessors()[Idx];
773 } else {
774 auto *Region = getParent();
775 assert(Region && !Region->isReplicator() && Region->getEntry() == this &&
776 "must be in the entry block of a non-replicate region");
777 assert(Idx < 2 && Region->getNumPredecessors() == 1 &&
778 "loop region has a single predecessor (preheader), its entry block "
779 "has 2 incoming blocks");
780
781 // Idx == 0 selects the predecessor of the region, Idx == 1 selects the
782 // region itself whose exiting block feeds the phi across the backedge.
783 Pred = Idx == 0 ? Region->getSinglePredecessor() : Region;
784 }
785 return Pred->getExitingBasicBlock();
786}
787
789 if (!isReplicator()) {
790 // Neglect the cost of canonical IV, matching the legacy cost model.
793 Cost += Block->cost(VF, Ctx);
794 InstructionCost BackedgeCost =
795 ForceTargetInstructionCost.getNumOccurrences()
797 : Ctx.TTI.getCFInstrCost(Instruction::UncondBr, Ctx.CostKind);
798 LLVM_DEBUG(dbgs() << "Cost of " << BackedgeCost << " for VF " << VF
799 << ": vector loop backedge\n");
800 Cost += BackedgeCost;
801 return Cost;
802 }
803
804 // Compute the cost of a replicate region. Replicating isn't supported for
805 // scalable vectors, return an invalid cost for them.
806 // TODO: Discard scalable VPlans with replicate recipes earlier after
807 // construction.
808 if (VF.isScalable())
810
811 // Compute and return the cost of the conditionally executed recipes.
812 assert(VF.isVector() && "Can only compute vector cost at the moment.");
814 return Then->cost(VF, Ctx);
815}
816
817#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
819 VPSlotTracker &SlotTracker) const {
820 O << Indent << (isReplicator() ? "<xVFxUF> " : "<x1> ") << getName() << ": {";
821 auto NewIndent = Indent + " ";
822 if (auto *CanIV = getCanonicalIV()) {
823 O << '\n';
824 CanIV->print(O, SlotTracker);
825 O << " = CANONICAL-IV\n";
826 }
827 if (auto *HdrMask = getUsedHeaderMask()) {
828 HdrMask->print(O, SlotTracker);
829 O << " = HEADER-MASK\n";
830 }
831 for (auto *BlockBase : vp_depth_first_shallow(Entry)) {
832 O << '\n';
833 BlockBase->print(O, NewIndent, SlotTracker);
834 }
835 O << Indent << "}\n";
836
837 printSuccessors(O, Indent);
838}
839#endif
840
842 auto *Header = cast<VPBasicBlock>(getEntry());
843 auto *ExitingLatch = cast<VPBasicBlock>(getExiting());
844 auto *CanIV = getCanonicalIV();
845 if (!CanIV->user_empty()) {
846 VPlan &Plan = *getPlan();
847 auto *Zero = Plan.getZero(CanIV->getType());
848 DebugLoc DL = CanIV->getDebugLoc();
850 VPBuilder HeaderBuilder(Header, Header->begin());
851 auto *ScalarR =
852 HeaderBuilder.createScalarPhi({Zero, CanIVInc}, DL, "index");
853 CanIV->replaceAllUsesWith(ScalarR);
854 }
855
856 VPBlockBase *Preheader = getSinglePredecessor();
857 VPBlockUtils::disconnectBlocks(Preheader, this);
858
859 for (VPBlockBase *VPB : vp_depth_first_shallow(Entry))
860 VPB->setParent(getParent());
861
862 VPBlockUtils::connectBlocks(Preheader, Header);
863 VPBlockUtils::transferSuccessors(this, ExitingLatch);
864 VPBlockUtils::connectBlocks(ExitingLatch, Header);
865}
866
868 // TODO: Represent the increment as VPRegionValue as well.
869 VPRegionValue *CanIV = getCanonicalIV();
870 assert(CanIV && "Expected a canonical IV");
871
872 if (auto *Inc = vputils::findCanonicalIVIncrement(*getPlan()))
873 return Inc;
874
875 assert(!getPlan()->getVFxUF().isMaterialized() &&
876 "VFxUF can be used only before it is materialized.");
877 auto *ExitingLatch = cast<VPBasicBlock>(getExiting());
878 return VPBuilder(ExitingLatch->getTerminator())
879 .createOverflowingOp(Instruction::Add, {CanIV, &getPlan()->getVFxUF()},
880 {hasCanonicalIVNUW(), /* HasNSW */ false},
881 CanIV->getDebugLoc(), "index.next");
882}
883
884VPlan::VPlan(Loop *L, Type *IdxTy)
885 : VectorTripCount(IdxTy), VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
886 setEntry(createVPIRBasicBlock(L->getLoopPreheader()));
887 ScalarHeader = createVPIRBasicBlock(L->getHeader());
888
889 SmallVector<BasicBlock *> IRExitBlocks;
890 L->getUniqueExitBlocks(IRExitBlocks);
891 for (BasicBlock *EB : IRExitBlocks)
892 ExitBlocks.push_back(createVPIRBasicBlock(EB));
893}
894
896 VPSymbolicValue DummyValue(nullptr);
897
898 // Redirect all recipe operands to DummyValue before deleting blocks.
899 for (VPBasicBlock *VPBB :
901 for (VPRecipeBase &R : *VPBB)
902 for (unsigned I = 0, E = R.getNumOperands(); I != E; I++)
903 R.setOperand(I, &DummyValue);
904
905 for (auto [Idx, VPB] : enumerate(CreatedBlocks)) {
906 assert(VPB->getNumber() == Idx && "block with mismatched number");
907 delete VPB;
908 }
909 for (VPValue *VPV : getLiveIns())
910 delete VPV;
911 delete BackedgeTakenCount;
912}
913
915 return is_contained(ExitBlocks, VPBB);
916}
917
918/// To make RUN_VPLAN_PASS print final VPlan.
919static void printFinalVPlan(VPlan &) {}
920
921/// Generate the code inside the preheader and body of the vectorized loop.
922/// Assumes a single pre-header basic-block was created for this. Introduce
923/// additional basic-blocks as needed, and fill them all.
926 "all region blocks must be dissolved before ::execute");
927
928 // Initialize CFG state.
929 State->CFG.PrevVPBB = nullptr;
930 State->CFG.ExitBB = State->CFG.PrevBB->getSingleSuccessor();
931
932 // Update VPDominatorTree since VPBasicBlock may be removed after State was
933 // constructed.
934 State->VPDT.recalculate(*this);
935
936 // Disconnect VectorPreHeader from ExitBB in both the CFG and DT.
937 BasicBlock *VectorPreHeader = State->CFG.PrevBB;
938 cast<UncondBrInst>(VectorPreHeader->getTerminator())->setSuccessor(nullptr);
939 State->CFG.DTU.applyUpdates(
940 {{DominatorTree::Delete, VectorPreHeader, State->CFG.ExitBB}});
941
942 LLVM_DEBUG(dbgs() << "Executing best plan with VF=" << State->VF
943 << ", UF=" << getConcreteUF() << '\n');
944 setName("Final VPlan");
945 // TODO: RUN_VPLAN_PASS/VPlanTransforms::runPass should automatically dump
946 // VPlans after some specific stages when "-debug" is specified, but that
947 // hasn't been implemented yet. For now, just do both:
948 LLVM_DEBUG(dump());
950
951 BasicBlock *ScalarPh = State->CFG.ExitBB;
952 VPBasicBlock *ScalarPhVPBB = getScalarPreheader();
953 if (ScalarPhVPBB) {
954 // Disconnect scalar preheader and scalar header, as the dominator tree edge
955 // will be updated as part of VPlan execution. This allows keeping the DTU
956 // logic generic during VPlan execution.
957 State->CFG.DTU.applyUpdates(
958 {{DominatorTree::Delete, ScalarPh, ScalarPh->getSingleSuccessor()}});
959 }
961 Entry);
962 // Generate code for the VPlan, in parts of the vector skeleton, loop body and
963 // successor blocks including the middle, exit and scalar preheader blocks.
964 for (VPBlockBase *Block : RPOT)
965 Block->execute(State);
966
967 if (hasEarlyExit()) {
968 // Fix up LoopInfo for extra dispatch blocks when vectorizing loops with
969 // early exits. For dispatch blocks, we need to find the smallest common
970 // loop of all successors that are in a loop. Note: we only need to update
971 // loop info for blocks after the middle block, but there is no easy way to
972 // get those at this point.
973 for (VPBlockBase *VPB : reverse(RPOT)) {
974 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
975 if (!VPBB || isa<VPIRBasicBlock>(VPBB))
976 continue;
977 BasicBlock *BB = State->CFG.VPBB2IRBB[VPBB];
978 Loop *L = State->LI->getLoopFor(BB);
979 if (!L || any_of(successors(BB),
980 [L](BasicBlock *Succ) { return L->contains(Succ); }))
981 continue;
982 // Find the innermost loop containing all successors that are in a loop.
983 // Successors not in any loop don't constrain the target loop.
984 Loop *Target = nullptr;
985 for (BasicBlock *Succ : successors(BB)) {
986 Loop *SuccLoop = State->LI->getLoopFor(Succ);
987 if (!SuccLoop)
988 continue;
989 if (!Target)
990 Target = SuccLoop;
991 else
992 Target = State->LI->getSmallestCommonLoop(Target, SuccLoop);
993 }
994 State->LI->removeBlock(BB);
995 if (Target)
996 Target->addBasicBlockToLoop(BB, *State->LI);
997 }
998 }
999
1000 // If the original loop is unreachable, delete it and all its blocks.
1001 if (!ScalarPhVPBB) {
1002 // DeleteDeadBlocks will remove single-entry phis. Remove them from the exit
1003 // VPIRBBs in VPlan as well, otherwise we would retain references to deleted
1004 // IR instructions.
1005 for (VPIRBasicBlock *EB : getExitBlocks()) {
1006 for (VPRecipeBase &R : make_early_inc_range(EB->phis())) {
1007 if (R.getNumOperands() == 1)
1008 R.eraseFromParent();
1009 }
1010 }
1011
1012 Loop *OrigLoop =
1013 State->LI->getLoopFor(getScalarHeader()->getIRBasicBlock());
1014 SmallVector<BasicBlock *> Blocks(OrigLoop->block_begin(),
1015 OrigLoop->block_end());
1016 Blocks.push_back(ScalarPh);
1017 while (!OrigLoop->isInnermost())
1018 State->LI->erase(*OrigLoop->begin());
1019 State->LI->erase(OrigLoop);
1020 for (auto *BB : Blocks)
1021 State->LI->removeBlock(BB);
1022 DeleteDeadBlocks(Blocks, &State->CFG.DTU);
1023 }
1024
1025 State->CFG.DTU.flush();
1026
1027 // Fix the latch (backedge) value of all header phis in all loop headers.
1029 if (!VPBlockUtils::isHeader(VPB, State->VPDT))
1030 continue;
1031 auto *Header = cast<VPBasicBlock>(VPB);
1032 auto *LatchVPBB = cast<VPBasicBlock>(Header->getPredecessors()[1]);
1033 BasicBlock *VectorLatchBB = State->CFG.VPBB2IRBB[LatchVPBB];
1034
1035 for (VPRecipeBase &R : Header->phis()) {
1036 auto *PhiR = cast<VPSingleDefRecipe>(&R);
1037 bool NeedsScalar =
1038 isa<VPPhi>(PhiR) || (isa<VPReductionPHIRecipe>(PhiR) &&
1039 cast<VPReductionPHIRecipe>(PhiR)->isInLoop());
1040
1041 Value *Phi = State->get(PhiR, NeedsScalar);
1042 Value *Val = State->get(PhiR->getOperand(1), NeedsScalar);
1043 cast<PHINode>(Phi)->addIncoming(Val, VectorLatchBB);
1044 }
1045 }
1046}
1047
1049 // For now only return the cost of the vector loop region, ignoring any other
1050 // blocks, like the preheader or middle blocks, expect for checking them for
1051 // recipes with invalid costs.
1053
1054 // If the cost of the loop region is invalid or any recipe in the skeleton
1055 // outside loop regions are invalid return an invalid cost.
1058 [&VF, &Ctx](VPBasicBlock *VPBB) {
1059 return !VPBB->cost(VF, Ctx).isValid();
1060 }))
1062
1063 return Cost;
1064}
1065
1067 // TODO: Cache if possible.
1069 if (auto *R = dyn_cast<VPRegionBlock>(B))
1070 return R->isReplicator() ? nullptr : R;
1071 return nullptr;
1072}
1073
1076 if (auto *R = dyn_cast<VPRegionBlock>(B))
1077 return R->isReplicator() ? nullptr : R;
1078 return nullptr;
1079}
1080
1082 const VPRegionBlock *LoopRegion = getVectorLoopRegion();
1083 assert(LoopRegion && "expected a vector loop region");
1085 vp_depth_first_shallow(LoopRegion->getEntry())),
1086 [](const VPRegionBlock *R) { return !R->isReplicator(); });
1087}
1088
1089#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1092
1093 if (!VF.user_empty()) {
1094 O << "\nLive-in ";
1095 VF.printAsOperand(O, SlotTracker);
1096 O << " = VF";
1097 }
1098
1099 if (!UF.user_empty()) {
1100 O << "\nLive-in ";
1101 UF.printAsOperand(O, SlotTracker);
1102 O << " = UF";
1103 }
1104
1105 if (!VFxUF.user_empty()) {
1106 O << "\nLive-in ";
1107 VFxUF.printAsOperand(O, SlotTracker);
1108 O << " = VF * UF";
1109 }
1110
1111 if (!VectorTripCount.user_empty()) {
1112 O << "\nLive-in ";
1113 VectorTripCount.printAsOperand(O, SlotTracker);
1114 O << " = vector-trip-count";
1115 }
1116
1117 if (BackedgeTakenCount && !BackedgeTakenCount->user_empty()) {
1118 O << "\nLive-in ";
1119 BackedgeTakenCount->printAsOperand(O, SlotTracker);
1120 O << " = backedge-taken count";
1121 }
1122
1123 O << "\n";
1124 if (TripCount && !TripCount->user_empty()) {
1125 if (isa<VPIRValue>(TripCount))
1126 O << "Live-in ";
1127 TripCount->printAsOperand(O, SlotTracker);
1128 O << " = original trip-count";
1129 O << "\n";
1130 }
1131}
1132
1136
1137 O << "VPlan '" << getName() << "' {";
1138
1139 printLiveIns(O);
1140
1142 RPOT(getEntry());
1143 for (const VPBlockBase *Block : RPOT) {
1144 O << '\n';
1145 Block->print(O, "", SlotTracker);
1146 }
1147
1148 O << "}\n";
1149}
1150
1151std::string VPlan::getName() const {
1152 std::string Out;
1153 raw_string_ostream RSO(Out);
1154 RSO << Name << " for ";
1155 if (!VFs.empty()) {
1156 RSO << "VF={" << VFs[0];
1157 for (ElementCount VF : drop_begin(VFs))
1158 RSO << "," << VF;
1159 RSO << "},";
1160 }
1161
1162 if (UFs.empty()) {
1163 RSO << "UF>=1";
1164 } else {
1165 RSO << "UF={" << UFs[0];
1166 for (unsigned UF : drop_begin(UFs))
1167 RSO << "," << UF;
1168 RSO << "}";
1169 }
1170
1171 return Out;
1172}
1173
1176 VPlanPrinter Printer(O, *this);
1177 Printer.dump();
1178}
1179
1181void VPlan::dump() const { print(dbgs()); }
1182#endif
1183
1184static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry,
1185 DenseMap<VPValue *, VPValue *> &Old2NewVPValues) {
1186 // Update the operands of all cloned recipes starting at NewEntry. This
1187 // traverses all reachable blocks. This is done in two steps, to handle cycles
1188 // in PHI recipes.
1190 OldDeepRPOT(Entry);
1192 NewDeepRPOT(NewEntry);
1193 // First, collect all mappings from old to new VPValues defined by cloned
1194 // recipes.
1195 for (const auto &[OldBB, NewBB] :
1198 assert(OldBB->getRecipeList().size() == NewBB->getRecipeList().size() &&
1199 "blocks must have the same number of recipes");
1200 for (const auto &[OldR, NewR] : zip(*OldBB, *NewBB)) {
1201 assert(OldR.getNumOperands() == NewR.getNumOperands() &&
1202 "recipes must have the same number of operands");
1203 assert(OldR.getNumDefinedValues() == NewR.getNumDefinedValues() &&
1204 "recipes must define the same number of operands");
1205 for (const auto &[OldV, NewV] :
1206 zip(OldR.definedValues(), NewR.definedValues()))
1207 Old2NewVPValues[OldV] = NewV;
1208 }
1209 }
1210
1211 // Update all operands to use cloned VPValues.
1212 for (VPBasicBlock *NewBB :
1214 for (VPRecipeBase &NewR : *NewBB)
1215 for (unsigned I = 0, E = NewR.getNumOperands(); I != E; ++I) {
1216 VPValue *NewOp = Old2NewVPValues.lookup(NewR.getOperand(I));
1217 NewR.setOperand(I, NewOp);
1218 }
1219 }
1220}
1221
1223 unsigned NumBlocksBeforeCloning = CreatedBlocks.size();
1224 // Clone blocks.
1225 const auto &[NewEntry, __] = VPBlockUtils::cloneFrom(Entry);
1226
1227 BasicBlock *ScalarHeaderIRBB = getScalarHeader()->getIRBasicBlock();
1228 VPIRBasicBlock *NewScalarHeader = nullptr;
1229 if (getScalarHeader()->hasPredecessors()) {
1230 NewScalarHeader = cast<VPIRBasicBlock>(*find_if(
1231 vp_depth_first_shallow(NewEntry), [ScalarHeaderIRBB](VPBlockBase *VPB) {
1232 auto *VPIRBB = dyn_cast<VPIRBasicBlock>(VPB);
1233 return VPIRBB && VPIRBB->getIRBasicBlock() == ScalarHeaderIRBB;
1234 }));
1235 } else {
1236 NewScalarHeader = createVPIRBasicBlock(ScalarHeaderIRBB);
1237 }
1238 // Create VPlan, clone live-ins and remap operands in the cloned blocks.
1239 auto *NewPlan =
1240 new VPlan(cast<VPBasicBlock>(NewEntry), NewScalarHeader, getIndexType());
1241 DenseMap<VPValue *, VPValue *> Old2NewVPValues;
1242 for (VPIRValue *OldLiveIn : getLiveIns())
1243 Old2NewVPValues[OldLiveIn] = NewPlan->getOrAddLiveIn(OldLiveIn);
1244
1245 if (auto *TripCountIRV = dyn_cast_or_null<VPIRValue>(TripCount))
1246 Old2NewVPValues[TripCountIRV] = NewPlan->getOrAddLiveIn(TripCountIRV);
1247 // else NewTripCount will be created and inserted into Old2NewVPValues when
1248 // TripCount is cloned. In any case NewPlan->TripCount is updated below.
1249
1250 assert(none_of(Old2NewVPValues.keys(), IsaPred<VPSymbolicValue>) &&
1251 "All VPSymbolicValues must be handled below");
1252
1253 if (auto *LoopRegion = getVectorLoopRegion()) {
1254 auto *NewLoopRegion = NewPlan->getVectorLoopRegion();
1255 for (auto [Old, New] : zip_equal(LoopRegion->getRegionValues(),
1256 NewLoopRegion->getRegionValues())) {
1257 Old2NewVPValues[Old] = New;
1258 if (Old->isMaterialized())
1259 New->markMaterialized();
1260 }
1261 }
1262
1263 if (BackedgeTakenCount)
1264 NewPlan->BackedgeTakenCount =
1265 new VPSymbolicValue(BackedgeTakenCount->getType());
1266
1267 // Map and propagate materialized state for symbolic values.
1268 for (auto [OldSV, NewSV] :
1269 {std::pair{&VectorTripCount, &NewPlan->VectorTripCount},
1270 {&VF, &NewPlan->VF},
1271 {&UF, &NewPlan->UF},
1272 {&VFxUF, &NewPlan->VFxUF},
1273 {BackedgeTakenCount, NewPlan->BackedgeTakenCount}}) {
1274 if (!OldSV)
1275 continue;
1276 Old2NewVPValues[OldSV] = NewSV;
1277 if (OldSV->isMaterialized())
1278 NewSV->markMaterialized();
1279 }
1280
1281 remapOperands(Entry, NewEntry, Old2NewVPValues);
1282
1283 // Initialize remaining fields of cloned VPlan.
1284 NewPlan->VFs = VFs;
1285 NewPlan->UFs = UFs;
1286 // TODO: Adjust names.
1287 NewPlan->Name = Name;
1288 if (TripCount) {
1289 assert(Old2NewVPValues.contains(TripCount) &&
1290 "TripCount must have been added to Old2NewVPValues");
1291 NewPlan->TripCount = Old2NewVPValues[TripCount];
1292 }
1293
1294 // Transfer all cloned blocks (the second half of all current blocks) from
1295 // current to new VPlan.
1296 unsigned NumBlocksAfterCloning = CreatedBlocks.size();
1297 for (unsigned I :
1298 seq<unsigned>(NumBlocksBeforeCloning, NumBlocksAfterCloning)) {
1299 this->CreatedBlocks[I]->setNumber(NewPlan->CreatedBlocks.size());
1300 NewPlan->CreatedBlocks.push_back(this->CreatedBlocks[I]);
1301 }
1302 CreatedBlocks.truncate(NumBlocksBeforeCloning);
1303
1304 // Update ExitBlocks of the new plan.
1305 for (VPBlockBase *VPB : NewPlan->CreatedBlocks) {
1306 if (VPB->getNumSuccessors() == 0 && isa<VPIRBasicBlock>(VPB) &&
1307 VPB != NewScalarHeader)
1308 NewPlan->ExitBlocks.push_back(cast<VPIRBasicBlock>(VPB));
1309 }
1310
1311 return NewPlan;
1312}
1313
1315 auto *VPIRBB = new VPIRBasicBlock(IRBB);
1316 VPIRBB->setNumber(CreatedBlocks.size());
1317 CreatedBlocks.push_back(VPIRBB);
1318 return VPIRBB;
1319}
1320
1322 auto *VPIRBB = createEmptyVPIRBasicBlock(IRBB);
1323 for (Instruction &I :
1324 make_range(IRBB->begin(), IRBB->getTerminator()->getIterator()))
1325 VPIRBB->appendRecipe(VPIRInstruction::create(I));
1326 return VPIRBB;
1327}
1328
1329#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1330
1331Twine VPlanPrinter::getUID(const VPBlockBase *Block) {
1332 return (isa<VPRegionBlock>(Block) ? "cluster_N" : "N") +
1333 Twine(getOrCreateBID(Block));
1334}
1335
1337 Depth = 1;
1338 bumpIndent(0);
1339 OS << "digraph VPlan {\n";
1340 OS << "graph [labelloc=t, fontsize=30; label=\"Vectorization Plan";
1341 if (!Plan.getName().empty())
1342 OS << "\\n" << DOT::EscapeString(Plan.getName());
1343
1344 {
1345 // Print live-ins.
1346 std::string Str;
1347 raw_string_ostream SS(Str);
1348 Plan.printLiveIns(SS);
1350 StringRef(Str).rtrim('\n').split(Lines, "\n");
1351 for (auto Line : Lines)
1352 OS << DOT::EscapeString(Line.str()) << "\\n";
1353 }
1354
1355 OS << "\"]\n";
1356 OS << "node [shape=rect, fontname=Courier, fontsize=30]\n";
1357 OS << "edge [fontname=Courier, fontsize=30]\n";
1358 OS << "compound=true\n";
1359
1360 for (const VPBlockBase *Block : vp_depth_first_shallow(Plan.getEntry()))
1361 dumpBlock(Block);
1362
1363 OS << "}\n";
1364}
1365
1366void VPlanPrinter::dumpBlock(const VPBlockBase *Block) {
1368 dumpBasicBlock(BasicBlock);
1370 dumpRegion(Region);
1371 else
1372 llvm_unreachable("Unsupported kind of VPBlock.");
1373}
1374
1375void VPlanPrinter::drawEdge(const VPBlockBase *From, const VPBlockBase *To,
1376 bool Hidden, const Twine &Label) {
1377 // Due to "dot" we print an edge between two regions as an edge between the
1378 // exiting basic block and the entry basic of the respective regions.
1379 const VPBlockBase *Tail = From->getExitingBasicBlock();
1380 const VPBlockBase *Head = To->getEntryBasicBlock();
1381 OS << Indent << getUID(Tail) << " -> " << getUID(Head);
1382 OS << " [ label=\"" << Label << '\"';
1383 if (Tail != From)
1384 OS << " ltail=" << getUID(From);
1385 if (Head != To)
1386 OS << " lhead=" << getUID(To);
1387 if (Hidden)
1388 OS << "; splines=none";
1389 OS << "]\n";
1390}
1391
1392void VPlanPrinter::dumpEdges(const VPBlockBase *Block) {
1393 auto &Successors = Block->getSuccessors();
1394 if (Successors.size() == 1)
1395 drawEdge(Block, Successors.front(), false, "");
1396 else if (Successors.size() == 2) {
1397 drawEdge(Block, Successors.front(), false, "T");
1398 drawEdge(Block, Successors.back(), false, "F");
1399 } else {
1400 unsigned SuccessorNumber = 0;
1401 for (auto *Successor : Successors)
1402 drawEdge(Block, Successor, false, Twine(SuccessorNumber++));
1403 }
1404}
1405
1406void VPlanPrinter::dumpBasicBlock(const VPBasicBlock *BasicBlock) {
1407 // Implement dot-formatted dump by performing plain-text dump into the
1408 // temporary storage followed by some post-processing.
1409 OS << Indent << getUID(BasicBlock) << " [label =\n";
1410 bumpIndent(1);
1411 std::string Str;
1412 raw_string_ostream SS(Str);
1413 // Use no indentation as we need to wrap the lines into quotes ourselves.
1414 BasicBlock->print(SS, "", SlotTracker);
1415
1416 // We need to process each line of the output separately, so split
1417 // single-string plain-text dump.
1419 StringRef(Str).rtrim('\n').split(Lines, "\n");
1420
1421 auto EmitLine = [&](StringRef Line, StringRef Suffix) {
1422 OS << Indent << '"' << DOT::EscapeString(Line.str()) << "\\l\"" << Suffix;
1423 };
1424
1425 // Don't need the "+" after the last line.
1426 for (auto Line : make_range(Lines.begin(), Lines.end() - 1))
1427 EmitLine(Line, " +\n");
1428 EmitLine(Lines.back(), "\n");
1429
1430 bumpIndent(-1);
1431 OS << Indent << "]\n";
1432
1433 dumpEdges(BasicBlock);
1434}
1435
1436void VPlanPrinter::dumpRegion(const VPRegionBlock *Region) {
1437 OS << Indent << "subgraph " << getUID(Region) << " {\n";
1438 bumpIndent(1);
1439 OS << Indent << "fontname=Courier\n"
1440 << Indent << "label=\""
1441 << DOT::EscapeString(Region->isReplicator() ? "<xVFxUF> " : "<x1> ")
1442 << DOT::EscapeString(Region->getName()) << "\"\n";
1443
1444 if (auto *CanIV = Region->getCanonicalIV()) {
1445 OS << Indent << "\"";
1446 std::string Op;
1447 raw_string_ostream S(Op);
1448 CanIV->printAsOperand(S, SlotTracker);
1449 OS << DOT::EscapeString(Op);
1450 OS << " = CANONICAL-IV\"\n";
1451 }
1452
1453 // Dump the blocks of the region.
1454 assert(Region->getEntry() && "Region contains no inner blocks.");
1455 for (const VPBlockBase *Block : vp_depth_first_shallow(Region->getEntry()))
1456 dumpBlock(Block);
1457 bumpIndent(-1);
1458 OS << Indent << "}\n";
1459 dumpEdges(Region);
1460}
1461
1462#endif
1463
1464/// Returns true if there is a vector loop region and \p VPV is defined in a
1465/// loop region.
1466static bool isDefinedInsideLoopRegions(const VPValue *VPV) {
1467 if (isa<VPRegionValue>(VPV))
1468 return true;
1469 const VPRecipeBase *DefR = VPV->getDefiningRecipe();
1470 return DefR && (!DefR->getParent()->getPlan()->getVectorLoopRegion() ||
1472}
1473
1478 replaceUsesWithIf(New, [](VPUser &, unsigned) { return true; });
1479 if (auto *SV = dyn_cast<VPSymbolicValue>(this))
1480 SV->markMaterialized();
1481}
1482
1484 VPValue *New,
1485 llvm::function_ref<bool(VPUser &U, unsigned Idx)> ShouldReplace) {
1487 // Note that this early exit is required for correctness; the implementation
1488 // below relies on the number of users for this VPValue to decrease, which
1489 // isn't the case if this == New.
1490 if (this == New)
1491 return;
1492
1493 for (unsigned J = 0; J < getNumUsers();) {
1494 VPUser *User = Users[J];
1495 bool RemovedUser = false;
1496 for (unsigned I = 0, E = User->getNumOperands(); I < E; ++I) {
1497 if (User->getOperand(I) != this || !ShouldReplace(*User, I))
1498 continue;
1499
1500 RemovedUser = true;
1501 User->setOperand(I, New);
1502 }
1503 // If a user got removed after updating the current user, the next user to
1504 // update will be moved to the current position, so we only need to
1505 // increment the index if the number of users did not change.
1506 if (!RemovedUser)
1507 J++;
1508 }
1509}
1510
1512 for (unsigned Idx = 0; Idx != getNumOperands(); ++Idx) {
1513 if (getOperand(Idx) == From)
1514 setOperand(Idx, To);
1515 }
1516}
1517
1518#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1520 OS << Tracker.getOrCreateName(this);
1521}
1522
1525 Op->printAsOperand(O, SlotTracker);
1526 });
1527}
1528#endif
1529
1530void VPSlotTracker::assignName(const VPValue *V) {
1531 assert(!VPValue2Name.contains(V) && "VPValue already has a name!");
1532 auto *UV = V->getUnderlyingValue();
1533 auto *VPI = dyn_cast_or_null<VPInstruction>(V);
1534 if (!UV && !(VPI && !VPI->getName().empty())) {
1535 VPValue2Name[V] = (Twine("vp<%") + Twine(NextSlot) + ">").str();
1536 NextSlot++;
1537 return;
1538 }
1539
1540 // Use the name of the underlying Value, wrapped in "ir<>", and versioned by
1541 // appending ".Number" to the name if there are multiple uses.
1542 std::string Name;
1543 if (UV)
1544 Name = getName(UV);
1545 else
1546 Name = VPI->getName();
1547
1548 assert(!Name.empty() && "Name cannot be empty.");
1549 StringRef Prefix = UV ? "ir<" : "vp<%";
1550 std::string BaseName = (Twine(Prefix) + Name + Twine(">")).str();
1551
1552 // First assign the base name for V.
1553 const auto &[A, _] = VPValue2Name.try_emplace(V, BaseName);
1554 // Integer or FP constants with different types will result in the same string
1555 // due to stripping types.
1557 return;
1558
1559 // If it is already used by C > 0 other VPValues, increase the version counter
1560 // C and use it for V.
1561 const auto &[C, UseInserted] = BaseName2Version.try_emplace(BaseName, 0);
1562 if (!UseInserted) {
1563 C->second++;
1564 A->second = (BaseName + Twine(".") + Twine(C->second)).str();
1565 }
1566}
1567
1568void VPSlotTracker::assignNames(const VPlan &Plan) {
1569 if (!Plan.VF.user_empty())
1570 assignName(&Plan.VF);
1571 if (!Plan.UF.user_empty())
1572 assignName(&Plan.UF);
1573 if (!Plan.VFxUF.user_empty())
1574 assignName(&Plan.VFxUF);
1575 assignName(&Plan.VectorTripCount);
1576 if (Plan.BackedgeTakenCount)
1577 assignName(Plan.BackedgeTakenCount);
1578 for (VPValue *LI : Plan.getLiveIns())
1579 assignName(LI);
1580
1581 ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<const VPBlockBase *>>
1582 RPOT(VPBlockDeepTraversalWrapper<const VPBlockBase *>(Plan.getEntry()));
1583 for (const VPBlockBase *VPB : RPOT) {
1584 if (auto *VPBB = dyn_cast<VPBasicBlock>(VPB))
1585 assignNames(VPBB);
1586 else
1587 for (auto *RV : cast<VPRegionBlock>(VPB)->getRegionValues())
1588 assignName(RV);
1589 }
1590}
1591
1592void VPSlotTracker::assignNames(const VPBasicBlock *VPBB) {
1593 for (const VPRecipeBase &Recipe : *VPBB)
1594 for (VPValue *Def : Recipe.definedValues())
1595 assignName(Def);
1596}
1597
1598std::string VPSlotTracker::getName(const Value *V) {
1599 std::string Name;
1600 raw_string_ostream S(Name);
1601 if (V->hasName() || !isa<Instruction>(V)) {
1602 V->printAsOperand(S, false);
1603 return Name;
1604 }
1605
1606 if (!MST) {
1607 // Lazily create the ModuleSlotTracker when we first hit an unnamed
1608 // instruction.
1609 auto *I = cast<Instruction>(V);
1610 // This check is required to support unit tests with incomplete IR.
1611 if (I->getParent()) {
1612 MST = std::make_unique<ModuleSlotTracker>(I->getModule());
1613 MST->incorporateFunction(*I->getFunction());
1614 } else {
1615 MST = std::make_unique<ModuleSlotTracker>(nullptr);
1616 }
1617 }
1618 V->printAsOperand(S, false, *MST);
1619 return Name;
1620}
1621
1622std::string VPSlotTracker::getOrCreateName(const VPValue *V) const {
1623 std::string Name = VPValue2Name.lookup(V);
1624 if (!Name.empty())
1625 return Name;
1626
1627 // If no name was assigned, no VPlan was provided when creating the slot
1628 // tracker or it is not reachable from the provided VPlan. This can happen,
1629 // e.g. when trying to print a recipe that has not been inserted into a VPlan
1630 // in a debugger.
1631 // TODO: Update VPSlotTracker constructor to assign names to recipes &
1632 // VPValues not associated with a VPlan, instead of constructing names ad-hoc
1633 // here.
1634 const VPRecipeBase *DefR = V->getDefiningRecipe();
1635 (void)DefR;
1636 assert((!DefR || !DefR->getParent() || !DefR->getParent()->getPlan()) &&
1637 "VPValue defined by a recipe in a VPlan?");
1638
1639 // Use the underlying value's name, if there is one.
1640 if (auto *UV = V->getUnderlyingValue()) {
1641 std::string Name;
1642 raw_string_ostream S(Name);
1643 UV->printAsOperand(S, false);
1644 return (Twine("ir<") + Name + ">").str();
1645 }
1646
1647 return "<badref>";
1648}
1649
1651 VPValue *TrueVal,
1652 VPValue *FalseVal, DebugLoc DL) {
1653 assert(ChainOp->getScalarType()->isIntegerTy(1) &&
1654 "ChainOp must be i1 for AnyOf reduction");
1655 VPIRFlags Flags(RecurKind::Or, /*IsOrdered=*/false, /*IsInLoop=*/false,
1656 FastMathFlags());
1657 auto *OrReduce =
1659 auto *Freeze = createNaryOp(Instruction::Freeze, {OrReduce}, DL);
1660 return createSelect(Freeze, TrueVal, FalseVal, DL, "rdx.select");
1661}
1662
1664 const std::function<bool(ElementCount)> &Predicate, VFRange &Range) {
1665 assert(!Range.isEmpty() && "Trying to test an empty VF range.");
1666 bool PredicateAtRangeStart = Predicate(Range.Start);
1667
1668 for (ElementCount TmpVF : VFRange(Range.Start * 2, Range.End))
1669 if (Predicate(TmpVF) != PredicateAtRangeStart) {
1670 Range.End = TmpVF;
1671 break;
1672 }
1673
1674 return PredicateAtRangeStart;
1675}
1676
1679 bool Reverse, DebugLoc DL) {
1680 VPlan &Plan = getPlan();
1682 if (Reverse) {
1683 // When folding the tail, we may compute an address that we don't in the
1684 // original scalar loop: drop the GEP no-wrap flags in this case. Otherwise
1685 // preserve existing flags without no-unsigned-wrap, as we will emit
1686 // negative indices.
1687 GEPNoWrapFlags ReverseFlags = Plan.hasTailFolded()
1689 : Flags.withoutNoUnsignedWrap();
1690 return tryInsertInstruction(new VPVectorEndPointerRecipe(
1691 Ptr, &Plan.getVF(), SourceElementTy, /*Stride=*/-1, ReverseFlags, DL));
1692 }
1693 Type *StrideTy = Plan.getDataLayout().getIndexType(Ptr->getScalarType());
1694 VPValue *StrideOne = Plan.getConstantInt(StrideTy, 1);
1695 return createVectorPointer(Ptr, SourceElementTy, StrideOne, Flags, DL);
1696}
1697
1699 assert(count_if(VPlans,
1700 [VF](const VPlanPtr &Plan) { return Plan->hasVF(VF); }) ==
1701 1 &&
1702 "Multiple VPlans for VF.");
1703
1704 for (const VPlanPtr &Plan : VPlans) {
1705 if (Plan->hasVF(VF))
1706 return *Plan.get();
1707 }
1708 llvm_unreachable("No plan found!");
1709}
1710
1713 // Reserve first location for self reference to the LoopID metadata node.
1714 MDs.push_back(nullptr);
1715 bool IsUnrollMetadata = false;
1716 MDNode *LoopID = L->getLoopID();
1717 if (LoopID) {
1718 // First find existing loop unrolling disable metadata.
1719 for (unsigned I = 1, IE = LoopID->getNumOperands(); I < IE; ++I) {
1720 auto *MD = dyn_cast<MDNode>(LoopID->getOperand(I));
1721 if (MD) {
1722 const auto *S = dyn_cast<MDString>(MD->getOperand(0));
1723 if (!S)
1724 continue;
1725 if (S->getString().starts_with("llvm.loop.unroll.runtime.disable"))
1726 continue;
1727 IsUnrollMetadata =
1728 S->getString().starts_with("llvm.loop.unroll.disable");
1729 }
1730 MDs.push_back(LoopID->getOperand(I));
1731 }
1732 }
1733
1734 if (!IsUnrollMetadata) {
1735 // Add runtime unroll disable metadata.
1736 LLVMContext &Context = L->getHeader()->getContext();
1737 SmallVector<Metadata *, 1> DisableOperands;
1738 DisableOperands.push_back(
1739 MDString::get(Context, "llvm.loop.unroll.runtime.disable"));
1740 MDNode *DisableNode = MDNode::get(Context, DisableOperands);
1741 MDs.push_back(DisableNode);
1742 MDNode *NewLoopID = MDNode::get(Context, MDs);
1743 // Set operand 0 to refer to the loop id itself.
1744 NewLoopID->replaceOperandWith(0, NewLoopID);
1745 L->setLoopID(NewLoopID);
1746 }
1747}
1748
1750 Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan,
1751 bool VectorizingEpilogue, MDNode *OrigLoopID,
1752 std::optional<unsigned> OrigAverageTripCount,
1753 unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF,
1754 bool DisableRuntimeUnroll) {
1755 // Update the metadata of the scalar loop. Skip the update when vectorizing
1756 // the epilogue loop to ensure it is updated only once. Also skip the update
1757 // when the scalar loop became unreachable.
1758 auto *ScalarPH = Plan.getScalarPreheader();
1759 if (ScalarPH && !VectorizingEpilogue) {
1760 std::optional<MDNode *> RemainderLoopID =
1763 if (RemainderLoopID) {
1764 OrigLoop->setLoopID(*RemainderLoopID);
1765 } else {
1766 if (DisableRuntimeUnroll)
1768
1769 LoopVectorizeHints Hints(OrigLoop, /*InterleaveOnlyWhenForced*/ false,
1770 *ORE);
1771 Hints.setAlreadyVectorized();
1772 }
1773 }
1774 // Tag the scalar remainder so downstream passes (e.g. the unroller and
1775 // WarnMissedTransforms) can produce more informative remarks. Only emit
1776 // when remarks are enabled.
1777 if (ORE->enabled() && ScalarPH && ScalarPH->hasPredecessors())
1778 OrigLoop->addIntLoopAttribute("llvm.loop.vectorize.epilogue", 1);
1779
1780 if (!VectorLoop)
1781 return;
1782
1783 if (std::optional<MDNode *> VectorizedLoopID = makeFollowupLoopID(
1784 OrigLoopID, {LLVMLoopVectorizeFollowupAll,
1786 VectorLoop->setLoopID(*VectorizedLoopID);
1787 } else {
1788 // Keep all loop hints from the original loop on the vector loop (we'll
1789 // replace the vectorizer-specific hints below).
1790 if (OrigLoopID)
1791 VectorLoop->setLoopID(OrigLoopID);
1792
1793 if (!VectorizingEpilogue) {
1794 LoopVectorizeHints Hints(VectorLoop, /*InterleaveOnlyWhenForced*/ false,
1795 *ORE);
1796 Hints.setAlreadyVectorized();
1797 }
1798 }
1799 // Tag the vector loop body so downstream passes can identify it. Only
1800 // emit when remarks are enabled.
1801 if (ORE->enabled())
1802 VectorLoop->addIntLoopAttribute("llvm.loop.vectorize.body", 1);
1804 TTI.getUnrollingPreferences(VectorLoop, *PSE.getSE(), UP, ORE);
1805 if (!UP.UnrollVectorizedLoop || VectorizingEpilogue)
1807
1808 // Set/update profile weights for the vector and remainder loops as original
1809 // loop iterations are now distributed among them. Note that original loop
1810 // becomes the scalar remainder loop after vectorization.
1811 //
1812 // For cases like foldTailByMasking() and requiresScalarEpiloque() we may
1813 // end up getting slightly roughened result but that should be OK since
1814 // profile is not inherently precise anyway. Note also possible bypass of
1815 // vector code caused by legality checks is ignored, assigning all the weight
1816 // to the vector loop, optimistically.
1817 //
1818 // For scalable vectorization we can't know at compile time how many
1819 // iterations of the loop are handled in one vector iteration, so instead
1820 // use the value of vscale used for tuning.
1821 unsigned AverageVectorTripCount = 0;
1822 unsigned RemainderAverageTripCount = 0;
1823 auto EC = VectorLoop->getLoopPreheader()->getParent()->getEntryCount();
1824 auto IsProfiled = EC && *EC != 0;
1825 if (!OrigAverageTripCount) {
1826 if (!IsProfiled)
1827 return;
1828 auto &SE = *PSE.getSE();
1829 AverageVectorTripCount = SE.getSmallConstantTripCount(VectorLoop);
1830 if (ProfcheckDisableMetadataFixes || !AverageVectorTripCount)
1831 return;
1832 if (ScalarPH)
1833 RemainderAverageTripCount =
1834 SE.getSmallConstantTripCount(OrigLoop) % EstimatedVFxUF;
1835 // Setting to 1 should be sufficient to generate the correct branch weights.
1836 OrigLoopInvocationWeight = 1;
1837 } else {
1838 // Calculate number of iterations in unrolled loop.
1839 AverageVectorTripCount = *OrigAverageTripCount / EstimatedVFxUF;
1840 // Calculate number of iterations for remainder loop.
1841 RemainderAverageTripCount = *OrigAverageTripCount % EstimatedVFxUF;
1842 }
1843 if (HeaderVPBB) {
1844 setLoopEstimatedTripCount(VectorLoop, AverageVectorTripCount,
1845 OrigLoopInvocationWeight);
1846 }
1847
1848 if (ScalarPH) {
1849 setLoopEstimatedTripCount(OrigLoop, RemainderAverageTripCount,
1850 OrigLoopInvocationWeight);
1851 }
1852}
1853
1854#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1856 if (VPlans.empty()) {
1857 O << "LV: No VPlans built.\n";
1858 return;
1859 }
1860 for (const auto &Plan : VPlans)
1862 Plan->printDOT(O);
1863 else
1864 Plan->print(O);
1865}
1866#endif
1867
1868bool llvm::canConstantBeExtended(const APInt *C, Type *NarrowType,
1870 APInt TruncatedVal = C->trunc(NarrowType->getScalarSizeInBits());
1871 unsigned WideSize = C->getBitWidth();
1872 APInt ExtendedVal = ExtKind == TTI::PR_SignExtend
1873 ? TruncatedVal.sext(WideSize)
1874 : TruncatedVal.zext(WideSize);
1875 return ExtendedVal == *C;
1876}
1877
1880 if (auto *IRV = dyn_cast<VPIRValue>(V))
1881 return TTI::getOperandInfo(IRV->getValue());
1882
1883 return {};
1884}
1885
1887 Type *ResultTy, ArrayRef<const VPValue *> Operands, ElementCount VF,
1888 TTI::VectorInstrContext VIC, bool AlwaysIncludeReplicatingR) {
1889 if (VF.isScalar())
1890 return 0;
1891
1892 assert(!VF.isScalable() &&
1893 "Scalarization overhead not supported for scalable vectors");
1894
1895 InstructionCost ScalarizationCost = 0;
1896 // Compute the cost of scalarizing the result if needed.
1897 if (!ResultTy->isVoidTy()) {
1898 for (Type *VectorTy :
1899 to_vector(getContainedTypes(toVectorizedTy(ResultTy, VF)))) {
1900 ScalarizationCost += TTI.getScalarizationOverhead(
1902 /*Insert=*/true, /*Extract=*/false, CostKind,
1903 /*ForPoisonSrc=*/true, {}, VIC);
1904 }
1905 }
1906 // Compute the cost of scalarizing the operands, skipping ones that do not
1907 // require extraction/scalarization and do not incur any overhead.
1908 SmallPtrSet<const VPValue *, 4> UniqueOperands;
1910 for (auto *Op : Operands) {
1911 if (isa<VPIRValue>(Op) ||
1912 (!AlwaysIncludeReplicatingR &&
1915 cast<VPReplicateRecipe>(Op)->getOpcode() == Instruction::Load) ||
1916 !UniqueOperands.insert(Op).second)
1917 continue;
1918 Tys.push_back(toVectorizedTy(Op->getScalarType(), VF));
1919 }
1920 return ScalarizationCost +
1921 TTI.getOperandsScalarizationOverhead(Tys, CostKind, VIC);
1922}
1923
1925 ElementCount VF) {
1926 const Instruction *UI = R->getUnderlyingInstr();
1927 if (isa<LoadInst>(UI))
1928 return true;
1929 assert(isa<StoreInst>(UI) && "R must either be a load or store");
1930
1931 if (!NumPredStores) {
1932 // Count the number of predicated stores in the VPlan, caching the result.
1933 // Only stores where scatter is not legal are counted, matching the legacy
1934 // cost model behavior.
1935 const VPlan &Plan = *R->getParent()->getPlan();
1936 NumPredStores = 0;
1937 for (const VPRegionBlock *VPRB :
1940 assert(VPRB->isReplicator() && "must only contain replicate regions");
1941 for (const VPBasicBlock *VPBB :
1943 vp_depth_first_shallow(VPRB->getEntry()))) {
1944 for (const VPRecipeBase &Recipe : *VPBB) {
1945 auto *RepR = dyn_cast<VPReplicateRecipe>(&Recipe);
1946 if (!RepR)
1947 continue;
1948 if (!isa<StoreInst>(RepR->getUnderlyingInstr()))
1949 continue;
1950 // Check if scatter is legal for this store. If so, don't count it.
1951 Type *Ty = RepR->getOperand(0)->getScalarType();
1952 auto *VTy = VectorType::get(Ty, VF);
1953 const Align Alignment =
1954 getLoadStoreAlignment(RepR->getUnderlyingInstr());
1955 if (!TTI.isLegalMaskedScatter(VTy, Alignment))
1956 ++(*NumPredStores);
1957 }
1958 }
1959 }
1960 }
1962}
1963
1965 return is_contained({Intrinsic::assume, Intrinsic::lifetime_end,
1966 Intrinsic::lifetime_start, Intrinsic::sideeffect,
1967 Intrinsic::pseudoprobe,
1968 Intrinsic::experimental_noalias_scope_decl},
1969 ID);
1970}
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< 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:672
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)
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:1711
static T * getPlanEntry(T *Start)
Definition VPlan.cpp:191
static void printFinalVPlan(VPlan &)
To make RUN_VPLAN_PASS print final VPlan.
Definition VPlan.cpp:919
static T * getEnclosingLoopRegionForRegion(T *P)
Return the enclosing loop region for region P.
Definition VPlan.cpp:586
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:1466
static bool hasConditionalTerminator(const VPBasicBlock *VPBB)
Definition VPlan.cpp:604
const char LLVMLoopVectorizeFollowupVectorized[]
Definition VPlan.cpp:63
static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry, DenseMap< VPValue *, VPValue * > &Old2NewVPValues)
Definition VPlan.cpp:1184
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:235
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
Definition APInt.cpp:1055
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
Definition APInt.cpp:1028
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:461
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:482
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:151
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:1698
void updateLoopMetadataAndProfileInfo(Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan, bool VectorizingEpilogue, MDNode *OrigLoopID, std::optional< unsigned > OrigAverageTripCount, unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF, bool DisableRuntimeUnroll)
Update loop metadata and profile info for both the scalar remainder loop and VectorLoop,...
Definition VPlan.cpp:1749
static bool getDecisionAndClampRange(const std::function< bool(ElementCount)> &Predicate, VFRange &Range)
Test a Predicate on a Range of VF's.
Definition VPlan.cpp:1663
void printPlans(raw_ostream &O)
Definition VPlan.cpp:1855
Utility class for getting and setting loop vectorizer hints in the form of loop metadata.
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:589
void setLoopID(MDNode *LoopID) const
Set the llvm.loop loop id metadata for this loop.
Definition LoopInfo.cpp:557
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:1565
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1432
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition Metadata.cpp:614
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:176
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
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:339
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:369
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:4376
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition VPlan.h:4451
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4403
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
Definition VPlan.cpp:508
iterator end()
Definition VPlan.h:4413
iterator begin()
Recipe iterator methods.
Definition VPlan.h:4411
VPBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Definition VPlan.cpp:542
InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override
Return the cost of this VPBasicBlock.
Definition VPlan.cpp:762
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:769
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:408
VPRegionBlock * getEnclosingLoopRegion()
Definition VPlan.cpp:596
VPBasicBlock * splitAt(iterator SplitAt)
Split current block at SplitAt by inserting a new block between the current block and its successors ...
Definition VPlan.cpp:563
RecipeListTy Recipes
The VPRecipes held in the order of output instructions to generate.
Definition VPlan.h:4391
void executeRecipes(VPTransformState *State, BasicBlock *BB)
Execute the recipes in the IR basic block BB.
Definition VPlan.cpp:549
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:676
bool isExiting() const
Returns true if the block is exiting it's parent region.
Definition VPlan.cpp:654
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:642
const VPRecipeBase & back() const
Definition VPlan.h:4425
bool empty() const
Definition VPlan.h:4422
size_t size() const
Definition VPlan.h:4421
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:94
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
Definition VPlan.h:315
VPRegionBlock * getParent()
Definition VPlan.h:192
const VPBasicBlock * getExitingBasicBlock() const
Definition VPlan.cpp:236
size_t getNumSuccessors() const
Definition VPlan.h:243
iterator_range< VPBlockBase ** > successors()
Definition VPlan.h:225
virtual void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const =0
Print plain-text dump of this VPBlockBase to O, prefixing all lines with Indent.
bool hasPredecessors() const
Returns true if this block has any predecessors.
Definition VPlan.h:223
void printSuccessors(raw_ostream &O, const Twine &Indent) const
Print the successors of this block to O, prefixing all lines with Indent.
Definition VPlan.cpp:664
size_t getNumPredecessors() const
Definition VPlan.h:244
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
Definition VPlan.h:306
VPBlockBase * getEnclosingBlockWithPredecessors()
Definition VPlan.cpp:258
bool hasSuccessors() const
Returns true if this block has any successors.
Definition VPlan.h:221
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:228
VPlan * getPlan()
Definition VPlan.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:183
VPBlockBase * getSinglePredecessor() const
Definition VPlan.h:239
const VPBlocksTy & getHierarchicalSuccessors()
Definition VPlan.h:263
VPBlockBase * getEnclosingBlockWithSuccessors()
An Enclosing Block of a block B is any block containing B, including B itself.
Definition VPlan.cpp:250
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:216
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:233
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:217
VPBlockBase(VPBlockTy SC, const std::string &N)
Definition VPlan.h:400
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBase NewBlock after BlockPtr.
Definition VPlanUtils.h:275
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:323
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:341
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:377
static void transferSuccessors(VPBlockBase *Old, VPBlockBase *New)
Transfer successors from Old to New. New must have no successors.
Definition VPlanUtils.h:361
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:691
VPlan-based builder utility analogous to IRBuilder.
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:1678
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:1650
VPInstruction * createOverflowingOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", const VPIRFlags &Flags={}, Type *ResultTy=nullptr)
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", const VPIRFlags &Flags={})
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:4529
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
Definition VPlan.cpp:476
BasicBlock * getIRBasicBlock() const
Definition VPlan.h:4553
VPIRBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Definition VPlan.cpp:501
Class to record and manage LLVM IR flags.
Definition VPlan.h:704
static LLVM_ABI_FOR_TEST VPIRInstruction * create(Instruction &I)
Create a new VPIRPhi for \I , if it is a PHINode, otherwise create a VPIRInstruction.
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1234
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
Definition VPlan.h:1280
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:411
LLVM_ABI_FOR_TEST void dump() const
Dump the recipe to stderr (for debugging).
Definition VPlan.cpp:117
VPBasicBlock * getParent()
Definition VPlan.h:483
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const
Print the recipe, delegating to printRecipe().
virtual LLVM_ABI_FOR_TEST ~VPRecipeValue()=0
Definition VPlan.cpp: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:4601
VPRegionBlock * clone() override
Clone all blocks in the single-entry single-exit region of the block and their recipes without updati...
Definition VPlan.cpp:741
const VPBlockBase * getEntry() const
Definition VPlan.h:4645
void dissolveToCFGLoop()
Remove the current region from its VPlan, connecting its predecessor to its entry,...
Definition VPlan.cpp:841
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4677
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
Definition VPlan.h:4740
VPRegionValue * getUsedHeaderMask() const
Return the header mask if it exists and is used, or null otherwise.
Definition VPlan.h:4733
VPInstruction * getOrCreateCanonicalIVIncrement()
Get the canonical IV increment instruction if it exists.
Definition VPlan.cpp:867
InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override
Return the cost of the block.
Definition VPlan.cpp:788
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:818
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4757
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPRegionBlock,...
Definition VPlan.cpp:758
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4713
const VPBlockBase * getExiting() const
Definition VPlan.h:4657
VPRegionValue * getHeaderMask() const
Return the header mask of the region, or null if not set.
Definition VPlan.h:4726
friend class VPlan
Definition VPlan.h:4602
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:3384
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:619
LLVM_ABI_FOR_TEST VPSingleDefValue(VPSingleDefRecipe *Def, Value *UV=nullptr, Type *Ty=nullptr)
Construct a VPSingleDefValue. Must only be used by VPSingleDefRecipe.
Definition VPlan.cpp: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:1622
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:1511
void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const
Print the operands to O.
Definition VPlan.cpp:1523
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:1474
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:1519
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:1477
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:1483
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:2267
LLVM_DUMP_METHOD void dump()
Definition VPlan.cpp:1336
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4780
LLVM_ABI_FOR_TEST void printDOT(raw_ostream &O) const
Print this VPlan in DOT format to O.
Definition VPlan.cpp:1175
friend class VPSlotTracker
Definition VPlan.h:4782
std::string getName() const
Return a string with the name of the plan and the applicable VFs and UFs.
Definition VPlan.cpp:1151
const DataLayout & getDataLayout() const
Definition VPlan.h:4987
VPBasicBlock * getEntry()
Definition VPlan.h:4876
Type * getIndexType() const
The type of the canonical induction variable of the vector loop.
Definition VPlan.h:5215
void setName(const Twine &newName)
Definition VPlan.h:5051
LLVM_ABI_FOR_TEST ~VPlan()
Definition VPlan.cpp:895
bool isExitBlock(VPBlockBase *VPBB)
Returns true if VPBB is an exit block.
Definition VPlan.cpp:914
friend class VPlanPrinter
Definition VPlan.h:4781
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:4981
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
Definition VPlan.cpp:1314
auto getLiveIns() const
Return the list of live-in VPValues available in the VPlan.
Definition VPlan.h:5115
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:4935
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1066
bool hasEarlyExit() const
Returns true if the VPlan is based on a loop with an early exit.
Definition VPlan.h:5185
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this plan.
Definition VPlan.cpp:1048
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:1081
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5033
void setEntry(VPBasicBlock *VPBB)
Definition VPlan.h:4865
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
Definition VPlan.h:5138
LLVM_ABI_FOR_TEST VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
Definition VPlan.cpp:1321
LLVM_DUMP_METHOD void dump() const
Dump the plan to stderr (for debugging).
Definition VPlan.cpp:1181
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4925
void execute(VPTransformState *State)
Generate the IR code for this VPlan.
Definition VPlan.cpp:924
LLVM_ABI_FOR_TEST void print(raw_ostream &O) const
Print this VPlan to O.
Definition VPlan.cpp:1134
bool hasTailFolded() const
Returns true if the vector loop region is tail-folded.
Definition VPlan.h:4897
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
Definition VPlan.h:4931
void printLiveIns(raw_ostream &O) const
Print the live-ins of this VPlan to O.
Definition VPlan.cpp:1090
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:4974
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:1222
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:5089
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition CallingConv.h:76
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
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:1868
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
Parameters that control the generic loop unrolling transformation.
bool UnrollVectorizedLoop
Disable runtime unrolling by default for vectorized loops.
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:1879
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:1964
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:1886
TargetTransformInfo::TargetCostKind CostKind
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:1924
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.
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.