65 "llvm.loop.vectorize.followup_vectorized";
67 "llvm.loop.vectorize.followup_epilogue";
70#define DEBUG_TYPE "loop-vectorize"
72#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
86 return Builder.CreateSub(
getRuntimeVF(Builder, Builder.getInt32Ty(), VF),
89 return Builder.getInt64(Lane);
94#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
105 (Instr && Instr->getParent()) ? Instr->getParent()->getPlan() :
nullptr);
118bool VPRecipeValue::isDefinedBy(
const VPDef *
D)
const {
128 return MultiDef->getDef();
159 "trying to delete a VPRecipeValue with remaining users");
164 assert(Def &&
"VPSingleDefValue requires a defining recipe");
165 Def->addDefinedValue(
this);
174 assert(Def &&
"VPMultiDefValue requires a defining recipe");
175 Def->addDefinedValue(
this);
213 if (!Successors.empty() || !Parent)
215 assert(Parent->getExiting() ==
this &&
216 "Block w/o successors not the exiting block of its parent.");
217 return Parent->getEnclosingBlockWithSuccessors();
221 if (!Predecessors.empty() || !Parent)
223 assert(Parent->getEntry() ==
this &&
224 "Block w/o predecessors not the entry of its parent.");
225 return Parent->getEnclosingBlockWithPredecessors();
230 while (It !=
end() && It->isPhi())
245 "VPRegionValue must be materialized before VPTransformState::get");
247 return Def->getUnderlyingValue();
254 return Data.VPV2Scalars[Def][0];
258 auto *VecPart =
Data.VPV2Vector[Def];
259 if (!VecPart->getType()->isVectorTy()) {
265 auto *Extract =
Builder.CreateExtractElement(VecPart, LaneV);
272 "VPRegionValue must be materialized before VPTransformState::get");
273 if (NeedsSingleScalar) {
277 Data.VPV2Scalars[Def].size() == 1)) &&
278 "Trying to access a single scalar per part but has multiple scalars "
285 return Data.VPV2Vector[Def];
287 auto GetBroadcastInstrs = [
this](
Value *V) {
302 if (
auto InsertPt = LastInst->getInsertionPointAfterDef())
303 Builder.SetInsertPoint(*InsertPt);
304 Value *VectorValue = GetBroadcastInstrs(ScalarValue);
305 set(Def, VectorValue);
316 ->shouldEmitDebugInfoForProfiling() &&
319 unsigned UF =
Plan->getConcreteUF();
323 Builder.SetCurrentDebugLocation(*NewDIL);
326 << DIL->getFilename() <<
" Line: " << DIL->getLine());
341 bool NeedsSingleScalar =
345 Value *Phi =
get(PhiR, NeedsSingleScalar);
346 Value *Val =
get(PhiR->getOperand(1), NeedsSingleScalar);
353 auto &
CFG = State.CFG;
365 auto &
CFG = State.CFG;
370 Loop *ParentLoop = State.CurrentParentLoop;
375 SuccOrExitVPB = SuccOrExitVPB ? SuccOrExitVPB :
this;
376 if (State.Plan->isExitBlock(SuccOrExitVPB)) {
377 ParentLoop = State.LI->getLoopFor(
381 if (ParentLoop && !State.LI->getLoopFor(NewBB))
394 VPBasicBlock *PredVPBB = PredVPBlock->getExitingBasicBlock();
396 assert(
CFG.VPBB2IRBB.contains(PredVPBB) &&
397 "Predecessor basic-block not found building successor.");
403 assert(PredVPSuccessors.size() == 1 &&
404 "Predecessor ending w/o branch must have single successor.");
405 DebugLoc DL = PredBBTerminator->getDebugLoc();
410 UBI->setSuccessor(NewBB);
422 if (TermBr->getSuccessor(0) != NewBB &&
423 TermBr->getSuccessor(1) != NewBB) {
424 unsigned Idx = PredVPSuccessors.front() ==
this ? 0 : 1;
425 BasicBlock *ReplacedSucc = TermBr->getSuccessor(Idx);
428 "only VPIRBasicBlock predecessors may have an existing successor "
432 TermBr->setSuccessor(Idx, NewBB);
443 "VPIRBasicBlock can have at most two successors at the moment!");
446 IRBB->moveAfter(State->CFG.PrevBB);
447 State->Builder.SetInsertPoint(IRBB->getTerminator());
448 State->CFG.PrevBB = IRBB;
449 State->CFG.VPBB2IRBB[
this] = IRBB;
454 auto *Br = State->Builder.CreateBr(IRBB);
455 Br->setOperand(0,
nullptr);
456 IRBB->getTerminator()->eraseFromParent();
460 "other blocks must be terminated by a branch");
476 Loop *PrevParentLoop = State->CurrentParentLoop;
477 State->CurrentParentLoop = State->LI->AllocateLoop();
484 State->LI->addTopLevelLoop(State->CurrentParentLoop);
488 BasicBlock *NewBB = createEmptyBasicBlock(*State);
490 State->Builder.SetInsertPoint(NewBB);
493 State->Builder.SetInsertPoint(Terminator);
495 State->CFG.PrevBB = NewBB;
496 State->CFG.VPBB2IRBB[
this] = NewBB;
504 State->CurrentParentLoop = State->CurrentParentLoop->getParentLoop();
516 <<
" in BB: " << BB->
getName() <<
'\n');
518 State->CFG.PrevVPBB =
this;
521 State->setDebugLocFrom(Recipe.getDebugLoc());
522 Recipe.execute(*State);
529 assert((SplitAt ==
end() || SplitAt->getParent() ==
this) &&
530 "can only split at a position in the same block");
538 if (ParentRegion && ParentRegion->getExiting() ==
this)
552 if (
P &&
P->isReplicator()) {
556 assert((!
P || !
P->isReplicator()) &&
"unexpected nested replicate regions");
573 "block with multiple successors doesn't have a recipe as terminator");
578 [[maybe_unused]]
bool IsSwitch =
588 "block with multiple successors not terminated by "
589 "conditional branch nor switch recipe");
595 assert((IsSwitch || IsBranchOnTwoConds) &&
596 "block with more than 2 successors not terminated by a switch or "
597 "branch-on-two-conds recipe");
603 "block with 0 or 1 successors terminated by conditional branch recipe");
623#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
631 O << Indent <<
"No successors\n";
633 O << Indent <<
"Successor(s): ";
636 O << LS << Succ->getName();
643 O << Indent <<
getName() <<
":\n";
645 auto RecipeIndent = Indent +
" ";
655std::pair<VPBlockBase *, VPBlockBase *>
663 Old2NewVPBlocks[BB] = NewBB;
664 if (InRegion && BB->getNumSuccessors() == 0) {
665 assert(!Exiting &&
"Multiple exiting blocks?");
669 assert((!InRegion || Exiting) &&
"regions must have a single exiting block");
676 NewPreds.
push_back(Old2NewVPBlocks[Pred]);
681 NewSuccs.
push_back(Old2NewVPBlocks[Succ]);
689 for (
const auto &[OldBB, NewBB] :
692 for (
const auto &[OldPred, NewPred] :
693 zip(OldBB->getPredecessors(), NewBB->getPredecessors()))
694 assert(NewPred == Old2NewVPBlocks[OldPred] &&
"Different predecessors");
696 for (
const auto &[OldSucc, NewSucc] :
697 zip(OldBB->successors(), NewBB->successors()))
698 assert(NewSucc == Old2NewVPBlocks[OldSucc] &&
"Different successors");
702 return std::make_pair(Old2NewVPBlocks[Entry],
703 Exiting ? Old2NewVPBlocks[Exiting] :
nullptr);
709 "not a valid replicating region");
717 VPRegionBlock *NewRegion =
719 getName(), NewEntry, NewExiting)
720 : Plan.createReplicateRegion(NewEntry, NewExiting,
getName());
726 NewRegion->CanIVInfo->clearNUW();
729 Block->setParent(NewRegion);
740 Cost += R.cost(VF, Ctx);
748 Cost += Ctx.Opts.force_target_instruction_cost
750 : Ctx.TTI.getCFInstrCost(Instruction::UncondBr, Ctx.CostKind);
762 "must be in the entry block of a non-replicate region");
764 "loop region has a single predecessor (preheader), its entry block "
765 "has 2 incoming blocks");
769 Pred = Idx == 0 ?
Region->getSinglePredecessor() :
Region;
771 return Pred->getExitingBasicBlock();
781 if (Ctx.Opts.force_target_instruction_cost)
783 LLVM_DEBUG(
dbgs() <<
"Cost of " <<
C <<
" for VF " << VF <<
": " << Name
787 AddCost(Ctx.TTI.getCFInstrCost(Instruction::UncondBr, Ctx.CostKind),
788 "vector loop backedge");
790 AddCost(Ctx.TTI.getArithmeticInstrCost(
792 "canonical IV increment");
806 assert(VF.
isVector() &&
"Can only compute vector cost at the moment.");
814 return Then->cost(VF, Ctx);
817 Cost += Then->cost(VF, Ctx);
819 if (Ctx.Opts.force_target_instruction_cost) {
820 ThenBranchCost =
InstructionCost(*Ctx.Opts.force_target_instruction_cost);
824 Ctx.TTI.getCFInstrCost(Instruction::UncondBr, Ctx.CostKind);
828 LLVM_DEBUG(
dbgs() <<
"Cost of " << ThenBranchCost <<
" for VF " << VF
829 <<
": unconditional branches from " << Then->getName()
831 return Cost + ThenBranchCost;
834#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
838 auto NewIndent = Indent +
" ";
842 O <<
" = CANONICAL-IV\n";
846 O <<
" = HEADER-MASK\n";
852 O << Indent <<
"}\n";
862 if (!CanIV->user_empty()) {
864 auto *Zero = Plan.getZero(CanIV->getType());
867 VPBuilder HeaderBuilder(Header->begin());
887 assert(CanIV &&
"Expected a canonical IV");
893 "VFxUF can be used only before it is materialized.");
895 return VPBuilder(ExitingLatch->getTerminator())
902 : VectorTripCount(IdxTy), VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
907 L->getUniqueExitBlocks(IRExitBlocks);
919 for (
unsigned I = 0, E = R.getNumOperands();
I != E;
I++)
920 R.setOperand(
I, &DummyValue);
922 for (
auto [Idx, VPB] :
enumerate(CreatedBlocks)) {
923 assert(VPB->getNumber() == Idx &&
"block with mismatched number");
942 "all region blocks must be dissolved before ::execute");
945 State->CFG.PrevVPBB =
nullptr;
946 State->CFG.ExitBB = State->CFG.PrevBB->getSingleSuccessor();
950 State->VPDT.recalculate(*
this);
953 BasicBlock *VectorPreHeader = State->CFG.PrevBB;
955 State->CFG.DTU.applyUpdates(
973 State->CFG.DTU.applyUpdates(
981 Block->execute(State);
994 Loop *L = State->LI->getLoopFor(BB);
996 [L](
BasicBlock *Succ) {
return L->contains(Succ); }))
1002 Loop *SuccLoop = State->LI->getLoopFor(Succ);
1008 Target = State->LI->getSmallestCommonLoop(
Target, SuccLoop);
1010 State->LI->removeBlock(BB);
1012 Target->addBasicBlockToLoop(BB, *State->LI);
1017 if (!ScalarPhVPBB) {
1023 if (R.getNumOperands() == 1)
1024 R.eraseFromParent();
1034 State->LI->erase(*OrigLoop->
begin());
1035 State->LI->erase(OrigLoop);
1036 for (
auto *BB : Blocks)
1037 State->LI->removeBlock(BB);
1041 State->CFG.DTU.flush();
1044 State->fixupHeaderPhis();
1075 return R->isReplicator() || R->getNumPredecessors() != 1 ? nullptr : R;
1076 if (!
B->hasSuccessors())
1092 assert(LoopRegion &&
"expected a vector loop region");
1098#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1102 if (!VF.user_empty()) {
1108 if (!UF.user_empty()) {
1114 if (!VFxUF.user_empty()) {
1120 if (!VectorTripCount.user_empty()) {
1123 O <<
" = vector-trip-count";
1127 if (TripCount && !TripCount->user_empty()) {
1131 O <<
" = original trip-count";
1140 O <<
"VPlan '" <<
getName() <<
"' {";
1157 RSO << Name <<
" for ";
1159 RSO <<
"VF={" << VFs[0];
1168 RSO <<
"UF={" << UFs[0];
1195 NewDeepRPOT(NewEntry);
1198 for (
const auto &[OldBB, NewBB] :
1201 assert(OldBB->getRecipeList().size() == NewBB->getRecipeList().
size() &&
1202 "blocks must have the same number of recipes");
1203 for (
const auto &[OldR, NewR] :
zip(*OldBB, *NewBB)) {
1204 assert(OldR.getNumOperands() == NewR.getNumOperands() &&
1205 "recipes must have the same number of operands");
1206 assert(OldR.getNumDefinedValues() == NewR.getNumDefinedValues() &&
1207 "recipes must define the same number of operands");
1208 for (
const auto &[OldV, NewV] :
1209 zip(OldR.definedValues(), NewR.definedValues()))
1210 Old2NewVPValues[OldV] = NewV;
1218 for (
unsigned I = 0,
E = NewR.getNumOperands();
I !=
E; ++
I) {
1220 NewR.setOperand(
I, NewOp);
1226 unsigned NumBlocksBeforeCloning = CreatedBlocks.size();
1236 return VPIRBB && VPIRBB->getIRBasicBlock() == ScalarHeaderIRBB;
1246 Old2NewVPValues[OldLiveIn] = NewPlan->getOrAddLiveIn(OldLiveIn);
1249 Old2NewVPValues[TripCountIRV] = NewPlan->getOrAddLiveIn(TripCountIRV);
1254 "All VPSymbolicValues must be handled below");
1257 auto *NewLoopRegion = NewPlan->getVectorLoopRegion();
1258 for (
auto [Old, New] :
zip_equal(LoopRegion->getRegionValues(),
1259 NewLoopRegion->getRegionValues())) {
1260 Old2NewVPValues[Old] = New;
1261 if (Old->isMaterialized())
1262 New->markMaterialized();
1267 for (
auto [OldSV, NewSV] :
1268 {std::pair{&VectorTripCount, &NewPlan->VectorTripCount},
1269 {&VF, &NewPlan->VF},
1270 {&UF, &NewPlan->UF},
1271 {&VFxUF, &NewPlan->VFxUF}}) {
1272 Old2NewVPValues[OldSV] = NewSV;
1273 if (OldSV->isMaterialized())
1274 NewSV->markMaterialized();
1283 NewPlan->Name = Name;
1286 "TripCount must have been added to Old2NewVPValues");
1287 NewPlan->TripCount = Old2NewVPValues[TripCount];
1292 unsigned NumBlocksAfterCloning = CreatedBlocks.size();
1294 seq<unsigned>(NumBlocksBeforeCloning, NumBlocksAfterCloning)) {
1295 this->CreatedBlocks[
I]->setPlan(NewPlan);
1296 this->CreatedBlocks[
I]->setNumber(NewPlan->CreatedBlocks.size());
1297 NewPlan->CreatedBlocks.push_back(this->CreatedBlocks[
I]);
1299 CreatedBlocks.truncate(NumBlocksBeforeCloning);
1304 VPB != NewScalarHeader)
1313 VPIRBB->setPlan(
this);
1314 VPIRBB->setNumber(CreatedBlocks.size());
1315 CreatedBlocks.push_back(VPIRBB);
1327#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1337 OS <<
"digraph VPlan {\n";
1338 OS <<
"graph [labelloc=t, fontsize=30; label=\"Vectorization Plan";
1339 if (!Plan.getName().empty())
1346 Plan.printLiveIns(SS);
1349 for (
auto Line : Lines)
1354 OS <<
"node [shape=rect, fontname=Courier, fontsize=30]\n";
1355 OS <<
"edge [fontname=Courier, fontsize=30]\n";
1356 OS <<
"compound=true\n";
1374 bool Hidden,
const Twine &Label) {
1379 OS << Indent << getUID(Tail) <<
" -> " << getUID(Head);
1380 OS <<
" [ label=\"" << Label <<
'\"';
1382 OS <<
" ltail=" << getUID(From);
1384 OS <<
" lhead=" << getUID(To);
1386 OS <<
"; splines=none";
1391 auto &Successors =
Block->getSuccessors();
1392 if (Successors.size() == 1)
1393 drawEdge(
Block, Successors.front(),
false,
"");
1394 else if (Successors.size() == 2) {
1395 drawEdge(
Block, Successors.front(),
false,
"T");
1396 drawEdge(
Block, Successors.back(),
false,
"F");
1398 unsigned SuccessorNumber = 0;
1407 OS << Indent << getUID(BasicBlock) <<
" [label =\n";
1410 raw_string_ostream
SS(Str);
1417 StringRef(Str).rtrim(
'\n').split(Lines,
"\n");
1419 auto EmitLine = [&](StringRef
Line, StringRef Suffix) {
1425 EmitLine(Line,
" +\n");
1426 EmitLine(
Lines.back(),
"\n");
1429 OS << Indent <<
"]\n";
1431 dumpEdges(BasicBlock);
1435 OS << Indent <<
"subgraph " << getUID(Region) <<
" {\n";
1437 OS << Indent <<
"fontname=Courier\n"
1438 << Indent <<
"label=\""
1442 if (
auto *CanIV =
Region->getCanonicalIV()) {
1443 OS << Indent <<
"\"";
1445 raw_string_ostream S(
Op);
1446 CanIV->printAsOperand(S, SlotTracker);
1448 OS <<
" = CANONICAL-IV\"\n";
1452 assert(
Region->getEntry() &&
"Region contains no inner blocks.");
1456 OS << Indent <<
"}\n";
1468 return DefR && (DefR->
getParent()->getEnclosingLoopRegion() ||
1469 !DefR->
getParent()->getPlan()->getVectorLoopRegion());
1478 SV->markMaterialized();
1492 bool RemovedUser =
false;
1515#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1527void VPSlotTracker::assignName(
const VPValue *V) {
1528 assert(!VPValue2Name.contains(V) &&
"VPValue already has a name!");
1529 auto *UV = V->getUnderlyingValue();
1531 if (!UV && !(VPI && !VPI->getName().empty())) {
1532 VPValue2Name[V] = (
Twine(
"vp<%") +
Twine(NextSlot) +
">").str();
1543 Name = VPI->getName();
1545 assert(!Name.empty() &&
"Name cannot be empty.");
1547 std::string BaseName = (
Twine(Prefix) + Name +
Twine(
">")).str();
1550 const auto &[
A,
_] = VPValue2Name.try_emplace(V, BaseName);
1558 const auto &[
C, UseInserted] = BaseName2Version.
try_emplace(BaseName, 0);
1561 A->second = (BaseName +
Twine(
".") +
Twine(
C->second)).str();
1565void VPSlotTracker::assignNames(
const VPlan &Plan) {
1567 assignName(&Plan.VF);
1569 assignName(&Plan.UF);
1571 assignName(&Plan.VFxUF);
1572 assignName(&Plan.VectorTripCount);
1576 ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<const VPBlockBase *>>
1577 RPOT(VPBlockDeepTraversalWrapper<const VPBlockBase *>(Plan.
getEntry()));
1578 for (
const VPBlockBase *VPB : RPOT) {
1587void VPSlotTracker::assignNames(
const VPBasicBlock *VPBB) {
1588 for (
const VPRecipeBase &Recipe : *VPBB)
1589 for (VPValue *Def : Recipe.definedValues())
1596 MST = std::make_unique<ModuleSlotTracker>(
getModule());
1598 MST->incorporateFunction(*F);
1603std::string VPSlotTracker::getName(
const Value *V) {
1605 raw_string_ostream S(Name);
1609 if (!
I ||
I->hasName() || !
I->getParent()) {
1610 V->printAsOperand(S,
false);
1614 V->printAsOperand(S,
false, getOrCreateMST());
1619 N->printAsOperand(O, getOrCreateMST(),
getModule());
1623 std::string Name = VPValue2Name.lookup(V);
1636 if (
auto *UV = V->getUnderlyingValue()) {
1639 UV->printAsOperand(S,
false);
1640 return (
Twine(
"ir<") + Name +
">").str();
1648 assert(!
Range.isEmpty() &&
"Trying to test an empty VF range.");
1649 bool PredicateAtRangeStart = Predicate(
Range.Start);
1652 if (Predicate(TmpVF) != PredicateAtRangeStart) {
1657 return PredicateAtRangeStart;
1662 [VF](
const VPlanPtr &Plan) {
return Plan->hasVF(VF); }) ==
1664 "Multiple VPlans for VF.");
1666 for (
const VPlanPtr &Plan : VPlans) {
1667 if (Plan->hasVF(VF))
1677 bool IsUnrollMetadata =
false;
1678 MDNode *LoopID = L->getLoopID();
1687 if (S->getString().starts_with(
"llvm.loop.unroll.runtime.disable"))
1690 S->getString().starts_with(
"llvm.loop.unroll.disable");
1696 if (!IsUnrollMetadata) {
1698 LLVMContext &Context = L->getHeader()->getContext();
1701 MDString::get(Context,
"llvm.loop.unroll.runtime.disable"));
1707 L->setLoopID(NewLoopID);
1713 bool VectorizingEpilogue,
MDNode *OrigLoopID,
1714 std::optional<unsigned> OrigAverageTripCount,
1715 unsigned OrigLoopInvocationWeight,
unsigned EstimatedVFxUF,
1716 bool DisableRuntimeUnroll,
bool UnrollVectorizedLoop) {
1721 if (ScalarPH && !VectorizingEpilogue) {
1722 std::optional<MDNode *> RemainderLoopID =
1725 if (RemainderLoopID) {
1726 OrigLoop->setLoopID(*RemainderLoopID);
1728 if (DisableRuntimeUnroll)
1739 if (ORE->enabled() && ScalarPH && ScalarPH->hasPredecessors())
1740 OrigLoop->addIntLoopAttribute(
"llvm.loop.vectorize.epilogue", 1);
1748 VectorLoop->
setLoopID(*VectorizedLoopID);
1755 if (!VectorizingEpilogue) {
1765 if (!UnrollVectorizedLoop || VectorizingEpilogue)
1781 unsigned AverageVectorTripCount = 0;
1782 unsigned RemainderAverageTripCount = 0;
1784 auto IsProfiled = EC && *EC != 0;
1785 if (!OrigAverageTripCount) {
1788 auto &SE = *PSE.getSE();
1789 AverageVectorTripCount = SE.getSmallConstantTripCount(VectorLoop);
1793 RemainderAverageTripCount =
1794 SE.getSmallConstantTripCount(OrigLoop) % EstimatedVFxUF;
1796 OrigLoopInvocationWeight = 1;
1799 AverageVectorTripCount = *OrigAverageTripCount / EstimatedVFxUF;
1801 RemainderAverageTripCount = *OrigAverageTripCount % EstimatedVFxUF;
1805 OrigLoopInvocationWeight);
1810 OrigLoopInvocationWeight);
1814#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1816 if (VPlans.empty()) {
1817 O <<
"LV: No VPlans built.\n";
1820 for (
const auto &Plan : VPlans)
1821 if (Opts.vplan_print_in_dot_format)
1831 unsigned WideSize =
C->getBitWidth();
1833 ? TruncatedVal.
sext(WideSize)
1834 : TruncatedVal.
zext(WideSize);
1835 return ExtendedVal == *
C;
1846#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1848 if (!PlanForSlotTracker)
1851 SlotTracker = std::make_unique<VPSlotTracker>(PlanForSlotTracker);
1852 return SlotTracker.get();
1863 "Scalarization overhead not supported for scalable vectors");
1868 for (
Type *VectorTy :
1870 ScalarizationCost +=
TTI.getScalarizationOverhead(
1882 (!AlwaysIncludeReplicatingR &&
1890 return ScalarizationCost +
1891 TTI.getOperandsScalarizationOverhead(Tys,
CostKind, VIC);
1905 const VPlan &Plan = *R->getParent()->getPlan();
1910 assert(VPRB->isReplicator() &&
"must only contain replicate regions");
1921 const Align Alignment =
1923 if (!
TTI.isLegalMaskedScatter(VTy, Alignment))
1933 return is_contained({Intrinsic::assume, Intrinsic::lifetime_end,
1934 Intrinsic::lifetime_start, Intrinsic::sideeffect,
1935 Intrinsic::pseudoprobe,
1936 Intrinsic::experimental_noalias_scope_decl},
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.
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.
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 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[]
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.
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.
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.
LLVM_ABI void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Update PHI nodes in this BasicBlock before removal of predecessor Pred.
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...
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
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.
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.
std::optional< uint64_t > getEntryCount() 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.
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.
block_iterator block_begin() const
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, bool UnrollVectorizedLoop)
Update loop metadata and profile info for both the scalar remainder loop and VectorLoop,...
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.
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.
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)
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.
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.
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.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
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
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 InstructionCost cost(ElementCount VF, VPCostContext &Ctx)=0
Return the cost of the block.
const std::string & getName() const
VPBlockBase * getSinglePredecessor() const
const VPBlocksTy & getHierarchicalSuccessors()
VPBlockBase * getEnclosingBlockWithSuccessors()
An Enclosing Block of a block B is any block containing B, including B itself.
const VPBasicBlock * getEntryBasicBlock() const
VPBlockBase * getSingleSuccessor() const
const VPBlocksTy & getSuccessors() const
VPBlockBase(VPBlockTy SC, const std::string &N)
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.
A recipe for generating conditional branches on the bits of a mask.
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="", 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.
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.
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.
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.
bool isFirstLane() const
Returns true if this is the first lane of the whole vector.
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)
~VPMultiDefValue() override
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
void dump() const
Dump the recipe to stderr (for debugging).
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const
Print the recipe, delegating to printRecipe().
virtual LLVM_ABI_FOR_TEST ~VPRecipeValue()=0
VPRecipeValue(unsigned char SC, Value *UV, Type *Ty=nullptr)
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...
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
VPRegionValue * getUsedHeaderMask() const
Return the header mask if it exists and is used, or null otherwise.
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.
Type * getCanonicalIVType() const
Return the type of the canonical IV for loop regions.
const VPBranchOnMaskRecipe * getEntryBranchOnMask() const
Return the VPBranchOnMaskRecipe from the entry block of this replicating region.
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
VPRegionValue * getHeaderMask() const
Return the header mask of the region, or null if not set.
VPValues are defined by a VPRegionBlock, like the canonical IV.
DebugLoc getDebugLoc() const
Returns the debug location of the VPRegionValue.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
VPSingleDefValue(VPSingleDefRecipe *Def, Value *UV=nullptr, Type *Ty=nullptr)
Construct a VPSingleDefValue. Must only be used by VPSingleDefRecipe.
~VPSingleDefValue() override
friend class VPSingleDefRecipe
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...
const Module * getModule() const
Returns the module the plan operates on, if any.
void printMetadataAsOperand(raw_ostream &O, const MDNode *N)
Print a reference to metadata node N to O.
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Type * getType() const
Returns the scalar type of this symbolic value.
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,...
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Value * getLiveInIRValue() const
Return the underlying IR value for a VPIRValue.
bool isDefinedOutsideLoopRegions() const
Returns true if the VPValue is defined outside any loop.
unsigned getVPValueID() const
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
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.
void replaceUsesWithIf(VPValue *New, llvm::function_ref< bool(VPUser *U)> ShouldReplace)
Go through the uses list for this VPValue and make each use point to New if the callback ShouldReplac...
@ VPVSingleDefValueSC
A symbolic live-in VPValue without IR backing.
@ VPVSymbolicSC
A live-in VPValue wrapping an IR Value.
@ VPRegionValueSC
A VPValue defined by a multi-def recipe.
@ VPVMultiDefValueSC
A VPValue defined by a VPSingleDefRecipe.
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
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()
Type * getIndexType() const
The type of the canonical induction variable of the vector loop.
void setName(const Twine &newName)
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.
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 ...
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
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.
const ilist_detail::compute_node_options< VPRecipeBase, Options... >::type::parent_ty * getParent() const
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.
LLVM_ABI std::string EscapeString(const std::string &Label)
@ BasicBlock
Various leaf nodes.
match_isa< To... > m_Isa()
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
bool match(Val *V, const Pattern &P)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
VPInstruction_match< VPInstruction::BranchOnTwoConds > m_BranchOnTwoConds()
VPInstruction_match< VPInstruction::BranchOnCount > m_BranchOnCount()
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
BranchProbability getExecutionProbability(BlockFrequency Freq)
Returns Freq as a BranchProbability, relative to the full mass.
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 by all users.
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.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
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.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
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
VPBuilderBase<> VPBuilder
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 make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
constexpr T divideNearest(U Numerator, V Denominator)
Returns (Numerator / Denominator) rounded by round-half-up.
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...
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)
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI bool setLoopEstimatedTripCount(Loop *L, unsigned EstimatedTripCount, std::optional< unsigned > EstimatedLoopInvocationWeight=std::nullopt)
Set llvm.loop.estimated_trip_count with the value EstimatedTripCount in the loop metadata of L.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
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.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
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.
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.
uint64_t getCostDivisor(std::optional< VPExecutionFrequency > Freq) const
TargetTransformInfo::OperandValueInfo getOperandInfo(VPValue *V) const
Returns the OperandInfo for V, if it is a live-in.
static bool isFreeScalarIntrinsic(Intrinsic::ID ID)
Returns true if ID is a pseudo intrinsic that is dropped via scalarization rather than widened.
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.
TargetTransformInfo::TargetCostKind CostKind
VPSlotTracker * getSlotTracker()
Return a VPSlotTracker to re-use for printing, lazily constructing it on first use.
const TargetTransformInfo & TTI
bool useEmulatedMaskMemRefHack(const VPReplicateRecipe *R, ElementCount VF)
Returns true if an artificially high cost for emulated masked memrefs should be used.
const VectorizeOptions & Opts
A VPValue representing a live-in from the input IR or a constant.
Type * getType() const
Returns the type of the underlying IR value.