49 #define DEBUG_TYPE "vplan" 64 return cast<VPBasicBlock>(Block);
71 return cast<VPBasicBlock>(Block);
79 return cast<VPBasicBlock>(Block);
86 return cast<VPBasicBlock>(Block);
90 if (!Successors.empty() || !Parent)
93 "Block w/o successors not the exit of its parent.");
98 if (!Predecessors.empty() || !Parent)
101 "Block w/o predecessors not the entry of its parent.");
136 assert(EnableVPlanNativePath &&
137 "Unexpected null predecessor in non VPlan-native path");
142 assert(PredBB &&
"Predecessor basic-block not found building successor.");
145 if (isa<UnreachableInst>(PredBBTerminator)) {
146 assert(PredVPSuccessors.size() == 1 &&
147 "Predecessor ending w/o branch must have single successor.");
148 PredBBTerminator->eraseFromParent();
151 assert(PredVPSuccessors.size() == 2 &&
152 "Predecessor ending with branch must have two successors.");
153 unsigned idx = PredVPSuccessors.front() ==
this ? 0 : 1;
154 assert(!PredBBTerminator->getSuccessor(idx) &&
155 "Trying to reset an existing successor block.");
156 PredBBTerminator->setSuccessor(idx, NewBB);
182 NewBB = createEmptyBasicBlock(State->
CFG);
195 <<
" in BB:" << NewBB->
getName() <<
'\n');
204 if (EnableVPlanNativePath && (CBV =
getCondBit())) {
206 assert(IRCBV &&
"Unexpected null underlying value for condition bit");
220 assert(isa<UnreachableInst>(CurrentTerminator) &&
221 "Expected to replace unreachable terminator with conditional " 224 CondBr->setSuccessor(0,
nullptr);
234 if (!isReplicator()) {
237 if (EnableVPlanNativePath) {
242 if (Block->getNumPredecessors() == 0)
247 if (Block->getNumSuccessors() == 0)
251 LLVM_DEBUG(
dbgs() <<
"LV: VPBlock in RPO " << Block->getName() <<
'\n');
252 Block->execute(State);
257 assert(!State->
Instance &&
"Replicating a Region with non-null instance.");
262 for (
unsigned Part = 0, UF = State->
UF; Part < UF; ++Part) {
264 for (
unsigned Lane = 0, VF = State->
VF; Lane < VF; ++Lane) {
268 LLVM_DEBUG(
dbgs() <<
"LV: VPBlock in RPO " << Block->getName() <<
'\n');
269 Block->execute(State);
280 Parent->getRecipeList().insert(InsertPos->
getIterator(),
this);
284 return getParent()->getRecipeList().erase(getIterator());
292 Value *A = State.
get(getOperand(0), Part);
293 Value *
B = State.
get(getOperand(1), Part);
295 State.
set(
this, V, Part);
301 Value *A = State.
get(getOperand(0), Part);
303 State.
set(
this, V, Part);
307 Value *IV = State.
get(getOperand(0), Part);
308 Value *TC = State.
get(getOperand(1), Part);
310 State.
set(
this, V, Part);
320 for (
unsigned Part = 0; Part < State.
UF; ++Part)
321 generateInstruction(State, Part);
325 O <<
" +\n" << Indent <<
"\"EMIT ";
342 O <<
"combined load";
345 O <<
"combined store";
351 for (
const VPValue *Operand : operands()) {
353 Operand->printAsOperand(O);
362 if (BackedgeTakenCount && BackedgeTakenCount->getNumUsers()) {
366 "trip.count.minus.1");
367 Value2VPValue[TCMO] = BackedgeTakenCount;
371 for (
auto &Entry : Value2VPValue)
376 assert(VectorHeaderBB &&
"Loop preheader does not have a single successor.");
399 Block->execute(State);
404 assert(EnableVPlanNativePath &&
405 "Unexpected VPBBsToFix in non VPlan-native path");
407 assert(BB &&
"Unexpected null basic block for VPBB");
414 BBTerminator->setSuccessor(Idx, State->
CFG.
VPBB2IRBB[SuccVPBB]);
422 assert((EnableVPlanNativePath ||
424 "Expected InnerLoop VPlan CFG to terminate with unreachable");
426 "Expected VPlan CFG to terminate with branch in NativePath");
433 assert(Merged &&
"Could not merge last basic block with latch.");
434 VectorLatchBB = LastBB;
437 if (!EnableVPlanNativePath)
438 updateDominatorTree(State->
DT, VectorPreHeaderBB, VectorLatchBB);
444 assert(LoopHeaderBB &&
"Loop preheader does not have a single successor.");
450 for (
auto *BB = LoopHeaderBB; BB != LoopLatchBB; BB = PostDomSucc) {
453 assert(Succs.size() <= 2 &&
454 "Basic block in vector loop has more than 2 successors.");
455 PostDomSucc = Succs[0];
456 if (Succs.size() == 1) {
457 assert(PostDomSucc->getSinglePredecessor() &&
458 "PostDom successor has more than one predecessor.");
463 if (PostDomSucc->getSingleSuccessor() == InterimSucc) {
464 PostDomSucc = Succs[1];
465 InterimSucc = Succs[0];
468 "One successor of a basic block does not lead to the other.");
470 "Interim successor has more than one predecessor.");
471 assert(PostDomSucc->hasNPredecessors(2) &&
472 "PostDom successor has more than two predecessors.");
479 return (isa<VPRegionBlock>(Block) ?
"cluster_N" :
"N") +
480 Twine(getOrCreateBID(Block));
484 const std::string &Name = Block->
getName();
487 return "VPB" +
Twine(getOrCreateBID(Block));
490 void VPlanPrinter::dump() {
493 OS <<
"digraph VPlan {\n";
494 OS <<
"graph [labelloc=t, fontsize=30; label=\"Vectorization Plan";
495 if (!Plan.getName().empty())
497 if (!Plan.Value2VPValue.empty() || Plan.BackedgeTakenCount) {
499 if (Plan.BackedgeTakenCount)
501 << *Plan.getOrCreateBackedgeTakenCount() <<
" := BackedgeTakenCount";
502 for (
auto Entry : Plan.Value2VPValue) {
503 OS <<
"\\n" << *Entry.second;
505 Entry.first->printAsOperand(OS,
false);
509 OS <<
"node [shape=rect, fontname=Courier, fontsize=30]\n";
510 OS <<
"edge [fontname=Courier, fontsize=30]\n";
511 OS <<
"compound=true\n";
519 void VPlanPrinter::dumpBlock(
const VPBlockBase *Block) {
534 OS <<
Indent << getUID(Tail) <<
" -> " << getUID(Head);
535 OS <<
" [ label=\"" << Label <<
'\"';
537 OS <<
" ltail=" << getUID(From);
539 OS <<
" lhead=" << getUID(To);
541 OS <<
"; splines=none";
545 void VPlanPrinter::dumpEdges(
const VPBlockBase *Block) {
547 if (Successors.size() == 1)
548 drawEdge(Block, Successors.front(),
false,
"");
549 else if (Successors.size() == 2) {
550 drawEdge(Block, Successors.front(),
false,
"T");
551 drawEdge(Block, Successors.back(),
false,
"F");
553 unsigned SuccessorNumber = 0;
560 OS <<
Indent << getUID(BasicBlock) <<
" [label =\n";
568 const VPValue *CBV = BasicBlock->getCondBit();
570 OS <<
" +\n" <<
Indent <<
" \"CondBit: ";
571 if (
const VPInstruction *CBI = dyn_cast<VPInstruction>(CBV)) {
572 CBI->printAsOperand(OS);
581 OS <<
"\n" <<
Indent <<
"]\n";
582 dumpEdges(BasicBlock);
586 OS <<
Indent <<
"subgraph " << getUID(Region) <<
" {\n";
588 OS <<
Indent <<
"fontname=Courier\n" 602 std::string IngredientString;
604 if (
auto *Inst = dyn_cast<Instruction>(V)) {
605 if (!Inst->getType()->isVoidTy()) {
606 Inst->printAsOperand(RSO,
false);
609 RSO << Inst->getOpcodeName() <<
" ";
610 unsigned E = Inst->getNumOperands();
612 Inst->getOperand(0)->printAsOperand(RSO,
false);
613 for (
unsigned I = 1;
I <
E; ++
I)
614 Inst->getOperand(
I)->printAsOperand(RSO <<
", ",
false);
623 O <<
" +\n" << Indent <<
"\"WIDEN\\l\"";
630 O <<
" +\n" << Indent <<
"\"WIDEN-INDUCTION";
640 O <<
" +\n" << Indent <<
"\"WIDEN-PHI " <<
VPlanIngredient(Phi) <<
"\\l\"";
644 O <<
" +\n" << Indent <<
"\"BLEND ";
645 Phi->printAsOperand(O,
false);
651 Phi->getIncomingValue(0)->printAsOperand(O,
false);
655 Phi->getIncomingValue(
I)->printAsOperand(O,
false);
665 << Indent <<
"\"" << (IsUniform ?
"CLONE " :
"REPLICATE ")
674 << Indent <<
"\"PHI-PREDICATED-INSTRUCTION " <<
VPlanIngredient(PredInst)
688 template void DomTreeBuilder::Calculate<VPDominatorTree>(
VPDominatorTree &DT);
697 void VPInterleavedAccessInfo::visitRegion(
VPRegionBlock *Region,
702 visitBlock(
Base, Old2New, IAI);
706 void VPInterleavedAccessInfo::visitBlock(
VPBlockBase *Block, Old2NewTy &Old2New,
708 if (
VPBasicBlock *VPBB = dyn_cast<VPBasicBlock>(Block)) {
710 assert(isa<VPInstruction>(&VPI) &&
"Can only handle VPInstructions");
711 auto *VPInst = cast<VPInstruction>(&VPI);
712 auto *Inst = cast<Instruction>(VPInst->getUnderlyingValue());
717 auto NewIGIter = Old2New.find(IG);
718 if (NewIGIter == Old2New.end())
720 IG->getFactor(), IG->isReverse(), IG->getAlignment());
722 if (Inst == IG->getInsertPos())
723 Old2New[IG]->setInsertPos(VPInst);
725 InterleaveGroupMap[VPInst] = Old2New[IG];
727 VPInst, IG->getIndex(Inst),
728 IG->isReverse() ? (-1) *
int(IG->getFactor()) : IG->getFactor());
730 }
else if (
VPRegionBlock *Region = dyn_cast<VPRegionBlock>(Block))
731 visitRegion(Region, Old2New, IAI);
739 visitRegion(cast<VPRegionBlock>(Plan.
getEntry()), Old2New, IAI);
const std::string & getName() const
void print(raw_ostream &O, const Twine &Indent) const override
Print the recipe.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void ReplaceInstWithInst(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
void execute(struct VPTransformState *State)
Generate the IR code for this VPlan.
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
This class represents lattice values for constants.
bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr)
Attempts to merge a block into its predecessor, if possible.
VPRegionBlock * getParent()
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
void push_back(const T &Elt)
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
iplist< VPRecipeBase >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
const VPBasicBlock * getExitBasicBlock() const
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...
Value * CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name="")
BlockT * getExit() const
Get the exit BasicBlock of the Region.
LLVMContext & getContext() const
Get the context in which this basic block lives.
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Value * CreateNot(Value *V, const Twine &Name="")
const VPBlocksTy & getHierarchicalSuccessors()
void execute(VPTransformState &State) override
Generate the instruction.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
static Optional< unsigned > getOpcode(ArrayRef< VPValue *> Values)
Returns the opcode of Values or ~0 if they do not all agree.
void execute(struct VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPBasicBlock, thereby "executing" the VPlan.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const VPBasicBlock * getEntryBasicBlock() const
void insertBefore(VPRecipeBase *InsertPos)
Insert an unlinked recipe into a basic block immediately before the specified recipe.
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Type * getType() const
All values are typed, get the type of this value.
Drive the analysis of interleaved memory accesses in the loop.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
The group of interleaved loads/stores sharing the same stride and close to each other.
const VPBlockBase * getExit() const
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void print(raw_ostream &O, const Twine &Indent) const override
Print the recipe.
VPBlockBase * getSingleHierarchicalSuccessor()
VPBlockBase * getSingleHierarchicalPredecessor()
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Value * getOperand(unsigned i) const
Interval::succ_iterator succ_end(Interval *I)
Core dominator tree base class.
const VPBlocksTy & getHierarchicalPredecessors()
Value * getUnderlyingValue()
Return the underlying Value attached to this VPValue.
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
VPInterleavedAccessInfo(VPlan &Plan, InterleavedAccessInfo &IAI)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
virtual Value * getOrCreateVectorValues(Value *V, unsigned Part)=0
LLVM Basic Block Representation.
std::string EscapeString(const std::string &Label)
This file contains the declarations of the Vectorization Plan base classes:
UnreachableInst * CreateUnreachable()
InterleaveGroup< Instruction > * getInterleaveGroup(const Instruction *Instr) const
Get the interleave group that Instr belongs to.
This function has undefined behavior.
const char * getOpcodeName() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void print(raw_ostream &O, const Twine &Indent) const override
Print the recipe.
void printAsOperand(raw_ostream &OS, bool PrintType) const
cl::opt< bool > EnableVPlanNativePath
void print(raw_ostream &O, const Twine &Indent) const override
Print the recipe.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
self_iterator getIterator()
void printAsOperand(raw_ostream &OS) const
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
void print(raw_ostream &O, const Twine &Indent) const override
Print the recipe.
An intrusive list with ownership and callbacks specified/controlled by ilist_traits, only with API safe for polymorphic types.
static void deleteCFG(VPBlockBase *Entry)
Delete all blocks reachable from a given VPBlockBase, inclusive.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
unsigned getNumOperands() const
BlockVerifier::State From
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Generic dominator tree construction - This file provides routines to construct immediate dominator in...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void print(raw_ostream &O, const Twine &Indent) const override
Print the recipe.
void execute(struct VPTransformState *State) override
The method which generates the output IR instructions that correspond to this VPRegionBlock, thereby "executing" the VPlan.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
const VPBlocksTy & getSuccessors() const
VPBlockBase * getEnclosingBlockWithSuccessors()
An Enclosing Block of a block B is any block containing B, including B itself.
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const VPBlockBase * getEntry() const
void replaceAllUsesWith(VPValue *New)
void print(raw_ostream &O, const Twine &Indent) const override
Print the recipe.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
void print(raw_ostream &OS) const
const VPBlocksTy & getPredecessors() const
LLVM_NODISCARD bool empty() const
Represents a single loop in the control flow graph.
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
iterator_range< df_iterator< T > > depth_first(const T &G)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
VPBasicBlock * getParent()
A raw_ostream that writes to an std::string.
bool insertMember(InstTy *Instr, int Index, unsigned NewAlign)
Try to insert a new member Instr with index Index and alignment NewAlign.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...
VPBlockBase * getEnclosingBlockWithPredecessors()
This is a concrete Recipe that models a single VPlan-level instruction.
void print(raw_ostream &O, const Twine &Indent) const override
Print the Recipe.