Add a overload to CostTable which allows it to infer the size of the table.

Use it to avoid repeating ourselves too often. Also store MVT::SimpleValueType
in the TTI tables so they can be statically initialized, MVT's constructors
create bloated initialization code otherwise.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188095 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2013-08-09 19:33:32 +00:00
parent 1edaeb61b2
commit fc6434a73d
3 changed files with 78 additions and 76 deletions

View File

@ -25,18 +25,25 @@ struct CostTblEntry {
unsigned Cost; unsigned Cost;
}; };
/// Find in cost table, TypeTy must be comparable by == /// Find in cost table, TypeTy must be comparable to CompareTy by ==
template <class TypeTy> template <class TypeTy, class CompareTy>
int CostTableLookup(const CostTblEntry<TypeTy> *Tbl, int CostTableLookup(const CostTblEntry<TypeTy> *Tbl, unsigned len, int ISD,
unsigned len, int ISD, TypeTy Ty) { CompareTy Ty) {
for (unsigned int i = 0; i < len; ++i) for (unsigned int i = 0; i < len; ++i)
if (Tbl[i].ISD == ISD && Tbl[i].Type == Ty) if (ISD == Tbl[i].ISD && Ty == Tbl[i].Type)
return i; return i;
// Could not find an entry. // Could not find an entry.
return -1; return -1;
} }
/// Find in cost table, TypeTy must be comparable to CompareTy by ==
template <class TypeTy, class CompareTy, unsigned N>
int CostTableLookup(const CostTblEntry<TypeTy>(&Tbl)[N], int ISD,
CompareTy Ty) {
return CostTableLookup(Tbl, N, ISD, Ty);
}
/// Type Conversion Cost Table /// Type Conversion Cost Table
template <class TypeTy> template <class TypeTy>
struct TypeConversionCostTblEntry { struct TypeConversionCostTblEntry {
@ -46,18 +53,28 @@ struct TypeConversionCostTblEntry {
unsigned Cost; unsigned Cost;
}; };
/// Find in type conversion cost table, TypeTy must be comparable by == /// Find in type conversion cost table, TypeTy must be comparable to CompareTy
template <class TypeTy> /// by ==
template <class TypeTy, class CompareTy>
int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy> *Tbl, int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy> *Tbl,
unsigned len, int ISD, TypeTy Dst, TypeTy Src) { unsigned len, int ISD, CompareTy Dst,
CompareTy Src) {
for (unsigned int i = 0; i < len; ++i) for (unsigned int i = 0; i < len; ++i)
if (Tbl[i].ISD == ISD && Tbl[i].Src == Src && Tbl[i].Dst == Dst) if (ISD == Tbl[i].ISD && Src == Tbl[i].Src && Dst == Tbl[i].Dst)
return i; return i;
// Could not find an entry. // Could not find an entry.
return -1; return -1;
} }
/// Find in type conversion cost table, TypeTy must be comparable to CompareTy
/// by ==
template <class TypeTy, class CompareTy, unsigned N>
int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy>(&Tbl)[N],
int ISD, CompareTy Dst, CompareTy Src) {
return ConvertCostTableLookup(Tbl, N, ISD, Dst, Src);
}
} // namespace llvm } // namespace llvm

View File

