Revert CostTable algorithm, will re-write
authorRenato Golin <renato.golin@linaro.org>
Sun, 20 Jan 2013 20:57:20 +0000 (20:57 +0000)
committerRenato Golin <renato.golin@linaro.org>
Sun, 20 Jan 2013 20:57:20 +0000 (20:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172992 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/TargetTransformInfo.h
lib/Analysis/TargetTransformInfo.cpp
lib/Target/X86/X86TargetTransformInfo.cpp

index 3d44e778c6365b1a6532ecc3aebfe8121256e2c1..d694aa6eca155e7f76fb708c57f124553fdec984 100644 (file)
@@ -210,58 +210,6 @@ public:
 /// satisfy the queries.
 ImmutablePass *createNoTargetTransformInfoPass();
 
-//======================================= COST TABLES ==
-
-/// \brief An entry in a cost table
-///
-/// Use it as a static array and call the CostTable below to
-/// iterate through it and find the elements you're looking for.
-///
-/// Leaving Types with fixed size to avoid complications during
-/// static destruction.
-struct CostTableEntry {
-  int ISD;       // instruction ID
-  MVT Types[2];  // Types { dest, source }
-  unsigned Cost; // ideal cost
-};
-
-/// \brief Cost table, containing one or more costs for different instructions
-///
-/// This class implement the cost table lookup, to simplify
-/// how targets declare their own costs.
-class CostTable {
-  const CostTableEntry *table;
-  const size_t size;
-  const unsigned numTypes;
-
-protected:
-  /// Searches for costs on the table
-  unsigned _findCost(int ISD, MVT *Types) const;
-
-  // We don't want to expose a multi-type cost table, since types are not
-  // sequential by nature. If you need more cost table types, implement
-  // them below.
-  CostTable(const CostTableEntry *table, const size_t size, unsigned numTypes);
-
-public:
-  /// Cost Not found while searching
-  static const unsigned COST_NOT_FOUND = -1;
-};
-
-/// Specialisation for one-type cost table
-class UnaryCostTable : public CostTable {
-public:
-  UnaryCostTable(const CostTableEntry *table, const size_t size);
-  unsigned findCost(int ISD, MVT Type) const;
-};
-
-/// Specialisation for two-type cost table
-class BinaryCostTable : public CostTable {
-public:
-  BinaryCostTable(const CostTableEntry *table, const size_t size);
-  unsigned findCost(int ISD, MVT Type, MVT SrcType) const;
-};
-
 } // End llvm namespace
 
 #endif
index 4873a7f923f02538adc3c031e815d74261cc49b2..3ef74eb2d6431f8c8cb93701164e622f9ae5433f 100644 (file)
@@ -286,48 +286,3 @@ char NoTTI::ID = 0;
 ImmutablePass *llvm::createNoTargetTransformInfoPass() {
   return new NoTTI();
 }
