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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178807 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Arnold Schwaighofer 2013-04-04 23:26:21 +00:00
parent 624a93ee47
commit 6bf4f67641
6 changed files with 61 additions and 13 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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");

View File

@ -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,

View File

@ -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,