Skip to content

Commit 56f5738

Browse files
committed
[LV] Move induction ::execute impls to VPlanRecipes.cpp (NFC).
All dependencies on code from LoopVectorize.cpp have been removed/refactored. Move the ::execute implementations to other recipe definitions in VPlanRecipes.cpp
1 parent 69e47de commit 56f5738

File tree

2 files changed

+268
-266
lines changed

2 files changed

+268
-266
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 0 additions & 266 deletions
Original file line numberDiff line numberDiff line change
@@ -408,13 +408,6 @@ static bool hasIrregularType(Type *Ty, const DataLayout &DL) {
408408
/// we always assume predicated blocks have a 50% chance of executing.
409409
static unsigned getReciprocalPredBlockProb() { return 2; }
410410

411-
/// A helper function that returns an integer or floating-point constant with
412-
/// value C.
413-
static Constant *getSignedIntOrFpConstant(Type *Ty, int64_t C) {
414-
return Ty->isIntegerTy() ? ConstantInt::getSigned(Ty, C)
415-
: ConstantFP::get(Ty, C);
416-
}
417-
418411
/// Returns "best known" trip count for the specified loop \p L as defined by
419412
/// the following procedure:
420413
/// 1) Returns exact trip count if it is known.
@@ -1017,14 +1010,6 @@ const SCEV *createTripCountSCEV(Type *IdxTy, PredicatedScalarEvolution &PSE,
10171010
return SE.getTripCountFromExitCount(BackedgeTakenCount, IdxTy, OrigLoop);
10181011
}
10191012

1020-
static Value *getRuntimeVFAsFloat(IRBuilderBase &B, Type *FTy,
1021-
ElementCount VF) {
1022-
assert(FTy->isFloatingPointTy() && "Expected floating point type!");
1023-
Type *IntTy = IntegerType::get(FTy->getContext(), FTy->getScalarSizeInBits());
1024-
Value *RuntimeVF = getRuntimeVF(B, IntTy, VF);
1025-
return B.CreateUIToFP(RuntimeVF, FTy);
1026-
}
1027-
10281013
void reportVectorizationFailure(const StringRef DebugMsg,
10291014
const StringRef OREMsg, const StringRef ORETag,
10301015
OptimizationRemarkEmitter *ORE, Loop *TheLoop,
@@ -2234,59 +2219,6 @@ static void collectSupportedLoops(Loop &L, LoopInfo *LI,
22342219
// LoopVectorizationCostModel and LoopVectorizationPlanner.
22352220
//===----------------------------------------------------------------------===//
22362221

2237-
/// This function adds
2238-
/// (StartIdx * Step, (StartIdx + 1) * Step, (StartIdx + 2) * Step, ...)
2239-
/// to each vector element of Val. The sequence starts at StartIndex.
2240-
/// \p Opcode is relevant for FP induction variable.
2241-
static Value *getStepVector(Value *Val, Value *StartIdx, Value *Step,
2242-
Instruction::BinaryOps BinOp, ElementCount VF,
2243-
IRBuilderBase &Builder) {
2244-
assert(VF.isVector() && "only vector VFs are supported");
2245-
2246-
// Create and check the types.
2247-
auto *ValVTy = cast<VectorType>(Val->getType());
2248-
ElementCount VLen = ValVTy->getElementCount();
2249-
2250-
Type *STy = Val->getType()->getScalarType();
2251-
assert((STy->isIntegerTy() || STy->isFloatingPointTy()) &&
2252-
"Induction Step must be an integer or FP");
2253-
assert(Step->getType() == STy && "Step has wrong type");
2254-
2255-
SmallVector<Constant *, 8> Indices;
2256-
2257-
// Create a vector of consecutive numbers from zero to VF.
2258-
VectorType *InitVecValVTy = ValVTy;
2259-
if (STy->isFloatingPointTy()) {
2260-
Type *InitVecValSTy =
2261-
IntegerType::get(STy->getContext(), STy->getScalarSizeInBits());
2262-
InitVecValVTy = VectorType::get(InitVecValSTy, VLen);
2263-
}
2264-
Value *InitVec = Builder.CreateStepVector(InitVecValVTy);
2265-
2266-
// Splat the StartIdx
2267-
Value *StartIdxSplat = Builder.CreateVectorSplat(VLen, StartIdx);
2268-
2269-
if (STy->isIntegerTy()) {
2270-
InitVec = Builder.CreateAdd(InitVec, StartIdxSplat);
2271-
Step = Builder.CreateVectorSplat(VLen, Step);
2272-
assert(Step->getType() == Val->getType() && "Invalid step vec");
2273-
// FIXME: The newly created binary instructions should contain nsw/nuw
2274-
// flags, which can be found from the original scalar operations.
2275-
Step = Builder.CreateMul(InitVec, Step);
2276-
return Builder.CreateAdd(Val, Step, "induction");
2277-
}
2278-
2279-
// Floating point induction.
2280-
assert((BinOp == Instruction::FAdd || BinOp == Instruction::FSub) &&
2281-
"Binary Opcode should be specified for FP induction");
2282-
InitVec = Builder.CreateUIToFP(InitVec, ValVTy);
2283-
InitVec = Builder.CreateFAdd(InitVec, StartIdxSplat);
2284-
2285-
Step = Builder.CreateVectorSplat(VLen, Step);
2286-
Value *MulOp = Builder.CreateFMul(InitVec, Step);
2287-
return Builder.CreateBinOp(BinOp, Val, MulOp, "induction");
2288-
}
2289-
22902222
/// Compute the transformed value of Index at offset StartValue using step
22912223
/// StepValue.
22922224
/// For integer induction, returns StartValue + Index * StepValue.
@@ -9188,107 +9120,6 @@ void VPInterleaveRecipe::print(raw_ostream &O, const Twine &Indent,
91889120
}
91899121
#endif
91909122

9191-
void VPWidenIntOrFpInductionRecipe::execute(VPTransformState &State) {
9192-
assert(!State.Instance && "Int or FP induction being replicated.");
9193-
9194-
Value *Start = getStartValue()->getLiveInIRValue();
9195-
const InductionDescriptor &ID = getInductionDescriptor();
9196-
TruncInst *Trunc = getTruncInst();
9197-
IRBuilderBase &Builder = State.Builder;
9198-
assert(IV->getType() == ID.getStartValue()->getType() && "Types must match");
9199-
assert(State.VF.isVector() && "must have vector VF");
9200-
9201-
// The value from the original loop to which we are mapping the new induction
9202-
// variable.
9203-
Instruction *EntryVal = Trunc ? cast<Instruction>(Trunc) : IV;
9204-
9205-
// Fast-math-flags propagate from the original induction instruction.
9206-
IRBuilder<>::FastMathFlagGuard FMFG(Builder);
9207-
if (ID.getInductionBinOp() && isa<FPMathOperator>(ID.getInductionBinOp()))
9208-
Builder.setFastMathFlags(ID.getInductionBinOp()->getFastMathFlags());
9209-
9210-
// Now do the actual transformations, and start with fetching the step value.
9211-
Value *Step = State.get(getStepValue(), VPIteration(0, 0));
9212-
9213-
assert((isa<PHINode>(EntryVal) || isa<TruncInst>(EntryVal)) &&
9214-
"Expected either an induction phi-node or a truncate of it!");
9215-
9216-
// Construct the initial value of the vector IV in the vector loop preheader
9217-
auto CurrIP = Builder.saveIP();
9218-
BasicBlock *VectorPH = State.CFG.getPreheaderBBFor(this);
9219-
Builder.SetInsertPoint(VectorPH->getTerminator());
9220-
if (isa<TruncInst>(EntryVal)) {
9221-
assert(Start->getType()->isIntegerTy() &&
9222-
"Truncation requires an integer type");
9223-
auto *TruncType = cast<IntegerType>(EntryVal->getType());
9224-
Step = Builder.CreateTrunc(Step, TruncType);
9225-
Start = Builder.CreateCast(Instruction::Trunc, Start, TruncType);
9226-
}
9227-
9228-
Value *Zero = getSignedIntOrFpConstant(Start->getType(), 0);
9229-
Value *SplatStart = Builder.CreateVectorSplat(State.VF, Start);
9230-
Value *SteppedStart = getStepVector(
9231-
SplatStart, Zero, Step, ID.getInductionOpcode(), State.VF, State.Builder);
9232-
9233-
// We create vector phi nodes for both integer and floating-point induction
9234-
// variables. Here, we determine the kind of arithmetic we will perform.
9235-
Instruction::BinaryOps AddOp;
9236-
Instruction::BinaryOps MulOp;
9237-
if (Step->getType()->isIntegerTy()) {
9238-
AddOp = Instruction::Add;
9239-
MulOp = Instruction::Mul;
9240-
} else {
9241-
AddOp = ID.getInductionOpcode();
9242-
MulOp = Instruction::FMul;
9243-
}
9244-
9245-
// Multiply the vectorization factor by the step using integer or
9246-
// floating-point arithmetic as appropriate.
9247-
Type *StepType = Step->getType();
9248-
Value *RuntimeVF;
9249-
if (Step->getType()->isFloatingPointTy())
9250-
RuntimeVF = getRuntimeVFAsFloat(Builder, StepType, State.VF);
9251-
else
9252-
RuntimeVF = getRuntimeVF(Builder, StepType, State.VF);
9253-
Value *Mul = Builder.CreateBinOp(MulOp, Step, RuntimeVF);
9254-
9255-
// Create a vector splat to use in the induction update.
9256-
//
9257-
// FIXME: If the step is non-constant, we create the vector splat with
9258-
// IRBuilder. IRBuilder can constant-fold the multiply, but it doesn't
9259-
// handle a constant vector splat.
9260-
Value *SplatVF = isa<Constant>(Mul)
9261-
? ConstantVector::getSplat(State.VF, cast<Constant>(Mul))
9262-
: Builder.CreateVectorSplat(State.VF, Mul);
9263-
Builder.restoreIP(CurrIP);
9264-
9265-
// We may need to add the step a number of times, depending on the unroll
9266-
// factor. The last of those goes into the PHI.
9267-
PHINode *VecInd = PHINode::Create(SteppedStart->getType(), 2, "vec.ind",
9268-
&*State.CFG.PrevBB->getFirstInsertionPt());
9269-
VecInd->setDebugLoc(EntryVal->getDebugLoc());
9270-
Instruction *LastInduction = VecInd;
9271-
for (unsigned Part = 0; Part < State.UF; ++Part) {
9272-
State.set(this, LastInduction, Part);
9273-
9274-
if (isa<TruncInst>(EntryVal))
9275-
State.addMetadata(LastInduction, EntryVal);
9276-
9277-
LastInduction = cast<Instruction>(
9278-
Builder.CreateBinOp(AddOp, LastInduction, SplatVF, "step.add"));
9279-
LastInduction->setDebugLoc(EntryVal->getDebugLoc());
9280-
}
9281-
9282-
LastInduction->setName("vec.ind.next");
9283-
VecInd->addIncoming(SteppedStart, VectorPH);
9284-
// Add induction update using an incorrect block temporarily. The phi node
9285-
// will be fixed after VPlan execution. Note that at this point the latch
9286-
// block cannot be used, as it does not exist yet.
9287-
// TODO: Model increment value in VPlan, by turning the recipe into a
9288-
// multi-def and a subclass of VPHeaderPHIRecipe.
9289-
VecInd->addIncoming(LastInduction, VectorPH);
9290-
}
9291-
92929123
void VPWidenPointerInductionRecipe::execute(VPTransformState &State) {
92939124
assert(IndDesc.getKind() == InductionDescriptor::IK_PtrInduction &&
92949125
"Not a pointer induction according to InductionDescriptor!");
@@ -9409,103 +9240,6 @@ void VPDerivedIVRecipe::execute(VPTransformState &State) {
94099240
State.set(this, DerivedIV, VPIteration(0, 0));
94109241
}
94119242

9412-
void VPScalarIVStepsRecipe::execute(VPTransformState &State) {
9413-
// Fast-math-flags propagate from the original induction instruction.
9414-
IRBuilder<>::FastMathFlagGuard FMFG(State.Builder);
9415-
if (IndDesc.getInductionBinOp() &&
9416-
isa<FPMathOperator>(IndDesc.getInductionBinOp()))
9417-
State.Builder.setFastMathFlags(
9418-
IndDesc.getInductionBinOp()->getFastMathFlags());
9419-
9420-
/// Compute scalar induction steps. \p ScalarIV is the scalar induction
9421-
/// variable on which to base the steps, \p Step is the size of the step.
9422-
9423-
Value *BaseIV = State.get(getOperand(0), VPIteration(0, 0));
9424-
Value *Step = State.get(getStepValue(), VPIteration(0, 0));
9425-
IRBuilderBase &Builder = State.Builder;
9426-
9427-
// Ensure step has the same type as that of scalar IV.
9428-
Type *BaseIVTy = BaseIV->getType()->getScalarType();
9429-
if (BaseIVTy != Step->getType()) {
9430-
// TODO: Also use VPDerivedIVRecipe when only the step needs truncating, to
9431-
// avoid separate truncate here.
9432-
assert(Step->getType()->isIntegerTy() &&
9433-
"Truncation requires an integer step");
9434-
Step = State.Builder.CreateTrunc(Step, BaseIVTy);
9435-
}
9436-
9437-
// We build scalar steps for both integer and floating-point induction
9438-
// variables. Here, we determine the kind of arithmetic we will perform.
9439-
Instruction::BinaryOps AddOp;
9440-
Instruction::BinaryOps MulOp;
9441-
if (BaseIVTy->isIntegerTy()) {
9442-
AddOp = Instruction::Add;
9443-
MulOp = Instruction::Mul;
9444-
} else {
9445-
AddOp = IndDesc.getInductionOpcode();
9446-
MulOp = Instruction::FMul;
9447-
}
9448-
9449-
// Determine the number of scalars we need to generate for each unroll
9450-
// iteration.
9451-
bool FirstLaneOnly = vputils::onlyFirstLaneUsed(this);
9452-
// Compute the scalar steps and save the results in State.
9453-
Type *IntStepTy =
9454-
IntegerType::get(BaseIVTy->getContext(), BaseIVTy->getScalarSizeInBits());
9455-
Type *VecIVTy = nullptr;
9456-
Value *UnitStepVec = nullptr, *SplatStep = nullptr, *SplatIV = nullptr;
9457-
if (!FirstLaneOnly && State.VF.isScalable()) {
9458-
VecIVTy = VectorType::get(BaseIVTy, State.VF);
9459-
UnitStepVec =
9460-
Builder.CreateStepVector(VectorType::get(IntStepTy, State.VF));
9461-
SplatStep = Builder.CreateVectorSplat(State.VF, Step);
9462-
SplatIV = Builder.CreateVectorSplat(State.VF, BaseIV);
9463-
}
9464-
9465-
unsigned StartPart = 0;
9466-
unsigned EndPart = State.UF;
9467-
unsigned StartLane = 0;
9468-
unsigned EndLane = FirstLaneOnly ? 1 : State.VF.getKnownMinValue();
9469-
if (State.Instance) {
9470-
StartPart = State.Instance->Part;
9471-
EndPart = StartPart + 1;
9472-
StartLane = State.Instance->Lane.getKnownLane();
9473-
EndLane = StartLane + 1;
9474-
}
9475-
for (unsigned Part = StartPart; Part < EndPart; ++Part) {
9476-
Value *StartIdx0 = createStepForVF(Builder, IntStepTy, State.VF, Part);
9477-
9478-
if (!FirstLaneOnly && State.VF.isScalable()) {
9479-
auto *SplatStartIdx = Builder.CreateVectorSplat(State.VF, StartIdx0);
9480-
auto *InitVec = Builder.CreateAdd(SplatStartIdx, UnitStepVec);
9481-
if (BaseIVTy->isFloatingPointTy())
9482-
InitVec = Builder.CreateSIToFP(InitVec, VecIVTy);
9483-
auto *Mul = Builder.CreateBinOp(MulOp, InitVec, SplatStep);
9484-
auto *Add = Builder.CreateBinOp(AddOp, SplatIV, Mul);
9485-
State.set(this, Add, Part);
9486-
// It's useful to record the lane values too for the known minimum number
9487-
// of elements so we do those below. This improves the code quality when
9488-
// trying to extract the first element, for example.
9489-
}
9490-
9491-
if (BaseIVTy->isFloatingPointTy())
9492-
StartIdx0 = Builder.CreateSIToFP(StartIdx0, BaseIVTy);
9493-
9494-
for (unsigned Lane = StartLane; Lane < EndLane; ++Lane) {
9495-
Value *StartIdx = Builder.CreateBinOp(
9496-
AddOp, StartIdx0, getSignedIntOrFpConstant(BaseIVTy, Lane));
9497-
// The step returned by `createStepForVF` is a runtime-evaluated value
9498-
// when VF is scalable. Otherwise, it should be folded into a Constant.
9499-
assert((State.VF.isScalable() || isa<Constant>(StartIdx)) &&
9500-
"Expected StartIdx to be folded to a constant when VF is not "
9501-
"scalable");
9502-
auto *Mul = Builder.CreateBinOp(MulOp, StartIdx, Step);
9503-
auto *Add = Builder.CreateBinOp(AddOp, BaseIV, Mul);
9504-
State.set(this, Add, VPIteration(Part, Lane));
9505-
}
9506-
}
9507-
}
9508-
95099243
void VPInterleaveRecipe::execute(VPTransformState &State) {
95109244
assert(!State.Instance && "Interleave group being replicated.");
95119245
State.ILV->vectorizeInterleaveGroup(IG, definedValues(), State, getAddr(),

0 commit comments

Comments
 (0)