30 return all_of(Def->users(),
31 [Def](
const VPUser *U) { return U->usesFirstLaneOnly(Def); });
35 return all_of(Def->users(),
36 [Def](
const VPUser *U) { return U->usesFirstPartOnly(Def); });
40 return all_of(Def->users(),
41 [Def](
const VPUser *U) { return U->usesScalars(Def); });
59 EntryVPBB->
insert(Expanded, Iter);
69 auto PropagatesPoisonFromRecipeOp = [](
const VPRecipeBase *R) {
78 while (!Worklist.
empty()) {
80 if (!Visited.
insert(Current).second)
87 if (MemR->getAddr() == Current)
92 unsigned Opcode = Rep->getOpcode();
93 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
94 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
100 if (
Op == Current && PropagatesPoisonFromRecipeOp(R)) {
101 Worklist.
push_back(R->getVPSingleValue());
115 unsigned Opcode = PtrVPI->getOpcode();
116 if (Opcode == Instruction::GetElementPtr) {
118 return PtrVPI->getGEPNoWrapFlags();
119 Ptr = PtrVPI->getOperand(0);
122 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
124 Ptr = PtrVPI->getOperand(0);
134 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
135 "RegionValue must be canonical IV");
143 Value *LiveIn = V->getUnderlyingValue();
223 (*Mask + 1).isPowerOf2())
288 Type *SourceElementType;
308 if (R->getTruncInst())
353 return all_of(PtrAdd->operands(), [&SE, L](
const SCEV *
Op) {
354 return SE.isLoopInvariant(Op, L) ||
355 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
356 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
369 [](
auto *
I) {
return I->getOpcode(); })
370 .Case<VPVectorPointerRecipe, VPPredInstPHIRecipe, VPScalarIVStepsRecipe>(
377 .
Default([](
auto *) {
return 0; });
380std::optional<std::pair<bool, unsigned>>
383 return std::make_pair(
true, IID);
385 return std::make_pair(
false, Opcode);
395 case Instruction::Freeze:
396 case Instruction::GetElementPtr:
397 case Instruction::ICmp:
398 case Instruction::FCmp:
399 case Instruction::Select:
421 return RV == RV->getDefiningRegion()->getCanonicalIV();
442 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
446 return !RR->isPartialReduction();
451 return Expr->isVectorToScalar();
460 return RV == RV->getDefiningRegion()->getCanonicalIV();
465 const VPBasicBlock *VPBB = R ? R->getParent() :
nullptr;
482 return R->isSingleScalar() &&
483 (!R->mayHaveSideEffects() ||
491 .Case([](
const VPPhi *) {
512 return RepR->doesGeneratePerAllLanes();
514 return VPI->doesGeneratePerAllLanes();
516 return SIVSteps->doesGeneratePerAllLanes();
532 return RR->getVFScaleFactor();
534 return RR->getVFScaleFactor();
536 return ER->getVFScaleFactor();
540 "getting scaling factor of reduction-start-vector not implemented yet");
550 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
554 return RepR && RepR->getOpcode() == Instruction::Alloca;
561 "FirstBB and LastBB from different regions");
563 bool InSingleSuccChain =
false;
565 InSingleSuccChain |= (Succ == LastBB);
566 assert(InSingleSuccChain &&
567 "LastBB unreachable from FirstBB in single-successor chain");
571 auto *LastIt =
find(Blocks, LastBB);
572 assert(LastIt != Blocks.end() &&
573 "LastBB unreachable from FirstBB in depth-first traversal");
574 Blocks.erase(std::next(LastIt), Blocks.end());
590 if (Pred != MiddleVPBB)
604 Builder.createDerivedIV(Kind, FPBinOp, StartV, CanonicalIV, Step, Flags);
613 BaseIV = Builder.createScalarCast(Instruction::Trunc, BaseIV, TruncTy,
DL);
619 if (ResultTy != StepTy) {
626 Builder.setInsertPoint(VecPreheader);
627 Step = Builder.createScalarCast(Instruction::Trunc, Step, ResultTy,
DL);
629 return Builder.createScalarIVSteps(InductionOpcode, FPBinOp, BaseIV, Step,
641 nullptr, StartV, StepV, PtrIV->
getDebugLoc(), Builder);
655 if (
auto *R = VPBB->getParent())
656 return !R->isReplicator() && !VPBB->hasPredecessors();
673std::pair<VPBasicBlock *, VPBasicBlock *>
679 assert(Header->getNumPredecessors() == 2 &&
680 "Header must have exactly 2 predecessors");
682 return {Header, Latch};
689std::optional<MemoryLocation>
696 if (
MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
697 Loc.AATags.NoAlias = NoAliasMD;
698 if (
MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
699 Loc.AATags.Scope = AliasScopeMD;
706 assert(CanIV &&
"Expected loop region to have a canonical IV");
712 auto IsIncrementStep = [&](
VPValue *Step) ->
bool {
714 return Step == &VFxUF;
717 if (!UF.isMaterialized())
718 return Step == &UF ||
747 IsIncrementStep(Step)) {
754 "After materializing VFxUF, an increment must exist");
757 "NUW flag in region and increment must match");
782 while (!WorkList.
empty()) {
784 if (!Seen.
insert(Cur).second)
792 return Seen.contains(Blend->getIncomingValue(I));
798 if (InterleaveR->getAddr() == Cur)
807 if (MemR->getAddr() == Cur && MemR->isConsecutive())
823 if (VPI && VPI->getMask() == Cur &&
838VPValue *VPSCEVExpander::tryToReuseIRValue(
const SCEV *S) {
841 VPlan &Plan = Builder.getPlan();
843 for (
Value *V : SE.getSCEVValues(S)) {
855 for (
Instruction *DropI : DropPoisonGeneratingInsts)
863 if (
VPValue *V = tryToReuseIRValue(S))
872 return Builder.createVScale(S->
getType(), DL);
876 AddE->hasNoSignedWrap());
886 return Builder.createNoWrapPtrAdd(
Base,
Offset, GEPFlags, DL);
891 auto UseSubtract = [](
const SCEV *
Op) {
892 return Op->isNonConstantNegative();
899 return !UseSubtract(L) && UseSubtract(R);
902 for (
const SCEV *
Op : SCEVOps) {
904 bool Negate = !
Ops.empty() && UseSubtract(
Op);
909 if (UseSubtract(
Op)) {
914 WrapFlags.
HasNSW && !SE.getSignedRangeMin(
Op).isMinSignedValue();
915 Result = Builder.createOverflowingOp(Instruction::Sub, {Result, OpV},
916 {
false, HasNSW}, DL);
919 Result = Builder.createOverflowingOp(Instruction::Add, {Result, OpV},
927 MulE->hasNoSignedWrap());
933 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, OpV},
941 const SCEV *RHSExpr = UDiv->getRHS();
946 Type *Ty = UDiv->getType();
947 bool GuaranteedNotPoison =
949 if (!GuaranteedNotPoison)
950 RHS = Builder.createScalarFreeze(RHS, DL);
951 if (!SE.isKnownNonZero(RHSExpr) || !GuaranteedNotPoison)
952 RHS = Builder.createScalarIntrinsic(
953 Intrinsic::umax, {RHS, Builder.getPlan().getConstantInt(Ty, 1)}, Ty,
956 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
969 Opcode = Instruction::Trunc;
972 Opcode = Instruction::ZExt;
975 Opcode = Instruction::SExt;
978 Opcode = Instruction::PtrToAddr;
986 if (Opcode == Instruction::PtrToAddr) {
987 VPlan &Plan = Builder.getPlan();
993 return SE.DT.dominates(CI->getParent(), PH);
999 return Builder.createScalarCast(Opcode,
Op, S->
getType(), DL);
1010 IntrinsicID = Intrinsic::umax;
1013 IntrinsicID = Intrinsic::smax;
1017 IntrinsicID = Intrinsic::umin;
1020 IntrinsicID = Intrinsic::smin;
1031 bool PrevSafeMode = SafeUDivMode;
1034 bool MayShortCircuit =
1035 IsSequential &&
Ops.size() !=
MinMax->getNumOperands() - 1;
1036 SafeUDivMode = MayShortCircuit || PrevSafeMode;
1038 SafeUDivMode = PrevSafeMode;
1039 if (MayShortCircuit)
1040 OpV = Builder.createScalarFreeze(OpV, DL);
1045 Result = Builder.createScalarIntrinsic(IntrinsicID, {Result,
Op},
1054 "can only expand AddRecs for loops outside VPlan's scope");
1068 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
1070 if (IsConditionalAssume)
1073 if (R.mayHaveSideEffects())
1078 R.getVPSingleValue() == R.getParent()->getPlan()->getTripCount())
1082 return all_of(R.definedValues(), [](
VPValue *V) { return V->user_empty(); });
1090 while (!WorkList.
empty()) {
1092 if (!Seen.
insert(Cur).second)
1100 R->eraseFromParent();
1106 for (
unsigned I = 0;
I !=
Users.size(); ++
I) {
1109 Users.insert_range(V->users());
1111 return Users.takeVector();
1133 VPlan &Plan = *R.getParent()->getPlan();
1134 auto FoldToIRValue = [&]() ->
Value * {
1136 if (OpcodeOrIID->first) {
1142 return Folder.FoldIntrinsic(OpcodeOrIID->second,
Ops, R.getScalarType(),
1143 RFlags ? RFlags->getFastMathFlagsOrNone()
1146 unsigned Opcode = OpcodeOrIID->second;
1152 R.getVPSingleValue()->getScalarType());
1155 return Folder.FoldBinOp(Instruction::BinaryOps::Xor,
Ops[0],
1157 case Instruction::Select:
1158 return Folder.FoldSelect(
Ops[0],
Ops[1],
Ops[2]);
1159 case Instruction::ICmp:
1160 case Instruction::FCmp:
1163 case Instruction::GetElementPtr: {
1166 return Folder.FoldGEP(
GEP->getSourceElementType(),
Ops[0],
1176 case Instruction::ExtractElement:
1183 if (
Value *V = FoldToIRValue())
1199 if (
none_of(Def->operands(), MatchPerm))
1204 return (Op->hasOneUse() && MatchPerm(Op)) || match(Op, m_LiveIn());
1209 for (
unsigned I = 0, E = Def->getNumOperands();
I != E; ++
I)
1210 if (
VPValue *
X = MatchPerm(Def->getOperand(
I)))
1211 Def->setOperand(
I,
X);
1215 Def->replaceUsesWithIf(
1216 Res, [&Res](
VPUser &U,
unsigned _) {
return &U != Res; });
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
iv Induction Variable Users
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file provides a LoopVectorizationPlanner class.
This file provides utility analysis objects describing memory locations.
This file implements a set that has insertion order iteration characteristics.
static SymbolRef::Type getType(const Symbol *Sym)
This file implements the TypeSwitch template, which mimics a switch() statement whose cases are type ...
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
static bool preservesUniformity(unsigned Opcode)
Returns true if Opcode preserves uniformity, i.e., if all operands are uniform, the result will also ...
static bool poisonGuaranteesUB(const VPValue *V)
Returns true if V being poison is guaranteed to trigger UB because it propagates to the address of a ...
static const uint32_t IV[8]
Class for arbitrary precision integers.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
This is the base class for all instructions that perform data casts.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Utility class for floating point operations which can have information about relaxed accuracy require...
Convenience struct for specifying and reasoning about fast-math flags.
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags noUnsignedWrap()
static GEPNoWrapFlags none()
A struct for saving information about induction variables.
InductionKind
This enum represents the kinds of inductions that we support.
@ IK_IntInduction
Integer induction variable. Step = C.
InstSimplifyFolder - Use InstructionSimplify to fold operations to existing values.
Represents a single loop in the control flow graph.
Representation for a specific memory location.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEV * getPredicatedSCEV(const SCEV *Expr)
Returns the rewritten SCEV for Expr in the context of the current SCEV predicate.
static LLVM_ABI void dropPoisonGeneratingAnnotationsAndReinfer(ScalarEvolution &SE, Instruction *I)
Drop poison-generating flags from I, then try re-infer via SCEV.
static LLVM_ABI CastInst * findReusableCastForPtrToAddr(Value *PtrOp, Type *Ty, const DataLayout &DL, function_ref< bool(const CastInst *)> Dominates)
Find an existing cast among PtrOp's users that computes the same value as a ptrtoaddr of PtrOp to Ty ...
This class represents an analyzed expression in the program.
static constexpr auto FlagAnyWrap
static constexpr auto FlagNSW
Type * getType() const
Return the LLVM type of this SCEV expression.
SCEVTypes getSCEVType() const
The main scalar evolution driver.
LLVM_ABI const SCEV * getUDivExpr(SCEVUse LHS, SCEVUse RHS)
Get a canonical unsigned division expression, or something simpler if possible.
LLVM_ABI bool isKnownNonNegative(const SCEV *S)
Test if the given expression is known to be non-negative.
LLVM_ABI const SCEV * getZeroExtendExpr(SCEVUse Op, Type *Ty, unsigned Depth=0)
LLVM_ABI const SCEV * getAbsExpr(const SCEV *Op, bool IsNSW)
LLVM_ABI const SCEV * getURemExpr(SCEVUse LHS, SCEVUse RHS)
Represents an unsigned remainder expression based on unsigned division.
LLVM_ABI const SCEV * getSMinExpr(SCEVUse LHS, SCEVUse RHS)
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
LLVM_ABI uint64_t getTypeSizeInBits(Type *Ty) const
Return the size in bits of the specified type, for which isSCEVable must return true.
LLVM_ABI const SCEV * getConstant(ConstantInt *V)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEV::NoWrapFlags Flags)
Get an add recurrence expression for the specified loop.
static LLVM_ABI bool isGuaranteedNotToBePoison(const SCEV *Op)
Returns true if Op is guaranteed to not be poison.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI const SCEV * getTruncateExpr(SCEVUse Op, Type *Ty, unsigned Depth=0)
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getSignExtendExpr(SCEVUse Op, Type *Ty, unsigned Depth=0)
LLVM_ABI const SCEV * getUMaxExpr(SCEVUse LHS, SCEVUse RHS)
const SCEV * getMinusOne(Type *Ty)
Return a SCEV for the constant -1 of a specific type.
LLVM_ABI const SCEV * getCouldNotCompute()
LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
const SCEV * getPowerOfTwo(Type *Ty, unsigned Power)
Return a SCEV for the constant Power of two.
LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI const SCEV * getSMaxExpr(SCEVUse LHS, SCEVUse RHS)
LLVM_ABI bool canReuseInstruction(const SCEV *S, Instruction *I, SmallVectorImpl< Instruction * > &DropPoisonGeneratingInsts)
Check whether it is poison-safe to represent the expression S using the instruction I.
LLVM_ABI const SCEV * getGEPExpr(GEPOperator *GEP, ArrayRef< SCEVUse > IndexExprs)
Returns an expression for a GEP.
LLVM_ABI const SCEV * getUMinExpr(SCEVUse LHS, SCEVUse RHS, bool Sequential=false)
LLVM_ABI const SCEV * getTruncateOrSignExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
A vector that has set insertion semantics.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionalit...
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
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.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
void insert(VPRecipeBase *Recipe, iterator InsertPt)
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
VPRegionBlock * getParent()
size_t getNumSuccessors() const
const VPBlocksTy & getPredecessors() const
const VPBasicBlock * getEntryBasicBlock() const
VPBlockBase * getSingleHierarchicalPredecessor()
VPBlockBase * getSingleSuccessor() const
const VPBlocksTy & getSuccessors() const
static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop latch, using isHeader().
static VPBasicBlock * getPlainCFGMiddleBlock(const VPlan &Plan)
Returns the middle block of Plan in plain CFG form (before regions are formed).
static bool isHeader(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop header, based on regions or VPDT in their absence.
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
static std::pair< VPBasicBlock *, VPBasicBlock * > getPlainCFGHeaderAndLatch(const VPlan &Plan)
Returns the header and latch of the outermost loop of Plan in plain CFG form (before regions are form...
static SmallVector< VPBasicBlock * > blocksInSingleSuccessorChainBetween(VPBasicBlock *FirstBB, VPBasicBlock *LastBB)
Returns the blocks between FirstBB and LastBB, where FirstBB to LastBB forms a single-sucessor chain.
RAII object that stores the current insertion point and restores it when the object is destroyed.
VPlan-based builder utility analogous to IRBuilder.
ArrayRef< VPRecipeValue * > definedValues()
Returns an ArrayRef of the values defined by the VPDef.
A recipe for converting Current into Start + Current * Step.
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
A special type of VPBasicBlock that wraps an existing IR basic block.
static VPIRFlags getDefaultFlags(unsigned Opcode, Type *ResultTy=nullptr)
Returns default flags for Opcode and scalar ResultTy for opcodes that support it, asserts otherwise.
This is a concrete Recipe that models a single VPlan-level instruction.
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
unsigned getOpcode() const
bool isVectorToScalar() const
Returns true if this VPInstruction produces a scalar value from a vector, e.g.
bool isSingleScalar() const
Returns true if the recipe produces a single scalar value.
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.
void insertAfter(VPRecipeBase *InsertPos)
Insert an unlinked Recipe into a basic block immediately after the specified Recipe.
Type * getScalarType() const
Returns the scalar type of this VPRecipeValue.
A recipe for handling reduction phis.
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
VPValues are defined by a VPRegionBlock, like the canonical IV.
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
VPValue * expand(const SCEV *S)
Expand S into recipes and live-ins using the builder.
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
bool isMaterialized() const
Returns true if this value has been materialized.
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.
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
VPWidenCastRecipe is a recipe to create vector cast instructions.
A recipe for handling GEP instructions.
VPIRValue * getStartValue() const
Returns the start value of the induction.
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
A recipe for widened phis.
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
LLVMContext & getContext() const
VPBasicBlock * getEntry()
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar 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.
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
auto m_VScale()
Matches a call to llvm.vscale().
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
auto m_ZExtOrTruncOrSelf(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
bool match(const SCEV *S, const Pattern &P)
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_commutative_match< Instruction::And, Op0_t, Op1_t > m_c_BinaryAnd(const Op0_t &Op0, const Op1_t &Op1)
Match a binary AND operation.
AllRecipe_match< Instruction::Or, Op0_t, Op1_t > m_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
Match a binary OR operation.
AllRecipe_match< Opcode, Op0_t, Op1_t > m_Binary(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_match< Opcode, Op0_t > m_Unary(const Op0_t &Op0)
auto m_GetElementPtr(const Op0_t &Op0, const Op1_t &Op1)
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::ExtractVectorForPart, Op0_t, Op1_t > m_ExtractVectorForPart(const Op0_t &Op0, const Op1_t &Op1)
VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
VPInstruction_match< VPInstruction::Broadcast, Op0_t > m_Broadcast(const Op0_t &Op0)
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
void pullOutPermutationsImpl(VPlan &Plan, function_ref< VPValue *(VPValue *Op)> Perm, function_ref< VPSingleDefRecipe *(VPSingleDefRecipe *X)> Build)
Template-independent implementation for pullOutPermutations.
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...
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr)
Get or create a VPValue that corresponds to the expansion of Expr.
bool cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking=false)
Return true if we do not know how to (mechanically) hoist or sink R.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
VPBasicBlock * getFirstLoopHeader(VPlan &Plan, VPDominatorTree &VPDT)
Returns the header block of the first, top-level loop, or null if none exist.
bool isAddressSCEVForCost(const SCEV *Addr, ScalarEvolution &SE, const Loop *L)
Returns true if Addr is an address SCEV that can be passed to TTI::getAddressComputationCost,...
bool onlyFirstPartUsed(const VPValue *Def)
Returns true if only the first part of Def is used.
Intrinsic::ID getIntrinsicID(const Ty *R)
Return the intrinsic ID underlying a call.
VPInstruction * findComputeReductionResult(VPReductionPHIRecipe *PhiR)
Find the ComputeReductionResult recipe for PhiR, looking through selects inserted for predicated redu...
VPInstruction * findCanonicalIVIncrement(VPlan &Plan)
Find the canonical IV increment of Plan's vector loop region.
std::optional< MemoryLocation > getMemoryLocation(const VPRecipeBase &R)
Return a MemoryLocation for R with noalias metadata populated from R, if the recipe is supported and ...
bool onlyFirstLaneUsed(const VPValue *Def)
Returns true if only the first lane of Def is used.
VPIRValue * tryToFoldLiveIns(VPSingleDefRecipe &R, ArrayRef< VPValue * > Operands, const DataLayout &DL)
Try to fold R using InstSimplifyFolder.
SmallVector< std::pair< VPBasicBlock *, VPIRBasicBlock * > > getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB)
Returns the (early exiting block, exit block) pairs of Plan, i.e.
VPValue * findIncomingAliasMask(const VPlan &Plan)
Finds the incoming alias-mask within the vector preheader.
void recursivelyDeleteDeadRecipes(VPValue *V)
Recursively delete V and any of its operands that become dead.
bool doesGeneratePerAllLanes(const VPRecipeBase *R)
Returns true if R produces scalar values for all VF lanes.
bool isDeadRecipe(VPRecipeBase &R)
Returns true if R is dead, i.e.
bool isElementwise(const VPValue *V)
Return true if V is elementwise, i.e. none of the lanes are permuted.
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
bool isUniformAcrossVFsAndUFs(const VPValue *V)
Checks if V is uniform across all VF lanes and UF parts.
bool isUsedByLoadStoreAddress(const VPValue *V)
Returns true if V is used as part of the address of another load or store.
std::optional< std::pair< bool, unsigned > > getOpcodeOrIntrinsicID(const VPValue *V)
Get the instruction opcode or intrinsic ID for the recipe defining V.
VPValue * scalarizeVPWidenPointerInduction(VPWidenPointerInductionRecipe *PtrIV, VPlan &Plan, VPBuilder &Builder)
Scalarize a VPWidenPointerInductionRecipe by replacing it with a PtrAdd (IndStart,...
GEPNoWrapFlags getGEPFlagsForPtr(VPValue *Ptr)
Returns the GEP nowrap flags for Ptr, looking through pointer casts mirroring Value::stripPointerCast...
const SCEV * getSCEVExprForVPValue(const VPValue *V, PredicatedScalarEvolution &PSE, const Loop *L=nullptr)
Return the SCEV expression for V.
unsigned getVFScaleFactor(VPRecipeBase *R)
Get the VF scaling factor applied to the recipe's output, if the recipe has one.
SmallVector< VPUser * > collectUsersRecursively(VPValue *V)
Collect all users of V, looking through recipes that define other values.
VPScalarIVStepsRecipe * createScalarIVSteps(VPlan &Plan, InductionDescriptor::InductionKind Kind, Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, Instruction *TruncI, VPIRValue *StartV, VPValue *Step, DebugLoc DL, VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags={})
Create a scalar-iv-steps recipe over Plan's canonical IV for an induction of Kind with InductionOpcod...
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void stable_sort(R &&Range)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr from_range_t from_range
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
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...
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
auto reverse(ContainerTy &&C)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
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
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
@ Increment
Incrementally increasing token ID.
@ Default
The result value is uniform if and only if all operands are uniform.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
A VPValue representing a live-in from the input IR or a constant.