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(
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 if (IntOrFPInd->hasFastMathFlags())
182 FMF = IntOrFPInd->getFastMathFlags();
183 if (IntOrFPInd->hasNoWrapFlags())
184 WrapFlags = IntOrFPInd->getNoWrapFlags();
187 VPValue *ScalarStep =
IV->getStepValue();
188 VPBuilder Builder(PH);
190 VPInstruction *VectorStep = Builder.createNaryOp(
194 ToSkip.
insert(VectorStep);
209 Builder.setInsertPoint(
IV->getParent(), InsertPtForPhi);
216 AddOpc =
ID.getInductionOpcode();
219 AddOpc = Instruction::Add;
220 AddFlags = WrapFlags;
222 AddFlags = VPIRFlags::WrapFlagsTy(
true,
false);
224 for (
unsigned Part = 1; Part !=
UF; ++Part) {
226 Part > 1 ?
"step.add." + std::to_string(Part) :
"step.add";
229 Builder.createNaryOp(AddOpc,
234 AddFlags,
IV->getDebugLoc(), Name);
236 addRecipeForPart(
IV,
Add, Part);
239 IV->addUnrolledPartOperands(VectorStep, Prev);
242void UnrollState::unrollHeaderPHIByUF(VPHeaderPHIRecipe *R,
251 unrollWidenInductionByUF(
IV, InsertPtForPhi);
256 if (RdxPhi && RdxPhi->isOrdered())
259 auto InsertPt = std::next(
R->getIterator());
260 for (
unsigned Part = 1; Part !=
UF; ++Part) {
261 VPRecipeBase *
Copy =
R->clone();
262 Copy->insertBefore(*
R->getParent(), InsertPt);
263 addRecipeForPart(R, Copy, Part);
271 "unexpected start VPInstruction");
276 StartV = VPI->getOperand(1);
278 auto *
C = VPI->clone();
279 C->setOperand(0,
C->getOperand(1));
283 for (
unsigned Part = 1; Part !=
UF; ++Part)
284 VPV2Parts[VPI][Part - 1] = StartV;
288 "unexpected header phi recipe not needing unrolled part");
294void UnrollState::unrollRecipeByUF(VPRecipeBase &R) {
300 addUniformForAllParts(VPI);
306 RepR->getOperand(1)->isDefinedOutsideLoopRegions()) {
313 addUniformForAllParts(RepR);
319 auto InsertPt = std::next(
R.getIterator());
320 VPBasicBlock &VPBB = *
R.getParent();
321 for (
unsigned Part = 1; Part !=
UF; ++Part) {
322 VPRecipeBase *
Copy =
R.clone();
323 Copy->insertBefore(VPBB, InsertPt);
324 addRecipeForPart(&R, Copy, Part);
333 Copy->setOperand(0, getValueForPart(
Op, Part - 1));
334 Copy->setOperand(1, getValueForPart(
Op, Part));
338 VPBuilder Builder(&R);
343 :
DL.getIndexType(
R.getVPSingleValue()->getScalarType());
345 VPValue *VF = Builder.createScalarZExtOrTrunc(
348 VPValue *VFxPart = Builder.createOverflowingOp(
352 VecPtr->addPerPartOffset(VFxPart);
359 if (Phi &&
Phi->isOrdered()) {
360 auto &Parts = VPV2Parts[
Phi];
363 Parts.push_back(Red);
365 Parts.push_back(
Copy->getVPSingleValue());
366 Phi->setOperand(1,
Copy->getVPSingleValue());
371 VEPR->setOperand(0,
R.getOperand(0));
372 VEPR->setOperand(1,
R.getOperand(1));
373 VEPR->materializeOffset(Part);
384 VPBuilder Builder(Copy);
385 VPValue *ScaledByPart = Builder.createOverflowingOp(
387 Copy->setOperand(1, ScaledByPart);
392 VEPR->materializeOffset();
400void UnrollState::unrollBlock(VPBlockBase *VPB) {
404 return unrollReplicateRegionByUF(VPR);
408 ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>>
410 for (VPBlockBase *VPB : RPOT)
431 addUniformForAllParts(VPI);
432 for (
unsigned Part = 1; Part !=
UF; ++Part)
433 VPI->addOperand(getValueForPart(Op1, Part));
439 addUniformForAllParts(VPI);
440 for (
unsigned Part = 1; Part !=
UF; ++Part)
441 VPI->addOperand(getValueForPart(Op1, Part));
449 addUniformForAllParts(VPI);
450 for (
unsigned Part = 1; Part !=
UF; ++Part) {
451 VPI->addOperand(getValueForPart(Op1, Part));
452 VPI->addOperand(getValueForPart(Op2, Part));
461 bool IsPenultimatePart =
463 unsigned PartIdx = IsPenultimatePart ?
UF - 2 :
UF - 1;
465 I->replaceAllUsesWith(getValueForPart(Op0, PartIdx));
473 R.setOperand(0, getValueForPart(Op0, UF - 1));
479 addUniformForAllParts(SingleDef);
484 unrollHeaderPHIByUF(
H, InsertPtForPhi);
493 assert(UF > 0 &&
"Unroll factor must be positive");
503 VPI->getOperand(1) == &Plan.
getVF()) {
504 VPI->replaceAllUsesWith(VPI->getOperand(0));
505 VPI->eraseFromParent();
517 UnrollState Unroller(Plan, UF);
525 Unroller.unrollBlock(VPB);
537 Unroller.remapOperand(&
H, 1, UF - 1);
540 if (Unroller.contains(
H.getVPSingleValue())) {
544 Unroller.remapOperands(&
H, Part);
554 assert(Lane > 0 &&
"Zero lane adds no offset to start index");
563 int SignedLane =
static_cast<int>(Lane);
565 SignedLane = -SignedLane;
566 LaneOffset = Plan.
getOrAddLiveIn(ConstantFP::get(BaseIVTy, SignedLane));
572 APInt(BaseIVBits, Lane,
false,
true));
573 AddOpcode = Instruction::Add;
577 VPValue *NewStartIndex = LaneOffset;
581 Builder.createNaryOp(AddOpcode, {OldStartIndex, LaneOffset}, Flags);
594 "DefR must be a VPReplicateRecipe, VPInstruction or "
595 "VPScalarIVStepsRecipe");
598 auto LaneDefs = Def2LaneDefs.find(
Op);
599 if (LaneDefs != Def2LaneDefs.end())
603 return Builder.createNaryOp(Instruction::ExtractElement, {
Op, Idx});
611 auto LaneDefs = Def2LaneDefs.find(
Op);
612 if (LaneDefs != Def2LaneDefs.end()) {
618 [[maybe_unused]]
bool Matched =
620 assert(Matched &&
"original op must have been Unpack");
639 VPValue *Ext = Builder.createNaryOp(Instruction::ExtractElement, {
Op, Idx});
650 *RepR, *RepR, RepR->getDebugLoc());
654 New->setOperand(Idx,
Op);
663 New->insertBefore(DefR);
684 "must not contain wide phis, inserts or extracts before conversion");
687 DebugLoc OldDL = OldR.getDebugLoc();
690 for (
const auto &[
I,
Op] :
enumerate(OldR.operands())) {
695 auto *DefR =
Op->getDefiningRecipe();
697 DefR->getParent() == VPB) ||
702 VPValue *Extract = Builder.createNaryOp(Instruction::ExtractElement,
704 OldR.setOperand(
I, Extract);
710 RepR->getUnderlyingInstr(), RepR->operands(),
711 true,
nullptr, *RepR, *RepR, OldDL);
712 NewR->insertBefore(RepR);
713 RepR->replaceAllUsesWith(NewR);
714 RepR->eraseFromParent();
717 {BranchOnMask->getOperand(0)}, OldDL);
718 BranchOnMask->eraseFromParent();
720 VPValue *PredOp = PredPhi->getOperand(0);
723 VPPhi *NewPhi = Builder.createScalarPhi({
Poison, PredOp}, OldDL);
725 PredPhi->eraseFromParent();
731 "unexpected unhandled recipe");
744 for (
const auto &[OldBB, NewBB] :
747 for (
auto &&[OldR, NewR] :
749 for (
const auto &[OldV, NewV] :
750 zip_equal(OldR.definedValues(), NewR.definedValues()))
751 Old2NewVPValues[OldV] = NewV;
754 for (
const auto &[
I, OldOp] :
enumerate(NewR.operands())) {
756 if (
auto *NewOp = Old2NewVPValues.
lookup(OldOp))
757 NewR.setOperand(
I, NewOp);
764 "extract indices must be zero");
765 NewR.setOperand(1, IdxLane);
769 "VPPhis expected to have only first lane used");
773 assert(BVUser->getOperand(0) == OldPhi &&
774 "Unexpected first operand of build vector user");
775 BVUser->setOperand(Lane, NewPhi);
792 assert(Predecessor &&
"Replicate region must have a single predecessor");
821 for (
auto &R : FirstLaneExiting->phis()) {
826 Type *ScalarTy = Phi->getScalarType();
835 Phi->replaceAllUsesWith(BV);
836 BV->setOperand(0, Phi);
843 for (
int Lane = NumLanes - 1; Lane > 0; --Lane) {
844 const auto &[CurrentLaneEntry, CurrentLaneExiting] =
852 NextLaneEntry = CurrentLaneEntry;
866 assert(BV->getNumOperands() == NumLanes &&
867 "BuildVector must have one operand per lane");
868 for (
const auto &[Idx,
Op] :
enumerate(BV->operands())) {
870 auto DL = ScalarPhi->getDebugLoc();
873 VPValue *PrevVal = Idx == 0 ?
Poison : BV->getOperand(Idx - 1);
875 auto *Insert = Builder.createNaryOp(
876 Instruction::InsertElement,
878 Builder.setInsertPoint(ScalarPhi);
879 auto *NewPhi = Builder.createWidenPhi({PrevVal, Insert},
DL);
880 ScalarPhi->replaceAllUsesWith(NewPhi);
881 ScalarPhi->eraseFromParent();
883 BV->replaceAllUsesWith(BV->getOperand(NumLanes - 1));
884 BV->eraseFromParent();
896 if (
Region->isReplicator())
901 "cannot replicate across scalable VFs");
950 if (DefR->getNumUsers() == 0) {
954 DefR->eraseFromParent();
963 Def2LaneDefs[DefR] = LaneDefs;
966 DefR->replaceUsesWithIf(LaneDefs[0], [DefR](
VPUser &U,
unsigned) {
967 return U.usesFirstLaneOnly(DefR);
977 assert(VPI->getNumOperands() == 1 &&
978 "Build(Struct)Vector must have a single operand before "
979 "replicating by VF");
980 VPI->setOperand(0, LaneDefs[0]);
982 VPI->addOperand(LaneDef);
988 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
static Value * getOpcode(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
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.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
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.
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
@ Unpack
Extracts all lanes from its (non-scalable) vector operand.
@ 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.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
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 * 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.
IntrinsicID_match m_Intrinsic()
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 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.