Skip to content

Commit 4b3ff63

Browse files
committed
!fixup Turn into VPlan transform
1 parent 844aa2a commit 4b3ff63

File tree

6 files changed

+153
-148
lines changed

6 files changed

+153
-148
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 20 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -8748,10 +8748,9 @@ static void addCanonicalIVRecipes(VPlan &Plan, Type *IdxTy, bool HasNUW,
87488748
/// Create and return a ResumePhi for \p WideIV, unless it is truncated. If the
87498749
/// induction recipe is not canonical, creates a VPDerivedIVRecipe to compute
87508750
/// the end value of the induction.
8751-
static VPValue *addResumePhiRecipeForInduction(
8751+
static VPInstruction *addResumePhiRecipeForInduction(
87528752
VPWidenInductionRecipe *WideIV, VPBuilder &VectorPHBuilder,
8753-
VPBuilder &ScalarPHBuilder, VPTypeAnalysis &TypeInfo, VPValue *VectorTC,
8754-
DenseMap<VPValue *, VPValue *> &EndValues) {
8753+
VPBuilder &ScalarPHBuilder, VPTypeAnalysis &TypeInfo, VPValue *VectorTC) {
87558754
auto *WideIntOrFp = dyn_cast<VPWidenIntOrFpInductionRecipe>(WideIV);
87568755
// Truncated wide inductions resume from the last lane of their vector value
87578756
// in the last vector iteration which is handled elsewhere.
@@ -8776,7 +8775,6 @@ static VPValue *addResumePhiRecipeForInduction(
87768775
ScalarTypeOfWideIV);
87778776
}
87788777

8779-
EndValues[WideIV] = EndValue;
87808778
auto *ResumePhiRecipe =
87818779
ScalarPHBuilder.createNaryOp(VPInstruction::ResumePhi, {EndValue, Start},
87828780
WideIV->getDebugLoc(), "bc.resume.val");
@@ -8785,10 +8783,10 @@ static VPValue *addResumePhiRecipeForInduction(
87858783

87868784
/// Create resume phis in the scalar preheader for first-order recurrences,
87878785
/// reductions and inductions, and update the VPIRInstructions wrapping the
8788-
/// original phis in the scalar header.
8786+
/// original phis in the scalar header. End values for inductions are added to
8787+
/// \p IVEndValues.
87898788
static void addScalarResumePhis(VPRecipeBuilder &Builder, VPlan &Plan,
8790-
Loop *OrigLoop,
8791-
DenseMap<VPValue *, VPValue *> &EndValues) {
8789+
DenseMap<VPValue *, VPValue *> &IVEndValues) {
87928790
VPTypeAnalysis TypeInfo(Plan.getCanonicalIV()->getScalarType());
87938791
auto *ScalarPH = Plan.getScalarPreheader();
87948792
auto *MiddleVPBB = cast<VPBasicBlock>(ScalarPH->getSinglePredecessor());
@@ -8806,9 +8804,10 @@ static void addScalarResumePhis(VPRecipeBuilder &Builder, VPlan &Plan,
88068804

88078805
auto *VectorPhiR = cast<VPHeaderPHIRecipe>(Builder.getRecipe(ScalarPhiI));
88088806
if (auto *WideIVR = dyn_cast<VPWidenInductionRecipe>(VectorPhiR)) {
8809-
if (VPValue *ResumePhi = addResumePhiRecipeForInduction(
8807+
if (VPInstruction *ResumePhi = addResumePhiRecipeForInduction(
88108808
WideIVR, VectorPHBuilder, ScalarPHBuilder, TypeInfo,
8811-
&Plan.getVectorTripCount(), EndValues)) {
8809+
&Plan.getVectorTripCount())) {
8810+
IVEndValues[WideIVR] = ResumePhi->getOperand(0);
88128811
ScalarPhiIRI->addOperand(ResumePhi);
88138812
continue;
88148813
}
@@ -8837,57 +8836,6 @@ static void addScalarResumePhis(VPRecipeBuilder &Builder, VPlan &Plan,
88378836
}
88388837
}
88398838

8840-
static bool isIVUse(VPValue *Incoming) {
8841-
VPRecipeBase *IncomingDef = Incoming->getDefiningRecipe();
8842-
if (!IncomingDef)
8843-
return false;
8844-
auto *WideIV = dyn_cast<VPWidenInductionRecipe>(IncomingDef);
8845-
if (WideIV) {
8846-
return isa<VPWidenPointerInductionRecipe>(WideIV) || !cast<VPWidenIntOrFpInductionRecipe>(WideIV)->getTruncInst();
8847-
}
8848-
8849-
if (IncomingDef->getNumOperands() != 2)
8850-
return false;
8851-
WideIV = dyn_cast<VPWidenInductionRecipe>(IncomingDef->getOperand(0));
8852-
if (!WideIV)
8853-
WideIV = dyn_cast<VPWidenInductionRecipe>(IncomingDef->getOperand(1));
8854-
if (!WideIV)
8855-
return false;
8856-
8857-
using namespace VPlanPatternMatch;
8858-
auto &ID = WideIV->getInductionDescriptor();
8859-
switch (ID.getInductionOpcode()) {
8860-
case Instruction::Add:
8861-
return match(Incoming,
8862-
m_c_Binary<Instruction::Add>(
8863-
m_VPValue(), m_Specific(WideIV->getStepValue())));
8864-
case Instruction::FAdd:
8865-
return match(Incoming,
8866-
m_c_Binary<Instruction::FAdd>(
8867-
m_VPValue(), m_Specific(WideIV->getStepValue())));
8868-
case Instruction::FSub:
8869-
return match(Incoming,
8870-
m_Binary<Instruction::FSub>(
8871-
m_VPValue(), m_Specific(WideIV->getStepValue())));
8872-
case Instruction::Sub: {
8873-
VPValue *Step;
8874-
return match(Incoming,
8875-
m_Binary<Instruction::Sub>(m_VPValue(), m_VPValue(Step))) &&
8876-
Step->isLiveIn() && WideIV->getStepValue()->isLiveIn() &&
8877-
(cast<ConstantInt>(Step->getLiveInIRValue())->getValue() +
8878-
cast<ConstantInt>(WideIV->getStepValue()->getLiveInIRValue())
8879-
->getValue())
8880-
.isZero();
8881-
}
8882-
default:
8883-
return ID.getKind() == InductionDescriptor::IK_PtrInduction &&
8884-
match(
8885-
Incoming,
8886-
m_GetElementPtr(m_VPValue(), m_Specific(WideIV->getStepValue())));
8887-
}
8888-
llvm_unreachable("should have been covered by switch above");
8889-
}
8890-
88918839
// Collect VPIRInstructions for phis in the exit blocks that are modeled
88928840
// in VPlan and add the exiting VPValue as operand. Some exiting values are not
88938841
// modeled explicitly yet and won't be included. Those are un-truncated
@@ -8925,80 +8873,13 @@ collectUsersInExitBlocks(Loop *OrigLoop, VPRecipeBuilder &Builder,
89258873
return ExitUsersToFix;
89268874
}
89278875

8928-
/// If \p Incoming is a user of a non-truncated induction, create recipes to
8929-
/// compute the final value and update the user \p ExitIRI.
8930-
static bool addInductionEndValue(
8931-
VPlan &Plan, VPIRInstruction *ExitIRI, VPValue *Incoming,
8932-
const MapVector<PHINode *, InductionDescriptor> &Inductions,
8933-
DenseMap<VPValue *, VPValue *> &EndValues, VPTypeAnalysis &TypeInfo) {
8934-
if ((isa<VPWidenIntOrFpInductionRecipe>(Incoming) &&
8935-
!cast<VPWidenIntOrFpInductionRecipe>(Incoming)->getTruncInst()) ||
8936-
isa<VPWidenPointerInductionRecipe>(Incoming) ||
8937-
(isa<Instruction>(Incoming->getUnderlyingValue()) &&
8938-
any_of(cast<Instruction>(Incoming->getUnderlyingValue())->users(),
8939-
[&Inductions](User *U) {
8940-
auto *P = dyn_cast<PHINode>(U);
8941-
return P && Inductions.contains(P);
8942-
}))) {
8943-
VPValue *IV;
8944-
if (auto *WideIV =
8945-
dyn_cast<VPWidenInductionRecipe>(Incoming->getDefiningRecipe()))
8946-
IV = WideIV;
8947-
else if (auto *WideIV =
8948-
dyn_cast<VPWidenInductionRecipe>(Incoming->getDefiningRecipe()
8949-
->getOperand(0)
8950-
->getDefiningRecipe()))
8951-
IV = WideIV;
8952-
else
8953-
IV = Incoming->getDefiningRecipe()->getOperand(1);
8954-
// Skip phi nodes already updated. This can be the case if 2 induction
8955-
// phis chase each other.
8956-
VPValue *EndValue = EndValues[IV];
8957-
if (any_of(cast<VPRecipeBase>(Incoming->getDefiningRecipe())->operands(),
8958-
IsaPred<VPWidenIntOrFpInductionRecipe,
8959-
VPWidenPointerInductionRecipe>)) {
8960-
ExitIRI->setOperand(0, EndValue);
8961-
return true;
8962-
}
8963-
8964-
VPBuilder B(Plan.getMiddleBlock()->getTerminator());
8965-
VPValue *Escape = nullptr;
8966-
auto *WideIV = cast<VPWidenInductionRecipe>(IV->getDefiningRecipe());
8967-
VPValue *Step = WideIV->getStepValue();
8968-
Type *ScalarTy = TypeInfo.inferScalarType(WideIV);
8969-
if (ScalarTy->isIntegerTy())
8970-
Escape =
8971-
B.createNaryOp(Instruction::Sub, {EndValue, Step}, {}, "ind.escape");
8972-
else if (ScalarTy->isPointerTy())
8973-
Escape = B.createPtrAdd(
8974-
EndValue,
8975-
B.createNaryOp(Instruction::Sub,
8976-
{Plan.getOrAddLiveIn(ConstantInt::get(
8977-
Step->getLiveInIRValue()->getType(), 0)),
8978-
Step}),
8979-
{}, "ind.escape");
8980-
else if (ScalarTy->isFloatingPointTy()) {
8981-
const auto &ID = WideIV->getInductionDescriptor();
8982-
Escape = B.createNaryOp(
8983-
ID.getInductionBinOp()->getOpcode() == Instruction::FAdd
8984-
? Instruction::FSub
8985-
: Instruction::FAdd,
8986-
{EndValue, Step}, {ID.getInductionBinOp()->getFastMathFlags()});
8987-
} else {
8988-
llvm_unreachable("all possible induction types must be handled");
8989-
}
8990-
ExitIRI->setOperand(0, Escape);
8991-
return true;
8992-
}
8993-
return false;
8994-
}
89958876
// Add exit values to \p Plan. Extracts are added for each entry in \p
89968877
// ExitUsersToFix if needed and their operands are updated. Returns true if all
89978878
// exit users can be handled, otherwise return false.
8998-
static bool addUsersInExitBlocks(
8999-
VPlan &Plan, const SetVector<VPIRInstruction *> &ExitUsersToFix,
9000-
const MapVector<PHINode *, InductionDescriptor> &Inductions,
9001-
DenseMap<VPValue *, VPValue *> &EndValues) {
8879+
static bool
8880+
addUsersInExitBlocks(VPlan &Plan,
8881+
const SetVector<VPIRInstruction *> &ExitUsersToFix,
8882+
DenseMap<VPValue *, VPValue *> &IVEndValues) {
90028883
if (ExitUsersToFix.empty())
90038884
return true;
90048885

@@ -9020,16 +8901,11 @@ static bool addUsersInExitBlocks(
90208901
if (ExitIRI->getParent()->getSinglePredecessor() != MiddleVPBB)
90218902
return false;
90228903

9023-
VPValue *Incoming = ExitIRI->getOperand(0);
9024-
if (addInductionEndValue(Plan, ExitIRI, Incoming, Inductions, EndValues,
9025-
TypeInfo))
9026-
continue;
9027-
90288904
LLVMContext &Ctx = ExitIRI->getInstruction().getContext();
90298905
VPValue *Ext = B.createNaryOp(VPInstruction::ExtractFromEnd,
90308906
{Op, Plan.getOrAddLiveIn(ConstantInt::get(
90318907
IntegerType::get(Ctx, 32), 1))});
9032-
ExitIRI->setOperand(0, Ext);
8908+
ExitIRI->setOperand(Idx, Ext);
90338909
}
90348910
}
90358911
return true;
@@ -9324,13 +9200,12 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
93249200
VPlanTransforms::handleUncountableEarlyExit(
93259201
*Plan, *PSE.getSE(), OrigLoop, UncountableExitingBlock, RecipeBuilder);
93269202
}
9327-
DenseMap<VPValue *, VPValue *> EndValues;
9328-
addScalarResumePhis(RecipeBuilder, *Plan, OrigLoop, EndValues);
9203+
DenseMap<VPValue *, VPValue *> IVEndValues;
9204+
addScalarResumePhis(RecipeBuilder, *Plan, IVEndValues);
93299205
SetVector<VPIRInstruction *> ExitUsersToFix =
93309206
collectUsersInExitBlocks(OrigLoop, RecipeBuilder, *Plan);
93319207
addExitUsersForFirstOrderRecurrences(*Plan, ExitUsersToFix);
9332-
if (!addUsersInExitBlocks(*Plan, ExitUsersToFix,
9333-
EndValues)) {
9208+
if (!addUsersInExitBlocks(*Plan, ExitUsersToFix, IVEndValues)) {
93349209
reportVectorizationFailure(
93359210
"Some exit values in loop with uncountable exit not supported yet",
93369211
"UncountableEarlyExitLoopsUnsupportedExitValue", ORE, OrigLoop);
@@ -9409,6 +9284,8 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
94099284
VPlanTransforms::addActiveLaneMask(*Plan, ForControlFlow,
94109285
WithoutRuntimeCheck);
94119286
}
9287+
9288+
VPlanTransforms::optimizeInductionExitUsers(*Plan, IVEndValues);
94129289
return Plan;
94139290
}
94149291

@@ -9457,8 +9334,8 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
94579334
auto *HeaderR = cast<VPHeaderPHIRecipe>(&R);
94589335
RecipeBuilder.setRecipe(HeaderR->getUnderlyingInstr(), HeaderR);
94599336
}
9460-
DenseMap<VPValue *, VPValue *> EndValues;
9461-
addScalarResumePhis(RecipeBuilder, *Plan, OrigLoop, EndValues);
9337+
DenseMap<VPValue *, VPValue *> IVEndValues;
9338+
addScalarResumePhis(RecipeBuilder, *Plan, IVEndValues);
94629339

94639340
assert(verifyVPlanIsValid(*Plan) && "VPlan is invalid");
94649341
return Plan;

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,9 @@ Value *VPTransformState::get(VPValue *Def, bool NeedsScalar) {
311311
LastLane = 0;
312312
}
313313

314-
auto *LastDef = get(Def, LastLane);
314+
auto *LastValue = get(Def, LastLane);
315315
auto OldIP = Builder.saveIP();
316-
if (auto *LastInst = dyn_cast<Instruction>(LastDef)) {
316+
if (auto *LastInst = dyn_cast<Instruction>(LastValue)) {
317317
// TODO: Remove once VPDerivedIVReicpe can be simplified, which requires
318318
// vector trip count being modeled in VPlan.
319319
// Set the insert point after the last scalarized instruction or after the
@@ -339,7 +339,7 @@ Value *VPTransformState::get(VPValue *Def, bool NeedsScalar) {
339339
} else {
340340
// Initialize packing with insertelements to start from undef.
341341
assert(!VF.isScalable() && "VF is assumed to be non scalable.");
342-
Value *Undef = PoisonValue::get(VectorType::get(LastDef->getType(), VF));
342+
Value *Undef = PoisonValue::get(VectorType::get(LastValue->getType(), VF));
343343
set(Def, Undef);
344344
for (unsigned Lane = 0; Lane < VF.getKnownMinValue(); ++Lane)
345345
packScalarIntoVectorValue(Def, Lane);

llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ void VPIRInstruction::execute(VPTransformState &State) {
843843
BasicBlock *PredBB = State.CFG.VPBB2IRBB[PredVPBB];
844844
// Set insertion point in PredBB in case an extract needs to be generated.
845845
// TODO: Model extracts explicitly.
846-
State.Builder.SetInsertPoint(&*PredBB->getTerminator());
846+
State.Builder.SetInsertPoint(PredBB, PredBB->getFirstNonPHIIt());
847847
Value *V = State.get(ExitValue, VPLane(Lane));
848848
auto *Phi = cast<PHINode>(&I);
849849
// If there is no existing block for PredBB in the phi, add a new incoming

0 commit comments

Comments
 (0)