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