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
|
||||
/// 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.
|
||||
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
|
||||
// original loop is widened to a vector form so we can use them to construct
|
||||
// the incoming edges.
|
||||
for (PHINode &Phi : OrigLoop->getHeader()->phis()) {
|
||||
// Handle first-order recurrences and reductions that need to be fixed.
|
||||
if (Legal->isFirstOrderRecurrence(&Phi))
|
||||
fixFirstOrderRecurrence(&Phi, State);
|
||||
else if (Legal->isReductionVariable(&Phi))
|
||||
fixReduction(&Phi, State);
|
||||
VPBasicBlock *Header = State.Plan->getEntry()->getEntryBasicBlock();
|
||||
for (VPRecipeBase &R : Header->phis()) {
|
||||
auto *PhiR = dyn_cast<VPWidenPHIRecipe>(&R);
|
||||
if (!PhiR)
|
||||
continue;
|
||||
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();
|
||||
}
|
||||
|
||||
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.
|
||||
assert(Legal->isReductionVariable(Phi) &&
|
||||
assert(Legal->isReductionVariable(OrigPhi) &&
|
||||
"Unable to find the reduction variable");
|
||||
RecurrenceDescriptor RdxDesc = Legal->getReductionVars()[Phi];
|
||||
RecurrenceDescriptor RdxDesc = *PhiR->getRecurrenceDescriptor();
|
||||
|
||||
RecurKind RK = RdxDesc.getRecurrenceKind();
|
||||
TrackingVH<Value> ReductionStartValue = RdxDesc.getRecurrenceStartValue();
|
||||
Instruction *LoopExitInst = RdxDesc.getLoopExitInstr();
|
||||
setDebugLocFromInst(Builder, ReductionStartValue);
|
||||
bool IsInLoopReductionPhi = Cost->isInLoopReduction(Phi);
|
||||
bool IsInLoopReductionPhi = Cost->isInLoopReduction(OrigPhi);
|
||||
|
||||
VPValue *LoopExitInstDef = State.Plan->getVPValue(LoopExitInst);
|
||||
// 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
|
||||
// any loop invariant values.
|
||||
BasicBlock *OrigLatch = OrigLoop->getLoopLatch();
|
||||
Value *OrigLoopVal = Phi->getIncomingValueForBlock(OrigLatch);
|
||||
Value *OrigLoopVal = OrigPhi->getIncomingValueForBlock(OrigLatch);
|
||||
BasicBlock *VectorLoopLatch = LI->getLoopFor(LoopVectorBody)->getLoopLatch();
|
||||
|
||||
bool IsOrdered = State.VF.isVector() && IsInLoopReductionPhi &&
|
||||
|
@ -4298,7 +4304,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
|
|||
for (unsigned Part = 0; Part < UF; ++Part) {
|
||||
if (IsOrdered && Part > 0)
|
||||
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);
|
||||
if (IsOrdered)
|
||||
Val = State.get(State.Plan->getVPValue(OrigLoopVal), UF - 1);
|
||||
|
@ -4313,7 +4319,7 @@ void InnerLoopVectorizer::fixReduction(PHINode *Phi, VPTransformState &State) {
|
|||
|
||||
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
|
||||
// a Select choosing between the vectorized LoopExitInst and vectorized Phi,
|
||||
// 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,
|
||||
TargetTransformInfo::ReductionFlags())) {
|
||||
auto *VecRdxPhi =
|
||||
cast<PHINode>(State.get(State.Plan->getVPValue(Phi), Part));
|
||||
cast<PHINode>(State.get(PhiR->getVPSingleValue(), Part));
|
||||
VecRdxPhi->setIncomingValueForBlock(
|
||||
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
|
||||
// from the vector body and from the backedge value.
|
||||
int IncomingEdgeBlockIdx =
|
||||
Phi->getBasicBlockIndex(OrigLoop->getLoopLatch());
|
||||
OrigPhi->getBasicBlockIndex(OrigLoop->getLoopLatch());
|
||||
assert(IncomingEdgeBlockIdx >= 0 && "Invalid block index");
|
||||
// Pick the other block.
|
||||
int SelfEdgeBlockIdx = (IncomingEdgeBlockIdx ? 0 : 1);
|
||||
Phi->setIncomingValue(SelfEdgeBlockIdx, BCBlockPhi);
|
||||
Phi->setIncomingValue(IncomingEdgeBlockIdx, LoopExitInst);
|
||||
OrigPhi->setIncomingValue(SelfEdgeBlockIdx, BCBlockPhi);
|
||||
OrigPhi->setIncomingValue(IncomingEdgeBlockIdx, LoopExitInst);
|
||||
}
|
||||
|
||||
void InnerLoopVectorizer::clearReductionWrapFlags(RecurrenceDescriptor &RdxDesc,
|
||||
|
|
|
@ -1051,6 +1051,8 @@ public:
|
|||
|
||||
/// Returns the \p I th incoming VPBasicBlock.
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue