24#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
25#define LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
68template <
typename InserterTy = VPBuilderDefaultInserter>
class VPBuilderBase;
129 VPlan *Plan =
nullptr;
132 const VPBlockTy SubclassID;
144 void appendPredecessor(VPBlockBase *Predecessor) {
145 assert(Predecessor &&
"Cannot add nullptr predecessor!");
150 void removePredecessor(VPBlockBase *Predecessor) {
151 auto Pos =
find(Predecessors, Predecessor);
152 assert(Pos &&
"Predecessor does not exist");
153 Predecessors.
erase(Pos);
157 void removeSuccessor(VPBlockBase *Successor) {
158 auto Pos =
find(Successors, Successor);
159 assert(Pos &&
"Successor does not exist");
160 Successors.
erase(Pos);
165 void replacePredecessor(VPBlockBase *Old, VPBlockBase *New) {
166 auto I =
find(Predecessors, Old);
168 assert(Old->getParent() ==
New->getParent() &&
169 "replaced predecessor must have the same parent");
175 void replaceSuccessor(VPBlockBase *Old, VPBlockBase *New) {
176 auto I =
find(Successors, Old);
178 assert(Old->getParent() ==
New->getParent() &&
179 "replaced successor must have the same parent");
188 const std::string &
getName()
const {
return Name; }
238 return (Successors.size() == 1 ? *Successors.begin() :
nullptr);
244 return (Predecessors.size() == 1 ? *Predecessors.begin() :
nullptr);
281 assert(Successors.empty() &&
"Setting one successor when others exist.");
283 "connected blocks must have the same parent");
292 assert(Successors.empty() &&
"Setting two successors when others exist.");
293 appendSuccessor(IfTrue);
294 appendSuccessor(IfFalse);
301 assert(Predecessors.empty() &&
"Block predecessors already set.");
302 for (
auto *Pred : NewPreds)
303 appendPredecessor(Pred);
310 assert(Successors.empty() &&
"Block successors already set.");
311 for (
auto *Succ : NewSuccs)
312 appendSuccessor(Succ);
324 assert(Predecessors.size() == 2 &&
"must have 2 predecessors to swap");
325 std::swap(Predecessors[0], Predecessors[1]);
332 assert(Successors.size() == 2 &&
"must have 2 successors to swap");
339 "must have Pred exactly once in Predecessors");
340 return std::distance(Predecessors.begin(),
find(Predecessors, Pred));
346 "must have Succ exactly once in Successors");
347 return std::distance(Successors.begin(),
find(Successors, Succ));
367#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
404 ilist_parent<VPBasicBlock>>,
432 VPVectorEndPointerSC,
434 VPWidenCanonicalIVSC,
438 VPWidenMemIntrinsicSC,
451 VPCurrentIterationPHISC,
452 VPActiveLaneMaskPHISC,
453 VPFirstOrderRecurrencePHISC,
454 VPWidenIntOrFpInductionSC,
455 VPWidenPointerInductionSC,
459 VPFirstPHISC = VPWidenPHISC,
460 VPFirstHeaderPHISC = VPCurrentIterationPHISC,
461 VPLastHeaderPHISC = VPReductionPHISC,
462 VPLastPHISC = VPReductionPHISC,
467 :
VPDef(),
VPUser(Operands), DL(DL), SubclassID(SC) {}
539 bool mayReadFromMemory()
const;
542 bool mayWriteToMemory()
const;
555#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
566 const VPRecipeTy SubclassID;
575#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
584#define VP_CLASSOF_IMPL(VPRecipeID) \
585 static inline bool classof(const VPRecipeBase *R) { \
586 return R->getVPRecipeID() == VPRecipeID; \
588 static inline bool classof(const VPValue *V) { \
589 auto *R = V->getDefiningRecipe(); \
590 return R && R->getVPRecipeID() == VPRecipeID; \
592 static inline bool classof(const VPUser *U) { \
593 auto *R = dyn_cast<VPRecipeBase>(U); \
594 return R && R->getVPRecipeID() == VPRecipeID; \
596 static inline bool classof(const VPSingleDefRecipe *R) { \
597 return R->getVPRecipeID() == VPRecipeID; \
615 switch (R->getVPRecipeID()) {
616 case VPRecipeBase::VPDerivedIVSC:
617 case VPRecipeBase::VPExpandSCEVSC:
618 case VPRecipeBase::VPExpressionSC:
619 case VPRecipeBase::VPInstructionSC:
620 case VPRecipeBase::VPReductionEVLSC:
621 case VPRecipeBase::VPReductionSC:
622 case VPRecipeBase::VPReplicateSC:
623 case VPRecipeBase::VPScalarIVStepsSC:
624 case VPRecipeBase::VPVectorPointerSC:
625 case VPRecipeBase::VPVectorEndPointerSC:
626 case VPRecipeBase::VPWidenCallSC:
627 case VPRecipeBase::VPWidenCanonicalIVSC:
628 case VPRecipeBase::VPWidenCastSC:
629 case VPRecipeBase::VPWidenGEPSC:
630 case VPRecipeBase::VPWidenIntrinsicSC:
631 case VPRecipeBase::VPWidenMemIntrinsicSC:
632 case VPRecipeBase::VPWidenSC:
633 case VPRecipeBase::VPBlendSC:
634 case VPRecipeBase::VPPredInstPHISC:
635 case VPRecipeBase::VPCurrentIterationPHISC:
636 case VPRecipeBase::VPActiveLaneMaskPHISC:
637 case VPRecipeBase::VPFirstOrderRecurrencePHISC:
638 case VPRecipeBase::VPWidenPHISC:
639 case VPRecipeBase::VPWidenIntOrFpInductionSC:
640 case VPRecipeBase::VPWidenPointerInductionSC:
641 case VPRecipeBase::VPReductionPHISC:
642 case VPRecipeBase::VPWidenLoadEVLSC:
643 case VPRecipeBase::VPWidenLoadSC:
645 case VPRecipeBase::VPBranchOnMaskSC:
646 case VPRecipeBase::VPInterleaveEVLSC:
647 case VPRecipeBase::VPInterleaveSC:
648 case VPRecipeBase::VPIRInstructionSC:
649 case VPRecipeBase::VPWidenStoreEVLSC:
650 case VPRecipeBase::VPWidenStoreSC:
651 case VPRecipeBase::VPHistogramSC:
658 auto *R = V->getDefiningRecipe();
677#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
686 enum class OperationType :
unsigned char {
708 return {
static_cast<bool>(
HasNUW),
false};
730 struct ExactFlagsTy {
732 ExactFlagsTy(
bool Exact) : IsExact(Exact) {}
734 struct FastMathFlagsTy {
735 char AllowReassoc : 1;
738 char NoSignedZeros : 1;
739 char AllowReciprocal : 1;
740 char AllowContract : 1;
748 uint8_t CmpPredStorage;
749 FastMathFlagsTy FMFs;
752 struct ReductionFlagsTy {
755 unsigned char Kind : 6;
757 unsigned char IsOrdered : 1;
758 unsigned char IsInLoop : 1;
759 FastMathFlagsTy FMFs;
761 ReductionFlagsTy(
RecurKind Kind,
bool IsOrdered,
bool IsInLoop,
763 : Kind(static_cast<unsigned char>(Kind)), IsOrdered(IsOrdered),
764 IsInLoop(IsInLoop), FMFs(FMFs) {}
767 OperationType OpType;
788 OpType = OperationType::FCmp;
790 FCmp->getPredicate());
792 FCmpFlags.FMFs = FCmp->getFastMathFlags();
794 OpType = OperationType::Cmp;
799 OpType = OperationType::DisjointOp;
802 OpType = OperationType::OverflowingBinOp;
803 WrapFlags = {
Op->hasNoUnsignedWrap(),
Op->hasNoSignedWrap()};
805 OpType = OperationType::Trunc;
808 OpType = OperationType::PossiblyExactOp;
811 OpType = OperationType::GEPOp;
814 "wrap flags truncated");
816 OpType = OperationType::NonNegOp;
819 OpType = OperationType::FPMathOp;
820 FMFs =
Op->getFastMathFlags();
830 : OpType(OperationType::FCmp),
AllFlags() {
837 : OpType(OperationType::OverflowingBinOp),
AllFlags() {
842 : OpType(OperationType::Trunc),
AllFlags() {
851 : OpType(OperationType::DisjointOp),
AllFlags() {
856 : OpType(OperationType::NonNegOp),
AllFlags() {
861 : OpType(OperationType::PossiblyExactOp),
AllFlags() {
866 : OpType(OperationType::GEPOp),
AllFlags() {
871 : OpType(OperationType::ReductionOp),
AllFlags() {
884 case OperationType::OverflowingBinOp:
888 case OperationType::Trunc:
892 case OperationType::DisjointOp:
895 case OperationType::PossiblyExactOp:
898 case OperationType::GEPOp:
901 case OperationType::FPMathOp:
902 case OperationType::FCmp:
903 case OperationType::ReductionOp:
904 getFMFsRef().NoNaNs =
false;
905 getFMFsRef().NoInfs =
false;
907 case OperationType::NonNegOp:
910 case OperationType::Cmp:
911 case OperationType::Other:
919 case OperationType::OverflowingBinOp:
923 case OperationType::Trunc:
927 case OperationType::DisjointOp:
930 case OperationType::PossiblyExactOp:
933 case OperationType::GEPOp:
937 case OperationType::FPMathOp:
938 case OperationType::FCmp:
941 case OperationType::NonNegOp:
944 case OperationType::ReductionOp:
946 case OperationType::Cmp:
947 case OperationType::Other:
953 assert((OpType == OperationType::Cmp || OpType == OperationType::FCmp) &&
954 "recipe doesn't have a compare predicate");
961 assert((OpType == OperationType::Cmp || OpType == OperationType::FCmp) &&
962 "recipe doesn't have a compare predicate");
963 if (OpType == OperationType::FCmp)
976 return OpType == OperationType::Cmp || OpType == OperationType::FCmp;
981 return OpType == OperationType::FPMathOp || OpType == OperationType::FCmp ||
982 OpType == OperationType::ReductionOp;
989 case OperationType::OverflowingBinOp:
991 case OperationType::Trunc:
1000 case OperationType::OverflowingBinOp:
1002 case OperationType::Trunc:
1011 case OperationType::OverflowingBinOp:
1012 case OperationType::Trunc:
1024 assert(OpType == OperationType::DisjointOp &&
1025 "recipe cannot have a disjoing flag");
1030 assert(OpType == OperationType::ReductionOp &&
1031 "recipe doesn't have reduction flags");
1036 assert(OpType == OperationType::ReductionOp &&
1037 "recipe doesn't have reduction flags");
1042 assert(OpType == OperationType::ReductionOp &&
1043 "recipe doesn't have reduction flags");
1049 FastMathFlagsTy &getFMFsRef() {
1050 if (OpType == OperationType::FCmp)
1052 if (OpType == OperationType::ReductionOp)
1056 const FastMathFlagsTy &getFMFsRef()
const {
1057 if (OpType == OperationType::FCmp)
1059 if (OpType == OperationType::ReductionOp)
1069 Type *ResultTy =
nullptr);
1078 Type *ResultTy)
const;
1081#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1087static_assert(
sizeof(
VPIRFlags) <= 3,
"VPIRFlags should not grow");
1099 return R->getVPRecipeID() == VPRecipeBase::VPBlendSC ||
1100 R->getVPRecipeID() == VPRecipeBase::VPInstructionSC ||
1101 R->getVPRecipeID() == VPRecipeBase::VPWidenSC ||
1102 R->getVPRecipeID() == VPRecipeBase::VPWidenGEPSC ||
1103 R->getVPRecipeID() == VPRecipeBase::VPWidenCallSC ||
1104 R->getVPRecipeID() == VPRecipeBase::VPWidenCastSC ||
1105 R->getVPRecipeID() == VPRecipeBase::VPWidenIntrinsicSC ||
1106 R->getVPRecipeID() == VPRecipeBase::VPWidenMemIntrinsicSC ||
1107 R->getVPRecipeID() == VPRecipeBase::VPReductionSC ||
1108 R->getVPRecipeID() == VPRecipeBase::VPReductionEVLSC ||
1109 R->getVPRecipeID() == VPRecipeBase::VPReplicateSC ||
1110 R->getVPRecipeID() == VPRecipeBase::VPVectorEndPointerSC ||
1111 R->getVPRecipeID() == VPRecipeBase::VPVectorPointerSC ||
1112 R->getVPRecipeID() == VPRecipeBase::VPWidenCanonicalIVSC ||
1113 R->getVPRecipeID() == VPRecipeBase::VPDerivedIVSC;
1122 auto *R = V->getDefiningRecipe();
1159 "vplan.execution.frequency";
1163 "vplan.prof.estimated";
1167 unsigned getMDKindID(
StringRef Kind)
const {
1168 assert(!Metadata.empty() &&
"no node to take the context from");
1169 return Metadata.front().second->getContext().getMDKindID(Kind);
1175 return Metadata.empty() ? nullptr :
getMetadata(getMDKindID(Kind));
1189 if (
MDNode *BW =
I.getMetadata(LLVMContext::MD_prof))
1190 Metadata.emplace_back(LLVMContext::MD_prof, BW);
1205 llvm::find_if(Metadata, [Kind](
const std::pair<unsigned, MDNode *> &
P) {
1206 return P.first == Kind;
1208 if (It != Metadata.end())
1211 Metadata.emplace_back(Kind,
Node);
1216 erase_if(Metadata, [Kind](
const auto &
P) {
return P.first == Kind; });
1226 find_if(Metadata, [Kind](
const auto &
P) {
return P.first == Kind; });
1227 return It != Metadata.end() ? It->second :
nullptr;
1232 void setExecutionFrequency(std::optional<VPExecutionFrequency> Freq,
1236 std::optional<VPExecutionFrequency> getExecutionFrequency()
const;
1239 void clearExecutionFrequency();
1245 return Node ?
Node : getInternalMetadata(EstimatedProfileMDName);
1250 return getInternalMetadata(EstimatedProfileMDName);
1256 "real profile data takes precedence over an estimate");
1260#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1301 return CallAttrs.hasFnAttr(Kind) || CalleeFnAttrs.
hasAttribute(Kind);
1304#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1457 bool doesGeneratePerAllLanes()
const;
1462 unsigned getNumOperandsForOpcode()
const;
1465 typedef unsigned char OpcodeTy;
1473 bool doesGenerateSingleScalar()
const;
1481 bool alwaysUnmasked()
const {
1487 if (!getUnderlyingValue())
1491 Opcode == Instruction::GetElementPtr ||
1492 Opcode == Instruction::ExtractValue;
1496 VPInstruction(
unsigned Opcode, ArrayRef<VPValue *>
Operands,
1497 const VPIRFlags &Flags = {},
const VPIRMetadata &MD = {},
1499 Type *ResultTy =
nullptr,
const VPIRAttributes &
Attrs = {});
1508 Type *ResultTy =
nullptr) {
1509 auto *New =
new VPInstruction(Opcode, NewOperands, *
this, *
this,
1532#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1541 case Instruction::Ret:
1542 case Instruction::UncondBr:
1543 case Instruction::CondBr:
1544 case Instruction::Store:
1545 case Instruction::Switch:
1546 case Instruction::IndirectBr:
1547 case Instruction::Resume:
1548 case Instruction::CatchRet:
1549 case Instruction::Unreachable:
1550 case Instruction::Fence:
1551 case Instruction::AtomicRMW:
1566 if (NumOpsForOpcode == -1u)
1580 if (alwaysUnmasked())
1582 assert(Mask->getScalarType()->isIntegerTy(1) &&
1583 "Mask must be an i1 (vector)");
1601 bool opcodeMayReadOrWriteFromMemory()
const;
1604 bool usesFirstLaneOnly(
const VPValue *
Op)
const override;
1613 bool usesFirstPartOnly(
const VPValue *
Op)
const override;
1617 bool isVectorToScalar()
const;
1620 bool isSingleScalar()
const;
1629#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1699 assert((R->getNumOperands() == 0 ||
1700 IncomingV->
getScalarType() == R->getOperand(0)->getScalarType()) &&
1701 "all incoming values must have the same type");
1702 R->addOperand(IncomingV);
1705#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1713 const Twine &Name =
"",
Type *ResultTy =
nullptr)
1719 return VPI && VPI->getOpcode() == Instruction::PHI;
1724 return VPI && VPI->getOpcode() == Instruction::PHI;
1729 return VPI && VPI->getOpcode() == Instruction::PHI;
1741#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1788 "Op must be an operand of the recipe");
1794 "Op must be an operand of the recipe");
1800 "Op must be an operand of the recipe");
1805#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1835#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1857 setUnderlyingValue(&
I);
1863 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenSC,
Operands,
1866 VPIRMetadata(
Metadata), Opcode(Opcode) {
1867 assert(flagsValidForOpcode(Opcode) &&
1868 "Set flags not supported for the provided opcode");
1869 assert(hasRequiredFlagsForOpcode(Opcode, getScalarType()) &&
1870 "Opcode requires specific flags to be set");
1897#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1906 "Op must be an operand of the recipe");
1907 return Opcode == Instruction::Select &&
Op ==
getOperand(0) &&
1924 DebugLoc
DL = DebugLoc::getUnknown())
1925 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenCastSC, Op, ResultTy, Flags,
1927 VPIRMetadata(
Metadata), Opcode(Opcode) {
1928 assert(flagsValidForOpcode(Opcode) &&
1929 "Set flags not supported for the provided opcode");
1930 assert(hasRequiredFlagsForOpcode(Opcode, ResultTy) &&
1931 "Opcode requires specific flags to be set");
1932 setUnderlyingValue(CI);
1955#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1969 bool MayReadFromMemory;
1972 bool MayWriteToMemory;
1975 bool MayHaveSideEffects;
1982 DebugLoc
DL = DebugLoc::getUnknown())
1983 : VPRecipeWithIRFlags(SC, CallArguments, Ty, Flags,
DL), VPIRMetadata(MD),
1984 VectorIntrinsicID(VectorIntrinsicID) {
1985 LLVMContext &Ctx = Ty->getContext();
1986 AttributeSet Attrs = Intrinsic::getFnAttributes(Ctx, VectorIntrinsicID);
1987 MemoryEffects ME = Attrs.getMemoryEffects();
1988 MayReadFromMemory = !ME.onlyWritesMemory();
1989 MayWriteToMemory = !ME.onlyReadsMemory();
1990 MayHaveSideEffects = MayWriteToMemory ||
1991 !Attrs.hasAttribute(Attribute::NoUnwind) ||
1992 !Attrs.hasAttribute(Attribute::WillReturn);
1996 CallInst *createVectorCall(VPTransformState &State);
2003 DebugLoc
DL = DebugLoc::getUnknown())
2004 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenIntrinsicSC, CallArguments, Ty,
2006 VPIRMetadata(MD), VectorIntrinsicID(VectorIntrinsicID),
2007 MayReadFromMemory(CI.mayReadFromMemory()),
2008 MayWriteToMemory(CI.mayWriteToMemory()),
2010 setUnderlyingValue(&CI);
2017 DebugLoc
DL = DebugLoc::getUnknown())
2018 : VPWidenIntrinsicRecipe(VPRecipeBase::VPWidenIntrinsicSC,
2019 VectorIntrinsicID, CallArguments, Ty, Flags,
2035 return R->getVPRecipeID() == VPRecipeBase::VPWidenIntrinsicSC ||
2036 R->getVPRecipeID() == VPRecipeBase::VPWidenMemIntrinsicSC;
2045 auto *R = V->getDefiningRecipe();
2081 bool usesFirstLaneOnly(
const VPValue *
Op)
const override;
2084#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2103 VectorIntrinsicID, CallArguments, Ty, {}, MD,
2105 Alignment(Alignment) {
2106 assert(getVectorMemoryIntrinsicPointerArgIdx(VectorIntrinsicID) &&
2107 getVectorIntrinsicMaskArgIdx(VectorIntrinsicID) &&
2108 "Expected a masked vector load/store intrinsic");
2109 assert((!Ty->isVoidTy() ||
2110 getVectorStoreIntrinsicDataArgIdx(VectorIntrinsicID)) &&
2111 "Expected data argument for store intrinsic");
2128 unsigned getAddrOpIdx()
const;
2138 bool IsMasked,
Align Alignment,
2160 const VPIRAttributes &Attrs = {},
DebugLoc DL = {})
2161 : VPRecipeWithIRFlags(VPRecipeBase::VPWidenCallSC, CallArguments,
2165 setUnderlyingValue(UV);
2166 assert(isa<Function>(getLastOperand()->getLiveInIRValue()) &&
2167 "last operand must be the called function");
2168 assert(cast<Function>(CallArguments.
back()->getLiveInIRValue())
2169 ->getReturnType() == getScalarType() &&
2170 "Scalar type must match return type of called scalar function");
2200 bool usesFirstLaneOnly(
const VPValue *
Op)
const override;
2203#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2251 "Op must be an operand of the recipe");
2261 bool mustNegateIncrement()
const {
2266#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2268 void printRecipe(raw_ostream &O,
const Twine &Indent,
2269 VPSlotTracker &SlotTracker)
const override;
2275 Type *SourceElementTy;
2284 SourceElementTy(SourceElementTy) {
2286 setUnderlyingValue(UV);
2319 bool usesFirstLaneOnly(
const VPValue *
Op)
const override;
2322#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2335 Type *SourceElementTy;
2345 Ptr->getScalarType(), GEPFlags,
DL),
2346 SourceElementTy(SourceElementTy), Stride(Stride) {
2347 assert(Stride < 0 &&
"Stride must be negative");
2368 "offset must be an integer index");
2376 "Op must be an operand of the recipe");
2390 "Op must be an operand of the recipe");
2405#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2417 Type *SourceElementTy;
2424 Ptr->getScalarType(), GEPFlags,
DL),
2425 SourceElementTy(SourceElementTy) {}
2438 "per-part offset must be an integer index");
2448 "Op must be an operand of the recipe");
2455 "Op must be an operand of the recipe");
2465 Clone->addPerPartOffset(VFxPart);
2477#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2518 return R->getVPRecipeID() >= VPRecipeBase::VPFirstHeaderPHISC &&
2519 R->getVPRecipeID() <= VPRecipeBase::VPLastHeaderPHISC;
2555 "backedge value must be appended right after construction");
2557 "backedge value must have the same type as the start value");
2562#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2587 "last-part value must match the induction recipe's scalar type");
2591 "splat-step must match the induction type for non-pointer "
2592 "inductions, or be an integer index for pointer inductions");
2598 return R->getVPRecipeID() == VPRecipeBase::VPWidenIntOrFpInductionSC ||
2599 R->getVPRecipeID() == VPRecipeBase::VPWidenPointerInductionSC;
2603 auto *R = V->getDefiningRecipe();
2635 return IndDesc.getNoWrapPredicates();
2642 "VPWidenIntOrFpInductionRecipe generates its own backedge value");
2648 "Op must be an operand of the recipe");
2680 Start, Step, IndDesc, ResultTy,
DL),
2697 "expandVPWidenIntOrFpInductionRecipe");
2736#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2770 "expandVPWidenPointerInduction");
2781#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2811 "all incoming values must have the same type");
2833#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2869 "Op must be an operand of the recipe");
2874#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2895 unsigned ScaleFactor) {
2896 assert((!Ordered || InLoop) &&
"Ordered implies in-loop");
2917 bool HasUsesOutsideReductionChain;
2926 bool ExpressionSunk =
false;
2933 bool HasUsesOutsideReductionChain =
false)
2936 VPIRFlags(Flags), Kind(Kind), Style(Style),
2937 HasUsesOutsideReductionChain(HasUsesOutsideReductionChain) {
2947 *Start, *BackedgeValue, Style, *
this, HasUsesOutsideReductionChain);
2948 Clone->ExpressionSunk = ExpressionSunk;
2964 auto *Partial = std::get_if<RdxUnordered>(&Style);
2965 return Partial ? Partial->VFScaleFactor : 1;
2971 assert(ScaleFactor > 1 &&
"must set to scale factor > 1");
2979 bool isOrdered()
const {
return std::holds_alternative<RdxOrdered>(Style); }
2983 return std::holds_alternative<RdxInLoop>(Style) ||
2984 std::holds_alternative<RdxOrdered>(Style);
2989 return HasUsesOutsideReductionChain;
2999 "Op must be an operand of the recipe");
3004#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3023 assert(
Operands.size() >= 2 &&
"Expected at least two operands!");
3025 [
this](
unsigned I) {
3029 "all incoming values must have the same type");
3031 [
this](
unsigned I) {
3032 return getMask(
I)->getScalarType()->isIntegerTy(1);
3034 "masks must be a bool");
3036 "blends require the flags of the phi they replace");
3073 assert(V->getScalarType()->isIntegerTy(1) &&
"Mask must be an i1 (vector)");
3086 bool usesFirstLaneOnly(
const VPValue *
Op)
const override;
3089#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3107 bool HasMask =
false;
3111 bool NeedsMaskForGaps =
false;
3119 NeedsMaskForGaps(NeedsMaskForGaps) {
3121 assert((!Mask || !IG->isReverse()) &&
3122 "Reversed masked interleave-group not supported.");
3123 if (StoredValues.
empty()) {
3125 assert(!Inst->getType()->isVoidTy() &&
"must have result");
3129 for (
auto *SV : StoredValues)
3142 return R->getVPRecipeID() == VPRecipeBase::VPInterleaveSC ||
3143 R->getVPRecipeID() == VPRecipeBase::VPInterleaveEVLSC;
3203 Mask, NeedsMaskForGaps, MD, DL) {}
3220 "Op must be an operand of the recipe");
3229#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3244 R.getStoredValues(), Mask, R.needsMaskForGaps(), R,
3246 assert(!getInterleaveGroup()->isReverse() &&
3247 "Reversed interleave-group with tail folding is not supported.");
3248 assert(!needsMaskForGaps() &&
"Interleaved access with gap mask is not "
3249 "supported for scalable vector.");
3269 "Op must be an operand of the recipe");
3279#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3295 bool IsConditional =
false;
3304 RdxKind(RdxKind), Style(Style) {
3312 "all incoming values must have the same type");
3315 "CondOp must be a bool");
3316 IsConditional =
true;
3327 {ChainOp, VecOp}, CondOp, Style,
DL) {}
3333 {ChainOp, VecOp}, CondOp, Style,
DL) {}
3344 return R->getVPRecipeID() == VPRecipeBase::VPReductionSC ||
3345 R->getVPRecipeID() == VPRecipeBase::VPReductionEVLSC;
3372 bool isOrdered()
const {
return std::holds_alternative<RdxOrdered>(Style); };
3377 return std::holds_alternative<RdxUnordered>(Style);
3381 return std::holds_alternative<RdxInLoop>(Style) ||
3382 std::holds_alternative<RdxOrdered>(Style);
3395 auto *Partial = std::get_if<RdxUnordered>(&Style);
3396 return Partial ? Partial->VFScaleFactor : 1;
3400#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3418 {R.getChainOp(), R.getVecOp(), &EVL}, CondOp,
3420 R.getVFScaleFactor()),
3440 "Op must be an operand of the recipe");
3445#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3459 bool IsSingleScalar;
3466 bool IsSingleScalar,
VPValue *Mask =
nullptr,
3468 DebugLoc
DL = DebugLoc::getUnknown())
3469 : VPRecipeWithIRFlags(VPRecipeBase::VPReplicateSC,
Operands,
3471 VPIRMetadata(
Metadata), IsSingleScalar(IsSingleScalar),
3472 IsPredicated(Mask) {
3473 assert((!IsSingleScalar || !
I->isCast()) &&
3474 "Single-scalar casts should use VPInstruction");
3475 setUnderlyingValue(
I);
3524 "Op must be an operand of the recipe");
3531 "Op must be an operand of the recipe");
3555#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3585#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3589 O << Indent <<
"BRANCH-ON-MASK ";
3597 "Op must be an operand of the recipe");
3620 enum class ExpressionTypes {
3627 NegatedExtendedReduction,
3639 ExtNegatedMulAccReduction,
3643 ExpressionTypes ExpressionType;
3664 "Expected an add or add-chain-with-subs reduction");
3665 if (Neg->getOpcode() == Instruction::Sub) {
3667 assert(SubConst && SubConst->isZero() &&
"Expected a negating sub");
3669 assert(Neg->getOpcode() == Instruction::FNeg &&
"Unexpected opcode");
3676 {Ext0, Ext1,
Mul, Red}) {}
3681 {Ext0, Ext1,
Mul, Neg, Red}) {
3682 assert((
Mul->getOpcode() == Instruction::Mul ||
3683 Mul->getOpcode() == Instruction::FMul) &&
3688 "Expected an add or add-chain-with-subs reduction");
3690 if (Neg->getOpcode() == Instruction::Sub) {
3692 assert(SubConst && SubConst->isZero() &&
3693 Neg->getOpcode() == Instruction::Sub &&
"Expected a negating sub");
3695 assert(Neg->getOpcode() == Instruction::FNeg &&
"Unexpected opcode");
3700 for (
auto *R :
reverse(ExpressionRecipes)) {
3701 if (ExpressionRecipesSeen.
insert(R).second)
3704 for (
VPValue *
T : LiveInPlaceholders)
3711 assert(!ExpressionRecipes.empty() &&
"empty expressions should be removed");
3713 for (
auto *R : ExpressionRecipes)
3714 NewExpressiondRecipes.
push_back(R->clone());
3715 for (
auto *New : NewExpressiondRecipes) {
3716 for (
const auto &[Idx, Old] :
enumerate(ExpressionRecipes))
3717 New->replaceUsesOfWith(Old, NewExpressiondRecipes[Idx]);
3720 for (
const auto &[Placeholder, OutsideOp] :
3722 New->replaceUsesOfWith(Placeholder, OutsideOp);
3737 return PR ? PR->getVFScaleFactor() : 1;
3760#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3799#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3825 assert(Mask->getScalarType()->isIntegerTy(1) &&
3826 "Mask must be an i1 (vector)");
3857 return isMasked() ? R->getLastOperand() :
nullptr;
3905 "Op must be an operand of the recipe");
3915#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3931 L.getIngredient().
getType(), &L.getIngredient(),
3960 "Op must be an operand of the recipe");
3970#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4012 "Op must be an operand of the recipe");
4022#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4066 "Op must be an operand of the recipe");
4081#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4108 llvm_unreachable(
"SCEV expressions must be expanded before final execute");
4123#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4153#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4180 "scalar phi recipe");
4193 "Op must be an operand of the recipe");
4198#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4213 CanonicalIV->
getType(), Flags) {}
4221 WideCanIV->addPerPartStep(Step);
4250 "per-part step must have the same type as the canonical IV");
4255#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4278 Start->getScalarType(), Flags),
4279 Kind(Kind), FPBinOp(FPBinOp) {}
4307 "Op must be an operand of the recipe");
4312#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4334 IV->getScalarType(), FMFs,
DL),
4335 InductionOpcode(Opcode) {}
4344 NewR->setStartIndex(StartIndex);
4378 bool doesGeneratePerAllLanes()
const;
4383 "Op must be an operand of the recipe");
4390#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4401template <
typename VPMixin,
typename... RecipeTys>
4404 CastInfoMixinImpl<VPMixin, RecipeTys...>> {
4405 static_assert((std::is_base_of_v<VPMixin, RecipeTys> && ...),
4406 "Each type in RecipeTys must derive from VPMixin");
4413 VPMixin *Out =
nullptr;
4415 assert(Out &&
"Illegal recipe for cast");
4436 CastInfo<VPPhiAccessors, VPRecipeBase *>> {};
4478 CastInfo<VPIRMetadata, VPRecipeBase *>> {};
4499 : VPBasicBlock(VPBasicBlockSC, Name) {
4560 return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC ||
4561 V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
4565 assert(Recipe &&
"No recipe to append.");
4567 assert(InsertPt.getNodeParent() ==
this &&
4568 "Insertion position not in this VPBasicBlock");
4570 Recipes.insert(InsertPt, Recipe);
4600#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4617 bool isExiting()
const;
4627 const VPBasicBlock *getCFGPredecessor(
unsigned Idx)
const;
4643inline const VPBasicBlock *
4653class VPIRBasicBlock :
public VPBasicBlock {
4660 : VPBasicBlock(VPIRBasicBlockSC,
4668 return V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
4685 std::unique_ptr<VPRegionValue> CanIV;
4688 std::unique_ptr<VPRegionValue> HeaderMask;
4705 assert(!HeaderMask &&
"Header mask already created");
4706 HeaderMask = std::make_unique<VPRegionValue>(
4708 CanIV->getDefiningRegion());
4709 return HeaderMask.get();
4739 std::unique_ptr<VPCanonicalIVInfo> CanIVInfo;
4744 const std::string &Name =
"")
4745 :
VPBlockBase(VPRegionBlockSC, Name), Entry(Entry), Exiting(Exiting) {
4747 assert(!Entry->hasPredecessors() &&
"Entry block has predecessors.");
4748 assert(Exiting &&
"Must also pass Exiting if Entry is passed.");
4749 assert(!Exiting->hasSuccessors() &&
"Exit block has successors.");
4750 Entry->setParent(
this);
4751 Exiting->setParent(
this);
4755 VPRegionBlock(Type *CanIVTy, DebugLoc
DL, VPBlockBase *Entry,
4756 VPBlockBase *Exiting,
const std::string &Name =
"")
4757 : VPRegionBlock(Entry, Exiting, Name) {
4758 CanIVInfo = std::make_unique<VPCanonicalIVInfo>(CanIVTy,
DL,
this);
4766 return V->getVPBlockID() == VPBlockBase::VPRegionBlockSC;
4776 "Entry block cannot have predecessors.");
4788 "Exit block cannot have successors.");
4789 Exiting = ExitingBlock;
4808 static_cast<const VPRegionBlock *
>(
this)->getEntryBranchOnMask());
4818#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4836 void dissolveToCFGLoop();
4846 return CanIVInfo ? CanIVInfo->getRegionValue() :
nullptr;
4849 return CanIVInfo ? CanIVInfo->getRegionValue() :
nullptr;
4854 return CanIVInfo->getRegionValue()->getType();
4859 return CanIVInfo ? CanIVInfo->getHeaderMask() :
nullptr;
4867 return HeaderMask && HeaderMask->
getNumUsers() > 0 ? HeaderMask :
nullptr;
4873 assert(CanIVInfo &&
"Can only create header mask for loop regions");
4874 return CanIVInfo->createHeaderMask();
4883 if (
auto *HM = CanIVInfo->getHeaderMask())
4895 CanIVInfo->clearNUW();
4969 : Entry(Entry), ScalarHeader(ScalarHeader), VectorTripCount(IdxTy),
4970 VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
4971 Entry->setPlan(
this);
4972 assert(ScalarHeader->getNumSuccessors() == 0 &&
4973 "scalar header must be a leaf node");
4986 : VectorTripCount(IdxTy), VF(IdxTy), UF(IdxTy), VFxUF(IdxTy) {
5050 "cannot call the function after vector loop region has been removed");
5077 assert(TripCount &&
"trip count needs to be set before accessing it");
5084 assert(!TripCount && NewTripCount &&
"TripCount should not be set yet.");
5085 TripCount = NewTripCount;
5092 "TripCount must be set when resetting");
5093 TripCount = NewTripCount;
5124 assert(
hasVF(VF) &&
"Cannot set VF not already in plan");
5131 assert(
hasVF(VF) &&
"tried to remove VF not present in plan");
5149 assert(VFs.size() == 1 &&
"expected plan with single VF");
5154 bool HasScalarVFOnly = VFs.size() == 1 && VFs[0].isScalar();
5156 "Plan with scalar VF should only have a single VF");
5157 return HasScalarVFOnly;
5160 bool hasUF(
unsigned UF)
const {
return UFs.empty() || UFs.contains(UF); }
5164 assert(UFs.size() == 1 &&
"Expected a single UF");
5169 assert(
hasUF(UF) &&
"Cannot set the UF not already in plan");
5186 assert(V &&
"Trying to get or add the VPIRValue of a null Value");
5187 auto [It, Inserted] = LiveIns.try_emplace(V);
5196 "Only VPIRValues should be in mapping");
5200 assert(V &&
"Trying to get or add the VPIRValue of a null VPIRValue");
5226 bool IsSigned =
false) {
5247#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
5272 VPB->setNumber(CreatedBlocks.size());
5273 CreatedBlocks.push_back(VPB);
5282 const std::string &Name =
"",
5287 VPB->setNumber(CreatedBlocks.size());
5288 CreatedBlocks.push_back(VPB);
5296 const std::string &Name =
"") {
5299 VPB->setNumber(CreatedBlocks.size());
5300 CreatedBlocks.push_back(VPB);
5319 unsigned NumExitPredecessors =
5331 return NumExitPredecessors >= 1;
5335 return NumExitPredecessors > 1;
5351#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 contains the simple types necessary to represent the attributes associated with functions a...
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
#define LLVM_PACKED_START
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static MaybeAlign getAlign(Value *Ptr)
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 MemAccessTy getAccessType(const TargetTransformInfo &TTI, Instruction *Inst, Value *OperandVal)
Return the type of the memory being accessed.
This file implements a map that provides insertion order iteration.
static Interval intersect(const Interval &I1, const Interval &I2)
This file provides utility analysis objects describing memory locations.
static StringRef getName(Value *V)
static bool mayHaveSideEffects(MachineInstr &MI)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
static const BasicSubtargetSubTypeKV * find(StringRef S, ArrayRef< BasicSubtargetSubTypeKV > A)
Find KV in array using binary search.
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
Get the last element.
bool empty() const
Check if the array is empty.
This class holds the attributes for a particular argument, parameter, function, or return value.
LLVM_ABI MemoryEffects getMemoryEffects() const
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
void setAttributes(AttributeList A)
Set the attributes for this call.
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.
A parsed version of the target data layout string in and methods for querying it.
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.
Class to represent function types.
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.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
This class represents an assumption made using SCEV expressions which can be checked at run-time.
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.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
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.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
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.
VPRecipeBase::RecipeListTy RecipeListTy
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.
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.
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
VPBasicBlock(VPBlockTy BlockSC, const Twine &Name="")
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,...
VPBlendRecipe * cloneWithOperands(ArrayRef< VPValue * > NewOperands)
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()
const VPlan * getPlan() const
void setPlan(VPlan *ParentPlan)
Sets the pointer of the plan containing the block.
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
unsigned getNumber() const
Return the unique number of the block.
void setNumber(unsigned N)
Set the unique number of the block, used for dominator tree.
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.
enum :unsigned char { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC } VPBlockTy
An enumeration for keeping track of the concrete subclass of VPBlockBase that are actually instantiat...
bool hasSuccessors() const
Returns true if this block has any successors.
const VPBlocksTy & getPredecessors() const
virtual VPBlockBase * clone()=0
Clone the current block and it's recipes without updating the operands of the cloned recipes,...
virtual InstructionCost cost(ElementCount VF, VPCostContext &Ctx)=0
Return the cost of the block.
const VPRegionBlock * getParent() const
const std::string & getName() const
void clearSuccessors()
Remove all the successors of this block.
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.
VPBlocksTy & getSuccessors()
VPBlockBase * getEnclosingBlockWithSuccessors()
An Enclosing Block of a block B is any block containing B, including B itself.
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
VPBlockBase(VPBlockTy SC, const std::string &N)
A recipe for generating conditional branches on the bits of a mask.
VPBranchOnMaskRecipe(VPValue *BlockInMask, DebugLoc DL, const VPIRMetadata &Metadata={})
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.
VPlan-based builder utility similar to IRBuilder.
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
VPRegionValue * getHeaderMask() const
VPRegionValue * getRegionValue()
VPCanonicalIVInfo(Type *Ty, DebugLoc DL, VPRegionBlock *Region)
const VPRegionValue * getRegionValue() const
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.
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
InductionDescriptor::InductionKind getInductionKind() const
VPValue * getIndex() const
const FPMathOperator * getFPBinOp() const
VPDerivedIVRecipe(InductionDescriptor::InductionKind Kind, const FPMathOperator *FPBinOp, VPValue *Start, VPValue *Current, VPValue *Step, const VPIRFlags::WrapFlagsTy &Flags={})
VPValue * getStepValue() const
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
VPDerivedIVRecipe * clone() override
Clone the current recipe.
~VPDerivedIVRecipe() override=default
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPValue * getStartValue() const
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, bool ExpandInIR=false)
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.
bool isVectorToScalar() const
Returns true if this VPExpressionRecipe produces a single scalar.
VPExpressionRecipe(VPWidenCastRecipe *Ext, VPWidenRecipe *Neg, VPReductionRecipe *Red)
VPExpressionRecipe * clone() override
Clone the current recipe.
SmallVector< VPSingleDefRecipe * > decompose()
Return and insert the recipes of the expression back into the VPlan, directly before the current reci...
~VPExpressionRecipe() override
ExpressionTypes getExpressionType() const
Returns the expression type of this recipe.
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)
VPExpressionRecipe(ExpressionTypes ExpressionType, ArrayRef< VPSingleDefRecipe * > ExpressionRecipes)
Construct a new VPExpressionRecipe by internalizing recipes in ExpressionRecipes.
VPExpressionRecipe(VPWidenCastRecipe *Ext0, VPWidenCastRecipe *Ext1, VPWidenRecipe *Mul, VPWidenRecipe *Neg, 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)
A recipe representing a sequence of load -> update -> store as part of a histogram operation.
VPHistogramRecipe(HistogramUpdateKind UpdateKind, ArrayRef< VPValue * > Operands, const VPIRMetadata &Metadata={}, DebugLoc DL=DebugLoc::getUnknown())
void execute(VPTransformState &State) override
Produce a vectorized histogram operation.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
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...
VP_CLASSOF_IMPL(VPRecipeBase::VPHistogramSC)
~VPHistogramRecipe() override=default
Manage IR attributes for call recipes.
void printFnAttrs(raw_ostream &O) const
Print function attributes carried with this object.
void printRetAttrs(raw_ostream &O) const
Print return-value attributes carried with this object.
MemoryEffects getMemoryEffects(AttributeSet CalleeFnAttrs) const
Returns the memory effects of a call with these attributes to a callee with function attributes Calle...
VPIRAttributes(AttributeList CallAttrs)
bool hasFnAttr(Attribute::AttrKind Kind, AttributeSet CalleeFnAttrs) const
Returns true if the call site or CalleeFnAttrs has Kind.
void intersectAttrs(const VPIRAttributes &Other, LLVMContext &Ctx)
Keep only the attributes valid for both this and Other.
void printParamAttrs(raw_ostream &O, unsigned ArgIdx) const
Print per-arg attributes for argument ArgIdx.
void applyAttrs(CallInst &WideCall) const
Apply the stored attributes to the widened call WideCall.
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.
WrapFlagsTy getNoWrapFlagsOrNone() const
ReductionFlagsTy ReductionFlags
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.
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.
static LLVM_ABI_FOR_TEST VPIRFlags getDefaultFlags(unsigned Opcode, Type *ResultTy=nullptr)
Returns default flags for Opcode and scalar ResultTy for opcodes that support it, asserts otherwise.
bool isReductionOrdered() const
CmpInst::Predicate getPredicate() const
WrapFlagsTy getNoWrapFlags() const
LLVM_ABI_FOR_TEST FastMathFlags getFastMathFlagsOrNone() const
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.
LLVM_ABI_FOR_TEST bool hasRequiredFlagsForOpcode(unsigned Opcode, Type *ResultTy) const
Returns true if Opcode with scalar result type ResultTy has its required flags set.
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.
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 last active lane from a set of vectors.
@ Intrinsic
Calls a scalar intrinsic. The intrinsic ID is the last operand.
@ 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...
@ WideIVStep
Scale the first operand (vector step) by the second operand (scalar-step).
@ ExtractPenultimateElement
@ ResumeForEpilogue
Explicit user for values in the main VPlan, used by the epilogue vector loop.
@ 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.
@ CanonicalIVIncrementForPart
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
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
void setName(StringRef NewName)
Set the symbolic name for the VPInstruction.
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe only uses scalars of operand Op.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPInstruction(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", Type *ResultTy=nullptr, const VPIRAttributes &Attrs={})
VPValue * getMask() const
Returns the mask for the VPInstruction.
bool isSingleScalar() const
Returns true if the recipe produces a single scalar value.
VPInstruction * cloneWithOperands(ArrayRef< VPValue * > NewOperands, Type *ResultTy=nullptr)
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.
A common base class for interleaved memory operations.
virtual unsigned getNumStoreOperands() const =0
Returns the number of stored operands of this interleave group.
VPInterleaveBase(VPRecipeTy SC, const InterleaveGroup< Instruction > *IG, ArrayRef< VPValue * > Operands, ArrayRef< VPValue * > StoredValues, VPValue *Mask, bool NeedsMaskForGaps, const VPIRMetadata &MD, DebugLoc DL)
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)
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.
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 ...
A VPRecipeValue defined by a multi-def recipe, stores a pointer to it.
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.
LLVM_ABI_FOR_TEST 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.
void addIncoming(VPValue *IncomingV)
Append IncomingV as an incoming value to the phi-like recipe.
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
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.
void moveBefore(RecipeListTy::iterator I)
Unlink this recipe and insert it before I.
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()
RecipeListTy::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void setDebugLoc(DebugLoc NewDL)
Set the recipe's debug location to NewDL.
bool mayWriteToMemory() const
Returns true if the recipe may write to memory.
VPRecipeTy getVPRecipeID() const
~VPRecipeBase() override=default
enum :unsigned char { VPBranchOnMaskSC, VPDerivedIVSC, VPExpandSCEVSC, VPExpressionSC, VPIRInstructionSC, VPInstructionSC, VPInterleaveEVLSC, VPInterleaveSC, VPReductionEVLSC, VPReductionSC, VPReplicateSC, VPScalarIVStepsSC, VPVectorPointerSC, VPVectorEndPointerSC, VPWidenCallSC, VPWidenCanonicalIVSC, VPWidenCastSC, VPWidenGEPSC, VPWidenIntrinsicSC, VPWidenMemIntrinsicSC, VPWidenLoadEVLSC, VPWidenLoadSC, VPWidenStoreEVLSC, VPWidenStoreSC, VPWidenSC, VPBlendSC, VPHistogramSC, VPWidenPHISC, VPPredInstPHISC, VPCurrentIterationPHISC, VPActiveLaneMaskPHISC, VPFirstOrderRecurrencePHISC, VPWidenIntOrFpInductionSC, VPWidenPointerInductionSC, VPReductionPHISC, VPFirstPHISC=VPWidenPHISC, VPFirstHeaderPHISC=VPCurrentIterationPHISC, VPLastHeaderPHISC=VPReductionPHISC, VPLastPHISC=VPReductionPHISC, } VPRecipeTy
An enumeration for keeping track of the concrete subclass of VPRecipeBase that is actually instantiat...
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,...
iplist< VPRecipeBase, ilist_parent< VPBasicBlock > > RecipeListTy
The list type holding the recipes of a VPBasicBlock.
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.
virtual VPRecipeBase * clone()=0
Clone the current recipe.
friend class VPBlockUtils
VPRecipeBase(VPRecipeTy SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
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.
void moveAfter(VPRecipeBase *MovePos)
Unlink this recipe from its current VPBasicBlock and insert it into the VPBasicBlock that MovePos liv...
Type * getScalarType() const
Returns the scalar type of this VPRecipeValue.
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 isExpressionSunk() const
bool hasUsesOutsideReductionChain() const
Returns true, if the phi is part of a multi-use reduction.
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.
VPReductionPHIRecipe * cloneWithOperands(VPValue *Start, VPValue *BackedgeValue)
RecurKind getRecurrenceKind() const
Returns the recurrence kind of the reduction.
A recipe to represent inloop, ordered or partial reduction operations.
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())
VPReductionRecipe(VPRecipeTy SC, RecurKind RdxKind, FastMathFlags FMFs, Instruction *I, ArrayRef< VPValue * > Operands, VPValue *CondOp, ReductionStyle Style, DebugLoc DL)
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
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
~VPRegionBlock() override=default
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
VPRegionValue * getUsedHeaderMask() const
Return the header mask if it exists and is used, or null otherwise.
void setExiting(VPBlockBase *ExitingBlock)
Set ExitingBlock as the exiting VPBlockBase of this VPRegionBlock.
VPBlockBase * getExiting()
VPBranchOnMaskRecipe * getEntryBranchOnMask()
const VPRegionValue * getCanonicalIV() const
SmallVector< VPRegionValue *, 2 > getRegionValues() const
Return the region values of the loop region (canonical IV, header mask) or an empty vector for replic...
void setEntry(VPBlockBase *EntryBlock)
Set EntryBlock as the entry VPBlockBase of this VPRegionBlock.
Type * getCanonicalIVType() const
Return the type of the canonical IV for loop regions.
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
void clearCanonicalIVNUW(VPInstruction *Increment)
Unsets NUW for the canonical IV increment Increment, for loop regions.
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
const VPBlockBase * getExiting() const
VPBasicBlock * getPreheaderVPBB()
Returns the pre-header VPBasicBlock of the loop region.
VPRegionValue * getHeaderMask() const
Return the header mask of the region, or null if not set.
static bool classof(const VPBlockBase *V)
Method to support type inquiry through isa, cast, and dyn_cast.
VPValues are defined by a VPRegionBlock, like the canonical IV.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
bool isSingleScalar() const
Returns true if the recipe produces a single scalar value.
unsigned getNumOperandsWithoutMask() const
Returns the number of operands, excluding the mask if the recipe is predicated.
VPReplicateRecipe(Instruction *I, ArrayRef< VPValue * > Operands, bool IsSingleScalar, VPValue *Mask=nullptr, const VPIRFlags &Flags={}, VPIRMetadata Metadata={}, DebugLoc DL=DebugLoc::getUnknown())
~VPReplicateRecipe() override=default
static Type * computeScalarType(const Instruction *I, ArrayRef< VPValue * > Operands)
Compute the scalar result type for a VPReplicateRecipe wrapping I with Operands (excluding any predic...
VPReplicateRecipe * cloneWithOperands(ArrayRef< VPValue * > NewOperands)
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
operand_range operandsWithoutMask()
Return the recipe's operands, excluding the mask of a predicated recipe.
bool isPredicated() const
VPReplicateRecipe * clone() override
Clone the current recipe.
bool doesGeneratePerAllLanes() const
Returns true if the recipe produces scalar values for all VF lanes.
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.
Instruction::BinaryOps getInductionOpcode() const
VPValue * getStepValue() const
void setStartIndex(VPValue *StartIndex)
Set or add the StartIndex operand.
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=DebugLoc::getUnknown())
~VPScalarIVStepsRecipe() override=default
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
static bool classof(const VPValue *V)
Instruction * getUnderlyingInstr()
Returns the underlying instruction.
static bool classof(const VPRecipeBase *R)
const Instruction * getUnderlyingInstr() const
VPSingleDefRecipe(VPRecipeTy SC, ArrayRef< VPValue * > Operands, Type *ResultTy, Value *UV=nullptr, DebugLoc DL=DebugLoc::getUnknown())
static bool classof(const VPUser *U)
VPSingleDefRecipe * clone() override=0
Clone the current recipe.
VPSingleDefValue(VPSingleDefRecipe *Def, Value *UV=nullptr, Type *Ty=nullptr)
Construct a VPSingleDefValue. Must only be used by VPSingleDefRecipe.
This class can be used to assign names to VPValues.
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
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
VPValue * getLastOperand() const
Returns the last operand.
iterator_range< operand_iterator > operand_range
void addOperand(VPValue *Operand)
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Value * getLiveInIRValue() const
Return the underlying IR value for a VPIRValue.
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
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.
void addOffset(VPValue *Offset)
Append Offset as the offset operand.
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.
void addPerPartOffset(VPValue *VFxPart)
Add the per-part offset (VFxPart) used for unrolled parts > 0.
VPValue * getStride() const
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, VPValue *Stride, 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.
VPValue * getVFxPart() const
A recipe for widening Call instructions using library calls.
const_operand_range args() const
VPWidenCallRecipe * clone() override
Clone the current recipe.
Function * getCalledScalarFunction() const
VPWidenCallRecipe(Value *UV, Function *Variant, ArrayRef< VPValue * > CallArguments, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={}, const VPIRAttributes &Attrs={}, DebugLoc DL={})
~VPWidenCallRecipe() override=default
~VPWidenCanonicalIVRecipe() override=default
VPValue * getStepValue() const
void addPerPartStep(VPValue *Step)
Add the per-part step (VF * Part) used for unrolled parts.
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.
VPRegionValue * getCanonicalIV() const
Return the canonical IV being widened.
VPWidenCanonicalIVRecipe * clone() override
Clone the current recipe.
VPWidenCanonicalIVRecipe(VPRegionValue *CanonicalIV, const VPIRFlags::WrapFlagsTy &Flags={})
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
VPWidenCastRecipe is a recipe to create vector cast instructions.
Instruction::CastOps getOpcode() const
~VPWidenCastRecipe() override=default
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(Type *SourceElementTy, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags={}, DebugLoc DL=DebugLoc::getUnknown(), GetElementPtrInst *UV=nullptr)
void execute(VPTransformState &State) override=0
Generate the phi nodes.
ArrayRef< const SCEVPredicate * > getNoWrapPredicates() const
Returns the SCEV predicates associated with this induction.
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)
VPValue * getBackedgeValue() override
Returns the incoming value from the loop backedge.
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.
VPValue * getStepValue()
Returns the step value of the induction.
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
static bool classof(const VPRecipeBase *R)
VPWidenInductionRecipe(VPRecipeTy Kind, PHINode *IV, VPValue *Start, VPValue *Step, const InductionDescriptor &IndDesc, Type *ResultTy, DebugLoc DL)
const VPValue * getVFValue() const
static bool classof(const VPSingleDefRecipe *R)
const VPValue * getStepValue() const
void addUnrolledPartOperands(VPValue *SplatVFStep, VPValue *LastPart)
After unrolling, append the splat-VF step (VF * step) and the value of the induction at the last unro...
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...
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenIntOrFpInductionRecipe.
VPWidenIntOrFpInductionRecipe * clone() override
Clone the current recipe.
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, const VPIRFlags &Flags, DebugLoc DL)
bool isTruncated() const
Returns true if this induction is evaluated in a narrower type than the start value.
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, Type *ResultTy, 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.
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(VPRecipeTy SC, Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown())
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.
bool mayReadFromMemory() const
Returns true if the intrinsic may read from memory.
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.
static bool classof(const VPSingleDefRecipe *R)
static bool classof(const VPValue *V)
VPWidenIntrinsicRecipe * clone() override
Clone the current recipe.
bool mayWriteToMemory() const
Returns true if the intrinsic may write to memory.
~VPWidenIntrinsicRecipe() override=default
static bool classof(const VPRecipeBase *R)
static bool classof(const VPUser *U)
~VPWidenMemIntrinsicRecipe() override=default
VPWidenMemIntrinsicRecipe * clone() override
Clone the current recipe.
VPWidenMemIntrinsicRecipe(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, Align Alignment, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown())
A common mixin class for widening memory operations.
bool IsMasked
Whether the memory access is masked.
bool isConsecutive() const
Return whether the loaded-from / stored-to addresses are consecutive.
virtual ~VPWidenMemoryRecipe()=default
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const
Return the cost of this VPWidenMemoryRecipe.
Instruction & getIngredient() const
bool Consecutive
Whether the accessed addresses are consecutive.
VPWidenMemoryRecipe(Instruction &I, Align Alignment, bool Consecutive, const VPIRMetadata &Metadata)
virtual const VPRecipeBase * getAsRecipe() const =0
VPValue * getMask() const
Return the mask used by this recipe.
Align Alignment
Alignment information for this memory access.
virtual VPRecipeBase * getAsRecipe()=0
Return a VPRecipeBase* to the current object.
bool isMasked() const
Returns true if the recipe is masked.
void setMask(VPValue *Mask)
Align getAlign() const
Returns the alignment of the memory access.
VPValue * getAddr() const
Return the address accessed by this recipe.
A recipe for widened phis.
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
unsigned getOpcode() const
This recipe generates a PHI.
VPWidenPHIRecipe * clone() override
Clone the current recipe.
~VPWidenPHIRecipe() override=default
VPWidenPHIRecipe(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new VPWidenPHIRecipe with incoming values IncomingValues, debug location DL and Name.
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.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenPointerInductionRecipe.
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
VPWidenRecipe * cloneWithOperands(ArrayRef< VPValue * > NewOperands)
unsigned getOpcode() const
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
ElementCount getSingleVF() const
Returns the single VF of the plan, asserting that the plan has exactly one VF.
const DataLayout & getDataLayout() const
LLVMContext & getContext() const
VPBasicBlock * getEntry()
Type * getIndexType() const
The type of the canonical induction variable of the vector loop.
void setName(const Twine &newName)
bool hasScalableVF() const
VPValue * getTripCount() const
The trip count of the original loop.
iterator_range< SmallSetVector< ElementCount, 2 >::iterator > vectorFactors() const
Returns an iterator range over all VFs of the plan.
LLVM_ABI_FOR_TEST ~VPlan()
VPIRValue * getOrAddLiveIn(VPIRValue *V)
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.
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
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
VPIRValue * getPoison(Type *Ty)
Return a VPIRValue wrapping a poison value of type Ty.
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
VPlan(BasicBlock *ScalarHeaderBB, Type *IdxTy)
Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock wrapping ScalarHeaderBB and vect...
VPSymbolicValue & getVectorTripCount()
The vector trip count.
VPIRValue * getOrAddLiveIn(Value *V)
Gets the live-in VPIRValue for V or adds a new live-in (if none exists yet) for V.
VPRegionBlock * createLoopRegion(Type *CanIVTy, DebugLoc DL, const std::string &Name="", VPBlockBase *Entry=nullptr, VPBlockBase *Exiting=nullptr)
Create a new loop region with a canonical IV using CanIVTy and DL.
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
void setVF(ElementCount VF)
unsigned getMaxBlockNumber() const
bool isUnrolled() const
Returns true if the VPlan already has been unrolled, i.e.
Function * getIRFunction() const
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
bool hasEarlyExit() const
Returns true if the VPlan is based on a loop with an early exit.
InstructionCost cost(ElementCount VF, VPCostContext &Ctx)
Return the cost of this plan.
LLVM_ABI_FOR_TEST bool isOuterLoop() const
Returns true if this VPlan is for an outer loop, i.e., its vector loop region contains a nested loop ...
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
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.
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
bool requiresScalarEpilogue() const
Returns true if the plan requires a scalar epilogue after the vector loop.
LLVM_DUMP_METHOD void dump() const
Dump the plan to stderr (for debugging).
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
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.
bool hasTailFolded() const
Returns true if the vector loop region is tail-folded.
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.
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
const VPSymbolicValue & getVF() const
bool hasScalarTail() const
Returns true if the scalar tail may execute after the vector loop, i.e.
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...
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.
const ParentTy * getParent() const
void setParent(ParentTy *Parent)
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.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
CastInfo helper for casting from VPRecipeBase to a mixin class that is not part of the VPRecipeBase c...
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
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,...
Type * toScalarizedTy(Type *Ty)
A helper for converting vectorized types to scalarized (non-vector) types.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
VPBuilderBase<> VPBuilder
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.
HistogramUpdateKind
The kind of update operation performed on the buckets of a histogram, i.e.
auto cast_or_null(const Y &Val)
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
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)
UncountableExitStyle
Different methods of handling early exits.
@ MaskedHandleExitInScalarLoop
All memory operations other than the load(s) required to determine whether an uncountable exit occurr...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isPointerTy(const Type *T)
LLVM_ABI Type * computeScalarTypeForInstruction(unsigned Opcode, ArrayRef< VPValue * > Operands)
Compute the scalar result type for an IR Opcode given Operands.
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.
@ AddChainWithSubs
A chain of adds and subs.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
auto sum_of(R &&Range, E Init=E{0})
Returns the sum of all values in Range with Init initial value.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
std::variant< RdxOrdered, RdxInLoop, RdxUnordered > ReductionStyle
@ Increment
Incrementally increasing token ID.
std::unique_ptr< VPlan > VPlanPtr
Implement std::hash so that hash_code can be used in STL containers.
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.
This struct provides a method for customizing the way a cast is performed.
Provides a cast trait that strips const from types to make it easier to implement a const-version of ...
This cast trait just provides the default implementation of doCastIfPossible to make CastInfo special...
Provides a cast trait that uses a defined pointer to pointer cast as a base for reference-to-referenc...
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.
Default inserter for VPBuilderBase, inserting R before It.
An overlay on VPConstant for VPValues that wrap a ConstantInt.
Struct to hold various analysis needed for cost computations.
const BlockFrequency Freq
VPExecutionFrequency(BlockFrequency Freq, bool IsEstimated)
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)
WrapFlagsTy withoutNoSignedWrap()
An overlay for VPIRInstructions wrapping PHI nodes enabling convenient use cast/dyn_cast/isa and exec...
static bool classof(const VPRecipeBase *U)
static bool classof(const VPUser *U)
PHINode & getIRPhi() const
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.
static bool classof(const VPUser *U)
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)
VPPhi(ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL, const Twine &Name="", Type *ResultTy=nullptr)
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.
static bool classof(const VPValue *V)
VPRecipeWithIRFlags(VPRecipeTy SC, ArrayRef< VPValue * > Operands, Type *ResultTy, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown())
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 recipe for widening load operations with vector-predication intrinsics, using the address to load f...
VPWidenLoadEVLRecipe * clone() override
Clone the current recipe.
unsigned getOpcode() const
Returns the opcode of the widened load.
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.
unsigned getOpcode() const
Returns the opcode of the widened load.
VPWidenLoadRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, Align Alignment, const VPIRMetadata &Metadata, DebugLoc DL)
VPWidenLoadRecipe * clone() override
Clone the current recipe.
VP_CLASSOF_IMPL(VPRecipeBase::VPWidenLoadSC)
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenLoadRecipe.
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.
VPWidenStoreEVLRecipe * clone() override
Clone the current recipe.
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.
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...
VPWidenStoreRecipe(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, Align Alignment, const VPIRMetadata &Metadata, DebugLoc DL)
VP_CLASSOF_IMPL(VPRecipeBase::VPWidenStoreSC)
VPValue * getStoredValue() const
Return the value stored by this recipe.
VPWidenStoreRecipe * clone() override
Clone the current recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenStoreRecipe.
bool usesFirstLaneOnly(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
static VPMixin * castFailed()
static bool isPossible(VPRecipeBase *R)
Used by isa.
static VPMixin * doCast(VPRecipeBase *R)
Used by cast.