forked from OSchip/llvm-project
CostModel: Add parameter to instruction cost to further classify operand values
On certain architectures we can support efficient vectorized version of instructions if the operand value is uniform (splat) or a constant scalar. An example of this is a vector shift on x86. We can efficiently support for (i = 0 ; i < ; i += 4) w[0:3] = v[0:3] << <2, 2, 2, 2> but not for (i = 0; i < ; i += 4) w[0:3] = v[0:3] << x[0:3] This patch adds a parameter to getArithmeticInstrCost to further qualify operand values as uniform or uniform constant. Targets can then choose to return a different cost for instructions with such operand values. A follow-up commit will test this feature on x86. radar://13576547 llvm-svn: 178807
This commit is contained in:
parent
bdcb4464e2
commit
b977387112
|
@ -263,6 +263,13 @@ public:
|
|||
SK_ExtractSubvector ///< ExtractSubvector Index indicates start offset.
|
||||
};
|
||||
|
||||
/// \brief Additonal information about an operand's possible values.
|
||||
enum OperandValueKind {
|
||||
OK_AnyValue, // Operand can have any value.
|
||||
OK_UniformValue, // Operand is uniform (splat of a value).
|
||||
OK_UniformConstantValue // Operand is uniform constant.
|
||||
};
|
||||
|
||||
/// \return The number of scalar or vector registers that the target has.
|
||||
/// If 'Vectors' is true, it returns the number of vector registers. If it is
|
||||
/// set to false, it returns the number of scalar registers.
|
||||
|
@ -277,7 +284,9 @@ public:
|
|||
virtual unsigned getMaximumUnrollFactor() const;
|
||||
|
||||
/// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
|
||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const;
|
||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
|
||||
OperandValueKind Opd1Info = OK_AnyValue,
|
||||
OperandValueKind Opd2Info = OK_AnyValue) const;
|
||||
|
||||
/// \return The cost of a shuffle instruction of kind Kind and of type Tp.
|
||||
/// The index and subtype parameters are used by the subvector insertion and
|
||||
|
|
|
@ -88,6 +88,23 @@ static bool isReverseVectorMask(SmallVector<int, 16> &Mask) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static TargetTransformInfo::OperandValueKind getOperandInfo(Value *V) {
|
||||
TargetTransformInfo::OperandValueKind OpInfo =
|
||||
TargetTransformInfo::OK_AnyValue;
|
||||
|
||||
// Check for a splat of a constant.
|
||||
ConstantDataVector *CDV = 0;
|
||||
if ((CDV = dyn_cast<ConstantDataVector>(V)))
|
||||
if (CDV->getSplatValue() != NULL)
|
||||
OpInfo = TargetTransformInfo::OK_UniformConstantValue;
|
||||
ConstantVector *CV = 0;
|
||||
if ((CV = dyn_cast<ConstantVector>(V)))
|
||||
if (CV->getSplatValue() != NULL)
|
||||
OpInfo = TargetTransformInfo::OK_UniformConstantValue;
|
||||
|
||||
return OpInfo;
|
||||
}
|
||||
|
||||
unsigned CostModelAnalysis::getInstructionCost(const Instruction *I) const {
|
||||
if (!TTI)
|
||||
return -1;
|
||||
|
@ -121,7 +138,12 @@ unsigned CostModelAnalysis::getInstructionCost(const Instruction *I) const {
|
|||
case Instruction::And:
|
||||
case Instruction::Or:
|
||||
case Instruction::Xor: {
|
||||
return TTI->getArithmeticInstrCost(I->getOpcode(), I->getType());
|
||||
TargetTransformInfo::OperandValueKind Op1VK =
|
||||
getOperandInfo(I->getOperand(0));
|
||||
TargetTransformInfo::OperandValueKind Op2VK =
|
||||
getOperandInfo(I->getOperand(1));
|
||||
return TTI->getArithmeticInstrCost(I->getOpcode(), I->getType(), Op1VK,
|
||||
Op2VK);
|
||||
}
|
||||
case Instruction::Select: {
|
||||
const SelectInst *SI = cast<SelectInst>(I);
|
||||
|
|
|
@ -150,8 +150,10 @@ unsigned TargetTransformInfo::getMaximumUnrollFactor() const {
|
|||
}
|
||||
|
||||
unsigned TargetTransformInfo::getArithmeticInstrCost(unsigned Opcode,
|
||||
Type *Ty) const {
|
||||
return PrevTTI->getArithmeticInstrCost(Opcode, Ty);
|
||||
Type *Ty,
|
||||
OperandValueKind Op1Info,
|
||||
OperandValueKind Op2Info) const {
|
||||
return PrevTTI->getArithmeticInstrCost(Opcode, Ty, Op1Info, Op2Info);
|
||||
}
|
||||
|
||||
unsigned TargetTransformInfo::getShuffleCost(ShuffleKind Kind, Type *Tp,
|
||||
|
@ -495,7 +497,8 @@ struct NoTTI : ImmutablePass, TargetTransformInfo {
|
|||
return 1;
|
||||
}
|
||||
|
||||
unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const {
|
||||
unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind,
|
||||
OperandValueKind) const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,9 @@ public:
|
|||
virtual unsigned getNumberOfRegisters(bool Vector) const;
|
||||
virtual unsigned getMaximumUnrollFactor() const;
|
||||
virtual unsigned getRegisterBitWidth(bool Vector) const;
|
||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const;
|
||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
|
||||
OperandValueKind,
|
||||
OperandValueKind) const;
|
||||
virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp,
|
||||
int Index, Type *SubTp) const;
|
||||
virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
|
||||
|
@ -193,7 +195,9 @@ unsigned BasicTTI::getMaximumUnrollFactor() const {
|
|||
return 1;
|
||||
}
|
||||
|
||||
unsigned BasicTTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty) const {
|
||||
unsigned BasicTTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
|
||||
OperandValueKind,
|
||||
OperandValueKind) const {
|
||||
// Check if any of the operands are vector operands.
|
||||
int ISD = TLI->InstructionOpcodeToISD(Opcode);
|
||||
assert(ISD && "Invalid opcode");
|
||||
|
|
|
@ -86,7 +86,9 @@ public:
|
|||
virtual unsigned getNumberOfRegisters(bool Vector) const;
|
||||
virtual unsigned getRegisterBitWidth(bool Vector) const;
|
||||
virtual unsigned getMaximumUnrollFactor() const;
|
||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const;
|
||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
|
||||
OperandValueKind,
|
||||
OperandValueKind) const;
|
||||
virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp,
|
||||
int Index, Type *SubTp) const;
|
||||
virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
|
||||
|
@ -166,11 +168,14 @@ unsigned PPCTTI::getMaximumUnrollFactor() const {
|
|||
return 2;
|
||||
}
|
||||
|
||||
unsigned PPCTTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty) const {
|
||||
unsigned PPCTTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
|
||||
OperandValueKind Op1Info,
|
||||
OperandValueKind Op2Info) const {
|
||||
assert(TLI->InstructionOpcodeToISD(Opcode) && "Invalid opcode");
|
||||
|
||||
// Fallback to the default implementation.
|
||||
return TargetTransformInfo::getArithmeticInstrCost(Opcode, Ty);
|
||||
return TargetTransformInfo::getArithmeticInstrCost(Opcode, Ty, Op1Info,
|
||||
Op2Info);
|
||||
}
|
||||
|
||||
unsigned PPCTTI::getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
|
||||
|
|
|
@ -86,7 +86,9 @@ public:
|
|||
virtual unsigned getNumberOfRegisters(bool Vector) const;
|
||||
virtual unsigned getRegisterBitWidth(bool Vector) const;
|
||||
virtual unsigned getMaximumUnrollFactor() const;
|
||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const;
|
||||
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
|
||||
OperandValueKind,
|
||||
OperandValueKind) const;
|
||||
virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp,
|
||||
int Index, Type *SubTp) const;
|
||||
virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
|
||||
|
@ -162,7 +164,9 @@ unsigned X86TTI::getMaximumUnrollFactor() const {
|
|||
return 2;
|
||||
}
|
||||
|
||||
unsigned X86TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty) const {
|
||||
unsigned X86TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
|
||||
OperandValueKind Op1Info,
|
||||
OperandValueKind Op2Info) const {
|
||||
// Legalize the type.
|
||||
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Ty);
|
||||
|
||||
|
@ -278,7 +282,8 @@ unsigned X86TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty) const {
|
|||
return 6;
|
||||
|
||||
// Fallback to the default implementation.
|
||||
return TargetTransformInfo::getArithmeticInstrCost(Opcode, Ty);
|
||||
return TargetTransformInfo::getArithmeticInstrCost(Opcode, Ty, Op1Info,
|
||||
Op2Info);
|
||||
}
|
||||
|
||||
unsigned X86TTI::getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
|
||||
|
|
Loading…
Reference in New Issue