Skip to content

Commit

Permalink
[VPlan] VPWidenIntOrFpInductionRecipe inherits from VPHeaderPHIRecipe
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D144125
  • Loading branch information
michaelmaitland committed Mar 15, 2023
1 parent 141b7d4 commit 194f3dc
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 81 deletions.
164 changes: 86 additions & 78 deletions llvm/lib/Transforms/Vectorize/VPlan.h
Expand Up @@ -1024,78 +1024,6 @@ class VPWidenGEPRecipe : public VPRecipeBase, public VPValue {
#endif
};

/// A recipe for handling phi nodes of integer and floating-point inductions,
/// producing their vector values.
class VPWidenIntOrFpInductionRecipe : public VPRecipeBase, public VPValue {
PHINode *IV;
const InductionDescriptor &IndDesc;
bool NeedsVectorIV;

public:
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step,
const InductionDescriptor &IndDesc,
bool NeedsVectorIV)
: VPRecipeBase(VPDef::VPWidenIntOrFpInductionSC, {Start, Step}),
VPValue(this, IV), IV(IV), IndDesc(IndDesc),
NeedsVectorIV(NeedsVectorIV) {}

VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step,
const InductionDescriptor &IndDesc,
TruncInst *Trunc, bool NeedsVectorIV)
: VPRecipeBase(VPDef::VPWidenIntOrFpInductionSC, {Start, Step}),
VPValue(this, Trunc), IV(IV), IndDesc(IndDesc),
NeedsVectorIV(NeedsVectorIV) {}

~VPWidenIntOrFpInductionRecipe() override = default;

VP_CLASSOF_IMPL(VPDef::VPWidenIntOrFpInductionSC)

/// Generate the vectorized and scalarized versions of the phi node as
/// needed by their users.
void execute(VPTransformState &State) override;

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// Print the recipe.
void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const override;
#endif

/// Returns the start value of the induction.
VPValue *getStartValue() { return getOperand(0); }
const VPValue *getStartValue() const { return getOperand(0); }

/// Returns the step value of the induction.
VPValue *getStepValue() { return getOperand(1); }
const VPValue *getStepValue() const { return getOperand(1); }

/// Returns the first defined value as TruncInst, if it is one or nullptr
/// otherwise.
TruncInst *getTruncInst() {
return dyn_cast_or_null<TruncInst>(getVPValue(0)->getUnderlyingValue());
}
const TruncInst *getTruncInst() const {
return dyn_cast_or_null<TruncInst>(getVPValue(0)->getUnderlyingValue());
}

PHINode *getPHINode() { return IV; }

/// 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;

/// Returns the scalar type of the induction.
const Type *getScalarType() const {
const TruncInst *TruncI = getTruncInst();
return TruncI ? TruncI->getType() : IV->getType();
}

/// Returns true if a vector phi needs to be created for the induction.
bool needsVectorIV() const { return NeedsVectorIV; }
};

