1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[VPlan] Make VPInstruction a VPDef

This patch turns updates VPInstruction to manage the value it defines
using VPDef. The VPValue is used  during VPlan construction and
codegeneration instead of the plain IR reference where possible.

Reviewed By: gilr

Differential Revision: https://reviews.llvm.org/D90565
This commit is contained in:
Florian Hahn 2020-12-22 09:20:47 +00:00
parent cf31f6d3c6
commit f84e692f2b
4 changed files with 20 additions and 49 deletions

View File

@ -8433,11 +8433,10 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
if (auto Recipe =
RecipeBuilder.tryToCreateWidenRecipe(Instr, Range, Plan)) {
// Check if the recipe can be converted to a VPValue. We need the extra
// down-casting step until VPRecipeBase inherits from VPValue.
VPValue *MaybeVPValue = Recipe->toVPValue();
if (!Instr->getType()->isVoidTy() && MaybeVPValue)
Plan->addVPValue(Instr, MaybeVPValue);
for (auto *Def : Recipe->definedValues()) {
auto *UV = Def->getUnderlyingValue();
Plan->addVPValue(UV, Def);
}
RecipeBuilder.setRecipe(Instr, Recipe);
VPBB->appendRecipe(Recipe);
@ -8613,10 +8612,11 @@ void LoopVectorizationPlanner::adjustRecipesForInLoopReductions(
: nullptr;
VPReductionRecipe *RedRecipe = new VPReductionRecipe(
&RdxDesc, R, ChainOp, VecOp, CondOp, Legal->hasFunNoNaNAttr(), TTI);
WidenRecipe->toVPValue()->replaceAllUsesWith(RedRecipe);
WidenRecipe->getVPValue()->replaceAllUsesWith(RedRecipe);
Plan->removeVPValueFor(R);
Plan->addVPValue(R, RedRecipe);
WidenRecipe->getParent()->insert(RedRecipe, WidenRecipe->getIterator());
WidenRecipe->getVPValue()->replaceAllUsesWith(RedRecipe);
WidenRecipe->eraseFromParent();
if (Kind == RecurrenceDescriptor::RK_IntegerMinMax ||
@ -8625,7 +8625,7 @@ void LoopVectorizationPlanner::adjustRecipesForInLoopReductions(
RecipeBuilder.getRecipe(cast<Instruction>(R->getOperand(0)));
assert(isa<VPWidenRecipe>(CompareRecipe) &&
"Expected to replace a VPWidenSC");
assert(CompareRecipe->toVPValue()->getNumUsers() == 0 &&
assert(cast<VPWidenRecipe>(CompareRecipe)->getNumUsers() == 0 &&
"Expected no remaining users");
CompareRecipe->eraseFromParent();
}
@ -8862,7 +8862,7 @@ void VPPredInstPHIRecipe::execute(VPTransformState &State) {
void VPWidenMemoryInstructionRecipe::execute(VPTransformState &State) {
VPValue *StoredValue = isStore() ? getStoredValue() : nullptr;
State.ILV->vectorizeMemoryInstruction(&Ingredient, State,
StoredValue ? nullptr : toVPValue(),
StoredValue ? nullptr : getVPValue(),
getAddr(), StoredValue, getMask());
}

View File

@ -119,22 +119,6 @@ VPUser *VPRecipeBase::toVPUser() {
return nullptr;
}
VPValue *VPRecipeBase::toVPValue() {
if (getNumDefinedValues() == 1)
return getVPValue();
if (auto *V = dyn_cast<VPInstruction>(this))
return V;
return nullptr;
}
const VPValue *VPRecipeBase::toVPValue() const {
if (getNumDefinedValues() == 1)
return getVPValue();
if (auto *V = dyn_cast<VPInstruction>(this))
return V;
return nullptr;
}
// 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) {
@ -352,12 +336,8 @@ void VPBasicBlock::execute(VPTransformState *State) {
void VPBasicBlock::dropAllReferences(VPValue *NewValue) {
for (VPRecipeBase &R : Recipes) {
if (VPValue *Def = R.toVPValue())
for (auto *Def : R.definedValues())
Def->replaceAllUsesWith(NewValue);
else if (auto *IR = dyn_cast<VPInterleaveRecipe>(&R)) {
for (auto *Def : IR->definedValues())
Def->replaceAllUsesWith(NewValue);
}
if (auto *User = R.toVPUser())
for (unsigned I = 0, E = User->getNumOperands(); I != E; I++)

View File

@ -677,22 +677,13 @@ public:
/// nullptr otherwise.
VPUser *toVPUser();
/// Returns a pointer to a VPValue, if the recipe inherits from VPValue or
/// nullptr otherwise.
VPValue *toVPValue();
const VPValue *toVPValue() const;
/// Returns the underlying instruction, if the recipe is a VPValue or nullptr
/// otherwise.
Instruction *getUnderlyingInstr() {
if (auto *VPV = toVPValue())
return cast_or_null<Instruction>(VPV->getUnderlyingValue());
return nullptr;
return cast<Instruction>(getVPValue()->getUnderlyingValue());
}
const Instruction *getUnderlyingInstr() const {
if (auto *VPV = toVPValue())
return cast_or_null<Instruction>(VPV->getUnderlyingValue());
return nullptr;
return cast<Instruction>(getVPValue()->getUnderlyingValue());
}
/// Method to support type inquiry through isa, cast, and dyn_cast.
@ -720,7 +711,7 @@ inline bool VPUser::classof(const VPDef *Def) {
/// While as any Recipe it may generate a sequence of IR instructions when
/// executed, these instructions would always form a single-def expression as
/// the VPInstruction is also a single def-use vertex.
class VPInstruction : public VPValue, public VPUser, public VPRecipeBase {
class VPInstruction : public VPRecipeBase, public VPUser, public VPValue {
friend class VPlanSlp;
public:
@ -746,12 +737,12 @@ protected:
public:
VPInstruction(unsigned Opcode, ArrayRef<VPValue *> Operands)
: VPValue(VPValue::VPVInstructionSC), VPUser(Operands),
VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) {}
: VPRecipeBase(VPRecipeBase::VPInstructionSC), VPUser(Operands),
VPValue(VPValue::VPVInstructionSC, nullptr, this), Opcode(Opcode) {}
VPInstruction(unsigned Opcode, ArrayRef<VPInstruction *> Operands)
: VPValue(VPValue::VPVInstructionSC), VPUser({}),
VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) {
: VPRecipeBase(VPRecipeBase::VPInstructionSC), VPUser({}),
VPValue(VPValue::VPVInstructionSC, nullptr, this), Opcode(Opcode) {
for (auto *I : Operands)
addOperand(I->getVPValue());
}

View File

@ -75,10 +75,6 @@ protected:
// for multiple underlying IRs (Polly?) by providing a new VPlan front-end,
// back-end and analysis information for the new IR.
/// Return the underlying Value attached to this VPValue.
Value *getUnderlyingValue() { return UnderlyingVal; }
const Value *getUnderlyingValue() const { return UnderlyingVal; }
// Set \p Val as the underlying Value of this VPValue.
void setUnderlyingValue(Value *Val) {
assert(!UnderlyingVal && "Underlying Value is already set.");
@ -86,6 +82,10 @@ protected:
}
public:
/// Return the underlying Value attached to this VPValue.
Value *getUnderlyingValue() { return UnderlyingVal; }
const Value *getUnderlyingValue() const { return UnderlyingVal; }
/// An enumeration for keeping track of the concrete subclass of VPValue that
/// are actually instantiated. Values of this enumeration are kept in the
/// SubclassID field of the VPValue objects. They are used for concrete