29#define DEBUG_TYPE "vplan"
36class PlainCFGBuilder {
47 std::unique_ptr<VPlan> Plan;
68 bool isExternalDef(
Value *Val);
75 : TheLoop(Lp), LI(LI), LVer(LVer), Plan(std::make_unique<VPlan>(Lp)) {}
78 std::unique_ptr<VPlan> buildPlainCFG();
88 VPBBPreds.
push_back(getOrCreateVPBB(Pred));
93 return L && BB == L->getHeader();
97void PlainCFGBuilder::fixHeaderPhis() {
98 for (
auto *Phi : PhisToFix) {
99 assert(IRDef2VPValue.count(Phi) &&
"Missing VPInstruction for PHINode.");
100 VPValue *VPVal = IRDef2VPValue[
Phi];
103 assert(PhiR->getNumOperands() == 0 &&
"Expected VPPhi with no operands.");
105 "Expected Phi in header block.");
107 "header phi must have exactly 2 operands");
110 getOrCreateVPOperand(
Phi->getIncomingValueForBlock(Pred)));
116VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {
117 if (
auto *VPBB = BB2VPBB.lookup(BB)) {
124 LLVM_DEBUG(
dbgs() <<
"Creating VPBasicBlock for " << Name <<
"\n");
125 VPBasicBlock *VPBB = Plan->createVPBasicBlock(Name);
136bool PlainCFGBuilder::isExternalDef(
Value *Val) {
152VPValue *PlainCFGBuilder::getOrCreateVPOperand(
Value *IRVal) {
153 auto VPValIt = IRDef2VPValue.find(IRVal);
154 if (VPValIt != IRDef2VPValue.end())
157 return VPValIt->second;
166 assert(isExternalDef(IRVal) &&
"Expected external definition as operand.");
170 VPValue *NewVPVal = Plan->getOrAddLiveIn(IRVal);
171 IRDef2VPValue[IRVal] = NewVPVal;
178void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
187 assert(!IRDef2VPValue.count(Inst) &&
188 "Instruction shouldn't have been visited.");
193 if (Br->isConditional()) {
194 VPValue *
Cond = getOrCreateVPOperand(Br->getCondition());
205 if (
SI->getNumCases() == 0)
208 for (
auto Case :
SI->cases())
209 Ops.push_back(getOrCreateVPOperand(Case.getCaseValue()));
215 VPSingleDefRecipe *NewR;
225 PhisToFix.push_back(Phi);
229 DenseMap<const VPBasicBlock *, VPValue *> VPPredToIncomingValue;
230 for (
unsigned I = 0;
I !=
Phi->getNumOperands(); ++
I) {
231 VPPredToIncomingValue[BB2VPBB[
Phi->getIncomingBlock(
I)]] =
232 getOrCreateVPOperand(
Phi->getIncomingValue(
I));
236 VPPredToIncomingValue.
lookup(Pred->getExitingBasicBlock()));
241 VPIRMetadata MD(*Inst);
243 const auto &[AliasScopeMD, NoAliasMD] =
246 MD.setMetadata(LLVMContext::MD_alias_scope, AliasScopeMD);
248 MD.setMetadata(LLVMContext::MD_noalias, NoAliasMD);
259 CI->getType(), CI->getDebugLoc(),
271 IRDef2VPValue[Inst] = NewR;
276std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG() {
279 for (VPIRBasicBlock *ExitVPBB : Plan->getExitBlocks())
280 BB2VPBB[ExitVPBB->getIRBasicBlock()] = ExitVPBB;
293 "Unexpected loop preheader");
294 for (
auto &
I : *ThePreheaderBB) {
295 if (
I.getType()->isVoidTy())
297 IRDef2VPValue[&
I] = Plan->getOrAddLiveIn(&
I);
300 LoopBlocksRPO RPO(TheLoop);
303 for (BasicBlock *BB : RPO) {
305 VPBasicBlock *VPBB = getOrCreateVPBB(BB);
307 setVPBBPredsFromBB(VPBB, BB);
310 createVPInstructionsForVPBB(VPBB, BB);
317 getOrCreateVPBB(
SI->getDefaultDest())};
318 for (
auto Case :
SI->cases())
319 Succs.
push_back(getOrCreateVPBB(Case.getCaseSuccessor()));
329 assert(BI->isConditional() && NumSuccs == 2 && BI->isConditional() &&
330 "block must have conditional branch with 2 successors");
334 VPBasicBlock *Successor0 = getOrCreateVPBB(IRSucc0);
335 VPBasicBlock *Successor1 = getOrCreateVPBB(IRSucc1);
339 for (
auto *EB : Plan->getExitBlocks())
340 setVPBBPredsFromBB(EB, EB->getIRBasicBlock());
347 Plan->getEntry()->setOneSuccessor(getOrCreateVPBB(TheLoop->
getHeader()));
348 Plan->getEntry()->setPlan(&*Plan);
355 for (
auto *EB : Plan->getExitBlocks()) {
356 for (VPRecipeBase &R : EB->phis()) {
358 PHINode &
Phi = PhiR->getIRPhi();
359 assert(PhiR->getNumOperands() == 0 &&
360 "no phi operands should be added yet");
361 for (BasicBlock *Pred :
predecessors(EB->getIRBasicBlock()))
363 getOrCreateVPOperand(
Phi.getIncomingValueForBlock(Pred)));
368 return std::move(Plan);
381 if (Preds.
size() != 2)
384 auto *PreheaderVPBB = Preds[0];
385 auto *LatchVPBB = Preds[1];
386 if (!VPDT.
dominates(PreheaderVPBB, HeaderVPB) ||
390 if (!VPDT.
dominates(PreheaderVPBB, HeaderVPB) ||
407 if (LatchVPBB->getSingleSuccessor() ||
408 LatchVPBB->getSuccessors()[0] != HeaderVPB)
411 assert(LatchVPBB->getNumSuccessors() == 2 &&
"Must have 2 successors");
415 "terminator must be a BranchOnCond");
417 Not->insertBefore(Term);
418 Term->setOperand(0, Not);
419 LatchVPBB->swapSuccessors();
432 assert(LatchExitVPB &&
"Latch expected to be left with a single successor");
442 R->setEntry(HeaderVPB);
443 R->setExiting(LatchVPBB);
455 Value *StartIdx = ConstantInt::get(IdxTy, 0);
460 HeaderVPBB->
insert(CanonicalIVPHI, HeaderVPBB->
begin());
474 auto *CanonicalIVIncrement = Builder.createOverflowingOp(
475 Instruction::Add, {CanonicalIVPHI, &Plan.
getVFxUF()}, {
true,
false},
DL,
477 CanonicalIVPHI->addOperand(CanonicalIVIncrement);
490 if (EB->getSinglePredecessor() != MiddleVPBB)
495 for (
unsigned Idx = 0; Idx != ExitIRI->getNumIncoming(); ++Idx) {
496 VPRecipeBase *Inc = ExitIRI->getIncomingValue(Idx)->getDefiningRecipe();
499 assert(ExitIRI->getNumOperands() == 1 &&
500 ExitIRI->getParent()->getSinglePredecessor() == MiddleVPBB &&
501 "exit values from early exits must be fixed when branch to "
502 "early-exit is added");
503 ExitIRI->extractLastLaneOfLastPartOfFirstOperand(
B);
525 if (LatchVPBB->getNumSuccessors() == 2) {
530 LatchVPBB->swapSuccessors();
540 "Invalid backedge-taken count");
543 InductionTy, TheLoop);
561 for (
const auto &[PhiR, ScalarPhiR] :
zip_equal(
565 {VectorPhiR, VectorPhiR->getOperand(0)}, VectorPhiR->getDebugLoc());
573 auto GetSimplifiedLiveInViaSCEV = [&](
VPValue *VPV) ->
VPValue * {
581 if (
VPValue *SimplifiedLiveIn = GetSimplifiedLiveInViaSCEV(LiveIn))
582 LiveIn->replaceAllUsesWith(SimplifiedLiveIn);
586std::unique_ptr<VPlan>
590 PlainCFGBuilder Builder(TheLoop, &LI, LVer);
591 std::unique_ptr<VPlan> VPlan0 = Builder.buildPlainCFG();
604 "step must be loop invariant");
609 "Start VPValue must match IndDesc's start value");
620 "must have an integer or float induction at this point");
649 "header must dominate its latch");
655 assert(PhiR->getNumOperands() == 2 &&
656 "Must have 2 operands for header phis");
659 VPValue *Start = PhiR->getOperand(0);
660 VPValue *BackedgeValue = PhiR->getOperand(1);
662 if (FixedOrderRecurrences.
contains(Phi)) {
670 auto InductionIt = Inductions.
find(Phi);
671 if (InductionIt != Inductions.
end())
674 PhiR->getDebugLoc());
680 "incoming value must match start value");
682 unsigned ScaleFactor = 1;
683 bool UseOrderedReductions = !AllowReordering && RdxDesc.
isOrdered();
697 PhiR->replaceAllUsesWith(HeaderPhiR);
698 PhiR->eraseFromParent();
703 bool HasUncountableEarlyExit) {
714 [[maybe_unused]]
bool HandledUncountableEarlyExit =
false;
717 if (Pred == MiddleVPBB)
719 if (HasUncountableEarlyExit) {
720 assert(!HandledUncountableEarlyExit &&
721 "can handle exactly one uncountable early exit");
724 HandledUncountableEarlyExit =
true;
734 assert((!HasUncountableEarlyExit || HandledUncountableEarlyExit) &&
735 "missed an uncountable exit that must be handled");
739 bool RequiresScalarEpilogueCheck,
746 if (MiddleVPBB->getNumSuccessors() == 1) {
748 "must have ScalarPH as single successor");
752 assert(MiddleVPBB->getNumSuccessors() == 2 &&
"must have 2 successors");
770 DebugLoc LatchDL = LatchVPBB->getTerminator()->getDebugLoc();
773 if (!RequiresScalarEpilogueCheck)
790 TopRegion->
setName(
"vector loop");
800 bool AddBranchWeights) {
816 "must have incoming values for all operands");
817 R.addOperand(R.getOperand(NumPredecessors - 2));
826 if (AddBranchWeights) {
830 Term->setMetadata(LLVMContext::MD_prof, BranchWeights);
836 ElementCount MinProfitableTripCount,
bool RequiresScalarEpilogue,
837 bool TailFolded,
bool CheckNeededWithTailFolding,
Loop *OrigLoop,
850 auto GetMinTripCount = [&]() ->
const SCEV * {
859 const SCEV *MinProfitableTripCountSCEV =
861 return SE.
getUMaxExpr(MinProfitableTripCountSCEV, VFxUF);
867 const SCEV *Step = GetMinTripCount();
869 if (CheckNeededWithTailFolding) {
877 VPValue *DistanceToMax = Builder.createNaryOp(
878 Instruction::Sub, {MaxUIntTripCount, TripCountVPV},
885 Builder.createExpandSCEV(Step),
DL);
898 TripCountCheck = Plan.
getTrue();
903 VPValue *MinTripCountVPV = Builder.createExpandSCEV(Step);
904 TripCountCheck = Builder.createICmp(
905 CmpPred, TripCountVPV, MinTripCountVPV,
DL,
"min.iters.check");
914 Term->setMetadata(LLVMContext::MD_prof, BranchWeights);
920 bool RequiresScalarEpilogue,
ElementCount EpilogueVF,
unsigned EpilogueUF,
921 unsigned MainLoopStep,
unsigned EpilogueLoopStep,
ScalarEvolution &SE) {
934 auto *CheckMinIters = Builder.createICmp(
945 unsigned EstimatedSkipCount = std::min(MainLoopStep, EpilogueLoopStep);
946 const uint32_t Weights[] = {EstimatedSkipCount,
947 MainLoopStep - EstimatedSkipCount};
951 Branch->setMetadata(LLVMContext::MD_prof, BranchWeights);
956template <
typename MatchT>
982 if (MinMaxR->getOperand(0) == RedPhiR)
983 return MinMaxR->getOperand(1);
985 assert(MinMaxR->getOperand(1) == RedPhiR &&
986 "Reduction phi operand expected");
987 return MinMaxR->getOperand(0);
992 MinMaxNumReductionsToHandle;
993 bool HasUnsupportedPhi =
false;
1000 HasUnsupportedPhi =
true;
1004 Cur->getRecurrenceKind())) {
1005 HasUnsupportedPhi =
true;
1009 VPValue *MinMaxOp = GetMinMaxCompareValue(Cur);
1013 MinMaxNumReductionsToHandle.
emplace_back(Cur, MinMaxOp);
1016 if (MinMaxNumReductionsToHandle.
empty())
1034 for (
auto &R : *VPBB) {
1042 VPValue *AllNaNLanes =
nullptr;
1044 for (
const auto &[
_, MinMaxOp] : MinMaxNumReductionsToHandle) {
1047 AllNaNLanes = AllNaNLanes ? LatchBuilder.
createOr(AllNaNLanes, RedNaNLanes)
1055 for (
const auto &[RedPhiR,
_] : MinMaxNumReductionsToHandle) {
1057 RedPhiR->getRecurrenceKind()) &&
1058 "unsupported reduction");
1065 auto *NewSel = MiddleBuilder.
createSelect(AnyNaNLane, RedPhiR,
1066 RdxResult->getOperand(1));
1068 assert(!RdxResults.
contains(RdxResult) &&
"RdxResult already used");
1069 RdxResults.
insert(RdxResult);
1074 "Unexpected terminator");
1075 auto *IsLatchExitTaken = LatchBuilder.
createICmp(
1077 LatchExitingBranch->getOperand(1));
1079 Instruction::Or, {AnyNaNLane, IsLatchExitTaken});
1088 VPValue *VecV = ResumeR->getOperand(0);
1092 if (DerivedIV->getNumUsers() == 1 &&
1098 DerivedIV->setOperand(1, NewSel);
1105 LLVM_DEBUG(
dbgs() <<
"Found resume phi we cannot update for VPlan with "
1106 "FMaxNum/FMinNum reduction.\n");
1116 VPValue *MiddleCond = MiddleTerm->getOperand(0);
1128 if (!MinMaxPhiR || !MinMaxPhiR->hasUsesOutsideReductionChain())
1137 RecurKind RdxKind = MinMaxPhiR->getRecurrenceKind();
1140 "only min/max recurrences support users outside the reduction chain");
1155 assert(MinMaxOp->getNumUsers() == 2 &&
1156 "MinMaxOp must have exactly 2 users");
1157 VPValue *MinMaxOpValue = MinMaxOp->getOperand(0);
1158 if (MinMaxOpValue == MinMaxPhiR)
1159 MinMaxOpValue = MinMaxOp->getOperand(1);
1166 if (!Cmp || Cmp->getNumUsers() != 1 ||
1167 (CmpOpA != MinMaxOpValue && CmpOpB != MinMaxOpValue))
1170 if (MinMaxOpValue != CmpOpB)
1177 if (MinMaxPhiR->getNumUsers() != 3)
1183 "one user must be MinMaxOp");
1184 assert(MinMaxResult &&
"MinMaxResult must be a user of MinMaxPhiR");
1186 "MinMaxResult must be a user of MinMaxOp (and of MinMaxPhiR");
1203 FindIVPhiR->getRecurrenceKind()))
1228 if (Pred != RdxPredicate)
1231 assert(!FindIVPhiR->isInLoop() && !FindIVPhiR->isOrdered() &&
1232 "cannot handle inloop/ordered reductions yet");
1258 "both results must be computed in the same block");
1264 auto *FinalMinMaxCmp =
1268 auto *FinalIVSelect =
1269 B.createSelect(FinalMinMaxCmp, LastIVExiting,
Sentinel);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static std::pair< Value *, APInt > getMask(Value *WideMask, unsigned Factor, ElementCount LeafValueEC)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file provides a LoopVectorizationPlanner class.
static constexpr uint32_t MinItersBypassWeights[]
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
const SmallVectorImpl< MachineOperand > & Cond
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
static void createLoopRegion(VPlan &Plan, VPBlockBase *HeaderVPB)
Create a new VPRegionBlock for the loop starting at HeaderVPB.
static bool isHeaderBB(BasicBlock *BB, Loop *L)
static VPHeaderPHIRecipe * createWidenInductionRecipe(PHINode *Phi, VPPhi *PhiR, VPValue *Start, const InductionDescriptor &IndDesc, VPlan &Plan, ScalarEvolution &SE, Loop &OrigLoop, DebugLoc DL)
Creates a VPWidenIntOrFpInductionRecipe or VPWidenPointerInductionRecipe for Phi based on IndDesc.
static void simplifyLiveInsWithSCEV(VPlan &Plan, ScalarEvolution &SE)
Check Plan's live-in and replace them with constants, if they can be simplified via SCEV.
static VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
static void addInitialSkeleton(VPlan &Plan, Type *InductionTy, DebugLoc IVDL, PredicatedScalarEvolution &PSE, Loop *TheLoop)
static void addCanonicalIVRecipes(VPlan &Plan, VPBasicBlock *HeaderVPBB, VPBasicBlock *LatchVPBB, Type *IdxTy, DebugLoc DL)
static bool canonicalHeaderAndLatch(VPBlockBase *HeaderVPB, const VPDominatorTree &VPDT)
Checks if HeaderVPB is a loop header block in the plain CFG; that is, it has exactly 2 predecessors (...
static constexpr uint32_t CheckBypassWeights[]
static void createExtractsForLiveOuts(VPlan &Plan, VPBasicBlock *MiddleVPBB)
Creates extracts for values in Plan defined in a loop region and used outside a loop region.
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
This file contains the declarations of the Vectorization Plan base classes:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
LLVM Basic Block Representation.
LLVM_ABI iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const
Return a const iterator range over the instructions in the block, skipping any debug instructions.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLE
signed less or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
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...
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
A struct for saving information about induction variables.
InductionKind getKind() const
const SCEV * getStep() const
@ IK_FpInduction
Floating point induction variable.
@ IK_PtrInduction
Pointer induction var. Step = C.
@ IK_IntInduction
Integer induction variable. Step = C.
Value * getStartValue() const
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
BlockT * getHeader() const
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
std::pair< MDNode *, MDNode * > getNoAliasMetadataFor(const Instruction *OrigInst) const
Returns a pair containing the alias_scope and noalias metadata nodes for OrigInst,...
Represents a single loop in the control flow graph.
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
This class implements a map that also provides access to all stored values in a deterministic order.
iterator find(const KeyT &Key)
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 * getSymbolicMaxBackedgeTakenCount()
Get the (predicated) symbolic max backedge count for the analyzed loop.
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
static bool isFPMinMaxNumRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating-point minnum/maxnum kind.
bool hasUsesOutsideReductionChain() const
Returns true if the reduction PHI has any uses outside the reduction chain.
TrackingVH< Value > getRecurrenceStartValue() const
static bool isFindLastIVRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
RecurKind getRecurrenceKind() const
bool isOrdered() const
Expose an ordered FP reduction to the instance users.
static bool isIntMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is an integer min/max kind.
This class represents an analyzed expression in the program.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getUMaxExpr(const SCEV *LHS, const SCEV *RHS)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getTripCountFromExitCount(const SCEV *ExitCount)
A version of getTripCountFromExitCount below which always picks an evaluation type which can not resu...
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 bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getElementCount(Type *Ty, ElementCount EC, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
LLVM_ABI const SCEV * applyLoopGuards(const SCEV *Expr, const Loop *L)
Try to apply information from loop guards for L to Expr.
LLVM_ABI bool isKnownPredicate(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
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
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.
The instances of the Type class are immutable: once they are created, they are never changed.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
iterator begin()
Recipe iterator methods.
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.
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
const VPRecipeBase & back() const
void insert(VPRecipeBase *Recipe, iterator InsertPt)
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
const VPBasicBlock * getExitingBasicBlock() const
void setName(const Twine &newName)
void swapSuccessors()
Swap successors of the block. The block must have exactly 2 successors.
size_t getNumPredecessors() const
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
const VPBlocksTy & getPredecessors() const
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
VPBlockBase * getSinglePredecessor() const
void swapPredecessors()
Swap predecessors of the block.
const VPBasicBlock * getEntryBasicBlock() const
void setOneSuccessor(VPBlockBase *Successor)
Set a given VPBlockBase Successor as the single successor of this VPBlockBase.
void setParent(VPRegionBlock *P)
VPBlockBase * getSingleSuccessor() const
const VPBlocksTy & getSuccessors() const
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBase NewBlock after BlockPtr.
static void insertOnEdge(VPBlockBase *From, VPBlockBase *To, VPBlockBase *BlockPtr)
Inserts BlockPtr on the edge between From and To.
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.
VPlan-based builder utility analogous to IRBuilder.
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createScalarCast(Instruction::CastOps Opcode, VPValue *Op, Type *ResultTy, DebugLoc DL, const VPIRFlags &Flags={}, const VPIRMetadata &Metadata={})
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< FastMathFlags > FMFs=std::nullopt)
VPBasicBlock::iterator getInsertPoint() const
VPInstruction * createFCmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new FCmp VPInstruction with predicate Pred and operands A and B.
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL, const Twine &Name="")
VPInstruction * createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new ICmp VPInstruction with predicate Pred and operands A and B.
VPInstruction * createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
void setInsertPoint(VPBasicBlock *TheBB)
This specifies that created VPInstructions should be appended to the end of the specified block.
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Instruction *Inst=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
Canonical scalar induction phi of the vector loop.
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
A special type of VPBasicBlock that wraps an existing IR basic block.
Class to record and manage LLVM IR flags.
This is a concrete Recipe that models a single VPlan-level instruction.
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
VPBasicBlock * getParent()
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
void moveBefore(VPBasicBlock &BB, iplist< VPRecipeBase >::iterator I)
Unlink this recipe and insert into BB before I.
void insertBefore(VPRecipeBase *InsertPos)
Insert an unlinked recipe into a basic block immediately before the specified recipe.
iplist< VPRecipeBase >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void moveAfter(VPRecipeBase *MovePos)
Unlink this recipe from its current VPBasicBlock and insert it into the VPBasicBlock that MovePos liv...
A recipe for handling reduction phis.
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
VPCanonicalIVPHIRecipe * getCanonicalIV()
Returns the canonical induction recipe of the region.
void setOperand(unsigned I, VPValue *New)
VPValue * getOperand(unsigned N) const
void addOperand(VPValue *Operand)
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
void setUnderlyingValue(Value *Val)
unsigned getNumUsers() const
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
LLVMContext & getContext() const
VPBasicBlock * getEntry()
VPValue & getVectorTripCount()
The vector trip count.
VPValue & getVFxUF()
Returns VF * UF of the vector loop region.
VPValue & getVF()
Returns the VF of the vector loop region.
VPValue * getTripCount() const
The trip count of the original loop.
VPValue * getTrue()
Return a VPValue wrapping i1 true.
auto getLiveIns() const
Return the list of live-in VPValues available in the VPlan.
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
VPValue * getConstantInt(Type *Ty, uint64_t Val, bool IsSigned=false)
Return a VPValue wrapping a ConstantInt with the given type and value.
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
void setTripCount(VPValue *NewTripCount)
Set the trip count assuming it is currently null; if it is not - use resetTripCount().
VPBasicBlock * getMiddleBlock()
Returns the 'middle' block of the plan, that is the block that selects whether to execute the scalar ...
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
LLVM_ABI_FOR_TEST VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
VPValue * getFalse()
Return a VPValue wrapping i1 false.
VPValue * getOrAddLiveIn(Value *V)
Gets the live-in VPValue for V or adds a new live-in (if none exists yet) for V.
VPRegionBlock * createLoopRegion(const std::string &Name="", VPBlockBase *Entry=nullptr, VPBlockBase *Exiting=nullptr)
Create a new loop region with Name and entry and exiting blocks set to Entry and Exiting respectively...
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
VPValue * getLiveIn(Value *V) const
Return the live-in VPValue for V, if there is one or nullptr otherwise.
VPBasicBlock * getVectorPreheader()
Returns the preheader of the vector loop region, if one exists, or null otherwise.
bool hasScalarTail() const
Returns true if the scalar tail may execute after the vector loop.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
MatchFunctor< Val, Pattern > match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
VPInstruction_match< VPInstruction::BranchOnCount > m_BranchOnCount()
class_match< VPValue > m_VPValue()
Match an arbitrary VPValue and ignore it.
bind_ty< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
NodeAddr< PhiNode * > Phi
friend class Instruction
Iterator for Instructions in a `BasicBlock.
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr)
Get or create a VPValue that corresponds to the expansion of Expr.
VPIRFlags getFlagsFromIndDesc(const InductionDescriptor &ID)
Extracts and returns NoWrap and FastMath flags from the induction binop in ID.
const SCEV * getSCEVExprForVPValue(const VPValue *V, ScalarEvolution &SE, const Loop *L=nullptr)
Return the SCEV expression for V.
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.
FunctionAddr VTableAddr Value
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicOp(Intrinsic::ID RdxID)
Returns the min/max intrinsic used when expanding a min/max reduction.
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.
ReductionStyle getReductionStyle(bool InLoop, bool Ordered, unsigned ScaleFactor)
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...
auto cast_or_null(const Y &Val)
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.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
auto succ_size(const MachineBasicBlock *BB)
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...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
iterator_range< po_iterator< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_post_order_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in post order.
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...
RecurKind
These are the kinds of recurrences that we support.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
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.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A recipe for handling first-order recurrence phis.