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