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(VPR);
349 VPValue *VF = Builder.createScalarZExtOrTrunc(
352 VPValue *VFxPart = Builder.createOverflowingOp(
355 Copy->setOperand(0, VPR->getOperand(0));
356 Copy->addOperand(VFxPart);
361 if (Phi &&
Phi->isOrdered()) {
362 auto &Parts = VPV2Parts[
Phi];
365 Parts.push_back(Red);
367 Parts.push_back(
Copy->getVPSingleValue());
368 Phi->setOperand(1,
Copy->getVPSingleValue());
373 VEPR->setOperand(0,
R.getOperand(0));
374 VEPR->setOperand(1,
R.getOperand(1));
375 VEPR->materializeOffset(Part);
391 VPBuilder Builder(Copy);
392 VPValue *ScaledByPart = Builder.createOverflowingOp(
394 Copy->setOperand(1, ScaledByPart);
399 VEPR->materializeOffset();
403void UnrollState::unrollBlock(VPBlockBase *VPB) {
407 return unrollReplicateRegionByUF(VPR);
411 ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>>
413 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);
681 "must not contain extracts before conversion");
685 for (
const auto &[
I,
Op] :
enumerate(OldR.operands())) {
689 auto *DefR =
Op->getDefiningRecipe();
691 DefR->getParent() == VPB) ||
696 VPValue *Extract = Builder.createNaryOp(
697 Instruction::ExtractElement, {
Op, Idx0}, OldR.getDebugLoc());
698 OldR.setOperand(
I, Extract);
706 *RepR, *RepR, RepR->getDebugLoc());
707 NewR->insertBefore(RepR);
708 RepR->replaceAllUsesWith(NewR);
709 RepR->eraseFromParent();
712 {BranchOnMask->getOperand(0)},
713 BranchOnMask->getDebugLoc());
714 BranchOnMask->eraseFromParent();
716 VPValue *PredOp = PredPhi->getOperand(0);
720 VPPhi *NewPhi = Builder.createScalarPhi({PoisonVal, PredOp},
721 PredPhi->getDebugLoc());
723 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);
760 NewR.setOperand(1, IdxLane);
775 assert(Predecessor &&
"Replicate region must have a single predecessor");
793 for (
int Lane = NumLanes - 1; Lane > 0; --Lane) {
794 const auto &[CurrentLaneEntry, CurrentLaneExiting] =
802 NextLaneEntry = CurrentLaneEntry;
823 if (
Region->isReplicator() &&
829 "cannot replicate across scalable VFs");
876 if (DefR->getNumUsers() == 0) {
880 DefR->eraseFromParent();
889 Def2LaneDefs[DefR] = LaneDefs;
892 DefR->replaceUsesWithIf(LaneDefs[0], [DefR](
VPUser &U,
unsigned) {
893 return U.usesFirstLaneOnly(DefR);
903 assert(VPI->getNumOperands() == 1 &&
904 "Build(Struct)Vector must have a single operand before "
905 "replicating by VF");
906 VPI->setOperand(0, LaneDefs[0]);
908 VPI->addOperand(LaneDef);
914 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 std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
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
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
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 blocksOnly(const T &Range)
Return an iterator range over Range which only includes BlockTy blocks.
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 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.
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.
@ 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...
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.
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
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.
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))
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
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< 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()
VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > m_ExtractLastPart(const Op0_t &Op0)
class_match< VPValue > m_VPValue()
Match an arbitrary VPValue and ignore it.
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)
VPInstruction_match< VPInstruction::FirstActiveLane, Op0_t > m_FirstActiveLane(const Op0_t &Op0)
bind_ty< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
VPInstruction_match< VPInstruction::ComputeAnyOfResult, Op0_t, Op1_t, Op2_t > m_ComputeAnyOfResult(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
VPInstruction_match< VPInstruction::ExtractLane, Op0_t, Op1_t > m_ExtractLane(const Op0_t &Op0, const Op1_t &Op1)
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 isUniformAcrossVFsAndUFs(VPValue *V)
Checks if V is uniform across all VF lanes and UF parts.
bool onlyFirstPartUsed(const VPValue *Def)
Returns true if only the first part of Def is used.
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 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.