forked from OSchip/llvm-project
[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
This commit is contained in:
parent
895ba21401
commit
2b7fa7f744
|
@ -599,7 +599,7 @@ protected:
|
||||||
|
|
||||||
/// Fix a reduction cross-iteration phi. This is the second phase of
|
/// Fix a reduction cross-iteration phi. This is the second phase of
|
||||||
/// vectorizing this phi node.
|
/// vectorizing this phi node.
|
||||||
void fixReduction(PHINode *Phi, VPTransformState &State);
|
void fixReduction(VPWidenPHIRecipe *Phi, VPTransformState &State);
|
||||||
|
|
||||||
/// Clear NSW/NUW flags from reduction instructions if necessary.
|
/// Clear NSW/NUW flags from reduction instructions if necessary.
|
||||||
void clearReductionWrapFlags(RecurrenceDescriptor &RdxDesc,
|
void clearReductionWrapFlags(RecurrenceDescriptor &RdxDesc,
|
||||||
|
@ -4065,12 +4065,16 @@ void InnerLoopVectorizer::fixCrossIterationPHIs(VPTransformState &State) {
|
||||||
// the currently empty PHI nodes. At this point every instruction in the
|
// the currently empty PHI nodes. At this point every instruction in the
|
||||||
// original loop is widened to a vector form so we can use them to construct
|
// original loop is widened to a vector form so we can use them to construct
|
||||||
// the incoming edges.
|
// the incoming edges.
|
||||||
for (PHINode &Phi : OrigLoop->getHeader()->phis()) {
|
VPBasicBlock *Header = State.Plan->getEntry()->getEntryBasicBlock();
|
||||||
// Handle first-order recurrences and reductions that need to be fixed.
|
for (VPRecipeBase &R : Header->phis()) {
|
||||||
if (Legal->isFirstOrderRecurrence(&Phi))
|
auto *PhiR = dyn_cast<VPWidenPHIRecipe>(&R);
|
||||||
fixFirstOrderRecurrence(&Phi, State);
|
if (!PhiR)
|
||||||
else if (Legal->isReductionVariable(&Phi))
|
continue;
|
||||||
fixReduction(&Phi, State);
|
auto *OrigPhi = cast<PHINode>(PhiR->getUnderlyingValue());
|
||||||
|
if (PhiR->getRecurrenceDescriptor()) {
|
||||||
|
fixReduction(PhiR, State);
|
||||||
|
} else if (Legal->isFirstOrderRecurrence(OrigPhi))
|
||||||
|
fixFirstOrderRecurrence(OrigPhi, State);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4265,17 +4269,19 @@ static bool useOrderedReductions(RecurrenceDescriptor &RdxDesc) {
|
||||||
return EnableStrictReductions && RdxDesc.isOrdered();
|
return EnableStrictReductions && RdxDesc.isOrdered();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
|
void InnerLoopVectorizer::fixReduction(VPWidenPHIRecipe *PhiR,
|
||||||
|
VPTransformState &State) {
|
||||||
|
PHINode *OrigPhi = cast<PHINode>(PhiR->getUnderlyingValue());
|
||||||
// Get it's reduction variable descriptor.
|
// Get it's reduction variable descriptor.
|
||||||
assert(Legal->isReductionVariable(Phi) &&
|
assert(Legal->isReductionVariable(OrigPhi) &&
|
||||||
"Unable to find the reduction variable");
|
"Unable to find the reduction variable");
|
||||||
RecurrenceDescriptor RdxDesc = Legal->getReductionVars()[Phi];
|
RecurrenceDescriptor RdxDesc = *PhiR->getRecurrenceDescriptor();
|
||||||
|
|
||||||
RecurKind RK = RdxDesc.getRecurrenceKind();
|
RecurKind RK = RdxDesc.getRecurrenceKind();
|
||||||
TrackingVH<Value> ReductionStartValue = RdxDesc.getRecurrenceStartValue();
|
TrackingVH<Value> ReductionStartValue = RdxDesc.getRecurrenceStartValue();
|
||||||
Instruction *LoopExitInst = RdxDesc.getLoopExitInstr();
|
Instruction *LoopExitInst = RdxDesc.getLoopExitInstr();
|
||||||
setDebugLocFromInst(Builder, ReductionStartValue);
|
setDebugLocFromInst(Builder, ReductionStartValue);
|
||||||
bool IsInLoopReductionPhi = Cost->isInLoopReduction(Phi);
|
bool IsInLoopReductionPhi = Cost->isInLoopReduction(OrigPhi);
|
||||||
|
|
||||||
VPValue *LoopExitInstDef = State.Plan->getVPValue(LoopExitInst);
|
VPValue *LoopExitInstDef = State.Plan->getVPValue(LoopExitInst);
|
||||||
// This is the vector-clone of the value that leaves the loop.
|
// This is the vector-clone of the value that leaves the loop.
|
||||||
|
@ -4289,7 +4295,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
|
||||||
// Reductions do not have to start at zero. They can start with
|
// Reductions do not have to start at zero. They can start with
|
||||||
// any loop invariant values.
|
// any loop invariant values.
|
||||||
BasicBlock *OrigLatch = OrigLoop->getLoopLatch();
|
BasicBlock *OrigLatch = OrigLoop->getLoopLatch();
|
||||||
Value *OrigLoopVal = Phi->getIncomingValueForBlock(OrigLatch);
|
Value *OrigLoopVal = OrigPhi->getIncomingValueForBlock(OrigLatch);
|
||||||
BasicBlock *VectorLoopLatch = LI->getLoopFor(LoopVectorBody)->getLoopLatch();
|
BasicBlock *VectorLoopLatch = LI->getLoopFor(LoopVectorBody)->getLoopLatch();
|
||||||
|
|
||||||
bool IsOrdered = State.VF.isVector() && IsInLoopReductionPhi &&
|
bool IsOrdered = State.VF.isVector() && IsInLoopReductionPhi &&
|
||||||
|
@ -4298,7 +4304,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
|
||||||
for (unsigned Part = 0; Part < UF; ++Part) {
|
for (unsigned Part = 0; Part < UF; ++Part) {
|
||||||
if (IsOrdered && Part > 0)
|
if (IsOrdered && Part > 0)
|
||||||
break;
|
break;
|
||||||
Value *VecRdxPhi = State.get(State.Plan->getVPValue(Phi), Part);
|
Value *VecRdxPhi = State.get(PhiR->getVPSingleValue(), Part);
|
||||||
Value *Val = State.get(State.Plan->getVPValue(OrigLoopVal), Part);
|
Value *Val = State.get(State.Plan->getVPValue(OrigLoopVal), Part);
|
||||||
if (IsOrdered)
|
if (IsOrdered)
|
||||||
Val = State.get(State.Plan->getVPValue(OrigLoopVal), UF - 1);
|
Val = State.get(State.Plan->getVPValue(OrigLoopVal), UF - 1);
|
||||||
|
@ -4313,7 +4319,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
|
||||||
|
|
||||||
setDebugLocFromInst(Builder, LoopExitInst);
|
setDebugLocFromInst(Builder, LoopExitInst);
|
||||||
|
|
||||||
Type *PhiTy = Phi->getType();
|
Type *PhiTy = OrigPhi->getType();
|
||||||
// If tail is folded by masking, the vector value to leave the loop should be
|
// If tail is folded by masking, the vector value to leave the loop should be
|
||||||
// a Select choosing between the vectorized LoopExitInst and vectorized Phi,
|
// a Select choosing between the vectorized LoopExitInst and vectorized Phi,
|
||||||
// instead of the former. For an inloop reduction the reduction will already
|
// instead of the former. For an inloop reduction the reduction will already
|
||||||
|
@ -4342,7 +4348,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
|
||||||
RdxDesc.getOpcode(), PhiTy,
|
RdxDesc.getOpcode(), PhiTy,
|
||||||
TargetTransformInfo::ReductionFlags())) {
|
TargetTransformInfo::ReductionFlags())) {
|
||||||
auto *VecRdxPhi =
|
auto *VecRdxPhi =
|
||||||
cast<PHINode>(State.get(State.Plan->getVPValue(Phi), Part));
|
cast<PHINode>(State.get(PhiR->getVPSingleValue(), Part));
|
||||||
VecRdxPhi->setIncomingValueForBlock(
|
VecRdxPhi->setIncomingValueForBlock(
|
||||||
LI->getLoopFor(LoopVectorBody)->getLoopLatch(), Sel);
|
LI->getLoopFor(LoopVectorBody)->getLoopLatch(), Sel);
|
||||||
}
|
}
|
||||||
|
@ -4444,12 +4450,12 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
|
||||||
// Fix the scalar loop reduction variable with the incoming reduction sum
|
// Fix the scalar loop reduction variable with the incoming reduction sum
|
||||||
// from the vector body and from the backedge value.
|
// from the vector body and from the backedge value.
|
||||||
int IncomingEdgeBlockIdx =
|
int IncomingEdgeBlockIdx =
|
||||||
Phi->getBasicBlockIndex(OrigLoop->getLoopLatch());
|
OrigPhi->getBasicBlockIndex(OrigLoop->getLoopLatch());
|
||||||
assert(IncomingEdgeBlockIdx >= 0 && "Invalid block index");
|
assert(IncomingEdgeBlockIdx >= 0 && "Invalid block index");
|
||||||
// Pick the other block.
|
// Pick the other block.
|
||||||
int SelfEdgeBlockIdx = (IncomingEdgeBlockIdx ? 0 : 1);
|
int SelfEdgeBlockIdx = (IncomingEdgeBlockIdx ? 0 : 1);
|
||||||
Phi->setIncomingValue(SelfEdgeBlockIdx, BCBlockPhi);
|
OrigPhi->setIncomingValue(SelfEdgeBlockIdx, BCBlockPhi);
|
||||||
Phi->setIncomingValue(IncomingEdgeBlockIdx, LoopExitInst);
|
OrigPhi->setIncomingValue(IncomingEdgeBlockIdx, LoopExitInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerLoopVectorizer::clearReductionWrapFlags(RecurrenceDescriptor &RdxDesc,
|
void InnerLoopVectorizer::clearReductionWrapFlags(RecurrenceDescriptor &RdxDesc,
|
||||||
|
|
|
@ -1051,6 +1051,8 @@ public:
|
||||||
|
|
||||||
/// Returns the \p I th incoming VPBasicBlock.
|
/// Returns the \p I th incoming VPBasicBlock.
|
||||||
VPBasicBlock *getIncomingBlock(unsigned I) { return IncomingBlocks[I]; }
|
VPBasicBlock *getIncomingBlock(unsigned I) { return IncomingBlocks[I]; }
|
||||||
|
|
||||||
|
RecurrenceDescriptor *getRecurrenceDescriptor() { return RdxDesc; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A recipe for vectorizing a phi-node as a sequence of mask-based select
|
/// A recipe for vectorizing a phi-node as a sequence of mask-based select
|
||||||
|
|
Loading…
Reference in New Issue