29 #define DEBUG_TYPE "loop-vectorize" 35 class PlainCFGBuilder {
67 bool isExternalDef(
Value *Val);
73 : TheLoop(Lp), LI(LI), Plan(P) {}
86 VPBBPreds.
push_back(getOrCreateVPBB(Pred));
92 void PlainCFGBuilder::fixPhiNodes() {
93 for (
auto *Phi : PhisToFix) {
94 assert(IRDef2VPValue.count(Phi) &&
"Missing VPInstruction for PHINode.");
95 VPValue *VPVal = IRDef2VPValue[Phi];
96 assert(isa<VPInstruction>(VPVal) &&
"Expected VPInstruction for phi node.");
97 auto *VPPhi = cast<VPInstruction>(VPVal);
98 assert(VPPhi->getNumOperands() == 0 &&
99 "Expected VPInstruction with no operands.");
101 for (
Value *
Op : Phi->operands())
102 VPPhi->addOperand(getOrCreateVPOperand(
Op));
109 auto BlockIt = BB2VPBB.find(BB);
110 if (BlockIt != BB2VPBB.end())
112 return BlockIt->second;
128 bool PlainCFGBuilder::isExternalDef(
Value *Val) {
136 assert(InstParent &&
"Expected instruction parent.");
140 assert(PH &&
"Expected loop pre-header.");
142 if (InstParent == PH)
147 BasicBlock *Exit = TheLoop->getUniqueExitBlock();
148 assert(Exit &&
"Expected loop with single exit.");
149 if (InstParent == Exit) {
155 return !TheLoop->contains(Inst);
162 VPValue *PlainCFGBuilder::getOrCreateVPOperand(
Value *IRVal) {
163 auto VPValIt = IRDef2VPValue.find(IRVal);
164 if (VPValIt != IRDef2VPValue.end())
167 return VPValIt->second;
176 assert(isExternalDef(IRVal) &&
"Expected external definition as operand.");
181 Plan.addExternalDef(NewVPVal);
182 IRDef2VPValue[IRVal] = NewVPVal;
189 void PlainCFGBuilder::createVPInstructionsForVPBB(
VPBasicBlock *VPBB,
191 VPIRBuilder.setInsertPoint(VPBB);
197 assert(!IRDef2VPValue.count(Inst) &&
198 "Instruction shouldn't have been visited.");
200 if (
auto *Br = dyn_cast<BranchInst>(Inst)) {
203 if (Br->isConditional())
204 getOrCreateVPOperand(Br->getCondition());
211 if (
auto *Phi = dyn_cast<PHINode>(Inst)) {
215 NewVPInst = cast<VPInstruction>(VPIRBuilder.createNaryOp(
217 PhisToFix.push_back(Phi);
227 NewVPInst = cast<VPInstruction>(
228 VPIRBuilder.createNaryOp(Inst->
getOpcode(), VPOperands, Inst));
231 IRDef2VPValue[Inst] = NewVPInst;
249 BasicBlock *PreheaderBB = TheLoop->getLoopPreheader();
251 "Unexpected loop preheader");
252 VPBasicBlock *PreheaderVPBB = getOrCreateVPBB(PreheaderBB);
253 createVPInstructionsForVPBB(PreheaderVPBB, PreheaderBB);
255 VPBlockBase *HeaderVPBB = getOrCreateVPBB(TheLoop->getHeader());
266 createVPInstructionsForVPBB(VPBB, BB);
272 assert(TI &&
"Terminator expected.");
277 assert(SuccVPBB &&
"VPBB Successor not found.");
279 }
else if (NumSuccs == 2) {
281 assert(SuccVPBB0 &&
"Successor 0 not found.");
283 assert(SuccVPBB1 &&
"Successor 1 not found.");
286 assert(isa<BranchInst>(TI) &&
"Unsupported terminator!");
287 auto *Br = cast<BranchInst>(TI);
288 Value *BrCond = Br->getCondition();
291 assert(IRDef2VPValue.count(BrCond) &&
292 "Missing condition bit in IRDef2VPValue!");
293 VPValue *VPCondBit = IRDef2VPValue[BrCond];
301 setVPBBPredsFromBB(VPBB, BB);
307 BasicBlock *LoopExitBB = TheLoop->getUniqueExitBlock();
308 assert(LoopExitBB &&
"Loops with multiple exits are not supported.");
310 createVPInstructionsForVPBB(LoopExitVPBB, LoopExitBB);
313 setVPBBPredsFromBB(LoopExitVPBB, LoopExitBB);
322 TopRegion->setEntry(PreheaderVPBB);
323 TopRegion->setExit(LoopExitVPBB);
328 PlainCFGBuilder PCFGBuilder(TheLoop, LI, Plan);
329 return PCFGBuilder.buildPlainCFG();
336 Plan.setEntry(TopRegion);
337 LLVM_DEBUG(Plan.setName(
"HCFGBuilder: Plain CFG\n");
dbgs() << Plan);
339 Verifier.verifyHierarchicalCFG(TopRegion);
342 VPDomTree.recalculate(*TopRegion);
343 LLVM_DEBUG(
dbgs() <<
"Dominator Tree after building the plain CFG.\n";
344 VPDomTree.print(
dbgs()));
350 VPLInfo.print(
dbgs()));
This class represents lattice values for constants.
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
void buildHierarchicalCFG()
Build H-CFG for TheLoop and update Plan accordingly.
void push_back(const T &Elt)
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
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 file provides a LoopVectorizationPlanner class.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
void setOneSuccessor(VPBlockBase *Successor)
Set a given VPBlockBase Successor as the single successor of this VPBlockBase.
VPlan-based builder utility analogous to IRBuilder.
LLVM Basic Block Representation.
void analyze(const DominatorTreeBase< BlockT, false > &DomTree)
Create the loop forest using a stable algorithm.
void setPredecessors(ArrayRef< VPBlockBase *> NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This file defines the VPlanHCFGBuilder class which contains the public interface (buildHierarchicalCF...
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse, VPValue *Condition)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
pred_range predecessors(BasicBlock *BB)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Represents a single loop in the control flow graph.
verify safepoint Safepoint IR Verifier
StringRef getName() const
Return a constant reference to the value's name.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Wrapper class to LoopBlocksDFS that provides a standard begin()/end() interface for the DFS reverse p...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
rpo Deduce function attributes in RPO
void perform(LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
This is a concrete Recipe that models a single VPlan-level instruction.
void setParent(VPRegionBlock *P)
const BasicBlock * getParent() const