@@ -24,48 +24,40 @@ using namespace llvm;
2424// / Checks if \p HeaderVPB is a loop header block in the plain CFG; that is, it
2525// / has exactly 2 predecessors (preheader and latch), where the block
2626// / dominates the latch and the preheader dominates the block. If it is a
27- // / header block, returns a pair with the corresponding preheader and latch
28- // / blocks . Otherwise return std::nullopt .
29- static std::optional<std::pair<VPBasicBlock *, VPBasicBlock *>>
30- getPreheaderAndLatch (VPBlockBase *HeaderVPB, const VPDominatorTree &VPDT) {
27+ // / header block return true, making sure the preheader appears first and
28+ // / the latch second . Otherwise return false .
29+ static bool canonicalHeader (VPBlockBase *HeaderVPB,
30+ const VPDominatorTree &VPDT) {
3131 ArrayRef<VPBlockBase *> Preds = HeaderVPB->getPredecessors ();
3232 if (Preds.size () != 2 )
33- return std:: nullopt ;
33+ return false ;
3434
35- auto *PreheaderVPBB = cast<VPBasicBlock>( Preds[0 ]) ;
36- auto *LatchVPBB = cast<VPBasicBlock>( Preds[1 ]) ;
35+ auto *PreheaderVPBB = Preds[0 ];
36+ auto *LatchVPBB = Preds[1 ];
3737 if (VPDT.dominates (PreheaderVPBB, HeaderVPB) &&
3838 VPDT.dominates (HeaderVPB, LatchVPBB))
39- return { std::make_pair (PreheaderVPBB, LatchVPBB)} ;
39+ return true ;
4040
4141 std::swap (PreheaderVPBB, LatchVPBB);
42+
4243 if (VPDT.dominates (PreheaderVPBB, HeaderVPB) &&
43- VPDT.dominates (HeaderVPB, LatchVPBB))
44- return {std::make_pair (PreheaderVPBB, LatchVPBB)};
44+ VPDT.dominates (HeaderVPB, LatchVPBB)) {
45+ // Canonicalize predecessors of header so that preheader is first and latch
46+ // second.
47+ HeaderVPB->swapPredecessors ();
48+ for (VPRecipeBase &R : cast<VPBasicBlock>(HeaderVPB)->phis ())
49+ R.swapOperands ();
50+ return true ;
51+ }
4552
46- return std:: nullopt ;
53+ return false ;
4754}
4855
49- // / Try to create a new VPRegionBlock if there is a loop starting at \p
50- // / HeaderVPB.
51- static void tryToCreateLoopRegion (VPlan &Plan, VPBlockBase *HeaderVPB,
52- VPDominatorTree &VPDT) {
53- auto Res = getPreheaderAndLatch (HeaderVPB, VPDT);
54- if (!Res)
55- return ;
56+ // / Create a new VPRegionBlock for the loop starting at \p HeaderVPB.
57+ static void createLoopRegion (VPlan &Plan, VPBlockBase *HeaderVPB) {
58+ auto *PreheaderVPBB = HeaderVPB->getPredecessors ()[0 ];
59+ auto *LatchVPBB = HeaderVPB->getPredecessors ()[1 ];
5660
57- const auto &[PreheaderVPBB, LatchVPBB] = *Res;
58-
59- // Swap the operands of header phis if needed. After creating the region, the
60- // incoming value from the preheader must be the first operand and the one
61- // from the latch must be the second operand.
62- if (HeaderVPB->getPredecessors ()[0 ] != PreheaderVPBB) {
63- for (VPRecipeBase &R : cast<VPBasicBlock>(HeaderVPB)->phis ()) {
64- VPValue *Inc0 = R.getOperand (0 );
65- R.setOperand (0 , R.getOperand (1 ));
66- R.setOperand (1 , Inc0);
67- }
68- }
6961 VPBlockUtils::disconnectBlocks (PreheaderVPBB, HeaderVPB);
7062 VPBlockUtils::disconnectBlocks (LatchVPBB, HeaderVPB);
7163 VPBlockBase *Succ = LatchVPBB->getSingleSuccessor ();
@@ -94,7 +86,8 @@ void VPlanTransforms::createLoopRegions(VPlan &Plan, Type *InductionTy,
9486 VPDominatorTree VPDT;
9587 VPDT.recalculate (Plan);
9688 for (VPBlockBase *HeaderVPB : vp_depth_first_shallow (Plan.getEntry ()))
97- tryToCreateLoopRegion (Plan, HeaderVPB, VPDT);
89+ if (canonicalHeader (HeaderVPB, VPDT))
90+ createLoopRegion (Plan, HeaderVPB);
9891
9992 VPRegionBlock *TopRegion = Plan.getVectorLoopRegion ();
10093 auto *OrigExiting = TopRegion->getExiting ();
0 commit comments