-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[VPlan] Simplify branch on False in VPlan transform (NFC). #140409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
063d70f
f5ee27b
74eddb5
61779cf
801b98d
069767b
d3df2c3
3f3f002
69ad1de
9233672
6ced27d
2b76566
5797781
761d4ca
ff89acf
fa0eab1
57652c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2379,13 +2379,15 @@ void InnerLoopVectorizer::introduceCheckBlockInVPlan(BasicBlock *CheckIRBB) { | |||||||||||||||||||||||||
| PreVectorPH->swapSuccessors(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // We just connected a new block to the scalar preheader. Update all | ||||||||||||||||||||||||||
| // ResumePhis by adding an incoming value for it, replicating the last value. | ||||||||||||||||||||||||||
| for (VPRecipeBase &R : *cast<VPBasicBlock>(ScalarPH)) { | ||||||||||||||||||||||||||
| auto *ResumePhi = dyn_cast<VPInstruction>(&R); | ||||||||||||||||||||||||||
| if (!ResumePhi || ResumePhi->getOpcode() != VPInstruction::ResumePhi) | ||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||
| // VPPhis by adding an incoming value for it, replicating the last value. | ||||||||||||||||||||||||||
| unsigned NumPredecessors = ScalarPH->getNumPredecessors(); | ||||||||||||||||||||||||||
| (void)NumPredecessors; | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
| (void)NumPredecessors; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed thanks
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| (void)NumPredecessors; | |
| for (VPRecipeBase &R : cast<VPBasicBlock>(ScalarPH)->phis()) { | |
| auto *ResumePhi = cast<VPPhi>(&R); | |
| ResumePhi->addOperand( | |
| ResumePhi->getOperand(ResumePhi->getNumOperands() - 1)); | |
| assert(ResumePhi->getNumIncoming() == NumPredecessors && | |
| "must have incoming values for all operands"); | |
| for (VPRecipeBase &R : cast<VPBasicBlock>(ScalarPH)->phis()) { | |
| assert(isa<VPPhi>(&R) && "Phi expected to be VPPhi"); | |
| assert(cast<VPPhi>(&R)->getNumIncoming() == NumPredecessors - 1 && | |
| "must have incoming values for all operands"); | |
| R->addOperand(R->getOperand(NumPredecessors - 1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated thanks
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -887,11 +887,6 @@ class VPInstruction : public VPRecipeWithIRFlags, | |||||
| SLPStore, | ||||||
| ActiveLaneMask, | ||||||
| ExplicitVectorLength, | ||||||
| /// Creates a scalar phi in a leaf VPBB with a single predecessor in VPlan. | ||||||
| /// The first operand is the incoming value from the predecessor in VPlan, | ||||||
| /// the second operand is the incoming value for all other predecessors | ||||||
| /// (which are currently not modeled in VPlan). | ||||||
| ResumePhi, | ||||||
| CalculateTripCountMinusVF, | ||||||
| // Increment the canonical IV separately for each unrolled part. | ||||||
| CanonicalIVIncrementForPart, | ||||||
|
|
@@ -1127,6 +1122,10 @@ class VPPhiAccessors { | |||||
| return getAsRecipe()->getNumOperands(); | ||||||
| } | ||||||
|
|
||||||
| /// Removes the incoming value corresponding to \p IncomingBlock, which must | ||||||
| /// be a predecessor. | ||||||
| void removeIncomingValue(VPBlockBase *IncomingBlock) const; | ||||||
|
||||||
| void removeIncomingValue(VPBlockBase *IncomingBlock) const; | |
| void removeIncomingValueFor(VPBlockBase *IncomingBlock) const; |
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -501,8 +501,10 @@ void VPlanTransforms::prepareForVectorization( | |||||
| cast<VPBasicBlock>(HeaderVPB), | ||||||
| cast<VPBasicBlock>(LatchVPB), Range); | ||||||
| HandledUncountableEarlyExit = true; | ||||||
| } else { | ||||||
| for (VPRecipeBase &R : EB->phis()) | ||||||
| cast<VPIRPhi>(&R)->removeIncomingValue(Pred); | ||||||
| } | ||||||
|
|
||||||
| cast<VPBasicBlock>(Pred)->getTerminator()->eraseFromParent(); | ||||||
| VPBlockUtils::disconnectBlocks(Pred, EB); | ||||||
| } | ||||||
|
|
@@ -526,56 +528,51 @@ void VPlanTransforms::prepareForVectorization( | |||||
| VPBasicBlock *ScalarPH = Plan.createVPBasicBlock("scalar.ph"); | ||||||
| VPBlockUtils::connectBlocks(ScalarPH, Plan.getScalarHeader()); | ||||||
|
|
||||||
| // If needed, add a check in the middle block to see if we have completed | ||||||
| // all of the iterations in the first vector loop. Three cases: | ||||||
| // 1) If we require a scalar epilogue, there is no conditional branch as | ||||||
| // we unconditionally branch to the scalar preheader. Remove the recipes | ||||||
| // from the exit blocks. | ||||||
| // 2) If (N - N%VF) == N, then we *don't* need to run the remainder. | ||||||
| // Thus if tail is to be folded, we know we don't need to run the | ||||||
| // remainder and we can set the condition to true. | ||||||
| // 3) Otherwise, construct a runtime check. | ||||||
|
|
||||||
| if (!RequiresScalarEpilogueCheck) { | ||||||
| if (auto *LatchExitVPB = MiddleVPBB->getSingleSuccessor()) | ||||||
| VPBlockUtils::disconnectBlocks(MiddleVPBB, LatchExitVPB); | ||||||
| VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH); | ||||||
| VPBlockUtils::connectBlocks(Plan.getEntry(), ScalarPH); | ||||||
| Plan.getEntry()->swapSuccessors(); | ||||||
|
|
||||||
| // The exit blocks are unreachable, remove their recipes to make sure no | ||||||
| // users remain that may pessimize transforms. | ||||||
| for (auto *EB : Plan.getExitBlocks()) { | ||||||
| for (VPRecipeBase &R : make_early_inc_range(*EB)) | ||||||
| R.eraseFromParent(); | ||||||
| } | ||||||
| return; | ||||||
| } | ||||||
|
|
||||||
| // The connection order corresponds to the operands of the conditional branch, | ||||||
| // with the middle block already connected to the exit block. | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Above two lines should be discarded? Or updated to end with "if needed"?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dropped by accident, restored, thanks |
||||||
| VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH); | ||||||
| // Also connect the entry block to the scalar preheader. | ||||||
| // TODO: Also introduce a branch recipe together with the minimum trip count | ||||||
| // check. | ||||||
| VPBlockUtils::connectBlocks(Plan.getEntry(), ScalarPH); | ||||||
| Plan.getEntry()->swapSuccessors(); | ||||||
|
|
||||||
| auto *ScalarLatchTerm = TheLoop->getLoopLatch()->getTerminator(); | ||||||
| // Here we use the same DebugLoc as the scalar loop latch terminator instead | ||||||
| // of the corresponding compare because they may have ended up with | ||||||
| // different line numbers and we want to avoid awkward line stepping while | ||||||
| // debugging. Eg. if the compare has got a line number inside the loop. | ||||||
| // If MiddleVPBB has a single successor the original loop exits via the latch | ||||||
|
||||||
| // If MiddleVPBB has a single successor the original loop exits via the latch | |
| // If MiddleVPBB has a single successor then the original loop does not exit via the latch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // If needed, add a check in the middle block to see if we have completed | |
| // Add a check in the middle block to see if we have completed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -733,17 +733,6 @@ Value *VPInstruction::generate(VPTransformState &State) { | |
| Value *Addend = State.get(getOperand(1), VPLane(0)); | ||
| return Builder.CreatePtrAdd(Ptr, Addend, Name, getGEPNoWrapFlags()); | ||
| } | ||
| case VPInstruction::ResumePhi: { | ||
| auto *NewPhi = | ||
| Builder.CreatePHI(State.TypeAnalysis.inferScalarType(this), 2, Name); | ||
| for (const auto &[IncVPV, PredVPBB] : | ||
| zip(operands(), getParent()->getPredecessors())) { | ||
| Value *IncV = State.get(IncVPV, /* IsScalar */ true); | ||
| BasicBlock *PredBB = State.CFG.VPBB2IRBB.at(cast<VPBasicBlock>(PredVPBB)); | ||
| NewPhi->addIncoming(IncV, PredBB); | ||
| } | ||
| return NewPhi; | ||
| } | ||
| case VPInstruction::AnyOf: { | ||
| Value *A = State.get(getOperand(0)); | ||
| return Builder.CreateOrReduce(A); | ||
|
|
@@ -847,8 +836,7 @@ bool VPInstruction::isVectorToScalar() const { | |
| } | ||
|
|
||
| bool VPInstruction::isSingleScalar() const { | ||
| return getOpcode() == VPInstruction::ResumePhi || | ||
| getOpcode() == Instruction::PHI; | ||
| return getOpcode() == Instruction::PHI; | ||
| } | ||
|
|
||
| void VPInstruction::execute(VPTransformState &State) { | ||
|
|
@@ -934,7 +922,6 @@ bool VPInstruction::onlyFirstLaneUsed(const VPValue *Op) const { | |
| case VPInstruction::CanonicalIVIncrementForPart: | ||
| case VPInstruction::BranchOnCount: | ||
| case VPInstruction::BranchOnCond: | ||
| case VPInstruction::ResumePhi: | ||
| return true; | ||
| case VPInstruction::PtrAdd: | ||
| return Op == getOperand(0) || vputils::onlyFirstLaneUsed(this); | ||
|
|
@@ -991,9 +978,6 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent, | |
| case VPInstruction::ActiveLaneMask: | ||
| O << "active lane mask"; | ||
| break; | ||
| case VPInstruction::ResumePhi: | ||
| O << "resume-phi"; | ||
| break; | ||
| case VPInstruction::ExplicitVectorLength: | ||
| O << "EXPLICIT-VECTOR-LENGTH"; | ||
| break; | ||
|
|
@@ -1101,21 +1085,36 @@ void VPInstructionWithType::print(raw_ostream &O, const Twine &Indent, | |
|
|
||
| void VPPhi::execute(VPTransformState &State) { | ||
| State.setDebugLocFrom(getDebugLoc()); | ||
| BasicBlock *VectorPH = State.CFG.VPBB2IRBB.at(getIncomingBlock(0)); | ||
| Value *Start = State.get(getIncomingValue(0), VPLane(0)); | ||
| PHINode *Phi = State.Builder.CreatePHI(Start->getType(), 2, getName()); | ||
| Phi->addIncoming(Start, VectorPH); | ||
| State.set(this, Phi, VPLane(0)); | ||
| PHINode *NewPhi = State.Builder.CreatePHI( | ||
| State.TypeAnalysis.inferScalarType(this), 2, getName()); | ||
| unsigned NumIncoming = getNumIncoming(); | ||
| if (getParent() != getParent()->getPlan()->getScalarPreheader()) { | ||
| // TODO: Fixup all incoming values of header phis once recipes defining them | ||
| // are introduced. | ||
| NumIncoming = 1; | ||
| } | ||
| for (unsigned Idx = 0; Idx != NumIncoming; ++Idx) { | ||
| Value *IncV = State.get(getIncomingValue(Idx), VPLane(0)); | ||
| BasicBlock *PredBB = State.CFG.VPBB2IRBB.at(getIncomingBlock(Idx)); | ||
| NewPhi->addIncoming(IncV, PredBB); | ||
| } | ||
| State.set(this, NewPhi, VPLane(0)); | ||
| } | ||
|
|
||
| #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||
| void VPPhi::print(raw_ostream &O, const Twine &Indent, | ||
| VPSlotTracker &SlotTracker) const { | ||
| O << Indent << "EMIT" << (isSingleScalar() ? "-SCALAR" : "") << " "; | ||
| printAsOperand(O, SlotTracker); | ||
| O << " = phi "; | ||
|
|
||
| printPhiOperands(O, SlotTracker); | ||
| const VPBasicBlock *Parent = getParent(); | ||
| if (Parent == Parent->getPlan()->getScalarPreheader()) { | ||
| // TODO: Use regular printing for resume-phis as well | ||
| O << " = resume-phi "; | ||
| printOperands(O, SlotTracker); | ||
| } else { | ||
| O << " = phi "; | ||
| printPhiOperands(O, SlotTracker); | ||
| } | ||
| } | ||
| #endif | ||
|
|
||
|
|
@@ -1186,6 +1185,16 @@ void VPIRPhi::execute(VPTransformState &State) { | |
| State.Builder.SetInsertPoint(Phi->getParent(), std::next(Phi->getIterator())); | ||
| } | ||
|
|
||
| void VPPhiAccessors::removeIncomingValue(VPBlockBase *IncomingBlock) const { | ||
| VPRecipeBase *R = const_cast<VPRecipeBase *>(getAsRecipe()); | ||
| auto &Preds = R->getParent()->getPredecessors(); | ||
| assert(R->getNumOperands() == Preds.size() && | ||
| "Number of phi operands must match number of predecessors"); | ||
| unsigned Position = std::distance(Preds.begin(), find(Preds, IncomingBlock)); | ||
|
||
| R->getOperand(Position)->removeUser(*R); | ||
| R->removeOperand(Position); | ||
|
||
| } | ||
|
|
||
| #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | ||
| void VPPhiAccessors::printPhiOperands(raw_ostream &O, | ||
| VPSlotTracker &SlotTracker) const { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: take the number of ScalarPH predecessors once, here, reuse it repeatedly inside the loop, asserting it is one more than the number of ResumePhi's operands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, thanks