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