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 @@ -8660,8 +8660,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 = @@ -8672,7 +8670,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 @@ -36,8 +36,8 @@ #include "llvm/ADT/Twine.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" -#include "llvm/Analysis/VectorUtils.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/FMF.h" #include @@ -2640,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. 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. @@ -468,20 +498,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); } @@ -926,10 +942,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 @@ -320,23 +337,45 @@ 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,10 +383,11 @@ // 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. 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/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,15 +103,15 @@ 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): vector.body\l" - ] - N1 -> N2 [ label=""] - N2 [label = "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" + @@ -118,17 +120,16 @@ " 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): vector.body, for.end\l" + + "No successors\l" + "CondBit: ir\<%exitcond\> (vector.body)\l" ] - N2 -> N2 [ label="T"] - N2 -> N3 [ label="F"] - N3 [label = - "for.end:\l" + - " EMIT ret\l" + - "No successors\l" - ] } + N1 -> N3 [ label="" ltail=cluster_N2] + N3 [label = + "for.end:\l" + + " EMIT ret\l" + + "No successors\l" + ] } )"; EXPECT_EQ(ExpectedStr, FullDump); @@ -176,8 +177,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/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp --- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp @@ -8,10 +8,11 @@ //===----------------------------------------------------------------------===// #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" -#include "llvm/ADT/PostOrderIterator.h" #include "gtest/gtest.h" #include 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; } };