diff options
| author | Nadav Rotem <nrotem@apple.com> | 2012-10-31 20:52:26 +0000 |
|---|---|---|
| committer | Nadav Rotem <nrotem@apple.com> | 2012-10-31 20:52:26 +0000 |
| commit | 6d7d39783da18067baa07d73d2d1a4aefb9b32bf (patch) | |
| tree | 734eeb364e7bc93c719d5a3d44dd11ff5f6ee60b /llvm/lib/Target | |
| parent | 5d361d7e3a99ad9cef6143ce37fef6fedb99de40 (diff) | |
| download | bcm5719-llvm-6d7d39783da18067baa07d73d2d1a4aefb9b32bf.tar.gz bcm5719-llvm-6d7d39783da18067baa07d73d2d1a4aefb9b32bf.zip | |
Fix a bug in the cost calculation of vector casts. Detect situations where bitcasts cost zero.
llvm-svn: 167170
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/TargetTransformImpl.cpp | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/llvm/lib/Target/TargetTransformImpl.cpp b/llvm/lib/Target/TargetTransformImpl.cpp index 38c704f2b1a..dbbf37a7dd0 100644 --- a/llvm/lib/Target/TargetTransformImpl.cpp +++ b/llvm/lib/Target/TargetTransformImpl.cpp @@ -211,40 +211,55 @@ unsigned VectorTargetTransformImpl::getCastInstrCost(unsigned Opcode, Type *Dst, std::pair<unsigned, EVT> DstLT = getTypeLegalizationCost(Dst->getContext(), TLI->getValueType(Dst)); - // If the cast is between same-sized registers, then the check is simple. - if (SrcLT.first == DstLT.first && - SrcLT.second.getSizeInBits() == DstLT.second.getSizeInBits()) { - // Just check the op cost: - if (!TLI->isOperationExpand(ISD, DstLT.second)) { - // The operation is legal. Assume it costs 1. Multiply - // by the type-legalization overhead. - return SrcLT.first * 1; - } + // Handle scalar conversions. + if (!Src->isVectorTy() && !Dst->isVectorTy()) { + // Just check the op cost. If the operation is legal then assume it costs 1. + if (!TLI->isOperationExpand(ISD, DstLT.second)) + return 1; + + // Assume that illegal scalar instruction are expensive. + return 4; } - unsigned ScalarizationCost = 1; + // Check vector-to-vector casts. + if (Dst->isVectorTy() && Src->isVectorTy()) { - // Otherwise, assume that the cast is scalarized. - if (Dst->isVectorTy()) { - unsigned Num = Dst->getVectorNumElements(); - unsigned Cost = getCastInstrCost(Opcode, Src->getScalarType(), - Dst->getScalarType()); - // return the cost of multiple scalar invocation plus the cost of inserting - // and extracting the values. - ScalarizationCost *= getScalarizationOverhead(Dst, true, true) + Num * Cost; - } + // If the cast is between same-sized registers, then the check is simple. + if (SrcLT.first == DstLT.first && + SrcLT.second.getSizeInBits() == DstLT.second.getSizeInBits()) { - if (Src->isVectorTy()) { - unsigned Num = Src->getVectorNumElements(); + // Bitcast between types that are legalized to the same type are free. + if (Opcode == Instruction::BitCast) + return 0; + + // Just check the op cost. If the operation is legal then assume it costs + // 1 and multiply by the type-legalization overhead. + if (!TLI->isOperationExpand(ISD, DstLT.second)) + return SrcLT.first * 1; + } + + // If we are converting vectors and the operation is illegal, or + // if the vectors are legalized to different types, estimate the + // scalarization costs. + unsigned Num = Dst->getVectorNumElements(); unsigned Cost = getCastInstrCost(Opcode, Dst->getScalarType(), Src->getScalarType()); - // return the cost of multiple scalar invocation plus the cost of inserting - // and extracting the values. - ScalarizationCost *= getScalarizationOverhead(Src, true, true) + Num * Cost; + + // Return the cost of multiple scalar invocation plus the cost of + // inserting and extracting the values. + return getScalarizationOverhead(Dst, true, true) + Num * Cost; } - return ScalarizationCost; -} + // We already handled vector-to-vector and scalar-to-scalar conversions. This + // is where we handle bitcast between vectors and scalars. We need to assume + // that the conversion is scalarized in one way or another. + if (Opcode == Instruction::BitCast) + // Illegal bitcasts are done by storing and loading from a stack slot. + return (Src->isVectorTy()? getScalarizationOverhead(Src, false, true):0) + + (Dst->isVectorTy()? getScalarizationOverhead(Dst, true, false):0); + + llvm_unreachable("Unhandled cast"); + } unsigned VectorTargetTransformImpl::getCFInstrCost(unsigned Opcode) const { return 1; |

