Skip to content

Commit 0fa741c

Browse files
committed
[VPlan] Simplify branch to scalar ph in VPlan transform. (NFC)
Simplify branch on false, starting with the branch from the middle block to the scalar preheader. Depends on #140405.
1 parent 87d022a commit 0fa741c

File tree

4 files changed

+54
-34
lines changed

4 files changed

+54
-34
lines changed

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,8 @@ class VPPhiAccessors {
11551155
return getAsRecipe()->getNumOperands();
11561156
}
11571157

1158+
void removeIncomingValue(VPBlockBase *VPB) const;
1159+
11581160
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
11591161
/// Print the recipe.
11601162
void printPhiOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const;
@@ -3736,6 +3738,15 @@ VPPhiAccessors::getIncomingBlock(unsigned Idx) const {
37363738
return getAsRecipe()->getParent()->getCFGPredecessor(Idx);
37373739
}
37383740

3741+
inline void VPPhiAccessors::removeIncomingValue(VPBlockBase *VPB) const {
3742+
VPRecipeBase *R = const_cast<VPRecipeBase *>(getAsRecipe());
3743+
const VPBasicBlock *Parent = R->getParent();
3744+
assert(R->getNumOperands() == Parent->getNumPredecessors());
3745+
auto I = find(Parent->getPredecessors(), VPB);
3746+
R->getOperand(I - Parent->getPredecessors().begin())->removeUser(*R);
3747+
R->removeOperand(I - Parent->getPredecessors().begin());
3748+
}
3749+
37393750
/// A special type of VPBasicBlock that wraps an existing IR basic block.
37403751
/// Recipes of the block get added before the first non-phi instruction in the
37413752
/// wrapped block.

llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,12 @@ void VPlanTransforms::prepareForVectorization(
507507
cast<VPBasicBlock>(HeaderVPB),
508508
cast<VPBasicBlock>(LatchVPB), Range);
509509
HandledUncountableEarlyExit = true;
510+
} else {
511+
for (VPRecipeBase &R : cast<VPIRBasicBlock>(EB)->phis()) {
512+
if (auto *PhiR = dyn_cast<VPIRPhi>(&R))
513+
PhiR->removeIncomingValue(Pred);
514+
}
510515
}
511-
512516
cast<VPBasicBlock>(Pred)->getTerminator()->eraseFromParent();
513517
VPBlockUtils::disconnectBlocks(Pred, EB);
514518
}
@@ -541,43 +545,31 @@ void VPlanTransforms::prepareForVectorization(
541545
// Thus if tail is to be folded, we know we don't need to run the
542546
// remainder and we can set the condition to true.
543547
// 3) Otherwise, construct a runtime check.
544-
545-
if (!RequiresScalarEpilogueCheck) {
546-
if (auto *LatchExitVPB = MiddleVPBB->getSingleSuccessor())
547-
VPBlockUtils::disconnectBlocks(MiddleVPBB, LatchExitVPB);
548-
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
549-
VPBlockUtils::connectBlocks(Plan.getEntry(), ScalarPH);
550-
Plan.getEntry()->swapSuccessors();
551-
552-
// The exit blocks are unreachable, remove their recipes to make sure no
553-
// users remain that may pessimize transforms.
554-
for (auto *EB : Plan.getExitBlocks()) {
555-
for (VPRecipeBase &R : make_early_inc_range(*EB))
556-
R.eraseFromParent();
557-
}
558-
return;
559-
}
560-
561-
// The connection order corresponds to the operands of the conditional branch,
562-
// with the middle block already connected to the exit block.
563548
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
564549
// Also connect the entry block to the scalar preheader.
565550
VPBlockUtils::connectBlocks(Plan.getEntry(), ScalarPH);
566551
Plan.getEntry()->swapSuccessors();
567552

553+
if (MiddleVPBB->getNumSuccessors() != 2)
554+
return;
555+
568556
auto *ScalarLatchTerm = TheLoop->getLoopLatch()->getTerminator();
569557
// Here we use the same DebugLoc as the scalar loop latch terminator instead
570558
// of the corresponding compare because they may have ended up with
571559
// different line numbers and we want to avoid awkward line stepping while
572560
// debugging. Eg. if the compare has got a line number inside the loop.
573561
VPBuilder Builder(MiddleVPBB);
574-
VPValue *Cmp =
575-
TailFolded
576-
? Plan.getOrAddLiveIn(ConstantInt::getTrue(
577-
IntegerType::getInt1Ty(TripCount->getType()->getContext())))
578-
: Builder.createICmp(CmpInst::ICMP_EQ, Plan.getTripCount(),
579-
&Plan.getVectorTripCount(),
580-
ScalarLatchTerm->getDebugLoc(), "cmp.n");
562+
VPValue *Cmp;
563+
if (TailFolded)
564+
Cmp = Plan.getOrAddLiveIn(ConstantInt::getTrue(
565+
IntegerType::getInt1Ty(TripCount->getType()->getContext())));
566+
else if (!RequiresScalarEpilogueCheck)
567+
Cmp = Plan.getOrAddLiveIn(ConstantInt::getFalse(
568+
IntegerType::getInt1Ty(TripCount->getType()->getContext())));
569+
else
570+
Cmp = Builder.createICmp(CmpInst::ICMP_EQ, Plan.getTripCount(),
571+
&Plan.getVectorTripCount(),
572+
ScalarLatchTerm->getDebugLoc(), "cmp.n");
581573
Builder.createNaryOp(VPInstruction::BranchOnCond, {Cmp},
582574
ScalarLatchTerm->getDebugLoc());
583575
}

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1732,11 +1732,21 @@ static void removeBranchOnCondTrue(VPlan &Plan) {
17321732
using namespace llvm::VPlanPatternMatch;
17331733
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
17341734
vp_depth_first_shallow(Plan.getEntry()))) {
1735-
if (VPBB->getNumSuccessors() != 2 || isa<VPIRBasicBlock>(VPBB) ||
1736-
!match(&VPBB->back(), m_BranchOnCond(m_True())))
1735+
VPValue *Cond;
1736+
if (VPBB->getNumSuccessors() != 2 || VPBB->empty() ||
1737+
!match(&VPBB->back(), m_BranchOnCond(m_VPValue(Cond))))
17371738
continue;
17381739

1739-
VPBasicBlock *RemovedSucc = cast<VPBasicBlock>(VPBB->getSuccessors()[1]);
1740+
unsigned RemovedIdx;
1741+
if (match(Cond, m_True()))
1742+
RemovedIdx = 1;
1743+
else if (match(Cond, m_False()))
1744+
RemovedIdx = 0;
1745+
else
1746+
continue;
1747+
1748+
VPBasicBlock *RemovedSucc =
1749+
cast<VPBasicBlock>(VPBB->getSuccessors()[RemovedIdx]);
17401750
const auto &Preds = RemovedSucc->getPredecessors();
17411751
assert(count(Preds, VPBB) == 1 &&
17421752
"There must be a single edge between VPBB and its successor");
@@ -1745,10 +1755,12 @@ static void removeBranchOnCondTrue(VPlan &Plan) {
17451755
// Values coming from VPBB into ResumePhi recipes of RemoveSucc are removed
17461756
// from these recipes.
17471757
for (VPRecipeBase &R : make_early_inc_range(*RemovedSucc)) {
1748-
assert((!isa<VPIRInstruction>(&R) ||
1749-
!isa<PHINode>(cast<VPIRInstruction>(&R)->getInstruction())) &&
1750-
!isa<VPHeaderPHIRecipe>(&R) &&
1751-
"Cannot update VPIRInstructions wrapping phis or header phis yet");
1758+
if (isa<VPIRPhi>(&R)) {
1759+
assert(RemovedSucc->getNumPredecessors() == 1);
1760+
cast<VPIRPhi>(&R)->removeIncomingValue(VPBB);
1761+
continue;
1762+
}
1763+
17521764
auto *VPI = dyn_cast<VPPhi>(&R);
17531765
if (!VPI)
17541766
break;

llvm/lib/Transforms/Vectorize/VPlanValue.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class VPSlotTracker;
3838
class VPUser;
3939
class VPRecipeBase;
4040
class VPInterleaveRecipe;
41+
class VPPhiAccessors;
4142

4243
// This is the base class of the VPlan Def/Use graph, used for modeling the data
4344
// flow into, within and out of the VPlan. VPValues can stand for live-ins
@@ -199,8 +200,12 @@ raw_ostream &operator<<(raw_ostream &OS, const VPRecipeBase &R);
199200
/// This class augments VPValue with operands which provide the inverse def-use
200201
/// edges from VPValue's users to their defs.
201202
class VPUser {
203+
friend class VPPhiAccessors;
204+
202205
SmallVector<VPValue *, 2> Operands;
203206

207+
void removeOperand(unsigned Idx) { Operands.erase(Operands.begin() + Idx); }
208+
204209
protected:
205210
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
206211
/// Print the operands to \p O.

0 commit comments

Comments
 (0)