Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -208,18 +208,19 @@ /// This is the most basic query for estimating call cost: it only knows the /// function type and (potentially) the number of arguments at the call site. /// The latter is only interesting for varargs function types. - int getCallCost(FunctionType *FTy, int NumArgs = -1) const; + int getCallCost(FunctionType *FTy, int NumArgs = -1, User *U = nullptr) const; /// Estimate the cost of calling a specific function when lowered. /// /// This overload adds the ability to reason about the particular function /// being called in the event it is a library call with special lowering. - int getCallCost(const Function *F, int NumArgs = -1) const; + int getCallCost(const Function *F, int NumArgs = -1, User *U = nullptr) const; /// Estimate the cost of calling a specific function when lowered. /// /// This overload allows specifying a set of candidate argument values. - int getCallCost(const Function *F, ArrayRef Arguments) const; + int getCallCost(const Function *F, ArrayRef Arguments, + User *U = nullptr) const; /// \returns A value by which our inlining threshold should be multiplied. /// This is primarily used to bump up the inlining threshold wholesale on @@ -233,13 +234,15 @@ /// /// Mirrors the \c getCallCost method but uses an intrinsic identifier. int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef ParamTys) const; + ArrayRef ParamTys, + const User *U = nullptr) const; /// Estimate the cost of an intrinsic when lowered. /// /// Mirrors the \c getCallCost method but uses an intrinsic identifier. int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef Arguments) const; + ArrayRef Arguments, + const User *U = nullptr) const; /// \return The estimated number of case clusters when lowering \p 'SI'. /// \p JTSize Set a jump table size only when \p SI is suitable for a jump @@ -809,6 +812,10 @@ /// Use -1 to indicate that there is no information on the index value. int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index = -1) const; + /// \Return the expected cost of a memcpy, which could e.g. depend on the + /// source/destination type and alignment and the number of bytes copied. + int getMemcpyCost(const Instruction *I) const; + /// \return The cost of Load and Store instructions. int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, unsigned AddressSpace, const Instruction *I = nullptr) const; @@ -1038,15 +1045,16 @@ virtual int getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef Operands) = 0; virtual int getExtCost(const Instruction *I, const Value *Src) = 0; - virtual int getCallCost(FunctionType *FTy, int NumArgs) = 0; - virtual int getCallCost(const Function *F, int NumArgs) = 0; + virtual int getCallCost(FunctionType *FTy, int NumArgs, User *U) = 0; + virtual int getCallCost(const Function *F, int NumArgs, User *U) = 0; virtual int getCallCost(const Function *F, - ArrayRef Arguments) = 0; + ArrayRef Arguments, User *U) = 0; virtual unsigned getInliningThresholdMultiplier() = 0; virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef ParamTys) = 0; + ArrayRef ParamTys, const User *U) = 0; virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef Arguments) = 0; + ArrayRef Arguments, + const User *U) = 0; virtual unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, unsigned &JTSize) = 0; virtual int @@ -1148,6 +1156,7 @@ Type *CondTy, const Instruction *I) = 0; virtual int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) = 0; + virtual int getMemcpyCost(const Instruction *I) = 0; virtual int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, unsigned AddressSpace, const Instruction *I) = 0; virtual int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, @@ -1239,26 +1248,27 @@ int getExtCost(const Instruction *I, const Value *Src) override { return Impl.getExtCost(I, Src); } - int getCallCost(FunctionType *FTy, int NumArgs) override { - return Impl.getCallCost(FTy, NumArgs); + int getCallCost(FunctionType *FTy, int NumArgs, User *U) override { + return Impl.getCallCost(FTy, NumArgs, U); } - int getCallCost(const Function *F, int NumArgs) override { - return Impl.getCallCost(F, NumArgs); + int getCallCost(const Function *F, int NumArgs, User *U) override { + return Impl.getCallCost(F, NumArgs, U); } int getCallCost(const Function *F, - ArrayRef Arguments) override { - return Impl.getCallCost(F, Arguments); + ArrayRef Arguments, User *U) override { + return Impl.getCallCost(F, Arguments, U); } unsigned getInliningThresholdMultiplier() override { return Impl.getInliningThresholdMultiplier(); } int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef ParamTys) override { - return Impl.getIntrinsicCost(IID, RetTy, ParamTys); + ArrayRef ParamTys, const User *U = nullptr) override { + return Impl.getIntrinsicCost(IID, RetTy, ParamTys, U); } int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef Arguments) override { - return Impl.getIntrinsicCost(IID, RetTy, Arguments); + ArrayRef Arguments, + const User *U = nullptr) override { + return Impl.getIntrinsicCost(IID, RetTy, Arguments, U); } int getUserCost(const User *U, ArrayRef Operands) override { return Impl.getUserCost(U, Operands); @@ -1494,6 +1504,9 @@ int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) override { return Impl.getVectorInstrCost(Opcode, Val, Index); } + int getMemcpyCost(const Instruction *I) { + return Impl.getMemcpyCost(I); + } int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, unsigned AddressSpace, const Instruction *I) override { return Impl.getMemoryOpCost(Opcode, Src, Alignment, AddressSpace, I); Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -23,6 +23,7 @@ #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" +#include "llvm/IR/IntrinsicInst.h" namespace llvm { @@ -123,7 +124,7 @@ return TTI::TCC_Basic; } - unsigned getCallCost(FunctionType *FTy, int NumArgs) { + unsigned getCallCost(FunctionType *FTy, int NumArgs, const User *U) { assert(FTy && "FunctionType must be provided to this routine."); // The target-independent implementation just measures the size of the @@ -141,7 +142,7 @@ unsigned getInliningThresholdMultiplier() { return 1; } unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef ParamTys) { + ArrayRef ParamTys, const User *U) { switch (IID) { default: // Intrinsics rarely (if ever) have normal argument setup constraints. @@ -149,6 +150,8 @@ // FIXME: This is wrong for libc intrinsics. return TTI::TCC_Basic; + case Intrinsic::memcpy: + return getMemcpyCost(dyn_cast(U)); case Intrinsic::annotation: case Intrinsic::assume: case Intrinsic::sideeffect: @@ -435,6 +438,10 @@ return 1; } + unsigned getMemcpyCost(const Instruction *I) { + return 1; + } + unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, unsigned AddressSpace, const Instruction *I) { return 1; @@ -680,7 +687,7 @@ public: using BaseT::getCallCost; - unsigned getCallCost(const Function *F, int NumArgs) { + unsigned getCallCost(const Function *F, int NumArgs, const User *U) { assert(F && "A concrete function must be provided to this routine."); if (NumArgs < 0) @@ -692,21 +699,22 @@ FunctionType *FTy = F->getFunctionType(); SmallVector ParamTys(FTy->param_begin(), FTy->param_end()); return static_cast(this) - ->getIntrinsicCost(IID, FTy->getReturnType(), ParamTys); + ->getIntrinsicCost(IID, FTy->getReturnType(), ParamTys, U); } if (!static_cast(this)->isLoweredToCall(F)) return TTI::TCC_Basic; // Give a basic cost if it will be lowered // directly. - return static_cast(this)->getCallCost(F->getFunctionType(), NumArgs); + return static_cast(this)->getCallCost(F->getFunctionType(), NumArgs, U); } - unsigned getCallCost(const Function *F, ArrayRef Arguments) { + unsigned getCallCost(const Function *F, ArrayRef Arguments, + const User *U) { // Simply delegate to generic handling of the call. // FIXME: We should use instsimplify or something else to catch calls which // will constant fold with these arguments. - return static_cast(this)->getCallCost(F, Arguments.size()); + return static_cast(this)->getCallCost(F, Arguments.size(), U); } using BaseT::getGEPCost; @@ -777,7 +785,7 @@ using BaseT::getIntrinsicCost; unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef Arguments) { + ArrayRef Arguments, const User *U) { // Delegate to the generic intrinsic handling code. This mostly provides an // opportunity for targets to (for example) special case the cost of // certain intrinsics based on constants used as arguments. @@ -785,7 +793,7 @@ ParamTys.reserve(Arguments.size()); for (unsigned Idx = 0, Size = Arguments.size(); Idx != Size; ++Idx) ParamTys.push_back(Arguments[Idx]->getType()); - return static_cast(this)->getIntrinsicCost(IID, RetTy, ParamTys); + return static_cast(this)->getIntrinsicCost(IID, RetTy, ParamTys, U); } unsigned getUserCost(const User *U, ArrayRef Operands) { @@ -809,11 +817,11 @@ // Just use the called value type. Type *FTy = CS.getCalledValue()->getType()->getPointerElementType(); return static_cast(this) - ->getCallCost(cast(FTy), CS.arg_size()); + ->getCallCost(cast(FTy), CS.arg_size(), U); } SmallVector Arguments(CS.arg_begin(), CS.arg_end()); - return static_cast(this)->getCallCost(F, Arguments); + return static_cast(this)->getCallCost(F, Arguments, U); } if (const CastInst *CI = dyn_cast(U)) { Index: include/llvm/CodeGen/BasicTTIImpl.h =================================================================== --- include/llvm/CodeGen/BasicTTIImpl.h +++ include/llvm/CodeGen/BasicTTIImpl.h @@ -292,12 +292,12 @@ } unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef Arguments) { - return BaseT::getIntrinsicCost(IID, RetTy, Arguments); + ArrayRef Arguments, const User *U) { + return BaseT::getIntrinsicCost(IID, RetTy, Arguments, U); } unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef ParamTys) { + ArrayRef ParamTys, const User *U) { if (IID == Intrinsic::cttz) { if (getTLI()->isCheapToSpeculateCttz()) return TargetTransformInfo::TCC_Basic; @@ -310,7 +310,7 @@ return TargetTransformInfo::TCC_Expensive; } - return BaseT::getIntrinsicCost(IID, RetTy, ParamTys); + return BaseT::getIntrinsicCost(IID, RetTy, ParamTys, U); } unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -60,15 +60,17 @@ return Cost; } -int TargetTransformInfo::getCallCost(FunctionType *FTy, int NumArgs) const { - int Cost = TTIImpl->getCallCost(FTy, NumArgs); +int TargetTransformInfo::getCallCost(FunctionType *FTy, int NumArgs, + User *U) const { + int Cost = TTIImpl->getCallCost(FTy, NumArgs, U); assert(Cost >= 0 && "TTI should not produce negative costs!"); return Cost; } int TargetTransformInfo::getCallCost(const Function *F, - ArrayRef Arguments) const { - int Cost = TTIImpl->getCallCost(F, Arguments); + ArrayRef Arguments, + User *U) const { + int Cost = TTIImpl->getCallCost(F, Arguments, U); assert(Cost >= 0 && "TTI should not produce negative costs!"); return Cost; } @@ -88,8 +90,9 @@ } int TargetTransformInfo::getIntrinsicCost( - Intrinsic::ID IID, Type *RetTy, ArrayRef Arguments) const { - int Cost = TTIImpl->getIntrinsicCost(IID, RetTy, Arguments); + Intrinsic::ID IID, Type *RetTy, ArrayRef Arguments, + const User *U) const { + int Cost = TTIImpl->getIntrinsicCost(IID, RetTy, Arguments, U); assert(Cost >= 0 && "TTI should not produce negative costs!"); return Cost; }