Skip to content

Commit 69ad1de

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 llvm#140405.
1 parent 3f3f002 commit 69ad1de

File tree

4 files changed

+53
-33
lines changed

4 files changed

+53
-33
lines changed

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,8 @@ class VPPhiAccessors {
11221122
return getAsRecipe()->getNumOperands();
11231123
}
11241124

1125+
void removeIncomingValue(VPBlockBase *VPB) const;
1126+
11251127
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
11261128
/// Print the recipe.
11271129
void printPhiOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const;
@@ -3715,6 +3717,15 @@ VPPhiAccessors::getIncomingBlock(unsigned Idx) const {
37153717
return getAsRecipe()->getParent()->getCFGPredecessor(Idx);
37163718
}
37173719

3720+
inline void VPPhiAccessors::removeIncomingValue(VPBlockBase *VPB) const {
3721+
VPRecipeBase *R = const_cast<VPRecipeBase *>(getAsRecipe());
3722+
const VPBasicBlock *Parent = R->getParent();
3723+
assert(R->getNumOperands() == Parent->getNumPredecessors());
3724+
auto I = find(Parent->getPredecessors(), VPB);
3725+
R->getOperand(I - Parent->getPredecessors().begin())->removeUser(*R);
3726+
R->removeOperand(I - Parent->getPredecessors().begin());
3727+
}
3728+
37183729
/// A special type of VPBasicBlock that wraps an existing IR basic block.
37193730
/// Recipes of the block get added before the first non-phi instruction in the
37203731
/// wrapped block.

llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,12 @@ void VPlanTransforms::prepareForVectorization(
501501
cast<VPBasicBlock>(HeaderVPB),
502502
cast<VPBasicBlock>(LatchVPB), Range);
503503
HandledUncountableEarlyExit = true;
504+
} else {
505+
for (VPRecipeBase &R : cast<VPIRBasicBlock>(EB)->phis()) {
506+
if (auto *PhiR = dyn_cast<VPIRPhi>(&R))
507+
PhiR->removeIncomingValue(Pred);
508+
}
504509
}
505-
506510
cast<VPBasicBlock>(Pred)->getTerminator()->eraseFromParent();
507511
VPBlockUtils::disconnectBlocks(Pred, EB);
508512
}
@@ -535,45 +539,33 @@ void VPlanTransforms::prepareForVectorization(
535539
// Thus if tail is to be folded, we know we don't need to run the
536540
// remainder and we can set the condition to true.
537541
// 3) Otherwise, construct a runtime check.
538-
539-
if (!RequiresScalarEpilogueCheck) {
540-
if (auto *LatchExitVPB = MiddleVPBB->getSingleSuccessor())
541-
VPBlockUtils::disconnectBlocks(MiddleVPBB, LatchExitVPB);
542-
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
543-
VPBlockUtils::connectBlocks(Plan.getEntry(), ScalarPH);
544-
Plan.getEntry()->swapSuccessors();
545-
546-
// The exit blocks are unreachable, remove their recipes to make sure no
547-
// users remain that may pessimize transforms.
548-
for (auto *EB : Plan.getExitBlocks()) {
549-
for (VPRecipeBase &R : make_early_inc_range(*EB))
550-
R.eraseFromParent();
551-
}
552-
return;
553-
}
554-
555-
// The connection order corresponds to the operands of the conditional branch,
556-
// with the middle block already connected to the exit block.
557542
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
558543
// Also connect the entry block to the scalar preheader.
559544
// TODO: Also introduce a branch recipe together with the minimum trip count
560545
// check.
561546
VPBlockUtils::connectBlocks(Plan.getEntry(), ScalarPH);
562547
Plan.getEntry()->swapSuccessors();
563548

549+
if (MiddleVPBB->getNumSuccessors() != 2)
550+
return;
551+
564552
auto *ScalarLatchTerm = TheLoop->getLoopLatch()->getTerminator();
565553
// Here we use the same DebugLoc as the scalar loop latch terminator instead
566554
// of the corresponding compare because they may have ended up with
567555
// different line numbers and we want to avoid awkward line stepping while
568556
// debugging. Eg. if the compare has got a line number inside the loop.
569557
VPBuilder Builder(MiddleVPBB);
570-
VPValue *Cmp =
571-
TailFolded
572-
? Plan.getOrAddLiveIn(ConstantInt::getTrue(
573-
IntegerType::getInt1Ty(TripCount->getType()->getContext())))
574-
: Builder.createICmp(CmpInst::ICMP_EQ, Plan.getTripCount(),
575-
&Plan.getVectorTripCount(),
576-
ScalarLatchTerm->getDebugLoc(), "cmp.n");
558+
VPValue *Cmp;
559+
if (TailFolded)
560+
Cmp = Plan.getOrAddLiveIn(ConstantInt::getTrue(
561+
IntegerType::getInt1Ty(TripCount->getType()->getContext())));
562+
else if (!RequiresScalarEpilogueCheck)
563+
Cmp = Plan.getOrAddLiveIn(ConstantInt::getFalse(
564+
IntegerType::getInt1Ty(TripCount->getType()->getContext())));
565+
else
566+
Cmp = Builder.createICmp(CmpInst::ICMP_EQ, Plan.getTripCount(),
567+
&Plan.getVectorTripCount(),
568+
ScalarLatchTerm->getDebugLoc(), "cmp.n");
577569
Builder.createNaryOp(VPInstruction::BranchOnCond, {Cmp},
578570
ScalarLatchTerm->getDebugLoc());
579571
}

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,11 +1847,21 @@ static void removeBranchOnCondTrue(VPlan &Plan) {
18471847
using namespace llvm::VPlanPatternMatch;
18481848
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
18491849
vp_depth_first_shallow(Plan.getEntry()))) {
1850+
VPValue *Cond;
18501851
if (VPBB->getNumSuccessors() != 2 || VPBB == Plan.getEntry() ||
1851-
!match(&VPBB->back(), m_BranchOnCond(m_True())))
1852+
!match(&VPBB->back(), m_BranchOnCond(m_VPValue(Cond))))
18521853
continue;
18531854

