@@ -607,10 +607,6 @@ class InnerLoopVectorizer {
607
607
BasicBlock *MiddleBlock, BasicBlock *VectorHeader,
608
608
VPlan &Plan, VPTransformState &State);
609
609
610
- // / Create the phi node for the resume value of first order recurrences in the
611
- // / scalar preheader and update the users in the scalar loop.
612
- void fixFixedOrderRecurrence (VPLiveOut *LO, VPTransformState &State);
613
-
614
610
// / Iteratively sink the scalarized operands of a predicated instruction into
615
611
// / the block that was created for it.
616
612
void sinkScalarOperands (Instruction *PredInst);
@@ -3339,8 +3335,6 @@ void InnerLoopVectorizer::fixVectorizedLoop(VPTransformState &State,
3339
3335
for (const auto &[_, LO] : to_vector (Plan.getLiveOuts ())) {
3340
3336
if (!Legal->isFixedOrderRecurrence (LO->getPhi ()))
3341
3337
continue ;
3342
- fixFixedOrderRecurrence (LO, State);
3343
- Plan.removeLiveOut (LO->getPhi ());
3344
3338
}
3345
3339
3346
3340
// Forget the original basic block.
@@ -3422,35 +3416,6 @@ static void reorderIncomingBlocks(SmallVectorImpl<BasicBlock *> &Blocks,
3422
3416
std::swap (Blocks[0 ], Blocks[1 ]);
3423
3417
}
3424
3418
3425
- void InnerLoopVectorizer::fixFixedOrderRecurrence (VPLiveOut *LO,
3426
- VPTransformState &State) {
3427
- // Extract the last vector element in the middle block. This will be the
3428
- // initial value for the recurrence when jumping to the scalar loop.
3429
- VPValue *VPExtract = LO->getOperand (0 );
3430
- using namespace llvm ::VPlanPatternMatch;
3431
- assert (match (VPExtract, m_VPInstruction<VPInstruction::ExtractFromEnd>(
3432
- m_VPValue (), m_VPValue ())) &&
3433
- " FOR LiveOut expects to use an extract from end." );
3434
- Value *ResumeScalarFOR = State.get (VPExtract, UF - 1 , true );
3435
-
3436
- // Fix the initial value of the original recurrence in the scalar loop.
3437
- PHINode *ScalarHeaderPhi = LO->getPhi ();
3438
- auto *InitScalarFOR =
3439
- ScalarHeaderPhi->getIncomingValueForBlock (LoopScalarPreHeader);
3440
- Builder.SetInsertPoint (LoopScalarPreHeader, LoopScalarPreHeader->begin ());
3441
- auto *ScalarPreheaderPhi =
3442
- Builder.CreatePHI (ScalarHeaderPhi->getType (), 2 , " scalar.recur.init" );
3443
- SmallVector<BasicBlock *> Blocks (predecessors (LoopScalarPreHeader));
3444
- reorderIncomingBlocks (Blocks, LoopMiddleBlock);
3445
- for (auto *BB : Blocks) {
3446
- auto *Incoming = BB == LoopMiddleBlock ? ResumeScalarFOR : InitScalarFOR;
3447
- ScalarPreheaderPhi->addIncoming (Incoming, BB);
3448
- }
3449
- ScalarHeaderPhi->setIncomingValueForBlock (LoopScalarPreHeader,
3450
- ScalarPreheaderPhi);
3451
- ScalarHeaderPhi->setName (" scalar.recur" );
3452
- }
3453
-
3454
3419
void InnerLoopVectorizer::sinkScalarOperands (Instruction *PredInst) {
3455
3420
// The basic block and loop containing the predicated instruction.
3456
3421
auto *PredBB = PredInst->getParent ();
@@ -8501,7 +8466,9 @@ static void addUsersInExitBlock(VPBasicBlock *HeaderVPBB, Loop *OrigLoop,
8501
8466
Value *IncomingValue =
8502
8467
ExitPhi.getIncomingValueForBlock (ExitingBB);
8503
8468
VPValue *V = Builder.getVPValueOrAddLiveIn (IncomingValue, Plan);
8504
- Plan.addLiveOut (&ExitPhi, V);
8469
+ Plan.addLiveOut (
8470
+ &ExitPhi, V,
8471
+ cast<VPBasicBlock>(Plan.getVectorLoopRegion ()->getSingleSuccessor ()));
8505
8472
}
8506
8473
}
8507
8474
@@ -8681,6 +8648,49 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
8681
8648
" VPBasicBlock" );
8682
8649
RecipeBuilder.fixHeaderPhis ();
8683
8650
8651
+ auto *MiddleVPBB =
8652
+ cast<VPBasicBlock>(Plan->getVectorLoopRegion ()->getSingleSuccessor ());
8653
+
8654
+ VPBasicBlock *ScalarPH = nullptr ;
8655
+ for (VPBlockBase *Succ : MiddleVPBB->getSuccessors ()) {
8656
+ auto *VPIRBB = dyn_cast<VPIRBasicBlock>(Succ);
8657
+ if (VPIRBB && VPIRBB->getIRBasicBlock () == OrigLoop->getHeader ()) {
8658
+ ScalarPH = VPIRBB;
8659
+ break ;
8660
+ }
8661
+ }
8662
+
8663
+ if (ScalarPH) {
8664
+ for (auto &H : HeaderVPBB->phis ()) {
8665
+ auto *FOR = dyn_cast<VPFirstOrderRecurrencePHIRecipe>(&H);
8666
+ if (!FOR)
8667
+ continue ;
8668
+ VPBuilder B (ScalarPH);
8669
+ VPBuilder MiddleBuilder;
8670
+ // Set insert point so new recipes are inserted before terminator and
8671
+ // condition, if there is either the former or both.
8672
+ if (MiddleVPBB->getNumSuccessors () != 2 )
8673
+ MiddleBuilder.setInsertPoint (MiddleVPBB);
8674
+ else if (isa<VPInstruction>(MiddleVPBB->getTerminator ()->getOperand (0 )))
8675
+ MiddleBuilder.setInsertPoint (
8676
+ &*std::prev (MiddleVPBB->getTerminator ()->getIterator ()));
8677
+ else
8678
+ MiddleBuilder.setInsertPoint (MiddleVPBB->getTerminator ());
8679
+
8680
+ // Extract the resume value and create a new VPLiveOut for it.
8681
+ auto *Resume = MiddleBuilder.createNaryOp (
8682
+ VPInstruction::ExtractFromEnd,
8683
+ {FOR->getBackedgeValue (),
8684
+ Plan->getOrAddLiveIn (
8685
+ ConstantInt::get (Plan->getCanonicalIV ()->getScalarType (), 1 ))},
8686
+ {}, " vector.recur.extract" );
8687
+ auto *R =
8688
+ B.createNaryOp (VPInstruction::ExitPhi, {Resume, FOR->getStartValue ()},
8689
+ {}, " scalar.recur.init" );
8690
+ Plan->addLiveOut (cast<PHINode>(FOR->getUnderlyingInstr ()), R, ScalarPH);
8691
+ }
8692
+ }
8693
+
8684
8694
// ---------------------------------------------------------------------------
8685
8695
// Transform initial VPlan: Apply previously taken decisions, in order, to
8686
8696
// bring the VPlan to its final state.
0 commit comments