Skip to content

Commit e26af8e

Browse files
committed
!fixup address latest comments, thanks!
1 parent 43a8ef7 commit e26af8e

File tree

10 files changed

+384
-121
lines changed

10 files changed

+384
-121
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7783,7 +7783,6 @@ DenseMap<const SCEV *, Value *> LoopVectorizationPlanner::executePlan(
77837783
LoopVectorizeHints Hints(L, true, *ORE);
77847784
Hints.setAlreadyVectorized();
77857785
}
7786-
77877786
TargetTransformInfo::UnrollingPreferences UP;
77887787
TTI.getUnrollingPreferences(L, *PSE.getSE(), UP, ORE);
77897788
if (!UP.UnrollVectorizedLoop || CanonicalIVStartValue)
@@ -8882,61 +8881,73 @@ static void addScalarResumePhis(VPRecipeBuilder &Builder, VPlan &Plan) {
88828881
static SetVector<VPIRInstruction *> collectUsersInExitBlocks(
88838882
Loop *OrigLoop, VPRecipeBuilder &Builder, VPlan &Plan,
88848883
const MapVector<PHINode *, InductionDescriptor> &Inductions) {
8884+
auto *MiddleVPBB = Plan.getMiddleBlock();
88858885
SetVector<VPIRInstruction *> ExitUsersToFix;
88868886
for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks()) {
8887-
BasicBlock *ExitBB = ExitVPBB->getIRBasicBlock();
88888887
for (VPRecipeBase &R : *ExitVPBB) {
88898888
auto *ExitIRI = dyn_cast<VPIRInstruction>(&R);
88908889
if (!ExitIRI)
88918890
continue;
88928891
auto *ExitPhi = dyn_cast<PHINode>(&ExitIRI->getInstruction());
88938892
if (!ExitPhi)
88948893
break;
8895-
for (BasicBlock *ExitingBB : predecessors(ExitBB)) {
8896-
if (!OrigLoop->contains(ExitingBB))
8897-
continue;
8898-
Value *IncomingValue = ExitPhi->getIncomingValueForBlock(ExitingBB);
8899-
VPValue *V = Builder.getVPValueOrAddLiveIn(IncomingValue);
8900-
// Exit values for inductions are computed and updated outside of VPlan
8901-
// and independent of induction recipes.
8902-
// TODO: Compute induction exit values in VPlan.
8903-
if ((isa<VPWidenIntOrFpInductionRecipe>(V) &&
8904-
!cast<VPWidenIntOrFpInductionRecipe>(V)->getTruncInst()) ||
8905-
isa<VPWidenPointerInductionRecipe>(V) ||
8906-
(isa<Instruction>(IncomingValue) &&
8907-
OrigLoop->contains(cast<Instruction>(IncomingValue)) &&
8908-
any_of(IncomingValue->users(), [&Inductions](User *U) {
8909-
auto *P = dyn_cast<PHINode>(U);
8910-
return P && Inductions.contains(P);
8911-
})))
8912-
continue;
8913-
ExitUsersToFix.insert(ExitIRI);
8914-
ExitIRI->addOperand(V);
8894+
for (VPBlockBase *PredVPBB : ExitVPBB->getPredecessors()) {
8895+
BasicBlock *ExitingBB = OrigLoop->getLoopLatch();
8896+
if (PredVPBB != MiddleVPBB) {
8897+
SmallVector<BasicBlock *> ExitingBlocks;
8898+
OrigLoop->getExitingBlocks(ExitingBlocks);
8899+
assert(ExitingBlocks.size() == 2 && "only support 2 exiting blocks");
8900+
ExitingBB = ExitingBB == ExitingBlocks[0] ? ExitingBlocks[1]
8901+
: ExitingBlocks[0];
8902+
}
8903+
Value *IncomingValue = ExitPhi->getIncomingValueForBlock(ExitingBB);
8904+
VPValue *V = Builder.getVPValueOrAddLiveIn(IncomingValue);
8905+
// Exit values for inductions are computed and updated outside of VPlan
8906+
// and independent of induction recipes.
8907+
// TODO: Compute induction exit values in VPlan.
8908+
if ((isa<VPWidenIntOrFpInductionRecipe>(V) &&
8909+
!cast<VPWidenIntOrFpInductionRecipe>(V)->getTruncInst()) ||
8910+
isa<VPWidenPointerInductionRecipe>(V) ||
8911+
(isa<Instruction>(IncomingValue) &&
8912+
OrigLoop->contains(cast<Instruction>(IncomingValue)) &&
8913+
any_of(IncomingValue->users(), [&Inductions](User *U) {
8914+
auto *P = dyn_cast<PHINode>(U);
8915+
return P && Inductions.contains(P);
8916+
}))) {
8917+
if (ExitVPBB->getSinglePredecessor() == MiddleVPBB)
8918+
continue;
8919+
}
8920+
ExitUsersToFix.insert(ExitIRI);
8921+
ExitIRI->addOperand(V);
89158922
}
89168923
}
89178924
}
89188925
return ExitUsersToFix;
89198926
}
89208927

89218928
// Add exit values to \p Plan. Extracts are added for each entry in \p
8922-
// ExitUsersToFix if needed and their operands are updated.
8923-
static void
8929+
// ExitUsersToFix if needed and their operands are updated. Returns true if all
8930+
// exit users can be handled, otherwise return false.
8931+
static bool
89248932
addUsersInExitBlocks(VPlan &Plan,
89258933
const SetVector<VPIRInstruction *> &ExitUsersToFix) {
89268934
if (ExitUsersToFix.empty())
8927-
return;
8935+
return true;
8936+
8937+
auto *MiddleVPBB = Plan.getMiddleBlock();
8938+
VPBuilder B(MiddleVPBB, MiddleVPBB->getFirstNonPhi());
89288939

89298940
// Introduce extract for exiting values and update the VPIRInstructions
89308941
// modeling the corresponding LCSSA phis.
89318942
for (VPIRInstruction *ExitIRI : ExitUsersToFix) {
8932-
89338943
VPValue *V = ExitIRI->getOperand(0);
89348944
// Pass live-in values used by exit phis directly through to their users in
89358945
// the exit block.
89368946
if (V->isLiveIn())
89378947
continue;
89388948

8939-
// Currently only live-ins can be used by exit values from blocks not exiting via the vector latch through to the middle block.
8949+
// Currently only live-ins can be used by exit values from blocks not
8950+
// exiting via the vector latch through to the middle block.
89408951
if (ExitIRI->getParent()->getSinglePredecessor() != MiddleVPBB)
89418952
return false;
89428953

@@ -9218,31 +9229,19 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
92189229
RecipeBuilder.fixHeaderPhis();
92199230

92209231
if (Legal->hasUncountableEarlyExit()) {
9232+
assert(Legal->getUncountableExitingBlocks().size() == 1 &&
9233+
"Only single uncountable exiting bock supported");
92219234
VPlanTransforms::handleUncountableEarlyExit(
9222-
*Plan, *PSE.getSE(), OrigLoop, Legal->getUncountableExitingBlocks(),
9235+
*Plan, *PSE.getSE(), OrigLoop, Legal->getUncountableExitingBlocks()[0],
92239236
RecipeBuilder);
92249237
}
92259238
addScalarResumePhis(RecipeBuilder, *Plan);
92269239
SetVector<VPIRInstruction *> ExitUsersToFix = collectUsersInExitBlocks(
92279240
OrigLoop, RecipeBuilder, *Plan, Legal->getInductionVars());
92289241
addExitUsersForFirstOrderRecurrences(*Plan, ExitUsersToFix);
9229-
if (!addUsersInExitBlocks(*Plan, ExitUsersToFix))
9230-
<<<<<<< HEAD
9231-
9232-
if (Legal->hasUncountableEarlyExit()) {
9233-
if (any_of(Plan->getExitBlocks(), [](VPIRBasicBlock *ExitBB) {
9234-
return any_of(*ExitBB, [](VPRecipeBase &R) {
9235-
auto VPIRI = cast<VPIRInstruction>(&R);
9236-
return VPIRI->getNumOperands() == 0 ||
9237-
any_of(VPIRI->operands(),
9238-
[](VPValue *Op) { return !Op->isLiveIn(); });
9239-
});
9240-
}))
9241-
return nullptr;
9242-
}
9242+
if (!addUsersInExitBlocks(*Plan, ExitUsersToFix))
9243+
return nullptr;
92439244

9244-
=======
9245-
>>>>>>> origin/main
92469245
// ---------------------------------------------------------------------------
92479246
// Transform initial VPlan: Apply previously taken decisions, in order, to
92489247
// bring the VPlan to its final state.
@@ -9998,11 +9997,10 @@ bool LoopVectorizePass::processLoop(Loop *L) {
99989997
if (LVL.hasUncountableEarlyExit()) {
99999998
if (!EnableEarlyExitVectorization) {
100009999
reportVectorizationFailure("Auto-vectorization of loops with uncountable "
10001-
"early exit is not yet supported",
10000+
"early exit is not enabled",
1000210001
"Auto-vectorization of loops with uncountable "
10003-
"early exit is not yet supported",
10004-
"UncountableEarlyExitLoopsUnsupported", ORE,
10005-
L);
10002+
"early exit is no enabled",
10003+
"UncountableEarlyExitLoopsDisabled", ORE, L);
1000610004
return false;
1000710005
}
1000810006
}

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -872,8 +872,10 @@ VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
872872

873873
// Create SCEV and VPValue for the trip count.
874874
// We use the symbolic max backedge-taken-count, which is used when
875-
// vectorizing loops with uncountable early exits
875+
// vectorizing loops with uncountable early exits.
876876
const SCEV *BackedgeTakenCountSCEV = PSE.getSymbolicMaxBackedgeTakenCount();
877+
assert(!isa<SCEVCouldNotCompute>(BackedgeTakenCountSCEV) &&
878+
"Invalid loop count");
877879
ScalarEvolution &SE = *PSE.getSE();
878880
const SCEV *TripCount = SE.getTripCountFromExitCount(BackedgeTakenCountSCEV,
879881
InductionTy, TheLoop);
@@ -907,16 +909,7 @@ VPlanPtr VPlan::createInitialVPlan(Type *InductionTy,
907909
// 2) If we require a scalar epilogue, there is no conditional branch as
908910
// we unconditionally branch to the scalar preheader. Do nothing.
909911
// 3) Otherwise, construct a runtime check.
910-
BasicBlock *IRExitBlock = TheLoop->getUniqueExitBlock();
911-
if (!IRExitBlock) {
912-
// If there's no unique exit block (i.e. vectorizing with an uncountable
913-
// early exit), use the block exiting from the latch. The other uncountable
914-
// exit blocks will be added later.
915-
auto *Term = cast<BranchInst>(TheLoop->getLoopLatch()->getTerminator());
916-
IRExitBlock = TheLoop->contains(Term->getSuccessor(0))
917-
? Term->getSuccessor(1)
918-
: Term->getSuccessor(0);
919-
}
912+
BasicBlock *IRExitBlock = TheLoop->getUniqueLatchExitBlock();
920913
auto *VPExitBlock = VPIRBasicBlock::fromBasicBlock(IRExitBlock);
921914
// The connection order corresponds to the operands of the conditional
922915
// branch.

llvm/lib/Transforms/Vectorize/VPlan.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,8 @@ class VPInstruction : public VPRecipeWithIRFlags,
12321232
// operand). Only generates scalar values (either for the first lane only or
12331233
// for all lanes, depending on its uses).
12341234
PtrAdd,
1235+
// Returns a scalar boolean value, which is true if any lane of its single
1236+
// operand is true.
12351237
AnyOf,
12361238
};
12371239

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ bool VPRecipeBase::mayWriteToMemory() const {
6868
default:
6969
return true;
7070
}
71-
case VPExpandSCEVSC:
72-
return getParent()->getPlan()->getTripCount() == getVPSingleValue();
7371
case VPInterleaveSC:
7472
return cast<VPInterleaveRecipe>(this)->getNumStoreOperands() > 0;
7573
case VPWidenStoreEVLSC:
@@ -165,8 +163,6 @@ bool VPRecipeBase::mayHaveSideEffects() const {
165163
case VPScalarCastSC:
166164
case VPReverseVectorPointerSC:
167165
return false;
168-
case VPExpandSCEVSC:
169-
return getParent()->getPlan()->getTripCount() == getVPSingleValue();
170166
case VPInstructionSC:
171167
return mayWriteToMemory();
172168
case VPWidenCallSC: {

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -509,12 +509,6 @@ void VPlanTransforms::removeDeadRecipes(VPlan &Plan) {
509509
ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<VPBlockBase *>> RPOT(
510510
Plan.getEntry());
511511

512-
for (VPRecipeBase &R : make_early_inc_range(
513-
reverse(*cast<VPBasicBlock>(Plan.getPreheader())))) {
514-
if (isDeadRecipe(R))
515-
R.eraseFromParent();
516-
}
517-
518512
for (VPBasicBlock *VPBB : reverse(VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT))) {
519513
// The recipes in the block are processed in reverse order, to catch chains
520514
// of dead recipes.
@@ -1809,45 +1803,42 @@ void VPlanTransforms::createInterleaveGroups(
18091803

18101804
void VPlanTransforms::handleUncountableEarlyExit(
18111805
VPlan &Plan, ScalarEvolution &SE, Loop *OrigLoop,
1812-
ArrayRef<BasicBlock *> UncountableExitingBlocks,
1813-
VPRecipeBuilder &RecipeBuilder) {
1806+
BasicBlock *UncountableExitingBlock, VPRecipeBuilder &RecipeBuilder) {
18141807
auto *LatchVPBB =
18151808
cast<VPBasicBlock>(Plan.getVectorLoopRegion()->getExiting());
18161809
VPBuilder Builder(LatchVPBB->getTerminator());
18171810
auto *MiddleVPBB = Plan.getMiddleBlock();
18181811
VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
18191812
VPValue *EarlyExitTaken = nullptr;
18201813

1821-
// Process all uncountable exiting blocks. For each exiting block, update the
1822-
// EarlyExitTaken, which tracks if any uncountable early exit has been taken.
1823-
// Also split the middle block and branch to the exit block for the early exit
1824-
// if it has been taken.
1825-
for (BasicBlock *Exiting : UncountableExitingBlocks) {
1826-
auto *ExitingTerm = cast<BranchInst>(Exiting->getTerminator());
1827-
BasicBlock *TrueSucc = ExitingTerm->getSuccessor(0);
1828-
BasicBlock *FalseSucc = ExitingTerm->getSuccessor(1);
1829-
VPIRBasicBlock *VPExitBlock;
1830-
if (OrigLoop->getUniqueExitBlock()) {
1831-
VPExitBlock = cast<VPIRBasicBlock>(MiddleVPBB->getSuccessors()[0]);
1832-
} else {
1833-
VPExitBlock = VPIRBasicBlock::fromBasicBlock(
1834-
!OrigLoop->contains(TrueSucc) ? TrueSucc : FalseSucc);
1835-
}
1814+
// Process the uncountable exiting block. Update EarlyExitTaken, which tracks
1815+
// if any uncountable early exit has been taken. Also split the middle block
1816+
// and branch to the exit block for the early exit if it has been taken.
1817+
auto *ExitingTerm =
1818+
cast<BranchInst>(UncountableExitingBlock->getTerminator());
1819+
BasicBlock *TrueSucc = ExitingTerm->getSuccessor(0);
1820+
BasicBlock *FalseSucc = ExitingTerm->getSuccessor(1);
1821+
VPIRBasicBlock *VPExitBlock;
1822+
if (OrigLoop->getUniqueExitBlock()) {
1823+
VPExitBlock = cast<VPIRBasicBlock>(MiddleVPBB->getSuccessors()[0]);
1824+
} else {
1825+
VPExitBlock = VPIRBasicBlock::fromBasicBlock(
1826+
!OrigLoop->contains(TrueSucc) ? TrueSucc : FalseSucc);
1827+
}
18361828

1837-
VPValue *M = RecipeBuilder.getBlockInMask(
1838-
OrigLoop->contains(TrueSucc) ? TrueSucc : FalseSucc);
1839-
auto *N = Builder.createNot(M);
1840-
EarlyExitTaken = Builder.createNaryOp(VPInstruction::AnyOf, {N});
1829+
VPValue *M = RecipeBuilder.getBlockInMask(
1830+
OrigLoop->contains(TrueSucc) ? TrueSucc : FalseSucc);
1831+
auto *N = Builder.createNot(M);
1832+
EarlyExitTaken = Builder.createNaryOp(VPInstruction::AnyOf, {N});
18411833

1842-
VPBasicBlock *NewMiddle = new VPBasicBlock("middle.split");
1843-
VPBlockUtils::disconnectBlocks(LoopRegion, MiddleVPBB);
1844-
VPBlockUtils::insertBlockAfter(NewMiddle, LoopRegion);
1845-
VPBlockUtils::connectBlocks(NewMiddle, VPExitBlock);
1846-
VPBlockUtils::connectBlocks(NewMiddle, MiddleVPBB);
1834+
VPBasicBlock *NewMiddle = new VPBasicBlock("middle.split");
1835+
VPBlockUtils::disconnectBlocks(LoopRegion, MiddleVPBB);
1836+
VPBlockUtils::insertBlockAfter(NewMiddle, LoopRegion);
1837+
VPBlockUtils::connectBlocks(NewMiddle, VPExitBlock);
1838+
VPBlockUtils::connectBlocks(NewMiddle, MiddleVPBB);
18471839

1848-
VPBuilder MiddleBuilder(NewMiddle);
1849-
MiddleBuilder.createNaryOp(VPInstruction::BranchOnCond, {EarlyExitTaken});
1850-
}
1840+
VPBuilder MiddleBuilder(NewMiddle);
1841+
MiddleBuilder.createNaryOp(VPInstruction::BranchOnCond, {EarlyExitTaken});
18511842

18521843
// Replace the condition controlling the exit from the vector loop with one
18531844
// exiting if either the original condition of the vector latch is true or any

llvm/lib/Transforms/Vectorize/VPlanTransforms.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,13 @@ struct VPlanTransforms {
127127
/// Update \p Plan to account for uncountable exit blocks in \p
128128
/// UncountableExitingBlocks by
129129
/// * updating the condition to exit the vector loop to include the early
130-
/// exit conditions
130+
/// exit conditions
131131
/// * splitting the original middle block to branch to the early exit blocks
132-
/// if taken. Returns false if the transformation wasn't successful.
133-
static void
134-
handleUncountableEarlyExit(VPlan &Plan, ScalarEvolution &SE, Loop *OrigLoop,
135-
ArrayRef<BasicBlock *> UncountableExitingBlocks,
136-
VPRecipeBuilder &RecipeBuilder);
132+
/// if taken. Returns false if the transformation wasn't successful.
133+
static void handleUncountableEarlyExit(VPlan &Plan, ScalarEvolution &SE,
134+
Loop *OrigLoop,
135+
BasicBlock *UncountableExitingBlock,
136+
VPRecipeBuilder &RecipeBuilder);
137137
};
138138

139139
} // namespace llvm

llvm/test/Transforms/LoopVectorize/early_exit_legality.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
22
; REQUIRES: asserts
3-
; RUN: opt -S < %s -p loop-vectorize -debug-only=loop-vectorize -disable-output 2>&1 | FileCheck %s
3+
; RUN: opt -S < %s -p loop-vectorize -debug-only=loop-vectorize -enable-early-exit-vectorization -force-vector-width=4 -disable-output 2>&1 | FileCheck %s
44

55
declare void @init_mem(ptr, i64);
66

0 commit comments

Comments
 (0)