@ -182,7 +182,7 @@ unsigned ARMTTI::getCastInstrCost(unsigned Opcode, Type *Dst,
assert(ISD && "Invalid opcode"); assert(ISD && "Invalid opcode");
// Single to/from double precision conversions. // Single to/from double precision conversions.
static const CostTblEntry<MVT> NEONFltDblTbl[] = { static const CostTblEntry<MVT::SimpleValueType> NEONFltDblTbl[] = {
// Vector fptrunc/fpext conversions. // Vector fptrunc/fpext conversions.
{ ISD::FP_ROUND, MVT::v2f64, 2 }, { ISD::FP_ROUND, MVT::v2f64, 2 },
{ ISD::FP_EXTEND, MVT::v2f32, 2 }, { ISD::FP_EXTEND, MVT::v2f32, 2 },
@ -192,8 +192,7 @@ unsigned ARMTTI::getCastInstrCost(unsigned Opcode, Type *Dst,
if (Src->isVectorTy() && ST->hasNEON() && (ISD == ISD::FP_ROUND || if (Src->isVectorTy() && ST->hasNEON() && (ISD == ISD::FP_ROUND ||
ISD == ISD::FP_EXTEND)) { ISD == ISD::FP_EXTEND)) {
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Src); std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Src);
int Idx = CostTableLookup<MVT>(NEONFltDblTbl, array_lengthof(NEONFltDblTbl), int Idx = CostTableLookup(NEONFltDblTbl, ISD, LT.second);
ISD, LT.second);
if (Idx != -1) if (Idx != -1)
return LT.first * NEONFltDblTbl[Idx].Cost; return LT.first * NEONFltDblTbl[Idx].Cost;
} }
@ -207,7 +206,8 @@ unsigned ARMTTI::getCastInstrCost(unsigned Opcode, Type *Dst,
// Some arithmetic, load and store operations have specific instructions // Some arithmetic, load and store operations have specific instructions
// to cast up/down their types automatically at no extra cost. // to cast up/down their types automatically at no extra cost.
// TODO: Get these tables to know at least what the related operations are. // TODO: Get these tables to know at least what the related operations are.
static const TypeConversionCostTblEntry<MVT> NEONVectorConversionTbl[] = { static const TypeConversionCostTblEntry<MVT::SimpleValueType>
NEONVectorConversionTbl[] = {
{ ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i16, 0 }, { ISD::SIGN_EXTEND, MVT::v4i32, MVT::v4i16, 0 },
{ ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i16, 0 }, { ISD::ZERO_EXTEND, MVT::v4i32, MVT::v4i16, 0 },
{ ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i32, 1 }, { ISD::SIGN_EXTEND, MVT::v2i64, MVT::v2i32, 1 },
@ -283,15 +283,15 @@ unsigned ARMTTI::getCastInstrCost(unsigned Opcode, Type *Dst,
}; };
if (SrcTy.isVector() && ST->hasNEON()) { if (SrcTy.isVector() && ST->hasNEON()) {
int Idx = ConvertCostTableLookup<MVT>(NEONVectorConversionTbl, int Idx = ConvertCostTableLookup(NEONVectorConversionTbl, ISD,
array_lengthof(NEONVectorConversionTbl), DstTy.getSimpleVT(), SrcTy.getSimpleVT());
ISD, DstTy.getSimpleVT(), SrcTy.getSimpleVT());
if (Idx != -1) if (Idx != -1)
return NEONVectorConversionTbl[Idx].Cost; return NEONVectorConversionTbl[Idx].Cost;
} }
// Scalar float to integer conversions. // Scalar float to integer conversions.
static const TypeConversionCostTblEntry<MVT> NEONFloatConversionTbl[] = { static const TypeConversionCostTblEntry<MVT::SimpleValueType>
NEONFloatConversionTbl[] = {
{ ISD::FP_TO_SINT, MVT::i1, MVT::f32, 2 }, { ISD::FP_TO_SINT, MVT::i1, MVT::f32, 2 },
{ ISD::FP_TO_UINT, MVT::i1, MVT::f32, 2 }, { ISD::FP_TO_UINT, MVT::i1, MVT::f32, 2 },
{ ISD::FP_TO_SINT, MVT::i1, MVT::f64, 2 }, { ISD::FP_TO_SINT, MVT::i1, MVT::f64, 2 },
@ -314,16 +314,15 @@ unsigned ARMTTI::getCastInstrCost(unsigned Opcode, Type *Dst,
{ ISD::FP_TO_UINT, MVT::i64, MVT::f64, 10 } { ISD::FP_TO_UINT, MVT::i64, MVT::f64, 10 }
}; };
if (SrcTy.isFloatingPoint() && ST->hasNEON()) { if (SrcTy.isFloatingPoint() && ST->hasNEON()) {
int Idx = ConvertCostTableLookup<MVT>(NEONFloatConversionTbl, int Idx = ConvertCostTableLookup(NEONFloatConversionTbl, ISD,
array_lengthof(NEONFloatConversionTbl), DstTy.getSimpleVT(), SrcTy.getSimpleVT());
ISD, DstTy.getSimpleVT(),
SrcTy.getSimpleVT());
if (Idx != -1) if (Idx != -1)
return NEONFloatConversionTbl[Idx].Cost; return NEONFloatConversionTbl[Idx].Cost;
} }
// Scalar integer to float conversions. // Scalar integer to float conversions.
static const TypeConversionCostTblEntry<MVT> NEONIntegerConversionTbl[] = { static const TypeConversionCostTblEntry<MVT::SimpleValueType>
NEONIntegerConversionTbl[] = {
{ ISD::SINT_TO_FP, MVT::f32, MVT::i1, 2 }, { ISD::SINT_TO_FP, MVT::f32, MVT::i1, 2 },
{ ISD::UINT_TO_FP, MVT::f32, MVT::i1, 2 }, { ISD::UINT_TO_FP, MVT::f32, MVT::i1, 2 },
{ ISD::SINT_TO_FP, MVT::f64, MVT::i1, 2 }, { ISD::SINT_TO_FP, MVT::f64, MVT::i1, 2 },
@ -347,16 +346,15 @@ unsigned ARMTTI::getCastInstrCost(unsigned Opcode, Type *Dst,
}; };
if (SrcTy.isInteger() && ST->hasNEON()) { if (SrcTy.isInteger() && ST->hasNEON()) {
int Idx = ConvertCostTableLookup<MVT>(NEONIntegerConversionTbl, int Idx = ConvertCostTableLookup(NEONIntegerConversionTbl, ISD,
array_lengthof(NEONIntegerConversionTbl), DstTy.getSimpleVT(), SrcTy.getSimpleVT());
ISD, DstTy.getSimpleVT(),
SrcTy.getSimpleVT());
if (Idx != -1) if (Idx != -1)
return NEONIntegerConversionTbl[Idx].Cost; return NEONIntegerConversionTbl[Idx].Cost;
} }
// Scalar integer conversion costs. // Scalar integer conversion costs.
static const TypeConversionCostTblEntry<MVT> ARMIntegerConversionTbl[] = { static const TypeConversionCostTblEntry<MVT::SimpleValueType>
ARMIntegerConversionTbl[] = {
// i16 -> i64 requires two dependent operations. // i16 -> i64 requires two dependent operations.
{ ISD::SIGN_EXTEND, MVT::i64, MVT::i16, 2 }, { ISD::SIGN_EXTEND, MVT::i64, MVT::i16, 2 },
@ -368,11 +366,8 @@ unsigned ARMTTI::getCastInstrCost(unsigned Opcode, Type *Dst,
}; };
if (SrcTy.isInteger()) { if (SrcTy.isInteger()) {
int Idx = int Idx = ConvertCostTableLookup(ARMIntegerConversionTbl, ISD,
ConvertCostTableLookup<MVT>(ARMIntegerConversionTbl, DstTy.getSimpleVT(), SrcTy.getSimpleVT());
array_lengthof(ARMIntegerConversionTbl),
ISD, DstTy.getSimpleVT(),
SrcTy.getSimpleVT());
if (Idx != -1) if (Idx != -1)
return ARMIntegerConversionTbl[Idx].Cost; return ARMIntegerConversionTbl[Idx].Cost;
} }
@ -400,7 +395,8 @@ unsigned ARMTTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
// On NEON a a vector select gets lowered to vbsl. // On NEON a a vector select gets lowered to vbsl.
if (ST->hasNEON() && ValTy->isVectorTy() && ISD == ISD::SELECT) { if (ST->hasNEON() && ValTy->isVectorTy() && ISD == ISD::SELECT) {
// Lowering of some vector selects is currently far from perfect. // Lowering of some vector selects is currently far from perfect.
static const TypeConversionCostTblEntry<MVT> NEONVectorSelectTbl[] = { static const TypeConversionCostTblEntry<MVT::SimpleValueType>
NEONVectorSelectTbl[] = {
{ ISD::SELECT, MVT::v16i1, MVT::v16i16, 2*16 + 1 + 3*1 + 4*1 }, { ISD::SELECT, MVT::v16i1, MVT::v16i16, 2*16 + 1 + 3*1 + 4*1 },
{ ISD::SELECT, MVT::v8i1, MVT::v8i32, 4*8 + 1*3 + 1*4 + 1*2 }, { ISD::SELECT, MVT::v8i1, MVT::v8i32, 4*8 + 1*3 + 1*4 + 1*2 },
{ ISD::SELECT, MVT::v16i1, MVT::v16i32, 4*16 + 1*6 + 1*8 + 1*4 }, { ISD::SELECT, MVT::v16i1, MVT::v16i32, 4*16 + 1*6 + 1*8 + 1*4 },
@ -412,10 +408,9 @@ unsigned ARMTTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
EVT SelCondTy = TLI->getValueType(CondTy); EVT SelCondTy = TLI->getValueType(CondTy);
EVT SelValTy = TLI->getValueType(ValTy); EVT SelValTy = TLI->getValueType(ValTy);
if (SelCondTy.isSimple() && SelValTy.isSimple()) { if (SelCondTy.isSimple() && SelValTy.isSimple()) {
int Idx = ConvertCostTableLookup<MVT>(NEONVectorSelectTbl, int Idx = ConvertCostTableLookup(NEONVectorSelectTbl, ISD,
array_lengthof(NEONVectorSelectTbl), SelCondTy.getSimpleVT(),
ISD, SelCondTy.getSimpleVT(), SelValTy.getSimpleVT());
SelValTy.getSimpleVT());
if (Idx != -1) if (Idx != -1)
return NEONVectorSelectTbl[Idx].Cost; return NEONVectorSelectTbl[Idx].Cost;
} }
@ -448,7 +443,7 @@ unsigned ARMTTI::getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
if (Kind != SK_Reverse) if (Kind != SK_Reverse)
return TargetTransformInfo::getShuffleCost(Kind, Tp, Index, SubTp); return TargetTransformInfo::getShuffleCost(Kind, Tp, Index, SubTp);
static const CostTblEntry<MVT> NEONShuffleTbl[] = { static const CostTblEntry<MVT::SimpleValueType> NEONShuffleTbl[] = {
// Reverse shuffle cost one instruction if we are shuffling within a double // Reverse shuffle cost one instruction if we are shuffling within a double
// word (vrev) or two if we shuffle a quad word (vrev, vext). // word (vrev) or two if we shuffle a quad word (vrev, vext).
{ ISD::VECTOR_SHUFFLE, MVT::v2i32, 1 }, { ISD::VECTOR_SHUFFLE, MVT::v2i32, 1 },
@ -464,8 +459,7 @@ unsigned ARMTTI::getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Tp); std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Tp);
int Idx = CostTableLookup<MVT>(NEONShuffleTbl, array_lengthof(NEONShuffleTbl), int Idx = CostTableLookup(NEONShuffleTbl, ISD::VECTOR_SHUFFLE, LT.second);
ISD::VECTOR_SHUFFLE, LT.second);
if (Idx == -1) if (Idx == -1)
return TargetTransformInfo::getShuffleCost(Kind, Tp, Index, SubTp); return TargetTransformInfo::getShuffleCost(Kind, Tp, Index, SubTp);
@ -480,7 +474,7 @@ unsigned ARMTTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueK
const unsigned FunctionCallDivCost = 20; const unsigned FunctionCallDivCost = 20;
const unsigned ReciprocalDivCost = 10; const unsigned ReciprocalDivCost = 10;
static const CostTblEntry<MVT> CostTbl[] = { static const CostTblEntry<MVT::SimpleValueType> CostTbl[] = {
// Division. // Division.
// These costs are somewhat random. Choose a cost of 20 to indicate that // These costs are somewhat random. Choose a cost of 20 to indicate that
// vectorizing devision (added function call) is going to be very expensive. // vectorizing devision (added function call) is going to be very expensive.
@ -524,8 +518,7 @@ unsigned ARMTTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueK
int Idx = -1; int Idx = -1;
if (ST->hasNEON()) if (ST->hasNEON())
Idx = CostTableLookup<MVT>(CostTbl, array_lengthof(CostTbl), ISDOpcode, Idx = CostTableLookup(CostTbl, ISDOpcode, LT.second);
LT.second);
if (Idx != -1) if (Idx != -1)
return LT.first * CostTbl[Idx].Cost; return LT.first * CostTbl[Idx].Cost;

View File

@ -174,7 +174,7 @@ unsigned X86TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
int ISD = TLI->InstructionOpcodeToISD(Opcode); int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode"); assert(ISD && "Invalid opcode");
static const CostTblEntry<MVT> AVX2CostTable[] = { static const CostTblEntry<MVT::SimpleValueType> AVX2CostTable[] = {
// Shifts on v4i64/v8i32 on AVX2 is legal even though we declare to // Shifts on v4i64/v8i32 on AVX2 is legal even though we declare to
// customize them to detect the cases where shift amount is a scalar one. // customize them to detect the cases where shift amount is a scalar one.
{ ISD::SHL, MVT::v4i32, 1 }, { ISD::SHL, MVT::v4i32, 1 },
@ -211,13 +211,13 @@ unsigned X86TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
// Look for AVX2 lowering tricks. // Look for AVX2 lowering tricks.
if (ST->hasAVX2()) { if (ST->hasAVX2()) {
int Idx = CostTableLookup<MVT>(AVX2CostTable, array_lengthof(AVX2CostTable), int Idx = CostTableLookup(AVX2CostTable, ISD, LT.second);
ISD, LT.second);
if (Idx != -1) if (Idx != -1)
return LT.first * AVX2CostTable[Idx].Cost; return LT.first * AVX2CostTable[Idx].Cost;
} }
static const CostTblEntry<MVT> SSE2UniformConstCostTable[] = { static const CostTblEntry<MVT::SimpleValueType>
SSE2UniformConstCostTable[] = {
// We don't correctly identify costs of casts because they are marked as // We don't correctly identify costs of casts because they are marked as
// custom. // custom.
// Constant splats are cheaper for the following instructions. // Constant splats are cheaper for the following instructions.
@ -238,15 +238,13 @@ unsigned X86TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
if (Op2Info == TargetTransformInfo::OK_UniformConstantValue && if (Op2Info == TargetTransformInfo::OK_UniformConstantValue &&
ST->hasSSE2()) { ST->hasSSE2()) {
int Idx = CostTableLookup<MVT>(SSE2UniformConstCostTable, int Idx = CostTableLookup(SSE2UniformConstCostTable, ISD, LT.second);
array_lengthof(SSE2UniformConstCostTable),
ISD, LT.second);
if (Idx != -1) if (Idx != -1)
return LT.first * SSE2UniformConstCostTable[Idx].Cost; return LT.first * SSE2UniformConstCostTable[Idx].Cost;
} }
static const CostTblEntry<MVT> SSE2CostTable[] = { static const CostTblEntry<MVT::SimpleValueType> SSE2CostTable[] = {
// We don't correctly identify costs of casts because they are marked as // We don't correctly identify costs of casts because they are marked as
// custom. // custom.
// For some cases, where the shift amount is a scalar we would be able // For some cases, where the shift amount is a scalar we would be able
@ -287,13 +285,12 @@ unsigned X86TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
}; };
if (ST->hasSSE2()) { if (ST->hasSSE2()) {
int Idx = CostTableLookup<MVT>(SSE2CostTable, array_lengthof(SSE2CostTable), int Idx = CostTableLookup(SSE2CostTable, ISD, LT.second);
ISD, LT.second);
if (Idx != -1) if (Idx != -1)
return LT.first * SSE2CostTable[Idx].Cost; return LT.first * SSE2CostTable[Idx].Cost;
} }
static const CostTblEntry<MVT> AVX1CostTable[] = { static const CostTblEntry<MVT::SimpleValueType> AVX1CostTable[] = {
// We don't have to scalarize unsupported ops. We can issue two half-sized // We don't have to scalarize unsupported ops. We can issue two half-sized
// operations and we only need to extract the upper YMM half. // operations and we only need to extract the upper YMM half.
// Two ops + 1 extract + 1 insert = 4. // Two ops + 1 extract + 1 insert = 4.
@ -312,21 +309,19 @@ unsigned X86TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty,
// Look for AVX1 lowering tricks. // Look for AVX1 lowering tricks.
if (ST->hasAVX() && !ST->hasAVX2()) { if (ST->hasAVX() && !ST->hasAVX2()) {
int Idx = CostTableLookup<MVT>(AVX1CostTable, array_lengthof(AVX1CostTable), int Idx = CostTableLookup(AVX1CostTable, ISD, LT.second);
ISD, LT.second);
if (Idx != -1) if (Idx != -1)
return LT.first * AVX1CostTable[Idx].Cost; return LT.first * AVX1CostTable[Idx].Cost;
} }
// Custom lowering of vectors. // Custom lowering of vectors.
static const CostTblEntry<MVT> CustomLowered[] = { static const CostTblEntry<MVT::SimpleValueType> CustomLowered[] = {
// A v2i64/v4i64 and multiply is custom lowered as a series of long // A v2i64/v4i64 and multiply is custom lowered as a series of long
// multiplies(3), shifts(4) and adds(2). // multiplies(3), shifts(4) and adds(2).
{ ISD::MUL, MVT::v2i64, 9 }, { ISD::MUL, MVT::v2i64, 9 },
{ ISD::MUL, MVT::v4i64, 9 }, { ISD::MUL, MVT::v4i64, 9 },
}; };
int Idx = CostTableLookup<MVT>(CustomLowered, array_lengthof(CustomLowered), int Idx = CostTableLookup(CustomLowered, ISD, LT.second);
ISD, LT.second);
if (Idx != -1) if (Idx != -1)
return LT.first * CustomLowered[Idx].Cost; return LT.first * CustomLowered[Idx].Cost;
@ -363,7 +358,8 @@ unsigned X86TTI::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) const {
std::pair<unsigned, MVT> LTSrc = TLI->getTypeLegalizationCost(Src); std::pair<unsigned, MVT> LTSrc = TLI->getTypeLegalizationCost(Src);
std::pair<unsigned, MVT> LTDest = TLI->getTypeLegalizationCost(Dst); std::pair<unsigned, MVT> LTDest = TLI->getTypeLegalizationCost(Dst);
static const TypeConversionCostTblEntry<MVT> SSE2ConvTbl[] = { static const TypeConversionCostTblEntry<MVT::SimpleValueType>
SSE2ConvTbl[] = {
// These are somewhat magic numbers justified by looking at the output of // These are somewhat magic numbers justified by looking at the output of
// Intel's IACA, running some kernels and making sure when we take // Intel's IACA, running some kernels and making sure when we take
// legalization into account the throughput will be overestimated. // legalization into account the throughput will be overestimated.
@ -387,9 +383,8 @@ unsigned X86TTI::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) const {
}; };
if (ST->hasSSE2() && !ST->hasAVX()) { if (ST->hasSSE2() && !ST->hasAVX()) {
int Idx = ConvertCostTableLookup<MVT>(SSE2ConvTbl, int Idx =
array_lengthof(SSE2ConvTbl), ConvertCostTableLookup(SSE2ConvTbl, ISD, LTDest.second, LTSrc.second);
ISD, LTDest.second, LTSrc.second);
if (Idx != -1) if (Idx != -1)
return LTSrc.first * SSE2ConvTbl[Idx].Cost; return LTSrc.first * SSE2ConvTbl[Idx].Cost;
} }
@ -401,7 +396,8 @@ unsigned X86TTI::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) const {
if (!SrcTy.isSimple() || !DstTy.isSimple()) if (!SrcTy.isSimple() || !DstTy.isSimple())
return TargetTransformInfo::getCastInstrCost(Opcode, Dst, Src); return TargetTransformInfo::getCastInstrCost(Opcode, Dst, Src);
static const TypeConversionCostTblEntry<MVT> AVXConversionTbl[] = { static const TypeConversionCostTblEntry<MVT::SimpleValueType>
AVXConversionTbl[] = {
{ ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, 1 }, { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, 1 },
{ ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, 1 }, { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, 1 },
{ ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, 1 }, { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, 1 },
@ -446,9 +442,8 @@ unsigned X86TTI::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) const {
}; };
if (ST->hasAVX()) { if (ST->hasAVX()) {
int Idx = ConvertCostTableLookup<MVT>(AVXConversionTbl, int Idx = ConvertCostTableLookup(AVXConversionTbl, ISD, DstTy.getSimpleVT(),
array_lengthof(AVXConversionTbl), SrcTy.getSimpleVT());
ISD, DstTy.getSimpleVT(), SrcTy.getSimpleVT());
if (Idx != -1) if (Idx != -1)
return AVXConversionTbl[Idx].Cost; return AVXConversionTbl[Idx].Cost;
} }
@ -466,7 +461,7 @@ unsigned X86TTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
int ISD = TLI->InstructionOpcodeToISD(Opcode); int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode"); assert(ISD && "Invalid opcode");
static const CostTblEntry<MVT> SSE42CostTbl[] = { static const CostTblEntry<MVT::SimpleValueType> SSE42CostTbl[] = {
{ ISD::SETCC, MVT::v2f64, 1 }, { ISD::SETCC, MVT::v2f64, 1 },
{ ISD::SETCC, MVT::v4f32, 1 }, { ISD::SETCC, MVT::v4f32, 1 },
{ ISD::SETCC, MVT::v2i64, 1 }, { ISD::SETCC, MVT::v2i64, 1 },
@ -475,7 +470,7 @@ unsigned X86TTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
{ ISD::SETCC, MVT::v16i8, 1 }, { ISD::SETCC, MVT::v16i8, 1 },
}; };
static const CostTblEntry<MVT> AVX1CostTbl[] = { static const CostTblEntry<MVT::SimpleValueType> AVX1CostTbl[] = {
{ ISD::SETCC, MVT::v4f64, 1 }, { ISD::SETCC, MVT::v4f64, 1 },
{ ISD::SETCC, MVT::v8f32, 1 }, { ISD::SETCC, MVT::v8f32, 1 },
// AVX1 does not support 8-wide integer compare. // AVX1 does not support 8-wide integer compare.
@ -485,7 +480,7 @@ unsigned X86TTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
{ ISD::SETCC, MVT::v32i8, 4 }, { ISD::SETCC, MVT::v32i8, 4 },
}; };
static const CostTblEntry<MVT> AVX2CostTbl[] = { static const CostTblEntry<MVT::SimpleValueType> AVX2CostTbl[] = {
{ ISD::SETCC, MVT::v4i64, 1 }, { ISD::SETCC, MVT::v4i64, 1 },
{ ISD::SETCC, MVT::v8i32, 1 }, { ISD::SETCC, MVT::v8i32, 1 },
{ ISD::SETCC, MVT::v16i16, 1 }, { ISD::SETCC, MVT::v16i16, 1 },
@ -493,22 +488,19 @@ unsigned X86TTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
}; };
if (ST->hasAVX2()) { if (ST->hasAVX2()) {
int Idx = CostTableLookup<MVT>(AVX2CostTbl, array_lengthof(AVX2CostTbl), int Idx = CostTableLookup(AVX2CostTbl, ISD, MTy);
ISD, MTy);
if (Idx != -1) if (Idx != -1)
return LT.first * AVX2CostTbl[Idx].Cost; return LT.first * AVX2CostTbl[Idx].Cost;
} }
if (ST->hasAVX()) { if (ST->hasAVX()) {
int Idx = CostTableLookup<MVT>(AVX1CostTbl, array_lengthof(AVX1CostTbl), int Idx = CostTableLookup(AVX1CostTbl, ISD, MTy);
ISD, MTy);
if (Idx != -1) if (Idx != -1)
return LT.first * AVX1CostTbl[Idx].Cost; return LT.first * AVX1CostTbl[Idx].Cost;
} }
if (ST->hasSSE42()) { if (ST->hasSSE42()) {
int Idx = CostTableLookup<MVT>(SSE42CostTbl, array_lengthof(SSE42CostTbl), int Idx = CostTableLookup(SSE42CostTbl, ISD, MTy);
ISD, MTy);
if (Idx != -1) if (Idx != -1)
return LT.first * SSE42CostTbl[Idx].Cost; return LT.first * SSE42CostTbl[Idx].Cost;
} }