24#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
25#define LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
85 const unsigned char SubclassID;
102 VPlan *Plan =
nullptr;
112 assert(Predecessor &&
"Cannot add nullptr predecessor!");
117 void removePredecessor(VPBlockBase *Predecessor) {
118 auto Pos =
find(Predecessors, Predecessor);
119 assert(Pos &&
"Predecessor does not exist");
120 Predecessors.
erase(Pos);
124 void removeSuccessor(VPBlockBase *Successor) {
125 auto Pos =
find(Successors, Successor);
126 assert(Pos &&
"Successor does not exist");
127 Successors.
erase(Pos);
132 void replacePredecessor(VPBlockBase *Old, VPBlockBase *New) {
133 auto I =
find(Predecessors, Old);
135 assert(Old->getParent() ==
New->getParent() &&
136 "replaced predecessor must have the same parent");
142 void replaceSuccessor(VPBlockBase *Old, VPBlockBase *New) {
143 auto I =
find(Successors, Old);
145 assert(Old->getParent() ==
New->getParent() &&
146 "replaced successor must have the same parent");
152 : SubclassID(SC), Name(
N) {}
159 using VPBlockTy =
enum { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC };
165 const std::string &
getName()
const {
return Name; }
179 const VPlan *getPlan()
const;
183 void setPlan(
VPlan *ParentPlan);
211 return (Successors.size() == 1 ? *Successors.begin() :
nullptr);
217 return (Predecessors.size() == 1 ? *Predecessors.begin() :
nullptr);
273 assert(Successors.empty() &&
"Setting one successor when others exist.");
275 "connected blocks must have the same parent");
284 assert(Successors.empty() &&
"Setting two successors when others exist.");
285 appendSuccessor(IfTrue);
286 appendSuccessor(IfFalse);
293 assert(Predecessors.empty() &&
"Block predecessors already set.");
294 for (
auto *Pred : NewPreds)
295 appendPredecessor(Pred);
302 assert(Successors.empty() &&
"Block successors already set.");
303 for (
auto *Succ : NewSuccs)
304 appendSuccessor(Succ);
316 assert(Predecessors.size() == 2 &&
"must have 2 predecessors to swap");
317 std::swap(Predecessors[0], Predecessors[1]);
324 assert(Successors.size() == 2 &&
"must have 2 successors to swap");
331 "must have Pred exactly once in Predecessors");
332 return std::distance(Predecessors.begin(),
find(Predecessors, Pred));
338 "must have Succ exactly once in Successors");
339 return std::distance(Successors.begin(),
find(Successors, Succ));
349#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
393 const unsigned char SubclassID;
396 VPBasicBlock *Parent =
nullptr;
420 VPVectorEndPointerSC,
422 VPWidenCanonicalIVSC,
439 VPCurrentIterationPHISC,
440 VPActiveLaneMaskPHISC,
441 VPFirstOrderRecurrencePHISC,
442 VPWidenIntOrFpInductionSC,
443 VPWidenPointerInductionSC,
447 VPFirstPHISC = VPWidenPHISC,
448 VPFirstHeaderPHISC = VPCanonicalIVPHISC,
449 VPLastHeaderPHISC = VPReductionPHISC,
450 VPLastPHISC = VPReductionPHISC,
455 :
VPDef(),
VPUser(Operands), SubclassID(SC), DL(DL) {}
464 const VPBasicBlock *
getParent()
const {
return Parent; }
526 bool mayReadFromMemory()
const;
529 bool mayWriteToMemory()
const;
540 bool isScalarCast()
const;
545#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
561#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
570#define VP_CLASSOF_IMPL(VPRecipeID) \
571 static inline bool classof(const VPRecipeBase *R) { \
572 return R->getVPRecipeID() == VPRecipeID; \
574 static inline bool classof(const VPValue *V) { \
575 auto *R = V->getDefiningRecipe(); \
576 return R && R->getVPRecipeID() == VPRecipeID; \
578 static inline bool classof(const VPUser *U) { \
579 auto *R = dyn_cast<VPRecipeBase>(U); \
580 return R && R->getVPRecipeID() == VPRecipeID; \
582 static inline bool classof(const VPSingleDefRecipe *R) { \
583 return R->getVPRecipeID() == VPRecipeID; \
600 switch (R->getVPRecipeID()) {
601 case VPRecipeBase::VPDerivedIVSC:
602 case VPRecipeBase::VPExpandSCEVSC:
603 case VPRecipeBase::VPExpressionSC:
604 case VPRecipeBase::VPInstructionSC:
605 case VPRecipeBase::VPReductionEVLSC:
606 case VPRecipeBase::VPReductionSC:
607 case VPRecipeBase::VPReplicateSC:
608 case VPRecipeBase::VPScalarIVStepsSC:
609 case VPRecipeBase::VPVectorPointerSC:
610 case VPRecipeBase::VPVectorEndPointerSC:
611 case VPRecipeBase::VPWidenCallSC:
612 case VPRecipeBase::VPWidenCanonicalIVSC:
613 case VPRecipeBase::VPWidenCastSC:
614 case VPRecipeBase::VPWidenGEPSC:
615 case VPRecipeBase::VPWidenIntrinsicSC:
616 case VPRecipeBase::VPWidenSC:
617 case VPRecipeBase::VPBlendSC:
618 case VPRecipeBase::VPPredInstPHISC:
619 case VPRecipeBase::VPCanonicalIVPHISC:
620 case VPRecipeBase::VPCurrentIterationPHISC:
621 case VPRecipeBase::VPActiveLaneMaskPHISC:
622 case VPRecipeBase::VPFirstOrderRecurrencePHISC:
623 case VPRecipeBase::VPWidenPHISC:
624 case VPRecipeBase::VPWidenIntOrFpInductionSC:
625 case VPRecipeBase::VPWidenPointerInductionSC:
626 case VPRecipeBase::VPReductionPHISC:
628 case VPRecipeBase::VPBranchOnMaskSC:
629 case VPRecipeBase::VPInterleaveEVLSC:
630 case VPRecipeBase::VPInterleaveSC:
631 case VPRecipeBase::VPIRInstructionSC:
632 case VPRecipeBase::VPWidenLoadEVLSC:
633 case VPRecipeBase::VPWidenLoadSC:
634 case VPRecipeBase::VPWidenStoreEVLSC:
635 case VPRecipeBase::VPWidenStoreSC:
636 case VPRecipeBase::VPHistogramSC:
645 auto *R = V->getDefiningRecipe();
664#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
672 enum class OperationType :
unsigned char {
712 struct ExactFlagsTy {
714 ExactFlagsTy(
bool Exact) : IsExact(Exact) {}
716 struct FastMathFlagsTy {
717 char AllowReassoc : 1;
720 char NoSignedZeros : 1;
721 char AllowReciprocal : 1;
722 char AllowContract : 1;
730 uint8_t CmpPredStorage;
731 FastMathFlagsTy FMFs;
734 struct ReductionFlagsTy {
737 unsigned char Kind : 6;
739 unsigned char IsOrdered : 1;
740 unsigned char IsInLoop : 1;
741 FastMathFlagsTy FMFs;
743 ReductionFlagsTy(
RecurKind Kind,
bool IsOrdered,
bool IsInLoop,
745 : Kind(static_cast<unsigned char>(Kind)), IsOrdered(IsOrdered),
746 IsInLoop(IsInLoop), FMFs(FMFs) {}
749 OperationType OpType;
770 OpType = OperationType::FCmp;
772 FCmp->getPredicate());
774 FCmpFlags.FMFs = FCmp->getFastMathFlags();
776 OpType = OperationType::Cmp;
781 OpType = OperationType::DisjointOp;
784 OpType = OperationType::OverflowingBinOp;
785 WrapFlags = {
Op->hasNoUnsignedWrap(),
Op->hasNoSignedWrap()};
787 OpType = OperationType::Trunc;
790 OpType = OperationType::PossiblyExactOp;
793 OpType = OperationType::GEPOp;
796 "wrap flags truncated");
798 OpType = OperationType::NonNegOp;
801 OpType = OperationType::FPMathOp;
802 FMFs =
Op->getFastMathFlags();
812 : OpType(OperationType::FCmp),
AllFlags() {
819 : OpType(OperationType::OverflowingBinOp),
AllFlags() {
824 : OpType(OperationType::Trunc),
AllFlags() {
833 : OpType(OperationType::DisjointOp),
AllFlags() {
838 : OpType(OperationType::NonNegOp),
AllFlags() {
843 : OpType(OperationType::PossiblyExactOp),
AllFlags() {
848 : OpType(OperationType::GEPOp),
AllFlags() {
853 : OpType(OperationType::ReductionOp),
AllFlags() {
858 OpType = Other.OpType;
872 case OperationType::OverflowingBinOp:
876 case OperationType::Trunc:
880 case OperationType::DisjointOp:
883 case OperationType::PossiblyExactOp:
886 case OperationType::GEPOp:
889 case OperationType::FPMathOp:
890 case OperationType::FCmp:
891 case OperationType::ReductionOp:
892 getFMFsRef().NoNaNs =
false;
893 getFMFsRef().NoInfs =
false;
895 case OperationType::NonNegOp:
898 case OperationType::Cmp:
899 case OperationType::Other:
907 case OperationType::OverflowingBinOp:
911 case OperationType::Trunc:
915 case OperationType::DisjointOp:
918 case OperationType::PossiblyExactOp:
921 case OperationType::GEPOp:
925 case OperationType::FPMathOp:
926 case OperationType::FCmp: {
927 const FastMathFlagsTy &
F = getFMFsRef();
928 I.setHasAllowReassoc(
F.AllowReassoc);
929 I.setHasNoNaNs(
F.NoNaNs);
930 I.setHasNoInfs(
F.NoInfs);
931 I.setHasNoSignedZeros(
F.NoSignedZeros);
932 I.setHasAllowReciprocal(
F.AllowReciprocal);
933 I.setHasAllowContract(
F.AllowContract);
934 I.setHasApproxFunc(
F.ApproxFunc);
937 case OperationType::NonNegOp:
940 case OperationType::ReductionOp:
942 case OperationType::Cmp:
943 case OperationType::Other:
949 assert((OpType == OperationType::Cmp || OpType == OperationType::FCmp) &&
950 "recipe doesn't have a compare predicate");
957 assert((OpType == OperationType::Cmp || OpType == OperationType::FCmp) &&
958 "recipe doesn't have a compare predicate");
959 if (OpType == OperationType::FCmp)
972 return OpType == OperationType::Cmp || OpType == OperationType::FCmp;
977 return OpType == OperationType::FPMathOp || OpType == OperationType::FCmp ||
978 OpType == OperationType::ReductionOp;
987 assert(OpType == OperationType::NonNegOp &&
988 "recipe doesn't have a NNEG flag");
994 case OperationType::OverflowingBinOp:
996 case OperationType::Trunc:
1005 case OperationType::OverflowingBinOp:
1007 case OperationType::Trunc:
1015 assert(OpType == OperationType::DisjointOp &&
1016 "recipe cannot have a disjoing flag");
1021 assert(OpType == OperationType::ReductionOp &&
1022 "recipe doesn't have reduction flags");
1027 assert(OpType == OperationType::ReductionOp &&
1028 "recipe doesn't have reduction flags");
1033 assert(OpType == OperationType::ReductionOp &&
1034 "recipe doesn't have reduction flags");
1040 FastMathFlagsTy &getFMFsRef() {
1041 if (OpType == OperationType::FCmp)
1043 if (OpType == OperationType::ReductionOp)
1047 const FastMathFlagsTy &getFMFsRef()
const {
1048 if (OpType == OperationType::FCmp)
1050 if (OpType == OperationType::ReductionOp)
1069#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1074static_assert(
sizeof(
VPIRFlags) <= 3,
"VPIRFlags should not grow");
1085 return R->getVPRecipeID() == VPRecipeBase::VPBlendSC ||
1086 R->getVPRecipeID() == VPRecipeBase::VPInstructionSC ||
1087 R->getVPRecipeID() == VPRecipeBase::VPWidenSC ||
1088 R->getVPRecipeID() == VPRecipeBase::VPWidenGEPSC ||
1089 R->getVPRecipeID() == VPRecipeBase::VPWidenCallSC ||
1090 R->getVPRecipeID() == VPRecipeBase::VPWidenCastSC ||
1091 R->getVPRecipeID() == VPRecipeBase::VPWidenIntrinsicSC ||
1092 R->getVPRecipeID() == VPRecipeBase::VPReductionSC ||
1093 R->getVPRecipeID() == VPRecipeBase::VPReductionEVLSC ||
1094 R->getVPRecipeID() == VPRecipeBase::VPReplicateSC ||
1095 R->getVPRecipeID() == VPRecipeBase::VPVectorEndPointerSC ||
1096 R->getVPRecipeID() == VPRecipeBase::VPVectorPointerSC;
1105 auto *R = V->getDefiningRecipe();
1158 llvm::find_if(Metadata, [Kind](
const std::pair<unsigned, MDNode *> &
P) {
1159 return P.first == Kind;
1161 if (It != Metadata.end())
1164 Metadata.emplace_back(Kind,
Node);
1174 find_if(Metadata, [Kind](
const auto &
P) {
return P.first == Kind; });
1175 return It != Metadata.end() ? It->second :
nullptr;
1178#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1198 Instruction::OtherOpsEnd + 1,
1318 bool doesGeneratePerAllLanes()
const;
1323 unsigned getNumOperandsForOpcode()
const;
1326 typedef unsigned char OpcodeTy;
1334 bool canGenerateScalarForFirstLane()
const;
1342 bool alwaysUnmasked()
const {
1348 if (!getUnderlyingValue())
1351 return Opcode == Instruction::PHI || Opcode == Instruction::GetElementPtr;
1355 VPInstruction(
unsigned Opcode, ArrayRef<VPValue *> Operands,
1356 const VPIRFlags &Flags = {},
const VPIRMetadata &MD = {},
1380#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1389 case Instruction::Ret:
1390 case Instruction::Br:
1391 case Instruction::Store:
1392 case Instruction::Switch:
1393 case Instruction::IndirectBr:
1394 case Instruction::Resume:
1395 case Instruction::CatchRet:
1396 case Instruction::Unreachable:
1397 case Instruction::Fence:
1398 case Instruction::AtomicRMW:
1412 if (NumOpsForOpcode == -1u)
1426 if (alwaysUnmasked())
1447 bool opcodeMayReadOrWriteFromMemory()
const;
1450 bool usesFirstLaneOnly(
const VPValue *
Op)
const override;
1453 bool usesFirstPartOnly(
const VPValue *
Op)
const override;
1457 bool isVectorToScalar()
const;
1461 bool isSingleScalar()
const;
1470#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1491 const Twine &Name =
"")
1493 ResultTy(ResultTy) {}
1498 if (R->isScalarCast())
1503 switch (VPI->getOpcode()) {
1507 case Instruction::Load:
1538#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1586 std::function<
const VPBasicBlock *(size_t)> GetBlock = [
this](
size_t Idx) {
1604#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1612 const Twine &Name =
"")
1617 return VPI && VPI->getOpcode() == Instruction::PHI;
1622 return VPI && VPI->getOpcode() == Instruction::PHI;
1627 return VPI && VPI->getOpcode() == Instruction::PHI;
1639#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1686 "Op must be an operand of the recipe");
1692 "Op must be an operand of the recipe");
1698 "Op must be an operand of the recipe");
1703#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1728#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1749 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenSC, Operands,
Flags,
DL),
1751 setUnderlyingValue(&
I);
1757 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenSC, Operands,
Flags,
DL),
1758 VPIRMetadata(
Metadata), Opcode(Opcode) {}
1782#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1791 "Op must be an operand of the recipe");
1792 return Opcode == Instruction::Select &&
Op ==
getOperand(0) &&
1793 Op->isDefinedOutsideLoopRegions();
1813 "Set flags not supported for the provided opcode");
1815 "Opcode requires specific flags to be set");
1842#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1858 bool MayReadFromMemory;
1861 bool MayWriteToMemory;
1864 bool MayHaveSideEffects;
1874 VPIRMetadata(MD), VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty),
1893 MayReadFromMemory = !ME.onlyWritesMemory();
1894 MayWriteToMemory = !ME.onlyReadsMemory();
1895 MayHaveSideEffects = MayWriteToMemory ||
1896 !Attrs.hasAttribute(Attribute::NoUnwind) ||
1897 !Attrs.hasAttribute(Attribute::WillReturn);
1905 operands(), ResultTy, *
this, *
this,
1941#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1961 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenCallSC, CallArguments,
Flags,
1964 setUnderlyingValue(UV);
1966 isa<Function>(getOperand(getNumOperands() - 1)->getLiveInIRValue()) &&
1967 "last operand must be the called function");
1994#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2040#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2049 Type *SourceElementTy;
2051 bool isPointerLoopInvariant()
const {
2052 return getOperand(0)->isDefinedOutsideLoopRegions();
2055 bool isIndexLoopInvariant(
unsigned I)
const {
2056 return getOperand(
I + 1)->isDefinedOutsideLoopRegions();
2064 SourceElementTy(
GEP->getSourceElementType()) {
2065 setUnderlyingValue(
GEP);
2097 bool usesFirstLaneOnly(
const VPValue *
Op)
const override;
2100#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2113 Type *SourceElementTy;
2124 SourceElementTy(SourceElementTy), Stride(Stride) {
2125 assert(Stride < 0 &&
"Stride must be negative");
2146 "Op must be an operand of the recipe");
2160 "Op must be an operand of the recipe");
2170 VEPR->addOperand(
Offset);
2175#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2186 Type *SourceElementTy;
2192 SourceElementTy(SourceElementTy) {}
2206 "Op must be an operand of the recipe");
2213 "Op must be an operand of the recipe");
2222 Clone->addOperand(Off);
2234#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2277 return R->getVPRecipeID() >= VPRecipeBase::VPFirstHeaderPHISC &&
2278 R->getVPRecipeID() <= VPRecipeBase::VPLastHeaderPHISC;
2320#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2342 return R->getVPRecipeID() == VPRecipeBase::VPWidenIntOrFpInductionSC ||
2343 R->getVPRecipeID() == VPRecipeBase::VPWidenPointerInductionSC;
2347 auto *R = V->getDefiningRecipe();
2387 "VPWidenIntOrFpInductionRecipe generates its own backedge value");
2394 "VPWidenIntOrFpInductionRecipe generates its own backedge value");
2400 "Op must be an operand of the recipe");
2423 Start, Step, IndDesc,
DL),
2433 Start, Step, IndDesc,
DL),
2455 "expandVPWidenIntOrFpInductionRecipe");
2495#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2511 Start, Step, IndDesc,
DL) {
2528 "expandVPWidenPointerInduction");
2535#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2583#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2619 "Op must be an operand of the recipe");
2624#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2645 unsigned ScaleFactor) {
2646 assert((!Ordered || InLoop) &&
"Ordered implies in-loop");
2667 bool HasUsesOutsideReductionChain;
2674 bool HasUsesOutsideReductionChain =
false)
2676 VPIRFlags(Flags), Kind(Kind), Style(Style),
2677 HasUsesOutsideReductionChain(HasUsesOutsideReductionChain) {
2687 HasUsesOutsideReductionChain);
2698 auto *Partial = std::get_if<RdxUnordered>(&Style);
2699 return Partial ? Partial->VFScaleFactor : 1;
2705 assert(ScaleFactor > 1 &&
"must set to scale factor > 1");
2718 bool isOrdered()
const {
return std::holds_alternative<RdxOrdered>(Style); }
2722 return std::holds_alternative<RdxInLoop>(Style) ||
2723 std::holds_alternative<RdxOrdered>(Style);
2731 return HasUsesOutsideReductionChain;
2737 "Op must be an operand of the recipe");
2742#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2760 assert(Operands.size() >= 2 &&
"Expected at least two operands!");
2809 "Op must be an operand of the recipe");
2813 [
this](
VPUser *U) {
return U->usesFirstLaneOnly(
this); });
2817#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2835 bool HasMask =
false;
2839 bool NeedsMaskForGaps =
false;
2848 NeedsMaskForGaps(NeedsMaskForGaps) {
2850 assert((!Mask || !IG->isReverse()) &&
2851 "Reversed masked interleave-group not supported.");
2852 if (StoredValues.
empty()) {
2853 for (
unsigned I = 0;
I < IG->getFactor(); ++
I)
2855 assert(!Inst->getType()->isVoidTy() &&
"must have result");
2859 for (
auto *SV : StoredValues)
2872 return R->getVPRecipeID() == VPRecipeBase::VPInterleaveSC ||
2873 R->getVPRecipeID() == VPRecipeBase::VPInterleaveEVLSC;
2933 Mask, NeedsMaskForGaps, MD, DL) {}
2950 "Op must be an operand of the recipe");
2959#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2974 R.getStoredValues(), Mask, R.needsMaskForGaps(), R,
2976 assert(!getInterleaveGroup()->isReverse() &&
2977 "Reversed interleave-group with tail folding is not supported.");
2978 assert(!needsMaskForGaps() &&
"Interleaved access with gap mask is not "
2979 "supported for scalable vector.");
2999 "Op must be an operand of the recipe");
3009#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3025 bool IsConditional =
false;
3036 IsConditional =
true;
3047 {ChainOp, VecOp}, CondOp, Style,
DL) {}
3053 {ChainOp, VecOp}, CondOp, Style,
DL) {}
3064 return R->getVPRecipeID() == VPRecipeBase::VPReductionSC ||
3065 R->getVPRecipeID() == VPRecipeBase::VPReductionEVLSC;
3092 bool isOrdered()
const {
return std::holds_alternative<RdxOrdered>(Style); };
3099 return std::holds_alternative<RdxInLoop>(Style) ||
3100 std::holds_alternative<RdxOrdered>(Style);
3113 auto *Partial = std::get_if<RdxUnordered>(&Style);
3114 return Partial ? Partial->VFScaleFactor : 1;
3118#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3136 {R.getChainOp(), R.getVecOp(), &EVL}, CondOp,
3157 "Op must be an operand of the recipe");
3162#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3176 bool IsSingleScalar;
3183 bool IsSingleScalar,
VPValue *Mask =
nullptr,
3185 DebugLoc
DL = DebugLoc::getUnknown())
3186 : VPRecipeWithIRFlags(VPRecipeBase::VPReplicateSC, Operands, Flags,
DL),
3187 VPIRMetadata(
Metadata), IsSingleScalar(IsSingleScalar),
3188 IsPredicated(Mask) {
3189 setUnderlyingValue(
I);
3200 Copy->transferFlags(*
this);
3222 "Op must be an operand of the recipe");
3229 "Op must be an operand of the recipe");
3236 bool shouldPack()
const;
3247#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3274#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3278 O << Indent <<
"BRANCH-ON-MASK ";
3286 "Op must be an operand of the recipe");
3309 enum class ExpressionTypes {
3325 ExtNegatedMulAccReduction,
3329 ExpressionTypes ExpressionType;
3337 VPExpressionRecipe(ExpressionTypes ExpressionType,
3342 : VPExpressionRecipe(ExpressionTypes::ExtendedReduction, {Ext, Red}) {}
3344 : VPExpressionRecipe(ExpressionTypes::MulAccReduction, {
Mul, Red}) {}
3347 : VPExpressionRecipe(ExpressionTypes::ExtMulAccReduction,
3348 {Ext0, Ext1,
Mul, Red}) {}
3352 : VPExpressionRecipe(ExpressionTypes::ExtNegatedMulAccReduction,
3353 {Ext0, Ext1,
Mul,
Sub, Red}) {
3354 assert(
Mul->getOpcode() == Instruction::Mul &&
"Expected a mul");
3356 "Expected an add reduction");
3359 assert(SubConst && SubConst->isZero() &&
3360 Sub->getOpcode() == Instruction::Sub &&
"Expected a negating sub");
3365 for (
auto *R :
reverse(ExpressionRecipes)) {
3366 if (ExpressionRecipesSeen.
insert(R).second)
3369 for (
VPValue *
T : LiveInPlaceholders)
3376 assert(!ExpressionRecipes.empty() &&
"empty expressions should be removed");
3378 for (
auto *R : ExpressionRecipes)
3379 NewExpressiondRecipes.
push_back(R->clone());
3380 for (
auto *New : NewExpressiondRecipes) {
3381 for (
const auto &[Idx, Old] :
enumerate(ExpressionRecipes))
3382 New->replaceUsesOfWith(Old, NewExpressiondRecipes[Idx]);
3385 for (
const auto &[Placeholder, OutsideOp] :
3387 New->replaceUsesOfWith(Placeholder, OutsideOp);
3389 return new VPExpressionRecipe(ExpressionType, NewExpressiondRecipes);
3407 return PR ? PR->getVFScaleFactor() : 1;
3430#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3470 "Op must be an operand of the recipe");
3475#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3510 std::initializer_list<VPValue *> Operands,
3518 "Reversed acccess without VPVectorEndPointerRecipe address?");
3527 return R->getVPRecipeID() == VPRecipeBase::VPWidenLoadSC ||
3528 R->getVPRecipeID() == VPRecipeBase::VPWidenStoreSC ||
3529 R->getVPRecipeID() == VPRecipeBase::VPWidenLoadEVLSC ||
3530 R->getVPRecipeID() == VPRecipeBase::VPWidenStoreEVLSC;
3600 "Op must be an operand of the recipe");
3607#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3622 {Addr, &EVL}, L.isConsecutive(), L.isReverse(), L,
3643 "Op must be an operand of the recipe");
3650#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3686 "Op must be an operand of the recipe");
3693#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3707 {Addr, StoredVal, &EVL}, S.isConsecutive(),
3708 S.isReverse(), S, S.getDebugLoc()) {
3730 "Op must be an operand of the recipe");
3742#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3764 llvm_unreachable(
"SCEV expressions must be expanded before final execute");
3777#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3806 "scalar phi recipe");
3818 "Op must be an operand of the recipe");
3825 "Op must be an operand of the recipe");
3837#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3867#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3894 "scalar phi recipe");
3907 "Op must be an operand of the recipe");
3912#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3948#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3971 const Twine &Name =
"")
3975 Start, CanonicalIV, Step, Name) {}
3981 Kind(Kind), FPBinOp(FPBinOp), Name(Name.str()) {}
4011 "Op must be an operand of the recipe");
4016#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4039 InductionOpcode(Opcode) {}
4045 IV, Step, VF, IndDesc.getInductionOpcode(),
4086 "Op must be an operand of the recipe");
4091#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4108template <
typename SrcTy>
4116 switch (R->getVPRecipeID()) {
4117 case VPRecipeBase::VPInstructionSC:
4119 case VPRecipeBase::VPIRInstructionSC:
4121 case VPRecipeBase::VPWidenPHISC:
4146template <
typename DstTy,
typename RecipeBasePtrTy>
4148 switch (R->getVPRecipeID()) {
4149 case VPRecipeBase::VPInstructionSC:
4151 case VPRecipeBase::VPWidenSC:
4153 case VPRecipeBase::VPWidenCastSC:
4155 case VPRecipeBase::VPWidenIntrinsicSC:
4157 case VPRecipeBase::VPWidenCallSC:
4159 case VPRecipeBase::VPReplicateSC:
4161 case VPRecipeBase::VPInterleaveSC:
4162 case VPRecipeBase::VPInterleaveEVLSC:
4164 case VPRecipeBase::VPWidenLoadSC:
4165 case VPRecipeBase::VPWidenLoadEVLSC:
4166 case VPRecipeBase::VPWidenStoreSC:
4167 case VPRecipeBase::VPWidenStoreEVLSC:
4177template <
typename DstTy,
typename SrcTy>
4275 return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC ||
4276 V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
4280 assert(Recipe &&
"No recipe to append.");
4281 assert(!Recipe->Parent &&
"Recipe already in VPlan");
4282 Recipe->Parent =
this;
4283 Recipes.insert(InsertPt, Recipe);
4313#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4330 bool isExiting()
const;
4340 const VPBasicBlock *getCFGPredecessor(
unsigned Idx)
const;
4356inline const VPBasicBlock *
4366class VPIRBasicBlock :
public VPBasicBlock {
4373 : VPBasicBlock(VPIRBasicBlockSC,
4381 return V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
4417 const std::string &Name =
"",
bool IsReplicator =
false)
4418 :
VPBlockBase(VPRegionBlockSC, Name), Entry(Entry), Exiting(Exiting),
4419 IsReplicator(IsReplicator) {
4420 assert(Entry->getPredecessors().empty() &&
"Entry block has predecessors.");
4421 assert(Exiting->getSuccessors().empty() &&
"Exit block has successors.");
4422 Entry->setParent(
this);
4423 Exiting->setParent(
this);
4425 VPRegionBlock(
const std::string &Name =
"",
bool IsReplicator =
false)
4426 :
VPBlockBase(VPRegionBlockSC, Name), Entry(nullptr), Exiting(nullptr),
4427 IsReplicator(IsReplicator) {}
4434 return V->getVPBlockID() == VPBlockBase::VPRegionBlockSC;
4444 "Entry block cannot have predecessors.");
4456 "Exit block cannot have successors.");
4457 Exiting = ExitingBlock;
4478#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4496 void dissolveToCFGLoop();
4501 if (EntryVPBB->
empty()) {
4591 : Entry(Entry), ScalarHeader(ScalarHeader) {
4592 Entry->setPlan(
this);
4593 assert(ScalarHeader->getNumSuccessors() == 0 &&
4594 "scalar header must be a leaf node");
4652 "cannot call the function after vector loop region has been removed");
4682 assert(TripCount &&
"trip count needs to be set before accessing it");
4689 assert(!TripCount && NewTripCount &&
"TripCount should not be set yet.");
4690 TripCount = NewTripCount;
4697 "TripCount must be set when resetting");
4698 TripCount = NewTripCount;
4703 if (!BackedgeTakenCount)
4705 return BackedgeTakenCount;
4729 assert(
hasVF(VF) &&
"Cannot set VF not already in plan");
4736 assert(
hasVF(VF) &&
"tried to remove VF not present in plan");
4752 bool HasScalarVFOnly = VFs.size() == 1 && VFs[0].isScalar();
4754 "Plan with scalar VF should only have a single VF");
4755 return HasScalarVFOnly;
4758 bool hasUF(
unsigned UF)
const {
return UFs.empty() || UFs.contains(UF); }
4762 assert(UFs.size() == 1 &&
"Expected a single UF");
4767 assert(
hasUF(UF) &&
"Cannot set the UF not already in plan");
4784 assert(V &&
"Trying to get or add the VPIRValue of a null Value");
4785 auto [It, Inserted] = LiveIns.try_emplace(V);
4794 "Only VPIRValues should be in mapping");
4798 assert(V &&
"Trying to get or add the VPIRValue of a null VPIRValue");
4824 bool IsSigned =
false) {
4840#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4864 CreatedBlocks.push_back(VPB);
4876 CreatedBlocks.push_back(VPB);
4884 const std::string &Name =
"") {
4886 CreatedBlocks.push_back(VPB);
4909 (ExitBlocks.size() == 1 && ExitBlocks[0]->getNumPredecessors() > 1);
4921#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file implements methods to test, set and extract typed bits from packed unsigned integers.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
#define LLVM_ABI_FOR_TEST
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
static std::pair< Value *, APInt > getMask(Value *WideMask, unsigned Factor, ElementCount LeafValueEC)
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
This file implements a map that provides insertion order iteration.
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
static StringRef getName(Value *V)
static bool mayHaveSideEffects(MachineInstr &MI)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static const BasicSubtargetSubTypeKV * find(StringRef S, ArrayRef< BasicSubtargetSubTypeKV > A)
Find KV in array using binary search.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
This file contains the declarations of the entities induced by Vectorization Plans,...
#define VP_CLASSOF_IMPL(VPRecipeID)
static const uint32_t IV[8]
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
LLVM Basic Block Representation.
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
static DebugLoc getUnknown()
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
static constexpr ElementCount getFixed(ScalarTy MinVal)
Utility class for floating point operations which can have information about relaxed accuracy require...
Convenience struct for specifying and reasoning about fast-math flags.
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags fromRaw(unsigned Flags)
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Common base class shared among various IRBuilders.
A struct for saving information about induction variables.
InductionKind
This enum represents the kinds of inductions that we support.
InnerLoopVectorizer vectorizes loops which contain only one basic block to a specified vectorization ...
The group of interleaved loads/stores sharing the same stride and close to each other.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
LoopVectorizationCostModel - estimates the expected speedups due to vectorization.
Represents a single loop in the control flow graph.
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
This class represents an analyzed expression in the program.
This class provides computation of slot numbers for LLVM Assembly writing.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator erase(const_iterator CI)
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.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
This class represents a truncation of integer types.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
void execute(VPTransformState &State) override
Generate the active lane mask phi of the vector loop.
VPActiveLaneMaskPHIRecipe * clone() override
Clone the current recipe.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPActiveLaneMaskPHIRecipe(VPValue *StartMask, DebugLoc DL)
~VPActiveLaneMaskPHIRecipe() override=default
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
RecipeListTy::const_iterator const_iterator
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
RecipeListTy::const_reverse_iterator const_reverse_iterator
RecipeListTy::iterator iterator
Instruction iterators...
RecipeListTy & getRecipeList()
Returns a reference to the list of recipes.
iplist< VPRecipeBase > RecipeListTy
VPBasicBlock(const unsigned char BlockSC, const Twine &Name="")
iterator begin()
Recipe iterator methods.
RecipeListTy::reverse_iterator reverse_iterator
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
const VPBasicBlock * getCFGPredecessor(unsigned Idx) const
Returns the predecessor block at index Idx with the predecessors as per the corresponding plain CFG.
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
const_reverse_iterator rbegin() const
RecipeListTy Recipes
The VPRecipes held in the order of output instructions to generate.
const VPRecipeBase & front() const
const_iterator begin() const
const VPRecipeBase & back() const
void insert(VPRecipeBase *Recipe, iterator InsertPt)
const_iterator end() const
static bool classof(const VPBlockBase *V)
Method to support type inquiry through isa, cast, and dyn_cast.
static RecipeListTy VPBasicBlock::* getSublistAccess(VPRecipeBase *)
Returns a pointer to a member of the recipe list.
reverse_iterator rbegin()
const_reverse_iterator rend() const
VPValue * getIncomingValue(unsigned Idx) const
Return incoming value number Idx.
VPValue * getMask(unsigned Idx) const
Return mask number Idx.
VPBlendRecipe(PHINode *Phi, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL)
The blend operation is a User of the incoming values and of their respective masks,...
unsigned getNumIncomingValues() const
Return the number of incoming values, taking into account when normalized the first incoming value wi...
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPBlendRecipe * clone() override
Clone the current recipe.
void setMask(unsigned Idx, VPValue *V)
Set mask number Idx to V.
bool isNormalized() const
A normalized blend is one that has an odd number of operands, whereby the first operand does not have...
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()
VPBlocksTy & getPredecessors()
iterator_range< VPBlockBase ** > predecessors()
LLVM_DUMP_METHOD void dump() const
Dump this VPBlockBase to dbgs().
void setName(const Twine &newName)
size_t getNumSuccessors() const
iterator_range< VPBlockBase ** > successors()
virtual void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const =0
Print plain-text dump of this VPBlockBase to O, prefixing all lines with Indent.
bool hasPredecessors() const
Returns true if this block has any predecessors.
void swapSuccessors()
Swap successors of the block. The block must have exactly 2 successors.
void printSuccessors(raw_ostream &O, const Twine &Indent) const
Print the successors of this block to O, prefixing all lines with Indent.
SmallVectorImpl< VPBlockBase * > VPBlocksTy
virtual ~VPBlockBase()=default
const VPBlocksTy & getHierarchicalPredecessors()
unsigned getIndexForSuccessor(const VPBlockBase *Succ) const
Returns the index for Succ in the blocks successor list.
size_t getNumPredecessors() const
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
VPBlockBase * getEnclosingBlockWithPredecessors()
unsigned getIndexForPredecessor(const VPBlockBase *Pred) const
Returns the index for Pred in the blocks predecessors list.
const VPBlocksTy & getPredecessors() const
virtual VPBlockBase * clone()=0
Clone the current block and it's recipes without updating the operands of the cloned recipes,...
enum { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC } VPBlockTy
An enumeration for keeping track of the concrete subclass of VPBlockBase that are actually instantiat...
virtual InstructionCost cost(ElementCount VF, VPCostContext &Ctx)=0
Return the cost of the block.
void setPlan(VPlan *ParentPlan)
Sets the pointer of the plan containing the block.
const VPRegionBlock * getParent() const
const std::string & getName() const
void clearSuccessors()
Remove all the successors of this block.
VPBlockBase * getSingleHierarchicalSuccessor()
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
VPBlockBase * getSinglePredecessor() const
virtual void execute(VPTransformState *State)=0
The method which generates the output IR that correspond to this VPBlockBase, thereby "executing" the...
const VPBlocksTy & getHierarchicalSuccessors()
void clearPredecessors()
Remove all the predecessor of this block.
friend class VPBlockUtils
unsigned getVPBlockID() const
void printAsOperand(raw_ostream &OS, bool PrintType=false) const
void swapPredecessors()
Swap predecessors of the block.
VPBlockBase(const unsigned char SC, const std::string &N)
VPBlocksTy & getSuccessors()
VPBlockBase * getEnclosingBlockWithSuccessors()
An Enclosing Block of a block B is any block containing B, including B itself.
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 * getSingleHierarchicalPredecessor()
VPBlockBase * getSingleSuccessor() const
const VPBlocksTy & getSuccessors() const
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPBranchOnMaskRecipe * clone() override
Clone the current recipe.
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
VPBranchOnMaskRecipe(VPValue *BlockInMask, DebugLoc DL)
VPlan-based builder utility analogous to IRBuilder.
Canonical scalar induction phi of the vector loop.
~VPCanonicalIVPHIRecipe() override=default
VPCanonicalIVPHIRecipe(VPIRValue *StartV, DebugLoc DL)
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPCanonicalIVPHIRecipe * clone() override
Clone the current recipe.
LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
bool usesFirstPartOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
VPIRValue * getStartValue() const
Returns the start value of the canonical induction.
Type * getScalarType() const
Returns the scalar type of the induction.
void execute(VPTransformState &State) override
Generate the phi nodes.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPCanonicalIVPHIRecipe.
VPCurrentIterationPHIRecipe * clone() override
Clone the current recipe.
VPCurrentIterationPHIRecipe(VPValue *StartIV, DebugLoc DL)
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPCurrentIterationPHIRecipe.
LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate the phi nodes.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
~VPCurrentIterationPHIRecipe() override=default
void execute(VPTransformState &State) override
Generate the transformed value of the induction at offset StartValue (1.
VPIRValue * getStartValue() const
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPDerivedIVRecipe.
VPValue * getStepValue() const
VPDerivedIVRecipe(const InductionDescriptor &IndDesc, VPIRValue *Start, VPCanonicalIVPHIRecipe *CanonicalIV, VPValue *Step, const Twine &Name="")
Type * getScalarType() const
VPDerivedIVRecipe * clone() override
Clone the current recipe.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
~VPDerivedIVRecipe() override=default
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPDerivedIVRecipe(InductionDescriptor::InductionKind Kind, const FPMathOperator *FPBinOp, VPIRValue *Start, VPValue *IV, VPValue *Step, const Twine &Name="")
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPExpandSCEVRecipe.
VPExpandSCEVRecipe(const SCEV *Expr)
const SCEV * getSCEV() const
VPExpandSCEVRecipe * clone() override
Clone the current recipe.
~VPExpandSCEVRecipe() override=default
void execute(VPTransformState &State) override
Method for generating code, must not be called as this recipe is abstract.
VPValue * getOperandOfResultType() const
Return the VPValue to use to infer the result type of the recipe.
VPExpressionRecipe * clone() override
Clone the current recipe.
void decompose()
Insert the recipes of the expression back into the VPlan, directly before the current recipe.
~VPExpressionRecipe() override
bool isSingleScalar() const
Returns true if the result of this VPExpressionRecipe is a single-scalar.
VPExpressionRecipe(VPWidenCastRecipe *Ext0, VPWidenCastRecipe *Ext1, VPWidenRecipe *Mul, VPWidenRecipe *Sub, VPReductionRecipe *Red)
VPExpressionRecipe(VPWidenCastRecipe *Ext, VPReductionRecipe *Red)
bool mayHaveSideEffects() const
Returns true if this expression contains recipes that may have side effects.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Compute the cost of this recipe either using a recipe's specialized implementation or using the legac...
bool mayReadOrWriteMemory() const
Returns true if this expression contains recipes that may read from or write to memory.
VPExpressionRecipe(VPWidenCastRecipe *Ext0, VPWidenCastRecipe *Ext1, VPWidenRecipe *Mul, VPReductionRecipe *Red)
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
unsigned getVFScaleFactor() const
VPExpressionRecipe(VPWidenRecipe *Mul, VPReductionRecipe *Red)
void execute(VPTransformState &State) override
Produce a vectorized histogram operation.
VPHistogramRecipe * clone() override
Clone the current recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPHistogramRecipe.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPValue * getMask() const
Return the mask operand if one was provided, or a null pointer if all lanes should be executed uncond...
unsigned getOpcode() const
VPHistogramRecipe(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
VP_CLASSOF_IMPL(VPRecipeBase::VPHistogramSC)
~VPHistogramRecipe() override=default
A special type of VPBasicBlock that wraps an existing IR basic block.
void execute(VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock,...
BasicBlock * getIRBasicBlock() const
static bool classof(const VPBlockBase *V)
~VPIRBasicBlock() override=default
VPIRBasicBlock * clone() override
Clone the current block and it's recipes, without updating the operands of the cloned recipes.
Class to record and manage LLVM IR flags.
ReductionFlagsTy ReductionFlags
LLVM_ABI_FOR_TEST bool hasRequiredFlagsForOpcode(unsigned Opcode) const
Returns true if Opcode has its required flags set.
VPIRFlags(RecurKind Kind, bool IsOrdered, bool IsInLoop, FastMathFlags FMFs)
LLVM_ABI_FOR_TEST bool flagsValidForOpcode(unsigned Opcode) const
Returns true if the set flags are valid for Opcode.
static VPIRFlags getDefaultFlags(unsigned Opcode)
Returns default flags for Opcode for opcodes that support it, asserts otherwise.
VPIRFlags(DisjointFlagsTy DisjointFlags)
VPIRFlags(WrapFlagsTy WrapFlags)
void printFlags(raw_ostream &O) const
VPIRFlags(CmpInst::Predicate Pred, FastMathFlags FMFs)
bool hasFastMathFlags() const
Returns true if the recipe has fast-math flags.
LLVM_ABI_FOR_TEST FastMathFlags getFastMathFlags() const
bool isReductionOrdered() const
CmpInst::Predicate getPredicate() const
bool hasNonNegFlag() const
Returns true if the recipe has non-negative flag.
void transferFlags(VPIRFlags &Other)
bool hasNoSignedWrap() const
void intersectFlags(const VPIRFlags &Other)
Only keep flags also present in Other.
VPIRFlags(TruncFlagsTy TruncFlags)
VPIRFlags(FastMathFlags FMFs)
VPIRFlags(NonNegFlagsTy NonNegFlags)
VPIRFlags(CmpInst::Predicate Pred)
VPIRFlags(ExactFlagsTy ExactFlags)
GEPNoWrapFlags getGEPNoWrapFlags() const
bool hasPredicate() const
Returns true if the recipe has a comparison predicate.
DisjointFlagsTy DisjointFlags
void setPredicate(CmpInst::Predicate Pred)
bool hasNoUnsignedWrap() const
NonNegFlagsTy NonNegFlags
bool isReductionInLoop() const
void dropPoisonGeneratingFlags()
Drop all poison-generating flags.
void applyFlags(Instruction &I) const
Apply the IR flags to I.
VPIRFlags(GEPNoWrapFlags GEPFlags)
RecurKind getRecurKind() const
VPIRFlags(Instruction &I)
Instruction & getInstruction() const
bool usesFirstPartOnly(const VPValue *Op) const override
Returns true if the VPUser only uses the first part of operand Op.
~VPIRInstruction() override=default
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
VPIRInstruction * clone() override
Clone the current recipe.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
static LLVM_ABI_FOR_TEST VPIRInstruction * create(Instruction &I)
Create a new VPIRPhi for \I , if it is a PHINode, otherwise create a VPIRInstruction.
LLVM_ABI_FOR_TEST InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPIRInstruction.
bool usesScalars(const VPValue *Op) const override
Returns true if the VPUser uses scalars of operand Op.
VPIRInstruction(Instruction &I)
VPIRInstruction::create() should be used to create VPIRInstructions, as subclasses may need to be cre...
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPInstructionWithType(unsigned Opcode, ArrayRef< VPValue * > Operands, Type *ResultTy, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPInstruction.
static bool classof(const VPUser *R)
static bool classof(const VPRecipeBase *R)
Type * getResultType() const
VPInstruction * clone() override
Clone the current recipe.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate the instruction.
This is a concrete Recipe that models a single VPlan-level instruction.
unsigned getNumOperandsWithoutMask() const
Returns the number of operands, excluding the mask if the VPInstruction is masked.
iterator_range< operand_iterator > operandsWithoutMask()
Returns an iterator range over the operands excluding the mask operand if present.
VPInstruction * clone() override
Clone the current recipe.
@ ExtractLastActive
Extracts the lane from the first operand corresponding to the last active (non-zero) lane in the mask...
@ 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...
@ ComputeAnyOfResult
Compute the final result of a AnyOf reduction with select(cmp(),x,y), where one of (x,...
@ WideIVStep
Scale the first operand (vector step) by the second operand (scalar-step).
@ ExtractPenultimateElement
@ ResumeForEpilogue
Explicit user for the resume phi of the canonical induction in the main VPlan, used by the epilogue v...
@ Unpack
Extracts all lanes from its (non-scalable) vector operand.
@ FirstOrderRecurrenceSplice
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
@ 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 ...
@ VScale
Returns the value for vscale.
@ CanonicalIVIncrementForPart
@ CalculateTripCountMinusVF
iterator_range< const_operand_iterator > operandsWithoutMask() const
void addMask(VPValue *Mask)
Add mask Mask to an unmasked VPInstruction, if it needs masking.
StringRef getName() const
Returns the symbolic name assigned to the VPInstruction.
unsigned getOpcode() const
VPInstruction(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
void setName(StringRef NewName)
Set the symbolic name for the VPInstruction.
VPValue * getMask() const
Returns the mask for the VPInstruction.
unsigned getNumOperandsForOpcode() const
Return the number of operands determined by the opcode of the VPInstruction, excluding mask.
bool isMasked() const
Returns true if the VPInstruction has a mask operand.
virtual unsigned getNumStoreOperands() const =0
Returns the number of stored operands of this interleave group.
bool usesFirstLaneOnly(const VPValue *Op) const override=0
Returns true if the recipe only uses the first lane of operand Op.
bool needsMaskForGaps() const
Return true if the access needs a mask because of the gaps.
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
static bool classof(const VPUser *U)
VPInterleaveBase(const unsigned char SC, const InterleaveGroup< Instruction > *IG, ArrayRef< VPValue * > Operands, ArrayRef< VPValue * > StoredValues, VPValue *Mask, bool NeedsMaskForGaps, const VPIRMetadata &MD, DebugLoc DL)
Instruction * getInsertPos() const
static bool classof(const VPRecipeBase *R)
const InterleaveGroup< Instruction > * getInterleaveGroup() const
VPValue * getMask() const
Return the mask used by this recipe.
ArrayRef< VPValue * > getStoredValues() const
Return the VPValues stored by this interleave group.
VPInterleaveBase * clone() override=0
Clone the current recipe.
VPValue * getAddr() const
Return the address accessed by this recipe.
A recipe for interleaved memory operations with vector-predication intrinsics.
bool usesFirstLaneOnly(const VPValue *Op) const override
The recipe only uses the first lane of the address, and EVL operand.
VPValue * getEVL() const
The VPValue of the explicit vector length.
~VPInterleaveEVLRecipe() override=default
unsigned getNumStoreOperands() const override
Returns the number of stored operands of this interleave group.
VPInterleaveEVLRecipe * clone() override
Clone the current recipe.
VPInterleaveEVLRecipe(VPInterleaveRecipe &R, VPValue &EVL, VPValue *Mask)
VPInterleaveRecipe is a recipe for transforming an interleave group of load or stores into one wide l...
unsigned getNumStoreOperands() const override
Returns the number of stored operands of this interleave group.
~VPInterleaveRecipe() override=default
VPInterleaveRecipe * clone() override
Clone the current recipe.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPInterleaveRecipe(const InterleaveGroup< Instruction > *IG, VPValue *Addr, ArrayRef< VPValue * > StoredValues, VPValue *Mask, bool NeedsMaskForGaps, const VPIRMetadata &MD, DebugLoc DL)
In what follows, the term "input IR" refers to code that is fed into the vectorizer whereas the term ...
Helper type to provide functions to access incoming values and blocks for phi-like recipes.
virtual const VPRecipeBase * getAsRecipe() const =0
Return a VPRecipeBase* to the current object.
VPValue * getIncomingValueForBlock(const VPBasicBlock *VPBB) const
Returns the incoming value for VPBB. VPBB must be an incoming block.
VPUser::const_operand_range incoming_values() const
Returns an interator range over the incoming values.
virtual unsigned getNumIncoming() const
Returns the number of incoming values, also number of incoming blocks.
void removeIncomingValueFor(VPBlockBase *IncomingBlock) const
Removes the incoming value for IncomingBlock, which must be a predecessor.
const VPBasicBlock * getIncomingBlock(unsigned Idx) const
Returns the incoming block with index Idx.
detail::zippy< llvm::detail::zip_first, VPUser::const_operand_range, const_incoming_blocks_range > incoming_values_and_blocks() const
Returns an iterator range over pairs of incoming values and corresponding incoming blocks.
VPValue * getIncomingValue(unsigned Idx) const
Returns the incoming VPValue with index Idx.
virtual ~VPPhiAccessors()=default
void printPhiOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const
Print the recipe.
void setIncomingValueForBlock(const VPBasicBlock *VPBB, VPValue *V) const
Sets the incoming value for VPBB to V.
iterator_range< mapped_iterator< detail::index_iterator, std::function< const VPBasicBlock *(size_t)> > > const_incoming_blocks_range
const_incoming_blocks_range incoming_blocks() const
Returns an iterator range over the incoming blocks.
~VPPredInstPHIRecipe() override=default
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
VPPredInstPHIRecipe * clone() override
Clone the current recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPPredInstPHIRecipe.
VPPredInstPHIRecipe(VPValue *PredV, DebugLoc DL)
Construct a VPPredInstPHIRecipe given PredInst whose value needs a phi nodes after merging 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.
virtual void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const =0
Each concrete VPRecipe prints itself, without printing common information, like debug info or metadat...
VPRegionBlock * getRegion()
void setDebugLoc(DebugLoc NewDL)
Set the recipe's debug location to NewDL.
bool mayWriteToMemory() const
Returns true if the recipe may write to memory.
~VPRecipeBase() override=default
VPBasicBlock * getParent()
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
virtual void execute(VPTransformState &State)=0
The method which generates the output IR instructions that correspond to this VPRecipe,...
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.
static bool classof(const VPDef *D)
Method to support type inquiry through isa, cast, and dyn_cast.
iplist< VPRecipeBase >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
virtual VPRecipeBase * clone()=0
Clone the current recipe.
friend class VPBlockUtils
const VPBasicBlock * getParent() const
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this recipe, taking into account if the cost computation should be skipped and the...
static bool classof(const VPUser *U)
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
unsigned getVPRecipeID() const
void moveAfter(VPRecipeBase *MovePos)
Unlink this recipe from its current VPBasicBlock and insert it into the VPBasicBlock that MovePos liv...
enum { VPBranchOnMaskSC, VPDerivedIVSC, VPExpandSCEVSC, VPExpressionSC, VPIRInstructionSC, VPInstructionSC, VPInterleaveEVLSC, VPInterleaveSC, VPReductionEVLSC, VPReductionSC, VPReplicateSC, VPScalarIVStepsSC, VPVectorPointerSC, VPVectorEndPointerSC, VPWidenCallSC, VPWidenCanonicalIVSC, VPWidenCastSC, VPWidenGEPSC, VPWidenIntrinsicSC, VPWidenLoadEVLSC, VPWidenLoadSC, VPWidenStoreEVLSC, VPWidenStoreSC, VPWidenSC, VPBlendSC, VPHistogramSC, VPWidenPHISC, VPPredInstPHISC, VPCanonicalIVPHISC, VPCurrentIterationPHISC, VPActiveLaneMaskPHISC, VPFirstOrderRecurrencePHISC, VPWidenIntOrFpInductionSC, VPWidenPointerInductionSC, VPReductionPHISC, VPFirstPHISC=VPWidenPHISC, VPFirstHeaderPHISC=VPCanonicalIVPHISC, VPLastHeaderPHISC=VPReductionPHISC, VPLastPHISC=VPReductionPHISC, } VPRecipeTy
An enumeration for keeping track of the concrete subclass of VPRecipeBase that is actually instantiat...
VPRecipeBase(const unsigned char SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
A VPValue defined by a recipe that produces one or more values.
LLVM_ABI_FOR_TEST VPRecipeValue(VPRecipeBase *Def, Value *UV=nullptr)
VPValue * getEVL() const
The VPValue of the explicit vector length.
VPReductionEVLRecipe(VPReductionRecipe &R, VPValue &EVL, VPValue *CondOp, DebugLoc DL=DebugLoc::getUnknown())
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPReductionEVLRecipe * clone() override
Clone the current recipe.
~VPReductionEVLRecipe() override=default
bool isOrdered() const
Returns true, if the phi is part of an ordered reduction.
void setVFScaleFactor(unsigned ScaleFactor)
Set the VFScaleFactor for this reduction phi.
VPReductionPHIRecipe * clone() override
Clone the current recipe.
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.
~VPReductionPHIRecipe() override=default
bool hasUsesOutsideReductionChain() const
Returns true, if the phi is part of a multi-use reduction.
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
VPReductionPHIRecipe(PHINode *Phi, RecurKind Kind, VPValue &Start, VPValue &BackedgeValue, ReductionStyle Style, const VPIRFlags &Flags, bool HasUsesOutsideReductionChain=false)
Create a new VPReductionPHIRecipe for the reduction Phi.
bool isInLoop() const
Returns true if the phi is part of an in-loop reduction.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate the phi/select nodes.
bool isPartialReduction() const
Returns true if the reduction outputs a vector with a scaled down VF.
RecurKind getRecurrenceKind() const
Returns the recurrence kind of the reduction.
A recipe to represent inloop, ordered or partial reduction operations.
VPReductionRecipe(const unsigned char SC, RecurKind RdxKind, FastMathFlags FMFs, Instruction *I, ArrayRef< VPValue * > Operands, VPValue *CondOp, ReductionStyle Style, DebugLoc DL)
bool isConditional() const
Return true if the in-loop reduction is conditional.
static bool classof(const VPRecipeBase *R)
static bool classof(const VPSingleDefRecipe *R)
VPValue * getVecOp() const
The VPValue of the vector value to be reduced.
VPValue * getCondOp() const
The VPValue of the condition for the block.
RecurKind getRecurrenceKind() const
Return the recurrence kind for the in-loop reduction.
VPReductionRecipe(RecurKind RdxKind, FastMathFlags FMFs, Instruction *I, VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp, ReductionStyle Style, DebugLoc DL=DebugLoc::getUnknown())
bool isOrdered() const
Return true if the in-loop reduction is ordered.
VPReductionRecipe(const RecurKind RdxKind, FastMathFlags FMFs, VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp, ReductionStyle Style, DebugLoc DL=DebugLoc::getUnknown())
bool isPartialReduction() const
Returns true if the reduction outputs a vector with a scaled down VF.
~VPReductionRecipe() override=default
VPValue * getChainOp() const
The VPValue of the scalar Chain being accumulated.
bool isInLoop() const
Returns true if the reduction is in-loop.
VPReductionRecipe * clone() override
Clone the current recipe.
static bool classof(const VPUser *U)
static bool classof(const VPValue *VPV)
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.
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
const VPBlockBase * getEntry() const
Type * getCanonicalIVType()
Return the type of the canonical IV for loop regions.
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
~VPRegionBlock() override=default
void setExiting(VPBlockBase *ExitingBlock)
Set ExitingBlock as the exiting VPBlockBase of this VPRegionBlock.
VPBlockBase * getExiting()
VPCanonicalIVPHIRecipe * getCanonicalIV()
Returns the canonical induction recipe of the region.
void setEntry(VPBlockBase *EntryBlock)
Set EntryBlock as the entry VPBlockBase of this VPRegionBlock.
const Type * getCanonicalIVType() const
const VPBlockBase * getExiting() const
const VPCanonicalIVPHIRecipe * getCanonicalIV() const
VPBasicBlock * getPreheaderVPBB()
Returns the pre-header VPBasicBlock of the loop region.
static bool classof(const VPBlockBase *V)
Method to support type inquiry through isa, cast, and dyn_cast.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
bool isSingleScalar() const
VPReplicateRecipe(Instruction *I, ArrayRef< VPValue * > Operands, bool IsSingleScalar, VPValue *Mask=nullptr, const VPIRFlags &Flags={}, VPIRMetadata Metadata={}, DebugLoc DL=DebugLoc::getUnknown())
~VPReplicateRecipe() override=default
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
bool isPredicated() const
VPReplicateRecipe * clone() override
Clone the current recipe.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
unsigned getOpcode() const
VPValue * getMask()
Return the mask of a predicated VPReplicateRecipe.
VPValue * getStepValue() const
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPScalarIVStepsRecipe.
VPScalarIVStepsRecipe(const InductionDescriptor &IndDesc, VPValue *IV, VPValue *Step, VPValue *VF, DebugLoc DL=DebugLoc::getUnknown())
VPScalarIVStepsRecipe * clone() override
Clone the current recipe.
VPValue * getStartIndex() const
Return the StartIndex, or null if known to be zero, valid only after unrolling.
VPValue * getVFValue() const
Return the number of scalars to produce per unroll part, used to compute StartIndex during unrolling.
VPScalarIVStepsRecipe(VPValue *IV, VPValue *Step, VPValue *VF, Instruction::BinaryOps Opcode, FastMathFlags FMFs, DebugLoc DL)
~VPScalarIVStepsRecipe() override=default
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
VPSingleDefRecipe(const unsigned char SC, ArrayRef< VPValue * > Operands, Value *UV, DebugLoc DL=DebugLoc::getUnknown())
static bool classof(const VPValue *V)
Instruction * getUnderlyingInstr()
Returns the underlying instruction.
static bool classof(const VPRecipeBase *R)
const Instruction * getUnderlyingInstr() const
static bool classof(const VPUser *U)
LLVM_ABI_FOR_TEST LLVM_DUMP_METHOD void dump() const
Print this VPSingleDefRecipe to dbgs() (for debugging).
VPSingleDefRecipe * clone() override=0
Clone the current recipe.
VPSingleDefRecipe(const unsigned char SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
This class can be used to assign names to VPValues.
Helper to access the operand that contains the unroll part for this recipe after unrolling.
VPValue * getUnrollPartOperand(const VPUser &U) const
Return the VPValue operand containing the unroll part or null if there is no such operand.
unsigned getUnrollPart(const VPUser &U) const
Return the unroll part.
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
void printOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const
Print the operands to O.
void setOperand(unsigned I, VPValue *New)
unsigned getNumOperands() const
operand_iterator op_end()
operand_iterator op_begin()
VPValue * getOperand(unsigned N) const
VPUser(ArrayRef< VPValue * > Operands)
iterator_range< const_operand_iterator > const_operand_range
iterator_range< operand_iterator > operand_range
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Value * getLiveInIRValue() const
Return the underlying IR value for a VPIRValue.
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
friend class VPRecipeValue
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
void setUnderlyingValue(Value *Val)
unsigned getNumUsers() const
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
VPValue * getVFValue() const
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
Type * getSourceElementType() const
int64_t getStride() const
VPVectorEndPointerRecipe * clone() override
Clone the current recipe.
VPValue * getOffset() const
bool usesFirstPartOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
VPVectorEndPointerRecipe(VPValue *Ptr, VPValue *VF, Type *SourceElementTy, int64_t Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPVectorPointerRecipe.
VPValue * getPointer() const
void materializeOffset(unsigned Part=0)
Adds the offset operand to the recipe.
Type * getSourceElementType() const
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
bool usesFirstPartOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
VPVectorPointerRecipe(VPValue *Ptr, Type *SourceElementTy, GEPNoWrapFlags GEPFlags, DebugLoc DL)
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPHeaderPHIRecipe.
VPVectorPointerRecipe * clone() override
Clone the current recipe.
A recipe for widening Call instructions using library calls.
VPWidenCallRecipe(Value *UV, Function *Variant, ArrayRef< VPValue * > CallArguments, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL={})
const_operand_range args() const
VPWidenCallRecipe * clone() override
Clone the current recipe.
Function * getCalledScalarFunction() const
~VPWidenCallRecipe() override=default
void execute(VPTransformState &State) override
Generate a canonical vector induction variable of the vector loop, with start = {<Part*VF,...
~VPWidenCanonicalIVRecipe() override=default
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenCanonicalIVPHIRecipe.
VPWidenCanonicalIVRecipe * clone() override
Clone the current recipe.
VPWidenCanonicalIVRecipe(VPCanonicalIVPHIRecipe *CanonicalIV)
VPWidenCastRecipe is a recipe to create vector cast instructions.
Instruction::CastOps getOpcode() const
LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
Type * getResultType() const
Returns the result type of the cast.
LLVM_ABI_FOR_TEST void execute(VPTransformState &State) override
Produce widened copies of the cast.
~VPWidenCastRecipe() override=default
LLVM_ABI_FOR_TEST InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenCastRecipe.
VPWidenCastRecipe(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, CastInst *CI=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL=DebugLoc::getUnknown())
VPWidenCastRecipe * clone() override
Clone the current recipe.
unsigned getOpcode() const
This recipe generates a GEP instruction.
Type * getSourceElementType() const
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenGEPRecipe.
VPWidenGEPRecipe * clone() override
Clone the current recipe.
~VPWidenGEPRecipe() override=default
VPWidenGEPRecipe(GetElementPtrInst *GEP, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags={}, DebugLoc DL=DebugLoc::getUnknown())
void execute(VPTransformState &State) override=0
Generate the phi nodes.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
static bool classof(const VPValue *V)
void setStepValue(VPValue *V)
Update the step value of the recipe.
VPValue * getBackedgeValue() override
Returns the incoming value from the loop backedge.
VPIRValue * getStartValue() const
Returns the start value of the induction.
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
PHINode * getPHINode() const
Returns the underlying PHINode if one exists, or null otherwise.
VPWidenInductionRecipe(unsigned char Kind, PHINode *IV, VPValue *Start, VPValue *Step, const InductionDescriptor &IndDesc, DebugLoc DL)
VPValue * getStepValue()
Returns the step value of the induction.
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
VPRecipeBase & getBackedgeRecipe() override
Returns the backedge value as a recipe.
static bool classof(const VPRecipeBase *R)
const VPValue * getVFValue() const
static bool classof(const VPSingleDefRecipe *R)
const VPValue * getStepValue() const
VPIRValue * getStartValue() const
Returns the start value of the induction.
const TruncInst * getTruncInst() const
void execute(VPTransformState &State) override
Generate the phi nodes.
~VPWidenIntOrFpInductionRecipe() override=default
VPValue * getSplatVFValue() const
If the recipe has been unrolled, return the VPValue for the induction increment, otherwise return nul...
VPWidenIntOrFpInductionRecipe * clone() override
Clone the current recipe.
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPIRValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, const VPIRFlags &Flags, DebugLoc DL)
TruncInst * getTruncInst()
Returns the first defined value as TruncInst, if it is one or nullptr otherwise.
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPIRValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, TruncInst *Trunc, const VPIRFlags &Flags, DebugLoc DL)
VPValue * getLastUnrolledPartOperand()
Returns the VPValue representing the value of this induction at the last unrolled part,...
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
Type * getScalarType() const
Returns the scalar type of the induction.
bool isCanonical() const
Returns true if the induction is canonical, i.e.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
A recipe for widening vector intrinsics.
VPWidenIntrinsicRecipe(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL=DebugLoc::getUnknown())
Intrinsic::ID getVectorIntrinsicID() const
Return the ID of the intrinsic.
LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
bool mayReadFromMemory() const
Returns true if the intrinsic may read from memory.
StringRef getIntrinsicName() const
Return to name of the intrinsic as string.
VPWidenIntrinsicRecipe(CallInst &CI, Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown())
bool mayHaveSideEffects() const
Returns true if the intrinsic may have side-effects.
VPWidenIntrinsicRecipe * clone() override
Clone the current recipe.
bool mayWriteToMemory() const
Returns true if the intrinsic may write to memory.
~VPWidenIntrinsicRecipe() override=default
LLVM_ABI_FOR_TEST bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
Type * getResultType() const
Return the scalar return type of the intrinsic.
LLVM_ABI_FOR_TEST void execute(VPTransformState &State) override
Produce a widened version of the vector intrinsic.
LLVM_ABI_FOR_TEST InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this vector intrinsic.
bool IsMasked
Whether the memory access is masked.
bool Reverse
Whether the consecutive accessed addresses are in reverse order.
bool isConsecutive() const
Return whether the loaded-from / stored-to addresses are consecutive.
static bool classof(const VPUser *U)
void execute(VPTransformState &State) override
Generate the wide load/store.
VPWidenMemoryRecipe * clone() override
Clone the current recipe.
Instruction & getIngredient() const
bool Consecutive
Whether the accessed addresses are consecutive.
static bool classof(const VPRecipeBase *R)
VPValue * getMask() const
Return the mask used by this recipe.
Align Alignment
Alignment information for this memory access.
bool isMasked() const
Returns true if the recipe is masked.
VPWidenMemoryRecipe(const char unsigned SC, Instruction &I, std::initializer_list< VPValue * > Operands, bool Consecutive, bool Reverse, const VPIRMetadata &Metadata, DebugLoc DL)
void setMask(VPValue *Mask)
Align getAlign() const
Returns the alignment of the memory access.
VPValue * getAddr() const
Return the address accessed by this recipe.
bool isReverse() const
Return whether the consecutive loaded/stored addresses are in reverse order.
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
VPWidenPHIRecipe(PHINode *Phi, VPValue *Start=nullptr, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new VPWidenPHIRecipe for Phi with start value Start and debug location DL.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenPHIRecipe.
VPWidenPHIRecipe * clone() override
Clone the current recipe.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
~VPWidenPHIRecipe() override=default
void execute(VPTransformState &State) override
Generate the phi/select nodes.
VPWidenPointerInductionRecipe * clone() override
Clone the current recipe.
~VPWidenPointerInductionRecipe() override=default
bool onlyScalarsGenerated(bool IsScalable)
Returns true if only scalar values will be generated.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate vector values for the pointer induction.
VPWidenPointerInductionRecipe(PHINode *Phi, VPValue *Start, VPValue *Step, VPValue *NumUnrolledElems, const InductionDescriptor &IndDesc, DebugLoc DL)
Create a new VPWidenPointerInductionRecipe for Phi with start value Start and the number of elements ...
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
VPWidenRecipe * clone() override
Clone the current recipe.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPWidenRecipe(Instruction &I, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL={})
VPWidenRecipe(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, DebugLoc DL={})
~VPWidenRecipe() override=default
unsigned getOpcode() const
Class that maps (parts of) an existing VPlan to trees of combined VPInstructions.
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.
LLVM_ABI_FOR_TEST void printDOT(raw_ostream &O) const
Print this VPlan in DOT format to O.
friend class VPSlotTracker
std::string getName() const
Return a string with the name of the plan and the applicable VFs and UFs.
bool hasVF(ElementCount VF) const
LLVMContext & getContext() const
VPBasicBlock * getEntry()
void setName(const Twine &newName)
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 * getOrCreateBackedgeTakenCount()
The backedge taken count of the original loop.
iterator_range< SmallSetVector< ElementCount, 2 >::iterator > vectorFactors() const
Returns an iterator range over all VFs of the plan.
VPIRBasicBlock * getExitBlock(BasicBlock *IRBB) const
Return the VPIRBasicBlock corresponding to IRBB.
LLVM_ABI_FOR_TEST ~VPlan()
VPIRValue * getOrAddLiveIn(VPIRValue *V)
const VPValue & getVF() const
VPValue & getUF()
Returns the UF of the vector loop region.
bool isExitBlock(VPBlockBase *VPBB)
Returns true if VPBB is an exit block.
const VPBasicBlock * getEntry() const
friend class VPlanPrinter
VPIRValue * getFalse()
Return a VPIRValue wrapping i1 false.
VPIRValue * getConstantInt(const APInt &Val)
Return a VPIRValue wrapping a ConstantInt with the given APInt value.
VPIRValue * getAllOnesValue(Type *Ty)
Return a VPIRValue wrapping the AllOnes value of type Ty.
VPRegionBlock * createReplicateRegion(VPBlockBase *Entry, VPBlockBase *Exiting, const std::string &Name="")
Create a new replicate region with Entry, Exiting and Name.
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
auto getLiveIns() const
Return the list of live-in VPValues available in the VPlan.
bool hasUF(unsigned UF) const
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
VPSymbolicValue & getVectorTripCount()
The vector trip count.
VPValue * getBackedgeTakenCount() const
VPIRValue * getOrAddLiveIn(Value *V)
Gets the live-in VPIRValue for V or adds a new live-in (if none exists yet) for V.
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
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.
bool hasEarlyExit() const
Returns true if the VPlan is based on a loop with an early exit.
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this plan.
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
VPIRValue * getConstantInt(unsigned BitWidth, uint64_t Val, bool IsSigned=false)
Return a VPIRValue wrapping a ConstantInt with the given bitwidth and value.
const VPBasicBlock * getMiddleBlock() const
void setTripCount(VPValue *NewTripCount)
Set the trip count assuming it is currently null; if it is not - use resetTripCount().
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 ...
void setEntry(VPBasicBlock *VPBB)
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
LLVM_ABI_FOR_TEST VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
void removeVF(ElementCount VF)
Remove VF from the plan.
VPIRValue * getTrue()
Return a VPIRValue wrapping i1 true.
VPRegionBlock * createLoopRegion(const std::string &Name="", VPBlockBase *Entry=nullptr, VPBlockBase *Exiting=nullptr)
Create a new loop region with Name and entry and exiting blocks set to Entry and Exiting respectively...
LLVM_DUMP_METHOD void dump() const
Dump the plan to stderr (for debugging).
bool hasScalarVFOnly() const
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
void execute(VPTransformState *State)
Generate the IR code for this VPlan.
LLVM_ABI_FOR_TEST void print(raw_ostream &O) const
Print this VPlan to O.
void addVF(ElementCount VF)
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
void printLiveIns(raw_ostream &O) const
Print the live-ins of this VPlan to O.
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_ABI_FOR_TEST VPlan * duplicate()
Clone the current VPlan, update all VPValues of the new VPlan and cloned recipes to refer to the clon...
VPlan(BasicBlock *ScalarHeaderBB)
Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock wrapping ScalarHeaderBB and a tr...
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.
ilist_node_with_parent()=default
Increasing range of size_t indices.
typename base_list_type::const_reverse_iterator const_reverse_iterator
typename base_list_type::reverse_iterator reverse_iterator
typename base_list_type::iterator iterator
typename base_list_type::const_iterator const_iterator
An intrusive list with ownership and callbacks specified/controlled by ilist_traits,...
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
This file defines classes to implement an intrusive doubly linked list class (i.e.
This file defines the ilist_node class template, which is a convenient base class for creating classe...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI AttributeSet getFnAttributes(LLVMContext &C, ID id)
Return the function attributes for an intrinsic.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
static auto castToVPIRMetadata(RecipeBasePtrTy R) -> DstTy
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.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
auto cast_if_present(const Y &Val)
cast_if_present<X> - Functionally identical to cast, except that a null value is accepted.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void getMetadataToPropagate(Instruction *Inst, SmallVectorImpl< std::pair< unsigned, MDNode * > > &Metadata)
Add metadata from Inst to Metadata, if it can be preserved after vectorization.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
auto cast_or_null(const Y &Val)
Align getLoadStoreAlignment(const Value *I)
A helper function that returns the alignment of load or store instruction.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool 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.
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...
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
constexpr unsigned BitWidth
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
std::variant< RdxOrdered, RdxInLoop, RdxUnordered > ReductionStyle
std::unique_ptr< VPlan > VPlanPtr
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static Bitfield::Type get(StorageType Packed)
Unpacks the field from the Packed value.
static void set(StorageType &Packed, typename Bitfield::Type Value)
Sets the typed value in the provided Packed value.
Support casting from VPRecipeBase -> VPPhiAccessors, by down-casting to the recipe types implementing...
static VPPhiAccessors * doCastIfPossible(SrcTy f)
doCastIfPossible is used by dyn_cast<>.
CastInfo< VPPhiAccessors, SrcTy > Self
static VPPhiAccessors * doCast(SrcTy R)
doCast is used by cast<>.
This struct provides a method for customizing the way a cast is performed.
static bool isPossible(const VPRecipeBase *f)
This struct provides a way to check if a given cast is possible.
static bool isPossible(const SrcTy &f)
This reduction is in-loop.
Possible variants of a reduction.
This reduction is unordered with the partial result scaled down by some factor.
A MapVector that performs no allocations if smaller than a certain size.
An overlay on VPIRValue for VPValues that wrap a ConstantInt.
Struct to hold various analysis needed for cost computations.
void execute(VPTransformState &State) override
Generate the phi nodes.
VPFirstOrderRecurrencePHIRecipe * clone() override
Clone the current recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this first-order recurrence phi recipe.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPFirstOrderRecurrencePHIRecipe(PHINode *Phi, VPValue &Start, VPValue &BackedgeValue)
DisjointFlagsTy(bool IsDisjoint)
NonNegFlagsTy(bool IsNonNeg)
TruncFlagsTy(bool HasNUW, bool HasNSW)
WrapFlagsTy(bool HasNUW, bool HasNSW)
static bool classof(const VPRecipeBase *U)
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
A VPValue representing a live-in from the input IR or a constant.
Type * getType() const
Returns the type of the underlying IR value.
static bool classof(const VPUser *U)
VPPhi(ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL, const Twine &Name="")
VPPhi * clone() override
Clone the current recipe.
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
static bool classof(const VPSingleDefRecipe *SDR)
static bool classof(const VPValue *V)
A pure-virtual common base class for recipes defining a single VPValue and using IR flags.
static bool classof(const VPSingleDefRecipe *R)
static bool classof(const VPRecipeBase *R)
InstructionCost getCostForRecipeWithOpcode(unsigned Opcode, ElementCount VF, VPCostContext &Ctx) const
Compute the cost for this recipe for VF, using Opcode and Ctx.
VPRecipeWithIRFlags(const unsigned char SC, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown())
static bool classof(const VPValue *V)
void execute(VPTransformState &State) override=0
The method which generates the output IR instructions that correspond to this VPRecipe,...
VPRecipeWithIRFlags * clone() override=0
Clone the current recipe.
static bool classof(const VPUser *U)
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
A recipe for widening load operations with vector-predication intrinsics, using the address to load f...
LLVM_ABI_FOR_TEST void execute(VPTransformState &State) override
Generate the wide load or gather.
LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
LLVM_ABI_FOR_TEST InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenLoadEVLRecipe.
VPValue * getEVL() const
Return the EVL operand.
VPWidenLoadEVLRecipe(VPWidenLoadRecipe &L, VPValue *Addr, VPValue &EVL, VPValue *Mask)
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
A recipe for widening load operations, using the address to load from and an optional mask.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
void execute(VPTransformState &State) override
Generate a wide load or gather.
VPWidenLoadRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, bool Reverse, const VPIRMetadata &Metadata, DebugLoc DL)
VPWidenLoadRecipe * clone() override
Clone the current recipe.
VP_CLASSOF_IMPL(VPRecipeBase::VPWidenLoadSC)
A recipe for widening store operations with vector-predication intrinsics, using the value to store,...
VPValue * getStoredValue() const
Return the address accessed by this recipe.
LLVM_ABI_FOR_TEST void execute(VPTransformState &State) override
Generate the wide store or scatter.
VPWidenStoreEVLRecipe(VPWidenStoreRecipe &S, VPValue *Addr, VPValue *StoredVal, VPValue &EVL, VPValue *Mask)
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
LLVM_ABI_FOR_TEST void printRecipe(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
LLVM_ABI_FOR_TEST InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenStoreEVLRecipe.
VPValue * getEVL() const
Return the EVL operand.
A recipe for widening store operations, using the stored value, the address to store to and an option...
VP_CLASSOF_IMPL(VPRecipeBase::VPWidenStoreSC)
VPValue * getStoredValue() const
Return the value stored by this recipe.
VPWidenStoreRecipe * clone() override
Clone the current recipe.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPWidenStoreRecipe(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, bool Reverse, const VPIRMetadata &Metadata, DebugLoc DL)