diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -7789,14 +7789,12 @@ 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) { - if (NeedDef.contains(Instr)) - Plan->addOrReplaceVPValue(Instr, MaybeVPValue); + for (auto *Def : Recipe->definedValues()) { + auto *UV = Def->getUnderlyingValue(); + if (NeedDef.contains(UV)) + Plan->addOrReplaceVPValue(UV, Def); else - Plan->addVPValue(Instr, MaybeVPValue); + Plan->addVPValue(UV, Def); } RecipeBuilder.setRecipe(Instr, Recipe); @@ -8186,8 +8184,8 @@ void VPWidenMemoryInstructionRecipe::execute(VPTransformState &State) { VPValue *StoredValue = isStore() ? getStoredValue() : nullptr; State.ILV->vectorizeMemoryInstruction(getUnderlyingInstr(), State, - StoredValue ? nullptr : toVPValue(), - getAddr(), StoredValue, getMask()); + StoredValue ? nullptr : this, getAddr(), + StoredValue, getMask()); } // Determine how to lower the scalar epilogue, which depends on 1) optimising diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -657,22 +657,13 @@ /// 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(VPV->getUnderlyingValue()); - return nullptr; + return cast(getVPValue()->getUnderlyingValue()); } const Instruction *getUnderlyingInstr() const { - if (auto *VPV = toVPValue()) - return cast_or_null(VPV->getUnderlyingValue()); - return nullptr; + return cast(getVPValue()->getUnderlyingValue()); } }; @@ -693,7 +684,7 @@ /// 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: @@ -719,12 +710,12 @@ public: VPInstruction(unsigned Opcode, ArrayRef Operands) - : VPValue(VPValue::VPInstructionSC), VPUser(Operands), - VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) {} + : VPRecipeBase(VPRecipeBase::VPInstructionSC), VPUser(Operands), + VPValue(VPValue::VPInstructionSC, nullptr, this), Opcode(Opcode) {} VPInstruction(unsigned Opcode, ArrayRef Operands) - : VPValue(VPValue::VPInstructionSC), VPUser({}), - VPRecipeBase(VPRecipeBase::VPInstructionSC), Opcode(Opcode) { + : VPRecipeBase(VPRecipeBase::VPInstructionSC), VPUser({}), + VPValue(VPValue::VPInstructionSC, nullptr, this), Opcode(Opcode) { for (auto *I : Operands) addOperand(I->getVPValue()); } diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -113,22 +113,6 @@ return nullptr; } -VPValue *VPRecipeBase::toVPValue() { - if (getNumDefinedValues() == 1) - return getVPValue(); - if (auto *V = dyn_cast(this)) - return V; - return nullptr; -} - -const VPValue *VPRecipeBase::toVPValue() const { - if (getNumDefinedValues() == 1) - return getVPValue(); - if (auto *V = dyn_cast(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 static T *getPlanEntry(T *Start) { @@ -371,12 +355,8 @@ 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(&R)) { - for (auto *Def : IR->definedValues()) - Def->replaceAllUsesWith(NewValue); - } if (auto *User = R.toVPUser()) for (unsigned I = 0, E = User->getNumOperands(); I != E; I++) diff --git a/llvm/lib/Transforms/Vectorize/VPlanValue.h b/llvm/lib/Transforms/Vectorize/VPlanValue.h --- a/llvm/lib/Transforms/Vectorize/VPlanValue.h +++ b/llvm/lib/Transforms/Vectorize/VPlanValue.h @@ -71,10 +71,6 @@ // 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."); @@ -82,6 +78,10 @@ } 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