28#define DEBUG_TYPE "loop-vectorize"
34class PlainCFGBuilder {
68 bool isExternalDef(
Value *Val);
75 : TheLoop(Lp), LI(LI), Plan(
P) {}
87 Loop *LoopForBB = LI->getLoopFor(BB);
88 if (!SinglePred || LI->getLoopFor(SinglePred) == LoopForBB)
92 assert(SinglePred == LI->getLoopFor(SinglePred)->getLoopLatch() &&
93 "SinglePred must be the only loop latch");
96 if (
auto *LatchBB = GetLatchOfExit(BB)) {
97 auto *PredRegion = getOrCreateVPBB(LatchBB)->getParent();
98 assert(VPBB == cast<VPBasicBlock>(PredRegion->getSingleSuccessor()) &&
99 "successor must already be set for PredRegion; it must have VPBB "
100 "as single successor");
107 VPBBPreds.
push_back(getOrCreateVPBB(Pred));
112 return L && BB == L->getHeader();
118 Loop *LoopOfBB = LI->getLoopFor(BB);
123void PlainCFGBuilder::fixPhiNodes() {
124 for (
auto *Phi : PhisToFix) {
125 assert(IRDef2VPValue.count(Phi) &&
"Missing VPInstruction for PHINode.");
127 assert(isa<VPWidenPHIRecipe>(VPVal) &&
128 "Expected WidenPHIRecipe for phi node.");
129 auto *VPPhi = cast<VPWidenPHIRecipe>(VPVal);
130 assert(VPPhi->getNumOperands() == 0 &&
131 "Expected VPInstruction with no operands.");
133 Loop *
L = LI->getLoopFor(
Phi->getParent());
140 getOrCreateVPOperand(
Phi->getIncomingValueForBlock(LoopPred)),
144 getOrCreateVPOperand(
Phi->getIncomingValueForBlock(LoopLatch)),
149 for (
unsigned I = 0;
I !=
Phi->getNumOperands(); ++
I)
150 VPPhi->addIncoming(getOrCreateVPOperand(
Phi->getIncomingValue(
I)),
151 BB2VPBB[
Phi->getIncomingBlock(
I)]);
167 P =
P->getParentLoop();
177 if (
auto *VPBB = BB2VPBB.lookup(BB)) {
189 Loop *LoopOfBB = LI->getLoopFor(BB);
193 auto *RegionOfVPBB = Loop2Region.lookup(LoopOfBB);
196 "Region should have been created by visiting header earlier");
202 "First visit of a header basic block expects to register its region.");
204 if (LoopOfBB == TheLoop) {
205 RegionOfVPBB = Plan.getVectorLoopRegion();
208 RegionOfVPBB->setParent(Loop2Region[LoopOfBB->
getParentLoop()]);
210 RegionOfVPBB->setEntry(VPBB);
211 Loop2Region[LoopOfBB] = RegionOfVPBB;
222bool PlainCFGBuilder::isExternalDef(
Value *Val) {
230 assert(InstParent &&
"Expected instruction parent.");
234 assert(PH &&
"Expected loop pre-header.");
236 if (InstParent == PH)
242 assert(Exit &&
"Expected loop with single exit.");
243 if (InstParent == Exit) {
249 return !TheLoop->contains(Inst);
257VPValue *PlainCFGBuilder::getOrCreateVPOperand(
Value *IRVal) {
258 auto VPValIt = IRDef2VPValue.find(IRVal);
259 if (VPValIt != IRDef2VPValue.end())
262 return VPValIt->second;
271 assert(isExternalDef(IRVal) &&
"Expected external definition as operand.");
275 VPValue *NewVPVal = Plan.getOrAddLiveIn(IRVal);
276 IRDef2VPValue[IRVal] = NewVPVal;
283void PlainCFGBuilder::createVPInstructionsForVPBB(
VPBasicBlock *VPBB,
285 VPIRBuilder.setInsertPoint(VPBB);
291 assert(!IRDef2VPValue.count(Inst) &&
292 "Instruction shouldn't have been visited.");
294 if (
auto *Br = dyn_cast<BranchInst>(Inst)) {
297 if (Br->isConditional()) {
298 VPValue *
Cond = getOrCreateVPOperand(Br->getCondition());
307 if (
auto *Phi = dyn_cast<PHINode>(Inst)) {
313 PhisToFix.push_back(Phi);
323 NewVPV = cast<VPInstruction>(
324 VPIRBuilder.createNaryOp(Inst->
getOpcode(), VPOperands, Inst));
327 IRDef2VPValue[Inst] = NewVPV;
332void PlainCFGBuilder::buildPlainCFG() {
338 BasicBlock *ThePreheaderBB = TheLoop->getLoopPreheader();
340 "Unexpected loop preheader");
341 auto *VectorPreheaderVPBB =
347 BB2VPBB[ThePreheaderBB] = VectorPreheaderVPBB;
348 BasicBlock *LoopExitBB = TheLoop->getUniqueExitBlock();
349 Loop2Region[LI->getLoopFor(TheLoop->getHeader())] = TheRegion;
350 assert(LoopExitBB &&
"Loops with multiple exits are not supported.");
357 BB2VPBB[TheLoop->getHeader()] = VectorHeaderVPBB;
360 if (TheLoop->getHeader() != TheLoop->getLoopLatch()) {
361 BB2VPBB[TheLoop->getLoopLatch()] = VectorLatchVPBB;
364 delete VectorLatchVPBB;
376 for (
auto &
I : *ThePreheaderBB) {
377 if (
I.getType()->isVoidTy())
379 IRDef2VPValue[&
I] = Plan.getOrAddLiveIn(&
I);
390 createVPInstructionsForVPBB(VPBB, BB);
391 Loop *LoopForBB = LI->getLoopFor(BB);
394 setVPBBPredsFromBB(VPBB, BB);
400 setRegionPredsFromBB(
Region, BB);
415 assert(BI->isConditional() && NumSuccs == 2 && BI->isConditional() &&
416 "block must have conditional branch with 2 successors");
419 assert(IRDef2VPValue.contains(BI->getCondition()) &&
420 "Missing condition bit in IRDef2VPValue!");
421 VPBasicBlock *Successor0 = getOrCreateVPBB(BI->getSuccessor(0));
422 VPBasicBlock *Successor1 = getOrCreateVPBB(BI->getSuccessor(1));
431 if (TheRegion !=
Region) {
444void VPlanHCFGBuilder::buildPlainCFG() {
445 PlainCFGBuilder PCFGBuilder(TheLoop, LI, Plan);
446 PCFGBuilder.buildPlainCFG();
457 LLVM_DEBUG(
dbgs() <<
"Dominator Tree after building the plain CFG.\n";
This file provides a LoopVectorizationPlanner class.
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isHeaderBB(BasicBlock *BB, Loop *L)
static bool doesContainLoop(const Loop *L, const Loop *OuterLoop)
Return true of L loop is contained within OuterLoop.
static bool isHeaderVPBB(VPBasicBlock *VPBB)
This file defines the VPlanHCFGBuilder class which contains the public interface (buildHierarchicalCF...
LLVM Basic Block Representation.
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.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
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...
This class represents an Operation in the Expression.
void print(raw_ostream &O) const
print - Convert to human readable form
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
unsigned getLoopDepth() const
Return the nesting level of this loop.
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
Wrapper class to LoopBlocksDFS that provides a standard begin()/end() interface for the DFS reverse p...
Represents a single loop in the control flow graph.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
VPRegionBlock * getParent()
const VPBasicBlock * getExitingBasicBlock() const
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
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.
VPBlockBase * getSinglePredecessor() const
void clearPredecessors()
Remove all the predecessor of this 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
VPlan-based builder utility analogous to IRBuilder.
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
const VPBlockBase * getEntry() const
void setExiting(VPBlockBase *ExitingBlock)
Set ExitingBlock as the exiting VPBlockBase of this VPRegionBlock.
A recipe for handling phis that are widened in the vector loop.
void buildHierarchicalCFG()
Build H-CFG for TheLoop and update Plan accordingly.
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
void setName(const Twine &newName)
LLVM Value Representation.
StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
NodeAddr< PhiNode * > Phi
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto succ_size(const MachineBasicBlock *BB)
auto predecessors(const MachineBasicBlock *BB)