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 @@ -792,6 +792,20 @@ bool mayReadOrWriteMemory() const { return mayReadFromMemory() || mayWriteToMemory(); } + + /// Returns the number of operands excluding mask operands, which must be the + /// last operand. Must be overwritten by sub-classes with mask operands. + virtual unsigned getNumNonMaskOperands() const { return getNumOperands(); } + + /// Returns true if the recipe is masked. + bool isMasked() const { return getNumOperands() != getNumNonMaskOperands(); } + + /// Return the mask used by this recipe. Note that a full mask is represented + /// by a nullptr. + VPValue *getMask() const { + // Mask is optional and therefore the last operand. + return isMasked() ? getOperand(getNumOperands() - 1) : nullptr; + } }; // Helper macro to define common classof implementations for recipes. @@ -1681,13 +1695,6 @@ return getOperand(0); // Address is the 1st, mandatory operand. } - /// Return the mask used by this recipe. Note that a full mask is represented - /// by a nullptr. - VPValue *getMask() const { - // Mask is optional and therefore the last, currently 2nd operand. - return HasMask ? getOperand(getNumOperands() - 1) : nullptr; - } - /// Return the VPValues stored by this interleave group. If it is a load /// interleave group, return an empty ArrayRef. ArrayRef getStoredValues() const { @@ -1720,6 +1727,11 @@ "Op must be an operand of the recipe"); return Op == getAddr() && !llvm::is_contained(getStoredValues(), Op); } + + /// Returns the number of operands excluding mask operands. + unsigned getNumNonMaskOperands() const override { + return HasMask ? getNumOperands() - 1 : getNumOperands(); + } }; /// A recipe to represent inloop reduction operations, performing a reduction on @@ -1823,10 +1835,9 @@ /// in a vector. bool shouldPack() const; - /// Return the mask of a predicated VPReplicateRecipe. - VPValue *getMask() { - assert(isPredicated() && "Trying to get the mask of a unpredicated recipe"); - return getOperand(getNumOperands() - 1); + /// Returns the number of operands excluding mask operands. + unsigned getNumNonMaskOperands() const override { + return isPredicated() ? getNumOperands() - 1 : getNumOperands(); } }; @@ -1926,10 +1937,6 @@ addOperand(Mask); } - bool isMasked() const { - return isStore() ? getNumOperands() == 3 : getNumOperands() == 2; - } - public: VPWidenMemoryInstructionRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask, bool Consecutive, bool Reverse) @@ -1956,13 +1963,6 @@ return getOperand(0); // Address is the 1st, mandatory operand. } - /// Return the mask used by this recipe. Note that a full mask is represented - /// by a nullptr. - VPValue *getMask() const { - // Mask is optional and therefore the last operand. - return isMasked() ? getOperand(getNumOperands() - 1) : nullptr; - } - /// Returns true if this recipe is a store. bool isStore() const { return isa(Ingredient); } @@ -2001,6 +2001,9 @@ } Instruction &getIngredient() const { return Ingredient; } + + /// Returns the number of operands excluding mask operands. + unsigned getNumNonMaskOperands() const override { return isStore() ? 2 : 1; } }; /// Recipe to expand a SCEV expression.