-
-//======================================= COST TABLES ==
-
-CostTable::CostTable(const CostTableEntry *table,
-                     const size_t size,
-                     unsigned numTypes)
-  : table(table), size(size), numTypes(numTypes) {
-  assert(table && "missing cost table");
-  assert(size > 0 && "empty cost table");
-}
-
-unsigned CostTable::_findCost(int ISD, MVT *Types) const {
-  for (unsigned i = 0; i < size; ++i) {
-    if (table[i].ISD != ISD)
-      continue;
-    bool found = true;
-    for (unsigned t=0; t<numTypes; t++) {
-      if (table[i].Types[t] != Types[t]) {
-        found = false;
-        break;
-      }
-    }
-    if (found)
-      return table[i].Cost;
-  }
-  return COST_NOT_FOUND;
-}
-
-UnaryCostTable::UnaryCostTable(const CostTableEntry *table,
-                               const size_t size)
-  : CostTable(table, size, 1) { }
-
-unsigned UnaryCostTable::findCost(int ISD, MVT Type) const {
-  MVT tys[1] = { Type };
-  return _findCost(ISD, tys);
-}
-
-BinaryCostTable::BinaryCostTable(const CostTableEntry *table,
-                                 const size_t size)
-  : CostTable(table, size, 2) { }
-
-unsigned BinaryCostTable::findCost(int ISD, MVT Type, MVT SrcType) const {
-  MVT tys[2] = { Type, SrcType };
-  return _findCost(ISD, tys);
-}
index a988cfef53fbca1ffccd224195cd224c6742e4cb..675c896d70311d988b370012cf0ae0123f7893b9 100644 (file)
@@ -119,6 +119,44 @@ llvm::createX86TargetTransformInfoPass(const X86TargetMachine *TM) {
 //
 //===----------------------------------------------------------------------===//
 
+namespace {
+struct X86CostTblEntry {
+  int ISD;
+  MVT Type;
+  unsigned Cost;
+};
+}
+
+static int
+FindInTable(const X86CostTblEntry *Tbl, unsigned len, int ISD, MVT Ty) {
+  for (unsigned int i = 0; i < len; ++i)
+    if (Tbl[i].ISD == ISD && Tbl[i].Type == Ty)
+      return i;
+
+  // Could not find an entry.
+  return -1;
+}
+
+namespace {
+struct X86TypeConversionCostTblEntry {
+  int ISD;
+  MVT Dst;
+  MVT Src;
+  unsigned Cost;
+};
+}
+
+static int
+FindInConvertTable(const X86TypeConversionCostTblEntry *Tbl, unsigned len,
+                   int ISD, MVT Dst, MVT Src) {
+  for (unsigned int i = 0; i < len; ++i)
+    if (Tbl[i].ISD == ISD && Tbl[i].Src == Src && Tbl[i].Dst == Dst)
+      return i;
+
+  // Could not find an entry.
+  return -1;
+}
+
 X86TTI::PopcntSupportKind X86TTI::getPopcntSupport(unsigned TyWidth) const {
   assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2");
   // TODO: Currently the __builtin_popcount() implementation using SSE3
@@ -168,24 +206,24 @@ unsigned X86TTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty) const {
   int ISD = TLI->InstructionOpcodeToISD(Opcode);
   assert(ISD && "Invalid opcode");
 
-  // 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.
-  // Two ops + 1 extract + 1 insert = 4.
-  static const CostTableEntry AVX1CostTable[] = {
-    { ISD::MUL,    { MVT::v8i32 },    4 },
-    { ISD::SUB,    { MVT::v8i32 },    4 },
-    { ISD::ADD,    { MVT::v8i32 },    4 },
-    { ISD::MUL,    { MVT::v4i64 },    4 },
-    { ISD::SUB,    { MVT::v4i64 },    4 },
-    { ISD::ADD,    { MVT::v4i64 },    4 },
-  };
-  UnaryCostTable costTable (AVX1CostTable, array_lengthof(AVX1CostTable));
+  static const X86CostTblEntry AVX1CostTable[] = {
+    // 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.
+    // Two ops + 1 extract + 1 insert = 4.
+    { ISD::MUL,     MVT::v8i32,    4 },
+    { ISD::SUB,     MVT::v8i32,    4 },
+    { ISD::ADD,     MVT::v8i32,    4 },
+    { ISD::MUL,     MVT::v4i64,    4 },
+    { ISD::SUB,     MVT::v4i64,    4 },
+    { ISD::ADD,     MVT::v4i64,    4 },
+    };
 
   // Look for AVX1 lowering tricks.
   if (ST->hasAVX()) {
-    unsigned cost = costTable.findCost(ISD, LT.second);
-    if (cost != BinaryCostTable::COST_NOT_FOUND)
-      return LT.first * cost;
+    int Idx = FindInTable(AVX1CostTable, array_lengthof(AVX1CostTable), ISD,
+                          LT.second);
+    if (Idx != -1)
+      return LT.first * AVX1CostTable[Idx].Cost;
   }
   // Fallback to the default implementation.
   return TargetTransformInfo::getArithmeticInstrCost(Opcode, Ty);
@@ -216,29 +254,30 @@ unsigned X86TTI::getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) const {
   if (!SrcTy.isSimple() || !DstTy.isSimple())
     return TargetTransformInfo::getCastInstrCost(Opcode, Dst, Src);
 
-  static const CostTableEntry AVXConversionTbl[] = {
-    { ISD::SIGN_EXTEND, { MVT::v8i32, MVT::v8i16 }, 1 },
-    { ISD::ZERO_EXTEND, { MVT::v8i32, MVT::v8i16 }, 1 },
-    { ISD::SIGN_EXTEND, { MVT::v4i64, MVT::v4i32 }, 1 },
-    { ISD::ZERO_EXTEND, { MVT::v4i64, MVT::v4i32 }, 1 },
-    { ISD::TRUNCATE,    { MVT::v4i32, MVT::v4i64 }, 1 },
-    { ISD::TRUNCATE,    { MVT::v8i16, MVT::v8i32 }, 1 },
-    { ISD::SINT_TO_FP,  { MVT::v8f32, MVT::v8i8  }, 1 },
-    { ISD::SINT_TO_FP,  { MVT::v4f32, MVT::v4i8  }, 1 },
-    { ISD::UINT_TO_FP,  { MVT::v8f32, MVT::v8i8  }, 1 },
-    { ISD::UINT_TO_FP,  { MVT::v4f32, MVT::v4i8  }, 1 },
-    { ISD::FP_TO_SINT,  { MVT::v8i8,  MVT::v8f32 }, 1 },
-    { ISD::FP_TO_SINT,  { MVT::v4i8,  MVT::v4f32 }, 1 },
-    { ISD::ZERO_EXTEND, { MVT::v8i32, MVT::v8i1  }, 6 },
-    { ISD::SIGN_EXTEND, { MVT::v8i32, MVT::v8i1  }, 9 },
-    { ISD::TRUNCATE,    { MVT::v8i32, MVT::v8i64 }, 3 }
+  static const X86TypeConversionCostTblEntry AVXConversionTbl[] = {
+    { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i16, 1 },
+    { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i16, 1 },
+    { ISD::SIGN_EXTEND, MVT::v4i64, MVT::v4i32, 1 },
+    { ISD::ZERO_EXTEND, MVT::v4i64, MVT::v4i32, 1 },
+    { ISD::TRUNCATE,    MVT::v4i32, MVT::v4i64, 1 },
+    { ISD::TRUNCATE,    MVT::v8i16, MVT::v8i32, 1 },
+    { ISD::SINT_TO_FP,  MVT::v8f32, MVT::v8i8,  1 },
+    { ISD::SINT_TO_FP,  MVT::v4f32, MVT::v4i8,  1 },
+    { ISD::UINT_TO_FP,  MVT::v8f32, MVT::v8i8,  1 },
+    { ISD::UINT_TO_FP,  MVT::v4f32, MVT::v4i8,  1 },
+    { ISD::FP_TO_SINT,  MVT::v8i8,  MVT::v8f32, 1 },
+    { ISD::FP_TO_SINT,  MVT::v4i8,  MVT::v4f32, 1 },
+    { ISD::ZERO_EXTEND, MVT::v8i32, MVT::v8i1,  6 },
+    { ISD::SIGN_EXTEND, MVT::v8i32, MVT::v8i1,  9 },
+    { ISD::TRUNCATE,    MVT::v8i32, MVT::v8i64, 3 },
   };
-  BinaryCostTable costTable (AVXConversionTbl, array_lengthof(AVXConversionTbl));
 
   if (ST->hasAVX()) {
-    unsigned cost = costTable.findCost(ISD, DstTy.getSimpleVT(), SrcTy.getSimpleVT());
-    if (cost != BinaryCostTable::COST_NOT_FOUND)
-      return cost;
+    int Idx = FindInConvertTable(AVXConversionTbl,
+                                 array_lengthof(AVXConversionTbl),
+                                 ISD, DstTy.getSimpleVT(), SrcTy.getSimpleVT());
+    if (Idx != -1)
+      return AVXConversionTbl[Idx].Cost;
   }
 
   return TargetTransformInfo::getCastInstrCost(Opcode, Dst, Src);
@@ -254,51 +293,48 @@ unsigned X86TTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
   int ISD = TLI->InstructionOpcodeToISD(Opcode);
   assert(ISD && "Invalid opcode");
 
-  static const CostTableEntry SSE42CostTbl[] = {
-    { ISD::SETCC,  { MVT::v2f64 },  1 },
-    { ISD::SETCC,  { MVT::v4f32 },  1 },
-    { ISD::SETCC,  { MVT::v2i64 },  1 },
-    { ISD::SETCC,  { MVT::v4i32 },  1 },
-    { ISD::SETCC,  { MVT::v8i16 },  1 },
-    { ISD::SETCC,  { MVT::v16i8 },  1 },
+  static const X86CostTblEntry SSE42CostTbl[] = {
+    { ISD::SETCC,   MVT::v2f64,   1 },
+    { ISD::SETCC,   MVT::v4f32,   1 },
+    { ISD::SETCC,   MVT::v2i64,   1 },
+    { ISD::SETCC,   MVT::v4i32,   1 },
+    { ISD::SETCC,   MVT::v8i16,   1 },
+    { ISD::SETCC,   MVT::v16i8,   1 },
   };
-  UnaryCostTable costTableSSE4 (SSE42CostTbl, array_lengthof(SSE42CostTbl));
 
-  static const CostTableEntry AVX1CostTbl[] = {
-    { ISD::SETCC,  { MVT::v4f64  },  1 },
-    { ISD::SETCC,  { MVT::v8f32  },  1 },
+  static const X86CostTblEntry AVX1CostTbl[] = {
+    { ISD::SETCC,   MVT::v4f64,   1 },
+    { ISD::SETCC,   MVT::v8f32,   1 },
     // AVX1 does not support 8-wide integer compare.
-    { ISD::SETCC,  { MVT::v4i64  },  4 },
-    { ISD::SETCC,  { MVT::v8i32  },  4 },
-    { ISD::SETCC,  { MVT::v16i16 },  4 },
-    { ISD::SETCC,  { MVT::v32i8  },  4 },
+    { ISD::SETCC,   MVT::v4i64,   4 },
+    { ISD::SETCC,   MVT::v8i32,   4 },
+    { ISD::SETCC,   MVT::v16i16,  4 },
+    { ISD::SETCC,   MVT::v32i8,   4 },
   };
-  UnaryCostTable costTableAVX1 (AVX1CostTbl, array_lengthof(AVX1CostTbl));
 
-  static const CostTableEntry AVX2CostTbl[] = {
-    { ISD::SETCC,  { MVT::v4i64  }, 1 },
-    { ISD::SETCC,  { MVT::v8i32  }, 1 },
-    { ISD::SETCC,  { MVT::v16i16 }, 1 },
-    { ISD::SETCC,  { MVT::v32i8  }, 1 },
+  static const X86CostTblEntry AVX2CostTbl[] = {
+    { ISD::SETCC,   MVT::v4i64,   1 },
+    { ISD::SETCC,   MVT::v8i32,   1 },
+    { ISD::SETCC,   MVT::v16i16,  1 },
+    { ISD::SETCC,   MVT::v32i8,   1 },
   };
-  UnaryCostTable costTableAVX2 (AVX2CostTbl, array_lengthof(AVX2CostTbl));
 
   if (ST->hasAVX2()) {
-    unsigned cost = costTableAVX2.findCost(ISD, MTy);
-    if (cost != BinaryCostTable::COST_NOT_FOUND)
-      return LT.first * cost;
+    int Idx = FindInTable(AVX2CostTbl, array_lengthof(AVX2CostTbl), ISD, MTy);
+    if (Idx != -1)
+      return LT.first * AVX2CostTbl[Idx].Cost;
   }
 
   if (ST->hasAVX()) {
-    unsigned cost = costTableAVX1.findCost(ISD, MTy);
-    if (cost != BinaryCostTable::COST_NOT_FOUND)
-      return LT.first * cost;
+    int Idx = FindInTable(AVX1CostTbl, array_lengthof(AVX1CostTbl), ISD, MTy);
+    if (Idx != -1)
+      return LT.first * AVX1CostTbl[Idx].Cost;
   }
 
   if (ST->hasSSE42()) {
-    unsigned cost = costTableSSE4.findCost(ISD, MTy);
-    if (cost != BinaryCostTable::COST_NOT_FOUND)
-      return LT.first * cost;
+    int Idx = FindInTable(SSE42CostTbl, array_lengthof(SSE42CostTbl), ISD, MTy);
+    if (Idx != -1)
+      return LT.first * SSE42CostTbl[Idx].Cost;
   }
 
   return TargetTransformInfo::getCmpSelInstrCost(Opcode, ValTy, CondTy);