-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[VPlan] Invert condition if needed when creating inner regions. #132292
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 3 commits
29bfcd0
0f7ad9e
fa812b5
26b6cb4
6339346
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 |
|---|---|---|
|
|
@@ -386,33 +386,53 @@ std::unique_ptr<VPlan> VPlanTransforms::buildPlainCFG( | |
| /// Checks if \p HeaderVPB is a loop header block in the plain CFG; that is, it | ||
| /// has exactly 2 predecessors (preheader and latch), where the block | ||
| /// dominates the latch and the preheader dominates the block. If it is a | ||
| /// header block return true, making sure the preheader appears first and | ||
| /// the latch second. Otherwise return false. | ||
| static bool canonicalHeader(VPBlockBase *HeaderVPB, | ||
| const VPDominatorTree &VPDT) { | ||
| /// header block return true and canonicalize the predecessors of the header | ||
| /// (making sure the preheader appears first and the latch second) and the | ||
| /// successors of the latch (making sure the loop exit comes first). Otherwise | ||
| /// return false. | ||
| static bool canonicalHeaderAndLatch(VPBlockBase *HeaderVPB, | ||
| const VPDominatorTree &VPDT) { | ||
| ArrayRef<VPBlockBase *> Preds = HeaderVPB->getPredecessors(); | ||
| if (Preds.size() != 2) | ||
| return false; | ||
|
|
||
| auto *PreheaderVPBB = Preds[0]; | ||
| auto *LatchVPBB = Preds[1]; | ||
| if (VPDT.dominates(PreheaderVPBB, HeaderVPB) && | ||
| VPDT.dominates(HeaderVPB, LatchVPBB)) | ||
| return true; | ||
| if (!VPDT.dominates(PreheaderVPBB, HeaderVPB) || | ||
| !VPDT.dominates(HeaderVPB, LatchVPBB)) { | ||
| std::swap(PreheaderVPBB, LatchVPBB); | ||
|
|
||
| std::swap(PreheaderVPBB, LatchVPBB); | ||
| if (!VPDT.dominates(PreheaderVPBB, HeaderVPB) || | ||
| !VPDT.dominates(HeaderVPB, LatchVPBB)) { | ||
| return false; | ||
| } else { | ||
| // Canonicalize predecessors of header so that preheader is first and | ||
| // latch second. | ||
| HeaderVPB->swapPredecessors(); | ||
| for (VPRecipeBase &R : cast<VPBasicBlock>(HeaderVPB)->phis()) | ||
| R.swapOperands(); | ||
| } | ||
| } | ||
|
|
||
| if (VPDT.dominates(PreheaderVPBB, HeaderVPB) && | ||
| VPDT.dominates(HeaderVPB, LatchVPBB)) { | ||
| // Canonicalize predecessors of header so that preheader is first and latch | ||
| // second. | ||
| HeaderVPB->swapPredecessors(); | ||
| for (VPRecipeBase &R : cast<VPBasicBlock>(HeaderVPB)->phis()) | ||
| R.swapOperands(); | ||
| return true; | ||
| // The two successors of conditional branch match the condition, with the | ||
| // first successor corresponding to true and the second to false. We | ||
| // canonicalize the successors of the latch when introducing the region, such | ||
| // that the latch exits the region when its condition is true; invert the | ||
| // original condition if the original CFG branches to the header on true. | ||
| if (!LatchVPBB->getSingleSuccessor() && | ||
|
||
| LatchVPBB->getSuccessors()[0] == HeaderVPB) { | ||
| assert(LatchVPBB->getNumSuccessors() == 2 && "Must have 2 successors"); | ||
| auto *Term = cast<VPBasicBlock>(LatchVPBB)->getTerminator(); | ||
|
||
| assert(cast<VPInstruction>(Term)->getOpcode() == | ||
| VPInstruction::BranchOnCond && | ||
| "terminator must be a BranchOnCond"); | ||
| auto *Not = new VPInstruction(VPInstruction::Not, {Term->getOperand(0)}); | ||
| Not->insertBefore(Term); | ||
| Term->setOperand(0, Not); | ||
|
||
| LatchVPBB->swapSuccessors(); | ||
| } | ||
|
|
||
| return false; | ||
| return true; | ||
| } | ||
|
|
||
| /// Create a new VPRegionBlock for the loop starting at \p HeaderVPB. | ||
|
|
@@ -447,7 +467,7 @@ void VPlanTransforms::createLoopRegions(VPlan &Plan, Type *InductionTy, | |
| VPDominatorTree VPDT; | ||
| VPDT.recalculate(Plan); | ||
| for (VPBlockBase *HeaderVPB : vp_depth_first_shallow(Plan.getEntry())) | ||
| if (canonicalHeader(HeaderVPB, VPDT)) | ||
| if (canonicalHeaderAndLatch(HeaderVPB, VPDT)) | ||
| createLoopRegion(Plan, HeaderVPB); | ||
|
|
||
| VPRegionBlock *TopRegion = Plan.getVectorLoopRegion(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,6 +55,9 @@ bool VPlanTransforms::tryToConvertVPInstructionsToVPRecipes( | |
| make_early_inc_range(make_range(VPBB->begin(), EndIter))) { | ||
|
|
||
| VPValue *VPV = Ingredient.getVPSingleValue(); | ||
|
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. Independent: using
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. Can rename separately, thanks |
||
| if (!VPV->getUnderlyingValue()) | ||
| continue; | ||
|
|
||
| Instruction *Inst = cast<Instruction>(VPV->getUnderlyingValue()); | ||
|
|
||
| VPRecipeBase *NewRecipe = nullptr; | ||
|
|
||
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