Skip to content

Commit 76c470a

Browse files
committed
!fixup address comments, thanks!
1 parent d0d2c2e commit 76c470a

File tree

3 files changed

+54
-66
lines changed

3 files changed

+54
-66
lines changed

llvm/lib/Transforms/Vectorize/VPlanConstruction.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ static void addCanonicalIVRecipes(VPlan &Plan, VPBasicBlock *HeaderVPBB,
463463
void VPlanTransforms::prepareForVectorization(
464464
VPlan &Plan, Type *InductionTy, PredicatedScalarEvolution &PSE,
465465
bool RequiresScalarEpilogueCheck, bool TailFolded, Loop *TheLoop,
466-
DebugLoc IVDL, bool HandleUncountableExit, VFRange &Range) {
466+
DebugLoc IVDL, bool HasUncountableEarlyExit, VFRange &Range) {
467467
VPDominatorTree VPDT;
468468
VPDT.recalculate(Plan);
469469

@@ -490,23 +490,35 @@ void VPlanTransforms::prepareForVectorization(
490490
addCanonicalIVRecipes(Plan, cast<VPBasicBlock>(HeaderVPB),
491491
cast<VPBasicBlock>(LatchVPB), InductionTy, IVDL);
492492

493-
if (HandleUncountableExit) {
494-
// Convert VPlans with early exits to a form only exiting via the latch
495-
// here, including adjusting the exit condition.
496-
handleUncountableEarlyExit(Plan, cast<VPBasicBlock>(HeaderVPB),
497-
cast<VPBasicBlock>(LatchVPB), Range);
498-
} else {
499-
// Disconnect all edges to exit blocks other than from the middle block.
500-
for (VPBlockBase *EB : to_vector(Plan.getExitBlocks())) {
501-
for (VPBlockBase *Pred : to_vector(EB->getPredecessors())) {
502-
if (Pred == MiddleVPBB)
503-
continue;
504-
cast<VPBasicBlock>(Pred)->getTerminator()->eraseFromParent();
505-
VPBlockUtils::disconnectBlocks(Pred, EB);
493+
[[maybe_unused]] bool HandledUncountableEarlyExit = false;
494+
for (VPIRBasicBlock *EB : Plan.getExitBlocks()) {
495+
for (VPBlockBase *Pred : to_vector(EB->getPredecessors())) {
496+
if (Pred == MiddleVPBB)
497+
continue;
498+
499+
if (HasUncountableEarlyExit) {
500+
assert(!HandledUncountableEarlyExit &&
501+
"can handle exactly one uncountable early exit");
502+
// Convert VPlans with early exits to a form exiting only via the latch
503+
// here, including adjusting the exit condition of the latch.
504+
handleUncountableEarlyExit(cast<VPBasicBlock>(Pred), EB, Plan,
505+
cast<VPBasicBlock>(HeaderVPB),
506+
cast<VPBasicBlock>(LatchVPB), Range);
507+
HandledUncountableEarlyExit = true;
508+
continue;
506509
}
510+
511+
// Otherwise all early exits must be countable and we require at least one
512+
// iteration in the scalar epilogue. Disconnect all edges to exit blocks
513+
// other than from the middle block.
514+
cast<VPBasicBlock>(Pred)->getTerminator()->eraseFromParent();
515+
VPBlockUtils::disconnectBlocks(Pred, EB);
507516
}
508517
}
509518

519+
assert((!HasUncountableEarlyExit || HandledUncountableEarlyExit) &&
520+
"did not handle uncountable early exit");
521+
510522
// Create SCEV and VPValue for the trip count.
511523
// We use the symbolic max backedge-taken-count, which works also when
512524
// vectorizing loops with uncountable early exits.

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 23 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,68 +2458,42 @@ void VPlanTransforms::convertToConcreteRecipes(VPlan &Plan,
24582458
R->eraseFromParent();
24592459
}
24602460

2461-
void VPlanTransforms::handleUncountableEarlyExit(VPlan &Plan,
2461+
void VPlanTransforms::handleUncountableEarlyExit(VPBasicBlock *EarlyExitingVPBB,
2462+
VPBasicBlock *EarlyExitVPBB,
2463+
2464+
VPlan &Plan,
24622465
VPBasicBlock *HeaderVPBB,
24632466
VPBasicBlock *LatchVPBB,
24642467
VFRange &Range) {
2465-
// First find the uncountable early exiting block by looking at the
2466-
// predecessors of the exit blocks.
2467-
VPBlockBase *MiddleVPBB = LatchVPBB->getSuccessors()[0];
2468-
VPBasicBlock *EarlyExitingVPBB = nullptr;
2469-
VPIRBasicBlock *EarlyExitVPBB = nullptr;
2470-
for (auto *EB : Plan.getExitBlocks()) {
2471-
for (VPBlockBase *Pred : EB->getPredecessors()) {
2472-
if (Pred != MiddleVPBB) {
2473-
EarlyExitingVPBB = cast<VPBasicBlock>(Pred);
2474-
EarlyExitVPBB = EB;
2475-
break;
2476-
}
2477-
}
2478-
}
2479-
assert(EarlyExitVPBB && "Must have a early exiting block.");
2480-
assert(all_of(Plan.getExitBlocks(),
2481-
[EarlyExitingVPBB, MiddleVPBB](VPIRBasicBlock *EB) {
2482-
return all_of(
2483-
EB->getPredecessors(),
2484-
[EarlyExitingVPBB, MiddleVPBB](VPBlockBase *Pred) {
2485-
return Pred == EarlyExitingVPBB || Pred == MiddleVPBB;
2486-
});
2487-
}) &&
2488-
"All exit blocks must only have EarlyExitingVPBB or MiddleVPBB as "
2489-
"predecessors.");
2490-
2491-
VPBuilder Builder(LatchVPBB->getTerminator());
2492-
VPBlockBase *TrueSucc = EarlyExitingVPBB->getSuccessors()[0];
2493-
VPValue *EarlyExitCond = EarlyExitingVPBB->getTerminator()->getOperand(0);
2494-
auto *EarlyExitTakenCond = TrueSucc == EarlyExitVPBB
2495-
? EarlyExitCond
2496-
: Builder.createNot(EarlyExitCond);
2468+
using namespace llvm::VPlanPatternMatch;
24972469

2470+
VPBlockBase *MiddleVPBB = LatchVPBB->getSuccessors()[0];
24982471
if (!EarlyExitVPBB->getSinglePredecessor() &&
24992472
EarlyExitVPBB->getPredecessors()[0] != MiddleVPBB) {
2500-
for (VPRecipeBase &R : EarlyExitVPBB->phis()) {
2501-
// Early exit operand should always be last, i.e., 0 if EarlyExitVPBB has
2502-
// a single predecessor and 1 if it has two.
2503-
// If EarlyExitVPBB has two predecessors, they are already ordered such
2504-
// that early exit is second (and latch exit is first), by construction.
2505-
// But its underlying IRBB (EarlyExitIRBB) may have its predecessors
2506-
// ordered the other way around, and it is the order of the latter which
2507-
// corresponds to the order of operands of EarlyExitVPBB's phi recipes.
2508-
// Therefore, if early exit (UncountableExitingBlock) is the first
2509-
// predecessor of EarlyExitIRBB, we swap the operands of phi recipes,
2510-
// thereby bringing them to match EarlyExitVPBB's predecessor order,
2511-
// with early exit being last (second). Otherwise they already match.
2473+
// Early exit operand should always be last phi operand. If EarlyExitVPBB
2474+
// has two predecessors and MiddleVPBB isn't the first, swap the operands of
2475+
// the phis.
2476+
for (VPRecipeBase &R : EarlyExitVPBB->phis())
25122477
cast<VPIRPhi>(&R)->swapOperands();
2513-
}
25142478
}
25152479

2480+
VPBuilder Builder(LatchVPBB->getTerminator());
2481+
VPBlockBase *TrueSucc = EarlyExitingVPBB->getSuccessors()[0];
2482+
assert(
2483+
match(EarlyExitingVPBB->getTerminator(), m_BranchOnCond(m_VPValue())) &&
2484+
"Terminator must be be BranchOnCond");
2485+
VPValue *CondOfEarlyExitingVPBB =
2486+
EarlyExitingVPBB->getTerminator()->getOperand(0);
2487+
auto *CondToEarlyExit = TrueSucc == EarlyExitVPBB
2488+
? CondOfEarlyExitingVPBB
2489+
: Builder.createNot(CondOfEarlyExitingVPBB);
25162490
EarlyExitingVPBB->getTerminator()->eraseFromParent();
25172491
VPBlockUtils::disconnectBlocks(EarlyExitingVPBB, EarlyExitVPBB);
25182492

25192493
// Split the middle block and have it conditionally branch to the early exit
25202494
// block if EarlyExitTaken.
25212495
VPValue *IsEarlyExitTaken =
2522-
Builder.createNaryOp(VPInstruction::AnyOf, {EarlyExitTakenCond});
2496+
Builder.createNaryOp(VPInstruction::AnyOf, {CondToEarlyExit});
25232497
VPBasicBlock *NewMiddle = Plan.createVPBasicBlock("middle.split");
25242498
VPBasicBlock *VectorEarlyExitVPBB =
25252499
Plan.createVPBasicBlock("vector.early.exit");
@@ -2537,7 +2511,7 @@ void VPlanTransforms::handleUncountableEarlyExit(VPlan &Plan,
25372511
// Early exit operand should always be last, i.e., 0 if EarlyExitVPBB has
25382512
// a single predecessor and 1 if it has two.
25392513
unsigned EarlyExitIdx = ExitIRI->getNumOperands() - 1;
2540-
if (!EarlyExitVPBB->getSinglePredecessor()) {
2514+
if (ExitIRI->getNumOperands() != 1) {
25412515
// The first of two operands corresponds to the latch exit, via MiddleVPBB
25422516
// predecessor. Extract its last lane.
25432517
ExitIRI->extractLastLaneOfFirstOperand(MiddleBuilder);
@@ -2553,7 +2527,7 @@ void VPlanTransforms::handleUncountableEarlyExit(VPlan &Plan,
25532527
LoopVectorizationPlanner::getDecisionAndClampRange(IsVector, Range)) {
25542528
// Update the incoming value from the early exit.
25552529
VPValue *FirstActiveLane = EarlyExitB.createNaryOp(
2556-
VPInstruction::FirstActiveLane, {EarlyExitTakenCond}, nullptr,
2530+
VPInstruction::FirstActiveLane, {CondToEarlyExit}, nullptr,
25572531
"first.active.lane");
25582532
IncomingFromEarlyExit = EarlyExitB.createNaryOp(
25592533
Instruction::ExtractElement, {IncomingFromEarlyExit, FirstActiveLane},

llvm/lib/Transforms/Vectorize/VPlanTransforms.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,15 @@ struct VPlanTransforms {
174174
/// Remove dead recipes from \p Plan.
175175
static void removeDeadRecipes(VPlan &Plan);
176176

177-
/// Update \p Plan to account for the uncountable early exit block in \p
178-
/// UncountableExitingBlock by
177+
/// Update \p Plan to account for the uncountable early exit from \p
178+
/// EarlyExitingVPBB to \p EarlyExitVPBB by
179179
/// * updating the condition exiting the vector loop to include the early
180180
/// exit conditions
181181
/// * splitting the original middle block to branch to the early exit block
182182
/// if taken.
183-
static void handleUncountableEarlyExit(VPlan &Plan, VPBasicBlock *HeaderVPBB,
183+
static void handleUncountableEarlyExit(VPBasicBlock *EarlyExitingVPBB,
184+
VPBasicBlock *EarlyExitVPBB,
185+
VPlan &Plan, VPBasicBlock *HeaderVPBB,
184186
VPBasicBlock *LatchVPBB,
185187
VFRange &Range);
186188

0 commit comments

Comments
 (0)