[PATCH] D159136: [VPlan] Simplify HCFG construction of region blocks (NFC).
Florian Hahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 23 13:30:06 PDT 2023
fhahn added inline comments.
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp:85
void PlainCFGBuilder::setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB) {
SmallVector<VPBlockBase *, 8> VPBBPreds;
// Collect VPBB predecessors.
----------------
Ayal wrote:
> Perhaps the following would more clearly update the current code by handling the exit block case separately, than during traversal over all predecessors:
> ```
> 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))
> VPBBPreds.push_back(getOrCreateVPBB(Pred));
> VPBB->setPredecessors(VPBBPreds);
> ```
> where a lambda or function would check isExitBB(), analogous to isHeaderBB(), possibly along with providing the Latch:
>
> ```
> BasicBlock* getLatchOfExit(BasicBlock *BB) {
> auto *SinglePred = BB->getSinglePredecessor();
> if (!SinglePred || LI->getLoopFor(SinglePred) == LI->getLoopFor(BB))
> return nullptr;
> // can assert SinglePred is the latch of its loop.
> return SinglePred;
> }
>
> ```
>
> ?
update, thanks!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp:108
+ // BB is a loop header block. Connect the region to the loop preheader,
+ // identified by checking if the parent doesn't match Region.
+ VPBasicBlock *PreheaderVPBB = nullptr;
----------------
Ayal wrote:
> Worth augmenting the comment with a note that this loop not only searches for the preheader (for which it could early-break once found or employ find_if()) but also (gets or) creates VPBB's for (all) its latch(es).
>
> This loop over predecessors has a trip count of 2; would unrolling it be clearer?
>
>
> ```
> assert(pred_size(BB) == 2 && "A preheader and single latch are expected");
> auto PredBBI = pred_begin(BB);
> auto *PredVPBB0 = getOrCreateVPBB(*PredBBI);
> auto *PredVPBB1 = getOrCreateVPBB(*++PredBBI);
> int Pred0InRegion = PredVPBB0->getParent() == Region;
> assert(Pred0InRegion ^ PredVPBB1->getParent() == Region &&
> "Expecting latch to be in region but not preheader");
> Region->setPredecessors({Pred0InRegion ? PredVPBB1 : PredVPBB0});
>
> ```
Now that we liberally use loop info, we can just use that here as well to identify the loop predecessor.
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp:170-172
+ if (RegionExists) {
+ VPBB->setParent(Loop2Region[LoopOfBB]);
+ } else {
----------------
Ayal wrote:
>
I think the current coding standard recommends using branches for both `if` and `else` when either requires them (https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements). Left the code as is for now.
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp:369
+ VPBasicBlock *Successor1 = getOrCreateVPBB(BI->getSuccessor(1));
+ if (!LoopForBB || BB != LoopForBB->getLoopLatch()) {
+ VPBB->setTwoSuccessors(Successor0, Successor1);
----------------
Ayal wrote:
> Note that checking if `BB == LoopForBB->getLoopLatch()` implies a single latch, compared to checking if `LoopForBB->isLoopLatch(BB)`. This is fine, and independent of handling loops with multiple exiting blocks.
Ack!
================
Comment at: llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp:162
// Retrieve existing VPBB.
return BlockIt->second;
}
----------------
Ayal wrote:
> fhahn wrote:
> > Ayal wrote:
> > > nit: BlockIt is not needed below, can simply check
> > >
> > > ```
> > > // Retrieve VPBB if exists.
> > > if (BB2VPBB.contains(BB))
> > > return BB2VPBB[BB];
> > > ```
> > Yes, but that would require 2 lookups I think?
> Yes, but such 2 lookups should be folded by the compiler rather than the programmer...
> We do use contains()/[] below for Loop2Region.
> Would this work better:
> ```
> // Retrieve VPBB if exists.
> if (auto BlockIt = BB2VPBB.find(BB) != BB2VPBB.end())
> return BlockIt->second;
> ```
> ?
> Yes, but such 2 lookups should be folded by the compiler rather than the programmer...
Agreed, but I think in this case the current compilers won't be able to do so :(
> Would this work better:
I don't think this will work, as BlockIt would be a bool I think (result of the compare).
Probably better to use `lookup`, which returns `nullptr` if the key doesn't exist.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D159136/new/
https://reviews.llvm.org/D159136
More information about the llvm-commits
mailing list