diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8647,8 +8647,6 @@ auto *CanonicalIVPHI = new VPCanonicalIVPHIRecipe(StartV, DL); VPRegionBlock *TopRegion = Plan.getVectorLoopRegion(); VPBasicBlock *Header = TopRegion->getEntryBasicBlock(); - if (IsVPlanNative) - Header = cast(Header->getSingleSuccessor()); Header->insert(CanonicalIVPHI, Header->begin()); auto *CanonicalIVIncrement = @@ -8659,7 +8657,6 @@ VPBasicBlock *EB = TopRegion->getExitBasicBlock(); if (IsVPlanNative) { - EB = cast(EB->getSinglePredecessor()); EB->setCondBit(nullptr); } EB->appendRecipe(CanonicalIVIncrement); diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -25,7 +25,6 @@ #ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_H #define LLVM_TRANSFORMS_VECTORIZE_VPLAN_H -#include "VPlanLoopInfo.h" #include "VPlanValue.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" @@ -37,6 +36,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/FMF.h" @@ -2489,9 +2489,6 @@ /// to be free when the plan's destructor is called. SmallVector VPValuesToFree; - /// Holds the VPLoopInfo analysis for this VPlan. - VPLoopInfo VPLInfo; - /// Indicates whether it is safe use the Value2VPValue mapping or if the /// mapping cannot be used any longer, because it is stale. bool Value2VPValueEnabled = true; @@ -2614,10 +2611,6 @@ Value2VPValue.erase(V); } - /// Return the VPLoopInfo analysis for this VPlan. - VPLoopInfo &getVPLoopInfo() { return VPLInfo; } - const VPLoopInfo &getVPLoopInfo() const { return VPLInfo; } - #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) /// Print this VPlan to \p O. void print(raw_ostream &O) const; @@ -2647,10 +2640,16 @@ /// Returns the VPRegionBlock of the vector loop. VPRegionBlock *getVectorLoopRegion() { - return cast(getEntry()); + auto *R = dyn_cast(getEntry()); + if (R) + return R; + return cast(getEntry()->getSingleSuccessor()); } const VPRegionBlock *getVectorLoopRegion() const { - return cast(getEntry()); + auto *R = dyn_cast(getEntry()); + if (R) + return R; + return cast(getEntry()->getSingleSuccessor()); } /// Returns the canonical induction recipe of the vector loop. @@ -2835,41 +2834,6 @@ return PredVPBB; } - /// Returns true if the edge \p FromBlock -> \p ToBlock is a back-edge. - static bool isBackEdge(const VPBlockBase *FromBlock, - const VPBlockBase *ToBlock, const VPLoopInfo *VPLI) { - assert(FromBlock->getParent() == ToBlock->getParent() && - FromBlock->getParent() && "Must be in same region"); - const VPLoop *FromLoop = VPLI->getLoopFor(FromBlock); - const VPLoop *ToLoop = VPLI->getLoopFor(ToBlock); - if (!FromLoop || !ToLoop || FromLoop != ToLoop) - return false; - - // A back-edge is a branch from the loop latch to its header. - return ToLoop->isLoopLatch(FromBlock) && ToBlock == ToLoop->getHeader(); - } - - /// Returns true if \p Block is a loop latch - static bool blockIsLoopLatch(const VPBlockBase *Block, - const VPLoopInfo *VPLInfo) { - if (const VPLoop *ParentVPL = VPLInfo->getLoopFor(Block)) - return ParentVPL->isLoopLatch(Block); - - return false; - } - - /// Count and return the number of succesors of \p PredBlock excluding any - /// backedges. - static unsigned countSuccessorsNoBE(VPBlockBase *PredBlock, - VPLoopInfo *VPLI) { - unsigned Count = 0; - for (VPBlockBase *SuccBlock : PredBlock->getSuccessors()) { - if (!VPBlockUtils::isBackEdge(PredBlock, SuccBlock, VPLI)) - Count++; - } - return Count; - } - /// Return an iterator range over \p Range which only includes \p BlockTy /// blocks. The accesses are casted to \p BlockTy. template diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -277,31 +277,59 @@ assert(PredBB && "Predecessor basic-block not found building successor."); auto *PredBBTerminator = PredBB->getTerminator(); LLVM_DEBUG(dbgs() << "LV: draw edge from" << PredBB->getName() << '\n'); - if (isa(PredBBTerminator)) { + auto *TermBr = dyn_cast(PredBBTerminator); + if (isa(PredBBTerminator) || + (TermBr && !TermBr->isConditional())) { assert(PredVPSuccessors.size() == 1 && "Predecessor ending w/o branch must have single successor."); - DebugLoc DL = PredBBTerminator->getDebugLoc(); - PredBBTerminator->eraseFromParent(); - auto *Br = BranchInst::Create(NewBB, PredBB); - Br->setDebugLoc(DL); + if (TermBr) { + TermBr->setSuccessor(0, NewBB); + } else { + DebugLoc DL = PredBBTerminator->getDebugLoc(); + PredBBTerminator->eraseFromParent(); + auto *Br = BranchInst::Create(NewBB, PredBB); + Br->setDebugLoc(DL); + } } else { - assert(PredVPSuccessors.size() == 2 && - "Predecessor ending with branch must have two successors."); - unsigned idx = PredVPSuccessors.front() == this ? 0 : 1; - assert(!PredBBTerminator->getSuccessor(idx) && - "Trying to reset an existing successor block."); - PredBBTerminator->setSuccessor(idx, NewBB); + if (PredVPSuccessors.size() == 2) { + unsigned idx = PredVPSuccessors.front() == this ? 0 : 1; + assert(!PredBBTerminator->getSuccessor(idx) && + "Trying to reset an existing successor block."); + PredBBTerminator->setSuccessor(idx, NewBB); + } else { + auto *Reg = dyn_cast(PredVPBB->getParent()); + assert(Reg && !Reg->isReplicator()); + assert(this == Reg->getSingleSuccessor()); + PredBBTerminator->setSuccessor(0, NewBB); + PredBBTerminator->setSuccessor( + 1, CFG.VPBB2IRBB[Reg->getEntryBasicBlock()]); + } } } return NewBB; } void VPBasicBlock::execute(VPTransformState *State) { + if (!getParent() && getNumSuccessors() == 0) + return; + bool Replica = State->Instance && !State->Instance->isFirstIteration(); VPBasicBlock *PrevVPBB = State->CFG.PrevVPBB; VPBlockBase *SingleHPred = nullptr; BasicBlock *NewBB = State->CFG.PrevBB; // Reuse it if possible. + auto GetEnclosingNonReplicateRegion = [](VPBasicBlock *VPBB) { + VPRegionBlock *P = VPBB->getParent(); + if (P && P->isReplicator()) + return P->getParent(); + return P; + }; + + auto IsNonReplicateR = [](VPBlockBase *BB) { + auto *R = dyn_cast(BB); + return R && !R->isReplicator(); + }; + // 1. Create an IR basic block, or reuse the last one if possible. // The last IR basic block is reused, as an optimization, in three cases: // A. the first VPBB reuses the loop header BB - when PrevVPBB is null; @@ -313,8 +341,10 @@ if (PrevVPBB && /* A */ !((SingleHPred = getSingleHierarchicalPredecessor()) && SingleHPred->getExitBasicBlock() == PrevVPBB && - PrevVPBB->getSingleHierarchicalSuccessor()) && /* B */ - !(Replica && getPredecessors().empty())) { /* C */ + PrevVPBB->getSingleHierarchicalSuccessor() && + (SingleHPred->getParent() == GetEnclosingNonReplicateRegion(this) && + !IsNonReplicateR(SingleHPred))) && /* B */ + !(Replica && getPredecessors().empty())) { /* C */ NewBB = createEmptyBasicBlock(State->CFG); State->Builder.SetInsertPoint(NewBB); // Temporarily terminate with unreachable until CFG is rewired. @@ -467,20 +497,6 @@ // Visit the VPBlocks connected to "this", starting from it. for (VPBlockBase *Block : RPOT) { - if (EnableVPlanNativePath) { - // The inner loop vectorization path does not represent loop preheader - // and exit blocks as part of the VPlan. In the VPlan-native path, skip - // vectorizing loop preheader block. In future, we may replace this - // check with the check for loop preheader. - if (Block->getNumPredecessors() == 0) - continue; - - // Skip vectorizing loop exit block. In future, we may replace this - // check with the check for loop exit. - if (Block->getNumSuccessors() == 0) - continue; - } - LLVM_DEBUG(dbgs() << "LV: VPBlock in RPO " << Block->getName() << '\n'); Block->execute(State); } @@ -923,10 +939,16 @@ // Initialize CFG state. State->CFG.PrevVPBB = nullptr; BasicBlock *VectorHeaderBB = State->CFG.VectorPreHeader->getSingleSuccessor(); - State->CFG.PrevBB = VectorHeaderBB; State->CFG.ExitBB = VectorHeaderBB->getSingleSuccessor(); + State->CFG.PrevBB = VectorHeaderBB; State->CurrentVectorLoop = State->LI->getLoopFor(VectorHeaderBB); + if (isa(getEntry())) { + MergeBlockIntoPredecessor(VectorHeaderBB); + State->CFG.PrevBB = State->CFG.VectorPreHeader; + VectorHeaderBB = State->CFG.VectorPreHeader; + } + // Remove the edge between Header and Latch to allow other connections. // Temporarily terminate with unreachable until CFG is rewired. // Note: this asserts the generated code's assumption that diff --git a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.h b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.h --- a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.h +++ b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.h @@ -57,9 +57,9 @@ // are introduced. VPDominatorTree VPDomTree; - /// Build plain CFG for TheLoop. Return a new VPRegionBlock (TopRegion) - /// enclosing the plain CFG. - VPRegionBlock *buildPlainCFG(); + /// Build plain CFG for TheLoop. Return the pre-header VPBasicBlock connected + /// to a new VPRegionBlock (TopRegion) enclosing the plain CFG. + VPBasicBlock *buildPlainCFG(); public: VPlanHCFGBuilder(Loop *Lp, LoopInfo *LI, VPlan &P) diff --git a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp --- a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp @@ -42,9 +42,6 @@ // Vectorization plan that we are working on. VPlan &Plan; - // Output Top Region. - VPRegionBlock *TopRegion = nullptr; - // Builder of the VPlan instruction-level representation. VPBuilder VPIRBuilder; @@ -59,8 +56,12 @@ // Hold phi node's that need to be fixed once the plain CFG has been built. SmallVector PhisToFix; + /// Maps loops in the original IR to their corresponding region. + DenseMap Loop2Region; + // Utility functions. - void setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB); + void setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB, + BasicBlock *LatchBB); void fixPhiNodes(); VPBasicBlock *getOrCreateVPBB(BasicBlock *BB); #ifndef NDEBUG @@ -73,18 +74,26 @@ PlainCFGBuilder(Loop *Lp, LoopInfo *LI, VPlan &P) : TheLoop(Lp), LI(LI), Plan(P) {} - // Build the plain CFG and return its Top Region. - VPRegionBlock *buildPlainCFG(); + /// Build plain CFG for TheLoop. Return the pre-header VPBasicBlock connected + /// to a new VPRegionBlock (TopRegion) enclosing the plain CFG. + VPBasicBlock *buildPlainCFG(); }; } // anonymous namespace // Set predecessors of \p VPBB in the same order as they are in \p BB. \p VPBB -// must have no predecessors. -void PlainCFGBuilder::setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB) { +// must have no predecessors. Skip \p HeaderBB if it is a predecessor. The +// backedge of the loop is modeled implicitly through the containing region +// block. +void PlainCFGBuilder::setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB, + BasicBlock *HeaderBB) { SmallVector VPBBPreds; // Collect VPBB predecessors. - for (BasicBlock *Pred : predecessors(BB)) - VPBBPreds.push_back(getOrCreateVPBB(Pred)); + for (BasicBlock *Pred : predecessors(BB)) { + if (Pred == HeaderBB) + continue; + auto *PredVPBB = getOrCreateVPBB(Pred); + VPBBPreds.push_back(PredVPBB); + } VPBB->setPredecessors(VPBBPreds); } @@ -114,11 +123,22 @@ // Retrieve existing VPBB. return BlockIt->second; + // Get or create a region for the loop containing BB. + Loop *CurrentLoop = LI->getLoopFor(BB); + VPRegionBlock *ParentR = nullptr; + if (CurrentLoop) { + auto Iter = Loop2Region.insert({CurrentLoop, nullptr}); + if (Iter.second) + Iter.first->second = new VPRegionBlock( + CurrentLoop->getHeader()->getName().str(), false /*isReplicator*/); + ParentR = Iter.first->second; + } + // Create new VPBB. LLVM_DEBUG(dbgs() << "Creating VPBasicBlock for " << BB->getName() << "\n"); VPBasicBlock *VPBB = new VPBasicBlock(BB->getName()); BB2VPBB[BB] = VPBB; - VPBB->setParent(TopRegion); + VPBB->setParent(ParentR); return VPBB; } @@ -238,11 +258,8 @@ } // Main interface to build the plain CFG. -VPRegionBlock *PlainCFGBuilder::buildPlainCFG() { - // 1. Create the Top Region. It will be the parent of all VPBBs. - TopRegion = new VPRegionBlock("TopRegion", false /*isReplicator*/); - - // 2. Scan the body of the loop in a topological order to visit each basic +VPBasicBlock *PlainCFGBuilder::buildPlainCFG() { + // 1. Scan the body of the loop in a topological order to visit each basic // block after having visited its predecessor basic blocks. Create a VPBB for // each BB and link it to its successor and predecessor VPBBs. Note that // predecessors must be set in the same order as they are in the incomming IR. @@ -264,10 +281,10 @@ } // Create empty VPBB for Loop H so that we can link PH->H. VPBlockBase *HeaderVPBB = getOrCreateVPBB(TheLoop->getHeader()); - // Preheader's predecessors will be set during the loop RPO traversal below. - PreheaderVPBB->setOneSuccessor(HeaderVPBB); HeaderVPBB->setName("vector.body"); + PreheaderVPBB->setOneSuccessor(HeaderVPBB); + LoopBlocksRPO RPO(TheLoop); RPO.perform(LI); @@ -302,15 +319,15 @@ // representing the condition bit in VPlan (which may be in another VPBB). assert(IRDef2VPValue.count(BrCond) && "Missing condition bit in IRDef2VPValue!"); - VPValue *VPCondBit = IRDef2VPValue[BrCond]; + VPValue *VPCondBit = IRDef2VPValue[BrCond]; // Link successors using condition bit. VPBB->setTwoSuccessors(SuccVPBB0, SuccVPBB1, VPCondBit); } else llvm_unreachable("Number of successors not supported."); // Set VPBB predecessors in the same order as they are in the incoming BB. - setVPBBPredsFromBB(VPBB, BB); + setVPBBPredsFromBB(VPBB, BB, nullptr); } // 3. Process outermost loop exit. We created an empty VPBB for the loop @@ -319,24 +336,45 @@ BasicBlock *LoopExitBB = TheLoop->getUniqueExitBlock(); assert(LoopExitBB && "Loops with multiple exits are not supported."); VPBasicBlock *LoopExitVPBB = BB2VPBB[LoopExitBB]; - createVPInstructionsForVPBB(LoopExitVPBB, LoopExitBB); - // Loop exit was already set as successor of the loop exiting BB. - // We only set its predecessor VPBB now. - setVPBBPredsFromBB(LoopExitVPBB, LoopExitBB); - - // 4. The whole CFG has been built at this point so all the input Values must + // Loop exit was already set as successor of the loop exiting BB. + // We only set its predecessor VPBB now. + setVPBBPredsFromBB(LoopExitVPBB, LoopExitBB, nullptr); + + // 4. Fix up region blocks for loops. For each loop, + // * use the header block as entry to the corresponding region, + // * use the latch block as exit of the corresponding region, + // * set the region as successor of the loop pre-header, and + // * set the exit block as successor to the region. + std::vector SubLoops = TheLoop->getSubLoops(); + SubLoops.push_back(TheLoop); + for (auto *L : SubLoops) { + auto *Header = L->getHeader(); + auto *Latch = L->getLoopLatch(); + auto *Region = Loop2Region[L]; + auto *HeaderVPBB = getOrCreateVPBB(Header); + auto *LatchVPBB = getOrCreateVPBB(Latch); + + auto *HeaderPred = getOrCreateVPBB(L->getLoopPreheader()); + VPBlockUtils::disconnectBlocks(HeaderPred, HeaderVPBB); + VPBlockUtils::disconnectBlocks(LatchVPBB, HeaderVPBB); + Region->setParent(HeaderPred->getParent()); + Region->setEntry(HeaderVPBB); + VPBlockUtils::connectBlocks(HeaderPred, Region); + + auto *LatchSucc = getOrCreateVPBB(L->getExitBlock()); + VPBlockUtils::disconnectBlocks(LatchVPBB, LatchSucc); + Region->setExit(LatchVPBB); + VPBlockUtils::connectBlocks(Region, LatchSucc); + } + // 5. The whole CFG has been built at this point so all the input Values must // have a VPlan couterpart. Fix VPlan phi nodes by adding their corresponding // VPlan operands. fixPhiNodes(); - // 5. Final Top Region setup. Set outermost loop pre-header and single exit as - // Top Region entry and exit. - TopRegion->setEntry(PreheaderVPBB); - TopRegion->setExit(LoopExitVPBB); - return TopRegion; + return PreheaderVPBB; } -VPRegionBlock *VPlanHCFGBuilder::buildPlainCFG() { +VPBasicBlock *VPlanHCFGBuilder::buildPlainCFG() { PlainCFGBuilder PCFGBuilder(TheLoop, LI, Plan); return PCFGBuilder.buildPlainCFG(); } @@ -344,20 +382,15 @@ // Public interface to build a H-CFG. void VPlanHCFGBuilder::buildHierarchicalCFG() { // Build Top Region enclosing the plain CFG and set it as VPlan entry. - VPRegionBlock *TopRegion = buildPlainCFG(); - Plan.setEntry(TopRegion); + VPBasicBlock *EntryVPBB = buildPlainCFG(); + Plan.setEntry(EntryVPBB); LLVM_DEBUG(Plan.setName("HCFGBuilder: Plain CFG\n"); dbgs() << Plan); + auto *TopRegion = cast(EntryVPBB->getSingleSuccessor()); Verifier.verifyHierarchicalCFG(TopRegion); // Compute plain CFG dom tree for VPLInfo. VPDomTree.recalculate(*TopRegion); LLVM_DEBUG(dbgs() << "Dominator Tree after building the plain CFG.\n"; VPDomTree.print(dbgs())); - - // Compute VPLInfo and keep it in Plan. - VPLoopInfo &VPLInfo = Plan.getVPLoopInfo(); - VPLInfo.analyze(VPDomTree); - LLVM_DEBUG(dbgs() << "VPLoop Info After buildPlainCFG:\n"; - VPLInfo.print(dbgs())); } diff --git a/llvm/lib/Transforms/Vectorize/VPlanLoopInfo.h b/llvm/lib/Transforms/Vectorize/VPlanLoopInfo.h deleted file mode 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanLoopInfo.h +++ /dev/null @@ -1,44 +0,0 @@ -//===-- VPLoopInfo.h --------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file defines VPLoopInfo analysis and VPLoop class. VPLoopInfo is a -/// specialization of LoopInfoBase for VPBlockBase. VPLoops is a specialization -/// of LoopBase that is used to hold loop metadata from VPLoopInfo. Further -/// information can be found in VectorizationPlanner.rst. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLOOPINFO_H -#define LLVM_TRANSFORMS_VECTORIZE_VPLOOPINFO_H - -#include "llvm/Analysis/LoopInfoImpl.h" - -namespace llvm { -class VPBlockBase; - -/// Hold analysis information for every loop detected by VPLoopInfo. It is an -/// instantiation of LoopBase. -class VPLoop : public LoopBase { -private: - friend class LoopInfoBase; - explicit VPLoop(VPBlockBase *VPB) : LoopBase(VPB) {} -}; - -/// VPLoopInfo provides analysis of natural loop for VPBlockBase-based -/// Hierarchical CFG. It is a specialization of LoopInfoBase class. -// TODO: VPLoopInfo is initially computed on top of the VPlan plain CFG, which -// is the same as the incoming IR CFG. If it's more efficient than running the -// whole loop detection algorithm, we may want to create a mechanism to -// translate LoopInfo into VPLoopInfo. However, that would require significant -// changes in LoopInfoBase class. -typedef LoopInfoBase VPLoopInfo; - -} // namespace llvm - -#endif // LLVM_TRANSFORMS_VECTORIZE_VPLOOPINFO_H diff --git a/llvm/lib/Transforms/Vectorize/VPlanPredicator.h b/llvm/lib/Transforms/Vectorize/VPlanPredicator.h --- a/llvm/lib/Transforms/Vectorize/VPlanPredicator.h +++ b/llvm/lib/Transforms/Vectorize/VPlanPredicator.h @@ -17,7 +17,6 @@ #include "LoopVectorizationPlanner.h" #include "VPlanDominatorTree.h" -#include "VPlanLoopInfo.h" #include namespace llvm { @@ -37,9 +36,6 @@ // VPlan being predicated. VPlan &Plan; - // VPLoopInfo for Plan's HCFG. - VPLoopInfo *VPLI; - // Dominator tree for Plan's HCFG. VPDominatorTree VPDomTree; diff --git a/llvm/lib/Transforms/Vectorize/VPlanPredicator.cpp b/llvm/lib/Transforms/Vectorize/VPlanPredicator.cpp --- a/llvm/lib/Transforms/Vectorize/VPlanPredicator.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanPredicator.cpp @@ -150,13 +150,8 @@ // Collect the outcome of this calculation for all predecessors // into IncomingPredicates. for (VPBlockBase *PredBlock : CurrBlock->getPredecessors()) { - // Skip back-edges - if (VPBlockUtils::isBackEdge(PredBlock, CurrBlock, VPLI)) - continue; - VPValue *IncomingPredicate = nullptr; - unsigned NumPredSuccsNoBE = - VPBlockUtils::countSuccessorsNoBE(PredBlock, VPLI); + unsigned NumPredSuccsNoBE = PredBlock->getNumSuccessors(); // If there is an unconditional branch to the currBB, then we don't create // edge predicates. We use the predecessor's block predicate instead. @@ -211,11 +206,8 @@ assert(!isa(CurrBlock) && "Nested region not expected"); // Linearize control flow by adding an unconditional edge between PrevBlock - // and CurrBlock skipping loop headers and latches to keep intact loop - // header predecessors and loop latch successors. - if (PrevBlock && !VPLI->isLoopHeader(CurrBlock) && - !VPBlockUtils::blockIsLoopLatch(PrevBlock, VPLI)) { - + // and CurrBlock. + if (PrevBlock) { LLVM_DEBUG(dbgs() << "Linearizing: " << PrevBlock->getName() << "->" << CurrBlock->getName() << "\n"); @@ -231,16 +223,15 @@ // Entry point. The driver function for the predicator. void VPlanPredicator::predicate() { // Predicate the blocks within Region. - predicateRegionRec(cast(Plan.getEntry())); + predicateRegionRec(Plan.getVectorLoopRegion()); // Linearlize the blocks with Region. - linearizeRegionRec(cast(Plan.getEntry())); + linearizeRegionRec(Plan.getVectorLoopRegion()); } -VPlanPredicator::VPlanPredicator(VPlan &Plan) - : Plan(Plan), VPLI(&(Plan.getVPLoopInfo())) { +VPlanPredicator::VPlanPredicator(VPlan &Plan) : Plan(Plan) { // FIXME: Predicator is currently computing the dominator information for the // top region. Once we start storing dominator information in a VPRegionBlock, // we can avoid this recalculation. - VPDomTree.recalculate(*(cast(Plan.getEntry()))); + VPDomTree.recalculate(*(Plan.getVectorLoopRegion())); } diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -24,15 +24,9 @@ GetIntOrFpInductionDescriptor, SmallPtrSetImpl &DeadInstructions, ScalarEvolution &SE) { - auto *TopRegion = cast(Plan->getEntry()); - ReversePostOrderTraversal RPOT(TopRegion->getEntry()); - - for (VPBlockBase *Base : RPOT) { - // Do not widen instructions in pre-header and exit blocks. - if (Base->getNumPredecessors() == 0 || Base->getNumSuccessors() == 0) - continue; - - VPBasicBlock *VPBB = Base->getEntryBasicBlock(); + ReversePostOrderTraversal> + RPOT(VPBlockRecursiveTraversalWrapper(Plan->getEntry())); + for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly(RPOT)) { // Introduce each ingredient into VPlan. for (VPRecipeBase &Ingredient : llvm::make_early_inc_range(*VPBB)) { VPValue *VPV = Ingredient.getVPSingleValue(); diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp --- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp @@ -50,7 +50,7 @@ assert(VPB->getParent() == Region && "VPBlockBase has wrong parent"); // Check block's condition bit. - if (VPB->getNumSuccessors() > 1) + if (VPB->getNumSuccessors() > 1 || Region->getExitBasicBlock() == VPB) assert(VPB->getCondBit() && "Missing condition bit!"); else assert(!VPB->getCondBit() && "Unexpected condition bit!"); diff --git a/llvm/unittests/Transforms/Vectorize/CMakeLists.txt b/llvm/unittests/Transforms/Vectorize/CMakeLists.txt --- a/llvm/unittests/Transforms/Vectorize/CMakeLists.txt +++ b/llvm/unittests/Transforms/Vectorize/CMakeLists.txt @@ -7,7 +7,6 @@ add_llvm_unittest(VectorizeTests VPlanDominatorTreeTest.cpp - VPlanLoopInfoTest.cpp VPlanPredicatorTest.cpp VPlanTest.cpp VPlanHCFGTest.cpp diff --git a/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp --- a/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanDominatorTreeTest.cpp @@ -42,12 +42,11 @@ auto Plan = buildPlainCFG(LoopHeader); // Build VPlan domination tree analysis. - VPRegionBlock *TopRegion = cast(Plan->getEntry()); + VPRegionBlock *TopRegion = Plan->getVectorLoopRegion(); VPDominatorTree VPDT; VPDT.recalculate(*TopRegion); - VPBlockBase *PH = TopRegion->getEntry(); - VPBlockBase *H = PH->getSingleSuccessor(); + VPBlockBase *H = TopRegion->getEntry()->getEntryBasicBlock(); VPBlockBase *IfThen = H->getSuccessors()[0]; VPBlockBase *IfElse = H->getSuccessors()[1]; VPBlockBase *Latch = IfThen->getSingleSuccessor(); @@ -55,7 +54,6 @@ ? Latch->getSuccessors()[0] : Latch->getSuccessors()[1]; // Reachability. - EXPECT_TRUE(VPDT.isReachableFromEntry(PH)); EXPECT_TRUE(VPDT.isReachableFromEntry(H)); EXPECT_TRUE(VPDT.isReachableFromEntry(IfThen)); EXPECT_TRUE(VPDT.isReachableFromEntry(IfElse)); @@ -63,42 +61,30 @@ EXPECT_TRUE(VPDT.isReachableFromEntry(Exit)); // VPBB dominance. - EXPECT_TRUE(VPDT.dominates(PH, PH)); - EXPECT_TRUE(VPDT.dominates(PH, H)); - EXPECT_TRUE(VPDT.dominates(PH, IfThen)); - EXPECT_TRUE(VPDT.dominates(PH, IfElse)); - EXPECT_TRUE(VPDT.dominates(PH, Latch)); - EXPECT_TRUE(VPDT.dominates(PH, Exit)); - - EXPECT_FALSE(VPDT.dominates(H, PH)); EXPECT_TRUE(VPDT.dominates(H, H)); EXPECT_TRUE(VPDT.dominates(H, IfThen)); EXPECT_TRUE(VPDT.dominates(H, IfElse)); EXPECT_TRUE(VPDT.dominates(H, Latch)); EXPECT_TRUE(VPDT.dominates(H, Exit)); - EXPECT_FALSE(VPDT.dominates(IfThen, PH)); EXPECT_FALSE(VPDT.dominates(IfThen, H)); EXPECT_TRUE(VPDT.dominates(IfThen, IfThen)); EXPECT_FALSE(VPDT.dominates(IfThen, IfElse)); EXPECT_FALSE(VPDT.dominates(IfThen, Latch)); EXPECT_FALSE(VPDT.dominates(IfThen, Exit)); - EXPECT_FALSE(VPDT.dominates(IfElse, PH)); EXPECT_FALSE(VPDT.dominates(IfElse, H)); EXPECT_FALSE(VPDT.dominates(IfElse, IfThen)); EXPECT_TRUE(VPDT.dominates(IfElse, IfElse)); EXPECT_FALSE(VPDT.dominates(IfElse, Latch)); EXPECT_FALSE(VPDT.dominates(IfElse, Exit)); - EXPECT_FALSE(VPDT.dominates(Latch, PH)); EXPECT_FALSE(VPDT.dominates(Latch, H)); EXPECT_FALSE(VPDT.dominates(Latch, IfThen)); EXPECT_FALSE(VPDT.dominates(Latch, IfElse)); EXPECT_TRUE(VPDT.dominates(Latch, Latch)); EXPECT_TRUE(VPDT.dominates(Latch, Exit)); - EXPECT_FALSE(VPDT.dominates(Exit, PH)); EXPECT_FALSE(VPDT.dominates(Exit, H)); EXPECT_FALSE(VPDT.dominates(Exit, IfThen)); EXPECT_FALSE(VPDT.dominates(Exit, IfElse)); @@ -106,42 +92,30 @@ EXPECT_TRUE(VPDT.dominates(Exit, Exit)); // VPBB proper dominance. - EXPECT_FALSE(VPDT.properlyDominates(PH, PH)); - EXPECT_TRUE(VPDT.properlyDominates(PH, H)); - EXPECT_TRUE(VPDT.properlyDominates(PH, IfThen)); - EXPECT_TRUE(VPDT.properlyDominates(PH, IfElse)); - EXPECT_TRUE(VPDT.properlyDominates(PH, Latch)); - EXPECT_TRUE(VPDT.properlyDominates(PH, Exit)); - - EXPECT_FALSE(VPDT.properlyDominates(H, PH)); EXPECT_FALSE(VPDT.properlyDominates(H, H)); EXPECT_TRUE(VPDT.properlyDominates(H, IfThen)); EXPECT_TRUE(VPDT.properlyDominates(H, IfElse)); EXPECT_TRUE(VPDT.properlyDominates(H, Latch)); EXPECT_TRUE(VPDT.properlyDominates(H, Exit)); - EXPECT_FALSE(VPDT.properlyDominates(IfThen, PH)); EXPECT_FALSE(VPDT.properlyDominates(IfThen, H)); EXPECT_FALSE(VPDT.properlyDominates(IfThen, IfThen)); EXPECT_FALSE(VPDT.properlyDominates(IfThen, IfElse)); EXPECT_FALSE(VPDT.properlyDominates(IfThen, Latch)); EXPECT_FALSE(VPDT.properlyDominates(IfThen, Exit)); - EXPECT_FALSE(VPDT.properlyDominates(IfElse, PH)); EXPECT_FALSE(VPDT.properlyDominates(IfElse, H)); EXPECT_FALSE(VPDT.properlyDominates(IfElse, IfThen)); EXPECT_FALSE(VPDT.properlyDominates(IfElse, IfElse)); EXPECT_FALSE(VPDT.properlyDominates(IfElse, Latch)); EXPECT_FALSE(VPDT.properlyDominates(IfElse, Exit)); - EXPECT_FALSE(VPDT.properlyDominates(Latch, PH)); EXPECT_FALSE(VPDT.properlyDominates(Latch, H)); EXPECT_FALSE(VPDT.properlyDominates(Latch, IfThen)); EXPECT_FALSE(VPDT.properlyDominates(Latch, IfElse)); EXPECT_FALSE(VPDT.properlyDominates(Latch, Latch)); EXPECT_TRUE(VPDT.properlyDominates(Latch, Exit)); - EXPECT_FALSE(VPDT.properlyDominates(Exit, PH)); EXPECT_FALSE(VPDT.properlyDominates(Exit, H)); EXPECT_FALSE(VPDT.properlyDominates(Exit, IfThen)); EXPECT_FALSE(VPDT.properlyDominates(Exit, IfElse)); @@ -149,42 +123,30 @@ EXPECT_FALSE(VPDT.properlyDominates(Exit, Exit)); // VPBB nearest common dominator. - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(PH, PH)); - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(PH, H)); - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(PH, IfThen)); - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(PH, IfElse)); - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(PH, Latch)); - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(PH, Exit)); - - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(H, PH)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(H, H)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(H, IfThen)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(H, IfElse)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(H, Latch)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(H, Exit)); - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(IfThen, PH)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(IfThen, H)); EXPECT_EQ(IfThen, VPDT.findNearestCommonDominator(IfThen, IfThen)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(IfThen, IfElse)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(IfThen, Latch)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(IfThen, Exit)); - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(IfElse, PH)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(IfElse, H)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(IfElse, IfThen)); EXPECT_EQ(IfElse, VPDT.findNearestCommonDominator(IfElse, IfElse)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(IfElse, Latch)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(IfElse, Exit)); - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(Latch, PH)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(Latch, H)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(Latch, IfThen)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(Latch, IfElse)); EXPECT_EQ(Latch, VPDT.findNearestCommonDominator(Latch, Latch)); EXPECT_EQ(Latch, VPDT.findNearestCommonDominator(Latch, Exit)); - EXPECT_EQ(PH, VPDT.findNearestCommonDominator(Exit, PH)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(Exit, H)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(Exit, IfThen)); EXPECT_EQ(H, VPDT.findNearestCommonDominator(Exit, IfElse)); diff --git a/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp --- a/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp @@ -49,8 +49,10 @@ VPBasicBlock *VecBB = Entry->getSingleSuccessor()->getEntryBasicBlock(); EXPECT_EQ(7u, VecBB->size()); - EXPECT_EQ(2u, VecBB->getNumPredecessors()); - EXPECT_EQ(2u, VecBB->getNumSuccessors()); + EXPECT_EQ(0u, VecBB->getNumPredecessors()); + EXPECT_EQ(0u, VecBB->getNumSuccessors()); + EXPECT_EQ(VecBB->getParent()->getEntryBasicBlock(), VecBB); + EXPECT_EQ(VecBB->getParent()->getExitBasicBlock(), VecBB); EXPECT_EQ(&*Plan, VecBB->getPlan()); auto Iter = VecBB->begin(); @@ -101,16 +103,16 @@ node [shape=rect, fontname=Courier, fontsize=30] edge [fontname=Courier, fontsize=30] compound=true - subgraph cluster_N0 { + N0 [label = + "entry:\l" + + "Successor(s): for.body\l" + ] + N0 -> N1 [ label="" lhead=cluster_N2] + subgraph cluster_N2 { fontname=Courier - label="\ TopRegion" + label="\ for.body" N1 [label = - "entry:\l" + - "Successor(s): for.body\l" - ] - N1 -> N2 [ label=""] - N2 [label = - "for.body:\l" + + "vector.body:\l" + " WIDEN-PHI ir\<%indvars.iv\> = phi ir\<0\>, ir\<%indvars.iv.next\>\l" + " EMIT ir\<%arr.idx\> = getelementptr ir\<%A\> ir\<%indvars.iv\>\l" + " EMIT ir\<%l1\> = load ir\<%arr.idx\>\l" + @@ -118,17 +120,15 @@ " EMIT store ir\<%res\> ir\<%arr.idx\>\l" + " EMIT ir\<%indvars.iv.next\> = add ir\<%indvars.iv\> ir\<1\>\l" + " EMIT ir\<%exitcond\> = icmp ir\<%indvars.iv.next\> ir\<%N\>\l" + - "Successor(s): for.body, for.end\l" + - "CondBit: ir\<%exitcond\> (for.body)\l" - ] - N2 -> N2 [ label="T"] - N2 -> N3 [ label="F"] - N3 [label = - "for.end:\l" + - " EMIT ret\l" + - "No successors\l" + "No successors\l" + + "CondBit: ir\<%exitcond\> (vector.body)\l" ] } + N1 -> N3 [ label="" ltail=cluster_N2] + N3 [label = + "for.end:\l" + + "No successors\l" + ] } )"; EXPECT_EQ(ExpectedStr, FullDump); @@ -176,8 +176,10 @@ VPBasicBlock *VecBB = Entry->getSingleSuccessor()->getEntryBasicBlock(); EXPECT_EQ(7u, VecBB->size()); - EXPECT_EQ(2u, VecBB->getNumPredecessors()); - EXPECT_EQ(2u, VecBB->getNumSuccessors()); + EXPECT_EQ(0u, VecBB->getNumPredecessors()); + EXPECT_EQ(0u, VecBB->getNumSuccessors()); + EXPECT_EQ(VecBB->getParent()->getEntryBasicBlock(), VecBB); + EXPECT_EQ(VecBB->getParent()->getExitBasicBlock(), VecBB); auto Iter = VecBB->begin(); EXPECT_NE(nullptr, dyn_cast(&*Iter++)); diff --git a/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp deleted file mode 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp +++ /dev/null @@ -1,86 +0,0 @@ -//===- llvm/unittests/Transforms/Vectorize/VPlanLoopInfoTest.cpp -----===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "../lib/Transforms/Vectorize/VPlanLoopInfo.h" -#include "VPlanTestBase.h" -#include "gtest/gtest.h" - -namespace llvm { -namespace { - -class VPlanLoopInfo : public VPlanTestBase {}; - -TEST_F(VPlanLoopInfo, BasicLoopInfoTest) { - const char *ModuleString = - "define void @f(i32* %a, i32* %b, i32* %c, i32 %N, i32 %M, i32 %K) {\n" - "entry:\n" - " br label %for.body\n" - "for.body:\n" - " %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]\n" - " br i1 true, label %if.then, label %if.else\n" - "if.then:\n" - " br label %for.inc\n" - "if.else:\n" - " br label %for.inc\n" - "for.inc:\n" - " %iv.next = add nuw nsw i64 %iv, 1\n" - " %exitcond = icmp eq i64 %iv.next, 300\n" - " br i1 %exitcond, label %for.end, label %for.body\n" - "for.end:\n" - " ret void\n" - "}\n"; - - Module &M = parseModule(ModuleString); - - Function *F = M.getFunction("f"); - BasicBlock *LoopHeader = F->getEntryBlock().getSingleSuccessor(); - auto Plan = buildHCFG(LoopHeader); - - // Build VPlan domination tree and loop info analyses. - VPRegionBlock *TopRegion = cast(Plan->getEntry()); - VPDominatorTree VPDT; - VPDT.recalculate(*TopRegion); - VPLoopInfo VPLI; - VPLI.analyze(VPDT); - - VPBlockBase *PH = TopRegion->getEntry(); - VPBlockBase *H = PH->getSingleSuccessor(); - VPBlockBase *IfThen = H->getSuccessors()[0]; - VPBlockBase *IfElse = H->getSuccessors()[1]; - VPBlockBase *Latch = IfThen->getSingleSuccessor(); - VPBlockBase *Exit = Latch->getSuccessors()[0] != H - ? Latch->getSuccessors()[0] - : Latch->getSuccessors()[1]; - - // Number of loops. - EXPECT_EQ(1, std::distance(VPLI.begin(), VPLI.end())); - VPLoop *VPLp = *VPLI.begin(); - - // VPBBs contained in VPLoop. - EXPECT_FALSE(VPLp->contains(PH)); - EXPECT_EQ(nullptr, VPLI.getLoopFor(PH)); - EXPECT_TRUE(VPLp->contains(H)); - EXPECT_EQ(VPLp, VPLI.getLoopFor(H)); - EXPECT_TRUE(VPLp->contains(IfThen)); - EXPECT_EQ(VPLp, VPLI.getLoopFor(IfThen)); - EXPECT_TRUE(VPLp->contains(IfElse)); - EXPECT_EQ(VPLp, VPLI.getLoopFor(IfElse)); - EXPECT_TRUE(VPLp->contains(Latch)); - EXPECT_EQ(VPLp, VPLI.getLoopFor(Latch)); - EXPECT_FALSE(VPLp->contains(Exit)); - EXPECT_EQ(nullptr, VPLI.getLoopFor(Exit)); - - // VPLoop's parts. - EXPECT_EQ(PH, VPLp->getLoopPreheader()); - EXPECT_EQ(H, VPLp->getHeader()); - EXPECT_EQ(Latch, VPLp->getLoopLatch()); - EXPECT_EQ(Latch, VPLp->getExitingBlock()); - EXPECT_EQ(Exit, VPLp->getExitBlock()); -} -} // namespace -} // namespace llvm diff --git a/llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp --- a/llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanPredicatorTest.cpp @@ -67,9 +67,8 @@ auto Plan = buildHCFG(LoopHeader); VPRegionBlock *TopRegion = Plan->getVectorLoopRegion(); - VPBlockBase *PH = TopRegion->getEntry(); - VPBlockBase *H = PH->getSingleSuccessor(); - VPBlockBase *InnerLoopH = H->getSingleSuccessor(); + VPBlockBase *H = TopRegion->getEntryBasicBlock(); + VPBlockBase *InnerLoopH = H->getSingleSuccessor()->getEntryBasicBlock(); VPBlockBase *OuterIf = InnerLoopH->getSuccessors()[0]; VPBlockBase *InnerLoopLatch = InnerLoopH->getSuccessors()[1]; VPBlockBase *InnerIf = OuterIf->getSuccessors()[0]; @@ -168,8 +167,7 @@ auto Plan = buildHCFG(LoopHeader); VPRegionBlock *TopRegion = Plan->getVectorLoopRegion(); - VPBlockBase *PH = TopRegion->getEntry(); - VPBlockBase *H = PH->getSingleSuccessor(); + VPBlockBase *H = TopRegion->getEntryBasicBlock(); VPBlockBase *OuterIfCmpBlk = H->getSingleSuccessor(); VPBlockBase *InnerIfCmpBlk = OuterIfCmpBlk->getSuccessors()[0]; VPBlockBase *InnerIfTSucc = InnerIfCmpBlk->getSuccessors()[0]; diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp --- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// #include "../lib/Transforms/Vectorize/VPlan.h" +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/PostOrderIterator.h" #include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h b/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h --- a/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h +++ b/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h @@ -76,8 +76,8 @@ auto Plan = std::make_unique(); VPlanHCFGBuilder HCFGBuilder(LI->getLoopFor(LoopHeader), LI.get(), *Plan); - VPRegionBlock *TopRegion = HCFGBuilder.buildPlainCFG(); - Plan->setEntry(TopRegion); + VPBasicBlock *EntryVPBB = HCFGBuilder.buildPlainCFG(); + Plan->setEntry(EntryVPBB); return Plan; } };