[llvm-commits] [llvm] r167395 - in /llvm/trunk: include/llvm/Target/TargetTransformImpl.h lib/Target/TargetTransformImpl.cpp lib/Target/X86/X86ISelLowering.cpp test/Analysis/CostModel/X86/arith.ll test/Transforms/LoopVectorize/X86/conversion-cost.ll

Nadav Rotem nrotem at apple.com
Mon Nov 5 11:32:46 PST 2012


Author: nadav
Date: Mon Nov  5 13:32:46 2012
New Revision: 167395

URL: http://llvm.org/viewvc/llvm-project?rev=167395&view=rev
Log:
Implement the cost of abnormal x86 instruction lowering as a table.


Modified:
    llvm/trunk/include/llvm/Target/TargetTransformImpl.h
    llvm/trunk/lib/Target/TargetTransformImpl.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/test/Analysis/CostModel/X86/arith.ll
    llvm/trunk/test/Transforms/LoopVectorize/X86/conversion-cost.ll

Modified: llvm/trunk/include/llvm/Target/TargetTransformImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetTransformImpl.h?rev=167395&r1=167394&r2=167395&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetTransformImpl.h (original)
+++ llvm/trunk/include/llvm/Target/TargetTransformImpl.h Mon Nov  5 13:32:46 2012
@@ -55,13 +55,16 @@
   const TargetLowering *TLI;
 
   /// Estimate the cost of type-legalization and the legalized type.
-  std::pair<unsigned, EVT>
+  std::pair<unsigned, MVT>
   getTypeLegalizationCost(LLVMContext &C, EVT Ty) const;
 
   /// Estimate the overhead of scalarizing an instruction. Insert and Extract
   /// are set if the result needs to be inserted and/or extracted from vectors.
   unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const;
 
+  // Get the ISD node that corresponds to the Instruction class opcode.
+  int InstructionOpcodeToISD(unsigned Opcode) const;
+
 public:
   explicit VectorTargetTransformImpl(const TargetLowering *TL) : TLI(TL) {}
 

Modified: llvm/trunk/lib/Target/TargetTransformImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetTransformImpl.cpp?rev=167395&r1=167394&r2=167395&view=diff
==============================================================================
--- llvm/trunk/lib/Target/TargetTransformImpl.cpp (original)
+++ llvm/trunk/lib/Target/TargetTransformImpl.cpp Mon Nov  5 13:32:46 2012
@@ -60,7 +60,7 @@
 // Calls used by the vectorizers.
 //
 //===----------------------------------------------------------------------===//
