Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -165,6 +165,13 @@ /// This overload allows specifying a set of candidate argument values. int getCallCost(const Function *F, ArrayRef Arguments) const; + /// \returns A value by which our inlining threshold should be multiplied, for + /// the given caller function. This is primarily used to bump up the inlining + /// threshold wholesale on targets where calls are unusually expensive. + /// TODO: This is a rather blunt instrument. Perhaps altering the costs of + /// individual classes of instructions would be better. + double getInliningThresholdMultiplier(const Function *Caller) const; + /// \brief Estimate the cost of an intrinsic when lowered. /// /// Mirrors the \c getCallCost method but uses an intrinsic identifier. @@ -586,6 +593,7 @@ virtual int getCallCost(const Function *F, int NumArgs) = 0; virtual int getCallCost(const Function *F, ArrayRef Arguments) = 0; + virtual double getInliningThresholdMultiplier(const Function *Caller) = 0; virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, ArrayRef ParamTys) = 0; virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, @@ -705,6 +713,9 @@ ArrayRef Arguments) override { return Impl.getCallCost(F, Arguments); } + double getInliningThresholdMultiplier(const Function *Caller) override { + return Impl.getInliningThresholdMultiplier(Caller); + } int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, ArrayRef ParamTys) override { return Impl.getIntrinsicCost(IID, RetTy, ParamTys); Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -128,6 +128,10 @@ return TTI::TCC_Basic * (NumArgs + 1); } + double getInliningThresholdMultiplier(const Function * /* Caller */) { + return 1; + } + unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, ArrayRef ParamTys) { switch (IID) { Index: include/llvm/CodeGen/BasicTTIImpl.h =================================================================== --- include/llvm/CodeGen/BasicTTIImpl.h +++ include/llvm/CodeGen/BasicTTIImpl.h @@ -216,6 +216,10 @@ return BaseT::getOperationCost(Opcode, Ty, OpTy); } + double getInliningThresholdMultiplier(const Function * /* Caller */) { + return 1; + } + void getUnrollingPreferences(Loop *L, TTI::UnrollingPreferences &UP) { // This unrolling functionality is target independent, but to provide some // motivation for its intended use, for x86: Index: lib/Analysis/InlineCost.cpp =================================================================== --- lib/Analysis/InlineCost.cpp +++ lib/Analysis/InlineCost.cpp @@ -620,6 +620,11 @@ ColdThreshold.getNumOccurrences() > 0) && ColdCallee && ColdThreshold < Threshold) Threshold = ColdThreshold; + + // Finally, take the target-specific inlining threshold multiplier into + // account. + Threshold = + std::round(Threshold * TTI.getInliningThresholdMultiplier(Caller)); } bool CallAnalyzer::visitCmpInst(CmpInst &I) { Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -66,6 +66,14 @@ return Cost; } +double TargetTransformInfo::getInliningThresholdMultiplier( + const Function *Caller) const { + double Multiplier = TTIImpl->getInliningThresholdMultiplier(Caller); + assert(!std::isnan(Multiplier) && "Multiplier cannot be nan"); + assert(!std::isinf(Multiplier) && "Multiplier cannot be infinity"); + return Multiplier; +} + int TargetTransformInfo::getIntrinsicCost( Intrinsic::ID IID, Type *RetTy, ArrayRef Arguments) const { int Cost = TTIImpl->getIntrinsicCost(IID, RetTy, Arguments);