/// A pure virtual base class for all recipes modeling header phis, including
/// phis for first order recurrences, pointer inductions and reductions. The
/// start value is the first operand of the recipe and the incoming value from
Expand All @@ -1121,9 +1049,9 @@ class VPWidenIntOrFpInductionRecipe : public VPRecipeBase, public VPValue {
/// per-lane based on the canonical induction.
class VPHeaderPHIRecipe : public VPRecipeBase, public VPValue {
protected:
VPHeaderPHIRecipe(unsigned char VPDefID, PHINode *Phi,
VPHeaderPHIRecipe(unsigned char VPDefID, Instruction *UnderlyingInstr,
VPValue *Start = nullptr)
: VPRecipeBase(VPDefID, {}), VPValue(this, Phi) {
: VPRecipeBase(VPDefID, {}), VPValue(this, UnderlyingInstr) {
if (Start)
addOperand(Start);
}
Expand All @@ -1134,12 +1062,12 @@ class VPHeaderPHIRecipe : public VPRecipeBase, public VPValue {
/// Method to support type inquiry through isa, cast, and dyn_cast.
static inline bool classof(const VPRecipeBase *B) {
return B->getVPDefID() >= VPDef::VPFirstHeaderPHISC &&
B->getVPDefID() <= VPDef::VPLastPHISC;
B->getVPDefID() <= VPDef::VPLastHeaderPHISC;
}
static inline bool classof(const VPValue *V) {
auto *B = V->getDefiningRecipe();
return B && B->getVPDefID() >= VPRecipeBase::VPFirstHeaderPHISC &&
B->getVPDefID() <= VPRecipeBase::VPLastPHISC;
B->getVPDefID() <= VPRecipeBase::VPLastHeaderPHISC;
}

/// Generate the phi nodes.
Expand All @@ -1163,17 +1091,97 @@ class VPHeaderPHIRecipe : public VPRecipeBase, public VPValue {
void setStartValue(VPValue *V) { setOperand(0, V); }

/// Returns the incoming value from the loop backedge.
VPValue *getBackedgeValue() {
virtual VPValue *getBackedgeValue() {
return getOperand(1);
}

/// Returns the backedge value as a recipe. The backedge value is guaranteed
/// to be a recipe.
VPRecipeBase &getBackedgeRecipe() {
virtual VPRecipeBase &getBackedgeRecipe() {
return *getBackedgeValue()->getDefiningRecipe();
}
};

/// A recipe for handling phi nodes of integer and floating-point inductions,
/// producing their vector values.
class VPWidenIntOrFpInductionRecipe : public VPHeaderPHIRecipe {
PHINode *IV;
TruncInst *Trunc;
const InductionDescriptor &IndDesc;
bool NeedsVectorIV;

public:
VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step,
const InductionDescriptor &IndDesc,
bool NeedsVectorIV)
: VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, IV, Start), IV(IV),
Trunc(nullptr), IndDesc(IndDesc), NeedsVectorIV(NeedsVectorIV) {
addOperand(Step);
}

VPWidenIntOrFpInductionRecipe(PHINode *IV, VPValue *Start, VPValue *Step,
const InductionDescriptor &IndDesc,
TruncInst *Trunc, bool NeedsVectorIV)
: VPHeaderPHIRecipe(VPDef::VPWidenIntOrFpInductionSC, Trunc, Start),
IV(IV), Trunc(Trunc), IndDesc(IndDesc), NeedsVectorIV(NeedsVectorIV) {
addOperand(Step);
}

~VPWidenIntOrFpInductionRecipe() override = default;

VP_CLASSOF_IMPL(VPDef::VPWidenIntOrFpInductionSC)

/// Generate the vectorized and scalarized versions of the phi node as
/// needed by their users.
void execute(VPTransformState &State) override;

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// Print the recipe.
void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const override;
#endif

VPValue *getBackedgeValue() override {
// TODO: All operands of base recipe must exist and be at same index in
// derived recipe.
llvm_unreachable(
"VPWidenIntOrFpInductionRecipe generates its own backedge value");
}

VPRecipeBase &getBackedgeRecipe() override {
// TODO: All operands of base recipe must exist and be at same index in
// derived recipe.
llvm_unreachable(
"VPWidenIntOrFpInductionRecipe generates its own backedge value");
}

/// Returns the step value of the induction.
VPValue *getStepValue() { return getOperand(1); }
const VPValue *getStepValue() const { return getOperand(1); }

/// Returns the first defined value as TruncInst, if it is one or nullptr
/// otherwise.
TruncInst *getTruncInst() { return Trunc; }
const TruncInst *getTruncInst() const { return Trunc; }

PHINode *getPHINode() { return IV; }

/// 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;

/// Returns the scalar type of the induction.
const Type *getScalarType() const {
return Trunc ? Trunc->getType() : IV->getType();
}

/// Returns true if a vector phi needs to be created for the induction.
bool needsVectorIV() const { return NeedsVectorIV; }
};

class VPWidenPointerInductionRecipe : public VPHeaderPHIRecipe {
const InductionDescriptor &IndDesc;

Expand Down
9 changes: 6 additions & 3 deletions llvm/lib/Transforms/Vectorize/VPlanValue.h
Expand Up @@ -346,20 +346,23 @@ class VPDef {
VPWidenMemoryInstructionSC,
VPWidenSC,
VPWidenSelectSC,

// Phi-like recipes. Need to be kept together.
// START: Phi-like recipes. Need to be kept together.
VPBlendSC,
VPPredInstPHISC,
// Header-phi recipes. Need to be kept together.
// START: SubclassID for recipes that inherit VPHeaderPHIRecipe.
// VPHeaderPHIRecipe need to be kept together.
VPCanonicalIVPHISC,
VPActiveLaneMaskPHISC,
VPFirstOrderRecurrencePHISC,
VPWidenPHISC,
VPWidenIntOrFpInductionSC,
VPWidenPointerInductionSC,
VPReductionPHISC,
// END: SubclassID for recipes that inherit VPHeaderPHIRecipe
// END: Phi-like recipes
VPFirstPHISC = VPBlendSC,
VPFirstHeaderPHISC = VPCanonicalIVPHISC,
VPLastHeaderPHISC = VPReductionPHISC,
VPLastPHISC = VPReductionPHISC,
};

Expand Down

0 comments on commit 194f3dc

Please sign in to comment.