34#define DEBUG_TYPE "vplan"
41class PlainCFGBuilder {
52 std::unique_ptr<VPlan> Plan;
73 bool isExternalDef(
Value *Val);
80 : TheLoop(Lp), LI(LI), LVer(LVer), Plan(std::make_unique<VPlan>(Lp)) {}
83 std::unique_ptr<VPlan> buildPlainCFG();
93 VPBBPreds.
push_back(getOrCreateVPBB(Pred));
98 return L && BB == L->getHeader();
102void PlainCFGBuilder::fixHeaderPhis() {
103 for (
auto *Phi : PhisToFix) {
104 assert(IRDef2VPValue.count(Phi) &&
"Missing VPInstruction for PHINode.");
105 VPValue *VPVal = IRDef2VPValue[
Phi];
108 assert(PhiR->getNumOperands() == 0 &&
"Expected VPPhi with no operands.");
110 "Expected Phi in header block.");
112 "header phi must have exactly 2 operands");
115 getOrCreateVPOperand(
Phi->getIncomingValueForBlock(Pred)));
121VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {
122 if (
auto *VPBB = BB2VPBB.lookup(BB)) {
129 LLVM_DEBUG(
dbgs() <<
"Creating VPBasicBlock for " << Name <<
"\n");
130 VPBasicBlock *VPBB = Plan->createVPBasicBlock(Name);
141bool PlainCFGBuilder::isExternalDef(
Value *Val) {
157VPValue *PlainCFGBuilder::getOrCreateVPOperand(
Value *IRVal) {
158 auto VPValIt = IRDef2VPValue.find(IRVal);
159 if (VPValIt != IRDef2VPValue.end())
162 return VPValIt->second;
171 assert(isExternalDef(IRVal) &&
"Expected external definition as operand.");
175 VPValue *NewVPVal = Plan->getOrAddLiveIn(IRVal);
176 IRDef2VPValue[IRVal] = NewVPVal;
183void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
192 assert(!IRDef2VPValue.count(Inst) &&
193 "Instruction shouldn't have been visited.");
198 if (Br->isConditional()) {
199 VPValue *
Cond = getOrCreateVPOperand(Br->getCondition());
210 if (
SI->getNumCases() == 0)
213 for (
auto Case :
SI->cases())
214 Ops.push_back(getOrCreateVPOperand(Case.getCaseValue()));
220 VPSingleDefRecipe *NewR;
231 PhisToFix.push_back(Phi);
235 DenseMap<const VPBasicBlock *, VPValue *> VPPredToIncomingValue;
236 for (
unsigned I = 0;
I !=
Phi->getNumOperands(); ++
I) {
237 VPPredToIncomingValue[BB2VPBB[
Phi->getIncomingBlock(
I)]] =
238 getOrCreateVPOperand(
Phi->getIncomingValue(
I));
242 VPPredToIncomingValue.
lookup(Pred->getExitingBasicBlock()));
247 VPIRMetadata MD(*Inst);
249 const auto &[AliasScopeMD, NoAliasMD] =
252 MD.setMetadata(LLVMContext::MD_alias_scope, AliasScopeMD);
254 MD.setMetadata(LLVMContext::MD_noalias, NoAliasMD);
265 CI->getType(), CI->getDebugLoc(),
270 LI->getDebugLoc(), MD);
281 IRDef2VPValue[Inst] = NewR;
286std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG() {
289 for (VPIRBasicBlock *ExitVPBB : Plan->getExitBlocks())
290 BB2VPBB[ExitVPBB->getIRBasicBlock()] = ExitVPBB;
303 "Unexpected loop preheader");
304 for (
auto &
I : *ThePreheaderBB) {
305 if (
I.getType()->isVoidTy())
307 IRDef2VPValue[&
I] = Plan->getOrAddLiveIn(&
I);
310 LoopBlocksRPO RPO(TheLoop);
313 for (BasicBlock *BB : RPO) {
315 VPBasicBlock *VPBB = getOrCreateVPBB(BB);
317 setVPBBPredsFromBB(VPBB, BB);
320 createVPInstructionsForVPBB(VPBB, BB);
327 getOrCreateVPBB(
SI->getDefaultDest())};
328 for (
auto Case :
SI->cases())
329 Succs.
push_back(getOrCreateVPBB(Case.getCaseSuccessor()));
339 assert(BI->isConditional() && NumSuccs == 2 && BI->isConditional() &&
340 "block must have conditional branch with 2 successors");
344 VPBasicBlock *Successor0 = getOrCreateVPBB(IRSucc0);
345 VPBasicBlock *Successor1 = getOrCreateVPBB(IRSucc1);
349 for (
auto *EB : Plan->getExitBlocks())
350 setVPBBPredsFromBB(EB, EB->getIRBasicBlock());
357 Plan->getEntry()->setOneSuccessor(getOrCreateVPBB(TheLoop->
getHeader()));
358 Plan->getEntry()->setPlan(&*Plan);
365 for (
auto *EB : Plan->getExitBlocks()) {
366 for (VPRecipeBase &R : EB->phis()) {
368 PHINode &
Phi = PhiR->getIRPhi();
369 assert(PhiR->getNumOperands() == 0 &&
370 "no phi operands should be added yet");
371 for (BasicBlock *Pred :
predecessors(EB->getIRBasicBlock()))
373 getOrCreateVPOperand(
Phi.getIncomingValueForBlock(Pred)));
378 return std::move(Plan);
391 if (Preds.
size() != 2)
394 auto *PreheaderVPBB = Preds[0];
395 auto *LatchVPBB = Preds[1];
396 if (!VPDT.
dominates(PreheaderVPBB, HeaderVPB) ||
400 if (!VPDT.
dominates(PreheaderVPBB, HeaderVPB) ||
417 if (LatchVPBB->getSingleSuccessor() ||
418 LatchVPBB->getSuccessors()[0] != HeaderVPB)
421 assert(LatchVPBB->getNumSuccessors() == 2 &&
"Must have 2 successors");
425 "terminator must be a BranchOnCond");
427 Not->insertBefore(Term);
428 Term->setOperand(0, Not);
429 LatchVPBB->swapSuccessors();
453 R->setEntry(HeaderVPB);
454 R->setExiting(LatchVPBB);
470 HeaderVPBB->
insert(CanonicalIVPHI, HeaderVPBB->
begin());
484 auto *CanonicalIVIncrement = Builder.createAdd(
485 CanonicalIVPHI, &Plan.
getVFxUF(),
DL,
"index.next", {true, false});
486 CanonicalIVPHI->addOperand(CanonicalIVIncrement);
504 VPValue *Exiting = ExitIRI->getIncomingValueForBlock(MiddleVPBB);
509 ExitIRI->setIncomingValueForBlock(MiddleVPBB, Exiting);
537 if (LatchVPBB->getNumSuccessors() == 2) {
542 LatchVPBB->swapSuccessors();
552 "Invalid backedge-taken count");
555 InductionTy, TheLoop);
579 "unexpected predecessor order of scalar ph");
580 for (
const auto &[PhiR, ScalarPhiR] :
583 VPValue *BackedgeVal = VectorPhiR->getOperand(1);
584 VPValue *ResumeFromVectorLoop =
591 {ResumeFromVectorLoop, VectorPhiR->getOperand(0)},
592 VectorPhiR->getDebugLoc());
601 auto GetSimplifiedLiveInViaSCEV = [&](
VPValue *VPV) ->
VPValue * {
609 if (
VPValue *SimplifiedLiveIn = GetSimplifiedLiveInViaSCEV(LiveIn))
610 LiveIn->replaceAllUsesWith(SimplifiedLiveIn);
617std::unique_ptr<VPlan>
621 PlainCFGBuilder Builder(TheLoop, &LI, LVer);
622 std::unique_ptr<VPlan> VPlan0 = Builder.buildPlainCFG();
639 "step must be loop invariant");
644 "Start VPValue must match IndDesc's start value");
658 VPUser *ExtractLastPartUser = ExtractLastPart->getSingleUser();
659 assert(ExtractLastPartUser &&
"must have a single user");
665 "last lane must be extracted in the middle block");
667 ExtractLastLane->replaceAllUsesWith(
669 ExtractLastLane->eraseFromParent();
670 ExtractLastPart->eraseFromParent();
676 Phi, Start, Step, &Plan.
getVFxUF(), IndDesc,
DL);
677 ReplaceExtractsWithExitingIVValue(WideIV);
683 "must have an integer or float induction at this point");
697 Phi, Start, Step, &Plan.
getVF(), IndDesc, Flags,
DL);
699 ReplaceExtractsWithExitingIVValue(WideIV);
714 "header must dominate its latch");
720 assert(PhiR->getNumOperands() == 2 &&
721 "Must have 2 operands for header phis");
725 VPValue *BackedgeValue = PhiR->getOperand(1);
727 if (FixedOrderRecurrences.
contains(Phi)) {
735 auto InductionIt = Inductions.
find(Phi);
736 if (InductionIt != Inductions.
end())
739 PhiR->getDebugLoc());
745 "incoming value must match start value");
747 unsigned ScaleFactor = 1;
748 bool UseOrderedReductions = !AllowReordering && RdxDesc.
isOrdered();
764 PhiR->replaceAllUsesWith(HeaderPhiR);
765 PhiR->eraseFromParent();
768 for (
const auto &[HeaderPhiR, ScalarPhiR] :
772 ResumePhiR->setName(
"scalar.recur.init");
774 ExtractLastLane->setName(
"vector.recur.extract");
792 if (!PhiR || !PhiR->isInLoop() || (MinVF.
isScalar() && !PhiR->isOrdered()))
795 RecurKind Kind = PhiR->getRecurrenceKind();
799 "AnyOf and Find reductions are not allowed for in-loop reductions");
801 bool IsFPRecurrence =
809 for (
unsigned I = 0;
I != Worklist.
size(); ++
I) {
813 if (!UserRecipe->getParent()->getEnclosingLoopRegion()) {
816 "U must be either in the loop region, the middle block or the "
817 "scalar preheader.");
824 Worklist.
insert(UserRecipe);
838 assert(Blend->getNumIncomingValues() == 2 &&
839 "Blend must have 2 incoming values");
840 unsigned PhiRIdx = Blend->getIncomingValue(0) == PhiR ? 0 : 1;
841 assert(Blend->getIncomingValue(PhiRIdx) == PhiR &&
842 "PhiR must be an operand of the blend");
843 Blend->replaceAllUsesWith(Blend->getIncomingValue(1 - PhiRIdx));
847 if (IsFPRecurrence) {
852 ->getFastMathFlags();
856 Instruction *CurrentLinkI = CurrentLink->getUnderlyingInstr();
864 "Expected current VPInstruction to be a call to the "
865 "llvm.fmuladd intrinsic");
866 assert(CurrentLink->getOperand(2) == PreviousLink &&
867 "expected a call where the previous link is the added operand");
875 {CurrentLink->getOperand(0), CurrentLink->getOperand(1)},
877 LinkVPBB->
insert(FMulRecipe, CurrentLink->getIterator());
883 VPBuilder Builder(LinkVPBB, CurrentLink->getIterator());
884 auto *
Sub = Builder.createSub(Zero, CurrentLink->getOperand(1),
886 Sub->setUnderlyingValue(CurrentLinkI);
890 unsigned IndexOfFirstOperand = 0;
896 "must be a select recipe");
897 IndexOfFirstOperand = 1;
902 CurrentLink->getOperand(IndexOfFirstOperand) == PreviousLink
903 ? IndexOfFirstOperand + 1
904 : IndexOfFirstOperand;
905 VecOp = CurrentLink->getOperand(VecOpId);
907 VecOp != PreviousLink &&
910 1 - (VecOpId - IndexOfFirstOperand)) == PreviousLink &&
911 "PreviousLink must be the operand other than VecOp");
919 assert(PhiR->getVFScaleFactor() == 1 &&
920 "inloop reductions must be unscaled");
922 Kind, FMFs, CurrentLinkI, PreviousLink, VecOp, CondOp,
930 RedRecipe->insertBefore(&*std::prev(std::prev(LinkVPBB->
end())));
934 CurrentLink->replaceAllUsesWith(RedRecipe);
936 PreviousLink = RedRecipe;
941 R->eraseFromParent();
945 bool HasUncountableEarlyExit) {
951 if (HasUncountableEarlyExit) {
961 if (Pred == MiddleVPBB)
968 EarlyExitingVPBB->getTerminator()->eraseFromParent();
975 bool RequiresScalarEpilogueCheck,
982 if (MiddleVPBB->getNumSuccessors() == 1) {
984 "must have ScalarPH as single successor");
988 assert(MiddleVPBB->getNumSuccessors() == 2 &&
"must have 2 successors");
1006 DebugLoc LatchDL = LatchVPBB->getTerminator()->getDebugLoc();
1009 if (!RequiresScalarEpilogueCheck)
1011 else if (TailFolded)
1026 TopRegion->
setName(
"vector loop");
1032 "only a single-exit block is supported currently");
1035 "the exit block must have middle block as single predecessor");
1039 "The vector loop region must have the middle block as its single "
1040 "successor for now");
1043 Header->
splitAt(Header->getFirstNonPhi());
1048 VPBuilder Builder(Header, Header->getFirstNonPhi());
1056 [[maybe_unused]]
bool TermBranchOnCount =
1060 assert(TermBranchOnCount &&
1063 std::next(IVInc->getDefiningRecipe()->getIterator()) ==
1065 "Unexpected canonical iv increment");
1069 OrigLatch->
splitAt(IVInc->getDefiningRecipe()->getIterator());
1070 Latch->
setName(
"vector.latch");
1084 NeedsPhi[V].push_back(&R);
1087 Builder.setInsertPoint(Latch, Latch->
begin());
1089 for (
const auto &[V,
Users] : NeedsPhi) {
1099 U->replaceUsesOfWith(V, Phi);
1116 R.getVPSingleValue()->replaceAllUsesWith(Ext);
1131 unsigned NumPreds = ScalarPH->getNumPredecessors();
1134 assert(Phi->getNumIncoming() == NumPreds - 1 &&
1135 "must have incoming values for all predecessors");
1136 Phi->addOperand(Phi->getOperand(NumPreds - 2));
1151 if (AddBranchWeights) {
1155 Term->setMetadata(LLVMContext::MD_prof, BranchWeights);
1161 bool AddBranchWeights) {
1170 ElementCount MinProfitableTripCount,
bool RequiresScalarEpilogue,
1185 auto GetMinTripCount = [&]() ->
const SCEV * {
1194 const SCEV *MinProfitableTripCountSCEV =
1196 return SE.
getUMaxExpr(MinProfitableTripCountSCEV, VFxUF);
1202 const SCEV *Step = GetMinTripCount();
1213 TripCountCheck = Plan.
getTrue();
1218 VPValue *MinTripCountVPV = Builder.createExpandSCEV(Step);
1219 TripCountCheck = Builder.createICmp(
1220 CmpPred, TripCountVPV, MinTripCountVPV,
DL,
"min.iters.check");
1229 Term->setMetadata(LLVMContext::MD_prof, BranchWeights);
1235 bool RequiresScalarEpilogue,
ElementCount EpilogueVF,
unsigned EpilogueUF,
1236 unsigned MainLoopStep,
unsigned EpilogueLoopStep,
ScalarEvolution &SE) {
1248 auto *CheckMinIters = Builder.createICmp(
1259 unsigned EstimatedSkipCount = std::min(MainLoopStep, EpilogueLoopStep);
1260 const uint32_t Weights[] = {EstimatedSkipCount,
1261 MainLoopStep - EstimatedSkipCount};
1265 Branch->setMetadata(LLVMContext::MD_prof, BranchWeights);
1282 auto GetMinOrMaxCompareValue =
1296 if (MinOrMaxR->getOperand(0) == RedPhiR)
1297 return MinOrMaxR->getOperand(1);
1299 assert(MinOrMaxR->getOperand(1) == RedPhiR &&
1300 "Reduction phi operand expected");
1301 return MinOrMaxR->getOperand(0);
1306 MinOrMaxNumReductionsToHandle;
1307 bool HasUnsupportedPhi =
false;
1314 HasUnsupportedPhi =
true;
1318 Cur->getRecurrenceKind())) {
1319 HasUnsupportedPhi =
true;
1323 VPValue *MinOrMaxOp = GetMinOrMaxCompareValue(Cur);
1327 MinOrMaxNumReductionsToHandle.
emplace_back(Cur, MinOrMaxOp);
1330 if (MinOrMaxNumReductionsToHandle.
empty())
1348 for (
auto &R : *VPBB) {
1356 VPValue *AllNaNLanes =
nullptr;
1358 for (
const auto &[
_, MinOrMaxOp] : MinOrMaxNumReductionsToHandle) {
1361 AllNaNLanes = AllNaNLanes ? LatchBuilder.
createOr(AllNaNLanes, RedNaNLanes)
1369 for (
const auto &[RedPhiR,
_] : MinOrMaxNumReductionsToHandle) {
1371 RedPhiR->getRecurrenceKind()) &&
1372 "unsupported reduction");
1377 assert(RdxResult &&
"must find a ComputeReductionResult");
1379 auto *NewSel = MiddleBuilder.
createSelect(AnyNaNLane, RedPhiR,
1380 RdxResult->getOperand(0));
1382 assert(!RdxResults.
contains(RdxResult) &&
"RdxResult already used");
1383 RdxResults.
insert(RdxResult);
1388 "Unexpected terminator");
1389 auto *IsLatchExitTaken = LatchBuilder.
createICmp(
1391 LatchExitingBranch->getOperand(1));
1392 auto *AnyExitTaken = LatchBuilder.
createOr(AnyNaNLane, IsLatchExitTaken);
1399 auto IsTC = [&Plan](
VPValue *V) {
1404 VPValue *VecV = ResumeR->getOperand(0);
1408 VPValue *DIVTC = DerivedIV->getOperand(1);
1409 if (DerivedIV->getNumUsers() == 1 && IsTC(DIVTC)) {
1413 DerivedIV->setOperand(1, NewSel);
1420 LLVM_DEBUG(
dbgs() <<
"Found resume phi we cannot update for VPlan with "
1421 "FMaxNum/FMinNum reduction.\n");
1431 VPValue *MiddleCond = MiddleTerm->getOperand(0);
1468 PhiR->getRecurrenceKind()))
1472 VPValue *BackedgeSelect = PhiR->getBackedgeValue();
1473 VPValue *CondSelect = BackedgeSelect;
1477 if (HeaderMask && !
match(BackedgeSelect,
1482 VPValue *
Cond =
nullptr, *Op1 =
nullptr, *Op2 =
nullptr;
1491 assert(!Blend->isNormalized() &&
"must run before blend normalizaion");
1492 unsigned NumIncomingDataValues = 0;
1493 for (
unsigned I = 0;
I < Blend->getNumIncomingValues(); ++
I) {
1496 ++NumIncomingDataValues;
1497 Cond = Blend->getMask(
I);
1502 return NumIncomingDataValues == 1;
1509 !MatchBlend(SelectR))
1512 assert(
Cond != HeaderMask &&
"Cond must not be HeaderMask");
1519 assert(RdxResult &&
"Could not find reduction result");
1524 Builder.insert(MaskPHI);
1527 Builder.setInsertPoint(SelectR);
1535 assert(Op2 == PhiR &&
"data value must be selected if Cond is true");
1538 Cond = Builder.createLogicalAnd(HeaderMask,
Cond);
1542 MaskPHI->addOperand(MaskSelect);
1548 PhiR->setBackedgeValue(DataSelect);
1551 Builder.setInsertPoint(RdxResult);
1552 auto *ExtractLastActive =
1554 {PhiR->getStartValue(), DataSelect, MaskSelect},
1555 RdxResult->getDebugLoc());
1556 RdxResult->replaceAllUsesWith(ExtractLastActive);
1557 RdxResult->eraseFromParent();
1582 "inloop and ordered reductions not supported");
1584 "FindIV reduction must not be scaled");
1596 "backedge value must be a select");
1597 if (FindIVSelectR->getOperand(1) != WideIV &&
1612 WidenCanIV->insertBefore(WideIV);
1615 FindIVSelectR->setOperand(FindIVSelectR->getOperand(1) == WideIV ? 1 : 2,
1672 auto *FinalMinOrMaxCmp =
1677 auto *FinalIVSelect =
1678 Builder.createSelect(FinalMinOrMaxCmp, LastIVExiting, MaxIV);
1687 auto *DerivedIVRecipe =
1692 DerivedIVRecipe->insertBefore(&*Builder.getInsertPoint());
1693 FinalCanIV = DerivedIVRecipe;
1701 VPValue *FinalIV = Builder.createSelect(
1702 AlwaysFalse, FindIVSelect->
getOperand(2), FinalCanIV);
1719 if (!MinOrMaxPhiR || !MinOrMaxPhiR->hasUsesOutsideReductionChain())
1730 RecurKind RdxKind = MinOrMaxPhiR->getRecurrenceKind();
1733 "only min/max recurrences support users outside the reduction chain");
1748 assert(MinOrMaxOp->getNumUsers() == 2 &&
1749 "MinOrMaxOp must have exactly 2 users");
1750 VPValue *MinOrMaxOpValue = MinOrMaxOp->getOperand(0);
1751 if (MinOrMaxOpValue == MinOrMaxPhiR)
1752 MinOrMaxOpValue = MinOrMaxOp->getOperand(1);
1759 if (!Cmp || Cmp->getNumUsers() != 1 ||
1760 (CmpOpA != MinOrMaxOpValue && CmpOpB != MinOrMaxOpValue))
1763 if (MinOrMaxOpValue != CmpOpB)
1769 if (MinOrMaxPhiR->getNumUsers() != 2)
1775 "one user must be MinOrMaxOp");
1776 assert(MinOrMaxResult &&
"MinOrMaxResult must be a user of MinOrMaxOp");
1793 FindIVPhiR->getRecurrenceKind()))
1796 assert(!FindIVPhiR->isInLoop() && !FindIVPhiR->isOrdered() &&
1797 "cannot handle inloop/ordered reductions yet");
1803 FindIVPhiR->getBackedgeValue());
1805 "must be able to retrieve the FindIVResult VPInstruction");
1817 bool IsValidKindPred = [RdxKind, Pred]() {
1831 if (!IsValidKindPred) {
1834 DEBUG_TYPE,
"VectorizationMultiUseReductionPredicate",
1836 <<
"Multi-use reduction with predicate "
1838 <<
" incompatible with reduction kind";
1844 auto *FindIVCmp = FindIVSelect->getOperand(0)->getDefiningRecipe();
1847 "both results must be computed in the same block");
1851 MinOrMaxResult->
moveBefore(*FindIVRdxResult->getParent(),
1852 FindIVRdxResult->getIterator());
1855 if (IsStrictPredicate) {
1858 MinOrMaxResult, FindIVSelect, FindIVCmp,
1889 auto *FinalMinOrMaxCmp =
1892 VPValue *LastIVExiting = FindIVRdxResult->getOperand(0);
1893 auto *FinalIVSelect =
1894 B.createSelect(FinalMinOrMaxCmp, LastIVExiting,
Sentinel);
1895 FindIVRdxResult->setOperand(0, FinalIVSelect);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
iv Induction Variable Users
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file provides a LoopVectorizationPlanner class.
static constexpr uint32_t MinItersBypassWeights[]
const SmallVectorImpl< MachineOperand > & Cond
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
static void createLoopRegion(VPlan &Plan, VPBlockBase *HeaderVPB)
Create a new VPRegionBlock for the loop starting at HeaderVPB.
static bool isHeaderBB(BasicBlock *BB, Loop *L)
static bool handleFirstArgMinOrMax(VPlan &Plan, VPReductionPHIRecipe *MinOrMaxPhiR, VPReductionPHIRecipe *FindLastIVPhiR, VPWidenIntOrFpInductionRecipe *WideIV, VPInstruction *MinOrMaxResult, VPInstruction *FindIVSelect, VPRecipeBase *FindIVCmp, VPInstruction *FindIVRdxResult)
Given a first argmin/argmax pattern with strict predicate consisting of 1) a MinOrMax reduction MinOr...
static VPHeaderPHIRecipe * createWidenInductionRecipe(PHINode *Phi, VPPhi *PhiR, VPIRValue *Start, const InductionDescriptor &IndDesc, VPlan &Plan, PredicatedScalarEvolution &PSE, Loop &OrigLoop, DebugLoc DL)
Creates a VPWidenIntOrFpInductionRecipe or VPWidenPointerInductionRecipe for Phi based on IndDesc.
static void insertCheckBlockBeforeVectorLoop(VPlan &Plan, VPBasicBlock *CheckBlockVPBB)
Insert CheckBlockVPBB on the edge leading to the vector preheader, connecting it to both vector and s...
static void simplifyLiveInsWithSCEV(VPlan &Plan, PredicatedScalarEvolution &PSE)
Check Plan's live-in and replace them with constants, if they can be simplified via SCEV.
static void addInitialSkeleton(VPlan &Plan, Type *InductionTy, DebugLoc IVDL, PredicatedScalarEvolution &PSE, Loop *TheLoop)
static void addBypassBranch(VPlan &Plan, VPBasicBlock *CheckBlockVPBB, VPValue *Cond, bool AddBranchWeights)
Create a BranchOnCond terminator in CheckBlockVPBB.
static void addCanonicalIVRecipes(VPlan &Plan, VPBasicBlock *HeaderVPBB, VPBasicBlock *LatchVPBB, Type *IdxTy, DebugLoc DL)
static bool canonicalHeaderAndLatch(VPBlockBase *HeaderVPB, const VPDominatorTree &VPDT)
Checks if HeaderVPB is a loop header block in the plain CFG; that is, it has exactly 2 predecessors (...
static VPInstruction * findFindIVSelect(VPValue *BackedgeVal)
Find and return the final select instruction of the FindIV result pattern for the given BackedgeVal: ...
static constexpr uint32_t CheckBypassWeights[]
static void printAfterInitialConstruction(VPlan &)
To make RUN_VPLAN_PASS print initial VPlan.
static auto getMatchingPhisForScalarLoop(VPBasicBlock *Header, VPBasicBlock *ScalarHeader)
Return an iterator range to iterate over pairs of matching phi nodes in Header and ScalarHeader,...
static void createExtractsForLiveOuts(VPlan &Plan, VPBasicBlock *MiddleVPBB)
Creates extracts for values in Plan defined in a loop region and used outside a loop region.
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 std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
This file contains the declarations of the Vectorization Plan base classes:
static const uint32_t IV[8]
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
LLVM Basic Block Representation.
LLVM_ABI iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const
Return a const iterator range over the instructions in the block, skipping any debug instructions.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
static LLVM_ABI StringRef getPredicateName(Predicate P)
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static DebugLoc getUnknown()
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...
Implements a dense probed hash-table based set.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
constexpr bool isScalar() const
Exactly one element.
Convenience struct for specifying and reasoning about fast-math flags.
static FastMathFlags getFast()
static bool isLT(Predicate P)
Return true if the predicate is SLT or ULT.
static bool isGT(Predicate P)
Return true if the predicate is SGT or UGT.
A struct for saving information about induction variables.
InductionKind getKind() const
const SCEV * getStep() const
@ IK_FpInduction
Floating point induction variable.
@ IK_PtrInduction
Pointer induction var. Step = C.
@ IK_IntInduction
Integer induction variable. Step = C.
Value * getStartValue() const
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
BlockT * getHeader() const
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
std::pair< MDNode *, MDNode * > getNoAliasMetadataFor(const Instruction *OrigInst) const
Returns a pair containing the alias_scope and noalias metadata nodes for OrigInst,...
Represents a single loop in the control flow graph.
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
This class implements a map that also provides access to all stored values in a deterministic order.
iterator find(const KeyT &Key)
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEV * getSymbolicMaxBackedgeTakenCount()
Get the (predicated) symbolic max backedge count for the analyzed loop.
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
static bool isFMulAddIntrinsic(Instruction *I)
Returns true if the instruction is a call to the llvm.fmuladd intrinsic.
FastMathFlags getFastMathFlags() const
static bool isFPMinMaxNumRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating-point minnum/maxnum kind.
bool hasUsesOutsideReductionChain() const
Returns true if the reduction PHI has any uses outside the reduction chain.
static bool isFindLastRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
TrackingVH< Value > getRecurrenceStartValue() const
static bool isAnyOfRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
RecurKind getRecurrenceKind() const
bool isOrdered() const
Expose an ordered FP reduction to the instance users.
static LLVM_ABI bool isFloatingPointRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating point kind.
static bool isFindIVRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
static bool isIntMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is an integer min/max kind.
static bool isMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is any min/max kind.
This class represents an analyzed expression in the program.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getUMaxExpr(const SCEV *LHS, const SCEV *RHS)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getTripCountFromExitCount(const SCEV *ExitCount)
A version of getTripCountFromExitCount below which always picks an evaluation type which can not resu...
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getElementCount(Type *Ty, ElementCount EC, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
LLVM_ABI const SCEV * applyLoopGuards(const SCEV *Expr, const Loop *L)
Try to apply information from loop guards for L to Expr.
LLVM_ABI bool isKnownPredicate(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
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.
iterator begin()
Recipe iterator methods.
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
VPBasicBlock * splitAt(iterator SplitAt)
Split current block at SplitAt by inserting a new block between the current block and its successors ...
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
const VPRecipeBase & back() const
void insert(VPRecipeBase *Recipe, iterator InsertPt)
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
void swapSuccessors()
Swap successors of the block. The block must have exactly 2 successors.
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
const VPBlocksTy & getPredecessors() const
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
VPBlockBase * getSinglePredecessor() const
void swapPredecessors()
Swap predecessors of the block.
const VPBasicBlock * getEntryBasicBlock() const
void setOneSuccessor(VPBlockBase *Successor)
Set a given VPBlockBase Successor as the single successor of this VPBlockBase.
void setParent(VPRegionBlock *P)
VPBlockBase * getSingleSuccessor() const
const VPBlocksTy & getSuccessors() const
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBase NewBlock after BlockPtr.
static void insertOnEdge(VPBlockBase *From, VPBlockBase *To, VPBlockBase *BlockPtr)
Inserts BlockPtr on the edge between From and To.
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 void transferSuccessors(VPBlockBase *Old, VPBlockBase *New)
Transfer successors from Old to New. New must have no successors.
VPlan-based builder utility analogous to IRBuilder.
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPBasicBlock::iterator getInsertPoint() const
VPInstruction * createScalarCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, DebugLoc DL, const VPIRMetadata &Metadata={})
VPInstruction * createFCmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new FCmp VPInstruction with predicate Pred and operands A and B.
VPInstructionWithType * createScalarLoad(Type *ResultTy, VPValue *Addr, DebugLoc DL, const VPIRMetadata &Metadata={})
static VPBuilder getToInsertAfter(VPRecipeBase *R)
Create a VPBuilder to insert after R.
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", const VPIRFlags &Flags={})
VPInstruction * createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new ICmp VPInstruction with predicate Pred and operands A and B.
VPInstruction * createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", const VPIRFlags &Flags={})
void setInsertPoint(VPBasicBlock *TheBB)
This specifies that created VPInstructions should be appended to the end of the specified block.
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.
Canonical scalar induction phi of the vector loop.
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
A special type of VPBasicBlock that wraps an existing IR basic block.
Class to record and manage LLVM IR flags.
RecurKind getRecurKind() const
This is a concrete Recipe that models a single VPlan-level instruction.
@ ExtractLastActive
Extracts the last active lane from a set of vectors.
@ ExtractLane
Extracts a single lane (first operand) from a set of vector operands.
@ ExitingIVValue
Compute the exiting value of a wide induction after vectorization, that is the value of the last lane...
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
VPBasicBlock * getParent()
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
void moveBefore(VPBasicBlock &BB, iplist< VPRecipeBase >::iterator I)
Unlink this recipe and insert into BB before I.
void insertBefore(VPRecipeBase *InsertPos)
Insert an unlinked recipe into a basic block immediately before the specified recipe.
iplist< VPRecipeBase >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void moveAfter(VPRecipeBase *MovePos)
Unlink this recipe from its current VPBasicBlock and insert it into the VPBasicBlock that MovePos liv...
A recipe for handling reduction phis.
bool isOrdered() const
Returns true, if the phi is part of an ordered reduction.
unsigned getVFScaleFactor() const
Get the factor that the VF of this recipe's output should be scaled by, or 1 if it isn't scaled.
bool isInLoop() const
Returns true if the phi is part of an in-loop reduction.
A recipe to represent inloop, ordered or partial reduction operations.
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Type * getCanonicalIVType()
Return the type of the canonical IV for loop regions.
VPCanonicalIVPHIRecipe * getCanonicalIV()
Returns the canonical induction recipe of the region.
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
An analysis for type-inference for VPValues.
Type * inferScalarType(const VPValue *V)
Infer the type of V. Returns the scalar type of V.
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
void setOperand(unsigned I, VPValue *New)
VPValue * getOperand(unsigned N) const
void addOperand(VPValue *Operand)
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
void setUnderlyingValue(Value *Val)
void replaceAllUsesWith(VPValue *New)
unsigned getNumUsers() const
A Recipe for widening the canonical induction variable of the vector loop.
VPValue * getStepValue()
Returns the step value of the induction.
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
VPIRValue * getStartValue() const
Returns the start value of the induction.
bool isCanonical() const
Returns true if the induction is canonical, i.e.
A recipe for widened phis.
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
VPIRValue * getLiveIn(Value *V) const
Return the live-in VPIRValue for V, if there is one or nullptr otherwise.
LLVMContext & getContext() const
VPBasicBlock * getEntry()
VPValue & getVFxUF()
Returns VF * UF of the vector loop region.
VPValue & getVF()
Returns the VF of the vector loop region.
VPValue * getTripCount() const
The trip count of the original loop.
VPValue * getOrCreateBackedgeTakenCount()
The backedge taken count of the original loop.
VPIRValue * getFalse()
Return a VPIRValue wrapping i1 false.
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.
VPSymbolicValue & getVectorTripCount()
The vector trip count.
VPIRValue * getOrAddLiveIn(Value *V)
Gets the live-in VPIRValue for V or adds a new live-in (if none exists yet) for V.
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
void setTripCount(VPValue *NewTripCount)
Set the trip count assuming it is currently null; if it is not - use resetTripCount().
VPBasicBlock * getMiddleBlock()
Returns the 'middle' block of the plan, that is the block that selects whether to execute the scalar ...
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,...
VPIRValue * getTrue()
Return a VPIRValue wrapping i1 true.
VPRegionBlock * createLoopRegion(const std::string &Name="", VPBlockBase *Entry=nullptr, VPBlockBase *Exiting=nullptr)
Create a new loop region with Name and entry and exiting blocks set to Entry and Exiting respectively...
bool hasScalarVFOnly() const
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
VPBasicBlock * getVectorPreheader()
Returns the preheader of the vector loop region, if one exists, or null otherwise.
bool hasScalarTail() const
Returns true if the scalar tail may execute after the vector loop.
VPIRValue * getConstantInt(Type *Ty, uint64_t Val, bool IsSigned=false)
Return a VPIRValue wrapping a ConstantInt with the given type and value.
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.
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
VPInstruction_match< VPInstruction::ExtractLastLane, VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > > m_ExtractLastLaneOfLastPart(const Op0_t &Op0)
bool matchFindIVResult(VPInstruction *VPI, Op0_t ReducedIV, Op1_t Start)
Match FindIV result pattern: select(icmp ne ComputeReductionResult(ReducedIV), Sentinel),...
VPInstruction_match< VPInstruction::ExtractLastLane, Op0_t > m_ExtractLastLane(const Op0_t &Op0)
VPInstruction_match< VPInstruction::BranchOnCount > m_BranchOnCount()
VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > m_ExtractLastPart(const Op0_t &Op0)
class_match< VPValue > m_VPValue()
Match an arbitrary VPValue and ignore it.
bind_ty< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
NodeAddr< PhiNode * > Phi
friend class Instruction
Iterator for Instructions in a `BasicBlock.
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr)
Get or create a VPValue that corresponds to the expansion of Expr.
VPInstruction * findComputeReductionResult(VPReductionPHIRecipe *PhiR)
Find the ComputeReductionResult recipe for PhiR, looking through selects inserted for predicated redu...
VPIRFlags getFlagsFromIndDesc(const InductionDescriptor &ID)
Extracts and returns NoWrap and FastMath flags from the induction binop in ID.
VPRecipeBase * findRecipe(VPValue *Start, PredT Pred)
Search Start's users for a recipe satisfying Pred, looking through recipes with definitions.
VPSingleDefRecipe * findHeaderMask(VPlan &Plan)
Collect the header mask with the pattern: (ICMP_ULE, WideCanonicalIV, backedge-taken-count) TODO: Int...
static VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
const SCEV * getSCEVExprForVPValue(const VPValue *V, PredicatedScalarEvolution &PSE, const Loop *L=nullptr)
Return the SCEV expression for V.
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.
FunctionAddr VTableAddr Value
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicOp(Intrinsic::ID RdxID)
Returns the min/max intrinsic used when expanding a min/max reduction.
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.
ReductionStyle getReductionStyle(bool InLoop, bool Ordered, unsigned ScaleFactor)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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...
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)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
auto succ_size(const MachineBasicBlock *BB)
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...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
iterator_range< po_iterator< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_post_order_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in post order.
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...
RecurKind
These are the kinds of recurrences that we support.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ FindIV
FindIV reduction with select(icmp(),x,y) where one of (x,y) is a loop induction variable (increasing ...
@ AnyOf
AnyOf reduction with select(cmp(),x,y) where one of (x,y) is loop invariant, and both x and y are int...
@ FMulAdd
Sum of float products with llvm.fmuladd(a * b + sum).
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ Sub
Subtraction of integers.
@ AddChainWithSubs
A chain of adds and subs.
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
A recipe for handling first-order recurrence phis.
A VPValue representing a live-in from the input IR or a constant.