@@ -554,6 +554,8 @@ VPBasicBlock *VPBasicBlock::splitAt(iterator SplitAt) {
554554template <typename T> static T *getEnclosingLoopRegionForRegion (T *P) {
555555 if (P && P->isReplicator ()) {
556556 P = P->getParent ();
557+ // Multiple loop regions can be nested, but replicate regions can only be
558+ // nested inside a loop region or must be outside any other region.
557559 assert ((!P || !cast<VPRegionBlock>(P)->isReplicator ()) &&
558560 " unexpected nested replicate regions" );
559561 }
@@ -933,6 +935,8 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
933935
934936 IRBuilder<> Builder (State.CFG .PrevBB ->getTerminator ());
935937 // FIXME: Model VF * UF computation completely in VPlan.
938+ assert ((!getVectorLoopRegion () || VFxUF.getNumUsers ()) &&
939+ " VFxUF expected to always have users" );
936940 unsigned UF = getUF ();
937941 if (VF.getNumUsers ()) {
938942 Value *RuntimeVF = getRuntimeVF (Builder, TCTy, State.VF );
@@ -986,54 +990,56 @@ void VPlan::execute(VPTransformState *State) {
986990 for (VPBlockBase *Block : RPOT)
987991 Block->execute (State);
988992
989- if (auto *LoopRegion = getVectorLoopRegion ()) {
990- VPBasicBlock *LatchVPBB = LoopRegion->getExitingBasicBlock ();
991- BasicBlock *VectorLatchBB = State->CFG .VPBB2IRBB [LatchVPBB];
993+ State->CFG .DTU .flush ();
992994
993- // Fix the latch value of canonical, reduction and first-order recurrences
994- // phis in the vector loop.
995- VPBasicBlock *Header = LoopRegion->getEntryBasicBlock ();
996- for (VPRecipeBase &R : Header->phis ()) {
997- // Skip phi-like recipes that generate their backedege values themselves.
998- if (isa<VPWidenPHIRecipe>(&R))
999- continue ;
995+ auto *LoopRegion = getVectorLoopRegion ();
996+ if (!LoopRegion)
997+ return ;
1000998
1001- if (isa<VPWidenInductionRecipe>(&R)) {
1002- PHINode *Phi = nullptr ;
1003- if (isa<VPWidenIntOrFpInductionRecipe>(&R)) {
1004- Phi = cast<PHINode>(State->get (R.getVPSingleValue ()));
1005- } else {
1006- auto *WidenPhi = cast<VPWidenPointerInductionRecipe>(&R);
1007- assert (!WidenPhi->onlyScalarsGenerated (State->VF .isScalable ()) &&
1008- " recipe generating only scalars should have been replaced" );
1009- auto *GEP = cast<GetElementPtrInst>(State->get (WidenPhi));
1010- Phi = cast<PHINode>(GEP->getPointerOperand ());
1011- }
1012-
1013- Phi->setIncomingBlock (1 , VectorLatchBB);
1014-
1015- // Move the last step to the end of the latch block. This ensures
1016- // consistent placement of all induction updates.
1017- Instruction *Inc = cast<Instruction>(Phi->getIncomingValue (1 ));
1018- Inc->moveBefore (VectorLatchBB->getTerminator ()->getPrevNode ());
1019-
1020- // Use the steps for the last part as backedge value for the induction.
1021- if (auto *IV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&R))
1022- Inc->setOperand (0 , State->get (IV->getLastUnrolledPartOperand ()));
1023- continue ;
999+ VPBasicBlock *LatchVPBB = LoopRegion->getExitingBasicBlock ();
1000+ BasicBlock *VectorLatchBB = State->CFG .VPBB2IRBB [LatchVPBB];
1001+
1002+ // Fix the latch value of canonical, reduction and first-order recurrences
1003+ // phis in the vector loop.
1004+ VPBasicBlock *Header = LoopRegion->getEntryBasicBlock ();
1005+ for (VPRecipeBase &R : Header->phis ()) {
1006+ // Skip phi-like recipes that generate their backedege values themselves.
1007+ if (isa<VPWidenPHIRecipe>(&R))
1008+ continue ;
1009+
1010+ if (isa<VPWidenInductionRecipe>(&R)) {
1011+ PHINode *Phi = nullptr ;
1012+ if (isa<VPWidenIntOrFpInductionRecipe>(&R)) {
1013+ Phi = cast<PHINode>(State->get (R.getVPSingleValue ()));
1014+ } else {
1015+ auto *WidenPhi = cast<VPWidenPointerInductionRecipe>(&R);
1016+ assert (!WidenPhi->onlyScalarsGenerated (State->VF .isScalable ()) &&
1017+ " recipe generating only scalars should have been replaced" );
1018+ auto *GEP = cast<GetElementPtrInst>(State->get (WidenPhi));
1019+ Phi = cast<PHINode>(GEP->getPointerOperand ());
10241020 }
10251021
1026- auto *PhiR = cast<VPHeaderPHIRecipe>(&R);
1027- bool NeedsScalar = isa<VPScalarPHIRecipe>(PhiR) ||
1028- (isa<VPReductionPHIRecipe>(PhiR) &&
1029- cast<VPReductionPHIRecipe>(PhiR)->isInLoop ());
1030- Value *Phi = State->get (PhiR, NeedsScalar);
1031- Value *Val = State->get (PhiR->getBackedgeValue (), NeedsScalar);
1032- cast<PHINode>(Phi)->addIncoming (Val, VectorLatchBB);
1022+ Phi->setIncomingBlock (1 , VectorLatchBB);
1023+
1024+ // Move the last step to the end of the latch block. This ensures
1025+ // consistent placement of all induction updates.
1026+ Instruction *Inc = cast<Instruction>(Phi->getIncomingValue (1 ));
1027+ Inc->moveBefore (VectorLatchBB->getTerminator ()->getPrevNode ());
1028+
1029+ // Use the steps for the last part as backedge value for the induction.
1030+ if (auto *IV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&R))
1031+ Inc->setOperand (0 , State->get (IV->getLastUnrolledPartOperand ()));
1032+ continue ;
10331033 }
1034- }
10351034
1036- State->CFG .DTU .flush ();
1035+ auto *PhiR = cast<VPHeaderPHIRecipe>(&R);
1036+ bool NeedsScalar = isa<VPScalarPHIRecipe>(PhiR) ||
1037+ (isa<VPReductionPHIRecipe>(PhiR) &&
1038+ cast<VPReductionPHIRecipe>(PhiR)->isInLoop ());
1039+ Value *Phi = State->get (PhiR, NeedsScalar);
1040+ Value *Val = State->get (PhiR->getBackedgeValue (), NeedsScalar);
1041+ cast<PHINode>(Phi)->addIncoming (Val, VectorLatchBB);
1042+ }
10371043}
10381044
10391045InstructionCost VPlan::cost (ElementCount VF, VPCostContext &Ctx) {
@@ -1399,13 +1405,17 @@ void VPlanIngredient::print(raw_ostream &O) const {
13991405
14001406#endif
14011407
1402- bool VPValue::isDefinedOutsideLoopRegions () const {
1403-
1404- return !hasDefiningRecipe () ||
1405- (!getDefiningRecipe ()->getParent ()->getEnclosingLoopRegion () &&
1406- getDefiningRecipe ()->getParent ()->getPlan ()->getVectorLoopRegion ());
1408+ // / Returns true if there is a vector loop region and \p VPV is defined in a
1409+ // / loop region.
1410+ static bool isDefinedInsideLoopRegions (const VPValue *VPV) {
1411+ const VPRecipeBase *DefR = VPV->getDefiningRecipe ();
1412+ return DefR && (!DefR->getParent ()->getPlan ()->getVectorLoopRegion () ||
1413+ DefR->getParent ()->getEnclosingLoopRegion ());
14071414}
14081415
1416+ bool VPValue::isDefinedOutsideLoopRegions () const {
1417+ return !isDefinedInsideLoopRegions (this );
1418+ }
14091419void VPValue::replaceAllUsesWith (VPValue *New) {
14101420 replaceUsesWithIf (New, [](VPUser &, unsigned ) { return true ; });
14111421}
0 commit comments