Skip to content

Commit 49676de

Browse files
committed
[VPlan] Make canonical IV part of the region
1 parent 85ef4b2 commit 49676de

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+425
-413
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4030,7 +4030,6 @@ static bool willGenerateVectors(VPlan &Plan, ElementCount VF,
40304030
case VPDef::VPScalarIVStepsSC:
40314031
case VPDef::VPReplicateSC:
40324032
case VPDef::VPInstructionSC:
4033-
case VPDef::VPCanonicalIVPHISC:
40344033
case VPDef::VPVectorPointerSC:
40354034
case VPDef::VPVectorEndPointerSC:
40364035
case VPDef::VPExpandSCEVSC:
@@ -8428,6 +8427,7 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(
84288427
m_Specific(Plan->getCanonicalIV()), m_VPValue())) &&
84298428
"Did not find the canonical IV increment");
84308429
cast<VPRecipeWithIRFlags>(IVInc)->dropPoisonGeneratingFlags();
8430+
Plan->getCanonicalIVInfo().HasNUW = false;
84318431
}
84328432

84338433
// ---------------------------------------------------------------------------
@@ -8491,8 +8491,7 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(
84918491
// latter are added above for masking.
84928492
// FIXME: Migrate code relying on the underlying instruction from VPlan0
84938493
// to construct recipes below to not use the underlying instruction.
8494-
if (isa<VPCanonicalIVPHIRecipe, VPWidenCanonicalIVRecipe, VPBlendRecipe>(
8495-
&R) ||
8494+
if (isa<VPWidenCanonicalIVRecipe, VPBlendRecipe>(&R) ||
84968495
(isa<VPInstruction>(&R) && !UnderlyingValue))
84978496
continue;
84988497

@@ -8679,8 +8678,6 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlan(VFRange &Range) {
86798678
VPRecipeBuilder RecipeBuilder(*Plan, OrigLoop, TLI, &TTI, Legal, CM, PSE,
86808679
Builder, BlockMaskCache, nullptr /*LVer*/);
86818680
for (auto &R : Plan->getVectorLoopRegion()->getEntryBasicBlock()->phis()) {
8682-
if (isa<VPCanonicalIVPHIRecipe>(&R))
8683-
continue;
86848681
auto *HeaderR = cast<VPHeaderPHIRecipe>(&R);
86858682
RecipeBuilder.setRecipe(HeaderR->getUnderlyingInstr(), HeaderR);
86868683
}
@@ -9430,8 +9427,6 @@ static void preparePlanForMainVectorLoop(VPlan &MainPlan, VPlan &EpiPlan) {
94309427
SmallPtrSet<PHINode *, 2> EpiWidenedPhis;
94319428
for (VPRecipeBase &R :
94329429
EpiPlan.getVectorLoopRegion()->getEntryBasicBlock()->phis()) {
9433-
if (isa<VPCanonicalIVPHIRecipe>(&R))
9434-
continue;
94359430
EpiWidenedPhis.insert(
94369431
cast<PHINode>(R.getVPSingleValue()->getUnderlyingValue()));
94379432
}
@@ -9492,8 +9487,9 @@ static void preparePlanForMainVectorLoop(VPlan &MainPlan, VPlan &EpiPlan) {
94929487
VPPhi *ResumePhi = nullptr;
94939488
if (ResumePhiIter == MainScalarPH->phis().end()) {
94949489
VPBuilder ScalarPHBuilder(MainScalarPH, MainScalarPH->begin());
9490+
Type *Ty = VPTypeAnalysis(MainPlan).inferScalarType(VectorTC);
94959491
ResumePhi = ScalarPHBuilder.createScalarPhi(
9496-
{VectorTC, MainPlan.getCanonicalIV()->getStartValue()}, {},
9492+
{VectorTC, MainPlan.getOrAddLiveIn(Constant::getNullValue(Ty))}, {},
94979493
"vec.epilog.resume.val");
94989494
} else {
94999495
ResumePhi = cast<VPPhi>(&*ResumePhiIter);
@@ -9523,7 +9519,7 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
95239519

95249520
// Ensure that the start values for all header phi recipes are updated before
95259521
// vectorizing the epilogue loop.
9526-
VPCanonicalIVPHIRecipe *IV = Plan.getCanonicalIV();
9522+
95279523
// When vectorizing the epilogue loop, the canonical induction start
95289524
// value needs to be changed from zero to the value after the main
95299525
// vector loop. Find the resume value created during execution of the main
@@ -9552,6 +9548,7 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
95529548
EPI.VectorTripCount = EPResumeVal->getOperand(0);
95539549
}
95549550
VPValue *VPV = Plan.getOrAddLiveIn(EPResumeVal);
9551+
VPValue *IV = VectorLoop->getCanonicalIV();
95559552
assert(all_of(IV->users(),
95569553
[](const VPUser *U) {
95579554
return isa<VPScalarIVStepsRecipe>(U) ||
@@ -9569,7 +9566,7 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
95699566

95709567
DenseMap<Value *, Value *> ToFrozen;
95719568
SmallVector<Instruction *> InstsToMove;
9572-
for (VPRecipeBase &R : drop_begin(Header->phis())) {
9569+
for (VPRecipeBase &R : Header->phis()) {
95739570
Value *ResumeV = nullptr;
95749571
// TODO: Move setting of resume values to prepareToExecute.
95759572
if (auto *ReductionPhi = dyn_cast<VPReductionPHIRecipe>(&R)) {
@@ -9610,7 +9607,6 @@ static SmallVector<Instruction *> preparePlanForEpilogueVectorLoop(
96109607
Value *Cmp = Builder.CreateICmpEQ(ResumeV, ToFrozen[StartV]);
96119608
if (auto *I = dyn_cast<Instruction>(Cmp))
96129609
InstsToMove.push_back(I);
9613-
96149610
Value *Sentinel = RdxResult->getOperand(2)->getLiveInIRValue();
96159611
ResumeV = Builder.CreateSelect(Cmp, Sentinel, ResumeV);
96169612
if (auto *I = dyn_cast<Instruction>(ResumeV))

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -768,10 +768,17 @@ static std::pair<VPBlockBase *, VPBlockBase *> cloneFrom(VPBlockBase *Entry) {
768768

769769
VPRegionBlock *VPRegionBlock::clone() {
770770
const auto &[NewEntry, NewExiting] = cloneFrom(getEntry());
771-
auto *NewRegion = getPlan()->createVPRegionBlock(NewEntry, NewExiting,
772-
getName(), isReplicator());
771+
auto *NewRegion =
772+
getPlan()->createVPRegionBlock(NewEntry, NewExiting, getName());
773773
for (VPBlockBase *Block : vp_depth_first_shallow(NewEntry))
774774
Block->setParent(NewRegion);
775+
776+
if (CanIVInfo.CanIV) {
777+
NewRegion->CanIVInfo.CanIV = new VPRegionValue();
778+
NewRegion->CanIVInfo.HasNUW = CanIVInfo.HasNUW;
779+
NewRegion->CanIVInfo.DL = CanIVInfo.DL;
780+
}
781+
775782
return NewRegion;
776783
}
777784

@@ -856,6 +863,11 @@ void VPRegionBlock::print(raw_ostream &O, const Twine &Indent,
856863
VPSlotTracker &SlotTracker) const {
857864
O << Indent << (isReplicator() ? "<xVFxUF> " : "<x1> ") << getName() << ": {";
858865
auto NewIndent = Indent + " ";
866+
if (auto *CanIV = getCanonicalIV()) {
867+
O << '\n';
868+
CanIV->print(O, SlotTracker);
869+
O << '\n';
870+
}
859871
for (auto *BlockBase : vp_depth_first_shallow(Entry)) {
860872
O << '\n';
861873
BlockBase->print(O, NewIndent, SlotTracker);
@@ -868,18 +880,37 @@ void VPRegionBlock::print(raw_ostream &O, const Twine &Indent,
868880

869881
void VPRegionBlock::dissolveToCFGLoop() {
870882
auto *Header = cast<VPBasicBlock>(getEntry());
871-
if (auto *CanIV = dyn_cast<VPCanonicalIVPHIRecipe>(&Header->front())) {
872-
assert(this == getPlan()->getVectorLoopRegion() &&
873-
"Canonical IV must be in the entry of the top-level loop region");
874-
auto *ScalarR = VPBuilder(CanIV).createScalarPhi(
875-
{CanIV->getStartValue(), CanIV->getBackedgeValue()},
876-
CanIV->getDebugLoc(), "index");
883+
auto *ExitingLatch = cast<VPBasicBlock>(getExiting());
884+
VPValue *CanIV = getCanonicalIV();
885+
if (CanIV && CanIV->getNumUsers() > 0) {
886+
auto *ExitingTerm = ExitingLatch->getTerminator();
887+
VPInstruction *CanIVInc = nullptr;
888+
// Check if there's a canonical IV increment via an existing terminator.
889+
if (match(ExitingTerm,
890+
m_BranchOnCount(m_VPInstruction(CanIVInc), m_VPValue()))) {
891+
assert(match(CanIVInc,
892+
m_Add(m_CombineOr(m_Specific(CanIV),
893+
m_Add(m_Specific(CanIV), m_LiveIn())),
894+
m_VPValue())) &&
895+
"invalid existing IV increment");
896+
}
897+
VPlan &Plan = *getPlan();
898+
if (!CanIVInc) {
899+
CanIVInc = VPBuilder(ExitingTerm)
900+
.createOverflowingOp(
901+
Instruction::Add, {CanIV, &Plan.getVFxUF()},
902+
{CanIVInfo.HasNUW, false}, CanIVInfo.DL, "index.next");
903+
}
904+
Type *CanIVTy = VPTypeAnalysis(Plan).inferScalarType(CanIV);
905+
auto *ScalarR =
906+
VPBuilder(Header, Header->begin())
907+
.createScalarPhi(
908+
{Plan.getOrAddLiveIn(ConstantInt::get(CanIVTy, 0)), CanIVInc},
909+
CanIVInfo.DL, "index");
877910
CanIV->replaceAllUsesWith(ScalarR);
878-
CanIV->eraseFromParent();
879911
}
880912

881913
VPBlockBase *Preheader = getSinglePredecessor();
882-
auto *ExitingLatch = cast<VPBasicBlock>(getExiting());
883914
VPBlockBase *Middle = getSingleSuccessor();
884915
VPBlockUtils::disconnectBlocks(Preheader, this);
885916
VPBlockUtils::disconnectBlocks(this, Middle);
@@ -916,7 +947,10 @@ VPlan::~VPlan() {
916947
for (unsigned I = 0, E = R.getNumOperands(); I != E; I++)
917948
R.setOperand(I, &DummyValue);
918949
}
950+
} else if (auto *CanIV = cast<VPRegionBlock>(VPB)->getCanonicalIV()) {
951+
CanIV->replaceAllUsesWith(&DummyValue);
919952
}
953+
920954
delete VPB;
921955
}
922956
for (VPValue *VPV : getLiveIns())
@@ -1224,6 +1258,11 @@ VPlan *VPlan::duplicate() {
12241258
// else NewTripCount will be created and inserted into Old2NewVPValues when
12251259
// TripCount is cloned. In any case NewPlan->TripCount is updated below.
12261260

1261+
if (auto *LoopRegion = getVectorLoopRegion()) {
1262+
Old2NewVPValues[LoopRegion->getCanonicalIV()] =
1263+
NewPlan->getVectorLoopRegion()->getCanonicalIV();
1264+
}
1265+
12271266
remapOperands(Entry, NewEntry, Old2NewVPValues);
12281267

12291268
// Initialize remaining fields of cloned VPlan.
@@ -1404,6 +1443,8 @@ void VPlanPrinter::dumpRegion(const VPRegionBlock *Region) {
14041443
/// Returns true if there is a vector loop region and \p VPV is defined in a
14051444
/// loop region.
14061445
static bool isDefinedInsideLoopRegions(const VPValue *VPV) {
1446+
if (isa<VPRegionValue>(VPV))
1447+
return true;
14071448
const VPRecipeBase *DefR = VPV->getDefiningRecipe();
14081449
return DefR && (!DefR->getParent()->getPlan()->getVectorLoopRegion() ||
14091450
DefR->getParent()->getEnclosingLoopRegion());
@@ -1513,9 +1554,12 @@ void VPSlotTracker::assignNames(const VPlan &Plan) {
15131554

15141555
ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<const VPBlockBase *>>
15151556
RPOT(VPBlockDeepTraversalWrapper<const VPBlockBase *>(Plan.getEntry()));
1516-
for (const VPBasicBlock *VPBB :
1517-
VPBlockUtils::blocksOnly<const VPBasicBlock>(RPOT))
1518-
assignNames(VPBB);
1557+
for (const VPBlockBase *VPB : RPOT) {
1558+
if (auto *VPBB = dyn_cast<VPBasicBlock>(VPB)) {
1559+
assignNames(VPBB);
1560+
} else if (auto *CanIV = cast<VPRegionBlock>(VPB)->getCanonicalIV())
1561+
assignName(CanIV);
1562+
}
15191563
}
15201564

15211565
void VPSlotTracker::assignNames(const VPBasicBlock *VPBB) {

0 commit comments

Comments
 (0)