summaryrefslogtreecommitdiff
path: root/lib/Target/TargetTransformImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/TargetTransformImpl.cpp')
-rw-r--r--lib/Target/TargetTransformImpl.cpp129
1 files changed, 127 insertions, 2 deletions
diff --git a/lib/Target/TargetTransformImpl.cpp b/lib/Target/TargetTransformImpl.cpp
index cee736bd71..382eecb766 100644
--- a/lib/Target/TargetTransformImpl.cpp
+++ b/lib/Target/TargetTransformImpl.cpp
@@ -9,6 +9,7 @@
#include "llvm/Target/TargetTransformImpl.h"
#include "llvm/Target/TargetLowering.h"
+#include <utility>
using namespace llvm;
@@ -53,11 +54,131 @@ unsigned ScalarTargetTransformImpl::getJumpBufSize() const {
// Calls used by the vectorizers.
//
//===----------------------------------------------------------------------===//
+int InstructionOpcodeToISD(unsigned Opcode) {
+ static const int OpToISDTbl[] = {
+ /*Instruction::Ret */ 0, // Opcode numbering start at #1.
+ /*Instruction::Br */ 0,
+ /*Instruction::Switch */ 0,
+ /*Instruction::IndirectBr */ 0,
+ /*Instruction::Invoke */ 0,
+ /*Instruction::Resume */ 0,
+ /*Instruction::Unreachable */ 0,
+ /*Instruction::Add */ ISD::ADD,
+ /*Instruction::FAdd */ ISD::FADD,
+ /*Instruction::Sub */ ISD::SUB,
+ /*Instruction::FSub */ ISD::FSUB,
+ /*Instruction::Mul */ ISD::MUL,
+ /*Instruction::FMul */ ISD::FMUL,
+ /*Instruction::UDiv */ ISD::UDIV,
+ /*Instruction::SDiv */ ISD::UDIV,
+ /*Instruction::FDiv */ ISD::FDIV,
+ /*Instruction::URem */ ISD::UREM,
+ /*Instruction::SRem */ ISD::SREM,
+ /*Instruction::FRem */ ISD::FREM,
+ /*Instruction::Shl */ ISD::SHL,
+ /*Instruction::LShr */ ISD::SRL,
+ /*Instruction::AShr */ ISD::SRA,
+ /*Instruction::And */ ISD::AND,
+ /*Instruction::Or */ ISD::OR,
+ /*Instruction::Xor */ ISD::XOR,
+ /*Instruction::Alloca */ 0,
+ /*Instruction::Load */ ISD::LOAD,
+ /*Instruction::Store */ ISD::STORE,
+ /*Instruction::GetElementPtr */ 0,
+ /*Instruction::Fence */ 0,
+ /*Instruction::AtomicCmpXchg */ 0,
+ /*Instruction::AtomicRMW */ 0,
+ /*Instruction::Trunc */ ISD::TRUNCATE,
+ /*Instruction::ZExt */ ISD::ZERO_EXTEND,
+ /*Instruction::SExt */ ISD::SEXTLOAD,
+ /*Instruction::FPToUI */ ISD::FP_TO_UINT,
+ /*Instruction::FPToSI */ ISD::FP_TO_SINT,
+ /*Instruction::UIToFP */ ISD::UINT_TO_FP,
+ /*Instruction::SIToFP */ ISD::SINT_TO_FP,
+ /*Instruction::FPTrunc */ ISD::FP_ROUND,
+ /*Instruction::FPExt */ ISD::FP_EXTEND,
+ /*Instruction::PtrToInt */ ISD::BITCAST,
+ /*Instruction::IntToPtr */ ISD::BITCAST,
+ /*Instruction::BitCast */ ISD::BITCAST,
+ /*Instruction::ICmp */ ISD::SETCC,
+ /*Instruction::FCmp */ ISD::SETCC,
+ /*Instruction::PHI */ 0,
+ /*Instruction::Call */ 0,
+ /*Instruction::Select */ ISD::SELECT,
+ /*Instruction::UserOp1 */ 0,
+ /*Instruction::UserOp2 */ 0,
+ /*Instruction::VAArg */ 0,
+ /*Instruction::ExtractElement*/ ISD::EXTRACT_VECTOR_ELT,
+ /*Instruction::InsertElement */ ISD::INSERT_VECTOR_ELT,
+ /*Instruction::ShuffleVector */ ISD::VECTOR_SHUFFLE,
+ /*Instruction::ExtractValue */ ISD::MERGE_VALUES,
+ /*Instruction::InsertValue */ ISD::MERGE_VALUES,
+ /*Instruction::LandingPad */ 0};
+
+ assert((Instruction::Ret == 1) && (Instruction::LandingPad == 58) &&
+ "Instruction order had changed");
+
+ // Opcode numbering starts at #1 but the table starts at #0, so we subtract
+ // one from the opcode number.
+ return OpToISDTbl[Opcode - 1];
+}
+
+std::pair<unsigned, EVT>
+VectorTargetTransformImpl::getTypeLegalizationCost(LLVMContext &C,
+ EVT Ty) const {
+ unsigned Cost = 1;
+ // We keep legalizing the type until we find a legal kind. We assume that
+ // the only operation that costs anything is the split. After splitting
+ // we need to handle two types.
+ while (true) {
+ TargetLowering::LegalizeKind LK = TLI->getTypeConversion(C, Ty);
+
+ if (LK.first == TargetLowering::TypeLegal)
+ return std::make_pair(Cost, LK.second);
+
+ if (LK.first == TargetLowering::TypeSplitVector)
+ Cost *= 2;
+
+ // Keep legalizing the type.
+ Ty = LK.second;
+ }
+}
unsigned
VectorTargetTransformImpl::getInstrCost(unsigned Opcode, Type *Ty1,
Type *Ty2) const {
- return 1;
+ // Check if any of the operands are vector operands.
+ int ISD = InstructionOpcodeToISD(Opcode);
+
+ // Selects on vectors are actually vector selects.
+ if (ISD == ISD::SELECT) {
+ assert(Ty2 && "Ty2 must hold the select type");
+ if (Ty2->isVectorTy())
+ ISD = ISD::VSELECT;
+ }
+
+ // If we don't have any information about this instruction assume it costs 1.
+ if (ISD == 0)
+ return 1;
+
+ assert(Ty1 && "We need to have at least one type");
+
+ // From this stage we look at the legalized type.
+ std::pair<unsigned, EVT> LT =
+ getTypeLegalizationCost(Ty1->getContext(), TLI->getValueType(Ty1));
+
+ if (TLI->isOperationLegalOrCustom(ISD, LT.second)) {
+ // The operation is legal. Assume it costs 1. Multiply
+ // by the type-legalization overhead.
+ return LT.first * 1;
+ }
+
+ unsigned NumElem =
+ (LT.second.isVector() ? LT.second.getVectorNumElements() : 1);
+
+ // We will probably scalarize this instruction. Assume that the cost is the
+ // number of the vector elements.
+ return LT.first * NumElem * 1;
}
unsigned
@@ -69,5 +190,9 @@ unsigned
VectorTargetTransformImpl::getMemoryOpCost(unsigned Opcode, Type *Src,
unsigned Alignment,
unsigned AddressSpace) const {
- return 1;
+ // From this stage we look at the legalized type.
+ std::pair<unsigned, EVT> LT =
+ getTypeLegalizationCost(Src->getContext(), TLI->getValueType(Src));
+ // Assume that all loads of legal types cost 1.
+ return LT.first;
}