Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -165,6 +165,16 @@ /// This overload allows specifying a set of candidate argument values. int getCallCost(const Function *F, ArrayRef Arguments) const; + /// \returns A fraction {numer, denom} 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. + std::pair + 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 +596,8 @@ virtual int getCallCost(const Function *F, int NumArgs) = 0; virtual int getCallCost(const Function *F, ArrayRef Arguments) = 0; + virtual std::pair + 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 +717,10 @@ ArrayRef Arguments) override { return Impl.getCallCost(F, Arguments); } + std::pair + 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,11 @@ return TTI::TCC_Basic * (NumArgs + 1); } + std::pair + getInliningThresholdMultiplier(const Function * /* Caller */) { + return {1, 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,11 @@ return BaseT::getOperationCost(Opcode, Ty, OpTy); } + std::pair + getInliningThresholdMultiplier(const Function * /* Caller */) { + return {1, 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. + std::pair Mult = TTI.getInliningThresholdMultiplier(Caller); + Threshold = Threshold * Mult.first / Mult.second; } bool CallAnalyzer::visitCmpInst(CmpInst &I) { Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -66,6 +66,15 @@ return Cost; } +std::pair TargetTransformInfo::getInliningThresholdMultiplier( + const Function *Caller) const { + std::pair Multiplier = + TTIImpl->getInliningThresholdMultiplier(Caller); + assert(Multiplier.first >= 0 && "Multiplier numerator cannot be negative"); + assert(Multiplier.second > 0 && "Multiplier denominator must be positive"); + return Multiplier; +} + int TargetTransformInfo::getIntrinsicCost( Intrinsic::ID IID, Type *RetTy, ArrayRef Arguments) const { int Cost = TTIImpl->getIntrinsicCost(IID, RetTy, Arguments);