Skip to content

Commit 2b7fa7f

Browse files
committed
[LV] Iterate over recipes in VPlan to fix PHI (NFC).
As we gradually move more elements of LV to VPlan, we are trying to reduce the number of places that still has to check IR of the original loop. This patch adjusts the code to fix cross iteration phis to get the PHIs to fix directly from the VPlan that is executed. We still need the original PHI to check for first-order recurrences, but we can get rid of that once we model that explicitly in VPlan as well. Reviewed By: Ayal Differential Revision: https://reviews.llvm.org/D99293
1 parent 895ba21 commit 2b7fa7f

File tree

2 files changed

+26
-18
lines changed

2 files changed

+26
-18
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ class InnerLoopVectorizer {
599599

600600
/// Fix a reduction cross-iteration phi. This is the second phase of
601601
/// vectorizing this phi node.
602-
void fixReduction(PHINode *Phi, VPTransformState &State);
602+
void fixReduction(VPWidenPHIRecipe *Phi, VPTransformState &State);
603603

604604
/// Clear NSW/NUW flags from reduction instructions if necessary.
605605
void clearReductionWrapFlags(RecurrenceDescriptor &RdxDesc,
@@ -4065,12 +4065,16 @@ void InnerLoopVectorizer::fixCrossIterationPHIs(VPTransformState &State) {
40654065
// the currently empty PHI nodes. At this point every instruction in the
40664066
// original loop is widened to a vector form so we can use them to construct
40674067
// the incoming edges.
4068-
for (PHINode &Phi : OrigLoop->getHeader()->phis()) {
4069-
// Handle first-order recurrences and reductions that need to be fixed.
4070-
if (Legal->isFirstOrderRecurrence(&Phi))
4071-
fixFirstOrderRecurrence(&Phi, State);
4072-
else if (Legal->isReductionVariable(&Phi))
4073-
fixReduction(&Phi, State);
4068+
VPBasicBlock *Header = State.Plan->getEntry()->getEntryBasicBlock();
4069+
for (VPRecipeBase &R : Header->phis()) {
4070+
auto *PhiR = dyn_cast<VPWidenPHIRecipe>(&R);
4071+
if (!PhiR)
4072+
continue;
4073+
auto *OrigPhi = cast<PHINode>(PhiR->getUnderlyingValue());
4074+
if (PhiR->getRecurrenceDescriptor()) {
4075+
fixReduction(PhiR, State);
4076+
} else if (Legal->isFirstOrderRecurrence(OrigPhi))
4077+
fixFirstOrderRecurrence(OrigPhi, State);
40744078
}
40754079
}
40764080

@@ -4265,17 +4269,19 @@ static bool useOrderedReductions(RecurrenceDescriptor &RdxDesc) {
42654269
return EnableStrictReductions && RdxDesc.isOrdered();
42664270
}
42674271

4268-
void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
4272+
void InnerLoopVectorizer::fixReduction(VPWidenPHIRecipe *PhiR,
4273+
VPTransformState &State) {
4274+
PHINode *OrigPhi = cast<PHINode>(PhiR->getUnderlyingValue());
42694275
// Get it's reduction variable descriptor.
4270-
assert(Legal->isReductionVariable(Phi) &&
4276+
assert(Legal->isReductionVariable(OrigPhi) &&
42714277
"Unable to find the reduction variable");
4272-
RecurrenceDescriptor RdxDesc = Legal->getReductionVars()[Phi];
4278+
RecurrenceDescriptor RdxDesc = *PhiR->getRecurrenceDescriptor();
42734279

42744280
RecurKind RK = RdxDesc.getRecurrenceKind();
42754281
TrackingVH<Value> ReductionStartValue = RdxDesc.getRecurrenceStartValue();
42764282
Instruction *LoopExitInst = RdxDesc.getLoopExitInstr();
42774283
setDebugLocFromInst(Builder, ReductionStartValue);
4278-
bool IsInLoopReductionPhi = Cost->isInLoopReduction(Phi);
4284+
bool IsInLoopReductionPhi = Cost->isInLoopReduction(OrigPhi);
42794285

42804286
VPValue *LoopExitInstDef = State.Plan->getVPValue(LoopExitInst);
42814287
// This is the vector-clone of the value that leaves the loop.
@@ -4289,7 +4295,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
42894295
// Reductions do not have to start at zero. They can start with
42904296
// any loop invariant values.
42914297
BasicBlock *OrigLatch = OrigLoop->getLoopLatch();
4292-
Value *OrigLoopVal = Phi->getIncomingValueForBlock(OrigLatch);
4298+
Value *OrigLoopVal = OrigPhi->getIncomingValueForBlock(OrigLatch);
42934299
BasicBlock *VectorLoopLatch = LI->getLoopFor(LoopVectorBody)->getLoopLatch();
42944300

42954301
bool IsOrdered = State.VF.isVector() && IsInLoopReductionPhi &&
@@ -4298,7 +4304,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
42984304
for (unsigned Part = 0; Part < UF; ++Part) {
42994305
if (IsOrdered && Part > 0)
43004306
break;
4301-
Value *VecRdxPhi = State.get(State.Plan->getVPValue(Phi), Part);
4307+
Value *VecRdxPhi = State.get(PhiR->getVPSingleValue(), Part);
43024308
Value *Val = State.get(State.Plan->getVPValue(OrigLoopVal), Part);
43034309
if (IsOrdered)
43044310
Val = State.get(State.Plan->getVPValue(OrigLoopVal), UF - 1);
@@ -4313,7 +4319,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
43134319

43144320
setDebugLocFromInst(Builder, LoopExitInst);
43154321

4316-
Type *PhiTy = Phi->getType();
4322+
Type *PhiTy = OrigPhi->getType();
43174323
// If tail is folded by masking, the vector value to leave the loop should be
43184324
// a Select choosing between the vectorized LoopExitInst and vectorized Phi,
43194325
// instead of the former. For an inloop reduction the reduction will already
@@ -4342,7 +4348,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
43424348
RdxDesc.getOpcode(), PhiTy,
43434349
TargetTransformInfo::ReductionFlags())) {
43444350
auto *VecRdxPhi =
4345-
cast<PHINode>(State.get(State.Plan->getVPValue(Phi), Part));
4351+
cast<PHINode>(State.get(PhiR->getVPSingleValue(), Part));
43464352
VecRdxPhi->setIncomingValueForBlock(
43474353
LI->getLoopFor(LoopVectorBody)->getLoopLatch(), Sel);
43484354
}
@@ -4444,12 +4450,12 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
44444450
// Fix the scalar loop reduction variable with the incoming reduction sum
44454451
// from the vector body and from the backedge value.
44464452
int IncomingEdgeBlockIdx =
4447-
Phi->getBasicBlockIndex(OrigLoop->getLoopLatch());
4453+
OrigPhi->getBasicBlockIndex(OrigLoop->getLoopLatch());
44484454
assert(IncomingEdgeBlockIdx >= 0 && "Invalid block index");
44494455
// Pick the other block.
44504456
int SelfEdgeBlockIdx = (IncomingEdgeBlockIdx ? 0 : 1);
4451-
Phi->setIncomingValue(SelfEdgeBlockIdx, BCBlockPhi);
4452-
Phi->setIncomingValue(IncomingEdgeBlockIdx, LoopExitInst);
4457+
OrigPhi->setIncomingValue(SelfEdgeBlockIdx, BCBlockPhi);
4458+
OrigPhi->setIncomingValue(IncomingEdgeBlockIdx, LoopExitInst);
44534459
}
44544460

44554461
void InnerLoopVectorizer::clearReductionWrapFlags(RecurrenceDescriptor &RdxDesc,

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,8 @@ class VPWidenPHIRecipe : public VPRecipeBase, public VPValue {
10511051

10521052
/// Returns the \p I th incoming VPBasicBlock.
10531053
VPBasicBlock *getIncomingBlock(unsigned I) { return IncomingBlocks[I]; }
1054+
1055+
RecurrenceDescriptor *getRecurrenceDescriptor() { return RdxDesc; }
10541056
};
10551057

10561058
/// A recipe for vectorizing a phi-node as a sequence of mask-based select

0 commit comments

Comments
 (0)