24#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
25#define LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
52class InnerLoopVectorizer;
54struct VPTransformState;
56class RecurrenceDescriptor;
65class VPReplicateRecipe;
68class LoopVectorizationCostModel;
84 const unsigned char SubclassID;
101 VPlan *Plan =
nullptr;
105 assert(Successor &&
"Cannot add nullptr successor!");
111 assert(Predecessor &&
"Cannot add nullptr predecessor!");
116 void removePredecessor(VPBlockBase *Predecessor) {
117 auto Pos =
find(Predecessors, Predecessor);
118 assert(Pos &&
"Predecessor does not exist");
119 Predecessors.
erase(Pos);
123 void removeSuccessor(VPBlockBase *Successor) {
124 auto Pos =
find(Successors, Successor);
125 assert(Pos &&
"Successor does not exist");
126 Successors.
erase(Pos);
131 void replacePredecessor(VPBlockBase *Old, VPBlockBase *New) {
132 auto I =
find(Predecessors, Old);
134 assert(Old->getParent() ==
New->getParent() &&
135 "replaced predecessor must have the same parent");
141 void replaceSuccessor(VPBlockBase *Old, VPBlockBase *New) {
142 auto I =
find(Successors, Old);
144 assert(Old->getParent() ==
New->getParent() &&
145 "replaced successor must have the same parent");
151 : SubclassID(SC),
Name(
N) {}
158 using VPBlockTy =
enum { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC };
178 const VPlan *getPlan()
const;
182 void setPlan(
VPlan *ParentPlan);
210 return (Successors.
size() == 1 ? *Successors.
begin() :
nullptr);
216 return (Predecessors.
size() == 1 ? *Predecessors.
begin() :
nullptr);
243 return getEnclosingBlockWithSuccessors()->getSuccessors();
259 return getEnclosingBlockWithPredecessors()->getPredecessors();
272 assert(Successors.
empty() &&
"Setting one successor when others exist.");
274 "connected blocks must have the same parent");
283 assert(Successors.
empty() &&
"Setting two successors when others exist.");
284 appendSuccessor(IfTrue);
285 appendSuccessor(IfFalse);
292 assert(Predecessors.
empty() &&
"Block predecessors already set.");
293 for (
auto *Pred : NewPreds)
294 appendPredecessor(Pred);
301 assert(Successors.
empty() &&
"Block successors already set.");
302 for (
auto *Succ : NewSuccs)
303 appendSuccessor(Succ);
315 assert(Predecessors.
size() == 2 &&
"must have 2 predecessors to swap");
316 std::swap(Predecessors[0], Predecessors[1]);
323 assert(Successors.
size() == 2 &&
"must have 2 successors to swap");
330 "must have Pred exactly once in Predecessors");
331 return std::distance(Predecessors.
begin(),
find(Predecessors, Pred));
337 "must have Succ exactly once in Successors");
338 return std::distance(Successors.
begin(),
find(Successors, Succ));
355#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
449 void removeFromParent();
471 bool mayReadFromMemory()
const;
474 bool mayWriteToMemory()
const;
478 return mayReadFromMemory() || mayWriteToMemory();
485 bool isScalarCast()
const;
499#define VP_CLASSOF_IMPL(VPDefID) \
500 static inline bool classof(const VPDef *D) { \
501 return D->getVPDefID() == VPDefID; \
503 static inline bool classof(const VPValue *V) { \
504 auto *R = V->getDefiningRecipe(); \
505 return R && R->getVPDefID() == VPDefID; \
507 static inline bool classof(const VPUser *U) { \
508 auto *R = dyn_cast<VPRecipeBase>(U); \
509 return R && R->getVPDefID() == VPDefID; \
511 static inline bool classof(const VPRecipeBase *R) { \
512 return R->getVPDefID() == VPDefID; \
514 static inline bool classof(const VPSingleDefRecipe *R) { \
515 return R->getVPDefID() == VPDefID; \
532 switch (R->getVPDefID()) {
533 case VPRecipeBase::VPDerivedIVSC:
534 case VPRecipeBase::VPEVLBasedIVPHISC:
535 case VPRecipeBase::VPExpandSCEVSC:
536 case VPRecipeBase::VPExpressionSC:
537 case VPRecipeBase::VPInstructionSC:
538 case VPRecipeBase::VPReductionEVLSC:
539 case VPRecipeBase::VPReductionSC:
540 case VPRecipeBase::VPReplicateSC:
541 case VPRecipeBase::VPScalarIVStepsSC:
542 case VPRecipeBase::VPVectorPointerSC:
543 case VPRecipeBase::VPVectorEndPointerSC:
544 case VPRecipeBase::VPWidenCallSC:
545 case VPRecipeBase::VPWidenCanonicalIVSC:
546 case VPRecipeBase::VPWidenCastSC:
547 case VPRecipeBase::VPWidenGEPSC:
548 case VPRecipeBase::VPWidenIntrinsicSC:
549 case VPRecipeBase::VPWidenSC:
550 case VPRecipeBase::VPWidenSelectSC:
551 case VPRecipeBase::VPBlendSC:
552 case VPRecipeBase::VPPredInstPHISC:
553 case VPRecipeBase::VPCanonicalIVPHISC:
554 case VPRecipeBase::VPActiveLaneMaskPHISC:
555 case VPRecipeBase::VPFirstOrderRecurrencePHISC:
556 case VPRecipeBase::VPWidenPHISC:
557 case VPRecipeBase::VPWidenIntOrFpInductionSC:
558 case VPRecipeBase::VPWidenPointerInductionSC:
559 case VPRecipeBase::VPReductionPHISC:
560 case VPRecipeBase::VPPartialReductionSC:
562 case VPRecipeBase::VPBranchOnMaskSC:
563 case VPRecipeBase::VPInterleaveEVLSC:
564 case VPRecipeBase::VPInterleaveSC:
565 case VPRecipeBase::VPIRInstructionSC:
566 case VPRecipeBase::VPWidenLoadEVLSC:
567 case VPRecipeBase::VPWidenLoadSC:
568 case VPRecipeBase::VPWidenStoreEVLSC:
569 case VPRecipeBase::VPWidenStoreSC:
570 case VPRecipeBase::VPHistogramSC:
579 auto *R = dyn_cast<VPRecipeBase>(U);
593#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
601 enum class OperationType :
unsigned char {
639 struct ExactFlagsTy {
642 struct FastMathFlagsTy {
643 char AllowReassoc : 1;
646 char NoSignedZeros : 1;
647 char AllowReciprocal : 1;
648 char AllowContract : 1;
654 OperationType OpType;
672 if (
auto *
Op = dyn_cast<CmpInst>(&
I)) {
673 OpType = OperationType::Cmp;
675 }
else if (
auto *
Op = dyn_cast<PossiblyDisjointInst>(&
I)) {
676 OpType = OperationType::DisjointOp;
678 }
else if (
auto *
Op = dyn_cast<OverflowingBinaryOperator>(&
I)) {
679 OpType = OperationType::OverflowingBinOp;
680 WrapFlags = {
Op->hasNoUnsignedWrap(),
Op->hasNoSignedWrap()};
681 }
else if (
auto *
Op = dyn_cast<TruncInst>(&
I)) {
682 OpType = OperationType::Trunc;
684 }
else if (
auto *
Op = dyn_cast<PossiblyExactOperator>(&
I)) {
685 OpType = OperationType::PossiblyExactOp;
687 }
else if (
auto *
GEP = dyn_cast<GetElementPtrInst>(&
I)) {
688 OpType = OperationType::GEPOp;
690 }
else if (
auto *PNNI = dyn_cast<PossiblyNonNegInst>(&
I)) {
691 OpType = OperationType::NonNegOp;
693 }
else if (
auto *
Op = dyn_cast<FPMathOperator>(&
I)) {
694 OpType = OperationType::FPMathOp;
695 FMFs =
Op->getFastMathFlags();
697 OpType = OperationType::Other;
721 OpType =
Other.OpType;
730 case OperationType::OverflowingBinOp:
734 case OperationType::Trunc:
738 case OperationType::DisjointOp:
741 case OperationType::PossiblyExactOp:
744 case OperationType::GEPOp:
747 case OperationType::FPMathOp:
751 case OperationType::NonNegOp:
754 case OperationType::Cmp:
755 case OperationType::Other:
763 case OperationType::OverflowingBinOp:
767 case OperationType::Trunc:
771 case OperationType::DisjointOp:
774 case OperationType::PossiblyExactOp:
777 case OperationType::GEPOp:
778 cast<GetElementPtrInst>(&
I)->setNoWrapFlags(
GEPFlags);
780 case OperationType::FPMathOp:
781 I.setHasAllowReassoc(
FMFs.AllowReassoc);
782 I.setHasNoNaNs(
FMFs.NoNaNs);
783 I.setHasNoInfs(
FMFs.NoInfs);
784 I.setHasNoSignedZeros(
FMFs.NoSignedZeros);
785 I.setHasAllowReciprocal(
FMFs.AllowReciprocal);
786 I.setHasAllowContract(
FMFs.AllowContract);
787 I.setHasApproxFunc(
FMFs.ApproxFunc);
789 case OperationType::NonNegOp:
792 case OperationType::Cmp:
793 case OperationType::Other:
799 assert(OpType == OperationType::Cmp &&
800 "recipe doesn't have a compare predicate");
805 assert(OpType == OperationType::Cmp &&
806 "recipe doesn't have a compare predicate");
824 assert(OpType == OperationType::NonNegOp &&
825 "recipe doesn't have a NNEG flag");
831 case OperationType::OverflowingBinOp:
833 case OperationType::Trunc:
842 case OperationType::OverflowingBinOp:
844 case OperationType::Trunc:
852 assert(OpType == OperationType::DisjointOp &&
853 "recipe cannot have a disjoing flag");
862#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
884 return R->getVPDefID() == VPRecipeBase::VPInstructionSC ||
885 R->getVPDefID() == VPRecipeBase::VPWidenSC ||
886 R->getVPDefID() == VPRecipeBase::VPWidenGEPSC ||
887 R->getVPDefID() == VPRecipeBase::VPWidenCallSC ||
888 R->getVPDefID() == VPRecipeBase::VPWidenCastSC ||
889 R->getVPDefID() == VPRecipeBase::VPWidenIntrinsicSC ||
890 R->getVPDefID() == VPRecipeBase::VPWidenSelectSC ||
891 R->getVPDefID() == VPRecipeBase::VPReductionSC ||
892 R->getVPDefID() == VPRecipeBase::VPReductionEVLSC ||
893 R->getVPDefID() == VPRecipeBase::VPReplicateSC ||
894 R->getVPDefID() == VPRecipeBase::VPVectorEndPointerSC ||
895 R->getVPDefID() == VPRecipeBase::VPVectorPointerSC;
899 auto *R = dyn_cast<VPRecipeBase>(U);
904 auto *R = dyn_cast_or_null<VPRecipeBase>(V->getDefiningRecipe());
909 auto *R = dyn_cast<VPRecipeBase>(U);
916 std::optional<InstructionCost>
930 unsigned getUnrollPart(
const VPUser &U)
const;
982 FirstOrderRecurrenceSplice =
983 Instruction::OtherOpsEnd + 1,
1062 typedef unsigned char OpcodeTy;
1066 const std::string
Name;
1074 bool doesGeneratePerAllLanes()
const;
1078 bool canGenerateScalarForFirstLane()
const;
1094 static unsigned getNumOperandsForOpcode(
unsigned Opcode);
1112 if (getUnderlyingValue())
1113 New->setUnderlyingValue(getUnderlyingInstr());
1128#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1141 case Instruction::Ret:
1142 case Instruction::Br:
1143 case Instruction::Store:
1144 case Instruction::Switch:
1145 case Instruction::IndirectBr:
1146 case Instruction::Resume:
1147 case Instruction::CatchRet:
1148 case Instruction::Unreachable:
1149 case Instruction::Fence:
1150 case Instruction::AtomicRMW:
1151 case VPInstruction::BranchOnCond:
1152 case VPInstruction::BranchOnCount:
1160 bool opcodeMayReadOrWriteFromMemory()
const;
1163 bool onlyFirstLaneUsed(
const VPValue *
Op)
const override;
1166 bool onlyFirstPartUsed(
const VPValue *
Op)
const override;
1170 bool isVectorToScalar()
const;
1174 bool isSingleScalar()
const;
1192 const Twine &Name =
"")
1198 if (R->isScalarCast())
1200 auto *VPI = dyn_cast<VPInstruction>(R);
1203 switch (VPI->getOpcode()) {
1214 return isa<VPInstructionWithType>(cast<VPRecipeBase>(R));
1237#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1278 std::function<
const VPBasicBlock *(size_t)> GetBlock = [
this](
size_t Idx) {
1296#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1307 auto *VPI = dyn_cast<VPInstruction>(U);
1308 return VPI && VPI->getOpcode() == Instruction::PHI;
1312 auto *VPI = dyn_cast<VPInstruction>(V);
1313 return VPI && VPI->getOpcode() == Instruction::PHI;
1317 auto *VPI = dyn_cast<VPInstruction>(SDR);
1318 return VPI && VPI->getOpcode() == Instruction::PHI;
1323 PhiR->setUnderlyingValue(getUnderlyingValue());
1329#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1375#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1383 "Op must be an operand of the recipe");
1389 "Op must be an operand of the recipe");
1395 "Op must be an operand of the recipe");
1414 auto *R = dyn_cast<VPIRInstruction>(U);
1415 return R && isa<PHINode>(R->getInstruction());
1422#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1456 R->setUnderlyingValue(getUnderlyingValue());
1472#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1491 Opcode(Opcode), ResultTy(ResultTy) {
1493 "opcode of underlying cast doesn't match");
1502 "Set flags not supported for the provided opcode");
1510 *cast<CastInst>(UV));
1524#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1545 bool MayReadFromMemory;
1548 bool MayWriteToMemory;
1551 bool MayHaveSideEffects;
1558 VPIRMetadata(CI), VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty),
1567 VPIRMetadata(), VectorIntrinsicID(VectorIntrinsicID), ResultTy(Ty) {
1573 MayHaveSideEffects = MayWriteToMemory ||
1574 !Attrs.hasAttribute(Attribute::NoUnwind) ||
1575 !Attrs.hasAttribute(Attribute::WillReturn);
1615#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1640 isa<Function>(getOperand(getNumOperands() - 1)->getLiveInIRValue()) &&
1641 "last operand must be the called function");
1661 return cast<Function>(getOperand(getNumOperands() - 1)->getLiveInIRValue());
1667#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1711#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1741#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1750 return getOperand(0);
1754 return getCond()->isDefinedOutsideLoopRegions();
1760 "Op must be an operand of the recipe");
1761 return Op == getCond() && isInvariantCond();
1767 bool isPointerLoopInvariant()
const {
1771 bool isIndexLoopInvariant(
unsigned I)
const {
1772 return getOperand(
I + 1)->isDefinedOutsideLoopRegions();
1775 bool areAllOperandsInvariant()
const {
1777 return Op->isDefinedOutsideLoopRegions();
1809#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1818 "Op must be an operand of the recipe");
1819 if (
Op == getOperand(0))
1820 return isPointerLoopInvariant();
1822 return !isPointerLoopInvariant() &&
Op->isDefinedOutsideLoopRegions();
1842 IndexedTy(IndexedTy), Stride(Stride) {
1843 assert(Stride < 0 &&
"Stride must be negative");
1855 "Op must be an operand of the recipe");
1869 "Op must be an operand of the recipe");
1880#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1897 IndexedTy(IndexedTy) {}
1905 "Op must be an operand of the recipe");
1912 "Op must be an operand of the recipe");
1933#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1969 UnderlyingInstr,
DL) {}
1978 return B->getVPDefID() >= VPDef::VPFirstHeaderPHISC &&
1979 B->getVPDefID() <= VPDef::VPLastHeaderPHISC;
1982 auto *
B = V->getDefiningRecipe();
1983 return B &&
B->getVPDefID() >= VPRecipeBase::VPFirstHeaderPHISC &&
1984 B->getVPDefID() <= VPRecipeBase::VPLastHeaderPHISC;
1994#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2002 return getNumOperands() == 0 ? nullptr : getOperand(0);
2005 return getNumOperands() == 0 ? nullptr : getOperand(0);
2013 return getOperand(1);
2022 return *getBackedgeValue()->getDefiningRecipe();
2041 return R->getVPDefID() == VPDef::VPWidenIntOrFpInductionSC ||
2042 R->getVPDefID() == VPDef::VPWidenPointerInductionSC;
2046 auto *R = V->getDefiningRecipe();
2080 "VPWidenIntOrFpInductionRecipe generates its own backedge value");
2087 "VPWidenIntOrFpInductionRecipe generates its own backedge value");
2093 "Op must be an operand of the recipe");
2146 "expandVPWidenIntOrFpInductionRecipe");
2149#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2178 return Trunc ? Trunc->
getType()
2191 bool IsScalarAfterVectorization;
2200 bool IsScalarAfterVectorization,
DebugLoc DL)
2203 IsScalarAfterVectorization(IsScalarAfterVectorization) {
2221 "expandVPWidenPointerInduction");
2227#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2273#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2300#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2309 "Op must be an operand of the recipe");
2330 unsigned VFScaleFactor = 1;
2335 bool IsInLoop =
false,
bool IsOrdered =
false,
2336 unsigned VFScaleFactor = 1)
2338 IsInLoop(IsInLoop), IsOrdered(IsOrdered), VFScaleFactor(VFScaleFactor) {
2339 assert((!IsOrdered || IsInLoop) &&
"IsOrdered requires IsInLoop");
2347 *
getOperand(0), IsInLoop, IsOrdered, VFScaleFactor);
2360#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2383 "Op must be an operand of the recipe");
2402 return new VPBlendRecipe(cast_or_null<PHINode>(getUnderlyingValue()),
2410 bool isNormalized()
const {
return getNumOperands() % 2; }
2415 return (getNumOperands() + isNormalized()) / 2;
2420 return Idx == 0 ? getOperand(0) : getOperand(
Idx * 2 - isNormalized());
2425 assert((
Idx > 0 || !isNormalized()) &&
"First index has no mask!");
2426 return Idx == 0 ? getOperand(1) : getOperand(
Idx * 2 + !isNormalized());
2437#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2446 "Op must be an operand of the recipe");
2450 [
this](
VPUser *U) {
return U->onlyFirstLaneUsed(
this); });
2465 bool HasMask =
false;
2469 bool NeedsMaskForGaps =
false;
2478 NeedsMaskForGaps(NeedsMaskForGaps) {
2481 "Reversed masked interleave-group not supported.");
2484 if (Inst->getType()->isVoidTy())
2489 for (
auto *SV : StoredValues)
2501 return R->getVPDefID() == VPRecipeBase::VPInterleaveSC ||
2502 R->getVPDefID() == VPRecipeBase::VPInterleaveEVLSC;
2506 auto *R = dyn_cast<VPRecipeBase>(U);
2507 return R && classof(R);
2512 return getOperand(0);
2519 return HasMask ? getOperand(getNumOperands() - 1) :
nullptr;
2548 (getNumStoreOperands() + (HasMask ? 1 : 0)),
2549 getNumStoreOperands());
2563 NeedsMaskForGaps, MD,
DL) {}
2578#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2586 "Op must be an operand of the recipe");
2591 return getNumOperands() - (
getMask() ? 2 : 1);
2603 R.getStoredValues(), Mask, R.needsMaskForGaps(), R,
2605 assert(!getInterleaveGroup()->isReverse() &&
2606 "Reversed interleave-group with tail folding is not supported.");
2607 assert(!needsMaskForGaps() &&
"Interleaved access with gap mask is not "
2608 "supported for scalable vector.");
2625#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2634 "Op must be an operand of the recipe");
2640 return getNumOperands() - (
getMask() ? 3 : 2);
2652 bool IsConditional =
false;
2660 IsOrdered(IsOrdered) {
2662 IsConditional =
true;
2665 setUnderlyingValue(
I);
2671 bool IsOrdered,
DebugLoc DL = DebugLoc::getUnknown())
2678 bool IsOrdered,
DebugLoc DL = DebugLoc::getUnknown())
2687 getUnderlyingInstr(), getChainOp(), getVecOp(),
2692 return R->getVPDefID() == VPRecipeBase::VPReductionSC ||
2693 R->getVPDefID() == VPRecipeBase::VPReductionEVLSC;
2697 auto *R = dyn_cast<VPRecipeBase>(U);
2698 return R && classof(R);
2708#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2726 return isConditional() ? getOperand(getNumOperands() - 1) :
nullptr;
2739 unsigned VFScaleFactor;
2745 VFScaleFactor, ReductionInst) {}
2752 Opcode(Opcode), VFScaleFactor(ScaleFactor) {
2753 [[maybe_unused]]
auto *AccumulatorRecipe =
2755 assert((isa<VPReductionPHIRecipe>(AccumulatorRecipe) ||
2756 isa<VPPartialReductionRecipe>(AccumulatorRecipe)) &&
2757 "Unexpected operand order for partial reduction recipe");
2782#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2798 VPDef::VPReductionEVLSC, R.getRecurrenceKind(),
2799 R.getFastMathFlags(),
2802 R.isOrdered(),
DL) {}
2815#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2827 "Op must be an operand of the recipe");
2828 return Op == getEVL();
2839 bool IsSingleScalar;
2846 bool IsSingleScalar,
VPValue *Mask =
nullptr,
2850 IsPredicated(Mask) {
2860 isPredicated() ?
getMask() :
nullptr, *
this);
2861 Copy->transferFlags(*
this);
2876#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2889 "Op must be an operand of the recipe");
2890 return isSingleScalar();
2896 "Op must be an operand of the recipe");
2903 bool shouldPack()
const;
2907 assert(isPredicated() &&
"Trying to get the mask of a unpredicated recipe");
2908 return getOperand(getNumOperands() - 1);
2911 unsigned getOpcode()
const {
return getUnderlyingInstr()->getOpcode(); }
2934#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
2938 O << Indent <<
"BRANCH-ON-MASK ";
2946 "Op must be an operand of the recipe");
2968 enum class ExpressionTypes {
2984 ExpressionTypes ExpressionType;
3003 {Ext0, Ext1,
Mul, Red}) {}
3006 for (
auto *R :
reverse(ExpressionRecipes))
3008 for (
VPValue *
T : LiveInPlaceholders)
3015 assert(!ExpressionRecipes.
empty() &&
"empty expressions should be removed");
3017 for (
auto *R : ExpressionRecipes)
3018 NewExpressiondRecipes.
push_back(R->clone());
3019 for (
auto *New : NewExpressiondRecipes) {
3020 for (
const auto &[
Idx, Old] :
enumerate(ExpressionRecipes))
3021 New->replaceUsesOfWith(Old, NewExpressiondRecipes[
Idx]);
3024 for (
const auto &[Placeholder, OutsideOp] :
3026 New->replaceUsesOfWith(Placeholder, OutsideOp);
3034 cast<VPReductionRecipe>(ExpressionRecipes.
back())->isConditional() ? 2
3052#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3097#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3106 "Op must be an operand of the recipe");
3125 bool IsMasked =
false;
3128 assert(!IsMasked &&
"cannot re-set mask");
3136 std::initializer_list<VPValue *>
Operands,
3137 bool Consecutive,
bool Reverse,
3141 assert((Consecutive || !
Reverse) &&
"Reverse implies consecutive");
3150 return R->getVPDefID() == VPRecipeBase::VPWidenLoadSC ||
3151 R->getVPDefID() == VPRecipeBase::VPWidenStoreSC ||
3152 R->getVPDefID() == VPRecipeBase::VPWidenLoadEVLSC ||
3153 R->getVPDefID() == VPRecipeBase::VPWidenStoreEVLSC;
3157 auto *R = dyn_cast<VPRecipeBase>(U);
3158 return R && classof(R);
3178 return isMasked() ? getOperand(getNumOperands() - 1) :
nullptr;
3198 bool Consecutive,
bool Reverse,
3217#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3226 "Op must be an operand of the recipe");
3229 return Op == getAddr() && isConsecutive();
3240 {
Addr, &EVL}, L.isConsecutive(), L.isReverse(), L,
3258#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3267 "Op must be an operand of the recipe");
3278 VPValue *Mask,
bool Consecutive,
bool Reverse,
3299#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3308 "Op must be an operand of the recipe");
3323 S.isReverse(), S, S.getDebugLoc()) {
3342#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3351 "Op must be an operand of the recipe");
3378 llvm_unreachable(
"SCEV expressions must be expanded before final execute");
3388#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3418 "scalar phi recipe");
3421#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3435 "Op must be an operand of the recipe");
3442 "Op must be an operand of the recipe");
3478#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3504 "scalar phi recipe");
3517 "Op must be an operand of the recipe");
3521#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3539 cast<VPCanonicalIVPHIRecipe>(
getOperand(0)));
3556#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3579 const Twine &Name =
"")
3583 Start, CanonicalIV, Step, Name) {}
3589 FPBinOp(FPBinOp), Name(Name.str()) {}
3611#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3627 "Op must be an operand of the recipe");
3644 InductionOpcode(Opcode) {}
3650 IV, Step, VF, IndDesc.getInductionOpcode(),
3652 ? IndDesc.getInductionBinOp()->getFastMathFlags()
3660 getOperand(0), getOperand(1), getOperand(2), InductionOpcode,
3667 bool isPart0()
const {
return getUnrollPart(*
this) == 0; }
3681#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3692 "Op must be an operand of the recipe");
3702 return isa<VPIRPhi, VPHeaderPHIRecipe, VPWidenPHIRecipe, VPPhi>(f);
3707template <
typename SrcTy>
3715 switch (R->getVPDefID()) {
3716 case VPDef::VPInstructionSC:
3717 return cast<VPPhi>(R);
3718 case VPDef::VPIRInstructionSC:
3719 return cast<VPIRPhi>(R);
3720 case VPDef::VPWidenPHISC:
3721 return cast<VPWidenPHIRecipe>(R);
3723 return cast<VPHeaderPHIRecipe>(R);
3752 appendRecipe(Recipe);
3767 while (!Recipes.empty())
3790 inline size_t size()
const {
return Recipes.size(); }
3791 inline bool empty()
const {
return Recipes.empty(); }
3802 return &VPBasicBlock::Recipes;
3807 return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC ||
3808 V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
3812 assert(Recipe &&
"No recipe to append.");
3813 assert(!Recipe->Parent &&
"Recipe already in VPlan");
3814 Recipe->Parent =
this;
3815 Recipes.
insert(InsertPt, Recipe);
3830 iterator getFirstNonPhi();
3834 return make_range(begin(), getFirstNonPhi());
3845#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3853 using VPBlockBase::print;
3862 bool isExiting()
const;
3888inline const VPBasicBlock *
3913 return V->getVPBlockID() == VPBlockBase::VPIRBasicBlockSC;
3949 const std::string &
Name =
"",
bool IsReplicator =
false)
3951 IsReplicator(IsReplicator) {
3952 assert(Entry->getPredecessors().empty() &&
"Entry block has predecessors.");
3954 Entry->setParent(
this);
3958 :
VPBlockBase(VPRegionBlockSC,
Name), Entry(nullptr), Exiting(nullptr),
3959 IsReplicator(IsReplicator) {}
3966 return V->getVPBlockID() == VPBlockBase::VPRegionBlockSC;
3976 "Entry block cannot have predecessors.");
3988 "Exit block cannot have successors.");
3989 Exiting = ExitingBlock;
3995 assert(!isReplicator() &&
"should only get pre-header of loop regions");
3996 return getSinglePredecessor()->getExitingBasicBlock();
4010#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4019 using VPBlockBase::print;
4028 void dissolveToCFGLoop();
4071 VPValue *BackedgeTakenCount =
nullptr;
4102 : Entry(Entry), ScalarHeader(ScalarHeader) {
4103 Entry->setPlan(
this);
4105 "scalar header must be a leaf node");
4164 "cannot call the function after vector loop region has been removed");
4166 if (RegionSucc->getSingleSuccessor() ||
4170 return cast<VPBasicBlock>(RegionSucc->getSuccessors()[1]);
4198 assert(TripCount &&
"trip count needs to be set before accessing it");
4205 assert(!TripCount && NewTripCount &&
"TripCount should not be set yet.");
4206 TripCount = NewTripCount;
4213 "TripCount must be set when resetting");
4214 TripCount = NewTripCount;
4219 if (!BackedgeTakenCount)
4220 BackedgeTakenCount =
new VPValue();
4221 return BackedgeTakenCount;
4240 assert(
hasVF(VF) &&
"Cannot set VF not already in plan");
4257 bool HasScalarVFOnly = VFs.
size() == 1 && VFs[0].isScalar();
4259 "Plan with scalar VF should only have a single VF");
4260 return HasScalarVFOnly;
4266 assert(UFs.
size() == 1 &&
"Expected a single UF");
4271 assert(
hasUF(UF) &&
"Cannot set the UF not already in plan");
4288 assert(V &&
"Trying to get or add the VPValue of a null Value");
4289 auto [It, Inserted] = Value2VPValue.
try_emplace(V);
4297 assert(It->second->isLiveIn() &&
"Only live-ins should be in mapping");
4319 [
this](
const auto &
P) {
4322 "all VPValues in Value2VPValue must also be in VPLiveIns");
4326#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4343 if (EntryVPBB->
empty()) {
4347 return cast<VPCanonicalIVPHIRecipe>(&*EntryVPBB->
begin());
4351 return SCEVToExpansion.
lookup(S);
4356 SCEVToExpansion[S] = V;
4377 const std::string &
Name =
"",
4378 bool IsReplicator =
false) {
4412 (ExitBlocks.
size() == 1 && ExitBlocks[0]->getNumPredecessors() > 1);
4424#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)
static const Function * getParent(const Value *V)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
std::optional< std::vector< StOtherPiece > > Other
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)
mir Rename Register Operands
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
MachineInstr unsigned OpIdx
static StringRef getName(Value *V)
const SmallVectorImpl< MachineOperand > & Cond
static bool mayHaveSideEffects(MachineInstr &MI)
This file implements the SmallBitVector class.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static const BasicSubtargetSubTypeKV * find(StringRef S, ArrayRef< BasicSubtargetSubTypeKV > A)
Find KV in array using binary search.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
This file contains the declarations of the entities induced by Vectorization Plans,...
#define VP_CLASSOF_IMPL(VPDefID)
static const uint32_t IV[8]
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
This class represents an Operation in the Expression.
static DebugLoc getUnknown()
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
static constexpr ElementCount getFixed(ScalarTy MinVal)
Utility class for floating point operations which can have information about relaxed accuracy require...
Convenience struct for specifying and reasoning about fast-math flags.
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags none()
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
A struct for saving information about induction variables.
InductionKind
This enum represents the kinds of inductions that we support.
The group of interleaved loads/stores sharing the same stride and close to each other.
uint32_t getFactor() const
InstTy * getMember(uint32_t Index) const
Get the member with the given index Index.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
Represents a single loop in the control flow graph.
bool onlyWritesMemory() const
Whether this function only (at most) writes memory.
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
This class represents an analyzed expression in the program.
This class represents the LLVM 'select' instruction.
size_type size() const
Determine the number of elements in the SetVector.
void clear()
Completely clear the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
This class provides computation of slot numbers for LLVM Assembly writing.
A SetVector that performs no allocations if smaller than a certain size.
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
This class represents a truncation of integer types.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
A recipe for generating the active lane mask for the vector loop that is used to predicate the vector...
void execute(VPTransformState &State) override
Generate the active lane mask phi of the vector loop.
VPActiveLaneMaskPHIRecipe * clone() override
Clone the current recipe.
VPActiveLaneMaskPHIRecipe(VPValue *StartMask, DebugLoc DL)
~VPActiveLaneMaskPHIRecipe() override=default
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
RecipeListTy::const_iterator const_iterator
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
RecipeListTy::const_reverse_iterator const_reverse_iterator
RecipeListTy::iterator iterator
Instruction iterators...
RecipeListTy & getRecipeList()
Returns a reference to the list of recipes.
VPBasicBlock(const unsigned char BlockSC, const Twine &Name="")
iterator begin()
Recipe iterator methods.
RecipeListTy::reverse_iterator reverse_iterator
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
const VPBasicBlock * getCFGPredecessor(unsigned Idx) const
Returns the predecessor block at index Idx with the predecessors as per the corresponding plain CFG.
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
A recipe for vectorizing a phi-node as a sequence of mask-based select instructions.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPValue * getIncomingValue(unsigned Idx) const
Return incoming value number Idx.
VPValue * getMask(unsigned Idx) const
Return mask number Idx.
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 * clone() override
Clone the current recipe.
VPBlendRecipe(PHINode *Phi, ArrayRef< VPValue * > Operands, DebugLoc DL)
The blend operation is a User of the incoming values and of their respective masks,...
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
VPRegionBlock * getParent()
VPBlocksTy & getPredecessors()
iterator_range< VPBlockBase ** > predecessors()
LLVM_DUMP_METHOD void dump() const
Dump this VPBlockBase to dbgs().
void setName(const Twine &newName)
size_t getNumSuccessors() const
iterator_range< VPBlockBase ** > successors()
virtual void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const =0
Print plain-text dump of this VPBlockBase to O, prefixing all lines with Indent.
bool hasPredecessors() const
Returns true if this block has any predecessors.
void swapSuccessors()
Swap successors of the block. The block must have exactly 2 successors.
bool isLegalToHoistInto()
Return true if it is legal to hoist instructions into this block.
virtual ~VPBlockBase()=default
const VPBlocksTy & getHierarchicalPredecessors()
unsigned getIndexForSuccessor(const VPBlockBase *Succ) const
Returns the index for Succ in the blocks successor list.
size_t getNumPredecessors() const
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
unsigned getIndexForPredecessor(const VPBlockBase *Pred) const
Returns the index for Pred in the blocks predecessors list.
const VPBlocksTy & getPredecessors() const
virtual VPBlockBase * clone()=0
Clone the current block and it's recipes without updating the operands of the cloned recipes,...
enum { VPRegionBlockSC, VPBasicBlockSC, VPIRBasicBlockSC } VPBlockTy
An enumeration for keeping track of the concrete subclass of VPBlockBase that are actually instantiat...
virtual InstructionCost cost(ElementCount VF, VPCostContext &Ctx)=0
Return the cost of the block.
void setPlan(VPlan *ParentPlan)
Sets the pointer of the plan containing the block.
const VPRegionBlock * getParent() const
const std::string & getName() const
void clearSuccessors()
Remove all the successors of this block.
VPBlockBase * getSingleHierarchicalSuccessor()
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
VPBlockBase * getSinglePredecessor() const
virtual void execute(VPTransformState *State)=0
The method which generates the output IR that correspond to this VPBlockBase, thereby "executing" the...
const VPBlocksTy & getHierarchicalSuccessors()
void clearPredecessors()
Remove all the predecessor of this block.
unsigned getVPBlockID() const
void printAsOperand(raw_ostream &OS, bool PrintType=false) const
void swapPredecessors()
Swap predecessors of the block.
VPBlockBase(const unsigned char SC, const std::string &N)
VPBlocksTy & getSuccessors()
const VPBasicBlock * getEntryBasicBlock() const
void setOneSuccessor(VPBlockBase *Successor)
Set a given VPBlockBase Successor as the single successor of this VPBlockBase.
void setParent(VPRegionBlock *P)
VPBlockBase * getSingleHierarchicalPredecessor()
VPBlockBase * getSingleSuccessor() const
const VPBlocksTy & getSuccessors() const
Class that provides utilities for VPBlockBases in VPlan.
A recipe for generating conditional branches on the bits of a mask.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPBranchOnMaskRecipe * clone() override
Clone the current recipe.
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
VPBranchOnMaskRecipe(VPValue *BlockInMask, DebugLoc DL)
VPlan-based builder utility analogous to IRBuilder.
Canonical scalar induction phi of the vector loop.
bool onlyFirstPartUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
~VPCanonicalIVPHIRecipe() override=default
VPCanonicalIVPHIRecipe * clone() override
Clone the current recipe.
VPCanonicalIVPHIRecipe(VPValue *StartV, DebugLoc DL)
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Type * getScalarType() const
Returns the scalar type of the induction.
void execute(VPTransformState &State) override
Generate the phi nodes.
void print(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 VPCanonicalIVPHIRecipe.
This class augments a recipe with a set of VPValues defined by the recipe.
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
void execute(VPTransformState &State) override
Generate the transformed value of the induction at offset StartValue (1.
void print(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 VPDerivedIVRecipe.
VPValue * getStepValue() const
Type * getScalarType() const
VPDerivedIVRecipe * clone() override
Clone the current recipe.
VPDerivedIVRecipe(InductionDescriptor::InductionKind Kind, const FPMathOperator *FPBinOp, VPValue *Start, VPValue *IV, VPValue *Step, const Twine &Name="")
~VPDerivedIVRecipe() override=default
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPValue * getStartValue() const
VPDerivedIVRecipe(const InductionDescriptor &IndDesc, VPValue *Start, VPCanonicalIVPHIRecipe *CanonicalIV, VPValue *Step, const Twine &Name="")
A recipe for generating the phi node for the current index of elements, adjusted in accordance with E...
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPEVLBasedIVPHIRecipe * clone() override
Clone the current recipe.
~VPEVLBasedIVPHIRecipe() override=default
void execute(VPTransformState &State) override
Generate the phi nodes.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPEVLBasedIVPHIRecipe.
VPEVLBasedIVPHIRecipe(VPValue *StartIV, DebugLoc DL)
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
Recipe to expand a SCEV expression.
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPExpandSCEVRecipe.
VPExpandSCEVRecipe(const SCEV *Expr)
const SCEV * getSCEV() const
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPExpandSCEVRecipe * clone() override
Clone the current recipe.
~VPExpandSCEVRecipe() override=default
A recipe to combine multiple recipes into a single 'expression' recipe, which should be considered a ...
void execute(VPTransformState &State) override
Method for generating code, must not be called as this recipe is abstract.
VPValue * getOperandOfResultType() const
Return the VPValue to use to infer the result type of the recipe.
VPExpressionRecipe * clone() override
Clone the current recipe.
void decompose()
Insert the recipes of the expression back into the VPlan, directly before the current recipe.
~VPExpressionRecipe() override
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the 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(VPWidenRecipe *Mul, VPReductionRecipe *Red)
A recipe representing a sequence of load -> update -> store as part of a histogram operation.
void execute(VPTransformState &State) override
Produce a vectorized histogram operation.
VP_CLASSOF_IMPL(VPDef::VPHistogramSC)
VPHistogramRecipe * clone() override
Clone the current recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPHistogramRecipe.
VPValue * getMask() const
Return the mask operand if one was provided, or a null pointer if all lanes should be executed uncond...
unsigned getOpcode() const
VPHistogramRecipe(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
~VPHistogramRecipe() override=default
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
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
~VPIRBasicBlock() override
static bool classof(const VPBlockBase *V)
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.
bool flagsValidForOpcode(unsigned Opcode) const
Returns true if the set flags are valid for Opcode.
VPIRFlags(DisjointFlagsTy DisjointFlags)
VPIRFlags(WrapFlagsTy WrapFlags)
CmpInst::Predicate CmpPredicate
void printFlags(raw_ostream &O) const
bool hasFastMathFlags() const
Returns true if the recipe has fast-math flags.
LLVM_ABI_FOR_TEST FastMathFlags getFastMathFlags() const
CmpInst::Predicate getPredicate() const
bool hasNonNegFlag() const
Returns true if the recipe has non-negative flag.
void transferFlags(VPIRFlags &Other)
bool hasNoSignedWrap() const
VPIRFlags(FastMathFlags FMFs)
VPIRFlags(NonNegFlagsTy NonNegFlags)
VPIRFlags(CmpInst::Predicate Pred)
GEPNoWrapFlags getGEPNoWrapFlags() const
bool hasPredicate() const
Returns true if the recipe has a comparison predicate.
DisjointFlagsTy DisjointFlags
void setPredicate(CmpInst::Predicate Pred)
bool hasNoUnsignedWrap() const
NonNegFlagsTy NonNegFlags
void dropPoisonGeneratingFlags()
Drop all poison-generating flags.
void applyFlags(Instruction &I) const
Apply the IR flags to I.
VPIRFlags(GEPNoWrapFlags GEPFlags)
VPIRFlags(Instruction &I)
A recipe to wrap on original IR instruction not to be modified during execution, except for PHIs.
Instruction & getInstruction() const
bool onlyFirstPartUsed(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,...
void extractLastLaneOfFirstOperand(VPBuilder &Builder)
Update the recipes first operand to the last lane of the operand using Builder.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
VPIRInstruction * clone() override
Clone the current recipe.
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.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
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...
A specialization of VPInstruction augmenting it with a dedicated result type, to be used when the opc...
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPInstruction.
static bool classof(const VPUser *R)
static bool classof(const VPRecipeBase *R)
Type * getResultType() const
VPInstructionWithType(unsigned Opcode, ArrayRef< VPValue * > Operands, Type *ResultTy, const VPIRFlags &Flags, DebugLoc DL, const Twine &Name="")
VPInstruction * clone() override
Clone the current recipe.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate the instruction.
This is a concrete Recipe that models a single VPlan-level instruction.
VPInstruction(unsigned Opcode, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
@ ExtractLane
Extracts a single lane (first operand) from a set of vector operands.
@ ComputeAnyOfResult
Compute the final result of a AnyOf reduction with select(cmp(),x,y), where one of (x,...
@ WideIVStep
Scale the first operand (vector step) by the second operand (scalar-step).
@ ExtractPenultimateElement
@ ResumeForEpilogue
Explicit user for the resume phi of the canonical induction in the main VPlan, used by the epilogue v...
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
@ BuildVector
Creates a fixed-width vector containing all operands.
@ BuildStructVector
Given operands of (the same) struct type, creates a struct of fixed- width vectors each containing a ...
@ VScale
Returns the value for vscale.
@ CanonicalIVIncrementForPart
@ CalculateTripCountMinusVF
StringRef getName() const
Returns the symbolic name assigned to the VPInstruction.
unsigned getOpcode() const
A common base class for interleaved memory operations.
virtual unsigned getNumStoreOperands() const =0
Returns the number of stored operands of this interleave group.
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)
virtual bool onlyFirstLaneUsed(const VPValue *Op) const override=0
Returns true if the recipe only uses the first lane of operand Op.
VPInterleaveBase(const unsigned char SC, const InterleaveGroup< Instruction > *IG, ArrayRef< VPValue * > Operands, ArrayRef< VPValue * > StoredValues, VPValue *Mask, bool NeedsMaskForGaps, const VPIRMetadata &MD, DebugLoc DL)
Instruction * getInsertPos() const
static bool classof(const VPRecipeBase *R)
const InterleaveGroup< Instruction > * getInterleaveGroup() const
VPValue * getMask() const
Return the mask used by this recipe.
ArrayRef< VPValue * > getStoredValues() const
Return the VPValues stored by this interleave group.
VPInterleaveBase * clone() override=0
Clone the current recipe.
VPValue * getAddr() const
Return the address accessed by this recipe.
A recipe for interleaved memory operations with vector-predication intrinsics.
~VPInterleaveEVLRecipe() override=default
bool onlyFirstLaneUsed(const VPValue *Op) const override
The recipe only uses the first lane of the address, and EVL operand.
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.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
~VPInterleaveRecipe() override=default
VPInterleaveRecipe * clone() override
Clone the current recipe.
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 recipe for forming partial reductions.
VPPartialReductionRecipe(Instruction *ReductionInst, VPValue *Op0, VPValue *Op1, VPValue *Cond, unsigned VFScaleFactor)
VPPartialReductionRecipe(unsigned Opcode, VPValue *Op0, VPValue *Op1, VPValue *Cond, unsigned ScaleFactor, Instruction *ReductionInst=nullptr)
~VPPartialReductionRecipe() override=default
unsigned getVFScaleFactor() const
Get the factor that the VF of this recipe's output should be scaled by.
void execute(VPTransformState &State) override
Generate the reduction in the loop.
void print(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 VPPartialReductionRecipe.
unsigned getOpcode() const
Get the binary op's opcode.
VPPartialReductionRecipe * clone() override
Clone the current recipe.
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.
VPUser::const_operand_range incoming_values() const
Returns an interator range over the incoming values.
virtual unsigned getNumIncoming() const
Returns the number of incoming values, also number of incoming blocks.
void removeIncomingValueFor(VPBlockBase *IncomingBlock) const
Removes the incoming value for IncomingBlock, which must be a predecessor.
const VPBasicBlock * getIncomingBlock(unsigned Idx) const
Returns the incoming block with index Idx.
detail::zippy< llvm::detail::zip_first, VPUser::const_operand_range, const_incoming_blocks_range > incoming_values_and_blocks() const
Returns an iterator range over pairs of incoming values and corresponding incoming blocks.
VPValue * getIncomingValue(unsigned Idx) const
Returns the incoming VPValue with index Idx.
virtual ~VPPhiAccessors()=default
void printPhiOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const
Print the recipe.
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 is a recipe for generating the phi nodes needed when control converges back from ...
~VPPredInstPHIRecipe() override=default
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
VPPredInstPHIRecipe * clone() override
Clone the current recipe.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPPredInstPHIRecipe.
VPPredInstPHIRecipe(VPValue *PredV, DebugLoc DL)
Construct a VPPredInstPHIRecipe given PredInst whose value needs a phi nodes after merging back from ...
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
bool mayReadOrWriteMemory() const
Returns true if the recipe may read from or write to memory.
void setDebugLoc(DebugLoc NewDL)
Set the recipe's debug location to NewDL.
virtual ~VPRecipeBase()=default
VPBasicBlock * getParent()
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
virtual void execute(VPTransformState &State)=0
The method which generates the output IR instructions that correspond to this VPRecipe,...
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.
const VPBasicBlock * getParent() const
static bool classof(const VPUser *U)
VPRecipeBase(const unsigned char SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
A recipe to represent inloop reduction operations with vector-predication intrinsics,...
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPValue * getEVL() const
The VPValue of the explicit vector length.
VPReductionEVLRecipe(VPReductionRecipe &R, VPValue &EVL, VPValue *CondOp, DebugLoc DL=DebugLoc::getUnknown())
VPReductionEVLRecipe * clone() override
Clone the current recipe.
~VPReductionEVLRecipe() override=default
A recipe for handling reduction phis.
bool isOrdered() const
Returns true, if the phi is part of an ordered reduction.
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.
~VPReductionPHIRecipe() override=default
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPReductionPHIRecipe(PHINode *Phi, RecurKind Kind, VPValue &Start, bool IsInLoop=false, bool IsOrdered=false, unsigned VFScaleFactor=1)
Create a new VPReductionPHIRecipe for the reduction Phi.
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
bool isInLoop() const
Returns true, if the phi is part of an in-loop reduction.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
void execute(VPTransformState &State) override
Generate the phi/select nodes.
RecurKind getRecurrenceKind() const
Returns the recurrence kind of the reduction.
A recipe to represent inloop reduction operations, performing a reduction on a vector operand into a ...
bool isConditional() const
Return true if the in-loop reduction is conditional.
static bool classof(const VPRecipeBase *R)
VPReductionRecipe(const RecurKind RdxKind, FastMathFlags FMFs, VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp, bool IsOrdered, DebugLoc DL=DebugLoc::getUnknown())
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.
bool isOrdered() const
Return true if the in-loop reduction is ordered.
~VPReductionRecipe() override=default
VPValue * getChainOp() const
The VPValue of the scalar Chain being accumulated.
VPReductionRecipe(RecurKind RdxKind, FastMathFlags FMFs, Instruction *I, VPValue *ChainOp, VPValue *VecOp, VPValue *CondOp, bool IsOrdered, DebugLoc DL=DebugLoc::getUnknown())
VPReductionRecipe * clone() override
Clone the current recipe.
VPReductionRecipe(const unsigned char SC, RecurKind RdxKind, FastMathFlags FMFs, Instruction *I, ArrayRef< VPValue * > Operands, VPValue *CondOp, bool IsOrdered, DebugLoc DL)
static bool classof(const VPUser *U)
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...
void setExiting(VPBlockBase *ExitingBlock)
Set ExitingBlock as the exiting VPBlockBase of this VPRegionBlock.
VPBlockBase * getExiting()
void setEntry(VPBlockBase *EntryBlock)
Set EntryBlock as the entry VPBlockBase of this VPRegionBlock.
const VPBlockBase * getExiting() const
VPBasicBlock * getPreheaderVPBB()
Returns the pre-header VPBasicBlock of the loop region.
~VPRegionBlock() override
static bool classof(const VPBlockBase *V)
Method to support type inquiry through isa, cast, and dyn_cast.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
VPReplicateRecipe(Instruction *I, ArrayRef< VPValue * > Operands, bool IsSingleScalar, VPValue *Mask=nullptr, VPIRMetadata Metadata={})
bool isSingleScalar() const
~VPReplicateRecipe() override=default
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
bool usesScalars(const VPValue *Op) const override
Returns true if the recipe uses scalars of operand Op.
bool isPredicated() const
VPReplicateRecipe * clone() override
Clone the current recipe.
unsigned getOpcode() const
VPValue * getMask()
Return the mask of a predicated VPReplicateRecipe.
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPValue * getStepValue() const
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPScalarIVStepsRecipe.
VPScalarIVStepsRecipe(const InductionDescriptor &IndDesc, VPValue *IV, VPValue *Step, VPValue *VF, DebugLoc DL=DebugLoc::getUnknown())
bool isPart0() const
Return true if this VPScalarIVStepsRecipe corresponds to part 0.
VPScalarIVStepsRecipe * clone() override
Clone the current recipe.
VPScalarIVStepsRecipe(VPValue *IV, VPValue *Step, VPValue *VF, Instruction::BinaryOps Opcode, FastMathFlags FMFs, DebugLoc DL)
~VPScalarIVStepsRecipe() override=default
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
VPSingleDefRecipe(const unsigned char SC, ArrayRef< VPValue * > Operands, Value *UV, DebugLoc DL=DebugLoc::getUnknown())
Instruction * getUnderlyingInstr()
Returns the underlying instruction.
static bool classof(const VPRecipeBase *R)
const Instruction * getUnderlyingInstr() const
static bool classof(const VPUser *U)
LLVM_DUMP_METHOD void dump() const
Print this VPSingleDefRecipe to dbgs() (for debugging).
VPSingleDefRecipe(const unsigned char SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
virtual VPSingleDefRecipe * clone() override=0
Clone the current recipe.
This class can be used to assign names to VPValues.
Helper to access the operand that contains the unroll part for this recipe after unrolling.
unsigned getUnrollPart(const VPUser &U) const
Return the unroll part.
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
void setOperand(unsigned I, VPValue *New)
unsigned getNumOperands() const
VPValue * getOperand(unsigned N) const
iterator_range< const_operand_iterator > const_operand_range
bool isDefinedOutsideLoopRegions() const
Returns true if the VPValue is defined outside any loop.
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Value * getLiveInIRValue() const
Returns the underlying IR value, if this VPValue is defined outside the scope of VPlan.
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
unsigned getNumUsers() const
bool isLiveIn() const
Returns true if this VPValue is a live-in, i.e. defined outside the VPlan.
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
bool onlyFirstPartUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
VPVectorEndPointerRecipe * clone() override
Clone the current recipe.
const VPValue * getVFValue() const
void print(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 VPVectorPointerRecipe.
VPVectorEndPointerRecipe(VPValue *Ptr, VPValue *VF, Type *IndexedTy, int64_t Stride, GEPNoWrapFlags GEPFlags, DebugLoc DL)
A recipe to compute the pointers for widened memory accesses of IndexTy.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
bool isFirstPart() const
Return true if this VPVectorPointerRecipe corresponds to part 0.
VPVectorPointerRecipe(VPValue *Ptr, Type *IndexedTy, GEPNoWrapFlags GEPFlags, DebugLoc DL)
void execute(VPTransformState &State) override
The method which generates the output IR instructions that correspond to this VPRecipe,...
bool onlyFirstPartUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first part of operand Op.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPHeaderPHIRecipe.
VPVectorPointerRecipe * clone() override
Clone the current recipe.
A recipe for widening Call instructions using library calls.
const_operand_range args() const
VPWidenCallRecipe * clone() override
Clone the current recipe.
VPWidenCallRecipe(Value *UV, Function *Variant, ArrayRef< VPValue * > CallArguments, DebugLoc DL=DebugLoc::getUnknown())
Function * getCalledScalarFunction() const
~VPWidenCallRecipe() override=default
A Recipe for widening the canonical induction variable of the vector loop.
void execute(VPTransformState &State) override
Generate a canonical vector induction variable of the vector loop, with start = {<Part*VF,...
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
~VPWidenCanonicalIVRecipe() override=default
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenCanonicalIVPHIRecipe.
VPWidenCanonicalIVRecipe * clone() override
Clone the current recipe.
VPWidenCanonicalIVRecipe(VPCanonicalIVPHIRecipe *CanonicalIV)
VPWidenCastRecipe is a recipe to create vector cast instructions.
VPWidenCastRecipe(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, CastInst &UI)
Instruction::CastOps getOpcode() const
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPWidenCastRecipe(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, const VPIRFlags &Flags={}, DebugLoc DL=DebugLoc::getUnknown())
Type * getResultType() const
Returns the result type of the cast.
void execute(VPTransformState &State) override
Produce widened copies of the cast.
~VPWidenCastRecipe() override=default
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenCastRecipe.
VPWidenCastRecipe * clone() override
Clone the current recipe.
A recipe for handling GEP instructions.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPWidenGEPRecipe(GetElementPtrInst *GEP, ArrayRef< VPValue * > Operands)
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenGEPRecipe.
VPWidenGEPRecipe * clone() override
Clone the current recipe.
~VPWidenGEPRecipe() override=default
Base class for widened induction (VPWidenIntOrFpInductionRecipe and VPWidenPointerInductionRecipe),...
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
static bool classof(const VPValue *V)
void setStepValue(VPValue *V)
Update the step value of the recipe.
VPValue * getBackedgeValue() override
Returns the incoming value from the loop backedge.
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
PHINode * getPHINode() const
VPWidenInductionRecipe(unsigned char Kind, PHINode *IV, VPValue *Start, VPValue *Step, const InductionDescriptor &IndDesc, DebugLoc DL)
VPValue * getStepValue()
Returns the step value of the induction.
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
VPRecipeBase & getBackedgeRecipe() override
Returns the backedge value as a recipe.
static bool classof(const VPRecipeBase *R)
static bool classof(const VPHeaderPHIRecipe *R)
const VPValue * getVFValue() const
const VPValue * getStepValue() const
virtual void execute(VPTransformState &State) override=0
Generate the phi nodes.
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
const TruncInst * getTruncInst() const
void execute(VPTransformState &State) override
Generate the phi nodes.
~VPWidenIntOrFpInductionRecipe() override=default
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, TruncInst *Trunc, DebugLoc DL)
VPWidenIntOrFpInductionRecipe * clone() override
Clone the current recipe.
TruncInst * getTruncInst()
Returns the first defined value as TruncInst, if it is one or nullptr otherwise.
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step, VPValue *VF, const InductionDescriptor &IndDesc, DebugLoc DL)
VPValue * getLastUnrolledPartOperand()
Returns the VPValue representing the value of this induction at the last unrolled part,...
unsigned getNumIncoming() const override
Returns the number of incoming values, also number of incoming blocks.
Type * getScalarType() const
Returns the scalar type of the induction.
bool isCanonical() const
Returns true if the induction is canonical, i.e.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPValue * getSplatVFValue()
A recipe for widening vector intrinsics.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the VPUser only uses the first lane of operand Op.
VPWidenIntrinsicRecipe(Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, 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.
StringRef getIntrinsicName() const
Return to name of the intrinsic as string.
VPWidenIntrinsicRecipe(CallInst &CI, Intrinsic::ID VectorIntrinsicID, ArrayRef< VPValue * > CallArguments, Type *Ty, DebugLoc DL=DebugLoc::getUnknown())
bool mayHaveSideEffects() const
Returns true if the intrinsic may have side-effects.
VPWidenIntrinsicRecipe * clone() override
Clone the current recipe.
bool mayWriteToMemory() const
Returns true if the intrinsic may write to memory.
~VPWidenIntrinsicRecipe() override=default
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
Type * getResultType() const
Return the scalar return type of the intrinsic.
void execute(VPTransformState &State) override
Produce a widened version of the vector intrinsic.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this vector intrinsic.
A common base class for widening memory operations.
bool Reverse
Whether the consecutive accessed addresses are in reverse order.
bool isConsecutive() const
Return whether the loaded-from / stored-to addresses are consecutive.
static bool classof(const VPUser *U)
void execute(VPTransformState &State) override
Generate the wide load/store.
VPWidenMemoryRecipe * clone() override
Clone the current recipe.
Instruction & getIngredient() const
bool Consecutive
Whether the accessed addresses are consecutive.
static bool classof(const VPRecipeBase *R)
VPValue * getMask() const
Return the mask used by this recipe.
bool isMasked() const
Returns true if the recipe is masked.
VPWidenMemoryRecipe(const char unsigned SC, Instruction &I, std::initializer_list< VPValue * > Operands, bool Consecutive, bool Reverse, const VPIRMetadata &Metadata, DebugLoc DL)
void setMask(VPValue *Mask)
VPValue * getAddr() const
Return the address accessed by this recipe.
bool isReverse() const
Return whether the consecutive loaded/stored addresses are in reverse order.
A recipe for widened phis.
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
VPWidenPHIRecipe(PHINode *Phi, VPValue *Start=nullptr, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new VPWidenPHIRecipe for Phi with start value Start and debug location DL.
VPWidenPHIRecipe * clone() override
Clone the current recipe.
~VPWidenPHIRecipe() override=default
VPWidenPointerInductionRecipe * clone() override
Clone the current recipe.
~VPWidenPointerInductionRecipe() override=default
bool onlyScalarsGenerated(bool IsScalable)
Returns true if only scalar values will be generated.
void execute(VPTransformState &State) override
Generate vector values for the pointer induction.
VPWidenPointerInductionRecipe(PHINode *Phi, VPValue *Start, VPValue *Step, VPValue *NumUnrolledElems, const InductionDescriptor &IndDesc, bool IsScalarAfterVectorization, DebugLoc DL)
Create a new VPWidenPointerInductionRecipe for Phi with start value Start and the number of elements ...
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
VPWidenRecipe * clone() override
Clone the current recipe.
VPWidenRecipe(Instruction &I, ArrayRef< VPValue * > Operands)
VPWidenRecipe(unsigned Opcode, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, const VPIRMetadata &Metadata, DebugLoc DL)
~VPWidenRecipe() override=default
unsigned getOpcode() const
VPlanPrinter prints a given VPlan to a given output stream.
Class that maps (parts of) an existing VPlan to trees of combined VPInstructions.
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
void printDOT(raw_ostream &O) const
Print this VPlan in DOT format to O.
std::string getName() const
Return a string with the name of the plan and the applicable VFs and UFs.
bool hasVF(ElementCount VF) const
LLVMContext & getContext() const
VPBasicBlock * getEntry()
VPRegionBlock * createVPRegionBlock(VPBlockBase *Entry, VPBlockBase *Exiting, const std::string &Name="", bool IsReplicator=false)
Create a new VPRegionBlock with Entry, Exiting and Name.
VPValue & getVectorTripCount()
The vector trip count.
void setName(const Twine &newName)
bool hasScalableVF() const
VPValue & getVFxUF()
Returns VF * UF of the vector loop region.
VPValue & getVF()
Returns the VF of the vector loop region.
VPValue * getTripCount() const
The trip count of the original loop.
VPValue * getTrue()
Return a VPValue wrapping i1 true.
VPValue * getOrCreateBackedgeTakenCount()
The backedge taken count of the original loop.
iterator_range< SmallSetVector< ElementCount, 2 >::iterator > vectorFactors() const
Returns an iterator range over all VFs of the plan.
VPlan(BasicBlock *ScalarHeaderBB, VPValue *TC)
Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock wrapping ScalarHeaderBB and a tr...
VPIRBasicBlock * getExitBlock(BasicBlock *IRBB) const
Return the VPIRBasicBlock corresponding to IRBB.
LLVM_ABI_FOR_TEST ~VPlan()
bool isExitBlock(VPBlockBase *VPBB)
Returns true if VPBB is an exit block.
const VPBasicBlock * getEntry() const
VPRegionBlock * createVPRegionBlock(const std::string &Name="")
Create a new loop VPRegionBlock with Name and entry and exiting blocks set to nullptr.
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
void addSCEVExpansion(const SCEV *S, VPValue *V)
bool hasUF(unsigned UF) const
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
void setVF(ElementCount VF)
bool isUnrolled() const
Returns true if the VPlan already has been unrolled, i.e.
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
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.
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,...
VPValue * getFalse()
Return a VPValue wrapping i1 false.
VPValue * getOrAddLiveIn(Value *V)
Gets the live-in VPValue for V or adds a new live-in (if none exists yet) for V.
LLVM_DUMP_METHOD void dump() const
Dump the plan to stderr (for debugging).
bool hasScalarVFOnly() const
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
void execute(VPTransformState *State)
Generate the IR code for this VPlan.
ArrayRef< VPValue * > getLiveIns() const
Return the list of live-in VPValues available in the VPlan.
VPCanonicalIVPHIRecipe * getCanonicalIV()
Returns the canonical induction recipe of the vector loop.
void print(raw_ostream &O) const
Print this VPlan to O.
void addVF(ElementCount VF)
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
VPValue * getLiveIn(Value *V) const
Return the live-in VPValue for V, if there is one or nullptr otherwise.
VPValue * getSCEVExpansion(const SCEV *S) const
void printLiveIns(raw_ostream &O) const
Print the live-ins of this VPlan to O.
VPBasicBlock * getVectorPreheader()
Returns the preheader of the vector loop region, if one exists, or null otherwise.
bool hasScalarTail() const
Returns true if the scalar tail may execute after the vector loop.
VPlan * duplicate()
Clone the current VPlan, update all VPValues of the new VPlan and cloned recipes to refer to the clon...
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
An ilist node that can access its parent list.
Increasing range of size_t indices.
base_list_type::const_reverse_iterator const_reverse_iterator
base_list_type::reverse_iterator reverse_iterator
base_list_type::const_iterator const_iterator
base_list_type::iterator iterator
iterator insert(iterator where, pointer New)
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.
@ BasicBlock
Various leaf nodes.
LLVM_ABI AttributeSet getFnAttributes(LLVMContext &C, ID id)
Return the function attributes for an intrinsic.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
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.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
SDValue getStoredValue(SDValue Op)
LLVM_ABI void getMetadataToPropagate(Instruction *Inst, SmallVectorImpl< std::pair< unsigned, MDNode * > > &Metadata)
Add metadata from Inst to Metadata, if it can be preserved after vectorization.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
auto cast_or_null(const Y &Val)
auto map_range(ContainerTy &&C, FuncTy F)
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)
std::unique_ptr< VPlan > VPlanPtr
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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.
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...
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Support casting from VPRecipeBase -> VPPhiAccessors, by down-casting to the recipe types implementing...
static VPPhiAccessors * doCastIfPossible(SrcTy f)
doCastIfPossible is used by dyn_cast<>.
static VPPhiAccessors * doCast(SrcTy R)
doCast is used by cast<>.
This struct provides a method for customizing the way a cast is performed.
static bool isPossible(const VPRecipeBase *f)
This struct provides a way to check if a given cast is possible.
static bool isPossible(const From &f)
Struct to hold various analysis needed for cost computations.
A recipe for handling first-order recurrence phis.
void execute(VPTransformState &State) override
Generate the phi nodes.
VPFirstOrderRecurrencePHIRecipe * clone() override
Clone the current recipe.
VPFirstOrderRecurrencePHIRecipe(PHINode *Phi, VPValue &Start)
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this first-order recurrence phi recipe.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
DisjointFlagsTy(bool IsDisjoint)
NonNegFlagsTy(bool IsNonNeg)
TruncFlagsTy(bool HasNUW, bool HasNSW)
WrapFlagsTy(bool HasNUW, bool HasNSW)
An overlay for VPIRInstructions wrapping PHI nodes enabling convenient use cast/dyn_cast/isa and exec...
static bool classof(const VPRecipeBase *U)
const VPRecipeBase * getAsRecipe() const override
Return a VPRecipeBase* to the current object.
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.
VPPhi(ArrayRef< VPValue * > Operands, DebugLoc DL, const Twine &Name="")
static bool classof(const VPSingleDefRecipe *SDR)
static bool classof(const VPValue *V)
A pure-virtual common base class for recipes defining a single VPValue and using IR flags.
static bool classof(const VPRecipeBase *R)
VPRecipeWithIRFlags(const unsigned char SC, ArrayRef< VPValue * > Operands, Instruction &I)
VPRecipeWithIRFlags(const unsigned char SC, ArrayRef< VPValue * > Operands, const VPIRFlags &Flags, DebugLoc DL=DebugLoc::getUnknown())
std::optional< 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)
static bool classof(const VPSingleDefRecipe *U)
void execute(VPTransformState &State) override=0
The method which generates the output IR instructions that correspond to this VPRecipe,...
static bool classof(const VPUser *U)
VPRecipeWithIRFlags(const unsigned char SC, ArrayRef< VPValue * > Operands, DebugLoc DL=DebugLoc::getUnknown())
A recipe for widening load operations with vector-predication intrinsics, using the address to load f...
void execute(VPTransformState &State) override
Generate the wide load or gather.
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenLoadEVLRecipe.
VPValue * getEVL() const
Return the EVL operand.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
VPWidenLoadEVLRecipe(VPWidenLoadRecipe &L, VPValue *Addr, VPValue &EVL, VPValue *Mask)
bool onlyFirstLaneUsed(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.
VP_CLASSOF_IMPL(VPDef::VPWidenLoadSC)
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPWidenLoadRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, bool Reverse, const VPIRMetadata &Metadata, DebugLoc DL)
VPWidenLoadRecipe * clone() override
Clone the current recipe.
A recipe for widening select instructions.
bool isInvariantCond() const
VPWidenSelectRecipe * clone() override
Clone the current recipe.
VPWidenSelectRecipe(SelectInst &I, ArrayRef< VPValue * > Operands)
VPValue * getCond() const
unsigned getOpcode() const
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
~VPWidenSelectRecipe() override=default
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.
void execute(VPTransformState &State) override
Generate the wide store or scatter.
void print(raw_ostream &O, const Twine &Indent, VPSlotTracker &SlotTracker) const override
Print the recipe.
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VPWidenStoreEVLRecipe(VPWidenStoreRecipe &S, VPValue *Addr, VPValue &EVL, VPValue *Mask)
InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override
Return the cost of this VPWidenStoreEVLRecipe.
VPValue * getEVL() const
Return the EVL operand.
A recipe for widening store operations, using the stored value, the address to store to and an option...
bool onlyFirstLaneUsed(const VPValue *Op) const override
Returns true if the recipe only uses the first lane of operand Op.
VP_CLASSOF_IMPL(VPDef::VPWidenStoreSC)
VPValue * getStoredValue() const
Return the value stored by this recipe.
VPWidenStoreRecipe * clone() override
Clone the current recipe.
VPWidenStoreRecipe(StoreInst &Store, VPValue *Addr, VPValue *StoredVal, VPValue *Mask, bool Consecutive, bool Reverse, const VPIRMetadata &Metadata, DebugLoc DL)