Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -107,6 +107,37 @@ /// \name Generic Target Information /// @{ + /// \brief The kind of cost model. + /// + /// Now we support following 3 kinds of cost model. + enum TargetCostKind { + TCK_Throughput, ///< The traditional cost model, it actually + ///< means reciprocal throughputs. + TCK_Latency, ///< The latency of instruction. + TCK_CodeSize ///< Instruction code size. + }; + + /// \brief Query the cost of a specified instruction. + /// + /// Clients should mainly use this interface to query the cost of the + /// specified instruction. + int getInstructionCost(const Instruction *I, enum TargetCostKind kind) const { + switch (kind){ + case TCK_Throughput: + return getUserCost(I); + + case TCK_Latency: + return getInstructionLatency(I); + + case TCK_CodeSize: + return getInstructionSize(I); + + default: + assert("Wrong cost kind passed in."); + return 0; + } + } + /// \brief Underlying constants for 'cost' values in this interface. /// /// Many APIs in this interface return a cost. This enum defines the @@ -843,6 +874,12 @@ /// @} private: + /// \brief Estimate the latency of specified instruction. + int getInstructionLatency(const Instruction *I) const; + + /// \brief Estimate the code size of specified instruction. + int getInstructionSize(const Instruction *I) const; + /// \brief The abstract base class used to type erase specific TTI /// implementations. class Concept; @@ -1015,6 +1052,8 @@ virtual bool useReductionIntrinsic(unsigned Opcode, Type *Ty, ReductionFlags) const = 0; virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0; + virtual int getInstructionLatency(const Instruction *I) = 0; + virtual int getInstructionSize(const Instruction *I) const = 0; }; template @@ -1367,6 +1406,12 @@ bool shouldExpandReduction(const IntrinsicInst *II) const override { return Impl.shouldExpandReduction(II); } + int getInstructionLatency(const Instruction *I) override { + return Impl.getInstructionLatency(I); + } + int getInstructionSize(const Instruction *I) const override { + return Impl.getInstructionSize(I); + } }; template Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -509,6 +509,15 @@ return true; } + int getInstructionSize(const Instruction *I) const { + if (isa(I)) + return 0; + + // This simple implementation is good enough for many RISC processors. + // But CISC processors need their own implementations. + return 4; + } + protected: // Obtain the minimum required size to hold the value (without the sign) // In case of a vector it returns the min required size for one element. @@ -740,6 +749,25 @@ Operator::getOpcode(U), U->getType(), U->getNumOperands() == 1 ? U->getOperand(0)->getType() : nullptr); } + + int getInstructionLatency(const Instruction *I) { + if (isa(I)) + return 0; + + if (isa(I)) + return 40; + + if (isa(I)) + return 4; + + Type *dstTy = I->getType(); + if (VectorType *VectorTy = dyn_cast(dstTy)) + dstTy = VectorTy->getElementType(); + if (dstTy->isFloatingPointTy()) + return 3; + + return 1; + } }; } Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -564,6 +564,14 @@ return TTIImpl->shouldExpandReduction(II); } +int TargetTransformInfo::getInstructionLatency(const Instruction *I) const { + return TTIImpl->getInstructionLatency(I); +} + +int TargetTransformInfo::getInstructionSize(const Instruction *I) const { + return TTIImpl->getInstructionSize(I); +} + TargetTransformInfo::Concept::~Concept() {} TargetIRAnalysis::TargetIRAnalysis() : TTICallback(&getDefaultTTI) {}