46 SmallPtrSet<VPRecipeBase *, 8> ToSkip;
50 DenseMap<VPValue *, SmallVector<VPValue *>> VPV2Parts;
53 void unrollReplicateRegionByUF(VPRegionBlock *VPR);
57 void unrollRecipeByUF(VPRecipeBase &R);
62 void unrollHeaderPHIByUF(VPHeaderPHIRecipe *R,
67 void unrollWidenInductionByUF(VPWidenInductionRecipe *
IV,
71 Type *CanIVIntTy = Plan.getVectorLoopRegion()->getCanonicalIVType();
72 return Plan.getConstantInt(CanIVIntTy, Part);
76 UnrollState(VPlan &Plan,
unsigned UF) : Plan(Plan), UF(UF) {}
78 void unrollBlock(VPBlockBase *VPB);
80 VPValue *getValueForPart(VPValue *V,
unsigned Part) {
83 assert((VPV2Parts.contains(V) && VPV2Parts[V].size() >= Part) &&
84 "accessed value does not exist");
85 return VPV2Parts[
V][Part - 1];
91 void addRecipeForPart(VPRecipeBase *OrigR, VPRecipeBase *CopyR,
94 const auto &[
V,
_] = VPV2Parts.try_emplace(VPV);
95 assert(
V->second.size() == Part - 1 &&
"earlier parts not set");
101 void addUniformForAllParts(VPSingleDefRecipe *R) {
102 const auto &[
V,
Inserted] = VPV2Parts.try_emplace(R);
103 assert(Inserted &&
"uniform value already added");
104 for (
unsigned Part = 0; Part != UF; ++Part)
105 V->second.push_back(R);
108 bool contains(VPValue *VPV)
const {
return VPV2Parts.contains(VPV); }
112 void remapOperand(VPRecipeBase *R,
unsigned OpIdx,
unsigned Part) {
114 R->setOperand(
OpIdx, getValueForPart(
Op, Part));
120 R->setOperand(
OpIdx, getValueForPart(
Op, Part));
126 unsigned Part,
VPlan &Plan) {
136 StartIndex = Builder.createOverflowingOp(
140 StartIndex = Builder.createScalarSExtOrTrunc(StartIndex, IntStepTy,
144 StartIndex = Builder.createScalarCast(Instruction::SIToFP, StartIndex,
150void UnrollState::unrollReplicateRegionByUF(
VPRegionBlock *VPR) {
152 for (
unsigned Part = 1; Part !=
UF; ++Part) {
158 for (
const auto &[PartIVPBB, Part0VPBB] :
161 for (
const auto &[PartIR, Part0R] :
zip(*PartIVPBB, *Part0VPBB)) {
166 addRecipeForPart(&Part0R, &PartIR, Part);
172void UnrollState::unrollWidenInductionByUF(
175 IV->getParent()->getEnclosingLoopRegion()->getSinglePredecessor());
176 Type *IVTy =
IV->getScalarType();
177 auto &
ID =
IV->getInductionDescriptor();
179 VPIRFlags::WrapFlagsTy WrapFlags(
false,
false);
181 FMF = IntOrFPInd->getFastMathFlagsOrNone();
182 WrapFlags = IntOrFPInd->getNoWrapFlagsOrNone();
185 VPValue *ScalarStep =
IV->getStepValue();
186 VPBuilder Builder(PH);
188 VPInstruction *VectorStep = Builder.createNaryOp(
192 ToSkip.
insert(VectorStep);
207 Builder.setInsertPoint(
IV->getParent(), InsertPtForPhi);
214 AddOpc =
ID.getInductionOpcode();
217 AddOpc = Instruction::Add;
218 AddFlags = WrapFlags;
220 AddFlags = VPIRFlags::WrapFlagsTy(
true,
false);
222 for (
unsigned Part = 1; Part !=
UF; ++Part) {
224 Part > 1 ?
"step.add." + std::to_string(Part) :
"step.add";
227 Builder.createNaryOp(AddOpc,
232 AddFlags,
IV->getDebugLoc(), Name);
234 addRecipeForPart(
IV,
Add, Part);
237 IV->addUnrolledPartOperands(VectorStep, Prev);
240void UnrollState::unrollHeaderPHIByUF(VPHeaderPHIRecipe *R,
249 unrollWidenInductionByUF(
IV, InsertPtForPhi);
254 if (RdxPhi && RdxPhi->isOrdered())
257 auto InsertPt = std::next(
R->getIterator());
258 for (
unsigned Part = 1; Part !=
UF; ++Part) {
259 VPRecipeBase *
Copy =
R->clone();
260 Copy->insertBefore(*
R->getParent(), InsertPt);
261 addRecipeForPart(R, Copy, Part);
269 "unexpected start VPInstruction");
274 StartV = VPI->getOperand(1);
276 auto *
C = VPI->clone();
277 C->setOperand(0,
C->getOperand(1));
281 for (
unsigned Part = 1; Part !=
UF; ++Part)
282 VPV2Parts[VPI][Part - 1] = StartV;
286 "unexpected header phi recipe not needing unrolled part");
292void UnrollState::unrollRecipeByUF(VPRecipeBase &R) {
298 addUniformForAllParts(VPI);
304 RepR->getOperand(1)->isDefinedOutsideLoopRegions()) {
311 addUniformForAllParts(RepR);
317 auto InsertPt = std::next(
R.getIterator());
318 VPBasicBlock &VPBB = *
R.getParent();
319 for (
unsigned Part = 1; Part !=
UF; ++Part) {
320 VPRecipeBase *
Copy =
R.clone();
321 Copy->insertBefore(VPBB, InsertPt);
322 addRecipeForPart(&R, Copy, Part);
331 Copy->setOperand(0, getValueForPart(
Op, Part - 1));
332 Copy->setOperand(1, getValueForPart(
Op, Part));
336 VPBuilder Builder(&R);
341 :
DL.getIndexType(
R.getVPSingleValue()->getScalarType());
342 VPValue *VF = Builder.createScalarZExtOrTrunc(&Plan.
getVF(), IndexTy,
345 VPValue *VFxPart = Builder.createOverflowingOp(
349 VecPtr->addPerPartOffset(VFxPart);
356 if (Phi &&
Phi->isOrdered()) {
357 auto &Parts = VPV2Parts[
Phi];
360 Parts.push_back(Red);
362 Parts.push_back(
Copy->getVPSingleValue());
363 Phi->setOperand(1,
Copy->getVPSingleValue());
368 VEPR->setOperand(0,
R.getOperand(0));
369 VEPR->setOperand(1,
R.getOperand(1));
370 VEPR->materializeOffset(Part);
381 VPBuilder Builder(Copy);
382 VPValue *ScaledByPart = Builder.createOverflowingOp(
384 Copy->setOperand(1, ScaledByPart);
389 VEPR->materializeOffset();
397void UnrollState::unrollBlock(VPBlockBase *VPB) {
401 return unrollReplicateRegionByUF(VPR);
405 ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>>
407 for (VPBlockBase *VPB : RPOT)
428 addUniformForAllParts(VPI);
429 for (
unsigned Part = 1; Part !=
UF; ++Part)
430 VPI->addOperand(getValueForPart(Op1, Part));
436 addUniformForAllParts(VPI);
437 for (
unsigned Part = 1; Part !=
UF; ++Part)
438 VPI->addOperand(getValueForPart(Op1, Part));
446 addUniformForAllParts(VPI);
447 for (
unsigned Part = 1; Part !=
UF; ++Part) {
448 VPI->addOperand(getValueForPart(Op1, Part));
449 VPI->addOperand(getValueForPart(Op2, Part));
458 bool IsPenultimatePart =
460 unsigned PartIdx = IsPenultimatePart ?
UF - 2 :
UF - 1;
462 I->replaceAllUsesWith(getValueForPart(Op0, PartIdx));
470 R.setOperand(0, getValueForPart(Op0, UF - 1));
476 addUniformForAllParts(SingleDef);
481 unrollHeaderPHIByUF(
H, InsertPtForPhi);
490 assert(UF > 0 &&
"Unroll factor must be positive");
500 VPI->getOperand(1) == &Plan.
getVF()) {
501 VPI->replaceAllUsesWith(VPI->getOperand(0));
502 VPI->eraseFromParent();
514 UnrollState Unroller(Plan, UF);
522 Unroller.unrollBlock(VPB);
534 Unroller.remapOperand(&
H, 1, UF - 1);
537 if (Unroller.contains(
H.getVPSingleValue())) {
541 Unroller.remapOperands(&
H, Part);
551 assert(Lane > 0 &&
"Zero lane adds no offset to start index");
560 int SignedLane =
static_cast<int>(Lane);
562 SignedLane = -SignedLane;
563 LaneOffset = Plan.
getOrAddLiveIn(ConstantFP::get(BaseIVTy, SignedLane));
569 APInt(BaseIVBits, Lane,
false,
true));
570 AddOpcode = Instruction::Add;
574 VPValue *NewStartIndex = LaneOffset;
578 Builder.createNaryOp(AddOpcode, {OldStartIndex, LaneOffset}, Flags);
591 "DefR must be a VPReplicateRecipe, VPInstruction or "
592 "VPScalarIVStepsRecipe");
595 auto LaneDefs = Def2LaneDefs.find(
Op);
596 if (LaneDefs != Def2LaneDefs.end())
600 return Builder.createNaryOp(Instruction::ExtractElement, {
Op, Idx});
608 auto LaneDefs = Def2LaneDefs.find(
Op);
609 if (LaneDefs != Def2LaneDefs.end()) {
615 [[maybe_unused]]
bool Matched =
617 assert(Matched &&
"original op must have been Unpack");
636 VPValue *Ext = Builder.createNaryOp(Instruction::ExtractElement, {
Op, Idx});
646 RepR->getOpcode(), NewOps,
nullptr, *RepR, *RepR,
647 RepR->getDebugLoc(), RepR->getUnderlyingInstr());
651 New->setOperand(Idx,
Op);
660 New->insertBefore(DefR);
681 "must not contain wide phis, inserts or extracts before conversion");
684 DebugLoc OldDL = OldR.getDebugLoc();
687 for (
const auto &[
I,
Op] :
enumerate(OldR.operands())) {
692 auto *DefR =
Op->getDefiningRecipe();
694 DefR->getParent() == VPB) ||
699 VPValue *Extract = Builder.createNaryOp(Instruction::ExtractElement,
701 OldR.setOperand(
I, Extract);
707 RepR->getOpcode(),
to_vector(RepR->operands()),
nullptr,
708 *RepR, *RepR, OldDL, RepR->getUnderlyingInstr());
709 NewR->insertBefore(RepR);
710 RepR->replaceAllUsesWith(NewR);
711 RepR->eraseFromParent();
714 {BranchOnMask->getOperand(0)}, OldDL);
715 BranchOnMask->eraseFromParent();
717 VPValue *PredOp = PredPhi->getOperand(0);
720 VPPhi *NewPhi = Builder.createScalarPhi({
Poison, PredOp}, OldDL);
722 PredPhi->eraseFromParent();
728 "unexpected unhandled recipe");
741 for (
const auto &[OldBB, NewBB] :
744 for (
auto &&[OldR, NewR] :
746 for (
const auto &[OldV, NewV] :
747 zip_equal(OldR.definedValues(), NewR.definedValues()))
748 Old2NewVPValues[OldV] = NewV;
751 for (
const auto &[
I, OldOp] :
enumerate(NewR.operands())) {
753 if (
auto *NewOp = Old2NewVPValues.
lookup(OldOp))
754 NewR.setOperand(
I, NewOp);
761 "extract indices must be zero");
762 NewR.setOperand(1, IdxLane);
766 "VPPhis expected to have only first lane used");
770 assert(BVUser->getOperand(0) == OldPhi &&
771 "Unexpected first operand of build vector user");
772 BVUser->setOperand(Lane, NewPhi);
789 assert(Predecessor &&
"Replicate region must have a single predecessor");
818 for (
auto &R : FirstLaneExiting->phis()) {
823 Type *ScalarTy = Phi->getScalarType();
832 Phi->replaceAllUsesWith(BV);
833 BV->setOperand(0, Phi);
840 for (
int Lane = NumLanes - 1; Lane > 0; --Lane) {
841 const auto &[CurrentLaneEntry, CurrentLaneExiting] =
849 NextLaneEntry = CurrentLaneEntry;
863 assert(BV->getNumOperands() == NumLanes &&
864 "BuildVector must have one operand per lane");
865 for (
const auto &[Idx,
Op] :
enumerate(BV->operands())) {
867 auto DL = ScalarPhi->getDebugLoc();
870 VPValue *PrevVal = Idx == 0 ?
Poison : BV->getOperand(Idx - 1);
872 auto *Insert = Builder.createNaryOp(
873 Instruction::InsertElement,
875 Builder.setInsertPoint(ScalarPhi);
876 auto *NewPhi = Builder.createWidenPhi({PrevVal, Insert},
DL);
877 ScalarPhi->replaceAllUsesWith(NewPhi);
878 ScalarPhi->eraseFromParent();
880 BV->replaceAllUsesWith(BV->getOperand(NumLanes - 1));
881 BV->eraseFromParent();
893 if (
Region->isReplicator())
898 "cannot replicate across scalable VFs");
942 if (DefR->user_empty()) {
946 DefR->eraseFromParent();
955 Def2LaneDefs[DefR] = LaneDefs;
958 DefR->replaceUsesWithIf(LaneDefs[0], [DefR](
VPUser &U,
unsigned) {
959 if (U.usesFirstLaneOnly(DefR))
972 assert(VPI->getNumOperands() == 1 &&
973 "Build(Struct)Vector must have a single operand before "
974 "replicating by VF");
975 VPI->setOperand(0, LaneDefs[0]);
977 VPI->addOperand(LaneDef);
983 R->eraseFromParent();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
ManagedStatic< HTTPClientCleanup > Cleanup
MachineInstr unsigned OpIdx
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
static ConstantInt * getConstantInt(Value *V, const DataLayout &DL)
Extract ConstantInt from value, looking through IntToPtr and PointerNullValue.
This file contains the declarations of different VPlan-related auxiliary helpers.
static void addLaneToStartIndex(VPScalarIVStepsRecipe *Steps, unsigned Lane, VPlan &Plan, VPRecipeBase *InsertPt)
Add a lane offset to the start index of Steps.
static void replicateReplicateRegionsByVF(VPlan &Plan, ElementCount VF, Type *IdxTy)
Collect and dissolve all replicate regions in the vector loop, replicating their blocks and recipes f...
static VPValue * cloneForLane(VPlan &Plan, VPBuilder &Builder, Type *IdxTy, VPSingleDefRecipe *DefR, VPLane Lane, const DenseMap< VPValue *, SmallVector< VPValue * > > &Def2LaneDefs)
Create a single-scalar clone of DefR (must be a VPReplicateRecipe, VPInstruction or VPScalarIVStepsRe...
static void addStartIndexForScalarSteps(VPScalarIVStepsRecipe *Steps, unsigned Part, VPlan &Plan)
static void convertRecipesInRegionBlocksToSingleScalar(VPlan &Plan, Type *IdxTy, VPBlockBase *Entry, ElementCount VF)
Convert recipes in region blocks to operate on a single lane 0.
static void dissolveReplicateRegion(VPRegionBlock *Region, ElementCount VF, VPlan &Plan, Type *IdxTy)
Dissolve a single replicate region by replicating its blocks for each lane of VF.
static void processLaneForReplicateRegion(VPlan &Plan, Type *IdxTy, unsigned Lane, VPBasicBlock *OldEntry, VPBasicBlock *NewEntry)
Update recipes in the cloned blocks rooted at NewEntry to match Lane, using the original blocks roote...
static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry, DenseMap< VPValue *, VPValue * > &Old2NewVPValues)
This file contains the declarations of the Vectorization Plan base classes:
static const uint32_t IV[8]
Class for arbitrary precision integers.
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
static DebugLoc getUnknown()
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
constexpr bool isScalar() const
Exactly one element.
Convenience struct for specifying and reasoning about fast-math flags.
static GEPNoWrapFlags none()
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
RegionT * getParent() const
Get the parent of the Region.
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
RecipeListTy::iterator iterator
Instruction iterators...
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.
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
const VPBasicBlock * getEntryBasicBlock() const
void setParent(VPRegionBlock *P)
VPBlockBase * getSingleSuccessor() const
static auto blocksAs(T &&Range)
Return an iterator range over Range with each block cast to BlockTy.
static void connectBlocks(VPBlockBase *From, VPBlockBase *To, unsigned PredIdx=-1u, unsigned SuccIdx=-1u)
Connect VPBlockBases From and To bi-directionally.
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
static void insertBlockBefore(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected block NewBlock before Blockptr.
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
static std::pair< VPBlockBase *, VPBlockBase * > cloneFrom(VPBlockBase *Entry)
Clone the CFG for all nodes reachable from Entry, including cloning the blocks and their recipes.
VPlan-based builder utility analogous to IRBuilder.
static VPBuilder getToInsertAfter(VPRecipeBase *R)
Create a VPBuilder to insert after R.
static VPSingleDefRecipe * createSingleScalarOp(unsigned Opcode, ArrayRef< VPValue * > Operands, VPValue *Mask, const VPIRFlags &Flags, const VPIRMetadata &Metadata, DebugLoc DL, Instruction *UV)
Create a single-scalar recipe with Opcode and Operands without inserting it.
VPValue * getVPValue(unsigned I)
Returns the VPValue with index I defined by the VPDef.
ArrayRef< VPRecipeValue * > definedValues()
Returns an ArrayRef of the values defined by the VPDef.
BasicBlock * getIRBasicBlock() const
Class to record and manage LLVM IR flags.
This is a concrete Recipe that models a single VPlan-level instruction.
@ WideIVStep
Scale the first operand (vector step) by the second operand (scalar-step).
@ ExtractPenultimateElement
@ 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 ...
@ CanonicalIVIncrementForPart
In what follows, the term "input IR" refers to code that is fed into the vectorizer whereas the term ...
Kind getKind() const
Returns the Kind of lane offset.
unsigned getKnownLane() const
Returns a compile-time known value for the lane index and asserts if the lane can only be calculated ...
@ ScalableLast
For ScalableLast, Lane is the offset from the start of the last N-element subvector in a scalable vec...
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
VPRegionBlock * clone() override
Clone all blocks in the single-entry single-exit region of the block and their recipes without updati...
const VPBlockBase * getEntry() const
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Type * getCanonicalIVType() const
Return the type of the canonical IV for loop regions.
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Instruction::BinaryOps getInductionOpcode() const
void setStartIndex(VPValue *StartIndex)
Set or add the StartIndex operand.
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.
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
VPSingleDefRecipe * clone() override=0
Clone the current recipe.
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
VPValue * getOperand(unsigned N) const
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
void replaceAllUsesWith(VPValue *New)
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
const DataLayout & getDataLayout() const
VPBasicBlock * getEntry()
VPValue * getTripCount() const
The trip count of the original loop.
VPIRValue * getPoison(Type *Ty)
Return a VPIRValue wrapping a poison value of type Ty.
VPIRValue * getOrAddLiveIn(Value *V)
Gets the live-in VPIRValue for V or adds a new live-in (if none exists yet) for V.
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
bool hasScalarVFOnly() const
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
VPIRValue * getConstantInt(Type *Ty, uint64_t Val, bool IsSigned=false)
Return a VPIRValue wrapping a ConstantInt with the given type and value.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
bool match(Val *V, const Pattern &P)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
VPInstruction_match< VPInstruction::ExtractLastLane, VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > > m_ExtractLastLaneOfLastPart(const Op0_t &Op0)
VPInstruction_match< VPInstruction::ComputeReductionResult, Op0_t > m_ComputeReductionResult(const Op0_t &Op0)
VPInstruction_match< Instruction::InsertElement, Op0_t, Op1_t, Op2_t > m_InsertElement(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
VPInstruction_match< VPInstruction::LastActiveLane, Op0_t > m_LastActiveLane(const Op0_t &Op0)
VPInstruction_match< VPInstruction::ExtractLastActive, Op0_t, Op1_t, Op2_t > m_ExtractLastActive(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
VPInstruction_match< Instruction::ExtractElement, Op0_t, Op1_t > m_ExtractElement(const Op0_t &Op0, const Op1_t &Op1)
VPInstruction_match< VPInstruction::BranchOnCount > m_BranchOnCount()
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > m_ExtractLastPart(const Op0_t &Op0)
VPInstruction_match< VPInstruction::BuildVector > m_BuildVector()
BuildVector is matches only its opcode, w/o matching its operands as the number of operands is not fi...
VPInstruction_match< VPInstruction::ExtractPenultimateElement, Op0_t > m_ExtractPenultimateElement(const Op0_t &Op0)
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
VPInstruction_match< VPInstruction::FirstActiveLane, Op0_t > m_FirstActiveLane(const Op0_t &Op0)
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
VPInstruction_match< VPInstruction::ExtractLane, Op0_t, Op1_t > m_ExtractLane(const Op0_t &Op0, const Op1_t &Op1)
VPInstruction_match< VPInstruction::BuildStructVector > m_BuildStructVector()
BuildStructVector matches only its opcode, w/o matching its operands as the number of operands is not...
NodeAddr< PhiNode * > Phi
bool isSingleScalar(const VPValue *VPV)
Returns true if VPV is a single scalar, either because it produces the same value for all lanes or on...
bool onlyFirstPartUsed(const VPValue *Def)
Returns true if only the first part of Def is used.
bool onlyFirstLaneUsed(const VPValue *Def)
Returns true if only the first lane of Def is used.
bool doesGeneratePerAllLanes(const VPRecipeBase *R)
Returns true if R produces scalar values for all VF lanes.
bool isUniformAcrossVFsAndUFs(const VPValue *V)
Checks if V is uniform across all VF lanes and UF parts.
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.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
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,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
iterator_range< df_iterator< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_depth_first_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order.
iterator_range< df_iterator< VPBlockDeepTraversalWrapper< VPBlockBase * > > > vp_depth_first_deep(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order while traversing t...
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
auto dyn_cast_or_null(const Y &Val)
auto reverse(ContainerTy &&C)
bool isa_and_present(const Y &Val)
isa_and_present<X> - Functionally identical to isa, except that a null value is accepted.
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.