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 | 0dba9a9a26f45119a82200d1db37b734b3e1bb22 (patch) | |
tree | 61fd5d2c6c9996b155713c95cb354026473216e2 /lib/Target | |
parent | 2932284f045005bc3ed850f9c42524fadf3ae3d8 (diff) | |
download | external_llvm-0dba9a9a26f45119a82200d1db37b734b3e1bb22.zip external_llvm-0dba9a9a26f45119a82200d1db37b734b3e1bb22.tar.gz external_llvm-0dba9a9a26f45119a82200d1db37b734b3e1bb22.tar.bz2 |
Fix a bug in the cost calculation of vector casts. Detect situations where bitcasts cost zero.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167170 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/TargetTransformImpl.cpp | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/lib/Target/TargetTransformImpl.cpp b/lib/Target/TargetTransformImpl.cpp index 38c704f..dbbf37a 100644 --- a/lib/Target/TargetTransformImpl.cpp +++ b/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; |