9#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANUTILS_H
10#define LLVM_TRANSFORMS_VECTORIZE_VPLANUTILS_H
45 auto PreservesUniformity = [](
unsigned Opcode) ->
bool {
49 case Instruction::GetElementPtr:
50 case Instruction::ICmp:
51 case Instruction::FCmp:
52 case Instruction::Select:
65 if (
auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
72 return Rep->isSingleScalar() || (PreservesUniformity(Rep->getOpcode()) &&
78 if (
auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
79 return PreservesUniformity(WidenR->getOpcode()) &&
82 if (
auto *VPI = dyn_cast<VPInstruction>(VPV))
83 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
84 (PreservesUniformity(VPI->getOpcode()) &&
88 return isa<VPExpandSCEVRecipe>(VPV);
122 "Can't insert new block with predecessors or successors.");
126 Succ->replacePredecessor(BlockPtr, NewBlock);
127 NewBlock->appendSuccessor(Succ);
140 "Can't insert new block with predecessors or successors.");
143 Pred->replaceSuccessor(BlockPtr, NewBlock);
144 NewBlock->appendPredecessor(Pred);
159 "Can't insert IfTrue with successors.");
161 "Can't insert IfFalse with successors.");
176 unsigned PredIdx = -1u,
unsigned SuccIdx = -1u) {
178 "Can't connect two block with different parents");
179 assert((SuccIdx != -1u ||
From->getNumSuccessors() < 2) &&
180 "Blocks can't have more than two successors.");
182 From->appendSuccessor(To);
184 From->getSuccessors()[SuccIdx] = To;
187 To->appendPredecessor(
From);
195 assert(To &&
"Successor to disconnect is null.");
196 From->removeSuccessor(To);
197 To->removePredecessor(
From);
204 Pred->replaceSuccessor(Old, New);
206 Succ->replacePredecessor(Old, New);
215 template <
typename BlockTy,
typename T>
218 using BaseTy = std::conditional_t<std::is_const<BlockTy>::value,
228 return cast<BlockTy>(&
Block);
239 unsigned SuccIdx =
From->getIndexForSuccessor(To);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
BlockVerifier::State From
std::pair< BasicBlock *, unsigned > BlockTy
A pair of (basic block, score).
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
This file contains the declarations of the Vectorization Plan base classes:
This class represents an analyzed expression in the program.
The main scalar evolution driver.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
A recipe for vectorizing a phi-node as a sequence of mask-based select instructions.
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
VPRegionBlock * getParent()
iterator_range< VPBlockBase ** > predecessors()
iterator_range< VPBlockBase ** > successors()
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
unsigned getIndexForPredecessor(const VPBlockBase *Pred) const
Returns the index for Pred in the blocks predecessors list.
const VPBlocksTy & getPredecessors() const
void clearSuccessors()
Remove all the successors of this block.
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
void clearPredecessors()
Remove all the predecessor of this block.
void setParent(VPRegionBlock *P)
const VPBlocksTy & getSuccessors() const
Class that provides utilities for VPBlockBases in VPlan.
static auto blocksOnly(const T &Range)
Return an iterator range over Range which only includes BlockTy blocks.
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 bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop latch, using isHeader().
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 void insertTwoBlocksAfter(VPBlockBase *IfTrue, VPBlockBase *IfFalse, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBases IfTrue and IfFalse after BlockPtr.
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 reassociateBlocks(VPBlockBase *Old, VPBlockBase *New)
Reassociate all the blocks connected to Old so that they now point to New.
static void insertBlockBefore(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected block NewBlock before Blockptr.
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
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...
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
bool isLiveIn() const
Returns true if this VPValue is a live-in, i.e. defined outside the VPlan.
A recipe for handling GEP instructions.
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
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.
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr)
Get or create a VPValue that corresponds to the expansion of Expr.
VPBasicBlock * getFirstLoopHeader(VPlan &Plan, VPDominatorTree &VPDT)
Returns the header block of the first, top-level loop, or null if none exist.
bool onlyFirstPartUsed(const VPValue *Def)
Returns true if only the first part of Def is used.
const SCEV * getSCEVExprForVPValue(VPValue *V, ScalarEvolution &SE)
Return the SCEV expression for V.
bool onlyFirstLaneUsed(const VPValue *Def)
Returns true if only the first lane of Def is used.
bool isHeaderMask(const VPValue *V, VPlan &Plan)
Return true if V is a header mask in Plan.
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto map_range(ContainerTy &&C, FuncTy F)
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...
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
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...
A recipe for widening select instructions.