41using namespace VPlanPatternMatch;
45 cl::desc(
"Enable use of wide get active lane mask instructions"));
50 GetIntOrFpInductionDescriptor,
54 Plan->getVectorLoopRegion());
55 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
57 if (!VPBB->getParent())
60 auto EndIter = Term ? Term->getIterator() : VPBB->end();
65 VPValue *VPV = Ingredient.getVPSingleValue();
72 if (
auto *PhiR = dyn_cast<VPPhi>(&Ingredient)) {
73 auto *Phi = cast<PHINode>(PhiR->getUnderlyingValue());
74 const auto *
II = GetIntOrFpInductionDescriptor(Phi);
80 VPValue *Start = Plan->getOrAddLiveIn(
II->getStartValue());
84 Phi, Start, Step, &Plan->getVF(), *
II, Ingredient.getDebugLoc());
87 assert(isa<VPInstruction>(&Ingredient) &&
88 "only VPInstructions expected here");
89 assert(!isa<PHINode>(Inst) &&
"phis should be handled above");
91 if (
LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
93 *Load, Ingredient.getOperand(0),
nullptr ,
95 Ingredient.getDebugLoc());
96 }
else if (
StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
98 *Store, Ingredient.getOperand(1), Ingredient.getOperand(0),
99 nullptr ,
false ,
false ,
103 }
else if (
CallInst *CI = dyn_cast<CallInst>(Inst)) {
109 {Ingredient.op_begin(), Ingredient.op_end() - 1}, CI->getType(),
111 }
else if (
SelectInst *SI = dyn_cast<SelectInst>(Inst)) {
113 }
else if (
auto *CI = dyn_cast<CastInst>(Inst)) {
115 CI->getOpcode(), Ingredient.getOperand(0), CI->getType(), *CI);
126 "Only recpies with zero or one defined values expected");
127 Ingredient.eraseFromParent();
135 bool Changed =
false;
139 for (
VPRegionBlock *VPR : VPBlockUtils::blocksOnly<VPRegionBlock>(Iter)) {
146 for (
auto &Recipe : *VPBB) {
149 dyn_cast_or_null<VPSingleDefRecipe>(
Op->getDefiningRecipe()))
150 WorkList.
insert({VPBB, Def});
156 for (
unsigned I = 0;
I != WorkList.
size(); ++
I) {
159 std::tie(SinkTo, SinkCandidate) = WorkList[
I];
160 if (SinkCandidate->
getParent() == SinkTo ||
164 if (
auto *RepR = dyn_cast<VPReplicateRecipe>(SinkCandidate)) {
165 if (!ScalarVFOnly && RepR->isSingleScalar())
167 }
else if (!isa<VPScalarIVStepsRecipe>(SinkCandidate))
170 bool NeedsDuplicating =
false;
175 auto CanSinkWithUser = [SinkTo, &NeedsDuplicating,
176 SinkCandidate](
VPUser *U) {
177 auto *UI = cast<VPRecipeBase>(U);
178 if (UI->getParent() == SinkTo)
180 NeedsDuplicating = UI->onlyFirstLaneUsed(SinkCandidate);
183 return NeedsDuplicating &&
184 isa<VPReplicateRecipe, VPScalarIVStepsRecipe>(SinkCandidate);
186 if (!
all_of(SinkCandidate->
users(), CanSinkWithUser))
189 if (NeedsDuplicating) {
193 if (
auto *SinkCandidateRepR =
194 dyn_cast<VPReplicateRecipe>(SinkCandidate)) {
199 nullptr , *SinkCandidateRepR);
202 Clone = SinkCandidate->
clone();
207 return cast<VPRecipeBase>(&U)->
getParent() != SinkTo;
213 dyn_cast_or_null<VPSingleDefRecipe>(
Op->getDefiningRecipe()))
214 WorkList.
insert({SinkTo, Def});
223 auto *EntryBB = dyn_cast<VPBasicBlock>(R->getEntry());
224 if (!EntryBB || EntryBB->size() != 1 ||
225 !isa<VPBranchOnMaskRecipe>(EntryBB->begin()))
228 return cast<VPBranchOnMaskRecipe>(&*EntryBB->begin())->getOperand(0);
233 auto *EntryBB = cast<VPBasicBlock>(R->getEntry());
234 if (EntryBB->getNumSuccessors() != 2)
237 auto *Succ0 = dyn_cast<VPBasicBlock>(EntryBB->getSuccessors()[0]);
238 auto *Succ1 = dyn_cast<VPBasicBlock>(EntryBB->getSuccessors()[1]);
239 if (!Succ0 || !Succ1)
242 if (Succ0->getNumSuccessors() + Succ1->getNumSuccessors() != 1)
244 if (Succ0->getSingleSuccessor() == Succ1)
246 if (Succ1->getSingleSuccessor() == Succ0)
261 for (
VPRegionBlock *Region1 : VPBlockUtils::blocksOnly<VPRegionBlock>(
263 if (!Region1->isReplicator())
265 auto *MiddleBasicBlock =
266 dyn_cast_or_null<VPBasicBlock>(Region1->getSingleSuccessor());
267 if (!MiddleBasicBlock || !MiddleBasicBlock->empty())
271 dyn_cast_or_null<VPRegionBlock>(MiddleBasicBlock->getSingleSuccessor());
272 if (!Region2 || !Region2->isReplicator())
277 if (!Mask1 || Mask1 != Mask2)
280 assert(Mask1 && Mask2 &&
"both region must have conditions");
286 if (TransformedRegions.
contains(Region1))
288 auto *MiddleBasicBlock = cast<VPBasicBlock>(Region1->getSingleSuccessor());
289 auto *Region2 = cast<VPRegionBlock>(MiddleBasicBlock->getSingleSuccessor());
293 if (!Then1 || !Then2)
312 cast<VPPredInstPHIRecipe>(&Phi1ToMove)->getOperand(0);
313 VPValue *Phi1ToMoveV = Phi1ToMove.getVPSingleValue();
315 return cast<VPRecipeBase>(&U)->getParent() == Then2;
319 if (Phi1ToMove.getVPSingleValue()->getNumUsers() == 0) {
320 Phi1ToMove.eraseFromParent();
323 Phi1ToMove.moveBefore(*Merge2, Merge2->begin());
337 TransformedRegions.
insert(Region1);
340 return !TransformedRegions.
empty();
347 std::string RegionName = (
Twine(
"pred.") + Instr->getOpcodeName()).str();
348 assert(Instr->getParent() &&
"Predicated instruction not in any basic block");
349 auto *BlockInMask = PredRecipe->
getMask();
352 BlockInMask, MaskDef ? MaskDef->getDebugLoc() :
DebugLoc());
368 RecipeWithoutMask->getDebugLoc());
388 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
391 if (
auto *RepR = dyn_cast<VPReplicateRecipe>(&R)) {
392 if (RepR->isPredicated())
411 if (ParentRegion && ParentRegion->
getExiting() == CurrentBlock)
420 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
425 if (!VPBB->getParent())
428 dyn_cast_or_null<VPBasicBlock>(VPBB->getSinglePredecessor());
429 if (!PredVPBB || PredVPBB->getNumSuccessors() != 1 ||
430 isa<VPIRBasicBlock>(PredVPBB))
436 VPBasicBlock *PredVPBB = cast<VPBasicBlock>(VPBB->getSinglePredecessor());
438 R.moveBefore(*PredVPBB, PredVPBB->
end());
440 auto *ParentRegion = VPBB->getParent();
441 if (ParentRegion && ParentRegion->getExiting() == VPBB)
442 ParentRegion->setExiting(PredVPBB);
443 for (
auto *Succ :
to_vector(VPBB->successors())) {
449 return !WorkList.
empty();
456 bool ShouldSimplify =
true;
457 while (ShouldSimplify) {
472 auto *
IV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&Phi);
473 if (!
IV ||
IV->getTruncInst())
484 auto &Casts =
IV->getInductionDescriptor().getCastInsts();
488 for (
auto *U : FindMyCast->
users()) {
489 auto *UserCast = dyn_cast<VPSingleDefRecipe>(U);
490 if (UserCast && UserCast->getUnderlyingValue() == IRCast) {
491 FoundUserCast = UserCast;
495 FindMyCast = FoundUserCast;
507 WidenNewIV = dyn_cast<VPWidenCanonicalIVRecipe>(U);
517 auto *WidenOriginalIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&Phi);
519 if (!WidenOriginalIV || !WidenOriginalIV->isCanonical())
539 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
540 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
541 match(RepR, m_Intrinsic<Intrinsic::assume>());
542 if (IsConditionalAssume)
545 if (R.mayHaveSideEffects())
549 return all_of(R.definedValues(),
550 [](
VPValue *V) { return V->getNumUsers() == 0; });
554 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
565 auto *PhiR = dyn_cast<VPPhi>(&R);
566 if (!PhiR || PhiR->getNumOperands() != 2 || PhiR->getNumUsers() != 1)
569 if (*PhiR->user_begin() !=
Incoming->getDefiningRecipe() ||
572 PhiR->replaceAllUsesWith(PhiR->getOperand(0));
573 PhiR->eraseFromParent();
574 Incoming->getDefiningRecipe()->eraseFromParent();
588 Kind, FPBinOp, StartV, CanonicalIV, Step,
"offset.idx");
604 if (ResultTy != StepTy) {
620 for (
unsigned I = 0;
I !=
Users.size(); ++
I) {
622 if (isa<VPHeaderPHIRecipe>(Cur))
625 Users.insert_range(V->users());
627 return Users.takeVector();
647 auto *PhiR = dyn_cast<VPWidenInductionRecipe>(&Phi);
657 auto *Def = dyn_cast<VPSingleDefRecipe>(U);
658 auto *RepR = dyn_cast<VPReplicateRecipe>(U);
660 if (!Def || !isa<VPReplicateRecipe, VPWidenRecipe>(Def) ||
661 Def->getNumUsers() == 0 || !Def->getUnderlyingValue() ||
662 (RepR && (RepR->isSingleScalar() || RepR->isPredicated())))
670 Def->operands(),
true);
671 Clone->insertAfter(Def);
672 Def->replaceAllUsesWith(Clone);
677 if (
auto *PtrIV = dyn_cast<VPWidenPointerInductionRecipe>(&Phi)) {
684 VPValue *StepV = PtrIV->getOperand(1);
687 nullptr, StartV, StepV, PtrIV->getDebugLoc(), Builder);
698 auto *WideIV = cast<VPWidenIntOrFpInductionRecipe>(&Phi);
699 if (HasOnlyVectorVFs &&
none_of(WideIV->users(), [WideIV](
VPUser *U) {
700 return U->usesScalars(WideIV);
706 Plan,
ID.getKind(),
ID.getInductionOpcode(),
707 dyn_cast_or_null<FPMathOperator>(
ID.getInductionBinOp()),
708 WideIV->getTruncInst(), WideIV->getStartValue(), WideIV->getStepValue(),
709 WideIV->getDebugLoc(), Builder);
712 if (!HasOnlyVectorVFs)
713 WideIV->replaceAllUsesWith(Steps);
715 WideIV->replaceUsesWithIf(Steps, [WideIV](
VPUser &U,
unsigned) {
716 return U.usesScalars(WideIV);
726 auto *WideIV = dyn_cast<VPWidenInductionRecipe>(VPV);
730 auto *IntOrFpIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(WideIV);
731 return (IntOrFpIV && IntOrFpIV->getTruncInst()) ? nullptr : WideIV;
736 if (!Def || Def->getNumOperands() != 2)
738 WideIV = dyn_cast<VPWidenInductionRecipe>(Def->getOperand(0));
740 WideIV = dyn_cast<VPWidenInductionRecipe>(Def->getOperand(1));
744 auto IsWideIVInc = [&]() {
745 auto &
ID = WideIV->getInductionDescriptor();
748 VPValue *IVStep = WideIV->getStepValue();
749 switch (
ID.getInductionOpcode()) {
750 case Instruction::Add:
752 case Instruction::FAdd:
755 case Instruction::FSub:
758 case Instruction::Sub: {
766 return !isa<SCEVCouldNotCompute>(IVStepSCEV) &&
767 !isa<SCEVCouldNotCompute>(StepSCEV) &&
777 return IsWideIVInc() ? WideIV :
nullptr;
788 if (!
match(
Op, m_VPInstruction<VPInstruction::ExtractLane>(
789 m_VPInstruction<VPInstruction::FirstActiveLane>(
798 auto *WideIntOrFp = dyn_cast<VPWidenIntOrFpInductionRecipe>(WideIV);
799 if (WideIntOrFp && WideIntOrFp->getTruncInst())
811 FirstActiveLane =
B.createScalarZExtOrTrunc(FirstActiveLane, CanonicalIVType,
812 FirstActiveLaneType,
DL);
813 EndValue =
B.createNaryOp(Instruction::Add, {EndValue, FirstActiveLane},
DL);
820 EndValue =
B.createNaryOp(Instruction::Add, {EndValue, One},
DL);
823 if (!WideIntOrFp || !WideIntOrFp->isCanonical()) {
825 VPValue *Start = WideIV->getStartValue();
826 VPValue *Step = WideIV->getStepValue();
827 EndValue =
B.createDerivedIV(
828 ID.getKind(), dyn_cast_or_null<FPMathOperator>(
ID.getInductionBinOp()),
829 Start, EndValue, Step);
849 assert(EndValue &&
"end value must have been pre-computed");
858 VPBuilder B(cast<VPBasicBlock>(PredVPBB)->getTerminator());
859 VPValue *Step = WideIV->getStepValue();
862 return B.createNaryOp(Instruction::Sub, {EndValue, Step}, {},
"ind.escape");
866 return B.createPtrAdd(EndValue,
867 B.createNaryOp(Instruction::Sub, {Zero, Step}), {},
871 const auto &
ID = WideIV->getInductionDescriptor();
872 return B.createNaryOp(
873 ID.getInductionBinOp()->getOpcode() == Instruction::FAdd
876 {EndValue, Step}, {ID.getInductionBinOp()->getFastMathFlags()});
889 auto *ExitIRI = cast<VPIRPhi>(&R);
891 for (
auto [
Idx, PredVPBB] :
enumerate(ExitVPBB->getPredecessors())) {
893 if (PredVPBB == MiddleVPBB)
895 ExitIRI->getOperand(
Idx),
899 ExitIRI->getOperand(
Idx), SE);
901 ExitIRI->setOperand(
Idx, Escape);
914 auto *ExpR = dyn_cast<VPExpandSCEVRecipe>(&R);
918 const auto &[V, Inserted] = SCEV2VPV.
try_emplace(ExpR->getSCEV(), ExpR);
921 ExpR->replaceAllUsesWith(V->second);
922 ExpR->eraseFromParent();
931 while (!WorkList.
empty()) {
933 if (!Seen.
insert(Cur).second)
940 WorkList.
append(R->op_begin(), R->op_end());
941 R->eraseFromParent();
953 if (!
Op->isLiveIn() || !
Op->getLiveInIRValue())
970 return Folder.
FoldBinOp(Instruction::BinaryOps::Xor, Ops[0],
972 case Instruction::Select:
973 return Folder.
FoldSelect(Ops[0], Ops[1], Ops[2]);
974 case Instruction::ICmp:
975 case Instruction::FCmp:
976 return Folder.
FoldCmp(cast<VPRecipeWithIRFlags>(R).getPredicate(), Ops[0],
978 case Instruction::GetElementPtr: {
979 auto &RFlags = cast<VPRecipeWithIRFlags>(R);
980 auto *
GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr());
982 RFlags.getGEPNoWrapFlags());
988 cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags());
991 case Instruction::ExtractElement:
992 assert(!Ops[0]->
getType()->isVectorTy() &&
"Live-ins should be scalar");
1000 VPlan *Plan = R.getParent()->getPlan();
1002 auto *Def = dyn_cast<VPSingleDefRecipe>(&R);
1019 .
Default([](
auto *) {
return false; }))
1023 if (
auto *PredPHI = dyn_cast<VPPredInstPHIRecipe>(&R)) {
1026 PredPHI->replaceAllUsesWith(
Op);
1033 if (TruncTy == ATy) {
1034 Def->replaceAllUsesWith(
A);
1037 if (isa<VPReplicateRecipe>(Def))
1043 : Instruction::ZExt;
1046 if (
auto *UnderlyingExt = R.getOperand(0)->getUnderlyingValue()) {
1048 VPC->setUnderlyingValue(UnderlyingExt);
1050 VPC->insertBefore(&R);
1051 Def->replaceAllUsesWith(VPC);
1054 VPC->insertBefore(&R);
1055 Def->replaceAllUsesWith(VPC);
1063 for (
VPUser *U :
A->users()) {
1064 auto *R = cast<VPRecipeBase>(U);
1065 for (
VPValue *VPV : R->definedValues())
1079 Def->replaceAllUsesWith(
X);
1080 Def->eraseFromParent();
1086 Def->replaceAllUsesWith(Def->getOperand(0) ==
X ? Def->getOperand(1)
1087 : Def->getOperand(0));
1088 Def->eraseFromParent();
1094 Def->replaceAllUsesWith(R.getOperand(0) ==
X ? R.getOperand(1)
1105 (!Def->getOperand(0)->hasMoreThanOneUniqueUser() ||
1106 !Def->getOperand(1)->hasMoreThanOneUniqueUser()))
1107 return Def->replaceAllUsesWith(
1111 return Def->replaceAllUsesWith(
X);
1116 Def->setOperand(0,
C);
1117 Def->setOperand(1,
Y);
1118 Def->setOperand(2,
X);
1127 X->hasMoreThanOneUniqueUser())
1128 return Def->replaceAllUsesWith(
1132 return Def->replaceAllUsesWith(
A);
1135 return Def->replaceAllUsesWith(R.getOperand(0) ==
A ? R.getOperand(1)
1140 return Def->replaceAllUsesWith(
A);
1145 auto *Cmp = cast<VPRecipeWithIRFlags>(
A);
1147 return match(U, m_CombineOr(m_Not(m_Specific(Cmp)),
1148 m_Select(m_Specific(Cmp), m_VPValue(),
1153 auto *R = cast<VPSingleDefRecipe>(U);
1156 R->setOperand(1,
Y);
1157 R->setOperand(2,
X);
1161 R->replaceAllUsesWith(Cmp);
1166 if (!Cmp->getDebugLoc() && R.getDebugLoc())
1167 Cmp->setDebugLoc(R.getDebugLoc());
1179 return Def->replaceAllUsesWith(Def->getOperand(1));
1181 if (
match(Def, m_VPInstruction<VPInstruction::WideIVStep>(
1186 Def->replaceAllUsesWith(
X);
1196 Def->setOperand(1, Def->getOperand(0));
1197 Def->setOperand(0,
Y);
1201 if (
auto *Phi = dyn_cast<VPFirstOrderRecurrencePHIRecipe>(Def)) {
1202 if (Phi->getOperand(0) == Phi->getOperand(1))
1203 Def->replaceAllUsesWith(Phi->getOperand(0));
1209 auto *BuildVector = cast<VPInstruction>(R.getOperand(0));
1210 Def->replaceAllUsesWith(
1211 BuildVector->getOperand(BuildVector->getNumOperands() - 1));
1216 if (
match(&R, m_VPInstruction<VPInstruction::ExtractPenultimateElement>(
1218 auto *BuildVector = cast<VPInstruction>(R.getOperand(0));
1219 Def->replaceAllUsesWith(
1220 BuildVector->getOperand(BuildVector->getNumOperands() - 2));
1224 if (
auto *Phi = dyn_cast<VPPhi>(Def)) {
1225 if (Phi->getNumOperands() == 1)
1226 Phi->replaceAllUsesWith(Phi->getOperand(0));
1236 if (
auto *VecPtr = dyn_cast<VPVectorPointerRecipe>(&R)) {
1237 if (VecPtr->isFirstPart()) {
1238 VecPtr->replaceAllUsesWith(VecPtr->getOperand(0));
1245 if (
auto *Steps = dyn_cast<VPScalarIVStepsRecipe>(Def)) {
1247 Steps->replaceAllUsesWith(Steps->getOperand(0));
1253 if (
match(Def, m_VPInstruction<VPInstruction::ReductionStartVector>(
1255 Def->replaceUsesWithIf(StartV, [](
const VPUser &U,
unsigned Idx) {
1256 auto *PhiR = dyn_cast<VPReductionPHIRecipe>(&U);
1257 return PhiR && PhiR->isInLoop();
1263 Def->replaceAllUsesWith(
A);
1270 Def->replaceAllUsesWith(OpVPI);
1279 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
1294 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
1297 if (!isa<VPWidenRecipe, VPWidenSelectRecipe, VPReplicateRecipe>(&R))
1299 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
1300 if (RepR && (RepR->isSingleScalar() || RepR->isPredicated()))
1303 auto *RepOrWidenR = cast<VPSingleDefRecipe>(&R);
1312 RepOrWidenR->operands(),
1314 Clone->insertBefore(RepOrWidenR);
1315 RepOrWidenR->replaceAllUsesWith(Clone);
1323 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
1326 auto *Blend = dyn_cast<VPBlendRecipe>(&R);
1332 if (Blend->isNormalized() || !
match(Blend->getMask(0),
m_False()))
1333 UniqueValues.
insert(Blend->getIncomingValue(0));
1334 for (
unsigned I = 1;
I != Blend->getNumIncomingValues(); ++
I)
1336 UniqueValues.
insert(Blend->getIncomingValue(
I));
1338 if (UniqueValues.
size() == 1) {
1339 Blend->replaceAllUsesWith(*UniqueValues.
begin());
1340 Blend->eraseFromParent();
1344 if (Blend->isNormalized())
1350 unsigned StartIndex = 0;
1351 for (
unsigned I = 0;
I != Blend->getNumIncomingValues(); ++
I) {
1356 if (Mask->getNumUsers() == 1 && !
match(Mask,
m_False())) {
1363 OperandsWithMask.
push_back(Blend->getIncomingValue(StartIndex));
1365 for (
unsigned I = 0;
I != Blend->getNumIncomingValues(); ++
I) {
1366 if (
I == StartIndex)
1368 OperandsWithMask.
push_back(Blend->getIncomingValue(
I));
1369 OperandsWithMask.
push_back(Blend->getMask(
I));
1373 new VPBlendRecipe(cast_or_null<PHINode>(Blend->getUnderlyingValue()),
1374 OperandsWithMask, Blend->getDebugLoc());
1375 NewBlend->insertBefore(&R);
1377 VPValue *DeadMask = Blend->getMask(StartIndex);
1379 Blend->eraseFromParent();
1384 if (NewBlend->getNumOperands() == 3 &&
1386 VPValue *Inc0 = NewBlend->getOperand(0);
1387 VPValue *Inc1 = NewBlend->getOperand(1);
1388 VPValue *OldMask = NewBlend->getOperand(2);
1389 NewBlend->setOperand(0, Inc1);
1390 NewBlend->setOperand(1, Inc0);
1391 NewBlend->setOperand(2, NewMask);
1393 cast<VPInstruction>(OldMask)->eraseFromParent();
1410 auto *TC = dyn_cast_if_present<ConstantInt>(
1421 APInt MaxVal = AlignedTC - 1;
1424 unsigned NewBitWidth =
1430 bool MadeChange =
false;
1434 auto *WideIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&Phi);
1439 if (!WideIV || !WideIV->isCanonical() ||
1440 WideIV->hasMoreThanOneUniqueUser() ||
1441 NewIVTy == WideIV->getScalarType())
1446 if (!
match(*WideIV->user_begin(),
1453 auto *NewStart = Plan.
getOrAddLiveIn(ConstantInt::get(NewIVTy, 0));
1454 WideIV->setStartValue(NewStart);
1455 auto *NewStep = Plan.
getOrAddLiveIn(ConstantInt::get(NewIVTy, 1));
1456 WideIV->setStepValue(NewStep);
1461 auto *Cmp = cast<VPInstruction>(*WideIV->user_begin());
1462 Cmp->setOperand(1, NewBTC);
1476 return any_of(
Cond->getDefiningRecipe()->operands(), [&Plan, BestVF, BestUF,
1478 return isConditionTrueViaVFAndUF(C, Plan, BestVF, BestUF, SE);
1491 const SCEV *VectorTripCount =
1493 if (isa<SCEVCouldNotCompute>(VectorTripCount))
1495 assert(!isa<SCEVCouldNotCompute>(VectorTripCount) &&
1496 "Trip count SCEV must be computable");
1516 auto *Term = &ExitingVPBB->
back();
1523 auto *Header = cast<VPBasicBlock>(VectorRegion->
getEntry());
1529 for (
unsigned Part = 0; Part < UF; ++Part) {
1536 Extracts[Part] = Ext;
1537 Ext->insertAfter(ALM);
1544 auto *Phi = dyn_cast<VPActiveLaneMaskPHIRecipe>(&R);
1548 match(Phi->getBackedgeValue(),
1550 assert(Index &&
"Expected index from ActiveLaneMask instruction");
1552 auto *
II = dyn_cast<VPInstruction>(Index);
1554 auto Part = cast<ConstantInt>(
II->getOperand(1)->getLiveInIRValue());
1555 Phis[Part->getZExtValue()] = Phi;
1562 "Expected one VPActiveLaneMaskPHIRecipe for each unroll part");
1564 auto *EntryALM = cast<VPInstruction>(Phis[0]->getStartValue());
1565 auto *LoopALM = cast<VPInstruction>(Phis[0]->getBackedgeValue());
1569 "Expected incoming values of Phi to be ActiveLaneMasks");
1575 EntryALM->setOperand(2, ALMMultiplier);
1576 LoopALM->setOperand(2, ALMMultiplier);
1580 ExtractFromALM(EntryALM, EntryExtracts);
1585 ExtractFromALM(LoopALM, LoopExtracts);
1586 VPInstruction *Not = cast<VPInstruction>(Term->getOperand(0));
1587 Not->setOperand(0, LoopExtracts[0]);
1590 for (
unsigned Part = 0; Part < UF; ++Part) {
1591 Phis[Part]->setStartValue(EntryExtracts[Part]);
1592 Phis[Part]->setBackedgeValue(LoopExtracts[Part]);
1605 auto *Term = &ExitingVPBB->
back();
1614 const SCEV *TripCount =
1616 assert(!isa<SCEVCouldNotCompute>(TripCount) &&
1617 "Trip count SCEV must be computable");
1620 if (TripCount->
isZero() ||
1638 auto *Header = cast<VPBasicBlock>(VectorRegion->
getEntry());
1640 if (auto *R = dyn_cast<VPWidenIntOrFpInductionRecipe>(&Phi))
1641 return R->isCanonical();
1642 return isa<VPCanonicalIVPHIRecipe, VPEVLBasedIVPHIRecipe,
1643 VPFirstOrderRecurrencePHIRecipe, VPPhi>(&Phi);
1646 if (
auto *R = dyn_cast<VPWidenIntOrFpInductionRecipe>(&HeaderR)) {
1649 R->getScalarType());
1651 HeaderR.eraseFromParent();
1654 auto *Phi = cast<VPPhiAccessors>(&HeaderR);
1655 HeaderR.getVPSingleValue()->replaceAllUsesWith(Phi->getIncomingValue(0));
1656 HeaderR.eraseFromParent();
1665 B->setParent(
nullptr);
1674 Term->getDebugLoc());
1678 Term->eraseFromParent();
1686 assert(Plan.
hasVF(BestVF) &&
"BestVF is not available in Plan");
1687 assert(Plan.
hasUF(BestUF) &&
"BestUF is not available in Plan");
1695 assert(Plan.
getUF() == BestUF &&
"BestUF must match the Plan's UF");
1713 auto TryToPushSinkCandidate = [&](
VPRecipeBase *SinkCandidate) {
1716 if (SinkCandidate == Previous)
1719 if (isa<VPHeaderPHIRecipe>(SinkCandidate) ||
1720 !Seen.
insert(SinkCandidate).second ||
1724 if (SinkCandidate->mayHaveSideEffects())
1733 for (
unsigned I = 0;
I != WorkList.
size(); ++
I) {
1736 "only recipes with a single defined value expected");
1739 if (!TryToPushSinkCandidate(cast<VPRecipeBase>(
User)))
1751 if (SinkCandidate == FOR)
1754 SinkCandidate->moveAfter(Previous);
1755 Previous = SinkCandidate;
1773 for (
VPUser *U : FOR->users()) {
1774 auto *R = cast<VPRecipeBase>(U);
1779 [&VPDT, HoistPoint](
VPUser *U) {
1780 auto *R = cast<VPRecipeBase>(U);
1781 return HoistPoint == R ||
1782 VPDT.properlyDominates(HoistPoint, R);
1784 "HoistPoint must dominate all users of FOR");
1786 auto NeedsHoisting = [HoistPoint, &VPDT,
1788 VPRecipeBase *HoistCandidate = HoistCandidateV->getDefiningRecipe();
1789 if (!HoistCandidate)
1795 "CFG in VPlan should still be flat, without replicate regions");
1797 if (!Visited.
insert(HoistCandidate).second)
1802 if (!EnclosingLoopRegion || isa<VPHeaderPHIRecipe>(HoistCandidate))
1809 return HoistCandidate;
1823 for (
unsigned I = 0;
I != HoistCandidates.
size(); ++
I) {
1826 "only recipes with a single defined value expected");
1827 if (!CanHoist(Current))
1838 if (
auto *R = NeedsHoisting(
Op))
1850 HoistCandidate->moveBefore(*HoistPoint->
getParent(),
1865 if (
auto *FOR = dyn_cast<VPFirstOrderRecurrencePHIRecipe>(&R))
1870 VPRecipeBase *Previous = FOR->getBackedgeValue()->getDefiningRecipe();
1873 while (
auto *PrevPhi =
1874 dyn_cast_or_null<VPFirstOrderRecurrencePHIRecipe>(Previous)) {
1875 assert(PrevPhi->getParent() == FOR->getParent());
1877 Previous = PrevPhi->getBackedgeValue()->getDefiningRecipe();
1887 if (isa<VPHeaderPHIRecipe>(Previous))
1895 {FOR, FOR->getBackedgeValue()});
1897 FOR->replaceAllUsesWith(RecurSplice);
1900 RecurSplice->setOperand(0, FOR);
1908 auto *PhiR = dyn_cast<VPReductionPHIRecipe>(&R);
1911 RecurKind RK = PhiR->getRecurrenceKind();
1917 if (
auto *RecWithFlags = dyn_cast<VPRecipeWithIRFlags>(U)) {
1918 RecWithFlags->dropPoisonGeneratingFlags();
1924struct VPCSEDenseMapInfo :
public DenseMapInfo<VPSingleDefRecipe *> {
1926 return Def == getEmptyKey() || Def == getTombstoneKey();
1932 static std::optional<std::pair<bool, unsigned>>
1935 std::optional<std::pair<bool, unsigned>>>(R)
1938 [](
auto *
I) {
return std::make_pair(
false,
I->getOpcode()); })
1939 .Case<VPWidenIntrinsicRecipe>([](
auto *
I) {
1940 return std::make_pair(
true,
I->getVectorIntrinsicID());
1942 .
Default([](
auto *) {
return std::nullopt; });
1950 auto C = getOpcodeOrIntrinsicID(Def);
1955 if (!
C || (!
C->first && (
C->second == Instruction::InsertValue ||
1956 C->second == Instruction::ExtractValue)))
1962 return !
Def->mayReadFromMemory();
1967 const VPlan *Plan =
Def->getParent()->getPlan();
1970 Def->getVPDefID(), getOpcodeOrIntrinsicID(Def),
1973 if (
auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(Def))
1974 if (RFlags->hasPredicate())
1983 if (
L->getVPDefID() !=
R->getVPDefID() ||
1984 getOpcodeOrIntrinsicID(L) != getOpcodeOrIntrinsicID(R) ||
1986 !
equal(
L->operands(),
R->operands()))
1988 if (
auto *LFlags = dyn_cast<VPRecipeWithIRFlags>(L))
1989 if (LFlags->hasPredicate() &&
1990 LFlags->getPredicate() !=
1991 cast<VPRecipeWithIRFlags>(R)->getPredicate())
1993 const VPlan *Plan =
L->getParent()->getPlan();
1995 return TypeInfo.inferScalarType(L) == TypeInfo.inferScalarType(R);
2006 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
2009 auto *Def = dyn_cast<VPSingleDefRecipe>(&R);
2010 if (!Def || !VPCSEDenseMapInfo::canHandle(Def))
2014 if (!VPDT.
dominates(V->getParent(), VPBB))
2017 if (
auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(V))
2018 RFlags->dropPoisonGeneratingFlags();
2019 Def->replaceAllUsesWith(V);
2036 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
2037 return RepR && RepR->getOpcode() == Instruction::Alloca;
2044 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
2047 if (CannotHoistRecipe(R))
2051 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi() ||
2053 return !Op->isDefinedOutsideLoopRegions();
2056 R.moveBefore(*Preheader, Preheader->
end());
2070 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
2078 VPValue *ResultVPV = R.getVPSingleValue();
2080 unsigned NewResSizeInBits = MinBWs.
lookup(UI);
2081 if (!NewResSizeInBits)
2088 if (isa<VPReplicateRecipe, VPWidenCastRecipe>(&R))
2094 (void)OldResSizeInBits;
2101 if (
auto *VPW = dyn_cast<VPRecipeWithIRFlags>(&R))
2102 VPW->dropPoisonGeneratingFlags();
2104 if (OldResSizeInBits != NewResSizeInBits &&
2109 Ext->insertAfter(&R);
2111 Ext->setOperand(0, ResultVPV);
2112 assert(OldResSizeInBits > NewResSizeInBits &&
"Nothing to shrink?");
2115 "Only ICmps should not need extending the result.");
2118 assert(!isa<VPWidenStoreRecipe>(&R) &&
"stores cannot be narrowed");
2119 if (isa<VPWidenLoadRecipe, VPWidenIntrinsicRecipe>(&R))
2123 unsigned StartIdx = isa<VPWidenSelectRecipe>(&R) ? 1 : 0;
2124 for (
unsigned Idx = StartIdx;
Idx != R.getNumOperands(); ++
Idx) {
2125 auto *
Op = R.getOperand(
Idx);
2126 unsigned OpSizeInBits =
2128 if (OpSizeInBits == NewResSizeInBits)
2130 assert(OpSizeInBits > NewResSizeInBits &&
"nothing to truncate");
2131 auto [ProcessedIter, IterIsEmpty] = ProcessedTruncs.
try_emplace(
Op);
2135 : ProcessedIter->second;
2136 R.setOperand(
Idx, NewOp);
2139 ProcessedIter->second = NewOp;
2140 if (!
Op->isLiveIn()) {
2152 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
2155 if (VPBB->getNumSuccessors() != 2 || VPBB == Plan.
getEntry() ||
2159 unsigned RemovedIdx;
2168 cast<VPBasicBlock>(VPBB->getSuccessors()[RemovedIdx]);
2170 "There must be a single edge between VPBB and its successor");
2174 cast<VPPhiAccessors>(&R)->removeIncomingValueFor(VPBB);
2179 VPBB->back().eraseFromParent();
2240 VPValue *StartV = CanonicalIVPHI->getStartValue();
2242 auto *CanonicalIVIncrement =
2243 cast<VPInstruction>(CanonicalIVPHI->getBackedgeValue());
2246 CanonicalIVIncrement->dropPoisonGeneratingFlags();
2247 DebugLoc DL = CanonicalIVIncrement->getDebugLoc();
2257 VPValue *TripCount, *IncrementValue;
2262 IncrementValue = CanonicalIVIncrement;
2268 IncrementValue = CanonicalIVPHI;
2280 {EntryIncrement, TC, ALMMultiplier},
DL,
2281 "active.lane.mask.entry");
2286 LaneMaskPhi->insertAfter(CanonicalIVPHI);
2292 auto *InLoopIncrement =
2294 {IncrementValue}, {
false,
false},
DL);
2296 {InLoopIncrement, TripCount, ALMMultiplier},
2297 DL,
"active.lane.mask.next");
2315 IsaPred<VPWidenCanonicalIVRecipe>);
2317 IsaPred<VPWidenCanonicalIVRecipe>) <= 1 &&
2318 "Must have at most one VPWideCanonicalIVRecipe");
2320 auto *WideCanonicalIV =
2321 cast<VPWidenCanonicalIVRecipe>(*FoundWidenCanonicalIVUser);
2322 WideCanonicalIVs.
push_back(WideCanonicalIV);
2329 auto *WidenOriginalIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&Phi);
2330 if (WidenOriginalIV && WidenOriginalIV->isCanonical())
2331 WideCanonicalIVs.
push_back(WidenOriginalIV);
2337 for (
auto *Wide : WideCanonicalIVs) {
2339 auto *VPI = dyn_cast<VPInstruction>(U);
2343 assert(VPI->getOperand(0) == Wide &&
2344 "WidenCanonicalIV must be the first operand of the compare");
2345 assert(!HeaderMask &&
"Multiple header masks found?");
2353 VPlan &Plan,
bool UseActiveLaneMaskForControlFlow,
2356 UseActiveLaneMaskForControlFlow) &&
2357 "DataAndControlFlowWithoutRuntimeCheck implies "
2358 "UseActiveLaneMaskForControlFlow");
2361 IsaPred<VPWidenCanonicalIVRecipe>);
2362 assert(FoundWidenCanonicalIVUser &&
2363 "Must have widened canonical IV when tail folding!");
2365 auto *WideCanonicalIV =
2366 cast<VPWidenCanonicalIVRecipe>(*FoundWidenCanonicalIVUser);
2368 if (UseActiveLaneMaskForControlFlow) {
2378 nullptr,
"active.lane.mask");
2404 assert(OrigMask &&
"Unmasked recipe when folding tail");
2409 return HeaderMask == OrigMask ? nullptr : OrigMask;
2414 auto *EndPtr = dyn_cast<VPVectorEndPointerRecipe>(
Addr);
2417 assert(EndPtr->getOperand(1) == &EndPtr->getParent()->getPlan()->getVF() &&
2418 "VPVectorEndPointerRecipe with non-VF VF operand?");
2422 return cast<VPWidenMemoryRecipe>(U)->isReverse();
2424 "VPVectorEndPointRecipe not used by reversed widened memory recipe?");
2433 VPValue *NewMask = GetNewMask(L->getMask());
2434 VPValue *NewAddr = GetNewAddr(L->getAddr());
2443 VPValue *NewMask = GetNewMask(
IR->getMask());
2447 VPValue *NewMask = GetNewMask(Red->getCondOp());
2462 Intrinsic::vp_merge, {&AllOneMask,
LHS,
RHS, &EVL},
2478 "User of VF that we can't transform to EVL.");
2480 return isa<VPWidenIntOrFpInductionRecipe, VPScalarIVStepsRecipe>(U);
2485 return match(U, m_c_Add(m_Specific(Plan.getCanonicalIV()),
2486 m_Specific(&Plan.getVFxUF()))) ||
2487 isa<VPWidenPointerInductionRecipe>(U);
2489 "Only users of VFxUF should be VPWidenPointerInductionRecipe and the "
2490 "increment of the canonical induction.");
2494 return isa<VPWidenPointerInductionRecipe>(U);
2504 any_of(Header->phis(), IsaPred<VPFirstOrderRecurrencePHIRecipe>);
2518 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
2523 m_VPInstruction<VPInstruction::FirstOrderRecurrenceSplice>(
2529 Intrinsic::experimental_vp_splice,
2530 {V1, V2, Imm, AllOneMask, PrevEVL, &EVL},
2533 R.getVPSingleValue()->replaceAllUsesWith(VPSplice);
2562 auto *CurRecipe = cast<VPRecipeBase>(U);
2569 assert(NumDefVal == CurRecipe->getNumDefinedValues() &&
2570 "New recipe must define the same number of values as the "
2573 if (isa<VPSingleDefRecipe, VPWidenLoadEVLRecipe, VPInterleaveEVLRecipe>(
2575 for (
unsigned I = 0;
I < NumDefVal; ++
I) {
2576 VPValue *CurVPV = CurRecipe->getVPValue(
I);
2588 R->eraseFromParent();
2638 VPlan &Plan,
const std::optional<unsigned> &MaxSafeElements) {
2643 VPValue *StartV = CanonicalIVPHI->getStartValue();
2647 EVLPhi->insertAfter(CanonicalIVPHI);
2648 VPBuilder Builder(Header, Header->getFirstNonPhi());
2655 if (MaxSafeElements) {
2658 Plan.
getOrAddLiveIn(ConstantInt::get(CanIVTy, *MaxSafeElements));
2665 auto *CanonicalIVIncrement =
2666 cast<VPInstruction>(CanonicalIVPHI->getBackedgeValue());
2672 OpVPEVL, CanIVTy, I32Ty, CanonicalIVIncrement->getDebugLoc());
2675 Instruction::Add, {OpVPEVL, EVLPhi},
2676 {CanonicalIVIncrement->hasNoUnsignedWrap(),
2677 CanonicalIVIncrement->hasNoSignedWrap()},
2678 CanonicalIVIncrement->getDebugLoc(),
"index.evl.next");
2682 Instruction::Sub, {AVLPhi, OpVPEVL}, {
true,
false},
2690 CanonicalIVPHI->replaceAllUsesWith(EVLPhi);
2691 CanonicalIVIncrement->setOperand(0, CanonicalIVPHI);
2701 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
2704 if (
auto *PhiR = dyn_cast<VPEVLBasedIVPHIRecipe>(&R)) {
2705 assert(!EVLPhi &&
"Found multiple EVL PHIs. Only one expected");
2716 [[maybe_unused]]
bool FoundAVL =
2719 assert(FoundAVL &&
"Didn't find AVL?");
2727 [[maybe_unused]]
bool FoundAVLNext =
2728 match(AVL, m_VPInstruction<Instruction::PHI>(
2730 assert(FoundAVLNext &&
"Didn't find AVL backedge?");
2740 auto *CanonicalIV = cast<VPPhi>(&*HeaderVPBB->
begin());
2741 VPValue *Backedge = CanonicalIV->getIncomingValue(1);
2744 "Unexpected canonical iv");
2750 CanonicalIV->eraseFromParent();
2758 auto *LatchExitingBr = cast<VPInstruction>(LatchExiting->
getTerminator());
2763 match(LatchExitingBr,
2766 "Unexpected terminator in EVL loop");
2783 auto *R = cast<VPRecipeBase>(&U);
2784 return R->getParent()->getParent() ||
2787 for (
const SCEV *Stride : StridesMap.
values()) {
2788 using namespace SCEVPatternMatch;
2789 auto *StrideV = cast<SCEVUnknown>(Stride)->getValue();
2790 const APInt *StrideConst;
2791 if (!
match(PSE.
getSCEV(StrideV), m_scev_APInt(StrideConst)))
2796 Plan.
getOrAddLiveIn(ConstantInt::get(Stride->getType(), *StrideConst));
2802 for (
Value *U : StrideV->users()) {
2803 if (!isa<SExtInst, ZExtInst>(U))
2808 unsigned BW = U->getType()->getScalarSizeInBits();
2810 isa<SExtInst>(U) ? StrideConst->
sext(BW) : StrideConst->
zext(BW);
2819 const std::function<
bool(
BasicBlock *)> &BlockNeedsPredication) {
2823 auto CollectPoisonGeneratingInstrsInBackwardSlice([&](
VPRecipeBase *Root) {
2828 while (!Worklist.
empty()) {
2829 VPRecipeBase *CurRec = Worklist.pop_back_val();
2831 if (!Visited.insert(CurRec).second)
2838 if (isa<VPWidenMemoryRecipe, VPInterleaveRecipe, VPScalarIVStepsRecipe,
2839 VPHeaderPHIRecipe>(CurRec))
2845 if (auto *RecWithFlags = dyn_cast<VPRecipeWithIRFlags>(CurRec)) {
2852 if (match(RecWithFlags, m_BinaryOr(m_VPValue(A), m_VPValue(B))) &&
2853 RecWithFlags->isDisjoint()) {
2854 VPBuilder Builder(RecWithFlags);
2855 VPInstruction *New = Builder.createOverflowingOp(
2856 Instruction::Add, {A, B}, {false, false},
2857 RecWithFlags->getDebugLoc());
2858 New->setUnderlyingValue(RecWithFlags->getUnderlyingValue());
2859 RecWithFlags->replaceAllUsesWith(New);
2860 RecWithFlags->eraseFromParent();
2863 RecWithFlags->dropPoisonGeneratingFlags();
2865 Instruction *Instr = dyn_cast_or_null<Instruction>(
2866 CurRec->getVPSingleValue()->getUnderlyingValue());
2868 assert((!Instr || !Instr->hasPoisonGeneratingFlags()) &&
2869 "found instruction with poison generating flags not covered by "
2870 "VPRecipeWithIRFlags");
2884 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(Iter)) {
2886 if (
auto *WidenRec = dyn_cast<VPWidenMemoryRecipe>(&Recipe)) {
2887 Instruction &UnderlyingInstr = WidenRec->getIngredient();
2888 VPRecipeBase *AddrDef = WidenRec->getAddr()->getDefiningRecipe();
2889 if (AddrDef && WidenRec->isConsecutive() &&
2890 BlockNeedsPredication(UnderlyingInstr.
getParent()))
2891 CollectPoisonGeneratingInstrsInBackwardSlice(AddrDef);
2892 }
else if (
auto *InterleaveRec = dyn_cast<VPInterleaveRecipe>(&Recipe)) {
2893 VPRecipeBase *AddrDef = InterleaveRec->getAddr()->getDefiningRecipe();
2897 InterleaveRec->getInterleaveGroup();
2898 bool NeedPredication =
false;
2900 I < NumMembers; ++
I) {
2903 NeedPredication |= BlockNeedsPredication(Member->getParent());
2906 if (NeedPredication)
2907 CollectPoisonGeneratingInstrsInBackwardSlice(AddrDef);
2919 if (InterleaveGroups.empty())
2927 for (
const auto *IG : InterleaveGroups) {
2929 cast<VPWidenMemoryRecipe>(RecipeBuilder.
getRecipe(IG->getMember(0)));
2932 if (
auto *StoreR = dyn_cast<VPWidenStoreRecipe>(Start))
2933 StoredValues.
push_back(StoreR->getStoredValue());
2934 for (
unsigned I = 1;
I < IG->getFactor(); ++
I) {
2939 cast<VPWidenMemoryRecipe>(RecipeBuilder.
getRecipe(MemberI));
2940 if (
auto *StoreR = dyn_cast<VPWidenStoreRecipe>(MemoryR))
2941 StoredValues.
push_back(StoreR->getStoredValue());
2945 bool NeedsMaskForGaps =
2946 (IG->requiresScalarEpilogue() && !ScalarEpilogueAllowed) ||
2947 (!StoredValues.
empty() && !IG->isFull());
2951 cast<VPWidenMemoryRecipe>(RecipeBuilder.
getRecipe(IRInsertPos));
2954 if (
auto *Gep = dyn_cast<GetElementPtrInst>(
2968 assert(IG->getIndex(IRInsertPos) != 0 &&
2969 "index of insert position shouldn't be zero");
2973 IG->getIndex(IRInsertPos),
2978 Addr =
B.createNoWrapPtrAdd(InsertPos->getAddr(), OffsetVPV, NW);
2984 if (IG->isReverse()) {
2987 -(int64_t)IG->getFactor(), NW, InsertPos->getDebugLoc());
2988 ReversePtr->insertBefore(InsertPos);
2992 InsertPos->getMask(), NeedsMaskForGaps,
2993 InterleaveMD, InsertPos->getDebugLoc());
2994 VPIG->insertBefore(InsertPos);
2997 for (
unsigned i = 0; i < IG->getFactor(); ++i)
3000 if (!Member->getType()->isVoidTy()) {
3061 AddOp = Instruction::Add;
3062 MulOp = Instruction::Mul;
3064 AddOp =
ID.getInductionOpcode();
3065 MulOp = Instruction::FMul;
3066 Flags =
ID.getInductionBinOp()->getFastMathFlags();
3096 WidePHI->addOperand(
Init);
3097 WidePHI->insertBefore(WidenIVR);
3108 Builder.
setInsertPoint(R->getParent(), std::next(R->getIterator()));
3125 auto *Next = Builder.
createNaryOp(AddOp, {Prev, Inc}, Flags,
3156 VPlan *Plan = R->getParent()->getPlan();
3157 VPValue *Start = R->getStartValue();
3158 VPValue *Step = R->getStepValue();
3159 VPValue *VF = R->getVFValue();
3161 assert(R->getInductionDescriptor().getKind() ==
3163 "Not a pointer induction according to InductionDescriptor!");
3166 "Recipe should have been replaced");
3176 Builder.
setInsertPoint(R->getParent(), R->getParent()->getFirstNonPhi());
3182 R->replaceAllUsesWith(PtrAdd);
3199 for (
VPRegionBlock *R : VPBlockUtils::blocksOnly<VPRegionBlock>(
3201 if (!R->isReplicator())
3205 R->dissolveToCFGLoop();
3211 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
3214 if (
auto *WidenIVR = dyn_cast<VPWidenIntOrFpInductionRecipe>(&R)) {
3220 if (
auto *WidenIVR = dyn_cast<VPWidenPointerInductionRecipe>(&R)) {
3228 if (
auto *Blend = dyn_cast<VPBlendRecipe>(&R)) {
3230 for (
unsigned I = 1;
I != Blend->getNumIncomingValues(); ++
I)
3232 Blend->getIncomingValue(
I),
Select,
3233 R.getDebugLoc(),
"predphi");
3238 if (
auto *Expr = dyn_cast<VPExpressionRecipe>(&R)) {
3245 if (!
match(&R, m_VPInstruction<VPInstruction::WideIVStep>(
3250 auto *VPI = cast<VPInstruction>(&R);
3254 ? Instruction::UIToFP
3255 : Instruction::Trunc;
3259 [[maybe_unused]]
auto *ConstStep =
3263 assert(!ConstStep || ConstStep->getValue() != 1);
3272 Flags = {VPI->getFastMathFlags()};
3277 MulOpc, {VectorStep, ScalarStep}, Flags, R.getDebugLoc());
3279 VPI->replaceAllUsesWith(VectorStep);
3285 R->eraseFromParent();
3298 "unsupported early exit VPBB");
3303 cast<VPIRPhi>(&R)->swapOperands();
3310 "Terminator must be be BranchOnCond");
3311 VPValue *CondOfEarlyExitingVPBB =
3313 auto *CondToEarlyExit = TrueSucc == EarlyExitVPBB
3314 ? CondOfEarlyExitingVPBB
3315 : Builder.
createNot(CondOfEarlyExitingVPBB);
3332 VPBuilder EarlyExitB(VectorEarlyExitVPBB);
3334 auto *ExitIRI = cast<VPIRPhi>(&R);
3337 unsigned EarlyExitIdx = ExitIRI->getNumOperands() - 1;
3338 if (ExitIRI->getNumOperands() != 1) {
3341 ExitIRI->extractLastLaneOfFirstOperand(MiddleBuilder);
3344 VPValue *IncomingFromEarlyExit = ExitIRI->getOperand(EarlyExitIdx);
3345 if (!IncomingFromEarlyExit->
isLiveIn()) {
3349 "first.active.lane");
3352 nullptr,
"early.exit.value");
3353 ExitIRI->
setOperand(EarlyExitIdx, IncomingFromEarlyExit);
3361 auto *LatchExitingBranch = cast<VPInstruction>(LatchVPBB->
getTerminator());
3363 "Unexpected terminator");
3364 auto *IsLatchExitTaken =
3366 LatchExitingBranch->getOperand(1));
3368 Instruction::Or, {IsEarlyExitTaken, IsLatchExitTaken});
3381 VPValue *VecOp = Red->getVecOp();
3384 auto IsExtendedRedValidAndClampRange = [&](
unsigned Opcode,
bool isZExt,
3385 Type *SrcTy) ->
bool {
3388 auto *SrcVecTy = cast<VectorType>(
toVectorTy(SrcTy, VF));
3391 Opcode, isZExt, RedTy, SrcVecTy, Red->getFastMathFlags(),
3394 cast<VPWidenCastRecipe>(VecOp)->computeCost(VF, Ctx);
3396 return ExtRedCost.
isValid() && ExtRedCost < ExtCost + RedCost;
3404 IsExtendedRedValidAndClampRange(
3406 cast<VPWidenCastRecipe>(VecOp)->getOpcode() ==
3407 Instruction::CastOps::ZExt,
3426 if (Opcode != Instruction::Add && Opcode != Instruction::Sub)
3432 auto IsMulAccValidAndClampRange =
3440 auto *SrcVecTy = cast<VectorType>(
toVectorTy(SrcTy, VF));
3442 isZExt, Opcode, RedTy, SrcVecTy,
CostKind);
3447 ExtCost += Ext0->computeCost(VF, Ctx);
3449 ExtCost += Ext1->computeCost(VF, Ctx);
3451 ExtCost += OuterExt->computeCost(VF, Ctx);
3453 return MulAccCost.
isValid() &&
3454 MulAccCost < ExtCost + MulCost + RedCost;
3459 VPValue *VecOp = Red->getVecOp();
3464 dyn_cast_if_present<VPWidenCastRecipe>(
A->getDefiningRecipe());
3466 dyn_cast_if_present<VPWidenCastRecipe>(
B->getDefiningRecipe());
3470 if (RecipeA && RecipeB &&
3471 (RecipeA->getOpcode() == RecipeB->getOpcode() ||
A ==
B) &&
3474 IsMulAccValidAndClampRange(RecipeA->getOpcode() ==
3475 Instruction::CastOps::ZExt,
3476 Mul, RecipeA, RecipeB,
nullptr)) {
3480 if (IsMulAccValidAndClampRange(
true,
Mul,
nullptr,
nullptr,
nullptr))
3489 auto *
Mul = cast<VPWidenRecipe>(Ext->getOperand(0)->getDefiningRecipe());
3491 cast<VPWidenCastRecipe>(
Mul->getOperand(0)->getDefiningRecipe());
3493 cast<VPWidenCastRecipe>(
Mul->getOperand(1)->getDefiningRecipe());
3494 if ((Ext->getOpcode() == Ext0->getOpcode() || Ext0 == Ext1) &&
3495 Ext0->getOpcode() == Ext1->getOpcode() &&
3496 IsMulAccValidAndClampRange(Ext0->getOpcode() ==
3497 Instruction::CastOps::ZExt,
3498 Mul, Ext0, Ext1, Ext)) {
3500 Ext0->getOpcode(), Ext0->getOperand(0), Ext->getResultType(), *Ext0,
3501 Ext0->getDebugLoc());
3502 NewExt0->insertBefore(Ext0);
3507 Ext->getResultType(), *Ext1,
3508 Ext1->getDebugLoc());
3511 Mul->setOperand(0, NewExt0);
3512 Mul->setOperand(1, NewExt1);
3513 Red->setOperand(1,
Mul);
3526 auto IP = std::next(Red->getIterator());
3527 auto *VPBB = Red->getParent();
3537 Red->replaceAllUsesWith(AbstractR);
3542 for (
VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
3545 if (
auto *Red = dyn_cast<VPReductionRecipe>(&R))
3568 for (
VPValue *VPV : VPValues) {
3570 (VPV->isLiveIn() && VPV->getLiveInIRValue() &&
3571 isa<Constant>(VPV->getLiveInIRValue())))
3578 if (
User->usesScalars(VPV))
3580 if (cast<VPRecipeBase>(
User)->
getParent() == VectorPreheader)
3581 HoistPoint = HoistBlock->
begin();
3584 cast<VPRecipeBase>(
User)->getParent()) &&
3585 "All users must be in the vector preheader or dominated by it");
3588 VPBuilder Builder(cast<VPBasicBlock>(HoistBlock), HoistPoint);
3591 [VPV, Broadcast](
VPUser &U,
unsigned Idx) {
3592 return Broadcast != &U && !U.usesScalars(VPV);
3600 assert(Plan.
hasVF(BestVF) &&
"BestVF is not available in Plan");
3601 assert(Plan.
hasUF(BestUF) &&
"BestUF is not available in Plan");
3619 if (!isa<SCEVConstant>(TCScev))
3623 if (
auto *ConstVecTC = dyn_cast<SCEVConstant>(VecTCScev))
3648 auto VPBBsOutsideLoopRegion = VPBlockUtils::blocksOnly<VPBasicBlock>(
3650 auto VPBBsInsideLoopRegion = VPBlockUtils::blocksOnly<VPBasicBlock>(
3660 concat<VPBasicBlock *>(VPBBsOutsideLoopRegion, VPBBsInsideLoopRegion)) {
3662 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
3663 auto UsesVectorOrInsideReplicateRegion = [RepR, LoopRegion](
VPUser *U) {
3666 return !U->usesScalars(RepR) || ParentRegion != LoopRegion;
3668 if (!RepR || RepR->isSingleScalar() ||
3669 none_of(RepR->users(), UsesVectorOrInsideReplicateRegion))
3679 RepR->replaceUsesWithIf(
3680 BuildVector, [BuildVector, &UsesVectorOrInsideReplicateRegion](
3682 return &U != BuildVector && UsesVectorOrInsideReplicateRegion(&U);
3691 bool RequiresScalarEpilogue) {
3693 assert(VectorTC.
isLiveIn() &&
"vector-trip-count must be a live-in");
3712 if (TailByMasking) {
3736 if (RequiresScalarEpilogue) {
3738 "requiring scalar epilogue is not supported with fail folding");
3774 BC, [&VF](
VPUser &U,
unsigned) {
return !U.usesScalars(&VF); });
3788 auto *Entry = cast<VPIRBasicBlock>(Plan.
getEntry());
3789 BasicBlock *EntryBB = Entry->getIRBasicBlock();
3792 if (isa<VPIRInstruction, VPIRPhi>(&R))
3794 auto *ExpSCEV = dyn_cast<VPExpandSCEVRecipe>(&R);
3797 const SCEV *Expr = ExpSCEV->getSCEV();
3800 ExpandedSCEVs[ExpSCEV->getSCEV()] = Res;
3805 ExpSCEV->eraseFromParent();
3808 "VPExpandSCEVRecipes must be at the beginning of the entry block, "
3809 "after any VPIRInstructions");
3812 auto EI = Entry->begin();
3814 if (EI != Entry->end() && isa<VPIRInstruction>(*EI) &&
3815 &cast<VPIRInstruction>(&*EI)->getInstruction() == &
I) {
3822 return ExpandedSCEVs;
3838 if (
auto *W = dyn_cast<VPWidenLoadRecipe>(DefR))
3841 if (
auto *
IR = dyn_cast<VPInterleaveRecipe>(DefR))
3842 return IR->getInterleaveGroup()->isFull() &&
IR->getVPValue(
Idx) == OpV;
3851 unsigned VectorRegWidth) {
3855 Type *GroupElementTy =
nullptr;
3859 [&TypeInfo, GroupElementTy](
VPValue *
Op) {
3860 return TypeInfo.inferScalarType(Op) == GroupElementTy;
3867 [&TypeInfo, GroupElementTy](
VPValue *
Op) {
3868 return TypeInfo.inferScalarType(Op) == GroupElementTy;
3875 return IG->getFactor() == VF && IG->getNumMembers() == VF &&
3876 GroupSize == VectorRegWidth;
3883 auto *RepR = dyn_cast<VPReplicateRecipe>(VPV);
3884 return RepR && RepR->isSingleScalar();
3888 unsigned VectorRegWidth) {
3898 if (isa<VPCanonicalIVPHIRecipe>(&R) ||
3902 if (isa<VPDerivedIVRecipe, VPScalarIVStepsRecipe>(&R) &&
3913 auto *InterleaveR = dyn_cast<VPInterleaveRecipe>(&R);
3914 if (R.mayWriteToMemory() && !InterleaveR)
3922 if (isa<VPVectorPointerRecipe>(&R) && Plan.
getUF() > 1)
3936 if (InterleaveR->getStoredValues().empty())
3941 auto *Member0 = InterleaveR->getStoredValues()[0];
3943 all_of(InterleaveR->getStoredValues(),
3944 [Member0](
VPValue *VPV) { return Member0 == VPV; })) {
3952 VPRecipeBase *DefR = Op.value()->getDefiningRecipe();
3955 auto *IR = dyn_cast<VPInterleaveRecipe>(DefR);
3956 return IR && IR->getInterleaveGroup()->isFull() &&
3957 IR->getVPValue(Op.index()) == Op.value();
3965 auto *WideMember0 = dyn_cast_or_null<VPWidenRecipe>(
3966 InterleaveR->getStoredValues()[0]->getDefiningRecipe());
3969 for (
const auto &[
I, V] :
enumerate(InterleaveR->getStoredValues())) {
3970 auto *R = dyn_cast_or_null<VPWidenRecipe>(V->getDefiningRecipe());
3971 if (!R || R->getOpcode() != WideMember0->getOpcode() ||
3972 R->getNumOperands() > 2)
3975 [WideMember0,
Idx =
I](
const auto &
P) {
3976 const auto &[OpIdx, OpV] = P;
3977 return !canNarrowLoad(WideMember0, OpIdx, OpV, Idx);
3984 if (StoreGroups.
empty())
3989 auto *R = V->getDefiningRecipe();
3992 if (
auto *LoadGroup = dyn_cast<VPInterleaveRecipe>(R)) {
3996 *cast<LoadInst>(LoadGroup->getInterleaveGroup()->getInsertPos()),
3997 LoadGroup->getAddr(), LoadGroup->getMask(),
true,
3998 false, {}, LoadGroup->getDebugLoc());
3999 L->insertBefore(LoadGroup);
4003 if (
auto *RepR = dyn_cast<VPReplicateRecipe>(R)) {
4004 assert(RepR->isSingleScalar() &&
4005 isa<LoadInst>(RepR->getUnderlyingInstr()) &&
4006 "must be a single scalar load");
4009 auto *WideLoad = cast<VPWidenLoadRecipe>(R);
4011 VPValue *PtrOp = WideLoad->getAddr();
4012 if (
auto *VecPtr = dyn_cast<VPVectorPointerRecipe>(PtrOp))
4013 PtrOp = VecPtr->getOperand(0);
4018 nullptr, *WideLoad);
4019 N->insertBefore(WideLoad);
4024 for (
auto *StoreGroup : StoreGroups) {
4026 VPValue *Member0 = StoreGroup->getStoredValues()[0];
4029 }
else if (
auto *WideMember0 =
4031 for (
unsigned Idx = 0, E = WideMember0->getNumOperands();
Idx != E; ++
Idx)
4032 WideMember0->setOperand(
Idx, NarrowOp(WideMember0->getOperand(
Idx)));
4035 Res = NarrowOp(Member0);
4039 *cast<StoreInst>(StoreGroup->getInterleaveGroup()->getInsertPos()),
4040 StoreGroup->getAddr(), Res,
nullptr,
true,
4041 false, {}, StoreGroup->getDebugLoc());
4042 S->insertBefore(StoreGroup);
4043 StoreGroup->eraseFromParent();
4049 auto *Inc = cast<VPInstruction>(CanIV->getBackedgeValue());
4053 ConstantInt::get(CanIV->getScalarType(), 1 * Plan.
getUF()));
4061 Inc->setOperand(1, UF);
4063 Plan.
getOrAddLiveIn(ConstantInt::get(CanIV->getScalarType(), 1)));
4074 dyn_cast_or_null<VPInstruction>(MiddleVPBB->
getTerminator());
4080 "must have a BranchOnCond");
4083 if (VF.
isScalable() && VScaleForTuning.has_value())
4084 VectorStep *= *VScaleForTuning;
4085 assert(VectorStep > 0 &&
"trip count should not be zero");
4089 MiddleTerm->addMetadata(LLVMContext::MD_prof, BranchWeights);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefAnalysis InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool isEqual(const Function &Caller, const Function &Callee)
static const Function * getParent(const Value *V)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
static bool isSentinel(const DWARFDebugNames::AttributeEncoding &AE)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
iv Induction Variable Users
Legalize the Machine IR a function s Machine IR
static bool mergeBlocksIntoPredecessors(Loop &L, DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU, ScalarEvolution &SE)
mir Rename Register Operands
MachineInstr unsigned OpIdx
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > & Cond
This file implements a set that has insertion order iteration characteristics.
static SymbolRef::Type getType(const Symbol *Sym)
This file implements the TypeSwitch template, which mimics a switch() statement whose cases are type ...
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 declares the class VPlanVerifier, which contains utility functions to check the consistency...
This file contains the declarations of the Vectorization Plan base classes:
static const uint32_t IV[8]
Class for arbitrary precision integers.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
unsigned getActiveBits() const
Compute the number of active bits in the value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
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...
This class represents a function call, abstracting a target machine's calling convention.
@ ICMP_ULT
unsigned less than
@ ICMP_ULE
unsigned less or equal
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
static DebugLoc getCompilerGenerated()
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...
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
constexpr bool isVector() const
One or more elements.
static constexpr ElementCount getScalable(ScalarTy MinVal)
Utility class for floating point operations which can have information about relaxed accuracy require...
Represents flags for the getelementptr instruction/expression.
GEPNoWrapFlags withoutNoUnsignedWrap() const
static GEPNoWrapFlags none()
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
A struct for saving information about induction variables.
InductionKind
This enum represents the kinds of inductions that we support.
@ IK_PtrInduction
Pointer induction var. Step = C.
@ IK_IntInduction
Integer induction variable. Step = C.
InstSimplifyFolder - Use InstructionSimplify to fold operations to existing values.
Value * FoldGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, GEPNoWrapFlags NW) const override
Value * FoldBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS) const override
Value * FoldSelect(Value *C, Value *True, Value *False) const override
Value * FoldCast(Instruction::CastOps Op, Value *V, Type *DestTy) const override
Value * FoldCmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
The group of interleaved loads/stores sharing the same stride and close to each other.
InstTy * getMember(uint32_t Index) const
Get the member with the given index Index.
uint32_t getNumMembers() const
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
static bool getDecisionAndClampRange(const std::function< bool(ElementCount)> &Predicate, VFRange &Range)
Test a Predicate on a Range of VF's.
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
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 * getSCEV(Value *V)
Returns the SCEV expression of V, in the context of the current SCEV predicate.
unsigned getOpcode() const
RegionT * getParent() const
Get the parent of the Region.
This class uses information about analyze scalars to rewrite expressions in canonical form.
LLVM_ABI Value * expandCodeFor(const SCEV *SH, Type *Ty, BasicBlock::iterator I)
Insert code to directly compute the specified SCEV expression into the program.
This class represents an analyzed expression in the program.
LLVM_ABI bool isZero() const
Return true if the expression is a constant zero.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
const DataLayout & getDataLayout() const
Return the DataLayout associated with the module this SCEV instance is operating on.
LLVM_ABI const SCEV * getNegativeSCEV(const SCEV *V, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
Return the SCEV object corresponding to -V.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getUDivExpr(const SCEV *LHS, const SCEV *RHS)
Get a canonical unsigned division expression, or something simpler if possible.
LLVM_ABI const SCEV * getElementCount(Type *Ty, ElementCount EC, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
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,...
This class represents the LLVM 'select' instruction.
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Provides information about what library functions are available for the current target.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionalit...
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
bool isPointerTy() const
True if this is an instance of PointerType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
bool isStructTy() const
True if this is an instance of StructType.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A recipe for generating the active lane mask for the vector loop that is used to predicate the vector...
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.
VPRegionBlock * getEnclosingLoopRegion()
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
A recipe for vectorizing a phi-node as a sequence of mask-based select instructions.
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
VPRegionBlock * getParent()
const VPBasicBlock * getExitingBasicBlock() const
void swapSuccessors()
Swap successors of the block. The block must have exactly 2 successors.
size_t getNumPredecessors() const
const VPBlocksTy & getPredecessors() const
VPBlockBase * getSinglePredecessor() const
const VPBasicBlock * getEntryBasicBlock() const
VPBlockBase * getSingleHierarchicalPredecessor()
VPBlockBase * getSingleSuccessor() const
const VPBlocksTy & getSuccessors() const
static void insertOnEdge(VPBlockBase *From, VPBlockBase *To, VPBlockBase *BlockPtr)
Inserts BlockPtr on the edge between From and To.
static void insertTwoBlocksAfter(VPBlockBase *IfTrue, VPBlockBase *IfFalse, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBases IfTrue and IfFalse after BlockPtr.
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.
A recipe for generating conditional branches on the bits of a mask.
RAII object that stores the current insertion point and restores it when the object is destroyed.
VPlan-based builder utility analogous to IRBuilder.
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPValue * createScalarZExtOrTrunc(VPValue *Op, Type *ResultTy, Type *SrcTy, DebugLoc DL)
VPValue * createElementCount(Type *Ty, ElementCount EC)
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createLogicalAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPDerivedIVRecipe * createDerivedIV(InductionDescriptor::InductionKind Kind, FPMathOperator *FPBinOp, VPValue *Start, VPValue *Current, VPValue *Step, const Twine &Name="")
Convert the input value Current to the corresponding value of an induction with Start and Step values...
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< FastMathFlags > FMFs=std::nullopt)
VPScalarIVStepsRecipe * createScalarIVSteps(Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, VPValue *IV, VPValue *Step, VPValue *VF, DebugLoc DL)
VPInstruction * createPtrAdd(VPValue *Ptr, VPValue *Offset, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createOverflowingOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPRecipeWithIRFlags::WrapFlagsTy WrapFlags, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
static VPBuilder getToInsertAfter(VPRecipeBase *R)
Create a VPBuilder to insert after R.
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL, const Twine &Name="")
VPWidenCastRecipe * createWidenCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy)
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 * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Instruction *Inst=nullptr, const Twine &Name="")
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
VPInstruction * createScalarCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, DebugLoc DL)
void setInsertPoint(VPBasicBlock *TheBB)
This specifies that created VPInstructions should be appended to the end of the specified block.
Canonical scalar induction phi of the vector loop.
Type * getScalarType() const
Returns the scalar type of the induction.
unsigned getNumDefinedValues() const
Returns the number of values defined by the VPDef.
ArrayRef< VPValue * > definedValues()
Returns an ArrayRef of the values defined by the VPDef.
VPValue * getVPSingleValue()
Returns the only VPValue defined by the VPDef.
VPValue * getVPValue(unsigned I)
Returns the VPValue with index I defined by the VPDef.
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
bool properlyDominates(const VPRecipeBase *A, const VPRecipeBase *B)
A recipe for generating the phi node for the current index of elements, adjusted in accordance with E...
A recipe to combine multiple recipes into a single 'expression' recipe, which should be considered a ...
A special type of VPBasicBlock that wraps an existing IR basic block.
Class to record and manage LLVM IR flags.
static LLVM_ABI_FOR_TEST VPIRInstruction * create(Instruction &I)
Create a new VPIRPhi for \I , if it is a PHINode, otherwise create a VPIRInstruction.
This is a concrete Recipe that models a single VPlan-level instruction.
@ ExtractLane
Extracts a single lane (first operand) from a set of vector operands.
@ FirstOrderRecurrenceSplice
@ BuildVector
Creates a fixed-width vector containing all operands.
@ BuildStructVector
Given operands of (the same) struct type, creates a struct of fixed- width vectors each containing a ...
@ CanonicalIVIncrementForPart
@ CalculateTripCountMinusVF
bool isVectorToScalar() const
Returns true if this VPInstruction produces a scalar value from a vector, e.g.
const InterleaveGroup< Instruction > * getInterleaveGroup() const
ArrayRef< VPValue * > getStoredValues() const
Return the VPValues stored by this interleave group.
A recipe for interleaved memory operations with vector-predication intrinsics.
VPInterleaveRecipe is a recipe for transforming an interleave group of load or stores into one wide l...
VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when control converges back from ...
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
bool mayReadFromMemory() const
Returns true if the recipe may read from memory.
bool mayReadOrWriteMemory() const
Returns true if the recipe may read from or write to memory.
bool mayHaveSideEffects() const
Returns true if the recipe may have side-effects.
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.
void insertAfter(VPRecipeBase *InsertPos)
Insert an unlinked Recipe into a basic block immediately after the specified Recipe.
iplist< VPRecipeBase >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Helper class to create VPRecipies from IR instructions.
VPRecipeBase * getRecipe(Instruction *I)
Return the recipe created for given ingredient.
A recipe to represent inloop reduction operations with vector-predication intrinsics,...
A recipe to represent inloop reduction operations, performing a reduction on a vector operand into a ...
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
const VPBlockBase * getEntry() const
void setExiting(VPBlockBase *ExitingBlock)
Set ExitingBlock as the exiting VPBlockBase of this VPRegionBlock.
const VPBlockBase * getExiting() const
VPBasicBlock * getPreheaderVPBB()
Returns the pre-header VPBasicBlock of the loop region.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
bool isSingleScalar() const
VPValue * getMask()
Return the mask of a predicated VPReplicateRecipe.
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
Instruction * getUnderlyingInstr()
Returns the underlying instruction.
virtual VPSingleDefRecipe * clone() override=0
Clone the current recipe.
An analysis for type-inference for VPValues.
LLVMContext & getContext()
Return the LLVMContext used by the analysis.
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)
operand_iterator op_end()
operand_iterator op_begin()
VPValue * getOperand(unsigned N) const
void addOperand(VPValue *Operand)
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Value * getLiveInIRValue() const
Returns the underlying IR value, if this VPValue is defined outside the scope of VPlan.
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
void setUnderlyingValue(Value *Val)
void replaceAllUsesWith(VPValue *New)
unsigned getNumUsers() const
bool isLiveIn() const
Returns true if this VPValue is a live-in, i.e. defined outside the VPlan.
void replaceUsesWithIf(VPValue *New, llvm::function_ref< bool(VPUser &U, unsigned Idx)> ShouldReplace)
Go through the uses list for this VPValue and make each use point to New if the callback ShouldReplac...
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
VPVectorEndPointerRecipe * clone() override
Clone the current recipe.
A Recipe for widening the canonical induction variable of the vector loop.
VPWidenCastRecipe is a recipe to create vector cast instructions.
A recipe for handling GEP instructions.
Base class for widened induction (VPWidenIntOrFpInductionRecipe and VPWidenPointerInductionRecipe),...
PHINode * getPHINode() const
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...
VPValue * getLastUnrolledPartOperand()
Returns the VPValue representing the value of this induction at the last unrolled part,...
VPValue * getSplatVFValue()
A recipe for widening vector intrinsics.
A common base class for widening memory operations.
VPValue * getMask() const
Return the mask used by this recipe.
VPValue * getAddr() const
Return the address accessed by this recipe.
A recipe for widened phis.
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
bool hasVF(ElementCount VF) const
LLVMContext & getContext() const
VPBasicBlock * getEntry()
VPRegionBlock * createVPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exiting, const std::string &Name="", bool IsReplicator=false)
Create a new VPRegionBlock with Entry, Exiting and Name.
VPValue & getVectorTripCount()
The vector trip count.
bool hasScalableVF() const
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 * getTrue()
Return a VPValue wrapping i1 true.
VPValue * getOrCreateBackedgeTakenCount()
The backedge taken count of the original loop.
bool hasUF(unsigned UF) const
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
void setVF(ElementCount VF)
bool isUnrolled() const
Returns true if the VPlan already has been unrolled, i.e.
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
void resetTripCount(VPValue *NewTripCount)
Resets the trip count for the VPlan.
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.
VPValue * getOrAddLiveIn(Value *V)
Gets the live-in VPValue for V or adds a new live-in (if none exists yet) for V.
bool hasScalarVFOnly() const
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
ArrayRef< VPValue * > getLiveIns() const
Return the list of live-in VPValues available in the VPlan.
VPCanonicalIVPHIRecipe * getCanonicalIV()
Returns the canonical induction recipe of the vector loop.
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
VPValue * getLiveIn(Value *V) const
Return the live-in VPValue for V, if there is one or nullptr otherwise.
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.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
iterator_range< user_iterator > users()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr LeafTy multiplyCoefficientBy(ScalarTy RHS) const
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
An efficient, type-erasing, non-owning reference to a callable.
An opaque object representing a hash code.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM)
Return A unsign-divided by B, rounded by the given rounding mode.
@ C
The default llvm calling convention, compatible with C.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
cst_pred_ty< is_all_ones > m_AllOnes()
Match an integer or vector with all bits set.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
match_combine_or< CastInst_match< OpTy, ZExtInst >, OpTy > m_ZExtOrSelf(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.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
deferredval_ty< Value > m_Deferred(Value *const &V)
Like m_Specific(), but works if the specific value to match is determined as part of the same match()...
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
AllRecipe_commutative_match< Instruction::And, Op0_t, Op1_t > m_c_BinaryAnd(const Op0_t &Op0, const Op1_t &Op1)
Match a binary AND operation.
AllRecipe_match< Instruction::Or, Op0_t, Op1_t > m_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
Match a binary OR operation.
AllRecipe_commutative_match< Instruction::Or, Op0_t, Op1_t > m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
GEPLikeRecipe_match< Op0_t, Op1_t > m_GetElementPtr(const Op0_t &Op0, const Op1_t &Op1)
VPInstruction_match< VPInstruction::ExtractLastElement, Op0_t > m_ExtractLastElement(const Op0_t &Op0)
specific_intval< 1 > m_False()
VPDerivedIV_match< Op0_t, Op1_t, Op2_t > m_DerivedIV(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
VPInstruction_match< VPInstruction::ActiveLaneMask, Op0_t, Op1_t, Op2_t > m_ActiveLaneMask(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
VPInstruction_match< VPInstruction::BranchOnCount, Op0_t, Op1_t > m_BranchOnCount(const Op0_t &Op0, const Op1_t &Op1)
specific_intval< 1 > m_True()
VPInstruction_match< VPInstruction::Broadcast, Op0_t > m_Broadcast(const Op0_t &Op0)
class_match< VPValue > m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::ExplicitVectorLength, Op0_t > m_EVL(const Op0_t &Op0)
VPInstruction_match< VPInstruction::BuildVector > m_BuildVector()
BuildVector is matches only its opcode, w/o matching its operands as the number of operands is not fi...
VPInstruction_match< VPInstruction::BranchOnCond, Op0_t > m_BranchOnCond(const Op0_t &Op0)
bind_ty< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
initializer< Ty > init(const Ty &Val)
NodeAddr< DefNode * > Def
bool isSingleScalar(const VPValue *VPV)
Returns true if VPV is a single scalar, either because it produces the same value for all lanes or on...
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr)
Get or create a VPValue that corresponds to the expansion of Expr.
const SCEV * getSCEVExprForVPValue(VPValue *V, ScalarEvolution &SE)
Return the SCEV expression for V.
bool onlyFirstLaneUsed(const VPValue *Def)
Returns true if only the first lane of Def is used.
bool isHeaderMask(const VPValue *V, VPlan &Plan)
Return true if V is a header mask in Plan.
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Intrinsic::ID getVectorIntrinsicIDForCall(const CallInst *CI, const TargetLibraryInfo *TLI)
Returns intrinsic ID for call.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
constexpr from_range_t from_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
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.
iterator_range< df_iterator< VPBlockDeepTraversalWrapper< VPBlockBase * > > > vp_depth_first_deep(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order while traversing t...
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
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)
iterator_range< po_iterator< VPBlockDeepTraversalWrapper< VPBlockBase * > > > vp_post_order_deep(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in post order while traversing through ...
void sort(IteratorTy Start, IteratorTy End)
std::unique_ptr< VPlan > VPlanPtr
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
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.
@ Mul
Product of integers.
@ Sub
Subtraction of integers.
@ AddChainWithSubs
A chain of adds and subs.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
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 BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)
Split the specified block at the specified instruction.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
@ DataAndControlFlowWithoutRuntimeCheck
Use predicate to control both data and control flow, but modify the trip count so that a runtime over...
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
Type * toVectorTy(Type *Scalar, ElementCount EC)
A helper function for converting Scalar types to vector types.
@ Default
The result values are uniform if and only if all operands are uniform.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
This struct is a compact representation of a valid (non-zero power of two) alignment.
An information struct used to provide DenseMap with the various necessary components for a given valu...
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
A range of powers-of-2 vectorization factors with fixed start and adjustable end.
Struct to hold various analysis needed for cost computations.
const TargetTransformInfo & TTI
A recipe for handling first-order recurrence phis.
A recipe for widening load operations with vector-predication intrinsics, using the address to load f...
A recipe for widening load operations, using the address to load from and an optional mask.
A recipe for widening select instructions.
A recipe for widening store operations with vector-predication intrinsics, using the value to store,...
A recipe for widening store operations, using the stored value, the address to store to and an option...