40#define DEBUG_TYPE "vplan"
48class PlainCFGBuilder {
65 std::unique_ptr<VPlan> Plan;
86 bool isExternalDef(
Value *Val);
95 : TheLoop(Lp), LI(LI), LVer(LVer), GetBPI(GetBPI),
96 Plan(std::make_unique<VPlan>(Lp, IdxTy)) {}
99 std::unique_ptr<VPlan> buildPlainCFG();
114 return L && BB == L->getHeader();
118void PlainCFGBuilder::fixHeaderPhis() {
119 for (
auto *Phi : PhisToFix) {
120 assert(IRDef2VPValue.count(Phi) &&
"Missing VPInstruction for PHINode.");
121 VPValue *VPVal = IRDef2VPValue[
Phi];
124 assert(PhiR->getNumOperands() == 0 &&
"Expected VPPhi with no operands.");
126 "Expected Phi in header block.");
128 "header phi must have exactly 2 operands");
131 getOrCreateVPOperand(
Phi->getIncomingValueForBlock(
Pred)));
137VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {
138 if (
auto *VPBB = BB2VPBB.lookup(BB)) {
145 LLVM_DEBUG(
dbgs() <<
"Creating VPBasicBlock for " << Name <<
"\n");
146 VPBasicBlock *VPBB = Plan->createVPBasicBlock(Name);
157bool PlainCFGBuilder::isExternalDef(
Value *Val) {
173VPValue *PlainCFGBuilder::getOrCreateVPOperand(
Value *IRVal) {
174 auto VPValIt = IRDef2VPValue.find(IRVal);
175 if (VPValIt != IRDef2VPValue.end())
178 return VPValIt->second;
187 assert(isExternalDef(IRVal) &&
"Expected external definition as operand.");
191 VPValue *NewVPVal = Plan->getOrAddLiveIn(IRVal);
192 IRDef2VPValue[IRVal] = NewVPVal;
197VPIRMetadata PlainCFGBuilder::getTerminatorMetadata(Instruction &Term) {
198 VPIRMetadata MD(Term);
199 if (MD.getMetadata(LLVMContext::MD_prof))
209 return BPI->getEdgeProbability(Term.getParent(), I).getNumerator();
211 MD.setEstimatedBranchWeights(
212 MDBuilder(Plan->getContext()).createBranchWeights(Weights));
219void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
223 for (Instruction &InstRef : *BB) {
228 assert(!IRDef2VPValue.count(Inst) &&
229 "Instruction shouldn't have been visited.");
238 VPValue *
Cond = getOrCreateVPOperand(Br->getCondition());
240 getTerminatorMetadata(*Inst),
247 if (
SI->getNumCases() == 0)
250 for (
auto Case :
SI->cases())
251 Ops.push_back(getOrCreateVPOperand(Case.getCaseValue()));
253 getTerminatorMetadata(*Inst),
258 VPSingleDefRecipe *NewR;
264 *Phi,
Phi->getType());
269 PhisToFix.push_back(Phi);
273 DenseMap<const VPBasicBlock *, VPValue *> VPPredToIncomingValue;
274 for (
unsigned I = 0;
I !=
Phi->getNumOperands(); ++
I) {
275 VPPredToIncomingValue[BB2VPBB[
Phi->getIncomingBlock(
I)]] =
276 getOrCreateVPOperand(
Phi->getIncomingValue(
I));
280 VPPredToIncomingValue.
lookup(
Pred->getExitingBasicBlock()));
285 VPIRMetadata MD(*Inst);
287 const auto &[AliasScopeMD, NoAliasMD] =
290 MD.setMetadata(LLVMContext::MD_alias_scope, AliasScopeMD);
292 MD.setMetadata(LLVMContext::MD_noalias, NoAliasMD);
296 "legality must reject aggregate-producing insertvalue");
303 for (
unsigned Idx : EVI->indices())
304 VPOperands.
push_back(Plan->getConstantInt(32, Idx));
305 VPIRAttributes
Attrs;
307 Attrs = VPIRAttributes(CI->getAttributes());
313 IRDef2VPValue[Inst] = NewR;
318std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG() {
321 for (VPIRBasicBlock *ExitVPBB : Plan->getExitBlocks())
322 BB2VPBB[ExitVPBB->getIRBasicBlock()] = ExitVPBB;
335 "Unexpected loop preheader");
336 for (
auto &
I : *ThePreheaderBB) {
337 if (
I.getType()->isVoidTy())
339 IRDef2VPValue[&
I] = Plan->getOrAddLiveIn(&
I);
342 LoopBlocksRPO RPO(TheLoop);
345 for (BasicBlock *BB : RPO) {
347 VPBasicBlock *VPBB = getOrCreateVPBB(BB);
349 setVPBBPredsFromBB(VPBB, BB);
352 createVPInstructionsForVPBB(VPBB, BB);
359 getOrCreateVPBB(
SI->getDefaultDest())};
360 for (
auto Case :
SI->cases())
361 Succs.
push_back(getOrCreateVPBB(Case.getCaseSuccessor()));
372 VPBasicBlock *Successor0 = getOrCreateVPBB(IRSucc0);
373 VPBasicBlock *Successor1 = getOrCreateVPBB(IRSucc1);
377 for (
auto *EB : Plan->getExitBlocks())
378 setVPBBPredsFromBB(EB, EB->getIRBasicBlock());
385 Plan->getEntry()->setOneSuccessor(getOrCreateVPBB(TheLoop->
getHeader()));
386 Plan->getEntry()->setPlan(&*Plan);
393 for (
auto *EB : Plan->getExitBlocks()) {
394 for (VPRecipeBase &R : EB->phis()) {
396 PHINode &
Phi = PhiR->getIRPhi();
397 assert(PhiR->getNumOperands() == 0 &&
398 "no phi operands should be added yet");
401 getOrCreateVPOperand(
Phi.getIncomingValueForBlock(
Pred)));
406 return std::move(Plan);
419 if (Preds.
size() != 2)
422 auto *PreheaderVPBB = Preds[0];
423 auto *LatchVPBB = Preds[1];
424 if (!VPDT.
dominates(PreheaderVPBB, HeaderVPB) ||
428 if (!VPDT.
dominates(PreheaderVPBB, HeaderVPB) ||
445 if (LatchVPBB->getSingleSuccessor() ||
446 LatchVPBB->getSuccessors()[0] != HeaderVPB)
449 assert(LatchVPBB->getNumSuccessors() == 2 &&
"Must have 2 successors");
453 "terminator must be a BranchOnCond");
455 Not->insertBefore(Term);
456 Term->setOperand(0, Not);
457 LatchVPBB->swapSuccessors();
468 auto *OutermostHeaderVPBB =
480 bool IsOutermost = HeaderVPB == OutermostHeaderVPBB;
481 Type *CanIVTy =
nullptr;
492 R->setEntry(HeaderVPB);
493 R->setExiting(LatchVPBB);
502 auto *LatchTerm = LatchVPBB->getTerminator();
507 auto *CanonicalIVIncrement = Builder.createAdd(
508 R->getCanonicalIV(), &Plan.
getVFxUF(),
DL,
"index.next", {true, false});
511 auto *IsLatchExitTaken = Builder.createICmp(
513 LatchTerm->setOperand(1, IsLatchExitTaken);
518 DebugLoc LatchDL = LatchTerm->getDebugLoc();
522 LatchTerm->eraseFromParent();
536 VPValue *Exiting = ExitIRI->getIncomingValueForBlock(MiddleVPBB);
541 ExitIRI->setIncomingValueForBlock(MiddleVPBB, Exiting);
571 if (LatchVPBB->getNumSuccessors() == 2) {
576 LatchVPBB->swapSuccessors();
586 "Invalid backedge-taken count");
589 InductionTy, TheLoop);
613 "unexpected predecessor order of scalar ph");
614 for (
const auto &[PhiR, ScalarPhiR] :
617 VPValue *BackedgeVal = VectorPhiR->getOperand(1);
618 VPValue *ResumeFromVectorLoop =
625 {ResumeFromVectorLoop, VectorPhiR->getOperand(0)},
626 VectorPhiR->getDebugLoc());
638 PlainCFGBuilder Builder(TheLoop, &LI, LVer, InductionTy, GetBPI);
639 std::unique_ptr<VPlan> VPlan0 = Builder.buildPlainCFG();
653 std::optional<VPExecutionFrequency> Freq = Frequencies.lookup(VPBB);
655 VPI.setExecutionFrequency(Freq, Ctx);
668 "step must be loop invariant");
673 "Start VPValue must match IndDesc's start value");
688 bool IsPredicated = !WideIV->getNoWrapPredicates().empty();
693 VPUser *ExtractLastPartUser = ExtractLastPart->getSingleUser();
694 assert(ExtractLastPartUser &&
"must have a single user");
700 "last lane must be extracted in the middle block");
704 any_of(ExtractLastLane->users(), [&](
VPUser *LaneUser) {
705 auto *R = cast<VPRecipeBase>(LaneUser);
706 return Plan.isExitBlock(R->getParent());
710 ExtractLastLane->replaceAllUsesWith(
712 ExtractLastLane->eraseFromParent();
713 ExtractLastPart->eraseFromParent();
719 Phi, Start, Step, &Plan.
getVFxUF(), IndDesc,
DL);
720 ReplaceExtractsWithExitingIVValueIfPossible(WideIV);
726 "must have an integer or float induction at this point");
740 Phi, Start, Step, &Plan.
getVF(), IndDesc, Flags,
DL);
742 ReplaceExtractsWithExitingIVValueIfPossible(WideIV);
756 auto TryToPushSinkCandidate = [&](
VPRecipeBase *SinkCandidate) {
759 if (SinkCandidate == Previous)
763 !Seen.
insert(SinkCandidate).second ||
776 for (
unsigned I = 0;
I != WorkList.
size(); ++
I) {
779 "only recipes with a single defined value expected");
794 if (SinkCandidate == FOR)
797 SinkCandidate->moveAfter(Previous);
798 Previous = SinkCandidate;
825 if (!HoistPoint || HoistPoint->
isPhi() ||
827 auto *R = cast<VPRecipeBase>(U);
828 return HoistPoint != R && !VPDT.properlyDominates(HoistPoint, R);
832 auto NeedsHoisting = [HoistPoint, &VPDT,
834 VPRecipeBase *HoistCandidate = HoistCandidateV->getDefiningRecipe();
838 if (!Visited.
insert(HoistCandidate).second)
844 return HoistCandidate;
854 for (
unsigned I = 0;
I != HoistCandidates.
size(); ++
I) {
857 "only recipes with a single defined value expected");
869 if (
auto *R = NeedsHoisting(
Op)) {
872 if (R->getNumDefinedValues() != 1)
893 HoistCandidate->moveBefore(HoistPoint->
getIterator());
909 return cast<VPFirstOrderRecurrencePHIRecipe>(&R);
916 VPRecipeBase *Previous = FOR->getBackedgeValue()->getDefiningRecipe();
917 while (
auto *PrevPhi =
919 assert(PrevPhi->getParent() == FOR->getParent() &&
920 "PrevPhi must be in same block as FOR");
922 "PrevPhi must not be visited multiple times");
923 Previous = PrevPhi->getBackedgeValue()->getDefiningRecipe();
933 ? Previous->
getParent()->getFirstNonPhi()
941 {FOR, FOR->getBackedgeValue()});
954 &ConditionalInductions,
960 "header must dominate its latch");
966 assert(PhiR->getNumOperands() == 2 &&
967 "Must have 2 operands for header phis");
971 VPValue *BackedgeValue = PhiR->getOperand(1);
973 if (FixedOrderRecurrences.
contains(Phi)) {
981 auto InductionIt = Inductions.
find(Phi);
982 if (InductionIt != Inductions.
end())
985 PhiR->getDebugLoc());
987 auto ConditionalInductionIt = ConditionalInductions.
find(Phi);
988 if (ConditionalInductionIt != ConditionalInductions.
end()) {
990 ConditionalInductionIt->second;
999 "incoming value must match start value");
1001 unsigned ScaleFactor = 1;
1002 bool UseOrderedReductions = !AllowReordering && RdxDesc.
isOrdered();
1016 PhiR->replaceAllUsesWith(HeaderPhiR);
1017 PhiR->eraseFromParent();
1022 "Failed to sink or hoist user of first-order recurrence",
1023 "CannotSinkHoistFORUser", ORE, &OrigLoop);
1031 for (
const auto &[HeaderPhiR, ScalarPhiR] :
1035 ResumePhiR->setName(
"scalar.recur.init");
1037 ExtractLastLane->setName(
"vector.recur.extract");
1050 unsigned SCEVCheckThreshold,
1058 if (WideIV.getNoWrapPredicates().empty())
1060 PredicatedIVs.
insert(&WideIV);
1061 for (
const auto *
P : WideIV.getNoWrapPredicates())
1066 if (TotalComplexity && OptForSize) {
1068 dbgs() <<
"LV: Not vectorizing: SCEV predicates needed for induction "
1069 "but optimizing for size\n");
1071 "Runtime SCEV check is required with -Os/-Oz",
1072 "runtime SCEV checks needed but optimizing for size",
1073 "CantVersionLoopWithOptForSize", ORE, TheLoop);
1077 if (TotalComplexity > SCEVCheckThreshold) {
1078 LLVM_DEBUG(
dbgs() <<
"LV: Not vectorizing: Too many SCEV checks needed ("
1079 << TotalComplexity <<
" > " << SCEVCheckThreshold
1082 "Too many SCEV checks needed",
1083 "Too many SCEV assumptions need to be made and checked at runtime",
1084 "TooManySCEVRunTimeChecks", ORE, TheLoop);
1098 if (!PhiR || !PhiR->isInLoop() || (MinVF.
isScalar() && !PhiR->isOrdered()))
1101 RecurKind Kind = PhiR->getRecurrenceKind();
1105 "AnyOf and Find reductions are not allowed for in-loop reductions");
1107 bool IsFPRecurrence =
1115 for (
unsigned I = 0;
I != Worklist.
size(); ++
I) {
1119 if (!UserRecipe->getParent()->getEnclosingLoopRegion()) {
1122 "U must be either in the loop region, the middle block or the "
1123 "scalar preheader.");
1130 Worklist.
insert(UserRecipe);
1144 assert(Blend->getNumIncomingValues() == 2 &&
1145 "Blend must have 2 incoming values");
1146 unsigned PhiRIdx = Blend->getIncomingValue(0) == PhiR ? 0 : 1;
1147 assert(Blend->getIncomingValue(PhiRIdx) == PhiR &&
1148 "PhiR must be an operand of the blend");
1149 Blend->replaceAllUsesWith(Blend->getIncomingValue(1 - PhiRIdx));
1153 if (IsFPRecurrence) {
1158 ->getFastMathFlagsOrNone();
1162 Instruction *CurrentLinkI = CurrentLink->getUnderlyingInstr();
1170 "Expected current VPInstruction to be a call to the "
1171 "llvm.fmuladd intrinsic");
1172 assert(CurrentLink->getOperand(2) == PreviousLink &&
1173 "expected a call where the previous link is the added operand");
1181 {CurrentLink->getOperand(0), CurrentLink->getOperand(1)},
1183 FMulRecipe->insertBefore(CurrentLink);
1190 auto *
Sub = Builder.createSub(
Zero, CurrentLink->getOperand(1),
1192 Sub->setUnderlyingValue(CurrentLinkI);
1196 unsigned IndexOfFirstOperand = 0;
1202 "must be a select recipe");
1203 IndexOfFirstOperand = 1;
1208 CurrentLink->getOperand(IndexOfFirstOperand) == PreviousLink
1209 ? IndexOfFirstOperand + 1
1210 : IndexOfFirstOperand;
1211 VecOp = CurrentLink->getOperand(VecOpId);
1213 VecOp != PreviousLink &&
1216 1 - (VecOpId - IndexOfFirstOperand)) == PreviousLink &&
1217 "PreviousLink must be the operand other than VecOp");
1220 assert(PhiR->getVFScaleFactor() == 1 &&
1221 "inloop reductions must be unscaled");
1224 Kind, FMFs, CurrentLinkI, PreviousLink, VecOp, CondOp,
1232 RedRecipe->insertBefore(&*std::prev(std::prev(LinkVPBB->
end())));
1236 CurrentLink->replaceAllUsesWith(RedRecipe);
1241 if (UserR->getParent() != LinkVPBB)
1245 UserR->moveAfter(RedRecipe);
1248 PreviousLink = RedRecipe;
1253 R->eraseFromParent();
1272 if (!VPI || VPI->getOpcode() != Instruction::Load) {
1273 assert(!R.mayReadFromMemory() &&
"unexpected recipe reading memory");
1278 VPValue *Ptr = VPI->getOperand(0);
1281 LLVM_DEBUG(
dbgs() <<
"LV: Not vectorizing: Found non-dereferenceable "
1282 "load with SCEVCouldNotCompute pointer\n");
1288 const SCEV *SizeSCEV =
1293 TheLoop, SE, DT, AC, &Preds))
1309 cast<VPIRPhi>(&R)->removeIncomingValueFor(EarlyExitingVPBB);
1310 EarlyExitingVPBB->getTerminator()->eraseFromParent();
1320 if (MiddleVPBB->getNumSuccessors() == 1) {
1322 "must have ScalarPH as single successor");
1326 assert(MiddleVPBB->getNumSuccessors() == 2 &&
"must have 2 successors");
1344 DebugLoc LatchDL = LatchVPBB->getTerminator()->getDebugLoc();
1360 assert(HeaderVPB->getPredecessors()[1]->getSuccessors().back() ==
1362 "latch must have the header as last successor");
1367 TopRegion->
setName(
"vector loop");
1373 "only a single-exit block is supported currently");
1376 "the exit block must have middle block as single predecessor");
1380 "The vector loop region must have the middle block as its single "
1381 "successor for now");
1384 Header->
splitAt(Header->getFirstNonPhi());
1388 VPBuilder Builder(Header->getFirstNonPhi());
1393 [[maybe_unused]]
bool TermBranchOnCount =
1397 assert(TermBranchOnCount &&
1400 std::next(IVInc->getDefiningRecipe()->getIterator()) ==
1402 "Unexpected canonical iv increment");
1406 OrigLatch->
splitAt(IVInc->getDefiningRecipe()->getIterator());
1407 Latch->
setName(
"vector.latch");
1416 auto *DefR =
Op->getDefiningRecipe();
1417 if (DefR && DefR->getParent()->getEnclosingLoopRegion() == LoopRegion &&
1419 NeedsPhi[
Op].push_back(&R);
1423 CollectBypassedOperands(R);
1425 CollectBypassedOperands(R);
1428 Builder.setInsertPoint(Latch->
begin());
1429 for (
const auto &[V,
Users] : NeedsPhi) {
1431 std::optional<VPIRFlags> Flags;
1433 "Value used by more than two reduction phis?");
1437 if (RdxPhi && !RdxPhi->isInLoop()) {
1442 VPInstruction *Phi = Builder.createScalarPhi({V, TailVal}, {},
"", Flags);
1444 U->replaceUsesOfWith(V, Phi);
1457 VPValue *LastActiveLane = Builder.createLastActiveLane(HeaderMask);
1460 R.getVPSingleValue()->replaceAllUsesWith(Ext);
1468 "Unexpected MiddleVPBB branch");
1478 "must have incoming values for all predecessors but the new one");
1479 Phi->addIncoming(Phi->getIncomingValue(Phi->getNumIncoming() - 1));
1502 "vector preheader must exist and have no phis to update");
1504 assert(MainScalarPH->getIRBasicBlock()->phis().empty() &&
1505 "MainPlan must not have generated phis in its scalar preheader");
1506 auto *EpilogueCheck =
1515 MainToEpiVPBB[MainEntry] = EpiPlan.
getEntry();
1521 if (VPBB != MainEntry && VPBB != MainScalarPH && VPBB->
hasSuccessors())
1522 MainToEpiVPBB[VPBB] =
1524 MainToEpiVPBB[MainScalarPH] = EpilogueCheck;
1535 if (MainVPBB == MainCheck) {
1548 for (
auto &[MainVPBB, EpiVPBB] :
drop_end(MainToEpiVPBB)) {
1549 Visited.
insert(MainVPBB);
1551 drop_begin(MainVPBB->getSuccessors(), EpiVPBB->getNumSuccessors()))
1552 if (
auto *SuccVPBB = MainToEpiVPBB.
lookup(Succ);
1553 SuccVPBB && !Visited.
contains(Succ))
1556 return EpilogueCheck;
1570 if (AddBranchWeights) {
1574 Term->setMetadata(LLVMContext::MD_prof, BranchWeights);
1580 bool AddBranchWeights) {
1587 bool AddBranchWeights) {
1602 std::tuple<VPValue *, VPValue *, const SCEV *>, 8>
1604 for (
const auto &[
A,
B] : Checks) {
1612 if (CG->NeedsFreeze) {
1613 Start = Builder.createFreeze(Start,
DL);
1614 End = Builder.createFreeze(
End,
DL);
1616 GroupToBounds[CG] = {Start,
End, Stride};
1622 for (
const auto &[
A,
B] : Checks) {
1623 auto [AStart, AEnd, AStride] = GroupToBounds[
A];
1624 auto [BStart, BEnd, BStride] = GroupToBounds[
B];
1630 Builder.createAnd(Bound0, Bound1,
DL,
"found.conflict");
1631 for (
const SCEV *Stride : {AStride, BStride}) {
1632 if (!Stride || !CheckedStrides.
insert(Stride).second)
1635 VPValue *IsNegative = Builder.createICmp(
1637 DL,
"stride.check");
1638 IsConflict = Builder.createOr(IsConflict, IsNegative,
DL);
1640 Cond = Builder.createOr(
Cond, IsConflict,
DL,
"conflict.rdx");
1657 for (
const auto &[SrcStart, SinkStart, AccessSize, NeedsFreeze] : Checks) {
1658 assert(UF * AccessSize > 0 &&
1659 "Threshold must be non-zero to use diff-check");
1660 Type *Ty = SinkStart->getType();
1662 const SCEV *ThresholdMinusOneSCEV =
1668 if (!SeenCompares.
insert({DiffSCEV, ThresholdMinusOneSCEV}).second)
1671 VPValue *ThresholdMinusOne = Expander.
expand(ThresholdMinusOneSCEV);
1677 VPValue *IsConflict = Builder.createICmp(
1680 IsConflict = Builder.createFreeze(IsConflict,
DL,
"diff.check.fr");
1681 Cond = Builder.createOr(
Cond, IsConflict,
DL,
"conflict.rdx");
1689 bool AddBranchWeights) {
1708 ElementCount MinProfitableTripCount,
bool RequiresScalarEpilogue,
1723 auto GetMinTripCount = [&]() ->
const SCEV * {
1732 const SCEV *MinProfitableTripCountSCEV =
1734 return SE.
getUMaxExpr(MinProfitableTripCountSCEV, VFxUF);
1739 const SCEV *Step = GetMinTripCount();
1750 TripCountCheck = Plan.
getTrue();
1757 TripCountCheck = Builder.createICmp(
1758 CmpPred, TripCountVPV, MinTripCountVPV,
DL,
"min.iters.check");
1767 Term->setMetadata(LLVMContext::MD_prof, BranchWeights);
1778 RequiresScalarEpilogue,
false,
1784 VPlan &Plan,
VPValue *MainVectorTripCount,
bool RequiresScalarEpilogue,
1785 ElementCount EpilogueVF,
unsigned MainLoopStep,
unsigned EpilogueLoopStep,
1788 auto *EpilogueCheck =
1794 assert(!RequiresScalarEpilogue &&
1795 "Expected no scalar epilogue for tail-folded plan");
1803 VPValue *VFxUF = Builder.createExpandSCEV(
1805 Builder.setInsertPoint(EpilogueCheck);
1806 VPValue *
Count = Builder.createSub(TC, MainVectorTripCount,
1812 auto *CheckMinIters = Builder.createICmp(
1823 unsigned EstimatedSkipCount = std::min(MainLoopStep, EpilogueLoopStep);
1824 const uint32_t Weights[] = {EstimatedSkipCount,
1825 MainLoopStep - EstimatedSkipCount};
1829 Branch->setMetadata(LLVMContext::MD_prof, BranchWeights);
1846 auto GetMinOrMaxCompareValue =
1864 if (MinOrMaxR->getOperand(0) == RedPhiR)
1865 return MinOrMaxR->getOperand(1);
1866 if (MinOrMaxR->getOperand(1) == RedPhiR)
1867 return MinOrMaxR->getOperand(0);
1873 MinOrMaxNumReductionsToHandle;
1874 bool HasUnsupportedPhi =
false;
1881 HasUnsupportedPhi =
true;
1885 Cur->getRecurrenceKind())) {
1886 HasUnsupportedPhi =
true;
1890 VPValue *MinOrMaxOp = GetMinOrMaxCompareValue(Cur);
1894 MinOrMaxNumReductionsToHandle.
emplace_back(Cur, MinOrMaxOp);
1897 if (MinOrMaxNumReductionsToHandle.
empty())
1921 for (
auto &R : *VPBB) {
1931 for (
auto &[Phi, MinOrMaxOp] : MinOrMaxNumReductionsToHandle) {
1932 VPRecipeBase *MinOrMaxR = Phi->getBackedgeValue()->getDefiningRecipe();
1935 MinOrMaxOp = Freeze;
1939 VPValue *AllNaNLanes =
nullptr;
1941 for (
const auto &[
_, MinOrMaxOp] : MinOrMaxNumReductionsToHandle) {
1944 AllNaNLanes = AllNaNLanes ? LatchBuilder.
createOr(AllNaNLanes, RedNaNLanes)
1952 for (
const auto &[RedPhiR,
_] : MinOrMaxNumReductionsToHandle) {
1954 RedPhiR->getRecurrenceKind()) &&
1955 "unsupported reduction");
1960 assert(RdxResult &&
"must find a ComputeReductionResult");
1962 auto *NewSel = MiddleBuilder.
createSelect(AnyNaNLane, RedPhiR,
1963 RdxResult->getOperand(0));
1965 assert(!RdxResults.
contains(RdxResult) &&
"RdxResult already used");
1966 RdxResults.
insert(RdxResult);
1971 "Unexpected terminator");
1972 auto *IsLatchExitTaken = LatchBuilder.
createICmp(
1974 LatchExitingBranch->getOperand(1));
1975 auto *AnyExitTaken = LatchBuilder.
createOr(AnyNaNLane, IsLatchExitTaken);
1982 auto IsTC = [&Plan](
VPValue *V) {
1987 VPValue *VecV = ResumeR->getOperand(0);
1991 VPValue *DIVTC = DerivedIV->getOperand(1);
1992 if (DerivedIV->hasOneUse() && IsTC(DIVTC)) {
1996 DerivedIV->setOperand(1, NewSel);
2003 LLVM_DEBUG(
dbgs() <<
"Found resume phi we cannot update for VPlan with "
2004 "FMaxNum/FMinNum reduction.\n");
2014 VPValue *MiddleCond = MiddleTerm->getOperand(0);
2050 PhiR.getRecurrenceKind()))
2060 VPValue *BackedgeSelect = PhiR->getBackedgeValue();
2061 VPValue *CondSelect = BackedgeSelect;
2066 !
match(BackedgeSelect,
2071 VPValue *
Cond =
nullptr, *Op1 =
nullptr, *Op2 =
nullptr;
2080 assert(!Blend->isNormalized() &&
"must run before blend normalizaion");
2081 unsigned NumIncomingDataValues = 0;
2082 for (
unsigned I = 0;
I < Blend->getNumIncomingValues(); ++
I) {
2083 VPValue *Incoming = Blend->getIncomingValue(
I);
2084 if (Incoming != PhiR) {
2085 ++NumIncomingDataValues;
2086 Cond = Blend->getMask(
I);
2091 return NumIncomingDataValues == 1;
2098 !MatchBlend(SelectR))
2105 return U != SelectR && U != BackedgeSelect->getDefiningRecipe();
2109 assert(
Cond != HeaderMask &&
"Cond must not be HeaderMask");
2115 assert(RdxResult &&
"Could not find reduction result");
2119 auto *MaskPHI = Builder.createWidenPhi(Plan.
getFalse());
2122 Builder.setInsertPoint(SelectR);
2130 assert(Op2 == PhiR &&
"data value must be selected if Cond is true");
2133 Cond = Builder.createLogicalAnd(HeaderMask,
Cond);
2138 MaskPHI->addIncoming(MaskSelect);
2144 PhiR->setBackedgeValue(DataSelect);
2147 Builder.setInsertPoint(RdxResult);
2148 auto *ExtractLastActive =
2150 {PhiR->getStartValue(), DataSelect, MaskSelect},
2151 RdxResult->getDebugLoc());
2152 RdxResult->replaceAllUsesWith(ExtractLastActive);
2153 RdxResult->eraseFromParent();
2178 "inloop and ordered reductions not supported");
2180 "FindIV reduction must not be scaled");
2195 auto *FindIVSelectVal = BackedgeVal;
2200 auto *FindIVSelectR =
2205 "backedge value must be a select");
2206 if (FindIVSelectR->getOperand(1) != WideIV &&
2221 WidenCanIV->insertBefore(WideIV);
2224 FindIVSelectR->setOperand(FindIVSelectR->getOperand(1) == WideIV ? 1 : 2,
2281 auto *FinalMinOrMaxCmp =
2286 auto *FinalIVSelect =
2287 Builder.createSelect(FinalMinOrMaxCmp, LastIVExiting, MaxIV);
2300 DerivedIVRecipe->insertBefore(Builder.getRecipeAtInsertPoint());
2301 FinalCanIV = DerivedIVRecipe;
2309 VPValue *FinalIV = Builder.createSelect(
2310 AlwaysFalse, FindIVSelect->
getOperand(2), FinalCanIV);
2327 if (!MinOrMaxPhiR || !MinOrMaxPhiR->hasUsesOutsideReductionChain())
2341 RecurKind RdxKind = MinOrMaxPhiR->getRecurrenceKind();
2344 "only min/max recurrences support users outside the reduction chain");
2346 auto *MinOrMaxBackedgeR =
2348 if (!MinOrMaxBackedgeR)
2354 auto *MinOrMaxOp = MinOrMaxBackedgeR;
2377 "Tailfolded MinOrMaxOp must have exactly 1 user");
2380 assert(MinOrMaxBackedgeR->getNumUsers() == 2 &&
2381 "MinOrMaxBackedgeR must have exactly 2 users");
2386 if (MinOrMaxOp->getOperand(0) == MinOrMaxPhiR)
2387 MinOrMaxOpValue = MinOrMaxOp->getOperand(1);
2388 else if (MinOrMaxOp->getOperand(1) == MinOrMaxPhiR)
2389 MinOrMaxOpValue = MinOrMaxOp->getOperand(0);
2398 if (!Cmp || Cmp->getNumUsers() != 1 ||
2399 (CmpOpA != MinOrMaxOpValue && CmpOpB != MinOrMaxOpValue))
2402 if (MinOrMaxOpValue != CmpOpB)
2410 if (MinOrMaxPhiR->getNumUsers() != (HeaderMask ? 3 : 2))
2417 "MinOrMaxResult must be a user of MinOrMaxBackedgeR");
2422 if (!Sel || (Sel->
getNumUsers() != (HeaderMask ? 1 : 2)) ||
2434 FindIVPhiR->getRecurrenceKind()))
2437 assert(!FindIVPhiR->isInLoop() && !FindIVPhiR->isOrdered() &&
2438 "cannot handle inloop/ordered reductions yet");
2444 FindIVPhiR->getBackedgeValue());
2446 "must be able to retrieve the FindIVResult VPInstruction");
2458 bool IsValidKindPred = [RdxKind, Pred]() {
2485 if (!IsValidKindPred) {
2488 DEBUG_TYPE,
"VectorizationMultiUseReductionPredicate",
2490 <<
"Multi-use reduction with predicate "
2492 <<
" incompatible with reduction kind";
2500 if (!StartC || StartC->getConstant()->isNaN())
2505 auto *FindIVCmp = FindIVSelect->getOperand(0)->getDefiningRecipe();
2508 "both results must be computed in the same block");
2512 MinOrMaxResult->
moveBefore(FindIVRdxResult->getIterator());
2515 if (IsStrictPredicate) {
2518 MinOrMaxResult, FindIVSelect, FindIVCmp,
2549 auto *FinalMinOrMaxCmp =
2554 VPValue *LastIVExiting = FindIVRdxResult->getOperand(0);
2555 auto *FinalIVSelect =
2556 B.createSelect(FinalMinOrMaxCmp, LastIVExiting,
Sentinel);
2557 FindIVRdxResult->setOperand(0, FinalIVSelect);
2568 auto *AliasMask = Builder.createNaryOp(
2573 Builder =
VPBuilder(Header->getFirstNonPhi());
2576 auto *ClampedHeaderMask = Builder.createAnd(HeaderMask, AliasMask);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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[]
SmallVector< MachineOperand, 4 > Cond
Provides some synthesis utilities to produce sequences of values.
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 addIncomingForLastPredecessor(VPBasicBlock *VPBB)
Add an incoming value to all phis in VPBB for its just-added last predecessor, re-using the value of ...
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 addBypassBranch(VPlan &Plan, VPBasicBlock *CheckBlockVPBB, VPValue *Cond, bool AddBranchWeights)
Create a BranchOnCond terminator in CheckBlockVPBB.
static VPValue * createDiffRuntimeChecks(VPlan &Plan, VPBuilder &Builder, VPSCEVExpander &Expander, ArrayRef< PointerDiffInfo > Checks, ScalarEvolution &SE, ElementCount VF, unsigned UF, DebugLoc DL)
Generate recipes for the memory runtime difference checks Checks using Builder and return the conditi...
static bool sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR, VPRecipeBase *Previous, const VPDominatorTree &VPDT)
Try to sink users of FOR after Previous.
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 void addInitialSkeleton(VPlan &Plan, Type *InductionTy, PredicatedScalarEvolution &PSE, Loop *TheLoop)
static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR, VPRecipeBase *Previous, const VPDominatorTree &VPDT)
Try to hoist Previous and its operands before all users of FOR.
static void createLoopRegion(VPlan &Plan, VPBlockBase *HeaderVPB, DebugLoc DL)
Create a new VPRegionBlock for the loop starting at HeaderVPB.
static VPInstruction * findFindIVSelect(VPValue *BackedgeVal)
Find and return the final select instruction of the FindIV result pattern for the given BackedgeVal: ...
static bool tryToSinkOrHoistRecurrenceUsers(VPBasicBlock *HeaderVPBB, const VPDominatorTree &VPDT)
Sink users of fixed-order recurrences past or hoist before the recipe defining the previous value,...
static constexpr uint32_t CheckBypassWeights[]
static void printAfterInitialConstruction(VPlan &)
To make RUN_VPLAN_PASS print initial VPlan.
static void createExtractsForLiveOuts(VPlan &Plan, VPBasicBlock *MiddleVPBB)
Creates extracts for values in Plan defined in a loop region and used outside a loop region.
static VPValue * createRuntimeChecks(VPlan &Plan, VPBuilder &Builder, VPSCEVExpander &Expander, ArrayRef< RuntimePointerCheck > Checks, const Loop *TheLoop, ScalarEvolution &SE, DebugLoc DL)
Generate recipes for the memory runtime checks Checks of TheLoop using Builder and return the conditi...
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
This file contains the declarations of different VPlan-related auxiliary helpers.
This file contains the declarations of the Vectorization Plan base classes:
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Analysis providing branch probability information.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ ICMP_ULT
unsigned less than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ 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)
bool isStrictPredicate() const
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
Describes a conditional induction variable: an induction variable that is updated only on loop iterat...
const SCEV * getStepSCEV() const
Returns a SCEV expression for the step of the conditional induction PHI.
A parsed version of the target data layout string in and methods for querying it.
static DebugLoc getUnknown()
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.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
static constexpr ElementCount getFixed(ScalarTy MinVal)
constexpr bool isScalar() const
Exactly one element.
Convenience struct for specifying and reasoning about fast-math flags.
static FastMathFlags getFast()
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.
This is an important class for using LLVM in a threaded context.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
BlockT * getHeader() const
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
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...
LLVM_ABI 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.
ValueT lookup(const KeyT &Key) const
iterator find(const KeyT &Key)
Post-order traversal of a graph.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
LLVM_ABI void addPredicate(const SCEVPredicate &Pred)
Adds a new predicate.
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEVPredicate & getPredicate() const
LLVM_ABI const SCEV * getSymbolicMaxBackedgeTakenCount()
Get the (predicated) symbolic max backedge count for the analyzed loop.
LLVM_ABI const SCEV * getSCEV(Value *V)
Returns the SCEV expression of V, in the context of the current SCEV predicate.
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 LLVM_ABI bool isIntegerRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is an integer kind.
static bool isMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is any min/max kind.
Holds information about the memory runtime legality checks to verify that a group of pointers do not ...
std::optional< ArrayRef< PointerDiffInfo > > getDiffChecks() const
const SmallVectorImpl< RuntimePointerCheck > & getChecks() const
Returns the checks that generateChecks created.
virtual unsigned getComplexity() const
Returns the estimated complexity of this predicate.
This class represents an analyzed expression in the program.
static constexpr auto FlagNUW
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getElementCount(Type *Ty, ElementCount EC, SCEVFlags Flags=SCEV::FlagNone)
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags=SCEV::FlagNone, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getTripCountFromExitCount(const SCEV *ExitCount)
A version of getTripCountFromExitCount below which always picks an evaluation type which can not resu...
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
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 * getUMaxExpr(SCEVUse LHS, SCEVUse RHS)
LLVM_ABI const SCEV * getStoreSizeOfExpr(Type *IntTy, Type *StoreTy)
Return an expression for the store size of StoreTy that is type IntTy.
LLVM_ABI bool isKnownPredicate(CmpPredicate Pred, SCEVUse LHS, SCEVUse RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
LLVM_ABI const SCEV * applyLoopGuards(const SCEV *Expr, const Loop *L)
Try to apply information from loop guards for L to Expr.
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.
Implements a dense probed hash-table based set with some number of buckets stored inline.
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.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
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...
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.
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.
size_t getNumPredecessors() const
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
bool hasSuccessors() const
Returns true if this block has any successors.
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 auto blocksAs(T &&Range)
Return an iterator range over Range with each block cast to BlockTy.
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 VPBasicBlock * getPlainCFGMiddleBlock(const VPlan &Plan)
Returns the middle block of Plan in plain CFG form (before regions are formed).
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 void reassociateBlocks(VPBlockBase *Old, VPBlockBase *New)
Reassociate all the blocks connected to Old so that they now point to New.
static std::pair< VPBasicBlock *, VPBasicBlock * > getPlainCFGHeaderAndLatch(const VPlan &Plan)
Returns the header and latch of the outermost loop of Plan in plain CFG form (before regions are form...
static void transferSuccessors(VPBlockBase *Old, VPBlockBase *New)
Transfer successors from Old to New. New must have no successors.
VPInstruction * createFreeze(VPValue *Op, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
static VPBuilderBase getToInsertAfter(VPRecipeBase *R)
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.
VPInstruction * createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPRecipeBase * getRecipeAtInsertPoint() const
Get the recipe at the current insert point or nullptr if the insert point is the end of the block.
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt)
Create a select of TrueVal and FalseVal based on Cond, using the default flags for the result type,...
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
void setInsertPoint(const VPInsertPoint &IP)
Set the current insert point.
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Instruction *Inst=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", Type *ResultTy=nullptr, const VPIRAttributes &Attrs={})
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
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.
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
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.
A recipe for handling scalar conditional induction PHIs.
unsigned getNumDefinedValues() const
Returns the number of values defined by the VPDef.
VPValue * getVPSingleValue()
Returns the only VPValue defined by the VPDef.
A recipe for converting Current into Start + Current * Step.
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
LLVM_ABI_FOR_TEST bool properlyDominates(const VPRecipeBase *A, const VPRecipeBase *B) const
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...
@ FirstOrderRecurrenceSplice
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
void addIncoming(VPValue *IncomingV)
Append IncomingV as an incoming value to the phi-like recipe.
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
void moveBefore(RecipeListTy::iterator I)
Unlink this recipe and insert it before I.
RecipeListTy::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
bool isPhi() const
Returns true for PHI-like recipes.
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
void insertBefore(VPRecipeBase *InsertPos)
Insert an unlinked recipe into a basic block immediately before the specified recipe.
void moveAfter(VPRecipeBase *MovePos)
Unlink this recipe from its current VPBasicBlock and insert it into the VPBasicBlock that MovePos liv...
Type * getScalarType() const
Returns the scalar type of this VPRecipeValue.
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.
RecurKind getRecurrenceKind() const
Returns the recurrence kind of the 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...
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
Type * getCanonicalIVType() const
Return the type of the canonical IV for loop regions.
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
VPRegionValue * getHeaderMask() const
Return the header mask of the region, or null if not set.
DebugLoc getDebugLoc() const
Returns the debug location of the VPRegionValue.
Lightweight SCEV-to-VPlan expander.
VPValue * expand(const SCEV *S)
Expand S into recipes and live-ins using the builder.
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
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 setOperand(unsigned I, VPValue *New)
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.
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
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...
void setUnderlyingValue(Value *Val)
void replaceAllUsesWith(VPValue *New)
unsigned getNumUsers() const
Base class for widened induction (VPWidenIntOrFpInductionRecipe and VPWidenPointerInductionRecipe),...
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...
bool isCanonical() const
Returns true if the induction is canonical, i.e.
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 * getTripCount() const
The trip count of the original loop.
VPIRValue * getFalse()
Return a VPIRValue wrapping i1 false.
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...
VPIRValue * getPoison(Type *Ty)
Return a VPIRValue wrapping a poison value of type Ty.
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.
VPRegionBlock * createLoopRegion(Type *CanIVTy, DebugLoc DL, const std::string &Name="", VPBlockBase *Entry=nullptr, VPBlockBase *Exiting=nullptr)
Create a new loop region with a canonical IV using CanIVTy and DL.
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
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.
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
bool hasScalarVFOnly() const
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
bool hasTailFolded() const
Returns true if the vector loop region is tail-folded.
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
bool hasScalarTail() const
Returns true if the scalar tail may execute after the vector loop, i.e.
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.
std::pair< iterator, bool > insert(const ValueT &V)
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ BasicBlock
Various leaf nodes.
void reportVectorizationFailure(const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr)
Reports a vectorization failure: print DebugMsg for debugging purposes along with the corresponding o...
auto m_Cmp()
Matches any compare instruction and ignore it.
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.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
SelectLike_match< CondTy, LTy, RTy > m_SelectLike(const CondTy &C, const LTy &TrueC, const RTy &FalseC)
Matches a value that behaves like a boolean-controlled select, i.e.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
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)
RecipeTy * findSingleUser(VPValue *V, const MatchT &P)
Return the sole user of V matching pattern P, casting it to RecipeTy, or nullptr.
bool matchFindIVResult(VPInstruction *VPI, Op0_t ReducedIV, Op1_t Start)
Match FindIV result pattern: select(icmp ne ComputeReductionResult(ReducedIV), Sentinel),...
VPInstruction_match< VPInstruction::BranchOnTwoConds > m_BranchOnTwoConds()
VPInstruction_match< VPInstruction::ExtractLastLane, Op0_t > m_ExtractLastLane(const Op0_t &Op0)
VPInstruction_match< VPInstruction::BranchOnCount > m_BranchOnCount()
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > m_ExtractLastPart(const Op0_t &Op0)
match_bind< 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.
bool cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking=false)
Return true if we do not know how to (mechanically) hoist or sink R.
VPInstruction * findComputeReductionResult(VPReductionPHIRecipe *PhiR)
Find the ComputeReductionResult recipe for PhiR, looking through selects inserted for predicated redu...
SmallVector< std::pair< VPBasicBlock *, VPIRBasicBlock * > > getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB)
Returns the (early exiting block, exit block) pairs of Plan, i.e.
DenseMap< const VPBasicBlock *, std::optional< VPExecutionFrequency > > computeExecutionFrequencies(ArrayRef< VPBasicBlock * > Blocks)
Computes for each block in Blocks, which must be in reverse post-order, the frequency with which it e...
VPIRFlags getFlagsForInduction(const InductionDescriptor &ID, const VPPhi *PhiR)
Extracts and returns NoWrap flags from PhiR and fast-math flags from ID.
VPRecipeBase * findRecipe(VPValue *Start, PredT Pred)
Search Start's users for a recipe satisfying Pred, looking through recipes with definitions.
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr, bool ExpandInIR=false)
Get or create a VPValue that corresponds to the expansion of Expr.
LLVM_ABI_FOR_TEST 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.
SmallVector< VPBasicBlock * > vp_rpo_plain_cfg_loop_body(VPBasicBlock *Header)
Returns the VPBasicBlocks forming the loop body of a plain (pre-region) VPlan in reverse post-order s...
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
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.
@ Load
The value being inserted comes from a load (InsertElement only).
VPBuilderBase<> VPBuilder
auto map_to_vector(ContainerTy &&C, FuncTy &&F)
Map a range to a SmallVector with element types deduced from the mapping.
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
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)
constexpr size_t range_size(R &&Range)
Returns the size of the Range, i.e., the number of elements.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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...
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
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...
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
RecurKind
These are the kinds of recurrences that we support.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ FMinimumNum
FP min with llvm.minimumnum semantics.
@ FindIV
FindIV reduction with select(icmp(),x,y) where one of (x,y) is a loop induction variable (increasing ...
@ FMinimum
FP min with llvm.minimum semantics.
@ FMaxNum
FP max with llvm.maxnum semantics including NaNs.
@ AnyOf
AnyOf reduction with select(cmp(),x,y) where one of (x,y) is loop invariant, and both x and y are int...
@ FMax
FP max implemented in terms of select(cmp()).
@ FMaximum
FP max with llvm.maximum semantics.
@ 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()).
@ FMin
FP min implemented in terms of select(cmp()).
@ FMinNum
FP min with llvm.minnum semantics including NaNs.
@ Sub
Subtraction of integers.
@ AddChainWithSubs
A chain of adds and subs.
@ FMaximumNum
FP max with llvm.maximumnum semantics.
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
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...
LLVM_ABI RuntimeCheckBounds getRuntimeCheckBounds(const RuntimeCheckingPtrGroup *CG, const Loop *TheLoop, ScalarEvolution &SE, bool HoistRuntimeChecks)
Return the bounds of CG in TheLoop.
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.
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.
@ End
Run the machine verifier once, at the end of the pipeline.
LLVM_ABI bool isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L, ScalarEvolution &SE, DominatorTree &DT, AssumptionCache *AC=nullptr, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Return true if we can prove that the given load (which is assumed to be within the specified loop) wo...
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A MapVector that performs no allocations if smaller than a certain size.
A recipe for handling first-order recurrence phis.
A VPValue representing a live-in from the input IR or a constant.
static LLVM_ABI bool HoistRuntimeChecks