64 "llvm.loop.vectorize.followup_vectorized";
66 "llvm.loop.vectorize.followup_epilogue";
75 cl::desc(
"Use dot format instead of plain text when dumping VPlans"));
77#define DEBUG_TYPE "loop-vectorize"
79#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
93 return Builder.CreateSub(
getRuntimeVF(Builder, Builder.getInt32Ty(), VF),
96 return Builder.getInt64(Lane);
101#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
112 (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() :
nullptr);
125bool VPRecipeValue::isDefinedBy(
const VPDef *
D)
const {
return Def ==
D; }
130 return DefValue ? DefValue->Def :
nullptr;
135 return DefValue ? DefValue->Def :
nullptr;
146 assert(Def &&
"VPRecipeValue requires a defining recipe");
147 Def->addDefinedValue(
this);
152 "trying to delete a VPRecipeValue with remaining users");
153 Def->removeDefinedValue(
this);
167 for (
unsigned i = 0; i < WorkList.
size(); i++) {
168 T *Current = WorkList[i];
169 if (!Current->hasPredecessors())
171 auto &Predecessors = Current->getPredecessors();
198 assert(ParentPlan->
getEntry() ==
this &&
"Can only set plan on its entry.");
218 if (!Successors.empty() || !Parent)
220 assert(Parent->getExiting() ==
this &&
221 "Block w/o successors not the exiting block of its parent.");
222 return Parent->getEnclosingBlockWithSuccessors();
226 if (!Predecessors.empty() || !Parent)
228 assert(Parent->getEntry() ==
this &&
229 "Block w/o predecessors not the entry of its parent.");
230 return Parent->getEnclosingBlockWithPredecessors();
235 while (It !=
end() && It->isPhi())
250 return Def->getUnderlyingValue();
253 return Data.VPV2Scalars[Def][
Lane.mapToCacheIndex(
VF)];
257 return Data.VPV2Scalars[Def][0];
264 return get(BuildVector->getOperand(
Lane.getKnownLane()),
true);
268 auto *VecPart =
Data.VPV2Vector[Def];
269 if (!VecPart->getType()->isVectorTy()) {
270 assert(
Lane.isFirstLane() &&
"cannot get lane > 0 for scalar");
275 auto *Extract =
Builder.CreateExtractElement(VecPart, LaneV);
285 Data.VPV2Scalars[Def].size() == 1)) &&
286 "Trying to access a single scalar per part but has multiple scalars "
293 return Data.VPV2Vector[Def];
295 auto GetBroadcastInstrs = [
this](
Value *V) {
304 Value *IRV = Def->getLiveInIRValue();
305 Value *
B = GetBroadcastInstrs(IRV);
314 set(Def, ScalarValue);
319 VPLane LastLane(IsSingleScalar ? 0 :
VF.getFixedValue() - 1);
324 assert(IsSingleScalar &&
"must be a single-scalar at this point");
331 ? LastInst->getParent()->getFirstNonPHIIt()
333 Builder.SetInsertPoint(&*NewIP);
334 Value *VectorValue = GetBroadcastInstrs(ScalarValue);
335 set(Def, VectorValue);
347 ->shouldEmitDebugInfoForProfiling() &&
350 unsigned UF =
Plan->getConcreteUF();
354 Builder.SetCurrentDebugLocation(*NewDIL);
357 << DIL->getFilename() <<
" Line: " << DIL->getLine());
369 for (
unsigned I = 0, E = StructTy->getNumElements();
I != E;
I++) {
370 Value *ScalarValue =
Builder.CreateExtractValue(ScalarInst,
I);
371 Value *VectorValue =
Builder.CreateExtractValue(WideValue,
I);
373 Builder.CreateInsertElement(VectorValue, ScalarValue, LaneExpr);
374 WideValue =
Builder.CreateInsertValue(WideValue, VectorValue,
I);
377 WideValue =
Builder.CreateInsertElement(WideValue, ScalarInst, LaneExpr);
383 auto &
CFG = State.CFG;
395 auto &
CFG = State.CFG;
400 Loop *ParentLoop = State.CurrentParentLoop;
405 SuccOrExitVPB = SuccOrExitVPB ? SuccOrExitVPB :
this;
406 if (State.Plan->isExitBlock(SuccOrExitVPB)) {
407 ParentLoop = State.LI->getLoopFor(
411 if (ParentLoop && !State.LI->getLoopFor(NewBB))
424 VPBasicBlock *PredVPBB = PredVPBlock->getExitingBasicBlock();
426 assert(
CFG.VPBB2IRBB.contains(PredVPBB) &&
427 "Predecessor basic-block not found building successor.");
433 assert(PredVPSuccessors.size() == 1 &&
434 "Predecessor ending w/o branch must have single successor.");
435 DebugLoc DL = PredBBTerminator->getDebugLoc();
436 PredBBTerminator->eraseFromParent();
440 UBI->setSuccessor(NewBB);
449 unsigned idx = PredVPSuccessors.front() ==
this ? 0 : 1;
451 assert((!TermBr->getSuccessor(idx) ||
453 (TermBr->getSuccessor(idx) == NewBB ||
454 PredVPBlock ==
getPlan()->getEntry()))) &&
455 "Trying to reset an existing successor block.");
456 TermBr->setSuccessor(idx, NewBB);
464 "VPIRBasicBlock can have at most two successors at the moment!");
467 IRBB->moveAfter(State->CFG.PrevBB);
468 State->Builder.SetInsertPoint(IRBB->getTerminator());
469 State->CFG.PrevBB = IRBB;
470 State->CFG.VPBB2IRBB[
this] = IRBB;
475 auto *Br = State->Builder.CreateBr(IRBB);
476 Br->setOperand(0,
nullptr);
477 IRBB->getTerminator()->eraseFromParent();
481 "other blocks must be terminated by a branch");
495 bool Replica =
bool(State->Lane);
500 Loop *PrevParentLoop = State->CurrentParentLoop;
501 State->CurrentParentLoop = State->LI->AllocateLoop();
508 State->LI->addTopLevelLoop(State->CurrentParentLoop);
513 assert((!R || R->isReplicator()) &&
514 "only replicate region blocks should remain");
518 if ((Replica &&
this ==
getParent()->getEntry()) ||
523 State->CFG.VPBB2IRBB[
this] = NewBB;
525 NewBB = createEmptyBasicBlock(*State);
527 State->Builder.SetInsertPoint(NewBB);
530 State->Builder.SetInsertPoint(Terminator);
532 State->CFG.PrevBB = NewBB;
533 State->CFG.VPBB2IRBB[
this] = NewBB;
542 State->CurrentParentLoop = State->CurrentParentLoop->getParentLoop();
554 <<
" in BB: " << BB->
getName() <<
'\n');
556 State->CFG.PrevVPBB =
this;
559 State->setDebugLocFrom(Recipe.getDebugLoc());
560 Recipe.execute(*State);
567 assert((SplitAt ==
end() || SplitAt->getParent() ==
this) &&
568 "can only split at a position in the same block");
576 if (ParentRegion && ParentRegion->getExiting() ==
this)
590 if (
P &&
P->isReplicator()) {
594 assert((!
P || !
P->isReplicator()) &&
"unexpected nested replicate regions");
611 "block with multiple successors doesn't have a recipe as terminator");
616 [[maybe_unused]]
bool IsSwitch =
626 "block with multiple successors not terminated by "
627 "conditional branch nor switch recipe");
633 assert((IsSwitch || IsBranchOnTwoConds) &&
634 "block with more than 2 successors not terminated by a switch or "
635 "branch-on-two-conds recipe");
641 "block with 0 or 1 successors terminated by conditional branch recipe");
661#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
669 O << Indent <<
"No successors\n";
671 O << Indent <<
"Successor(s): ";
674 O << LS << Succ->getName();
681 O << Indent <<
getName() <<
":\n";
683 auto RecipeIndent = Indent +
" ";
693std::pair<VPBlockBase *, VPBlockBase *>
701 Old2NewVPBlocks[BB] = NewBB;
702 if (InRegion && BB->getNumSuccessors() == 0) {
703 assert(!Exiting &&
"Multiple exiting blocks?");
707 assert((!InRegion || Exiting) &&
"regions must have a single exiting block");
714 NewPreds.
push_back(Old2NewVPBlocks[Pred]);
719 NewSuccs.
push_back(Old2NewVPBlocks[Succ]);
727 for (
const auto &[OldBB, NewBB] :
730 for (
const auto &[OldPred, NewPred] :
731 zip(OldBB->getPredecessors(), NewBB->getPredecessors()))
732 assert(NewPred == Old2NewVPBlocks[OldPred] &&
"Different predecessors");
734 for (
const auto &[OldSucc, NewSucc] :
735 zip(OldBB->successors(), NewBB->successors()))
736 assert(NewSucc == Old2NewVPBlocks[OldSucc] &&
"Different successors");
740 return std::make_pair(Old2NewVPBlocks[Entry],
741 Exiting ? Old2NewVPBlocks[Exiting] :
nullptr);
748 VPRegionBlock *NewRegion =
750 getName(), NewEntry, NewExiting)
751 : Plan.createReplicateRegion(NewEntry, NewExiting,
getName());
754 Block->setParent(NewRegion);
760 "Loop regions should have been lowered to plain CFG");
761 assert(!State->Lane &&
"Replicating a Region with non-null instance.");
762 assert(!State->VF.isScalable() &&
"VF is assumed to be non scalable.");
767 for (
unsigned Lane = 0, VF = State->VF.getFixedValue(); Lane < VF; ++Lane) {
772 Block->execute(State);
783 Cost += R.cost(VF, Ctx);
794 "must be in the entry block of a non-replicate region");
796 "loop region has a single predecessor (preheader), its entry block "
797 "has 2 incoming blocks");
801 Pred = Idx == 0 ?
Region->getSinglePredecessor() :
Region;
803 return Pred->getExitingBasicBlock();
815 : Ctx.TTI.getCFInstrCost(Instruction::UncondBr, Ctx.CostKind);
816 LLVM_DEBUG(
dbgs() <<
"Cost of " << BackedgeCost <<
" for VF " << VF
817 <<
": vector loop backedge\n");
818 Cost += BackedgeCost;
830 assert(VF.
isVector() &&
"Can only compute vector cost at the moment.");
832 return Then->cost(VF, Ctx);
835#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
839 auto NewIndent = Indent +
" ";
843 O <<
" = CANONICAL-IV\n";
849 O << Indent <<
"}\n";
859 if (CanIV->getNumUsers() > 0) {
861 auto *Zero = Plan.getZero(CanIV->getType());
864 VPBuilder HeaderBuilder(Header, Header->begin());
884 assert(CanIV &&
"Expected a canonical IV");
890 "VFxUF can be used only before it is materialized.");
892 return VPBuilder(ExitingLatch->getTerminator())
903 L->getUniqueExitBlocks(IRExitBlocks);
911 for (
auto *VPB : CreatedBlocks) {
916 for (
auto *Def : R.definedValues())
917 Def->replaceAllUsesWith(&DummyValue);
919 for (
unsigned I = 0, E = R.getNumOperands();
I != E;
I++)
920 R.setOperand(
I, &DummyValue);
923 CanIV->replaceAllUsesWith(&DummyValue);
930 delete BackedgeTakenCount;
953 State->CFG.PrevVPBB =
nullptr;
954 State->CFG.ExitBB = State->CFG.PrevBB->getSingleSuccessor();
958 State->VPDT.recalculate(*
this);
961 BasicBlock *VectorPreHeader = State->CFG.PrevBB;
963 State->CFG.DTU.applyUpdates(
981 State->CFG.DTU.applyUpdates(
989 Block->execute(State);
1002 Loop *L = State->LI->getLoopFor(BB);
1004 [L](
BasicBlock *Succ) {
return L->contains(Succ); }))
1010 Loop *SuccLoop = State->LI->getLoopFor(Succ);
1016 Target = State->LI->getSmallestCommonLoop(
Target, SuccLoop);
1018 State->LI->removeBlock(BB);
1020 Target->addBasicBlockToLoop(BB, *State->LI);
1025 if (!ScalarPhVPBB) {
1031 if (R.getNumOperands() == 1)
1032 R.eraseFromParent();
1039 Blocks.push_back(ScalarPh);
1041 State->LI->erase(*OrigLoop->
begin());
1042 State->LI->erase(OrigLoop);
1043 for (
auto *BB : Blocks)
1044 State->LI->removeBlock(BB);
1048 State->CFG.DTU.flush();
1055 BasicBlock *VectorLatchBB = State->CFG.VPBB2IRBB[LatchVPBB];
1070 Value *Phi = State->get(PhiR, NeedsScalar);
1073 Value *Val = State->get(PhiR->getOperand(1), NeedsScalar);
1100 return R->isReplicator() ? nullptr : R;
1107 return R->isReplicator() ? nullptr : R;
1111#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1115 if (VF.getNumUsers() > 0) {
1121 if (UF.getNumUsers() > 0) {
1127 if (VFxUF.getNumUsers() > 0) {
1133 if (VectorTripCount.getNumUsers() > 0) {
1136 O <<
" = vector-trip-count";
1139 if (BackedgeTakenCount && BackedgeTakenCount->getNumUsers()) {
1141 BackedgeTakenCount->printAsOperand(O,
SlotTracker);
1142 O <<
" = backedge-taken count";
1150 O <<
" = original trip-count";
1159 O <<
"VPlan '" <<
getName() <<
"' {";
1176 RSO << Name <<
" for ";
1178 RSO <<
"VF={" << VFs[0];
1187 RSO <<
"UF={" << UFs[0];
1214 NewDeepRPOT(NewEntry);
1217 for (
const auto &[OldBB, NewBB] :
1220 assert(OldBB->getRecipeList().size() == NewBB->getRecipeList().size() &&
1221 "blocks must have the same number of recipes");
1222 for (
const auto &[OldR, NewR] :
zip(*OldBB, *NewBB)) {
1223 assert(OldR.getNumOperands() == NewR.getNumOperands() &&
1224 "recipes must have the same number of operands");
1225 assert(OldR.getNumDefinedValues() == NewR.getNumDefinedValues() &&
1226 "recipes must define the same number of operands");
1227 for (
const auto &[OldV, NewV] :
1228 zip(OldR.definedValues(), NewR.definedValues()))
1229 Old2NewVPValues[OldV] = NewV;
1237 for (
unsigned I = 0,
E = NewR.getNumOperands();
I !=
E; ++
I) {
1239 NewR.setOperand(
I, NewOp);
1245 unsigned NumBlocksBeforeCloning = CreatedBlocks.size();
1255 return VPIRBB && VPIRBB->getIRBasicBlock() == ScalarHeaderIRBB;
1264 Old2NewVPValues[OldLiveIn] = NewPlan->getOrAddLiveIn(OldLiveIn);
1267 Old2NewVPValues[TripCountIRV] = NewPlan->getOrAddLiveIn(TripCountIRV);
1272 auto *OldCanIV = LoopRegion->getCanonicalIV();
1273 auto *NewCanIV = NewPlan->getVectorLoopRegion()->getCanonicalIV();
1274 assert(OldCanIV && NewCanIV &&
1275 "Loop regions of both plans must have canonical IVs.");
1276 Old2NewVPValues[OldCanIV] = NewCanIV;
1280 "All VPSymbolicValues must be handled below");
1282 if (BackedgeTakenCount)
1286 for (
auto [OldSV, NewSV] :
1287 {std::pair{&VectorTripCount, &NewPlan->VectorTripCount},
1288 {&VF, &NewPlan->VF},
1289 {&UF, &NewPlan->UF},
1290 {&VFxUF, &NewPlan->VFxUF},
1291 {BackedgeTakenCount, NewPlan->BackedgeTakenCount}}) {
1294 Old2NewVPValues[OldSV] = NewSV;
1295 if (OldSV->isMaterialized())
1296 NewSV->markMaterialized();
1305 NewPlan->Name = Name;
1308 "TripCount must have been added to Old2NewVPValues");
1309 NewPlan->TripCount = Old2NewVPValues[TripCount];
1314 unsigned NumBlocksAfterCloning = CreatedBlocks.size();
1316 seq<unsigned>(NumBlocksBeforeCloning, NumBlocksAfterCloning))
1317 NewPlan->CreatedBlocks.push_back(this->CreatedBlocks[
I]);
1318 CreatedBlocks.truncate(NumBlocksBeforeCloning);
1323 VPB != NewScalarHeader)
1332 CreatedBlocks.push_back(VPIRBB);
1344#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1352 const std::string &Name =
Block->getName();
1361 OS <<
"digraph VPlan {\n";
1362 OS <<
"graph [labelloc=t, fontsize=30; label=\"Vectorization Plan";
1363 if (!Plan.getName().empty())
1370 Plan.printLiveIns(SS);
1373 for (
auto Line : Lines)
1378 OS <<
"node [shape=rect, fontname=Courier, fontsize=30]\n";
1379 OS <<
"edge [fontname=Courier, fontsize=30]\n";
1380 OS <<
"compound=true\n";
1398 bool Hidden,
const Twine &Label) {
1403 OS << Indent << getUID(
Tail) <<
" -> " << getUID(Head);
1404 OS <<
" [ label=\"" << Label <<
'\"';
1406 OS <<
" ltail=" << getUID(From);
1408 OS <<
" lhead=" << getUID(To);
1410 OS <<
"; splines=none";
1415 auto &Successors =
Block->getSuccessors();
1416 if (Successors.size() == 1)
1417 drawEdge(
Block, Successors.front(),
false,
"");
1418 else if (Successors.size() == 2) {
1419 drawEdge(
Block, Successors.front(),
false,
"T");
1420 drawEdge(
Block, Successors.back(),
false,
"F");
1422 unsigned SuccessorNumber = 0;
1431 OS << Indent << getUID(BasicBlock) <<
" [label =\n";
1434 raw_string_ostream
SS(Str);
1441 StringRef(Str).rtrim(
'\n').split(Lines,
"\n");
1443 auto EmitLine = [&](StringRef
Line, StringRef Suffix) {
1449 EmitLine(Line,
" +\n");
1450 EmitLine(
Lines.back(),
"\n");
1453 OS << Indent <<
"]\n";
1455 dumpEdges(BasicBlock);
1459 OS << Indent <<
"subgraph " << getUID(Region) <<
" {\n";
1461 OS << Indent <<
"fontname=Courier\n"
1462 << Indent <<
"label=\""
1466 if (
auto *CanIV =
Region->getCanonicalIV()) {
1467 OS << Indent <<
"\"";
1469 raw_string_ostream S(
Op);
1470 CanIV->printAsOperand(S, SlotTracker);
1472 OS <<
" = CANONICAL-IV\"\n";
1476 assert(
Region->getEntry() &&
"Region contains no inner blocks.");
1480 OS << Indent <<
"}\n";
1492 return DefR && (!DefR->
getParent()->getPlan()->getVectorLoopRegion() ||
1502 SV->markMaterialized();
1517 bool RemovedUser =
false;
1540#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1552void VPSlotTracker::assignName(
const VPValue *V) {
1553 assert(!VPValue2Name.contains(V) &&
"VPValue already has a name!");
1554 auto *UV = V->getUnderlyingValue();
1556 if (!UV && !(VPI && !VPI->getName().empty())) {
1557 VPValue2Name[V] = (
Twine(
"vp<%") +
Twine(NextSlot) +
">").str();
1568 Name = VPI->getName();
1570 assert(!Name.empty() &&
"Name cannot be empty.");
1572 std::string BaseName = (
Twine(Prefix) + Name +
Twine(
">")).str();
1575 const auto &[
A,
_] = VPValue2Name.try_emplace(V, BaseName);
1583 const auto &[
C, UseInserted] = BaseName2Version.
try_emplace(BaseName, 0);
1586 A->second = (BaseName +
Twine(
".") +
Twine(
C->second)).str();
1590void VPSlotTracker::assignNames(
const VPlan &Plan) {
1592 assignName(&Plan.VF);
1594 assignName(&Plan.UF);
1596 assignName(&Plan.VFxUF);
1597 assignName(&Plan.VectorTripCount);
1598 if (Plan.BackedgeTakenCount)
1599 assignName(Plan.BackedgeTakenCount);
1603 ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<const VPBlockBase *>>
1604 RPOT(VPBlockDeepTraversalWrapper<const VPBlockBase *>(Plan.
getEntry()));
1605 for (
const VPBlockBase *VPB : RPOT) {
1613void VPSlotTracker::assignNames(
const VPBasicBlock *VPBB) {
1614 for (
const VPRecipeBase &Recipe : *VPBB)
1615 for (VPValue *Def : Recipe.definedValues())
1619std::string VPSlotTracker::getName(
const Value *V) {
1621 raw_string_ostream S(Name);
1623 V->printAsOperand(S,
false);
1632 if (
I->getParent()) {
1633 MST = std::make_unique<ModuleSlotTracker>(
I->getModule());
1634 MST->incorporateFunction(*
I->getFunction());
1636 MST = std::make_unique<ModuleSlotTracker>(
nullptr);
1639 V->printAsOperand(S,
false, *MST);
1644 std::string Name = VPValue2Name.lookup(V);
1658 "VPValue defined by a recipe in a VPlan?");
1661 if (
auto *UV = V->getUnderlyingValue()) {
1664 UV->printAsOperand(S,
false);
1665 return (
Twine(
"ir<") + Name +
">").str();
1675 .inferScalarType(ChainOp)
1677 "ChainOp must be i1 for AnyOf reduction");
1682 auto *Freeze =
createNaryOp(Instruction::Freeze, {OrReduce},
DL);
1683 return createSelect(Freeze, TrueVal, FalseVal,
DL,
"rdx.select");
1688 assert(!
Range.isEmpty() &&
"Trying to test an empty VF range.");
1689 bool PredicateAtRangeStart = Predicate(
Range.Start);
1692 if (Predicate(TmpVF) != PredicateAtRangeStart) {
1697 return PredicateAtRangeStart;
1707 auto MaxVFTimes2 = MaxVF * 2;
1709 VFRange SubRange = {VF, MaxVFTimes2};
1710 if (
auto Plan = tryToBuildVPlan(SubRange)) {
1715 VPlans.push_back(std::move(Plan));
1723 [VF](
const VPlanPtr &Plan) {
return Plan->hasVF(VF); }) ==
1725 "Multiple VPlans for VF.");
1727 for (
const VPlanPtr &Plan : VPlans) {
1728 if (Plan->hasVF(VF))
1738 bool IsUnrollMetadata =
false;
1739 MDNode *LoopID = L->getLoopID();
1748 if (S->getString().starts_with(
"llvm.loop.unroll.runtime.disable"))
1751 S->getString().starts_with(
"llvm.loop.unroll.disable");
1757 if (!IsUnrollMetadata) {
1759 LLVMContext &Context = L->getHeader()->getContext();
1762 MDString::get(Context,
"llvm.loop.unroll.runtime.disable"));
1768 L->setLoopID(NewLoopID);
1774 bool VectorizingEpilogue,
MDNode *OrigLoopID,
1775 std::optional<unsigned> OrigAverageTripCount,
1776 unsigned OrigLoopInvocationWeight,
unsigned EstimatedVFxUF,
1777 bool DisableRuntimeUnroll) {
1782 if (ScalarPH && !VectorizingEpilogue) {
1783 std::optional<MDNode *> RemainderLoopID =
1786 if (RemainderLoopID) {
1787 OrigLoop->setLoopID(*RemainderLoopID);
1789 if (DisableRuntimeUnroll)
1794 Hints.setAlreadyVectorized();
1800 if (ORE->enabled() && ScalarPH && ScalarPH->hasPredecessors())
1801 OrigLoop->addIntLoopAttribute(
"llvm.loop.vectorize.epilogue", 1);
1809 VectorLoop->
setLoopID(*VectorizedLoopID);
1816 if (!VectorizingEpilogue) {
1819 Hints.setAlreadyVectorized();
1827 TTI.getUnrollingPreferences(VectorLoop, *PSE.getSE(), UP, ORE);
1844 unsigned AverageVectorTripCount = 0;
1845 unsigned RemainderAverageTripCount = 0;
1847 auto IsProfiled = EC && EC->getCount();
1848 if (!OrigAverageTripCount) {
1851 auto &SE = *PSE.getSE();
1852 AverageVectorTripCount = SE.getSmallConstantTripCount(VectorLoop);
1856 RemainderAverageTripCount =
1857 SE.getSmallConstantTripCount(OrigLoop) % EstimatedVFxUF;
1859 OrigLoopInvocationWeight = 1;
1862 AverageVectorTripCount = *OrigAverageTripCount / EstimatedVFxUF;
1864 RemainderAverageTripCount = *OrigAverageTripCount % EstimatedVFxUF;
1868 OrigLoopInvocationWeight);
1873 OrigLoopInvocationWeight);
1877#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1879 if (VPlans.empty()) {
1880 O <<
"LV: No VPlans built.\n";
1883 for (
const auto &Plan : VPlans)
1894 unsigned WideSize =
C->getBitWidth();
1896 ? TruncatedVal.
sext(WideSize)
1897 : TruncatedVal.
zext(WideSize);
1898 return ExtendedVal == *
C;
1916 "Scalarization overhead not supported for scalable vectors");
1921 for (
Type *VectorTy :
1923 ScalarizationCost +=
TTI.getScalarizationOverhead(
1933 for (
auto *
Op : Operands) {
1935 (!AlwaysIncludeReplicatingR &&
1943 return ScalarizationCost +
1944 TTI.getOperandsScalarizationOverhead(Tys,
CostKind, VIC);
1958 const VPlan &Plan = *R->getParent()->getPlan();
1963 assert(VPRB->isReplicator() &&
"must only contain replicate regions");
1974 Type *Ty =
Types.inferScalarType(RepR->getOperand(0));
1976 const Align Alignment =
1978 if (!
TTI.isLegalMaskedScatter(VTy, Alignment))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu next use AMDGPU Next Use Analysis Printer
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This file defines the LoopVectorizationLegality class.
This file provides a LoopVectorizationPlanner class.
cl::opt< unsigned > NumberOfStoresToPredicate("vectorize-num-stores-pred", cl::init(1), cl::Hidden, cl::desc("Max number of stores to be predicated behind an if."))
The number of stores in a loop that are allowed to need predication.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static StringRef getName(Value *V)
This file defines the SmallVector class.
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.
static void addRuntimeUnrollDisableMetaData(Loop *L)
static T * getPlanEntry(T *Start)
static void printFinalVPlan(VPlan &)
To make RUN_VPLAN_PASS print final VPlan.
static T * getEnclosingLoopRegionForRegion(T *P)
Return the enclosing loop region for region P.
const char LLVMLoopVectorizeFollowupAll[]
static bool isDefinedInsideLoopRegions(const VPValue *VPV)
Returns true if there is a vector loop region and VPV is defined in a loop region.
static bool hasConditionalTerminator(const VPBasicBlock *VPBB)
const char LLVMLoopVectorizeFollowupVectorized[]
static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry, DenseMap< VPValue *, VPValue * > &Old2NewVPValues)
const char LLVMLoopVectorizeFollowupEpilogue[]
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.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Function * getParent() const
Return the enclosing method, or null if none.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
std::optional< const DILocation * > cloneByMultiplyingDuplicationFactor(unsigned DF) const
Returns a new DILocation with duplication factor DF * current duplication factor encoded in the discr...
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
constexpr bool isVector() const
One or more elements.
constexpr bool isScalar() const
Exactly one element.
Convenience struct for specifying and reasoning about fast-math flags.
std::optional< ProfileCount > getEntryCount(bool AllowSynthetic=false) const
Get the entry count for this function.
Common base class shared among various IRBuilders.
static InstructionCost getInvalid(CostType Val=0)
This is an important class for using LLVM in a threaded context.
A helper class to return the specified delimiter string after the first invocation of operator String...
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
std::vector< BlockT * > & getBlocksVector()
Return a direct, mutable handle to the blocks vector so that we can mutate it efficiently with techni...
void addChildLoop(LoopT *NewChild)
Add the specified loop to be a child of this loop.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
VPlan & getPlanFor(ElementCount VF) const
Return the VPlan for VF.
void updateLoopMetadataAndProfileInfo(Loop *VectorLoop, VPBasicBlock *HeaderVPBB, const VPlan &Plan, bool VectorizingEpilogue, MDNode *OrigLoopID, std::optional< unsigned > OrigAverageTripCount, unsigned OrigLoopInvocationWeight, unsigned EstimatedVFxUF, bool DisableRuntimeUnroll)
Update loop metadata and profile info for both the scalar remainder loop and VectorLoop,...
void buildVPlans(ElementCount MinVF, ElementCount MaxVF)
Build VPlans for power-of-2 VF's between MinVF and MaxVF inclusive, according to the information gath...
static bool getDecisionAndClampRange(const std::function< bool(ElementCount)> &Predicate, VFRange &Range)
Test a Predicate on a Range of VF's.
void printPlans(raw_ostream &O)
Utility class for getting and setting loop vectorizer hints in the form of loop metadata.
Represents a single loop in the control flow graph.
LLVM_ABI void addIntLoopAttribute(StringRef Name, unsigned Value, ArrayRef< StringRef > RemovePrefixes={}) const
Add an integer metadata attribute to this loop's loop-ID node.
void setLoopID(MDNode *LoopID) const
Set the llvm.loop loop id metadata for this loop.
LLVM_ABI void replaceOperandWith(unsigned I, Metadata *New)
Replace a specific operand.
const MDOperand & getOperand(unsigned I) const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned getNumOperands() const
Return number of MDNode operands.
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
size_type size() const
Determine the number of elements in the SetVector.
void insert_range(Range &&R)
bool insert(const value_type &X)
Insert a new element into the SetVector.
This class provides computation of slot numbers for LLVM Assembly writing.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
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.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isVoidTy() const
Return true if this is 'void'.
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
This function has undefined behavior.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
RecipeListTy::iterator iterator
Instruction iterators...
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
iterator begin()
Recipe iterator methods.
VPBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override
Return the cost of this VPBasicBlock.
const VPBasicBlock * getCFGPredecessor(unsigned Idx) const
Returns the predecessor block at index Idx with the predecessors as per the corresponding plain CFG.
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
void connectToPredecessors(VPTransformState &State)
Connect the VPBBs predecessors' in the VPlan CFG to the IR basic block generated for this VPBB.
VPRegionBlock * getEnclosingLoopRegion()
VPBasicBlock * splitAt(iterator SplitAt)
Split current block at SplitAt by inserting a new block between the current block and its successors ...
RecipeListTy Recipes
The VPRecipes held in the order of output instructions to generate.
void executeRecipes(VPTransformState *State, BasicBlock *BB)
Execute the recipes in the IR basic block BB.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print this VPBsicBlock to O, prefixing all lines with Indent.
bool isExiting() const
Returns true if the block is exiting it's parent region.
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
const VPRecipeBase & back() const
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
VPRegionBlock * getParent()
const VPBasicBlock * getExitingBasicBlock() const
void setName(const Twine &newName)
size_t getNumSuccessors() const
iterator_range< VPBlockBase ** > successors()
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.
void printSuccessors(raw_ostream &O, const Twine &Indent) const
Print the successors of this block to O, prefixing all lines with Indent.
size_t getNumPredecessors() const
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
VPBlockBase * getEnclosingBlockWithPredecessors()
bool hasSuccessors() const
Returns true if this block has any successors.
const VPBlocksTy & getPredecessors() const
virtual VPBlockBase * clone()=0
Clone the current block and it's recipes without updating the operands of the cloned recipes,...
void setPlan(VPlan *ParentPlan)
Sets the pointer of the plan containing the block.
const std::string & getName() const
VPBlockBase * getSinglePredecessor() const
const VPBlocksTy & getHierarchicalSuccessors()
VPBlockBase(const unsigned char SC, const std::string &N)
VPBlockBase * getEnclosingBlockWithSuccessors()
An Enclosing Block of a block B is any block containing B, including B itself.
const VPBasicBlock * getEntryBasicBlock() const
VPBlockBase * getSingleHierarchicalPredecessor()
VPBlockBase * getSingleSuccessor() const
const VPBlocksTy & getSuccessors() const
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBase NewBlock after BlockPtr.
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.
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
static void transferSuccessors(VPBlockBase *Old, VPBlockBase *New)
Transfer successors from Old to New. New must have no successors.
static std::pair< VPBlockBase *, VPBlockBase * > cloneFrom(VPBlockBase *Entry)
Clone the CFG for all nodes reachable from Entry, including cloning the blocks and their recipes.
VPlan-based builder utility analogous to IRBuilder.
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 ...
VPBasicBlock * getInsertBlock() const
VPInstruction * createOverflowingOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPRecipeWithIRFlags::WrapFlagsTy WrapFlags={false, false}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", const VPIRFlags &Flags={})
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", const VPIRFlags &Flags={})
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Instruction *Inst=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
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.
A special type of VPBasicBlock that wraps an existing IR basic block.
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
BasicBlock * getIRBasicBlock() const
VPIRBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Class to record and manage LLVM IR flags.
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.
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
In what follows, the term "input IR" refers to code that is fed into the vectorizer whereas the term ...
Value * getAsRuntimeExpr(IRBuilderBase &Builder, const ElementCount &VF) const
Returns an expression describing the lane index that can be used at runtime.
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...
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
LLVM_ABI_FOR_TEST void dump() const
Dump the recipe to stderr (for debugging).
VPBasicBlock * getParent()
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const
Print the recipe, delegating to printRecipe().
virtual LLVM_ABI_FOR_TEST ~VPRecipeValue()
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
VPRegionBlock * clone() override
Clone all blocks in the single-entry single-exit region of the block and their recipes without updati...
const VPBlockBase * getEntry() const
void dissolveToCFGLoop()
Remove the current region from its VPlan, connecting its predecessor to its entry,...
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
VPInstruction * getOrCreateCanonicalIVIncrement()
Get the canonical IV increment instruction if it exists.
InstructionCost cost(ElementCount VF, VPCostContext &Ctx) override
Return the cost of the block.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print this VPRegionBlock to O (recursively), prefixing all lines with Indent.
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPRegionBlock,...
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
const VPBlockBase * getExiting() const
VPValues defined by a VPRegionBlock, like the canonical IV.
Type * getType() const
Returns the type of the VPRegionValue.
DebugLoc getDebugLoc() const
Returns the debug location of the VPRegionValue.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
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...
An analysis for type-inference for VPValues.
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
void replaceUsesOfWith(VPValue *From, VPValue *To)
Replaces all uses of From in the VPUser with To.
void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const
Print the operands to O.
void setOperand(unsigned I, VPValue *New)
unsigned getNumOperands() const
VPValue * getOperand(unsigned N) const
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Value * getLiveInIRValue() const
Return the underlying IR value for a VPIRValue.
bool isDefinedOutsideLoopRegions() const
Returns true if the VPValue is defined outside any loop.
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
void printAsOperand(raw_ostream &OS, VPSlotTracker &Tracker) const
friend class VPRecipeValue
void assertNotMaterialized() const
Assert that this VPValue has not been materialized, if it is a VPSymbolicValue.
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
@ VPVRecipeValueSC
A symbolic live-in VPValue without IR backing.
void dump() const
Dump the value to stderr (for debugging).
void print(raw_ostream &OS, VPSlotTracker &Tracker) const
void replaceAllUsesWith(VPValue *New)
unsigned getNumUsers() const
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...
LLVM_DUMP_METHOD void dump()
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
LLVM_ABI_FOR_TEST void printDOT(raw_ostream &O) const
Print this VPlan in DOT format to O.
friend class VPSlotTracker
std::string getName() const
Return a string with the name of the plan and the applicable VFs and UFs.
VPBasicBlock * getEntry()
void setName(const Twine &newName)
VPIRBasicBlock * getExitBlock(BasicBlock *IRBB) const
Return the VPIRBasicBlock corresponding to IRBB.
LLVM_ABI_FOR_TEST ~VPlan()
bool isExitBlock(VPBlockBase *VPBB)
Returns true if VPBB is an exit block.
friend class VPlanPrinter
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
auto getLiveIns() const
Return the list of live-in VPValues available in the VPlan.
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
bool hasEarlyExit() const
Returns true if the VPlan is based on a loop with an early exit.
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this plan.
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
void setEntry(VPBasicBlock *VPBB)
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
LLVM_ABI_FOR_TEST VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
LLVM_DUMP_METHOD void dump() const
Dump the plan to stderr (for debugging).
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
void execute(VPTransformState *State)
Generate the IR code for this VPlan.
LLVM_ABI_FOR_TEST void print(raw_ostream &O) const
Print this VPlan to O.
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
void printLiveIns(raw_ostream &O) const
Print the live-ins of this VPlan to O.
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...
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI std::string EscapeString(const std::string &Label)
@ BasicBlock
Various leaf nodes.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
bool match(Val *V, const Pattern &P)
VPInstruction_match< VPInstruction::BranchOnTwoConds > m_BranchOnTwoConds()
VPInstruction_match< VPInstruction::BranchOnCount > m_BranchOnCount()
VPInstruction_match< VPInstruction::BuildVector > m_BuildVector()
BuildVector is matches only its opcode, w/o matching its operands as the number of operands is not fi...
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
bool isSingleScalar(const VPValue *VPV)
Returns true if VPV is a single scalar, either because it produces the same value for all lanes or on...
VPBasicBlock * getFirstLoopHeader(VPlan &Plan, VPDominatorTree &VPDT)
Returns the header block of the first, top-level loop, or null if none exist.
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.
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.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
cl::opt< bool > ProfcheckDisableMetadataFixes
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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)
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...
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.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
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...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
cl::opt< unsigned > ForceTargetInstructionCost
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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.
FunctionAddr VTableAddr Next
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...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
ArrayRef< Type * > getContainedTypes(Type *const &Ty)
Returns the types contained in Ty.
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
LLVM_ABI void DeleteDeadBlocks(ArrayRef< BasicBlock * > BBs, DomTreeUpdater *DTU=nullptr, bool KeepOneInputPHIs=false)
Delete the specified blocks from BB.
std::unique_ptr< VPlan > VPlanPtr
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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.
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.
TargetTransformInfo::TargetCostKind CostKind
const TargetTransformInfo & TTI
bool useEmulatedMaskMemRefHack(const VPReplicateRecipe *R, ElementCount VF)
Returns true if an artificially high cost for emulated masked memrefs should be used.
A VPValue representing a live-in from the input IR or a constant.
Type * getType() const
Returns the type of the underlying IR value.
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.