Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp
35266 views
//===-- VPlanHCFGBuilder.cpp ----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file implements the construction of a VPlan-based Hierarchical CFG10/// (H-CFG) for an incoming IR. This construction comprises the following11/// components and steps:12//13/// 1. PlainCFGBuilder class: builds a plain VPBasicBlock-based CFG that14/// faithfully represents the CFG in the incoming IR. A VPRegionBlock (Top15/// Region) is created to enclose and serve as parent of all the VPBasicBlocks16/// in the plain CFG.17/// NOTE: At this point, there is a direct correspondence between all the18/// VPBasicBlocks created for the initial plain CFG and the incoming19/// BasicBlocks. However, this might change in the future.20///21//===----------------------------------------------------------------------===//2223#include "VPlanHCFGBuilder.h"24#include "LoopVectorizationPlanner.h"25#include "llvm/Analysis/LoopIterator.h"2627#define DEBUG_TYPE "loop-vectorize"2829using namespace llvm;3031namespace {32// Class that is used to build the plain CFG for the incoming IR.33class PlainCFGBuilder {34private:35// The outermost loop of the input loop nest considered for vectorization.36Loop *TheLoop;3738// Loop Info analysis.39LoopInfo *LI;4041// Vectorization plan that we are working on.42VPlan &Plan;4344// Builder of the VPlan instruction-level representation.45VPBuilder VPIRBuilder;4647// NOTE: The following maps are intentionally destroyed after the plain CFG48// construction because subsequent VPlan-to-VPlan transformation may49// invalidate them.50// Map incoming BasicBlocks to their newly-created VPBasicBlocks.51DenseMap<BasicBlock *, VPBasicBlock *> BB2VPBB;52// Map incoming Value definitions to their newly-created VPValues.53DenseMap<Value *, VPValue *> IRDef2VPValue;5455// Hold phi node's that need to be fixed once the plain CFG has been built.56SmallVector<PHINode *, 8> PhisToFix;5758/// Maps loops in the original IR to their corresponding region.59DenseMap<Loop *, VPRegionBlock *> Loop2Region;6061// Utility functions.62void setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB);63void setRegionPredsFromBB(VPRegionBlock *VPBB, BasicBlock *BB);64void fixPhiNodes();65VPBasicBlock *getOrCreateVPBB(BasicBlock *BB);66#ifndef NDEBUG67bool isExternalDef(Value *Val);68#endif69VPValue *getOrCreateVPOperand(Value *IRVal);70void createVPInstructionsForVPBB(VPBasicBlock *VPBB, BasicBlock *BB);7172public:73PlainCFGBuilder(Loop *Lp, LoopInfo *LI, VPlan &P)74: TheLoop(Lp), LI(LI), Plan(P) {}7576/// Build plain CFG for TheLoop and connects it to Plan's entry.77void buildPlainCFG();78};79} // anonymous namespace8081// Set predecessors of \p VPBB in the same order as they are in \p BB. \p VPBB82// must have no predecessors.83void PlainCFGBuilder::setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB) {84auto GetLatchOfExit = [this](BasicBlock *BB) -> BasicBlock * {85auto *SinglePred = BB->getSinglePredecessor();86Loop *LoopForBB = LI->getLoopFor(BB);87if (!SinglePred || LI->getLoopFor(SinglePred) == LoopForBB)88return nullptr;89// The input IR must be in loop-simplify form, ensuring a single predecessor90// for exit blocks.91assert(SinglePred == LI->getLoopFor(SinglePred)->getLoopLatch() &&92"SinglePred must be the only loop latch");93return SinglePred;94};95if (auto *LatchBB = GetLatchOfExit(BB)) {96auto *PredRegion = getOrCreateVPBB(LatchBB)->getParent();97assert(VPBB == cast<VPBasicBlock>(PredRegion->getSingleSuccessor()) &&98"successor must already be set for PredRegion; it must have VPBB "99"as single successor");100VPBB->setPredecessors({PredRegion});101return;102}103// Collect VPBB predecessors.104SmallVector<VPBlockBase *, 2> VPBBPreds;105for (BasicBlock *Pred : predecessors(BB))106VPBBPreds.push_back(getOrCreateVPBB(Pred));107VPBB->setPredecessors(VPBBPreds);108}109110static bool isHeaderBB(BasicBlock *BB, Loop *L) {111return L && BB == L->getHeader();112}113114void PlainCFGBuilder::setRegionPredsFromBB(VPRegionBlock *Region,115BasicBlock *BB) {116// BB is a loop header block. Connect the region to the loop preheader.117Loop *LoopOfBB = LI->getLoopFor(BB);118Region->setPredecessors({getOrCreateVPBB(LoopOfBB->getLoopPredecessor())});119}120121// Add operands to VPInstructions representing phi nodes from the input IR.122void PlainCFGBuilder::fixPhiNodes() {123for (auto *Phi : PhisToFix) {124assert(IRDef2VPValue.count(Phi) && "Missing VPInstruction for PHINode.");125VPValue *VPVal = IRDef2VPValue[Phi];126assert(isa<VPWidenPHIRecipe>(VPVal) &&127"Expected WidenPHIRecipe for phi node.");128auto *VPPhi = cast<VPWidenPHIRecipe>(VPVal);129assert(VPPhi->getNumOperands() == 0 &&130"Expected VPInstruction with no operands.");131132Loop *L = LI->getLoopFor(Phi->getParent());133if (isHeaderBB(Phi->getParent(), L)) {134// For header phis, make sure the incoming value from the loop135// predecessor is the first operand of the recipe.136assert(Phi->getNumOperands() == 2);137BasicBlock *LoopPred = L->getLoopPredecessor();138VPPhi->addIncoming(139getOrCreateVPOperand(Phi->getIncomingValueForBlock(LoopPred)),140BB2VPBB[LoopPred]);141BasicBlock *LoopLatch = L->getLoopLatch();142VPPhi->addIncoming(143getOrCreateVPOperand(Phi->getIncomingValueForBlock(LoopLatch)),144BB2VPBB[LoopLatch]);145continue;146}147148for (unsigned I = 0; I != Phi->getNumOperands(); ++I)149VPPhi->addIncoming(getOrCreateVPOperand(Phi->getIncomingValue(I)),150BB2VPBB[Phi->getIncomingBlock(I)]);151}152}153154static bool isHeaderVPBB(VPBasicBlock *VPBB) {155return VPBB->getParent() && VPBB->getParent()->getEntry() == VPBB;156}157158/// Return true of \p L loop is contained within \p OuterLoop.159static bool doesContainLoop(const Loop *L, const Loop *OuterLoop) {160if (L->getLoopDepth() < OuterLoop->getLoopDepth())161return false;162const Loop *P = L;163while (P) {164if (P == OuterLoop)165return true;166P = P->getParentLoop();167}168return false;169}170171// Create a new empty VPBasicBlock for an incoming BasicBlock in the region172// corresponding to the containing loop or retrieve an existing one if it was173// already created. If no region exists yet for the loop containing \p BB, a new174// one is created.175VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {176if (auto *VPBB = BB2VPBB.lookup(BB)) {177// Retrieve existing VPBB.178return VPBB;179}180181// Create new VPBB.182StringRef Name = isHeaderBB(BB, TheLoop) ? "vector.body" : BB->getName();183LLVM_DEBUG(dbgs() << "Creating VPBasicBlock for " << Name << "\n");184VPBasicBlock *VPBB = new VPBasicBlock(Name);185BB2VPBB[BB] = VPBB;186187// Get or create a region for the loop containing BB.188Loop *LoopOfBB = LI->getLoopFor(BB);189if (!LoopOfBB || !doesContainLoop(LoopOfBB, TheLoop))190return VPBB;191192auto *RegionOfVPBB = Loop2Region.lookup(LoopOfBB);193if (!isHeaderBB(BB, LoopOfBB)) {194assert(RegionOfVPBB &&195"Region should have been created by visiting header earlier");196VPBB->setParent(RegionOfVPBB);197return VPBB;198}199200assert(!RegionOfVPBB &&201"First visit of a header basic block expects to register its region.");202// Handle a header - take care of its Region.203if (LoopOfBB == TheLoop) {204RegionOfVPBB = Plan.getVectorLoopRegion();205} else {206RegionOfVPBB = new VPRegionBlock(Name.str(), false /*isReplicator*/);207RegionOfVPBB->setParent(Loop2Region[LoopOfBB->getParentLoop()]);208}209RegionOfVPBB->setEntry(VPBB);210Loop2Region[LoopOfBB] = RegionOfVPBB;211return VPBB;212}213214#ifndef NDEBUG215// Return true if \p Val is considered an external definition. An external216// definition is either:217// 1. A Value that is not an Instruction. This will be refined in the future.218// 2. An Instruction that is outside of the CFG snippet represented in VPlan,219// i.e., is not part of: a) the loop nest, b) outermost loop PH and, c)220// outermost loop exits.221bool PlainCFGBuilder::isExternalDef(Value *Val) {222// All the Values that are not Instructions are considered external223// definitions for now.224Instruction *Inst = dyn_cast<Instruction>(Val);225if (!Inst)226return true;227228BasicBlock *InstParent = Inst->getParent();229assert(InstParent && "Expected instruction parent.");230231// Check whether Instruction definition is in loop PH.232BasicBlock *PH = TheLoop->getLoopPreheader();233assert(PH && "Expected loop pre-header.");234235if (InstParent == PH)236// Instruction definition is in outermost loop PH.237return false;238239// Check whether Instruction definition is in the loop exit.240BasicBlock *Exit = TheLoop->getUniqueExitBlock();241assert(Exit && "Expected loop with single exit.");242if (InstParent == Exit) {243// Instruction definition is in outermost loop exit.244return false;245}246247// Check whether Instruction definition is in loop body.248return !TheLoop->contains(Inst);249}250#endif251252// Create a new VPValue or retrieve an existing one for the Instruction's253// operand \p IRVal. This function must only be used to create/retrieve VPValues254// for *Instruction's operands* and not to create regular VPInstruction's. For255// the latter, please, look at 'createVPInstructionsForVPBB'.256VPValue *PlainCFGBuilder::getOrCreateVPOperand(Value *IRVal) {257auto VPValIt = IRDef2VPValue.find(IRVal);258if (VPValIt != IRDef2VPValue.end())259// Operand has an associated VPInstruction or VPValue that was previously260// created.261return VPValIt->second;262263// Operand doesn't have a previously created VPInstruction/VPValue. This264// means that operand is:265// A) a definition external to VPlan,266// B) any other Value without specific representation in VPlan.267// For now, we use VPValue to represent A and B and classify both as external268// definitions. We may introduce specific VPValue subclasses for them in the269// future.270assert(isExternalDef(IRVal) && "Expected external definition as operand.");271272// A and B: Create VPValue and add it to the pool of external definitions and273// to the Value->VPValue map.274VPValue *NewVPVal = Plan.getOrAddLiveIn(IRVal);275IRDef2VPValue[IRVal] = NewVPVal;276return NewVPVal;277}278279// Create new VPInstructions in a VPBasicBlock, given its BasicBlock280// counterpart. This function must be invoked in RPO so that the operands of a281// VPInstruction in \p BB have been visited before (except for Phi nodes).282void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,283BasicBlock *BB) {284VPIRBuilder.setInsertPoint(VPBB);285for (Instruction &InstRef : BB->instructionsWithoutDebug(false)) {286Instruction *Inst = &InstRef;287288// There shouldn't be any VPValue for Inst at this point. Otherwise, we289// visited Inst when we shouldn't, breaking the RPO traversal order.290assert(!IRDef2VPValue.count(Inst) &&291"Instruction shouldn't have been visited.");292293if (auto *Br = dyn_cast<BranchInst>(Inst)) {294// Conditional branch instruction are represented using BranchOnCond295// recipes.296if (Br->isConditional()) {297VPValue *Cond = getOrCreateVPOperand(Br->getCondition());298VPIRBuilder.createNaryOp(VPInstruction::BranchOnCond, {Cond}, Inst);299}300301// Skip the rest of the Instruction processing for Branch instructions.302continue;303}304305VPValue *NewVPV;306if (auto *Phi = dyn_cast<PHINode>(Inst)) {307// Phi node's operands may have not been visited at this point. We create308// an empty VPInstruction that we will fix once the whole plain CFG has309// been built.310NewVPV = new VPWidenPHIRecipe(Phi);311VPBB->appendRecipe(cast<VPWidenPHIRecipe>(NewVPV));312PhisToFix.push_back(Phi);313} else {314// Translate LLVM-IR operands into VPValue operands and set them in the315// new VPInstruction.316SmallVector<VPValue *, 4> VPOperands;317for (Value *Op : Inst->operands())318VPOperands.push_back(getOrCreateVPOperand(Op));319320// Build VPInstruction for any arbitrary Instruction without specific321// representation in VPlan.322NewVPV = cast<VPInstruction>(323VPIRBuilder.createNaryOp(Inst->getOpcode(), VPOperands, Inst));324}325326IRDef2VPValue[Inst] = NewVPV;327}328}329330// Main interface to build the plain CFG.331void PlainCFGBuilder::buildPlainCFG() {332// 0. Reuse the top-level region, vector-preheader and exit VPBBs from the333// skeleton. These were created directly rather than via getOrCreateVPBB(),334// revisit them now to update BB2VPBB. Note that header/entry and335// latch/exiting VPBB's of top-level region have yet to be created.336VPRegionBlock *TheRegion = Plan.getVectorLoopRegion();337BasicBlock *ThePreheaderBB = TheLoop->getLoopPreheader();338assert((ThePreheaderBB->getTerminator()->getNumSuccessors() == 1) &&339"Unexpected loop preheader");340auto *VectorPreheaderVPBB =341cast<VPBasicBlock>(TheRegion->getSinglePredecessor());342// ThePreheaderBB conceptually corresponds to both Plan.getPreheader() (which343// wraps the original preheader BB) and Plan.getEntry() (which represents the344// new vector preheader); here we're interested in setting BB2VPBB to the345// latter.346BB2VPBB[ThePreheaderBB] = VectorPreheaderVPBB;347BasicBlock *LoopExitBB = TheLoop->getUniqueExitBlock();348Loop2Region[LI->getLoopFor(TheLoop->getHeader())] = TheRegion;349assert(LoopExitBB && "Loops with multiple exits are not supported.");350BB2VPBB[LoopExitBB] = cast<VPBasicBlock>(TheRegion->getSingleSuccessor());351352// The existing vector region's entry and exiting VPBBs correspond to the loop353// header and latch.354VPBasicBlock *VectorHeaderVPBB = TheRegion->getEntryBasicBlock();355VPBasicBlock *VectorLatchVPBB = TheRegion->getExitingBasicBlock();356BB2VPBB[TheLoop->getHeader()] = VectorHeaderVPBB;357VectorHeaderVPBB->clearSuccessors();358VectorLatchVPBB->clearPredecessors();359if (TheLoop->getHeader() != TheLoop->getLoopLatch()) {360BB2VPBB[TheLoop->getLoopLatch()] = VectorLatchVPBB;361} else {362TheRegion->setExiting(VectorHeaderVPBB);363delete VectorLatchVPBB;364}365366// 1. Scan the body of the loop in a topological order to visit each basic367// block after having visited its predecessor basic blocks. Create a VPBB for368// each BB and link it to its successor and predecessor VPBBs. Note that369// predecessors must be set in the same order as they are in the incomming IR.370// Otherwise, there might be problems with existing phi nodes and algorithm371// based on predecessors traversal.372373// Loop PH needs to be explicitly visited since it's not taken into account by374// LoopBlocksDFS.375for (auto &I : *ThePreheaderBB) {376if (I.getType()->isVoidTy())377continue;378IRDef2VPValue[&I] = Plan.getOrAddLiveIn(&I);379}380381LoopBlocksRPO RPO(TheLoop);382RPO.perform(LI);383384for (BasicBlock *BB : RPO) {385// Create or retrieve the VPBasicBlock for this BB and create its386// VPInstructions.387VPBasicBlock *VPBB = getOrCreateVPBB(BB);388VPRegionBlock *Region = VPBB->getParent();389createVPInstructionsForVPBB(VPBB, BB);390Loop *LoopForBB = LI->getLoopFor(BB);391// Set VPBB predecessors in the same order as they are in the incoming BB.392if (!isHeaderBB(BB, LoopForBB)) {393setVPBBPredsFromBB(VPBB, BB);394} else {395// BB is a loop header, set the predecessor for the region, except for the396// top region, whose predecessor was set when creating VPlan's skeleton.397assert(isHeaderVPBB(VPBB) && "isHeaderBB and isHeaderVPBB disagree");398if (TheRegion != Region)399setRegionPredsFromBB(Region, BB);400}401402// Set VPBB successors. We create empty VPBBs for successors if they don't403// exist already. Recipes will be created when the successor is visited404// during the RPO traversal.405auto *BI = cast<BranchInst>(BB->getTerminator());406unsigned NumSuccs = succ_size(BB);407if (NumSuccs == 1) {408auto *Successor = getOrCreateVPBB(BB->getSingleSuccessor());409VPBB->setOneSuccessor(isHeaderVPBB(Successor)410? Successor->getParent()411: static_cast<VPBlockBase *>(Successor));412continue;413}414assert(BI->isConditional() && NumSuccs == 2 && BI->isConditional() &&415"block must have conditional branch with 2 successors");416// Look up the branch condition to get the corresponding VPValue417// representing the condition bit in VPlan (which may be in another VPBB).418assert(IRDef2VPValue.contains(BI->getCondition()) &&419"Missing condition bit in IRDef2VPValue!");420VPBasicBlock *Successor0 = getOrCreateVPBB(BI->getSuccessor(0));421VPBasicBlock *Successor1 = getOrCreateVPBB(BI->getSuccessor(1));422if (!LoopForBB || BB != LoopForBB->getLoopLatch()) {423VPBB->setTwoSuccessors(Successor0, Successor1);424continue;425}426// For a latch we need to set the successor of the region rather than that427// of VPBB and it should be set to the exit, i.e., non-header successor,428// except for the top region, whose successor was set when creating VPlan's429// skeleton.430if (TheRegion != Region) {431Region->setOneSuccessor(isHeaderVPBB(Successor0) ? Successor1432: Successor0);433Region->setExiting(VPBB);434}435}436437// 2. The whole CFG has been built at this point so all the input Values must438// have a VPlan couterpart. Fix VPlan phi nodes by adding their corresponding439// VPlan operands.440fixPhiNodes();441}442443void VPlanHCFGBuilder::buildPlainCFG() {444PlainCFGBuilder PCFGBuilder(TheLoop, LI, Plan);445PCFGBuilder.buildPlainCFG();446}447448// Public interface to build a H-CFG.449void VPlanHCFGBuilder::buildHierarchicalCFG() {450// Build Top Region enclosing the plain CFG.451buildPlainCFG();452LLVM_DEBUG(Plan.setName("HCFGBuilder: Plain CFG\n"); dbgs() << Plan);453454// Compute plain CFG dom tree for VPLInfo.455VPDomTree.recalculate(Plan);456LLVM_DEBUG(dbgs() << "Dominator Tree after building the plain CFG.\n";457VPDomTree.print(dbgs()));458}459460461