44 VPTypeAnalysis TypeInfo;
48 SmallPtrSet<VPRecipeBase *, 8> ToSkip;
52 DenseMap<VPValue *, SmallVector<VPValue *>> VPV2Parts;
55 void unrollReplicateRegionByUF(VPRegionBlock *VPR);
59 void unrollRecipeByUF(VPRecipeBase &R);
64 void unrollHeaderPHIByUF(VPHeaderPHIRecipe *R,
69 void unrollWidenInductionByUF(VPWidenInductionRecipe *
IV,
73 Type *CanIVIntTy = Plan.getVectorLoopRegion()->getCanonicalIVType();
74 return Plan.getConstantInt(CanIVIntTy, Part);
78 UnrollState(VPlan &Plan,
unsigned UF) : Plan(Plan), UF(UF), TypeInfo(Plan) {}
80 void unrollBlock(VPBlockBase *VPB);
82 VPValue *getValueForPart(VPValue *V,
unsigned Part) {
85 assert((VPV2Parts.contains(V) && VPV2Parts[V].size() >= Part) &&
86 "accessed value does not exist");
87 return VPV2Parts[
V][Part - 1];
93 void addRecipeForPart(VPRecipeBase *OrigR, VPRecipeBase *CopyR,
96 const auto &[
V,
_] = VPV2Parts.try_emplace(VPV);
97 assert(
V->second.size() == Part - 1 &&
"earlier parts not set");
103 void addUniformForAllParts(VPSingleDefRecipe *R) {
104 const auto &[
V,
Inserted] = VPV2Parts.try_emplace(R);
105 assert(Inserted &&
"uniform value already added");
106 for (
unsigned Part = 0; Part != UF; ++Part)
107 V->second.push_back(R);
110 bool contains(VPValue *VPV)
const {
return VPV2Parts.contains(VPV); }
114 void remapOperand(VPRecipeBase *R,
unsigned OpIdx,
unsigned Part) {
116 R->setOperand(
OpIdx, getValueForPart(
Op, Part));
122 R->setOperand(
OpIdx, getValueForPart(
Op, Part));
128 unsigned Part,
VPlan &Plan,
139 StartIndex = Builder.createOverflowingOp(
144 StartIndex = Builder.createScalarSExtOrTrunc(
149 StartIndex = Builder.createScalarCast(Instruction::SIToFP, StartIndex,
155void UnrollState::unrollReplicateRegionByUF(
VPRegionBlock *VPR) {
157 for (
unsigned Part = 1; Part !=
UF; ++Part) {
163 for (
const auto &[PartIVPBB, Part0VPBB] :
166 for (
const auto &[PartIR, Part0R] :
zip(*PartIVPBB, *Part0VPBB)) {
171 addRecipeForPart(&Part0R, &PartIR, Part);
177void UnrollState::unrollWidenInductionByUF(
180 IV->getParent()->getEnclosingLoopRegion()->getSinglePredecessor());
182 auto &
ID =
IV->getInductionDescriptor();
184 VPIRFlags::WrapFlagsTy WrapFlags(
false,
false);
186 if (IntOrFPInd->hasFastMathFlags())
187 FMF = IntOrFPInd->getFastMathFlags();
188 if (IntOrFPInd->hasNoWrapFlags())
189 WrapFlags = IntOrFPInd->getNoWrapFlags();
192 VPValue *ScalarStep =
IV->getStepValue();
193 VPBuilder Builder(PH);
196 VPInstruction *VectorStep = Builder.createNaryOp(
200 ToSkip.
insert(VectorStep);
215 Builder.setInsertPoint(
IV->getParent(), InsertPtForPhi);
222 AddOpc =
ID.getInductionOpcode();
225 AddOpc = Instruction::Add;
226 AddFlags = WrapFlags;
228 AddFlags = VPIRFlags::WrapFlagsTy(
true,
false);
230 for (
unsigned Part = 1; Part !=
UF; ++Part) {
232 Part > 1 ?
"step.add." + std::to_string(Part) :
"step.add";
235 Builder.createNaryOp(AddOpc,
240 AddFlags,
IV->getDebugLoc(), Name);
242 addRecipeForPart(
IV,
Add, Part);
245 IV->addOperand(VectorStep);
246 IV->addOperand(Prev);
249void UnrollState::unrollHeaderPHIByUF(VPHeaderPHIRecipe *R,
258 unrollWidenInductionByUF(
IV, InsertPtForPhi);
263 if (RdxPhi && RdxPhi->isOrdered())
266 auto InsertPt = std::next(
R->getIterator());
267 for (
unsigned Part = 1; Part !=
UF; ++Part) {
268 VPRecipeBase *
Copy =
R->clone();
269 Copy->insertBefore(*
R->getParent(), InsertPt);
270 addRecipeForPart(R, Copy, Part);
278 "unexpected start VPInstruction");
283 StartV = VPI->getOperand(1);
285 auto *
C = VPI->clone();
286 C->setOperand(0,
C->getOperand(1));
290 for (
unsigned Part = 1; Part !=
UF; ++Part)
291 VPV2Parts[VPI][Part - 1] = StartV;
295 "unexpected header phi recipe not needing unrolled part");
301void UnrollState::unrollRecipeByUF(VPRecipeBase &R) {
307 addUniformForAllParts(VPI);
313 RepR->getOperand(1)->isDefinedOutsideLoopRegions()) {
320 addUniformForAllParts(RepR);
326 auto InsertPt = std::next(
R.getIterator());
327 VPBasicBlock &VPBB = *
R.getParent();
328 for (
unsigned Part = 1; Part !=
UF; ++Part) {
329 VPRecipeBase *
Copy =
R.clone();
330 Copy->insertBefore(VPBB, InsertPt);
331 addRecipeForPart(&R, Copy, Part);
340 Copy->setOperand(0, getValueForPart(
Op, Part - 1));
341 Copy->setOperand(1, getValueForPart(
Op, Part));
345 VPBuilder Builder(&R);
352 VPValue *VF = Builder.createScalarZExtOrTrunc(
355 VPValue *VFxPart = Builder.createOverflowingOp(
358 Copy->addOperand(VFxPart);
363 if (Phi &&
Phi->isOrdered()) {
364 auto &Parts = VPV2Parts[
Phi];
367 Parts.push_back(Red);
369 Parts.push_back(
Copy->getVPSingleValue());
370 Phi->setOperand(1,
Copy->getVPSingleValue());
375 VEPR->setOperand(0,
R.getOperand(0));
376 VEPR->setOperand(1,
R.getOperand(1));
377 VEPR->materializeOffset(Part);
388 VPBuilder Builder(Copy);
389 VPValue *ScaledByPart = Builder.createOverflowingOp(
391 Copy->setOperand(1, ScaledByPart);
396 VEPR->materializeOffset();
404void UnrollState::unrollBlock(VPBlockBase *VPB) {
408 return unrollReplicateRegionByUF(VPR);
412 ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>>
414 for (VPBlockBase *VPB : RPOT)
435 for (
unsigned Part = 1; Part !=
UF; ++Part)
436 R.addOperand(getValueForPart(Op1, Part));
442 for (
unsigned Part = 1; Part !=
UF; ++Part)
443 R.addOperand(getValueForPart(Op1, Part));
451 for (
unsigned Part = 1; Part !=
UF; ++Part) {
452 R.addOperand(getValueForPart(Op1, Part));
453 R.addOperand(getValueForPart(Op2, Part));
462 bool IsPenultimatePart =
464 unsigned PartIdx = IsPenultimatePart ?
UF - 2 :
UF - 1;
466 I->replaceAllUsesWith(getValueForPart(Op0, PartIdx));
474 R.setOperand(0, getValueForPart(Op0, UF - 1));
480 addUniformForAllParts(SingleDef);
485 unrollHeaderPHIByUF(
H, InsertPtForPhi);
494 assert(UF > 0 &&
"Unroll factor must be positive");
504 VPI->getOperand(1) == &Plan.
getVF()) {
505 VPI->replaceAllUsesWith(VPI->getOperand(0));
506 VPI->eraseFromParent();
518 UnrollState Unroller(Plan, UF);
526 Unroller.unrollBlock(VPB);
538 Unroller.remapOperand(&
H, 1, UF - 1);
541 if (Unroller.contains(
H.getVPSingleValue())) {
545 Unroller.remapOperands(&
H, Part);
555 assert(Lane > 0 &&
"Zero lane adds no offset to start index");
565 int SignedLane =
static_cast<int>(Lane);
567 SignedLane = -SignedLane;
568 LaneOffset = Plan.
getOrAddLiveIn(ConstantFP::get(BaseIVTy, SignedLane));
574 APInt(BaseIVBits, Lane,
false,
true));
575 AddOpcode = Instruction::Add;
579 VPValue *NewStartIndex = LaneOffset;
583 Builder.createNaryOp(AddOpcode, {OldStartIndex, LaneOffset}, Flags);
596 "DefR must be a VPReplicateRecipe, VPInstruction or "
597 "VPScalarIVStepsRecipe");
600 auto LaneDefs = Def2LaneDefs.find(
Op);
601 if (LaneDefs != Def2LaneDefs.end())
605 return Builder.createNaryOp(Instruction::ExtractElement, {
Op, Idx});
613 auto LaneDefs = Def2LaneDefs.find(
Op);
614 if (LaneDefs != Def2LaneDefs.end()) {
620 [[maybe_unused]]
bool Matched =
622 assert(Matched &&
"original op must have been Unpack");
641 VPValue *Ext = Builder.createNaryOp(Instruction::ExtractElement, {
Op, Idx});
652 *RepR, *RepR, RepR->getDebugLoc());
656 New->setOperand(Idx,
Op);
665 New->insertBefore(DefR);
687 "must not contain wide phis, inserts or extracts before conversion");
690 DebugLoc OldDL = OldR.getDebugLoc();
693 for (
const auto &[
I,
Op] :
enumerate(OldR.operands())) {
698 auto *DefR =
Op->getDefiningRecipe();
700 DefR->getParent() == VPB) ||
705 VPValue *Extract = Builder.createNaryOp(Instruction::ExtractElement,
707 OldR.setOperand(
I, Extract);
713 RepR->getUnderlyingInstr(), RepR->operands(),
714 true,
nullptr, *RepR, *RepR, OldDL);
715 NewR->insertBefore(RepR);
716 RepR->replaceAllUsesWith(NewR);
717 RepR->eraseFromParent();
720 {BranchOnMask->getOperand(0)}, OldDL);
721 BranchOnMask->eraseFromParent();
723 VPValue *PredOp = PredPhi->getOperand(0);
726 VPPhi *NewPhi = Builder.createScalarPhi({
Poison, PredOp}, OldDL);
728 PredPhi->eraseFromParent();
734 "unexpected unhandled recipe");
747 for (
const auto &[OldBB, NewBB] :
750 for (
auto &&[OldR, NewR] :
752 for (
const auto &[OldV, NewV] :
753 zip_equal(OldR.definedValues(), NewR.definedValues()))
754 Old2NewVPValues[OldV] = NewV;
757 for (
const auto &[
I, OldOp] :
enumerate(NewR.operands())) {
759 if (
auto *NewOp = Old2NewVPValues.
lookup(OldOp))
760 NewR.setOperand(
I, NewOp);
767 "extract indices must be zero");
768 NewR.setOperand(1, IdxLane);
772 "VPPhis expected to have only first lane used");
776 assert(BVUser->getOperand(0) == OldPhi &&
777 "Unexpected first operand of build vector user");
778 BVUser->setOperand(Lane, NewPhi);
795 assert(Predecessor &&
"Replicate region must have a single predecessor");
825 for (
auto &R : FirstLaneExiting->phis()) {
839 Phi->replaceAllUsesWith(BV);
840 BV->setOperand(0, Phi);
847 for (
int Lane = NumLanes - 1; Lane > 0; --Lane) {
848 const auto &[CurrentLaneEntry, CurrentLaneExiting] =
856 NextLaneEntry = CurrentLaneEntry;
870 assert(BV->getNumOperands() == NumLanes &&
871 "BuildVector must have one operand per lane");
872 for (
const auto &[Idx,
Op] :
enumerate(BV->operands())) {
874 auto DL = ScalarPhi->getDebugLoc();
877 VPValue *PrevVal = Idx == 0 ?
Poison : BV->getOperand(Idx - 1);
879 auto *Insert = Builder.createNaryOp(
880 Instruction::InsertElement,
882 Builder.setInsertPoint(ScalarPhi);
883 auto *NewPhi = Builder.createWidenPhi({PrevVal, Insert},
DL);
884 ScalarPhi->replaceAllUsesWith(NewPhi);
885 ScalarPhi->eraseFromParent();
887 BV->replaceAllUsesWith(BV->getOperand(NumLanes - 1));
888 BV->eraseFromParent();
900 if (
Region->isReplicator())
905 "cannot replicate across scalable VFs");
954 if (DefR->getNumUsers() == 0) {
958 DefR->eraseFromParent();
967 Def2LaneDefs[DefR] = LaneDefs;
970 DefR->replaceUsesWithIf(LaneDefs[0], [DefR](
VPUser &U,
unsigned) {
971 return U.usesFirstLaneOnly(DefR);
981 assert(VPI->getNumOperands() == 1 &&
982 "Build(Struct)Vector must have a single operand before "
983 "replicating by VF");
984 VPI->setOperand(0, LaneDefs[0]);
986 VPI->addOperand(LaneDef);
992 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, VPTypeAnalysis &TypeInfo)
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.
An analysis for type-inference for VPValues.
Type * inferScalarType(const VPValue *V)
Infer the type of V. Returns the scalar type of V.
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,...
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.
Type * getType() const
Returns the scalar type of this symbolic value.