-static int InstructionOpcodeToISD(unsigned Opcode) {
+int VectorTargetTransformImpl::InstructionOpcodeToISD(unsigned Opcode) const {
   enum InstructionOpcodes {
 #define HANDLE_INST(NUM, OPCODE, CLASS) OPCODE = NUM,
 #define LAST_OTHER_INST(NUM) InstructionOpcodesCount = NUM
@@ -130,7 +130,7 @@
   llvm_unreachable("Unknown instruction type encountered!");
 }
 
-std::pair<unsigned, EVT>
+std::pair<unsigned, MVT>
 VectorTargetTransformImpl::getTypeLegalizationCost(LLVMContext &C,
                                                    EVT Ty) const {
   unsigned Cost = 1;
@@ -141,7 +141,7 @@
     TargetLowering::LegalizeKind LK = TLI->getTypeConversion(C, Ty);
 
     if (LK.first == TargetLowering::TypeLegal)
-      return std::make_pair(Cost, Ty);
+      return std::make_pair(Cost, Ty.getSimpleVT());
 
     if (LK.first == TargetLowering::TypeSplitVector)
       Cost *= 2;
@@ -174,7 +174,7 @@
   int ISD = InstructionOpcodeToISD(Opcode);
   assert(ISD && "Invalid opcode");
 
-  std::pair<unsigned, EVT> LT =
+  std::pair<unsigned, MVT> LT =
   getTypeLegalizationCost(Ty->getContext(), TLI->getValueType(Ty));
 
   if (!TLI->isOperationExpand(ISD, LT.second)) {
@@ -205,10 +205,10 @@
   int ISD = InstructionOpcodeToISD(Opcode);
   assert(ISD && "Invalid opcode");
 
-  std::pair<unsigned, EVT> SrcLT =
+  std::pair<unsigned, MVT> SrcLT =
   getTypeLegalizationCost(Src->getContext(), TLI->getValueType(Src));
 
-  std::pair<unsigned, EVT> DstLT =
+  std::pair<unsigned, MVT> DstLT =
   getTypeLegalizationCost(Dst->getContext(), TLI->getValueType(Dst));
 
   // Handle scalar conversions.
@@ -283,7 +283,7 @@
       ISD = ISD::VSELECT;
   }
 
-  std::pair<unsigned, EVT> LT =
+  std::pair<unsigned, MVT> LT =
   getTypeLegalizationCost(ValTy->getContext(), TLI->getValueType(ValTy));
 
   if (!TLI->isOperationExpand(ISD, LT.second)) {
@@ -326,7 +326,7 @@
 VectorTargetTransformImpl::getMemoryOpCost(unsigned Opcode, Type *Src,
                                            unsigned Alignment,
                                            unsigned AddressSpace) const {
-  std::pair<unsigned, EVT> LT =
+  std::pair<unsigned, MVT> LT =
   getTypeLegalizationCost(Src->getContext(), TLI->getValueType(Src));
 
   // Assume that all loads of legal types cost 1.
@@ -335,7 +335,7 @@
 
 unsigned
 VectorTargetTransformImpl::getNumberOfParts(Type *Tp) const {
-  std::pair<unsigned, EVT> LT =
+  std::pair<unsigned, MVT> LT =
     getTypeLegalizationCost(Tp->getContext(), TLI->getValueType(Tp));
   return LT.first;
 }

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=167395&r1=167394&r2=167395&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Nov  5 13:32:46 2012
@@ -17505,63 +17505,51 @@
   return Res;
 }
 
+//===----------------------------------------------------------------------===//
+//
+// X86 cost model.
+//
+//===----------------------------------------------------------------------===//
+
+struct X86CostTblEntry {
+  int ISD;
+  MVT Type;
+  unsigned Cost;
+};
+
 unsigned
 X86VectorTargetTransformInfo::getArithmeticInstrCost(unsigned Opcode,
                                                      Type *Ty) const {
+  // Legalize the type.
+  std::pair<unsigned, MVT> LT =
+  getTypeLegalizationCost(Ty->getContext(), TLI->getValueType(Ty));
+
+  int ISD = InstructionOpcodeToISD(Opcode);
+  assert(ISD && "Invalid opcode");
+
   const X86Subtarget &ST =
   TLI->getTargetMachine().getSubtarget<X86Subtarget>();
 
-  // Fix some of the inaccuracies of the target independent estimation.
-  if (Ty->isVectorTy() && ST.hasSSE41()) {
-    unsigned NumElem = Ty->getVectorNumElements();
-    unsigned SizeInBits = Ty->getScalarType()->getScalarSizeInBits();
-
-    bool Is2 = (NumElem == 2);
-    bool Is4 = (NumElem == 4);
-    bool Is8 = (NumElem == 8);
-    bool Is32bits = (SizeInBits == 32);
-    bool Is64bits = (SizeInBits == 64);
-    bool HasAvx = ST.hasAVX();
-    bool HasAvx2 = ST.hasAVX2();
-
-    switch (Opcode) {
-      case Instruction::Add:
-      case Instruction::Sub:
-      case Instruction::Mul: {
-        // Only AVX2 has support for 8-wide integer operations.
-        if (Is32bits && (Is4 || (Is8 && HasAvx2))) return 1;
-        if (Is64bits && (Is2 || (Is4 && HasAvx2))) return 1;
-
-        // We don't have to completly scalarize unsupported ops. We can
-        // issue two half-sized operations (with some overhead).
-        // We don't need to extract the lower part of the YMM to the XMM.
-        // Extract the upper, two ops, insert the upper = 4.
-        if (Is32bits && Is8 && HasAvx) return 4;
-        if (Is64bits && Is4 && HasAvx) return 4;
-        break;
-      }
-      case Instruction::FAdd:
-      case Instruction::FSub:
-      case Instruction::FMul: {
-        // AVX has support for 8-wide float operations.
-        if (Is32bits && (Is4 || (Is8 && HasAvx))) return 1;
-        if (Is64bits && (Is2 || (Is4 && HasAvx))) return 1;
-        break;
-      }
-      case Instruction::Shl:
-      case Instruction::LShr:
-      case Instruction::AShr:
-      case Instruction::And:
-      case Instruction::Or:
-      case Instruction::Xor: {
-        // AVX has support for 8-wide integer bitwise operations.
-        if (Is32bits && (Is4 || (Is8 && HasAvx))) return 1;
-        if (Is64bits && (Is2 || (Is4 && HasAvx))) return 1;
-        break;
-      }
+  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())
+    for (unsigned int i = 0, e = array_lengthof(AVX1CostTable); i < e; ++i) {
+      if (AVX1CostTable[i].ISD == ISD && AVX1CostTable[i].Type == LT.second)
+        return LT.first * AVX1CostTable[i].Cost;
     }
-  }
 
+  // Fallback to the default implementation.
   return VectorTargetTransformImpl::getArithmeticInstrCost(Opcode, Ty);
 }
 

Modified: llvm/trunk/test/Analysis/CostModel/X86/arith.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/CostModel/X86/arith.ll?rev=167395&r1=167394&r2=167395&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/CostModel/X86/arith.ll (original)
+++ llvm/trunk/test/Analysis/CostModel/X86/arith.ll Mon Nov  5 13:32:46 2012
@@ -12,6 +12,8 @@
   %C = add <2 x i64> undef, undef
   ;CHECK: cost of 4 {{.*}} add
   %D = add <4 x i64> undef, undef
+  ;CHECK: cost of 8 {{.*}} add
+  %E = add <8 x i64> undef, undef
   ;CHECK: cost of 1 {{.*}} ret
   ret i32 undef
 }

Modified: llvm/trunk/test/Transforms/LoopVectorize/X86/conversion-cost.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopVectorize/X86/conversion-cost.ll?rev=167395&r1=167394&r2=167395&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopVectorize/X86/conversion-cost.ll (original)
+++ llvm/trunk/test/Transforms/LoopVectorize/X86/conversion-cost.ll Mon Nov  5 13:32:46 2012
@@ -25,7 +25,7 @@
 }
 
 ;CHECK: @conversion_cost2
-;CHECK: store <8 x float>
+;CHECK-NOT: <8 x float>
 ;CHECK: ret
 define i32 @conversion_cost2(i32 %n, i8* nocapture %A, float* nocapture %B) nounwind uwtable ssp {
   %1 = icmp sgt i32 %n, 9





More information about the llvm-commits mailing list