@@ -8687,34 +8687,10 @@ void LoopVectorizationPlanner::buildVPlansWithVPRecipes(ElementCount MinVF,
8687
8687
auto &ConditionalAssumes = Legal->getConditionalAssumes ();
8688
8688
DeadInstructions.insert (ConditionalAssumes.begin (), ConditionalAssumes.end ());
8689
8689
8690
- MapVector<Instruction *, Instruction *> &SinkAfter = Legal->getSinkAfter ();
8691
- // Dead instructions do not need sinking. Remove them from SinkAfter.
8692
- for (Instruction *I : DeadInstructions)
8693
- SinkAfter.erase (I);
8694
-
8695
- // Cannot sink instructions after dead instructions (there won't be any
8696
- // recipes for them). Instead, find the first non-dead previous instruction.
8697
- for (auto &P : Legal->getSinkAfter ()) {
8698
- Instruction *SinkTarget = P.second ;
8699
- Instruction *FirstInst = &*SinkTarget->getParent ()->begin ();
8700
- (void )FirstInst;
8701
- while (DeadInstructions.contains (SinkTarget)) {
8702
- assert (
8703
- SinkTarget != FirstInst &&
8704
- " Must find a live instruction (at least the one feeding the "
8705
- " fixed-order recurrence PHI) before reaching beginning of the block" );
8706
- SinkTarget = SinkTarget->getPrevNode ();
8707
- assert (SinkTarget != P.first &&
8708
- " sink source equals target, no sinking required" );
8709
- }
8710
- P.second = SinkTarget;
8711
- }
8712
-
8713
8690
auto MaxVFPlusOne = MaxVF.getWithIncrement (1 );
8714
8691
for (ElementCount VF = MinVF; ElementCount::isKnownLT (VF, MaxVFPlusOne);) {
8715
8692
VFRange SubRange = {VF, MaxVFPlusOne};
8716
- VPlans.push_back (
8717
- buildVPlanWithVPRecipes (SubRange, DeadInstructions, SinkAfter));
8693
+ VPlans.push_back (buildVPlanWithVPRecipes (SubRange, DeadInstructions));
8718
8694
VF = SubRange.End ;
8719
8695
}
8720
8696
}
@@ -8820,8 +8796,7 @@ static void addUsersInExitBlock(VPBasicBlock *HeaderVPBB,
8820
8796
}
8821
8797
8822
8798
VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes (
8823
- VFRange &Range, SmallPtrSetImpl<Instruction *> &DeadInstructions,
8824
- const MapVector<Instruction *, Instruction *> &SinkAfter) {
8799
+ VFRange &Range, SmallPtrSetImpl<Instruction *> &DeadInstructions) {
8825
8800
8826
8801
SmallPtrSet<const InterleaveGroup<Instruction> *, 1 > InterleaveGroups;
8827
8802
@@ -8832,12 +8807,6 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
8832
8807
// process after constructing the initial VPlan.
8833
8808
// ---------------------------------------------------------------------------
8834
8809
8835
- // Mark instructions we'll need to sink later and their targets as
8836
- // ingredients whose recipe we'll need to record.
8837
- for (const auto &Entry : SinkAfter) {
8838
- RecipeBuilder.recordRecipeOf (Entry.first );
8839
- RecipeBuilder.recordRecipeOf (Entry.second );
8840
- }
8841
8810
for (const auto &Reduction : CM.getInLoopReductionChains ()) {
8842
8811
PHINode *Phi = Reduction.first ;
8843
8812
RecurKind Kind =
@@ -8905,7 +8874,6 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
8905
8874
DFS.perform (LI);
8906
8875
8907
8876
VPBasicBlock *VPBB = HeaderVPBB;
8908
- SmallVector<VPWidenIntOrFpInductionRecipe *> InductionsToMove;
8909
8877
for (BasicBlock *BB : make_range (DFS.beginRPO (), DFS.endRPO ())) {
8910
8878
// Relevant instructions from basic block BB will be grouped into VPRecipe
8911
8879
// ingredients and fill a new VPBasicBlock.
@@ -8960,19 +8928,15 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
8960
8928
Plan->addVPValue (UV, Def);
8961
8929
}
8962
8930
8931
+ RecipeBuilder.setRecipe (Instr, Recipe);
8963
8932
if (isa<VPWidenIntOrFpInductionRecipe>(Recipe) &&
8964
8933
HeaderVPBB->getFirstNonPhi () != VPBB->end ()) {
8965
- // Keep track of VPWidenIntOrFpInductionRecipes not in the phi section
8966
- // of the header block. That can happen for truncates of induction
8967
- // variables. Those recipes are moved to the phi section of the header
8968
- // block after applying SinkAfter, which relies on the original
8969
- // position of the trunc.
8934
+ // Move VPWidenIntOrFpInductionRecipes for optimized truncates to the
8935
+ // phi section of HeaderVPBB.
8970
8936
assert (isa<TruncInst>(Instr));
8971
- InductionsToMove.push_back (
8972
- cast<VPWidenIntOrFpInductionRecipe>(Recipe));
8973
- }
8974
- RecipeBuilder.setRecipe (Instr, Recipe);
8975
- VPBB->appendRecipe (Recipe);
8937
+ Recipe->insertBefore (*HeaderVPBB, HeaderVPBB->getFirstNonPhi ());
8938
+ } else
8939
+ VPBB->appendRecipe (Recipe);
8976
8940
continue ;
8977
8941
}
8978
8942
@@ -9007,115 +8971,16 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
9007
8971
// bring the VPlan to its final state.
9008
8972
// ---------------------------------------------------------------------------
9009
8973
9010
- // Apply Sink-After legal constraints.
9011
- auto GetReplicateRegion = [](VPRecipeBase *R) -> VPRegionBlock * {
9012
- auto *Region = dyn_cast_or_null<VPRegionBlock>(R->getParent ()->getParent ());
9013
- if (Region && Region->isReplicator ()) {
9014
- assert (Region->getNumSuccessors () == 1 &&
9015
- Region->getNumPredecessors () == 1 && " Expected SESE region!" );
9016
- assert (R->getParent ()->size () == 1 &&
9017
- " A recipe in an original replicator region must be the only "
9018
- " recipe in its block" );
9019
- return Region;
9020
- }
9021
- return nullptr ;
9022
- };
9023
- for (const auto &Entry : SinkAfter) {
9024
- VPRecipeBase *Sink = RecipeBuilder.getRecipe (Entry.first );
9025
- VPRecipeBase *Target = RecipeBuilder.getRecipe (Entry.second );
9026
-
9027
- auto *TargetRegion = GetReplicateRegion (Target);
9028
- auto *SinkRegion = GetReplicateRegion (Sink);
9029
- if (!SinkRegion) {
9030
- // If the sink source is not a replicate region, sink the recipe directly.
9031
- if (TargetRegion) {
9032
- // The target is in a replication region, make sure to move Sink to
9033
- // the block after it, not into the replication region itself.
9034
- VPBasicBlock *NextBlock =
9035
- cast<VPBasicBlock>(TargetRegion->getSuccessors ().front ());
9036
- Sink->moveBefore (*NextBlock, NextBlock->getFirstNonPhi ());
9037
- } else
9038
- Sink->moveAfter (Target);
9039
- continue ;
9040
- }
9041
-
9042
- // The sink source is in a replicate region. Unhook the region from the CFG.
9043
- auto *SinkPred = SinkRegion->getSinglePredecessor ();
9044
- auto *SinkSucc = SinkRegion->getSingleSuccessor ();
9045
- VPBlockUtils::disconnectBlocks (SinkPred, SinkRegion);
9046
- VPBlockUtils::disconnectBlocks (SinkRegion, SinkSucc);
9047
- VPBlockUtils::connectBlocks (SinkPred, SinkSucc);
9048
-
9049
- if (TargetRegion) {
9050
- // The target recipe is also in a replicate region, move the sink region
9051
- // after the target region.
9052
- auto *TargetSucc = TargetRegion->getSingleSuccessor ();
9053
- VPBlockUtils::disconnectBlocks (TargetRegion, TargetSucc);
9054
- VPBlockUtils::connectBlocks (TargetRegion, SinkRegion);
9055
- VPBlockUtils::connectBlocks (SinkRegion, TargetSucc);
9056
- } else {
9057
- // The sink source is in a replicate region, we need to move the whole
9058
- // replicate region, which should only contain a single recipe in the
9059
- // main block.
9060
- auto *SplitBlock =
9061
- Target->getParent ()->splitAt (std::next (Target->getIterator ()));
9062
-
9063
- auto *SplitPred = SplitBlock->getSinglePredecessor ();
9064
-
9065
- VPBlockUtils::disconnectBlocks (SplitPred, SplitBlock);
9066
- VPBlockUtils::connectBlocks (SplitPred, SinkRegion);
9067
- VPBlockUtils::connectBlocks (SinkRegion, SplitBlock);
9068
- }
9069
- }
9070
-
9071
8974
VPlanTransforms::removeRedundantCanonicalIVs (*Plan);
9072
8975
VPlanTransforms::removeRedundantInductionCasts (*Plan);
9073
8976
9074
- // Now that sink-after is done, move induction recipes for optimized truncates
9075
- // to the phi section of the header block.
9076
- for (VPWidenIntOrFpInductionRecipe *Ind : InductionsToMove)
9077
- Ind->moveBefore (*HeaderVPBB, HeaderVPBB->getFirstNonPhi ());
9078
-
9079
8977
// Adjust the recipes for any inloop reductions.
9080
8978
adjustRecipesForReductions (cast<VPBasicBlock>(TopRegion->getExiting ()), Plan,
9081
8979
RecipeBuilder, Range.Start );
9082
8980
9083
- // Introduce a recipe to combine the incoming and previous values of a
9084
- // fixed-order recurrence.
9085
- for (VPRecipeBase &R :
9086
- Plan->getVectorLoopRegion ()->getEntryBasicBlock ()->phis ()) {
9087
- auto *RecurPhi = dyn_cast<VPFirstOrderRecurrencePHIRecipe>(&R);
9088
- if (!RecurPhi)
9089
- continue ;
9090
-
9091
- VPRecipeBase *PrevRecipe = &RecurPhi->getBackedgeRecipe ();
9092
- // Fixed-order recurrences do not contain cycles, so this loop is guaranteed
9093
- // to terminate.
9094
- while (auto *PrevPhi =
9095
- dyn_cast<VPFirstOrderRecurrencePHIRecipe>(PrevRecipe))
9096
- PrevRecipe = &PrevPhi->getBackedgeRecipe ();
9097
- VPBasicBlock *InsertBlock = PrevRecipe->getParent ();
9098
- auto *Region = GetReplicateRegion (PrevRecipe);
9099
- if (Region)
9100
- InsertBlock = dyn_cast<VPBasicBlock>(Region->getSingleSuccessor ());
9101
- if (!InsertBlock) {
9102
- InsertBlock = new VPBasicBlock (Region->getName () + " .succ" );
9103
- VPBlockUtils::insertBlockAfter (InsertBlock, Region);
9104
- }
9105
- if (Region || PrevRecipe->isPhi ())
9106
- Builder.setInsertPoint (InsertBlock, InsertBlock->getFirstNonPhi ());
9107
- else
9108
- Builder.setInsertPoint (InsertBlock, std::next (PrevRecipe->getIterator ()));
9109
-
9110
- auto *RecurSplice = cast<VPInstruction>(
9111
- Builder.createNaryOp (VPInstruction::FirstOrderRecurrenceSplice,
9112
- {RecurPhi, RecurPhi->getBackedgeValue ()}));
9113
-
9114
- RecurPhi->replaceAllUsesWith (RecurSplice);
9115
- // Set the first operand of RecurSplice to RecurPhi again, after replacing
9116
- // all users.
9117
- RecurSplice->setOperand (0 , RecurPhi);
9118
- }
8981
+ // Sink users of fixed-order recurrence past the recipe defining the previous
8982
+ // value and introduce FirstOrderRecurrenceSplice VPInstructions.
8983
+ VPlanTransforms::adjustFixedOrderRecurrences (*Plan, Builder);
9119
8984
9120
8985
// Interleave memory: for each Interleave Group we marked earlier as relevant
9121
8986
// for this VPlan, replace the Recipes widening its memory instructions with a
0 commit comments