[llvm] c0cf209 - [VPlan] Add VPWidenIntOrFpInductionRecipe::isCanonical, use it (NFCI).
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 21 01:35:26 PST 2022
Author: Florian Hahn
Date: 2022-01-21T09:35:06Z
New Revision: c0cf209076a29076ebf43c59dff3cc3c8400e4d7
URL: https://github.com/llvm/llvm-project/commit/c0cf209076a29076ebf43c59dff3cc3c8400e4d7
DIFF: https://github.com/llvm/llvm-project/commit/c0cf209076a29076ebf43c59dff3cc3c8400e4d7.diff
LOG: [VPlan] Add VPWidenIntOrFpInductionRecipe::isCanonical, use it (NFCI).
This patch adds VPWidenIntOrFpInductionRecipe::isCanonical to check if
an induction recipe is canonical. The code is also updated to use it
instead of isCanonicalID.
Reviewed By: Ayal
Differential Revision: https://reviews.llvm.org/D117551
Added:
Modified:
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
llvm/lib/Transforms/Vectorize/VPlan.cpp
llvm/lib/Transforms/Vectorize/VPlan.h
llvm/lib/Transforms/Vectorize/VPlanValue.h
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 56b8bd8564f2a..d186ae59a74a2 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -510,8 +510,7 @@ class InnerLoopVectorizer {
/// is provided, the integer induction variable will first be truncated to
/// the corresponding type. \p CanonicalIV is the scalar value generated for
/// the canonical induction variable.
- void widenIntOrFpInduction(PHINode *IV, const InductionDescriptor &ID,
- Value *Start, TruncInst *Trunc, VPValue *Def,
+ void widenIntOrFpInduction(PHINode *IV, VPWidenIntOrFpInductionRecipe *Def,
VPTransformState &State, Value *CanonicalIV);
/// Construct the vector value of a scalarized value \p V one lane at a time.
@@ -2478,17 +2477,12 @@ bool InnerLoopVectorizer::needsScalarInduction(Instruction *IV) const {
return llvm::any_of(IV->users(), isScalarInst);
}
-/// Returns true if \p ID starts at 0 and has a step of 1.
-static bool isCanonicalID(const InductionDescriptor &ID) {
- if (!ID.getConstIntStepValue() || !ID.getConstIntStepValue()->isOne())
- return false;
- auto *StartC = dyn_cast<ConstantInt>(ID.getStartValue());
- return StartC && StartC->isZero();
-}
-
void InnerLoopVectorizer::widenIntOrFpInduction(
- PHINode *IV, const InductionDescriptor &ID, Value *Start, TruncInst *Trunc,
- VPValue *Def, VPTransformState &State, Value *CanonicalIV) {
+ PHINode *IV, VPWidenIntOrFpInductionRecipe *Def, VPTransformState &State,
+ Value *CanonicalIV) {
+ Value *Start = Def->getStartValue()->getLiveInIRValue();
+ const InductionDescriptor &ID = Def->getInductionDescriptor();
+ TruncInst *Trunc = Def->getTruncInst();
IRBuilder<> &Builder = State.Builder;
assert(IV->getType() == ID.getStartValue()->getType() && "Types must match");
assert(!State.VF.isZero() && "VF must be non-zero");
@@ -2519,7 +2513,7 @@ void InnerLoopVectorizer::widenIntOrFpInduction(
auto CreateScalarIV = [&](Value *&Step) -> Value * {
Value *ScalarIV = CanonicalIV;
Type *NeededType = IV->getType();
- if (!isCanonicalID(ID) || ScalarIV->getType() != NeededType) {
+ if (!Def->isCanonical() || ScalarIV->getType() != NeededType) {
ScalarIV =
NeededType->isIntegerTy()
? Builder.CreateSExtOrTrunc(ScalarIV, NeededType)
@@ -9702,9 +9696,7 @@ void VPWidenGEPRecipe::execute(VPTransformState &State) {
void VPWidenIntOrFpInductionRecipe::execute(VPTransformState &State) {
assert(!State.Instance && "Int or FP induction being replicated.");
auto *CanonicalIV = State.get(getParent()->getPlan()->getCanonicalIV(), 0);
- State.ILV->widenIntOrFpInduction(IV, getInductionDescriptor(),
- getStartValue()->getLiveInIRValue(),
- getTruncInst(), this, State, CanonicalIV);
+ State.ILV->widenIntOrFpInduction(IV, this, State, CanonicalIV);
}
void VPWidenPHIRecipe::execute(VPTransformState &State) {
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp
index 04c8e399c5438..0ec2361390590 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp
@@ -1263,6 +1263,12 @@ void VPWidenIntOrFpInductionRecipe::print(raw_ostream &O, const Twine &Indent,
O << " " << VPlanIngredient(IV);
}
+bool VPWidenIntOrFpInductionRecipe::isCanonical() const {
+ auto *StartC = dyn_cast<ConstantInt>(getStartValue()->getLiveInIRValue());
+ auto *StepC = dyn_cast<SCEVConstant>(getInductionDescriptor().getStep());
+ return StartC && StartC->isZero() && StepC && StepC->isOne();
+}
+
void VPWidenGEPRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
O << Indent << "WIDEN-GEP ";
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index c7946b6d2adef..10d5c1b3409a5 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -1059,6 +1059,7 @@ class VPWidenIntOrFpInductionRecipe : public VPRecipeBase, public VPValue {
/// Returns the start value of the induction.
VPValue *getStartValue() { return getOperand(0); }
+ const VPValue *getStartValue() const { return getOperand(0); }
/// Returns the first defined value as TruncInst, if it is one or nullptr
/// otherwise.
@@ -1071,6 +1072,10 @@ class VPWidenIntOrFpInductionRecipe : public VPRecipeBase, public VPValue {
/// Returns the induction descriptor for the recipe.
const InductionDescriptor &getInductionDescriptor() const { return IndDesc; }
+
+ /// Returns true if the induction is canonical, i.e. starting at 0 and
+ /// incremented by UF * VF (= the original IV is incremented by 1).
+ bool isCanonical() const;
};
/// A pure virtual base class for all recipes modeling header phis, including
diff --git a/llvm/lib/Transforms/Vectorize/VPlanValue.h b/llvm/lib/Transforms/Vectorize/VPlanValue.h
index 2df547e960ba9..5296d2b9485cc 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanValue.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanValue.h
@@ -178,6 +178,7 @@ class VPValue {
void replaceAllUsesWith(VPValue *New);
VPDef *getDef() { return Def; }
+ const VPDef *getDef() const { return Def; }
/// Returns the underlying IR value, if this VPValue is defined outside the
/// scope of VPlan. Returns nullptr if the VPValue is defined by a VPDef
@@ -187,6 +188,11 @@ class VPValue {
"VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
return getUnderlyingValue();
}
+ const Value *getLiveInIRValue() const {
+ assert(!getDef() &&
+ "VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
+ return getUnderlyingValue();
+ }
};
typedef DenseMap<Value *, VPValue *> Value2VPValueTy;
More information about the llvm-commits
mailing list