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:
parent
cf31f6d3c6
commit
f84e692f2b
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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++)
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user