[VPlan] Update VPValue::getDef to return VPRecipeBase, adjust name(NFC)

The return value of getDef is guaranteed to be a VPRecipeBase and all
users can also accept a VPRecipeBase *. Most users actually case to
VPRecipeBase or a specific recipe before using it, so this change
removes a number of redundant casts.

Also rename it to getDefiningRecipe to make the name a bit clearer.

Reviewed By: Ayal

Differential Revision: https://reviews.llvm.org/D136068
This commit is contained in:
Florian Hahn
2022-11-16 22:12:08 +00:00
parent 06e972ed91
commit 32f1c5531b
6 changed files with 53 additions and 45 deletions

View File

@@ -1050,8 +1050,8 @@ void InnerLoopVectorizer::collectPoisonGeneratingRecipes(
// Add new definitions to the worklist.
for (VPValue *operand : CurRec->operands())
if (VPDef *OpDef = operand->getDef())
Worklist.push_back(cast<VPRecipeBase>(OpDef));
if (VPRecipeBase *OpDef = operand->getDefiningRecipe())
Worklist.push_back(OpDef);
}
});
@@ -1064,13 +1064,12 @@ void InnerLoopVectorizer::collectPoisonGeneratingRecipes(
for (VPRecipeBase &Recipe : *VPBB) {
if (auto *WidenRec = dyn_cast<VPWidenMemoryInstructionRecipe>(&Recipe)) {
Instruction &UnderlyingInstr = WidenRec->getIngredient();
VPDef *AddrDef = WidenRec->getAddr()->getDef();
VPRecipeBase *AddrDef = WidenRec->getAddr()->getDefiningRecipe();
if (AddrDef && WidenRec->isConsecutive() &&
Legal->blockNeedsPredication(UnderlyingInstr.getParent()))
collectPoisonGeneratingInstrsInBackwardSlice(
cast<VPRecipeBase>(AddrDef));
collectPoisonGeneratingInstrsInBackwardSlice(AddrDef);
} else if (auto *InterleaveRec = dyn_cast<VPInterleaveRecipe>(&Recipe)) {
VPDef *AddrDef = InterleaveRec->getAddr()->getDef();
VPRecipeBase *AddrDef = InterleaveRec->getAddr()->getDefiningRecipe();
if (AddrDef) {
// Check if any member of the interleave group needs predication.
const InterleaveGroup<Instruction> *InterGroup =
@@ -1085,8 +1084,7 @@ void InnerLoopVectorizer::collectPoisonGeneratingRecipes(
}
if (NeedPredication)
collectPoisonGeneratingInstrsInBackwardSlice(
cast<VPRecipeBase>(AddrDef));
collectPoisonGeneratingInstrsInBackwardSlice(AddrDef);
}
}
}
@@ -8481,11 +8479,12 @@ VPBasicBlock *VPRecipeBuilder::handleReplication(
// value. Avoid hoisting the insert-element which packs the scalar value into
// a vector value, as that happens iff all users use the vector value.
for (VPValue *Op : Recipe->operands()) {
auto *PredR = dyn_cast_or_null<VPPredInstPHIRecipe>(Op->getDef());
auto *PredR =
dyn_cast_or_null<VPPredInstPHIRecipe>(Op->getDefiningRecipe());
if (!PredR)
continue;
auto *RepR =
cast_or_null<VPReplicateRecipe>(PredR->getOperand(0)->getDef());
auto *RepR = cast_or_null<VPReplicateRecipe>(
PredR->getOperand(0)->getDefiningRecipe());
assert(RepR->isPredicated() &&
"expected Replicate recipe to be predicated");
RepR->setAlsoPack(false);
@@ -8911,7 +8910,7 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
Plan->addVPValue(Instr, VPV);
// If the re-used value is a recipe, register the recipe for the
// instruction, in case the recipe for Instr needs to be recorded.
if (auto *R = dyn_cast_or_null<VPRecipeBase>(VPV->getDef()))
if (VPRecipeBase *R = VPV->getDefiningRecipe())
RecipeBuilder.setRecipe(Instr, R);
continue;
}
@@ -9055,12 +9054,12 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
if (!RecurPhi)
continue;
VPRecipeBase *PrevRecipe = RecurPhi->getBackedgeRecipe();
VPRecipeBase *PrevRecipe = &RecurPhi->getBackedgeRecipe();
// Fixed-order recurrences do not contain cycles, so this loop is guaranteed
// to terminate.
while (auto *PrevPhi =
dyn_cast<VPFirstOrderRecurrencePHIRecipe>(PrevRecipe))
PrevRecipe = PrevPhi->getBackedgeRecipe();
PrevRecipe = &PrevPhi->getBackedgeRecipe();
VPBasicBlock *InsertBlock = PrevRecipe->getParent();
auto *Region = GetReplicateRegion(PrevRecipe);
if (Region)
@@ -9283,7 +9282,7 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
VPValue *Cond =
RecipeBuilder.createBlockInMask(OrigLoop->getHeader(), Plan);
VPValue *Red = PhiR->getBackedgeValue();
assert(cast<VPRecipeBase>(Red->getDef())->getParent() != LatchVPBB &&
assert(Red->getDefiningRecipe()->getParent() != LatchVPBB &&
"reduction recipe must be defined before latch");
Builder.createNaryOp(Instruction::Select, {Cond, Red, PhiR});
}
@@ -9657,7 +9656,7 @@ void VPReplicateRecipe::execute(VPTransformState &State) {
// A store of a loop varying value to a loop invariant address only
// needs only the last copy of the store.
if (isa<StoreInst>(UI) && !getOperand(1)->getDef()) {
if (isa<StoreInst>(UI) && !getOperand(1)->getDefiningRecipe()) {
auto Lane = VPLane::getLastLaneForVF(State.VF);
State.ILV->scalarizeInstruction(UI, this, VPIteration(State.UF - 1, Lane), IsPredicated,
State);
@@ -9875,8 +9874,8 @@ Value *VPTransformState::get(VPValue *Def, unsigned Part) {
// Check if there is a scalar value for the selected lane.
if (!hasScalarValue(Def, {Part, LastLane})) {
// At the moment, VPWidenIntOrFpInductionRecipes can also be uniform.
assert((isa<VPWidenIntOrFpInductionRecipe>(Def->getDef()) ||
isa<VPScalarIVStepsRecipe>(Def->getDef())) &&
assert((isa<VPWidenIntOrFpInductionRecipe>(Def->getDefiningRecipe()) ||
isa<VPScalarIVStepsRecipe>(Def->getDefiningRecipe())) &&
"unexpected recipe found to be invariant");
IsUniform = true;
LastLane = 0;

View File

@@ -109,6 +109,14 @@ void VPDef::dump() const {
}
#endif
VPRecipeBase *VPValue::getDefiningRecipe() {
return cast_or_null<VPRecipeBase>(Def);
}
const VPRecipeBase *VPValue::getDefiningRecipe() const {
return cast_or_null<VPRecipeBase>(Def);
}
// Get the top-most entry block of \p Start. This is the entry block of the
// containing VPlan. This function is templated to support both const and non-const blocks
template <typename T> static T *getPlanEntry(T *Start) {
@@ -202,7 +210,7 @@ VPBasicBlock::iterator VPBasicBlock::getFirstNonPhi() {
}
Value *VPTransformState::get(VPValue *Def, const VPIteration &Instance) {
if (!Def->getDef())
if (!Def->getDefiningRecipe())
return Def->getLiveInIRValue();
if (hasScalarValue(Def, Instance)) {
@@ -1104,6 +1112,6 @@ VPValue *vputils::getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
VPBasicBlock *Preheader = Plan.getEntry()->getEntryBasicBlock();
VPValue *Step = new VPExpandSCEVRecipe(Expr, SE);
Preheader->appendRecipe(cast<VPRecipeBase>(Step->getDef()));
Preheader->appendRecipe(Step->getDefiningRecipe());
return Step;
}

View File

@@ -1175,8 +1175,8 @@ public:
/// Returns the backedge value as a recipe. The backedge value is guaranteed
/// to be a recipe.
VPRecipeBase *getBackedgeRecipe() {
return cast<VPRecipeBase>(getBackedgeValue()->getDef());
VPRecipeBase &getBackedgeRecipe() {
return *getBackedgeValue()->getDefiningRecipe();
}
};
@@ -1944,7 +1944,7 @@ public:
/// Returns the scalar type of the induction.
const Type *getScalarType() const {
return cast<VPCanonicalIVPHIRecipe>(getOperand(0)->getDef())
return cast<VPCanonicalIVPHIRecipe>(getOperand(0)->getDefiningRecipe())
->getScalarType();
}
};
@@ -3059,7 +3059,7 @@ inline bool isUniformAfterVectorization(VPValue *VPV) {
// vectorization inside a vector region.
if (VPV->isDefinedOutsideVectorRegions())
return true;
VPDef *Def = VPV->getDef();
VPRecipeBase *Def = VPV->getDefiningRecipe();
assert(Def && "Must have definition for value defined inside vector region");
if (auto Rep = dyn_cast<VPReplicateRecipe>(Def))
return Rep->isUniform();

View File

@@ -723,7 +723,7 @@ bool VPScalarIVStepsRecipe::isCanonical() const {
if (CanIV->getStartValue() != getStartValue())
return false;
auto *StepVPV = getStepValue();
if (StepVPV->getDef())
if (StepVPV->getDefiningRecipe())
return false;
auto *StepC = dyn_cast_or_null<ConstantInt>(StepVPV->getLiveInIRValue());
return StepC && StepC->isOne();

View File

@@ -182,19 +182,21 @@ public:
void replaceAllUsesWith(VPValue *New);
VPDef *getDef() { return Def; }
const VPDef *getDef() const { return Def; }
/// Returns the recipe defining this VPValue or nullptr if it is not defined
/// by a recipe, i.e. is a live-in.
VPRecipeBase *getDefiningRecipe();
const VPRecipeBase *getDefiningRecipe() const;
/// 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
/// inside a VPlan.
Value *getLiveInIRValue() {
assert(!getDef() &&
assert(!getDefiningRecipe() &&
"VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
return getUnderlyingValue();
}
const Value *getLiveInIRValue() const {
assert(!getDef() &&
assert(!getDefiningRecipe() &&
"VPValue is not a live-in; it is defined by a VPDef inside a VPlan");
return getUnderlyingValue();
}
@@ -202,7 +204,7 @@ public:
/// Returns true if the VPValue is defined outside any vector regions, i.e. it
/// is a live-in value.
/// TODO: Also handle recipes defined in pre-header blocks.
bool isDefinedOutsideVectorRegions() const { return !getDef(); }
bool isDefinedOutsideVectorRegions() const { return !getDefiningRecipe(); }
};
typedef DenseMap<Value *, VPValue *> Value2VPValueTy;
@@ -328,7 +330,7 @@ class VPDef {
/// Add \p V as a defined value by this VPDef.
void addDefinedValue(VPValue *V) {
assert(V->getDef() == this &&
assert(V->Def == this &&
"can only add VPValue already linked with this VPDef");
DefinedValues.push_back(V);
}
@@ -336,8 +338,7 @@ class VPDef {
/// Remove \p V from the values defined by this VPDef. \p V must be a defined
/// value of this VPDef.
void removeDefinedValue(VPValue *V) {
assert(V->getDef() == this &&
"can only remove VPValue linked with this VPDef");
assert(V->Def == this && "can only remove VPValue linked with this VPDef");
assert(is_contained(DefinedValues, V) &&
"VPValue to remove must be in DefinedValues");
erase_value(DefinedValues, V);

View File

@@ -813,8 +813,8 @@ TEST(VPRecipeTest, CastVPWidenCallRecipeToVPUserAndVPDef) {
EXPECT_EQ(&Recipe, BaseR);
VPValue *VPV = &Recipe;
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDef()));
EXPECT_EQ(&Recipe, dyn_cast<VPRecipeBase>(VPV->getDef()));
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
EXPECT_EQ(&Recipe, dyn_cast<VPRecipeBase>(VPV->getDefiningRecipe()));
delete Call;
}
@@ -841,8 +841,8 @@ TEST(VPRecipeTest, CastVPWidenSelectRecipeToVPUserAndVPDef) {
EXPECT_EQ(&WidenSelectR, BaseR);
VPValue *VPV = &WidenSelectR;
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDef()));
EXPECT_EQ(&WidenSelectR, dyn_cast<VPRecipeBase>(VPV->getDef()));
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
EXPECT_EQ(&WidenSelectR, dyn_cast<VPRecipeBase>(VPV->getDefiningRecipe()));
delete SelectI;
}
@@ -866,8 +866,8 @@ TEST(VPRecipeTest, CastVPWidenGEPRecipeToVPUserAndVPDef) {
EXPECT_EQ(&Recipe, BaseR);
VPValue *VPV = &Recipe;
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDef()));
EXPECT_EQ(&Recipe, dyn_cast<VPRecipeBase>(VPV->getDef()));
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
EXPECT_EQ(&Recipe, dyn_cast<VPRecipeBase>(VPV->getDefiningRecipe()));
delete GEP;
}
@@ -945,8 +945,8 @@ TEST(VPRecipeTest, CastVPWidenMemoryInstructionRecipeToVPUserAndVPDef) {
EXPECT_EQ(&Recipe, BaseR);
VPValue *VPV = Recipe.getVPSingleValue();
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDef()));
EXPECT_EQ(&Recipe, dyn_cast<VPRecipeBase>(VPV->getDef()));
EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
EXPECT_EQ(&Recipe, dyn_cast<VPRecipeBase>(VPV->getDefiningRecipe()));
delete Load;
}
@@ -1207,10 +1207,10 @@ TEST(VPDoubleValueDefTest, traverseUseLists) {
EXPECT_EQ(&I3, DoubleValueDefV1Users[1]);
// Now check that we can get the right VPDef for each defined value.
EXPECT_EQ(&DoubleValueDef, I1.getOperand(0)->getDef());
EXPECT_EQ(&DoubleValueDef, I1.getOperand(1)->getDef());
EXPECT_EQ(&DoubleValueDef, I2.getOperand(0)->getDef());
EXPECT_EQ(&DoubleValueDef, I3.getOperand(0)->getDef());
EXPECT_EQ(&DoubleValueDef, I1.getOperand(0)->getDefiningRecipe());
EXPECT_EQ(&DoubleValueDef, I1.getOperand(1)->getDefiningRecipe());
EXPECT_EQ(&DoubleValueDef, I2.getOperand(0)->getDefiningRecipe());
EXPECT_EQ(&DoubleValueDef, I3.getOperand(0)->getDefiningRecipe());
}
} // namespace