1854-
VPBasicBlock *RemovedSucc = cast<VPBasicBlock>(VPBB->getSuccessors()[1]);
1855+
unsigned RemovedIdx;
1856+
if (match(Cond, m_True()))
1857+
RemovedIdx = 1;
1858+
else if (match(Cond, m_False()))
1859+
RemovedIdx = 0;
1860+
else
1861+
continue;
1862+
1863+
VPBasicBlock *RemovedSucc =
1864+
cast<VPBasicBlock>(VPBB->getSuccessors()[RemovedIdx]);
18551865
const auto &Preds = RemovedSucc->getPredecessors();
18561866
assert(count(Preds, VPBB) == 1 &&
18571867
"There must be a single edge between VPBB and its successor");
@@ -1860,10 +1870,12 @@ static void removeBranchOnCondTrue(VPlan &Plan) {
18601870
// Values coming from VPBB into ResumePhi recipes of RemoveSucc are removed
18611871
// from these recipes.
18621872
for (VPRecipeBase &R : make_early_inc_range(*RemovedSucc)) {
1863-
assert((!isa<VPIRInstruction>(&R) ||
1864-
!isa<PHINode>(cast<VPIRInstruction>(&R)->getInstruction())) &&
1865-
!isa<VPHeaderPHIRecipe>(&R) &&
1866-
"Cannot update VPIRInstructions wrapping phis or header phis yet");
1873+
if (isa<VPIRPhi>(&R)) {
1874+
assert(RemovedSucc->getNumPredecessors() == 1);
1875+
cast<VPIRPhi>(&R)->removeIncomingValue(VPBB);
1876+
continue;
1877+
}
1878+
18671879
auto *VPI = dyn_cast<VPPhi>(&R);
18681880
if (!VPI)
18691881
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)