-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[VPlan] Introduce all loop regions as VPlan transform. (NFC) #129402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
d5ba9a3
9854453
a88f03e
646a112
29f6ddf
2a500dd
cc81801
2a8344e
67a30f1
3b1618e
2d3f087
c6903d6
decf567
29b7487
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,26 +14,57 @@ | |||||||
| #include "LoopVectorizationPlanner.h" | ||||||||
| #include "VPlan.h" | ||||||||
| #include "VPlanCFG.h" | ||||||||
| #include "VPlanDominatorTree.h" | ||||||||
| #include "VPlanTransforms.h" | ||||||||
| #include "llvm/Analysis/LoopInfo.h" | ||||||||
| #include "llvm/Analysis/ScalarEvolution.h" | ||||||||
|
|
||||||||
| using namespace llvm; | ||||||||
|
|
||||||||
| /// Create and return a new VPRegionBlock for loop starting at \p HeaderVPBB, if | ||||||||
| /// it is a header of a loop. | ||||||||
| static VPRegionBlock *introduceRegion(VPlan &Plan, VPBlockBase *HeaderVPBB, | ||||||||
| VPDominatorTree &VPDT) { | ||||||||
| if (HeaderVPBB->getNumPredecessors() != 2) | ||||||||
| return nullptr; | ||||||||
| VPBlockBase *PreheaderVPBB = HeaderVPBB->getPredecessors()[0]; | ||||||||
| VPBlockBase *LatchVPBB = HeaderVPBB->getPredecessors()[1]; | ||||||||
| if (!VPDT.dominates(HeaderVPBB, LatchVPBB)) | ||||||||
| return nullptr; | ||||||||
| assert(VPDT.dominates(PreheaderVPBB, HeaderVPBB) && | ||||||||
| "preheader must dominate header"); | ||||||||
|
||||||||
| VPBlockUtils::disconnectBlocks(PreheaderVPBB, HeaderVPBB); | ||||||||
| VPBlockUtils::disconnectBlocks(LatchVPBB, HeaderVPBB); | ||||||||
| VPBlockBase *Succ = LatchVPBB->getSingleSuccessor(); | ||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, thanks! |
||||||||
| if (Succ) | ||||||||
| VPBlockUtils::disconnectBlocks(LatchVPBB, Succ); | ||||||||
|
|
||||||||
| auto *R = Plan.createVPRegionBlock(HeaderVPBB, LatchVPBB, "", | ||||||||
| false /*isReplicator*/); | ||||||||
| // All VPBB's reachable shallowly from HeaderVPBB belong to top level loop, | ||||||||
| // because VPlan is expected to end at top level latch. | ||||||||
|
||||||||
| // because VPlan is expected to end at top level latch. | |
| // because VPlan is expected to end at top level latch disconnected above. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about setting the parent of the newly introduced region itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this additional latch block really needed, or can it be removed (independently)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is unsed only for convenience, when adjusting reductions it is used to place selects there if needed. I'll look into remove it separartely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps worth a comment, along with explaining that this section assigns distinct names to the (just created) Top Region and its latch block, which is introduced as a convenience.
Can also reset the name of Top Region's header to "vector.body" here, instead of setting it during plain CFG construction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks!
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduce nested regions also before bailing out above when a scalar epilog check is not required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved up the loop to create all regions via the loop (also the top-most).
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cfg is flat so both shallow and deep traverse all blocks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are nested regions introduced from outermost in? Is the parent of an inner region set to its enclosing region?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are created from outermost to innermost. Updated to also set the parents of the created regions, thanks
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,9 +12,7 @@ | |
| /// components and steps: | ||
| // | ||
| /// 1. PlainCFGBuilder class: builds a plain VPBasicBlock-based CFG that | ||
| /// faithfully represents the CFG in the incoming IR. A VPRegionBlock (Top | ||
| /// Region) is created to enclose and serve as parent of all the VPBasicBlocks | ||
| /// in the plain CFG. | ||
| /// faithfully represents the CFG in the incoming IR. | ||
| /// NOTE: At this point, there is a direct correspondence between all the | ||
| /// VPBasicBlocks created for the initial plain CFG and the incoming | ||
| /// BasicBlocks. However, this might change in the future. | ||
|
|
@@ -57,12 +55,8 @@ class PlainCFGBuilder { | |
| // Hold phi node's that need to be fixed once the plain CFG has been built. | ||
| SmallVector<PHINode *, 8> PhisToFix; | ||
|
|
||
| /// Maps loops in the original IR to their corresponding region. | ||
| DenseMap<Loop *, VPRegionBlock *> Loop2Region; | ||
|
|
||
| // Utility functions. | ||
| void setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB); | ||
| void setRegionPredsFromBB(VPRegionBlock *VPBB, BasicBlock *BB); | ||
| void fixHeaderPhis(); | ||
| VPBasicBlock *getOrCreateVPBB(BasicBlock *BB); | ||
| #ifndef NDEBUG | ||
|
|
@@ -83,25 +77,6 @@ class PlainCFGBuilder { | |
| // 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) { | ||
| auto GetLatchOfExit = [this](BasicBlock *BB) -> BasicBlock * { | ||
| auto *SinglePred = BB->getSinglePredecessor(); | ||
| Loop *LoopForBB = LI->getLoopFor(BB); | ||
| if (!SinglePred || LI->getLoopFor(SinglePred) == LoopForBB) | ||
| return nullptr; | ||
| // The input IR must be in loop-simplify form, ensuring a single predecessor | ||
| // for exit blocks. | ||
| assert(SinglePred == LI->getLoopFor(SinglePred)->getLoopLatch() && | ||
| "SinglePred must be the only loop latch"); | ||
| return SinglePred; | ||
| }; | ||
| if (auto *LatchBB = GetLatchOfExit(BB)) { | ||
| auto *PredRegion = getOrCreateVPBB(LatchBB)->getParent(); | ||
| assert(VPBB == cast<VPBasicBlock>(PredRegion->getSingleSuccessor()) && | ||
| "successor must already be set for PredRegion; it must have VPBB " | ||
| "as single successor"); | ||
| VPBB->setPredecessors({PredRegion}); | ||
| return; | ||
| } | ||
| // Collect VPBB predecessors. | ||
| SmallVector<VPBlockBase *, 2> VPBBPreds; | ||
| for (BasicBlock *Pred : predecessors(BB)) | ||
|
|
@@ -113,13 +88,6 @@ static bool isHeaderBB(BasicBlock *BB, Loop *L) { | |
| return L && BB == L->getHeader(); | ||
| } | ||
|
|
||
| void PlainCFGBuilder::setRegionPredsFromBB(VPRegionBlock *Region, | ||
| BasicBlock *BB) { | ||
| // BB is a loop header block. Connect the region to the loop preheader. | ||
| Loop *LoopOfBB = LI->getLoopFor(BB); | ||
| Region->setPredecessors({getOrCreateVPBB(LoopOfBB->getLoopPredecessor())}); | ||
| } | ||
|
|
||
| // Add operands to VPInstructions representing phi nodes from the input IR. | ||
| void PlainCFGBuilder::fixHeaderPhis() { | ||
| for (auto *Phi : PhisToFix) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Header phi's expect preheader as first predecessor and latch as second, corresponding to operands added below, so make sure here the predecessors are ordered accordingly, i.e., swap if needed? Later when loop regions are introduced, can rely on this order.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I updated the patch to use the original order here and swap if needed when region is introduced.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But here it's easy to set (both) things right?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previosuly it wasnt consistent, but with the current patch it is; both use the order from the CFG in the current version and are a 1-1 translation of the CFG. In the current patch, the canonicalization of header phi operand and header predecessor order is done completely separate from CFG construction, when the region is introduced. In general, I think we should move away from directly relying on the operands to retrieve incoming values and move towards an interface
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ah, ok, I see. Sketching how separate canonicalization may look like, for clarify and to help reason about what if anything should be fused: Let VPlanCFG0 denote the initial VPlan, constructed from IR. VPlanCFG0 may indeed be a consistent 1-1 translation of the CFG and IR, arguably with all its branches - including early-exits and latch-to-exit (and perhaps unconditional branches too), possibly also representing the BasicBlock operands of phi's and branches as VPValues wrapping these Values, as operands of the corresponding VPIRInstructions. Let VPlanCFG1 denote the result of canonicalizing VPlanCFG0's phi's and branches according to predecessors/successors order (instead of their BasicBlock operands). It may be better to change the types of recipes used, even when the original predecessor/successor order is retained, to clarify that they belong to distinct VPlan "modes" or "stages". Early-exit branch recipes and successors can be eliminated now. Let VPlanHCFG0 denote the (first) HCFG VPlan produced by a VPlan transform devoted to canonical-CFG --> HCFG conversion that introduces child (or actually all loop) regions into VPlanCFG1. Would this transform need to update/change any recipes?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yep, I have some follow-up patches to retain the exit branches and keep the exit blocks connected. In a sense, the specific operand order (1st op = preheader, 2nd op = latch) for header phis is purely a consequence of introducing a region, which itself only has a single predecessor I think. So introducing the canonical order at this point seems like a good fit; the header phis are the only ones which need their order adjusted. Using a separate recipe for the initial recipes sounds good, something like VPInstruction which always has an underlying instruction would be good, but already models the operands/defs in VPlan via operands. Unfortunately VPIRInstruction is already taken. We would need a version that defines result VPValues and uses VPvalue as operands. |
||
|
|
@@ -150,19 +118,6 @@ static bool isHeaderVPBB(VPBasicBlock *VPBB) { | |
| return VPBB->getParent() && VPBB->getParent()->getEntry() == VPBB; | ||
| } | ||
|
|
||
| /// Return true of \p L loop is contained within \p OuterLoop. | ||
| static bool doesContainLoop(const Loop *L, const Loop *OuterLoop) { | ||
| if (L->getLoopDepth() < OuterLoop->getLoopDepth()) | ||
| return false; | ||
| const Loop *P = L; | ||
| while (P) { | ||
| if (P == OuterLoop) | ||
| return true; | ||
| P = P->getParentLoop(); | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| // Create a new empty VPBasicBlock for an incoming BasicBlock in the region | ||
| // corresponding to the containing loop or retrieve an existing one if it was | ||
|
||
| // already created. If no region exists yet for the loop containing \p BB, a new | ||
|
|
@@ -178,28 +133,6 @@ VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) { | |
| LLVM_DEBUG(dbgs() << "Creating VPBasicBlock for " << Name << "\n"); | ||
| VPBasicBlock *VPBB = Plan.createVPBasicBlock(Name); | ||
| BB2VPBB[BB] = VPBB; | ||
|
|
||
| // Get or create a region for the loop containing BB, except for the top | ||
| // region of TheLoop which is created later. | ||
| Loop *LoopOfBB = LI->getLoopFor(BB); | ||
| if (!LoopOfBB || LoopOfBB == TheLoop || !doesContainLoop(LoopOfBB, TheLoop)) | ||
| return VPBB; | ||
|
|
||
| auto *RegionOfVPBB = Loop2Region.lookup(LoopOfBB); | ||
| if (!isHeaderBB(BB, LoopOfBB)) { | ||
| assert(RegionOfVPBB && | ||
| "Region should have been created by visiting header earlier"); | ||
| VPBB->setParent(RegionOfVPBB); | ||
| return VPBB; | ||
| } | ||
|
|
||
| assert(!RegionOfVPBB && | ||
| "First visit of a header basic block expects to register its region."); | ||
| // Handle a header - take care of its Region. | ||
| RegionOfVPBB = Plan.createVPRegionBlock(Name.str(), false /*isReplicator*/); | ||
| RegionOfVPBB->setParent(Loop2Region[LoopOfBB->getParentLoop()]); | ||
| RegionOfVPBB->setEntry(VPBB); | ||
| Loop2Region[LoopOfBB] = RegionOfVPBB; | ||
| return VPBB; | ||
| } | ||
|
|
||
|
|
@@ -351,6 +284,8 @@ void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB, | |
| // Main interface to build the plain CFG. | ||
| void PlainCFGBuilder::buildPlainCFG( | ||
| DenseMap<VPBlockBase *, BasicBlock *> &VPB2IRBB) { | ||
| VPIRBasicBlock *Entry = cast<VPIRBasicBlock>(Plan.getEntry()); | ||
| BB2VPBB[Entry->getIRBasicBlock()] = Entry; | ||
|
|
||
| // 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 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo below: incomming
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will adjust separately. |
||
|
|
@@ -376,23 +311,21 @@ void PlainCFGBuilder::buildPlainCFG( | |
| for (BasicBlock *BB : RPO) { | ||
| // Create or retrieve the VPBasicBlock for this BB. | ||
| VPBasicBlock *VPBB = getOrCreateVPBB(BB); | ||
| VPRegionBlock *Region = VPBB->getParent(); | ||
| Loop *LoopForBB = LI->getLoopFor(BB); | ||
| // Set VPBB predecessors in the same order as they are in the incoming BB. | ||
| if (!isHeaderBB(BB, LoopForBB)) { | ||
| setVPBBPredsFromBB(VPBB, BB); | ||
|
||
| } else if (Region) { | ||
| // BB is a loop header and there's a corresponding region, set the | ||
| // predecessor for it. | ||
| setRegionPredsFromBB(Region, BB); | ||
| } else { | ||
| VPBB->setPredecessors({getOrCreateVPBB(LoopForBB->getLoopPredecessor()), | ||
| getOrCreateVPBB(LoopForBB->getLoopLatch())}); | ||
| } | ||
|
|
||
| // Create VPInstructions for BB. | ||
| createVPInstructionsForVPBB(VPBB, BB); | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can VPBB's successors be set according to BB's successors, in all cases, similar to predecessors. Or according to case order for switches, and true/false for conditional branches, but independent of loop latch or not?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, we could , with extra logic when introducing regions to figure out what successor is the exit block and which one the header. Should be doable, but might be better separately?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Assumptions about successors and successor order should be consistent with terminating recipes that target them, including the removal of early-exit branches/successors. Perhaps similar to [header]phisToFix/fixHeaderPhis() that should arguably post-process predecessors to align with phi recipes as they are fixed, after first mirroring the IR predecessors as-is, a post-processing of VPIRInstructions that first wrap IR terminals should take care of both converting them into BranchOnCond/Switch VP[nonIR]Instructions along with possible swapping of successors, plus removal of early-exit branches? Can be done separately if preferred.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated the patch to make the phi operand order consistent with predecessors. At the moment,connections to exit blocks are dropped, but they should be retained as follow up (initial patch here 317d975 )
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, this may clarify some confusion raised elsewhere. |
||
| if (BB == TheLoop->getLoopLatch()) { | ||
| VPBasicBlock *HeaderVPBB = getOrCreateVPBB(LoopForBB->getHeader()); | ||
| VPBlockUtils::connectBlocks(VPBB, HeaderVPBB); | ||
| VPBB->setOneSuccessor(HeaderVPBB); | ||
| continue; | ||
| } | ||
|
|
||
|
|
@@ -423,21 +356,11 @@ void PlainCFGBuilder::buildPlainCFG( | |
| BasicBlock *IRSucc1 = BI->getSuccessor(1); | ||
| VPBasicBlock *Successor0 = getOrCreateVPBB(IRSucc0); | ||
| VPBasicBlock *Successor1 = getOrCreateVPBB(IRSucc1); | ||
| if (BB == LoopForBB->getLoopLatch()) { | ||
| // For a latch we need to set the successor of the region rather than that | ||
| // of VPBB and it should be set to the exit, i.e., non-header successor, | ||
| // except for the top region, which is handled elsewhere. | ||
| assert(LoopForBB != TheLoop && | ||
| "Latch of the top region should have been handled earlier"); | ||
| Region->setOneSuccessor(isHeaderVPBB(Successor0) ? Successor1 | ||
| : Successor0); | ||
| Region->setExiting(VPBB); | ||
| continue; | ||
| } | ||
|
|
||
| // Don't connect any blocks outside the current loop except the latch for | ||
| // now. The latch is handled above. | ||
| if (LoopForBB) { | ||
| // Don't connect any blocks outside the current loop except the latch, which | ||
| // is handled below. | ||
|
||
| if (LoopForBB && | ||
| (LoopForBB == TheLoop || BB != LoopForBB->getLoopLatch())) { | ||
|
||
| if (!LoopForBB->contains(IRSucc0)) { | ||
| VPBB->setOneSuccessor(Successor1); | ||
| continue; | ||
|
|
@@ -456,21 +379,16 @@ void PlainCFGBuilder::buildPlainCFG( | |
| // corresponding VPlan operands. | ||
| fixHeaderPhis(); | ||
|
|
||
| VPBlockUtils::connectBlocks(Plan.getEntry(), | ||
| getOrCreateVPBB(TheLoop->getHeader())); | ||
| Plan.getEntry()->setOneSuccessor(getOrCreateVPBB(TheLoop->getHeader())); | ||
| Plan.getEntry()->setPlan(&Plan); | ||
|
|
||
| for (const auto &[IRBB, VPB] : BB2VPBB) | ||
| VPB2IRBB[VPB] = IRBB; | ||
|
|
||
| LLVM_DEBUG(Plan.setName("Plain CFG\n"); dbgs() << Plan); | ||
| } | ||
|
|
||
| void VPlanHCFGBuilder::buildPlainCFG() { | ||
| PlainCFGBuilder PCFGBuilder(TheLoop, LI, Plan); | ||
| PCFGBuilder.buildPlainCFG(VPB2IRBB); | ||
|
Comment on lines
365
to
367
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems even more redundant now to have both VPlanHCFGBuilder and PCFGBuilder, both with their buildPlainCFG().
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, I left it as-is to avoid unneccessary changes. Will move the code to VPlanConstruction.cpp as follow-up, removing VPlanHCFGBuilder.{h,cpp}. |
||
| } | ||
|
|
||
| // Public interface to build a H-CFG. | ||
| void VPlanHCFGBuilder::buildHierarchicalCFG() { | ||
| // Build Top Region enclosing the plain CFG. | ||
| buildPlainCFG(); | ||
| LLVM_DEBUG(Plan.setName("HCFGBuilder: Plain CFG\n"); dbgs() << Plan); | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -30,7 +30,6 @@ namespace llvm { | |||||
|
|
||||||
| class Loop; | ||||||
| class LoopInfo; | ||||||
| class VPRegionBlock; | ||||||
| class VPlan; | ||||||
| class VPlanTestIRBase; | ||||||
| class VPBlockBase; | ||||||
|
|
@@ -54,15 +53,12 @@ class VPlanHCFGBuilder { | |||||
| /// created for a input IR basic block. | ||||||
| DenseMap<VPBlockBase *, BasicBlock *> VPB2IRBB; | ||||||
|
|
||||||
| /// Build plain CFG for TheLoop and connects it to Plan's entry. | ||||||
| void buildPlainCFG(); | ||||||
|
|
||||||
| public: | ||||||
| VPlanHCFGBuilder(Loop *Lp, LoopInfo *LI, VPlan &P) | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
but better be consistent with VPlanHCFGBuilder.h file name, i.e., do so when moving to VPlanConstruction?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, I left it as-is to avoid unneccessary changes. Will move the code to VPlanConstruction.cpp as follow-up, removing VPlanHCFGBuilder.{h,cpp}. |
||||||
| : TheLoop(Lp), LI(LI), Plan(P) {} | ||||||
|
|
||||||
| /// Build H-CFG for TheLoop and update Plan accordingly. | ||||||
| void buildHierarchicalCFG(); | ||||||
| /// Build plain CFG for TheLoop and connects it to Plan's entry. | ||||||
| void buildPlainCFG(); | ||||||
|
|
||||||
| /// Return the input IR BasicBlock corresponding to \p VPB. Returns nullptr if | ||||||
| /// there is no such corresponding block. | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks!